aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharles Yin <charles.yin@nokia.com>2011-10-21 15:26:16 +1000
committerCharles Yin <charles.yin@nokia.com>2011-10-21 16:04:04 +1000
commita4100aa65f3d7963198584aec21eb4f67f646fe0 (patch)
treee1dabd1f72f2a6de102b8187b7ef391686d61397
parent6574543e74e6eca1c3e76f5dcd5f47bfb33e9bdd (diff)
parent2bf7113a0ddfe4490cf9df1780a72c36ae282f8c (diff)
Merge branch 'master' into animation-refactor
Conflicts: src/declarative/debugger/qdeclarativedebughelper.cpp src/declarative/items/qsgcanvas.cpp src/declarative/particles/qsgparticlesystem.cpp src/declarative/particles/qsgparticlesystem_p.h src/declarative/scenegraph/qsgcontext_p.h src/declarative/util/qdeclarativeanimation.cpp src/declarative/util/qdeclarativeanimation_p.h src/declarative/util/qdeclarativebehavior.cpp src/declarative/util/qdeclarativesmoothedanimation.cpp src/declarative/util/qdeclarativesmoothedanimation_p_p.h tests/auto/declarative/qdeclarativetimer/qdeclarativetimer.pro Change-Id: I74c51cb6f7b6fb2f96b8f107c4a6f7468462cd50
-rw-r--r--doc/config/qtdeclarative_doc.pri13
-rw-r--r--doc/config/qtquick-dita.qdocconf24
-rw-r--r--doc/config/qtquick.qdocconf84
-rwxr-xr-xdoc/config/style/qtquick.css681
-rw-r--r--doc/src/declarative/advtutorial.qdoc2
-rw-r--r--doc/src/declarative/anchor-layout.qdoc16
-rw-r--r--doc/src/declarative/animation.qdoc8
-rw-r--r--doc/src/declarative/basictypes.qdoc69
-rw-r--r--doc/src/declarative/codingconventions.qdoc6
-rw-r--r--doc/src/declarative/declarativeui.qdoc4
-rw-r--r--doc/src/declarative/example-slideswitch.qdoc10
-rw-r--r--doc/src/declarative/extending.qdoc18
-rw-r--r--doc/src/declarative/focus.qdoc8
-rw-r--r--doc/src/declarative/globalobject.qdoc28
-rw-r--r--doc/src/declarative/javascriptblocks.qdoc4
-rw-r--r--doc/src/declarative/modules.qdoc8
-rw-r--r--doc/src/declarative/network.qdoc2
-rw-r--r--doc/src/declarative/pics/declarative-qmlfocus1.pngbin22047 -> 0 bytes
-rw-r--r--doc/src/declarative/pics/declarative-qmlfocus2.pngbin24225 -> 0 bytes
-rw-r--r--doc/src/declarative/pics/declarative-qmlfocus3.pngbin26300 -> 0 bytes
-rw-r--r--doc/src/declarative/pics/declarative-qmlfocus4.pngbin21401 -> 0 bytes
-rw-r--r--doc/src/declarative/propertybinding.qdoc24
-rw-r--r--doc/src/declarative/qdeclarativedocument.qdoc10
-rw-r--r--doc/src/declarative/qdeclarativeintro.qdoc14
-rw-r--r--doc/src/declarative/qdeclarativemodels.qdoc42
-rw-r--r--doc/src/declarative/qdeclarativeperformance.qdoc46
-rw-r--r--doc/src/declarative/qdeclarativesecurity.qdoc4
-rw-r--r--doc/src/declarative/qdeclarativestates.qdoc6
-rw-r--r--doc/src/declarative/qmlevents.qdoc4
-rw-r--r--doc/src/declarative/qmlreusablecomponents.qdoc8
-rw-r--r--doc/src/declarative/qmlsyntax.qdoc6
-rw-r--r--doc/src/declarative/qmlviewer.qdoc4
-rw-r--r--doc/src/declarative/qmlviews.qdoc6
-rw-r--r--doc/src/declarative/qtbinding.qdoc2
-rw-r--r--doc/src/declarative/qtdeclarative.qdoc2
-rw-r--r--doc/src/declarative/qtjavascript.qdoc2
-rw-r--r--doc/src/declarative/qtprogrammers.qdoc4
-rw-r--r--doc/src/declarative/qtquick-intro.qdoc6
-rw-r--r--doc/src/declarative/scope.qdoc2
-rw-r--r--doc/src/declarative/tutorial.qdoc26
-rw-r--r--doc/src/declarative/whatsnew.qdoc189
-rw-r--r--doc/src/images/3d-axis.png (renamed from doc/src/declarative/pics/3d-axis.png)bin13840 -> 13840 bytes
-rw-r--r--doc/src/images/3d-rotation-axis.png (renamed from doc/src/declarative/pics/3d-rotation-axis.png)bin11078 -> 11078 bytes
-rw-r--r--doc/src/images/BorderImage.png (renamed from doc/src/declarative/pics/BorderImage.png)bin8094 -> 8094 bytes
-rw-r--r--doc/src/images/ListViewHighlight.png (renamed from doc/src/declarative/pics/ListViewHighlight.png)bin3582 -> 3582 bytes
-rw-r--r--doc/src/images/ListViewHorizontal.png (renamed from doc/src/declarative/pics/ListViewHorizontal.png)bin5802 -> 5802 bytes
-rw-r--r--doc/src/images/ListViewVertical.png (renamed from doc/src/declarative/pics/ListViewVertical.png)bin2424 -> 2424 bytes
-rw-r--r--doc/src/images/anatomy-component.png (renamed from doc/src/declarative/pics/anatomy-component.png)bin4902 -> 4902 bytes
-rw-r--r--doc/src/images/anchorchanges.png (renamed from doc/src/declarative/pics/anchorchanges.png)bin566 -> 566 bytes
-rw-r--r--doc/src/images/anchors.svg (renamed from doc/src/declarative/pics/anchors.svg)0
-rw-r--r--doc/src/images/animatedimageitem.gif (renamed from doc/src/declarative/pics/animatedimageitem.gif)bin9997 -> 9997 bytes
-rw-r--r--doc/src/images/axisrotation.png (renamed from doc/src/declarative/pics/axisrotation.png)bin8891 -> 8891 bytes
-rw-r--r--doc/src/images/blur_example.png (renamed from doc/src/declarative/pics/blur_example.png)bin64019 -> 64019 bytes
-rw-r--r--doc/src/images/content.png (renamed from doc/src/declarative/pics/content.png)bin1978 -> 1978 bytes
-rw-r--r--doc/src/images/declarative-adv-tutorial1.png (renamed from doc/src/declarative/pics/declarative-adv-tutorial1.png)bin203229 -> 203229 bytes
-rw-r--r--doc/src/images/declarative-adv-tutorial2.png (renamed from doc/src/declarative/pics/declarative-adv-tutorial2.png)bin249451 -> 249451 bytes
-rw-r--r--doc/src/images/declarative-adv-tutorial3.png (renamed from doc/src/declarative/pics/declarative-adv-tutorial3.png)bin283378 -> 283378 bytes
-rw-r--r--doc/src/images/declarative-adv-tutorial4.gif (renamed from doc/src/declarative/pics/declarative-adv-tutorial4.gif)bin1687445 -> 1687445 bytes
-rw-r--r--doc/src/images/dial-example.gif (renamed from doc/src/declarative/pics/dial-example.gif)bin566465 -> 566465 bytes
-rw-r--r--doc/src/images/edge1.png (renamed from doc/src/declarative/pics/edge1.png)bin3423 -> 3423 bytes
-rw-r--r--doc/src/images/edge2.png (renamed from doc/src/declarative/pics/edge2.png)bin3436 -> 3436 bytes
-rw-r--r--doc/src/images/edge3.png (renamed from doc/src/declarative/pics/edge3.png)bin3854 -> 3854 bytes
-rw-r--r--doc/src/images/edge4.png (renamed from doc/src/declarative/pics/edge4.png)bin5152 -> 5152 bytes
-rw-r--r--doc/src/images/edges.png (renamed from doc/src/declarative/pics/edges.png)bin15226 -> 15226 bytes
-rw-r--r--doc/src/images/edges.svg (renamed from doc/src/declarative/pics/edges.svg)0
-rw-r--r--doc/src/images/edges_examples.svg (renamed from doc/src/declarative/pics/edges_examples.svg)0
-rw-r--r--doc/src/images/edges_qml.png (renamed from doc/src/declarative/pics/edges_qml.png)bin21731 -> 21731 bytes
-rw-r--r--doc/src/images/edges_qml.svg (renamed from doc/src/declarative/pics/edges_qml.svg)0
-rw-r--r--doc/src/images/extending-tutorial-chapter1.png (renamed from doc/src/declarative/pics/extending-tutorial-chapter1.png)bin6687 -> 6687 bytes
-rw-r--r--doc/src/images/extending-tutorial-chapter2.png (renamed from doc/src/declarative/pics/extending-tutorial-chapter2.png)bin7318 -> 7318 bytes
-rw-r--r--doc/src/images/extending-tutorial-chapter3.png (renamed from doc/src/declarative/pics/extending-tutorial-chapter3.png)bin8145 -> 8145 bytes
-rw-r--r--doc/src/images/extending-tutorial-chapter5.png (renamed from doc/src/declarative/pics/extending-tutorial-chapter5.png)bin5557 -> 5557 bytes
-rw-r--r--doc/src/images/flickable.gif (renamed from doc/src/declarative/pics/flickable.gif)bin185221 -> 185221 bytes
-rw-r--r--doc/src/images/flipable.gif (renamed from doc/src/declarative/pics/flipable.gif)bin131710 -> 131710 bytes
-rw-r--r--doc/src/images/gridLayout_example.png (renamed from doc/src/declarative/pics/gridLayout_example.png)bin437 -> 437 bytes
-rw-r--r--doc/src/images/gridview-highlight.png (renamed from doc/src/declarative/pics/gridview-highlight.png)bin11806 -> 11806 bytes
-rw-r--r--doc/src/images/gridview-simple.png (renamed from doc/src/declarative/pics/gridview-simple.png)bin10149 -> 10149 bytes
-rw-r--r--doc/src/images/highlight.gif (renamed from doc/src/declarative/pics/highlight.gif)bin18259 -> 18259 bytes
-rw-r--r--doc/src/images/horizontalpositioner_example.png (renamed from doc/src/declarative/pics/horizontalpositioner_example.png)bin292 -> 292 bytes
-rw-r--r--doc/src/images/imageprovider.png (renamed from doc/src/declarative/pics/imageprovider.png)bin420 -> 420 bytes
-rw-r--r--doc/src/images/layoutmirroring.png (renamed from doc/src/declarative/pics/layoutmirroring.png)bin2542 -> 2542 bytes
-rw-r--r--doc/src/images/listmodel-nested.png (renamed from doc/src/declarative/pics/listmodel-nested.png)bin7493 -> 7493 bytes
-rw-r--r--doc/src/images/listmodel.png (renamed from doc/src/declarative/pics/listmodel.png)bin3407 -> 3407 bytes
-rw-r--r--doc/src/images/listview-highlight.png (renamed from doc/src/declarative/pics/listview-highlight.png)bin5918 -> 5918 bytes
-rw-r--r--doc/src/images/listview-simple.png (renamed from doc/src/declarative/pics/listview-simple.png)bin5351 -> 5351 bytes
-rw-r--r--doc/src/images/margins_qml.png (renamed from doc/src/declarative/pics/margins_qml.png)bin18476 -> 18476 bytes
-rw-r--r--doc/src/images/margins_qml.svg (renamed from doc/src/declarative/pics/margins_qml.svg)0
-rw-r--r--doc/src/images/parentchange.png (renamed from doc/src/declarative/pics/parentchange.png)bin509 -> 509 bytes
-rw-r--r--doc/src/images/particles.gif (renamed from doc/src/declarative/pics/particles.gif)bin163068 -> 163068 bytes
-rw-r--r--doc/src/images/pathview.gif (renamed from doc/src/declarative/pics/pathview.gif)bin90512 -> 90512 bytes
-rw-r--r--doc/src/images/positioner-add.gif (renamed from doc/src/declarative/pics/positioner-add.gif)bin7821 -> 7821 bytes
-rw-r--r--doc/src/images/positioner-move.gif (renamed from doc/src/declarative/pics/positioner-move.gif)bin6154 -> 6154 bytes
-rw-r--r--doc/src/images/positioner-remove.gif (renamed from doc/src/declarative/pics/positioner-remove.gif)bin5610 -> 5610 bytes
-rw-r--r--doc/src/images/propanim.gif (renamed from doc/src/declarative/pics/propanim.gif)bin74909 -> 74909 bytes
-rw-r--r--doc/src/images/qml-context-object.png (renamed from doc/src/declarative/pics/qml-context-object.png)bin23602 -> 23602 bytes
-rw-r--r--doc/src/images/qml-context-tree.png (renamed from doc/src/declarative/pics/qml-context-tree.png)bin10337 -> 10337 bytes
-rw-r--r--doc/src/images/qml-context.png (renamed from doc/src/declarative/pics/qml-context.png)bin61465 -> 61465 bytes
-rw-r--r--doc/src/images/qml-extending-types.png (renamed from doc/src/declarative/pics/qml-extending-types.png)bin738 -> 738 bytes
-rw-r--r--doc/src/images/qml-gradient.png (renamed from doc/src/declarative/pics/qml-gradient.png)bin364 -> 364 bytes
-rw-r--r--doc/src/images/qml-scope.png (renamed from doc/src/declarative/pics/qml-scope.png)bin47564 -> 47564 bytes
-rw-r--r--doc/src/images/qtlogo.png (renamed from doc/src/declarative/pics/qtlogo.png)bin2738 -> 2738 bytes
-rw-r--r--doc/src/images/rect-border-width.png (renamed from doc/src/declarative/pics/rect-border-width.png)bin374 -> 374 bytes
-rw-r--r--doc/src/images/rect-color.png (renamed from doc/src/declarative/pics/rect-color.png)bin570 -> 570 bytes
-rw-r--r--doc/src/images/rect-smooth.png (renamed from doc/src/declarative/pics/rect-smooth.png)bin24241 -> 24241 bytes
-rw-r--r--doc/src/images/reflection_example.png (renamed from doc/src/declarative/pics/reflection_example.png)bin30919 -> 30919 bytes
-rw-r--r--doc/src/images/repeater-index.png (renamed from doc/src/declarative/pics/repeater-index.png)bin3024 -> 3024 bytes
-rw-r--r--doc/src/images/repeater-modeldata.png (renamed from doc/src/declarative/pics/repeater-modeldata.png)bin3394 -> 3394 bytes
-rw-r--r--doc/src/images/repeater-simple.png (renamed from doc/src/declarative/pics/repeater-simple.png)bin404 -> 404 bytes
-rw-r--r--doc/src/images/repeater.png (renamed from doc/src/declarative/pics/repeater.png)bin800 -> 800 bytes
-rw-r--r--doc/src/images/scalegrid.svg (renamed from doc/src/declarative/pics/scalegrid.svg)0
-rw-r--r--doc/src/images/shadow_example.png (renamed from doc/src/declarative/pics/shadow_example.png)bin4775 -> 4775 bytes
-rw-r--r--doc/src/images/squish-transform.png (renamed from doc/src/declarative/pics/squish-transform.png)bin9652 -> 9652 bytes
-rw-r--r--doc/src/images/squish.png (renamed from doc/src/declarative/pics/squish.png)bin8590 -> 8590 bytes
-rw-r--r--doc/src/images/switch-example.gif (renamed from doc/src/declarative/pics/switch-example.gif)bin25270 -> 25270 bytes
-rw-r--r--doc/src/images/translate.png (renamed from doc/src/declarative/pics/translate.png)bin398 -> 398 bytes
-rw-r--r--doc/src/images/verticalpositioner_example.png (renamed from doc/src/declarative/pics/verticalpositioner_example.png)bin385 -> 385 bytes
-rw-r--r--doc/src/images/verticalpositioner_transition.gif (renamed from doc/src/declarative/pics/verticalpositioner_transition.gif)bin12641 -> 12641 bytes
-rw-r--r--doc/src/images/visualitemmodel.png (renamed from doc/src/declarative/pics/visualitemmodel.png)bin347 -> 347 bytes
-rw-r--r--doc/src/images/webview.png (renamed from doc/src/declarative/pics/webview.png)bin126662 -> 126662 bytes
-rw-r--r--doc/src/qtquick1/declarativeui.qdoc6
-rw-r--r--doc/src/qtquick1/qdeclarativeperformance.qdoc2
-rw-r--r--doc/src/qtquick1/whatsnew.qdoc47
-rw-r--r--doc/src/snippets/declarative/drag.qml75
-rw-r--r--doc/src/snippets/declarative/visualdatagroup.qml (renamed from examples/declarative/inputmethods/spellcheck/Key.qml)68
-rw-r--r--examples/declarative/canvas/bezierCurve/bezierCurve.qml2
-rw-r--r--examples/declarative/canvas/quadraticCurveTo/quadraticCurveTo.qml2
-rw-r--r--examples/declarative/canvas/roundedrect/roundedrect.qml2
-rw-r--r--examples/declarative/canvas/smile/smile.qml2
-rw-r--r--examples/declarative/canvas/squircle/squircle.qml2
-rw-r--r--examples/declarative/canvas/tiger/tiger.qml2
-rw-r--r--examples/declarative/canvas/twitterfriends/TwitterUser.qml2
-rw-r--r--examples/declarative/draganddrop/dragtarget.qmlproject (renamed from examples/declarative/dragtarget/dragtarget.qmlproject)0
-rw-r--r--examples/declarative/draganddrop/tiles/DragTile.qml (renamed from examples/declarative/screenorientation/Core/Button.qml)70
-rw-r--r--examples/declarative/draganddrop/tiles/DropTile.qml (renamed from examples/declarative/dragtarget/tiles/DropTile.qml)34
-rw-r--r--examples/declarative/draganddrop/tiles/tiles.qml (renamed from examples/declarative/dragtarget/tiles/tiles.qml)30
-rw-r--r--examples/declarative/draganddrop/views/gridview.qml117
-rw-r--r--examples/declarative/dragtarget/lists/listmodel.qml296
-rw-r--r--examples/declarative/dragtarget/text/dragtext.qml182
-rw-r--r--examples/declarative/dragtarget/text/text.qmlproject16
-rw-r--r--examples/declarative/dragtarget/tiles/DragTile.qml99
-rw-r--r--examples/declarative/imageelements/ImageCell.qml (renamed from examples/declarative/imageelements/image/ImageCell.qml)5
-rw-r--r--examples/declarative/imageelements/borderimage.qml (renamed from examples/declarative/imageelements/borderimage/borderimage.qml)0
-rw-r--r--examples/declarative/imageelements/content/MyBorderImage.qml (renamed from examples/declarative/imageelements/borderimage/content/MyBorderImage.qml)0
-rw-r--r--examples/declarative/imageelements/content/ShadowRectangle.qml (renamed from examples/declarative/imageelements/borderimage/content/ShadowRectangle.qml)0
-rw-r--r--examples/declarative/imageelements/content/bw.png (renamed from examples/declarative/imageelements/borderimage/content/bw.png)bin1357 -> 1357 bytes
-rw-r--r--examples/declarative/imageelements/content/colors-round.sci (renamed from examples/declarative/imageelements/borderimage/content/colors-round.sci)0
-rw-r--r--examples/declarative/imageelements/content/colors-stretch.sci (renamed from examples/declarative/imageelements/borderimage/content/colors-stretch.sci)0
-rw-r--r--examples/declarative/imageelements/content/colors.png (renamed from examples/declarative/imageelements/borderimage/content/colors.png)bin1655 -> 1655 bytes
-rw-r--r--examples/declarative/imageelements/content/qt-logo.png (renamed from examples/declarative/imageelements/image/qml/qt-logo.png)bin5149 -> 5149 bytes
-rw-r--r--examples/declarative/imageelements/content/shadow.png (renamed from examples/declarative/imageelements/borderimage/content/shadow.png)bin588 -> 588 bytes
-rw-r--r--examples/declarative/imageelements/image.qml (renamed from examples/declarative/imageelements/image/image.qml)2
-rw-r--r--examples/declarative/imageelements/image/image.desktop11
-rw-r--r--examples/declarative/imageelements/image/image.pngbin3400 -> 0 bytes
-rw-r--r--examples/declarative/imageelements/image/image.pro39
-rw-r--r--examples/declarative/imageelements/image/image.svg93
-rw-r--r--examples/declarative/imageelements/image/main.cpp54
-rw-r--r--examples/declarative/imageelements/image/qml/ImageCell.qml60
-rw-r--r--examples/declarative/imageelements/image/qml/image.qml66
-rw-r--r--examples/declarative/imageelements/image/qmlapplicationviewer/qmlapplicationviewer.cpp197
-rw-r--r--examples/declarative/imageelements/image/qmlapplicationviewer/qmlapplicationviewer.h79
-rw-r--r--examples/declarative/imageelements/image/qmlapplicationviewer/qmlapplicationviewer.pri154
-rw-r--r--examples/declarative/imageelements/shadows.qml (renamed from examples/declarative/imageelements/borderimage/shadows.qml)0
-rw-r--r--examples/declarative/imageelements/shadows/main.cpp54
-rw-r--r--examples/declarative/imageelements/shadows/qml/borderimage.qml97
-rw-r--r--examples/declarative/imageelements/shadows/qml/content/MyBorderImage.qml90
-rw-r--r--examples/declarative/imageelements/shadows/qml/content/ShadowRectangle.qml54
-rw-r--r--examples/declarative/imageelements/shadows/qml/content/bw.pngbin1357 -> 0 bytes
-rw-r--r--examples/declarative/imageelements/shadows/qml/content/colors-round.sci7
-rw-r--r--examples/declarative/imageelements/shadows/qml/content/colors-stretch.sci5
-rw-r--r--examples/declarative/imageelements/shadows/qml/content/colors.pngbin1655 -> 0 bytes
-rw-r--r--examples/declarative/imageelements/shadows/qml/content/shadow.pngbin588 -> 0 bytes
-rw-r--r--examples/declarative/imageelements/shadows/qml/shadows.qml64
-rw-r--r--examples/declarative/imageelements/shadows/qmlapplicationviewer/qmlapplicationviewer.cpp197
-rw-r--r--examples/declarative/imageelements/shadows/qmlapplicationviewer/qmlapplicationviewer.h79
-rw-r--r--examples/declarative/imageelements/shadows/qmlapplicationviewer/qmlapplicationviewer.pri154
-rw-r--r--examples/declarative/imageelements/shadows/shadows.desktop11
-rw-r--r--examples/declarative/imageelements/shadows/shadows.pngbin3400 -> 0 bytes
-rw-r--r--examples/declarative/imageelements/shadows/shadows.pro39
-rw-r--r--examples/declarative/imageelements/shadows/shadows.svg93
-rw-r--r--examples/declarative/inputmethods/inputmethods.qmlproject16
-rw-r--r--examples/declarative/inputmethods/spellcheck/Keyboard.qml141
-rw-r--r--examples/declarative/inputmethods/spellcheck/spellcheck.qml137
-rw-r--r--examples/declarative/modelviews/listview/content/ToggleButton.qml40
-rw-r--r--examples/declarative/modelviews/visualdatamodel/dragselection.qml200
-rw-r--r--examples/declarative/modelviews/visualdatamodel/slideshow.qml155
-rw-r--r--examples/declarative/modelviews/visualdatamodel/sortedmodel.qml141
-rw-r--r--examples/declarative/modelviews/visualdatamodel/visualdatamodel.qmlproject (renamed from examples/declarative/dragtarget/lists/lists.qmlproject)0
-rw-r--r--examples/declarative/particles/affectors/gravity.qml8
-rw-r--r--examples/declarative/particles/affectors/groupgoal.qml9
-rw-r--r--examples/declarative/particles/affectors/move.qml (renamed from examples/declarative/inputmethods/spellcheck/WordSuggestions.qml)136
-rw-r--r--examples/declarative/particles/customparticle/blurparticles.qml4
-rw-r--r--examples/declarative/particles/customparticle/imagecolors.qml14
-rw-r--r--examples/declarative/particles/emitters/emitmask.qml2
-rw-r--r--examples/declarative/particles/emitters/timedgroupchanges.qml2
-rw-r--r--examples/declarative/particles/emitters/trailemitter.qml12
-rw-r--r--examples/declarative/particles/imageparticle/allatonce.qml24
-rw-r--r--examples/declarative/particles/imageparticle/deformation.qml17
-rw-r--r--examples/declarative/particles/imageparticle/rotation.qml11
-rw-r--r--examples/declarative/particles/imageparticle/sprites.qml139
-rw-r--r--examples/declarative/particles/images/bear_tiles.pngbin0 -> 40349 bytes
-rw-r--r--examples/declarative/particles/images/launcherIcons/allatonce.pngbin9590 -> 7075 bytes
-rw-r--r--examples/declarative/particles/images/launcherIcons/blurparticles.pngbin7793 -> 19109 bytes
-rw-r--r--examples/declarative/particles/images/launcherIcons/deformation.pngbin2863 -> 2870 bytes
-rw-r--r--examples/declarative/particles/images/launcherIcons/emitmask.pngbin6963 -> 45055 bytes
-rw-r--r--examples/declarative/particles/images/launcherIcons/imagecolors.pngbin12784 -> 56647 bytes
-rw-r--r--examples/declarative/particles/images/launcherIcons/rotation.pngbin4705 -> 20661 bytes
-rw-r--r--examples/declarative/particles/images/launcherIcons/sprites.pngbin2565 -> 17009 bytes
-rw-r--r--examples/declarative/particles/images/singlesmile.pngbin269 -> 0 bytes
-rw-r--r--examples/declarative/particles/images/smileMask.pngbin259 -> 0 bytes
-rw-r--r--examples/declarative/particles/images/squarefacesprite2.pngbin459 -> 0 bytes
-rw-r--r--examples/declarative/particles/images/squarefacesprite3.pngbin476 -> 0 bytes
-rw-r--r--examples/declarative/particles/images/squarefacesprite4.pngbin553 -> 0 bytes
-rw-r--r--examples/declarative/particles/images/squarefacesprite5.pngbin623 -> 0 bytes
-rw-r--r--examples/declarative/particles/images/squarefacesprite6.pngbin615 -> 0 bytes
-rw-r--r--examples/declarative/particles/images/squarefacesprite7.pngbin581 -> 0 bytes
-rw-r--r--examples/declarative/particles/images/squarefacespriteX.pngbin474 -> 0 bytes
-rw-r--r--examples/declarative/particles/images/squarefacespriteXX.pngbin255 -> 0 bytes
-rw-r--r--examples/declarative/particles/images/squarefacewhite.pngbin496 -> 0 bytes
-rw-r--r--examples/declarative/particles/images/squarefacewhiteX.pngbin463 -> 0 bytes
-rw-r--r--examples/declarative/particles/images/squarefacewhiteXX.pngbin261 -> 0 bytes
-rw-r--r--examples/declarative/particles/images/starfish_0.pngbin0 -> 15972 bytes
-rw-r--r--examples/declarative/particles/images/starfish_1.pngbin0 -> 15746 bytes
-rw-r--r--examples/declarative/particles/images/starfish_2.pngbin0 -> 16067 bytes
-rw-r--r--examples/declarative/particles/images/starfish_3.pngbin0 -> 16201 bytes
-rw-r--r--examples/declarative/particles/images/starfish_4.pngbin0 -> 14698 bytes
-rw-r--r--examples/declarative/particles/images/starfish_mask.pngbin0 -> 11301 bytes
-rw-r--r--examples/declarative/particles/itemparticle/particleview.qml3
-rw-r--r--examples/declarative/particles/plasmapatrol/content/LaserHardpoint.qml2
-rw-r--r--examples/declarative/samegame/SamegameCore/BoomBlock.qml2
-rw-r--r--examples/declarative/screenorientation/Core/Bubble.qml90
-rw-r--r--examples/declarative/screenorientation/Core/screenorientation.js94
-rw-r--r--examples/declarative/screenorientation/screenorientation.qml201
-rw-r--r--examples/declarative/screenorientation/screenorientation.qmlproject16
-rw-r--r--modules/qt_qmldevtools.pri19
-rw-r--r--qtdeclarative.pro2
-rw-r--r--src/3rdparty/javascriptcore/DateMath.cpp4
-rw-r--r--src/declarative/debugger/debugger.pri4
-rw-r--r--src/declarative/debugger/qdeclarativedebugclient.cpp4
-rw-r--r--src/declarative/debugger/qdeclarativedebuggerstatus.cpp2
-rw-r--r--src/declarative/debugger/qdeclarativedebughelper.cpp8
-rw-r--r--src/declarative/debugger/qdeclarativedebugserver.cpp12
-rw-r--r--src/declarative/debugger/qdeclarativedebugserverconnection_p.h2
-rw-r--r--src/declarative/debugger/qdeclarativedebugservice.cpp6
-rw-r--r--src/declarative/debugger/qdeclarativedebugtrace.cpp73
-rw-r--r--src/declarative/debugger/qdeclarativedebugtrace_p.h19
-rw-r--r--src/declarative/debugger/qdeclarativeenginedebug.cpp6
-rw-r--r--src/declarative/debugger/qdeclarativeenginedebugservice.cpp30
-rw-r--r--src/declarative/debugger/qdeclarativeinspectorinterface_p.h2
-rw-r--r--src/declarative/debugger/qdeclarativeinspectorservice.cpp22
-rw-r--r--src/declarative/debugger/qdeclarativeinspectorservice_p.h3
-rw-r--r--src/declarative/debugger/qpacketprotocol.cpp2
-rw-r--r--src/declarative/debugger/qv8debugservice.cpp73
-rw-r--r--src/declarative/debugger/qv8debugservice_p.h15
-rw-r--r--src/declarative/debugger/qv8profilerservice.cpp247
-rw-r--r--src/declarative/debugger/qv8profilerservice_p.h115
-rw-r--r--src/declarative/designer/designersupport.cpp12
-rw-r--r--src/declarative/items/context2d/context2d.pri2
-rw-r--r--src/declarative/items/context2d/qsgcanvasitem.cpp74
-rw-r--r--src/declarative/items/context2d/qsgcanvasitem_p.h8
-rw-r--r--src/declarative/items/context2d/qsgcontext2d.cpp1057
-rw-r--r--src/declarative/items/context2d/qsgcontext2d_p.h7
-rw-r--r--src/declarative/items/context2d/qsgcontext2dcommandbuffer.cpp115
-rw-r--r--src/declarative/items/context2d/qsgcontext2dcommandbuffer_p.h13
-rw-r--r--src/declarative/items/context2d/qsgcontext2dnode.cpp14
-rw-r--r--src/declarative/items/context2d/qsgcontext2dnode_p.h6
-rw-r--r--src/declarative/items/context2d/qsgcontext2dtexture.cpp137
-rw-r--r--src/declarative/items/context2d/qsgcontext2dtexture_p.h8
-rw-r--r--src/declarative/items/context2d/qsgcontext2dtile.cpp12
-rw-r--r--src/declarative/items/context2d/qsgcontext2dtile_p.h5
-rw-r--r--src/declarative/items/items.pri9
-rw-r--r--src/declarative/items/qsganchors.cpp26
-rw-r--r--src/declarative/items/qsganimatedimage.cpp20
-rw-r--r--src/declarative/items/qsganimation.cpp12
-rw-r--r--src/declarative/items/qsgborderimage.cpp13
-rw-r--r--src/declarative/items/qsgborderimage_p_p.h8
-rw-r--r--src/declarative/items/qsgcanvas.cpp282
-rw-r--r--src/declarative/items/qsgcanvas.h3
-rw-r--r--src/declarative/items/qsgcanvas_p.h16
-rw-r--r--src/declarative/items/qsgdrag.cpp462
-rw-r--r--src/declarative/items/qsgdrag_p.h208
-rw-r--r--src/declarative/items/qsgdragtarget.cpp361
-rw-r--r--src/declarative/items/qsgdroparea.cpp426
-rw-r--r--src/declarative/items/qsgdroparea_p.h (renamed from src/declarative/items/qsgdragtarget_p.h)116
-rw-r--r--src/declarative/items/qsgevent.h137
-rw-r--r--src/declarative/items/qsgevents_p_p.h3
-rw-r--r--src/declarative/items/qsgflickable.cpp280
-rw-r--r--src/declarative/items/qsgflickable_p.h30
-rw-r--r--src/declarative/items/qsgflickable_p_p.h26
-rw-r--r--src/declarative/items/qsggridview.cpp270
-rw-r--r--src/declarative/items/qsgimage.cpp14
-rw-r--r--src/declarative/items/qsgimagebase.cpp1
-rw-r--r--src/declarative/items/qsgimplicitsizeitem.cpp4
-rw-r--r--src/declarative/items/qsgimplicitsizeitem_p_p.h6
-rw-r--r--src/declarative/items/qsgitem.cpp81
-rw-r--r--src/declarative/items/qsgitem.h11
-rw-r--r--src/declarative/items/qsgitem_p.h8
-rw-r--r--src/declarative/items/qsgitemsmodule.cpp18
-rw-r--r--src/declarative/items/qsgitemview.cpp183
-rw-r--r--src/declarative/items/qsgitemview_p.h1
-rw-r--r--src/declarative/items/qsgitemview_p_p.h21
-rw-r--r--src/declarative/items/qsglistview.cpp259
-rw-r--r--src/declarative/items/qsgloader.cpp229
-rw-r--r--src/declarative/items/qsgloader_p.h5
-rw-r--r--src/declarative/items/qsgloader_p_p.h23
-rw-r--r--src/declarative/items/qsgmousearea.cpp146
-rw-r--r--src/declarative/items/qsgmousearea_p.h37
-rw-r--r--src/declarative/items/qsgmousearea_p_p.h1
-rw-r--r--src/declarative/items/qsgninepatchnode.cpp36
-rw-r--r--src/declarative/items/qsgninepatchnode_p.h2
-rw-r--r--src/declarative/items/qsgpainteditem.cpp2
-rw-r--r--src/declarative/items/qsgpathview.cpp34
-rw-r--r--src/declarative/items/qsgpathview_p_p.h1
-rw-r--r--src/declarative/items/qsgpincharea.cpp2
-rw-r--r--src/declarative/items/qsgpositioners.cpp12
-rw-r--r--src/declarative/items/qsgrepeater.cpp7
-rw-r--r--src/declarative/items/qsgscalegrid.cpp2
-rw-r--r--src/declarative/items/qsgshadereffect.cpp6
-rw-r--r--src/declarative/items/qsgshadereffect_p.h2
-rw-r--r--src/declarative/items/qsgshadereffectsource.cpp2
-rw-r--r--src/declarative/items/qsgshadereffectsource_p.h4
-rw-r--r--src/declarative/items/qsgsprite.cpp74
-rw-r--r--src/declarative/items/qsgsprite_p.h1
-rw-r--r--src/declarative/items/qsgspriteengine.cpp76
-rw-r--r--src/declarative/items/qsgspriteengine_p.h8
-rw-r--r--src/declarative/items/qsgspriteimage.cpp216
-rw-r--r--src/declarative/items/qsgspriteimage_p.h17
-rw-r--r--src/declarative/items/qsgtext.cpp288
-rw-r--r--src/declarative/items/qsgtext_p.h37
-rw-r--r--src/declarative/items/qsgtext_p_p.h9
-rw-r--r--src/declarative/items/qsgtextedit.cpp92
-rw-r--r--src/declarative/items/qsgtextedit_p.h2
-rw-r--r--src/declarative/items/qsgtextedit_p_p.h14
-rw-r--r--src/declarative/items/qsgtextinput.cpp115
-rw-r--r--src/declarative/items/qsgtextinput_p_p.h17
-rw-r--r--src/declarative/items/qsgtextnode.cpp659
-rw-r--r--src/declarative/items/qsgtextnode_p.h5
-rw-r--r--src/declarative/items/qsgtranslate.cpp3
-rw-r--r--src/declarative/items/qsgview.cpp12
-rw-r--r--src/declarative/items/qsgview_p.h3
-rw-r--r--src/declarative/items/qsgvisualadaptormodel.cpp4
-rw-r--r--src/declarative/items/qsgvisualadaptormodel_p.h2
-rw-r--r--src/declarative/items/qsgvisualdatamodel.cpp2104
-rw-r--r--src/declarative/items/qsgvisualdatamodel_p.h126
-rw-r--r--src/declarative/particles/defaultshaders/coloredfragment.shader9
-rw-r--r--src/declarative/particles/defaultshaders/coloredvertex.shader44
-rw-r--r--src/declarative/particles/defaultshaders/defaultFadeInOut.pngbin286 -> 0 bytes
-rw-r--r--src/declarative/particles/defaultshaders/deformablefragment.shader9
-rw-r--r--src/declarative/particles/defaultshaders/deformablevertex.shader65
-rw-r--r--src/declarative/particles/defaultshaders/identitytable.pngbin90 -> 0 bytes
-rw-r--r--src/declarative/particles/defaultshaders/imagefragment.shader45
-rw-r--r--src/declarative/particles/defaultshaders/imagevertex.shader126
-rw-r--r--src/declarative/particles/defaultshaders/simplefragment.shader8
-rw-r--r--src/declarative/particles/defaultshaders/simplevertex.shader39
-rw-r--r--src/declarative/particles/defaultshaders/spritefragment.shader17
-rw-r--r--src/declarative/particles/defaultshaders/spriteimagefragment.shader9
-rw-r--r--src/declarative/particles/defaultshaders/spriteimagevertex.shader52
-rw-r--r--src/declarative/particles/defaultshaders/spritevertex.shader113
-rw-r--r--src/declarative/particles/defaultshaders/tabledfragment.shader23
-rw-r--r--src/declarative/particles/defaultshaders/tabledvertex.shader56
-rw-r--r--src/declarative/particles/particleresources/noise.png (renamed from src/declarative/particles/defaultshaders/noise.png)bin19477 -> 19477 bytes
-rw-r--r--src/declarative/particles/particles.pri10
-rw-r--r--src/declarative/particles/particles.qrc8
-rw-r--r--src/declarative/particles/qsgage.cpp2
-rw-r--r--src/declarative/particles/qsgcumulativedirection_p.h5
-rw-r--r--src/declarative/particles/qsgcustomaffector.cpp4
-rw-r--r--src/declarative/particles/qsgcustomparticle.cpp30
-rw-r--r--src/declarative/particles/qsgcustomparticle_p.h4
-rw-r--r--src/declarative/particles/qsgfriction.cpp17
-rw-r--r--src/declarative/particles/qsggravity.cpp5
-rw-r--r--src/declarative/particles/qsggroupgoal.cpp111
-rw-r--r--src/declarative/particles/qsggroupgoal_p.h (renamed from src/imports/inputcontext/plugin.cpp)67
-rw-r--r--src/declarative/particles/qsgimageparticle.cpp344
-rw-r--r--src/declarative/particles/qsgimageparticle_p.h16
-rw-r--r--src/declarative/particles/qsgitemparticle.cpp10
-rw-r--r--src/declarative/particles/qsgmove.cpp131
-rw-r--r--src/declarative/particles/qsgmove_p.h155
-rw-r--r--src/declarative/particles/qsgparticleaffector.cpp12
-rw-r--r--src/declarative/particles/qsgparticleemitter.cpp7
-rw-r--r--src/declarative/particles/qsgparticlegroup_p.h7
-rw-r--r--src/declarative/particles/qsgparticlepainter.cpp8
-rw-r--r--src/declarative/particles/qsgparticlepainter_p.h2
-rw-r--r--src/declarative/particles/qsgparticlesmodule.cpp16
-rw-r--r--src/declarative/particles/qsgparticlesystem.cpp218
-rw-r--r--src/declarative/particles/qsgparticlesystem_p.h48
-rw-r--r--src/declarative/particles/qsgpointattractor.cpp9
-rw-r--r--src/declarative/particles/qsgrectangleextruder.cpp2
-rw-r--r--src/declarative/particles/qsgrectangleextruder_p.h2
-rw-r--r--src/declarative/particles/qsgspritegoal.cpp35
-rw-r--r--src/declarative/particles/qsgspritegoal_p.h4
-rw-r--r--src/declarative/particles/qsgtrailemitter.cpp43
-rw-r--r--src/declarative/particles/qsgtrailemitter_p.h6
-rw-r--r--src/declarative/particles/qsgturbulence.cpp6
-rw-r--r--src/declarative/qml/ftw/ftw.pri9
-rw-r--r--src/declarative/qml/ftw/qdeclarativerefcount_p.h58
-rw-r--r--src/declarative/qml/ftw/qdeclarativethread.cpp359
-rw-r--r--src/declarative/qml/ftw/qdeclarativethread_p.h318
-rw-r--r--src/declarative/qml/ftw/qfieldlist_p.h29
-rw-r--r--src/declarative/qml/ftw/qfinitestack_p.h186
-rw-r--r--src/declarative/qml/ftw/qmetaobjectbuilder.cpp2605
-rw-r--r--src/declarative/qml/ftw/qmetaobjectbuilder_p.h325
-rw-r--r--src/declarative/qml/ftw/qrecursionwatcher_p.h (renamed from src/declarative/qml/v4/qdeclarativev4bindings_p.h)70
-rw-r--r--src/declarative/qml/parser/parser.pri2
-rw-r--r--src/declarative/qml/parser/qdeclarativejsglobal_p.h7
-rw-r--r--src/declarative/qml/qdeclarative.h5
-rw-r--r--src/declarative/qml/qdeclarativebinding.cpp15
-rw-r--r--src/declarative/qml/qdeclarativebinding_p.h4
-rw-r--r--src/declarative/qml/qdeclarativebinding_p_p.h6
-rw-r--r--src/declarative/qml/qdeclarativeboundsignal.cpp20
-rw-r--r--src/declarative/qml/qdeclarativecleanup.cpp45
-rw-r--r--src/declarative/qml/qdeclarativecleanup_p.h6
-rw-r--r--src/declarative/qml/qdeclarativecompileddata.cpp39
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp372
-rw-r--r--src/declarative/qml/qdeclarativecompiler_p.h63
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp942
-rw-r--r--src/declarative/qml/qdeclarativecomponent.h13
-rw-r--r--src/declarative/qml/qdeclarativecomponent_p.h29
-rw-r--r--src/declarative/qml/qdeclarativecontext.cpp28
-rw-r--r--src/declarative/qml/qdeclarativecontext_p.h21
-rw-r--r--src/declarative/qml/qdeclarativecustomparser.cpp16
-rw-r--r--src/declarative/qml/qdeclarativecustomparser_p.h14
-rw-r--r--src/declarative/qml/qdeclarativecustomparser_p_p.h8
-rw-r--r--src/declarative/qml/qdeclarativedata_p.h49
-rw-r--r--src/declarative/qml/qdeclarativedirparser.cpp10
-rw-r--r--src/declarative/qml/qdeclarativedirparser_p.h4
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp346
-rw-r--r--src/declarative/qml/qdeclarativeengine.h7
-rw-r--r--src/declarative/qml/qdeclarativeengine_p.h296
-rw-r--r--src/declarative/qml/qdeclarativeexpression.cpp127
-rw-r--r--src/declarative/qml/qdeclarativeexpression.h1
-rw-r--r--src/declarative/qml/qdeclarativeexpression_p.h22
-rw-r--r--src/declarative/qml/qdeclarativeextensioninterface.h12
-rw-r--r--src/declarative/qml/qdeclarativeextensionplugin.h4
-rw-r--r--src/declarative/qml/qdeclarativefastproperties.cpp6
-rw-r--r--src/declarative/qml/qdeclarativeglobal_p.h26
-rw-r--r--src/declarative/qml/qdeclarativeguard_p.h4
-rw-r--r--src/declarative/qml/qdeclarativeimport.cpp32
-rw-r--r--src/declarative/qml/qdeclarativeimport_p.h1
-rw-r--r--src/declarative/qml/qdeclarativeincubator.cpp686
-rw-r--r--src/declarative/qml/qdeclarativeincubator.h130
-rw-r--r--src/declarative/qml/qdeclarativeincubator_p.h104
-rw-r--r--src/declarative/qml/qdeclarativeinfo.cpp12
-rw-r--r--src/declarative/qml/qdeclarativeinstruction.cpp31
-rw-r--r--src/declarative/qml/qdeclarativeinstruction_p.h57
-rw-r--r--src/declarative/qml/qdeclarativeintegercache.cpp2
-rw-r--r--src/declarative/qml/qdeclarativeintegercache_p.h4
-rw-r--r--src/declarative/qml/qdeclarativelist.cpp6
-rw-r--r--src/declarative/qml/qdeclarativelist_p.h2
-rw-r--r--src/declarative/qml/qdeclarativemetatype.cpp23
-rw-r--r--src/declarative/qml/qdeclarativemetatype_p.h2
-rw-r--r--src/declarative/qml/qdeclarativenotifier.cpp93
-rw-r--r--src/declarative/qml/qdeclarativenotifier_p.h168
-rw-r--r--src/declarative/qml/qdeclarativeproperty.cpp244
-rw-r--r--src/declarative/qml/qdeclarativeproperty_p.h27
-rw-r--r--src/declarative/qml/qdeclarativepropertycache.cpp40
-rw-r--r--src/declarative/qml/qdeclarativepropertycache_p.h148
-rw-r--r--src/declarative/qml/qdeclarativeproxymetaobject.cpp4
-rw-r--r--src/declarative/qml/qdeclarativeproxymetaobject_p.h2
-rw-r--r--src/declarative/qml/qdeclarativerewrite.cpp4
-rw-r--r--src/declarative/qml/qdeclarativescript.cpp11
-rw-r--r--src/declarative/qml/qdeclarativescript_p.h6
-rw-r--r--src/declarative/qml/qdeclarativesqldatabase.cpp8
-rw-r--r--src/declarative/qml/qdeclarativestringconverters.cpp2
-rw-r--r--src/declarative/qml/qdeclarativetypeloader.cpp581
-rw-r--r--src/declarative/qml/qdeclarativetypeloader_p.h106
-rw-r--r--src/declarative/qml/qdeclarativetypenamecache.cpp15
-rw-r--r--src/declarative/qml/qdeclarativetypenamecache_p.h13
-rw-r--r--src/declarative/qml/qdeclarativevaluetype.cpp6
-rw-r--r--src/declarative/qml/qdeclarativevaluetype_p.h4
-rw-r--r--src/declarative/qml/qdeclarativevme.cpp1000
-rw-r--r--src/declarative/qml/qdeclarativevme_p.h160
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject.cpp176
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject_p.h40
-rw-r--r--src/declarative/qml/qdeclarativewatcher.cpp8
-rw-r--r--src/declarative/qml/qdeclarativeworkerscript.cpp13
-rw-r--r--src/declarative/qml/qdeclarativexmlhttprequest.cpp12
-rw-r--r--src/declarative/qml/qml.pri4
-rw-r--r--src/declarative/qml/rewriter/rewriter.pri2
-rw-r--r--src/declarative/qml/rewriter/textwriter.cpp2
-rw-r--r--src/declarative/qml/v4/qdeclarativev4instruction.cpp553
-rw-r--r--src/declarative/qml/v4/qv4bindings.cpp (renamed from src/declarative/qml/v4/qdeclarativev4bindings.cpp)248
-rw-r--r--src/declarative/qml/v4/qv4bindings_p.h148
-rw-r--r--src/declarative/qml/v4/qv4compiler.cpp (renamed from src/declarative/qml/v4/qdeclarativev4compiler.cpp)566
-rw-r--r--src/declarative/qml/v4/qv4compiler_p.h (renamed from src/declarative/qml/v4/qdeclarativev4compiler_p.h)16
-rw-r--r--src/declarative/qml/v4/qv4compiler_p_p.h (renamed from src/declarative/qml/v4/qdeclarativev4compiler_p_p.h)34
-rw-r--r--src/declarative/qml/v4/qv4instruction.cpp400
-rw-r--r--src/declarative/qml/v4/qv4instruction_p.h (renamed from src/declarative/qml/v4/qdeclarativev4instruction_p.h)126
-rw-r--r--src/declarative/qml/v4/qv4ir.cpp (renamed from src/declarative/qml/v4/qdeclarativev4ir.cpp)2
-rw-r--r--src/declarative/qml/v4/qv4ir_p.h (renamed from src/declarative/qml/v4/qdeclarativev4ir_p.h)10
-rw-r--r--src/declarative/qml/v4/qv4irbuilder.cpp (renamed from src/declarative/qml/v4/qdeclarativev4irbuilder.cpp)210
-rw-r--r--src/declarative/qml/v4/qv4irbuilder_p.h (renamed from src/declarative/qml/v4/qdeclarativev4irbuilder_p.h)14
-rw-r--r--src/declarative/qml/v4/qv4program_p.h (renamed from src/declarative/qml/v4/qdeclarativev4program_p.h)18
-rw-r--r--src/declarative/qml/v4/v4.pri26
-rw-r--r--src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp20
-rw-r--r--src/declarative/qml/v8/qjsengine.cpp2
-rw-r--r--src/declarative/qml/v8/qjsvalue_impl_p.h8
-rw-r--r--src/declarative/qml/v8/qjsvalueiterator_impl_p.h6
-rw-r--r--src/declarative/qml/v8/qv8bindings.cpp114
-rw-r--r--src/declarative/qml/v8/qv8bindings_p.h46
-rw-r--r--src/declarative/qml/v8/qv8engine.cpp67
-rw-r--r--src/declarative/qml/v8/qv8engine_p.h22
-rw-r--r--src/declarative/qml/v8/qv8gccallback_p.h4
-rw-r--r--src/declarative/qml/v8/qv8profiler_p.h (renamed from src/declarative/qml/ftw/qdeclarativerefcount.cpp)30
-rw-r--r--src/declarative/qml/v8/qv8qobjectwrapper.cpp18
-rw-r--r--src/declarative/qml/v8/qv8valuetypewrapper.cpp14
-rw-r--r--src/declarative/qml/v8/qv8variantwrapper.cpp6
-rw-r--r--src/declarative/qml/v8/script.pri3
-rw-r--r--src/declarative/qml/v8/v8.pri2
-rw-r--r--src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp15
-rw-r--r--src/declarative/scenegraph/coreapi/qsgdefaultrenderer_p.h47
-rw-r--r--src/declarative/scenegraph/coreapi/qsgnode.cpp24
-rw-r--r--src/declarative/scenegraph/coreapi/qsgnodeupdater.cpp2
-rw-r--r--src/declarative/scenegraph/coreapi/qsgrenderer.cpp5
-rw-r--r--src/declarative/scenegraph/qsgcontext.cpp10
-rw-r--r--src/declarative/scenegraph/qsgcontext_p.h10
-rw-r--r--src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp3
-rw-r--r--src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp2
-rw-r--r--src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h2
-rw-r--r--src/declarative/scenegraph/scenegraph.pri1
-rw-r--r--src/declarative/scenegraph/util/qsgflatcolormaterial.cpp4
-rw-r--r--src/declarative/scenegraph/util/qsgsimpletexturenode.cpp6
-rw-r--r--src/declarative/scenegraph/util/qsgtexture.cpp62
-rw-r--r--src/declarative/scenegraph/util/qsgtexture.h3
-rw-r--r--src/declarative/scenegraph/util/qsgtexture_p.h9
-rw-r--r--src/declarative/scenegraph/util/qsgtextureprovider.cpp4
-rw-r--r--src/declarative/scenegraph/util/qsgvertexcolormaterial.cpp8
-rw-r--r--src/declarative/util/qdeclarativeanimation.cpp25
-rw-r--r--src/declarative/util/qdeclarativeanimation_p.h2
-rw-r--r--src/declarative/util/qdeclarativeanimation_p_p.h5
-rw-r--r--src/declarative/util/qdeclarativeapplication.cpp6
-rw-r--r--src/declarative/util/qdeclarativeapplication_p.h2
-rw-r--r--src/declarative/util/qdeclarativebehavior.cpp18
-rw-r--r--src/declarative/util/qdeclarativebehavior_p.h3
-rw-r--r--src/declarative/util/qdeclarativebind.cpp12
-rw-r--r--src/declarative/util/qdeclarativechangeset.cpp21
-rw-r--r--src/declarative/util/qdeclarativechangeset_p.h9
-rw-r--r--src/declarative/util/qdeclarativeconnections.cpp10
-rw-r--r--src/declarative/util/qdeclarativeconnections_p.h1
-rw-r--r--src/declarative/util/qdeclarativefontloader.cpp2
-rw-r--r--src/declarative/util/qdeclarativelistaccessor.cpp6
-rw-r--r--src/declarative/util/qdeclarativelistcompositor.cpp1202
-rw-r--r--src/declarative/util/qdeclarativelistcompositor_p.h373
-rw-r--r--src/declarative/util/qdeclarativelistmodel.cpp26
-rw-r--r--src/declarative/util/qdeclarativelistmodel_p.h2
-rw-r--r--src/declarative/util/qdeclarativelistmodel_p_p.h8
-rw-r--r--src/declarative/util/qdeclarativelistmodelworkeragent.cpp10
-rw-r--r--src/declarative/util/qdeclarativelistmodelworkeragent_p.h2
-rw-r--r--src/declarative/util/qdeclarativeopenmetaobject.cpp8
-rw-r--r--src/declarative/util/qdeclarativepackage.cpp2
-rw-r--r--src/declarative/util/qdeclarativepath.cpp9
-rw-r--r--src/declarative/util/qdeclarativepath_p.h2
-rw-r--r--src/declarative/util/qdeclarativepath_p_p.h2
-rw-r--r--src/declarative/util/qdeclarativepathinterpolator.cpp2
-rw-r--r--src/declarative/util/qdeclarativepixmapcache.cpp6
-rw-r--r--src/declarative/util/qdeclarativepropertychanges.cpp37
-rw-r--r--src/declarative/util/qdeclarativepropertychanges_p.h4
-rw-r--r--src/declarative/util/qdeclarativepropertymap.cpp4
-rw-r--r--src/declarative/util/qdeclarativesmoothedanimation.cpp12
-rw-r--r--src/declarative/util/qdeclarativesmoothedanimation_p.h2
-rw-r--r--src/declarative/util/qdeclarativesmoothedanimation_p_p.h13
-rw-r--r--src/declarative/util/qdeclarativespringanimation.cpp6
-rw-r--r--src/declarative/util/qdeclarativespringanimation_p.h2
-rw-r--r--src/declarative/util/qdeclarativestate.cpp14
-rw-r--r--src/declarative/util/qdeclarativestate_p_p.h5
-rw-r--r--src/declarative/util/qdeclarativestategroup.cpp12
-rw-r--r--src/declarative/util/qdeclarativestategroup_p.h2
-rw-r--r--src/declarative/util/qdeclarativestateoperations.cpp13
-rw-r--r--src/declarative/util/qdeclarativestateoperations_p.h2
-rw-r--r--src/declarative/util/qdeclarativestyledtext.cpp2
-rw-r--r--src/declarative/util/qdeclarativesvgparser.cpp19
-rw-r--r--src/declarative/util/qdeclarativesystempalette.cpp2
-rw-r--r--src/declarative/util/qdeclarativetimeline.cpp2
-rw-r--r--src/declarative/util/qdeclarativetimer.cpp2
-rw-r--r--src/declarative/util/qdeclarativetransition.cpp15
-rw-r--r--src/declarative/util/qdeclarativetransition_p.h2
-rw-r--r--src/declarative/util/qdeclarativetransitionmanager.cpp15
-rw-r--r--src/declarative/util/qdeclarativetransitionmanager_p_p.h2
-rw-r--r--src/declarative/util/qdeclarativeutilmodule.cpp59
-rw-r--r--src/declarative/util/qdeclarativexmllistmodel.cpp10
-rw-r--r--src/declarative/util/qlistmodelinterface.cpp2
-rw-r--r--src/declarative/util/util.pri4
-rw-r--r--src/imports/gestures/qdeclarativegesturearea.cpp2
-rw-r--r--src/imports/imports.pro2
-rw-r--r--src/imports/inputcontext/declarativeinputcontext.cpp199
-rw-r--r--src/imports/inputcontext/declarativeinputcontext.h104
-rwxr-xr-xsrc/imports/inputcontext/inputcontext.pro38
-rw-r--r--src/imports/inputcontext/inputcontextfilter.cpp352
-rw-r--r--src/imports/inputcontext/inputcontextfilter.h162
-rw-r--r--src/imports/inputcontext/inputcontextmodule.cpp413
-rw-r--r--src/imports/inputcontext/inputcontextmodule.h121
-rw-r--r--src/imports/inputcontext/qmldir1
-rw-r--r--src/imports/testlib/TestCase.qml5
-rw-r--r--src/imports/testlib/main.cpp8
-rw-r--r--src/imports/testlib/testcase.qdoc14
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp115
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.h8
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/editor.qrc24
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/color-picker-24.pngbin3440 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/color-picker-hicontrast.pngbin3192 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/color-picker.pngbin3173 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/from-qml-24.pngbin3395 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/from-qml.pngbin3205 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/inspectormode-24.pngbin1283 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/inspectormode.pngbin3539 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/pause-24.pngbin3307 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/pause.pngbin3097 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/play-24.pngbin3655 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/play.pngbin3363 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/reload.pngbin3418 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/resize_handle.pngbin160 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/select-24.pngbin3510 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/select-marquee-24.pngbin2891 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/select-marquee.pngbin2871 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/select.pngbin3308 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/to-qml-24.pngbin3407 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/to-qml.pngbin3227 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/zoom-24.pngbin3566 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/images/zoom.pngbin3347 -> 0 bytes
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/qmltoolbar.cpp328
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/qmltoolbar.h132
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/editor/toolbarcolorbox.cpp134
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/qdeclarativeviewinspector.cpp16
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/qdeclarativeviewinspector.h3
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro6
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/sgviewinspector.cpp39
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/sgviewinspector.h3
-rw-r--r--src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp6
-rw-r--r--src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h1
-rw-r--r--src/plugins/qmltooling/qmltooling.pro3
-rw-r--r--src/qmldevtools/qmldevtools.pro20
-rw-r--r--src/qmltest/quicktest.cpp50
-rw-r--r--src/qmltest/quicktestevent.cpp2
-rw-r--r--src/qmltest/quicktestresult.cpp11
-rw-r--r--src/qmltest/quicktestresult_p.h3
-rw-r--r--src/qtquick1/graphicsitems/qdeclarativeflickable.cpp107
-rw-r--r--src/qtquick1/graphicsitems/qdeclarativeflickable_p_p.h8
-rw-r--r--src/qtquick1/graphicsitems/qdeclarativegridview.cpp133
-rw-r--r--src/qtquick1/graphicsitems/qdeclarativelistview.cpp152
-rw-r--r--src/qtquick1/graphicsitems/qdeclarativetextinput.cpp3
-rw-r--r--src/qtquick1/graphicsitems/qdeclarativevisualitemmodel.cpp2
-rw-r--r--src/qtquick1/util/qdeclarativeanimation.cpp2
-rw-r--r--src/qtquick1/util/qdeclarativebehavior.cpp2
-rw-r--r--src/qtquick1/util/qdeclarativeconnections.cpp2
-rw-r--r--src/qtquick1/util/qdeclarativeopenmetaobject.cpp2
-rw-r--r--src/qtquick1/util/qdeclarativepropertychanges.cpp14
-rw-r--r--src/qtquick1/util/qdeclarativepropertychanges_p.h2
-rw-r--r--src/qtquick1/util/qdeclarativestategroup.cpp2
-rw-r--r--src/qtquick1/util/qdeclarativeview.cpp6
-rw-r--r--src/qtquick1/util/qdeclarativexmllistmodel.cpp8
-rw-r--r--src/src.pro1
-rw-r--r--sync.profile4
-rw-r--r--tests/auto/auto.pro5
-rw-r--r--tests/auto/declarative/debugger/debugger.pro12
-rw-r--r--tests/auto/declarative/debugger/qdeclarativedebugclient/qdeclarativedebugclient.pro (renamed from tests/auto/declarative/qdeclarativedebugclient/qdeclarativedebugclient.pro)6
-rw-r--r--tests/auto/declarative/debugger/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp (renamed from tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp)1
-rw-r--r--tests/auto/declarative/debugger/qdeclarativedebugjs/data/test.js (renamed from tests/auto/declarative/qdeclarativedebugjs/data/test.js)0
-rw-r--r--tests/auto/declarative/debugger/qdeclarativedebugjs/data/test.qml (renamed from tests/auto/declarative/qdeclarativedebugjs/data/test.qml)12
-rw-r--r--tests/auto/declarative/debugger/qdeclarativedebugjs/qdeclarativedebugjs.pro22
-rw-r--r--tests/auto/declarative/debugger/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp (renamed from tests/auto/declarative/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp)51
-rw-r--r--tests/auto/declarative/debugger/qdeclarativedebugservice/qdeclarativedebugservice.pro (renamed from tests/auto/declarative/qdeclarativedebugservice/qdeclarativedebugservice.pro)6
-rw-r--r--tests/auto/declarative/debugger/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp (renamed from tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp)2
-rw-r--r--tests/auto/declarative/debugger/qdeclarativeenginedebug/qdeclarativeenginedebug.pro (renamed from tests/auto/declarative/qdeclarativeenginedebug/qdeclarativeenginedebug.pro)6
-rw-r--r--tests/auto/declarative/debugger/qdeclarativeenginedebug/tst_qdeclarativeenginedebug.cpp (renamed from tests/auto/declarative/qdeclarativeenginedebug/tst_qdeclarativeenginedebug.cpp)1
-rw-r--r--tests/auto/declarative/debugger/qpacketprotocol/qpacketprotocol.pro (renamed from tests/auto/declarative/qpacketprotocol/qpacketprotocol.pro)6
-rw-r--r--tests/auto/declarative/debugger/qpacketprotocol/tst_qpacketprotocol.cpp (renamed from tests/auto/declarative/qpacketprotocol/tst_qpacketprotocol.cpp)0
-rw-r--r--tests/auto/declarative/debugger/shared/debugutil.cpp (renamed from tests/auto/declarative/shared/debugutil.cpp)0
-rw-r--r--tests/auto/declarative/debugger/shared/debugutil_p.h (renamed from tests/auto/declarative/shared/debugutil_p.h)0
-rw-r--r--tests/auto/declarative/declarative.pro43
-rw-r--r--tests/auto/declarative/examples/examples.pro6
-rw-r--r--tests/auto/declarative/examples/tst_examples.cpp3
-rw-r--r--tests/auto/declarative/geometry/geometry.pro6
-rw-r--r--tests/auto/declarative/nodes/nodes.pro6
-rw-r--r--tests/auto/declarative/parserstress/parserstress.pro18
-rw-r--r--tests/auto/declarative/parserstress/tst_parserstress.cpp2
-rw-r--r--tests/auto/declarative/qdeclarativeanimations/data/pathInterpolatorBack.qml11
-rw-r--r--tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro16
-rw-r--r--tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp127
-rw-r--r--tests/auto/declarative/qdeclarativeapplication/qdeclarativeapplication.pro9
-rw-r--r--tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp20
-rw-r--r--tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro18
-rw-r--r--tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp57
-rw-r--r--tests/auto/declarative/qdeclarativebinding/qdeclarativebinding.pro16
-rw-r--r--tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp18
-rw-r--r--tests/auto/declarative/qdeclarativechangeset/qdeclarativechangeset.pro14
-rw-r--r--tests/auto/declarative/qdeclarativechangeset/tst_qdeclarativechangeset.cpp31
-rw-r--r--tests/auto/declarative/qdeclarativecomponent/data/incubateObject.qml36
-rw-r--r--tests/auto/declarative/qdeclarativecomponent/qdeclarativecomponent.pro13
-rw-r--r--tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp37
-rw-r--r--tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro16
-rw-r--r--tests/auto/declarative/qdeclarativeconnection/tst_qdeclarativeconnection.cpp24
-rw-r--r--tests/auto/declarative/qdeclarativecontext/qdeclarativecontext.pro10
-rw-r--r--tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp5
-rw-r--r--tests/auto/declarative/qdeclarativecpputils/qdeclarativecpputils.pro9
-rw-r--r--tests/auto/declarative/qdeclarativecpputils/tst_qdeclarativecpputils.cpp106
-rw-r--r--tests/auto/declarative/qdeclarativedebugjs/qdeclarativedebugjs.pro27
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent.qml23
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent2.qml26
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent3.qml16
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent4.qml28
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent5.qml7
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarInheritanceComponent.qml22
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarOwnershipComponent.qml37
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/doubleEvaluate.qml6
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreationOwnership.qml20
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.handle.1.qml4
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.handle.2.qml4
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.object.1.qml4
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.object.2.qml4
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/jsimport/importPragmaLibraryWithImports.js9
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/jsimport/importPragmaLibraryWithPragmaLibraryImports.js11
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/jsimport/testImportPragmaLibraryWithImports.qml7
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/jsimport/testImportPragmaLibraryWithPragmaLibraryImports.qml7
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/objectConversion.qml16
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.1.qml22
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.2.qml24
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.3.qml19
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.4.qml18
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.5.qml18
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.6.qml18
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.7.qml18
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.8.qml12
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.9.qml19
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.circular.2.qml26
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.circular.qml44
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.inherit.qml34
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.reparent.qml27
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVarCpp.qml17
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVarImplicitOwnership.qml26
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.2.qml24
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.3.qml31
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.3.type.qml5
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.4.qml25
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.4.type1.qml23
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.4.type2.qml6
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.qml22
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/stringArg.qml49
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro16
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp4
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/testtypes.h78
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp697
-rw-r--r--tests/auto/declarative/qdeclarativeengine/qdeclarativeengine.pro10
-rw-r--r--tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp7
-rw-r--r--tests/auto/declarative/qdeclarativeerror/data/test.txt (renamed from tests/auto/declarative/qdeclarativeerror/test.txt)0
-rw-r--r--tests/auto/declarative/qdeclarativeerror/qdeclarativeerror.pro14
-rw-r--r--tests/auto/declarative/qdeclarativeerror/tst_qdeclarativeerror.cpp10
-rw-r--r--tests/auto/declarative/qdeclarativeexpression/qdeclarativeexpression.pro16
-rw-r--r--tests/auto/declarative/qdeclarativeexpression/tst_qdeclarativeexpression.cpp8
-rw-r--r--tests/auto/declarative/qdeclarativefolderlistmodel/qdeclarativefolderlistmodel.pro16
-rw-r--r--tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp27
-rw-r--r--tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro16
-rw-r--r--tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp19
-rw-r--r--tests/auto/declarative/qdeclarativeimageprovider/qdeclarativeimageprovider.pro14
-rw-r--r--tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp10
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/AsynchronousIfNestedType.qml7
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/asynchronousIfNested.1.qml5
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/asynchronousIfNested.2.qml6
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/asynchronousIfNested.3.qml5
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/chainedAsynchronousIfNested.qml5
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/clear.qml8
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/clearDuringCompletion.qml6
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/forceCompletion.qml9
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/nestedComponent.js1
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/nestedComponent.qml10
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/noIncubationController.qml5
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/objectDeleted.errors.txt1
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/objectDeleted.qml8
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/recursiveClear.1.qml9
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/recursiveClear.2.qml8
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/selfDelete.qml5
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/setInitialState.qml17
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/statusChanged.nested.qml12
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/data/statusChanged.qml5
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/qdeclarativeincubator.pro15
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/testtypes.cpp109
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/testtypes.h105
-rw-r--r--tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp852
-rw-r--r--tests/auto/declarative/qdeclarativeinfo/qdeclarativeinfo.pro18
-rw-r--r--tests/auto/declarative/qdeclarativeinfo/tst_qdeclarativeinfo.cpp8
-rw-r--r--tests/auto/declarative/qdeclarativeinstruction/qdeclarativeinstruction.pro10
-rw-r--r--tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp27
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/assignLiteralToVar.qml32
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/LocalInternal.qml (renamed from tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/LocalInternal.qml)0
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/Test.qml (renamed from tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/Test.qml)0
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/TestLocal.qml (renamed from tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/TestLocal.qml)0
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/TestNamed.qml (renamed from tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/TestNamed.qml)0
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/TestSubDir.qml (renamed from tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/TestSubDir.qml)0
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/UndeclaredLocal.qml (renamed from tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/UndeclaredLocal.qml)0
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/WrongTestLocal.qml (renamed from tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/WrongTestLocal.qml)0
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/noqmldir/Test.qml (renamed from tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/noqmldir/Test.qml)0
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/pics/blue.png (renamed from tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/pics/blue.png)bin84 -> 84 bytes
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/qmldir (renamed from tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir)0
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/subdir/SubTest.qml (renamed from tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/subdir/SubTest.qml)0
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/subdir/qmldir (renamed from tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/subdir/qmldir)0
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro17
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp103
-rw-r--r--tests/auto/declarative/qdeclarativelistcompositor/qdeclarativelistcompositor.pro9
-rw-r--r--tests/auto/declarative/qdeclarativelistcompositor/tst_qdeclarativelistcompositor.cpp1322
-rw-r--r--tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro14
-rw-r--r--tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp7
-rw-r--r--tests/auto/declarative/qdeclarativelistreference/qdeclarativelistreference.pro10
-rw-r--r--tests/auto/declarative/qdeclarativelistreference/tst_qdeclarativelistreference.cpp4
-rw-r--r--tests/auto/declarative/qdeclarativemetatype/qdeclarativemetatype.pro12
-rw-r--r--tests/auto/declarative/qdeclarativemetatype/tst_qdeclarativemetatype.cpp7
-rw-r--r--tests/auto/declarative/qdeclarativemoduleplugin/plugin.2.1/plugin.2.1.pro3
-rw-r--r--tests/auto/declarative/qdeclarativemoduleplugin/plugin.2/plugin.2.pro3
-rw-r--r--tests/auto/declarative/qdeclarativemoduleplugin/plugin/plugin.pro3
-rw-r--r--tests/auto/declarative/qdeclarativemoduleplugin/pluginMixed/pluginMixed.pro3
-rw-r--r--tests/auto/declarative/qdeclarativemoduleplugin/pluginVersion/pluginVersion.pro3
-rw-r--r--tests/auto/declarative/qdeclarativemoduleplugin/pluginWithQmlFile/pluginWithQmlFile.pro3
-rw-r--r--tests/auto/declarative/qdeclarativemoduleplugin/pluginWrongCase/pluginWrongCase.pro3
-rw-r--r--tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp80
-rw-r--r--tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.pro21
-rw-r--r--tests/auto/declarative/qdeclarativepath/qdeclarativepath.pro16
-rw-r--r--tests/auto/declarative/qdeclarativepath/tst_qdeclarativepath.cpp13
-rw-r--r--tests/auto/declarative/qdeclarativepixmapcache/qdeclarativepixmapcache.pro17
-rw-r--r--tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp12
-rw-r--r--tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro16
-rw-r--r--tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp9
-rw-r--r--tests/auto/declarative/qdeclarativepropertymap/qdeclarativepropertymap.pro6
-rw-r--r--tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro19
-rw-r--r--tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp8
-rw-r--r--tests/auto/declarative/qdeclarativescriptdebugging/data/backtrace1.js11
-rw-r--r--tests/auto/declarative/qdeclarativescriptdebugging/data/backtrace1.qml27
-rw-r--r--tests/auto/declarative/qdeclarativescriptdebugging/qdeclarativescriptdebugging.pro21
-rw-r--r--tests/auto/declarative/qdeclarativescriptdebugging/tst_qdeclarativescriptdebugging.cpp154
-rw-r--r--tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro16
-rw-r--r--tests/auto/declarative/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp17
-rw-r--r--tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro16
-rw-r--r--tests/auto/declarative/qdeclarativespringanimation/tst_qdeclarativespringanimation.cpp13
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro19
-rw-r--r--tests/auto/declarative/qdeclarativesqldatabase/tst_qdeclarativesqldatabase.cpp47
-rw-r--r--tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro18
-rw-r--r--tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp127
-rw-r--r--tests/auto/declarative/qdeclarativestyledtext/qdeclarativestyledtext.pro10
-rw-r--r--tests/auto/declarative/qdeclarativesystempalette/qdeclarativesystempalette.pro12
-rw-r--r--tests/auto/declarative/qdeclarativesystempalette/tst_qdeclarativesystempalette.cpp7
-rw-r--r--tests/auto/declarative/qdeclarativetimer/qdeclarativetimer.pro10
-rw-r--r--tests/auto/declarative/qdeclarativetimer/tst_qdeclarativetimer.cpp10
-rw-r--r--tests/auto/declarative/qdeclarativetranslation/qdeclarativetranslation.pro16
-rw-r--r--tests/auto/declarative/qdeclarativetranslation/tst_qdeclarativetranslation.cpp12
-rw-r--r--tests/auto/declarative/qdeclarativev4/qdeclarativev4.pro19
-rw-r--r--tests/auto/declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro16
-rw-r--r--tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp8
-rw-r--r--tests/auto/declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro16
-rw-r--r--tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp34
-rw-r--r--tests/auto/declarative/qdeclarativexmlhttprequest/qdeclarativexmlhttprequest.pro16
-rw-r--r--tests/auto/declarative/qdeclarativexmlhttprequest/tst_qdeclarativexmlhttprequest.cpp15
-rw-r--r--tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro20
-rw-r--r--tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp58
-rw-r--r--tests/auto/declarative/qjsengine/qjsengine.pro21
-rw-r--r--tests/auto/declarative/qjsengine/tst_qjsengine.cpp66
-rw-r--r--tests/auto/declarative/qjsvalue/qjsvalue.pro5
-rw-r--r--tests/auto/declarative/qjsvalueiterator/qjsvalueiterator.pro5
-rw-r--r--tests/auto/declarative/qmetaobjectbuilder/qmetaobjectbuilder.pro6
-rw-r--r--tests/auto/declarative/qmlmin/qmlmin.pro5
-rw-r--r--tests/auto/declarative/qmlplugindump/qmlplugindump.pro7
-rw-r--r--tests/auto/declarative/qmlplugindump/tst_qmlplugindump.cpp111
-rw-r--r--tests/auto/declarative/qsganimatedimage/qsganimatedimage.pro16
-rw-r--r--tests/auto/declarative/qsganimatedimage/tst_qsganimatedimage.cpp43
-rw-r--r--tests/auto/declarative/qsgborderimage/qsgborderimage.pro17
-rw-r--r--tests/auto/declarative/qsgborderimage/tst_qsgborderimage.cpp37
-rw-r--r--tests/auto/declarative/qsgcanvas/qsgcanvas.pro6
-rw-r--r--tests/auto/declarative/qsgcanvas/tst_qsgcanvas.cpp54
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/anim-gr.gifbin0 -> 241 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/anim-gr.pngbin0 -> 460 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/anim-poster-gr.pngbin0 -> 422 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/background.pngbin0 -> 86 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/broken.pngbin0 -> 87 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/ggrr-256x256.pngbin0 -> 120 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/green-16x16.pngbin0 -> 92 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/green-1x1.pngbin0 -> 82 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/green-256x256.pngbin0 -> 103 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/green-2x2.pngbin0 -> 118 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/green.pngbin0 -> 87 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/grgr-256x256.pngbin0 -> 130 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/red-16x16.pngbin0 -> 130 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/red.pngbin0 -> 87 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/redtransparent.pngbin0 -> 109 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/rgrg-256x256.pngbin0 -> 131 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/rrgg-256x256.pngbin0 -> 120 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/testhelper.js18
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/transparent.pngbin0 -> 100 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/transparent50.pngbin0 -> 155 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/tst_arc.qml487
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/tst_arcto.qml410
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/tst_canvas.qml274
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/tst_composite.qml380
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/tst_drawimage.qml662
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/tst_fillStyle.qml113
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/tst_fillrect.qml23
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/tst_gradient.qml981
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/tst_line.qml831
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/tst_path.qml1443
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/tst_pattern.qml34
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/tst_pixel.qml30
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/tst_shadow.qml59
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/tst_state.qml389
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/tst_strokeStyle.qml48
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/tst_text.qml34
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/tst_transform.qml487
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/yellow.pngbin0 -> 95 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/data/yellow75.pngbin0 -> 150 bytes
-rw-r--r--tests/auto/declarative/qsgcanvasitem/qsgcanvasitem.pro34
-rw-r--r--tests/auto/declarative/qsgcanvasitem/tst_qsgcanvasitem.cpp42
-rw-r--r--tests/auto/declarative/qsgdrag/qsgdrag.pro9
-rw-r--r--tests/auto/declarative/qsgdrag/tst_qsgdrag.cpp827
-rw-r--r--tests/auto/declarative/qsgdroparea/qsgdroparea.pro9
-rw-r--r--tests/auto/declarative/qsgdroparea/tst_qsgdroparea.cpp1110
-rw-r--r--tests/auto/declarative/qsgflickable/data/margins.qml19
-rw-r--r--tests/auto/declarative/qsgflickable/qsgflickable.pro18
-rw-r--r--tests/auto/declarative/qsgflickable/tst_qsgflickable.cpp93
-rw-r--r--tests/auto/declarative/qsgflipable/qsgflipable.pro16
-rw-r--r--tests/auto/declarative/qsgflipable/tst_qsgflipable.cpp17
-rw-r--r--tests/auto/declarative/qsgfocusscope/qsgfocusscope.pro18
-rw-r--r--tests/auto/declarative/qsgfocusscope/tst_qsgfocusscope.cpp40
-rw-r--r--tests/auto/declarative/qsggridview/data/ComponentView.qml14
-rw-r--r--tests/auto/declarative/qsggridview/data/creationContext.qml5
-rw-r--r--tests/auto/declarative/qsggridview/data/gridview4.qml2
-rw-r--r--tests/auto/declarative/qsggridview/data/margins.qml55
-rw-r--r--tests/auto/declarative/qsggridview/data/resizeview.qml24
-rw-r--r--tests/auto/declarative/qsggridview/data/snapToRow.qml49
-rw-r--r--tests/auto/declarative/qsggridview/qsggridview.pro17
-rw-r--r--tests/auto/declarative/qsggridview/tst_qsggridview.cpp603
-rw-r--r--tests/auto/declarative/qsgimage/qsgimage.pro18
-rw-r--r--tests/auto/declarative/qsgimage/tst_qsgimage.cpp85
-rw-r--r--tests/auto/declarative/qsgitem/qsgitem.pro6
-rw-r--r--tests/auto/declarative/qsgitem/tst_qsgitem.cpp9
-rw-r--r--tests/auto/declarative/qsgitem2/data/mapCoordinates.qml45
-rw-r--r--tests/auto/declarative/qsgitem2/qsgitem.pro18
-rw-r--r--tests/auto/declarative/qsgitem2/qsgitem2.pro13
-rw-r--r--tests/auto/declarative/qsgitem2/tst_qsgitem.cpp78
-rw-r--r--tests/auto/declarative/qsglistview/data/ComponentView.qml16
-rw-r--r--tests/auto/declarative/qsglistview/data/creationContext.qml5
-rw-r--r--tests/auto/declarative/qsglistview/data/fillModelOnComponentCompleted.qml (renamed from tests/auto/declarative/qsglistview/data/header1.qml)3
-rw-r--r--tests/auto/declarative/qsglistview/data/margins.qml47
-rw-r--r--tests/auto/declarative/qsglistview/data/qtbug-21742.qml36
-rw-r--r--tests/auto/declarative/qsglistview/data/resizeview.qml22
-rw-r--r--tests/auto/declarative/qsglistview/data/snapToItem.qml49
-rw-r--r--tests/auto/declarative/qsglistview/incrementalmodel.cpp2
-rw-r--r--tests/auto/declarative/qsglistview/qsglistview.pro19
-rw-r--r--tests/auto/declarative/qsglistview/tst_qsglistview.cpp623
-rw-r--r--tests/auto/declarative/qsgloader/data/BigComponent.qml5015
-rw-r--r--tests/auto/declarative/qsgloader/data/active.7.qml14
-rw-r--r--tests/auto/declarative/qsgloader/data/active.8.qml13
-rw-r--r--tests/auto/declarative/qsgloader/data/asynchronous.qml16
-rw-r--r--tests/auto/declarative/qsgloader/data/initialPropertyValues.8.qml20
-rw-r--r--tests/auto/declarative/qsgloader/qsgloader.pro16
-rw-r--r--tests/auto/declarative/qsgloader/tst_qsgloader.cpp190
-rw-r--r--tests/auto/declarative/qsgmousearea/qsgmousearea.pro16
-rw-r--r--tests/auto/declarative/qsgmousearea/tst_qsgmousearea.cpp121
-rw-r--r--tests/auto/declarative/qsgpathview/data/ComponentView.qml17
-rw-r--r--tests/auto/declarative/qsgpathview/data/creationContext.qml5
-rw-r--r--tests/auto/declarative/qsgpathview/qsgpathview.pro19
-rw-r--r--tests/auto/declarative/qsgpathview/tst_qsgpathview.cpp85
-rw-r--r--tests/auto/declarative/qsgpincharea/qsgpincharea.pro16
-rw-r--r--tests/auto/declarative/qsgpincharea/tst_qsgpincharea.cpp15
-rw-r--r--tests/auto/declarative/qsgpositioners/qsgpositioners.pro19
-rw-r--r--tests/auto/declarative/qsgpositioners/tst_qsgpositioners.cpp85
-rw-r--r--tests/auto/declarative/qsgrepeater/qsgrepeater.pro16
-rw-r--r--tests/auto/declarative/qsgrepeater/tst_qsgrepeater.cpp31
-rw-r--r--tests/auto/declarative/qsgtext/data/embeddedImagesLocal.qml1
-rw-r--r--tests/auto/declarative/qsgtext/data/embeddedImagesLocalError.qml1
-rw-r--r--tests/auto/declarative/qsgtext/data/embeddedImagesRemote.qml1
-rw-r--r--tests/auto/declarative/qsgtext/data/embeddedImagesRemoteError.qml1
-rw-r--r--tests/auto/declarative/qsgtext/data/lineLayout.qml35
-rw-r--r--tests/auto/declarative/qsgtext/qsgtext.pro18
-rw-r--r--tests/auto/declarative/qsgtext/tst_qsgtext.cpp143
-rw-r--r--tests/auto/declarative/qsgtextedit/data/cursorTest.qml3
-rw-r--r--tests/auto/declarative/qsgtextedit/data/openInputPanel.qml1
-rw-r--r--tests/auto/declarative/qsgtextedit/data/qtbug-22058.qml39
-rw-r--r--tests/auto/declarative/qsgtextedit/qsgtextedit.pro18
-rw-r--r--tests/auto/declarative/qsgtextedit/tst_qsgtextedit.cpp564
-rw-r--r--tests/auto/declarative/qsgtextinput/data/cursorTest.qml5
-rw-r--r--tests/auto/declarative/qsgtextinput/data/openInputPanel.qml1
-rw-r--r--tests/auto/declarative/qsgtextinput/qsgtextinput.pro17
-rw-r--r--tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp625
-rw-r--r--tests/auto/declarative/qsgview/qsgview.pro17
-rw-r--r--tests/auto/declarative/qsgview/tst_qsgview.cpp20
-rw-r--r--tests/auto/declarative/qsgvisualdatamodel/data/create.qml22
-rw-r--r--tests/auto/declarative/qsgvisualdatamodel/data/groups.qml40
-rw-r--r--tests/auto/declarative/qsgvisualdatamodel/qsgvisualdatamodel.pro15
-rw-r--r--tests/auto/declarative/qsgvisualdatamodel/tst_qsgvisualdatamodel.cpp933
-rw-r--r--tests/auto/declarative/shared/util.h85
-rw-r--r--tests/auto/declarative/symbianlibs.pri9
-rw-r--r--tests/auto/declarative/v4/data/conditionalExpr.qml (renamed from tests/auto/declarative/qdeclarativev4/data/conditionalExpr.qml)0
-rw-r--r--tests/auto/declarative/v4/data/doubleBoolJump.qml (renamed from tests/auto/declarative/qdeclarativev4/data/doubleBoolJump.qml)0
-rw-r--r--tests/auto/declarative/v4/data/fetchException.qml (renamed from tests/auto/declarative/qdeclarativev4/data/fetchException.qml)0
-rw-r--r--tests/auto/declarative/v4/data/logicalOr.2.qml (renamed from tests/auto/declarative/qdeclarativev4/data/logicalOr.2.qml)0
-rw-r--r--tests/auto/declarative/v4/data/logicalOr.qml (renamed from tests/auto/declarative/qdeclarativev4/data/logicalOr.qml)0
-rw-r--r--tests/auto/declarative/v4/data/nestedObjectAccess.qml (renamed from tests/auto/declarative/qdeclarativev4/data/nestedObjectAccess.qml)0
-rw-r--r--tests/auto/declarative/v4/data/nullQObject.qml (renamed from tests/auto/declarative/qdeclarativev4/data/nullQObject.qml)0
-rw-r--r--tests/auto/declarative/v4/data/qrealToIntRounding.qml (renamed from tests/auto/declarative/qdeclarativev4/data/qrealToIntRounding.qml)0
-rw-r--r--tests/auto/declarative/v4/data/subscriptionsInConditionalExpressions.qml (renamed from tests/auto/declarative/qdeclarativev4/data/subscriptionsInConditionalExpressions.qml)0
-rw-r--r--tests/auto/declarative/v4/data/unaryMinus.qml (renamed from tests/auto/declarative/qdeclarativev4/data/unaryMinus.qml)0
-rw-r--r--tests/auto/declarative/v4/data/unnecessaryReeval.qml (renamed from tests/auto/declarative/qdeclarativev4/data/unnecessaryReeval.qml)0
-rw-r--r--tests/auto/declarative/v4/testtypes.cpp (renamed from tests/auto/declarative/qdeclarativev4/testtypes.cpp)0
-rw-r--r--tests/auto/declarative/v4/testtypes.h (renamed from tests/auto/declarative/qdeclarativev4/testtypes.h)0
-rw-r--r--tests/auto/declarative/v4/tst_v4.cpp (renamed from tests/auto/declarative/qdeclarativev4/tst_qdeclarativev4.cpp)36
-rw-r--r--tests/auto/declarative/v4/v4.pro15
-rw-r--r--tests/auto/headersclean/headersclean.pro5
-rw-r--r--tests/auto/particles/particles.pro28
-rw-r--r--tests/auto/particles/qsgage/data/jump.qml70
-rw-r--r--tests/auto/particles/qsgage/data/kill.qml66
-rw-r--r--tests/auto/particles/qsgage/data/onceoff.qml69
-rw-r--r--tests/auto/particles/qsgage/data/sustained.qml69
-rw-r--r--tests/auto/particles/qsgage/qsgage.pro13
-rw-r--r--tests/auto/particles/qsgage/tst_qsgage.cpp165
-rw-r--r--tests/auto/particles/qsgangleddirection/data/basic.qml68
-rw-r--r--tests/auto/particles/qsgangleddirection/qsgangleddirection.pro11
-rw-r--r--tests/auto/particles/qsgangleddirection/tst_qsgangleddirection.cpp92
-rw-r--r--tests/auto/particles/qsgcumulativedirection/data/basic.qml74
-rw-r--r--tests/auto/particles/qsgcumulativedirection/qsgcumulativedirection.pro11
-rw-r--r--tests/auto/particles/qsgcumulativedirection/tst_qsgcumulativedirection.cpp88
-rw-r--r--tests/auto/particles/qsgcustomaffector/data/basic.qml82
-rw-r--r--tests/auto/particles/qsgcustomaffector/qsgcustomaffector.pro11
-rw-r--r--tests/auto/particles/qsgcustomaffector/tst_qsgcustomaffector.cpp88
-rw-r--r--tests/auto/particles/qsgcustomparticle/data/basic.qml71
-rw-r--r--tests/auto/particles/qsgcustomparticle/qsgcustomparticle.pro11
-rw-r--r--tests/auto/particles/qsgcustomparticle/tst_qsgcustomparticle.cpp94
-rw-r--r--tests/auto/particles/qsgellipseextruder/data/basic.qml77
-rw-r--r--tests/auto/particles/qsgellipseextruder/qsgellipseextruder.pro11
-rw-r--r--tests/auto/particles/qsgellipseextruder/tst_qsgellipseextruder.cpp120
-rw-r--r--tests/auto/particles/qsgfriction/data/basic.qml87
-rw-r--r--tests/auto/particles/qsgfriction/qsgfriction.pro11
-rw-r--r--tests/auto/particles/qsgfriction/tst_qsgfriction.cpp107
-rw-r--r--tests/auto/particles/qsggravity/data/basic.qml70
-rw-r--r--tests/auto/particles/qsggravity/qsggravity.pro11
-rw-r--r--tests/auto/particles/qsggravity/tst_qsggravity.cpp84
-rw-r--r--tests/auto/particles/qsgimageparticle/data/basic.qml66
-rw-r--r--tests/auto/particles/qsgimageparticle/data/colored.qml68
-rw-r--r--tests/auto/particles/qsgimageparticle/data/deformed.qml71
-rw-r--r--tests/auto/particles/qsgimageparticle/data/sprite.qml71
-rw-r--r--tests/auto/particles/qsgimageparticle/data/tabled.qml69
-rw-r--r--tests/auto/particles/qsgimageparticle/qsgimageparticle.pro11
-rw-r--r--tests/auto/particles/qsgimageparticle/tst_qsgimageparticle.cpp285
-rw-r--r--tests/auto/particles/qsgitemparticle/data/basic.qml66
-rw-r--r--tests/auto/particles/qsgitemparticle/qsgitemparticle.pro11
-rw-r--r--tests/auto/particles/qsgitemparticle/tst_qsgitemparticle.cpp95
-rw-r--r--tests/auto/particles/qsglineextruder/data/basic.qml76
-rw-r--r--tests/auto/particles/qsglineextruder/qsglineextruder.pro11
-rw-r--r--tests/auto/particles/qsglineextruder/tst_qsglineextruder.cpp103
-rw-r--r--tests/auto/particles/qsgmaskextruder/data/basic.qml68
-rw-r--r--tests/auto/particles/qsgmaskextruder/data/smallmask.pngbin0 -> 719 bytes
-rw-r--r--tests/auto/particles/qsgmaskextruder/qsgmaskextruder.pro11
-rw-r--r--tests/auto/particles/qsgmaskextruder/tst_qsgmaskextruder.cpp88
-rw-r--r--tests/auto/particles/qsgparticlegroup/data/basic.qml73
-rw-r--r--tests/auto/particles/qsgparticlegroup/qsgparticlegroup.pro11
-rw-r--r--tests/auto/particles/qsgparticlegroup/tst_qsgparticlegroup.cpp89
-rw-r--r--tests/auto/particles/qsgparticlesystem/data/basic.qml66
-rw-r--r--tests/auto/particles/qsgparticlesystem/qsgparticlesystem.pro11
-rw-r--r--tests/auto/particles/qsgparticlesystem/tst_qsgparticlesystem.cpp92
-rw-r--r--tests/auto/particles/qsgpointattractor/data/basic.qml73
-rw-r--r--tests/auto/particles/qsgpointattractor/qsgpointattractor.pro11
-rw-r--r--tests/auto/particles/qsgpointattractor/tst_qsgpointattractor.cpp89
-rw-r--r--tests/auto/particles/qsgpointdirection/data/basic.qml68
-rw-r--r--tests/auto/particles/qsgpointdirection/qsgpointdirection.pro11
-rw-r--r--tests/auto/particles/qsgpointdirection/tst_qsgpointdirection.cpp90
-rw-r--r--tests/auto/particles/qsgrectangleextruder/data/basic.qml78
-rw-r--r--tests/auto/particles/qsgrectangleextruder/qsgrectangleextruder.pro11
-rw-r--r--tests/auto/particles/qsgrectangleextruder/tst_qsgrectangleextruder.cpp113
-rw-r--r--tests/auto/particles/qsgtargetdirection/data/basic.qml67
-rw-r--r--tests/auto/particles/qsgtargetdirection/qsgtargetdirection.pro11
-rw-r--r--tests/auto/particles/qsgtargetdirection/tst_qsgtargetdirection.cpp88
-rw-r--r--tests/auto/particles/qsgtrailemitter/data/basic.qml77
-rw-r--r--tests/auto/particles/qsgtrailemitter/qsgtrailemitter.pro11
-rw-r--r--tests/auto/particles/qsgtrailemitter/tst_qsgtrailemitter.cpp105
-rw-r--r--tests/auto/particles/qsgturbulence/data/basic.qml73
-rw-r--r--tests/auto/particles/qsgturbulence/qsgturbulence.pro11
-rw-r--r--tests/auto/particles/qsgturbulence/tst_qsgturbulence.cpp86
-rw-r--r--tests/auto/particles/qsgwander/data/basic.qml72
-rw-r--r--tests/auto/particles/qsgwander/qsgwander.pro11
-rw-r--r--tests/auto/particles/qsgwander/tst_qsgwander.cpp94
-rw-r--r--tests/auto/particles/shared/particlestestsshared.h90
-rw-r--r--tests/auto/particles/shared/squarefacesprite.png (renamed from examples/declarative/particles/images/squarefacesprite.png)bin496 -> 496 bytes
-rw-r--r--tests/auto/particles/shared/star.pngbin0 -> 1550 bytes
-rw-r--r--tests/auto/particles/shared/table.pngbin0 -> 704 bytes
-rw-r--r--tests/auto/qmldevtools/compile/compile.pro8
-rw-r--r--tests/auto/qmldevtools/compile/tst_compile.cpp (renamed from src/plugins/qmltooling/qmldbg_inspector/editor/toolbarcolorbox.h)45
-rw-r--r--tests/auto/qmldevtools/qmldevtools.pro6
-rw-r--r--tests/auto/qmltest/events/tst_wheel.qml43
-rw-r--r--tests/auto/qmltest/qmltest.pro15
-rw-r--r--tests/auto/qmltest/selftests/tst_selftests.qml32
-rw-r--r--tests/auto/qtquick1/examples/examples.pro6
-rw-r--r--tests/auto/qtquick1/moduleqt47/moduleqt47.pro14
-rw-r--r--tests/auto/qtquick1/moduleqt47/tst_moduleqt47.cpp5
-rw-r--r--tests/auto/qtquick1/qdeclarativeanchors/qdeclarativeanchors.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativeanchors/tst_qdeclarativeanchors.cpp7
-rw-r--r--tests/auto/qtquick1/qdeclarativeanimatedimage/qdeclarativeanimatedimage.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp6
-rw-r--r--tests/auto/qtquick1/qdeclarativeanimations/qdeclarativeanimations.pro16
-rw-r--r--tests/auto/qtquick1/qdeclarativeanimations/tst_qdeclarativeanimations.cpp7
-rw-r--r--tests/auto/qtquick1/qdeclarativeapplication/qdeclarativeapplication.pro6
-rw-r--r--tests/auto/qtquick1/qdeclarativeapplication/tst_qdeclarativeapplication.cpp1
-rw-r--r--tests/auto/qtquick1/qdeclarativebehaviors/qdeclarativebehaviors.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp6
-rw-r--r--tests/auto/qtquick1/qdeclarativebinding/qdeclarativebinding.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativebinding/tst_qdeclarativebinding.cpp7
-rw-r--r--tests/auto/qtquick1/qdeclarativeborderimage/qdeclarativeborderimage.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativeborderimage/tst_qdeclarativeborderimage.cpp6
-rw-r--r--tests/auto/qtquick1/qdeclarativeconnection/qdeclarativeconnection.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativeconnection/tst_qdeclarativeconnection.cpp7
-rw-r--r--tests/auto/qtquick1/qdeclarativeflickable/qdeclarativeflickable.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativeflickable/tst_qdeclarativeflickable.cpp8
-rw-r--r--tests/auto/qtquick1/qdeclarativeflipable/qdeclarativeflipable.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativeflipable/tst_qdeclarativeflipable.cpp5
-rw-r--r--tests/auto/qtquick1/qdeclarativefocusscope/qdeclarativefocusscope.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp6
-rw-r--r--tests/auto/qtquick1/qdeclarativefontloader/qdeclarativefontloader.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativefontloader/tst_qdeclarativefontloader.cpp6
-rw-r--r--tests/auto/qtquick1/qdeclarativegridview/qdeclarativegridview.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativegridview/tst_qdeclarativegridview.cpp14
-rw-r--r--tests/auto/qtquick1/qdeclarativeimage/qdeclarativeimage.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativeimage/tst_qdeclarativeimage.cpp6
-rw-r--r--tests/auto/qtquick1/qdeclarativeimageprovider/qdeclarativeimageprovider.pro11
-rw-r--r--tests/auto/qtquick1/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp6
-rw-r--r--tests/auto/qtquick1/qdeclarativeitem/qdeclarativeitem.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativeitem/tst_qdeclarativeitem.cpp7
-rw-r--r--tests/auto/qtquick1/qdeclarativelayoutitem/qdeclarativelayoutitem.pro15
-rw-r--r--tests/auto/qtquick1/qdeclarativelayoutitem/tst_qdeclarativelayoutitem.cpp6
-rw-r--r--tests/auto/qtquick1/qdeclarativelistmodel/qdeclarativelistmodel.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp7
-rw-r--r--tests/auto/qtquick1/qdeclarativelistview/qdeclarativelistview.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativelistview/tst_qdeclarativelistview.cpp6
-rw-r--r--tests/auto/qtquick1/qdeclarativeloader/qdeclarativeloader.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativeloader/tst_qdeclarativeloader.cpp6
-rw-r--r--tests/auto/qtquick1/qdeclarativemousearea/qdeclarativemousearea.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativemousearea/tst_qdeclarativemousearea.cpp5
-rw-r--r--tests/auto/qtquick1/qdeclarativeparticles/qdeclarativeparticles.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativeparticles/tst_qdeclarativeparticles.cpp5
-rw-r--r--tests/auto/qtquick1/qdeclarativepathview/qdeclarativepathview.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativepathview/tst_qdeclarativepathview.cpp7
-rw-r--r--tests/auto/qtquick1/qdeclarativepincharea/qdeclarativepincharea.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativepincharea/tst_qdeclarativepincharea.cpp5
-rw-r--r--tests/auto/qtquick1/qdeclarativepositioners/qdeclarativepositioners.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativepositioners/tst_qdeclarativepositioners.cpp6
-rw-r--r--tests/auto/qtquick1/qdeclarativerepeater/qdeclarativerepeater.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativerepeater/tst_qdeclarativerepeater.cpp5
-rw-r--r--tests/auto/qtquick1/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp6
-rw-r--r--tests/auto/qtquick1/qdeclarativespringanimation/qdeclarativespringanimation.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativespringanimation/tst_qdeclarativespringanimation.cpp6
-rw-r--r--tests/auto/qtquick1/qdeclarativestates/qdeclarativestates.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativestates/tst_qdeclarativestates.cpp5
-rw-r--r--tests/auto/qtquick1/qdeclarativesystempalette/qdeclarativesystempalette.pro10
-rw-r--r--tests/auto/qtquick1/qdeclarativesystempalette/tst_qdeclarativesystempalette.cpp7
-rw-r--r--tests/auto/qtquick1/qdeclarativetext/qdeclarativetext.pro15
-rw-r--r--tests/auto/qtquick1/qdeclarativetext/tst_qdeclarativetext.cpp7
-rw-r--r--tests/auto/qtquick1/qdeclarativetextedit/qdeclarativetextedit.pro15
-rw-r--r--tests/auto/qtquick1/qdeclarativetextedit/tst_qdeclarativetextedit.cpp14
-rw-r--r--tests/auto/qtquick1/qdeclarativetextinput/qdeclarativetextinput.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativetextinput/tst_qdeclarativetextinput.cpp14
-rw-r--r--tests/auto/qtquick1/qdeclarativetimer/qdeclarativetimer.pro10
-rw-r--r--tests/auto/qtquick1/qdeclarativetimer/tst_qdeclarativetimer.cpp10
-rw-r--r--tests/auto/qtquick1/qdeclarativeview/qdeclarativeview.pro15
-rw-r--r--tests/auto/qtquick1/qdeclarativeview/tst_qdeclarativeview.cpp7
-rw-r--r--tests/auto/qtquick1/qdeclarativeviewer/qdeclarativeviewer.pro15
-rw-r--r--tests/auto/qtquick1/qdeclarativeviewer/tst_qdeclarativeviewer.cpp9
-rw-r--r--tests/auto/qtquick1/qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro14
-rw-r--r--tests/auto/qtquick1/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp5
-rw-r--r--tests/auto/qtquick1/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro18
-rw-r--r--tests/auto/qtquick1/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp11
-rw-r--r--tests/auto/qtquick1/qtquick1.pro5
-rw-r--r--tests/benchmarks/declarative/binding/binding.pro14
-rw-r--r--tests/benchmarks/declarative/binding/tst_binding.cpp5
-rw-r--r--tests/benchmarks/declarative/compilation/compilation.pro12
-rw-r--r--tests/benchmarks/declarative/compilation/tst_compilation.cpp5
-rw-r--r--tests/benchmarks/declarative/creation/creation.pro13
-rw-r--r--tests/benchmarks/declarative/creation/tst_creation.cpp7
-rw-r--r--tests/benchmarks/declarative/holistic/holistic.pro12
-rw-r--r--tests/benchmarks/declarative/holistic/tst_holistic.cpp5
-rw-r--r--tests/benchmarks/declarative/javascript/javascript.pro4
-rw-r--r--tests/benchmarks/declarative/js/qjsengine/qjsengine.pro9
-rw-r--r--tests/benchmarks/declarative/js/qjsengine/tst_qjsengine.cpp5
-rw-r--r--tests/benchmarks/declarative/js/qjsvalue/qjsvalue.pro4
-rw-r--r--tests/benchmarks/declarative/js/qjsvalueiterator/qjsvalueiterator.pro4
-rw-r--r--tests/benchmarks/declarative/pointers/pointers.pro4
-rw-r--r--tests/benchmarks/declarative/qdeclarativecomponent/qdeclarativecomponent.pro14
-rw-r--r--tests/benchmarks/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp5
-rw-r--r--tests/benchmarks/declarative/qdeclarativedebugtrace/qdeclarativedebugtrace.pro4
-rw-r--r--tests/benchmarks/declarative/qdeclarativeimage/qdeclarativeimage.pro12
-rw-r--r--tests/benchmarks/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp5
-rw-r--r--tests/benchmarks/declarative/qdeclarativemetaproperty/qdeclarativemetaproperty.pro14
-rw-r--r--tests/benchmarks/declarative/qdeclarativemetaproperty/tst_qdeclarativemetaproperty.cpp5
-rw-r--r--tests/benchmarks/declarative/qmltime/qmltime.cpp11
-rw-r--r--tests/benchmarks/declarative/qmltime/qmltime.pro11
-rw-r--r--tests/benchmarks/declarative/script/script.pro16
-rw-r--r--tests/benchmarks/declarative/script/tst_script.cpp5
-rw-r--r--tests/benchmarks/declarative/typeimports/tst_typeimports.cpp5
-rw-r--r--tests/benchmarks/declarative/typeimports/typeimports.pro12
-rw-r--r--tests/benchmarks/particles/affectors/affectors.pro10
-rw-r--r--tests/benchmarks/particles/affectors/data/basic.qml74
-rw-r--r--tests/benchmarks/particles/affectors/data/filtered.qml81
-rw-r--r--tests/benchmarks/particles/affectors/tst_affectors.cpp164
-rw-r--r--tests/benchmarks/particles/emission/data/basic.qml67
-rw-r--r--tests/benchmarks/particles/emission/emission.pro10
-rw-r--r--tests/benchmarks/particles/emission/tst_emission.cpp118
-rw-r--r--tests/benchmarks/particles/particles.pro5
-rw-r--r--tests/shared/util.h70
-rw-r--r--tests/system/sys_elements.qtt405
-rw-r--r--tests/testapplications/elements/content/AffectorElement.qml184
-rw-r--r--tests/testapplications/elements/content/AnimatedImageElement.qml4
-rw-r--r--tests/testapplications/elements/content/AppContainer.qml38
-rw-r--r--tests/testapplications/elements/content/BorderImageElement.qml4
-rw-r--r--tests/testapplications/elements/content/BugPanel.qml38
-rw-r--r--tests/testapplications/elements/content/ColumnElement.qml4
-rw-r--r--tests/testapplications/elements/content/DirectionElement.qml127
-rw-r--r--tests/testapplications/elements/content/DoubleValidatorElement.qml4
-rw-r--r--tests/testapplications/elements/content/EmitterElement.qml107
-rw-r--r--tests/testapplications/elements/content/FlickableElement.qml2
-rw-r--r--tests/testapplications/elements/content/FlipableElement.qml4
-rw-r--r--tests/testapplications/elements/content/FlowElement.qml4
-rw-r--r--tests/testapplications/elements/content/FocusScopeElement.qml38
-rw-r--r--tests/testapplications/elements/content/FontLoaderElement.qml36
-rw-r--r--tests/testapplications/elements/content/GradientElement.qml38
-rw-r--r--tests/testapplications/elements/content/GridElement.qml4
-rw-r--r--tests/testapplications/elements/content/GridViewElement.qml43
-rw-r--r--tests/testapplications/elements/content/Help.qml38
-rw-r--r--tests/testapplications/elements/content/HelpDesk.qml38
-rw-r--r--tests/testapplications/elements/content/ImageElement.qml4
-rw-r--r--tests/testapplications/elements/content/ImageParticleElement.qml100
-rw-r--r--tests/testapplications/elements/content/IntValidatorElement.qml4
-rw-r--r--tests/testapplications/elements/content/KeysElement.qml2
-rw-r--r--tests/testapplications/elements/content/ListViewElement.qml2
-rw-r--r--tests/testapplications/elements/content/MouseAreaElement.qml2
-rw-r--r--tests/testapplications/elements/content/ParallelAnimationElement.qml4
-rw-r--r--tests/testapplications/elements/content/ParticleSystemElement.qml97
-rw-r--r--tests/testapplications/elements/content/RectangleElement.qml2
-rw-r--r--tests/testapplications/elements/content/RegExpValidatorElement.qml4
-rw-r--r--tests/testapplications/elements/content/RepeaterElement.qml4
-rw-r--r--tests/testapplications/elements/content/RowElement.qml4
-rw-r--r--tests/testapplications/elements/content/ScaleElement.qml4
-rw-r--r--tests/testapplications/elements/content/SequentialAnimationElement.qml4
-rw-r--r--tests/testapplications/elements/content/ShapeElement.qml149
-rw-r--r--tests/testapplications/elements/content/SystemPaletteElement.qml38
-rw-r--r--tests/testapplications/elements/content/SystemTestHelp.qml38
-rw-r--r--tests/testapplications/elements/content/TextEditElement.qml4
-rw-r--r--tests/testapplications/elements/content/TextElement.qml4
-rw-r--r--tests/testapplications/elements/content/TextInputElement.qml4
-rw-r--r--tests/testapplications/elements/content/TrailEmitterElement.qml165
-rw-r--r--tests/testapplications/elements/content/XmlListModelElement.qml38
-rw-r--r--tests/testapplications/elements/content/elements.js38
-rw-r--r--tests/testapplications/elements/content/pics/logo-hollowed.pngbin0 -> 637 bytes
-rw-r--r--tests/testapplications/elements/content/pics/smile.png (renamed from examples/declarative/particles/images/smile.png)bin15408 -> 15408 bytes
-rw-r--r--tests/testapplications/elements/content/pics/star.pngbin0 -> 1550 bytes
-rw-r--r--tests/testapplications/elements/elements.qml4
-rw-r--r--tests/testapplications/textlayout/styledtext-layout.qml109
-rw-r--r--tools/qmlmin/main.cpp18
-rw-r--r--tools/qmlmin/qmlmin.pro4
-rw-r--r--tools/qmlplugindump/main.cpp37
-rw-r--r--tools/qmlscene/main.cpp52
-rw-r--r--tools/qmlviewer/deviceorientation_harmattan.cpp22
-rw-r--r--tools/qmlviewer/qmlruntime.cpp2
1251 files changed, 49373 insertions, 21058 deletions
diff --git a/doc/config/qtdeclarative_doc.pri b/doc/config/qtdeclarative_doc.pri
new file mode 100644
index 0000000000..51f2fceb7a
--- /dev/null
+++ b/doc/config/qtdeclarative_doc.pri
@@ -0,0 +1,13 @@
+OTHER_FILES += \
+ $$PWD/qtquick.qdocconf \
+ $$PWD/qtquick-dita.qdocconf
+
+online_docs.commands = qdoc3 $$PWD/qtquick.qdocconf
+
+dita_docs.commands = qdoc3 $$PWD/qtquick-dita.qdocconf
+
+docs.depends = dita_docs online_docs
+QMAKE_EXTRA_TARGETS = docs dita_docs online_docs
+QMAKE_CLEAN += \
+ "-r $$PWD/html" \
+ "-r $$PWD/ditaxml" \ No newline at end of file
diff --git a/doc/config/qtquick-dita.qdocconf b/doc/config/qtquick-dita.qdocconf
new file mode 100644
index 0000000000..e259a2fa74
--- /dev/null
+++ b/doc/config/qtquick-dita.qdocconf
@@ -0,0 +1,24 @@
+# Name of the project.
+project = Qt Quick
+
+# Directories in which to search for files to document and images.
+# By default set to the root directory of the project for sources
+# and headers and qdoc will therefore generate output for each file.
+# Images should be placed in <rootdir>/dic/images and examples in
+# <rootdir>/examples.
+# Paths are relative to the location of this file.
+exampledirs += ../src/examples
+headerdirs += ../src
+sourcedirs += ../src
+
+
+
+#Do not change the variables after this line unless you know what you are doing.
+
+outputdir = ../ditaxml
+outputformats = DITAXML
+
+examples.fileextensions = "*.cpp *.h *.js *.svg *.xml *.ui *.qml"
+examples.imageextensions = "*.png *.jpeg *.jpg *.gif *.mng"
+headers.fileextensions = "*.h *.ch *.h++ *.hh *.hpp *.hxx"
+sources.fileextensions = "*.cpp *.qdoc *.mm *.qml"
diff --git a/doc/config/qtquick.qdocconf b/doc/config/qtquick.qdocconf
new file mode 100644
index 0000000000..3f8988e549
--- /dev/null
+++ b/doc/config/qtquick.qdocconf
@@ -0,0 +1,84 @@
+# Name of the project.
+project = Qt Quick
+description = Qt Quick Documentation
+
+# Directories in which to search for files to document and images.
+# By default set to the root directory of the project for sources
+# and headers and qdoc will therefore generate output for each file.
+# Images should be placed in <rootdir>/dic/images and examples in
+# <rootdir>/examples.
+# Paths are relative to the location of this file.
+
+exampledirs += ../src/examples \
+ ../.. \
+ ../../examples
+
+headerdirs += ../src \
+ ../../src
+
+imagedirs += ../src/images \
+
+sourcedirs += ../src \
+ ../../src
+
+excludedirs += ../src/qtquick1 \
+ ../../src/qtquick1
+
+#indexes = $QT5DOC/doc/html/qt.index
+
+# The following parameters are for creating a qhp file, the qhelpgenerator
+# program can convert the qhp file into a qch file which can be opened in
+# Qt Assistant and/or Qt Creator.
+
+# Defines the name of the project. You cannot use operators (+, =, -) in
+# the name. Properties for this project are set using a qhp.<projectname>.property
+# format.
+qhp.projects = qtquick
+
+# Sets the name of the output qhp file.
+qhp.qtquick.file = qtquick.qhp
+
+# Namespace for the output file. This namespace is used to distinguish between
+# different documentation files in Creator/Assistant. Normal format for MP
+# projects should be: com.nokia.mp.<projectname>.version with version being
+# a number containing a major, minor and revision element. E.g. version 1.0
+# becomes 100.
+qhp.qtquick.namespace = qtquick.200
+
+# Title for the package, will be the main title for the package in
+# Assistant/Creator.
+qhp.qtquick.indexTitle = Qt Quick Documentation
+
+# Extra files to add to the output which are not linked to from anywhere
+# using a qdoc \l command.
+qhp.qtquick.extraFiles = style/qtquick.css \
+ index.html
+
+# Only update the name of the project for the next variables.
+qhp.qtquick.virtualFolder = qdoc
+qhp.qtquick.subprojects = classes
+qhp.qtquick.subprojects.classes.title = Classes
+qhp.qtquick.subprojects.classes.selectors = class fake:headerfile
+qhp.qtquick.subprojects.classes.sortPages = true
+
+
+
+# Do NOT change the variables after this line unless you know what you are doing.
+
+outputdir = ../html
+outputformats = HTML
+
+examples.fileextensions = "*.cpp *.h *.js *.svg *.xml *.ui *.qml"
+examples.imageextensions = "*.png *.jpeg *.jpg *.gif *.mng"
+headers.fileextensions = "*.h *.ch *.h++ *.hh *.hpp *.hxx"
+sources.fileextensions = "*.cpp *.qdoc *.mm *.qml"
+
+HTML.nobreadcrumbs = "true"
+
+HTML.templatedir = .
+HTML.stylesheets = style/qtquick.css
+
+HTML.headerstyles = " <link rel=\"stylesheet\" type=\"text/css\" href=\"style/qtquick.css\" />\n"
+HTML.endheader = "</head>\n<body>\n"
+
+HTML.footer = "<div class=\"footer\">Copyright (c) 2011 Nokia Corporation and/or its subsidiaries. All rights reserved.</div>\n"
diff --git a/doc/config/style/qtquick.css b/doc/config/style/qtquick.css
new file mode 100755
index 0000000000..bdd0ea3d29
--- /dev/null
+++ b/doc/config/style/qtquick.css
@@ -0,0 +1,681 @@
+@media screen
+{
+
+/* basic elements */
+ html
+ {
+ color: #000000;
+ background: #FFFFFF;
+ }
+ table
+ {
+ border-collapse: collapse;
+ border-spacing: 0;
+ }
+ fieldset, img
+ {
+ border: 0;
+ max-width:100%;
+ }
+ address, caption, cite, code, dfn, em, strong, th, var, optgroup
+ {
+ font-style: inherit;
+ font-weight: inherit;
+ }
+ del, ins
+ {
+ text-decoration: none;
+ }
+ ol li
+ {
+ list-style: decimal;
+ }
+ ul li
+ {
+ list-style: none;
+ }
+ caption, th
+ {
+ text-align: left;
+ }
+ h1, h2, h3, h4, h5, h6
+ {
+ font-size: 100%;
+ }
+ q:before, q:after
+ {
+ content: '';
+ }
+ abbr, acronym
+ {
+ border: 0;
+ font-variant: normal;
+ }
+ sup, sub
+ {
+ vertical-align: baseline;
+ }
+ tt, .qmlreadonly span, .qmldefault span
+ {
+ word-spacing:0.5em;
+ }
+ legend
+ {
+ color: #000000;
+ }
+ strong
+ {
+ font-weight: bold;
+ }
+ em
+ {
+ font-style: italic;
+ }
+
+ body
+ {
+ margin: 0px;
+ font-family: sans-serif;
+ line-height: normal
+ }
+ a
+ {
+ color: #00732F;
+ text-decoration: none;
+ }
+ hr
+ {
+ background-color: #E6E6E6;
+ border: 1px solid #E6E6E6;
+ height: 1px;
+ width: 100%;
+ text-align: left;
+ margin: 1.5em 0 1.5em 0;
+ }
+
+ pre
+ {
+ border: 1px solid #DDDDDD;
+ -moz-border-radius: 0.7em 0.7em 0.7em 0.7em;
+ -webkit-border-radius: 0.7em 0.7em 0.7em 0.7em;
+ border-radius: 0.7em 0.7em 0.7em 0.7em;
+ margin: 0 1.5em 1em 1em;
+ padding: 1em 1em 1em 1em;
+ overflow-x: auto;
+ }
+ table, pre
+ {
+ -moz-border-radius: 0.7em 0.7em 0.7em 0.7em;
+ -webkit-border-radius: 0.7em 0.7em 0.7em 0.7em;
+ border-radius: 0.7em 0.7em 0.7em 0.7em;
+ background-color: #F6F6F6;
+ border: 1px solid #E6E6E6;
+ border-collapse: separate;
+ margin-bottom: 2.5em;
+ }
+ pre {
+ font-size: 90%;
+ display: block;
+ overflow:hidden;
+ }
+ thead
+ {
+ margin-top: 0.5em;
+ font-weight: bold
+ }
+ th
+ {
+ padding: 0.5em 1.5em 0.5em 1em;
+ background-color: #E1E1E1;
+ border-left: 1px solid #E6E6E6;
+ }
+ td
+ {
+ padding: 0.25em 1.5em 0.25em 1em;
+ }
+
+ td.rightAlign
+ {
+ padding: 0.25em 0.5em 0.25em 1em;
+ }
+ table tr.odd
+ {
+ border-left: 1px solid #E6E6E6;
+ background-color: #F6F6F6;
+ color: black;
+ }
+ table tr.even
+ {
+ border-left: 1px solid #E6E6E6;
+ background-color: #ffffff;
+ color: #202020;
+ }
+
+ div.float-left
+ {
+ float: left; margin-right: 2em
+ }
+ div.float-right
+ {
+ float: right; margin-left: 2em
+ }
+
+ span.comment
+ {
+ color: #008B00;
+ }
+ span.string, span.char
+ {
+ color: #000084;
+ }
+ span.number
+ {
+ color: #a46200;
+ }
+ span.operator
+ {
+ color: #202020;
+ }
+ span.keyword
+ {
+ color: #840000;
+ }
+ span.name
+ {
+ color: black
+ }
+ span.type
+ {
+ font-weight: bold
+ }
+ span.type a:visited
+ {
+ color: #0F5300;
+ }
+ span.preprocessor
+ {
+ color: #404040
+ }
+/* end basic elements */
+
+/* font style elements */
+ .heading
+ {
+ font-weight: bold;
+ font-size: 125%;
+ }
+ .subtitle
+ {
+ font-size: 110%
+ }
+ .small-subtitle
+ {
+ font-size: 100%
+ }
+ .red
+ {
+ color:red;
+ }
+/* end font style elements */
+
+/* global settings*/
+ .header, .footer
+ {
+ display: block;
+ clear: both;
+ overflow: hidden;
+ }
+/* end global settings*/
+
+/* header elements */
+ .header .qtref
+ {
+ color: #00732F;
+ font-weight: bold;
+ font-size: 130%;
+ }
+
+ .header .content
+ {
+ margin-left: 5px;
+ margin-top: 5px;
+ margin-bottom: 0.5em;
+ }
+
+ .header .breadcrumb
+ {
+ font-size: 90%;
+ padding: 0.5em 0 0.5em 1em;
+ margin: 0;
+ background-color: #fafafa;
+ height: 1.35em;
+ border-bottom: 1px solid #d1d1d1;
+ }
+
+ .header .breadcrumb ul
+ {
+ margin: 0;
+ padding: 0;
+ }
+
+ .header .content
+ {
+ word-wrap: break-word;
+ }
+
+ .header .breadcrumb ul li
+ {
+ float: left;
+ background: url(../images/breadcrumb.png) no-repeat 0 3px;
+ padding-left: 1.5em;
+ margin-left: 1.5em;
+ }
+
+ .header .breadcrumb ul li.last
+ {
+ font-weight: normal;
+ }
+
+ .header .breadcrumb ul li a
+ {
+ color: #00732F;
+ }
+
+ .header .breadcrumb ul li.first
+ {
+ background-image: none;
+ padding-left: 0;
+ margin-left: 0;
+ }
+
+ .header .content ol li {
+ background: none;
+ margin-bottom: 1.0em;
+ margin-left: 1.2em;
+ padding-left: 0
+ }
+
+ .header .content li
+ {
+ background: url(../images/bullet_sq.png) no-repeat 0 5px;
+ margin-bottom: 1em;
+ padding-left: 1.2em;
+ }
+
+/* end header elements */
+
+/* content elements */
+ .content h1
+ {
+ font-weight: bold;
+ font-size: 130%
+ }
+
+ .content h2
+ {
+ font-weight: bold;
+ font-size: 120%;
+ width: 100%;
+ }
+ .content h3
+ {
+ font-weight: bold;
+ font-size: 110%;
+ width: 100%;
+ }
+ .content table p
+ {
+ margin: 0
+ }
+ .content ul
+ {
+ padding-left: 2.5em;
+ }
+ .content li
+ {
+ padding-top: 0.25em;
+ padding-bottom: 0.25em;
+ }
+ .content ul img {
+ vertical-align: middle;
+ }
+
+ .content a:visited
+ {
+ color: #4c0033;
+ text-decoration: none;
+ }
+
+ .content a:visited:hover
+ {
+ color: #4c0033;
+ text-decoration: underline;
+ }
+
+ a:hover
+ {
+ color: #4c0033;
+ text-decoration: underline;
+ }
+ descr p a
+ {
+ text-decoration: underline;
+ }
+
+ .descr p a:visited
+ {
+ text-decoration: underline;
+ }
+
+ .alphaChar{
+ width:95%;
+ background-color:#F6F6F6;
+ border:1px solid #E6E6E6;
+ -moz-border-radius: 7px 7px 7px 7px;
+ border-radius: 7px 7px 7px 7px;
+ -webkit-border-radius: 7px 7px 7px 7px;
+ font-size:12pt;
+ padding-left:10px;
+ margin-top:10px;
+ margin-bottom:10px;
+ }
+ .flowList{
+ /*vertical-align:top;*/
+ /*margin:20px auto;*/
+
+ column-count:3;
+ -webkit-column-count:3;
+ -moz-column-count:3;
+/*
+ column-width:100%;
+ -webkit-column-width:200px;
+ -col-column-width:200px;
+*/
+ column-gap:41px;
+ -webkit-column-gap:41px;
+ -moz-column-gap:41px;
+
+ column-rule: 1px dashed #ccc;
+ -webkit-column-rule: 1px dashed #ccc;
+ -moz-column-rule: 1px dashed #ccc;
+ }
+
+ .flowList dl{
+ }
+ .flowList dd{
+ /*display:inline-block;*/
+ margin-left:10px;
+ min-width:250px;
+ line-height: 1.5;
+ min-width:100%;
+ min-height:15px;
+ }
+
+ .flowList dd a{
+ }
+
+ .mainContent
+ {
+ padding-left:5px;
+ }
+
+ .content .flowList p{
+ padding:0px;
+ }
+
+ .content .alignedsummary
+ {
+ margin: 15px;
+ }
+
+
+ .qmltype
+ {
+ text-align: center;
+ font-size: 120%;
+ }
+ .qmlreadonly
+ {
+ padding-left: 5px;
+ float: right;
+ color: #254117;
+ }
+
+ .qmldefault
+ {
+ padding-left: 5px;
+ float: right;
+ color: red;
+ }
+
+ .qmldoc
+ {
+ }
+
+ .generic .alphaChar{
+ margin-top:5px;
+ }
+
+ .generic .odd .alphaChar{
+ background-color: #F6F6F6;
+ }
+
+ .generic .even .alphaChar{
+ background-color: #FFFFFF;
+ }
+
+ .memItemRight{
+ padding: 0.25em 1.5em 0.25em 0;
+ }
+ .highlightedCode
+ {
+ margin: 1.0em;
+ }
+ .annotated td {
+ padding: 0.25em 0.5em 0.25em 0.5em;
+ }
+
+ .toc
+ {
+ font-size: 80%
+ }
+
+ .header .content .toc ul
+ {
+ padding-left: 0px;
+ }
+
+ .content .toc h3 {
+ border-bottom: 0px;
+ margin-top: 0px;
+ }
+
+ .content .toc h3 a:hover {
+ color: #00732F;
+ text-decoration: none;
+ }
+
+ .content .toc .level2
+ {
+ margin-left: 1.5em;
+ }
+
+ .content .toc .level3
+ {
+ margin-left: 3.0em;
+ }
+
+ .content ul li
+ {
+ background: url(../images/bullet_sq.png) no-repeat 0 0.7em;
+ padding-left: 1em
+ }
+
+ .content .toc li
+ {
+ background: url(../images/bullet_dn.png) no-repeat 0 5px;
+ padding-left: 1em
+ }
+
+ .relpage
+ {
+ -moz-border-radius: 7px 7px 7px 7px;
+ -webkit-border-radius: 7px 7px 7px 7px;
+ border-radius: 7px 7px 7px 7px;
+ border: 1px solid #DDDDDD;
+ padding: 25px 25px;
+ clear: both;
+ }
+ .relpage ul
+ {
+ float: none;
+ padding: 1.5em;
+ }
+
+ h3.fn, span.fn
+ {
+ -moz-border-radius:7px 7px 7px 7px;
+ -webkit-border-radius:7px 7px 7px 7px;
+ border-radius:7px 7px 7px 7px;
+ background-color: #F6F6F6;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #E6E6E6;
+ font-weight: bold;
+ word-spacing:3px;
+ padding:3px 5px;
+ }
+
+ .functionIndex {
+ font-size:12pt;
+ word-spacing:10px;
+ margin-bottom:10px;
+ background-color: #F6F6F6;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #E6E6E6;
+ -moz-border-radius: 7px 7px 7px 7px;
+ -webkit-border-radius: 7px 7px 7px 7px;
+ border-radius: 7px 7px 7px 7px;
+ width:100%;
+ }
+
+ .centerAlign
+ {
+ text-align:center;
+ }
+
+ .rightAlign
+ {
+ text-align:right;
+ }
+
+ .leftAlign
+ {
+ text-align:left;
+ }
+
+ .topAlign{
+ vertical-align:top
+ }
+
+ .functionIndex a{
+ display:inline-block;
+ }
+
+/* end content elements */
+/* footer elements */
+
+ .footer
+ {
+ color: #393735;
+ font-size: 0.75em;
+ text-align: center;
+ padding-top: 1.5em;
+ padding-bottom: 1em;
+ background-color: #E6E7E8;
+ margin: 0;
+ }
+ .footer p
+ {
+ margin: 0.25em
+ }
+ .small
+ {
+ font-size: 0.5em;
+ }
+/* end footer elements */
+
+ .item {
+ float: left;
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+ }
+
+
+ .item .primary {
+ margin-right: 220px;
+ position: relative;
+ }
+
+ .item hr {
+ margin-left: -220px;
+ }
+
+ .item .secondary {
+ float: right;
+ width: 200px;
+ position: relative;
+ }
+
+ .item .cols {
+ clear: both;
+ display: block;
+ }
+
+ .item .cols .col {
+ float: left;
+ margin-left: 1.5%;
+ }
+
+ .item .cols .col.first {
+ margin-left: 0;
+ }
+
+ .item .cols.two .col {
+ width: 45%;
+ }
+
+ .item .box {
+ margin: 0 0 10px 0;
+ }
+
+ .item .box h3 {
+ margin: 0 0 10px 0;
+ }
+
+ .cols.unclear {
+ clear:none;
+ }
+}
+
+/* end of screen media */
+
+/* start of print media */
+
+@media print
+{
+ input, textarea, .header, .footer, .toolbar, .feedback, .wrapper .hd, .wrapper .bd .sidebar, .wrapper .ft, #feedbackBox, #blurpage, .toc, .breadcrumb, .toolbar, .floatingResult
+ {
+ display: none;
+ background: none;
+ }
+ .content
+ {
+ background: none;
+ display: block;
+ width: 100%; margin: 0; float: none;
+ }
+}
+/* end of print media */
diff --git a/doc/src/declarative/advtutorial.qdoc b/doc/src/declarative/advtutorial.qdoc
index b2f9deca6b..f6b6c71610 100644
--- a/doc/src/declarative/advtutorial.qdoc
+++ b/doc/src/declarative/advtutorial.qdoc
@@ -35,7 +35,7 @@ This tutorial walks step-by-step through the creation of a full application usin
It assumes that you already know the basics of QML (for example, from reading the
\l{QML Tutorial}{simple tutorial}).
-In this tutorial we write a game, \e {Same Game}, based on the Same Game application
+In this tutorial we write a game, \i {Same Game}, based on the Same Game application
included in the declarative \c examples directory, which looks like this:
\image declarative-samegame.png
diff --git a/doc/src/declarative/anchor-layout.qdoc b/doc/src/declarative/anchor-layout.qdoc
index a84abf436b..0273b8eda6 100644
--- a/doc/src/declarative/anchor-layout.qdoc
+++ b/doc/src/declarative/anchor-layout.qdoc
@@ -34,7 +34,7 @@
\title Anchor-based Layout in QML
In addition to the more traditional \l Grid, \l Row, and \l Column,
-QML also provides a way to layout items using the concept of \e anchors.
+QML also provides a way to layout items using the concept of \i anchors.
Each item can be thought of as having a set of 7 invisible "anchor lines":
\l {Item::anchors.left}{left}, \l {Item::anchors.horizontalCenter}{horizontalCenter},
\l {Item::anchors.right}{right}, \l {Item::anchors.top}{top},
@@ -44,7 +44,7 @@ and \l {Item::anchors.bottom}{bottom}.
\image edges_qml.png
The baseline (not pictured above) corresponds to the imaginary line on which
-text would sit. For items with no text it is the same as \e top.
+text would sit. For items with no text it is the same as \i top.
The QML anchoring system allows you to define relationships between the anchor lines of different items. For example, you can write:
@@ -53,7 +53,7 @@ Rectangle { id: rect1; ... }
Rectangle { id: rect2; anchors.left: rect1.right; ... }
\endcode
-In this case, the left edge of \e rect2 is bound to the right edge of \e rect1, producing the following:
+In this case, the left edge of \i rect2 is bound to the right edge of \i rect1, producing the following:
\image edge1.png
@@ -68,8 +68,8 @@ Rectangle { id: rect2; anchors.left: rect1.right; anchors.top: rect1.bottom; ...
\image edge3.png
By specifying multiple horizontal or vertical anchors you can control the size of an item. Below,
-\e rect2 is anchored to the right of \e rect1 and the left of \e rect3. If either of the blue
-rectangles are moved, \e rect2 will stretch and shrink as necessary:
+\i rect2 is anchored to the right of \i rect1 and the left of \i rect3. If either of the blue
+rectangles are moved, \i rect2 will stretch and shrink as necessary:
\code
Rectangle { id: rect1; x: 0; ... }
@@ -85,7 +85,7 @@ and horizontalCenter anchors to the verticalCenter and horizontalCenter of the t
\section1 Anchor Margins and Offsets
-The anchoring system also allows \e margins and \e offsets to be specified for an item's anchors.
+The anchoring system also allows \i margins and \i offsets to be specified for an item's anchors.
Margins specify the amount of empty space to leave to the outside of an item's anchor, while
offsets allow positioning to be manipulated using the center anchor lines. An item can
specify its anchor margins individually through \l {Item::anchors.leftMargin}{leftMargin},
@@ -105,11 +105,11 @@ Rectangle { id: rect1; ... }
Rectangle { id: rect2; anchors.left: rect1.right; anchors.leftMargin: 5; ... }
\endcode
-In this case, a margin of 5 pixels is reserved to the left of \e rect2, producing the following:
+In this case, a margin of 5 pixels is reserved to the left of \i rect2, producing the following:
\image edge2.png
-\note Anchor margins only apply to anchors; they are \e not a generic means of applying margins to an \l Item.
+\note Anchor margins only apply to anchors; they are \i not a generic means of applying margins to an \l Item.
If an anchor margin is specified for an edge but the item is not anchored to any item on that
edge, the margin is not applied.
diff --git a/doc/src/declarative/animation.qdoc b/doc/src/declarative/animation.qdoc
index ef01d14414..16fa2d9307 100644
--- a/doc/src/declarative/animation.qdoc
+++ b/doc/src/declarative/animation.qdoc
@@ -80,7 +80,7 @@ directly. This may be done in signal handlers or attached properties.
\snippet doc/src/snippets/declarative/animation.qml direct property change
-However, to create more control, \e {property animations} apply smooth movements
+However, to create more control, \i {property animations} apply smooth movements
by interpolating values between property value changes. Property animations
provide timing controls and allows different interpolations through
\l{qml-easing-animation}{easing curves}.
@@ -125,7 +125,7 @@ that the transition applies to any state change.
\section2 Default Animation as Behaviors
-Default property animations are set using \e {behavior animations}. Animations
+Default property animations are set using \i {behavior animations}. Animations
declared in \l {Behavior} elements apply to the property and animates any
property value changes. However, Behavior elements have an
\c enabled property to purposely enable or disable the behavior animations.
@@ -146,7 +146,7 @@ demonstration of behavioral animations.
\section1 Playing Animations in Parallel or in Sequence
-Animations can run \e {in parallel} or \e {in sequence}. Parallel animations
+Animations can run \i {in parallel} or \i {in sequence}. Parallel animations
will play a group of animations at the same time while sequential animations
play a group of animations in order: one after the other. Grouping animations in
\l{SequentialAnimation} and \l{ParallelAnimation} will play the animations in
@@ -207,7 +207,7 @@ In addition, QML provides several other elements useful for animation:
\o PauseAnimation: enables pauses during animations
\o ScriptAction: allows JavaScript to be executed during an animation, and can
be used together with StateChangeScript to reused existing scripts
-\o PropertyAction: changes a property \e immediately during an animation,
+\o PropertyAction: changes a property \i immediately during an animation,
without animating the property change
\endlist
diff --git a/doc/src/declarative/basictypes.qdoc b/doc/src/declarative/basictypes.qdoc
index 1c412db143..1bc13739fa 100644
--- a/doc/src/declarative/basictypes.qdoc
+++ b/doc/src/declarative/basictypes.qdoc
@@ -422,14 +422,69 @@
\sa {QML Basic Types}
*/
+ /*!
+ \qmlbasictype var
+ \ingroup qmlbasictypes
+
+ \brief A var type is a generic property type.
+
+ A var is a generic property type capable of storing any data type.
+ It is equivalent to a regular JavaScript variable.
+ For example, var properties can store numbers, strings, objects and
+ arrays:
+
+ \qml
+ Item {
+ property var aNumber: 100
+ property var aBool: false
+ property var aString: "Hello world!"
+ property var anotherString: String("#FF008800")
+ property var aColor: Qt.rgba(0.2, 0.3, 0.4, 0.5)
+ property var aRect: Qt.rect(10, 10, 10, 10)
+ property var aPoint: Qt.point(10, 10)
+ property var aSize: Qt.size(10, 10)
+ property var aVector3d: Qt.vector3d(100, 100, 100)
+ property var anArray: [1, 2, 3, "four", "five"]
+ property var anObject: { "foo": 10, "bar": 20 }
+ }
+ \endqml
+
+ It is important to note that properties of JavaScript objects cannot
+ be bound to:
+
+ \qml
+ Item {
+ property var car: new vehicle(4)
+ property int wheelCount: car.wheels
+
+ function vehicle(wheels) {
+ this.wheels = wheels;
+ this.talk = function() { print("I have " + this.wheels + " wheels!"); }
+ }
+
+ Component.onCompleted: {
+ car.wheels = 6; // wheelCount will _not_ be updated
+ }
+ }
+ \endqml
+
+ \sa {QML Basic Types}
+*/
+
+
/*!
+ \obsolete
\qmlbasictype variant
\ingroup qmlbasictypes
\brief A variant type is a generic property type.
- A variant is a generic property type. A variant type property can hold
- any of the \l {QML Basic Types}{basic type} values:
+ A variant is a generic property type. It is obsolete and exists only to
+ support old applications; new applications should use "var" type
+ properties instead.
+
+ A variant type property can hold any of the \l {QML Basic Types}{basic type}
+ values:
\qml
Item {
@@ -480,12 +535,12 @@
\endqml
While this is a convenient way to store array and map-type values, you
- must be aware that the \c items and \c attributes properties above are \e not
+ must be aware that the \c items and \c attributes properties above are \i not
QML objects (and certainly not JavaScript object either) and the key-value
- pairs in \c attributes are \e not QML properties. Rather, the \c items
+ pairs in \c attributes are \i not QML properties. Rather, the \c items
property holds an array of values, and \c attributes holds a set of key-value
pairs. Since they are stored as a set of values, instead of as an object,
- their contents \e cannot be modified individually:
+ their contents \i cannot be modified individually:
\qml
Item {
@@ -511,7 +566,7 @@
One way to "update" the contents of an array or map is to copy the property
to a JavaScript object, modify the copy as desired, and then reassign the
property to the updated copy. Note, however, that this is not efficient.
- In the example below, which reassigns the \c attributes property, the \e entire
+ In the example below, which reassigns the \c attributes property, the \i entire
set of key-value pairs must be serialized and deserialized every time it is
copied between a JavaScript object and a QML property:
@@ -534,7 +589,7 @@
within a JavaScript file.
JavaScript programmers should also note that when a JavaScript object is
- copied to an array or map property, the \e contents of the object (that is,
+ copied to an array or map property, the \i contents of the object (that is,
its key-value properties) are copied, rather than the object itself. The
property does not hold a reference to the original JavaScript object, and
extra data such as the object's JavaScript prototype chain is also lost in
diff --git a/doc/src/declarative/codingconventions.qdoc b/doc/src/declarative/codingconventions.qdoc
index 8222ebce41..f65e53c678 100644
--- a/doc/src/declarative/codingconventions.qdoc
+++ b/doc/src/declarative/codingconventions.qdoc
@@ -53,7 +53,7 @@ Through our documentation and examples, QML objects are always structured in the
For better readability, we separate these different parts with an empty line.
-For example, a hypothetical \e photo QML object would look like this:
+For example, a hypothetical \i photo QML object would look like this:
\snippet doc/src/snippets/declarative/codingconventions/photo.qml 0
@@ -61,7 +61,7 @@ For example, a hypothetical \e photo QML object would look like this:
\section1 Grouped Properties
If using multiple properties from a group of properties,
-we use the \e {group notation} rather than the \e {dot notation} to improve readability.
+we use the \i {group notation} rather than the \i {dot notation} to improve readability.
For example, this:
@@ -77,7 +77,7 @@ can be written like this:
QML and JavaScript do not enforce private properties like C++. There is a need
to hide these private properties, for example, when the properties are part of
the implementation. As a convention, private properties begin with two
-\e underscore characters. For example, \c __area, is a property that is
+\i underscore characters. For example, \c __area, is a property that is
accessible but is not meant for public use. Note that QML and JavaScript will
grant the user access to these properties.
diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc
index d89ca53dbb..d79f474da3 100644
--- a/doc/src/declarative/declarativeui.qdoc
+++ b/doc/src/declarative/declarativeui.qdoc
@@ -46,11 +46,11 @@ Qt applications.
\section1 Getting Started
\list
-\o \l{Intro to Qt Quick}{Introduction to Qt Quick}
+\o \l{Introduction to Qt Quick}
\o \l{QML for Qt Programmers}{QML Programming for Qt Programmers}
\o \l{Getting Started Programming with QML}
-\o \l{What's new in Qt Quick}{What's New in the Qt Quick Release}
+\o \l{What's New in Qt Quick 2}{What's New in the Qt Quick Release}
\o \l{QML Examples and Demos}
\endlist
diff --git a/doc/src/declarative/example-slideswitch.qdoc b/doc/src/declarative/example-slideswitch.qdoc
index a4d8cbe855..482dff0f45 100644
--- a/doc/src/declarative/example-slideswitch.qdoc
+++ b/doc/src/declarative/example-slideswitch.qdoc
@@ -39,7 +39,7 @@ The elements that compose the switch are:
\o a \c on property (the interface to interact with the switch),
\o two images (the background image and the knob),
\o two mouse regions for user interation (on the background image and on the knob),
-\o two states (a \e on state and a \e off state),
+\o two states (a \i on state and a \i off state),
\o two functions or slots to react to the user interation (\c toggle() and \c dorelease()),
\o and a transition that describe how to go from one state to the other.
\endlist
@@ -92,8 +92,8 @@ in the \c dorelease() function that is called in the \c onReleased property.
We define the two states of the switch:
\list
-\o In the \e on state the knob is on the right (\c x position is 78) and the \c on property is \c true.
-\o In the \e off state the knob is on the left (\c x position is 1) and the \c on property is \c false.
+\o In the \i on state the knob is on the right (\c x position is 78) and the \c on property is \c true.
+\o In the \i off state the knob is on the left (\c x position is 1) and the \c on property is \c false.
\endlist
For more information on states see \l{qmlstates}{QML States}.
@@ -105,13 +105,13 @@ We add two JavaScript functions to our switch:
\snippet examples/declarative/ui-components/slideswitch/content/Switch.qml 2
This first function is called when the background image or the knob are clicked. We simply want the switch to toggle between the two
-states (\e on and \e off).
+states (\i on and \i off).
\snippet examples/declarative/ui-components/slideswitch/content/Switch.qml 3
This second function is called when the knob is released and we want to make sure that the knob does not end up between states
-(neither \e on nor \e off). If it is the case call the \c toggle() function otherwise we do nothing.
+(neither \i on nor \i off). If it is the case call the \c toggle() function otherwise we do nothing.
For more information on scripts see \l{Integrating JavaScript}.
diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc
index 0f7becdc83..0563f65cc0 100644
--- a/doc/src/declarative/extending.qdoc
+++ b/doc/src/declarative/extending.qdoc
@@ -98,11 +98,11 @@ document, which includes the following:
\endlist
When a property of a supported type is added to a C++ class, in a QML
-element based on the C++ class, a \e{value-changed} signal handler
+element based on the C++ class, a \i{value-changed} signal handler
will be available. See \l{Signal Support} below.
QML is typesafe. Attempting to assign an invalid value to a property
-will generate an error. For example, assuming the \e{name} property
+will generate an error. For example, assuming the \i{name} property
of the \c Person element had a type of QString, this would cause an
error:
@@ -150,9 +150,9 @@ only available from a particular version of QCppItem onwards. This permits new p
and features to be added to existing elements without breaking existing programs.
QML enables this by allowing the properties, methods and signals of a class to be tagged with
-a particular \e revision, so that they are only accessible if the relevant module version
+a particular \i revision, so that they are only accessible if the relevant module version
is imported. In this case, the author can tag the \c root property as being added in
-\e {revision 1} of the class, and register that revision in version 1.1 of the module.
+\i {revision 1} of the class, and register that revision in version 1.1 of the module.
The REVISION tag is used to mark the \c root property as added in revision 1 of the class.
Methods such as Q_INVOKABLE's, signals and slots can also be tagged for a
@@ -285,7 +285,7 @@ code used to create the \c Boy and \c Girl types.
The QML snippet shown above assigns a collection of objects to the
\c BirthdayParty's default property.
-The \e {default property} is a syntactic convenience that allows a type designer to
+The \i {default property} is a syntactic convenience that allows a type designer to
specify a single property as the type's default. The default property is
assigned to whenever no explicit property is specified. As a convenience, it is
behaviorally identical to assigning to the default property explicitly by name.
@@ -385,8 +385,8 @@ property accesses. Consequently the attachment object may not be deleted until
\a object is destroyed.
\endquotation
-Conceptually, attached properties are a \e type exporting a set of additional
-properties that can be set on \e any other object instance. Attached properties
+Conceptually, attached properties are a \i type exporting a set of additional
+properties that can be set on \i any other object instance. Attached properties
cannot be limited to only attaching to a sub-set of object instances, although
their effect may be so limited.
@@ -492,9 +492,9 @@ If you want to use signals from items not created in QML, you can access their
signals with the \l {Connections} element.
Additionally, if a property is added to a C++ class, all QML elements
-based on that C++ class will have a \e{value-changed} signal handler
+based on that C++ class will have a \i{value-changed} signal handler
for that property. The name of the signal handler is
-\e{on<Property-name>Changed}, with the first letter of the property
+\i{on<Property-name>Changed}, with the first letter of the property
name being upper case.
\note The QML signal handler will always be named
diff --git a/doc/src/declarative/focus.qdoc b/doc/src/declarative/focus.qdoc
index d75bd11a36..54d4f81538 100644
--- a/doc/src/declarative/focus.qdoc
+++ b/doc/src/declarative/focus.qdoc
@@ -38,7 +38,7 @@
When a key is pressed or released, a key event is generated and delivered to the
focused QML \l Item. To facilitate the construction of reusable components
and to address some of the cases unique to fluid user interfaces, the QML items add aged
-\e scope based extension to Qt's traditional keyboard focus model.
+\i scope based extension to Qt's traditional keyboard focus model.
\tableofcontents
@@ -50,7 +50,7 @@ When the user presses or releases a key, the following occurs:
\o If the Qt widget containing the \l QDeclarativeView has focus, the key event
is delivered to it. Otherwise, regular Qt key handling continues.
\o The key event is delivered by the scene to the QML \l Item with
-\e {active focus}. If no Item has active focus, the key event is
+\i {active focus}. If no Item has active focus, the key event is
\l {QEvent::ignore()}{ignored} and regular Qt key handling continues.
\o If the QML Item with active focus accepts the key event, propagation
stops. Otherwise the event is "bubbled up", by recursively passing it to each
@@ -123,7 +123,7 @@ the focus, but it cannot control the focus when it is imported or reused.
Likewise, the \c window component does not have the ability to know if its
imported components are requesting the focus.
-To solve this problem, the QML introduces a concept known as a \e {focus scope}.
+To solve this problem, the QML introduces a concept known as a \i {focus scope}.
For existing Qt users, a focus scope is like an automatic focus proxy.
A focus scope is created by declaring the \l FocusScope element.
@@ -135,7 +135,7 @@ visual result shown.
\image declarative-qmlfocus3.png
-Conceptually \e {focus scopes} are quite simple.
+Conceptually \i {focus scopes} are quite simple.
\list
\o Within each focus scope one element may have \c {Item::focus} set to
\c true. If more than one \l Item has the \c focus property set, the
diff --git a/doc/src/declarative/globalobject.qdoc b/doc/src/declarative/globalobject.qdoc
index 4b8b538a65..f4e9d0df8f 100644
--- a/doc/src/declarative/globalobject.qdoc
+++ b/doc/src/declarative/globalobject.qdoc
@@ -49,7 +49,7 @@ The XMLHttpRequest API implements the same \l {http://www.w3.org/TR/XMLHttpReque
as many popular web browsers with following exceptions:
\list
\i QML's XMLHttpRequest does not enforce the same origin policy.
-\i QML's XMLHttpRequest does not support \e synchronous requests.
+\i QML's XMLHttpRequest does not support \i synchronous requests.
\endlist
Additionally, the \c responseXML XML DOM tree currently supported by QML is a reduced subset
@@ -142,9 +142,9 @@ using the Offline Storage API.
\section3 db = openDatabaseSync(identifier, version, description, estimated_size, callback(db))
-Returns the database identified by \e identifier. If the database does not already exist, it
-is created, and the function \e callback is called with the database as a parameter. \e description
-and \e estimated_size are written to the INI file (described below), but are otherwise currently
+Returns the database identified by \i identifier. If the database does not already exist, it
+is created, and the function \i callback is called with the database as a parameter. \i description
+and \i estimated_size are written to the INI file (described below), but are otherwise currently
unused.
May throw exception with code property SQLException.DATABASE_ERR, or SQLException.VERSION_ERR.
@@ -164,37 +164,37 @@ This data can be used by application tools.
\section3 db.changeVersion(from, to, callback(tx))
-This method allows you to perform a \e{Scheme Upgrade}.
+This method allows you to perform a \i{Scheme Upgrade}.
-If the current version of \e db is not \e from, then an exception is thrown.
+If the current version of \i db is not \i from, then an exception is thrown.
-Otherwise, a database transaction is created and passed to \e callback. In this function,
-you can call \e executeSql on \e tx to upgrade the database.
+Otherwise, a database transaction is created and passed to \i callback. In this function,
+you can call \i executeSql on \i tx to upgrade the database.
May throw exception with code property SQLException.DATABASE_ERR or SQLException.UNKNOWN_ERR.
\section3 db.transaction(callback(tx))
-This method creates a read/write transaction and passed to \e callback. In this function,
-you can call \e executeSql on \e tx to read and modify the database.
+This method creates a read/write transaction and passed to \i callback. In this function,
+you can call \i executeSql on \i tx to read and modify the database.
If the callback throws exceptions, the transaction is rolled back.
\section3 db.readTransaction(callback(tx))
-This method creates a read-only transaction and passed to \e callback. In this function,
-you can call \e executeSql on \e tx to read the database (with SELECT statements).
+This method creates a read-only transaction and passed to \i callback. In this function,
+you can call \i executeSql on \i tx to read the database (with SELECT statements).
\section3 results = tx.executeSql(statement, values)
-This method executes a SQL \e statement, binding the list of \e values to SQL positional parameters ("?").
+This method executes a SQL \i statement, binding the list of \i values to SQL positional parameters ("?").
It returns a results object, with the following properties:
\table
\header \o \bold {Type} \o \bold {Property} \o \bold {Value} \o \bold {Applicability}
\row \o int \o rows.length \o The number of rows in the result \o SELECT
-\row \o var \o rows.item(i) \o Function that returns row \e i of the result \o SELECT
+\row \o var \o rows.item(i) \o Function that returns row \i i of the result \o SELECT
\row \o int \o rowsAffected \o The number of rows affected by a modification \o UPDATE, DELETE
\row \o string \o insertId \o The id of the row inserted \o INSERT
\endtable
diff --git a/doc/src/declarative/javascriptblocks.qdoc b/doc/src/declarative/javascriptblocks.qdoc
index 01d0d45a2d..ba2bda34b5 100644
--- a/doc/src/declarative/javascriptblocks.qdoc
+++ b/doc/src/declarative/javascriptblocks.qdoc
@@ -211,12 +211,12 @@ or modules).
It is occasionally necessary to run some imperative code at application (or
component instance) startup. While it is tempting to just include the startup
-script as \e {global code} in an external script file, this can have severe limitations
+script as \i {global code} in an external script file, this can have severe limitations
as the QML environment may not have been fully established. For example, some objects
might not have been created or some \l {Property Binding}s may not have been run.
\l {QML JavaScript Restrictions} covers the exact limitations of global script code.
-The QML \l Component element provides an \e attached \c onCompleted property that
+The QML \l Component element provides an \i attached \c onCompleted property that
can be used to trigger the execution of script code at startup after the
QML environment has been completely established. For example:
diff --git a/doc/src/declarative/modules.qdoc b/doc/src/declarative/modules.qdoc
index 259c77ff3c..d37dc9d215 100644
--- a/doc/src/declarative/modules.qdoc
+++ b/doc/src/declarative/modules.qdoc
@@ -57,7 +57,7 @@ This imports version 1.0 of the "QtQuick" module into the global namespace. (The
library itself must be imported to use any of the \l {QML Elements}, as they
are not included in the global namespace by default.)
-The \c Qt module is an \e installed module; it is found in the
+The \c Qt module is an \i installed module; it is found in the
\l{#import-path}{import path}. There are two types of QML modules:
located modules (defined by a URL) and installed modules (defined by a URI).
@@ -268,7 +268,7 @@ a module that is imported as a network resource.
By default, when a module is imported, its contents are imported into the global namespace. You may choose to import the module into another namespace, either to allow identically-named types to be referenced, or purely for readability.
-To import a module into a specific namespace, use the \e as keyword:
+To import a module into a specific namespace, use the \i as keyword:
\snippet doc/src/snippets/declarative/imports/named-imports.qml imports
@@ -327,7 +327,7 @@ may be marked with the \c internal keyword: \bold {internal <TypeName> <File>}.
The same type can be provided by different files in different versions, in which
case later versions (e.g. 1.2) must precede earlier versions (e.g. 1.0),
-since the \e first name-version match is used and a request for a version of a type
+since the \i first name-version match is used and a request for a version of a type
can be fulfilled by one defined in an earlier version of the module. If a user attempts
to import a version earlier than the earliest provided or later than the latest provided,
the import produces a runtime error, but if the user imports a version within the range of versions provided,
@@ -338,7 +338,7 @@ If multiple are provided, only the first in the search path will be used (regard
are provided by directories later in the search path).
The versioning system ensures that a given QML file will work regardless of the version
-of installed software, since a versioned import \e only imports types for that version,
+of installed software, since a versioned import \i only imports types for that version,
leaving other identifiers available, even if the actual installed version might otherwise
provide those identifiers.
diff --git a/doc/src/declarative/network.qdoc b/doc/src/declarative/network.qdoc
index f04d198506..3375ead141 100644
--- a/doc/src/declarative/network.qdoc
+++ b/doc/src/declarative/network.qdoc
@@ -42,7 +42,7 @@ Image {
}
\endqml
-Since a \e relative URL is the same
+Since a \i relative URL is the same
as a relative file, development of QML on regular file systems remains simple:
\qml
diff --git a/doc/src/declarative/pics/declarative-qmlfocus1.png b/doc/src/declarative/pics/declarative-qmlfocus1.png
deleted file mode 100644
index fd05146d8a..0000000000
--- a/doc/src/declarative/pics/declarative-qmlfocus1.png
+++ /dev/null
Binary files differ
diff --git a/doc/src/declarative/pics/declarative-qmlfocus2.png b/doc/src/declarative/pics/declarative-qmlfocus2.png
deleted file mode 100644
index a946e2c49f..0000000000
--- a/doc/src/declarative/pics/declarative-qmlfocus2.png
+++ /dev/null
Binary files differ
diff --git a/doc/src/declarative/pics/declarative-qmlfocus3.png b/doc/src/declarative/pics/declarative-qmlfocus3.png
deleted file mode 100644
index ba55f76098..0000000000
--- a/doc/src/declarative/pics/declarative-qmlfocus3.png
+++ /dev/null
Binary files differ
diff --git a/doc/src/declarative/pics/declarative-qmlfocus4.png b/doc/src/declarative/pics/declarative-qmlfocus4.png
deleted file mode 100644
index e21f2a6aa9..0000000000
--- a/doc/src/declarative/pics/declarative-qmlfocus4.png
+++ /dev/null
Binary files differ
diff --git a/doc/src/declarative/propertybinding.qdoc b/doc/src/declarative/propertybinding.qdoc
index c35ed2574a..133b830b58 100644
--- a/doc/src/declarative/propertybinding.qdoc
+++ b/doc/src/declarative/propertybinding.qdoc
@@ -35,7 +35,7 @@
\section1 Properties
-QML components have \e properties that can be read and modified by other objects.
+QML components have \i properties that can be read and modified by other objects.
In QML, properties serve many purposes but their main function is to bind to
values. Values may be a \l{QML Basic Types}{basic type}, or other QML elements.
@@ -104,7 +104,7 @@ although it is possible to use the \l {Using the Binding Element}{Binding} eleme
\section1 Types of Properties
-Properties may bind to different types, but they are are \e type-safe. That is,
+Properties may bind to different types, but they are are \i type-safe. That is,
properties only allow you to assign a value that matches the property type. For
example, if a property is a real, and if you try to assign a string to it you
will get an error.
@@ -163,21 +163,21 @@ For more information about the \c children property, please read the
\keyword attached-properties
\section2 Attached Properties
-Certain objects provide additional properties by \e attaching properties to other
-objects. For example, the \l Keys element have properties that can \e attach to other QML
+Certain objects provide additional properties by \i attaching properties to other
+objects. For example, the \l Keys element have properties that can \i attach to other QML
objects to provide keyboard handling.
\snippet doc/src/snippets/declarative/properties.qml list attached property
The element \l ListView provides the delegate, \c listdelegate, the property
\c isCurrentItem as an attached property. The \c ListView.isCurrentItem
-\e{attached property} provides highlight information to the delegate.
+\i{attached property} provides highlight information to the delegate.
Effectively, the \l ListView element attaches the \c ListView.isCurrentItem
property to each delegate it creates.
\keyword attached-signalhandlers
\section2 Attached Signal Handlers
-\e {Attached signal handlers} are similar
+\i {Attached signal handlers} are similar
to \l{Attached Properties}{attached properties} in that they attach to objects
to provide additional functionality to objects. Two prominent elements,
\l Component and \l Keys element provide
@@ -210,8 +210,8 @@ for more details about list properties and their available operations.
\keyword qml-grouped-properties
\section2 Grouped Properties
-In some cases properties form a logical group and use either the \e dot notation
-or \e group notation.
+In some cases properties form a logical group and use either the \i dot notation
+or \i group notation.
Grouped properties may be written both ways:
\snippet doc/src/snippets/declarative/properties.qml grouped properties
@@ -222,8 +222,8 @@ In the element documentation grouped properties are shown using the dot notation
Unlike a property definition, which allocates a new, unique storage space for
the property, a property alias connects the newly declared property, called the
-\e{aliasing property} as a direct reference to an existing property, the
-\e{aliased property}. Read or write operations on the aliasing property results
+\i{aliasing property} as a direct reference to an existing property, the
+\i{aliased property}. Read or write operations on the aliasing property results
in a read or write operations on the aliased property, respectively.
A property alias declaration is similar to an ordinary property definition:
@@ -285,8 +285,8 @@ aliases to reassign children to the \l ListView, creating a tab effect.
\section2 Default Properties
When imported, QML components will bind declared children to their designated
-\e{default properties}. The optional \c default attribute specifies a property
-as the \e {default property}. For example, the State element's default property
+\i{default properties}. The optional \c default attribute specifies a property
+as the \i {default property}. For example, the State element's default property
is its \l{State::changes}{changes} property. \l PropertyChanges elements
may simply be placed as the \c{State}'s children and they will be bound to the
\c changes property.
diff --git a/doc/src/declarative/qdeclarativedocument.qdoc b/doc/src/declarative/qdeclarativedocument.qdoc
index aa9692f45c..84ec796b6a 100644
--- a/doc/src/declarative/qdeclarativedocument.qdoc
+++ b/doc/src/declarative/qdeclarativedocument.qdoc
@@ -43,14 +43,14 @@ QML documents are always encoded in UTF-8 format.
A QML document always begins with one or more import statements. To prevent elements
introduced in later versions from affecting existing QML programs, the element types
available within a document are controlled by the imported QML \l {Modules}. That is,
-QML is a \e versioned language.
+QML is a \i versioned language.
-Syntactically a QML document is self contained; QML does \e not have a preprocessor that
+Syntactically a QML document is self contained; QML does \i not have a preprocessor that
modifies the document prior to presentation to the QML runtime. \c import statements
do not "include" code in the document, but instead instruct the QML runtime on how to
resolve type references found in the document. Any type reference present in a QML
document - such as \c Rectangle and \c ListView - including those made within an
-\l {Inline JavaScript}{JavaScript block} or \l {Property Binding}s, are \e resolved based exclusively on the
+\l {Inline JavaScript}{JavaScript block} or \l {Property Binding}s, are \i resolved based exclusively on the
import statements. QML does not import any modules by default, so at least one \c import
statement must be present or no elements will be available!
@@ -64,7 +64,7 @@ resolved according to the document scope.
A QML document defines a single, top-level \l {QDeclarativeComponent}{QML component}. A QML component
is a template that is interpreted by the QML runtime to create an object with some predefined
behaviour. As it is a template, a single QML component can be "run" multiple times to
-produce several objects, each of which are said to be \e instances of the component.
+produce several objects, each of which are said to be \i instances of the component.
Once created, instances are not dependent on the component that created them, so they can
operate on independent data. Here is an example of a simple "Button" component (defined
@@ -111,7 +111,7 @@ to other QML components and applications in the same directory.
In addition to the top-level component that all QML documents define, and any reusable
components placed in separate files, documents may also
-include \e inline components. Inline components are declared using the
+include \i inline components. Inline components are declared using the
\l Component element, as can be seen in the first example above. Inline components share
all the characteristics of regular top-level components and use the same \c import list as their
containing QML document. Components are one of the most basic building blocks in QML, and are
diff --git a/doc/src/declarative/qdeclarativeintro.qdoc b/doc/src/declarative/qdeclarativeintro.qdoc
index 97739e232c..7df49e57f3 100644
--- a/doc/src/declarative/qdeclarativeintro.qdoc
+++ b/doc/src/declarative/qdeclarativeintro.qdoc
@@ -123,7 +123,7 @@ line opacity: 0.5 has been turned into a comment.
\section1 Object Identifiers
-Each object can be given a special \e id value that allows the object to be identified
+Each object can be given a special \i id value that allows the object to be identified
and referred to by other objects.
For example, below we have two \l Text objects. The first \l Text object
@@ -208,7 +208,7 @@ Item {
}
\endqml
-QML properties are what is known as \e type-safe. That is, they only allow you to assign a value that
+QML properties are what is known as \i type-safe. That is, they only allow you to assign a value that
matches the property type. For example, the \c x property of item is a real, and if you try to assign
a string to it you will get an error.
@@ -226,7 +226,7 @@ letter.
When a property changes value, it can send a signal to notify others of this change.
-To receive these signals, simply create a \e {signal handler} named with an \c on<Property>Changed
+To receive these signals, simply create a \i {signal handler} named with an \c on<Property>Changed
syntax. For example, the \l Rectangle element has \l {Item::}{width} and \l {Rectangle::}{color}
properties. Below, we have a \l Rectangle object that has defined two signal handlers,
\c onWidthChanged and \c onColorChanged, which will automaticallly be called whenever these
@@ -332,10 +332,10 @@ Text {
\target attached-properties
Some objects attach properties to another object. Attached Properties
-are of the form \e {Type.property} where \e Type is the type of the
-element that attaches \e property.
+are of the form \i {Type.property} where \i Type is the type of the
+element that attaches \i property.
-For example, the \l ListView element attaches the \e ListView.isCurrentItem property
+For example, the \l ListView element attaches the \i ListView.isCurrentItem property
to each delegate it creates:
\qml
@@ -385,7 +385,7 @@ Item {
}
\endqml
-All signal handlers begin with \e "on".
+All signal handlers begin with \i "on".
Some signal handlers include an optional parameter. For example
the MouseArea \l{MouseArea::}{onPressed} signal handler has a \c mouse parameter
diff --git a/doc/src/declarative/qdeclarativemodels.qdoc b/doc/src/declarative/qdeclarativemodels.qdoc
index 2399a6e2ad..165b704885 100644
--- a/doc/src/declarative/qdeclarativemodels.qdoc
+++ b/doc/src/declarative/qdeclarativemodels.qdoc
@@ -36,26 +36,26 @@
QML items such as ListView, GridView and \l Repeater require Data Models
that provide the data to be displayed.
-These items typically require a \e delegate component that
+These items typically require a \i delegate component that
creates an instance for each item in the model. Models may be static, or
have items modified, inserted, removed or moved dynamically.
Data is provided to the delegate via named data roles which the
-delegate may bind to. Here is a ListModel with two roles, \e type and \e age,
+delegate may bind to. Here is a ListModel with two roles, \i type and \i age,
and a ListView with a delegate that binds to these roles to display their
values:
\snippet doc/src/snippets/declarative/qml-data-models/listmodel-listview.qml document
If there is a naming clash between the model's properties and the delegate's
-properties, the roles can be accessed with the qualified \e model name instead.
-For example, if a \l Text element had \e type or \e age properties, the text in the
-above example would display those property values instead of the \e type and \e age values
+properties, the roles can be accessed with the qualified \i model name instead.
+For example, if a \l Text element had \i type or \i age properties, the text in the
+above example would display those property values instead of the \i type and \i age values
from the model item. In this case, the properties could have been referenced as
\c model.type and \c model.age instead to ensure the delegate displays the
property values from the model item.
-A special \e index role containing the index of the item in the model
+A special \i index role containing the index of the item in the model
is also available to the delegate. Note this index is set to -1 if the item is removed from
the model. If you bind to the index role, be sure that the logic
accounts for the possibility of index being -1, i.e. that the item
@@ -64,8 +64,8 @@ it is possible to delay delegate destruction in some views via a \c delayRemove
attached property.)
Models that do not have named roles (such as the QStringList model shown below)
-will have the data provided via the \e modelData role. The \e modelData role is also provided for
-models that have only one role. In this case the \e modelData role
+will have the data provided via the \i modelData role. The \i modelData role is also provided for
+models that have only one role. In this case the \i modelData role
contains the same data as the named role.
QML provides several types of data models among the built-in set of
@@ -88,7 +88,7 @@ available roles are specified by the \l ListElement properties.
\snippet doc/src/snippets/declarative/qml-data-models/listelements.qml model
-The above model has two roles, \e name and \e cost. These can be bound
+The above model has two roles, \i name and \i cost. These can be bound
to by a ListView delegate, for example:
\snippet doc/src/snippets/declarative/qml-data-models/listelements.qml view
@@ -103,7 +103,7 @@ insertion are the only roles that will be shown in the view:
\dots
\snippet doc/src/snippets/declarative/qml-data-models/dynamic-listmodel.qml mouse area
-When the MouseArea is clicked, \c fruitModel will have two roles, \e cost and \e name.
+When the MouseArea is clicked, \c fruitModel will have two roles, \i cost and \i name.
Even if subsequent roles are added, only the first two will be handled by views
using the model. To reset the roles available in the model, call ListModel::clear().
@@ -113,7 +113,7 @@ using the model. To reset the roles available in the model, call ListModel::clea
XmlListModel allows construction of a model from an XML data source. The roles
are specified via the \l XmlRole element.
-The following model has three roles, \e title, \e link and \e description:
+The following model has three roles, \i title, \i link and \i description:
\qml
XmlListModel {
id: feedModel
@@ -157,7 +157,7 @@ models.
\section2 QStringList-based model
-A model may be a simple QStringList, which provides the contents of the list via the \e modelData role.
+A model may be a simple QStringList, which provides the contents of the list via the \i modelData role.
Here is a ListView with a delegate that references its model item's
value using the \c modelData role:
@@ -234,7 +234,7 @@ QAbstractItemModel::setRoleNames(). The default role names set by Qt are:
\endtable
Here is an application with a QAbstractListModel subclass named \c AnimalModel
-that has \e type and \e size roles. It calls QAbstractItemModel::setRoleNames() to set the
+that has \i type and \i size roles. It calls QAbstractItemModel::setRoleNames() to set the
role names for accessing the properties via QML:
\snippet examples/declarative/modelviews/abstractitemmodel/model.h 0
@@ -248,7 +248,7 @@ role names for accessing the properties via QML:
\snippet examples/declarative/modelviews/abstractitemmodel/main.cpp 0
\dots
-This model is displayed by a ListView delegate that accesses the \e type and \e size
+This model is displayed by a ListView delegate that accesses the \i type and \i size
roles:
\snippet examples/declarative/modelviews/abstractitemmodel/view.qml 0
@@ -268,7 +268,7 @@ the VisualDataModel element provides several properties and functions for use
with models of type QAbstractItemModel:
\list
-\o \e hasModelChildren role property to determine whether a node has child nodes.
+\o \i hasModelChildren role property to determine whether a node has child nodes.
\o \l VisualDataModel::rootIndex allows the root node to be specifed
\o \l VisualDataModel::modelIndex() returns a QModelIndex which can be assigned to VisualDataModel::rootIndex
\o \l VisualDataModel::parentModelIndex() returns a QModelIndex which can be assigned to VisualDataModel::rootIndex
@@ -358,8 +358,8 @@ An object instance can be used to specify a model with a single object element.
properties of the object are provided as roles.
The example below creates a list with one item, showing the color of the
-\e myText text. Note the use of the fully qualified \e model.color property
-to avoid clashing with \e color property of the Text element in the delegate.
+\i myText text. Note the use of the fully qualified \i model.color property
+to avoid clashing with \i color property of the Text element in the delegate.
\qml
Rectangle {
@@ -398,9 +398,9 @@ different for each view, and you would like these different settings to
be properties of each of the views. Similarly, it might be of interest
to access or show some properties of the model.
-In the following example, the delegate shows the property \e{language}
+In the following example, the delegate shows the property \i{language}
of the model, and the color of one of the fields depends on the
-property \e{fruit_color} of the view.
+property \i{fruit_color} of the view.
\snippet doc/src/snippets/declarative/models/views-models-delegates.qml rectangle
@@ -418,8 +418,8 @@ a function in the model, e.g.:
ListView.view.model.setData(index, field, value)
\endjs
-...assuming that \e{field} holds the name of the field which should be
-updated, and that \e{value} holds the new value.
+...assuming that \i{field} holds the name of the field which should be
+updated, and that \i{value} holds the new value.
*/
diff --git a/doc/src/declarative/qdeclarativeperformance.qdoc b/doc/src/declarative/qdeclarativeperformance.qdoc
index 03643e72a6..737f19f67a 100644
--- a/doc/src/declarative/qdeclarativeperformance.qdoc
+++ b/doc/src/declarative/qdeclarativeperformance.qdoc
@@ -26,7 +26,7 @@
****************************************************************************/
/*!
-\page qdeclarativeperformance.html
+\page qtquick2-performance.html
\title QML Performance
\section1 Opaque Items
@@ -37,7 +37,7 @@ this is when a "details" page is shown over the main application view.
\section1 Clipping
-\e clip is set to false by default. Enable clipping only when necessary.
+\i clip is set to false by default. Enable clipping only when necessary.
\section1 Anchors vs. Binding
@@ -115,36 +115,30 @@ provide an image that includes the frame and the shadow.
Avoid running JavaScript during animation. For example, running a complex
JavaScript expression for each frame of an x property animation.
-\section1 Rendering
+\section1 Loading later
-Often using a different graphics system will give superior performance to the native
-graphics system (this is especially the case on X11). This can be configured using
-QApplication::setGraphicsSystem() or via the command line using the \c -graphicssystem
-switch.
+Startup time is influenced by the amount of QML that must be loaded. Breaking your
+application into components which can be loaded when needed will allow faster startup time.
+This allows better runtime memory management by unloading the components when no
+longer needed.
-You can enable OpenGL acceleration using the \c opengl graphics system, or by setting a
-QGLWidget as the viewport of your QDeclarativeView.
+This may be achieved by using either \l Loader or creating components
+\l {Dynamic Object Management in QML}{dynamically}.
-You may need to try various options to find what works the best for your application.
-For embedded X11-based devices one recommended combination is to use the raster graphics
-system with a QGLWidget for the viewport. While this doesn't guarantee the \bold fastest
-performance for all use-cases, it typically has \bold{consistently good} performance for
-all use-cases. In contrast, only using the raster paint engine may result in very good
-performance for parts of your application and very poor performance elsewhere.
+\section1 Property Types
-The QML Viewer uses the raster graphics system by default for X11 and OS X. It also
-includes a \c -opengl command line option which sets a QGLWidget as the viewport of the
-view. On OS X, a QGLWidget is always used.
-
-You can also prevent QDeclarativeView from painting its window background if
-you will provide the background of your application using QML, e.g.
+When possible use a specific type, rather than variant, when declaring properties.
\code
-QDeclarativeView window;
-window.setAttribute(Qt::WA_OpaquePaintEvent);
-window.setAttribute(Qt::WA_NoSystemBackground);
-window.viewport()->setAttribute(Qt::WA_OpaquePaintEvent);
-window.viewport()->setAttribute(Qt::WA_NoSystemBackground);
+Item {
+ property variant foo: 10
+ property real bar: 10
+
+ x: foo * 2
+ y: bar *3
+}
\endcode
+bar is faster than foo.
+
*/
diff --git a/doc/src/declarative/qdeclarativesecurity.qdoc b/doc/src/declarative/qdeclarativesecurity.qdoc
index d70d840e8d..0e91b13299 100644
--- a/doc/src/declarative/qdeclarativesecurity.qdoc
+++ b/doc/src/declarative/qdeclarativesecurity.qdoc
@@ -66,7 +66,7 @@ A non-exhaustive list of the ways you could shoot yourself in the foot is:
\endlist
However, the above does not mean that you have no use for the network transparency of QML.
-There are many good and useful things you \e can do:
+There are many good and useful things you \i can do:
\list
\i Create \l Image elements with source URLs of any online images. GOOD
@@ -74,7 +74,7 @@ There are many good and useful things you \e can do:
\i Use \l{XMLHttpRequest}{XMLHttpRequest} to interact with online services. GOOD
\endlist
-The only reason this page is necessary at all is that JavaScript, when run in a \e{web browser},
+The only reason this page is necessary at all is that JavaScript, when run in a \i{web browser},
has quite many restrictions. With QML, you should neither rely on similar restrictions, nor
worry about working around them.
*/
diff --git a/doc/src/declarative/qdeclarativestates.qdoc b/doc/src/declarative/qdeclarativestates.qdoc
index 9857894d2b..6b66d31f38 100644
--- a/doc/src/declarative/qdeclarativestates.qdoc
+++ b/doc/src/declarative/qdeclarativestates.qdoc
@@ -44,14 +44,14 @@
\o \l AnchorChanges
\endlist
-Many user interface designs are \e state driven; interfaces have configurations
+Many user interface designs are \i state driven; interfaces have configurations
that differ depending on the current state. For example, a traffic signal will
configure its flags or lights depending on its state. While in the signal's
\c stop state, a red light will turn on while the yellow and the green lights
will turn off. In the \c caution state, the yellow light is on while the other
lights are turned off.
-In QML, \e states are a set of property configurations defined in a \l State
+In QML, \i states are a set of property configurations defined in a \l State
element. Different configurations could, for example:
\list
@@ -104,7 +104,7 @@ It can also:
\section1 The Default State
-Every \l Item based component has a \c state property and a \e{default state}.
+Every \l Item based component has a \c state property and a \i{default state}.
The default state is the empty string (\c{""}) and contains all of an item's
initial property values. The default state is useful for managing property
values before state changes. Setting the \c state property to an empty string
diff --git a/doc/src/declarative/qmlevents.qdoc b/doc/src/declarative/qmlevents.qdoc
index 36db3efe02..ddc28126e3 100644
--- a/doc/src/declarative/qmlevents.qdoc
+++ b/doc/src/declarative/qmlevents.qdoc
@@ -61,7 +61,7 @@ If the signal has no parameters, the "\c{()}" brackets are optional. If
parameters are used, the parameter types must be declared, as for the \c string
and \c variant arguments of the \c perform signal.
-Adding a signal to an item automatically adds a \e{signal handler} as well. The
+Adding a signal to an item automatically adds a \i{signal handler} as well. The
signal hander is named \c on<SignalName>, with the first letter of the signal in
uppercase. The previous signals have the following signal handlers:
\snippet doc/src/snippets/declarative/events.qml signal handler declaration
@@ -85,7 +85,7 @@ Note that the \c Component.onCompleted is an
Signal objects have a \c connect() method to a connect a signal either to a
method or another signal. When a signal is connected to a method, the method is
automatically invoked whenever the signal is emitted. (In Qt terminology, the
-method is a \e slot that is connected to the \e signal; all methods defined in
+method is a \i slot that is connected to the \i signal; all methods defined in
QML are created as \l{Signals & Slots}{Qt slots}.) This enables a signal
to be received by a method instead of a \l {Signal Handlers}{signal handler}.
diff --git a/doc/src/declarative/qmlreusablecomponents.qdoc b/doc/src/declarative/qmlreusablecomponents.qdoc
index 9860dd4aa2..2c84a7ce53 100644
--- a/doc/src/declarative/qmlreusablecomponents.qdoc
+++ b/doc/src/declarative/qmlreusablecomponents.qdoc
@@ -34,10 +34,10 @@
\title Importing Reusable Components
-A \e component is an instantiable QML definition, typically contained in a
-\c .qml file. For instance, a Button \e component may be defined in
+A \i component is an instantiable QML definition, typically contained in a
+\c .qml file. For instance, a Button \i component may be defined in
\c Button.qml. The QML runtime may instantiate this Button component to create
-Button \e objects. Alternatively, a component may be defined inside a
+Button \i objects. Alternatively, a component may be defined inside a
\l Component element.
Moreover, the Button definition may also contain other components. A Button
@@ -111,7 +111,7 @@ signal handler executes when the component finishes destruction.
\keyword qml-top-level
\section1 Top-Level Component
-Choosing the \e{top-level} or the \e{root} object of components is an important
+Choosing the \i{top-level} or the \i{root} object of components is an important
design aspect because the top-level object dictates which properties are
accessible outside the component. Some elements are not visual elements and
will not have visual properties exposed outside the component. Likewise, some
diff --git a/doc/src/declarative/qmlsyntax.qdoc b/doc/src/declarative/qmlsyntax.qdoc
index 43be6af686..dfabc32985 100644
--- a/doc/src/declarative/qmlsyntax.qdoc
+++ b/doc/src/declarative/qmlsyntax.qdoc
@@ -103,7 +103,7 @@ Rotation {
\endcode
These expressions can include references to other objects and properties, in which case
-a \e binding is established: when the value of the expression changes, the property the
+a \i binding is established: when the value of the expression changes, the property the
expression has been assigned to is automatically updated to that value.
\code
@@ -122,8 +122,8 @@ Item {
In the example above, the \c text2 object will display the same text as \c text1. If \c text1 is changed,
\c text2 is automatically changed to the same value.
-Note that to refer to other objects, we use their \e id values. (See below for more
-information on the \e id property.)
+Note that to refer to other objects, we use their \i id values. (See below for more
+information on the \i id property.)
\section1 QML Comments
diff --git a/doc/src/declarative/qmlviewer.qdoc b/doc/src/declarative/qmlviewer.qdoc
index 85df063b70..8638e467cf 100644
--- a/doc/src/declarative/qmlviewer.qdoc
+++ b/doc/src/declarative/qmlviewer.qdoc
@@ -37,7 +37,7 @@ runtime to load QML documents and also includes additional features useful for
the development of QML-based applications.
The QML Viewer is a tool for testing and developing QML applications. It is
-\e not intended for use in a production environment and should not be used for the
+\i not intended for use in a production environment and should not be used for the
deployment of QML applications. In those cases, the QML runtime should be invoked
from a Qt application instead; see \l {Qt Declarative UI Runtime} for more
information.
@@ -203,7 +203,7 @@ through the \c active property of the \l {QML:Qt::application}{Qt.application} o
N900 platform and most S60 5.0-based or newer Symbian devices, this property
automatically updates to reflect the device's actual orientation; on other platforms,
this indicates the orientation currently selected in the QML Viewer's
-\e {Settings -> Properties} menu. The \c orientation value can be one of the following:
+\i {Settings -> Properties} menu. The \c orientation value can be one of the following:
\list
\o \c Orientation.Portrait
diff --git a/doc/src/declarative/qmlviews.qdoc b/doc/src/declarative/qmlviews.qdoc
index e28c4ec31a..13015e0ff6 100644
--- a/doc/src/declarative/qmlviews.qdoc
+++ b/doc/src/declarative/qmlviews.qdoc
@@ -66,7 +66,7 @@ For more information, consult the \l {QML Data Models} article.
\keyword qml-view-delegate
\section1 View Delegates
-Views need a \e delegate to visually represent an item in a list. A view will
+Views need a \i delegate to visually represent an item in a list. A view will
visualize each item list according to the template defined by the delegate.
Items in a model are accessible through the \c index property as well as the
item's properties.
@@ -75,7 +75,7 @@ item's properties.
\section1 Decorating Views
-Views allow visual customization through \e decoration properties such as the \c header, \c footer, and \c section properties. By binding an object, usually
+Views allow visual customization through \i decoration properties such as the \c header, \c footer, and \c section properties. By binding an object, usually
another visual object, to these properties, the views are decoratable. A footer
may include a \l Rectangle element showcasing borders or a header that displays
a logo on top of the list.
@@ -107,7 +107,7 @@ specified.
\section1 ListView Sections
-\l {ListView} contents may be grouped into \e sections, where related list items
+\l {ListView} contents may be grouped into \i sections, where related list items
are labeled according to their sections. Further, the sections may be decorated
with \l{qml-view-delegate}{delegates}.
diff --git a/doc/src/declarative/qtbinding.qdoc b/doc/src/declarative/qtbinding.qdoc
index 5c125b25d3..fe147210b7 100644
--- a/doc/src/declarative/qtbinding.qdoc
+++ b/doc/src/declarative/qtbinding.qdoc
@@ -626,7 +626,7 @@ To use the resource system in a mixed QML/C++ application:
Once this is done, all files specified by relative paths in QML will be loaded from
the resource system instead. Use of the resource system is completely transparent to
the QML layer; this means all QML code should refer to resource files using relative
-paths and should \e not use the \c qrc scheme. This scheme should only be used from
+paths and should \i not use the \c qrc scheme. This scheme should only be used from
C++ code for referring to resource files.
Here is a application packaged using the \l {The Qt Resource System}{Qt resource system}.
diff --git a/doc/src/declarative/qtdeclarative.qdoc b/doc/src/declarative/qtdeclarative.qdoc
index 75420d5172..e83641d4c6 100644
--- a/doc/src/declarative/qtdeclarative.qdoc
+++ b/doc/src/declarative/qtdeclarative.qdoc
@@ -95,7 +95,7 @@
int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName);
\endcode
- The former is the standard form which registers the type \e T as a new type.
+ The former is the standard form which registers the type \i T as a new type.
The latter allows a particular revision of a class to be registered in
a specified version (see \l {QML Type Versioning}).
diff --git a/doc/src/declarative/qtjavascript.qdoc b/doc/src/declarative/qtjavascript.qdoc
index 6d5e237c63..7c053dd7ac 100644
--- a/doc/src/declarative/qtjavascript.qdoc
+++ b/doc/src/declarative/qtjavascript.qdoc
@@ -63,7 +63,7 @@
Custom properties can be made available to scripts by registering
them with the script engine. This is most easily done by setting
- properties of the script engine's \e{Global Object}:
+ properties of the script engine's \i{Global Object}:
\snippet doc/src/snippets/qtjavascript/registeringvalues/main.cpp 0
diff --git a/doc/src/declarative/qtprogrammers.qdoc b/doc/src/declarative/qtprogrammers.qdoc
index ef011356b4..168b1c532d 100644
--- a/doc/src/declarative/qtprogrammers.qdoc
+++ b/doc/src/declarative/qtprogrammers.qdoc
@@ -30,7 +30,7 @@
\target qtprogrammers
\title QML for Qt Programmers
-While QML does not require Qt knowledge to use, if you \e are already familiar with Qt,
+While QML does not require Qt knowledge to use, if you \i are already familiar with Qt,
much of your knowledge is directly relevant to learning and using QML. Of course,
an application with a UI defined in QML also uses Qt for all the non-UI logic.
@@ -46,7 +46,7 @@ QML provides direct access to the following concepts from Qt:
\o Qt models - used directly in data binding (QAbstractItemModel)
\endlist
-Qt knowledge is \e required for \l {Extending QML Functionalities using C++},
+Qt knowledge is \i required for \l {Extending QML Functionalities using C++},
and also for \l{Integrating QML Code with existing Qt UI code}.
\section1 QML Items compared with QWidgets
diff --git a/doc/src/declarative/qtquick-intro.qdoc b/doc/src/declarative/qtquick-intro.qdoc
index bdad2c3047..8083b8a0ef 100644
--- a/doc/src/declarative/qtquick-intro.qdoc
+++ b/doc/src/declarative/qtquick-intro.qdoc
@@ -27,7 +27,7 @@
/*!
\page qml-intro.html
-\title Intro to Qt Quick
+\title Introduction to Qt Quick
Qt Quick is a collection of technologies that are designed to help developers
create the kind of intuitive, modern, and fluid user interfaces that are
@@ -44,7 +44,7 @@ environment (IDE) introduces tools for developing Qt Quick applications.
\section1 The QML Language
QML is a high level, scripted language. Its commands, more correctly
-\e elements, leverage the power and efficiency of the Qt libraries to make easy
+\i elements, leverage the power and efficiency of the Qt libraries to make easy
to use commands that perform intuitive functions. Drawing a rectangle,
displaying an image, and application events -- all are possible with declarative
programming.
@@ -53,7 +53,7 @@ The language also allows more flexibility of these commands by using
\l{About JavaScript}{JavaScript} to implement the high level user interface
logic.
-A QML element usually has various \e properties that help define the element.
+A QML element usually has various \i properties that help define the element.
For example, if we created an element called Circle then the radius of the
circle would be a property. Building user interfaces by importing these elements
is one of the great feature of QML and Qt Quick.
diff --git a/doc/src/declarative/scope.qdoc b/doc/src/declarative/scope.qdoc
index b601beff05..b37af6619f 100644
--- a/doc/src/declarative/scope.qdoc
+++ b/doc/src/declarative/scope.qdoc
@@ -126,7 +126,7 @@ require the use of the JavaScript \c this property.
Care must be used when accessing \l {Attached Properties} from bindings due
to their interaction with the scope object. Conceptually attached properties
-exist on \e all objects, even if they only have an effect on a subset of those.
+exist on \i all objects, even if they only have an effect on a subset of those.
Consequently unqualified attached property reads will always resolve to an
attached property on the scope object, which is not always what the programmer
intended.
diff --git a/doc/src/declarative/tutorial.qdoc b/doc/src/declarative/tutorial.qdoc
index 569b9fc834..23056f861b 100644
--- a/doc/src/declarative/tutorial.qdoc
+++ b/doc/src/declarative/tutorial.qdoc
@@ -94,7 +94,7 @@ We add a \l Text element as a child of the root Rectangle element that displays
The \c y property is used to position the text vertically at 30 pixels from the top of its parent.
The \c anchors.horizontalCenter property refers to the horizontal center of an element.
-In this case, we specify that our text element should be horizontally centered in the \e page element (see \l{anchor-layout}{Anchor-Based Layout}).
+In this case, we specify that our text element should be horizontally centered in the \i page element (see \l{anchor-layout}{Anchor-Based Layout}).
The \c font.pointSize and \c font.bold properties are related to fonts and use the \l{dot properties}{dot notation}.
@@ -137,23 +137,23 @@ Here is the QML code for \c Cell.qml:
\snippet examples/declarative/tutorials/helloworld/Cell.qml 1
-The root element of our component is an \l Item with the \c id \e container.
+The root element of our component is an \l Item with the \c id \i container.
An \l Item is the most basic visual element in QML and is often used as a container for other elements.
\snippet examples/declarative/tutorials/helloworld/Cell.qml 4
-We declare a \c cellColor property. This property is accessible from \e outside our component, this allows us
+We declare a \c cellColor property. This property is accessible from \i outside our component, this allows us
to instantiate the cells with different colors.
This property is just an alias to an existing property - the color of the rectangle that compose the cell (see \l{Property Binding}).
\snippet examples/declarative/tutorials/helloworld/Cell.qml 5
-We want our component to also have a signal that we call \e clicked with a \e cellColor parameter of type \e color.
+We want our component to also have a signal that we call \i clicked with a \i cellColor parameter of type \i color.
We will use this signal to change the color of the text in the main QML file later.
\snippet examples/declarative/tutorials/helloworld/Cell.qml 2
-Our cell component is basically a colored rectangle with the \c id \e rectangle.
+Our cell component is basically a colored rectangle with the \c id \i rectangle.
The \c anchors.fill property is a convenient way to set the size of an element.
In this case the rectangle will have the same size as its parent (see \l{anchor-layout}{Anchor-Based Layout}).
@@ -163,8 +163,8 @@ In this case the rectangle will have the same size as its parent (see \l{anchor-
In order to change the color of the text when clicking on a cell, we create a \l MouseArea element with
the same size as its parent.
-A \l MouseArea defines a signal called \e clicked.
-When this signal is triggered we want to emit our own \e clicked signal with the color as parameter.
+A \l MouseArea defines a signal called \i clicked.
+When this signal is triggered we want to emit our own \i clicked signal with the color as parameter.
\section2 The main QML file
@@ -176,8 +176,8 @@ We create the color picker by putting 6 cells with different colors in a grid.
\snippet examples/declarative/tutorials/helloworld/tutorial2.qml 1
-When the \e clicked signal of our cell is triggered, we want to set the color of the text to the \e cellColor passed as a parameter.
-We can react to any signal of our component through a property of the name \e 'onSignalName' (see \l{Signal Handlers}).
+When the \i clicked signal of our cell is triggered, we want to set the color of the text to the \i cellColor passed as a parameter.
+We can react to any signal of our component through a property of the name \i 'onSignalName' (see \l{Signal Handlers}).
*/
/*!
@@ -200,10 +200,10 @@ Here is the QML code:
\snippet examples/declarative/tutorials/helloworld/tutorial3.qml 2
-First, we create a new \e down state for our text element.
+First, we create a new \i down state for our text element.
This state will be activated when the \l MouseArea is pressed, and deactivated when it is released.
-The \e down state includes a set of property changes from our implicit \e {default state}
+The \i down state includes a set of property changes from our implicit \i {default state}
(the items as they were initially defined in the QML).
Specifically, we set the \c y property of the text to \c 160, the rotation to \c 180 and the \c color to red.
@@ -213,9 +213,9 @@ Because we don't want the text to appear at the bottom instantly but rather move
we add a transition between our two states.
\c from and \c to define the states between which the transition will run.
-In this case, we want a transition from the default state to our \e down state.
+In this case, we want a transition from the default state to our \i down state.
-Because we want the same transition to be run in reverse when changing back from the \e down state to the default state,
+Because we want the same transition to be run in reverse when changing back from the \i down state to the default state,
we set \c reversible to \c true.
This is equivalent to writing the two transitions separately.
diff --git a/doc/src/declarative/whatsnew.qdoc b/doc/src/declarative/whatsnew.qdoc
index da001605b3..4c44166472 100644
--- a/doc/src/declarative/whatsnew.qdoc
+++ b/doc/src/declarative/whatsnew.qdoc
@@ -26,8 +26,8 @@
****************************************************************************/
/*!
-\title What's New in Qt Quick
-\page qtquick-whatsnew.html
+\title What's New in Qt Quick 2
+\page qtquick2-whatsnew.html
\section1 Qt 5.0.0 includes QtQuick 2.0
@@ -91,9 +91,10 @@ These will now be propagated to the highest-stacking-order enabled MouseArea whi
You can still ignore these events in the handler to let them pass through.
The Binding element can now be used as a value source, and will also restore any previously
-set binding when its \e when clause becomes false.
+set binding when its \i when clause becomes false.
Flickable: added dragging, draggingHorizontally and draggingVerically properties.
+Added topMargin, bottomMargin, leftMargin, rightMargin, xOrigin, yOrigin properties.
Image has two new properties: horizontalAlignment and verticalAlignment. It also has a new value for
fillMode (Image.Pad) that does not transform the image.
@@ -109,14 +110,23 @@ Loader improvements:
- now only emits the \c sourceChanged signal when the source is changed and the
\c sourceComponentChanged signal when the sourceComponent is changed. It used to emit both signals when one of the properties was changed.
+Text improvements:
+ - a \c onLineLaidOut handler is called for every line during the layout process. This gives the opportunity to position and resize a line as it is being laid out.
+ - a \c doLayout method was added to trigger the layout from Javascript.
+ - now automatically switch to StyledText instead of RichText if textFormat is set to AutoText.
+
PathView now has a \c currentItem property
-ListView and GridView now have headerItem and footerItem properties (the instantiated
-header and footer items).
+ListView and GridView:
+ - now have headerItem and footerItem properties (the instantiated header and footer items).
+ - In RightToLeft layout the preferredHighlightBegin/End are now also reversed.
ListView section.labelPositioning property added to allow keeping the current section label
at the start and/or next section label at the end of the view.
+A new property type ("var") has been introduced which obsoletes "variant" properties in QML.
+Properties of this type are equivalent to regular JavaScript variables. See the documentation
+on \l{QML Basic Types} for more information about "var" properties.
\section2 QtQuick 1 is now a separate library and module
@@ -130,173 +140,6 @@ QDeclarativeView and QDeclarativeItem headers are now in the QtQuick 1 module, i
"import QtQuick 1.0" loads the module dynamically. To deploy QtQuick 1 applications
the library (lib/libQtQuick1*) and plugin (imports/QtQuick/) must be installed.
+\sa {What's New in Qt Quick 1}{What's New in Qt Quick 1}
-\section1 Qt 4.7.4 includes QtQuick 1.1
-
-QtQuick 1.1 is a minor feature update. \e {import QtQuick 1.1} to use the new
-features.
-
-\section2 PinchArea
-
-PinchArea provides support for the common two finger pinch gesture.
-
-\section2 LayoutMirroring attached property
-
-\l {LayoutMirroring}{Layout mirroring} is useful when you need to support both
-left-to-right and right-to-left layout versions of your application that target
-different language areas.
-
-\section2 Anchors
-
-Added the following property:
-\list
-\o \l {Item::}{anchors.mirrored}
-\endlist
-
-\section2 Text
-
-Added the following properties:
-\list
-\o \l {Text::}{lineHeight}
-\o \l {Text::}{lineHeightMode}
-\o \l {Text::}{lineCount}
-\o \l {Text::}{maximumLineCount}
-\o \l {Text::}{truncated}
-\o \l {Text::}{effectiveHorizontalAlignment}
-\endlist
-
-horizontalAlignment now accepts Text.AlignJustify alignment mode.
-
-\section2 TextEdit
-
-Added the following properties, methods and signal handlers:
-\list
-\o \l {TextEdit::}{canPaste}
-\o \l {TextEdit::}{lineCount}
-\o \l {TextEdit::}{inputMethodComposing}
-\o \l {TextEdit::}{mouseSelectionMode}
-\o \l {TextEdit::}{effectiveHorizontalAlignment}
-\o \l {TextEdit::}{deselect()}
-\o \l {TextEdit::}{isRightToLeft()}
-\o \l {TextEdit::}{moveCursorSelection()} to enable selection by word
-\o \l {TextEdit::}{onLinkActivated}
-\endlist
-
-\section2 TextInput
-
-Added the following properties and methods:
-\list
-\o \l {TextInput::}{canPaste}
-\o \l {TextInput::}{inputMethodComposing}
-\o \l {TextInput::}{mouseSelectionMode}
-\o \l {TextInput::}{effectiveHorizontalAlignment}
-\o \l {TextInput::}{deselect()}
-\o \l {TextInput::}{isRightToLeft()}
-\o \l {TextInput::}{moveCursorSelection()} to enable selection by word
-\endlist
-
-\section2 Image, BorderImage and AnimatedImage
-
-Added the following properties:
-\list
-\o \l{Image::}{cache}
-\o \l{Image::}{mirror}
-\endlist
-
-\section2 Item
-
-Added the following properties:
-\list
-\o \l{Item::}{implicitWidth} and \l{Item::}{implicitHeight}
-\endlist
-
-\section2 Flickable
-
-Added the following methods:
-\list
-\o \l{Flickable::}{resizeContent()}
-\o \l{Flickable::}{returnToBounds()}
-\endlist
-
-\section2 MouseArea
-
-Added the following property:
-\list
-\o \l{MouseArea::}{preventStealing}
-\endlist
-
-\section2 ListView and GridView
-
-Added the following properties and methods:
-\list
-\o \l{ListView::}{layoutDirection}
-\o \l{ListView::}{effectiveLayoutDirection}
-\o \l{ListView::}{positionViewAtBeginning()}
-\o \l{ListView::}{positionViewAtEnd()}
-\endlist
-
-\section2 Flow, Grid and Row
-
-Added the following properties:
-\list
-\o \l{Flow::}{layoutDirection}
-\o \l{Flow::}{effectiveLayoutDirection}
-\endlist
-
-\section2 Repeater
-
-Added the following methods and signal handlers:
-\list
-\o \l{Repeater::}{onItemAdded}
-\o \l{Repeater::}{onItemRemoved}
-\o \l{Repeater::}{itemAt()}
-\endlist
-
-\section2 Component
-
-\list
-\o The \l{Component::}{createObject()} method now accepts a map of initial
-property values for the created object.
-\endlist
-
-\section2 Qt
-
-\list
-\o Added the \l {QML:Qt::application}{Qt.application} object to hold generic
-global application properties.
-\endlist
-
-\section2 Other changes
-
-\list
-\o Functions can be \l{Property Binding#Property Binding}{assigned to properties from JavaScript}
-to create property bindings.
-\o QtQuick now supports Right to Left layout in positioners, views, anchors and text elements.
-\endlist
-
-
-\section1 Qt 4.7.1
-
-\section2 QtQuick namespace
-
-In prior Qt releases, all the Qt Quick elements were available in the \e Qt
-namespace. Starting with Qt 4.7.1, the elements are also available in the
-\e QtQuick namespace, which improves naming consistency, and allows the
-development of Qt Quick to occur at a faster rate than Qt's usual minor release
-schedule.
-
-The change for developers is very simple - where you previously wrote
-\e {import Qt 4.7}, just replace it with \e {import QtQuick 1.0}, like this:
-
-\code
-import QtQuick 1.0
-
-Text {
- text: "Welcome to QtQuick 1.0!"
-}
-\endcode
-
-\e {import Qt 4.7} continues to work so existing applications won't break even
-if they aren't updated, but it is recommended that all import statements be
-modified to the new form.
*/
diff --git a/doc/src/declarative/pics/3d-axis.png b/doc/src/images/3d-axis.png
index 1a587ffd28..1a587ffd28 100644
--- a/doc/src/declarative/pics/3d-axis.png
+++ b/doc/src/images/3d-axis.png
Binary files differ
diff --git a/doc/src/declarative/pics/3d-rotation-axis.png b/doc/src/images/3d-rotation-axis.png
index b9402156f0..b9402156f0 100644
--- a/doc/src/declarative/pics/3d-rotation-axis.png
+++ b/doc/src/images/3d-rotation-axis.png
Binary files differ
diff --git a/doc/src/declarative/pics/BorderImage.png b/doc/src/images/BorderImage.png
index 651dd8aa76..651dd8aa76 100644
--- a/doc/src/declarative/pics/BorderImage.png
+++ b/doc/src/images/BorderImage.png
Binary files differ
diff --git a/doc/src/declarative/pics/ListViewHighlight.png b/doc/src/images/ListViewHighlight.png
index 02bf51dabf..02bf51dabf 100644
--- a/doc/src/declarative/pics/ListViewHighlight.png
+++ b/doc/src/images/ListViewHighlight.png
Binary files differ
diff --git a/doc/src/declarative/pics/ListViewHorizontal.png b/doc/src/images/ListViewHorizontal.png
index 4633a0e151..4633a0e151 100644
--- a/doc/src/declarative/pics/ListViewHorizontal.png
+++ b/doc/src/images/ListViewHorizontal.png
Binary files differ
diff --git a/doc/src/declarative/pics/ListViewVertical.png b/doc/src/images/ListViewVertical.png
index e0b23d95e1..e0b23d95e1 100644
--- a/doc/src/declarative/pics/ListViewVertical.png
+++ b/doc/src/images/ListViewVertical.png
Binary files differ
diff --git a/doc/src/declarative/pics/anatomy-component.png b/doc/src/images/anatomy-component.png
index 6125b0091c..6125b0091c 100644
--- a/doc/src/declarative/pics/anatomy-component.png
+++ b/doc/src/images/anatomy-component.png
Binary files differ
diff --git a/doc/src/declarative/pics/anchorchanges.png b/doc/src/images/anchorchanges.png
index 4973e4e9aa..4973e4e9aa 100644
--- a/doc/src/declarative/pics/anchorchanges.png
+++ b/doc/src/images/anchorchanges.png
Binary files differ
diff --git a/doc/src/declarative/pics/anchors.svg b/doc/src/images/anchors.svg
index 08b00ed6e3..08b00ed6e3 100644
--- a/doc/src/declarative/pics/anchors.svg
+++ b/doc/src/images/anchors.svg
diff --git a/doc/src/declarative/pics/animatedimageitem.gif b/doc/src/images/animatedimageitem.gif
index 85c3cb5609..85c3cb5609 100644
--- a/doc/src/declarative/pics/animatedimageitem.gif
+++ b/doc/src/images/animatedimageitem.gif
Binary files differ
diff --git a/doc/src/declarative/pics/axisrotation.png b/doc/src/images/axisrotation.png
index 4cddcdfcaf..4cddcdfcaf 100644
--- a/doc/src/declarative/pics/axisrotation.png
+++ b/doc/src/images/axisrotation.png
Binary files differ
diff --git a/doc/src/declarative/pics/blur_example.png b/doc/src/images/blur_example.png
index 763b11224a..763b11224a 100644
--- a/doc/src/declarative/pics/blur_example.png
+++ b/doc/src/images/blur_example.png
Binary files differ
diff --git a/doc/src/declarative/pics/content.png b/doc/src/images/content.png
index 47a98ac9a5..47a98ac9a5 100644
--- a/doc/src/declarative/pics/content.png
+++ b/doc/src/images/content.png
Binary files differ
diff --git a/doc/src/declarative/pics/declarative-adv-tutorial1.png b/doc/src/images/declarative-adv-tutorial1.png
index 1699ab0e4d..1699ab0e4d 100644
--- a/doc/src/declarative/pics/declarative-adv-tutorial1.png
+++ b/doc/src/images/declarative-adv-tutorial1.png
Binary files differ
diff --git a/doc/src/declarative/pics/declarative-adv-tutorial2.png b/doc/src/images/declarative-adv-tutorial2.png
index ba27c442ce..ba27c442ce 100644
--- a/doc/src/declarative/pics/declarative-adv-tutorial2.png
+++ b/doc/src/images/declarative-adv-tutorial2.png
Binary files differ
diff --git a/doc/src/declarative/pics/declarative-adv-tutorial3.png b/doc/src/images/declarative-adv-tutorial3.png
index d500434d14..d500434d14 100644
--- a/doc/src/declarative/pics/declarative-adv-tutorial3.png
+++ b/doc/src/images/declarative-adv-tutorial3.png
Binary files differ
diff --git a/doc/src/declarative/pics/declarative-adv-tutorial4.gif b/doc/src/images/declarative-adv-tutorial4.gif
index 827458daa5..827458daa5 100644
--- a/doc/src/declarative/pics/declarative-adv-tutorial4.gif
+++ b/doc/src/images/declarative-adv-tutorial4.gif
Binary files differ
diff --git a/doc/src/declarative/pics/dial-example.gif b/doc/src/images/dial-example.gif
index 4e90ba91c4..4e90ba91c4 100644
--- a/doc/src/declarative/pics/dial-example.gif
+++ b/doc/src/images/dial-example.gif
Binary files differ
diff --git a/doc/src/declarative/pics/edge1.png b/doc/src/images/edge1.png
index f4bc16d01f..f4bc16d01f 100644
--- a/doc/src/declarative/pics/edge1.png
+++ b/doc/src/images/edge1.png
Binary files differ
diff --git a/doc/src/declarative/pics/edge2.png b/doc/src/images/edge2.png
index 71bda8eb0b..71bda8eb0b 100644
--- a/doc/src/declarative/pics/edge2.png
+++ b/doc/src/images/edge2.png
Binary files differ
diff --git a/doc/src/declarative/pics/edge3.png b/doc/src/images/edge3.png
index 51bb894c3e..51bb894c3e 100644
--- a/doc/src/declarative/pics/edge3.png
+++ b/doc/src/images/edge3.png
Binary files differ
diff --git a/doc/src/declarative/pics/edge4.png b/doc/src/images/edge4.png
index aee3bd109f..aee3bd109f 100644
--- a/doc/src/declarative/pics/edge4.png
+++ b/doc/src/images/edge4.png
Binary files differ
diff --git a/doc/src/declarative/pics/edges.png b/doc/src/images/edges.png
index 211b1019a4..211b1019a4 100644
--- a/doc/src/declarative/pics/edges.png
+++ b/doc/src/images/edges.png
Binary files differ
diff --git a/doc/src/declarative/pics/edges.svg b/doc/src/images/edges.svg
index 25698ca40f..25698ca40f 100644
--- a/doc/src/declarative/pics/edges.svg
+++ b/doc/src/images/edges.svg
diff --git a/doc/src/declarative/pics/edges_examples.svg b/doc/src/images/edges_examples.svg
index 31e9901f07..31e9901f07 100644
--- a/doc/src/declarative/pics/edges_examples.svg
+++ b/doc/src/images/edges_examples.svg
diff --git a/doc/src/declarative/pics/edges_qml.png b/doc/src/images/edges_qml.png
index 73f22f92b3..73f22f92b3 100644
--- a/doc/src/declarative/pics/edges_qml.png
+++ b/doc/src/images/edges_qml.png
Binary files differ
diff --git a/doc/src/declarative/pics/edges_qml.svg b/doc/src/images/edges_qml.svg
index 1814ec6b20..1814ec6b20 100644
--- a/doc/src/declarative/pics/edges_qml.svg
+++ b/doc/src/images/edges_qml.svg
diff --git a/doc/src/declarative/pics/extending-tutorial-chapter1.png b/doc/src/images/extending-tutorial-chapter1.png
index 9f5836b09c..9f5836b09c 100644
--- a/doc/src/declarative/pics/extending-tutorial-chapter1.png
+++ b/doc/src/images/extending-tutorial-chapter1.png
Binary files differ
diff --git a/doc/src/declarative/pics/extending-tutorial-chapter2.png b/doc/src/images/extending-tutorial-chapter2.png
index 5c8f222aad..5c8f222aad 100644
--- a/doc/src/declarative/pics/extending-tutorial-chapter2.png
+++ b/doc/src/images/extending-tutorial-chapter2.png
Binary files differ
diff --git a/doc/src/declarative/pics/extending-tutorial-chapter3.png b/doc/src/images/extending-tutorial-chapter3.png
index 825553fc5f..825553fc5f 100644
--- a/doc/src/declarative/pics/extending-tutorial-chapter3.png
+++ b/doc/src/images/extending-tutorial-chapter3.png
Binary files differ
diff --git a/doc/src/declarative/pics/extending-tutorial-chapter5.png b/doc/src/images/extending-tutorial-chapter5.png
index 0c2e69e1b4..0c2e69e1b4 100644
--- a/doc/src/declarative/pics/extending-tutorial-chapter5.png
+++ b/doc/src/images/extending-tutorial-chapter5.png
Binary files differ
diff --git a/doc/src/declarative/pics/flickable.gif b/doc/src/images/flickable.gif
index f7a3319496..f7a3319496 100644
--- a/doc/src/declarative/pics/flickable.gif
+++ b/doc/src/images/flickable.gif
Binary files differ
diff --git a/doc/src/declarative/pics/flipable.gif b/doc/src/images/flipable.gif
index 6af46c3e10..6af46c3e10 100644
--- a/doc/src/declarative/pics/flipable.gif
+++ b/doc/src/images/flipable.gif
Binary files differ
diff --git a/doc/src/declarative/pics/gridLayout_example.png b/doc/src/images/gridLayout_example.png
index 6b120e9639..6b120e9639 100644
--- a/doc/src/declarative/pics/gridLayout_example.png
+++ b/doc/src/images/gridLayout_example.png
Binary files differ
diff --git a/doc/src/declarative/pics/gridview-highlight.png b/doc/src/images/gridview-highlight.png
index b54af37f93..b54af37f93 100644
--- a/doc/src/declarative/pics/gridview-highlight.png
+++ b/doc/src/images/gridview-highlight.png
Binary files differ
diff --git a/doc/src/declarative/pics/gridview-simple.png b/doc/src/images/gridview-simple.png
index a102939f2b..a102939f2b 100644
--- a/doc/src/declarative/pics/gridview-simple.png
+++ b/doc/src/images/gridview-simple.png
Binary files differ
diff --git a/doc/src/declarative/pics/highlight.gif b/doc/src/images/highlight.gif
index fbef256f54..fbef256f54 100644
--- a/doc/src/declarative/pics/highlight.gif
+++ b/doc/src/images/highlight.gif
Binary files differ
diff --git a/doc/src/declarative/pics/horizontalpositioner_example.png b/doc/src/images/horizontalpositioner_example.png
index 42f90ec7ae..42f90ec7ae 100644
--- a/doc/src/declarative/pics/horizontalpositioner_example.png
+++ b/doc/src/images/horizontalpositioner_example.png
Binary files differ
diff --git a/doc/src/declarative/pics/imageprovider.png b/doc/src/images/imageprovider.png
index 422103cb07..422103cb07 100644
--- a/doc/src/declarative/pics/imageprovider.png
+++ b/doc/src/images/imageprovider.png
Binary files differ
diff --git a/doc/src/declarative/pics/layoutmirroring.png b/doc/src/images/layoutmirroring.png
index df90ac4f9a..df90ac4f9a 100644
--- a/doc/src/declarative/pics/layoutmirroring.png
+++ b/doc/src/images/layoutmirroring.png
Binary files differ
diff --git a/doc/src/declarative/pics/listmodel-nested.png b/doc/src/images/listmodel-nested.png
index ee7ffba67a..ee7ffba67a 100644
--- a/doc/src/declarative/pics/listmodel-nested.png
+++ b/doc/src/images/listmodel-nested.png
Binary files differ
diff --git a/doc/src/declarative/pics/listmodel.png b/doc/src/images/listmodel.png
index 7ab1771f15..7ab1771f15 100644
--- a/doc/src/declarative/pics/listmodel.png
+++ b/doc/src/images/listmodel.png
Binary files differ
diff --git a/doc/src/declarative/pics/listview-highlight.png b/doc/src/images/listview-highlight.png
index dc5c6b3b57..dc5c6b3b57 100644
--- a/doc/src/declarative/pics/listview-highlight.png
+++ b/doc/src/images/listview-highlight.png
Binary files differ
diff --git a/doc/src/declarative/pics/listview-simple.png b/doc/src/images/listview-simple.png
index 71a1c5172f..71a1c5172f 100644
--- a/doc/src/declarative/pics/listview-simple.png
+++ b/doc/src/images/listview-simple.png
Binary files differ
diff --git a/doc/src/declarative/pics/margins_qml.png b/doc/src/images/margins_qml.png
index d7d73a3fc9..d7d73a3fc9 100644
--- a/doc/src/declarative/pics/margins_qml.png
+++ b/doc/src/images/margins_qml.png
Binary files differ
diff --git a/doc/src/declarative/pics/margins_qml.svg b/doc/src/images/margins_qml.svg
index 1f0ff022bb..1f0ff022bb 100644
--- a/doc/src/declarative/pics/margins_qml.svg
+++ b/doc/src/images/margins_qml.svg
diff --git a/doc/src/declarative/pics/parentchange.png b/doc/src/images/parentchange.png
index 93206fbbb2..93206fbbb2 100644
--- a/doc/src/declarative/pics/parentchange.png
+++ b/doc/src/images/parentchange.png
Binary files differ
diff --git a/doc/src/declarative/pics/particles.gif b/doc/src/images/particles.gif
index 763a8a8616..763a8a8616 100644
--- a/doc/src/declarative/pics/particles.gif
+++ b/doc/src/images/particles.gif
Binary files differ
diff --git a/doc/src/declarative/pics/pathview.gif b/doc/src/images/pathview.gif
index 4052eb264b..4052eb264b 100644
--- a/doc/src/declarative/pics/pathview.gif
+++ b/doc/src/images/pathview.gif
Binary files differ
diff --git a/doc/src/declarative/pics/positioner-add.gif b/doc/src/images/positioner-add.gif
index 86e9247073..86e9247073 100644
--- a/doc/src/declarative/pics/positioner-add.gif
+++ b/doc/src/images/positioner-add.gif
Binary files differ
diff --git a/doc/src/declarative/pics/positioner-move.gif b/doc/src/images/positioner-move.gif
index 1825c2282b..1825c2282b 100644
--- a/doc/src/declarative/pics/positioner-move.gif
+++ b/doc/src/images/positioner-move.gif
Binary files differ
diff --git a/doc/src/declarative/pics/positioner-remove.gif b/doc/src/images/positioner-remove.gif
index 708651190c..708651190c 100644
--- a/doc/src/declarative/pics/positioner-remove.gif
+++ b/doc/src/images/positioner-remove.gif
Binary files differ
diff --git a/doc/src/declarative/pics/propanim.gif b/doc/src/images/propanim.gif
index f86406ee7f..f86406ee7f 100644
--- a/doc/src/declarative/pics/propanim.gif
+++ b/doc/src/images/propanim.gif
Binary files differ
diff --git a/doc/src/declarative/pics/qml-context-object.png b/doc/src/images/qml-context-object.png
index 1b91aff651..1b91aff651 100644
--- a/doc/src/declarative/pics/qml-context-object.png
+++ b/doc/src/images/qml-context-object.png
Binary files differ
diff --git a/doc/src/declarative/pics/qml-context-tree.png b/doc/src/images/qml-context-tree.png
index 6bba5f4f05..6bba5f4f05 100644
--- a/doc/src/declarative/pics/qml-context-tree.png
+++ b/doc/src/images/qml-context-tree.png
Binary files differ
diff --git a/doc/src/declarative/pics/qml-context.png b/doc/src/images/qml-context.png
index bdf2ecd2c6..bdf2ecd2c6 100644
--- a/doc/src/declarative/pics/qml-context.png
+++ b/doc/src/images/qml-context.png
Binary files differ
diff --git a/doc/src/declarative/pics/qml-extending-types.png b/doc/src/images/qml-extending-types.png
index 6990d7c190..6990d7c190 100644
--- a/doc/src/declarative/pics/qml-extending-types.png
+++ b/doc/src/images/qml-extending-types.png
Binary files differ
diff --git a/doc/src/declarative/pics/qml-gradient.png b/doc/src/images/qml-gradient.png
index 5eefdd2031..5eefdd2031 100644
--- a/doc/src/declarative/pics/qml-gradient.png
+++ b/doc/src/images/qml-gradient.png
Binary files differ
diff --git a/doc/src/declarative/pics/qml-scope.png b/doc/src/images/qml-scope.png
index be025c8c3d..be025c8c3d 100644
--- a/doc/src/declarative/pics/qml-scope.png
+++ b/doc/src/images/qml-scope.png
Binary files differ
diff --git a/doc/src/declarative/pics/qtlogo.png b/doc/src/images/qtlogo.png
index 399bd0b1d9..399bd0b1d9 100644
--- a/doc/src/declarative/pics/qtlogo.png
+++ b/doc/src/images/qtlogo.png
Binary files differ
diff --git a/doc/src/declarative/pics/rect-border-width.png b/doc/src/images/rect-border-width.png
index e232cf3ebd..e232cf3ebd 100644
--- a/doc/src/declarative/pics/rect-border-width.png
+++ b/doc/src/images/rect-border-width.png
Binary files differ
diff --git a/doc/src/declarative/pics/rect-color.png b/doc/src/images/rect-color.png
index b258ba9b6c..b258ba9b6c 100644
--- a/doc/src/declarative/pics/rect-color.png
+++ b/doc/src/images/rect-color.png
Binary files differ
diff --git a/doc/src/declarative/pics/rect-smooth.png b/doc/src/images/rect-smooth.png
index 7ffd8aba33..7ffd8aba33 100644
--- a/doc/src/declarative/pics/rect-smooth.png
+++ b/doc/src/images/rect-smooth.png
Binary files differ
diff --git a/doc/src/declarative/pics/reflection_example.png b/doc/src/images/reflection_example.png
index fd9bb48022..fd9bb48022 100644
--- a/doc/src/declarative/pics/reflection_example.png
+++ b/doc/src/images/reflection_example.png
Binary files differ
diff --git a/doc/src/declarative/pics/repeater-index.png b/doc/src/images/repeater-index.png
index 3dbe6d0571..3dbe6d0571 100644
--- a/doc/src/declarative/pics/repeater-index.png
+++ b/doc/src/images/repeater-index.png
Binary files differ
diff --git a/doc/src/declarative/pics/repeater-modeldata.png b/doc/src/images/repeater-modeldata.png
index 6d8df0d9d5..6d8df0d9d5 100644
--- a/doc/src/declarative/pics/repeater-modeldata.png
+++ b/doc/src/images/repeater-modeldata.png
Binary files differ
diff --git a/doc/src/declarative/pics/repeater-simple.png b/doc/src/images/repeater-simple.png
index 6da62951dc..6da62951dc 100644
--- a/doc/src/declarative/pics/repeater-simple.png
+++ b/doc/src/images/repeater-simple.png
Binary files differ
diff --git a/doc/src/declarative/pics/repeater.png b/doc/src/images/repeater.png
index 973df27a74..973df27a74 100644
--- a/doc/src/declarative/pics/repeater.png
+++ b/doc/src/images/repeater.png
Binary files differ
diff --git a/doc/src/declarative/pics/scalegrid.svg b/doc/src/images/scalegrid.svg
index e386f3d7bb..e386f3d7bb 100644
--- a/doc/src/declarative/pics/scalegrid.svg
+++ b/doc/src/images/scalegrid.svg
diff --git a/doc/src/declarative/pics/shadow_example.png b/doc/src/images/shadow_example.png
index 6214620f0c..6214620f0c 100644
--- a/doc/src/declarative/pics/shadow_example.png
+++ b/doc/src/images/shadow_example.png
Binary files differ
diff --git a/doc/src/declarative/pics/squish-transform.png b/doc/src/images/squish-transform.png
index 0eb848edc2..0eb848edc2 100644
--- a/doc/src/declarative/pics/squish-transform.png
+++ b/doc/src/images/squish-transform.png
Binary files differ
diff --git a/doc/src/declarative/pics/squish.png b/doc/src/images/squish.png
index 73bf2920de..73bf2920de 100644
--- a/doc/src/declarative/pics/squish.png
+++ b/doc/src/images/squish.png
Binary files differ
diff --git a/doc/src/declarative/pics/switch-example.gif b/doc/src/images/switch-example.gif
index 3d6582fecc..3d6582fecc 100644
--- a/doc/src/declarative/pics/switch-example.gif
+++ b/doc/src/images/switch-example.gif
Binary files differ
diff --git a/doc/src/declarative/pics/translate.png b/doc/src/images/translate.png
index baf58b0eb6..baf58b0eb6 100644
--- a/doc/src/declarative/pics/translate.png
+++ b/doc/src/images/translate.png
Binary files differ
diff --git a/doc/src/declarative/pics/verticalpositioner_example.png b/doc/src/images/verticalpositioner_example.png
index 458dc7f481..458dc7f481 100644
--- a/doc/src/declarative/pics/verticalpositioner_example.png
+++ b/doc/src/images/verticalpositioner_example.png
Binary files differ
diff --git a/doc/src/declarative/pics/verticalpositioner_transition.gif b/doc/src/images/verticalpositioner_transition.gif
index ed61adb5ab..ed61adb5ab 100644
--- a/doc/src/declarative/pics/verticalpositioner_transition.gif
+++ b/doc/src/images/verticalpositioner_transition.gif
Binary files differ
diff --git a/doc/src/declarative/pics/visualitemmodel.png b/doc/src/images/visualitemmodel.png
index 5e6d1325b2..5e6d1325b2 100644
--- a/doc/src/declarative/pics/visualitemmodel.png
+++ b/doc/src/images/visualitemmodel.png
Binary files differ
diff --git a/doc/src/declarative/pics/webview.png b/doc/src/images/webview.png
index 0d24586587..0d24586587 100644
--- a/doc/src/declarative/pics/webview.png
+++ b/doc/src/images/webview.png
Binary files differ
diff --git a/doc/src/qtquick1/declarativeui.qdoc b/doc/src/qtquick1/declarativeui.qdoc
index d89ca53dbb..6769fb0ead 100644
--- a/doc/src/qtquick1/declarativeui.qdoc
+++ b/doc/src/qtquick1/declarativeui.qdoc
@@ -27,7 +27,7 @@
/*!
\title Qt Quick
-\page qtquick.html
+\page qtquick1.html
\ingroup qt-gui-concepts
\brief Qt Quick provides a declarative framework for building highly
@@ -50,7 +50,7 @@ Qt applications.
\o \l{QML for Qt Programmers}{QML Programming for Qt Programmers}
\o \l{Getting Started Programming with QML}
-\o \l{What's new in Qt Quick}{What's New in the Qt Quick Release}
+\o \l{What's new in Qt Quick 1}{What's New in the Qt Quick Release}
\o \l{QML Examples and Demos}
\endlist
@@ -140,7 +140,7 @@ examples for porting}
\list
\o \l{QML Best Practices: Coding Conventions}{Coding Tips}
-\o \l{QML Performance}{Performance Tips}
+\o \l{QML Performance - Qt Quick 1}{Performance Tips}
\endlist
\section1 License Information
diff --git a/doc/src/qtquick1/qdeclarativeperformance.qdoc b/doc/src/qtquick1/qdeclarativeperformance.qdoc
index 03643e72a6..ba2402c154 100644
--- a/doc/src/qtquick1/qdeclarativeperformance.qdoc
+++ b/doc/src/qtquick1/qdeclarativeperformance.qdoc
@@ -27,7 +27,7 @@
/*!
\page qdeclarativeperformance.html
-\title QML Performance
+\title QML Performance - Qt Quick 1
\section1 Opaque Items
diff --git a/doc/src/qtquick1/whatsnew.qdoc b/doc/src/qtquick1/whatsnew.qdoc
index d3db1346ea..9cf31d5dcf 100644
--- a/doc/src/qtquick1/whatsnew.qdoc
+++ b/doc/src/qtquick1/whatsnew.qdoc
@@ -26,51 +26,8 @@
****************************************************************************/
/*!
-\title What's New in Qt Quick
-\page qtquick-whatsnew.html
-
-\section1 Qt 5.0.0 includes QtQuick 2.0
-
-QtQuick 2.0 is a major update.
-
-MouseArea now propagates clicked, doubleClicked and pressAndHold differently to pressed.
-These will now be propagated to the highest-stacking-order enabled MouseArea which has a handler for them.
-You can still ignore these events in the handler to let them pass through.
-
-The Binding element can now be used as a value source, and will also restore any previously
-set binding when its \e when clause becomes false.
-
-QDeclarativeExpression can now be directly (and more efficiently) constructed from a
-QDeclarativeScriptString.
-
-Flickable: added dragging, draggingHorizontally and draggingVerically properties.
-
-Image has two new properties: horizontalAlignment and verticalAlignment. It also has a new value for
-fillMode (Image.Pad) that does not transform the image.
-
-The Loader element now only emits the \c sourceChanged signal when the source is changed and the
-\c sourceComponentChanged signal when the sourceComponent is changed. It used to emit both signals when one
-of the properties was changed.
-
-\section2 QtQuick 1 is now a separate library and module
-
-Writing C++ applications using QtQuick 1 specific API, i.e. QDeclarativeView or QDeclarativeItem
-requires adding the "qtquick1" module to the .pro file, e.g. QT += declarative qtquick1
-
-QDeclarativeView and QDeclarativeItem headers are now in the QtQuick 1 module, i.e.
-#include <QtQuick1/QDeclarativeView>
-#include <QtQuick1/QDeclarativeItem>
-
-"import QtQuick 1.0" loads the module dynamically. To deploy QtQuick 1 applications
-the library (lib/libQtQuick1*) and plugin (imports/QtQuick/) must be installed.
-
-
-\section2 PathView
-
-Added the following properties:
-\list
-\o \l {PathView::}{currentItem}
-\endlist
+\title What's New in Qt Quick 1
+\page qtquick1-whatsnew.html
\section1 Qt 4.7.4 includes QtQuick 1.1
diff --git a/doc/src/snippets/declarative/drag.qml b/doc/src/snippets/declarative/drag.qml
new file mode 100644
index 0000000000..d863fdf510
--- /dev/null
+++ b/doc/src/snippets/declarative/drag.qml
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//![0]
+import QtQuick 2.0
+
+Item {
+ width: 200; height: 200
+
+ DropArea {
+ x: 75; y: 75
+ width: 50; height: 50
+
+ Rectangle {
+ anchors.fill: parent
+ color: "green"
+
+ visible: parent.containsDrag
+ }
+ }
+
+ Rectangle {
+ x: 10; y: 10
+ width: 20; height: 20
+ color: "red"
+
+ Drag.active: dragArea.drag.active
+ Drag.hotSpot.x: 10
+ Drag.hotSpot.y: 10
+
+ MouseArea {
+ id: dragArea
+ anchors.fill: parent
+
+ drag.target: parent
+ }
+ }
+}
+//![0]
diff --git a/examples/declarative/inputmethods/spellcheck/Key.qml b/doc/src/snippets/declarative/visualdatagroup.qml
index c95a3f0b2c..feb41e27cb 100644
--- a/examples/declarative/inputmethods/spellcheck/Key.qml
+++ b/doc/src/snippets/declarative/visualdatagroup.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the examples of the Qt Toolkit.
+** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
@@ -37,49 +37,45 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
+//![0]
import QtQuick 2.0
Rectangle {
- property string text
- property string displayText
- property alias font: keyText.font
- property int key: 0
-
- id: root
- radius: 2
-
- width: 28
- height: 28
-
- gradient: Gradient {
- GradientStop { position: 0.0; color: "darkgrey" }
- GradientStop { position: 1.0; color: "grey" }
- }
+ width: 200; height: 100
- Text {
- id: keyText
+ VisualDataModel {
+ id: visualModel
+ model: ListModel {
+ ListElement { name: "Apple" }
+ ListElement { name: "Orange" }
+ }
- anchors.fill: parent
-
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
-
- font.pixelSize: 18
- font.capitalization: keyboard.shift && displayText == "" ? Font.AllUppercase : Font.MixedCase
+ groups: [
+ VisualDataGroup { name: "selected" }
+ ]
- text: root.displayText != "" ? root.displayText : root.text
-
- style: !mouseArea.pressed ? Text.Raised : Text.Normal
- color: "white"
- styleColor: "grey"
+ delegate: Rectangle {
+ id: item
+ height: 25
+ width: 200
+ Text {
+ text: {
+ var text = "Name: " + name
+ if (item.VisualDataModel.inSelected)
+ text += " (" + item.VisualDataModel.selectedIndex + ")"
+ return text;
+ }
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: item.VisualDataModel.inSelected = !item.VisualDataModel.inSelected
+ }
+ }
}
- MouseArea {
- id: mouseArea
-
+ ListView {
anchors.fill: parent
- onPressed: keyboard.keyPress(key, text)
- onReleased: keyboard.keyRelease(key, text)
+ model: visualModel
}
}
+//![0]
diff --git a/examples/declarative/canvas/bezierCurve/bezierCurve.qml b/examples/declarative/canvas/bezierCurve/bezierCurve.qml
index 4d30c4dbd1..cfd3e1f76f 100644
--- a/examples/declarative/canvas/bezierCurve/bezierCurve.qml
+++ b/examples/declarative/canvas/bezierCurve/bezierCurve.qml
@@ -120,4 +120,4 @@ Item {
}
}
}
-}
+} \ No newline at end of file
diff --git a/examples/declarative/canvas/quadraticCurveTo/quadraticCurveTo.qml b/examples/declarative/canvas/quadraticCurveTo/quadraticCurveTo.qml
index 00d9e9d2dc..7bd954648a 100644
--- a/examples/declarative/canvas/quadraticCurveTo/quadraticCurveTo.qml
+++ b/examples/declarative/canvas/quadraticCurveTo/quadraticCurveTo.qml
@@ -124,4 +124,4 @@ Item {
}
}
}
-}
+} \ No newline at end of file
diff --git a/examples/declarative/canvas/roundedrect/roundedrect.qml b/examples/declarative/canvas/roundedrect/roundedrect.qml
index 50c07eac42..c657e315e5 100644
--- a/examples/declarative/canvas/roundedrect/roundedrect.qml
+++ b/examples/declarative/canvas/roundedrect/roundedrect.qml
@@ -121,4 +121,4 @@ Item {
}
}
}
-}
+} \ No newline at end of file
diff --git a/examples/declarative/canvas/smile/smile.qml b/examples/declarative/canvas/smile/smile.qml
index 3a7fbe7cac..7db84a1d5e 100644
--- a/examples/declarative/canvas/smile/smile.qml
+++ b/examples/declarative/canvas/smile/smile.qml
@@ -124,4 +124,4 @@ Item {
}
}
}
-}
+} \ No newline at end of file
diff --git a/examples/declarative/canvas/squircle/squircle.qml b/examples/declarative/canvas/squircle/squircle.qml
index f9845e849e..9f69dcffd7 100644
--- a/examples/declarative/canvas/squircle/squircle.qml
+++ b/examples/declarative/canvas/squircle/squircle.qml
@@ -151,4 +151,4 @@ Item {
}
}
}
-}
+} \ No newline at end of file
diff --git a/examples/declarative/canvas/tiger/tiger.qml b/examples/declarative/canvas/tiger/tiger.qml
index 5ec920436c..0c53a2bd39 100644
--- a/examples/declarative/canvas/tiger/tiger.qml
+++ b/examples/declarative/canvas/tiger/tiger.qml
@@ -125,4 +125,4 @@ Item {
}
}
}
-}
+} \ No newline at end of file
diff --git a/examples/declarative/canvas/twitterfriends/TwitterUser.qml b/examples/declarative/canvas/twitterfriends/TwitterUser.qml
index 7b16581d69..8f98505a0b 100644
--- a/examples/declarative/canvas/twitterfriends/TwitterUser.qml
+++ b/examples/declarative/canvas/twitterfriends/TwitterUser.qml
@@ -291,4 +291,4 @@ Item {
x.send();
}
}
-}
+} \ No newline at end of file
diff --git a/examples/declarative/dragtarget/dragtarget.qmlproject b/examples/declarative/draganddrop/dragtarget.qmlproject
index d4909f8685..d4909f8685 100644
--- a/examples/declarative/dragtarget/dragtarget.qmlproject
+++ b/examples/declarative/draganddrop/dragtarget.qmlproject
diff --git a/examples/declarative/screenorientation/Core/Button.qml b/examples/declarative/draganddrop/tiles/DragTile.qml
index 8fefe0c0cf..d7bc920735 100644
--- a/examples/declarative/screenorientation/Core/Button.qml
+++ b/examples/declarative/draganddrop/tiles/DragTile.qml
@@ -38,34 +38,52 @@
**
****************************************************************************/
-import QtQuick 1.0
+import QtQuick 2.0
+
Item {
- id: button
- signal clicked
- property string text
- property bool toggled: false
- width: 100
- height: 60
- Rectangle {
- anchors.fill: button
- anchors.margins: mouseArea.pressed ? 3 : 2
- color: toggled ? (mouseArea.pressed ? "#442222" : "darkred") : (mouseArea.pressed ? "#333333": "black")
- radius: mouseArea.pressed ? 8 : 6
- Text {
- id: text
- anchors.centerIn: parent
- text: button.text
- font.pixelSize: mouseArea.pressed ? 12 : 14
- color: "white"
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
- }
- MouseArea {
- id: mouseArea
- anchors.fill: parent
- onClicked: {
- button.clicked()
+ id: root
+ property string colorKey
+
+ width: 100; height: 100
+
+ MouseArea {
+ id: mouseArea
+
+ width: 100; height: 100
+ anchors.centerIn: parent
+
+ drag.target: tile
+
+ onReleased: parent = tile.Drag.target !== null ? tile.Drag.target : root
+
+ Rectangle {
+ id: tile
+
+ width: 100; height: 100
+
+ anchors.horizontalCenter: parent.horizontalCenter; anchors.verticalCenter: parent.verticalCenter
+ color: colorKey
+
+ Drag.keys: [ colorKey ]
+ Drag.active: mouseArea.drag.active
+ Drag.hotSpot.x: 50
+ Drag.hotSpot.y: 50
+
+ Text {
+ anchors.fill: parent
+ color: "white"
+ font.pixelSize: 90
+ text: modelData + 1
+ horizontalAlignment:Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+
+ states: State {
+ when: mouseArea.drag.active
+ ParentChange { target: tile; parent: root }
+ AnchorChanges { target: tile; anchors.verticalCenter: undefined; anchors.horizontalCenter: undefined }
}
}
}
}
+
diff --git a/examples/declarative/dragtarget/tiles/DropTile.qml b/examples/declarative/draganddrop/tiles/DropTile.qml
index 80aa81f671..492706439a 100644
--- a/examples/declarative/dragtarget/tiles/DropTile.qml
+++ b/examples/declarative/draganddrop/tiles/DropTile.qml
@@ -40,31 +40,29 @@
import QtQuick 2.0
-Rectangle {
- id: dropRectangle
+DropArea {
+ id: dragTarget
property string colorKey
-
- color: colorKey
+ property alias dropProxy: dragTarget
width: 100; height: 100
+ keys: [ colorKey ]
- DragTarget {
- id: dragTarget
+ Rectangle {
+ id: dropRectangle
anchors.fill: parent
+ color: colorKey
- keys: [ colorKey ]
- dropItem: dropRectangle
- }
-
- states: [
- State {
- when: dragTarget.containsDrag
- PropertyChanges {
- target: dropRectangle
- color: "grey"
+ states: [
+ State {
+ when: dragTarget.containsDrag
+ PropertyChanges {
+ target: dropRectangle
+ color: "grey"
+ }
}
- }
- ]
+ ]
+ }
}
diff --git a/examples/declarative/dragtarget/tiles/tiles.qml b/examples/declarative/draganddrop/tiles/tiles.qml
index 1f783e3322..17dcd3b547 100644
--- a/examples/declarative/dragtarget/tiles/tiles.qml
+++ b/examples/declarative/draganddrop/tiles/tiles.qml
@@ -48,12 +48,6 @@ Rectangle {
color: "black"
- DragTarget {
- id: resetTarget
-
- anchors.fill: parent
- }
-
Grid {
id: redDestination
@@ -61,22 +55,16 @@ Rectangle {
anchors.margins: 5
width: 300
height: 300
-
opacity: 0.5
-
columns: 3
Repeater {
- model: 9
- delegate: DropTile {
- colorKey: "red"
- }
+ model: 9;
+ delegate: DropTile { colorKey: "red" }
}
}
Grid {
- id: blueDestination
-
anchors.right: blueSource.left; anchors.bottom: parent.bottom;
anchors.margins: 5
width: 300
@@ -88,9 +76,7 @@ Rectangle {
Repeater {
model: 9
- delegate: DropTile {
- colorKey: "blue"
- }
+ delegate: DropTile { colorKey: "blue" }
}
}
@@ -100,12 +86,11 @@ Rectangle {
anchors.left: parent.left; anchors.top: parent.top; anchors.bottom: parent.bottom
anchors.margins: 5
width: 100
+ spacing: -60
Repeater {
model: 9
- delegate: DragTile {
- colorKey: "red"
- }
+ delegate: DragTile { colorKey: "red" }
}
}
Column {
@@ -114,12 +99,11 @@ Rectangle {
anchors.right: parent.right; anchors.top: parent.top; anchors.bottom: parent.bottom
anchors.margins: 5
width: 100
+ spacing: -60
Repeater {
model: 9
- delegate: DragTile {
- colorKey: "blue"
- }
+ delegate: DragTile { colorKey: "blue" }
}
}
}
diff --git a/examples/declarative/draganddrop/views/gridview.qml b/examples/declarative/draganddrop/views/gridview.qml
new file mode 100644
index 0000000000..f16a79c9dc
--- /dev/null
+++ b/examples/declarative/draganddrop/views/gridview.qml
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+GridView {
+ id: root
+ width: 360; height: 360
+ cellWidth: 90; cellHeight: 90
+
+ model: VisualDataModel {
+ id: visualModel
+ model: ListModel {
+ id: colorModel
+ ListElement { color: "blue" }
+ ListElement { color: "green" }
+ ListElement { color: "red" }
+ ListElement { color: "yellow" }
+ ListElement { color: "orange" }
+ ListElement { color: "purple" }
+ ListElement { color: "cyan" }
+ ListElement { color: "magenta" }
+ ListElement { color: "chartreuse" }
+ ListElement { color: "aquamarine" }
+ ListElement { color: "indigo" }
+ ListElement { color: "black" }
+ ListElement { color: "chartreuse" }
+ ListElement { color: "violet" }
+ ListElement { color: "grey" }
+ ListElement { color: "springgreen" }
+ }
+
+ delegate: MouseArea {
+ id: delegateRoot
+
+ property int visualIndex: VisualDataModel.itemsIndex
+
+ width: 90; height: 90
+ drag.target: icon
+
+ Rectangle {
+ id: icon
+ width: 80; height: 80
+ anchors {
+ horizontalCenter: parent.horizontalCenter;
+ verticalCenter: parent.verticalCenter
+ }
+ color: model.color
+ radius: 3
+
+ Drag.active: delegateRoot.pressed
+ Drag.source: delegateRoot
+ Drag.hotSpot.x: 40
+ Drag.hotSpot.y: 40
+
+ states: [
+ State {
+ when: icon.Drag.active
+ ParentChange {
+ target: icon
+ parent: root
+ }
+
+ AnchorChanges {
+ target: icon;
+ anchors.horizontalCenter: undefined;
+ anchors.verticalCenter: undefined
+ }
+ }
+ ]
+ }
+
+ DropArea {
+ anchors { fill: parent; margins: 15 }
+
+ onEntered: visualModel.items.move(drag.source.visualIndex, delegateRoot.visualIndex)
+ }
+ }
+ }
+}
diff --git a/examples/declarative/dragtarget/lists/listmodel.qml b/examples/declarative/dragtarget/lists/listmodel.qml
deleted file mode 100644
index f153087e7b..0000000000
--- a/examples/declarative/dragtarget/lists/listmodel.qml
+++ /dev/null
@@ -1,296 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.0
-
-
-Rectangle {
- id: root
- color: "grey"
-
- width: 720
- height: 380
-
- Component {
- id: draggedText
- Text {
- x: rootTarget.dragX - 10
- y: rootTarget.dragY - 10
- width: 20
- height: 20
-
- text: rootTarget.dragData.display
- font.pixelSize: 18
- }
- }
-
- DragTarget {
- id: rootTarget
-
- anchors.fill: parent
- }
-
- Loader {
- anchors.fill: parent
- sourceComponent: rootTarget.containsDrag ? draggedText : undefined
- }
-
- GridView {
- id: gridView
-
- width: 240
- height: 360
-
- anchors.left: parent.left
- anchors.verticalCenter: parent.verticalCenter
- anchors.margins: 10
-
- cellWidth: 60
- cellHeight: 60
-
- model: ListModel {
- id: gridModel
-
- ListElement { display: "1" }
- ListElement { display: "2" }
- ListElement { display: "3" }
- ListElement { display: "4" }
- ListElement { display: "5" }
- ListElement { display: "6" }
- ListElement { display: "7" }
- ListElement { display: "8" }
- ListElement { display: "9" }
- ListElement { display: "10" }
- ListElement { display: "11" }
- ListElement { display: "12" }
- ListElement { display: "13" }
- ListElement { display: "14" }
- ListElement { display: "15" }
- ListElement { display: "16" }
- ListElement { display: "17" }
- ListElement { display: "18" }
- ListElement { display: "19" }
- ListElement { display: "20" }
- ListElement { display: "21" }
- ListElement { display: "22" }
- ListElement { display: "23" }
- ListElement { display: "24" }
- }
-
- delegate: Rectangle {
- id: root
-
- width: 60
- height: 60
-
- color: "black"
-
- Text {
- anchors.fill: parent
- color: draggable.drag.active ? "gold" : "white"
- text: display
- font.pixelSize: 16
- verticalAlignment: Text.AlignVCenter
- horizontalAlignment: Text.AlignHCenter
- }
-
- MouseArea {
- id: draggable
-
- property int initialIndex
-
- width: 60
- height: 60
-
- drag.data: model
- drag.keys: ["grid"]
- drag.target: draggable
-
- states: State {
- when: !draggable.drag.active
- PropertyChanges { target: draggable; x: 0; y: 0 }
- }
- }
- }
-
- DragTarget {
- anchors.fill: parent
-
- keys: [ "grid" ]
- onPositionChanged: {
- var index = gridView.indexAt(drag.x, drag.y)
- if (index != -1)
- gridModel.move(drag.data.index, index, 1)
- }
- }
-
- DragTarget {
- property int dragIndex
- anchors.fill: parent
-
- keys: [ "list" ]
- onEntered: {
- dragIndex = gridView.indexAt(drag.x, drag.y)
- if (dragIndex != -1) {
- gridModel.insert(dragIndex, { "display": drag.data.display })
- } else {
- event.accepted = false
- }
- }
- onPositionChanged: {
- var index = gridView.indexAt(drag.x, drag.y);
- if (index != -1) {
- gridModel.move(dragIndex, index, 1)
- dragIndex = index
- }
- }
- onExited: gridModel.remove(dragIndex, 1)
- }
- }
-
- ListView {
- id: listView
-
- width: 240
- height: 360
-
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- anchors.margins: 10
-
- model: ListModel {
- id: listModel
-
- ListElement { display: "a" }
- ListElement { display: "b" }
- ListElement { display: "c" }
- ListElement { display: "d"}
- ListElement { display: "e" }
- ListElement { display: "f" }
- ListElement { display: "g" }
- ListElement { display: "h" }
- ListElement { display: "i" }
- ListElement { display: "j" }
- ListElement { display: "k" }
- ListElement { display: "l" }
- ListElement { display: "m" }
- ListElement { display: "n" }
- ListElement { display: "o" }
- ListElement { display: "p" }
- ListElement { display: "q" }
- ListElement { display: "r" }
- ListElement { display: "s" }
- ListElement { display: "t" }
- ListElement { display: "u" }
- ListElement { display: "v" }
- ListElement { display: "w" }
- ListElement { display: "x" }
- }
-
- delegate: Rectangle {
- id: root
-
- width: 240
- height: 15
-
- color: "black"
-
- Text {
- anchors.fill: parent
- color: draggable.drag.active ? "gold" : "white"
- text: display
- font.pixelSize: 12
- verticalAlignment: Text.AlignVCenter
- horizontalAlignment: Text.AlignHCenter
- }
-
- MouseArea {
- id: draggable
-
- width: 240
- height: 15
-
- drag.data: model
- drag.keys: ["list"]
- drag.target: draggable
-
- states: State {
- when: !draggable.drag.active
- PropertyChanges { target: draggable; x: 0; y: 0 }
- }
- }
- }
-
- DragTarget {
- anchors.fill: parent
-
- keys: [ "list" ]
- onPositionChanged: {
- var index = listView.indexAt(drag.x, drag.y)
- if (index != -1)
- listModel.move(drag.data.index, index, 1)
- }
- }
-
- DragTarget {
- property int dragIndex
- anchors.fill: parent
-
- keys: [ "grid" ]
-
- onEntered: {
- dragIndex = listView.indexAt(drag.x, drag.y)
- if (dragIndex != -1) {
- listModel.insert(dragIndex, { "display": drag.data.display })
- } else {
- event.accepted = false
- }
- }
- onPositionChanged: {
- var index = listView.indexAt(drag.x, drag.y);
- if (index != -1) {
- listModel.move(dragIndex, index, 1)
- dragIndex = index
- }
- }
- onExited: listModel.remove(dragIndex, 1)
- }
- }
-}
diff --git a/examples/declarative/dragtarget/text/dragtext.qml b/examples/declarative/dragtarget/text/dragtext.qml
deleted file mode 100644
index 49858d1fc4..0000000000
--- a/examples/declarative/dragtarget/text/dragtext.qml
+++ /dev/null
@@ -1,182 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.0
-
-Item {
- id: root
- width: 320; height: 480
-
- Rectangle {
- id: inputRect
- anchors.left: parent.left; anchors.right: parent.right; anchors.top: parent.top
- anchors.margins: 2
- height: input.implicitHeight + 4
-
- border.width: 1
-
- TextInput {
- id: input
- anchors.fill: parent; anchors.margins: 2
-
- text: "the quick brown fox jumped over the lazy dog"
-
- DragTarget {
- id: inputTarget
-
- anchors.fill: parent
-
- Component {
- id: draggedInputText
- Text {
- x: inputTarget.dragX
- y: inputTarget.dragY
- text: inputTarget.dragData
- color: "blue"
- font: input.font
- }
- }
-
- Loader {
- sourceComponent: parent.containsDrag ? draggedInputText : undefined
- }
- }
-
-
- MouseArea {
- id: inputDraggable
-
- anchors.fill: parent
- enabled: input.selectionStart != input.selectionEnd
-
- drag.data: input.selectedText
- drag.target: inputDraggable
-
- drag.onDragged: {
- var position = input.positionAt(mouse.x);
- mouse.accepted = position >= input.selectionStart && position < input.selectionEnd
- }
-
- MouseArea {
- anchors.fill: parent
-
- onPressed: {
- var position = input.positionAt(mouse.x);
- if (position < input.selectionStart || position >= input.selectionEnd) {
- input.cursorPosition = position
- } else {
- mouse.accepted = false
- }
- }
- onPositionChanged: input.moveCursorSelection(input.positionAt(mouse.x))
- }
- }
- }
- }
-
- Rectangle {
- id: editRect
- anchors.left: parent.left; anchors.right: parent.right;
- anchors.top: inputRect.bottom; anchors.bottom: parent.bottom
- anchors.margins: 2
-
- border.width: 1
-
- TextEdit {
- id: edit
- anchors.fill: parent; anchors.margins: 2
-
- text: "the quick brown fox jumped over the lazy dog"
- font.pixelSize: 18
- wrapMode: TextEdit.WordWrap
-
- DragTarget {
- id: editTarget
-
- anchors.fill: parent
-
-
- Component {
- id: draggedEditText
- Text {
- x: editTarget.dragX
- y: editTarget.dragY
- text: editTarget.dragData
- color: "red"
- font: edit.font
- }
- }
-
- Loader {
- sourceComponent: parent.containsDrag ? draggedEditText : undefined
- }
- }
-
- MouseArea {
- id: editDraggable
-
- anchors.fill: parent
- enabled: edit.selectionStart != edit.selectionEnd
-
- drag.data: edit.selectedText
- drag.target: editDraggable
-
- drag.onDragged: {
- var position = edit.positionAt(mouse.x, mouse.y);
- mouse.accepted = position >= edit.selectionStart && position < edit.selectionEnd
- }
-
- MouseArea {
- anchors.fill: parent
-
- onPressed: {
- var position = edit.positionAt(mouse.x, mouse.y);
- if (position < edit.selectionStart || position >= edit.selectionEnd) {
- edit.cursorPosition = position
- } else {
- mouse.accepted = false
- }
- }
- onPositionChanged: edit.moveCursorSelection(edit.positionAt(mouse.x, mouse.y))
- }
- }
- }
- }
-}
diff --git a/examples/declarative/dragtarget/text/text.qmlproject b/examples/declarative/dragtarget/text/text.qmlproject
deleted file mode 100644
index d4909f8685..0000000000
--- a/examples/declarative/dragtarget/text/text.qmlproject
+++ /dev/null
@@ -1,16 +0,0 @@
-import QmlProject 1.0
-
-Project {
- /* Include .qml, .js, and image files from current directory and subdirectories */
- QmlFiles {
- directory: "."
- }
- JavaScriptFiles {
- directory: "."
- }
- ImageFiles {
- directory: "."
- }
- /* List of plugin directories passed to QML runtime */
- // importPaths: [ " ../exampleplugin " ]
-}
diff --git a/examples/declarative/dragtarget/tiles/DragTile.qml b/examples/declarative/dragtarget/tiles/DragTile.qml
deleted file mode 100644
index f1bd79314a..0000000000
--- a/examples/declarative/dragtarget/tiles/DragTile.qml
+++ /dev/null
@@ -1,99 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.0
-
-Rectangle {
- id: dragRectangle
-
- property Item dropTarget
-
- property string colorKey
-
- color: colorKey
-
- width: 100; height: 100
-
- Text {
- anchors.fill: parent
- color: "white"
- font.pixelSize: 90
- text: modelData + 1
- horizontalAlignment:Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
- }
-
- MouseArea {
- id: draggable
-
- anchors.fill: parent
-
- drag.target: parent
- drag.keys: [ colorKey ]
-
- drag.onDropped: dropTarget = dropItem
-
- states: [
- State {
- when: dragRectangle.dropTarget != undefined && !draggable.drag.active
- ParentChange {
- target: dragRectangle
- parent: dropTarget
- x: 0
- y: 0
- }
- },
- State {
- when: dragRectangle.dropTarget != undefined && draggable.drag.active
- ParentChange {
- target: dragRectangle
- parent: dropTarget
- }
- },
- State {
- when: !draggable.drag.active
- AnchorChanges {
- target: dragRectangle
- anchors.horizontalCenter: parent.horizontalCenter
- }
- }
- ]
- }
-}
diff --git a/examples/declarative/imageelements/image/ImageCell.qml b/examples/declarative/imageelements/ImageCell.qml
index 46a432f660..572b87db4e 100644
--- a/examples/declarative/imageelements/image/ImageCell.qml
+++ b/examples/declarative/imageelements/ImageCell.qml
@@ -37,7 +37,8 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-import QtQuick 1.0
+import QtQuick 2.0
+import "content"
Item {
property alias mode: image.fillMode
@@ -48,7 +49,7 @@ Item {
Image {
id: image
width: parent.width; height: parent.height - captionItem.height
- source: "qt-logo.png"
+ source: "content/qt-logo.png"
clip: true // only makes a difference if mode is PreserveAspectCrop
smooth: true
}
diff --git a/examples/declarative/imageelements/borderimage/borderimage.qml b/examples/declarative/imageelements/borderimage.qml
index 8fede46a9a..8fede46a9a 100644
--- a/examples/declarative/imageelements/borderimage/borderimage.qml
+++ b/examples/declarative/imageelements/borderimage.qml
diff --git a/examples/declarative/imageelements/borderimage/content/MyBorderImage.qml b/examples/declarative/imageelements/content/MyBorderImage.qml
index 4ad69fdb1d..4ad69fdb1d 100644
--- a/examples/declarative/imageelements/borderimage/content/MyBorderImage.qml
+++ b/examples/declarative/imageelements/content/MyBorderImage.qml
diff --git a/examples/declarative/imageelements/borderimage/content/ShadowRectangle.qml b/examples/declarative/imageelements/content/ShadowRectangle.qml
index 4d0df21459..4d0df21459 100644
--- a/examples/declarative/imageelements/borderimage/content/ShadowRectangle.qml
+++ b/examples/declarative/imageelements/content/ShadowRectangle.qml
diff --git a/examples/declarative/imageelements/borderimage/content/bw.png b/examples/declarative/imageelements/content/bw.png
index 486eaae96e..486eaae96e 100644
--- a/examples/declarative/imageelements/borderimage/content/bw.png
+++ b/examples/declarative/imageelements/content/bw.png
Binary files differ
diff --git a/examples/declarative/imageelements/borderimage/content/colors-round.sci b/examples/declarative/imageelements/content/colors-round.sci
index 506f6f5f99..506f6f5f99 100644
--- a/examples/declarative/imageelements/borderimage/content/colors-round.sci
+++ b/examples/declarative/imageelements/content/colors-round.sci
diff --git a/examples/declarative/imageelements/borderimage/content/colors-stretch.sci b/examples/declarative/imageelements/content/colors-stretch.sci
index e4989a723c..e4989a723c 100644
--- a/examples/declarative/imageelements/borderimage/content/colors-stretch.sci
+++ b/examples/declarative/imageelements/content/colors-stretch.sci
diff --git a/examples/declarative/imageelements/borderimage/content/colors.png b/examples/declarative/imageelements/content/colors.png
index dfb62f3d64..dfb62f3d64 100644
--- a/examples/declarative/imageelements/borderimage/content/colors.png
+++ b/examples/declarative/imageelements/content/colors.png
Binary files differ
diff --git a/examples/declarative/imageelements/image/qml/qt-logo.png b/examples/declarative/imageelements/content/qt-logo.png
index 14ddf2a028..14ddf2a028 100644
--- a/examples/declarative/imageelements/image/qml/qt-logo.png
+++ b/examples/declarative/imageelements/content/qt-logo.png
Binary files differ
diff --git a/examples/declarative/imageelements/borderimage/content/shadow.png b/examples/declarative/imageelements/content/shadow.png
index 431af8545d..431af8545d 100644
--- a/examples/declarative/imageelements/borderimage/content/shadow.png
+++ b/examples/declarative/imageelements/content/shadow.png
Binary files differ
diff --git a/examples/declarative/imageelements/image/image.qml b/examples/declarative/imageelements/image.qml
index abaa095100..d174831510 100644
--- a/examples/declarative/imageelements/image/image.qml
+++ b/examples/declarative/imageelements/image.qml
@@ -38,7 +38,7 @@
**
****************************************************************************/
-import QtQuick 1.0
+import QtQuick 2.0
Rectangle {
width: 490
diff --git a/examples/declarative/imageelements/image/image.desktop b/examples/declarative/imageelements/image/image.desktop
deleted file mode 100644
index 6103d44733..0000000000
--- a/examples/declarative/imageelements/image/image.desktop
+++ /dev/null
@@ -1,11 +0,0 @@
-[Desktop Entry]
-Encoding=UTF-8
-Version=1.0
-Type=Application
-Terminal=false
-Name=image
-Exec=/opt/usr/bin/image
-Icon=image
-X-Window-Icon=
-X-HildonDesk-ShowInToolbar=true
-X-Osso-Type=application/x-executable
diff --git a/examples/declarative/imageelements/image/image.png b/examples/declarative/imageelements/image/image.png
deleted file mode 100644
index 707d5c4e85..0000000000
--- a/examples/declarative/imageelements/image/image.png
+++ /dev/null
Binary files differ
diff --git a/examples/declarative/imageelements/image/image.pro b/examples/declarative/imageelements/image/image.pro
deleted file mode 100644
index c5e94cc159..0000000000
--- a/examples/declarative/imageelements/image/image.pro
+++ /dev/null
@@ -1,39 +0,0 @@
-# Add more folders to ship with the application, here
-folder_01.source = qml
-folder_01.target = qml
-DEPLOYMENTFOLDERS = folder_01
-
-# Additional import path used to resolve QML modules in Creator's code model
-QML_IMPORT_PATH =
-
-# Avoid auto screen rotation
-DEFINES += ORIENTATIONLOCK
-
-# Needs to be defined for Symbian
-#DEFINES += NETWORKACCESS
-
-symbian:TARGET.UID3 = 0xE5D64785
-
-# Smart Installer package's UID
-# This UID is from the protected range
-# and therefore the package will fail to install if self-signed
-# By default qmake uses the unprotected range value if unprotected UID is defined for the application
-# and 0x2002CCCF value if protected UID is given to the application
-#symbian:DEPLOYMENT.installer_header = 0x2002CCCF
-
-# Define QMLJSDEBUGGER to allow debugging of QML in debug builds
-# (This might significantly increase build time)
-# DEFINES += QMLJSDEBUGGER
-
-# If your application uses the Qt Mobility libraries, uncomment
-# the following lines and add the respective components to the
-# MOBILITY variable.
-# CONFIG += mobility
-# MOBILITY +=
-
-# The .cpp file which was generated for your project. Feel free to hack it.
-SOURCES += main.cpp
-
-# Please do not modify the following two lines. Required for deployment.
-include(qmlapplicationviewer/qmlapplicationviewer.pri)
-qtcAddDeployment()
diff --git a/examples/declarative/imageelements/image/image.svg b/examples/declarative/imageelements/image/image.svg
deleted file mode 100644
index 566acfada0..0000000000
--- a/examples/declarative/imageelements/image/image.svg
+++ /dev/null
@@ -1,93 +0,0 @@
-<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- height="44px"
- version="1.1"
- viewBox="0 0 44 44"
- width="44px"
- x="0px"
- y="0px"
- id="svg2"
- inkscape:version="0.47 r22583"
- sodipodi:docname="qt.svg">
- <metadata
- id="metadata18">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <defs
- id="defs16">
- <inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="0 : 22 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_z="44 : 22 : 1"
- inkscape:persp3d-origin="22 : 14.666667 : 1"
- id="perspective2836" />
- </defs>
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1920"
- inkscape:window-height="1020"
- id="namedview14"
- showgrid="false"
- inkscape:zoom="21.454545"
- inkscape:cx="49.412871"
- inkscape:cy="21.894358"
- inkscape:window-x="-4"
- inkscape:window-y="-4"
- inkscape:window-maximized="1"
- inkscape:current-layer="g3" />
- <g
- transform="matrix(0.18308778,0,0,0.18308778,6.6100946,3.2385199)"
- id="g3">
- <path
- d="M 43.09,0.3586 C 40.94,0.0036 38.84,-0.0824 36.81,0.0776 31.968136,0.39505671 27.122677,0.73638425 22.28,1.0696 9.62,2.0816 0,12.4996 0,26.8896 l 0,169.7 14.19,13.2 28.87,-209.42 0.03,-0.011 z"
- style="fill:#006225"
- id="path5"
- sodipodi:nodetypes="cccccccc" />
- <path
- d="m 174.4,160 c 0,12.5 -7.75,24.07 -17.57,25.77 L 14.23,209.73 V 25.93 C 14.23,9.21 27.57,-2.27 43.12,0.3 l 131.3,21.52 v 138.2 z"
- style="fill:#80c342"
- id="path7" />
- <path
- d="m 154.9,80.96 -12.96,-0.598 0,0.278 6.945,0.32 6.016,0 z"
- style="fill:#006225"
- id="path11" />
- <path
- d="m 144.6,135.6 c 0.66,0.328 1.43,0.476 2.351,0.476 0.161,0 0.329,-0.004 0.497,-0.016 2.55,-0.148 5.32,-0.933 8.343,-2.308 h -6.015 c -1.821,0.832 -3.532,1.457 -5.176,1.848 z"
- style="fill:#006225"
- id="path13" />
- <path
- id="path17"
- style="fill:#ffffff"
- d="m 91.15,132.4 c 2.351,-6.051 3.511,-17.91 3.511,-35.62 0,-15.89 -1.148,-26.82 -3.484,-32.81 -2.336,-6.027 -5.832,-9.281 -10.52,-9.691 -0.359,-0.031 -0.714,-0.051 -1.058,-0.051 -4.34,0 -7.68,2.535 -10.01,7.625 -2.52,5.543 -3.793,17.04 -3.793,34.44 0,16.82 1.238,28.75 3.734,35.75 2.356,6.672 5.879,9.976 10.5,9.976 0.207,0 0.41,-0.008 0.621,-0.019 4.633,-0.293 8.121,-3.496 10.49,-9.602 m 17.98,3.75 c -4.117,9.707 -10.39,16.06 -18.99,19 0.867,4.449 2.176,7.441 3.922,9.019 1.351,1.211 3.433,1.821 6.222,1.821 0.805,0 1.668,-0.055 2.59,-0.157 v 13.12 l -5.961,0.782 c -1.758,0.23 -3.426,0.343 -5.004,0.343 -5.218,0 -9.445,-1.265 -12.62,-3.824 -4.207,-3.379 -7.308,-9.894 -9.297,-19.54 -9.136,-1.945 -16.26,-7.754 -21.19,-17.5 -5.004,-9.902 -7.551,-24.39 -7.551,-43.34 0,-20.43 3.484,-35.51 10.34,-45.07 5.789,-8.07 13.86,-12.04 24.02,-12.04 1.629,0 3.309,0.102 5.043,0.305 11.95,1.375 20.62,7.016 26.26,16.79 5.535,9.562 8.254,23.27 8.254,41.26 0,16.48 -2,29.45 -6.043,39.02 z M 130.4,45.91 l 11.52,1.238 0,20.21 12.96,0.914 0,12.68 -12.96,-0.598 0,46.33 c 0,4.032 0.445,6.625 1.34,7.789 0.8,1.067 2.046,1.594 3.71,1.594 0.161,0 0.329,-0.004 0.497,-0.016 2.55,-0.148 5.32,-0.933 8.343,-2.308 v 11.65 c -5.136,2.258 -10.18,3.598 -15.12,4.02 -0.718,0.055 -1.41,0.086 -2.078,0.086 -4.48,0 -7.906,-1.301 -10.25,-3.934 -2.73,-3.051 -4.09,-7.949 -4.09,-14.67 V 79.535 L 118.046,79.25 V 65.66 l 7.586,0.547 4.773,-20.3 z" />
- <path
- d="m 100.3,166 c 0.809,0 1.672,-0.055 2.59,-0.157 H 98.054 C 98.73,165.949 99.507,166 100.3,166 z"
- style="fill:#006225"
- id="path19" />
- <path
- id="path21"
- style="fill:#006225"
- d="m 84.85,63.98 c 2.336,5.997 3.484,16.92 3.484,32.81 0,17.7 -1.16,29.57 -3.512,35.62 -1.894,4.879 -4.527,7.902 -7.863,9.07 0.965,0.368 1.992,0.551 3.078,0.551 0.207,0 0.41,-0.008 0.621,-0.019 4.633,-0.293 8.121,-3.496 10.49,-9.602 2.351,-6.051 3.511,-17.91 3.511,-35.62 0,-15.89 -1.148,-26.82 -3.484,-32.81 -2.336,-6.027 -5.832,-9.281 -10.52,-9.691 -0.359,-0.031 -0.714,-0.051 -1.058,-0.051 -1.09,0 -2.117,0.16 -3.082,0.481 h -0.004 c 3.601,1.121 6.379,4.215 8.336,9.261 z m -2.344,114.3 c -0.113,-0.05 -0.227,-0.105 -0.336,-0.16 -0.012,-0.004 -0.023,-0.012 -0.035,-0.015 -0.102,-0.051 -0.207,-0.106 -0.309,-0.157 -0.019,-0.011 -0.039,-0.019 -0.058,-0.031 -0.09,-0.051 -0.184,-0.098 -0.278,-0.148 -0.027,-0.016 -0.054,-0.036 -0.086,-0.051 -0.082,-0.043 -0.164,-0.09 -0.242,-0.137 -0.039,-0.023 -0.078,-0.047 -0.113,-0.07 -0.07,-0.039 -0.145,-0.082 -0.215,-0.125 -0.047,-0.031 -0.094,-0.059 -0.14,-0.09 -0.059,-0.039 -0.118,-0.074 -0.176,-0.113 -0.059,-0.039 -0.114,-0.075 -0.168,-0.114 -0.051,-0.031 -0.102,-0.066 -0.149,-0.097 -0.066,-0.047 -0.132,-0.094 -0.195,-0.137 -0.039,-0.027 -0.078,-0.055 -0.113,-0.082 -0.078,-0.055 -0.153,-0.113 -0.231,-0.172 -0.023,-0.016 -0.05,-0.035 -0.078,-0.055 -0.098,-0.078 -0.199,-0.156 -0.297,-0.234 -4.207,-3.379 -7.308,-9.894 -9.297,-19.54 -9.136,-1.945 -16.26,-7.754 -21.19,-17.5 -5.004,-9.902 -7.551,-24.39 -7.551,-43.34 0,-20.43 3.484,-35.51 10.34,-45.07 5.789,-8.07 13.86,-12.04 24.02,-12.04 h -6.351 c -10.15,0.008 -18.22,3.977 -24,12.04 -6.855,9.563 -10.34,24.64 -10.34,45.07 0,18.95 2.547,33.44 7.551,43.34 4.934,9.75 12.05,15.56 21.19,17.5 1.989,9.641 5.09,16.16 9.297,19.54 3.176,2.559 7.403,3.824 12.62,3.824 0.098,0 0.199,0 0.297,-0.004 h 5.539 c -3.406,-0.05 -6.383,-0.66 -8.906,-1.828 L 82.498,178.28 z M 128.4,145.6 c -2.73,-3.051 -4.09,-7.949 -4.09,-14.67 V 79.57 l -6.226,-0.285 v -13.59 h -6.016 v 3.035 c 0.871,3.273 1.555,6.82 2.063,10.64 l 4.164,0.192 v 51.36 c 0,6.723 1.367,11.62 4.09,14.67 2.343,2.633 5.765,3.934 10.25,3.934 h 6.015 c -4.48,0 -7.906,-1.301 -10.25,-3.934 z m 2.043,-99.66 -6.016,0 -4.668,19.88 5.911,0.422 4.773,-20.3 z" />
- </g>
-</svg>
diff --git a/examples/declarative/imageelements/image/main.cpp b/examples/declarative/imageelements/image/main.cpp
deleted file mode 100644
index 09cc88438d..0000000000
--- a/examples/declarative/imageelements/image/main.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtGui/QApplication>
-#include "qmlapplicationviewer.h"
-
-int main(int argc, char *argv[])
-{
- QApplication app(argc, argv);
-
- QmlApplicationViewer viewer;
- viewer.setOrientation(QmlApplicationViewer::ScreenOrientationLockLandscape);
- viewer.setMainQmlFile(QLatin1String("qml/qml/image.qml"));
- viewer.showExpanded();
-
- return app.exec();
-}
diff --git a/examples/declarative/imageelements/image/qml/ImageCell.qml b/examples/declarative/imageelements/image/qml/ImageCell.qml
deleted file mode 100644
index e8a6c55102..0000000000
--- a/examples/declarative/imageelements/image/qml/ImageCell.qml
+++ /dev/null
@@ -1,60 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-import QtQuick 1.0
-
-Item {
- property alias mode: image.fillMode
- property alias caption: captionItem.text
-
- width: parent.cellWidth; height: parent.cellHeight
-
- Image {
- id: image
- width: parent.width; height: parent.height - captionItem.height
- source: "qt-logo.png"
- clip: true // only makes a difference if mode is PreserveAspectCrop
- smooth: true
- }
-
- Text {
- id: captionItem
- anchors.horizontalCenter: parent.horizontalCenter; anchors.bottom: parent.bottom
- }
-}
diff --git a/examples/declarative/imageelements/image/qml/image.qml b/examples/declarative/imageelements/image/qml/image.qml
deleted file mode 100644
index f00fc18f8e..0000000000
--- a/examples/declarative/imageelements/image/qml/image.qml
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 1.0
-
-Rectangle {
- width: 490
- height: 285
-
- Grid {
- property int cellWidth: (width - (spacing * (columns - 1))) / columns
- property int cellHeight: (height - (spacing * (rows - 1))) / rows
-
- anchors.fill: parent
- anchors.margins: 30
-
- columns: 3
- rows: 2
- spacing: 30
-
- ImageCell { mode: Image.Stretch; caption: "Stretch" }
- ImageCell { mode: Image.PreserveAspectFit; caption: "PreserveAspectFit" }
- ImageCell { mode: Image.PreserveAspectCrop; caption: "PreserveAspectCrop" }
-
- ImageCell { mode: Image.Tile; caption: "Tile" }
- ImageCell { mode: Image.TileHorizontally; caption: "TileHorizontally" }
- ImageCell { mode: Image.TileVertically; caption: "TileVertically" }
- }
-}
diff --git a/examples/declarative/imageelements/image/qmlapplicationviewer/qmlapplicationviewer.cpp b/examples/declarative/imageelements/image/qmlapplicationviewer/qmlapplicationviewer.cpp
deleted file mode 100644
index 411a04c139..0000000000
--- a/examples/declarative/imageelements/image/qmlapplicationviewer/qmlapplicationviewer.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// checksum 0x28c7 version 0x2000a
-/*
- This file was generated by the Qt Quick Application wizard of Qt Creator.
- QmlApplicationViewer is a convenience class containing mobile device specific
- code such as screen orientation handling. Also QML paths and debugging are
- handled here.
- It is recommended not to modify this file, since newer versions of Qt Creator
- may offer an updated version of it.
-*/
-
-#include "qmlapplicationviewer.h"
-
-#include <QtCore/QCoreApplication>
-#include <QtCore/QDir>
-#include <QtCore/QFileInfo>
-#include <QtDeclarative/QDeclarativeComponent>
-#include <QtDeclarative/QDeclarativeEngine>
-#include <QtDeclarative/QDeclarativeContext>
-
-#if defined(QMLJSDEBUGGER)
-#include <qt_private/qdeclarativedebughelper_p.h>
-#endif
-
-#if defined(QMLJSDEBUGGER) && !defined(NO_JSDEBUGGER)
-#include <jsdebuggeragent.h>
-#endif
-#if defined(QMLJSDEBUGGER) && !defined(NO_QMLOBSERVER)
-#include <qdeclarativeviewobserver.h>
-#endif
-
-#if defined(Q_OS_SYMBIAN) && defined(ORIENTATIONLOCK)
-#include <eikenv.h>
-#include <eikappui.h>
-#include <aknenv.h>
-#include <aknappui.h>
-#endif // Q_OS_SYMBIAN && ORIENTATIONLOCK
-
-#if defined(QMLJSDEBUGGER)
-
-// Enable debugging before any QDeclarativeEngine is created
-struct QmlJsDebuggingEnabler
-{
- QmlJsDebuggingEnabler()
- {
- QDeclarativeDebugHelper::enableDebugging();
- }
-};
-
-// Execute code in constructor before first QDeclarativeEngine is instantiated
-static QmlJsDebuggingEnabler enableDebuggingHelper;
-
-#endif // QMLJSDEBUGGER
-
-class QmlApplicationViewerPrivate
-{
- QString mainQmlFile;
- friend class QmlApplicationViewer;
- static QString adjustPath(const QString &path);
-};
-
-QString QmlApplicationViewerPrivate::adjustPath(const QString &path)
-{
-#ifdef Q_OS_UNIX
-#ifdef Q_OS_MAC
- if (!QDir::isAbsolutePath(path))
- return QCoreApplication::applicationDirPath()
- + QLatin1String("/../Resources/") + path;
-#else
- const QString pathInShareDir = QCoreApplication::applicationDirPath()
- + QLatin1String("/../share/")
- + QFileInfo(QCoreApplication::applicationFilePath()).fileName()
- + QLatin1Char('/') + path;
- if (QFileInfo(pathInShareDir).exists())
- return pathInShareDir;
-#endif
-#endif
- return path;
-}
-
-QmlApplicationViewer::QmlApplicationViewer(QWidget *parent) :
- QDeclarativeView(parent),
- m_d(new QmlApplicationViewerPrivate)
-{
- connect(engine(), SIGNAL(quit()), SLOT(close()));
- setResizeMode(QDeclarativeView::SizeRootObjectToView);
-#if defined(QMLJSDEBUGGER) && !defined(NO_JSDEBUGGER)
- new QmlJSDebugger::JSDebuggerAgent(engine());
-#endif
-#if defined(QMLJSDEBUGGER) && !defined(NO_QMLOBSERVER)
- new QmlJSDebugger::QDeclarativeViewObserver(this, parent);
-#endif
-}
-
-QmlApplicationViewer::~QmlApplicationViewer()
-{
- delete m_d;
-}
-
-void QmlApplicationViewer::setMainQmlFile(const QString &file)
-{
- m_d->mainQmlFile = QmlApplicationViewerPrivate::adjustPath(file);
- setSource(QUrl::fromLocalFile(m_d->mainQmlFile));
-}
-
-void QmlApplicationViewer::addImportPath(const QString &path)
-{
- engine()->addImportPath(QmlApplicationViewerPrivate::adjustPath(path));
-}
-
-void QmlApplicationViewer::setOrientation(ScreenOrientation orientation)
-{
-#ifdef Q_OS_SYMBIAN
- if (orientation != ScreenOrientationAuto) {
-#if defined(ORIENTATIONLOCK)
- const CAknAppUiBase::TAppUiOrientation uiOrientation =
- (orientation == ScreenOrientationLockPortrait) ? CAknAppUi::EAppUiOrientationPortrait
- : CAknAppUi::EAppUiOrientationLandscape;
- CAknAppUi* appUi = dynamic_cast<CAknAppUi*> (CEikonEnv::Static()->AppUi());
- TRAPD(error,
- if (appUi)
- appUi->SetOrientationL(uiOrientation);
- );
- Q_UNUSED(error)
-#else // ORIENTATIONLOCK
- qWarning("'ORIENTATIONLOCK' needs to be defined on Symbian when locking the orientation.");
-#endif // ORIENTATIONLOCK
- }
-#elif defined(Q_WS_MAEMO_5)
- Qt::WidgetAttribute attribute;
- switch (orientation) {
- case ScreenOrientationLockPortrait:
- attribute = Qt::WA_Maemo5PortraitOrientation;
- break;
- case ScreenOrientationLockLandscape:
- attribute = Qt::WA_Maemo5LandscapeOrientation;
- break;
- case ScreenOrientationAuto:
- default:
- attribute = Qt::WA_Maemo5AutoOrientation;
- break;
- }
- setAttribute(attribute, true);
-#else // Q_OS_SYMBIAN
- Q_UNUSED(orientation);
-#endif // Q_OS_SYMBIAN
-}
-
-void QmlApplicationViewer::showExpanded()
-{
-#ifdef Q_OS_SYMBIAN
- showFullScreen();
-#elif defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
- showMaximized();
-#else
- show();
-#endif
-}
diff --git a/examples/declarative/imageelements/image/qmlapplicationviewer/qmlapplicationviewer.h b/examples/declarative/imageelements/image/qmlapplicationviewer/qmlapplicationviewer.h
deleted file mode 100644
index f5b24b0199..0000000000
--- a/examples/declarative/imageelements/image/qmlapplicationviewer/qmlapplicationviewer.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// checksum 0x5a59 version 0x2000a
-/*
- This file was generated by the Qt Quick Application wizard of Qt Creator.
- QmlApplicationViewer is a convenience class containing mobile device specific
- code such as screen orientation handling. Also QML paths and debugging are
- handled here.
- It is recommended not to modify this file, since newer versions of Qt Creator
- may offer an updated version of it.
-*/
-
-#ifndef QMLAPPLICATIONVIEWER_H
-#define QMLAPPLICATIONVIEWER_H
-
-#include <QtDeclarative/QDeclarativeView>
-
-class QmlApplicationViewer : public QDeclarativeView
-{
- Q_OBJECT
-
-public:
- enum ScreenOrientation {
- ScreenOrientationLockPortrait,
- ScreenOrientationLockLandscape,
- ScreenOrientationAuto
- };
-
- explicit QmlApplicationViewer(QWidget *parent = 0);
- virtual ~QmlApplicationViewer();
-
- void setMainQmlFile(const QString &file);
- void addImportPath(const QString &path);
- void setOrientation(ScreenOrientation orientation);
- void showExpanded();
-
-private:
- class QmlApplicationViewerPrivate *m_d;
-};
-
-#endif // QMLAPPLICATIONVIEWER_H
diff --git a/examples/declarative/imageelements/image/qmlapplicationviewer/qmlapplicationviewer.pri b/examples/declarative/imageelements/image/qmlapplicationviewer/qmlapplicationviewer.pri
deleted file mode 100644
index 1c0c7edb39..0000000000
--- a/examples/declarative/imageelements/image/qmlapplicationviewer/qmlapplicationviewer.pri
+++ /dev/null
@@ -1,154 +0,0 @@
-# checksum 0x3dc8 version 0x2000a
-# This file was generated by the Qt Quick Application wizard of Qt Creator.
-# The code below adds the QmlApplicationViewer to the project and handles the
-# activation of QML debugging.
-# It is recommended not to modify this file, since newer versions of Qt Creator
-# may offer an updated version of it.
-
-QT += declarative
-
-SOURCES += $$PWD/qmlapplicationviewer.cpp
-HEADERS += $$PWD/qmlapplicationviewer.h
-INCLUDEPATH += $$PWD
-
-defineTest(minQtVersion) {
- maj = $$1
- min = $$2
- patch = $$3
- isEqual(QT_MAJOR_VERSION, $$maj) {
- isEqual(QT_MINOR_VERSION, $$min) {
- isEqual(QT_PATCH_VERSION, $$patch) {
- return(true)
- }
- greaterThan(QT_PATCH_VERSION, $$patch) {
- return(true)
- }
- }
- greaterThan(QT_MINOR_VERSION, $$min) {
- return(true)
- }
- }
- return(false)
-}
-
-contains(DEFINES, QMLJSDEBUGGER) {
- CONFIG(debug, debug|release) {
- !minQtVersion(4, 7, 1) {
- warning()
- warning("Disabling QML debugging:")
- warning()
- warning("Debugging QML requires the qmljsdebugger library that ships with Qt Creator.")
- warning("This library requires Qt 4.7.1 or newer.")
- warning()
- DEFINES -= QMLJSDEBUGGER
- } else:isEmpty(QMLJSDEBUGGER_PATH) {
- warning()
- warning("Disabling QML debugging:")
- warning()
- warning("Debugging QML requires the qmljsdebugger library that ships with Qt Creator.")
- warning("Please specify its location on the qmake command line, eg")
- warning(" qmake -r QMLJSDEBUGGER_PATH=$CREATORDIR/share/qtcreator/qmljsdebugger")
- warning()
- DEFINES -= QMLJSDEBUGGER
- } else {
- include($$QMLJSDEBUGGER_PATH/qmljsdebugger-lib.pri)
- }
- } else {
- DEFINES -= QMLJSDEBUGGER
- }
-}
-# This file was generated by an application wizard of Qt Creator.
-# The code below handles deployment to Symbian and Maemo, aswell as copying
-# of the application data to shadow build directories on desktop.
-# It is recommended not to modify this file, since newer versions of Qt Creator
-# may offer an updated version of it.
-
-defineTest(qtcAddDeployment) {
-for(deploymentfolder, DEPLOYMENTFOLDERS) {
- item = item$${deploymentfolder}
- itemsources = $${item}.sources
- $$itemsources = $$eval($${deploymentfolder}.source)
- itempath = $${item}.path
- $$itempath= $$eval($${deploymentfolder}.target)
- export($$itemsources)
- export($$itempath)
- DEPLOYMENT += $$item
-}
-
-MAINPROFILEPWD = $$PWD
-
-symbian {
- ICON = $${TARGET}.svg
- TARGET.EPOCHEAPSIZE = 0x20000 0x2000000
- contains(DEFINES, ORIENTATIONLOCK):LIBS += -lavkon -leikcore -lcone
- contains(DEFINES, NETWORKACCESS):TARGET.CAPABILITY += NetworkServices
-} else:win32 {
- !isEqual(PWD,$$OUT_PWD) {
- copyCommand = @echo Copying application data...
- for(deploymentfolder, DEPLOYMENTFOLDERS) {
- source = $$eval($${deploymentfolder}.source)
- pathSegments = $$split(source, /)
- sourceAndTarget = $$MAINPROFILEPWD/$$source $$OUT_PWD/$$eval($${deploymentfolder}.target)/$$last(pathSegments)
- copyCommand += && $(COPY_DIR) $$replace(sourceAndTarget, /, \\)
- }
- copydeploymentfolders.commands = $$copyCommand
- first.depends = $(first) copydeploymentfolders
- export(first.depends)
- export(copydeploymentfolders.commands)
- QMAKE_EXTRA_TARGETS += first copydeploymentfolders
- }
-} else:unix {
- maemo5 {
- installPrefix = /opt/usr
- desktopfile.path = /usr/share/applications/hildon
- } else {
- installPrefix = /usr/local
- desktopfile.path = /usr/share/applications
- !isEqual(PWD,$$OUT_PWD) {
- copyCommand = @echo Copying application data...
- for(deploymentfolder, DEPLOYMENTFOLDERS) {
- macx {
- target = $$OUT_PWD/$${TARGET}.app/Contents/Resources/$$eval($${deploymentfolder}.target)
- } else {
- target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
- }
- copyCommand += && $(MKDIR) $$target
- copyCommand += && $(COPY_DIR) $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source) $$target
- }
- copydeploymentfolders.commands = $$copyCommand
- first.depends = $(first) copydeploymentfolders
- export(first.depends)
- export(copydeploymentfolders.commands)
- QMAKE_EXTRA_TARGETS += first copydeploymentfolders
- }
- }
- for(deploymentfolder, DEPLOYMENTFOLDERS) {
- item = item$${deploymentfolder}
- itemfiles = $${item}.files
- $$itemfiles = $$eval($${deploymentfolder}.source)
- itempath = $${item}.path
- $$itempath = $${installPrefix}/share/$${TARGET}/$$eval($${deploymentfolder}.target)
- export($$itemfiles)
- export($$itempath)
- INSTALLS += $$item
- }
- icon.files = $${TARGET}.png
- icon.path = /usr/share/icons/hicolor/64x64/apps
- desktopfile.files = $${TARGET}.desktop
- target.path = $${installPrefix}/bin
- export(icon.files)
- export(icon.path)
- export(desktopfile.files)
- export(desktopfile.path)
- export(target.path)
- INSTALLS += desktopfile icon target
-}
-
-export (ICON)
-export (INSTALLS)
-export (DEPLOYMENT)
-export (TARGET.EPOCHEAPSIZE)
-export (TARGET.CAPABILITY)
-export (LIBS)
-export (QMAKE_EXTRA_TARGETS)
-}
diff --git a/examples/declarative/imageelements/borderimage/shadows.qml b/examples/declarative/imageelements/shadows.qml
index ebc2cdadcf..ebc2cdadcf 100644
--- a/examples/declarative/imageelements/borderimage/shadows.qml
+++ b/examples/declarative/imageelements/shadows.qml
diff --git a/examples/declarative/imageelements/shadows/main.cpp b/examples/declarative/imageelements/shadows/main.cpp
deleted file mode 100644
index c8a9b85b78..0000000000
--- a/examples/declarative/imageelements/shadows/main.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtGui/QApplication>
-#include "qmlapplicationviewer.h"
-
-int main(int argc, char *argv[])
-{
- QApplication app(argc, argv);
-
- QmlApplicationViewer viewer;
- viewer.setOrientation(QmlApplicationViewer::ScreenOrientationLockLandscape);
- viewer.setMainQmlFile(QLatin1String("qml/qml/shadows.qml"));
- viewer.showExpanded();
-
- return app.exec();
-}
diff --git a/examples/declarative/imageelements/shadows/qml/borderimage.qml b/examples/declarative/imageelements/shadows/qml/borderimage.qml
deleted file mode 100644
index 53e35f97e8..0000000000
--- a/examples/declarative/imageelements/shadows/qml/borderimage.qml
+++ /dev/null
@@ -1,97 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 1.0
-import "content"
-
-Rectangle {
- id: page
- width: 1030; height: 540
-
- Grid {
- anchors.centerIn: parent; spacing: 20
-
- MyBorderImage {
- minWidth: 120; maxWidth: 240; minHeight: 120; maxHeight: 240
- source: "content/colors.png"; margin: 30
- }
-
- MyBorderImage {
- minWidth: 120; maxWidth: 240; minHeight: 120; maxHeight: 240
- source: "content/colors.png"; margin: 30
- horizontalMode: BorderImage.Repeat; verticalMode: BorderImage.Repeat
- }
-
- MyBorderImage {
- minWidth: 120; maxWidth: 240; minHeight: 120; maxHeight: 240
- source: "content/colors.png"; margin: 30
- horizontalMode: BorderImage.Stretch; verticalMode: BorderImage.Repeat
- }
-
- MyBorderImage {
- minWidth: 120; maxWidth: 240; minHeight: 120; maxHeight: 240
- source: "content/colors.png"; margin: 30
- horizontalMode: BorderImage.Round; verticalMode: BorderImage.Round
- }
-
- MyBorderImage {
- minWidth: 60; maxWidth: 200; minHeight: 40; maxHeight: 200
- source: "content/bw.png"; margin: 10
- }
-
- MyBorderImage {
- minWidth: 60; maxWidth: 200; minHeight: 40; maxHeight: 200
- source: "content/bw.png"; margin: 10
- horizontalMode: BorderImage.Repeat; verticalMode: BorderImage.Repeat
- }
-
- MyBorderImage {
- minWidth: 60; maxWidth: 200; minHeight: 40; maxHeight: 200
- source: "content/bw.png"; margin: 10
- horizontalMode: BorderImage.Stretch; verticalMode: BorderImage.Repeat
- }
-
- MyBorderImage {
- minWidth: 60; maxWidth: 200; minHeight: 40; maxHeight: 200
- source: "content/bw.png"; margin: 10
- horizontalMode: BorderImage.Round; verticalMode: BorderImage.Round
- }
- }
-}
diff --git a/examples/declarative/imageelements/shadows/qml/content/MyBorderImage.qml b/examples/declarative/imageelements/shadows/qml/content/MyBorderImage.qml
deleted file mode 100644
index 96495cbefa..0000000000
--- a/examples/declarative/imageelements/shadows/qml/content/MyBorderImage.qml
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 1.0
-
-Item {
- id: container
-
- property alias horizontalMode: image.horizontalTileMode
- property alias verticalMode: image.verticalTileMode
- property alias source: image.source
-
- property int minWidth
- property int minHeight
- property int maxWidth
- property int maxHeight
- property int margin
-
- width: 240; height: 240
-
- BorderImage {
- id: image; anchors.centerIn: parent
-
- SequentialAnimation on width {
- loops: Animation.Infinite
- NumberAnimation {
- from: container.minWidth; to: container.maxWidth
- duration: 2000; easing.type: Easing.InOutQuad
- }
- NumberAnimation {
- from: container.maxWidth; to: container.minWidth
- duration: 2000; easing.type: Easing.InOutQuad
- }
- }
-
- SequentialAnimation on height {
- loops: Animation.Infinite
- NumberAnimation {
- from: container.minHeight; to: container.maxHeight
- duration: 2000; easing.type: Easing.InOutQuad
- }
- NumberAnimation {
- from: container.maxHeight; to: container.minHeight
- duration: 2000; easing.type: Easing.InOutQuad
- }
- }
-
- border.top: container.margin
- border.left: container.margin
- border.bottom: container.margin
- border.right: container.margin
- }
-}
diff --git a/examples/declarative/imageelements/shadows/qml/content/ShadowRectangle.qml b/examples/declarative/imageelements/shadows/qml/content/ShadowRectangle.qml
deleted file mode 100644
index 839ecf1177..0000000000
--- a/examples/declarative/imageelements/shadows/qml/content/ShadowRectangle.qml
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 1.0
-
-Item {
- property alias color : rectangle.color
-
- BorderImage {
- anchors.fill: rectangle
- anchors { leftMargin: -6; topMargin: -6; rightMargin: -8; bottomMargin: -8 }
- border { left: 10; top: 10; right: 10; bottom: 10 }
- source: "shadow.png"; smooth: true
- }
-
- Rectangle { id: rectangle; anchors.fill: parent }
-}
diff --git a/examples/declarative/imageelements/shadows/qml/content/bw.png b/examples/declarative/imageelements/shadows/qml/content/bw.png
deleted file mode 100644
index 486eaae96e..0000000000
--- a/examples/declarative/imageelements/shadows/qml/content/bw.png
+++ /dev/null
Binary files differ
diff --git a/examples/declarative/imageelements/shadows/qml/content/colors-round.sci b/examples/declarative/imageelements/shadows/qml/content/colors-round.sci
deleted file mode 100644
index 506f6f5f99..0000000000
--- a/examples/declarative/imageelements/shadows/qml/content/colors-round.sci
+++ /dev/null
@@ -1,7 +0,0 @@
-border.left:30
-border.top:30
-border.right:30
-border.bottom:30
-horizontalTileRule:Round
-verticalTileRule:Round
-source:colors.png
diff --git a/examples/declarative/imageelements/shadows/qml/content/colors-stretch.sci b/examples/declarative/imageelements/shadows/qml/content/colors-stretch.sci
deleted file mode 100644
index e4989a723c..0000000000
--- a/examples/declarative/imageelements/shadows/qml/content/colors-stretch.sci
+++ /dev/null
@@ -1,5 +0,0 @@
-border.left:30
-border.top:30
-border.right:30
-border.bottom:30
-source:colors.png
diff --git a/examples/declarative/imageelements/shadows/qml/content/colors.png b/examples/declarative/imageelements/shadows/qml/content/colors.png
deleted file mode 100644
index dfb62f3d64..0000000000
--- a/examples/declarative/imageelements/shadows/qml/content/colors.png
+++ /dev/null
Binary files differ
diff --git a/examples/declarative/imageelements/shadows/qml/content/shadow.png b/examples/declarative/imageelements/shadows/qml/content/shadow.png
deleted file mode 100644
index 431af8545d..0000000000
--- a/examples/declarative/imageelements/shadows/qml/content/shadow.png
+++ /dev/null
Binary files differ
diff --git a/examples/declarative/imageelements/shadows/qml/shadows.qml b/examples/declarative/imageelements/shadows/qml/shadows.qml
deleted file mode 100644
index d547f63eac..0000000000
--- a/examples/declarative/imageelements/shadows/qml/shadows.qml
+++ /dev/null
@@ -1,64 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 1.0
-import "content"
-
-Rectangle {
- id: window
-
- width: 480; height: 320
- color: "gray"
-
- ShadowRectangle {
- anchors.centerIn: parent; width: 250; height: 250
- color: "lightsteelblue"
- }
-
- ShadowRectangle {
- anchors.centerIn: parent; width: 200; height: 200
- color: "steelblue"
- }
-
- ShadowRectangle {
- anchors.centerIn: parent; width: 150; height: 150
- color: "thistle"
- }
-}
diff --git a/examples/declarative/imageelements/shadows/qmlapplicationviewer/qmlapplicationviewer.cpp b/examples/declarative/imageelements/shadows/qmlapplicationviewer/qmlapplicationviewer.cpp
deleted file mode 100644
index 411a04c139..0000000000
--- a/examples/declarative/imageelements/shadows/qmlapplicationviewer/qmlapplicationviewer.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// checksum 0x28c7 version 0x2000a
-/*
- This file was generated by the Qt Quick Application wizard of Qt Creator.
- QmlApplicationViewer is a convenience class containing mobile device specific
- code such as screen orientation handling. Also QML paths and debugging are
- handled here.
- It is recommended not to modify this file, since newer versions of Qt Creator
- may offer an updated version of it.
-*/
-
-#include "qmlapplicationviewer.h"
-
-#include <QtCore/QCoreApplication>
-#include <QtCore/QDir>
-#include <QtCore/QFileInfo>
-#include <QtDeclarative/QDeclarativeComponent>
-#include <QtDeclarative/QDeclarativeEngine>
-#include <QtDeclarative/QDeclarativeContext>
-
-#if defined(QMLJSDEBUGGER)
-#include <qt_private/qdeclarativedebughelper_p.h>
-#endif
-
-#if defined(QMLJSDEBUGGER) && !defined(NO_JSDEBUGGER)
-#include <jsdebuggeragent.h>
-#endif
-#if defined(QMLJSDEBUGGER) && !defined(NO_QMLOBSERVER)
-#include <qdeclarativeviewobserver.h>
-#endif
-
-#if defined(Q_OS_SYMBIAN) && defined(ORIENTATIONLOCK)
-#include <eikenv.h>
-#include <eikappui.h>
-#include <aknenv.h>
-#include <aknappui.h>
-#endif // Q_OS_SYMBIAN && ORIENTATIONLOCK
-
-#if defined(QMLJSDEBUGGER)
-
-// Enable debugging before any QDeclarativeEngine is created
-struct QmlJsDebuggingEnabler
-{
- QmlJsDebuggingEnabler()
- {
- QDeclarativeDebugHelper::enableDebugging();
- }
-};
-
-// Execute code in constructor before first QDeclarativeEngine is instantiated
-static QmlJsDebuggingEnabler enableDebuggingHelper;
-
-#endif // QMLJSDEBUGGER
-
-class QmlApplicationViewerPrivate
-{
- QString mainQmlFile;
- friend class QmlApplicationViewer;
- static QString adjustPath(const QString &path);
-};
-
-QString QmlApplicationViewerPrivate::adjustPath(const QString &path)
-{
-#ifdef Q_OS_UNIX
-#ifdef Q_OS_MAC
- if (!QDir::isAbsolutePath(path))
- return QCoreApplication::applicationDirPath()
- + QLatin1String("/../Resources/") + path;
-#else
- const QString pathInShareDir = QCoreApplication::applicationDirPath()
- + QLatin1String("/../share/")
- + QFileInfo(QCoreApplication::applicationFilePath()).fileName()
- + QLatin1Char('/') + path;
- if (QFileInfo(pathInShareDir).exists())
- return pathInShareDir;
-#endif
-#endif
- return path;
-}
-
-QmlApplicationViewer::QmlApplicationViewer(QWidget *parent) :
- QDeclarativeView(parent),
- m_d(new QmlApplicationViewerPrivate)
-{
- connect(engine(), SIGNAL(quit()), SLOT(close()));
- setResizeMode(QDeclarativeView::SizeRootObjectToView);
-#if defined(QMLJSDEBUGGER) && !defined(NO_JSDEBUGGER)
- new QmlJSDebugger::JSDebuggerAgent(engine());
-#endif
-#if defined(QMLJSDEBUGGER) && !defined(NO_QMLOBSERVER)
- new QmlJSDebugger::QDeclarativeViewObserver(this, parent);
-#endif
-}
-
-QmlApplicationViewer::~QmlApplicationViewer()
-{
- delete m_d;
-}
-
-void QmlApplicationViewer::setMainQmlFile(const QString &file)
-{
- m_d->mainQmlFile = QmlApplicationViewerPrivate::adjustPath(file);
- setSource(QUrl::fromLocalFile(m_d->mainQmlFile));
-}
-
-void QmlApplicationViewer::addImportPath(const QString &path)
-{
- engine()->addImportPath(QmlApplicationViewerPrivate::adjustPath(path));
-}
-
-void QmlApplicationViewer::setOrientation(ScreenOrientation orientation)
-{
-#ifdef Q_OS_SYMBIAN
- if (orientation != ScreenOrientationAuto) {
-#if defined(ORIENTATIONLOCK)
- const CAknAppUiBase::TAppUiOrientation uiOrientation =
- (orientation == ScreenOrientationLockPortrait) ? CAknAppUi::EAppUiOrientationPortrait
- : CAknAppUi::EAppUiOrientationLandscape;
- CAknAppUi* appUi = dynamic_cast<CAknAppUi*> (CEikonEnv::Static()->AppUi());
- TRAPD(error,
- if (appUi)
- appUi->SetOrientationL(uiOrientation);
- );
- Q_UNUSED(error)
-#else // ORIENTATIONLOCK
- qWarning("'ORIENTATIONLOCK' needs to be defined on Symbian when locking the orientation.");
-#endif // ORIENTATIONLOCK
- }
-#elif defined(Q_WS_MAEMO_5)
- Qt::WidgetAttribute attribute;
- switch (orientation) {
- case ScreenOrientationLockPortrait:
- attribute = Qt::WA_Maemo5PortraitOrientation;
- break;
- case ScreenOrientationLockLandscape:
- attribute = Qt::WA_Maemo5LandscapeOrientation;
- break;
- case ScreenOrientationAuto:
- default:
- attribute = Qt::WA_Maemo5AutoOrientation;
- break;
- }
- setAttribute(attribute, true);
-#else // Q_OS_SYMBIAN
- Q_UNUSED(orientation);
-#endif // Q_OS_SYMBIAN
-}
-
-void QmlApplicationViewer::showExpanded()
-{
-#ifdef Q_OS_SYMBIAN
- showFullScreen();
-#elif defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
- showMaximized();
-#else
- show();
-#endif
-}
diff --git a/examples/declarative/imageelements/shadows/qmlapplicationviewer/qmlapplicationviewer.h b/examples/declarative/imageelements/shadows/qmlapplicationviewer/qmlapplicationviewer.h
deleted file mode 100644
index f5b24b0199..0000000000
--- a/examples/declarative/imageelements/shadows/qmlapplicationviewer/qmlapplicationviewer.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// checksum 0x5a59 version 0x2000a
-/*
- This file was generated by the Qt Quick Application wizard of Qt Creator.
- QmlApplicationViewer is a convenience class containing mobile device specific
- code such as screen orientation handling. Also QML paths and debugging are
- handled here.
- It is recommended not to modify this file, since newer versions of Qt Creator
- may offer an updated version of it.
-*/
-
-#ifndef QMLAPPLICATIONVIEWER_H
-#define QMLAPPLICATIONVIEWER_H
-
-#include <QtDeclarative/QDeclarativeView>
-
-class QmlApplicationViewer : public QDeclarativeView
-{
- Q_OBJECT
-
-public:
- enum ScreenOrientation {
- ScreenOrientationLockPortrait,
- ScreenOrientationLockLandscape,
- ScreenOrientationAuto
- };
-
- explicit QmlApplicationViewer(QWidget *parent = 0);
- virtual ~QmlApplicationViewer();
-
- void setMainQmlFile(const QString &file);
- void addImportPath(const QString &path);
- void setOrientation(ScreenOrientation orientation);
- void showExpanded();
-
-private:
- class QmlApplicationViewerPrivate *m_d;
-};
-
-#endif // QMLAPPLICATIONVIEWER_H
diff --git a/examples/declarative/imageelements/shadows/qmlapplicationviewer/qmlapplicationviewer.pri b/examples/declarative/imageelements/shadows/qmlapplicationviewer/qmlapplicationviewer.pri
deleted file mode 100644
index 1c0c7edb39..0000000000
--- a/examples/declarative/imageelements/shadows/qmlapplicationviewer/qmlapplicationviewer.pri
+++ /dev/null
@@ -1,154 +0,0 @@
-# checksum 0x3dc8 version 0x2000a
-# This file was generated by the Qt Quick Application wizard of Qt Creator.
-# The code below adds the QmlApplicationViewer to the project and handles the
-# activation of QML debugging.
-# It is recommended not to modify this file, since newer versions of Qt Creator
-# may offer an updated version of it.
-
-QT += declarative
-
-SOURCES += $$PWD/qmlapplicationviewer.cpp
-HEADERS += $$PWD/qmlapplicationviewer.h
-INCLUDEPATH += $$PWD
-
-defineTest(minQtVersion) {
- maj = $$1
- min = $$2
- patch = $$3
- isEqual(QT_MAJOR_VERSION, $$maj) {
- isEqual(QT_MINOR_VERSION, $$min) {
- isEqual(QT_PATCH_VERSION, $$patch) {
- return(true)
- }
- greaterThan(QT_PATCH_VERSION, $$patch) {
- return(true)
- }
- }
- greaterThan(QT_MINOR_VERSION, $$min) {
- return(true)
- }
- }
- return(false)
-}
-
-contains(DEFINES, QMLJSDEBUGGER) {
- CONFIG(debug, debug|release) {
- !minQtVersion(4, 7, 1) {
- warning()
- warning("Disabling QML debugging:")
- warning()
- warning("Debugging QML requires the qmljsdebugger library that ships with Qt Creator.")
- warning("This library requires Qt 4.7.1 or newer.")
- warning()
- DEFINES -= QMLJSDEBUGGER
- } else:isEmpty(QMLJSDEBUGGER_PATH) {
- warning()
- warning("Disabling QML debugging:")
- warning()
- warning("Debugging QML requires the qmljsdebugger library that ships with Qt Creator.")
- warning("Please specify its location on the qmake command line, eg")
- warning(" qmake -r QMLJSDEBUGGER_PATH=$CREATORDIR/share/qtcreator/qmljsdebugger")
- warning()
- DEFINES -= QMLJSDEBUGGER
- } else {
- include($$QMLJSDEBUGGER_PATH/qmljsdebugger-lib.pri)
- }
- } else {
- DEFINES -= QMLJSDEBUGGER
- }
-}
-# This file was generated by an application wizard of Qt Creator.
-# The code below handles deployment to Symbian and Maemo, aswell as copying
-# of the application data to shadow build directories on desktop.
-# It is recommended not to modify this file, since newer versions of Qt Creator
-# may offer an updated version of it.
-
-defineTest(qtcAddDeployment) {
-for(deploymentfolder, DEPLOYMENTFOLDERS) {
- item = item$${deploymentfolder}
- itemsources = $${item}.sources
- $$itemsources = $$eval($${deploymentfolder}.source)
- itempath = $${item}.path
- $$itempath= $$eval($${deploymentfolder}.target)
- export($$itemsources)
- export($$itempath)
- DEPLOYMENT += $$item
-}
-
-MAINPROFILEPWD = $$PWD
-
-symbian {
- ICON = $${TARGET}.svg
- TARGET.EPOCHEAPSIZE = 0x20000 0x2000000
- contains(DEFINES, ORIENTATIONLOCK):LIBS += -lavkon -leikcore -lcone
- contains(DEFINES, NETWORKACCESS):TARGET.CAPABILITY += NetworkServices
-} else:win32 {
- !isEqual(PWD,$$OUT_PWD) {
- copyCommand = @echo Copying application data...
- for(deploymentfolder, DEPLOYMENTFOLDERS) {
- source = $$eval($${deploymentfolder}.source)
- pathSegments = $$split(source, /)
- sourceAndTarget = $$MAINPROFILEPWD/$$source $$OUT_PWD/$$eval($${deploymentfolder}.target)/$$last(pathSegments)
- copyCommand += && $(COPY_DIR) $$replace(sourceAndTarget, /, \\)
- }
- copydeploymentfolders.commands = $$copyCommand
- first.depends = $(first) copydeploymentfolders
- export(first.depends)
- export(copydeploymentfolders.commands)
- QMAKE_EXTRA_TARGETS += first copydeploymentfolders
- }
-} else:unix {
- maemo5 {
- installPrefix = /opt/usr
- desktopfile.path = /usr/share/applications/hildon
- } else {
- installPrefix = /usr/local
- desktopfile.path = /usr/share/applications
- !isEqual(PWD,$$OUT_PWD) {
- copyCommand = @echo Copying application data...
- for(deploymentfolder, DEPLOYMENTFOLDERS) {
- macx {
- target = $$OUT_PWD/$${TARGET}.app/Contents/Resources/$$eval($${deploymentfolder}.target)
- } else {
- target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
- }
- copyCommand += && $(MKDIR) $$target
- copyCommand += && $(COPY_DIR) $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source) $$target
- }
- copydeploymentfolders.commands = $$copyCommand
- first.depends = $(first) copydeploymentfolders
- export(first.depends)
- export(copydeploymentfolders.commands)
- QMAKE_EXTRA_TARGETS += first copydeploymentfolders
- }
- }
- for(deploymentfolder, DEPLOYMENTFOLDERS) {
- item = item$${deploymentfolder}
- itemfiles = $${item}.files
- $$itemfiles = $$eval($${deploymentfolder}.source)
- itempath = $${item}.path
- $$itempath = $${installPrefix}/share/$${TARGET}/$$eval($${deploymentfolder}.target)
- export($$itemfiles)
- export($$itempath)
- INSTALLS += $$item
- }
- icon.files = $${TARGET}.png
- icon.path = /usr/share/icons/hicolor/64x64/apps
- desktopfile.files = $${TARGET}.desktop
- target.path = $${installPrefix}/bin
- export(icon.files)
- export(icon.path)
- export(desktopfile.files)
- export(desktopfile.path)
- export(target.path)
- INSTALLS += desktopfile icon target
-}
-
-export (ICON)
-export (INSTALLS)
-export (DEPLOYMENT)
-export (TARGET.EPOCHEAPSIZE)
-export (TARGET.CAPABILITY)
-export (LIBS)
-export (QMAKE_EXTRA_TARGETS)
-}
diff --git a/examples/declarative/imageelements/shadows/shadows.desktop b/examples/declarative/imageelements/shadows/shadows.desktop
deleted file mode 100644
index 83acea36a1..0000000000
--- a/examples/declarative/imageelements/shadows/shadows.desktop
+++ /dev/null
@@ -1,11 +0,0 @@
-[Desktop Entry]
-Encoding=UTF-8
-Version=1.0
-Type=Application
-Terminal=false
-Name=shadows
-Exec=/opt/usr/bin/shadows
-Icon=shadows
-X-Window-Icon=
-X-HildonDesk-ShowInToolbar=true
-X-Osso-Type=application/x-executable
diff --git a/examples/declarative/imageelements/shadows/shadows.png b/examples/declarative/imageelements/shadows/shadows.png
deleted file mode 100644
index 707d5c4e85..0000000000
--- a/examples/declarative/imageelements/shadows/shadows.png
+++ /dev/null
Binary files differ
diff --git a/examples/declarative/imageelements/shadows/shadows.pro b/examples/declarative/imageelements/shadows/shadows.pro
deleted file mode 100644
index 6c8889682c..0000000000
--- a/examples/declarative/imageelements/shadows/shadows.pro
+++ /dev/null
@@ -1,39 +0,0 @@
-# Add more folders to ship with the application, here
-folder_01.source = qml
-folder_01.target = qml
-DEPLOYMENTFOLDERS = folder_01
-
-# Additional import path used to resolve QML modules in Creator's code model
-QML_IMPORT_PATH =
-
-# Avoid auto screen rotation
-DEFINES += ORIENTATIONLOCK
-
-# Needs to be defined for Symbian
-#DEFINES += NETWORKACCESS
-
-symbian:TARGET.UID3 = 0xE2C00C58
-
-# Smart Installer package's UID
-# This UID is from the protected range
-# and therefore the package will fail to install if self-signed
-# By default qmake uses the unprotected range value if unprotected UID is defined for the application
-# and 0x2002CCCF value if protected UID is given to the application
-#symbian:DEPLOYMENT.installer_header = 0x2002CCCF
-
-# Define QMLJSDEBUGGER to allow debugging of QML in debug builds
-# (This might significantly increase build time)
-# DEFINES += QMLJSDEBUGGER
-
-# If your application uses the Qt Mobility libraries, uncomment
-# the following lines and add the respective components to the
-# MOBILITY variable.
-# CONFIG += mobility
-# MOBILITY +=
-
-# The .cpp file which was generated for your project. Feel free to hack it.
-SOURCES += main.cpp
-
-# Please do not modify the following two lines. Required for deployment.
-include(qmlapplicationviewer/qmlapplicationviewer.pri)
-qtcAddDeployment()
diff --git a/examples/declarative/imageelements/shadows/shadows.svg b/examples/declarative/imageelements/shadows/shadows.svg
deleted file mode 100644
index 566acfada0..0000000000
--- a/examples/declarative/imageelements/shadows/shadows.svg
+++ /dev/null
@@ -1,93 +0,0 @@
-<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- height="44px"
- version="1.1"
- viewBox="0 0 44 44"
- width="44px"
- x="0px"
- y="0px"
- id="svg2"
- inkscape:version="0.47 r22583"
- sodipodi:docname="qt.svg">
- <metadata
- id="metadata18">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <defs
- id="defs16">
- <inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="0 : 22 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_z="44 : 22 : 1"
- inkscape:persp3d-origin="22 : 14.666667 : 1"
- id="perspective2836" />
- </defs>
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1920"
- inkscape:window-height="1020"
- id="namedview14"
- showgrid="false"
- inkscape:zoom="21.454545"
- inkscape:cx="49.412871"
- inkscape:cy="21.894358"
- inkscape:window-x="-4"
- inkscape:window-y="-4"
- inkscape:window-maximized="1"
- inkscape:current-layer="g3" />
- <g
- transform="matrix(0.18308778,0,0,0.18308778,6.6100946,3.2385199)"
- id="g3">
- <path
- d="M 43.09,0.3586 C 40.94,0.0036 38.84,-0.0824 36.81,0.0776 31.968136,0.39505671 27.122677,0.73638425 22.28,1.0696 9.62,2.0816 0,12.4996 0,26.8896 l 0,169.7 14.19,13.2 28.87,-209.42 0.03,-0.011 z"
- style="fill:#006225"
- id="path5"
- sodipodi:nodetypes="cccccccc" />
- <path
- d="m 174.4,160 c 0,12.5 -7.75,24.07 -17.57,25.77 L 14.23,209.73 V 25.93 C 14.23,9.21 27.57,-2.27 43.12,0.3 l 131.3,21.52 v 138.2 z"
- style="fill:#80c342"
- id="path7" />
- <path
- d="m 154.9,80.96 -12.96,-0.598 0,0.278 6.945,0.32 6.016,0 z"
- style="fill:#006225"
- id="path11" />
- <path
- d="m 144.6,135.6 c 0.66,0.328 1.43,0.476 2.351,0.476 0.161,0 0.329,-0.004 0.497,-0.016 2.55,-0.148 5.32,-0.933 8.343,-2.308 h -6.015 c -1.821,0.832 -3.532,1.457 -5.176,1.848 z"
- style="fill:#006225"
- id="path13" />
- <path
- id="path17"
- style="fill:#ffffff"
- d="m 91.15,132.4 c 2.351,-6.051 3.511,-17.91 3.511,-35.62 0,-15.89 -1.148,-26.82 -3.484,-32.81 -2.336,-6.027 -5.832,-9.281 -10.52,-9.691 -0.359,-0.031 -0.714,-0.051 -1.058,-0.051 -4.34,0 -7.68,2.535 -10.01,7.625 -2.52,5.543 -3.793,17.04 -3.793,34.44 0,16.82 1.238,28.75 3.734,35.75 2.356,6.672 5.879,9.976 10.5,9.976 0.207,0 0.41,-0.008 0.621,-0.019 4.633,-0.293 8.121,-3.496 10.49,-9.602 m 17.98,3.75 c -4.117,9.707 -10.39,16.06 -18.99,19 0.867,4.449 2.176,7.441 3.922,9.019 1.351,1.211 3.433,1.821 6.222,1.821 0.805,0 1.668,-0.055 2.59,-0.157 v 13.12 l -5.961,0.782 c -1.758,0.23 -3.426,0.343 -5.004,0.343 -5.218,0 -9.445,-1.265 -12.62,-3.824 -4.207,-3.379 -7.308,-9.894 -9.297,-19.54 -9.136,-1.945 -16.26,-7.754 -21.19,-17.5 -5.004,-9.902 -7.551,-24.39 -7.551,-43.34 0,-20.43 3.484,-35.51 10.34,-45.07 5.789,-8.07 13.86,-12.04 24.02,-12.04 1.629,0 3.309,0.102 5.043,0.305 11.95,1.375 20.62,7.016 26.26,16.79 5.535,9.562 8.254,23.27 8.254,41.26 0,16.48 -2,29.45 -6.043,39.02 z M 130.4,45.91 l 11.52,1.238 0,20.21 12.96,0.914 0,12.68 -12.96,-0.598 0,46.33 c 0,4.032 0.445,6.625 1.34,7.789 0.8,1.067 2.046,1.594 3.71,1.594 0.161,0 0.329,-0.004 0.497,-0.016 2.55,-0.148 5.32,-0.933 8.343,-2.308 v 11.65 c -5.136,2.258 -10.18,3.598 -15.12,4.02 -0.718,0.055 -1.41,0.086 -2.078,0.086 -4.48,0 -7.906,-1.301 -10.25,-3.934 -2.73,-3.051 -4.09,-7.949 -4.09,-14.67 V 79.535 L 118.046,79.25 V 65.66 l 7.586,0.547 4.773,-20.3 z" />
- <path
- d="m 100.3,166 c 0.809,0 1.672,-0.055 2.59,-0.157 H 98.054 C 98.73,165.949 99.507,166 100.3,166 z"
- style="fill:#006225"
- id="path19" />
- <path
- id="path21"
- style="fill:#006225"
- d="m 84.85,63.98 c 2.336,5.997 3.484,16.92 3.484,32.81 0,17.7 -1.16,29.57 -3.512,35.62 -1.894,4.879 -4.527,7.902 -7.863,9.07 0.965,0.368 1.992,0.551 3.078,0.551 0.207,0 0.41,-0.008 0.621,-0.019 4.633,-0.293 8.121,-3.496 10.49,-9.602 2.351,-6.051 3.511,-17.91 3.511,-35.62 0,-15.89 -1.148,-26.82 -3.484,-32.81 -2.336,-6.027 -5.832,-9.281 -10.52,-9.691 -0.359,-0.031 -0.714,-0.051 -1.058,-0.051 -1.09,0 -2.117,0.16 -3.082,0.481 h -0.004 c 3.601,1.121 6.379,4.215 8.336,9.261 z m -2.344,114.3 c -0.113,-0.05 -0.227,-0.105 -0.336,-0.16 -0.012,-0.004 -0.023,-0.012 -0.035,-0.015 -0.102,-0.051 -0.207,-0.106 -0.309,-0.157 -0.019,-0.011 -0.039,-0.019 -0.058,-0.031 -0.09,-0.051 -0.184,-0.098 -0.278,-0.148 -0.027,-0.016 -0.054,-0.036 -0.086,-0.051 -0.082,-0.043 -0.164,-0.09 -0.242,-0.137 -0.039,-0.023 -0.078,-0.047 -0.113,-0.07 -0.07,-0.039 -0.145,-0.082 -0.215,-0.125 -0.047,-0.031 -0.094,-0.059 -0.14,-0.09 -0.059,-0.039 -0.118,-0.074 -0.176,-0.113 -0.059,-0.039 -0.114,-0.075 -0.168,-0.114 -0.051,-0.031 -0.102,-0.066 -0.149,-0.097 -0.066,-0.047 -0.132,-0.094 -0.195,-0.137 -0.039,-0.027 -0.078,-0.055 -0.113,-0.082 -0.078,-0.055 -0.153,-0.113 -0.231,-0.172 -0.023,-0.016 -0.05,-0.035 -0.078,-0.055 -0.098,-0.078 -0.199,-0.156 -0.297,-0.234 -4.207,-3.379 -7.308,-9.894 -9.297,-19.54 -9.136,-1.945 -16.26,-7.754 -21.19,-17.5 -5.004,-9.902 -7.551,-24.39 -7.551,-43.34 0,-20.43 3.484,-35.51 10.34,-45.07 5.789,-8.07 13.86,-12.04 24.02,-12.04 h -6.351 c -10.15,0.008 -18.22,3.977 -24,12.04 -6.855,9.563 -10.34,24.64 -10.34,45.07 0,18.95 2.547,33.44 7.551,43.34 4.934,9.75 12.05,15.56 21.19,17.5 1.989,9.641 5.09,16.16 9.297,19.54 3.176,2.559 7.403,3.824 12.62,3.824 0.098,0 0.199,0 0.297,-0.004 h 5.539 c -3.406,-0.05 -6.383,-0.66 -8.906,-1.828 L 82.498,178.28 z M 128.4,145.6 c -2.73,-3.051 -4.09,-7.949 -4.09,-14.67 V 79.57 l -6.226,-0.285 v -13.59 h -6.016 v 3.035 c 0.871,3.273 1.555,6.82 2.063,10.64 l 4.164,0.192 v 51.36 c 0,6.723 1.367,11.62 4.09,14.67 2.343,2.633 5.765,3.934 10.25,3.934 h 6.015 c -4.48,0 -7.906,-1.301 -10.25,-3.934 z m 2.043,-99.66 -6.016,0 -4.668,19.88 5.911,0.422 4.773,-20.3 z" />
- </g>
-</svg>
diff --git a/examples/declarative/inputmethods/inputmethods.qmlproject b/examples/declarative/inputmethods/inputmethods.qmlproject
deleted file mode 100644
index d4909f8685..0000000000
--- a/examples/declarative/inputmethods/inputmethods.qmlproject
+++ /dev/null
@@ -1,16 +0,0 @@
-import QmlProject 1.0
-
-Project {
- /* Include .qml, .js, and image files from current directory and subdirectories */
- QmlFiles {
- directory: "."
- }
- JavaScriptFiles {
- directory: "."
- }
- ImageFiles {
- directory: "."
- }
- /* List of plugin directories passed to QML runtime */
- // importPaths: [ " ../exampleplugin " ]
-}
diff --git a/examples/declarative/inputmethods/spellcheck/Keyboard.qml b/examples/declarative/inputmethods/spellcheck/Keyboard.qml
deleted file mode 100644
index 533762e7ba..0000000000
--- a/examples/declarative/inputmethods/spellcheck/Keyboard.qml
+++ /dev/null
@@ -1,141 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.0
-import Qt.labs.inputcontext 1.0 as InputContext
-
-
-Rectangle {
- id: keyboard
-
- radius: 5
- height: 122
- width: 324
-
- property bool shift: false
-
- gradient: Gradient {
- GradientStop { position: 0.0; color: "lightgrey" }
- GradientStop { position: 1.0; color: "white" }
- }
-
- Column {
- anchors.left: parent.left; anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
-
- spacing: 2
-
- Row {
- spacing: 2
- anchors.horizontalCenter: parent.horizontalCenter
-
- Key { key: Qt.Key_Q; text: "q"; }
- Key { key: Qt.Key_W; text: "w"; }
- Key { key: Qt.Key_E; text: "e"; }
- Key { key: Qt.Key_R; text: "r"; }
- Key { key: Qt.Key_T; text: "t"; }
- Key { key: Qt.Key_Y; text: "y"; }
- Key { key: Qt.Key_U; text: "u"; }
- Key { key: Qt.Key_I; text: "i"; }
- Key { key: Qt.Key_O; text: "o"; }
- Key { key: Qt.Key_P; text: "p"; }
- }
- Row {
- spacing: 2
- anchors.horizontalCenter: parent.horizontalCenter
-
- Key { key: Qt.Key_A; text: "a"; }
- Key { key: Qt.Key_S; text: "s"; }
- Key { key: Qt.Key_D; text: "d"; }
- Key { key: Qt.Key_F; text: "f"; }
- Key { key: Qt.Key_G; text: "g"; }
- Key { key: Qt.Key_H; text: "h"; }
- Key { key: Qt.Key_J; text: "j"; }
- Key { key: Qt.Key_K; text: "k"; }
- Key { key: Qt.Key_L; text: "l"; }
- }
- Row {
- spacing: 2
- anchors.horizontalCenter: parent.horizontalCenter
-
- Key { key: Qt.Key_Shift; displayText: "shift"; width: 50 }
- Key { key: Qt.Key_Z; text: "z"; }
- Key { key: Qt.Key_X; text: "x"; }
- Key { key: Qt.Key_C; text: "c"; }
- Key { key: Qt.Key_V; text: "v"; }
- Key { key: Qt.Key_B; text: "b"; }
- Key { key: Qt.Key_N; text: "n"; }
- Key { key: Qt.Key_M; text: "m"; }
- Key { key: Qt.Key_Comma; text: ","; }
- Key { key: Qt.Key_Period; text: "."; }
- }
-
- Row {
- spacing: 2
- anchors.horizontalCenter: parent.horizontalCenter
-
- Key { key: Qt.Key_Enter; text: "\n"; displayText: "enter"; width: 90 }
- Key { key: Qt.Key_Space; text: " "; displayText: "space"; width: 138}
- Key { key: Qt.Key_Backspace; displayText: "backspace"; width: 90 }
- }
- }
-
- function keyPress(key, text)
- {
- if (key == Qt.Key_Shift)
- keyboard.shift = !keyboard.shift
- else if (keyboard.shift)
- InputContext.sendKeyPress(key, text.toUpperCase(), Qt.ShiftModifier)
- else
- InputContext.sendKeyPress(key, text)
- }
-
- function keyRelease(key, text)
- {
- if (key != Qt.Key_Shift) {
- if (keyboard.shift) {
- InputContext.sendKeyRelease(key, text.toUpperCase(), Qt.ShiftModifier)
- keyboard.shift = false
- } else {
- InputContext.sendKeyRelease(key, text)
- }
- }
- }
-}
diff --git a/examples/declarative/inputmethods/spellcheck/spellcheck.qml b/examples/declarative/inputmethods/spellcheck/spellcheck.qml
deleted file mode 100644
index 57e81451a6..0000000000
--- a/examples/declarative/inputmethods/spellcheck/spellcheck.qml
+++ /dev/null
@@ -1,137 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.0
-import Qt.labs.inputcontext 1.0 as InputContext
-
-Item {
- width: 360
- height: 240
-
- function filterKeyPress(key, text)
- {
- switch (key) {
- case Qt.Key_Enter:
- case Qt.Key_Return:
- case Qt.Key_Space:
- case Qt.Key_Tab:
- if (InputContext.preeditText != "")
- InputContext.commit();
- break;
- case Qt.Key_Backspace:
- if (InputContext.preeditText != "") {
- InputContext.preeditText = InputContext.preeditText.substr(0, InputContext.preeditText.length - 1);
- return true;
- }
- break;
- default:
- if (text != "") {
- InputContext.preeditText += text
- return true;
- } else if (InputContext.preeditText != "") {
- InputContext.commit();
- }
- break;
- }
- return false;
- }
-
- Rectangle {
- anchors.left: parent.left; anchors.top: parent.top; anchors.right: parent.right;
- anchors.bottom: keyboard.top
- anchors.margins: 2
-
- border.width: 1
- radius: 2
-
- TextEdit {
- id: textEdit
-
- wrapMode: TextEdit.WordWrap
-
- anchors.fill: parent
- anchors.margins: 2
- }
-
- MouseArea {
- anchors.fill: textEdit
-
- onPressed: {
- mouse.accepted = false
- var position = textEdit.positionAt(mouse.x, mouse.y);
- if (position != textEdit.cursorPosition) {
- InputContext.commit()
- textEdit.cursorPosition = textEdit.positionAt(mouse.x, mouse.y)
- textEdit.selectWord()
- var word = textEdit.selectedText
- if (word != "") {
- InputContext.commit("");
- InputContext.preeditText = word;
- }
- }
- }
- }
- }
-
- WordSuggestions {}
-
- Keyboard {
- id: keyboard
- anchors.horizontalCenter: parent.horizontalCenter
-
- y: parent.height
-
- states: [
- State {
- name: "visible"
- PropertyChanges { target: keyboard; y: parent.height - height }
- when: InputContext.softwareInputPanelVisible
- },
- State {
- name: "hidden"
- PropertyChanges { target: keyboard; y: parent.height }
- when: !InputContext.softwareInputPanelVisible
- }
- ]
- transitions: Transition {
- NumberAnimation { properties: "y"; easing.type: Easing.InOutQuad; duration: 100 }
- }
- }
-}
diff --git a/examples/declarative/modelviews/listview/content/ToggleButton.qml b/examples/declarative/modelviews/listview/content/ToggleButton.qml
index 2d8221e915..756f5a618f 100644
--- a/examples/declarative/modelviews/listview/content/ToggleButton.qml
+++ b/examples/declarative/modelviews/listview/content/ToggleButton.qml
@@ -1,3 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
import QtQuick 2.0
Rectangle {
diff --git a/examples/declarative/modelviews/visualdatamodel/dragselection.qml b/examples/declarative/modelviews/visualdatamodel/dragselection.qml
new file mode 100644
index 0000000000..afbea1ff94
--- /dev/null
+++ b/examples/declarative/modelviews/visualdatamodel/dragselection.qml
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ id: root
+
+ width: 320
+ height: 480
+
+ property bool dragging: false
+
+ Component {
+ id: packageDelegate
+ Package {
+ id: packageRoot
+
+ MouseArea {
+ id: visibleContainer
+ Package.name: "visible"
+
+ width: 64
+ height: 64
+ enabled: packageRoot.VisualDataModel.inSelected
+
+ drag.target: draggable
+
+ Item {
+ id: draggable
+
+ width: 64
+ height: 64
+
+ Drag.active: visibleContainer.drag.active
+
+ anchors { horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter }
+
+ states: State {
+ when: visibleContainer.drag.active
+ AnchorChanges { target: draggable; anchors { horizontalCenter: undefined; verticalCenter: undefined} }
+ ParentChange { target: selectionView; parent: draggable; x: 0; y: 0 }
+ PropertyChanges { target: root; dragging: true }
+ ParentChange { target: draggable; parent: root }
+ }
+ }
+ DropArea {
+ anchors.fill: parent
+ onEntered: visualModel.items.move(selectedItems, 0, packageRoot.VisualDataModel.itemsIndex, selectedItems.count)
+ }
+ }
+ Item {
+ id: selectionContainer
+ Package.name: "selection"
+
+ width: 64
+ height: 64
+
+ visible: PathView.onPath
+ }
+ Rectangle {
+ id: content
+ parent: visibleContainer
+
+ width: 58
+ height: 58
+
+ radius: 8
+
+ gradient: Gradient {
+ GradientStop { id: gradientStart; position: 0.0; color: "#8AC953" }
+ GradientStop { id: gradientEnd; position: 1.0; color: "#8BC953" }
+ }
+
+ border.width: 2
+ border.color: "#007423"
+
+ state: root.dragging && packageRoot.VisualDataModel.inSelected ? "selected" : "visible"
+
+ Text {
+ anchors.fill: parent
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ color: "white"
+ text: modelData
+ font.pixelSize: 18
+ }
+
+ Rectangle {
+ anchors { right: parent.right; top: parent.top; margins: 3 }
+ width: 12; height: 12
+ color: packageRoot.VisualDataModel.inSelected ? "black" : "white"
+ radius: 6
+
+ border.color: "white"
+ border.width: 2
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: packageRoot.VisualDataModel.inSelected = !packageRoot.VisualDataModel.inSelected
+ }
+ }
+
+ states: [
+ State {
+ name: "selected"
+ ParentChange { target: content; parent: selectionContainer; x: 3; y: 3 }
+ PropertyChanges { target: packageRoot; VisualDataModel.inItems: visibleContainer.drag.active }
+ PropertyChanges { target: gradientStart; color: "#017423" }
+ PropertyChanges { target: gradientStart; color: "#007423" }
+ }, State {
+ name: "visible"
+ PropertyChanges { target: packageRoot; VisualDataModel.inItems: true }
+ ParentChange { target: content; parent: visibleContainer; x: 3; y: 3 }
+ PropertyChanges { target: gradientStart; color: "#8AC953" }
+ PropertyChanges { target: gradientStart; color: "#8BC953" }
+ }
+ ]
+ transitions: Transition {
+ PropertyAction { target: packageRoot; properties: "VisualDataModel.inItems" }
+ ParentAnimation {
+ target: content
+ NumberAnimation { target: content; properties: "x,y"; duration: 500 }
+ }
+ ColorAnimation { targets: [gradientStart, gradientEnd]; duration: 500 }
+ }
+ }
+ }
+ }
+
+ VisualDataModel {
+ id: visualModel
+ model: 35
+ delegate: packageDelegate
+
+ groups: VisualDataGroup { id: selectedItems; name: "selected" }
+
+ Component.onCompleted: parts.selection.filterOnGroup = "selected"
+ }
+
+ PathView {
+ id: selectionView
+
+ height: 64
+ width: 64
+
+ model: visualModel.parts.selection
+
+ path: Path {
+ startX: 0
+ startY: 0
+ PathLine { x: 64; y: 64 }
+ }
+ }
+
+ GridView {
+ id: itemsView
+ anchors { fill: parent }
+ cellWidth: 64
+ cellHeight: 64
+ model: visualModel.parts.visible
+ }
+}
diff --git a/examples/declarative/modelviews/visualdatamodel/slideshow.qml b/examples/declarative/modelviews/visualdatamodel/slideshow.qml
new file mode 100644
index 0000000000..edf1f0f057
--- /dev/null
+++ b/examples/declarative/modelviews/visualdatamodel/slideshow.qml
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+
+ property Item displayItem: null
+
+ width: 300; height: 400
+
+ color: "black"
+
+ VisualDataModel {
+ id: visualModel
+
+ model: XmlListModel {
+ source: "http://api.flickr.com/services/feeds/photos_public.gne?format=rss2"
+ query: "/rss/channel/item"
+ namespaceDeclarations: "declare namespace media=\"http://search.yahoo.com/mrss/\";"
+
+ XmlRole { name: "imagePath"; query: "media:thumbnail/@url/string()" }
+ XmlRole { name: "url"; query: "media:content/@url/string()" }
+ }
+
+ delegate: Item {
+ id: delegateItem
+
+ width: 76; height: 76
+
+ Rectangle {
+ id: image
+ x: 0; y: 0; width: 76; height: 76
+ border.width: 1
+ border.color: "white"
+ color: "black"
+
+ Image {
+ anchors.fill: parent
+ anchors.leftMargin: 1
+ anchors.topMargin: 1
+
+ source: imagePath
+ fillMode: Image.PreserveAspectFit
+
+ }
+
+ MouseArea {
+ id: clickArea
+ anchors.fill: parent
+
+ onClicked: root.displayItem = root.displayItem !== delegateItem ? delegateItem : null
+ }
+
+ states: [
+ State {
+ when: root.displayItem === delegateItem
+ name: "inDisplay";
+ ParentChange { target: image; parent: imageContainer; x: 75; y: 75; width: 150; height: 150 }
+ PropertyChanges { target: image; z: 2 }
+ PropertyChanges { target: delegateItem; VisualDataModel.inItems: false }
+ },
+ State {
+ when: root.displayItem !== delegateItem
+ name: "inList";
+ ParentChange { target: image; parent: delegateItem; x: 2; y: 2; width: 75; height: 75 }
+ PropertyChanges { target: image; z: 1 }
+ PropertyChanges { target: delegateItem; VisualDataModel.inItems: true }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ from: "inList"
+ SequentialAnimation {
+ PropertyAction { target: delegateItem; property: "VisualDataModel.inPersistedItems"; value: true }
+ ParentAnimation {
+ target: image;
+ via: root
+ NumberAnimation { target: image; properties: "x,y,width,height"; duration: 1000 }
+ }
+ }
+ }, Transition {
+ from: "inDisplay"
+ SequentialAnimation {
+ ParentAnimation {
+ target: image
+ NumberAnimation { target: image; properties: "x,y,width,height"; duration: 1000 }
+ }
+ PropertyAction { target: delegateItem; property: "VisualDataModel.inPersistedItems"; value: false }
+ }
+ }
+ ]
+ }
+ }
+ }
+
+
+ PathView {
+ id: imagePath
+
+ anchors { left: parent.left; top: imageContainer.bottom; right: parent.right; bottom: parent.bottom }
+ model: visualModel
+
+ pathItemCount: 7
+ path: Path {
+ startX: -50; startY: 0
+ PathQuad { x: 150; y: 50; controlX: 0; controlY: 50 }
+ PathQuad { x: 350; y: 0; controlX: 300; controlY: 50 }
+ }
+ }
+
+ Item {
+ id: imageContainer
+ anchors { fill: parent; bottomMargin: 100 }
+ }
+}
diff --git a/examples/declarative/modelviews/visualdatamodel/sortedmodel.qml b/examples/declarative/modelviews/visualdatamodel/sortedmodel.qml
new file mode 100644
index 0000000000..2a72060422
--- /dev/null
+++ b/examples/declarative/modelviews/visualdatamodel/sortedmodel.qml
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ width: 480; height: 640
+
+ Component {
+ id: numberDelegate
+
+ Text {
+ id: numberText
+ anchors { left: parent.left; right: parent.right }
+ text: number
+
+ horizontalAlignment: Text.AlignHCenter
+ font.pixelSize: 18
+
+ Text {
+ anchors { left: parent.left; baseline: parent.baseline }
+ text: index
+
+ horizontalAlignment: Text.AlignLeft
+ font.pixelSize: 12
+ }
+ Text {
+ anchors { right: parent.right; baseline: parent.baseline }
+ text: numberText.VisualDataModel.itemsIndex
+
+ horizontalAlignment: Text.AlignRight
+ font.pixelSize: 12
+ }
+ }
+ }
+
+ ListView {
+ anchors {
+ left: parent.left; top: parent.top;
+ right: parent.horizontalCenter; bottom: button.top
+ leftMargin: 2; topMargin: 2; rightMargin: 1; bottomMargin: 2
+ }
+
+ model: ListModel {
+ id: unsortedModel
+ }
+ delegate: numberDelegate
+ }
+ ListView {
+ anchors {
+ left: parent.horizontalCenter; top: parent.top;
+ right: parent.right; bottom: button.top
+ leftMargin: 1; topMargin: 2; rightMargin: 2; bottomMargin: 2
+ }
+ model: VisualDataModel {
+ model: unsortedModel
+ delegate: numberDelegate
+
+ items.onChanged: {
+ for (var i = 0; i < inserted.length; ++i) {
+ for (var j = inserted[i].index; j < inserted[i].index + inserted[i].count; ++j) {
+ var number = items.get(j).model.number
+ for (var l = 0, k = 0; l < unsortedModel.count; ++l) {
+ if (l == inserted[k].index) {
+ l += inserted[k].count - 1
+ ++k
+ } else if (number < items.get(l).model.number) {
+ items.move(j, l, 1)
+ break
+ }
+ }
+ inserted[i].index += 1;
+ inserted[i].count -= 1;
+ }
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ id: button
+
+ anchors { left: parent.left; right: parent.right; bottom: parent.bottom; margins: 2 }
+ height: moreText.implicitHeight + 4
+
+ color: "black"
+
+ Text {
+ id: moreText
+
+ anchors.fill: parent
+ text: "More"
+ color: "white"
+ font.pixelSize: 18
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+ MouseArea {
+ anchors.fill: parent
+
+ onClicked: unsortedModel.append({ "number": Math.floor(Math.random() * 100) })
+ }
+ }
+}
diff --git a/examples/declarative/dragtarget/lists/lists.qmlproject b/examples/declarative/modelviews/visualdatamodel/visualdatamodel.qmlproject
index d4909f8685..d4909f8685 100644
--- a/examples/declarative/dragtarget/lists/lists.qmlproject
+++ b/examples/declarative/modelviews/visualdatamodel/visualdatamodel.qmlproject
diff --git a/examples/declarative/particles/affectors/gravity.qml b/examples/declarative/particles/affectors/gravity.qml
index 97d9c8569a..47710e6306 100644
--- a/examples/declarative/particles/affectors/gravity.qml
+++ b/examples/declarative/particles/affectors/gravity.qml
@@ -82,10 +82,12 @@ Item {
}
ParticleSystem { id: sys }
- Gravity {
+ Move {
system: sys
- angle: ground.rotation + 90
- acceleration: 32
+ acceleration: AngleDirection {
+ angle: ground.rotation + 90
+ magnitude: 32
+ }
}
Emitter {
system: sys
diff --git a/examples/declarative/particles/affectors/groupgoal.qml b/examples/declarative/particles/affectors/groupgoal.qml
index 35febf3353..836392cdd4 100644
--- a/examples/declarative/particles/affectors/groupgoal.qml
+++ b/examples/declarative/particles/affectors/groupgoal.qml
@@ -67,11 +67,10 @@ Rectangle {
colorVariation: 0.1
color: "#2060160f"
}
- SpriteGoal {
+ GroupGoal {
whenCollidingWith: ["lit"]
goalState: "lighting"
jump: true
- systemStates: true
}
}
ParticleGroup {
@@ -163,11 +162,10 @@ Rectangle {
sizeVariation: 2
endSize: 0
speed: PointDirection { y:-100; yVariation: 4; xVariation: 4 }
- SpriteGoal {
+ GroupGoal {
groups: ["unlit"]
goalState: "lit"
jump: true
- systemStates: true
system: particles
x: -15
y: -55
@@ -177,11 +175,10 @@ Rectangle {
}
}
//Click to enflame
- SpriteGoal {//TODO: Aux emiiters in the state definition (which allows the occasional ball to spontaneously combust)
+ GroupGoal {
groups: ["unlit"]
goalState: "lighting"
jump: true
- systemStates: true
enabled: ma.pressed
width: 18
height: 18
diff --git a/examples/declarative/inputmethods/spellcheck/WordSuggestions.qml b/examples/declarative/particles/affectors/move.qml
index 5c4e9cb4a2..93ff37bd74 100644
--- a/examples/declarative/inputmethods/spellcheck/WordSuggestions.qml
+++ b/examples/declarative/particles/affectors/move.qml
@@ -39,62 +39,104 @@
****************************************************************************/
import QtQuick 2.0
-import Qt.labs.inputcontext 1.0 as InputContext
-
-ListView {
- property int globalX: InputContext.microFocus.x + ((InputContext.microFocus.width - width) / 2)
- property int globalY: InputContext.microFocus.y + InputContext.microFocus.height
-
- x: parent.mapToItem(null, globalX, globalY).x
- y: parent.mapToItem(null, globalX, globalY).y
-
- visible: suggestionModel.count > 0
-
- width: 200
- height: 70
-
- InputContext.KeyFilter {
- onPressed: event.accepted = filterKeyPress(event.key, event.text)
- }
-
- InputContext.MouseHandler {
- onPressed: {
- if (cursor < 0 || cursor >= InputContext.preeditText.length)
- InputContext.commit()
+import QtQuick.Particles 2.0
+
+Rectangle {
+ width: 360
+ height: 540
+ color: "black"
+ ParticleSystem {
+ anchors.fill: parent
+ ImageParticle {
+ groups: ["A"]
+ anchors.fill: parent
+ source: "../images/star.png"
+ color:"#FF1010"
+ redVariation: 0.8
}
- }
-
- model: XmlListModel {
- id: suggestionModel
-
- query: "/query/results/s:suggestion"
- namespaceDeclarations: "declare namespace s=\"http://www.inktomi.com/\";"
- source: InputContext.preeditText.length > 4 ? "http://query.yahooapis.com/v1/public/yql?q=select * from search.spelling where query=\"" + InputContext.preeditText + "\"" : ""
-
- XmlRole { name: "suggestion"; query: "string()" }
- }
- delegate: Rectangle {
- radius: 2
- color: "lightsteelblue"
+ Emitter {
+ group: "A"
+ emitRate: 100
+ lifeSpan: 2800
+ size: 32
+ sizeVariation: 8
+ speed: PointDirection{ x: 66; xVariation: 20 }
+ width: 80
+ height: 80
+ }
- anchors.horizontalCenter: parent.horizontalCenter
+ Move {
+ groups: ["A"]
+ x: 120
+ width: 80
+ height: 80
+ relative: true
+ once: true
+ position: PointDirection { x: 120; }
+ }
- width: suggestionText.implicitWidth + 2
- height: suggestionText.implicitHeight + 2
+ ImageParticle {
+ groups: ["B"]
+ anchors.fill: parent
+ source: "../images/star.png"
+ color:"#10FF10"
+ greenVariation: 0.8
+ }
- Text {
- id: suggestionText
+ Emitter {
+ group: "B"
+ emitRate: 100
+ lifeSpan: 2800
+ size: 32
+ sizeVariation: 8
+ speed: PointDirection{ x: 240; xVariation: 60 }
+ y: 260
+ width: 10
+ height: 10
+ }
- font: InputContext.font
- text: suggestion
+ Move {
+ groups: ["B"]
+ x: 120
+ y: 240
+ width: 80
+ height: 80
+ relative: true
+ once: true
+ speed: AngleDirection { angleVariation:360; magnitude: 72 }
+ }
+ ImageParticle {
+ groups: ["C"]
anchors.fill: parent
- anchors.margins: 1
+ source: "../images/star.png"
+ color:"#1010FF"
+ blueVariation: 0.8
}
- MouseArea {
- anchors.fill: parent
- onClicked: InputContext.commit(suggestion)
+
+ Emitter {
+ group: "C"
+ y: 400
+ emitRate: 100
+ lifeSpan: 2800
+ size: 32
+ sizeVariation: 8
+ speed: PointDirection{ x: 80; xVariation: 10 }
+ width: 80
+ height: 80
}
+
+ Move {
+ groups: ["C"]
+ x: 120
+ y: 400
+ width: 80
+ height: 80
+ relative: true
+ once: true
+ acceleration: PointDirection { y: -80; }
+ }
+
}
}
diff --git a/examples/declarative/particles/customparticle/blurparticles.qml b/examples/declarative/particles/customparticle/blurparticles.qml
index 9767818bd3..9a18be4bb2 100644
--- a/examples/declarative/particles/customparticle/blurparticles.qml
+++ b/examples/declarative/particles/customparticle/blurparticles.qml
@@ -54,7 +54,7 @@ Rectangle {
emitRate: 1
lifeSpan: 12000
speed: PointDirection {x:20;}
- size: 64
+ size: 128
}
ShaderEffectSource {
id: theSource
@@ -63,7 +63,7 @@ Rectangle {
}
Image {
id: theItem
- source: "../images/smile.png"
+ source: "../images/starfish_1.png"
}
CustomParticle {
diff --git a/examples/declarative/particles/customparticle/imagecolors.qml b/examples/declarative/particles/customparticle/imagecolors.qml
index 591fd2421f..0498631fa4 100644
--- a/examples/declarative/particles/customparticle/imagecolors.qml
+++ b/examples/declarative/particles/customparticle/imagecolors.qml
@@ -62,7 +62,7 @@ Rectangle {
}
Image {
id: picture
- source: "../images/smile.png"
+ source: "../images/starfish_3.png"
}
ShaderEffectSource {
id: particleSource
@@ -71,7 +71,7 @@ Rectangle {
}
Image {
id: particle
- source: "../images/particle.png"
+ source: "../images/particle4.png"
}
vertexShader:"
uniform highp float maxWidth;
@@ -104,15 +104,15 @@ Rectangle {
id: emitter
system: sys
enabled: false
- lifeSpan: 4000
- maximumEmitted: 1200
+ lifeSpan: 8000
+ maximumEmitted: 4000
anchors.fill: parent
- size: 32
- speed: PointDirection { xVariation: 12; yVariation: 12 }
+ size: 16
+ acceleration: PointDirection { xVariation: 12; yVariation: 12 }
}
MouseArea {
anchors.fill: parent
- onClicked: emitter.burst(1200);
+ onClicked: emitter.burst(4000);
}
}
}
diff --git a/examples/declarative/particles/emitters/emitmask.qml b/examples/declarative/particles/emitters/emitmask.qml
index 1703ab2d20..dad2f7a64b 100644
--- a/examples/declarative/particles/emitters/emitmask.qml
+++ b/examples/declarative/particles/emitters/emitmask.qml
@@ -64,7 +64,7 @@ Rectangle {
lifeSpan: 720
size: 10
shape: MaskShape {
- source: "../images/smileMask.png"
+ source: "../images/starfish_mask.png"
}
}
diff --git a/examples/declarative/particles/emitters/timedgroupchanges.qml b/examples/declarative/particles/emitters/timedgroupchanges.qml
index 5da64f1e50..e668436684 100644
--- a/examples/declarative/particles/emitters/timedgroupchanges.qml
+++ b/examples/declarative/particles/emitters/timedgroupchanges.qml
@@ -82,7 +82,7 @@ Rectangle {
running: true
triggeredOnStart: true
repeat: true
- onTriggered:startingEmitter.pulse(0.1);
+ onTriggered:startingEmitter.pulse(100);
}
Emitter {
id: startingEmitter
diff --git a/examples/declarative/particles/emitters/trailemitter.qml b/examples/declarative/particles/emitters/trailemitter.qml
index e246b6605f..841c6c9217 100644
--- a/examples/declarative/particles/emitters/trailemitter.qml
+++ b/examples/declarative/particles/emitters/trailemitter.qml
@@ -117,8 +117,9 @@ Rectangle {
emitRatePerParticle: 120
lifeSpan: 180
- emitWidth: 8
- emitHeight: 8
+ emitWidth: TrailEmitter.ParticleSize
+ emitHeight: TrailEmitter.ParticleSize
+ emitShape: EllipseShape{}
size: 16
sizeVariation: 4
@@ -134,8 +135,9 @@ Rectangle {
emitRatePerParticle: 128
lifeSpan: 2400
- emitWidth: 16
- emitHeight: 16
+ emitWidth: TrailEmitter.ParticleSize
+ emitHeight: TrailEmitter.ParticleSize
+ emitShape: EllipseShape{}
speed: PointDirection {yVariation: 16; xVariation: 16}
acceleration: PointDirection {y: -16}
@@ -159,7 +161,7 @@ Rectangle {
speed: PointDirection {y:-17*4*2; xVariation: 6*6}
acceleration: PointDirection {y: 17*2; xVariation: 6*6}
- size: 12
+ size: 8
sizeVariation: 4
}
diff --git a/examples/declarative/particles/imageparticle/allatonce.qml b/examples/declarative/particles/imageparticle/allatonce.qml
index 0d5a11f386..797a835bbd 100644
--- a/examples/declarative/particles/imageparticle/allatonce.qml
+++ b/examples/declarative/particles/imageparticle/allatonce.qml
@@ -52,23 +52,9 @@ Rectangle {
ImageParticle {
sprites: [
Sprite {
- name: "licking"
- source: "../images/squarefacewhite.png"
- frames: 6
- duration: 120
- to: {"dying":1, "licking":5}
- },
- Sprite {
- name: "dying"
- source: "../images/squarefacewhiteX.png"
- frames: 4
- duration: 120
- to: {"dead":1}
- },
- Sprite {
- name: "dead"
- source: "../images/squarefacewhiteXX.png"
- frames: 1
+ name: "bear"
+ source: "../images/bear_tiles.png"
+ frames: 13
duration: 120
}
]
@@ -90,8 +76,8 @@ Rectangle {
emitRate: 200
lifeSpan: 6000
speed: AngleDirection {angleVariation: 360; magnitude: 80; magnitudeVariation: 40}
- size: 40
- endSize: 80
+ size: 60
+ endSize: 120
}
Text {
diff --git a/examples/declarative/particles/imageparticle/deformation.qml b/examples/declarative/particles/imageparticle/deformation.qml
index 989a699395..5bd9f74c89 100644
--- a/examples/declarative/particles/imageparticle/deformation.qml
+++ b/examples/declarative/particles/imageparticle/deformation.qml
@@ -50,7 +50,7 @@ Rectangle {
ImageParticle {
system: sys
groups: ["goingLeft", "goingRight"]
- source: "../images/singlesmile.png"
+ source: "../images/starfish_4.png"
rotation: 90
rotationSpeed: 90
autoRotation: true
@@ -58,7 +58,8 @@ Rectangle {
ImageParticle {
system: sys
groups: ["goingDown"]
- source: "../images/squarefacespriteXX.png"
+ source: "../images/starfish_0.png"
+ rotation: 180
yVector: PointDirection { y: 0.5; yVariation: 0.25; xVariation: 0.25; }
}
@@ -90,8 +91,8 @@ Rectangle {
group: "goingRight"
speed: PointDirection { x: 100 }
lifeSpan: 4000
- emitRate: 2
- size: 32
+ emitRate: 1
+ size: 128
}
Emitter {
id: emitB
@@ -102,8 +103,8 @@ Rectangle {
group: "goingLeft"
speed: PointDirection { x: -100 }
lifeSpan: 4000
- emitRate: 2
- size: 32
+ emitRate: 1
+ size: 128
}
Emitter {
id: emitC
@@ -114,7 +115,7 @@ Rectangle {
group: "goingDown"
speed: PointDirection { x: 100 }
lifeSpan: 4000
- emitRate: 2
- size: 32
+ emitRate: 1
+ size: 128
}
}
diff --git a/examples/declarative/particles/imageparticle/rotation.qml b/examples/declarative/particles/imageparticle/rotation.qml
index fe77e43f73..d5a6e8d315 100644
--- a/examples/declarative/particles/imageparticle/rotation.qml
+++ b/examples/declarative/particles/imageparticle/rotation.qml
@@ -49,20 +49,23 @@ Rectangle {
ImageParticle {
id: up
system: sys
- source: "../images/smile.png"
+ source: "../images/starfish_2.png"
}
Emitter {
anchors.centerIn: parent
system: sys
- emitRate: 1000
- size: 20
+ emitRate: 10
+ size: 200
lifeSpan: 10000
speed: AngleDirection {angleVariation: 360; magnitudeVariation: 100;}
}
MouseArea {
anchors.fill: parent
- onClicked: up.autoRotation = !up.autoRotation
+ onClicked: {
+ up.autoRotation = !up.autoRotation
+ up.rotation = up.autoRotation ? -90 : 0
+ }
}
}
diff --git a/examples/declarative/particles/imageparticle/sprites.qml b/examples/declarative/particles/imageparticle/sprites.qml
index ad18c48640..dfc4447e45 100644
--- a/examples/declarative/particles/imageparticle/sprites.qml
+++ b/examples/declarative/particles/imageparticle/sprites.qml
@@ -42,69 +42,20 @@ import QtQuick 2.0
import QtQuick.Particles 2.0
Rectangle {
- color: "goldenrod"
+ color: "lightsteelblue"
width: 800
height: 800
id: root
SpriteImage {
- sprites: [Sprite {
- name: "happy"
- source: "../images/squarefacesprite2.png"
- frames: 6
- duration: 120
- to: {"silly": 0.4, "sad": 0.2, "cyclops":0.1, "boggled":0.3, "dying":0.0}
- }, Sprite {
- name: "silly"
- source: "../images/squarefacesprite.png"
- frames: 6
- duration: 120
- to: {"love": 0.4, "happy": 0.1, "evil": 0.2, "cyclops":0.1, "boggled":0.2}
- }, Sprite {
- name: "sad"
- source: "../images/squarefacesprite3.png"
- frames: 6
- duration: 120
- to: {"love" : 0.2, "evil": 0.2, "silly": 0.2, "cyclops":0.2, "boggled":0.2}
- }, Sprite {
- name: "cyclops"
- source: "../images/squarefacesprite4.png"
- frames: 6
- duration: 120
- to: {"love": 0.1, "evil": 0.1, "silly":0.1, "boggled":0.1, "cyclops" : 1.0}
- }, Sprite {
- name: "evil"
- source: "../images/squarefacesprite5.png"
- frames: 6
- duration: 120
- to: {"happy": 1.0}
- }, Sprite {
- name: "love"
- source: "../images/squarefacesprite6.png"
- frames: 6
- duration: 120
- to: {"sad": 0.6, "evil":0.4, "boggled":0.2}
- }, Sprite {
- name: "boggled"
- source: "../images/squarefacesprite7.png"
- frames: 6
- duration: 120
- to: {"love" : 0.2, "evil": 0.2, "silly": 0.2, "cyclops":0.1, "sad":0.2}
- }, Sprite {
- name: "dying"
- source: "../images/squarefacespriteX.png"
- frames: 4
- duration: 120
- to: {"dead":1.0}
- }, Sprite {
- name: "dead"
- source: "../images/squarefacespriteXX.png"
- frames: 1
- duration: 10000
- }]
-
- width: 100
- height: 100
+ sprites: Sprite {
+ name: "bear"
+ source: "../images/bear_tiles.png"
+ frames: 13
+ duration: 120
+ }
+ width: 250
+ height: 250
x: 20
y: 20
z:4
@@ -118,68 +69,38 @@ Rectangle {
system: sys
sprites: [Sprite {
name: "happy"
- source: "../images/squarefacesprite2.png"
- frames: 6
- duration: 120
- to: {"silly": 0.4, "sad": 0.2, "cyclops":0.1, "boggled":0.3, "dying":0.0}
- }, Sprite {
- name: "silly"
- source: "../images/squarefacesprite.png"
- frames: 6
- duration: 120
- to: {"love": 0.4, "happy": 0.1, "evil": 0.2, "cyclops":0.1, "boggled":0.2}
- }, Sprite {
- name: "sad"
- source: "../images/squarefacesprite3.png"
- frames: 6
- duration: 120
- to: {"love" : 0.2, "evil": 0.2, "silly": 0.2, "cyclops":0.2, "boggled":0.2}
- }, Sprite {
- name: "cyclops"
- source: "../images/squarefacesprite4.png"
- frames: 6
- duration: 120
- to: {"love": 0.1, "evil": 0.1, "silly":0.1, "boggled":0.1, "cyclops" : 1.0}
- }, Sprite {
- name: "evil"
- source: "../images/squarefacesprite5.png"
- frames: 6
- duration: 120
- to: {"happy": 1.0}
- }, Sprite {
- name: "love"
- source: "../images/squarefacesprite6.png"
- frames: 6
- duration: 120
- to: {"sad": 0.6, "evil":0.4, "boggled":0.2}
+ source: "../images/starfish_1.png"
+ frames: 1
+ duration: 260
+ to: {"happy": 1, "silly": 1, "angry": 1}
}, Sprite {
- name: "boggled"
- source: "../images/squarefacesprite7.png"
- frames: 6
- duration: 120
- to: {"love" : 0.2, "evil": 0.2, "silly": 0.2, "cyclops":0.1, "sad":0.2}
+ name: "angry"
+ source: "../images/starfish_0.png"
+ frames: 1
+ duration: 260
+ to: {"happy": 1, "silly": 1, "angry": 1}
}, Sprite {
- name: "dying"
- source: "../images/squarefacespriteX.png"
- frames: 4
- duration: 120
- to: {"dead":1.0}
+ name: "silly"
+ source: "../images/starfish_2.png"
+ frames: 1
+ duration: 260
+ to: {"happy": 1, "silly": 1, "noticedbear": 0}
}, Sprite {
- name: "dead"
- source: "../images/squarefacespriteXX.png"
+ name: "noticedbear"
+ source: "../images/starfish_3.png"
frames: 1
- duration: 10000
+ duration: 2600
}]
}
Emitter {
system: sys
- emitRate: 16
+ emitRate: 2
lifeSpan: 10000
speed: AngleDirection {angle: 90; magnitude: 60; angleVariation: 5}
acceleration: PointDirection { y: 10 }
- size: 30
- sizeVariation: 10
+ size: 160
+ sizeVariation: 40
width: parent.width
height: 100
}
@@ -189,6 +110,6 @@ Rectangle {
width: root.width;
height: root.height/2;
y: root.height/2;
- goalState:"dead"
+ goalState:"noticedbear"
}
}
diff --git a/examples/declarative/particles/images/bear_tiles.png b/examples/declarative/particles/images/bear_tiles.png
new file mode 100644
index 0000000000..6bbb2a9b6d
--- /dev/null
+++ b/examples/declarative/particles/images/bear_tiles.png
Binary files differ
diff --git a/examples/declarative/particles/images/launcherIcons/allatonce.png b/examples/declarative/particles/images/launcherIcons/allatonce.png
index 0d87eea427..b61d2d50d8 100644
--- a/examples/declarative/particles/images/launcherIcons/allatonce.png
+++ b/examples/declarative/particles/images/launcherIcons/allatonce.png
Binary files differ
diff --git a/examples/declarative/particles/images/launcherIcons/blurparticles.png b/examples/declarative/particles/images/launcherIcons/blurparticles.png
index 7a247ae46e..4337f979cb 100644
--- a/examples/declarative/particles/images/launcherIcons/blurparticles.png
+++ b/examples/declarative/particles/images/launcherIcons/blurparticles.png
Binary files differ
diff --git a/examples/declarative/particles/images/launcherIcons/deformation.png b/examples/declarative/particles/images/launcherIcons/deformation.png
index 78ea52790f..d1b722df01 100644
--- a/examples/declarative/particles/images/launcherIcons/deformation.png
+++ b/examples/declarative/particles/images/launcherIcons/deformation.png
Binary files differ
diff --git a/examples/declarative/particles/images/launcherIcons/emitmask.png b/examples/declarative/particles/images/launcherIcons/emitmask.png
index 5603964939..e943a4adb9 100644
--- a/examples/declarative/particles/images/launcherIcons/emitmask.png
+++ b/examples/declarative/particles/images/launcherIcons/emitmask.png
Binary files differ
diff --git a/examples/declarative/particles/images/launcherIcons/imagecolors.png b/examples/declarative/particles/images/launcherIcons/imagecolors.png
index f990e6c03e..0ff13a346e 100644
--- a/examples/declarative/particles/images/launcherIcons/imagecolors.png
+++ b/examples/declarative/particles/images/launcherIcons/imagecolors.png
Binary files differ
diff --git a/examples/declarative/particles/images/launcherIcons/rotation.png b/examples/declarative/particles/images/launcherIcons/rotation.png
index dd51498514..6a8dbea236 100644
--- a/examples/declarative/particles/images/launcherIcons/rotation.png
+++ b/examples/declarative/particles/images/launcherIcons/rotation.png
Binary files differ
diff --git a/examples/declarative/particles/images/launcherIcons/sprites.png b/examples/declarative/particles/images/launcherIcons/sprites.png
index dd01518ac4..144216ac7c 100644
--- a/examples/declarative/particles/images/launcherIcons/sprites.png
+++ b/examples/declarative/particles/images/launcherIcons/sprites.png
Binary files differ
diff --git a/examples/declarative/particles/images/singlesmile.png b/examples/declarative/particles/images/singlesmile.png
deleted file mode 100644
index 4087fa6b7f..0000000000
--- a/examples/declarative/particles/images/singlesmile.png
+++ /dev/null
Binary files differ
diff --git a/examples/declarative/particles/images/smileMask.png b/examples/declarative/particles/images/smileMask.png
deleted file mode 100644
index 65a0143e9e..0000000000
--- a/examples/declarative/particles/images/smileMask.png
+++ /dev/null
Binary files differ
diff --git a/examples/declarative/particles/images/squarefacesprite2.png b/examples/declarative/particles/images/squarefacesprite2.png
deleted file mode 100644
index 7106a520a4..0000000000
--- a/examples/declarative/particles/images/squarefacesprite2.png
+++ /dev/null
Binary files differ
diff --git a/examples/declarative/particles/images/squarefacesprite3.png b/examples/declarative/particles/images/squarefacesprite3.png
deleted file mode 100644
index f4e6f26856..0000000000
--- a/examples/declarative/particles/images/squarefacesprite3.png
+++ /dev/null
Binary files differ
diff --git a/examples/declarative/particles/images/squarefacesprite4.png b/examples/declarative/particles/images/squarefacesprite4.png
deleted file mode 100644
index 1e094eed4a..0000000000
--- a/examples/declarative/particles/images/squarefacesprite4.png
+++ /dev/null
Binary files differ
diff --git a/examples/declarative/particles/images/squarefacesprite5.png b/examples/declarative/particles/images/squarefacesprite5.png
deleted file mode 100644
index 1cfc5c7f8c..0000000000
--- a/examples/declarative/particles/images/squarefacesprite5.png
+++ /dev/null
Binary files differ
diff --git a/examples/declarative/particles/images/squarefacesprite6.png b/examples/declarative/particles/images/squarefacesprite6.png
deleted file mode 100644
index b040139a9e..0000000000
--- a/examples/declarative/particles/images/squarefacesprite6.png
+++ /dev/null
Binary files differ
diff --git a/examples/declarative/particles/images/squarefacesprite7.png b/examples/declarative/particles/images/squarefacesprite7.png
deleted file mode 100644
index b1e5e4e339..0000000000
--- a/examples/declarative/particles/images/squarefacesprite7.png
+++ /dev/null
Binary files differ
diff --git a/examples/declarative/particles/images/squarefacespriteX.png b/examples/declarative/particles/images/squarefacespriteX.png
deleted file mode 100644
index 93a0181dd0..0000000000
--- a/examples/declarative/particles/images/squarefacespriteX.png
+++ /dev/null
Binary files differ
diff --git a/examples/declarative/particles/images/squarefacespriteXX.png b/examples/declarative/particles/images/squarefacespriteXX.png
deleted file mode 100644
index 3159efe246..0000000000
--- a/examples/declarative/particles/images/squarefacespriteXX.png
+++ /dev/null
Binary files differ
diff --git a/examples/declarative/particles/images/squarefacewhite.png b/examples/declarative/particles/images/squarefacewhite.png
deleted file mode 100644
index 02259c5762..0000000000
--- a/examples/declarative/particles/images/squarefacewhite.png
+++ /dev/null
Binary files differ
diff --git a/examples/declarative/particles/images/squarefacewhiteX.png b/examples/declarative/particles/images/squarefacewhiteX.png
deleted file mode 100644
index 59af205c6b..0000000000
--- a/examples/declarative/particles/images/squarefacewhiteX.png
+++ /dev/null
Binary files differ
diff --git a/examples/declarative/particles/images/squarefacewhiteXX.png b/examples/declarative/particles/images/squarefacewhiteXX.png
deleted file mode 100644
index b0f15c6785..0000000000
--- a/examples/declarative/particles/images/squarefacewhiteXX.png
+++ /dev/null
Binary files differ
diff --git a/examples/declarative/particles/images/starfish_0.png b/examples/declarative/particles/images/starfish_0.png
new file mode 100644
index 0000000000..8747f0236e
--- /dev/null
+++ b/examples/declarative/particles/images/starfish_0.png
Binary files differ
diff --git a/examples/declarative/particles/images/starfish_1.png b/examples/declarative/particles/images/starfish_1.png
new file mode 100644
index 0000000000..1f3f159d5e
--- /dev/null
+++ b/examples/declarative/particles/images/starfish_1.png
Binary files differ
diff --git a/examples/declarative/particles/images/starfish_2.png b/examples/declarative/particles/images/starfish_2.png
new file mode 100644
index 0000000000..c6c7e5a676
--- /dev/null
+++ b/examples/declarative/particles/images/starfish_2.png
Binary files differ
diff --git a/examples/declarative/particles/images/starfish_3.png b/examples/declarative/particles/images/starfish_3.png
new file mode 100644
index 0000000000..307a89f815
--- /dev/null
+++ b/examples/declarative/particles/images/starfish_3.png
Binary files differ
diff --git a/examples/declarative/particles/images/starfish_4.png b/examples/declarative/particles/images/starfish_4.png
new file mode 100644
index 0000000000..d61c26545a
--- /dev/null
+++ b/examples/declarative/particles/images/starfish_4.png
Binary files differ
diff --git a/examples/declarative/particles/images/starfish_mask.png b/examples/declarative/particles/images/starfish_mask.png
new file mode 100644
index 0000000000..2ef74f902b
--- /dev/null
+++ b/examples/declarative/particles/images/starfish_mask.png
Binary files differ
diff --git a/examples/declarative/particles/itemparticle/particleview.qml b/examples/declarative/particles/itemparticle/particleview.qml
index 5d393e6a06..ddc447bddd 100644
--- a/examples/declarative/particles/itemparticle/particleview.qml
+++ b/examples/declarative/particles/itemparticle/particleview.qml
@@ -128,7 +128,7 @@ Item {
alertItem = alertDelegate.createObject(root);
alertItem.x = root.width/2 - alertItem.width/2
alertItem.y = root.height/2 - alertItem.height/2
- spawnFireworks.pulse(0.2);
+ spawnFireworks.pulse(200);
stopAlert.start();
}
focus: true
@@ -225,7 +225,6 @@ Item {
fillMode: Image.PreserveAspectFit;
width: parent.width-4; height: parent.height-4
onStatusChanged: if (img.status == Image.Ready) {
- container.opacity = 0;
loading.opacity = 0;
mp.take(container);
}
diff --git a/examples/declarative/particles/plasmapatrol/content/LaserHardpoint.qml b/examples/declarative/particles/plasmapatrol/content/LaserHardpoint.qml
index 007d533b56..4c2254d570 100644
--- a/examples/declarative/particles/plasmapatrol/content/LaserHardpoint.qml
+++ b/examples/declarative/particles/plasmapatrol/content/LaserHardpoint.qml
@@ -81,7 +81,7 @@ Item {
offset = Math.random() * 100;
}
target = container.mapFromItem(targetArg, offset + targetArg.width/2, offset + targetArg.height/2);
- emitter.pulse(0.10);
+ emitter.pulse(100);
// console.log("Fire box: " + Math.min(container.width/2, target.x) + "," + Math.min(container.height/2, target.y) + " " + (Math.max(container.width/2, target.x) - Math.min(container.width/2, target.x)) + "," + (Math.max(container.height/2, target.y) - Math.min(container.height/2, target.y)));
}
Emitter {
diff --git a/examples/declarative/samegame/SamegameCore/BoomBlock.qml b/examples/declarative/samegame/SamegameCore/BoomBlock.qml
index df3e9bd8fa..e5d4f4090b 100644
--- a/examples/declarative/samegame/SamegameCore/BoomBlock.qml
+++ b/examples/declarative/samegame/SamegameCore/BoomBlock.qml
@@ -104,7 +104,7 @@ Item {
State {
name: "DeathState"; when: dying == true
- StateChangeScript { script: particles.pulse(0.1); }
+ StateChangeScript { script: particles.pulse(100); }
PropertyChanges { target: img; opacity: 0 }
StateChangeScript { script: block.destroy(1000); }
}
diff --git a/examples/declarative/screenorientation/Core/Bubble.qml b/examples/declarative/screenorientation/Core/Bubble.qml
deleted file mode 100644
index 446fa1f196..0000000000
--- a/examples/declarative/screenorientation/Core/Bubble.qml
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 1.0
-
-Rectangle {
- property bool rising: false
- property bool verticalRise: true
- property real xAttractor: 0
- property real yAttractor: 0
-
- width: 5 + 10*Math.random()
- height: width
- radius: Math.floor(width/2)-1
- property real amountOfGray: Math.random()
- color: Qt.rgba(amountOfGray,amountOfGray,amountOfGray,1)
-
- y: (rising && verticalRise) ? yAttractor : Math.random()*(main.inPortrait ? main.baseHeight : main.baseWidth)
- x: (rising && !verticalRise) ? xAttractor : Math.random()*(main.inPortrait ? main.baseWidth : main.baseHeight)
- Behavior on x {
- id: xBehavior
- SmoothedAnimation {
- velocity: 100+Math.random()*100
- }
- }
- Behavior on y {
- id: yBehavior
- SmoothedAnimation {
- velocity: 100+Math.random()*100
- }
- }
- Timer {
- interval: 80+Math.random()*40
- repeat: true
- running: true
- onTriggered: {
- if (rising) {
- if (x > main.width || x < 0) {
- xBehavior.enabled = false;
- rising = false;
- xBehavior.enabled = true;
- rising = true;
- }
- if (y > main.height || y < 0) {
- yBehavior.enabled = false;
- rising = false;
- yBehavior.enabled = true;
- rising = true;
- }
- }
- }
- }
-}
diff --git a/examples/declarative/screenorientation/Core/screenorientation.js b/examples/declarative/screenorientation/Core/screenorientation.js
deleted file mode 100644
index ffc6dc8fe6..0000000000
--- a/examples/declarative/screenorientation/Core/screenorientation.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-function printOrientation(orientation) {
- var orientationString;
- if (orientation == Orientation.Portrait) {
- orientationString = "Portrait";
- } else if (orientation == Orientation.Landscape) {
- orientationString = "Landscape";
- } else if (orientation == Orientation.PortraitInverted) {
- orientationString = "Portrait inverted";
- } else if (orientation == Orientation.LandscapeInverted) {
- orientationString = "Landscape inverted";
- } else {
- orientationString = "UnknownOrientation";
- }
- return orientationString;
-}
-
-function getAngle(orientation) {
- var angle;
- if (orientation == Orientation.Portrait) {
- angle = 0;
- } else if (orientation == Orientation.Landscape) {
- angle = 90;
- } else if (orientation == Orientation.PortraitInverted) {
- angle = 180;
- } else if (orientation == Orientation.LandscapeInverted) {
- angle = 270;
- } else {
- angle = 0;
- }
- return angle;
-}
-
-function parallel(firstOrientation, secondOrientation) {
- var difference = getAngle(firstOrientation) - getAngle(secondOrientation)
- return difference % 180 == 0;
-}
-
-function calculateGravityPoint(firstOrientation, secondOrientation) {
- var position = Qt.point(0, 0);
- var difference = getAngle(firstOrientation) - getAngle(secondOrientation)
- if (difference < 0) {
- difference = 360 + difference;
- }
- if (difference == 0) {
- position = Qt.point(0, -10);
- } else if (difference == 90) {
- position = Qt.point(-10, 0);
- } else if (difference == 180) {
- position = Qt.point(0, 1000);
- } else if (difference == 270) {
- position = Qt.point(1000, 0);
- }
- return position;
-}
diff --git a/examples/declarative/screenorientation/screenorientation.qml b/examples/declarative/screenorientation/screenorientation.qml
deleted file mode 100644
index 2575274b53..0000000000
--- a/examples/declarative/screenorientation/screenorientation.qml
+++ /dev/null
@@ -1,201 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 1.0
-import "Core"
-import "Core/screenorientation.js" as ScreenOrientation
-
-Rectangle {
- id: window
- width: 360
- height: 640
- color: "white"
-
- Rectangle {
- id: main
- clip: true
- property variant selectedOrientation: Orientation.UnknownOrientation
- property variant activeOrientation: selectedOrientation == Orientation.UnknownOrientation ? runtime.orientation : selectedOrientation
- state: "orientation " + activeOrientation
- property bool inPortrait: (activeOrientation == Orientation.Portrait || activeOrientation == Orientation.PortraitInverted);
-
- // rotation correction for landscape devices like N900
- property bool landscapeWindow: window.width > window.height
- property variant rotationDelta: landscapeWindow ? -90 : 0
- rotation: rotationDelta
-
- // initial state is portrait
- property real baseWidth: landscapeWindow ? window.height-10 : window.width-10
- property real baseHeight: landscapeWindow ? window.width-10 : window.height-10
-
- width: baseWidth
- height: baseHeight
- anchors.centerIn: parent
-
- color: "black"
- gradient: Gradient {
- GradientStop { position: 0.0; color: Qt.rgba(0.5,0.5,0.5,0.5) }
- GradientStop { position: 0.8; color: "black" }
- GradientStop { position: 1.0; color: "black" }
- }
- Item {
- id: bubbles
- property bool rising: false
- anchors.fill: parent
- property variant gravityPoint: ScreenOrientation.calculateGravityPoint(main.activeOrientation, runtime.orientation)
- Repeater {
- model: 24
- Bubble {
- rising: bubbles.rising
- verticalRise: ScreenOrientation.parallel(main.activeOrientation, runtime.orientation)
- xAttractor: parent.gravityPoint.x
- yAttractor: parent.gravityPoint.y
- }
- }
- Component.onCompleted: bubbles.rising = true;
- }
-
- Column {
- width: centeredText.width
- anchors.verticalCenter: parent.verticalCenter
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.verticalCenterOffset: 30
- Text {
- text: "Orientation"
- color: "white"
- font.pixelSize: 22
- anchors.horizontalCenter: parent.horizontalCenter
- }
- Text {
- id: centeredText
- text: ScreenOrientation.printOrientation(main.activeOrientation)
- color: "white"
- font.pixelSize: 40
- anchors.horizontalCenter: parent.horizontalCenter
- }
- Text {
- text: "sensor: " + ScreenOrientation.printOrientation(runtime.orientation)
- color: "white"
- font.pixelSize: 14
- anchors.horizontalCenter: parent.horizontalCenter
- }
- }
- Flow {
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.margins: 10
- spacing: 4
- Button {
- width: main.inPortrait ? (parent.width-4)/2 : (parent.width-8)/3
- text: "Portrait"
- onClicked: main.selectedOrientation = Orientation.Portrait
- toggled: main.selectedOrientation == Orientation.Portrait
- }
- Button {
- width: main.inPortrait ? (parent.width-4)/2 : (parent.width-8)/3
- text: "Portrait inverted"
- onClicked: main.selectedOrientation = Orientation.PortraitInverted
- toggled: main.selectedOrientation == Orientation.PortraitInverted
- }
- Button {
- width: main.inPortrait ? (parent.width-4)/2 : (parent.width-8)/3
- text: "Landscape"
- onClicked: main.selectedOrientation = Orientation.Landscape
- toggled: main.selectedOrientation == Orientation.Landscape
- }
- Button {
- width: main.inPortrait ? (parent.width-4)/2 : (parent.width-8)/3
- text: "Landscape inverted"
- onClicked: main.selectedOrientation = Orientation.LandscapeInverted
- toggled: main.selectedOrientation == Orientation.LandscapeInverted
- }
- Button {
- width: main.inPortrait ? parent.width : 2*(parent.width-2)/3
- text: "From runtime.orientation"
- onClicked: main.selectedOrientation = Orientation.UnknownOrientation
- toggled: main.selectedOrientation == Orientation.UnknownOrientation
- }
- }
- states: [
- State {
- name: "orientation " + Orientation.Landscape
- PropertyChanges {
- target: main
- rotation: ScreenOrientation.getAngle(Orientation.Landscape)+rotationDelta
- width: baseHeight
- height: baseWidth
- }
- },
- State {
- name: "orientation " + Orientation.PortraitInverted
- PropertyChanges {
- target: main
- rotation: ScreenOrientation.getAngle(Orientation.PortraitInverted)+rotationDelta
- width: baseWidth
- height: baseHeight
- }
- },
- State {
- name: "orientation " + Orientation.LandscapeInverted
- PropertyChanges {
- target: main
- rotation: ScreenOrientation.getAngle(Orientation.LandscapeInverted)+rotationDelta
- width: baseHeight
- height: baseWidth
- }
- }
- ]
- transitions: Transition {
- ParallelAnimation {
- RotationAnimation {
- direction: RotationAnimation.Shortest
- duration: 300
- easing.type: Easing.InOutQuint
- }
- NumberAnimation {
- properties: "x,y,width,height"
- duration: 300
- easing.type: Easing.InOutQuint
- }
- }
- }
- }
-}
diff --git a/examples/declarative/screenorientation/screenorientation.qmlproject b/examples/declarative/screenorientation/screenorientation.qmlproject
deleted file mode 100644
index d4909f8685..0000000000
--- a/examples/declarative/screenorientation/screenorientation.qmlproject
+++ /dev/null
@@ -1,16 +0,0 @@
-import QmlProject 1.0
-
-Project {
- /* Include .qml, .js, and image files from current directory and subdirectories */
- QmlFiles {
- directory: "."
- }
- JavaScriptFiles {
- directory: "."
- }
- ImageFiles {
- directory: "."
- }
- /* List of plugin directories passed to QML runtime */
- // importPaths: [ " ../exampleplugin " ]
-}
diff --git a/modules/qt_qmldevtools.pri b/modules/qt_qmldevtools.pri
new file mode 100644
index 0000000000..7365f13404
--- /dev/null
+++ b/modules/qt_qmldevtools.pri
@@ -0,0 +1,19 @@
+QT.qmldevtools.VERSION = 5.0.0
+QT.qmldevtools.MAJOR_VERSION = 5
+QT.qmldevtools.MINOR_VERSION = 0
+QT.qmldevtools.PATCH_VERSION = 0
+
+QT.qmldevtools.name = QtQmlDevTools
+QT.qmldevtools.bins = $$QT_MODULE_BIN_BASE
+QT.qmldevtools.includes = $$QT_MODULE_INCLUDE_BASE/QtQmlDevTools
+QT.qmldevtools.private_includes = $$QT_MODULE_INCLUDE_BASE/QtQmlDevTools/$$QT.qmldevtools.VERSION
+QT.qmldevtools.sources = $$QT_MODULE_BASE/src/qmldevtools
+QT.qmldevtools.libs = $$QT_MODULE_LIB_BASE
+QT.qmldevtools.plugins = $$QT_MODULE_PLUGIN_BASE
+QT.qmldevtools.imports = $$QT_MODULE_IMPORT_BASE
+QT.qmldevtools.depends = core
+QT.qmldevtools.module_config = staticlib
+QT.qmldevtools.DEFINES = QT_QMLDEVTOOLS_LIB
+
+QT_CONFIG += qmldevtools
+
diff --git a/qtdeclarative.pro b/qtdeclarative.pro
index 084a7200c5..306b7a2002 100644
--- a/qtdeclarative.pro
+++ b/qtdeclarative.pro
@@ -24,3 +24,5 @@ SUBDIRS += module_qtdeclarative_src \
module_qtdeclarative_tools \
module_qtdeclarative_examples \
module_qtdeclarative_tests \
+
+include(doc/config/qtdeclarative_doc.pri) \ No newline at end of file
diff --git a/src/3rdparty/javascriptcore/DateMath.cpp b/src/3rdparty/javascriptcore/DateMath.cpp
index e4775273e2..8932840366 100644
--- a/src/3rdparty/javascriptcore/DateMath.cpp
+++ b/src/3rdparty/javascriptcore/DateMath.cpp
@@ -75,7 +75,7 @@
#include <limits>
#include <stdint.h>
#include <time.h>
-#include <math.h>
+#include <cmath>
//#if HAVE(SYS_TIME_H)
#if defined(EXISTS_SYS_TIME)
@@ -346,7 +346,7 @@ double timeClip(double t)
return NaN;
return t >= 0 ? floor(t) : ceil(t);
#else
- if (!isfinite(t) || fabs(t) > maxECMAScriptTime)
+ if (!std::isfinite(t) || fabs(t) > maxECMAScriptTime)
return NaN;
return trunc(t);
#endif
diff --git a/src/declarative/debugger/debugger.pri b/src/declarative/debugger/debugger.pri
index a257da216f..5bc0a2d92e 100644
--- a/src/declarative/debugger/debugger.pri
+++ b/src/declarative/debugger/debugger.pri
@@ -1,5 +1,3 @@
-INCLUDEPATH += $$PWD
-
SOURCES += \
$$PWD/qdeclarativedebuggerstatus.cpp \
$$PWD/qpacketprotocol.cpp \
@@ -11,6 +9,7 @@ SOURCES += \
$$PWD/qdeclarativedebugserver.cpp \
$$PWD/qdeclarativeinspectorservice.cpp \
$$PWD/qv8debugservice.cpp \
+ $$PWD/qv8profilerservice.cpp \
$$PWD/qdeclarativeenginedebugservice.cpp
HEADERS += \
@@ -27,5 +26,6 @@ HEADERS += \
$$PWD/qdeclarativeinspectorservice_p.h \
$$PWD/qdeclarativeinspectorinterface_p.h \
$$PWD/qv8debugservice_p.h \
+ $$PWD/qv8profilerservice_p.h \
$$PWD/qdeclarativeenginedebugservice_p.h \
$$PWD/qdeclarativedebug.h
diff --git a/src/declarative/debugger/qdeclarativedebugclient.cpp b/src/declarative/debugger/qdeclarativedebugclient.cpp
index 606ad2deae..5018e9535e 100644
--- a/src/declarative/debugger/qdeclarativedebugclient.cpp
+++ b/src/declarative/debugger/qdeclarativedebugclient.cpp
@@ -39,9 +39,9 @@
**
****************************************************************************/
-#include "private/qdeclarativedebugclient_p.h"
+#include "qdeclarativedebugclient_p.h"
-#include "private/qpacketprotocol_p.h"
+#include "qpacketprotocol_p.h"
#include <QtCore/qdebug.h>
#include <QtCore/qstringlist.h>
diff --git a/src/declarative/debugger/qdeclarativedebuggerstatus.cpp b/src/declarative/debugger/qdeclarativedebuggerstatus.cpp
index 609e14497a..4f016b4afc 100644
--- a/src/declarative/debugger/qdeclarativedebuggerstatus.cpp
+++ b/src/declarative/debugger/qdeclarativedebuggerstatus.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "private/qdeclarativedebuggerstatus_p.h"
+#include "qdeclarativedebuggerstatus_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/debugger/qdeclarativedebughelper.cpp b/src/declarative/debugger/qdeclarativedebughelper.cpp
index e6b3563a9a..e9e9387af1 100644
--- a/src/declarative/debugger/qdeclarativedebughelper.cpp
+++ b/src/declarative/debugger/qdeclarativedebughelper.cpp
@@ -39,7 +39,11 @@
**
****************************************************************************/
-#include "private/qdeclarativedebughelper_p.h"
+#include "qdeclarativedebughelper_p.h"
+
+#include <QtDeclarative/QJSEngine>
+
+#include <private/qdeclarativeengine_p.h>
#include "private/qabstractanimation2_p.h"
#include <private/qdeclarativeengine_p.h>
#include <QtDeclarative/QJSEngine>
@@ -63,4 +67,4 @@ void QDeclarativeDebugHelper::enableDebugging() {
#endif
}
-QT_END_NAMESPACE
+QT_END_NAMESPACE \ No newline at end of file
diff --git a/src/declarative/debugger/qdeclarativedebugserver.cpp b/src/declarative/debugger/qdeclarativedebugserver.cpp
index da7a8d2eab..5a888c7dc1 100644
--- a/src/declarative/debugger/qdeclarativedebugserver.cpp
+++ b/src/declarative/debugger/qdeclarativedebugserver.cpp
@@ -39,17 +39,17 @@
**
****************************************************************************/
-#include "private/qdeclarativedebugserver_p.h"
-#include "private/qdeclarativedebugservice_p.h"
-#include "private/qdeclarativedebugservice_p_p.h"
-#include "private/qdeclarativeengine_p.h"
+#include "qdeclarativedebugserver_p.h"
+#include "qdeclarativedebugservice_p.h"
+#include "qdeclarativedebugservice_p_p.h"
+#include <private/qdeclarativeengine_p.h>
#include <QtCore/QDir>
#include <QtCore/QPluginLoader>
#include <QtCore/QStringList>
#include <private/qobject_p.h>
-#include <private/qguiapplication_p.h>
+#include <private/qcoreapplication_p.h>
QT_BEGIN_NAMESPACE
@@ -169,7 +169,7 @@ QDeclarativeDebugServer *QDeclarativeDebugServer::instance()
if (!commandLineTested) {
commandLineTested = true;
- QGuiApplicationPrivate *appD = static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(qApp));
+ QCoreApplicationPrivate *appD = static_cast<QCoreApplicationPrivate*>(QObjectPrivate::get(qApp));
#ifndef QDECLARATIVE_NO_DEBUG_PROTOCOL
// ### remove port definition when protocol is changed
int port = 0;
diff --git a/src/declarative/debugger/qdeclarativedebugserverconnection_p.h b/src/declarative/debugger/qdeclarativedebugserverconnection_p.h
index 832224ea33..a3e439dfd6 100644
--- a/src/declarative/debugger/qdeclarativedebugserverconnection_p.h
+++ b/src/declarative/debugger/qdeclarativedebugserverconnection_p.h
@@ -42,7 +42,7 @@
#ifndef QDECLARATIVEDEBUGSERVERCONNECTION_H
#define QDECLARATIVEDEBUGSERVERCONNECTION_H
-#include <QtDeclarative/private/qdeclarativeglobal_p.h>
+#include <private/qdeclarativeglobal_p.h>
//
// W A R N I N G
diff --git a/src/declarative/debugger/qdeclarativedebugservice.cpp b/src/declarative/debugger/qdeclarativedebugservice.cpp
index ecd9e0fb85..be60ea4609 100644
--- a/src/declarative/debugger/qdeclarativedebugservice.cpp
+++ b/src/declarative/debugger/qdeclarativedebugservice.cpp
@@ -39,9 +39,9 @@
**
****************************************************************************/
-#include "private/qdeclarativedebugservice_p.h"
-#include "private/qdeclarativedebugservice_p_p.h"
-#include "private/qdeclarativedebugserver_p.h"
+#include "qdeclarativedebugservice_p.h"
+#include "qdeclarativedebugservice_p_p.h"
+#include "qdeclarativedebugserver_p.h"
#include <QtCore/QDebug>
#include <QtCore/QStringList>
diff --git a/src/declarative/debugger/qdeclarativedebugtrace.cpp b/src/declarative/debugger/qdeclarativedebugtrace.cpp
index befc3ea374..7d63849383 100644
--- a/src/declarative/debugger/qdeclarativedebugtrace.cpp
+++ b/src/declarative/debugger/qdeclarativedebugtrace.cpp
@@ -44,6 +44,11 @@
#include <QtCore/qdatastream.h>
#include <QtCore/qurl.h>
#include <QtCore/qtimer.h>
+#include <QtCore/qthread.h>
+#include <QtCore/qcoreapplication.h>
+
+// this contains QUnifiedTimer
+#include <private/qabstractanimation_p.h>
QT_BEGIN_NAMESPACE
@@ -62,6 +67,9 @@ QByteArray QDeclarativeDebugData::toByteArray() const
ds << detailData;
if (messageType == (int)QDeclarativeDebugTrace::RangeLocation)
ds << detailData << line;
+ if (messageType == (int)QDeclarativeDebugTrace::Event &&
+ detailType == (int)QDeclarativeDebugTrace::AnimationFrame)
+ ds << framerate << animationcount;
return data;
}
@@ -74,9 +82,28 @@ QDeclarativeDebugTrace::QDeclarativeDebugTrace()
// wait for first message indicating whether to trace or not
while (!m_messageReceived)
waitForMessage();
+
+ QUnifiedTimer::instance()->registerProfilerCallback( &animationFrame );
}
}
+QDeclarativeDebugTrace::~QDeclarativeDebugTrace()
+{
+ // unregister the callback
+ QUnifiedTimer::instance()->registerProfilerCallback( 0 );
+}
+
+void QDeclarativeDebugTrace::addEngine(QDeclarativeEngine * /*engine*/)
+{
+ // just make sure that the service is properly registered
+ traceInstance();
+}
+
+void QDeclarativeDebugTrace::removeEngine(QDeclarativeEngine */*engine*/)
+{
+
+}
+
void QDeclarativeDebugTrace::addEvent(EventType t)
{
if (QDeclarativeDebugService::isDebuggingEnabled())
@@ -119,12 +146,18 @@ void QDeclarativeDebugTrace::endRange(RangeType t)
traceInstance()->endRangeImpl(t);
}
+void QDeclarativeDebugTrace::animationFrame(qint64 delta)
+{
+ Q_ASSERT(QDeclarativeDebugService::isDebuggingEnabled());
+ traceInstance()->animationFrameImpl(delta);
+}
+
void QDeclarativeDebugTrace::addEventImpl(EventType event)
{
if (status() != Enabled || !m_enabled)
return;
- QDeclarativeDebugData ed = {m_timer.nsecsElapsed(), (int)Event, (int)event, QString(), -1};
+ QDeclarativeDebugData ed = {m_timer.nsecsElapsed(), (int)Event, (int)event, QString(), -1, 0, 0};
processMessage(ed);
}
@@ -133,7 +166,7 @@ void QDeclarativeDebugTrace::startRangeImpl(RangeType range)
if (status() != Enabled || !m_enabled)
return;
- QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeStart, (int)range, QString(), -1};
+ QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeStart, (int)range, QString(), -1, 0, 0};
processMessage(rd);
}
@@ -142,7 +175,7 @@ void QDeclarativeDebugTrace::rangeDataImpl(RangeType range, const QString &rData
if (status() != Enabled || !m_enabled)
return;
- QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeData, (int)range, rData, -1};
+ QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeData, (int)range, rData, -1, 0, 0};
processMessage(rd);
}
@@ -151,7 +184,7 @@ void QDeclarativeDebugTrace::rangeDataImpl(RangeType range, const QUrl &rData)
if (status() != Enabled || !m_enabled)
return;
- QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeData, (int)range, rData.toString(QUrl::FormattingOption(0x100)), -1};
+ QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeData, (int)range, rData.toString(QUrl::FormattingOption(0x100)), -1, 0, 0};
processMessage(rd);
}
@@ -160,7 +193,7 @@ void QDeclarativeDebugTrace::rangeLocationImpl(RangeType range, const QString &f
if (status() != Enabled || !m_enabled)
return;
- QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeLocation, (int)range, fileName, line};
+ QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeLocation, (int)range, fileName, line, 0, 0};
processMessage(rd);
}
@@ -169,7 +202,7 @@ void QDeclarativeDebugTrace::rangeLocationImpl(RangeType range, const QUrl &file
if (status() != Enabled || !m_enabled)
return;
- QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeLocation, (int)range, fileName.toString(QUrl::FormattingOption(0x100)), line};
+ QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeLocation, (int)range, fileName.toString(QUrl::FormattingOption(0x100)), line, 0, 0};
processMessage(rd);
}
@@ -178,17 +211,34 @@ void QDeclarativeDebugTrace::endRangeImpl(RangeType range)
if (status() != Enabled || !m_enabled)
return;
- QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeEnd, (int)range, QString(), -1};
+ QDeclarativeDebugData rd = {m_timer.nsecsElapsed(), (int)RangeEnd, (int)range, QString(), -1, 0, 0};
processMessage(rd);
}
+void QDeclarativeDebugTrace::animationFrameImpl(qint64 delta)
+{
+ if (status() != Enabled || !m_enabled)
+ return;
+
+ int animCount = QUnifiedTimer::instance()->runningAnimationCount();
+
+ if (animCount > 0 && delta > 0) {
+ // trim fps to integer
+ int fps = 1000 / delta;
+ QDeclarativeDebugData ed = {m_timer.nsecsElapsed(), (int)Event, (int)AnimationFrame, QString(), -1, fps, animCount};
+ processMessage(ed);
+ }
+}
+
/*
Either send the message directly, or queue up
a list of messages to send later (via sendMessages)
*/
void QDeclarativeDebugTrace::processMessage(const QDeclarativeDebugData &message)
{
- if (m_deferredSend)
+ QMutexLocker locker(&m_mutex);
+ if (m_deferredSend
+ || (QThread::currentThread() != QCoreApplication::instance()->thread()))
m_data.append(message);
else
sendMessage(message.toByteArray());
@@ -200,6 +250,7 @@ void QDeclarativeDebugTrace::processMessage(const QDeclarativeDebugData &message
void QDeclarativeDebugTrace::sendMessages()
{
if (m_deferredSend) {
+ QMutexLocker locker(&m_mutex);
//### this is a suboptimal way to send batched messages
for (int i = 0; i < m_data.count(); ++i)
sendMessage(m_data.at(i).toByteArray());
@@ -222,8 +273,12 @@ void QDeclarativeDebugTrace::messageReceived(const QByteArray &message)
m_messageReceived = true;
- if (!m_enabled)
+ if (!m_enabled) {
+ m_enabled = true;
+ addEvent(EndTrace);
+ m_enabled = false;
sendMessages();
+ }
}
QT_END_NAMESPACE
diff --git a/src/declarative/debugger/qdeclarativedebugtrace_p.h b/src/declarative/debugger/qdeclarativedebugtrace_p.h
index fb2ef53a4a..26535e1676 100644
--- a/src/declarative/debugger/qdeclarativedebugtrace_p.h
+++ b/src/declarative/debugger/qdeclarativedebugtrace_p.h
@@ -55,6 +55,8 @@
#include <private/qdeclarativedebugservice_p.h>
#include <QtCore/qelapsedtimer.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qvector.h>
QT_BEGIN_HEADER
@@ -69,11 +71,17 @@ struct QDeclarativeDebugData
//###
QString detailData; //used by RangeData and RangeLocation
int line; //used by RangeLocation
+ int framerate; //used by animation events
+ int animationcount; //used by animation events
QByteArray toByteArray() const;
};
+Q_DECLARE_TYPEINFO(QDeclarativeDebugData, Q_MOVABLE_TYPE);
+
class QUrl;
+class QDeclarativeEngine;
+
class Q_DECLARATIVE_EXPORT QDeclarativeDebugTrace : public QDeclarativeDebugService
{
public:
@@ -92,6 +100,8 @@ public:
FramePaint,
Mouse,
Key,
+ AnimationFrame,
+ EndTrace,
MaximumEventType
};
@@ -106,6 +116,9 @@ public:
MaximumRangeType
};
+ static void addEngine(QDeclarativeEngine *engine);
+ static void removeEngine(QDeclarativeEngine *engine);
+
static void addEvent(EventType);
static void startRange(RangeType);
@@ -114,8 +127,10 @@ public:
static void rangeLocation(RangeType, const QString &, int);
static void rangeLocation(RangeType, const QUrl &, int);
static void endRange(RangeType);
+ static void animationFrame(qint64);
QDeclarativeDebugTrace();
+ ~QDeclarativeDebugTrace();
protected:
virtual void messageReceived(const QByteArray &);
private:
@@ -126,13 +141,15 @@ private:
void rangeLocationImpl(RangeType, const QString &, int);
void rangeLocationImpl(RangeType, const QUrl &, int);
void endRangeImpl(RangeType);
+ void animationFrameImpl(qint64);
void processMessage(const QDeclarativeDebugData &);
void sendMessages();
QElapsedTimer m_timer;
bool m_enabled;
bool m_deferredSend;
bool m_messageReceived;
- QList<QDeclarativeDebugData> m_data;
+ QVector<QDeclarativeDebugData> m_data;
+ QMutex m_mutex;
};
QT_END_NAMESPACE
diff --git a/src/declarative/debugger/qdeclarativeenginedebug.cpp b/src/declarative/debugger/qdeclarativeenginedebug.cpp
index 237e2d6376..537e1e6a3d 100644
--- a/src/declarative/debugger/qdeclarativeenginedebug.cpp
+++ b/src/declarative/debugger/qdeclarativeenginedebug.cpp
@@ -39,11 +39,11 @@
**
****************************************************************************/
-#include "private/qdeclarativeenginedebug_p.h"
+#include "qdeclarativeenginedebug_p.h"
-#include "private/qdeclarativedebugclient_p.h"
+#include "qdeclarativedebugclient_p.h"
-#include <qdeclarativeenginedebugservice_p.h>
+#include "qdeclarativeenginedebugservice_p.h"
#include <private/qobject_p.h>
diff --git a/src/declarative/debugger/qdeclarativeenginedebugservice.cpp b/src/declarative/debugger/qdeclarativeenginedebugservice.cpp
index 9841f8778e..7fa577d7d9 100644
--- a/src/declarative/debugger/qdeclarativeenginedebugservice.cpp
+++ b/src/declarative/debugger/qdeclarativeenginedebugservice.cpp
@@ -39,20 +39,20 @@
**
****************************************************************************/
-#include "private/qdeclarativeenginedebugservice_p.h"
-
-#include "private/qdeclarativeboundsignal_p.h"
-#include "qdeclarativeengine.h"
-#include "private/qdeclarativemetatype_p.h"
-#include "qdeclarativeproperty.h"
-#include "private/qdeclarativeproperty_p.h"
-#include "private/qdeclarativebinding_p.h"
-#include "private/qdeclarativecontext_p.h"
-#include "private/qdeclarativewatcher_p.h"
-#include "private/qdeclarativevaluetype_p.h"
-#include "private/qdeclarativevmemetaobject_p.h"
-#include "private/qdeclarativeexpression_p.h"
-#include "private/qdeclarativepropertychanges_p.h"
+#include "qdeclarativeenginedebugservice_p.h"
+
+#include <private/qdeclarativeboundsignal_p.h>
+#include <qdeclarativeengine.h>
+#include <private/qdeclarativemetatype_p.h>
+#include <qdeclarativeproperty.h>
+#include <private/qdeclarativeproperty_p.h>
+#include <private/qdeclarativebinding_p.h>
+#include <private/qdeclarativecontext_p.h>
+#include <private/qdeclarativewatcher_p.h>
+#include <private/qdeclarativevaluetype_p.h>
+#include <private/qdeclarativevmemetaobject_p.h>
+#include <private/qdeclarativeexpression_p.h>
+#include <private/qdeclarativepropertychanges_p.h>
#include <QtCore/qdebug.h>
#include <QtCore/qmetaobject.h>
@@ -372,7 +372,7 @@ QDeclarativeEngineDebugService::objectData(QObject *object)
QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
if (type) {
- QString typeName = QLatin1String(type->qmlTypeName());
+ QString typeName = type->qmlTypeName();
int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
rv.objectType = lastSlash < 0 ? typeName : typeName.mid(lastSlash+1);
} else {
diff --git a/src/declarative/debugger/qdeclarativeinspectorinterface_p.h b/src/declarative/debugger/qdeclarativeinspectorinterface_p.h
index d0d9f44d7b..d4cd783b16 100644
--- a/src/declarative/debugger/qdeclarativeinspectorinterface_p.h
+++ b/src/declarative/debugger/qdeclarativeinspectorinterface_p.h
@@ -53,7 +53,7 @@
// We mean it.
//
-#include <QtDeclarative/private/qdeclarativeglobal_p.h>
+#include <private/qdeclarativeglobal_p.h>
QT_BEGIN_HEADER
diff --git a/src/declarative/debugger/qdeclarativeinspectorservice.cpp b/src/declarative/debugger/qdeclarativeinspectorservice.cpp
index f1ae354066..56441ae606 100644
--- a/src/declarative/debugger/qdeclarativeinspectorservice.cpp
+++ b/src/declarative/debugger/qdeclarativeinspectorservice.cpp
@@ -39,8 +39,9 @@
**
****************************************************************************/
-#include "private/qdeclarativeinspectorservice_p.h"
-#include "private/qdeclarativeinspectorinterface_p.h"
+#include "qdeclarativeinspectorservice_p.h"
+#include "qdeclarativeinspectorinterface_p.h"
+#include "qdeclarativedebugserver_p.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
@@ -65,11 +66,13 @@ QDeclarativeInspectorService *QDeclarativeInspectorService::instance()
void QDeclarativeInspectorService::addView(QObject *view)
{
m_views.append(view);
+ updateStatus();
}
void QDeclarativeInspectorService::removeView(QObject *view)
{
m_views.removeAll(view);
+ updateStatus();
}
void QDeclarativeInspectorService::sendMessage(const QByteArray &message)
@@ -80,17 +83,26 @@ void QDeclarativeInspectorService::sendMessage(const QByteArray &message)
QDeclarativeDebugService::sendMessage(message);
}
-void QDeclarativeInspectorService::statusChanged(Status status)
+void QDeclarativeInspectorService::statusChanged(Status /*status*/)
{
- if (m_views.isEmpty())
+ updateStatus();
+}
+
+void QDeclarativeInspectorService::updateStatus()
+{
+ if (m_views.isEmpty()) {
+ if (m_inspectorPlugin)
+ m_inspectorPlugin->deactivate();
return;
+ }
- if (status == Enabled) {
+ if (status() == Enabled) {
if (!m_inspectorPlugin)
m_inspectorPlugin = loadInspectorPlugin();
if (!m_inspectorPlugin) {
qWarning() << "Error while loading inspector plugin";
+ QDeclarativeDebugServer::instance()->removeService(this);
return;
}
diff --git a/src/declarative/debugger/qdeclarativeinspectorservice_p.h b/src/declarative/debugger/qdeclarativeinspectorservice_p.h
index 98b2e9deeb..df51ab8bfe 100644
--- a/src/declarative/debugger/qdeclarativeinspectorservice_p.h
+++ b/src/declarative/debugger/qdeclarativeinspectorservice_p.h
@@ -53,7 +53,7 @@
// We mean it.
//
-#include "private/qdeclarativedebugservice_p.h"
+#include "qdeclarativedebugservice_p.h"
#include <private/qdeclarativeglobal_p.h>
#include <QtCore/QList>
@@ -88,6 +88,7 @@ protected:
virtual void messageReceived(const QByteArray &);
private:
+ void updateStatus();
static QDeclarativeInspectorInterface *loadInspectorPlugin();
QList<QObject*> m_views;
diff --git a/src/declarative/debugger/qpacketprotocol.cpp b/src/declarative/debugger/qpacketprotocol.cpp
index 9b95d06e1e..3abb369e63 100644
--- a/src/declarative/debugger/qpacketprotocol.cpp
+++ b/src/declarative/debugger/qpacketprotocol.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "private/qpacketprotocol_p.h"
+#include "qpacketprotocol_p.h"
#include <QtCore/QBuffer>
#include <QtCore/QElapsedTimer>
diff --git a/src/declarative/debugger/qv8debugservice.cpp b/src/declarative/debugger/qv8debugservice.cpp
index 8486ddf49e..ecdf5977c8 100644
--- a/src/declarative/debugger/qv8debugservice.cpp
+++ b/src/declarative/debugger/qv8debugservice.cpp
@@ -41,9 +41,9 @@
#include "qv8debugservice_p.h"
#include "qdeclarativedebugservice_p_p.h"
-#include "qv8debug_p.h"
-#include "qv8engine_p.h"
-#include "qdeclarativeengine_p.h"
+#include <private/qv8debug_p.h>
+#include <private/qv8engine_p.h>
+#include <private/qdeclarativeengine_p.h>
#include <QtCore/QEventLoop>
#include <QtCore/QHash>
@@ -62,8 +62,8 @@ void DebugMessageHandler(const v8::Debug::Message& message)
return;
}
- const QByteArray response(QV8Engine::toStringStatic(
- message.GetJSON()).toUtf8());
+ const QString response(QV8Engine::toStringStatic(
+ message.GetJSON()));
QV8DebugService *service = QV8DebugService::instance();
service->debugMessageHandler(response);
@@ -99,13 +99,16 @@ public:
isolate->Dispose();
}
+ void sendDebugMessage(const QString &message);
+ static QByteArray packMessage(const QString &message);
+
bool initialized;
QJSEngine *engine;
v8::Isolate *isolate;
QList<QDeclarativeEngine *> engines;
QEventLoop loop;
QHash<QString,QString> sourcePath;
- QHash<QString,QByteArray> requestCache;
+ QHash<QString,QString> requestCache;
QHash<int,QString> eventList;
};
@@ -150,9 +153,9 @@ void QV8DebugService::removeEngine(QDeclarativeEngine *engine)
d->engines.removeAll(engine);
}
-void QV8DebugService::debugMessageHandler(QByteArray message)
+void QV8DebugService::debugMessageHandler(const QString &message)
{
- sendMessage(packMessage(message));
+ sendMessage(QV8DebugServicePrivate::packMessage(message));
}
void QV8DebugService::executionStopped()
@@ -164,7 +167,7 @@ void QV8DebugService::executionStopped()
}
}
-void QV8DebugService::appendSourcePath(QByteArray message)
+void QV8DebugService::appendSourcePath(const QString &message)
{
Q_D(QV8DebugService);
@@ -174,9 +177,8 @@ void QV8DebugService::appendSourcePath(QByteArray message)
receive any messages related to this operation */
{
v8::Isolate::Scope i_scope(d->isolate);
- QString req(message);
QJSValue parser = d->engine->evaluate(QLatin1String("JSON.parse"));
- QJSValue out = parser.call(QJSValue(), QJSValueList() << QJSValue(req));
+ QJSValue out = parser.call(QJSValue(), QJSValueList() << QJSValue(message));
msgMap = out.toVariant().toMap();
}
@@ -189,25 +191,24 @@ void QV8DebugService::appendSourcePath(QByteArray message)
//Check if there are any pending breakpoint requests for this file
if (d->requestCache.contains(fileName)) {
- QList<QByteArray> list = d->requestCache.values(fileName);
+ QList<QString> list = d->requestCache.values(fileName);
d->requestCache.remove(fileName);
- foreach (QByteArray request, list) {
- request.replace(fileName.toUtf8(), sourcePath.toUtf8());
- sendDebugMessage(request);
+ foreach (QString request, list) {
+ request.replace(fileName, sourcePath);
+ d->sendDebugMessage(request);
}
}
}
-void QV8DebugService::signalEmitted(const char *signal)
+void QV8DebugService::signalEmitted(const QString &signal)
{
//This function is only called by QDeclarativeBoundSignal
//only if there is a slot connected to the signal. Hence, there
//is no need for additional check.
Q_D(QV8DebugService);
- QString function(signal);
//Parse just the name and remove the class info
- if (d->eventList.key(function.left(function.indexOf(QLatin1String("("))))) {
+ if (d->eventList.key(signal.left(signal.indexOf(QLatin1String("("))))) {
v8::Debug::DebugBreak();
}
}
@@ -221,8 +222,12 @@ void QV8DebugService::messageReceived(const QByteArray &message)
ds >> command;
if (command == "V8DEBUG") {
- QByteArray request;
- ds >> request;
+ QString request;
+ {
+ QByteArray requestArray;
+ ds >> requestArray;
+ request = QString::fromUtf8(requestArray);
+ }
QVariantMap reqMap;
/* Parse the byte string in a separate isolate
@@ -230,9 +235,8 @@ void QV8DebugService::messageReceived(const QByteArray &message)
receive any messages related to this operation */
{
v8::Isolate::Scope i_scope(d->isolate);
- QString req(request);
QJSValue parser = d->engine->evaluate(QLatin1String("JSON.parse"));
- QJSValue out = parser.call(QJSValue(), QJSValueList() << QJSValue(req));
+ QJSValue out = parser.call(QJSValue(), QJSValueList() << QJSValue(request));
reqMap = out.toVariant().toMap();
}
@@ -257,7 +261,7 @@ void QV8DebugService::messageReceived(const QByteArray &message)
//Check if the filepath has been cached
if (d->sourcePath.contains(fileName)) {
QString filePath = d->sourcePath.value(fileName);
- request.replace(fileName.toUtf8(), filePath.toUtf8());
+ request.replace(fileName, filePath);
} else {
//Store the setbreakpoint message till filepath is resolved
d->requestCache.insertMulti(fileName, request);
@@ -282,8 +286,8 @@ void QV8DebugService::messageReceived(const QByteArray &message)
// "success" : true
// }
{
- v8::Isolate::Scope i_scope(d->isolate);
- const QString obj("{}");
+ v8::Isolate::Scope(d->isolate);
+ const QString obj(QLatin1String("{}"));
QJSValue parser = d->engine->evaluate(QLatin1String("JSON.parse"));
QJSValue jsonVal = parser.call(QJSValue(), QJSValueList() << obj);
jsonVal.setProperty(QLatin1String("type"), QJSValue(QLatin1String("response")));
@@ -316,14 +320,14 @@ void QV8DebugService::messageReceived(const QByteArray &message)
QJSValue stringify = d->engine->evaluate(QLatin1String("JSON.stringify"));
QJSValue json = stringify.call(QJSValue(), QJSValueList() << jsonVal);
- debugMessageHandler(json.toString().toUtf8());
+ debugMessageHandler(json.toString());
}
}
} else if (debugCommand == QLatin1String("clearbreakpoint")) {
//check if the breakpoint is a negative integer (event breakpoint)
const QVariantMap arguments = reqMap.value(QLatin1String("arguments")).toMap();
- const int bp = arguments.value("breakpoint").toInt();
+ const int bp = arguments.value(QLatin1String("breakpoint")).toInt();
if (bp < 0) {
d->eventList.remove(bp);
@@ -331,30 +335,27 @@ void QV8DebugService::messageReceived(const QByteArray &message)
}
}
if (forwardRequestToV8)
- sendDebugMessage(request);
+ d->sendDebugMessage(request);
}
}
QDeclarativeDebugService::messageReceived(message);
}
-void QV8DebugService::sendDebugMessage(const QByteArray &msg)
+void QV8DebugServicePrivate::sendDebugMessage(const QString &message)
{
- Q_D(QV8DebugService);
+ if (loop.isRunning())
+ loop.exit();
- const QString message(msg);
- if (d->loop.isRunning()) {
- d->loop.exit();
- }
v8::Debug::SendCommand(message.utf16(), message.size());
}
-QByteArray QV8DebugService::packMessage(QByteArray &message)
+QByteArray QV8DebugServicePrivate::packMessage(const QString &message)
{
QByteArray reply;
QDataStream rs(&reply, QIODevice::WriteOnly);
QByteArray cmd("V8DEBUG");
- rs << cmd << message;
+ rs << cmd << message.toUtf8();
return reply;
}
diff --git a/src/declarative/debugger/qv8debugservice_p.h b/src/declarative/debugger/qv8debugservice_p.h
index 09b8f66fb0..d8101ae3ff 100644
--- a/src/declarative/debugger/qv8debugservice_p.h
+++ b/src/declarative/debugger/qv8debugservice_p.h
@@ -53,9 +53,7 @@
// We mean it.
//
-#include <QtCore/QPointer>
-
-#include "private/qdeclarativedebugservice_p.h"
+#include "qdeclarativedebugservice_p.h"
QT_BEGIN_HEADER
@@ -64,7 +62,6 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
class QDeclarativeEngine;
-class QJSEngine;
class QV8DebugServicePrivate;
class QV8DebugService : public QDeclarativeDebugService
@@ -79,21 +76,17 @@ public:
void addEngine(QDeclarativeEngine *);
void removeEngine(QDeclarativeEngine *);
- void debugMessageHandler(QByteArray message);
+ void debugMessageHandler(const QString &message);
void executionStopped();
- void appendSourcePath(QByteArray message);
+ void appendSourcePath(const QString &message);
- void signalEmitted(const char *signal);
+ void signalEmitted(const QString &signal);
protected:
void messageReceived(const QByteArray &);
private:
- void sendDebugMessage(const QByteArray &msg);
- QByteArray packMessage(QByteArray &message);
-
-private:
Q_DISABLE_COPY(QV8DebugService)
Q_DECLARE_PRIVATE(QV8DebugService)
};
diff --git a/src/declarative/debugger/qv8profilerservice.cpp b/src/declarative/debugger/qv8profilerservice.cpp
new file mode 100644
index 0000000000..92a191688c
--- /dev/null
+++ b/src/declarative/debugger/qv8profilerservice.cpp
@@ -0,0 +1,247 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qv8profilerservice_p.h"
+#include "qdeclarativedebugservice_p_p.h"
+#include <private/qdeclarativeengine_p.h>
+#include <private/qv8profiler_p.h>
+
+#include <QtCore/QHash>
+
+QT_BEGIN_NAMESPACE
+
+Q_GLOBAL_STATIC(QV8ProfilerService, v8ServiceInstance)
+
+class ByteArrayOutputStream : public v8::OutputStream
+{
+ QByteArray *_buffer;
+public:
+ ByteArrayOutputStream(QByteArray *buffer)
+ : v8::OutputStream(),
+ _buffer(buffer) {}
+ void EndOfStream() {}
+ WriteResult WriteAsciiChunk(char *data, int size)
+ {
+ QByteArray b(data, size);
+ _buffer->append(b);
+ return kContinue;
+ }
+};
+
+// convert to a QByteArray that can be sent to the debug client
+QByteArray QV8ProfilerData::toByteArray() const
+{
+ QByteArray data;
+ //### using QDataStream is relatively expensive
+ QDataStream ds(&data, QIODevice::WriteOnly);
+ ds << messageType << filename << functionname << lineNumber << totalTime << selfTime << treeLevel;
+
+ return data;
+}
+
+class QV8ProfilerServicePrivate : public QDeclarativeDebugServicePrivate
+{
+ Q_DECLARE_PUBLIC(QV8ProfilerService)
+
+public:
+ QV8ProfilerServicePrivate()
+ :initialized(false)
+ {
+ }
+
+ void takeSnapshot(v8::HeapSnapshot::Type);
+
+ void printProfileTree(const v8::CpuProfileNode *node, int level = 0);
+ void sendMessages();
+
+ QList<QV8ProfilerData> m_data;
+
+ bool initialized;
+ QList<QDeclarativeEngine *> engines;
+};
+
+QV8ProfilerService::QV8ProfilerService(QObject *parent)
+ : QDeclarativeDebugService(*(new QV8ProfilerServicePrivate()), QLatin1String("V8Profiler"), parent)
+{
+ Q_D(QV8ProfilerService);
+ if (status() == Enabled) {
+ // ,block mode, client attached
+ while (!d->initialized)
+ waitForMessage();
+ }
+}
+
+QV8ProfilerService::~QV8ProfilerService()
+{
+}
+
+QV8ProfilerService *QV8ProfilerService::instance()
+{
+ return v8ServiceInstance();
+}
+
+void QV8ProfilerService::addEngine(QDeclarativeEngine *engine)
+{
+ Q_D(QV8ProfilerService);
+ Q_ASSERT(engine);
+ Q_ASSERT(!d->engines.contains(engine));
+
+ d->engines.append(engine);
+}
+
+void QV8ProfilerService::removeEngine(QDeclarativeEngine *engine)
+{
+ Q_D(QV8ProfilerService);
+ Q_ASSERT(engine);
+ Q_ASSERT(d->engines.contains(engine));
+
+ d->engines.removeOne(engine);
+}
+
+void QV8ProfilerService::messageReceived(const QByteArray &message)
+{
+ Q_D(QV8ProfilerService);
+
+ QDataStream ds(message);
+ QByteArray command;
+ QByteArray option;
+ QByteArray title;
+ ds >> command >> option;
+
+ if (command == "V8PROFILER") {
+ ds >> title;
+ if (option == "start") {
+ d->initialized = true;
+ startProfiling(QString::fromUtf8(title));
+ } else if (option == "stop") {
+ stopProfiling(QString::fromUtf8(title));
+ // Send messages to client
+ d->sendMessages();
+ }
+ }
+
+ if (command == "V8SNAPSHOT") {
+ if (option == "full")
+ d->takeSnapshot(v8::HeapSnapshot::kFull);
+ else if (option == "delete") {
+ v8::HeapProfiler::DeleteAllSnapshots();
+ }
+ }
+
+ QDeclarativeDebugService::messageReceived(message);
+}
+
+void QV8ProfilerService::startProfiling(const QString &title)
+{
+ // Start Profiling
+ v8::HandleScope handle_scope;
+ v8::Handle<v8::String> v8title = v8::String::New(reinterpret_cast<const uint16_t*>(title.data()), title.size());
+ v8::CpuProfiler::StartProfiling(v8title);
+}
+
+void QV8ProfilerService::stopProfiling(const QString &title)
+{
+ Q_D(QV8ProfilerService);
+ // Stop profiling
+ v8::HandleScope handle_scope;
+ v8::Handle<v8::String> v8title = v8::String::New(reinterpret_cast<const uint16_t*>(title.data()), title.size());
+ const v8::CpuProfile *cpuProfile = v8::CpuProfiler::StopProfiling(v8title);
+ const v8::CpuProfileNode *rootNode = cpuProfile->GetTopDownRoot();
+
+ d->printProfileTree(rootNode);
+}
+
+void QV8ProfilerServicePrivate::printProfileTree(const v8::CpuProfileNode *node, int level)
+{
+ for (int index = 0 ; index < node->GetChildrenCount() ; index++) {
+ const v8::CpuProfileNode* childNode = node->GetChild(index);
+ if (QV8Engine::toStringStatic(childNode->GetScriptResourceName()).length() > 0) {
+
+ QV8ProfilerData rd = {(int)QV8ProfilerService::V8Entry, QV8Engine::toStringStatic(childNode->GetScriptResourceName()),
+ QV8Engine::toStringStatic(childNode->GetFunctionName()),
+ childNode->GetLineNumber(), childNode->GetTotalTime(), childNode->GetSelfTime(), level};
+ m_data.append(rd);
+
+ // different nodes might have common children: fix at client side
+ if (childNode->GetChildrenCount() > 0) {
+ printProfileTree(childNode, level+1);
+ }
+ }
+ }
+}
+
+void QV8ProfilerServicePrivate::takeSnapshot(v8::HeapSnapshot::Type snapshotType)
+{
+ Q_Q(QV8ProfilerService);
+
+ v8::HandleScope scope;
+ v8::Local<v8::String> title = v8::String::New("");
+
+ QByteArray jsonSnapshot;
+ ByteArrayOutputStream bos(&jsonSnapshot);
+ const v8::HeapSnapshot *snapshot = v8::HeapProfiler::TakeSnapshot(title, snapshotType);
+ snapshot->Serialize(&bos, v8::HeapSnapshot::kJSON);
+
+ QByteArray data;
+ QDataStream ds(&data, QIODevice::WriteOnly);
+ ds << (int)QV8ProfilerService::V8Snapshot << jsonSnapshot;
+
+ q->sendMessage(data);
+}
+
+void QV8ProfilerServicePrivate::sendMessages()
+{
+ Q_Q(QV8ProfilerService);
+
+ for (int i = 0; i < m_data.count(); ++i)
+ q->sendMessage(m_data.at(i).toByteArray());
+ m_data.clear();
+
+ //indicate completion
+ QByteArray data;
+ QDataStream ds(&data, QIODevice::WriteOnly);
+ ds << (int)QV8ProfilerService::V8Complete;
+
+ q->sendMessage(data);
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/declarative/debugger/qv8profilerservice_p.h b/src/declarative/debugger/qv8profilerservice_p.h
new file mode 100644
index 0000000000..ea5119cd50
--- /dev/null
+++ b/src/declarative/debugger/qv8profilerservice_p.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QV8PROFILERSERVICE_P_H
+#define QV8PROFILERSERVICE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qdeclarativedebugservice_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+struct QV8ProfilerData
+{
+ int messageType;
+ QString filename;
+ QString functionname;
+ int lineNumber;
+ double totalTime;
+ double selfTime;
+ int treeLevel;
+
+ QByteArray toByteArray() const;
+};
+
+class QDeclarativeEngine;
+class QV8ProfilerServicePrivate;
+
+class QV8ProfilerService : public QDeclarativeDebugService
+{
+ Q_OBJECT
+public:
+ enum MessageType {
+ V8Entry,
+ V8Complete,
+ V8Snapshot,
+
+ V8MaximumMessage
+ };
+
+ QV8ProfilerService(QObject *parent = 0);
+ ~QV8ProfilerService();
+
+ static QV8ProfilerService *instance();
+
+ void addEngine(QDeclarativeEngine *);
+ void removeEngine(QDeclarativeEngine *);
+
+ void startProfiling(const QString &title);
+ void stopProfiling(const QString &title);
+
+protected:
+ void messageReceived(const QByteArray &);
+
+private:
+ Q_DISABLE_COPY(QV8ProfilerService)
+ Q_DECLARE_PRIVATE(QV8ProfilerService)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QV8PROFILERSERVICE_P_H
diff --git a/src/declarative/designer/designersupport.cpp b/src/declarative/designer/designersupport.cpp
index aaaeeb4ef0..d582ed1fe0 100644
--- a/src/declarative/designer/designersupport.cpp
+++ b/src/declarative/designer/designersupport.cpp
@@ -40,13 +40,13 @@
****************************************************************************/
#include "designersupport.h"
-#include "qsgitem_p.h"
+#include <private/qsgitem_p.h>
-#include <QtDeclarative/private/qsgshadereffectsource_p.h>
-#include <QtDeclarative/private/qsgrectangle_p.h>
-#include <QtDeclarative/private/qdeclarativeengine_p.h>
-#include <QtDeclarative/private/qsgview_p.h>
-#include <QtDeclarative/private/qdeclarativestategroup_p.h>
+#include <private/qsgshadereffectsource_p.h>
+#include <private/qsgrectangle_p.h>
+#include <private/qdeclarativeengine_p.h>
+#include <private/qsgview_p.h>
+#include <private/qdeclarativestategroup_p.h>
#include <QtGui/QImage>
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/items/context2d/context2d.pri b/src/declarative/items/context2d/context2d.pri
index 60fe28dd43..31ed75d82a 100644
--- a/src/declarative/items/context2d/context2d.pri
+++ b/src/declarative/items/context2d/context2d.pri
@@ -1,5 +1,3 @@
-INCLUDEPATH += $$PWD
-
SOURCES += \
$$PWD/qsgcanvasitem.cpp \
$$PWD/qsgcontext2d.cpp \
diff --git a/src/declarative/items/context2d/qsgcanvasitem.cpp b/src/declarative/items/context2d/qsgcanvasitem.cpp
index a8d1920b60..b3b4eab30d 100644
--- a/src/declarative/items/context2d/qsgcanvasitem.cpp
+++ b/src/declarative/items/context2d/qsgcanvasitem.cpp
@@ -39,16 +39,16 @@
**
****************************************************************************/
-#include "private/qsgadaptationlayer_p.h"
+#include <private/qsgadaptationlayer_p.h>
#include "qsgcanvasitem_p.h"
-#include "qsgitem_p.h"
+#include <private/qsgitem_p.h>
#include "qsgcontext2d_p.h"
#include "qsgcontext2dnode_p.h"
#include "qsgcontext2dtexture_p.h"
-#include "qdeclarativepixmapcache_p.h"
+#include <private/qdeclarativepixmapcache_p.h>
#include <qdeclarativeinfo.h>
-#include "qdeclarativeengine_p.h"
+#include <private/qdeclarativeengine_p.h>
#include <QtCore/QBuffer>
QT_BEGIN_NAMESPACE
@@ -85,7 +85,7 @@ QSGCanvasItemPrivate::QSGCanvasItemPrivate()
, hasTileSize(false)
, hasCanvasWindow(false)
, componentCompleted(false)
- , renderTarget(QSGCanvasItem::Image)
+ , renderTarget(QSGCanvasItem::FramebufferObject)
{
}
@@ -184,10 +184,6 @@ QSGCanvasItem::QSGCanvasItem(QSGItem *parent)
QSGCanvasItem::~QSGCanvasItem()
{
Q_D(QSGCanvasItem);
- if (d->texture) {
- d->texture->setItem(0);
- d->texture->deleteLater();
- }
delete d->context;
}
@@ -216,6 +212,7 @@ void QSGCanvasItem::setCanvasSize(const QSizeF & size)
d->canvasSize = size;
emit canvasSizeChanged();
polish();
+ update();
}
}
@@ -249,6 +246,7 @@ void QSGCanvasItem::setTileSize(const QSize & size)
emit tileSizeChanged();
polish();
+ update();
}
}
@@ -279,6 +277,7 @@ void QSGCanvasItem::setCanvasWindow(const QRectF& rect)
d->hasCanvasWindow = true;
emit canvasWindowChanged();
polish();
+ update();
}
}
@@ -378,6 +377,7 @@ void QSGCanvasItem::setRenderInThread(bool renderInThread)
disconnect(this, SIGNAL(painted()), this, SLOT(update()));
emit renderInThreadChanged();
polish();
+ update();
}
}
@@ -406,26 +406,28 @@ void QSGCanvasItem::geometryChanged(const QRectF &newGeometry,
}
polish();
+ update();
}
void QSGCanvasItem::componentComplete()
{
Q_D(QSGCanvasItem);
+ QSGItem::componentComplete();
- createContext();
+ if (!d->context)
+ createContext();
createTexture();
- markDirty(d->canvasWindow);
- QSGItem::componentComplete();
-
d->baseUrl = qmlEngine(this)->contextForObject(this)->baseUrl();
+ requestPaint();
+ updatePolish(); //force update the canvas sizes to texture for the first time
+ update();
d->componentCompleted = true;
}
void QSGCanvasItem::updatePolish()
{
Q_D(QSGCanvasItem);
-
QSGItem::updatePolish();
if (d->texture) {
if (!d->renderInThread && d->dirtyRect.isValid())
@@ -448,6 +450,7 @@ QSGNode *QSGCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
node = new QSGContext2DNode(this);
node->setTexture(d->texture);
+ node->setSize(d->canvasWindow.size());
node->update();
return node;
}
@@ -496,7 +499,7 @@ void QSGCanvasItem::createContext()
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Canvas::getContext(string contextId)
+ \qmlmethod object QtQuick2::Canvas::getContext(string contextId)
Currently, the canvas item only support the 2D context. If the \a contextId
parameter isn't provided or is "2d", then the QtQuick2::Context2D object is
@@ -505,11 +508,13 @@ void QSGCanvasItem::createContext()
QDeclarativeV8Handle QSGCanvasItem::getContext(const QString &contextId)
{
Q_D(QSGCanvasItem);
- Q_UNUSED(contextId);
- if (d->context)
- return QDeclarativeV8Handle::fromHandle(d->context->v8value());
- return QDeclarativeV8Handle::fromHandle(v8::Undefined());
+ if (contextId.toLower() != QLatin1String("2d"))
+ return QDeclarativeV8Handle::fromHandle(v8::Undefined());
+
+ if (!d->context)
+ createContext();
+ return QDeclarativeV8Handle::fromHandle(d->context->v8value());
}
/*!
@@ -526,7 +531,9 @@ void QSGCanvasItem::markDirty(const QRectF& region)
{
Q_D(QSGCanvasItem);
d->dirtyRect |= region;
- polish();
+ if (d->componentCompleted)
+ polish();
+ update();
}
@@ -544,7 +551,9 @@ void QSGCanvasItem::markDirty(const QRectF& region)
*/
bool QSGCanvasItem::save(const QString &filename) const
{
- return toImage().save(filename);
+ Q_D(const QSGCanvasItem);
+ QUrl url = d->baseUrl.resolved(QUrl::fromLocalFile(filename));
+ return toImage().save(url.toLocalFile());
}
QImage QSGCanvasItem::loadedImage(const QUrl& url)
@@ -675,24 +684,23 @@ QString QSGCanvasItem::toDataURL(const QString& mimeType) const
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
- QString mime = mimeType;
+ QString mime = mimeType.toLower();
QString type;
- if (mimeType == QLatin1Literal("image/bmp"))
+ if (mime == QLatin1Literal("image/png")) {
+ type = QLatin1Literal("PNG");
+ } else if (mime == QLatin1Literal("image/bmp"))
type = QLatin1Literal("BMP");
- else if (mimeType == QLatin1Literal("image/jpeg"))
+ else if (mime == QLatin1Literal("image/jpeg"))
type = QLatin1Literal("JPEG");
- else if (mimeType == QLatin1Literal("image/x-portable-pixmap"))
+ else if (mime == QLatin1Literal("image/x-portable-pixmap"))
type = QLatin1Literal("PPM");
- else if (mimeType == QLatin1Literal("image/tiff"))
+ else if (mime == QLatin1Literal("image/tiff"))
type = QLatin1Literal("TIFF");
- else if (mimeType == QLatin1Literal("image/xbm"))
- type = QLatin1Literal("XBM");
- else if (mimeType == QLatin1Literal("image/xpm"))
+ else if (mime == QLatin1Literal("image/xpm"))
type = QLatin1Literal("XPM");
- else {
- type = QLatin1Literal("PNG");
- mime = QLatin1Literal("image/png");
- }
+ else
+ return QLatin1Literal("data:,");
+
image.save(&buffer, type.toAscii());
buffer.close();
QString dataUrl = QLatin1Literal("data:%1;base64,%2");
diff --git a/src/declarative/items/context2d/qsgcanvasitem_p.h b/src/declarative/items/context2d/qsgcanvasitem_p.h
index 8d6441ac60..131a3f5fff 100644
--- a/src/declarative/items/context2d/qsgcanvasitem_p.h
+++ b/src/declarative/items/context2d/qsgcanvasitem_p.h
@@ -42,11 +42,9 @@
#ifndef QSGCANVASITEM_P_H
#define QSGCANVASITEM_P_H
-#include "qsgitem.h"
+#include <qsgitem.h>
#include <private/qv8engine_p.h>
-
-
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -54,7 +52,7 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
class QSGContext2D;
class QSGCanvasItemPrivate;
-class QSGCanvasItem : public QSGItem
+class Q_DECLARATIVE_EXPORT QSGCanvasItem : public QSGItem
{
Q_OBJECT
Q_ENUMS(RenderTarget)
@@ -147,4 +145,4 @@ QML_DECLARE_TYPE(QSGCanvasItem)
QT_END_HEADER
-#endif //QSGCANVASITEM_P_H \ No newline at end of file
+#endif //QSGCANVASITEM_P_H
diff --git a/src/declarative/items/context2d/qsgcontext2d.cpp b/src/declarative/items/context2d/qsgcontext2d.cpp
index e98c614754..5944a02658 100644
--- a/src/declarative/items/context2d/qsgcontext2d.cpp
+++ b/src/declarative/items/context2d/qsgcontext2d.cpp
@@ -42,23 +42,26 @@
#include "qsgcontext2d_p.h"
#include "qsgcontext2dcommandbuffer_p.h"
#include "qsgcanvasitem_p.h"
-#include "qsgitem_p.h"
-#include "qsgshadereffectsource_p.h"
+#include <private/qsgitem_p.h>
+#include <private/qsgshadereffectsource_p.h>
#include <QtGui/qopenglframebufferobject.h>
#include <QtCore/qdebug.h>
-#include "private/qsgcontext_p.h"
-#include "private/qdeclarativesvgparser_p.h"
-#include "private/qdeclarativepath_p.h"
+#include <private/qsgcontext_p.h>
+#include <private/qdeclarativesvgparser_p.h>
+#include <private/qdeclarativepath_p.h>
-#include "private/qsgimage_p_p.h"
+#include <private/qsgimage_p_p.h>
#include <QtGui/qguiapplication.h>
#include <qdeclarativeinfo.h>
#include <QtCore/qmath.h>
-#include "qv8engine_p.h"
+#include <private/qv8engine_p.h>
+
+#include <qdeclarativeengine.h>
+#include <private/qv8domerrors_p.h>
+#include <QtCore/qnumeric.h>
-#include "qdeclarativeengine.h"
QT_BEGIN_NAMESPACE
/*!
\qmlclass Context2D QSGContext2D
@@ -95,205 +98,82 @@ QT_BEGIN_NAMESPACE
static const double Q_PI = 3.14159265358979323846; // pi
#define DEGREES(t) ((t) * 180.0 / Q_PI)
-#define qClamp(val, min, max) qMin(qMax(val, min), max)
#define CHECK_CONTEXT(r) if (!r || !r->context || !r->context->buffer()) \
V8THROW_ERROR("Not a Context2D object");
#define CHECK_CONTEXT_SETTER(r) if (!r || !r->context || !r->context->buffer()) \
V8THROW_ERROR_SETTER("Not a Context2D object");
-
-static inline int extractInt(const char **name)
+#define qClamp(val, min, max) qMin(qMax(val, min), max)
+#define CHECK_RGBA(c) (c == '-' || c == '.' || (c >=0 && c <= 9))
+QColor qt_color_from_string(v8::Local<v8::Value> name)
{
- int result = 0;
- bool negative = false;
+ v8::String::AsciiValue str(name);
- //eat leading whitespace
- while (isspace(*name[0]))
- ++*name;
+ char *p = *str;
+ int len = str.length();
+ //rgb/hsl color string has at least 7 characters
+ if (!p || len > 255 || len <= 7)
+ return QColor(p);
+ else {
+ bool isRgb(false), isHsl(false), hasAlpha(false);
- if (*name[0] == '-') {
- ++*name;
- negative = true;
- } /*else if (name[0] == '+')
- ++name; //ignore*/
+ while (isspace(*p)) p++;
+ if (strncmp(p, "rgb", 3) == 0)
+ isRgb = true;
+ else if (strncmp(p, "hsl", 3) == 0)
+ isHsl = true;
+ else
+ return QColor(p);
- //construct number
- while (isdigit(*name[0])) {
- result = result * 10 + (*name[0] - '0');
- ++*name;
- }
- if (negative)
- result = -result;
+ p+=3; //skip "rgb" or "hsl"
+ hasAlpha = (*p == 'a') ? true : false;
- //handle optional percentage
- if (*name[0] == '%')
- result *= qreal(255)/100; //### floor or round?
-
- //eat trailing whitespace
- while (isspace(*name[0]))
- ++*name;
+ ++p; //skip "("
- return result;
-}
+ if (hasAlpha) ++p; //skip "a"
-static bool qt_get_rgb(const QString &string, QRgb *rgb)
-{
- const char *name = string.toLatin1().constData();
- int len = qstrlen(name);
-
- if (len < 5)
- return false;
+ int rh, gs, bl, alpha = 255;
- bool handleAlpha = false;
-
- if (name[0] != 'r')
- return false;
- if (name[1] != 'g')
- return false;
- if (name[2] != 'b')
- return false;
- if (name[3] == 'a') {
- handleAlpha = true;
- if(name[3] != '(')
- return false;
- } else if (name[3] != '(')
- return false;
-
- name += 4;
-
- int r, g, b, a = 1;
- int result;
-
- //red
- result = extractInt(&name);
- if (name[0] == ',') {
- r = result;
- ++name;
- } else
- return false;
-
- //green
- result = extractInt(&name);
- if (name[0] == ',') {
- g = result;
- ++name;
- } else
- return false;
-
- char nextChar = handleAlpha ? ',' : ')';
-
- //blue
- result = extractInt(&name);
- if (name[0] == nextChar) {
- b = result;
- ++name;
- } else
- return false;
-
- //alpha
- if (handleAlpha) {
- result = extractInt(&name);
- if (name[0] == ')') {
- a = result * 255; //map 0-1 to 0-255
- ++name;
- } else
- return false;
- }
-
- if (name[0] != '\0')
- return false;
-
- *rgb = qRgba(qClamp(r,0,255), qClamp(g,0,255), qClamp(b,0,255), qClamp(a,0,255));
- return true;
-}
-
-//### unify with qt_get_rgb?
-static bool qt_get_hsl(const QString &string, QColor *color)
-{
- const char *name = string.toLatin1().constData();
- int len = qstrlen(name);
-
- if (len < 5)
- return false;
-
- bool handleAlpha = false;
-
- if (name[0] != 'h')
- return false;
- if (name[1] != 's')
- return false;
- if (name[2] != 'l')
- return false;
- if (name[3] == 'a') {
- handleAlpha = true;
- if(name[3] != '(')
- return false;
- } else if (name[3] != '(')
- return false;
-
- name += 4;
-
- int h, s, l, a = 1;
- int result;
-
- //hue
- result = extractInt(&name);
- if (name[0] == ',') {
- h = result;
- ++name;
- } else
- return false;
-
- //saturation
- result = extractInt(&name);
- if (name[0] == ',') {
- s = result;
- ++name;
- } else
- return false;
-
- char nextChar = handleAlpha ? ',' : ')';
-
- //lightness
- result = extractInt(&name);
- if (name[0] == nextChar) {
- l = result;
- ++name;
- } else
- return false;
-
- //alpha
- if (handleAlpha) {
- result = extractInt(&name);
- if (name[0] == ')') {
- a = result * 255; //map 0-1 to 0-255
- ++name;
- } else
- return false;
- }
-
- if (name[0] != '\0')
- return false;
-
- *color = QColor::fromHsl(qClamp(h,0,255), qClamp(s,0,255), qClamp(l,0,255), qClamp(a,0,255));
- return true;
-}
-
-//### optimize further
-QColor qt_color_from_string(const QString &name)
-{
- if (name.startsWith(QLatin1String("rgb"))) {
- QRgb rgb;
- if (qt_get_rgb(name, &rgb))
- return QColor(rgb);
- } else if (name.startsWith(QLatin1String("hsl"))) {
- QColor color;
- if (qt_get_hsl(name, &color))
- return color;
- }
+ //red
+ while (isspace(*p)) p++;
+ rh = strtol(p, &p, 10);
+ if (*p == '%') {
+ rh = qRound(rh/100.0 * 255);
+ ++p;
+ }
+ if (*p++ != ',') return QColor();
+
+ //green
+ while (isspace(*p)) p++;
+ gs = strtol(p, &p, 10);
+ if (*p == '%') {
+ gs = qRound(gs/100.0 * 255);
+ ++p;
+ }
+ if (*p++ != ',') return QColor();
+
+ //blue
+ while (isspace(*p)) p++;
+ bl = strtol(p, &p, 10);
+ if (*p == '%') {
+ bl = qRound(bl/100.0 * 255);
+ ++p;
+ }
+
+ if (hasAlpha) {
+ if (*p++!= ',') return QColor();
+ while (isspace(*p)) p++;
+ alpha = qRound(strtod(p, &p) * 255);
+ }
- return QColor(name);
+ if (*p != ')') return QColor();
+ if (isRgb)
+ return QColor::fromRgba(qRgba(qClamp(rh, 0, 255), qClamp(gs, 0, 255), qClamp(bl, 0, 255), qClamp(alpha, 0, 255)));
+ else
+ return QColor::fromHsl(qClamp(rh, 0, 255), qClamp(gs, 0, 255), qClamp(bl, 0, 255), qClamp(alpha, 0, 255));
+ }
+ return QColor();
}
QFont qt_font_from_string(const QString& fontString) {
@@ -332,9 +212,8 @@ public:
v8::Persistent<v8::Function> constructorPixelArray;
v8::Persistent<v8::Function> constructorImageData;
};
-V8_DEFINE_EXTENSION(QSGContext2DEngineData, engineData);
-
+V8_DEFINE_EXTENSION(QSGContext2DEngineData, engineData)
class QV8Context2DResource : public QV8ObjectResource
{
@@ -348,8 +227,14 @@ class QV8Context2DStyleResource : public QV8ObjectResource
{
V8_RESOURCE_TYPE(Context2DStyleType)
public:
- QV8Context2DStyleResource(QV8Engine *e) : QV8ObjectResource(e) {}
+ QV8Context2DStyleResource(QV8Engine *e)
+ : QV8ObjectResource(e)
+ , patternRepeatX(false)
+ , patternRepeatY(false)
+ {}
QBrush brush;
+ bool patternRepeatX:1;
+ bool patternRepeatY:1;
};
class QV8Context2DPixelArrayResource : public QV8ObjectResource
@@ -528,10 +413,10 @@ static v8::Local<v8::Object> qt_create_image_data(qreal w, qreal h, QV8Engine* e
QV8Context2DPixelArrayResource *r = new QV8Context2DPixelArrayResource(engine);
if (image.isNull()) {
r->image = QImage(w, h, QImage::Format_ARGB32);
- r->image.fill(Qt::transparent);
+ r->image.fill(0x00000000);
} else {
Q_ASSERT(image.width() == w && image.height() == h);
- r->image = image;
+ r->image = image.format() == QImage::Format_ARGB32 ? image : image.convertToFormat(QImage::Format_ARGB32);
}
v8::Local<v8::Object> pixelData = ed->constructorPixelArray->NewInstance();
pixelData->SetExternalResource(r);
@@ -560,7 +445,7 @@ static v8::Handle<v8::Value> ctx2d_canvas(v8::Local<v8::String>, const v8::Acces
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::restore()
+ \qmlmethod object QtQuick2::Context2D::restore()
Pops the top state on the stack, restoring the context to that state.
\sa QtQuick2::Context2D::save()
@@ -575,7 +460,7 @@ static v8::Handle<v8::Value> ctx2d_restore(const v8::Arguments &args)
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::reset()
+ \qmlmethod object QtQuick2::Context2D::reset()
Resets the context state and properties to the default values.
*/
static v8::Handle<v8::Value> ctx2d_reset(const v8::Arguments &args)
@@ -584,11 +469,14 @@ static v8::Handle<v8::Value> ctx2d_reset(const v8::Arguments &args)
CHECK_CONTEXT(r)
r->context->reset();
+ r->context->m_path = QPainterPath();
+ r->context->m_path.setFillRule(Qt::WindingFill);
+
return args.This();
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::save()
+ \qmlmethod object QtQuick2::Context2D::save()
Pushes the current state onto the state stack.
Before changing any state attributes, you should save the current state
@@ -629,7 +517,7 @@ static v8::Handle<v8::Value> ctx2d_save(const v8::Arguments &args)
// transformations
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::rotate(real angle)
+ \qmlmethod object QtQuick2::Context2D::rotate(real angle)
Rotate the canvas around the current origin by \c angle in radians and clockwise direction.
\code
ctx.rotate(Math.PI/2);
@@ -648,9 +536,11 @@ static v8::Handle<v8::Value> ctx2d_rotate(const v8::Arguments &args)
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
CHECK_CONTEXT(r)
-
if (args.Length() == 1) {
qreal angle = args[0]->NumberValue();
+ if (!qIsFinite(angle))
+ return args.This();
+
r->context->state.matrix.rotate(DEGREES(angle));
r->context->buffer()->updateMatrix(r->context->state.matrix);
}
@@ -659,7 +549,7 @@ static v8::Handle<v8::Value> ctx2d_rotate(const v8::Arguments &args)
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::scale(real x, real y)
+ \qmlmethod object QtQuick2::Context2D::scale(real x, real y)
Increases or decreases the size of each unit in the canvas grid by multiplying the scale factors
to the current tranform matrix.
Where \c x is the scale factor in the horizontal direction and \c y is the scale factor in the
@@ -682,6 +572,9 @@ static v8::Handle<v8::Value> ctx2d_scale(const v8::Arguments &args)
qreal x, y;
x = args[0]->NumberValue();
y = args[1]->NumberValue();
+ if (!qIsFinite(x) || !qIsFinite(y))
+ return args.This();
+
r->context->state.matrix.scale(x, y);
r->context->buffer()->updateMatrix(r->context->state.matrix);
}
@@ -690,7 +583,7 @@ static v8::Handle<v8::Value> ctx2d_scale(const v8::Arguments &args)
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::setTransform(real a, real b, real c, real d, real e, real f)
+ \qmlmethod object QtQuick2::Context2D::setTransform(real a, real b, real c, real d, real e, real f)
Changes the transformation matrix to the matrix given by the arguments as described below.
Modifying the transformation matrix directly enables you to perform scaling,
@@ -729,12 +622,22 @@ static v8::Handle<v8::Value> ctx2d_setTransform(const v8::Arguments &args)
if (args.Length() == 6) {
- r->context->state.matrix = QTransform(args[0]->NumberValue(),
- args[1]->NumberValue(),
- args[2]->NumberValue(),
- args[3]->NumberValue(),
- args[4]->NumberValue(),
- args[5]->NumberValue());
+ qreal a = args[0]->NumberValue();
+ qreal b = args[1]->NumberValue();
+ qreal c = args[2]->NumberValue();
+ qreal d = args[3]->NumberValue();
+ qreal e = args[4]->NumberValue();
+ qreal f = args[5]->NumberValue();
+
+ if (!qIsFinite(a)
+ || !qIsFinite(b)
+ || !qIsFinite(c)
+ || !qIsFinite(d)
+ || !qIsFinite(e)
+ || !qIsFinite(f))
+ return args.This();
+
+ r->context->state.matrix = QTransform(a, b, c, d, e, f);
r->context->buffer()->updateMatrix(r->context->state.matrix);
}
@@ -742,7 +645,7 @@ static v8::Handle<v8::Value> ctx2d_setTransform(const v8::Arguments &args)
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::transform(real a, real b, real c, real d, real e, real f)
+ \qmlmethod object QtQuick2::Context2D::transform(real a, real b, real c, real d, real e, real f)
This method is very similar to \a QtQuick2::Context2D::setTransform(), but instead of replacing the old
tranform matrix, this method applies the given tranform matrix to the current matrix by mulitplying to it.
@@ -758,12 +661,22 @@ static v8::Handle<v8::Value> ctx2d_transform(const v8::Arguments &args)
if (args.Length() == 6) {
- r->context->state.matrix *= QTransform(args[0]->NumberValue(),
- args[1]->NumberValue(),
- args[2]->NumberValue(),
- args[3]->NumberValue(),
- args[4]->NumberValue(),
- args[5]->NumberValue());
+ qreal a = args[0]->NumberValue();
+ qreal b = args[1]->NumberValue();
+ qreal c = args[2]->NumberValue();
+ qreal d = args[3]->NumberValue();
+ qreal e = args[4]->NumberValue();
+ qreal f = args[5]->NumberValue();
+
+ if (!qIsFinite(a)
+ || !qIsFinite(b)
+ || !qIsFinite(c)
+ || !qIsFinite(d)
+ || !qIsFinite(e)
+ || !qIsFinite(f))
+ return args.This();
+
+ r->context->state.matrix *= QTransform(a, b, c, d, e, f);
r->context->buffer()->updateMatrix(r->context->state.matrix);
}
@@ -771,7 +684,7 @@ static v8::Handle<v8::Value> ctx2d_transform(const v8::Arguments &args)
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::translate(real x, real y)
+ \qmlmethod object QtQuick2::Context2D::translate(real x, real y)
Translates the origin of the canvas to point (\c x, \c y).
\c x is the horizontal distance that the origin is translated, in coordinate space units,
@@ -786,8 +699,13 @@ static v8::Handle<v8::Value> ctx2d_translate(const v8::Arguments &args)
if (args.Length() == 2) {
- r->context->state.matrix.translate(args[0]->NumberValue(),
- args[1]->NumberValue());
+ qreal x = args[0]->NumberValue();
+ qreal y = args[1]->NumberValue();
+
+ if (!qIsFinite(x) || !qIsFinite(y))
+ return args.This();
+
+ r->context->state.matrix.translate(x, y);
r->context->buffer()->updateMatrix(r->context->state.matrix);
}
@@ -796,7 +714,7 @@ static v8::Handle<v8::Value> ctx2d_translate(const v8::Arguments &args)
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::resetTransform()
+ \qmlmethod object QtQuick2::Context2D::resetTransform()
Reset the transformation matrix to default value.
\sa QtQuick2::Context2D::transform(), QtQuick2::Context2D::setTransform(), QtQuick2::Context2D::reset()
@@ -814,7 +732,7 @@ static v8::Handle<v8::Value> ctx2d_resetTransform(const v8::Arguments &args)
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::shear(real sh, real sv )
+ \qmlmethod object QtQuick2::Context2D::shear(real sh, real sv )
Shear the transformation matrix with \a sh in horizontal direction and \a sv in vertical direction.
*/
static v8::Handle<v8::Value> ctx2d_shear(const v8::Arguments &args)
@@ -822,10 +740,16 @@ static v8::Handle<v8::Value> ctx2d_shear(const v8::Arguments &args)
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
CHECK_CONTEXT(r)
- r->context->state.matrix.shear(args[0]->NumberValue(),
- args[1]->NumberValue());
- r->context->buffer()->updateMatrix(r->context->state.matrix);
+ if (args.Length() == 2) {
+ qreal sh = args[0]->NumberValue();
+ qreal sv = args[1]->NumberValue();
+ if (!qIsFinite(sh) || !qIsFinite(sv))
+ return args.This();
+
+ r->context->state.matrix.shear(sh, sv);
+ r->context->buffer()->updateMatrix(r->context->state.matrix);
+ }
return args.This();
}
// compositing
@@ -851,6 +775,9 @@ static void ctx2d_globalAlpha_set(v8::Local<v8::String>, v8::Local<v8::Value> va
qreal globalAlpha = value->NumberValue();
+ if (!qIsFinite(globalAlpha))
+ return;
+
if (globalAlpha >= 0.0 && globalAlpha <= 1.0 && r->context->state.globalAlpha != globalAlpha) {
r->context->state.globalAlpha = globalAlpha;
r->context->buffer()->setGlobalAlpha(r->context->state.globalAlpha);
@@ -902,7 +829,11 @@ static void ctx2d_globalCompositeOperation_set(v8::Local<v8::String>, v8::Local<
QV8Engine *engine = V8ENGINE_ACCESSOR();
- QPainter::CompositionMode cm = qt_composite_mode_from_string(engine->toString(value));
+ QString mode = engine->toString(value);
+ QPainter::CompositionMode cm = qt_composite_mode_from_string(mode);
+ if (cm == QPainter::CompositionMode_SourceOver && mode != QStringLiteral("source-over"))
+ return;
+
if (cm != r->context->state.globalCompositeOperation) {
r->context->state.globalCompositeOperation = cm;
r->context->buffer()->setGlobalCompositeOperation(cm);
@@ -937,6 +868,19 @@ static v8::Handle<v8::Value> ctx2d_fillStyle(v8::Local<v8::String>, const v8::Ac
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
CHECK_CONTEXT(r)
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+ QColor color = r->context->state.fillStyle.color();
+ if (color.isValid()) {
+ if (color.alpha() == 255)
+ return engine->toString(color.name());
+ QString alphaString = QString::number(color.alphaF(), 'f');
+ while (alphaString.endsWith(QLatin1Char('0')))
+ alphaString.chop(1);
+ if (alphaString.endsWith(QLatin1Char('.')))
+ alphaString += QLatin1Char('0');
+ return engine->toString(QString::fromLatin1("rgba(%1, %2, %3, %4)").arg(color.red()).arg(color.green()).arg(color.blue()).arg(alphaString));
+ }
return r->context->m_fillStyle;
}
@@ -947,24 +891,28 @@ static void ctx2d_fillStyle_set(v8::Local<v8::String>, v8::Local<v8::Value> valu
QV8Engine *engine = V8ENGINE_ACCESSOR();
- r->context->m_fillStyle = value;
if (value->IsObject()) {
QColor color = engine->toVariant(value, qMetaTypeId<QColor>()).value<QColor>();
if (color.isValid()) {
r->context->state.fillStyle = color;
r->context->buffer()->setFillStyle(color);
+ r->context->m_fillStyle = value;
} else {
QV8Context2DStyleResource *style = v8_resource_cast<QV8Context2DStyleResource>(value->ToObject());
if (style && style->brush != r->context->state.fillStyle) {
r->context->state.fillStyle = style->brush;
- r->context->buffer()->setFillStyle(style->brush);
+ r->context->buffer()->setFillStyle(style->brush, style->patternRepeatX, style->patternRepeatY);
+ r->context->m_fillStyle = value;
+ r->context->state.fillPatternRepeatX = style->patternRepeatX;
+ r->context->state.fillPatternRepeatY = style->patternRepeatY;
}
}
} else if (value->IsString()) {
- QColor color = qt_color_from_string(engine->toString(value));
+ QColor color = qt_color_from_string(value);
if (color.isValid() && r->context->state.fillStyle != QBrush(color)) {
r->context->state.fillStyle = QBrush(color);
r->context->buffer()->setFillStyle(r->context->state.fillStyle);
+ r->context->m_fillStyle = value;
}
}
}
@@ -996,10 +944,10 @@ static void ctx2d_fillRule_set(v8::Local<v8::String>, v8::Local<v8::Value> value
QV8Engine *engine = V8ENGINE_ACCESSOR();
- if ((value->IsString() && engine->toString(value) == "WindingFill")
+ if ((value->IsString() && engine->toString(value) == QStringLiteral("WindingFill"))
||(value->IsNumber() && value->NumberValue() == Qt::WindingFill)) {
r->context->state.fillRule = Qt::WindingFill;
- } else if ((value->IsString() && engine->toString(value) == "OddEvenFill")
+ } else if ((value->IsString() && engine->toString(value) == QStringLiteral("OddEvenFill"))
||(value->IsNumber() && value->NumberValue() == Qt::OddEvenFill)) {
r->context->state.fillRule = Qt::OddEvenFill;
} else {
@@ -1025,7 +973,19 @@ v8::Handle<v8::Value> ctx2d_strokeStyle(v8::Local<v8::String>, const v8::Accesso
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
CHECK_CONTEXT(r)
+ QV8Engine *engine = V8ENGINE_ACCESSOR();
+ QColor color = r->context->state.strokeStyle.color();
+ if (color.isValid()) {
+ if (color.alpha() == 255)
+ return engine->toString(color.name());
+ QString alphaString = QString::number(color.alphaF(), 'f');
+ while (alphaString.endsWith(QLatin1Char('0')))
+ alphaString.chop(1);
+ if (alphaString.endsWith(QLatin1Char('.')))
+ alphaString += QLatin1Char('0');
+ return engine->toString(QString::fromLatin1("rgba(%1, %2, %3, %4)").arg(color.red()).arg(color.green()).arg(color.blue()).arg(alphaString));
+ }
return r->context->m_strokeStyle;
}
@@ -1036,30 +996,35 @@ static void ctx2d_strokeStyle_set(v8::Local<v8::String>, v8::Local<v8::Value> va
QV8Engine *engine = V8ENGINE_ACCESSOR();
- r->context->m_strokeStyle = value;
if (value->IsObject()) {
QColor color = engine->toVariant(value, qMetaTypeId<QColor>()).value<QColor>();
if (color.isValid()) {
r->context->state.fillStyle = color;
r->context->buffer()->setStrokeStyle(color);
+ r->context->m_strokeStyle = value;
} else {
QV8Context2DStyleResource *style = v8_resource_cast<QV8Context2DStyleResource>(value->ToObject());
if (style && style->brush != r->context->state.strokeStyle) {
r->context->state.strokeStyle = style->brush;
- r->context->buffer()->setStrokeStyle(style->brush);
+ r->context->buffer()->setStrokeStyle(style->brush, style->patternRepeatX, style->patternRepeatY);
+ r->context->m_strokeStyle = value;
+ r->context->state.strokePatternRepeatX = style->patternRepeatX;
+ r->context->state.strokePatternRepeatY = style->patternRepeatY;
+
}
}
} else if (value->IsString()) {
- QColor color = qt_color_from_string(engine->toString(value));
+ QColor color = qt_color_from_string(value);
if (color.isValid() && r->context->state.strokeStyle != QBrush(color)) {
r->context->state.strokeStyle = QBrush(color);
r->context->buffer()->setStrokeStyle(r->context->state.strokeStyle);
+ r->context->m_strokeStyle = value;
}
}
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::createLinearGradient(real x0, real y0, real x1, real y1)
+ \qmlmethod object QtQuick2::Context2D::createLinearGradient(real x0, real y0, real x1, real y1)
Returns a CanvasGradient object that represents a linear gradient that transitions the color along a line between
the start point (\a x0, \a y0) and the end point (\a x1, \a y1).
@@ -1069,6 +1034,7 @@ static void ctx2d_strokeStyle_set(v8::Local<v8::String>, v8::Local<v8::Value> va
\sa QtQuick2::Context2D::CanvasGradient::addColorStop
\sa QtQuick2::Context2D::createRadialGradient
+ \sa QtQuick2::Context2D::ctx2d_createConicalGradient
\sa QtQuick2::Context2D::createPattern
\sa QtQuick2::Context2D::fillStyle
\sa QtQuick2::Context2D::strokeStyle
@@ -1083,14 +1049,21 @@ static v8::Handle<v8::Value> ctx2d_createLinearGradient(const v8::Arguments &arg
QV8Engine *engine = V8ENGINE();
if (args.Length() == 4) {
- //TODO:infinite or NaN, the method must raise a NOT_SUPPORTED_ERR
QSGContext2DEngineData *ed = engineData(engine);
v8::Local<v8::Object> gradient = ed->constructorGradient->NewInstance();
QV8Context2DStyleResource *r = new QV8Context2DStyleResource(engine);
- r->brush = QLinearGradient(args[0]->NumberValue(),
- args[1]->NumberValue(),
- args[2]->NumberValue(),
- args[3]->NumberValue());
+ qreal x0 = args[0]->NumberValue();
+ qreal y0 = args[1]->NumberValue();
+ qreal x1 = args[2]->NumberValue();
+ qreal y1 = args[3]->NumberValue();
+
+ if (!qIsFinite(x0)
+ || !qIsFinite(y0)
+ || !qIsFinite(x1)
+ || !qIsFinite(y1))
+ V8THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createLinearGradient(): Incorrect arguments")
+
+ r->brush = QLinearGradient(x0, y0, x1, y1);
gradient->SetExternalResource(r);
return gradient;
}
@@ -1099,12 +1072,13 @@ static v8::Handle<v8::Value> ctx2d_createLinearGradient(const v8::Arguments &arg
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::createRadialGradient(real x0, real y0, real r0, real x1, real y1, real r1)
+ \qmlmethod object QtQuick2::Context2D::createRadialGradient(real x0, real y0, real r0, real x1, real y1, real r1)
Returns a CanvasGradient object that represents a radial gradient that paints along the cone given by the start circle with
origin (x0, y0) and radius r0, and the end circle with origin (x1, y1) and radius r1.
\sa QtQuick2::Context2D::CanvasGradient::addColorStop
\sa QtQuick2::Context2D::createLinearGradient
+ \sa QtQuick2::Context2D::ctx2d_createConicalGradient
\sa QtQuick2::Context2D::createPattern
\sa QtQuick2::Context2D::fillStyle
\sa QtQuick2::Context2D::strokeStyle
@@ -1129,8 +1103,19 @@ static v8::Handle<v8::Value> ctx2d_createRadialGradient(const v8::Arguments &arg
qreal x1 = args[3]->NumberValue();
qreal y1 = args[4]->NumberValue();
qreal r1 = args[5]->NumberValue();
- //TODO:infinite or NaN, a NOT_SUPPORTED_ERR exception must be raised.
- //If either of r0 or r1 are negative, an INDEX_SIZE_ERR exception must be raised.
+
+ if (!qIsFinite(x0)
+ || !qIsFinite(y0)
+ || !qIsFinite(x1)
+ || !qIsFinite(r0)
+ || !qIsFinite(r1)
+ || !qIsFinite(y1))
+ V8THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createRadialGradient(): Incorrect arguments")
+
+ if (r0 < 0 || r1 < 0)
+ V8THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "createRadialGradient(): Incorrect arguments")
+
+
r->brush = QRadialGradient(QPointF(x1, y1), r0+r1, QPointF(x0, y0));
gradient->SetExternalResource(r);
return gradient;
@@ -1138,6 +1123,49 @@ static v8::Handle<v8::Value> ctx2d_createRadialGradient(const v8::Arguments &arg
return args.This();
}
+
+/*!
+ \qmlmethod object QtQuick2::Context2D::createConicalGradient(real x, real y, real angle)
+ Returns a CanvasGradient object that represents a conical gradient that interpolate colors counter-clockwise around a center point (\c x, \c y)
+ with start angle \c angle in units of radians.
+
+ \sa QtQuick2::Context2D::CanvasGradient::addColorStop
+ \sa QtQuick2::Context2D::createLinearGradient
+ \sa QtQuick2::Context2D::ctx2d_createRadialGradient
+ \sa QtQuick2::Context2D::createPattern
+ \sa QtQuick2::Context2D::fillStyle
+ \sa QtQuick2::Context2D::strokeStyle
+ */
+
+static v8::Handle<v8::Value> ctx2d_createConicalGradient(const v8::Arguments &args)
+{
+ QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+ CHECK_CONTEXT(r)
+
+
+ QV8Engine *engine = V8ENGINE();
+
+ if (args.Length() == 6) {
+ QSGContext2DEngineData *ed = engineData(engine);
+ v8::Local<v8::Object> gradient = ed->constructorGradient->NewInstance();
+ QV8Context2DStyleResource *r = new QV8Context2DStyleResource(engine);
+
+ qreal x = args[0]->NumberValue();
+ qreal y = args[1]->NumberValue();
+ qreal angle = DEGREES(args[2]->NumberValue());
+ if (!qIsFinite(x) || !qIsFinite(y))
+ V8THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createConicalGradient(): Incorrect arguments");
+
+ if (!qIsFinite(angle))
+ V8THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "createConicalGradient(): Incorrect arguments");
+
+ r->brush = QConicalGradient(x, y, angle);
+ gradient->SetExternalResource(r);
+ return gradient;
+ }
+
+ return args.This();
+}
/*!
\qmlmethod variant createPattern(Color color, enumeration patternMode)
This is a overload function.
@@ -1189,43 +1217,57 @@ static v8::Handle<v8::Value> ctx2d_createPattern(const v8::Arguments &args)
QV8Engine *engine = V8ENGINE();
- //FIXME::
-
-// if (args.Length() == 2) {
-// QSGContext2DEngineData *ed = engineData(engine);
-// v8::Local<v8::Object> pattern = ed->constructorPattern->NewInstance();
-// QV8Context2DStyleResource *r = new QV8Context2DStyleResource(engine);
-
-// QImage img;
-
-// QSGItem* item = qobject_cast<QSGItem*>(engine->toQObject(args[0]));
-// if (item) {
-// img = qt_item_to_image(item);
-// if (img.isNull()) {
-// //exception: INVALID_STATE_ERR
-// }
-// } /*else {
-// //exception: TYPE_MISMATCH_ERR
-// }*/
-
-// QString repetition = engine->toString(args[1]);
-
-// if (repetition == "repeat" || repetition.isEmpty()) {
-// //TODO
-// } else if (repetition == "repeat-x") {
-// //TODO
-// } else if (repetition == "repeat-y") {
-// //TODO
-// } else if (repetition == "no-repeat") {
-// //TODO
-// } else {
-// //TODO: exception: SYNTAX_ERR
-// }
-// r->brush = img;
-// pattern->SetExternalResource(r);
- // return pattern;
-// }
- return v8::Null();
+ if (args.Length() == 2) {
+ QSGContext2DEngineData *ed = engineData(engine);
+ QV8Context2DStyleResource *styleResouce = new QV8Context2DStyleResource(engine);
+
+ QColor color = engine->toVariant(args[0], qMetaTypeId<QColor>()).value<QColor>();
+ if (color.isValid()) {
+ int patternMode = args[1]->IntegerValue();
+ Qt::BrushStyle style = Qt::SolidPattern;
+ if (patternMode >= 0 && patternMode < Qt::LinearGradientPattern) {
+ style = static_cast<Qt::BrushStyle>(patternMode);
+ }
+ styleResouce->brush = QBrush(color, style);
+ } else {
+ QImage patternTexture;
+
+ if (args[0]->IsObject()) {
+ QV8Context2DPixelArrayResource *pixelData = v8_resource_cast<QV8Context2DPixelArrayResource>(args[0]->ToObject()->Get(v8::String::New("data"))->ToObject());
+ if (pixelData) {
+ patternTexture = pixelData->image;
+ }
+ } else {
+ patternTexture = r->context->createImage(QUrl(engine->toString(args[0]->ToString())));
+ }
+
+ if (!patternTexture.isNull()) {
+ styleResouce->brush.setTextureImage(patternTexture);
+
+ QString repetition = engine->toString(args[1]);
+ if (repetition == QStringLiteral("repeat") || repetition.isEmpty()) {
+ styleResouce->patternRepeatX = true;
+ styleResouce->patternRepeatY = true;
+ } else if (repetition == QStringLiteral("repeat-x")) {
+ styleResouce->patternRepeatX = true;
+ } else if (repetition == QStringLiteral("repeat-y")) {
+ styleResouce->patternRepeatY = true;
+ } else if (repetition == QStringLiteral("no-repeat")) {
+ styleResouce->patternRepeatY = false;
+ styleResouce->patternRepeatY = false;
+ } else {
+ //TODO: exception: SYNTAX_ERR
+ }
+
+ }
+ }
+
+ v8::Local<v8::Object> pattern = ed->constructorPattern->NewInstance();
+ pattern->SetExternalResource(styleResouce);
+ return pattern;
+
+ }
+ return v8::Undefined();
}
// line styles
@@ -1275,6 +1317,8 @@ static void ctx2d_lineCap_set(v8::Local<v8::String>, v8::Local<v8::Value> value,
cap = Qt::FlatCap;
else if (lineCap == QLatin1String("square"))
cap = Qt::SquareCap;
+ else
+ return;
if (cap != r->context->state.lineCap) {
r->context->state.lineCap = cap;
@@ -1331,6 +1375,8 @@ static void ctx2d_lineJoin_set(v8::Local<v8::String>, v8::Local<v8::Value> value
join = Qt::BevelJoin;
else if (lineJoin == QLatin1String("miter"))
join = Qt::MiterJoin;
+ else
+ return;
if (join != r->context->state.lineJoin) {
r->context->state.lineJoin = join;
@@ -1358,7 +1404,7 @@ static void ctx2d_lineWidth_set(v8::Local<v8::String>, v8::Local<v8::Value> valu
qreal w = value->NumberValue();
- if (w > 0 && w != r->context->state.lineWidth) {
+ if (w > 0 && qIsFinite(w) && w != r->context->state.lineWidth) {
r->context->state.lineWidth = w;
r->context->buffer()->setLineWidth(w);
}
@@ -1385,7 +1431,7 @@ static void ctx2d_miterLimit_set(v8::Local<v8::String>, v8::Local<v8::Value> val
qreal ml = value->NumberValue();
- if (ml > 0 && ml != r->context->state.miterLimit) {
+ if (ml > 0 && qIsFinite(ml) && ml != r->context->state.miterLimit) {
r->context->state.miterLimit = ml;
r->context->buffer()->setMiterLimit(ml);
}
@@ -1411,7 +1457,7 @@ static void ctx2d_shadowBlur_set(v8::Local<v8::String>, v8::Local<v8::Value> val
CHECK_CONTEXT_SETTER(r)
qreal blur = value->NumberValue();
- if (blur > 0 && blur != r->context->state.shadowBlur) {
+ if (blur > 0 && qIsFinite(blur) && blur != r->context->state.shadowBlur) {
r->context->state.shadowBlur = blur;
r->context->buffer()->setShadowBlur(blur);
}
@@ -1437,9 +1483,7 @@ static void ctx2d_shadowColor_set(v8::Local<v8::String>, v8::Local<v8::Value> va
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
CHECK_CONTEXT_SETTER(r)
- QV8Engine *engine = V8ENGINE_ACCESSOR();
-
- QColor color = qt_color_from_string(engine->toString(value));
+ QColor color = qt_color_from_string(value);
if (color.isValid() && color != r->context->state.shadowColor) {
r->context->state.shadowColor = color;
@@ -1468,9 +1512,8 @@ static void ctx2d_shadowOffsetX_set(v8::Local<v8::String>, v8::Local<v8::Value>
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
CHECK_CONTEXT_SETTER(r)
- //TODO: check value:infinite or NaN
qreal offsetX = value->NumberValue();
- if (offsetX != r->context->state.shadowOffsetX) {
+ if (qIsFinite(offsetX) && offsetX != r->context->state.shadowOffsetX) {
r->context->state.shadowOffsetX = offsetX;
r->context->buffer()->setShadowOffsetX(offsetX);
}
@@ -1494,9 +1537,9 @@ static void ctx2d_shadowOffsetY_set(v8::Local<v8::String>, v8::Local<v8::Value>
{
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
CHECK_CONTEXT_SETTER(r)
- //TODO: check value:infinite or NaN
+
qreal offsetY = value->NumberValue();
- if (offsetY != r->context->state.shadowOffsetY) {
+ if (qIsFinite(offsetY) && offsetY != r->context->state.shadowOffsetY) {
r->context->state.shadowOffsetY = offsetY;
r->context->buffer()->setShadowOffsetY(offsetY);
}
@@ -1529,7 +1572,7 @@ static void ctx2d_path_set(v8::Local<v8::String>, v8::Local<v8::Value> value, co
//rects
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::clearRect(real x, real y, real w, real h)
+ \qmlmethod object QtQuick2::Context2D::clearRect(real x, real y, real w, real h)
Clears all pixels on the canvas in the given rectangle to transparent black.
*/
static v8::Handle<v8::Value> ctx2d_clearRect(const v8::Arguments &args)
@@ -1539,16 +1582,21 @@ static v8::Handle<v8::Value> ctx2d_clearRect(const v8::Arguments &args)
if (args.Length() == 4) {
- r->context->buffer()->clearRect(args[0]->NumberValue(),
- args[1]->NumberValue(),
- args[2]->NumberValue(),
- args[3]->NumberValue());
+ qreal x = args[0]->NumberValue();
+ qreal y = args[1]->NumberValue();
+ qreal w = args[2]->NumberValue();
+ qreal h = args[3]->NumberValue();
+
+ if (!qIsFinite(x) || !qIsFinite(y) || !qIsFinite(w) || !qIsFinite(h))
+ return args.This();
+
+ r->context->buffer()->clearRect(x, y, w, h);
}
return args.This();
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::fillRect(real x, real y, real w, real h)
+ \qmlmethod object QtQuick2::Context2D::fillRect(real x, real y, real w, real h)
Paint the specified rectangular area using the fillStyle.
\sa QtQuick2::Context2D::fillStyle
@@ -1558,19 +1606,23 @@ static v8::Handle<v8::Value> ctx2d_fillRect(const v8::Arguments &args)
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
CHECK_CONTEXT(r)
-
if (args.Length() == 4) {
- r->context->buffer()->fillRect(args[0]->NumberValue(),
- args[1]->NumberValue(),
- args[2]->NumberValue(),
- args[3]->NumberValue());
+ qreal x = args[0]->NumberValue();
+ qreal y = args[1]->NumberValue();
+ qreal w = args[2]->NumberValue();
+ qreal h = args[3]->NumberValue();
+
+ if (!qIsFinite(x) || !qIsFinite(y) || !qIsFinite(w) || !qIsFinite(h))
+ return args.This();
+
+ r->context->buffer()->fillRect(x, y, w, h);
}
return args.This();
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::fillRect(real x, real y, real w, real h)
+ \qmlmethod object QtQuick2::Context2D::fillRect(real x, real y, real w, real h)
Stroke the specified rectangle's path using the strokeStyle, lineWidth, lineJoin,
and (if appropriate) miterLimit attributes.
@@ -1586,18 +1638,23 @@ static v8::Handle<v8::Value> ctx2d_strokeRect(const v8::Arguments &args)
if (args.Length() == 4) {
- r->context->buffer()->strokeRect(args[0]->NumberValue(),
- args[1]->NumberValue(),
- args[2]->NumberValue(),
- args[3]->NumberValue());
+ qreal x = args[0]->NumberValue();
+ qreal y = args[1]->NumberValue();
+ qreal w = args[2]->NumberValue();
+ qreal h = args[3]->NumberValue();
+
+ if (!qIsFinite(x) || !qIsFinite(y) || !qIsFinite(w) || !qIsFinite(h))
+ return args.This();
+
+ r->context->buffer()->strokeRect(x, y, w, h);
}
-
+
return args.This();
}
// Complex shapes (paths) API
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::arc(real x, real y, real radius, real startAngle, real endAngle, bool anticlockwise)
+ \qmlmethod object QtQuick2::Context2D::arc(real x, real y, real radius, real startAngle, real endAngle, bool anticlockwise)
Adds an arc to the current subpath that lies on the circumference of the circle whose center is at the point (\c x,\cy) and whose radius is \c radius.
\image qml-item-canvas-arcTo2.png
\sa QtQuick2::Context2D::arcTo
@@ -1615,7 +1672,17 @@ static v8::Handle<v8::Value> ctx2d_arc(const v8::Arguments &args)
antiClockwise = args[5]->BooleanValue();
qreal radius = args[2]->NumberValue();
- //Throws an INDEX_SIZE_ERR exception if the given radius is negative.
+ qreal x = args[0]->NumberValue();
+ qreal y = args[1]->NumberValue();
+ qreal sa = args[3]->NumberValue();
+ qreal ea = args[4]->NumberValue();
+
+ if (!qIsFinite(x) || !qIsFinite(y) || !qIsFinite(sa) || !qIsFinite(ea))
+ return args.This();
+
+ if (radius < 0)
+ V8THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "Incorrect argument radius");
+
r->context->arc(args[0]->NumberValue(),
args[1]->NumberValue(),
radius,
@@ -1628,7 +1695,7 @@ static v8::Handle<v8::Value> ctx2d_arc(const v8::Arguments &args)
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::arcTo(real x1, real y1, real x2, real y2, real radius)
+ \qmlmethod object QtQuick2::Context2D::arcTo(real x1, real y1, real x2, real y2, real radius)
Adds an arc with the given control points and radius to the current subpath, connected to the previous point by a straight line.
To draw an arc, you begin with the same steps your followed to create a line:
@@ -1653,7 +1720,19 @@ static v8::Handle<v8::Value> ctx2d_arcTo(const v8::Arguments &args)
CHECK_CONTEXT(r)
+
if (args.Length() == 5) {
+ qreal x1 = args[0]->NumberValue();
+ qreal y1 = args[1]->NumberValue();
+ qreal x2 = args[2]->NumberValue();
+ qreal y2 = args[3]->NumberValue();
+
+ if (!qIsFinite(x1) || !qIsFinite(y1) || !qIsFinite(x2) || !qIsFinite(y2))
+ return args.This();
+
+ qreal radius = args[4]->NumberValue();
+ if (radius < 0)
+ V8THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "Incorrect argument radius");
r->context->arcTo(args[0]->NumberValue(),
args[1]->NumberValue(),
args[2]->NumberValue(),
@@ -1665,7 +1744,7 @@ static v8::Handle<v8::Value> ctx2d_arcTo(const v8::Arguments &args)
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::beginPath()
+ \qmlmethod object QtQuick2::Context2D::beginPath()
Resets the current path to a new path.
*/
@@ -1681,7 +1760,7 @@ static v8::Handle<v8::Value> ctx2d_beginPath(const v8::Arguments &args)
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::bezierCurveTo(real cp1x, real cp1y, real cp2x, real cp2y, real x, real y)
+ \qmlmethod object QtQuick2::Context2D::bezierCurveTo(real cp1x, real cp1y, real cp2x, real cp2y, real x, real y)
Adds a cubic Bezier curve between the current position and the given endPoint using the control points specified by (\c cp1x, cp1y),
and (\c cp2x, \c cp2y).
@@ -1706,19 +1785,24 @@ static v8::Handle<v8::Value> ctx2d_bezierCurveTo(const v8::Arguments &args)
if (args.Length() == 6) {
- r->context->bezierCurveTo(args[0]->NumberValue(),
- args[1]->NumberValue(),
- args[2]->NumberValue(),
- args[3]->NumberValue(),
- args[4]->NumberValue(),
- args[5]->NumberValue());
+ qreal cp1x = args[0]->NumberValue();
+ qreal cp1y = args[1]->NumberValue();
+ qreal cp2x = args[2]->NumberValue();
+ qreal cp2y = args[3]->NumberValue();
+ qreal x = args[4]->NumberValue();
+ qreal y = args[5]->NumberValue();
+
+ if (!qIsFinite(cp1x) || !qIsFinite(cp1y) || !qIsFinite(cp2x) || !qIsFinite(cp2y) || !qIsFinite(x) || !qIsFinite(y))
+ return args.This();
+
+ r->context->bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
}
return args.This();
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::clip()
+ \qmlmethod object QtQuick2::Context2D::clip()
Creates the clipping region from the current path.
Any parts of the shape outside the clipping path are not displayed.
@@ -1746,14 +1830,19 @@ static v8::Handle<v8::Value> ctx2d_clip(const v8::Arguments &args)
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
CHECK_CONTEXT(r)
- r->context->state.clipPath = r->context->m_path;
+ QPainterPath clipPath = r->context->m_path;
+ clipPath.closeSubpath();
+ if (!r->context->state.clipPath.isEmpty())
+ r->context->state.clipPath = clipPath.intersected(r->context->state.clipPath);
+ else
+ r->context->state.clipPath = clipPath;
r->context->buffer()->clip(r->context->state.clipPath);
-
+
return args.This();
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::closePath()
+ \qmlmethod object QtQuick2::Context2D::closePath()
Closes the current subpath by drawing a line to the beginning of the subpath, automatically starting a new path.
The current point of the new path is the previous subpath's first point.
@@ -1771,7 +1860,7 @@ static v8::Handle<v8::Value> ctx2d_closePath(const v8::Arguments &args)
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::fill()
+ \qmlmethod object QtQuick2::Context2D::fill()
Fills the subpaths with the current fill style.
@@ -1790,7 +1879,7 @@ static v8::Handle<v8::Value> ctx2d_fill(const v8::Arguments &args)
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::lineTo(real x, real y)
+ \qmlmethod object QtQuick2::Context2D::lineTo(real x, real y)
Draws a line from the current position to the point (x, y).
*/
@@ -1801,15 +1890,20 @@ static v8::Handle<v8::Value> ctx2d_lineTo(const v8::Arguments &args)
if (args.Length() == 2) {
- r->context->lineTo(args[0]->NumberValue(),
- args[1]->NumberValue());
+ qreal x = args[0]->NumberValue();
+ qreal y = args[1]->NumberValue();
+
+ if (!qIsFinite(x) || !qIsFinite(y))
+ return args.This();
+
+ r->context->lineTo(x, y);
}
return args.This();
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::moveTo(real x, real y)
+ \qmlmethod object QtQuick2::Context2D::moveTo(real x, real y)
Creates a new subpath with the given point.
*/
@@ -1818,17 +1912,19 @@ static v8::Handle<v8::Value> ctx2d_moveTo(const v8::Arguments &args)
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
CHECK_CONTEXT(r)
-
if (args.Length() == 2) {
- r->context->moveTo(args[0]->NumberValue(),
- args[1]->NumberValue());
- }
+ qreal x = args[0]->NumberValue();
+ qreal y = args[1]->NumberValue();
+ if (!qIsFinite(x) || !qIsFinite(y))
+ return args.This();
+ r->context->moveTo(x, y);
+ }
return args.This();
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::quadraticCurveTo(real cpx, real cpy, real x, real y)
+ \qmlmethod object QtQuick2::Context2D::quadraticCurveTo(real cpx, real cpy, real x, real y)
Adds a quadratic Bezier curve between the current point and the endpoint (\c x, \c y) with the control point specified by (\c cpx, \c cpy).
@@ -1839,19 +1935,23 @@ static v8::Handle<v8::Value> ctx2d_quadraticCurveTo(const v8::Arguments &args)
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
CHECK_CONTEXT(r)
-
if (args.Length() == 4) {
- r->context->quadraticCurveTo(args[0]->NumberValue(),
- args[1]->NumberValue(),
- args[2]->NumberValue(),
- args[3]->NumberValue());
+ qreal cpx = args[0]->NumberValue();
+ qreal cpy = args[1]->NumberValue();
+ qreal x = args[2]->NumberValue();
+ qreal y = args[3]->NumberValue();
+
+ if (!qIsFinite(cpx) || !qIsFinite(cpy) || !qIsFinite(x) || !qIsFinite(y))
+ return args.This();
+
+ r->context->quadraticCurveTo(cpx, cpy, x, y);
}
return args.This();
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::rect(real x, real y, real w, real h)
+ \qmlmethod object QtQuick2::Context2D::rect(real x, real y, real w, real h)
Adds a rectangle at position (\c x, \c y), with the given width \c w and height \c h, as a closed subpath.
*/
@@ -1862,17 +1962,22 @@ static v8::Handle<v8::Value> ctx2d_rect(const v8::Arguments &args)
if (args.Length() == 4) {
- r->context->rect(args[0]->NumberValue(),
- args[1]->NumberValue(),
- args[2]->NumberValue(),
- args[3]->NumberValue());
+ qreal x = args[0]->NumberValue();
+ qreal y = args[1]->NumberValue();
+ qreal w = args[2]->NumberValue();
+ qreal h = args[3]->NumberValue();
+
+ if (!qIsFinite(x) || !qIsFinite(y) || !qIsFinite(w) || !qIsFinite(h))
+ return args.This();
+
+ r->context->rect(x, y, w, h);
}
return args.This();
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::roundedRect(real x, real y, real w, real h, real xRadius, real yRadius)
+ \qmlmethod object QtQuick2::Context2D::roundedRect(real x, real y, real w, real h, real xRadius, real yRadius)
Adds the given rectangle rect with rounded corners to the path. The \c xRadius and \c yRadius arguments specify the radius of the
ellipses defining the corners of the rounded rectangle.
@@ -1882,21 +1987,28 @@ static v8::Handle<v8::Value> ctx2d_roundedRect(const v8::Arguments &args)
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
CHECK_CONTEXT(r)
-
if (args.Length() == 6) {
- r->context->roundedRect(args[0]->NumberValue(),
- args[1]->NumberValue(),
- args[2]->NumberValue(),
- args[3]->NumberValue(),
- args[4]->NumberValue(),
- args[5]->NumberValue());
+ qreal x = args[0]->NumberValue();
+ qreal y = args[1]->NumberValue();
+ qreal w = args[2]->NumberValue();
+ qreal h = args[3]->NumberValue();
+ qreal xr = args[4]->NumberValue();
+ qreal yr = args[5]->NumberValue();
+
+ if (!qIsFinite(x) || !qIsFinite(y) || !qIsFinite(w) || !qIsFinite(h))
+ return args.This();
+
+ if (!qIsFinite(xr) || !qIsFinite(yr))
+ V8THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "roundedRect(): Invalid arguments");
+
+ r->context->roundedRect(x, y, w, h, xr, yr);
}
return args.This();
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::ellipse(real x, real y, real w, real h)
+ \qmlmethod object QtQuick2::Context2D::ellipse(real x, real y, real w, real h)
Creates an ellipse within the bounding rectangle defined by its top-left corner at (\a x, \ y), width \a w and height \a h,
and adds it to the path as a closed subpath.
@@ -1910,17 +2022,23 @@ static v8::Handle<v8::Value> ctx2d_ellipse(const v8::Arguments &args)
if (args.Length() == 4) {
- r->context->ellipse(args[0]->NumberValue(),
- args[1]->NumberValue(),
- args[2]->NumberValue(),
- args[3]->NumberValue());
+ qreal x = args[0]->NumberValue();
+ qreal y = args[1]->NumberValue();
+ qreal w = args[2]->NumberValue();
+ qreal h = args[3]->NumberValue();
+
+ if (!qIsFinite(x) || !qIsFinite(y) || !qIsFinite(w) || !qIsFinite(h))
+ return args.This();
+
+
+ r->context->ellipse(x, y, w, h);
}
return args.This();
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::text(string text, real x, real y)
+ \qmlmethod object QtQuick2::Context2D::text(string text, real x, real y)
Adds the given \c text to the path as a set of closed subpaths created from the current context font supplied.
The subpaths are positioned so that the left end of the text's baseline lies at the point specified by (\c x, \c y).
@@ -1932,16 +2050,18 @@ static v8::Handle<v8::Value> ctx2d_text(const v8::Arguments &args)
QV8Engine *engine = V8ENGINE();
if (args.Length() == 3) {
- r->context->text(engine->toString(args[0]),
- args[1]->NumberValue(),
- args[2]->NumberValue());
- }
+ qreal x = args[1]->NumberValue();
+ qreal y = args[2]->NumberValue();
+ if (!qIsFinite(x) || !qIsFinite(y))
+ return args.This();
+ r->context->text(engine->toString(args[0]), x, y);
+ }
return args.This();
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::stroke()
+ \qmlmethod object QtQuick2::Context2D::stroke()
Strokes the subpaths with the current stroke style.
@@ -1961,7 +2081,7 @@ static v8::Handle<v8::Value> ctx2d_stroke(const v8::Arguments &args)
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::isPointInPath(real x, real y)
+ \qmlmethod object QtQuick2::Context2D::isPointInPath(real x, real y)
Returns true if the given point is in the current path.
@@ -1972,32 +2092,32 @@ static v8::Handle<v8::Value> ctx2d_isPointInPath(const v8::Arguments &args)
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
CHECK_CONTEXT(r)
-
bool pointInPath = false;
if (args.Length() == 2) {
- pointInPath = r->context->isPointInPath(args[0]->NumberValue(),
- args[1]->NumberValue());
+ qreal x = args[0]->NumberValue();
+ qreal y = args[1]->NumberValue();
+ if (!qIsFinite(x) || !qIsFinite(y))
+ return v8::Boolean::New(false);
+ pointInPath = r->context->isPointInPath(x, y);
}
-
return v8::Boolean::New(pointInPath);
}
static v8::Handle<v8::Value> ctx2d_drawFocusRing(const v8::Arguments &args)
{
- V8THROW_ERROR("Context2D::drawFocusRing is not supported")
+ V8THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::drawFocusRing is not supported");
return args.This();
}
static v8::Handle<v8::Value> ctx2d_setCaretSelectionRect(const v8::Arguments &args)
{
- V8THROW_ERROR("Context2D::setCaretSelectionRect is not supported")
+ V8THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::setCaretSelectionRect is not supported");
return args.This();
}
static v8::Handle<v8::Value> ctx2d_caretBlinkRate(const v8::Arguments &args)
{
- V8THROW_ERROR("Context2D::caretBlinkRate is not supported")
-
+ V8THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::caretBlinkRate is not supported");
return args.This();
}
// text
@@ -2015,7 +2135,7 @@ v8::Handle<v8::Value> ctx2d_font(v8::Local<v8::String>, const v8::AccessorInfo &
QV8Engine *engine = V8ENGINE_ACCESSOR();
- return engine->toString(r->context->m_fontString);
+ return engine->toString(r->context->state.font.toString());
}
static void ctx2d_font_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
@@ -2025,9 +2145,8 @@ static void ctx2d_font_set(v8::Local<v8::String>, v8::Local<v8::Value> value, co
QV8Engine *engine = V8ENGINE_ACCESSOR();
QString fs = engine->toString(value);
- if (fs != r->context->m_fontString) {
- r->context->m_fontString = fs;
- QFont font = qt_font_from_string(fs);
+ QFont font = qt_font_from_string(fs);
+ if (font != r->context->state.font) {
r->context->state.font = font;
}
}
@@ -2087,6 +2206,8 @@ static void ctx2d_textAlign_set(v8::Local<v8::String>, v8::Local<v8::Value> valu
ta = QSGContext2D::Right;
else if (textAlign == QLatin1String("center"))
ta = QSGContext2D::Center;
+ else
+ return;
if (ta != r->context->state.textAlign) {
r->context->state.textAlign = ta;
@@ -2149,6 +2270,8 @@ static void ctx2d_textBaseline_set(v8::Local<v8::String>, v8::Local<v8::Value> v
tb = QSGContext2D::Bottom;
else if (textBaseline == QLatin1String("middle"))
tb = QSGContext2D::Middle;
+ else
+ return;
if (tb != r->context->state.textBaseline) {
r->context->state.textBaseline = tb;
@@ -2156,7 +2279,7 @@ static void ctx2d_textBaseline_set(v8::Local<v8::String>, v8::Local<v8::Value> v
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::fillText(text, x, y)
+ \qmlmethod object QtQuick2::Context2D::fillText(text, x, y)
Fills the given text at the given position.
\sa QtQuick2::Context2D::font
\sa QtQuick2::Context2D::textAlign
@@ -2168,20 +2291,19 @@ static v8::Handle<v8::Value> ctx2d_fillText(const v8::Arguments &args)
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
CHECK_CONTEXT(r)
-
QV8Engine *engine = V8ENGINE();
-
if (args.Length() == 3) {
- QPainterPath textPath = r->context->createTextGlyphs(args[1]->NumberValue(),
- args[2]->NumberValue(),
- engine->toString(args[0]));
+ qreal x = args[1]->NumberValue();
+ qreal y = args[2]->NumberValue();
+ if (!qIsFinite(x) || !qIsFinite(y))
+ return args.This();
+ QPainterPath textPath = r->context->createTextGlyphs(x, y, engine->toString(args[0]));
r->context->buffer()->fill(textPath);
}
-
return args.This();
}
/*!
- \qmlmethod QtQuick2::Context2D QtQuick2::Context2D::strokeText(text, x, y)
+ \qmlmethod object QtQuick2::Context2D::strokeText(text, x, y)
Strokes the given text at the given position.
\sa QtQuick2::Context2D::font
\sa QtQuick2::Context2D::textAlign
@@ -2193,16 +2315,15 @@ static v8::Handle<v8::Value> ctx2d_strokeText(const v8::Arguments &args)
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
CHECK_CONTEXT(r)
-
QV8Engine *engine = V8ENGINE();
-
if (args.Length() == 3) {
- QPainterPath textPath = r->context->createTextGlyphs(args[1]->NumberValue(),
- args[2]->NumberValue(),
- engine->toString(args[0]));
+ qreal x = args[1]->NumberValue();
+ qreal y = args[2]->NumberValue();
+ if (!qIsFinite(x) || !qIsFinite(y))
+ return args.This();
+ QPainterPath textPath = r->context->createTextGlyphs(x, y, engine->toString(args[0]));
r->context->buffer()->stroke(textPath);
}
-
return args.This();
}
/*!
@@ -2232,7 +2353,6 @@ static v8::Handle<v8::Value> ctx2d_measureText(const v8::Arguments &args)
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
CHECK_CONTEXT(r)
-
QV8Engine *engine = V8ENGINE();
if (args.Length() == 1) {
@@ -2242,7 +2362,6 @@ static v8::Handle<v8::Value> ctx2d_measureText(const v8::Arguments &args)
tm->Set(v8::String::New("width"), v8::Number::New(width));
return tm;
}
-
return v8::Undefined();
}
@@ -2292,7 +2411,7 @@ static v8::Handle<v8::Value> ctx2d_measureText(const v8::Arguments &args)
Note:
- The \a image type can be an Image item, an image url or a \a {QtQuick2::CanvasImageData} object.
+ The \a image type can be an Image or Canvas item, an image url or a \a {QtQuick2::CanvasImageData} object.
When given as Image item, if the image isn't fully loaded, this method draws nothing.
When given as url string, the image should be loaded by calling Canvas item's \a QtQuick2::Canvas::loadImage() method first.
This image been drawing is subject to the current context clip path, even the given \c image is a {QtQuick2::CanvasImageData} object.
@@ -2310,48 +2429,50 @@ static v8::Handle<v8::Value> ctx2d_drawImage(const v8::Arguments &args)
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
CHECK_CONTEXT(r)
-
QV8Engine *engine = V8ENGINE();
-
- //TODO: handle exceptions
-
qreal sx, sy, sw, sh, dx, dy, dw, dh;
- if (args.Length() != 3 && args.Length() != 5 && args.Length() != 9) {
- //parameter error
+ if (!args.Length())
return args.This();
- }
-
QImage image;
if (args[0]->IsString()) {
- image = r->context->createImage(QUrl(engine->toString(args[0]->ToString())));
+ QUrl url(engine->toString(args[0]->ToString()));
+ if (!url.isValid())
+ V8THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
+
+ image = r->context->createImage(url);
} else if (args[0]->IsObject()) {
- QSGImage* imageItem = qobject_cast<QSGImage*>(engine->toQObject(args[0]->ToObject()));
- QV8Context2DPixelArrayResource *r = v8_resource_cast<QV8Context2DPixelArrayResource>(args[0]->ToObject()->GetInternalField(0)->ToObject());
- if (r) {
- image = r->image;
+ QSGImage *imageItem = qobject_cast<QSGImage*>(engine->toQObject(args[0]->ToObject()));
+ QSGCanvasItem *canvas = qobject_cast<QSGCanvasItem*>(engine->toQObject(args[0]->ToObject()));
+
+ QV8Context2DPixelArrayResource *pix = v8_resource_cast<QV8Context2DPixelArrayResource>(args[0]->ToObject()->GetInternalField(0)->ToObject());
+ if (pix) {
+ image = pix->image;
} else if (imageItem) {
image = imageItem->pixmap().toImage();
+ } else if (canvas) {
+ image = canvas->toImage();
} else {
- //wrong image type
- return args.This();
+ V8THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
+ } else {
+ V8THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
if (args.Length() == 3) {
dx = args[1]->NumberValue();
dy = args[2]->NumberValue();
sx = 0;
sy = 0;
- sw = image.isNull()? -1 : image.width();
- sh = image.isNull()? -1 : image.height();
+ sw = image.width();
+ sh = image.height();
dw = sw;
dh = sh;
} else if (args.Length() == 5) {
sx = 0;
sy = 0;
- sw = image.isNull()? -1 : image.width();
- sh = image.isNull()? -1 : image.height();
+ sw = image.width();
+ sh = image.height();
dx = args[1]->NumberValue();
dy = args[2]->NumberValue();
dw = args[3]->NumberValue();
@@ -2366,11 +2487,28 @@ static v8::Handle<v8::Value> ctx2d_drawImage(const v8::Arguments &args)
dw = args[7]->NumberValue();
dh = args[8]->NumberValue();
} else {
- //error
return args.This();
}
- r->context->buffer()->drawImage(image,sx, sy, sw, sh, dx, dy, dw, dh);
+ if (!qIsFinite(sx)
+ || !qIsFinite(sy)
+ || !qIsFinite(sw)
+ || !qIsFinite(sh)
+ || !qIsFinite(dx)
+ || !qIsFinite(dy)
+ || !qIsFinite(dw)
+ || !qIsFinite(dh))
+ return args.This();
+
+ if (!image.isNull()) {
+ if (sx < 0 || sy < 0 || sw == 0 || sh == 0
+ || sx + sw > image.width() || sy + sh > image.height()
+ || sx + sw < 0 || sy + sh < 0) {
+ V8THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "drawImage(), index size error");
+ }
+
+ r->context->buffer()->drawImage(image,sx, sy, sw, sh, dx, dy, dw, dh);
+ }
return args.This();
}
@@ -2488,10 +2626,10 @@ static v8::Handle<v8::Value> ctx2d_imageData_filter(const v8::Arguments &args)
if (args.Length() >= 1) {
int filterFlag = args[0]->IntegerValue();
- switch(filterFlag) {
+ switch (filterFlag) {
case QSGCanvasItem::Mono :
{
- r->image = r->image.convertToFormat(QImage::Format_Mono).convertToFormat(QImage::Format_ARGB32);
+ r->image = r->image.convertToFormat(QImage::Format_Mono).convertToFormat(QImage::Format_ARGB32_Premultiplied);
}
break;
case QSGCanvasItem::GrayScale :
@@ -2611,11 +2749,10 @@ v8::Handle<v8::Value> ctx2d_pixelArray_indexed(uint32_t index, const v8::Accesso
{
QV8Context2DPixelArrayResource *r = v8_resource_cast<QV8Context2DPixelArrayResource>(args.This());
- if (r && index && index < r->image.width() * r->image.height() * 4) {
- const int w = r->image.width();
- const int h = r->image.height();
- const int row = (index / 4) / w;
- const int col = (index / 4) % w;
+ if (r && index < static_cast<quint32>(r->image.width() * r->image.height() * 4)) {
+ const quint32 w = r->image.width();
+ const quint32 row = (index / 4) / w;
+ const quint32 col = (index / 4) % w;
const QRgb* pixel = reinterpret_cast<const QRgb*>(r->image.constScanLine(row));
pixel += col;
switch (index % 4) {
@@ -2637,11 +2774,10 @@ v8::Handle<v8::Value> ctx2d_pixelArray_indexed_set(uint32_t index, v8::Local<v8:
QV8Context2DPixelArrayResource *r = v8_resource_cast<QV8Context2DPixelArrayResource>(info.This());
const int v = value->Uint32Value();
- if (r && index > 0 && index < r->image.width() * r->image.height() * 4 && v > 0 && v <= 255) {
- const int w = r->image.width();
- const int h = r->image.height();
- const int row = (index / 4) / w;
- const int col = (index / 4) % w;
+ if (r && index < static_cast<quint32>(r->image.width() * r->image.height() * 4) && v > 0 && v <= 255) {
+ const quint32 w = r->image.width();
+ const quint32 row = (index / 4) / w;
+ const quint32 col = (index / 4) % w;
QRgb* pixel = reinterpret_cast<QRgb*>(r->image.scanLine(row));
pixel += col;
@@ -2683,7 +2819,6 @@ static v8::Handle<v8::Value> ctx2d_createImageData(const v8::Arguments &args)
QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
CHECK_CONTEXT(r)
-
QV8Engine *engine = V8ENGINE();
if (args.Length() == 1) {
@@ -2702,8 +2837,14 @@ static v8::Handle<v8::Value> ctx2d_createImageData(const v8::Arguments &args)
} else if (args.Length() == 2) {
qreal w = args[0]->NumberValue();
qreal h = args[1]->NumberValue();
+
+ if (!qIsFinite(w) || !qIsFinite(h))
+ V8THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createImageData(): invalid arguments");
+
if (w > 0 && h > 0)
return qt_create_image_data(w, h, engine, QImage());
+ else
+ V8THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "createImageData(): invalid arguments");
}
return v8::Undefined();
}
@@ -2723,9 +2864,13 @@ static v8::Handle<v8::Value> ctx2d_getImageData(const v8::Arguments &args)
qreal y = args[1]->NumberValue();
qreal w = args[2]->NumberValue();
qreal h = args[3]->NumberValue();
+ if (!qIsFinite(x) || !qIsFinite(y) || !qIsFinite(w) || !qIsFinite(w))
+ V8THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "getImageData(): Invalid arguments");
+
+ if (w <= 0 || h <= 0)
+ V8THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "getImageData(): Invalid arguments");
+
QImage image = r->context->canvas()->toImage(QRectF(x, y, w, h));
- if (image.format() != QImage::Format_ARGB32)
- image = image.convertToFormat(QImage::Format_ARGB32);
v8::Local<v8::Object> imageData = qt_create_image_data(w, h, engine, image);
return imageData;
@@ -2734,7 +2879,7 @@ static v8::Handle<v8::Value> ctx2d_getImageData(const v8::Arguments &args)
}
/*!
- \qmlmethod QtQuick2::Context2D putImageData(QtQuick2::CanvasImageData imageData, real dx, real dy, real dirtyX, real dirtyY, real dirtyWidth, real dirtyHeight)
+ \qmlmethod object QtQuick2::Context2D::putImageData(QtQuick2::CanvasImageData imageData, real dx, real dy, real dirtyX, real dirtyY, real dirtyWidth, real dirtyHeight)
Paints the data from the given ImageData object onto the canvas. If a dirty rectangle (\a dirtyX, \a dirtyY, \a dirtyWidth, \a dirtyHeight) is provided, only the pixels from that rectangle are painted.
*/
static v8::Handle<v8::Value> ctx2d_putImageData(const v8::Arguments &args)
@@ -2745,12 +2890,15 @@ static v8::Handle<v8::Value> ctx2d_putImageData(const v8::Arguments &args)
return v8::Undefined();
if (args[0]->IsNull() || !args[0]->IsObject()) {
- V8THROW_ERROR("Context2D::putImageData, the image data type mismatch");
+ V8THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "Context2D::putImageData, the image data type mismatch");
}
qreal dx = args[1]->NumberValue();
qreal dy = args[2]->NumberValue();
qreal w, h, dirtyX, dirtyY, dirtyWidth, dirtyHeight;
+ if (!qIsFinite(dx) || !qIsFinite(dy))
+ V8THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "putImageData() : Invalid arguments");
+
v8::Local<v8::Object> imageData = args[0]->ToObject();
QV8Context2DPixelArrayResource *pixelArray = v8_resource_cast<QV8Context2DPixelArrayResource>(imageData->Get(v8::String::New("data"))->ToObject());
if (pixelArray) {
@@ -2762,6 +2910,11 @@ static v8::Handle<v8::Value> ctx2d_putImageData(const v8::Arguments &args)
dirtyY = args[4]->NumberValue();
dirtyWidth = args[5]->NumberValue();
dirtyHeight = args[6]->NumberValue();
+
+ if (!qIsFinite(dirtyX) || !qIsFinite(dirtyY) || !qIsFinite(dirtyWidth) || !qIsFinite(dirtyHeight))
+ V8THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "putImageData() : Invalid arguments");
+
+
if (dirtyWidth < 0) {
dirtyX = dirtyX+dirtyWidth;
dirtyWidth = -dirtyWidth;
@@ -2843,18 +2996,16 @@ static v8::Handle<v8::Value> ctx2d_gradient_addColorStop(const v8::Arguments &ar
if (args[1]->IsObject()) {
color = engine->toVariant(args[1], qMetaTypeId<QColor>()).value<QColor>();
} else {
- color = qt_color_from_string(engine->toString(args[1]));
+ color = qt_color_from_string(args[1]);
}
- if (pos < 0.0 || pos > 1.0) {
- //Throws an INDEX_SIZE_ERR exception
- V8THROW_ERROR("CanvasGradient: parameter offset out of range");
+ if (pos < 0.0 || pos > 1.0 || !qIsFinite(pos)) {
+ V8THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "CanvasGradient: parameter offset out of range");
}
if (color.isValid()) {
gradient.setColorAt(pos, color);
} else {
- //Throws a SYNTAX_ERR exception
- V8THROW_ERROR("CanvasGradient: parameter color is not a valid color string");
+ V8THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "CanvasGradient: parameter color is not a valid color string");
}
style->brush = gradient;
}
@@ -3082,14 +3233,14 @@ int baseLineOffset(QSGContext2D::TextBaseLineType value, const QFontMetrics &met
{
int offset = 0;
switch (value) {
- case QSGContext2D::QSGContext2D::Top:
+ case QSGContext2D::Top:
break;
- case QSGContext2D::QSGContext2D::Alphabetic:
- case QSGContext2D::QSGContext2D::Middle:
- case QSGContext2D::QSGContext2D::Hanging:
+ case QSGContext2D::Alphabetic:
+ case QSGContext2D::Middle:
+ case QSGContext2D::Hanging:
offset = metrics.ascent();
break;
- case QSGContext2D::QSGContext2D::Bottom:
+ case QSGContext2D::Bottom:
offset = metrics.height();
break;
}
@@ -3104,12 +3255,12 @@ static int textAlignOffset(QSGContext2D::TextAlignType value, const QFontMetrics
else if (value == QSGContext2D::End)
value = QGuiApplication::layoutDirection() == Qt::LeftToRight ? QSGContext2D::Right: QSGContext2D::Left;
switch (value) {
- case QSGContext2D::QSGContext2D::Center:
+ case QSGContext2D::Center:
offset = metrics.width(text)/2;
break;
- case QSGContext2D::QSGContext2D::Right:
+ case QSGContext2D::Right:
offset = metrics.width(text);
- case QSGContext2D::QSGContext2D::Left:
+ case QSGContext2D::Left:
default:
break;
}
@@ -3183,6 +3334,7 @@ QSGContext2DEngineData::QSGContext2DEngineData(QV8Engine *engine)
ft->InstanceTemplate()->SetAccessor(v8::String::New("strokeStyle"), ctx2d_strokeStyle, ctx2d_strokeStyle_set, v8::External::Wrap(engine));
ft->PrototypeTemplate()->Set(v8::String::New("createLinearGradient"), V8FUNCTION(ctx2d_createLinearGradient, engine));
ft->PrototypeTemplate()->Set(v8::String::New("createRadialGradient"), V8FUNCTION(ctx2d_createRadialGradient, engine));
+ ft->PrototypeTemplate()->Set(v8::String::New("createConicalGradient"), V8FUNCTION(ctx2d_createConicalGradient, engine));
ft->PrototypeTemplate()->Set(v8::String::New("createPattern"), V8FUNCTION(ctx2d_createPattern, engine));
ft->InstanceTemplate()->SetAccessor(v8::String::New("lineCap"), ctx2d_lineCap, ctx2d_lineCap_set, v8::External::Wrap(engine));
ft->InstanceTemplate()->SetAccessor(v8::String::New("lineJoin"), ctx2d_lineJoin, ctx2d_lineJoin_set, v8::External::Wrap(engine));
@@ -3296,8 +3448,9 @@ void QSGContext2D::popState()
if (newState.miterLimit != state.miterLimit)
buffer()->setMiterLimit(newState.miterLimit);
- if (newState.clipPath != state.clipPath)
+ if (newState.clipPath != state.clipPath) {
buffer()->clip(newState.clipPath);
+ }
if (newState.shadowBlur != state.shadowBlur)
buffer()->setShadowBlur(newState.shadowBlur);
@@ -3310,7 +3463,6 @@ void QSGContext2D::popState()
if (newState.shadowOffsetY != state.shadowOffsetY)
buffer()->setShadowOffsetY(newState.shadowOffsetY);
-
state = newState;
}
void QSGContext2D::pushState()
@@ -3324,12 +3476,19 @@ void QSGContext2D::reset()
newState.matrix = QTransform();
QPainterPath defaultClipPath;
- defaultClipPath.addRect(0, 0, m_canvas->canvasSize().width(), m_canvas->canvasSize().height());
+
+ QRect r(0, 0, m_canvas->canvasSize().width(), m_canvas->canvasSize().height());
+ r = r.united(m_canvas->canvasWindow().toRect());
+ defaultClipPath.addRect(r);
newState.clipPath = defaultClipPath;
newState.clipPath.setFillRule(Qt::WindingFill);
- newState.strokeStyle = Qt::black;
- newState.fillStyle = Qt::black;
+ newState.strokeStyle = QColor("#000000");
+ newState.fillStyle = QColor("#000000");
+ newState.fillPatternRepeatX = false;
+ newState.fillPatternRepeatY = false;
+ newState.strokePatternRepeatX = false;
+ newState.strokePatternRepeatY = false;
newState.fillRule = Qt::WindingFill;
newState.globalAlpha = 1.0;
newState.lineWidth = 1;
@@ -3345,10 +3504,10 @@ void QSGContext2D::reset()
newState.textAlign = QSGContext2D::Start;
newState.textBaseline = QSGContext2D::Alphabetic;
- m_fontString = "";
m_stateStack.clear();
m_stateStack.push(newState);
popState();
+ m_buffer->clearRect(0, 0, m_canvas->width(), m_canvas->height());
}
void QSGContext2D::setV8Engine(QV8Engine *engine)
diff --git a/src/declarative/items/context2d/qsgcontext2d_p.h b/src/declarative/items/context2d/qsgcontext2d_p.h
index 830a185a31..10c1e331f9 100644
--- a/src/declarative/items/context2d/qsgcontext2d_p.h
+++ b/src/declarative/items/context2d/qsgcontext2d_p.h
@@ -69,7 +69,7 @@ class QSGCanvasItem;
class QSGContext2DCommandBuffer;
class QDeclarativePixmap;
-class QSGContext2D
+class Q_DECLARATIVE_EXPORT QSGContext2D
{
public:
enum TextBaseLineType { Alphabetic=0, Top, Middle, Bottom, Hanging};
@@ -111,6 +111,10 @@ public:
QPainterPath clipPath;
QBrush strokeStyle;
QBrush fillStyle;
+ bool fillPatternRepeatX:1;
+ bool fillPatternRepeatY:1;
+ bool strokePatternRepeatX:1;
+ bool strokePatternRepeatY:1;
Qt::FillRule fillRule;
qreal globalAlpha;
qreal lineWidth;
@@ -170,7 +174,6 @@ public:
v8::Local<v8::Value> m_fillStyle;
v8::Local<v8::Value> m_strokeStyle;
v8::Handle<v8::Value> m_v8path;
- QString m_fontString;
QV8Engine *m_v8engine;
v8::Persistent<v8::Object> m_v8value;
};
diff --git a/src/declarative/items/context2d/qsgcontext2dcommandbuffer.cpp b/src/declarative/items/context2d/qsgcontext2dcommandbuffer.cpp
index 224f640abc..29ed5fbc12 100644
--- a/src/declarative/items/context2d/qsgcontext2dcommandbuffer.cpp
+++ b/src/declarative/items/context2d/qsgcontext2dcommandbuffer.cpp
@@ -41,18 +41,20 @@
#include "qsgcontext2dcommandbuffer_p.h"
#include "qsgcanvasitem_p.h"
-#include "qdeclarative.h"
+#include <qdeclarative.h>
#include <QtCore/QMutex>
#define HAS_SHADOW(offsetX, offsetY, blur, color) (color.isValid() && color.alpha() && (blur || offsetX || offsetY))
+QT_BEGIN_NAMESPACE
+
void qt_image_boxblur(QImage& image, int radius, bool quality);
static QImage makeShadowImage(const QImage& image, qreal offsetX, qreal offsetY, qreal blur, const QColor& color)
{
QImage shadowImg(image.width() + blur + qAbs(offsetX),
image.height() + blur + qAbs(offsetY),
- QImage::Format_ARGB32);
+ QImage::Format_ARGB32_Premultiplied);
shadowImg.fill(0);
QPainter tmpPainter(&shadowImg);
tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
@@ -78,7 +80,7 @@ static void fillRectShadow(QPainter* p, QRectF shadowRect, qreal offsetX, qreal
QRectF r = shadowRect;
r.moveTo(0, 0);
- QImage shadowImage(r.size().width() + 1, r.size().height() + 1, QImage::Format_ARGB32);
+ QImage shadowImage(r.size().width() + 1, r.size().height() + 1, QImage::Format_ARGB32_Premultiplied);
QPainter tp;
tp.begin(&shadowImage);
tp.fillRect(r, p->brush());
@@ -97,7 +99,7 @@ static void fillShadowPath(QPainter* p, const QPainterPath& path, qreal offsetX,
QRectF r = path.boundingRect();
QImage img(r.size().width() + r.left() + 1,
r.size().height() + r.top() + 1,
- QImage::Format_ARGB32);
+ QImage::Format_ARGB32_Premultiplied);
img.fill(0);
QPainter tp(&img);
tp.fillPath(path.translated(0, 0), p->brush());
@@ -116,7 +118,7 @@ static void strokeShadowPath(QPainter* p, const QPainterPath& path, qreal offset
QRectF r = path.boundingRect();
QImage img(r.size().width() + r.left() + 1,
r.size().height() + r.top() + 1,
- QImage::Format_ARGB32);
+ QImage::Format_ARGB32_Premultiplied);
img.fill(0);
QPainter tp(&img);
tp.strokePath(path, p->pen());
@@ -128,6 +130,72 @@ static void strokeShadowPath(QPainter* p, const QPainterPath& path, qreal offset
p->drawImage(dx, dy, shadowImage);
p->strokePath(path, p->pen());
}
+static inline void drawRepeatPattern(QPainter* p, const QImage& image, const QRectF& rect, const bool repeatX, const bool repeatY)
+{
+ // Patterns must be painted so that the top left of the first image is anchored at
+ // the origin of the coordinate space
+ if (!image.isNull()) {
+ int w = image.width();
+ int h = image.height();
+ int startX, startY;
+ QRect r(static_cast<int>(rect.x()), static_cast<int>(rect.y()), static_cast<int>(rect.width()), static_cast<int>(rect.height()));
+
+ // startX, startY is the coordinate of the first image we need to put on the left-top of the rect
+ if (repeatX && repeatY) {
+ // repeat
+ // startX, startY is at the left top side of the left-top of the rect
+ startX = r.x() >=0 ? r.x() - (r.x() % w) : r.x() - (w - qAbs(r.x()) % w);
+ startY = r.y() >=0 ? r.y() - (r.y() % h) : r.y() - (h - qAbs(r.y()) % h);
+ } else {
+ if (!repeatX && !repeatY) {
+ // no-repeat
+ // only draw the image once at orgin once, check if need to draw
+ QRect imageRect(0, 0, w, h);
+ if (imageRect.intersects(r)) {
+ startX = 0;
+ startY = 0;
+ } else
+ return;
+ } else if (repeatX && !repeatY) {
+ // repeat-x
+ // startY is fixed, but startX change based on the left-top of the rect
+ QRect imageRect(r.x(), 0, r.width(), h);
+ if (imageRect.intersects(r)) {
+ startX = r.x() >=0 ? r.x() - (r.x() % w) : r.x() - (w - qAbs(r.x()) % w);
+ startY = 0;
+ } else
+ return;
+ } else {
+ // repeat-y
+ // startX is fixed, but startY change based on the left-top of the rect
+ QRect imageRect(0, r.y(), w, r.height());
+ if (imageRect.intersects(r)) {
+ startX = 0;
+ startY = r.y() >=0 ? r.y() - (r.y() % h) : r.y() - (h - qAbs(r.y()) % h);
+ } else
+ return;
+ }
+ }
+
+ int x = startX;
+ int y = startY;
+ do {
+ // repeat Y
+ do {
+ // repeat X
+ QRect imageRect(x, y, w, h);
+ QRect intersectRect = imageRect.intersected(r);
+ QPoint destStart(intersectRect.x(), intersectRect.y());
+ QRect sourceRect(intersectRect.x() - imageRect.x(), intersectRect.y() - imageRect.y(), intersectRect.width(), intersectRect.height());
+
+ p->drawImage(destStart, image, sourceRect);
+ x += w;
+ } while (repeatX && x < r.x() + r.width());
+ x = startX;
+ y += h;
+ } while (repeatY && y < r.y() + r.height());
+ }
+}
QPen QSGContext2DCommandBuffer::makePen(QSGContext2D::State state)
{
@@ -184,7 +252,13 @@ QSGContext2D::State QSGContext2DCommandBuffer::replay(QPainter* p, QSGContext2D:
}
case QSGContext2D::ClearRect:
{
- p->eraseRect(takeRect());
+ QPainter::CompositionMode cm = p->compositionMode();
+ qreal alpha = p->opacity();
+ p->setCompositionMode(QPainter::CompositionMode_Source);
+ p->setOpacity(0);
+ p->fillRect(takeRect(), QColor(qRgba(0, 0, 0, 0)));
+ p->setCompositionMode(cm);
+ p->setOpacity(alpha);
break;
}
case QSGContext2D::FillRect:
@@ -219,12 +293,16 @@ QSGContext2D::State QSGContext2DCommandBuffer::replay(QPainter* p, QSGContext2D:
case QSGContext2D::FillStyle:
{
state.fillStyle = takeFillStyle();
+ state.fillPatternRepeatX = takeBool();
+ state.fillPatternRepeatY = takeBool();
p->setBrush(state.fillStyle);
break;
}
case QSGContext2D::StrokeStyle:
{
state.strokeStyle = takeStrokeStyle();
+ state.strokePatternRepeatX = takeBool();
+ state.strokePatternRepeatY = takeBool();
pen.setBrush(state.strokeStyle);
p->setPen(pen);
break;
@@ -262,10 +340,12 @@ QSGContext2D::State QSGContext2DCommandBuffer::replay(QPainter* p, QSGContext2D:
break;
case QSGContext2D::Fill:
{
+ QPainterPath path = takePath();
+ path.closeSubpath();
if (HAS_SHADOW(state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor))
- fillShadowPath(p,takePath(), state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor);
+ fillShadowPath(p,path, state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor);
else
- p->fillPath(takePath(), p->brush());
+ p->fillPath(path, p->brush());
break;
}
case QSGContext2D::Stroke:
@@ -278,22 +358,11 @@ QSGContext2D::State QSGContext2DCommandBuffer::replay(QPainter* p, QSGContext2D:
}
case QSGContext2D::Clip:
{
- QPainterPath clipPath = takePath();
- clipPath.closeSubpath();
- state.clipPath = state.clipPath.intersected(clipPath);
- if (!p->clipPath().isEmpty())
- clipPath = clipPath.intersected(p->clipPath());
+ state.clipPath = takePath();
p->setClipping(true);
- p->setClipPath(clipPath);
+ p->setClipPath(state.clipPath);
break;
}
- case QSGContext2D::UpdateBrush:
- {
- state.fillStyle = takeBrush();
- p->setBrush(state.fillStyle);
- break;
- }
-
case QSGContext2D::GlobalAlpha:
{
state.globalAlpha = takeGlobalAlpha();
@@ -355,6 +424,7 @@ QSGContext2D::State QSGContext2DCommandBuffer::replay(QPainter* p, QSGContext2D:
QSGContext2DCommandBuffer::QSGContext2DCommandBuffer()
: cmdIdx(0)
, intIdx(0)
+ , boolIdx(0)
, realIdx(0)
, colorIdx(0)
, matrixIdx(0)
@@ -373,6 +443,7 @@ void QSGContext2DCommandBuffer::clear()
{
commands.clear();
ints.clear();
+ bools.clear();
reals.clear();
colors.clear();
matrixes.clear();
@@ -386,6 +457,7 @@ void QSGContext2DCommandBuffer::reset()
{
cmdIdx = 0;
intIdx = 0;
+ boolIdx = 0;
realIdx = 0;
colorIdx = 0;
matrixIdx = 0;
@@ -394,4 +466,5 @@ void QSGContext2DCommandBuffer::reset()
imageIdx = 0;
}
+QT_END_NAMESPACE
diff --git a/src/declarative/items/context2d/qsgcontext2dcommandbuffer_p.h b/src/declarative/items/context2d/qsgcontext2dcommandbuffer_p.h
index d95adeeafd..cab82e2f67 100644
--- a/src/declarative/items/context2d/qsgcontext2dcommandbuffer_p.h
+++ b/src/declarative/items/context2d/qsgcontext2dcommandbuffer_p.h
@@ -43,7 +43,7 @@
#define QSGCONTEXT2DCOMMANDBUFFER_P_H
#include "qsgcontext2d_p.h"
-#include "qdeclarativepixmapcache_p.h"
+#include <private/qdeclarativepixmapcache_p.h>
QT_BEGIN_HEADER
@@ -89,10 +89,11 @@ public:
ints << cm;
}
- inline void setStrokeStyle(const QBrush &style)
+ inline void setStrokeStyle(const QBrush &style, bool repeatX = false, bool repeatY = false)
{
commands << QSGContext2D::StrokeStyle;
brushes << style;
+ bools << repeatX << repeatY;
}
inline void drawImage(const QImage& image, qreal sx, qreal sy, qreal sw, qreal sh, qreal dx, qreal dy, qreal dw, qreal dh)
@@ -157,10 +158,11 @@ public:
- inline void setFillStyle(const QBrush &style)
+ inline void setFillStyle(const QBrush &style, bool repeatX = false, bool repeatY = false)
{
- commands << QSGContext2D::UpdateBrush;
+ commands << QSGContext2D::FillStyle;
brushes << style;
+ bools << repeatX << repeatY;
}
@@ -229,6 +231,7 @@ public:
inline const QImage& takeImage() { return images[imageIdx++]; }
inline int takeInt() { return ints[intIdx++]; }
+ inline bool takeBool() {return bools[boolIdx++]; }
inline qreal takeReal() { return reals[realIdx++]; }
inline QColor takeColor() { return colors[colorIdx++]; }
inline QBrush takeBrush() { return brushes[brushIdx++]; }
@@ -239,6 +242,7 @@ private:
void setPainterState(QPainter* painter, QSGContext2D::State state, const QPen& pen);
int cmdIdx;
int intIdx;
+ int boolIdx;
int realIdx;
int colorIdx;
int matrixIdx;
@@ -248,6 +252,7 @@ private:
QVector<QSGContext2D::PaintCommand> commands;
QVector<int> ints;
+ QVector<bool> bools;
QVector<qreal> reals;
QVector<QColor> colors;
QVector<QTransform> matrixes;
diff --git a/src/declarative/items/context2d/qsgcontext2dnode.cpp b/src/declarative/items/context2d/qsgcontext2dnode.cpp
index 4173b32e60..87de8cf157 100644
--- a/src/declarative/items/context2d/qsgcontext2dnode.cpp
+++ b/src/declarative/items/context2d/qsgcontext2dnode.cpp
@@ -52,6 +52,7 @@ QSGContext2DNode::QSGContext2DNode(QSGCanvasItem* item)
, m_item(item)
, m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
, m_texture(0)
+ , m_size(1, 1)
, m_dirtyGeometry(false)
, m_dirtyTexture(false)
{
@@ -63,6 +64,15 @@ QSGContext2DNode::QSGContext2DNode(QSGCanvasItem* item)
QSGContext2DNode::~QSGContext2DNode()
{
+ delete m_texture;
+}
+
+void QSGContext2DNode::setSize(const QSizeF& size)
+{
+ if (m_size != size) {
+ m_dirtyGeometry = true;
+ m_size = size;
+ }
}
void QSGContext2DNode::preprocess()
@@ -71,7 +81,6 @@ void QSGContext2DNode::preprocess()
QSGDynamicTexture *t = qobject_cast<QSGDynamicTexture *>(m_material.texture());
if (t) {
doDirty = t->updateTexture();
- updateGeometry();
}
if (doDirty) {
m_dirtyTexture = true;
@@ -106,10 +115,9 @@ void QSGContext2DNode::updateTexture()
void QSGContext2DNode::updateGeometry()
{
- QSizeF size = m_item->canvasWindow().size();
QRectF source = m_texture->textureSubRect();
QSGGeometry::updateTexturedRectGeometry(&m_geometry,
- QRectF(0, 0, size.width(), size.height()),
+ QRectF(0, 0, m_size.width(), m_size.height()),
source);
markDirty(DirtyGeometry);
}
diff --git a/src/declarative/items/context2d/qsgcontext2dnode_p.h b/src/declarative/items/context2d/qsgcontext2dnode_p.h
index 70446d7357..88c3619095 100644
--- a/src/declarative/items/context2d/qsgcontext2dnode_p.h
+++ b/src/declarative/items/context2d/qsgcontext2dnode_p.h
@@ -42,8 +42,8 @@
#ifndef QSGCONTEXT2DNODE_P_H
#define QSGCONTEXT2DNODE_P_H
-#include "qsgnode.h"
-#include "qsgtexturematerial.h"
+#include <qsgnode.h>
+#include <qsgtexturematerial.h>
#include "qsgcanvasitem_p.h"
#include "qsgcontext2dtexture_p.h"
@@ -63,6 +63,7 @@ public:
void setTexture(QSGContext2DTexture* texture);
void update();
void preprocess();
+ void setSize(const QSizeF& size);
private:
void updateTexture();
void updateGeometry();
@@ -72,6 +73,7 @@ private:
QSGTextureMaterial m_materialO;
QSGGeometry m_geometry;
QSGContext2DTexture* m_texture;
+ QSizeF m_size;
bool m_dirtyGeometry;
bool m_dirtyTexture;
diff --git a/src/declarative/items/context2d/qsgcontext2dtexture.cpp b/src/declarative/items/context2d/qsgcontext2dtexture.cpp
index 4833c1301c..721f847978 100644
--- a/src/declarative/items/context2d/qsgcontext2dtexture.cpp
+++ b/src/declarative/items/context2d/qsgcontext2dtexture.cpp
@@ -42,8 +42,8 @@
#include "qsgcontext2dtexture_p.h"
#include "qsgcontext2dtile_p.h"
#include "qsgcanvasitem_p.h"
-#include "qsgitem_p.h"
-#include "private/qsgtexture_p.h"
+#include <private/qsgitem_p.h>
+#include <private/qsgtexture_p.h>
#include "qsgcontext2dcommandbuffer_p.h"
#include <QOpenGLPaintDevice>
@@ -142,12 +142,7 @@ void QSGContext2DTexture::setItem(QSGCanvasItem* item)
m_context = item->context();
m_state = m_context->state;
unlock();
- connect(this, SIGNAL(textureChanged()), m_item, SIGNAL(painted()), Qt::QueuedConnection);
- canvasChanged(item->canvasSize().toSize()
- , item->tileSize()
- , item->canvasWindow().toAlignedRect()
- , item->canvasWindow().toAlignedRect()
- , item->smooth());
+ connect(this, SIGNAL(textureChanged()), m_item, SIGNAL(painted()));
}
}
@@ -155,17 +150,23 @@ bool QSGContext2DTexture::setCanvasWindow(const QRect& r)
{
if (m_canvasWindow != r) {
m_canvasWindow = r;
+ return true;
}
+ return false;
}
bool QSGContext2DTexture::setDirtyRect(const QRect &r)
{
bool doDirty = false;
- foreach (QSGContext2DTile* t, m_tiles) {
- bool dirty = t->rect().intersected(r).isValid();
- t->markDirty(dirty);
- if (dirty)
- doDirty = true;
+ if (m_tiledCanvas) {
+ foreach (QSGContext2DTile* t, m_tiles) {
+ bool dirty = t->rect().intersected(r).isValid();
+ t->markDirty(dirty);
+ if (dirty)
+ doDirty = true;
+ }
+ } else {
+ doDirty = m_canvasWindow.intersected(r).isValid();
}
return doDirty;
}
@@ -181,26 +182,27 @@ void QSGContext2DTexture::canvasChanged(const QSize& canvasSize, const QSize& ti
if (ts.height() > canvasSize.height())
ts.setHeight(canvasSize.height());
- bool canvasChanged = setCanvasSize(canvasSize);
- bool tileChanged = setTileSize(ts);
+ setCanvasSize(canvasSize);
+ setTileSize(ts);
- bool doDirty = false;
if (canvasSize == canvasWindow.size()) {
m_tiledCanvas = false;
m_dirtyCanvas = false;
} else {
m_tiledCanvas = true;
- if (dirtyRect.isValid())
- doDirty = setDirtyRect(dirtyRect);
}
- bool windowChanged = setCanvasWindow(canvasWindow);
+ bool doDirty = false;
+ if (dirtyRect.isValid())
+ doDirty = setDirtyRect(dirtyRect);
+ bool windowChanged = setCanvasWindow(canvasWindow);
if (windowChanged || doDirty) {
if (m_threadRendering)
QMetaObject::invokeMethod(this, "paint", Qt::QueuedConnection);
- else if (supportDirectRendering())
- QMetaObject::invokeMethod(this, "paint", Qt::DirectConnection);
+ else if (supportDirectRendering()) {
+ QMetaObject::invokeMethod(this, "paint", Qt::DirectConnection);
+ }
}
setSmooth(smooth);
@@ -310,7 +312,7 @@ void QSGContext2DTexture::paint()
return;
} else if (dirtyTile) {
m_state = ccb->replay(tile->createPainter(smooth), oldState);
-
+ tile->drawFinished();
lock();
tile->markDirty(false);
unlock();
@@ -403,11 +405,19 @@ void QSGContext2DTexture::clearTiles()
QSGContext2DFBOTexture::QSGContext2DFBOTexture()
: QSGContext2DTexture()
, m_fbo(0)
+ , m_multisampledFbo(0)
, m_paint_device(0)
{
m_threadRendering = false;
}
+QSGContext2DFBOTexture::~QSGContext2DFBOTexture()
+{
+ delete m_fbo;
+ delete m_multisampledFbo;
+ delete m_paint_device;
+}
+
bool QSGContext2DFBOTexture::setCanvasSize(const QSize &size)
{
QSize s = QSize(qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.width()))
@@ -460,9 +470,9 @@ void QSGContext2DFBOTexture::bind()
QRectF QSGContext2DFBOTexture::textureSubRect() const
{
return QRectF(0
- , 1
+ , 0
, qreal(m_canvasWindow.width()) / m_fboSize.width()
- , qreal(-m_canvasWindow.height()) / m_fboSize.height());
+ , qreal(m_canvasWindow.height()) / m_fboSize.height());
}
@@ -502,6 +512,21 @@ void QSGContext2DFBOTexture::grabImage()
}
}
+bool QSGContext2DFBOTexture::doMultisampling() const
+{
+ static bool extensionsChecked = false;
+ static bool multisamplingSupported = false;
+
+ if (!extensionsChecked) {
+ QList<QByteArray> extensions = QByteArray((const char *)glGetString(GL_EXTENSIONS)).split(' ');
+ multisamplingSupported = extensions.contains("GL_EXT_framebuffer_multisample")
+ && extensions.contains("GL_EXT_framebuffer_blit");
+ extensionsChecked = true;
+ }
+
+ return multisamplingSupported && m_smooth;
+}
+
QImage QSGContext2DFBOTexture::toImage(const QRectF& region)
{
#define QML_CONTEXT2D_WAIT_MAX 5000
@@ -548,35 +573,65 @@ QPaintDevice* QSGContext2DFBOTexture::beginPainting()
if (m_canvasWindow.size().isEmpty() && !m_threadRendering) {
delete m_fbo;
+ delete m_multisampledFbo;
m_fbo = 0;
+ m_multisampledFbo = 0;
+ return 0;
} else if (!m_fbo || m_fbo->size() != m_fboSize) {
- QOpenGLFramebufferObjectFormat format;
- format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
- format.setInternalTextureFormat(GL_RGBA);
- format.setMipmap(false);
- format.setTextureTarget(GL_TEXTURE_2D);
delete m_fbo;
- glDisable(GL_DEPTH_TEST);
- glDepthMask(false);
+ delete m_multisampledFbo;
+ if (doMultisampling()) {
+ {
+ QOpenGLFramebufferObjectFormat format;
+ format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
+ format.setSamples(8);
+ m_multisampledFbo = new QOpenGLFramebufferObject(m_fboSize, format);
+ }
+ {
+ QOpenGLFramebufferObjectFormat format;
+ format.setAttachment(QOpenGLFramebufferObject::NoAttachment);
+ m_fbo = new QOpenGLFramebufferObject(m_fboSize, format);
+ }
+ } else {
+ QOpenGLFramebufferObjectFormat format;
+ format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
- m_fbo = new QOpenGLFramebufferObject(m_fboSize, format);
- glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
- updateBindOptions(false);
+ m_fbo = new QOpenGLFramebufferObject(m_fboSize, format);
+ }
}
- m_fbo->bind();
+ if (doMultisampling())
+ m_multisampledFbo->bind();
+ else
+ m_fbo->bind();
+
- if (!m_paint_device)
- m_paint_device = new QOpenGLPaintDevice(m_fbo->size());
+ if (!m_paint_device) {
+ QOpenGLPaintDevice *gl_device = new QOpenGLPaintDevice(m_fbo->size());
+ gl_device->setPaintFlipped(true);
+ m_paint_device = gl_device;
+ }
return m_paint_device;
}
+void QSGContext2DFBOTexture::endPainting()
+{
+ QSGContext2DTexture::endPainting();
+ if (m_multisampledFbo) {
+ QOpenGLFramebufferObject::blitFramebuffer(m_fbo, m_multisampledFbo);
+ m_multisampledFbo->release();
+ } else if (m_fbo)
+ m_fbo->release();
+}
void qt_quit_context2d_render_thread()
{
QThread* thread = globalCanvasThreadRenderInstance();
- thread->quit();
- thread->wait();
+
+ if (thread->isRunning()) {
+ thread->exit(0);
+ thread->wait(1000);
+ }
}
QSGContext2DImageTexture::QSGContext2DImageTexture(bool threadRendering)
@@ -601,7 +656,7 @@ QSGContext2DImageTexture::QSGContext2DImageTexture(bool threadRendering)
QSGContext2DImageTexture::~QSGContext2DImageTexture()
{
- m_texture->deleteLater();
+ delete m_texture;
}
int QSGContext2DImageTexture::textureId() const
@@ -696,7 +751,7 @@ QPaintDevice* QSGContext2DImageTexture::beginPainting()
lock();
if (m_image.size() != m_canvasWindow.size()) {
m_image = QImage(m_canvasWindow.size(), QImage::Format_ARGB32_Premultiplied);
- m_image.fill(Qt::transparent);
+ m_image.fill(0x00000000);
}
unlock();
return &m_image;
diff --git a/src/declarative/items/context2d/qsgcontext2dtexture_p.h b/src/declarative/items/context2d/qsgcontext2dtexture_p.h
index 0fb315497a..dbc383d7fc 100644
--- a/src/declarative/items/context2d/qsgcontext2dtexture_p.h
+++ b/src/declarative/items/context2d/qsgcontext2dtexture_p.h
@@ -42,7 +42,7 @@
#ifndef QSGCONTEXT2DTEXTURE_P_H
#define QSGCONTEXT2DTEXTURE_P_H
-#include "qsgtexture.h"
+#include <qsgtexture.h>
#include "qsgcanvasitem_p.h"
#include "qsgcontext2d_p.h"
@@ -100,7 +100,7 @@ public Q_SLOTS:
protected:
void paintWithoutTiles();
- virtual QPaintDevice* beginPainting() {m_painting = true;}
+ virtual QPaintDevice* beginPainting() {m_painting = true; return 0; }
virtual void endPainting() {m_painting = false;}
virtual QSGContext2DTile* createTile() const = 0;
virtual void compositeTile(QSGContext2DTile* tile) = 0;
@@ -133,11 +133,13 @@ class QSGContext2DFBOTexture : public QSGContext2DTexture
public:
QSGContext2DFBOTexture();
+ ~QSGContext2DFBOTexture();
virtual int textureId() const;
virtual bool updateTexture();
virtual QSGContext2DTile* createTile() const;
virtual QImage toImage(const QRectF& region = QRectF());
virtual QPaintDevice* beginPainting();
+ virtual void endPainting();
QRectF textureSubRect() const;
virtual bool supportThreadRendering() const {return false;}
virtual bool supportDirectRendering() const {return false;}
@@ -151,8 +153,10 @@ private Q_SLOTS:
void grabImage();
private:
+ bool doMultisampling() const;
QImage m_grabedImage;
QOpenGLFramebufferObject *m_fbo;
+ QOpenGLFramebufferObject *m_multisampledFbo;
QMutex m_mutex;
QWaitCondition m_condition;
QSize m_fboSize;
diff --git a/src/declarative/items/context2d/qsgcontext2dtile.cpp b/src/declarative/items/context2d/qsgcontext2dtile.cpp
index 14051b62c1..8c8ef836b0 100644
--- a/src/declarative/items/context2d/qsgcontext2dtile.cpp
+++ b/src/declarative/items/context2d/qsgcontext2dtile.cpp
@@ -109,10 +109,18 @@ void QSGContext2DFBOTile::aboutToDraw()
{
m_fbo->bind();
if (!m_device) {
- m_device = new QOpenGLPaintDevice(rect().size());
+ QOpenGLPaintDevice *gl_device = new QOpenGLPaintDevice(rect().size());
+ m_device = gl_device;
+ QPainter p(m_device);
+ p.fillRect(QRectF(0, 0, m_fbo->width(), m_fbo->height()), QColor(qRgba(0, 0, 0, 0)));
+ p.end();
}
}
+void QSGContext2DFBOTile::drawFinished()
+{
+ m_fbo->release();
+}
void QSGContext2DFBOTile::setRect(const QRect& r)
{
@@ -154,4 +162,4 @@ void QSGContext2DImageTile::setRect(const QRect& r)
m_image = QImage(r.size(), QImage::Format_ARGB32_Premultiplied);
}
m_device = &m_image;
-}
+} \ No newline at end of file
diff --git a/src/declarative/items/context2d/qsgcontext2dtile_p.h b/src/declarative/items/context2d/qsgcontext2dtile_p.h
index d5317f9357..57b68ef67d 100644
--- a/src/declarative/items/context2d/qsgcontext2dtile_p.h
+++ b/src/declarative/items/context2d/qsgcontext2dtile_p.h
@@ -67,11 +67,10 @@ public:
virtual void setRect(const QRect& r) = 0;
virtual QPainter* createPainter(bool smooth = false);
-
+ virtual void drawFinished() {}
protected:
virtual void aboutToDraw() {}
-
uint m_dirty : 1;
QRect m_rect;
QPaintDevice* m_device;
@@ -86,10 +85,10 @@ public:
~QSGContext2DFBOTile();
virtual void setRect(const QRect& r);
QOpenGLFramebufferObject* fbo() const {return m_fbo;}
+ void drawFinished();
protected:
void aboutToDraw();
-
private:
diff --git a/src/declarative/items/items.pri b/src/declarative/items/items.pri
index 04330748e1..025f67ab90 100644
--- a/src/declarative/items/items.pri
+++ b/src/declarative/items/items.pri
@@ -1,5 +1,3 @@
-INCLUDEPATH += $$PWD
-
HEADERS += \
$$PWD/qsgevents_p_p.h \
$$PWD/qsgitemchangelistener_p.h \
@@ -64,8 +62,8 @@ HEADERS += \
$$PWD/qsgspriteengine_p.h \
$$PWD/qsgsprite_p.h \
$$PWD/qsgspriteimage_p.h \
- $$PWD/qsgevent.h \
- $$PWD/qsgdragtarget_p.h \
+ $$PWD/qsgdrag_p.h \
+ $$PWD/qsgdroparea_p.h \
$$PWD/qsgitemview_p.h \
$$PWD/qsgitemview_p_p.h
@@ -110,7 +108,8 @@ SOURCES += \
$$PWD/qsgspriteengine.cpp \
$$PWD/qsgsprite.cpp \
$$PWD/qsgspriteimage.cpp \
- $$PWD/qsgdragtarget.cpp \
+ $$PWD/qsgdrag.cpp \
+ $$PWD/qsgdroparea.cpp \
$$PWD/qsgitemview.cpp
SOURCES += \
diff --git a/src/declarative/items/qsganchors.cpp b/src/declarative/items/qsganchors.cpp
index 6d5b5a3d83..67ca0317c4 100644
--- a/src/declarative/items/qsganchors.cpp
+++ b/src/declarative/items/qsganchors.cpp
@@ -76,7 +76,7 @@ static qreal vcenter(QSGItem *item)
static qreal position(QSGItem *item, QSGAnchorLine::AnchorLine anchorLine)
{
qreal ret = 0.0;
- switch(anchorLine) {
+ switch (anchorLine) {
case QSGAnchorLine::Left:
ret = item->x();
break;
@@ -109,7 +109,7 @@ static qreal position(QSGItem *item, QSGAnchorLine::AnchorLine anchorLine)
static qreal adjustedPosition(QSGItem *item, QSGAnchorLine::AnchorLine anchorLine)
{
qreal ret = 0.0;
- switch(anchorLine) {
+ switch (anchorLine) {
case QSGAnchorLine::Left:
ret = 0.0;
break;
@@ -253,7 +253,7 @@ void QSGAnchorsPrivate::addDepend(QSGItem *item)
{
if (!item)
return;
-
+
QSGItemPrivate *p = QSGItemPrivate::get(item);
p->addItemChangeListener(this, QSGItemPrivate::Geometry);
}
@@ -887,7 +887,7 @@ void QSGAnchors::setLeftMargin(qreal offset)
if (d->leftMargin == offset)
return;
d->leftMargin = offset;
- if(d->fill)
+ if (d->fill)
d->fillChanged();
else
d->updateHorizontalAnchors();
@@ -906,7 +906,7 @@ void QSGAnchors::setRightMargin(qreal offset)
if (d->rightMargin == offset)
return;
d->rightMargin = offset;
- if(d->fill)
+ if (d->fill)
d->fillChanged();
else
d->updateHorizontalAnchors();
@@ -925,13 +925,13 @@ void QSGAnchors::setMargins(qreal offset)
if (d->margins == offset)
return;
//###Is it significantly faster to set them directly so we can call fillChanged only once?
- if(!d->rightMargin || d->rightMargin == d->margins)
+ if (!d->rightMargin || d->rightMargin == d->margins)
setRightMargin(offset);
- if(!d->leftMargin || d->leftMargin == d->margins)
+ if (!d->leftMargin || d->leftMargin == d->margins)
setLeftMargin(offset);
- if(!d->topMargin || d->topMargin == d->margins)
+ if (!d->topMargin || d->topMargin == d->margins)
setTopMargin(offset);
- if(!d->bottomMargin || d->bottomMargin == d->margins)
+ if (!d->bottomMargin || d->bottomMargin == d->margins)
setBottomMargin(offset);
d->margins = offset;
emit marginsChanged();
@@ -950,7 +950,7 @@ void QSGAnchors::setHorizontalCenterOffset(qreal offset)
if (d->hCenterOffset == offset)
return;
d->hCenterOffset = offset;
- if(d->centerIn)
+ if (d->centerIn)
d->centerInChanged();
else
d->updateHorizontalAnchors();
@@ -969,7 +969,7 @@ void QSGAnchors::setTopMargin(qreal offset)
if (d->topMargin == offset)
return;
d->topMargin = offset;
- if(d->fill)
+ if (d->fill)
d->fillChanged();
else
d->updateVerticalAnchors();
@@ -988,7 +988,7 @@ void QSGAnchors::setBottomMargin(qreal offset)
if (d->bottomMargin == offset)
return;
d->bottomMargin = offset;
- if(d->fill)
+ if (d->fill)
d->fillChanged();
else
d->updateVerticalAnchors();
@@ -1007,7 +1007,7 @@ void QSGAnchors::setVerticalCenterOffset(qreal offset)
if (d->vCenterOffset == offset)
return;
d->vCenterOffset = offset;
- if(d->centerIn)
+ if (d->centerIn)
d->centerInChanged();
else
d->updateVerticalAnchors();
diff --git a/src/declarative/items/qsganimatedimage.cpp b/src/declarative/items/qsganimatedimage.cpp
index e4bba512af..93e0284417 100644
--- a/src/declarative/items/qsganimatedimage.cpp
+++ b/src/declarative/items/qsganimatedimage.cpp
@@ -144,7 +144,7 @@ QSGAnimatedImage::~QSGAnimatedImage()
bool QSGAnimatedImage::isPaused() const
{
Q_D(const QSGAnimatedImage);
- if(!d->_movie)
+ if (!d->_movie)
return false;
return d->_movie->state()==QMovie::Paused;
}
@@ -152,10 +152,10 @@ bool QSGAnimatedImage::isPaused() const
void QSGAnimatedImage::setPaused(bool pause)
{
Q_D(QSGAnimatedImage);
- if(pause == d->paused)
+ if (pause == d->paused)
return;
d->paused = pause;
- if(!d->_movie)
+ if (!d->_movie)
return;
d->_movie->setPaused(pause);
}
@@ -179,7 +179,7 @@ bool QSGAnimatedImage::isPlaying() const
void QSGAnimatedImage::setPlaying(bool play)
{
Q_D(QSGAnimatedImage);
- if(play == d->playing)
+ if (play == d->playing)
return;
d->playing = play;
if (!d->_movie)
@@ -282,11 +282,11 @@ void QSGAnimatedImage::load()
connect(d->_movie, SIGNAL(frameChanged(int)),
this, SLOT(movieUpdate()));
d->_movie->setCacheMode(QMovie::CacheAll);
- if(d->playing)
+ if (d->playing)
d->_movie->start();
else
d->_movie->jumpToFrame(0);
- if(d->paused)
+ if (d->paused)
d->_movie->setPaused(true);
d->setPixmap(d->_movie->currentPixmap());
d->status = Ready;
@@ -347,13 +347,13 @@ void QSGAnimatedImage::movieRequestFinished()
connect(d->_movie, SIGNAL(frameChanged(int)),
this, SLOT(movieUpdate()));
d->_movie->setCacheMode(QMovie::CacheAll);
- if(d->playing)
+ if (d->playing)
d->_movie->start();
if (d->paused || !d->playing) {
d->_movie->jumpToFrame(d->preset_currentframe);
d->preset_currentframe = 0;
}
- if(d->paused)
+ if (d->paused)
d->_movie->setPaused(true);
d->setPixmap(d->_movie->currentPixmap());
d->status = Ready;
@@ -370,11 +370,11 @@ void QSGAnimatedImage::movieUpdate()
void QSGAnimatedImage::playingStatusChanged()
{
Q_D(QSGAnimatedImage);
- if((d->_movie->state() != QMovie::NotRunning) != d->playing){
+ if ((d->_movie->state() != QMovie::NotRunning) != d->playing) {
d->playing = (d->_movie->state() != QMovie::NotRunning);
emit playingChanged();
}
- if((d->_movie->state() == QMovie::Paused) != d->paused){
+ if ((d->_movie->state() == QMovie::Paused) != d->paused) {
d->playing = (d->_movie->state() == QMovie::Paused);
emit pausedChanged();
}
diff --git a/src/declarative/items/qsganimation.cpp b/src/declarative/items/qsganimation.cpp
index 4a3d0c8ec5..6acbfa0518 100644
--- a/src/declarative/items/qsganimation.cpp
+++ b/src/declarative/items/qsganimation.cpp
@@ -43,8 +43,8 @@
#include "qsganimation_p_p.h"
#include "qsgstateoperations_p.h"
-#include <qdeclarativeproperty_p.h>
-#include <qdeclarativepath_p.h>
+#include <private/qdeclarativeproperty_p.h>
+#include <private/qdeclarativepath_p.h>
#include <QtDeclarative/qdeclarativeinfo.h>
#include <QtCore/qmath.h>
@@ -114,7 +114,7 @@ void QSGParentAnimation::setVia(QSGItem *via)
//### mirrors same-named function in QSGItem
QPointF QSGParentAnimationPrivate::computeTransformOrigin(QSGItem::TransformOrigin origin, qreal width, qreal height) const
{
- switch(origin) {
+ switch (origin) {
default:
case QSGItem::TopLeft:
return QPointF(0, 0);
@@ -689,8 +689,8 @@ void QSGPathAnimationUpdater::setValue(qreal v)
}
//### could cache properties rather than reconstructing each time
- QDeclarativePropertyPrivate::write(QDeclarativeProperty(target, "x"), currentPos.x(), QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
- QDeclarativePropertyPrivate::write(QDeclarativeProperty(target, "y"), currentPos.y(), QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
+ QDeclarativePropertyPrivate::write(QDeclarativeProperty(target, QStringLiteral("x")), currentPos.x(), QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
+ QDeclarativePropertyPrivate::write(QDeclarativeProperty(target, QStringLiteral("y")), currentPos.y(), QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
//adjust angle according to orientation
if (!fixed) {
@@ -741,7 +741,7 @@ void QSGPathAnimationUpdater::setValue(qreal v)
else if (v > exitStart)
angle = endRotation * (v - exitStart) / exitInterval + angle * (exitInterval - (v - exitStart)) / exitInterval;
}
- QDeclarativePropertyPrivate::write(QDeclarativeProperty(target, "rotation"), angle, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
+ QDeclarativePropertyPrivate::write(QDeclarativeProperty(target, QStringLiteral("rotation")), angle, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
}
/*
diff --git a/src/declarative/items/qsgborderimage.cpp b/src/declarative/items/qsgborderimage.cpp
index 30b10321a0..fb407d7e2c 100644
--- a/src/declarative/items/qsgborderimage.cpp
+++ b/src/declarative/items/qsgborderimage.cpp
@@ -314,18 +314,7 @@ void QSGBorderImage::load()
} else {
QNetworkRequest req(d->url);
d->sciReply = qmlEngine(this)->networkAccessManager()->get(req);
-
- static int sciReplyFinished = -1;
- static int thisSciRequestFinished = -1;
- if (sciReplyFinished == -1) {
- sciReplyFinished =
- QNetworkReply::staticMetaObject.indexOfSignal("finished()");
- thisSciRequestFinished =
- QSGBorderImage::staticMetaObject.indexOfSlot("sciRequestFinished()");
- }
-
- QMetaObject::connect(d->sciReply, sciReplyFinished, this,
- thisSciRequestFinished, Qt::DirectConnection);
+ FAST_CONNECT(d->sciReply, SIGNAL(finished()), this, SLOT(sciRequestFinished()))
}
} else {
diff --git a/src/declarative/items/qsgborderimage_p_p.h b/src/declarative/items/qsgborderimage_p_p.h
index 69e02cd00b..27816697f4 100644
--- a/src/declarative/items/qsgborderimage_p_p.h
+++ b/src/declarative/items/qsgborderimage_p_p.h
@@ -83,13 +83,7 @@ public:
Q_Q(QSGBorderImage);
if (!border) {
border = new QSGScaleGrid(q);
- static int borderChangedSignalIdx = -1;
- static int doUpdateSlotIdx = -1;
- if (borderChangedSignalIdx < 0)
- borderChangedSignalIdx = QSGScaleGrid::staticMetaObject.indexOfSignal("borderChanged()");
- if (doUpdateSlotIdx < 0)
- doUpdateSlotIdx = QSGBorderImage::staticMetaObject.indexOfSlot("doUpdate()");
- QMetaObject::connect(border, borderChangedSignalIdx, q, doUpdateSlotIdx);
+ FAST_CONNECT(border, SIGNAL(borderChanged()), q, SLOT(doUpdate()))
}
return border;
}
diff --git a/src/declarative/items/qsgcanvas.cpp b/src/declarative/items/qsgcanvas.cpp
index 2cdcda7061..b1c3d26b1e 100644
--- a/src/declarative/items/qsgcanvas.cpp
+++ b/src/declarative/items/qsgcanvas.cpp
@@ -45,8 +45,6 @@
#include "qsgitem.h"
#include "qsgitem_p.h"
-#include "qsgevent.h"
-
#include <private/qsgrenderer_p.h>
#include <private/qsgflashnode_p.h>
@@ -60,11 +58,21 @@
#include <QtGui/qevent.h>
#include <QtGui/qmatrix4x4.h>
#include <QtCore/qvarlengtharray.h>
+#include <QtDeclarative/qdeclarativeincubator.h>
#include <private/qdeclarativedebugtrace_p.h>
QT_BEGIN_NAMESPACE
+#define QSG_CANVAS_TIMING
+#ifdef QSG_CANVAS_TIMING
+static bool qsg_canvas_timing = !qgetenv("QML_CANVAS_TIMING").isEmpty();
+static QTime threadTimer;
+static int syncTime;
+static int renderTime;
+static int swapTime;
+#endif
+
DEFINE_BOOL_CONFIG_OPTION(qmlFixedAnimationStep, QML_FIXED_ANIMATION_STEP)
DEFINE_BOOL_CONFIG_OPTION(qmlNoThreadedRenderer, QML_BAD_GUI_RENDER_LOOP)
@@ -78,6 +86,45 @@ void QSGCanvasPrivate::updateFocusItemTransform()
qApp->inputPanel()->setInputItemTransform(QSGItemPrivate::get(focus)->itemToCanvasTransform());
}
+class QSGCanvasIncubationController : public QObject, public QDeclarativeIncubationController
+{
+public:
+ QSGCanvasIncubationController(QSGCanvasPrivate *canvas)
+ : m_canvas(canvas), m_eventSent(false) {}
+
+protected:
+ virtual bool event(QEvent *e)
+ {
+ if (e->type() == QEvent::User) {
+ Q_ASSERT(m_eventSent);
+
+ bool *amtp = m_canvas->thread->allowMainThreadProcessing();
+ while (incubatingObjectCount()) {
+ if (amtp)
+ incubateWhile(amtp);
+ else
+ incubateFor(5);
+ QCoreApplication::processEvents();
+ }
+
+ m_eventSent = false;
+ }
+ return QObject::event(e);
+ }
+
+ virtual void incubatingObjectCountChanged(int count)
+ {
+ if (count && !m_eventSent) {
+ m_eventSent = true;
+ QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+ }
+ }
+
+private:
+ QSGCanvasPrivate *m_canvas;
+ bool m_eventSent;
+};
+
class QSGCanvasPlainRenderLoop : public QObject, public QSGCanvasRenderLoop
{
public:
@@ -416,6 +463,7 @@ QSGCanvasPrivate::QSGCanvasPrivate()
, thread(0)
, animationDriver(0)
, renderTarget(0)
+ , incubationController(0)
{
}
@@ -459,6 +507,7 @@ void QSGCanvasPrivate::init(QSGCanvas *c)
thread->moveContextToThread(context);
q->setSurfaceType(QWindow::OpenGLSurface);
+ q->setFormat(context->defaultSurfaceFormat());
}
void QSGCanvasPrivate::transformTouchPoints(QList<QTouchEvent::TouchPoint> &touchPoints, const QTransform &transform)
@@ -721,7 +770,10 @@ void QSGCanvasPrivate::notifyFocusChangesRecur(QSGItem **items, int remaining)
void QSGCanvasPrivate::updateInputMethodData()
{
- qApp->inputPanel()->setInputItem(activeFocusItem);
+ QSGItem *inputItem = 0;
+ if (activeFocusItem && activeFocusItem->flags() & QSGItem::ItemAcceptsInputMethod)
+ inputItem = activeFocusItem;
+ qApp->inputPanel()->setInputItem(inputItem);
}
QVariant QSGCanvas::inputMethodQuery(Qt::InputMethodQuery query) const
@@ -788,6 +840,8 @@ QSGCanvas::~QSGCanvas()
QSGItemPrivate *rootItemPrivate = QSGItemPrivate::get(d->rootItem);
rootItemPrivate->removeFromDirtyList();
+ delete d->incubationController; d->incubationController = 0;
+
delete d->rootItem; d->rootItem = 0;
d->cleanupNodes();
}
@@ -850,11 +904,11 @@ bool QSGCanvas::event(QEvent *e)
d->clearHover();
d->lastMousePosition = QPoint();
break;
- case QSGEvent::SGDragEnter:
- case QSGEvent::SGDragExit:
- case QSGEvent::SGDragMove:
- case QSGEvent::SGDragDrop:
- d->deliverDragEvent(static_cast<QSGDragEvent *>(e));
+ case QEvent::DragEnter:
+ case QEvent::DragLeave:
+ case QEvent::DragMove:
+ case QEvent::Drop:
+ d->deliverDragEvent(&d->dragGrabber, e);
break;
case QEvent::WindowDeactivate:
rootItem()->windowDeactivateEvent();
@@ -938,10 +992,9 @@ bool QSGCanvasPrivate::deliverMouseEvent(QMouseEvent *event)
lastMousePosition = event->windowPos();
- if (!mouseGrabberItem &&
+ if (!mouseGrabberItem &&
event->type() == QEvent::MouseButtonPress &&
(event->button() & event->buttons()) == event->buttons()) {
-
return deliverInitialMousePressEvent(rootItem, event);
}
@@ -1295,6 +1348,7 @@ bool QSGCanvasPrivate::deliverTouchPoints(QSGItem *item, QTouchEvent *event, con
touchEvent.setModifiers(event->modifiers());
touchEvent.setTouchPointStates(eventStates);
touchEvent.setTouchPoints(eventPoints);
+ touchEvent.setTimestamp(event->timestamp());
touchEvent.accept();
q->sendEvent(item, &touchEvent);
@@ -1315,76 +1369,124 @@ bool QSGCanvasPrivate::deliverTouchPoints(QSGItem *item, QTouchEvent *event, con
return false;
}
-void QSGCanvasPrivate::deliverDragEvent(QSGDragEvent *event)
+void QSGCanvasPrivate::deliverDragEvent(QSGDragGrabber *grabber, QEvent *event)
{
Q_Q(QSGCanvas);
- if (event->type() == QSGEvent::SGDragExit || event->type() == QSGEvent::SGDragDrop) {
- if (QSGItem *grabItem = event->grabItem()) {
- event->setPosition(grabItem->mapFromScene(event->scenePosition()));
- q->sendEvent(grabItem, event);
+ grabber->resetTarget();
+ QSGDragGrabber::iterator grabItem = grabber->begin();
+ if (grabItem != grabber->end()) {
+ Q_ASSERT(event->type() != QEvent::DragEnter);
+ if (event->type() == QEvent::Drop) {
+ QDropEvent *e = static_cast<QDropEvent *>(event);
+ for (e->setAccepted(false); !e->isAccepted() && grabItem != grabber->end(); grabItem = grabber->release(grabItem)) {
+ QPointF p = (**grabItem)->mapFromScene(e->pos());
+ QDropEvent translatedEvent(
+ p.toPoint(),
+ e->possibleActions(),
+ e->mimeData(),
+ e->mouseButtons(),
+ e->keyboardModifiers());
+ QSGDropEventEx::copyActions(&translatedEvent, *e);
+ q->sendEvent(**grabItem, &translatedEvent);
+ e->setAccepted(translatedEvent.isAccepted());
+ e->setDropAction(translatedEvent.dropAction());
+ grabber->setTarget(**grabItem);
+ }
}
- } else if (!deliverDragEvent(rootItem, event)) {
- if (QSGItem *grabItem = event->grabItem()) {
- QSGDragEvent exitEvent(QSGEvent::SGDragExit, *event);
- exitEvent.setPosition(grabItem->mapFromScene(event->scenePosition()));
- q->sendEvent(grabItem, &exitEvent);
- event->setDropItem(0);
- event->setGrabItem(0);
+ if (event->type() != QEvent::DragMove) { // Either an accepted drop or a leave.
+ QDragLeaveEvent leaveEvent;
+ for (; grabItem != grabber->end(); grabItem = grabber->release(grabItem))
+ q->sendEvent(**grabItem, &leaveEvent);
+ return;
+ } else for (; grabItem != grabber->end(); grabItem = grabber->release(grabItem)) {
+ QDragMoveEvent *moveEvent = static_cast<QDragMoveEvent *>(event);
+ if (deliverDragEvent(grabber, **grabItem, moveEvent)) {
+ moveEvent->setAccepted(true);
+ for (++grabItem; grabItem != grabber->end();) {
+ QPointF p = (**grabItem)->mapFromScene(moveEvent->pos());
+ if (QRectF(0, 0, (**grabItem)->width(), (**grabItem)->height()).contains(p)) {
+ QDragMoveEvent translatedEvent(
+ p.toPoint(),
+ moveEvent->possibleActions(),
+ moveEvent->mimeData(),
+ moveEvent->mouseButtons(),
+ moveEvent->keyboardModifiers());
+ QSGDropEventEx::copyActions(&translatedEvent, *moveEvent);
+ q->sendEvent(**grabItem, &translatedEvent);
+ ++grabItem;
+ } else {
+ QDragLeaveEvent leaveEvent;
+ q->sendEvent(**grabItem, &leaveEvent);
+ grabItem = grabber->release(grabItem);
+ }
+ }
+ return;
+ } else {
+ QDragLeaveEvent leaveEvent;
+ q->sendEvent(**grabItem, &leaveEvent);
+ }
}
- event->setAccepted(false);
+ }
+ if (event->type() == QEvent::DragEnter || event->type() == QEvent::DragMove) {
+ QDragMoveEvent *e = static_cast<QDragMoveEvent *>(event);
+ QDragEnterEvent enterEvent(
+ e->pos(),
+ e->possibleActions(),
+ e->mimeData(),
+ e->mouseButtons(),
+ e->keyboardModifiers());
+ QSGDropEventEx::copyActions(&enterEvent, *e);
+ event->setAccepted(deliverDragEvent(grabber, rootItem, &enterEvent));
}
}
-bool QSGCanvasPrivate::deliverDragEvent(QSGItem *item, QSGDragEvent *event)
+bool QSGCanvasPrivate::deliverDragEvent(QSGDragGrabber *grabber, QSGItem *item, QDragMoveEvent *event)
{
Q_Q(QSGCanvas);
+ bool accepted = false;
QSGItemPrivate *itemPrivate = QSGItemPrivate::get(item);
- if (itemPrivate->opacity == 0.0)
+ if (itemPrivate->opacity == 0.0 || !item->isVisible() || !item->isEnabled())
return false;
- if (itemPrivate->flags & QSGItem::ItemClipsChildrenToShape) {
- QPointF p = item->mapFromScene(event->scenePosition());
- if (!QRectF(0, 0, item->width(), item->height()).contains(p))
- return false;
- }
-
- QList<QSGItem *> children = itemPrivate->paintOrderChildItems();
- for (int ii = children.count() - 1; ii >= 0; --ii) {
- QSGItem *child = children.at(ii);
- if (!child->isVisible() || !child->isEnabled())
- continue;
- if (deliverDragEvent(child, event))
- return true;
- }
-
- QPointF p = item->mapFromScene(event->scenePosition());
+ QPointF p = item->mapFromScene(event->pos());
if (QRectF(0, 0, item->width(), item->height()).contains(p)) {
- event->setPosition(p);
-
- if (event->type() == QSGEvent::SGDragMove && item != event->grabItem()) {
- QSGDragEvent enterEvent(QSGEvent::SGDragEnter, *event);
- q->sendEvent(item, &enterEvent);
- if (enterEvent.isAccepted()) {
- if (QSGItem *grabItem = event->grabItem()) {
- QSGDragEvent exitEvent(QSGEvent::SGDragExit, *event);
- q->sendEvent(grabItem, &exitEvent);
+ if (event->type() == QEvent::DragMove || itemPrivate->flags & QSGItem::ItemAcceptsDrops) {
+ QDragMoveEvent translatedEvent(
+ p.toPoint(),
+ event->possibleActions(),
+ event->mimeData(),
+ event->mouseButtons(),
+ event->keyboardModifiers(),
+ event->type());
+ QSGDropEventEx::copyActions(&translatedEvent, *event);
+ q->sendEvent(item, &translatedEvent);
+ if (event->type() == QEvent::DragEnter) {
+ if (translatedEvent.isAccepted()) {
+ grabber->grab(item);
+ accepted = true;
}
- event->setDropItem(enterEvent.dropItem());
- event->setGrabItem(item);
} else {
- return false;
+ accepted = true;
}
}
+ } else if (itemPrivate->flags & QSGItem::ItemClipsChildrenToShape) {
+ return false;
+ }
- q->sendEvent(item, event);
- if (event->isAccepted()) {
- event->setGrabItem(item);
+ QDragEnterEvent enterEvent(
+ event->pos(),
+ event->possibleActions(),
+ event->mimeData(),
+ event->mouseButtons(),
+ event->keyboardModifiers());
+ QSGDropEventEx::copyActions(&enterEvent, *event);
+ QList<QSGItem *> children = itemPrivate->paintOrderChildItems();
+ for (int ii = children.count() - 1; ii >= 0; --ii) {
+ if (deliverDragEvent(grabber, children.at(ii), &enterEvent))
return true;
- }
- event->setAccepted(true);
}
- return false;
+ return accepted;
}
bool QSGCanvasPrivate::sendFilteredMouseEvent(QSGItem *target, QSGItem *item, QMouseEvent *event)
@@ -1392,14 +1494,14 @@ bool QSGCanvasPrivate::sendFilteredMouseEvent(QSGItem *target, QSGItem *item, QM
if (!target)
return false;
- if (sendFilteredMouseEvent(target->parentItem(), item, event))
- return true;
-
QSGItemPrivate *targetPrivate = QSGItemPrivate::get(target);
if (targetPrivate->filtersChildMouseEvents)
if (target->childMouseEventFilter(item, event))
return true;
+ if (sendFilteredMouseEvent(target->parentItem(), item, event))
+ return true;
+
return false;
}
@@ -1440,7 +1542,7 @@ bool QSGCanvas::sendEvent(QSGItem *item, QEvent *e)
case QEvent::MouseButtonRelease:
case QEvent::MouseButtonDblClick:
case QEvent::MouseMove:
- // XXX todo - should sendEvent be doing this? how does it relate to forwarded events?
+ // XXX todo - should sendEvent be doing this? how does it relate to forwarded events?
{
QMouseEvent *se = static_cast<QMouseEvent *>(e);
if (!d->sendFilteredMouseEvent(item->parentItem(), item, se)) {
@@ -1462,11 +1564,11 @@ bool QSGCanvas::sendEvent(QSGItem *item, QEvent *e)
case QEvent::TouchEnd:
QSGItemPrivate::get(item)->deliverTouchEvent(static_cast<QTouchEvent *>(e));
break;
- case QSGEvent::SGDragEnter:
- case QSGEvent::SGDragExit:
- case QSGEvent::SGDragMove:
- case QSGEvent::SGDragDrop:
- QSGItemPrivate::get(item)->deliverDragEvent(static_cast<QSGDragEvent *>(e));
+ case QEvent::DragEnter:
+ case QEvent::DragMove:
+ case QEvent::DragLeave:
+ case QEvent::Drop:
+ QSGItemPrivate::get(item)->deliverDragEvent(e);
break;
default:
break;
@@ -1826,16 +1928,30 @@ QImage QSGCanvas::grabFrameBuffer()
return d->thread ? d->thread->grab() : QImage();
}
+/*!
+ Returns an incubation controller that splices incubation between frames
+ for this canvas. QSGView automatically installs this controller for you.
+
+ The controller is owned by the canvas and will be destroyed when the canvas
+ is deleted.
+*/
+QDeclarativeIncubationController *QSGCanvas::incubationController() const
+{
+ Q_D(const QSGCanvas);
+
+ if (!d->incubationController)
+ d->incubationController = new QSGCanvasIncubationController(const_cast<QSGCanvasPrivate *>(d));
+ return d->incubationController;
+}
void QSGCanvasRenderLoop::createGLContext()
{
gl = new QOpenGLContext();
- gl->setFormat(renderer->format());
+ gl->setFormat(renderer->requestedFormat());
gl->create();
}
-
void QSGCanvasRenderThread::run()
{
#ifdef THREAD_DEBUG
@@ -1874,6 +1990,7 @@ void QSGCanvasRenderThread::run()
#ifdef THREAD_DEBUG
printf(" RenderThread: aquired sync lock...\n");
#endif
+ allowMainThreadProcessingFlag = false;
QCoreApplication::postEvent(this, new QEvent(QEvent::User));
#ifdef THREAD_DEBUG
printf(" RenderThread: going to sleep...\n");
@@ -1886,24 +2003,35 @@ void QSGCanvasRenderThread::run()
#ifdef THREAD_DEBUG
printf(" RenderThread: Doing locked sync\n");
#endif
+#ifdef QSG_CANVAS_TIMING
+ if (qsg_canvas_timing)
+ threadTimer.start();
+#endif
inSync = true;
syncSceneGraph();
inSync = false;
// Wake GUI after sync to let it continue animating and event processing.
+ allowMainThreadProcessingFlag = true;
wake();
unlock();
#ifdef THREAD_DEBUG
printf(" RenderThread: sync done\n");
#endif
-
-
+#ifdef QSG_CANVAS_TIMING
+ if (qsg_canvas_timing)
+ syncTime = threadTimer.elapsed();
+#endif
#ifdef THREAD_DEBUG
printf(" RenderThread: rendering... %d x %d\n", windowSize.width(), windowSize.height());
#endif
renderSceneGraph(windowSize);
+#ifdef QSG_CANVAS_TIMING
+ if (qsg_canvas_timing)
+ renderTime = threadTimer.elapsed() - syncTime;
+#endif
// The content of the target buffer is undefined after swap() so grab needs
// to happen before swap();
@@ -1923,6 +2051,14 @@ void QSGCanvasRenderThread::run()
#ifdef THREAD_DEBUG
printf(" RenderThread: swap complete...\n");
#endif
+#ifdef QSG_CANVAS_TIMING
+ if (qsg_canvas_timing) {
+ swapTime = threadTimer.elapsed() - renderTime;
+ qDebug() << "- Breakdown of frame time: sync:" << syncTime
+ << "ms render:" << renderTime << "ms swap:" << swapTime
+ << "ms total:" << swapTime + renderTime << "ms";
+ }
+#endif
lock();
isPaintCompleted = true;
@@ -2260,4 +2396,4 @@ void QSGCanvasRenderThread::maybeUpdate()
#include "moc_qsgcanvas.cpp"
-QT_END_NAMESPACE
+QT_END_NAMESPACE \ No newline at end of file
diff --git a/src/declarative/items/qsgcanvas.h b/src/declarative/items/qsgcanvas.h
index a2bb278c0a..094fe40553 100644
--- a/src/declarative/items/qsgcanvas.h
+++ b/src/declarative/items/qsgcanvas.h
@@ -56,6 +56,7 @@ class QSGItem;
class QSGEngine;
class QSGCanvasPrivate;
class QOpenGLFramebufferObject;
+class QDeclarativeIncubationController;
class Q_DECLARATIVE_EXPORT QSGCanvas : public QWindow
{
@@ -85,6 +86,8 @@ public:
void setRenderTarget(QOpenGLFramebufferObject *fbo);
QOpenGLFramebufferObject *renderTarget() const;
+ QDeclarativeIncubationController *incubationController() const;
+
Q_SIGNALS:
void frameSwapped();
void sceneGraphInitialized();
diff --git a/src/declarative/items/qsgcanvas_p.h b/src/declarative/items/qsgcanvas_p.h
index 67f399e4e4..042b3824cd 100644
--- a/src/declarative/items/qsgcanvas_p.h
+++ b/src/declarative/items/qsgcanvas_p.h
@@ -55,10 +55,10 @@
#include "qsgitem.h"
#include "qsgcanvas.h"
-#include "qsgevent.h"
#include <private/qdeclarativeguard_p.h>
#include <private/qsgcontext_p.h>
+#include <private/qsgdrag_p.h>
#include <QtCore/qthread.h>
#include <QtCore/qmutex.h>
@@ -84,6 +84,7 @@ class QSGCanvasPrivate;
class QTouchEvent;
class QSGCanvasRenderLoop;
+class QSGCanvasIncubationController;
class QSGCanvasPrivate : public QWindowPrivate
{
@@ -101,6 +102,7 @@ public:
QSGItem *activeFocusItem;
QSGItem *mouseGrabberItem;
+ QSGDragGrabber dragGrabber;
// Mouse positions are saved in widget coordinates
QPointF lastMousePosition;
@@ -117,8 +119,8 @@ public:
bool sendHoverEvent(QEvent::Type, QSGItem *, const QPointF &scenePos, const QPointF &lastScenePos,
Qt::KeyboardModifiers modifiers, bool accepted);
bool clearHover();
- void deliverDragEvent(QSGDragEvent *);
- bool deliverDragEvent(QSGItem *item, QSGDragEvent *);
+ void deliverDragEvent(QSGDragGrabber *, QEvent *);
+ bool deliverDragEvent(QSGDragGrabber *, QSGItem *, QDragMoveEvent *);
QList<QSGItem*> hoverItems;
enum FocusOption {
@@ -167,6 +169,8 @@ public:
QOpenGLFramebufferObject *renderTarget;
QHash<int, QSGItem *> itemForTouchPointId;
+
+ mutable QSGCanvasIncubationController *incubationController;
};
class QSGCanvasRenderLoop
@@ -196,6 +200,7 @@ public:
virtual void animationStarted() = 0;
virtual void animationStopped() = 0;
virtual void moveContextToThread(QSGContext *) { }
+ virtual bool *allowMainThreadProcessing() { return 0; }
protected:
void initializeSceneGraph() { d->initializeSceneGraph(); }
@@ -226,6 +231,7 @@ class QSGCanvasRenderThread : public QThread, public QSGCanvasRenderLoop
public:
QSGCanvasRenderThread()
: mutex(QMutex::NonRecursive)
+ , allowMainThreadProcessingFlag(true)
, animationRunning(false)
, isGuiBlocked(0)
, isPaintCompleted(false)
@@ -258,6 +264,7 @@ public:
void setWindowSize(const QSize &size) { windowSize = size; }
void maybeUpdate();
void moveContextToThread(QSGContext *c) { c->moveToThread(this); }
+ bool *allowMainThreadProcessing() { return &allowMainThreadProcessingFlag; }
bool event(QEvent *);
@@ -271,6 +278,8 @@ public:
QMutex mutex;
QWaitCondition condition;
+ bool allowMainThreadProcessingFlag;
+
QSize windowSize;
QSize renderedSize;
@@ -292,7 +301,6 @@ public:
void run();
};
-
Q_DECLARE_OPERATORS_FOR_FLAGS(QSGCanvasPrivate::FocusOptions)
QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgdrag.cpp b/src/declarative/items/qsgdrag.cpp
new file mode 100644
index 0000000000..b95e495477
--- /dev/null
+++ b/src/declarative/items/qsgdrag.cpp
@@ -0,0 +1,462 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsgdrag_p.h"
+
+#include <private/qsgitem_p.h>
+#include <private/qsgevents_p_p.h>
+#include <private/qsgitemchangelistener_p.h>
+#include <private/qv8engine_p.h>
+
+#include <QtGui/qevent.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGDragAttachedPrivate : public QObjectPrivate, public QSGItemChangeListener
+{
+ Q_DECLARE_PUBLIC(QSGDragAttached)
+public:
+ static QSGDragAttachedPrivate *get(QSGDragAttached *attached) {
+ return static_cast<QSGDragAttachedPrivate *>(QObjectPrivate::get(attached)); }
+
+ QSGDragAttachedPrivate()
+ : attachedItem(0)
+ , mimeData(0)
+ , proposedAction(Qt::MoveAction)
+ , supportedActions(Qt::MoveAction | Qt::CopyAction | Qt::LinkAction)
+ , active(false)
+ , listening(false)
+ {
+ }
+
+ void itemGeometryChanged(QSGItem *, const QRectF &, const QRectF &);
+ void start() { start(supportedActions); }
+ void start(Qt::DropActions supportedActions);
+ void setTarget(QSGItem *item);
+
+ QSGDragGrabber dragGrabber;
+
+ QDeclarativeGuard<QObject> source;
+ QDeclarativeGuard<QObject> target;
+ QSGItem *attachedItem;
+ QSGDragMimeData *mimeData;
+ Qt::DropAction proposedAction;
+ Qt::DropActions supportedActions;
+ bool active : 1;
+ bool listening : 1;
+ QPointF hotSpot;
+ QStringList keys;
+};
+
+/*!
+ \qmlclass Drag QSGDrag
+ \inqmlmodule QtQuick 2
+ \brief The Drag attached property provides drag and drop events for moved Items.
+
+ Using the Drag attached property any Item can made a source of drag and drop
+ events within a scene.
+
+ When a drag is \l active on an item any change in that items position will
+ generate a drag events that will be sent to any DropArea that intersects
+ the with new position of the item. Other items which implement drag and
+ drop event handlers can also receive these events.
+
+ The following snippet shows how an item can be dragged with a MouseArea.
+ However, dragging is not limited to mouse drags, anything that can move an item
+ can generate drag events, this can include touch events, animations and bindings.
+
+ \snippet doc/src/snippets/declarative/drag.qml 0
+
+ A drag can be terminated either by cancelling it with Drag.cancel() or setting
+ Drag.active to false, or it can be terminated with a drop event by calling
+ Drag.drop(). If the drop event is accepted Drag.drop() will return the
+ \l {supportedActions}{drop action} chosen by the recipient of the event,
+ otherwise it will return Qt.IgnoreAction.
+
+*/
+
+void QSGDragAttachedPrivate::itemGeometryChanged(QSGItem *, const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ Q_Q(QSGDragAttached);
+ if (newGeometry.topLeft() == oldGeometry.topLeft() || !active)
+ return;
+
+ if (QSGCanvas *canvas = attachedItem->canvas()) {
+ QPoint scenePos = attachedItem->mapToScene(hotSpot).toPoint();
+ QDragMoveEvent event(scenePos, mimeData->m_supportedActions, mimeData, Qt::NoButton, Qt::NoModifier);
+ QSGDropEventEx::setProposedAction(&event, proposedAction);
+ QSGCanvasPrivate::get(canvas)->deliverDragEvent(&dragGrabber, &event);
+ if (target != dragGrabber.target()) {
+ target = dragGrabber.target();
+ emit q->targetChanged();
+ }
+ }
+}
+
+QSGDragAttached::QSGDragAttached(QObject *parent)
+ : QObject(*new QSGDragAttachedPrivate, parent)
+{
+ Q_D(QSGDragAttached);
+ d->attachedItem = qobject_cast<QSGItem *>(parent);
+ d->source = d->attachedItem;
+}
+
+QSGDragAttached::~QSGDragAttached()
+{
+ Q_D(QSGDragAttached);
+ delete d->mimeData;
+}
+
+/*!
+ \qmlattachedproperty bool QtQuick2::Drag::active
+
+ This property holds whether a drag event sequence is currently active.
+
+ Setting this property to true will send a QDragEnter event to the scene
+ with the item's current position. Setting it to false will send a
+ QDragLeave event.
+
+ While a drag is active any change in an item's position will send a QDragMove
+ event with item's new position to the scene.
+*/
+
+bool QSGDragAttached::isActive() const
+{
+ Q_D(const QSGDragAttached);
+ return d->active;
+}
+
+void QSGDragAttached::setActive(bool active)
+{
+ Q_D(QSGDragAttached);
+ if (d->active != active) {
+ if (active)
+ d->start(d->supportedActions);
+ else
+ cancel();
+ }
+}
+
+/*!
+ \qmlattachedproperty Object QtQuick2::Drag::source
+
+ This property holds an object that is identified to recipients of drag events as
+ the source of the events. By default this is the item Drag property is attached to.
+
+ Changes to source while a Drag is active don't take effect until a new drag is started.
+*/
+
+QObject *QSGDragAttached::source() const
+{
+ Q_D(const QSGDragAttached);
+ return d->source;
+}
+
+void QSGDragAttached::setSource(QObject *item)
+{
+ Q_D(QSGDragAttached);
+ if (d->source != item) {
+ d->source = item;
+ emit sourceChanged();
+ }
+}
+
+void QSGDragAttached::resetSource()
+{
+ Q_D(QSGDragAttached);
+ if (d->source != d->attachedItem) {
+ d->source = d->attachedItem;
+ emit sourceChanged();
+ }
+}
+
+/*!
+ \qmlattachedproperty Object QtQuick2::Drag::target
+
+ While a drag is active this property holds the last object to accept an
+ enter event from the dragged item, if the current drag position doesn't
+ intersect any accepting targets it is null.
+
+ When a drag is not active this property holds the object that accepted
+ the drop event that ended the drag, if no object accepted the drop or
+ the drag was cancelled the target will then be null.
+*/
+
+QObject *QSGDragAttached::target() const
+{
+ Q_D(const QSGDragAttached);
+ return d->target;
+}
+
+/*!
+ \qmlattachedproperty QPointF QtQuick2::Drag::hotSpot
+
+ This property holds the drag position relative to the top left of the item.
+
+ By default this is (0, 0).
+
+ Changes to hotSpot will take effect when the next event is sent.
+*/
+
+QPointF QSGDragAttached::hotSpot() const
+{
+ Q_D(const QSGDragAttached);
+ return d->hotSpot;
+}
+
+void QSGDragAttached::setHotSpot(const QPointF &hotSpot)
+{
+ Q_D(QSGDragAttached);
+ if (d->hotSpot != hotSpot) {
+ d->hotSpot = hotSpot;
+ emit hotSpotChanged();
+ // Send a move event if active?
+ }
+}
+
+/*!
+ \qmlattachedproperty stringlist QtQuick2::Drag::keys
+
+ This property holds a list of keys that can be used by a DropArea to filter drag events.
+
+ Changes to keys while a Drag is active don't take effect until a new drag is started.
+*/
+
+QStringList QSGDragAttached::keys() const
+{
+ Q_D(const QSGDragAttached);
+ return d->keys;
+}
+
+void QSGDragAttached::setKeys(const QStringList &keys)
+{
+ Q_D(QSGDragAttached);
+ if (d->keys != keys) {
+ d->keys = keys;
+ emit keysChanged();
+ }
+}
+
+/*!
+ \qmlattachedproperty flags QtQuick2::Drag::supportedActions
+
+ This property holds return values of Drag.drop() supported by the drag source.
+
+ Changes to supportedActions while a Drag is active don't take effect
+ until a new drag is started.
+*/
+
+Qt::DropActions QSGDragAttached::supportedActions() const
+{
+ Q_D(const QSGDragAttached);
+ return d->supportedActions;
+}
+
+void QSGDragAttached::setSupportedActions(Qt::DropActions actions)
+{
+ Q_D(QSGDragAttached);
+ if (d->supportedActions != actions) {
+ d->supportedActions = actions;
+ emit supportedActionsChanged();
+ }
+}
+
+/*!
+ \qmlattachedproperty enumeration QtQuick2::Drag::proposedAction
+
+ This property holds an action that is recommended by the drag source as a
+ return value from Drag.drop().
+
+ Changes to proposedAction will take effect when the next event is sent.
+*/
+
+Qt::DropAction QSGDragAttached::proposedAction() const
+{
+ Q_D(const QSGDragAttached);
+ return d->proposedAction;
+}
+
+void QSGDragAttached::setProposedAction(Qt::DropAction action)
+{
+ Q_D(QSGDragAttached);
+ if (d->proposedAction != action) {
+ d->proposedAction = action;
+ emit proposedActionChanged();
+ // send a move event with the new default action if active?
+ }
+}
+
+void QSGDragAttachedPrivate::start(Qt::DropActions supportedActions)
+{
+ Q_Q(QSGDragAttached);
+ Q_ASSERT(!active);
+
+ if (QSGCanvas *canvas = attachedItem ? attachedItem->canvas() : 0) {
+ if (!mimeData)
+ mimeData = new QSGDragMimeData;
+ if (!listening) {
+ QSGItemPrivate::get(attachedItem)->addItemChangeListener(this, QSGItemPrivate::Geometry);
+ listening = true;
+ }
+
+ mimeData->m_source = source;
+ mimeData->m_supportedActions = supportedActions;
+ mimeData->m_keys = keys;
+ active = true;
+
+ QPoint scenePos = attachedItem->mapToScene(hotSpot).toPoint();
+ QDragEnterEvent event(scenePos, supportedActions, mimeData, Qt::NoButton, Qt::NoModifier);
+ QSGDropEventEx::setProposedAction(&event, proposedAction);
+ QSGCanvasPrivate::get(canvas)->deliverDragEvent(&dragGrabber, &event);
+
+ emit q->activeChanged();
+ if (target != dragGrabber.target()) {
+ target = dragGrabber.target();
+ emit q->targetChanged();
+ }
+ }
+}
+
+/*!
+ \qmlattachedmethod void QtQuick2::Drag::start(flags supportedActions)
+
+ Starts sending drag events.
+
+ The optional \a supportedActions argument can be used to override the \l supportedActions
+ property for the started sequence.
+*/
+
+void QSGDragAttached::start(QDeclarativeV8Function *args)
+{
+ Q_D(QSGDragAttached);
+ if (d->active)
+ cancel();
+
+ Qt::DropActions supportedActions = d->supportedActions;
+ // check arguments for supportedActions, maybe data?
+ if (args->Length() >= 1) {
+ v8::Local<v8::Value> v = (*args)[0];
+ if (v->IsInt32())
+ supportedActions = Qt::DropActions(v->Int32Value());
+ }
+
+ d->start(supportedActions);
+}
+
+/*!
+ \qmlattachedmethod enum QtQuick2::Drag::drop()
+
+ Ends a drag sequence by sending a drop event to the target item.
+
+ Returns the action accepted by the target item. If the target item or a parent doesn't accept
+ the drop event then Qt.IgnoreAction will be returned.
+
+ The returned drop action may be one of:
+
+ \list
+ \o Qt.CopyAction Copy the data to the target
+ \o Qt.MoveAction Move the data from the source to the target
+ \o Qt.LinkAction Create a link from the source to the target.
+ \o Qt.IgnoreAction Ignore the action (do nothing with the data).
+ \endlist
+
+*/
+
+int QSGDragAttached::drop()
+{
+ Q_D(QSGDragAttached);
+ Qt::DropAction acceptedAction = Qt::IgnoreAction;
+
+ if (!d->active)
+ return acceptedAction;
+
+ QObject *target = 0;
+
+ if (QSGCanvas *canvas = d->attachedItem->canvas()) {
+ QPoint scenePos = d->attachedItem->mapToScene(d->hotSpot).toPoint();
+
+ QDropEvent event(
+ scenePos, d->mimeData->m_supportedActions, d->mimeData, Qt::NoButton, Qt::NoModifier);
+ QSGDropEventEx::setProposedAction(&event, d->proposedAction);
+ QSGCanvasPrivate::get(canvas)->deliverDragEvent(&d->dragGrabber, &event);
+
+ if (event.isAccepted()) {
+ acceptedAction = event.dropAction();
+ target = d->dragGrabber.target();
+ }
+ }
+
+ d->active = false;
+ if (d->target != target) {
+ d->target = target;
+ emit targetChanged();
+ }
+
+ emit activeChanged();
+ return acceptedAction;
+}
+
+/*!
+ \qmlattachedmethod void QtQuick2::Drag::cancel()
+
+ Ends a drag sequence.
+*/
+
+void QSGDragAttached::cancel()
+{
+ Q_D(QSGDragAttached);
+ if (!d->active)
+ return;
+
+ if (QSGCanvas *canvas = d->attachedItem->canvas()) {
+ QDragLeaveEvent event;
+ QSGCanvasPrivate::get(canvas)->deliverDragEvent(&d->dragGrabber, &event);
+ }
+
+ d->active = false;
+ if (d->target) {
+ d->target = 0;
+ emit targetChanged();
+ }
+ emit activeChanged();
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgdrag_p.h b/src/declarative/items/qsgdrag_p.h
new file mode 100644
index 0000000000..246c6e6beb
--- /dev/null
+++ b/src/declarative/items/qsgdrag_p.h
@@ -0,0 +1,208 @@
+// Commit: c6e6a35aeb8794d68a3ca0c4e27a3a1181c066b5
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSGDRAG_P_H
+#define QSGDRAG_P_H
+
+#include <qsgitem.h>
+
+#include <private/qv8engine_p.h>
+
+#include <QtCore/qmimedata.h>
+#include <QtCore/qstringlist.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QSGItem;
+class QSGDrag;
+class QSGDragPrivate;
+
+class QSGDragGrabber
+{
+ class Item : public QDeclarativeGuard<QSGItem>
+ {
+ public:
+ Item(QSGItem *item) : QDeclarativeGuard<QSGItem>(item) {}
+
+ QIntrusiveListNode node;
+ protected:
+ void objectDestroyed(QSGItem *) { delete this; }
+ };
+
+ typedef QIntrusiveList<Item, &Item::node> ItemList;
+
+public:
+ QSGDragGrabber() : m_target(0) {}
+ ~QSGDragGrabber() { while (!m_items.isEmpty()) delete m_items.first(); }
+
+
+ QObject *target() const
+ {
+ if (m_target)
+ return m_target;
+ else if (!m_items.isEmpty())
+ return *m_items.first();
+ else
+ return 0;
+ }
+ void setTarget(QObject *target) { m_target = target; }
+ void resetTarget() { m_target = 0; }
+
+ typedef ItemList::iterator iterator;
+ iterator begin() { return m_items.begin(); }
+ iterator end() { return m_items.end(); }
+
+ void grab(QSGItem *item) { m_items.insert(new Item(item)); }
+ iterator release(iterator at) { Item *item = *at; at = at.erase(); delete item; return at; }
+
+private:
+
+ ItemList m_items;
+ QObject *m_target;
+};
+
+class QSGDropEventEx : public QDropEvent
+{
+public:
+ void setProposedAction(Qt::DropAction action) { default_action = action; drop_action = action; }
+
+ static void setProposedAction(QDropEvent *event, Qt::DropAction action) {
+ static_cast<QSGDropEventEx *>(event)->setProposedAction(action);
+ }
+
+ void copyActions(const QDropEvent &from) {
+ default_action = from.proposedAction(); drop_action = from.dropAction(); }
+
+ static void copyActions(QDropEvent *to, const QDropEvent &from) {
+ static_cast<QSGDropEventEx *>(to)->copyActions(from);
+ }
+};
+
+class QSGDragMimeData : public QMimeData
+{
+ Q_OBJECT
+public:
+ QSGDragMimeData()
+ : m_source(0)
+ {
+ }
+
+ QStringList keys() const { return m_keys; }
+ QObject *source() const { return m_source; }
+
+private:
+ QObject *m_source;
+ Qt::DropActions m_supportedActions;
+ QStringList m_keys;
+
+ friend class QSGDragAttached;
+ friend class QSGDragAttachedPrivate;
+};
+
+class QDeclarativeV8Function;
+
+class QSGDragAttachedPrivate;
+class QSGDragAttached : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged)
+ Q_PROPERTY(QObject *source READ source WRITE setSource NOTIFY sourceChanged RESET resetSource)
+ Q_PROPERTY(QObject *target READ target NOTIFY targetChanged)
+ Q_PROPERTY(QPointF hotSpot READ hotSpot WRITE setHotSpot NOTIFY hotSpotChanged)
+ Q_PROPERTY(QStringList keys READ keys WRITE setKeys NOTIFY keysChanged)
+ Q_PROPERTY(Qt::DropActions supportedActions READ supportedActions WRITE setSupportedActions NOTIFY supportedActionsChanged)
+ Q_PROPERTY(Qt::DropAction proposedAction READ proposedAction WRITE setProposedAction NOTIFY proposedActionChanged)
+public:
+ QSGDragAttached(QObject *parent);
+ ~QSGDragAttached();
+
+ bool isActive() const;
+ void setActive(bool active);
+
+ QObject *source() const;
+ void setSource(QObject *item);
+ void resetSource();
+
+ QObject *target() const;
+
+ QPointF hotSpot() const;
+ void setHotSpot(const QPointF &hotSpot);
+
+ QStringList keys() const;
+ void setKeys(const QStringList &keys);
+
+ Qt::DropActions supportedActions() const;
+ void setSupportedActions(Qt::DropActions actions);
+
+ Qt::DropAction proposedAction() const;
+ void setProposedAction(Qt::DropAction action);
+
+ Q_INVOKABLE int drop();
+
+public Q_SLOTS:
+ void start(QDeclarativeV8Function *);
+ void cancel();
+
+Q_SIGNALS:
+ void activeChanged();
+ void sourceChanged();
+ void targetChanged();
+ void hotSpotChanged();
+ void keysChanged();
+ void supportedActionsChanged();
+ void proposedActionChanged();
+
+private:
+ Q_DECLARE_PRIVATE(QSGDragAttached)
+};
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/declarative/items/qsgdragtarget.cpp b/src/declarative/items/qsgdragtarget.cpp
deleted file mode 100644
index 9ccc8703d4..0000000000
--- a/src/declarative/items/qsgdragtarget.cpp
+++ /dev/null
@@ -1,361 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgdragtarget_p.h"
-#include "qsgitem_p.h"
-#include "qsgcanvas.h"
-
-/*!
- \qmlclass DragEvent QSGDragEvent
- \brief The DragEvent object provides information about a drag event.
-
- The position of the drag event can be obtained from the \l x and \l
- properties, the \l keys property identifies the drag keys of the event
- source and the \l data property contains the payload of the drag event.
-*/
-
-/*!
- \qmlproperty real DragEvent::x
-
- This property holds the x coordinate of a drag event.
-*/
-
-/*!
- \qmlproperty real DragEvent::y
-
- This property holds the y coordinate of a drag event.
-*/
-
-/*!
- \qmlproperty stringlist DragEvent::keys
-
- This property holds a list of keys identifying the data type or source of a
- drag event.
-*/
-
-/*!
- \qmlproperty variant DragEvent::data
-
- This property holds data payload of a drag event.
-*/
-
-/*!
- \qmlproperty real DragEvent::accepted
-
- This property holds whether the drag event was accepted by a handler.
-
- The default value is true.
-*/
-
-class QSGDragTargetPrivate : public QSGItemPrivate
-{
- Q_DECLARE_PUBLIC(QSGDragTarget)
-
-public:
- QSGDragTargetPrivate();
- ~QSGDragTargetPrivate();
-
- bool hasMatchingKey(const QStringList &keys) const;
-
- QStringList keys;
- QRegExp keyRegExp;
- QVariant dragData;
- QPointF dragPosition;
- QSGItem *dropItem;
- bool containsDrag : 1;
-};
-
-QSGDragTargetPrivate::QSGDragTargetPrivate()
- : dropItem(0)
- , containsDrag(false)
-{
-}
-
-QSGDragTargetPrivate::~QSGDragTargetPrivate()
-{
-}
-
-/*!
- \qmlclass DragTarget QSGDragTarget
- \brief The DragTarget item provides drag and drop handling.
-
- A DragTarget is an invisible item which receives events when another item
- is dragged over it.
-
- A MouseArea item can be used to drag items.
-
- The \l keys property can be used to filter drag events which don't include
- a matching key.
-
- The \l dropItem property is communicated to the source of a drag event as
- the recipient of a drop on the drag target.
-
- The \l delegate property provides a means to specify a component to be
- instantiated for each active drag over a drag target.
-*/
-
-QSGDragTarget::QSGDragTarget(QSGItem *parent)
- : QSGItem(*new QSGDragTargetPrivate, parent)
-{
-}
-
-QSGDragTarget::~QSGDragTarget()
-{
-}
-
-/*!
- \qmlproperty bool DragTarget::containsDrag
-
- This property identifies whether the DragTarget currently contains any
- dragged items.
-*/
-
-bool QSGDragTarget::containsDrag() const
-{
- Q_D(const QSGDragTarget);
- return d->containsDrag;
-}
-
-/*!
- \qmlproperty stringlist DragTarget::keys
-
- This property holds a list of drag keys a DragTarget will accept.
-*/
-
-QStringList QSGDragTarget::keys() const
-{
- Q_D(const QSGDragTarget);
- return d->keys;
-}
-
-void QSGDragTarget::setKeys(const QStringList &keys)
-{
- Q_D(QSGDragTarget);
- if (d->keys != keys) {
- d->keys = keys;
-
- if (keys.isEmpty()) {
- d->keyRegExp = QRegExp();
- } else {
- QString pattern = QLatin1Char('(') + QRegExp::escape(keys.first());
- for (int i = 1; i < keys.count(); ++i)
- pattern += QLatin1Char('|') + QRegExp::escape(keys.at(i));
- pattern += QLatin1Char(')');
- d->keyRegExp = QRegExp(pattern.replace(QLatin1String("\\*"), QLatin1String(".+")));
- }
- emit keysChanged();
- }
-}
-
-/*!
- \qmlproperty Item DragTarget::dropItem
-
- This property identifies an item as the recipient of a drop event within
- a DragTarget.
-
- \sa MouseArea::drag.dropItem
-*/
-
-QSGItem *QSGDragTarget::dropItem() const
-{
- Q_D(const QSGDragTarget);
- return d->dropItem;
-}
-
-void QSGDragTarget::setDropItem(QSGItem *item)
-{
- Q_D(QSGDragTarget);
- if (d->dropItem != item) {
- d->dropItem = item;
- emit dropItemChanged();
- }
-}
-
-void QSGDragTarget::resetDropItem()
-{
- Q_D(QSGDragTarget);
- if (d->dropItem) {
- d->dropItem = 0;
- emit dropItemChanged();
- }
-}
-
-qreal QSGDragTarget::dragX() const
-{
- Q_D(const QSGDragTarget);
- return d->dragPosition.x();
-}
-
-qreal QSGDragTarget::dragY() const
-{
- Q_D(const QSGDragTarget);
- return d->dragPosition.y();
-}
-
-QVariant QSGDragTarget::dragData() const
-{
- Q_D(const QSGDragTarget);
- return d->dragData;
-}
-
-/*!
- \qmlsignal DragTarget::onPositionChanged(DragEvent drag)
- \qmlattachedsignal DragTarget::onPositionChanged(DragEvent drag)
-
- This handler is called when the position of a drag has changed.
-*/
-
-void QSGDragTarget::dragMoveEvent(QSGDragEvent *event)
-{
- Q_D(QSGDragTarget);
- if (!d->containsDrag) {
- event->setAccepted(false);
- return;
- }
-
- event->setDropItem(d->dropItem);
-
- d->dragPosition = event->position();
- emit dragPositionChanged();
-
- QSGDragTargetEvent dragTargetEvent(event);
- emit positionChanged(&dragTargetEvent);
-}
-
-bool QSGDragTargetPrivate::hasMatchingKey(const QStringList &keys) const
-{
- if (keyRegExp.isEmpty())
- return true;
-
- foreach (const QString &key, keys) {
- if (keyRegExp.exactMatch(key))
- return true;
- }
- return false;
-}
-
-/*!
- \qmlsignal DragTarget::onEntered(DragEvent drag)
- \qmlattachedsignal DragTarget::onEntered(DragEvent drag)
-
- This handler is called when a drag enters the bounds of a DragTarget.
-*/
-
-void QSGDragTarget::dragEnterEvent(QSGDragEvent *event)
-{
- Q_D(QSGDragTarget);
- if (!d->effectiveEnable || !d->hasMatchingKey(event->keys()) || d->containsDrag) {
- event->setAccepted(false);
- return;
- }
-
- event->setDropItem(d->dropItem);
-
- QSGDragTargetEvent dragTargetEvent(event);
- emit entered(&dragTargetEvent);
-
- if (event->isAccepted()) {
-
- d->dragData = event->data();
- d->containsDrag = true;
- if (!d->dragData.isNull())
- emit dragDataChanged();
- emit containsDragChanged();
- }
-}
-
-/*!
- \qmlsignal DragTarget::onExited(DragEvent drag)
- \qmlattachedsignal DragTarget::onExited(DragEvent drag)
-
- This handler is called when a drag exits the bounds of a DragTarget.
-*/
-
-void QSGDragTarget::dragExitEvent(QSGDragEvent *event)
-{
- Q_D(QSGDragTarget);
- if (!d->containsDrag) {
- event->setAccepted(false);
- return;
- }
-
- QSGDragTargetEvent dragTargetEvent(event);
- emit exited(&dragTargetEvent);
-
- d->containsDrag = false;
- emit containsDragChanged();
- if (!d->dragData.isNull()) {
- d->dragData = QVariant();
- emit dragDataChanged();
- }
-}
-
-/*!
- \qmlsignal DragTarget::onDropped(DragEvent drag)
- \qmlattachedsignal DragTarget::onDropped(DragEvent drag)
-
- This handler is called when a drop event occurs within the bounds of a
- a DragTarget.
-*/
-
-void QSGDragTarget::dragDropEvent(QSGDragEvent *event)
-{
- Q_D(QSGDragTarget);
- if (!d->containsDrag) {
- event->setAccepted(false);
- return;
- }
-
- event->setDropItem(d->dropItem);
-
- QSGDragTargetEvent dragTargetEvent(event);
- emit dropped(&dragTargetEvent);
-
- d->containsDrag = false;
- emit containsDragChanged();
- if (!d->dragData.isNull()) {
- d->dragData = QVariant();
- emit dragDataChanged();
- }
-}
-
-QT_END_NAMESPACE
-
diff --git a/src/declarative/items/qsgdroparea.cpp b/src/declarative/items/qsgdroparea.cpp
new file mode 100644
index 0000000000..a1b81be1ae
--- /dev/null
+++ b/src/declarative/items/qsgdroparea.cpp
@@ -0,0 +1,426 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsgdroparea_p.h"
+#include "qsgdrag_p.h"
+#include "qsgitem_p.h"
+#include "qsgcanvas.h"
+
+#include <private/qdeclarativeengine_p.h>
+
+QSGDropAreaDrag::QSGDropAreaDrag(QSGDropAreaPrivate *d, QObject *parent)
+ : QObject(parent)
+ , d(d)
+{
+}
+
+QSGDropAreaDrag::~QSGDropAreaDrag()
+{
+}
+
+class QSGDropAreaPrivate : public QSGItemPrivate
+{
+ Q_DECLARE_PUBLIC(QSGDropArea)
+
+public:
+ QSGDropAreaPrivate();
+ ~QSGDropAreaPrivate();
+
+ bool hasMatchingKey(const QStringList &keys) const;
+
+ QStringList getKeys(const QMimeData *mimeData) const;
+
+ QStringList keys;
+ QRegExp keyRegExp;
+ QPointF dragPosition;
+ QSGDropAreaDrag *drag;
+ QDeclarativeGuard<QObject> source;
+ QDeclarativeGuard<QMimeData> mimeData;
+};
+
+QSGDropAreaPrivate::QSGDropAreaPrivate()
+ : drag(0)
+{
+}
+
+QSGDropAreaPrivate::~QSGDropAreaPrivate()
+{
+ delete drag;
+}
+
+/*!
+ \qmlclass DropArea QSGDropArea
+ \inqmlmodule QtQuick 2
+ \brief The DropArea item provides drag and drop handling.
+
+ A DropArea is an invisible item which receives events when other items are
+ dragged over it.
+
+ The Drag attached property can be used to notify the DropArea when an Item is
+ dragged over it.
+
+ The \l keys property can be used to filter drag events which don't include
+ a matching key.
+
+ The \l dropItem property is communicated to the source of a drag event as
+ the recipient of a drop on the drag target.
+
+ The \l delegate property provides a means to specify a component to be
+ instantiated for each active drag over a drag target.
+*/
+
+QSGDropArea::QSGDropArea(QSGItem *parent)
+ : QSGItem(*new QSGDropAreaPrivate, parent)
+{
+ setFlags(ItemAcceptsDrops);
+}
+
+QSGDropArea::~QSGDropArea()
+{
+}
+
+/*!
+ \qmlproperty bool QtQuick2::DropArea::containsDrag
+
+ This property identifies whether the DropArea currently contains any
+ dragged items.
+*/
+
+bool QSGDropArea::containsDrag() const
+{
+ Q_D(const QSGDropArea);
+ return d->mimeData;
+}
+
+/*!
+ \qmlproperty stringlist QtQuick2::DropArea::keys
+
+ This property holds a list of drag keys a DropArea will accept.
+
+ If no keys are listed the DropArea will accept events from any drag source,
+ otherwise the drag source must have at least one compatible key.
+
+ \sa QtQuick2::Drag::keys
+*/
+
+QStringList QSGDropArea::keys() const
+{
+ Q_D(const QSGDropArea);
+ return d->keys;
+}
+
+void QSGDropArea::setKeys(const QStringList &keys)
+{
+ Q_D(QSGDropArea);
+ if (d->keys != keys) {
+ d->keys = keys;
+
+ if (keys.isEmpty()) {
+ d->keyRegExp = QRegExp();
+ } else {
+ QString pattern = QLatin1Char('(') + QRegExp::escape(keys.first());
+ for (int i = 1; i < keys.count(); ++i)
+ pattern += QLatin1Char('|') + QRegExp::escape(keys.at(i));
+ pattern += QLatin1Char(')');
+ d->keyRegExp = QRegExp(pattern.replace(QLatin1String("\\*"), QLatin1String(".+")));
+ }
+ emit keysChanged();
+ }
+}
+
+QSGDropAreaDrag *QSGDropArea::drag()
+{
+ Q_D(QSGDropArea);
+ if (!d->drag)
+ d->drag = new QSGDropAreaDrag(d);
+ return d->drag;
+}
+
+/*!
+ \qmlproperty Object QtQuick2::DropArea::drag.source
+
+ This property holds the source of a drag.
+*/
+
+QObject *QSGDropAreaDrag::source() const
+{
+ return d->source;
+}
+
+/*!
+ \qmlproperty qreal QtQuick2::DropArea::drag.x
+ \qmlproperty qreal QtQuick2::DropArea::drag.y
+
+ These properties hold the coordinates of the last drag event.
+*/
+
+qreal QSGDropAreaDrag::x() const
+{
+ return d->dragPosition.x();
+}
+
+qreal QSGDropAreaDrag::y() const
+{
+ return d->dragPosition.y();
+}
+
+/*!
+ \qmlsignal QtQuick2::DropArea::onPositionChanged(DragEvent drag)
+
+ This handler is called when the position of a drag has changed.
+*/
+
+void QSGDropArea::dragMoveEvent(QDragMoveEvent *event)
+{
+ Q_D(QSGDropArea);
+ if (!d->mimeData)
+ return;
+
+ d->dragPosition = event->pos();
+ if (d->drag)
+ emit d->drag->positionChanged();
+
+ event->accept();
+ QSGDropEvent dragTargetEvent(d, event);
+ emit positionChanged(&dragTargetEvent);
+}
+
+bool QSGDropAreaPrivate::hasMatchingKey(const QStringList &keys) const
+{
+ if (keyRegExp.isEmpty())
+ return true;
+
+ foreach (const QString &key, keys) {
+ if (keyRegExp.exactMatch(key))
+ return true;
+ }
+ return false;
+}
+
+QStringList QSGDropAreaPrivate::getKeys(const QMimeData *mimeData) const
+{
+ if (const QSGDragMimeData *dragMime = qobject_cast<const QSGDragMimeData *>(mimeData))
+ return dragMime->keys();
+ return mimeData->formats();
+}
+
+/*!
+ \qmlsignal QtQuick2::DropArea::onEntered(DragEvent drag)
+
+ This handler is called when a \a drag enters the bounds of a DropArea.
+*/
+
+void QSGDropArea::dragEnterEvent(QDragEnterEvent *event)
+{
+ Q_D(QSGDropArea);
+ const QMimeData *mimeData = event->mimeData();
+ if (!d->effectiveEnable || d->mimeData || !mimeData || !d->hasMatchingKey(d->getKeys(mimeData)))
+ return;
+
+ d->dragPosition = event->pos();
+
+ event->accept();
+ QSGDropEvent dragTargetEvent(d, event);
+ emit entered(&dragTargetEvent);
+
+ if (event->isAccepted()) {
+ d->mimeData = const_cast<QMimeData *>(mimeData);
+ if (QSGDragMimeData *dragMime = qobject_cast<QSGDragMimeData *>(d->mimeData))
+ d->source = dragMime->source();
+ else
+ d->source = event->source();
+ d->dragPosition = event->pos();
+ if (d->drag) {
+ emit d->drag->positionChanged();
+ emit d->drag->sourceChanged();
+ }
+ emit containsDragChanged();
+ }
+}
+
+/*!
+ \qmlsignal QtQuick2::DropArea::onExited()
+
+ This handler is called when a drag exits the bounds of a DropArea.
+*/
+
+void QSGDropArea::dragLeaveEvent(QDragLeaveEvent *)
+{
+ Q_D(QSGDropArea);
+ if (!d->mimeData)
+ return;
+
+ emit exited();
+
+ d->mimeData = 0;
+ d->source = 0;
+ emit containsDragChanged();
+ if (d->drag)
+ emit d->drag->sourceChanged();
+}
+
+/*!
+ \qmlsignal QtQuick2::DropArea::onDropped(DragEvent drop)
+
+ This handler is called when a drop event occurs within the bounds of a
+ a DropArea.
+*/
+
+void QSGDropArea::dropEvent(QDropEvent *event)
+{
+ Q_D(QSGDropArea);
+ if (!d->mimeData)
+ return;
+
+ QSGDropEvent dragTargetEvent(d, event);
+ emit dropped(&dragTargetEvent);
+
+ d->mimeData = 0;
+ d->source = 0;
+ emit containsDragChanged();
+ if (d->drag)
+ emit d->drag->sourceChanged();
+}
+
+/*!
+ \qmlclass DragEvent QSGDragEvent
+ \inqmlmodule QtQuick 2
+ \brief The DragEvent object provides information about a drag event.
+
+ The position of the drag event can be obtained from the \l x and \l y
+ properties, and the \l keys property identifies the drag keys of the event
+ \l source.
+*/
+
+/*!
+ \qmlproperty real QtQuick2::DragEvent::x
+
+ This property holds the x coordinate of a drag event.
+*/
+
+/*!
+ \qmlproperty real QtQuick2::DragEvent::y
+
+ This property holds the y coordinate of a drag event.
+*/
+
+/*!
+ \qmlproperty Object QtQuick2::DragEvent::drag.source
+
+ This property holds the source of a drag event.
+*/
+
+QObject *QSGDropEvent::source()
+{
+ if (const QSGDragMimeData *dragMime = qobject_cast<const QSGDragMimeData *>(event->mimeData()))
+ return dragMime->source();
+ else
+ return event->source();
+}
+
+/*!
+ \qmlproperty stringlist QtQuick2::DragEvent::keys
+
+ This property holds a list of keys identifying the data type or source of a
+ drag event.
+*/
+
+QStringList QSGDropEvent::keys() const
+{
+ return d->getKeys(event->mimeData());
+}
+
+/*!
+ \qmlproperty enum QtQuick2::DragEvent::action
+
+ This property holds the action that the \l source is to perform on an accepted drop.
+
+ The drop action may be one of:
+
+ \list
+ \o Qt.CopyAction Copy the data to the target
+ \o Qt.MoveAction Move the data from the source to the target
+ \o Qt.LinkAction Create a link from the source to the target.
+ \o Qt.IgnoreAction Ignore the action (do nothing with the data).
+ \endlist
+*/
+
+/*!
+ \qmlproperty flags QtQuick2::DragEvent::supportedActions
+
+ This property holds the set of \l {action}{actions} supported by the
+ drag source.
+*/
+
+/*!
+ \qmlproperty real QtQuick2::DragEvent::accepted
+
+ This property holds whether the drag event was accepted by a handler.
+
+ The default value is true.
+*/
+
+/*!
+ \qmlmethod void QtQuick2::DragEvent::accept()
+ \qmlmethod void QtQuick2::DragEvent::accept(enum action)
+
+ Accepts the drag event.
+
+ If an \a action is specified it will overwrite the value of the \l action property.
+*/
+
+void QSGDropEvent::accept(QDeclarativeV8Function *args)
+{
+ Qt::DropAction action = event->dropAction();
+
+ if (args->Length() >= 1) {
+ v8::Local<v8::Value> v = (*args)[0];
+ if (v->IsInt32())
+ action = Qt::DropAction(v->Int32Value());
+ }
+ // get action from arguments.
+ event->setDropAction(action);
+ event->accept();
+}
+
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/items/qsgdragtarget_p.h b/src/declarative/items/qsgdroparea_p.h
index 004bec1f20..cd51f57e0b 100644
--- a/src/declarative/items/qsgdragtarget_p.h
+++ b/src/declarative/items/qsgdroparea_p.h
@@ -39,11 +39,15 @@
**
****************************************************************************/
-#ifndef QSGDRAGTARGET_P_H
-#define QSGDRAGTARGET_P_H
+#ifndef QSGDROPAREA_P_H
+#define QSGDROPAREA_P_H
#include "qsgitem.h"
-#include "qsgevent.h"
+
+#include <private/qdeclarativeguard_p.h>
+#include <private/qv8engine_p.h>
+
+#include <QtGui/qevent.h>
QT_BEGIN_HEADER
@@ -51,44 +55,78 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
-class QSGDragTargetEvent : public QObject
+class QSGDropAreaPrivate;
+class QSGDropEvent : public QObject
{
Q_OBJECT
Q_PROPERTY(qreal x READ x)
Q_PROPERTY(qreal y READ y)
- Q_PROPERTY(QVariant data READ data)
+ Q_PROPERTY(QObject *source READ source)
Q_PROPERTY(QStringList keys READ keys)
+ Q_PROPERTY(Qt::DropActions supportedActions READ supportedActions)
+ Q_PROPERTY(Qt::DropAction action READ action WRITE setAction RESET resetAction)
Q_PROPERTY(bool accepted READ accepted WRITE setAccepted)
public:
- QSGDragTargetEvent(QSGDragEvent *event) : _event(event) {}
+ QSGDropEvent(QSGDropAreaPrivate *d, QDropEvent *event) : d(d), event(event) {}
+
+ qreal x() const { return event->pos().x(); }
+ qreal y() const { return event->pos().y(); }
+
+ QObject *source();
+
+ Qt::DropActions supportedActions() const { return event->possibleActions(); }
+ Qt::DropAction action() const { return event->dropAction(); }
+ void setAction(Qt::DropAction action) { event->setDropAction(action); }
+ void resetAction() { event->setDropAction(event->proposedAction()); }
+
+ QStringList keys() const;
+
+ bool accepted() const { return event->isAccepted(); }
+ void setAccepted(bool accepted) { event->setAccepted(accepted); }
+
+ Q_INVOKABLE void accept(QDeclarativeV8Function *);
- qreal x() const { return _event->x(); }
- qreal y() const { return _event->y(); }
+private:
+ QSGDropAreaPrivate *d;
+ QDropEvent *event;
+};
- QVariant data() const { return _event->data(); }
- QStringList keys() const { return _event->keys(); }
+class QSGDropAreaDrag : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal x READ x NOTIFY positionChanged)
+ Q_PROPERTY(qreal y READ y NOTIFY positionChanged)
+ Q_PROPERTY(QObject *source READ source NOTIFY sourceChanged)
+public:
+ QSGDropAreaDrag(QSGDropAreaPrivate *d, QObject *parent = 0);
+ ~QSGDropAreaDrag();
- bool accepted() const { return _event->isAccepted(); }
- void setAccepted(bool accepted) { _event->setAccepted(accepted); }
+ qreal x() const;
+ qreal y() const;
+ QObject *source() const;
+
+Q_SIGNALS:
+ void positionChanged();
+ void sourceChanged();
private:
- QSGDragEvent *_event;
+ QSGDropAreaPrivate *d;
+
+ friend class QSGDropArea;
+ friend class QSGDropAreaPrivate;
};
-class QSGDragTargetPrivate;
-class Q_AUTOTEST_EXPORT QSGDragTarget : public QSGItem
+class QSGDropAreaPrivate;
+class Q_AUTOTEST_EXPORT QSGDropArea : public QSGItem
{
Q_OBJECT
Q_PROPERTY(bool containsDrag READ containsDrag NOTIFY containsDragChanged)
- Q_PROPERTY(QSGItem *dropItem READ dropItem WRITE setDropItem NOTIFY dropItemChanged RESET resetDropItem)
Q_PROPERTY(QStringList keys READ keys WRITE setKeys NOTIFY keysChanged)
- Q_PROPERTY(qreal dragX READ dragX NOTIFY dragPositionChanged)
- Q_PROPERTY(qreal dragY READ dragY NOTIFY dragPositionChanged)
- Q_PROPERTY(QVariant dragData READ dragData NOTIFY dragDataChanged)
+ Q_PROPERTY(QSGDropAreaDrag *drag READ drag CONSTANT)
public:
- QSGDragTarget(QSGItem *parent=0);
- ~QSGDragTarget();
+ QSGDropArea(QSGItem *parent=0);
+ ~QSGDropArea();
bool containsDrag() const;
void setContainsDrag(bool drag);
@@ -96,41 +134,33 @@ public:
QStringList keys() const;
void setKeys(const QStringList &keys);
- QSGItem *dropItem() const;
- void setDropItem(QSGItem *item);
- void resetDropItem();
-
- qreal dragX() const;
- qreal dragY() const;
- QVariant dragData() const;
+ QSGDropAreaDrag *drag();
Q_SIGNALS:
void containsDragChanged();
void keysChanged();
- void dropItemChanged();
- void dragPositionChanged();
- void dragDataChanged();
+ void sourceChanged();
- void entered(QSGDragTargetEvent *drag);
- void exited(QSGDragTargetEvent *drag);
- void positionChanged(QSGDragTargetEvent *drag);
- void dropped(QSGDragTargetEvent *drag);
+ void entered(QSGDropEvent *drag);
+ void exited();
+ void positionChanged(QSGDropEvent *drag);
+ void dropped(QSGDropEvent *drop);
protected:
- void dragMoveEvent(QSGDragEvent *event);
- void dragEnterEvent(QSGDragEvent *event);
- void dragExitEvent(QSGDragEvent *event);
- void dragDropEvent(QSGDragEvent *event);
+ void dragMoveEvent(QDragMoveEvent *event);
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dragLeaveEvent(QDragLeaveEvent *event);
+ void dropEvent(QDropEvent *event);
private:
- Q_DISABLE_COPY(QSGDragTarget)
- Q_DECLARE_PRIVATE(QSGDragTarget)
+ Q_DISABLE_COPY(QSGDropArea)
+ Q_DECLARE_PRIVATE(QSGDropArea)
};
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QSGDragTargetEvent)
-QML_DECLARE_TYPE(QSGDragTarget)
+QML_DECLARE_TYPE(QSGDropEvent)
+QML_DECLARE_TYPE(QSGDropArea)
QT_END_HEADER
diff --git a/src/declarative/items/qsgevent.h b/src/declarative/items/qsgevent.h
deleted file mode 100644
index d82ee809ae..0000000000
--- a/src/declarative/items/qsgevent.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDRAGEVENT_H
-#define QDRAGEVENT_H
-
-#include <QtCore/qcoreevent.h>
-#include <QtCore/qnamespace.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qvariant.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGItem;
-
-class Q_DECLARATIVE_EXPORT QSGEvent : public QEvent
-{
-public:
- // XXX: Merge types into QEvent or formally reserve a suitable range.
- // Alternatively start from QEvent::User and add a SGUser value for use by items.
- enum SGType
- {
- SGDragEnter = 600,
- SGDragExit,
- SGDragMove,
- SGDragDrop
- };
-
- QSGEvent(QSGEvent::SGType type) : QEvent(Type(type)) {}
-
- SGType type() const { return SGType(QEvent::type()); }
-};
-
-class Q_DECLARATIVE_EXPORT QSGDragEvent : public QSGEvent
-{
-public:
- QSGDragEvent(
- SGType type,
- const QPointF &scenePosition,
- const QVariant &data,
- const QStringList &keys,
- QSGItem *grabItem = 0)
- : QSGEvent(type)
- , _scenePosition(scenePosition),
- _data(data)
- , _keys(keys)
- , _dropItem(0)
- , _grabItem(grabItem)
- {
- }
- QSGDragEvent(SGType type, const QSGDragEvent &event)
- : QSGEvent(type)
- , _scenePosition(event._scenePosition)
- , _position(event._position)
- , _data(event._data)
- , _keys(event._keys)
- , _dropItem(event._dropItem)
- , _grabItem(event._grabItem)
- {
- }
-
- QVariant data() const { return _data; }
-
- qreal x() const { return _position.x(); }
- qreal y() const { return _position.y(); }
- QPointF position() const { return _position; }
- void setPosition(const QPointF &position) { _position = position; }
-
- QPointF scenePosition() const { return _scenePosition; }
-
- QStringList keys() const { return _keys; }
-
- QSGItem *dropItem() const { return _dropItem; }
- void setDropItem(QSGItem *dropItem) { _dropItem = dropItem; }
-
- QSGItem *grabItem() const { return _grabItem; }
- void setGrabItem(QSGItem *item) { _grabItem = item; }
-
-private:
- QPointF _scenePosition;
- QPointF _position;
- QVariant _data;
- QStringList _keys;
- QSGItem *_dropItem;
- QSGItem *_grabItem;
-};
-
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
-
diff --git a/src/declarative/items/qsgevents_p_p.h b/src/declarative/items/qsgevents_p_p.h
index 0aa95c017b..1d2b6a9dec 100644
--- a/src/declarative/items/qsgevents_p_p.h
+++ b/src/declarative/items/qsgevents_p_p.h
@@ -90,7 +90,8 @@ private:
QKeyEvent event;
};
-class QSGMouseEvent : public QObject
+// used in QtLocation
+class Q_DECLARATIVE_EXPORT QSGMouseEvent : public QObject
{
Q_OBJECT
Q_PROPERTY(int x READ x)
diff --git a/src/declarative/items/qsgflickable.cpp b/src/declarative/items/qsgflickable.cpp
index 36d7db217c..4871a43e8d 100644
--- a/src/declarative/items/qsgflickable.cpp
+++ b/src/declarative/items/qsgflickable.cpp
@@ -171,9 +171,7 @@ QSGFlickablePrivate::QSGFlickablePrivate()
: contentItem(new QSGItem)
, hData(this, &QSGFlickablePrivate::setViewportX)
, vData(this, &QSGFlickablePrivate::setViewportY)
- , flickingHorizontally(false), flickingVertically(false)
, hMoved(false), vMoved(false)
- , movingHorizontally(false), movingVertically(false)
, stealMouse(false), pressed(false), interactive(true), calcVelocity(false)
, pixelAligned(false)
, deceleration(QML_FLICK_DEFAULTDECELERATION)
@@ -190,20 +188,8 @@ void QSGFlickablePrivate::init()
Q_Q(QSGFlickable);
QDeclarative_setParent_noEvent(contentItem, q);
contentItem->setParentItem(q);
- static int timelineUpdatedIdx = -1;
- static int timelineCompletedIdx = -1;
- static int flickableTickedIdx = -1;
- static int flickableMovementEndingIdx = -1;
- if (timelineUpdatedIdx == -1) {
- timelineUpdatedIdx = QDeclarativeTimeLine::staticMetaObject.indexOfSignal("updated()");
- timelineCompletedIdx = QDeclarativeTimeLine::staticMetaObject.indexOfSignal("completed()");
- flickableTickedIdx = QSGFlickable::staticMetaObject.indexOfSlot("ticked()");
- flickableMovementEndingIdx = QSGFlickable::staticMetaObject.indexOfSlot("movementEnding()");
- }
- QMetaObject::connect(&timeline, timelineUpdatedIdx,
- q, flickableTickedIdx, Qt::DirectConnection);
- QMetaObject::connect(&timeline, timelineCompletedIdx,
- q, flickableMovementEndingIdx, Qt::DirectConnection);
+ FAST_CONNECT(&timeline, SIGNAL(updated()), q, SLOT(ticked()))
+ FAST_CONNECT(&timeline, SIGNAL(completed()), q, SLOT(movementEnding()))
q->setAcceptedMouseButtons(Qt::LeftButton);
q->setFiltersChildMouseEvents(true);
QSGItemPrivate *viewportPrivate = QSGItemPrivate::get(contentItem);
@@ -298,18 +284,18 @@ void QSGFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent
else
timeline.accel(data.move, v, deceleration, maxDistance);
timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this));
- if (!flickingHorizontally && q->xflick()) {
- flickingHorizontally = true;
+ if (!hData.flicking && q->xflick()) {
+ hData.flicking = true;
emit q->flickingChanged();
emit q->flickingHorizontallyChanged();
- if (!flickingVertically)
+ if (!vData.flicking)
emit q->flickStarted();
}
- if (!flickingVertically && q->yflick()) {
- flickingVertically = true;
+ if (!vData.flicking && q->yflick()) {
+ vData.flicking = true;
emit q->flickingChanged();
emit q->flickingVerticallyChanged();
- if (!flickingHorizontally)
+ if (!hData.flicking)
emit q->flickStarted();
}
} else {
@@ -423,6 +409,16 @@ void QSGFlickablePrivate::updateBeginningEnd()
atBoundaryChange = true;
}
+ if (vData.extentsChanged) {
+ vData.extentsChanged = false;
+ emit q->yOriginChanged();
+ }
+
+ if (hData.extentsChanged) {
+ hData.extentsChanged = false;
+ emit q->xOriginChanged();
+ }
+
if (atBoundaryChange)
emit q->isAtBoundaryChanged();
@@ -594,6 +590,7 @@ qreal QSGFlickable::contentX() const
void QSGFlickable::setContentX(qreal pos)
{
Q_D(QSGFlickable);
+ d->hData.explicitValue = true;
d->timeline.reset(d->hData.move);
d->vTime = d->timeline.time();
movementXEnding();
@@ -612,6 +609,7 @@ qreal QSGFlickable::contentY() const
void QSGFlickable::setContentY(qreal pos)
{
Q_D(QSGFlickable);
+ d->vData.explicitValue = true;
d->timeline.reset(d->vData.move);
d->vTime = d->timeline.time();
movementYEnding();
@@ -645,11 +643,11 @@ void QSGFlickable::setInteractive(bool interactive)
Q_D(QSGFlickable);
if (interactive != d->interactive) {
d->interactive = interactive;
- if (!interactive && (d->flickingHorizontally || d->flickingVertically)) {
+ if (!interactive && (d->hData.flicking || d->vData.flicking)) {
d->timeline.clear();
d->vTime = d->timeline.time();
- d->flickingHorizontally = false;
- d->flickingVertically = false;
+ d->hData.flicking = false;
+ d->vData.flicking = false;
emit flickingChanged();
emit flickingHorizontallyChanged();
emit flickingVerticallyChanged();
@@ -819,8 +817,8 @@ void QSGFlickablePrivate::handleMousePressEvent(QMouseEvent *event)
pressPos = event->localPos();
hData.pressPos = hData.move.value();
vData.pressPos = vData.move.value();
- flickingHorizontally = false;
- flickingVertically = false;
+ hData.flicking = false;
+ vData.flicking = false;
QSGItemPrivate::start(pressTime);
QSGItemPrivate::start(velocityTime);
}
@@ -944,13 +942,10 @@ void QSGFlickablePrivate::handleMouseReleaseEvent(QMouseEvent *event)
pressed = false;
// if we drag then pause before release we should not cause a flick.
- if (QSGItemPrivate::elapsed(lastPosTime) < 100) {
- vData.updateVelocity();
- hData.updateVelocity();
- } else {
- hData.velocity = 0.0;
- vData.velocity = 0.0;
- }
+ qint64 elapsed = QSGItemPrivate::elapsed(lastPosTime);
+
+ vData.updateVelocity();
+ hData.updateVelocity();
draggingEnding();
@@ -959,7 +954,7 @@ void QSGFlickablePrivate::handleMouseReleaseEvent(QMouseEvent *event)
vTime = timeline.time();
- qreal velocity = vData.velocity;
+ qreal velocity = elapsed < 100 ? vData.velocity : 0;
if (vData.atBeginning || vData.atEnd)
velocity /= 2;
if (q->yflick() && qAbs(velocity) > MinimumFlickVelocity && qAbs(event->localPos().y() - pressPos.y()) > FlickThreshold) {
@@ -970,7 +965,7 @@ void QSGFlickablePrivate::handleMouseReleaseEvent(QMouseEvent *event)
fixupY();
}
- velocity = hData.velocity;
+ velocity = elapsed < 100 ? hData.velocity : 0;
if (hData.atBeginning || hData.atEnd)
velocity /= 2;
if (q->xflick() && qAbs(velocity) > MinimumFlickVelocity && qAbs(event->localPos().x() - pressPos.x()) > FlickThreshold) {
@@ -1036,9 +1031,9 @@ void QSGFlickable::wheelEvent(QWheelEvent *event)
valid = true;
}
if (valid) {
- d->flickingVertically = false;
+ d->vData.flicking = false;
d->flickY(d->vData.velocity);
- if (d->flickingVertically) {
+ if (d->vData.flicking) {
d->vMoved = true;
movementStarting();
}
@@ -1054,9 +1049,9 @@ void QSGFlickable::wheelEvent(QWheelEvent *event)
valid = true;
}
if (valid) {
- d->flickingHorizontally = false;
+ d->hData.flicking = false;
d->flickX(d->hData.velocity);
- if (d->flickingHorizontally) {
+ if (d->hData.flicking) {
d->hMoved = true;
movementStarting();
}
@@ -1137,23 +1132,37 @@ void QSGFlickable::timerEvent(QTimerEvent *event)
qreal QSGFlickable::minYExtent() const
{
- return 0.0;
+ Q_D(const QSGFlickable);
+ return d->vData.startMargin;
}
qreal QSGFlickable::minXExtent() const
{
- return 0.0;
+ Q_D(const QSGFlickable);
+ return d->hData.startMargin;
}
/* returns -ve */
qreal QSGFlickable::maxXExtent() const
{
- return width() - vWidth();
+ Q_D(const QSGFlickable);
+ return width() - vWidth() - d->hData.endMargin;
}
/* returns -ve */
qreal QSGFlickable::maxYExtent() const
{
- return height() - vHeight();
+ Q_D(const QSGFlickable);
+ return height() - vHeight() - d->vData.endMargin;
+}
+
+void QSGFlickable::componentComplete()
+{
+ Q_D(QSGFlickable);
+ QSGItem::componentComplete();
+ if (!d->hData.explicitValue && d->hData.startMargin != 0.)
+ setContentX(-minXExtent());
+ if (!d->vData.explicitValue && d->vData.startMargin != 0.)
+ setContentY(-minYExtent());
}
void QSGFlickable::viewportMoved()
@@ -1188,7 +1197,7 @@ void QSGFlickable::viewportMoved()
}
}
- if (!d->vData.inOvershoot && !d->vData.fixingUp && d->flickingVertically
+ if (!d->vData.inOvershoot && !d->vData.fixingUp && d->vData.flicking
&& (d->vData.move.value() > minYExtent() || d->vData.move.value() < maxYExtent())
&& qAbs(d->vData.smoothVelocity.value()) > 100) {
// Increase deceleration if we've passed a bound
@@ -1198,7 +1207,7 @@ void QSGFlickable::viewportMoved()
d->timeline.accel(d->vData.move, -d->vData.smoothVelocity.value(), d->deceleration*QML_FLICK_OVERSHOOTFRICTION, maxDistance);
d->timeline.callback(QDeclarativeTimeLineCallback(&d->vData.move, d->fixupY_callback, d));
}
- if (!d->hData.inOvershoot && !d->hData.fixingUp && d->flickingHorizontally
+ if (!d->hData.inOvershoot && !d->hData.fixingUp && d->hData.flicking
&& (d->hData.move.value() > minXExtent() || d->hData.move.value() < maxXExtent())
&& qAbs(d->hData.smoothVelocity.value()) > 100) {
// Increase deceleration if we've passed a bound
@@ -1230,7 +1239,7 @@ void QSGFlickable::geometryChanged(const QRectF &newGeometry,
emit contentWidthChanged();
}
// Make sure that we're entirely in view.
- if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
+ if (!d->pressed && !d->hData.moving && !d->vData.moving) {
d->fixupMode = QSGFlickablePrivate::Immediate;
d->fixupX();
}
@@ -1243,7 +1252,7 @@ void QSGFlickable::geometryChanged(const QRectF &newGeometry,
emit contentHeightChanged();
}
// Make sure that we're entirely in view.
- if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
+ if (!d->pressed && !d->hData.moving && !d->vData.moving) {
d->fixupMode = QSGFlickablePrivate::Immediate;
d->fixupY();
}
@@ -1372,8 +1381,9 @@ void QSGFlickable::setContentWidth(qreal w)
d->contentItem->setWidth(width());
else
d->contentItem->setWidth(w);
+ d->hData.markExtentsDirty();
// Make sure that we're entirely in view.
- if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
+ if (!d->pressed && !d->hData.moving && !d->vData.moving) {
d->fixupMode = QSGFlickablePrivate::Immediate;
d->fixupX();
} else if (!d->pressed && d->hData.fixingUp) {
@@ -1400,8 +1410,9 @@ void QSGFlickable::setContentHeight(qreal h)
d->contentItem->setHeight(height());
else
d->contentItem->setHeight(h);
+ d->vData.markExtentsDirty();
// Make sure that we're entirely in view.
- if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
+ if (!d->pressed && !d->hData.moving && !d->vData.moving) {
d->fixupMode = QSGFlickablePrivate::Immediate;
d->fixupY();
} else if (!d->pressed && d->vData.fixingUp) {
@@ -1413,8 +1424,124 @@ void QSGFlickable::setContentHeight(qreal h)
}
/*!
+ \qmlproperty real QtQuick2::Flickable::topMargin
+ \qmlproperty real QtQuick2::Flickable::leftMargin
+ \qmlproperty real QtQuick2::Flickable::bottomMargin
+ \qmlproperty real QtQuick2::Flickable::rightMargin
+
+ These properties hold the margins around the content. This space is reserved
+ in addition to the contentWidth and contentHeight.
+*/
+
+
+qreal QSGFlickable::topMargin() const
+{
+ Q_D(const QSGFlickable);
+ return d->vData.startMargin;
+}
+
+void QSGFlickable::setTopMargin(qreal m)
+{
+ Q_D(QSGFlickable);
+ if (d->vData.startMargin == m)
+ return;
+ d->vData.startMargin = m;
+ d->vData.markExtentsDirty();
+ if (!d->pressed && !d->hData.moving && !d->vData.moving) {
+ d->fixupMode = QSGFlickablePrivate::Immediate;
+ d->fixupY();
+ }
+ emit topMarginChanged();
+ d->updateBeginningEnd();
+}
+
+qreal QSGFlickable::bottomMargin() const
+{
+ Q_D(const QSGFlickable);
+ return d->vData.endMargin;
+}
+
+void QSGFlickable::setBottomMargin(qreal m)
+{
+ Q_D(QSGFlickable);
+ if (d->vData.endMargin == m)
+ return;
+ d->vData.endMargin = m;
+ d->vData.markExtentsDirty();
+ if (!d->pressed && !d->hData.moving && !d->vData.moving) {
+ d->fixupMode = QSGFlickablePrivate::Immediate;
+ d->fixupY();
+ }
+ emit bottomMarginChanged();
+ d->updateBeginningEnd();
+}
+
+qreal QSGFlickable::leftMargin() const
+{
+ Q_D(const QSGFlickable);
+ return d->hData.startMargin;
+}
+
+void QSGFlickable::setLeftMargin(qreal m)
+{
+ Q_D(QSGFlickable);
+ if (d->hData.startMargin == m)
+ return;
+ d->hData.startMargin = m;
+ d->hData.markExtentsDirty();
+ if (!d->pressed && !d->hData.moving && !d->vData.moving) {
+ d->fixupMode = QSGFlickablePrivate::Immediate;
+ d->fixupX();
+ }
+ emit leftMarginChanged();
+ d->updateBeginningEnd();
+}
+
+qreal QSGFlickable::rightMargin() const
+{
+ Q_D(const QSGFlickable);
+ return d->hData.endMargin;
+}
+
+void QSGFlickable::setRightMargin(qreal m)
+{
+ Q_D(QSGFlickable);
+ if (d->hData.endMargin == m)
+ return;
+ d->hData.endMargin = m;
+ d->hData.markExtentsDirty();
+ if (!d->pressed && !d->hData.moving && !d->vData.moving) {
+ d->fixupMode = QSGFlickablePrivate::Immediate;
+ d->fixupX();
+ }
+ emit rightMarginChanged();
+ d->updateBeginningEnd();
+}
+
+/*!
+ \qmlproperty real QtQuick2::Flickable::xOrigin
+ \qmlproperty real QtQuick2::Flickable::yOrigin
+
+ These properties hold the origin of the content. This is usually (0,0), however
+ ListView and GridView may have an arbitrary origin due to delegate size variation,
+ or item insertion/removal outside the visible region.
+*/
+
+qreal QSGFlickable::yOrigin() const
+{
+ Q_D(const QSGFlickable);
+ return -minYExtent() + d->vData.startMargin;
+}
+
+qreal QSGFlickable::xOrigin() const
+{
+ Q_D(const QSGFlickable);
+ return -minXExtent() + d->hData.startMargin;
+}
+
+
+/*!
\qmlmethod QtQuick2::Flickable::resizeContent(real width, real height, QPointF center)
- \preliminary
Resizes the content to \a width x \a height about \a center.
@@ -1453,7 +1580,6 @@ void QSGFlickable::resizeContent(qreal w, qreal h, QPointF center)
/*!
\qmlmethod QtQuick2::Flickable::returnToBounds()
- \preliminary
Ensures the content is within legal bounds.
@@ -1529,7 +1655,7 @@ bool QSGFlickable::sendMouseEvent(QMouseEvent *event)
mouseEvent.setAccepted(false);
- switch(mouseEvent.type()) {
+ switch (mouseEvent.type()) {
case QEvent::MouseMove:
d->handleMouseMoveEvent(&mouseEvent);
break;
@@ -1645,7 +1771,7 @@ void QSGFlickable::setFlickDeceleration(qreal deceleration)
bool QSGFlickable::isFlicking() const
{
Q_D(const QSGFlickable);
- return d->flickingHorizontally || d->flickingVertically;
+ return d->hData.flicking || d->vData.flicking;
}
/*!
@@ -1659,13 +1785,13 @@ bool QSGFlickable::isFlicking() const
bool QSGFlickable::isFlickingHorizontally() const
{
Q_D(const QSGFlickable);
- return d->flickingHorizontally;
+ return d->hData.flicking;
}
bool QSGFlickable::isFlickingVertically() const
{
Q_D(const QSGFlickable);
- return d->flickingVertically;
+ return d->vData.flicking;
}
/*!
@@ -1772,36 +1898,36 @@ void QSGFlickable::setPressDelay(int delay)
bool QSGFlickable::isMoving() const
{
Q_D(const QSGFlickable);
- return d->movingHorizontally || d->movingVertically;
+ return d->hData.moving || d->vData.moving;
}
bool QSGFlickable::isMovingHorizontally() const
{
Q_D(const QSGFlickable);
- return d->movingHorizontally;
+ return d->hData.moving;
}
bool QSGFlickable::isMovingVertically() const
{
Q_D(const QSGFlickable);
- return d->movingVertically;
+ return d->vData.moving;
}
void QSGFlickable::movementStarting()
{
Q_D(QSGFlickable);
- if (d->hMoved && !d->movingHorizontally) {
- d->movingHorizontally = true;
+ if (d->hMoved && !d->hData.moving) {
+ d->hData.moving = true;
emit movingChanged();
emit movingHorizontallyChanged();
- if (!d->movingVertically)
+ if (!d->vData.moving)
emit movementStarted();
}
- else if (d->vMoved && !d->movingVertically) {
- d->movingVertically = true;
+ else if (d->vMoved && !d->vData.moving) {
+ d->vData.moving = true;
emit movingChanged();
emit movingVerticallyChanged();
- if (!d->movingHorizontally)
+ if (!d->hData.moving)
emit movementStarted();
}
}
@@ -1818,20 +1944,20 @@ void QSGFlickable::movementEnding()
void QSGFlickable::movementXEnding()
{
Q_D(QSGFlickable);
- if (d->flickingHorizontally) {
- d->flickingHorizontally = false;
+ if (d->hData.flicking) {
+ d->hData.flicking = false;
emit flickingChanged();
emit flickingHorizontallyChanged();
- if (!d->flickingVertically)
+ if (!d->vData.flicking)
emit flickEnded();
}
if (!d->pressed && !d->stealMouse) {
- if (d->movingHorizontally) {
- d->movingHorizontally = false;
+ if (d->hData.moving) {
+ d->hData.moving = false;
d->hMoved = false;
emit movingChanged();
emit movingHorizontallyChanged();
- if (!d->movingVertically)
+ if (!d->vData.moving)
emit movementEnded();
}
}
@@ -1841,20 +1967,20 @@ void QSGFlickable::movementXEnding()
void QSGFlickable::movementYEnding()
{
Q_D(QSGFlickable);
- if (d->flickingVertically) {
- d->flickingVertically = false;
+ if (d->vData.flicking) {
+ d->vData.flicking = false;
emit flickingChanged();
emit flickingVerticallyChanged();
- if (!d->flickingHorizontally)
+ if (!d->hData.flicking)
emit flickEnded();
}
if (!d->pressed && !d->stealMouse) {
- if (d->movingVertically) {
- d->movingVertically = false;
+ if (d->vData.moving) {
+ d->vData.moving = false;
d->vMoved = false;
emit movingChanged();
emit movingVerticallyChanged();
- if (!d->movingHorizontally)
+ if (!d->hData.moving)
emit movementEnded();
}
}
diff --git a/src/declarative/items/qsgflickable_p.h b/src/declarative/items/qsgflickable_p.h
index d638b921c5..54581a5932 100644
--- a/src/declarative/items/qsgflickable_p.h
+++ b/src/declarative/items/qsgflickable_p.h
@@ -63,6 +63,14 @@ class Q_AUTOTEST_EXPORT QSGFlickable : public QSGItem
Q_PROPERTY(qreal contentY READ contentY WRITE setContentY NOTIFY contentYChanged)
Q_PROPERTY(QSGItem *contentItem READ contentItem CONSTANT)
+ Q_PROPERTY(qreal topMargin READ topMargin WRITE setTopMargin NOTIFY topMarginChanged)
+ Q_PROPERTY(qreal bottomMargin READ bottomMargin WRITE setBottomMargin NOTIFY bottomMarginChanged)
+ Q_PROPERTY(qreal yOrigin READ yOrigin NOTIFY yOriginChanged)
+
+ Q_PROPERTY(qreal leftMargin READ leftMargin WRITE setLeftMargin NOTIFY leftMarginChanged)
+ Q_PROPERTY(qreal rightMargin READ rightMargin WRITE setRightMargin NOTIFY rightMarginChanged)
+ Q_PROPERTY(qreal xOrigin READ xOrigin NOTIFY xOriginChanged)
+
Q_PROPERTY(qreal horizontalVelocity READ horizontalVelocity NOTIFY horizontalVelocityChanged)
Q_PROPERTY(qreal verticalVelocity READ verticalVelocity NOTIFY verticalVelocityChanged)
@@ -122,6 +130,21 @@ public:
qreal contentY() const;
virtual void setContentY(qreal pos);
+ qreal topMargin() const;
+ void setTopMargin(qreal m);
+
+ qreal bottomMargin() const;
+ void setBottomMargin(qreal m);
+
+ qreal leftMargin() const;
+ void setLeftMargin(qreal m);
+
+ qreal rightMargin() const;
+ void setRightMargin(qreal m);
+
+ virtual qreal yOrigin() const;
+ virtual qreal xOrigin() const;
+
bool isMoving() const;
bool isMovingHorizontally() const;
bool isMovingVertically() const;
@@ -169,6 +192,12 @@ Q_SIGNALS:
void contentHeightChanged();
void contentXChanged();
void contentYChanged();
+ void topMarginChanged();
+ void bottomMarginChanged();
+ void leftMarginChanged();
+ void rightMarginChanged();
+ void yOriginChanged();
+ void xOriginChanged();
void movingChanged();
void movingHorizontallyChanged();
void movingVerticallyChanged();
@@ -219,6 +248,7 @@ protected:
virtual qreal maxYExtent() const;
qreal vWidth() const;
qreal vHeight() const;
+ virtual void componentComplete();
virtual void viewportMoved();
virtual void geometryChanged(const QRectF &newGeometry,
const QRectF &oldGeometry);
diff --git a/src/declarative/items/qsgflickable_p_p.h b/src/declarative/items/qsgflickable_p_p.h
index 21c31060b8..b7a91a072b 100644
--- a/src/declarative/items/qsgflickable_p_p.h
+++ b/src/declarative/items/qsgflickable_p_p.h
@@ -60,6 +60,7 @@
#include <QtDeclarative/qdeclarative.h>
#include <QtCore/qdatetime.h>
+#include "qplatformdefs.h"
#include <private/qdeclarativetimeline_p_p.h>
#include <private/qdeclarativeanimation_p_p.h>
@@ -95,8 +96,11 @@ public:
struct AxisData {
AxisData(QSGFlickablePrivate *fp, void (QSGFlickablePrivate::*func)(qreal))
- : move(fp, func), viewSize(-1), smoothVelocity(fp), atEnd(false), atBeginning(true)
- , fixingUp(false), inOvershoot(false), dragging(false)
+ : move(fp, func), viewSize(-1), startMargin(0), endMargin(0)
+ , smoothVelocity(fp), atEnd(false), atBeginning(true)
+ , fixingUp(false), inOvershoot(false), moving(false), flicking(false)
+ , dragging(false), extentsChanged(false)
+ , explicitValue(false), minExtentDirty(true), maxExtentDirty(true)
{}
void reset() {
@@ -106,6 +110,12 @@ public:
inOvershoot = false;
}
+ void markExtentsDirty() {
+ minExtentDirty = true;
+ maxExtentDirty = true;
+ extentsChanged = true;
+ }
+
void addVelocitySample(qreal v, qreal maxVelocity);
void updateVelocity();
@@ -117,13 +127,21 @@ public:
qreal dragMaxBound;
qreal velocity;
qreal flickTarget;
+ qreal startMargin;
+ qreal endMargin;
QSGFlickablePrivate::Velocity smoothVelocity;
QPODVector<qreal,10> velocityBuffer;
bool atEnd : 1;
bool atBeginning : 1;
bool fixingUp : 1;
bool inOvershoot : 1;
+ bool moving : 1;
+ bool flicking : 1;
bool dragging : 1;
+ bool extentsChanged : 1;
+ bool explicitValue : 1;
+ mutable bool minExtentDirty : 1;
+ mutable bool maxExtentDirty : 1;
};
void flickX(qreal velocity);
@@ -158,12 +176,8 @@ public:
AxisData vData;
QDeclarativeTimeLine timeline;
- bool flickingHorizontally : 1;
- bool flickingVertically : 1;
bool hMoved : 1;
bool vMoved : 1;
- bool movingHorizontally : 1;
- bool movingVertically : 1;
bool stealMouse : 1;
bool pressed : 1;
bool interactive : 1;
diff --git a/src/declarative/items/qsggridview.cpp b/src/declarative/items/qsggridview.cpp
index 61d2213408..87c8447533 100644
--- a/src/declarative/items/qsggridview.cpp
+++ b/src/declarative/items/qsggridview.cpp
@@ -51,9 +51,14 @@
#include <QtCore/qmath.h>
#include <QtCore/qcoreapplication.h>
#include <math.h>
+#include "qplatformdefs.h"
QT_BEGIN_NAMESPACE
+#ifndef QML_FLICK_SNAPONETHRESHOLD
+#define QML_FLICK_SNAPONETHRESHOLD 30
+#endif
+
//----------------------------------------------------------------------------
class FxGridItemSG : public FxViewItem
@@ -168,7 +173,7 @@ public:
virtual void repositionPackageItemAt(QSGItem *item, int index);
virtual void resetItemPosition(FxViewItem *item, FxViewItem *toItem);
virtual void resetFirstItemPosition();
- virtual void moveItemBy(FxViewItem *item, const QList<FxViewItem *> &items, const QList<FxViewItem *> &movedBackwards);
+ virtual void moveItemBy(FxViewItem *item, qreal forwards, qreal backwards);
virtual void createHighlight();
virtual void updateHighlight();
@@ -176,7 +181,7 @@ public:
virtual void setPosition(qreal pos);
virtual void layoutVisibleItems();
- bool applyInsertionChange(const QDeclarativeChangeSet::Insert &, QList<FxViewItem *> *, QList<FxViewItem *>*, FxViewItem *);
+ bool applyInsertionChange(const QDeclarativeChangeSet::Insert &, FxViewItem *, InsertionsResult *);
virtual qreal headerSize() const;
virtual qreal footerSize() const;
@@ -334,9 +339,15 @@ qreal QSGGridViewPrivate::snapPosAt(qreal pos) const
Q_Q(const QSGGridView);
qreal snapPos = 0;
if (!visibleItems.isEmpty()) {
+ qreal highlightStart = highlightRangeStart;
+ if (isRightToLeftTopToBottom())
+ highlightStart = highlightRangeEndValid ? -size() + highlightRangeEnd : -size();
+
+ pos += highlightStart;
pos += rowSize()/2;
snapPos = static_cast<FxGridItemSG*>(visibleItems.first())->rowPos() - visibleIndex / columns * rowSize();
snapPos = pos - fmodf(pos - snapPos, qreal(rowSize()));
+ snapPos -= highlightStart;
qreal maxExtent;
qreal minExtent;
if (isRightToLeftTopToBottom()) {
@@ -571,6 +582,8 @@ void QSGGridViewPrivate::repositionPackageItemAt(QSGItem *item, int index)
void QSGGridViewPrivate::resetItemPosition(FxViewItem *item, FxViewItem *toItem)
{
+ if (item == toItem)
+ return;
FxGridItemSG *toGridItem = static_cast<FxGridItemSG*>(toItem);
static_cast<FxGridItemSG*>(item)->setPosition(toGridItem->colPos(), toGridItem->rowPos());
}
@@ -581,9 +594,10 @@ void QSGGridViewPrivate::resetFirstItemPosition()
item->setPosition(0, 0);
}
-void QSGGridViewPrivate::moveItemBy(FxViewItem *item, const QList<FxViewItem *> &forwards, const QList<FxViewItem *> &backwards)
+void QSGGridViewPrivate::moveItemBy(FxViewItem *item, qreal forwards, qreal backwards)
{
- int moveCount = forwards.count() - backwards.count();
+ int moveCount = (forwards / rowSize()) - (backwards / rowSize());
+
FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(item);
gridItem->setPosition(gridItem->colPos(), gridItem->rowPos() + ((moveCount / columns) * rowSize()));
}
@@ -779,6 +793,7 @@ void QSGGridViewPrivate::itemGeometryChanged(QSGItem *item, const QRectF &newGeo
if (item == q) {
if (newGeometry.height() != oldGeometry.height() || newGeometry.width() != oldGeometry.width()) {
updateViewport();
+ forceLayout = true;
q->polish();
}
}
@@ -801,62 +816,56 @@ void QSGGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
fixupMode = moveReason == Mouse ? fixupMode : Immediate;
- qreal highlightStart;
- qreal highlightEnd;
- qreal viewPos;
- if (isRightToLeftTopToBottom()) {
- // Handle Right-To-Left exceptions
- viewPos = -position()-size();
- highlightStart = highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart;
- highlightEnd = highlightRangeEndValid ? size()-highlightRangeStart : highlightRangeEnd;
- } else {
- viewPos = position();
- highlightStart = highlightRangeStart;
- highlightEnd = highlightRangeEnd;
- }
+ qreal viewPos = isRightToLeftTopToBottom() ? -position()-size() : position();
+ bool strictHighlightRange = haveHighlightRange && highlightRange == QSGGridView::StrictlyEnforceRange;
if (snapMode != QSGGridView::NoSnap) {
qreal tempPosition = isRightToLeftTopToBottom() ? -position()-size() : position();
- FxViewItem *topItem = snapItemAt(tempPosition+highlightStart);
- FxViewItem *bottomItem = snapItemAt(tempPosition+highlightEnd);
+ if (snapMode == QSGGridView::SnapOneRow && moveReason == Mouse) {
+ // if we've been dragged < rowSize()/2 then bias towards the next row
+ qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
+ qreal bias = 0;
+ if (data.velocity > 0 && dist > QML_FLICK_SNAPONETHRESHOLD && dist < rowSize()/2)
+ bias = rowSize()/2;
+ else if (data.velocity < 0 && dist < -QML_FLICK_SNAPONETHRESHOLD && dist > -rowSize()/2)
+ bias = -rowSize()/2;
+ if (isRightToLeftTopToBottom())
+ bias = -bias;
+ tempPosition -= bias;
+ }
+ FxViewItem *topItem = snapItemAt(tempPosition+highlightRangeStart);
+ if (!topItem && strictHighlightRange && currentItem) {
+ // StrictlyEnforceRange always keeps an item in range
+ updateHighlight();
+ topItem = currentItem;
+ }
+ FxViewItem *bottomItem = snapItemAt(tempPosition+highlightRangeEnd);
+ if (!bottomItem && strictHighlightRange && currentItem) {
+ // StrictlyEnforceRange always keeps an item in range
+ updateHighlight();
+ bottomItem = currentItem;
+ }
qreal pos;
- if (topItem && bottomItem && haveHighlightRange && highlightRange == QSGGridView::StrictlyEnforceRange) {
- qreal topPos = qMin(topItem->position() - highlightStart, -maxExtent);
- qreal bottomPos = qMax(bottomItem->position() - highlightEnd, -minExtent);
- pos = qAbs(data.move + topPos) < qAbs(data.move + bottomPos) ? topPos : bottomPos;
- } else if (topItem) {
- qreal headerPos = 0;
- if (header)
- headerPos = isRightToLeftTopToBottom() ? static_cast<FxGridItemSG*>(header)->rowPos() + cellWidth - headerSize() : static_cast<FxGridItemSG*>(header)->rowPos();
- if (topItem->index == 0 && header && tempPosition+highlightStart < headerPos+headerSize()/2) {
- pos = isRightToLeftTopToBottom() ? - headerPos + highlightStart - size() : headerPos - highlightStart;
+ bool isInBounds = -position() > maxExtent && -position() <= minExtent;
+ if (topItem && (isInBounds || strictHighlightRange)) {
+ qreal headerPos = header ? static_cast<FxGridItemSG*>(header)->rowPos() : 0;
+ if (topItem->index == 0 && header && tempPosition+highlightRangeStart < headerPos+headerSize()/2 && !strictHighlightRange) {
+ pos = isRightToLeftTopToBottom() ? - headerPos + highlightRangeStart - size() : headerPos - highlightRangeStart;
} else {
if (isRightToLeftTopToBottom())
- pos = qMax(qMin(-topItem->position() + highlightStart - size(), -maxExtent), -minExtent);
+ pos = qMax(qMin(-topItem->position() + highlightRangeStart - size(), -maxExtent), -minExtent);
else
- pos = qMax(qMin(topItem->position() - highlightStart, -maxExtent), -minExtent);
+ pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent);
}
- } else if (bottomItem) {
+ } else if (bottomItem && isInBounds) {
if (isRightToLeftTopToBottom())
- pos = qMax(qMin(-bottomItem->position() + highlightStart - size(), -maxExtent), -minExtent);
+ pos = qMax(qMin(-bottomItem->position() + highlightRangeEnd - size(), -maxExtent), -minExtent);
else
- pos = qMax(qMin(bottomItem->position() - highlightStart, -maxExtent), -minExtent);
+ pos = qMax(qMin(bottomItem->position() - highlightRangeEnd, -maxExtent), -minExtent);
} else {
QSGItemViewPrivate::fixup(data, minExtent, maxExtent);
return;
}
- if (currentItem && haveHighlightRange && highlightRange == QSGGridView::StrictlyEnforceRange) {
- updateHighlight();
- qreal currPos = static_cast<FxGridItemSG*>(currentItem)->rowPos();
- if (isRightToLeftTopToBottom())
- pos = -pos-size(); // Transform Pos if required
- if (pos < currPos + rowSize() - highlightEnd)
- pos = currPos + rowSize() - highlightEnd;
- if (pos > currPos - highlightStart)
- pos = currPos - highlightStart;
- if (isRightToLeftTopToBottom())
- pos = -pos-size(); // Untransform
- }
qreal dist = qAbs(data.move + pos);
if (dist > 0) {
@@ -873,10 +882,10 @@ void QSGGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
if (currentItem) {
updateHighlight();
qreal pos = static_cast<FxGridItemSG*>(currentItem)->rowPos();
- if (viewPos < pos + rowSize() - highlightEnd)
- viewPos = pos + rowSize() - highlightEnd;
- if (viewPos > pos - highlightStart)
- viewPos = pos - highlightStart;
+ if (viewPos < pos + rowSize() - highlightRangeEnd)
+ viewPos = pos + rowSize() - highlightRangeEnd;
+ if (viewPos > pos - highlightRangeStart)
+ viewPos = pos - highlightRangeStart;
if (isRightToLeftTopToBottom())
viewPos = -viewPos-size();
timeline.reset(data.move);
@@ -914,8 +923,14 @@ void QSGGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent,
if (velocity > 0) {
if (data.move.value() < minExtent) {
if (snapMode == QSGGridView::SnapOneRow) {
- if (FxViewItem *item = firstVisibleItem())
- maxDistance = qAbs(item->position() + dataValue);
+ // if we've been dragged < averageSize/2 then bias towards the next item
+ qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
+ qreal bias = dist < rowSize()/2 ? rowSize()/2 : 0;
+ if (isRightToLeftTopToBottom())
+ bias = -bias;
+ data.flickTarget = -snapPosAt(-dataValue - bias);
+ maxDistance = qAbs(data.flickTarget - data.move.value());
+ velocity = maxVelocity;
} else {
maxDistance = qAbs(minExtent - data.move.value());
}
@@ -925,8 +940,14 @@ void QSGGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent,
} else {
if (data.move.value() > maxExtent) {
if (snapMode == QSGGridView::SnapOneRow) {
- qreal pos = snapPosAt(-dataValue) + (isRightToLeftTopToBottom() ? 0 : rowSize());
- maxDistance = qAbs(pos + dataValue);
+ // if we've been dragged < averageSize/2 then bias towards the next item
+ qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
+ qreal bias = -dist < rowSize()/2 ? rowSize()/2 : 0;
+ if (isRightToLeftTopToBottom())
+ bias = -bias;
+ data.flickTarget = -snapPosAt(-dataValue + bias);
+ maxDistance = qAbs(data.flickTarget - data.move.value());
+ velocity = -maxVelocity;
} else {
maxDistance = qAbs(maxExtent - data.move.value());
}
@@ -935,7 +956,6 @@ void QSGGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent,
data.flickTarget = maxExtent;
}
bool overShoot = boundsBehavior == QSGFlickable::DragAndOvershootBounds;
- qreal highlightStart = isRightToLeftTopToBottom() && highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart;
if (maxDistance > 0 || overShoot) {
// This mode requires the grid to stop exactly on a row boundary.
qreal v = velocity;
@@ -954,9 +974,20 @@ void QSGGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent,
dist = qMin(dist, maxDistance);
if (v > 0)
dist = -dist;
- qreal distTemp = isRightToLeftTopToBottom() ? -dist : dist;
- data.flickTarget = -snapPosAt(-(dataValue - highlightStart) + distTemp) + highlightStart;
+ if (snapMode != QSGGridView::SnapOneRow) {
+ qreal distTemp = isRightToLeftTopToBottom() ? -dist : dist;
+ data.flickTarget = -snapPosAt(-dataValue + distTemp);
+ }
data.flickTarget = isRightToLeftTopToBottom() ? -data.flickTarget+size() : data.flickTarget;
+ if (overShoot) {
+ if (data.flickTarget >= minExtent) {
+ overshootDist = overShootDistance(vSize);
+ data.flickTarget += overshootDist;
+ } else if (data.flickTarget <= maxExtent) {
+ overshootDist = overShootDistance(vSize);
+ data.flickTarget -= overshootDist;
+ }
+ }
qreal adjDist = -data.flickTarget + data.move.value();
if (qAbs(adjDist) > qAbs(dist)) {
// Prevent painfully slow flicking - adjust velocity to suit flickDeceleration
@@ -977,14 +1008,14 @@ void QSGGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent,
timeline.reset(data.move);
timeline.accel(data.move, v, accel, maxDistance + overshootDist);
timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this));
- if (!flickingHorizontally && q->xflick()) {
- flickingHorizontally = true;
+ if (!hData.flicking && q->xflick()) {
+ hData.flicking = true;
emit q->flickingChanged();
emit q->flickingHorizontallyChanged();
emit q->flickStarted();
}
- if (!flickingVertically && q->yflick()) {
- flickingVertically = true;
+ if (!vData.flicking && q->yflick()) {
+ vData.flicking = true;
emit q->flickingChanged();
emit q->flickingVerticallyChanged();
emit q->flickStarted();
@@ -1482,7 +1513,7 @@ void QSGGridView::viewportMoved()
d->inViewportMoved = true;
d->lazyRelease = true;
- if (d->flickingHorizontally || d->flickingVertically) {
+ if (d->hData.flicking || d->vData.flicking) {
if (yflick()) {
if (d->vData.velocity > 0)
d->bufferMode = QSGGridViewPrivate::BufferBefore;
@@ -1498,28 +1529,17 @@ void QSGGridView::viewportMoved()
}
}
d->refill();
- if (d->flickingHorizontally || d->flickingVertically || d->movingHorizontally || d->movingVertically)
+ if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving)
d->moveReason = QSGGridViewPrivate::Mouse;
if (d->moveReason != QSGGridViewPrivate::SetIndex) {
if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) {
// reposition highlight
qreal pos = d->highlight->position();
- qreal viewPos;
- qreal highlightStart;
- qreal highlightEnd;
- if (d->isRightToLeftTopToBottom()) {
- viewPos = -d->position()-d->size();
- highlightStart = d->highlightRangeStartValid ? d->size()-d->highlightRangeEnd : d->highlightRangeStart;
- highlightEnd = d->highlightRangeEndValid ? d->size()-d->highlightRangeStart : d->highlightRangeEnd;
- } else {
- viewPos = d->position();
- highlightStart = d->highlightRangeStart;
- highlightEnd = d->highlightRangeEnd;
- }
- if (pos > viewPos + highlightEnd - d->highlight->size())
- pos = viewPos + highlightEnd - d->highlight->size();
- if (pos < viewPos + highlightStart)
- pos = viewPos + highlightStart;
+ qreal viewPos = d->isRightToLeftTopToBottom() ? -d->position()-d->size() : d->position();
+ if (pos > viewPos + d->highlightRangeEnd - d->highlight->size())
+ pos = viewPos + d->highlightRangeEnd - d->highlight->size();
+ if (pos < viewPos + d->highlightRangeStart)
+ pos = viewPos + d->highlightRangeStart;
if (pos != d->highlight->position()) {
d->highlightXAnimator->stop();
@@ -1719,7 +1739,7 @@ void QSGGridView::moveCurrentIndexRight()
}
}
-bool QSGGridViewPrivate::applyInsertionChange(const QDeclarativeChangeSet::Insert &change, QList<FxViewItem *> *movedBackwards, QList<FxViewItem *> *addedItems, FxViewItem *firstVisible)
+bool QSGGridViewPrivate::applyInsertionChange(const QDeclarativeChangeSet::Insert &change, FxViewItem *firstVisible, InsertionsResult *insertResult)
{
Q_Q(QSGGridView);
@@ -1734,7 +1754,7 @@ bool QSGGridViewPrivate::applyInsertionChange(const QDeclarativeChangeSet::Inser
--i;
if (visibleItems.at(i)->index + 1 == modelIndex) {
// Special case of appending an item to the model.
- index = visibleIndex + visibleItems.count();
+ index = visibleItems.count();
} else {
if (modelIndex <= visibleIndex) {
// Insert before visible items
@@ -1749,19 +1769,10 @@ bool QSGGridViewPrivate::applyInsertionChange(const QDeclarativeChangeSet::Inser
}
}
- int insertCount = count;
- if (index < visibleIndex && visibleItems.count()) {
- insertCount -= visibleIndex - index;
- index = visibleIndex;
- modelIndex = visibleIndex;
- }
-
qreal tempPos = isRightToLeftTopToBottom() ? -position()-size()+q->width()+1 : position();
- int to = buffer+tempPos+size()-1;
int colPos = 0;
int rowPos = 0;
if (visibleItems.count()) {
- index -= visibleIndex;
if (index < visibleItems.count()) {
FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(visibleItems.at(index));
colPos = gridItem->colPos();
@@ -1785,30 +1796,69 @@ bool QSGGridViewPrivate::applyInsertionChange(const QDeclarativeChangeSet::Inser
item->index += count;
}
- int i = 0;
- bool prevAddedCount = addedItems->count();
- while (i < insertCount && rowPos <= to + rowSize()*(columns - (colPos/colSize()))/qreal(columns)) {
- FxViewItem *item = 0;
- if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i)))) {
- if (item->index > modelIndex + i)
- movedBackwards->append(item);
- item->index = modelIndex + i;
+ int prevAddedCount = insertResult->addedItems.count();
+ if (firstVisible && rowPos < firstVisible->position()) {
+ // Insert items before the visible item.
+ int insertionIdx = index;
+ int i = count - 1;
+ int from = tempPos - buffer;
+
+ while (i >= 0) {
+ if (rowPos > from) {
+ insertResult->sizeAddedBeforeVisible += rowSize();
+ } else {
+ FxViewItem *item = 0;
+ if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i)))) {
+ if (item->index > modelIndex + i)
+ insertResult->movedBackwards.append(item);
+ item->index = modelIndex + i;
+ }
+ if (!item)
+ item = createItem(modelIndex + i);
+
+ visibleItems.insert(insertionIdx, item);
+ if (!change.isMove()) {
+ insertResult->addedItems.append(item);
+ insertResult->sizeAddedBeforeVisible += rowSize();
+ }
+ }
+ colPos -= colSize();
+ if (colPos < 0) {
+ colPos = colSize() * (columns - 1);
+ rowPos -= rowSize();
+ }
+ index++;
+ i--;
}
- if (!item)
- item = createItem(modelIndex + i);
- visibleItems.insert(index, item);
- if (!change.isMove())
- addedItems->append(item);
- colPos += colSize();
- if (colPos > colSize() * (columns-1)) {
- colPos = 0;
- rowPos += rowSize();
+ } else {
+ int i = 0;
+ int to = buffer+tempPos+size()-1;
+ while (i < count && rowPos <= to + rowSize()*(columns - (colPos/colSize()))/qreal(columns)) {
+ FxViewItem *item = 0;
+ if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i)))) {
+ if (item->index > modelIndex + i)
+ insertResult->movedBackwards.append(item);
+ item->index = modelIndex + i;
+ }
+ if (!item)
+ item = createItem(modelIndex + i);
+
+ visibleItems.insert(index, item);
+ if (!change.isMove())
+ insertResult->addedItems.append(item);
+ colPos += colSize();
+ if (colPos > colSize() * (columns-1)) {
+ colPos = 0;
+ rowPos += rowSize();
+ }
+ ++index;
+ ++i;
}
- ++index;
- ++i;
}
- return addedItems->count() > prevAddedCount;
+ updateVisibleIndex();
+
+ return insertResult->addedItems.count() > prevAddedCount;
}
/*!
diff --git a/src/declarative/items/qsgimage.cpp b/src/declarative/items/qsgimage.cpp
index 8cf85997cb..9461de4278 100644
--- a/src/declarative/items/qsgimage.cpp
+++ b/src/declarative/items/qsgimage.cpp
@@ -63,6 +63,10 @@ public:
}
QSGTexture *texture() const {
+
+ if (m_texture->isAtlasTexture())
+ const_cast<QSGImageTextureProvider *>(this)->m_texture = m_texture->removedFromAtlas();
+
if (m_texture) {
m_texture->setFiltering(m_smooth ? QSGTexture::Linear : QSGTexture::Nearest);
m_texture->setMipmapFiltering(QSGTexture::Nearest);
@@ -485,7 +489,7 @@ void QSGImage::updatePaintedGeometry()
if (widthScale <= heightScale) {
d->paintedWidth = w;
d->paintedHeight = widthScale * qreal(d->pix.height());
- } else if(heightScale < widthScale) {
+ } else if (heightScale < widthScale) {
d->paintedWidth = heightScale * qreal(d->pix.width());
d->paintedHeight = h;
}
@@ -506,7 +510,7 @@ void QSGImage::updatePaintedGeometry()
qreal heightScale = height() / qreal(d->pix.height());
if (widthScale < heightScale) {
widthScale = heightScale;
- } else if(heightScale < widthScale) {
+ } else if (heightScale < widthScale) {
heightScale = widthScale;
}
@@ -570,7 +574,7 @@ QSGNode *QSGImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
}
QSGImageNode *node = static_cast<QSGImageNode *>(oldNode);
- if (!node) {
+ if (!node) {
d->pixmapChanged = true;
node = d->sceneGraphContext()->createImageNode();
node->setTexture(texture);
@@ -704,6 +708,10 @@ void QSGImage::pixmapChange()
QSGImageBase::pixmapChange();
updatePaintedGeometry();
d->pixmapChanged = true;
+
+ // Make sure we update the texture provider when the image has changed.
+ if (d->provider)
+ update();
}
QSGImage::VAlignment QSGImage::verticalAlignment() const
diff --git a/src/declarative/items/qsgimagebase.cpp b/src/declarative/items/qsgimagebase.cpp
index 5c6334de66..0c08010d34 100644
--- a/src/declarative/items/qsgimagebase.cpp
+++ b/src/declarative/items/qsgimagebase.cpp
@@ -208,6 +208,7 @@ void QSGImageBase::load()
if (d->cache)
options |= QDeclarativePixmap::Cache;
d->pix.clear(this);
+ pixmapChange();
d->pix.load(qmlEngine(this), d->url, d->explicitSourceSize ? sourceSize() : QSize(), options);
if (d->pix.isLoading()) {
diff --git a/src/declarative/items/qsgimplicitsizeitem.cpp b/src/declarative/items/qsgimplicitsizeitem.cpp
index 34890d876a..163b73b39c 100644
--- a/src/declarative/items/qsgimplicitsizeitem.cpp
+++ b/src/declarative/items/qsgimplicitsizeitem.cpp
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#include "private/qsgimplicitsizeitem_p.h"
-#include "private/qsgimplicitsizeitem_p_p.h"
+#include "qsgimplicitsizeitem_p.h"
+#include "qsgimplicitsizeitem_p_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/items/qsgimplicitsizeitem_p_p.h b/src/declarative/items/qsgimplicitsizeitem_p_p.h
index 30631de62c..3ddd69d7d3 100644
--- a/src/declarative/items/qsgimplicitsizeitem_p_p.h
+++ b/src/declarative/items/qsgimplicitsizeitem_p_p.h
@@ -54,9 +54,9 @@
// We mean it.
//
-#include "private/qsgitem_p.h"
-#include "private/qsgpainteditem_p.h"
-#include "private/qsgimplicitsizeitem_p.h"
+#include "qsgitem_p.h"
+#include "qsgpainteditem_p.h"
+#include "qsgimplicitsizeitem_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/items/qsgitem.cpp b/src/declarative/items/qsgitem.cpp
index a1e43171de..bdea19b3e0 100644
--- a/src/declarative/items/qsgitem.cpp
+++ b/src/declarative/items/qsgitem.cpp
@@ -44,7 +44,6 @@
#include "qsgcanvas.h"
#include <QtDeclarative/qjsengine.h>
#include "qsgcanvas_p.h"
-#include "qsgevent.h"
#include "qsgevents_p_p.h"
@@ -605,7 +604,7 @@ void QSGKeyNavigationAttached::setDown(QSGItem *i)
d->downSet = true;
QSGKeyNavigationAttached* other =
qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
- if(other && !other->d_func()->upSet){
+ if (other && !other->d_func()->upSet) {
other->d_func()->up = qobject_cast<QSGItem*>(parent());
emit other->upChanged();
}
@@ -627,7 +626,7 @@ void QSGKeyNavigationAttached::setTab(QSGItem *i)
d->tabSet = true;
QSGKeyNavigationAttached* other =
qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
- if(other && !other->d_func()->backtabSet){
+ if (other && !other->d_func()->backtabSet) {
other->d_func()->backtab = qobject_cast<QSGItem*>(parent());
emit other->backtabChanged();
}
@@ -649,7 +648,7 @@ void QSGKeyNavigationAttached::setBacktab(QSGItem *i)
d->backtabSet = true;
QSGKeyNavigationAttached* other =
qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
- if(other && !other->d_func()->tabSet){
+ if (other && !other->d_func()->tabSet) {
other->d_func()->tab = qobject_cast<QSGItem*>(parent());
emit other->tabChanged();
}
@@ -696,7 +695,7 @@ void QSGKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
}
bool mirror = false;
- switch(event->key()) {
+ switch (event->key()) {
case Qt::Key_Left: {
if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
@@ -759,7 +758,7 @@ void QSGKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
}
bool mirror = false;
- switch(event->key()) {
+ switch (event->key()) {
case Qt::Key_Left:
if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
@@ -2698,7 +2697,7 @@ QSGItemPrivate::AnchorLines *QSGItemPrivate::anchorLines() const
void QSGItemPrivate::siblingOrderChanged()
{
Q_Q(QSGItem);
- for(int ii = 0; ii < changeListeners.count(); ++ii) {
+ for (int ii = 0; ii < changeListeners.count(); ++ii) {
const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
if (change.types & QSGItemPrivate::SiblingOrder) {
change.listener->itemSiblingOrderChanged(q);
@@ -2759,7 +2758,7 @@ void QSGItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeomet
if (d->_anchors)
QSGAnchorsPrivate::get(d->_anchors)->updateMe();
- for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
+ for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
const QSGItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
if (change.types & QSGItemPrivate::Geometry)
change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
@@ -2882,24 +2881,26 @@ void QSGItem::hoverLeaveEvent(QHoverEvent *event)
Q_UNUSED(event);
}
-void QSGItem::dragMoveEvent(QSGDragEvent *event)
+void QSGItem::dragEnterEvent(QDragEnterEvent *event)
{
- event->setAccepted(false);
+ Q_UNUSED(event);
}
-void QSGItem::dragEnterEvent(QSGDragEvent *event)
+void QSGItem::dragMoveEvent(QDragMoveEvent *event)
{
- event->setAccepted(false);
+
+ Q_UNUSED(event);
}
-void QSGItem::dragExitEvent(QSGDragEvent *event)
+void QSGItem::dragLeaveEvent(QDragLeaveEvent *event)
{
- event->setAccepted(false);
+
+ Q_UNUSED(event);
}
-void QSGItem::dragDropEvent(QSGDragEvent *event)
+void QSGItem::dropEvent(QDropEvent *event)
{
- event->setAccepted(false);
+ Q_UNUSED(event);
}
bool QSGItem::childMouseEventFilter(QSGItem *, QEvent *)
@@ -3021,7 +3022,7 @@ void QSGItem::setBaselineOffset(qreal offset)
d->baselineOffset = offset;
- for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
+ for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
const QSGItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
if (change.types & QSGItemPrivate::Geometry) {
QSGAnchorsPrivate *anchor = change.listener->anchorPrivate();
@@ -3244,8 +3245,8 @@ QDeclarativeStateGroup *QSGItemPrivate::_states()
_stateGroup = new QDeclarativeStateGroup;
if (!componentComplete)
_stateGroup->classBegin();
- QObject::connect(_stateGroup, SIGNAL(stateChanged(QString)),
- q, SIGNAL(stateChanged(QString)));
+ FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
+ q, SIGNAL(stateChanged(QString)))
}
return _stateGroup;
@@ -3271,7 +3272,7 @@ QSGItemPrivate::AnchorLines::AnchorLines(QSGItem *q)
QPointF QSGItemPrivate::computeTransformOrigin() const
{
- switch(origin) {
+ switch (origin) {
default:
case QSGItem::TopLeft:
return QPointF(0, 0);
@@ -3376,7 +3377,7 @@ void QSGItemPrivate::deliverMouseEvent(QMouseEvent *e)
Q_ASSERT(e->isAccepted());
- switch(e->type()) {
+ switch (e->type()) {
default:
Q_ASSERT(!"Unknown event type");
case QEvent::MouseMove:
@@ -3409,7 +3410,7 @@ void QSGItemPrivate::deliverTouchEvent(QTouchEvent *e)
void QSGItemPrivate::deliverHoverEvent(QHoverEvent *e)
{
Q_Q(QSGItem);
- switch(e->type()) {
+ switch (e->type()) {
default:
Q_ASSERT(!"Unknown event type");
case QEvent::HoverEnter:
@@ -3424,23 +3425,23 @@ void QSGItemPrivate::deliverHoverEvent(QHoverEvent *e)
}
}
-void QSGItemPrivate::deliverDragEvent(QSGDragEvent *e)
+void QSGItemPrivate::deliverDragEvent(QEvent *e)
{
Q_Q(QSGItem);
switch (e->type()) {
default:
Q_ASSERT(!"Unknown event type");
- case QSGEvent::SGDragEnter:
- q->dragEnterEvent(e);
+ case QEvent::DragEnter:
+ q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
break;
- case QSGEvent::SGDragExit:
- q->dragExitEvent(e);
+ case QEvent::DragLeave:
+ q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
break;
- case QSGEvent::SGDragMove:
- q->dragMoveEvent(e);
+ case QEvent::DragMove:
+ q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
break;
- case QSGEvent::SGDragDrop:
- q->dragDropEvent(e);
+ case QEvent::Drop:
+ q->dropEvent(static_cast<QDropEvent *>(e));
break;
}
}
@@ -3774,7 +3775,7 @@ void QSGItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
for (int ii = 0; ii < childItems.count(); ++ii)
QSGItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
- for(int ii = 0; ii < changeListeners.count(); ++ii) {
+ for (int ii = 0; ii < changeListeners.count(); ++ii) {
const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
if (change.types & QSGItemPrivate::Visibility)
change.listener->itemVisibilityChanged(q);
@@ -3928,12 +3929,12 @@ void QSGItemPrivate::derefFromEffectItem(bool unhide)
void QSGItemPrivate::itemChange(QSGItem::ItemChange change, const QSGItem::ItemChangeData &data)
{
Q_Q(QSGItem);
- switch(change) {
+ switch (change) {
case QSGItem::ItemChildAddedChange:
q->itemChange(change, data);
if (_contents && componentComplete)
_contents->childAdded(data.item);
- for(int ii = 0; ii < changeListeners.count(); ++ii) {
+ for (int ii = 0; ii < changeListeners.count(); ++ii) {
const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
if (change.types & QSGItemPrivate::Children) {
change.listener->itemChildAdded(q, data.item);
@@ -3944,7 +3945,7 @@ void QSGItemPrivate::itemChange(QSGItem::ItemChange change, const QSGItem::ItemC
q->itemChange(change, data);
if (_contents && componentComplete)
_contents->childRemoved(data.item);
- for(int ii = 0; ii < changeListeners.count(); ++ii) {
+ for (int ii = 0; ii < changeListeners.count(); ++ii) {
const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
if (change.types & QSGItemPrivate::Children) {
change.listener->itemChildRemoved(q, data.item);
@@ -3956,7 +3957,7 @@ void QSGItemPrivate::itemChange(QSGItem::ItemChange change, const QSGItem::ItemC
break;
case QSGItem::ItemVisibleHasChanged:
q->itemChange(change, data);
- for(int ii = 0; ii < changeListeners.count(); ++ii) {
+ for (int ii = 0; ii < changeListeners.count(); ++ii) {
const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
if (change.types & QSGItemPrivate::Visibility) {
change.listener->itemVisibilityChanged(q);
@@ -3965,7 +3966,7 @@ void QSGItemPrivate::itemChange(QSGItem::ItemChange change, const QSGItem::ItemC
break;
case QSGItem::ItemParentHasChanged:
q->itemChange(change, data);
- for(int ii = 0; ii < changeListeners.count(); ++ii) {
+ for (int ii = 0; ii < changeListeners.count(); ++ii) {
const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
if (change.types & QSGItemPrivate::Parent) {
change.listener->itemParentChanged(q, data.item);
@@ -3974,7 +3975,7 @@ void QSGItemPrivate::itemChange(QSGItem::ItemChange change, const QSGItem::ItemC
break;
case QSGItem::ItemOpacityHasChanged:
q->itemChange(change, data);
- for(int ii = 0; ii < changeListeners.count(); ++ii) {
+ for (int ii = 0; ii < changeListeners.count(); ++ii) {
const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
if (change.types & QSGItemPrivate::Opacity) {
change.listener->itemOpacityChanged(q);
@@ -3986,7 +3987,7 @@ void QSGItemPrivate::itemChange(QSGItem::ItemChange change, const QSGItem::ItemC
break;
case QSGItem::ItemRotationHasChanged:
q->itemChange(change, data);
- for(int ii = 0; ii < changeListeners.count(); ++ii) {
+ for (int ii = 0; ii < changeListeners.count(); ++ii) {
const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
if (change.types & QSGItemPrivate::Rotation) {
change.listener->itemRotationChanged(q);
@@ -4467,7 +4468,7 @@ void QSGItem::setAcceptHoverEvents(bool enabled)
d->hoverEnabled = enabled;
}
-void QSGItem::grabMouse()
+void QSGItem::grabMouse()
{
Q_D(QSGItem);
if (!d->canvas)
diff --git a/src/declarative/items/qsgitem.h b/src/declarative/items/qsgitem.h
index e340a6a364..018453f68f 100644
--- a/src/declarative/items/qsgitem.h
+++ b/src/declarative/items/qsgitem.h
@@ -154,7 +154,8 @@ public:
ItemClipsChildrenToShape = 0x01,
ItemAcceptsInputMethod = 0x02,
ItemIsFocusScope = 0x04,
- ItemHasContents = 0x08
+ ItemHasContents = 0x08,
+ ItemAcceptsDrops = 0x10
// Remember to increment the size of QSGItemPrivate::flags
};
Q_DECLARE_FLAGS(Flags, Flag)
@@ -373,10 +374,10 @@ protected:
virtual void hoverEnterEvent(QHoverEvent *event);
virtual void hoverMoveEvent(QHoverEvent *event);
virtual void hoverLeaveEvent(QHoverEvent *event);
- virtual void dragMoveEvent(QSGDragEvent *event);
- virtual void dragEnterEvent(QSGDragEvent *event);
- virtual void dragExitEvent(QSGDragEvent *event);
- virtual void dragDropEvent(QSGDragEvent *event);
+ virtual void dragEnterEvent(QDragEnterEvent *);
+ virtual void dragMoveEvent(QDragMoveEvent *);
+ virtual void dragLeaveEvent(QDragLeaveEvent *);
+ virtual void dropEvent(QDropEvent *);
virtual bool childMouseEventFilter(QSGItem *, QEvent *);
virtual void windowDeactivateEvent();
diff --git a/src/declarative/items/qsgitem_p.h b/src/declarative/items/qsgitem_p.h
index e48c1043e5..c0ed1dbc8b 100644
--- a/src/declarative/items/qsgitem_p.h
+++ b/src/declarative/items/qsgitem_p.h
@@ -232,7 +232,7 @@ public:
QDeclarativeStateGroup *_stateGroup;
QSGItem::TransformOrigin origin:5;
- quint32 flags:4;
+ quint32 flags:5;
bool widthValid:1;
bool heightValid:1;
bool componentComplete:1;
@@ -326,7 +326,7 @@ public:
void deliverWheelEvent(QWheelEvent *);
void deliverTouchEvent(QTouchEvent *);
void deliverHoverEvent(QHoverEvent *);
- void deliverDragEvent(QSGDragEvent *);
+ void deliverDragEvent(QEvent *);
bool calcEffectiveVisible() const;
void setEffectiveVisibleRecur(bool);
@@ -670,7 +670,7 @@ private:
};
QSGTransformNode *QSGItemPrivate::itemNode()
-{
+{
if (!itemNodeInstance) {
itemNodeInstance = createTransformNode();
itemNodeInstance->setFlag(QSGNode::OwnedByParent, false);
@@ -679,7 +679,7 @@ QSGTransformNode *QSGItemPrivate::itemNode()
itemNodeInstance->description = QString::fromLatin1("QSGItem(%1)").arg(QString::fromLatin1(q->metaObject()->className()));
#endif
}
- return itemNodeInstance;
+ return itemNodeInstance;
}
QSGNode *QSGItemPrivate::childContainerNode()
diff --git a/src/declarative/items/qsgitemsmodule.cpp b/src/declarative/items/qsgitemsmodule.cpp
index 41823c1a4d..bb471dd05a 100644
--- a/src/declarative/items/qsgitemsmodule.cpp
+++ b/src/declarative/items/qsgitemsmodule.cpp
@@ -73,12 +73,13 @@
#include "qsganimation_p.h"
#include <private/qsgshadereffect_p.h>
#include <private/qsgshadereffectsource_p.h>
-//#include "private/qsgpincharea_p.h"
-#include "qsgcanvasitem_p.h"
-#include "qsgcontext2d_p.h"
+//#include <private/qsgpincharea_p.h>
+#include <private/qsgcanvasitem_p.h>
+#include <private/qsgcontext2d_p.h>
#include "qsgsprite_p.h"
#include "qsgspriteimage_p.h"
-#include "qsgdragtarget_p.h"
+#include "qsgdrag_p.h"
+#include "qsgdroparea_p.h"
static QDeclarativePrivate::AutoParentResult qsgitem_autoParent(QObject *obj, QObject *parent)
{
@@ -106,7 +107,6 @@ static void qt_sgitems_defineModule(const char *uri, int major, int minor)
#endif
qmlRegisterType<QSGBorderImage>(uri,major,minor,"BorderImage");
qmlRegisterType<QSGColumn>(uri,major,minor,"Column");
- qmlRegisterType<QSGDrag>(uri,major,minor,"Drag");
qmlRegisterType<QSGFlickable>(uri,major,minor,"Flickable");
qmlRegisterType<QSGFlipable>(uri,major,minor,"Flipable");
qmlRegisterType<QSGFlow>(uri,major,minor,"Flow");
@@ -149,6 +149,7 @@ static void qt_sgitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QSGTextInput>(uri,major,minor,"TextInput");
qmlRegisterType<QSGViewSection>(uri,major,minor,"ViewSection");
qmlRegisterType<QSGVisualDataModel>(uri,major,minor,"VisualDataModel");
+ qmlRegisterType<QSGVisualDataGroup>(uri,major,minor,"VisualDataGroup");
qmlRegisterType<QSGVisualItemModel>(uri,major,minor,"VisualItemModel");
qmlRegisterType<QSGAnchors>();
@@ -158,6 +159,7 @@ static void qt_sgitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QDeclarativePathElement>();
qmlRegisterType<QDeclarativeCurve>();
qmlRegisterType<QSGScaleGrid>();
+ qmlRegisterType<QSGTextLine>();
#ifndef QT_NO_VALIDATOR
qmlRegisterType<QValidator>();
#endif
@@ -195,8 +197,10 @@ static void qt_sgitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QSGPathAnimation>("QtQuick",2,0,"PathAnimation");
qmlRegisterType<QDeclarativePathInterpolator>("QtQuick",2,0,"PathInterpolator");
- qmlRegisterType<QSGDragTarget>("QtQuick", 2, 0, "DragTarget");
- qmlRegisterType<QSGDragTargetEvent>();
+ qmlRegisterType<QSGDropArea>("QtQuick", 2, 0, "DropArea");
+ qmlRegisterType<QSGDropEvent>();
+ qmlRegisterType<QSGDropAreaDrag>();
+ qmlRegisterUncreatableType<QSGDrag>("QtQuick", 2, 0, "Drag", QSGDragAttached::tr("Drag is only available via attached properties"));
}
void QSGItemsModule::defineModule()
diff --git a/src/declarative/items/qsgitemview.cpp b/src/declarative/items/qsgitemview.cpp
index 291592b871..5b95097dcc 100644
--- a/src/declarative/items/qsgitemview.cpp
+++ b/src/declarative/items/qsgitemview.cpp
@@ -97,18 +97,21 @@ void QSGItemViewChangeSet::applyChanges(const QDeclarativeChangeSet &changeSet)
}
}
foreach (const QDeclarativeChangeSet::Insert &i, changeSet.inserts()) {
- itemCount += i.count;
if (moveId == -1) {
- if (newCurrentIndex >= i.index) {
+ if (itemCount && newCurrentIndex >= i.index) {
newCurrentIndex += i.count;
currentChanged = true;
} else if (newCurrentIndex < 0) {
newCurrentIndex = 0;
currentChanged = true;
+ } else if (newCurrentIndex == 0 && !itemCount) {
+ // this is the first item, set the initial current index
+ currentChanged = true;
}
} else if (moveId == i.moveId) {
newCurrentIndex = i.index + moveOffset;
}
+ itemCount += i.count;
}
}
@@ -198,6 +201,8 @@ void QSGItemView::setModel(const QVariant &model)
if (!d->ownModel) {
d->model = new QSGVisualDataModel(qmlContext(this), this);
d->ownModel = true;
+ if (isComponentComplete())
+ static_cast<QSGVisualDataModel *>(d->model.data())->componentComplete();
} else {
d->model = oldModel;
}
@@ -401,8 +406,7 @@ void QSGItemView::setHeader(QDeclarativeComponent *headerComponent)
d->header = 0;
d->headerComponent = headerComponent;
- d->minExtentDirty = true;
- d->maxExtentDirty = true;
+ d->markExtentsDirty();
if (isComponentComplete()) {
d->updateHeader();
@@ -724,14 +728,12 @@ void QSGItemViewPrivate::itemGeometryChanged(QSGItem *item, const QRectF &newGeo
if (header && header->item == item) {
updateHeader();
- minExtentDirty = true;
- maxExtentDirty = true;
+ markExtentsDirty();
if (!q->isMoving() && !q->isFlicking())
fixupPosition();
} else if (footer && footer->item == item) {
updateFooter();
- minExtentDirty = true;
- maxExtentDirty = true;
+ markExtentsDirty();
if (!q->isMoving() && !q->isFlicking())
fixupPosition();
}
@@ -819,30 +821,14 @@ void QSGItemView::trackedPositionChanged()
if (d->trackedItem != d->currentItem) {
trackedSize += d->currentItem->sectionSize();
}
- qreal viewPos;
- qreal highlightStart;
- qreal highlightEnd;
- if (d->isContentFlowReversed()) {
- viewPos = -d->position()-d->size();
- highlightStart = d->highlightRangeStartValid ? d->size()-d->highlightRangeEnd : d->highlightRangeStart;
- highlightEnd = d->highlightRangeEndValid ? d->size()-d->highlightRangeStart : d->highlightRangeEnd;
- } else {
- viewPos = d->position();
- highlightStart = d->highlightRangeStart;
- highlightEnd = d->highlightRangeEnd;
- }
+ qreal viewPos = d->isContentFlowReversed() ? -d->position()-d->size() : d->position();
qreal pos = viewPos;
if (d->haveHighlightRange) {
- if (d->highlightRange == StrictlyEnforceRange) {
- if (trackedPos > pos + highlightEnd - d->trackedItem->size())
- pos = trackedPos - highlightEnd + d->trackedItem->size();
- if (trackedPos < pos + highlightStart)
- pos = trackedPos - highlightStart;
- } else {
- if (trackedPos > pos + highlightEnd - trackedSize)
- pos = trackedPos - highlightEnd + trackedSize;
- if (trackedPos < pos + highlightStart)
- pos = trackedPos - highlightStart;
+ if (trackedPos > pos + d->highlightRangeEnd - trackedSize)
+ pos = trackedPos - d->highlightRangeEnd + trackedSize;
+ if (trackedPos < pos + d->highlightRangeStart)
+ pos = trackedPos - d->highlightRangeStart;
+ if (d->highlightRange != StrictlyEnforceRange) {
if (pos > d->endPosition() - d->size())
pos = d->endPosition() - d->size();
if (pos < d->startPosition())
@@ -892,8 +878,7 @@ void QSGItemView::trackedPositionChanged()
void QSGItemView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QSGItemView);
- d->maxExtentDirty = true;
- d->minExtentDirty = true;
+ d->markExtentsDirty();
QSGFlickable::geometryChanged(newGeometry, oldGeometry);
}
@@ -904,8 +889,8 @@ qreal QSGItemView::minYExtent() const
if (d->layoutOrientation() == Qt::Horizontal)
return QSGFlickable::minYExtent();
- if (d->minExtentDirty) {
- d->minExtent = -d->startPosition();
+ if (d->vData.minExtentDirty) {
+ d->minExtent = d->vData.startMargin-d->startPosition();
if (d->header)
d->minExtent += d->headerSize();
if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
@@ -914,7 +899,7 @@ qreal QSGItemView::minYExtent() const
d->minExtent -= d->visibleItem(0)->sectionSize();
d->minExtent = qMax(d->minExtent, -(d->endPositionAt(0) - d->highlightRangeEnd));
}
- d->minExtentDirty = false;
+ d->vData.minExtentDirty = false;
}
return d->minExtent;
@@ -926,7 +911,7 @@ qreal QSGItemView::maxYExtent() const
if (d->layoutOrientation() == Qt::Horizontal)
return height();
- if (d->maxExtentDirty) {
+ if (d->vData.maxExtentDirty) {
if (!d->model || !d->model->count()) {
d->maxExtent = d->header ? -d->headerSize() : 0;
d->maxExtent += height();
@@ -940,10 +925,11 @@ qreal QSGItemView::maxYExtent() const
if (d->footer)
d->maxExtent -= d->footerSize();
+ d->maxExtent -= d->vData.endMargin;
qreal minY = minYExtent();
if (d->maxExtent > minY)
d->maxExtent = minY;
- d->maxExtentDirty = false;
+ d->vData.maxExtentDirty = false;
}
return d->maxExtent;
}
@@ -954,26 +940,26 @@ qreal QSGItemView::minXExtent() const
if (d->layoutOrientation() == Qt::Vertical)
return QSGFlickable::minXExtent();
- if (d->minExtentDirty) {
+ if (d->hData.minExtentDirty) {
d->minExtent = -d->startPosition();
qreal highlightStart;
qreal highlightEnd;
qreal endPositionFirstItem = 0;
if (d->isContentFlowReversed()) {
+ d->minExtent += d->hData.endMargin;
if (d->model && d->model->count())
endPositionFirstItem = d->positionAt(d->model->count()-1);
else if (d->header)
d->minExtent += d->headerSize();
- highlightStart = d->highlightRangeStartValid
- ? d->highlightRangeStart - (d->lastPosition()-endPositionFirstItem)
- : d->size() - (d->lastPosition()-endPositionFirstItem);
- highlightEnd = d->highlightRangeEndValid ? d->highlightRangeEnd : d->size();
+ highlightStart = d->highlightRangeEndValid ? d->size() - d->highlightRangeEnd : d->size();
+ highlightEnd = d->highlightRangeStartValid ? d->size() - d->highlightRangeStart : d->size();
if (d->footer)
d->minExtent += d->footerSize();
qreal maxX = maxXExtent();
if (d->minExtent < maxX)
d->minExtent = maxX;
} else {
+ d->minExtent += d->hData.startMargin;
endPositionFirstItem = d->endPositionAt(0);
highlightStart = d->highlightRangeStart;
highlightEnd = d->highlightRangeEnd;
@@ -982,9 +968,11 @@ qreal QSGItemView::minXExtent() const
}
if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
d->minExtent += highlightStart;
- d->minExtent = qMax(d->minExtent, -(endPositionFirstItem - highlightEnd));
+ d->minExtent = d->isContentFlowReversed()
+ ? qMin(d->minExtent, endPositionFirstItem + highlightEnd)
+ : qMax(d->minExtent, -(endPositionFirstItem - highlightEnd));
}
- d->minExtentDirty = false;
+ d->hData.minExtentDirty = false;
}
return d->minExtent;
@@ -996,14 +984,14 @@ qreal QSGItemView::maxXExtent() const
if (d->layoutOrientation() == Qt::Vertical)
return width();
- if (d->maxExtentDirty) {
+ if (d->hData.maxExtentDirty) {
qreal highlightStart;
qreal highlightEnd;
qreal lastItemPosition = 0;
d->maxExtent = 0;
if (d->isContentFlowReversed()) {
- highlightStart = d->highlightRangeStartValid ? d->highlightRangeEnd : d->size();
- highlightEnd = d->highlightRangeEndValid ? d->highlightRangeStart : d->size();
+ highlightStart = d->highlightRangeEndValid ? d->size() - d->highlightRangeEnd : d->size();
+ highlightEnd = d->highlightRangeStartValid ? d->size() - d->highlightRangeStart : d->size();
lastItemPosition = d->endPosition();
} else {
highlightStart = d->highlightRangeStart;
@@ -1028,14 +1016,16 @@ qreal QSGItemView::maxXExtent() const
if (d->isContentFlowReversed()) {
if (d->header)
d->maxExtent -= d->headerSize();
+ d->maxExtent -= d->hData.startMargin;
} else {
if (d->footer)
d->maxExtent -= d->footerSize();
+ d->maxExtent -= d->hData.endMargin;
qreal minX = minXExtent();
if (d->maxExtent > minX)
d->maxExtent = minX;
}
- d->maxExtentDirty = false;
+ d->hData.maxExtentDirty = false;
}
return d->maxExtent;
@@ -1057,6 +1047,14 @@ void QSGItemView::setContentY(qreal pos)
QSGFlickable::setContentY(pos);
}
+qreal QSGItemView::xOrigin() const
+{
+ Q_D(const QSGItemView);
+ if (d->isContentFlowReversed())
+ return -maxXExtent() + d->size() - d->hData.startMargin;
+ else
+ return -minXExtent() + d->hData.startMargin;
+}
void QSGItemView::updatePolish()
{
@@ -1068,6 +1066,9 @@ void QSGItemView::updatePolish()
void QSGItemView::componentComplete()
{
Q_D(QSGItemView);
+ if (d->model && d->ownModel)
+ static_cast<QSGVisualDataModel *>(d->model.data())->componentComplete();
+
QSGFlickable::componentComplete();
updateSections();
@@ -1090,6 +1091,8 @@ void QSGItemView::componentComplete()
d->moveReason = QSGItemViewPrivate::Other;
d->fixupPosition();
}
+ if (d->model && d->model->count())
+ emit countChanged();
}
@@ -1111,7 +1114,6 @@ QSGItemViewPrivate::QSGItemViewPrivate()
, ownModel(false), wrap(false), lazyRelease(false), deferredRelease(false)
, inApplyModelChanges(false), inViewportMoved(false), forceLayout(false), currentIndexCleared(false)
, haveHighlightRange(false), autoHighlight(true), highlightRangeStartValid(false), highlightRangeEndValid(false)
- , minExtentDirty(true), maxExtentDirty(true)
{
}
@@ -1144,7 +1146,16 @@ qreal QSGItemViewPrivate::endPosition() const
qreal QSGItemViewPrivate::contentStartPosition() const
{
- return -headerSize();
+ Q_Q(const QSGItemView);
+ qreal pos = -headerSize();
+ if (layoutOrientation() == Qt::Vertical)
+ pos -= vData.startMargin;
+ else if (isContentFlowReversed())
+ pos -= hData.endMargin;
+ else
+ pos -= hData.startMargin;
+
+ return pos;
}
int QSGItemViewPrivate::findLastVisibleIndex(int defaultValue) const
@@ -1263,8 +1274,7 @@ void QSGItemViewPrivate::clear()
createHighlight();
trackedItem = 0;
- minExtentDirty = true;
- maxExtentDirty = true;
+ markExtentsDirty();
itemCount = 0;
}
@@ -1318,8 +1328,7 @@ void QSGItemViewPrivate::refill(qreal from, qreal to, bool doBuffer)
}
if (changed) {
- minExtentDirty = true;
- maxExtentDirty = true;
+ markExtentsDirty();
visibleItemsChanged();
} else if (!doBuffer && buffer && bufferMode != NoBuffer) {
refill(from, to, true);
@@ -1363,6 +1372,9 @@ void QSGItemViewPrivate::updateViewport()
void QSGItemViewPrivate::layout()
{
Q_Q(QSGItemView);
+ if (inApplyModelChanges)
+ return;
+
if (!isValid() && !visibleItems.count()) {
clear();
setPosition(contentStartPosition());
@@ -1376,8 +1388,7 @@ void QSGItemViewPrivate::layout()
layoutVisibleItems();
refill();
- minExtentDirty = true;
- maxExtentDirty = true;
+ markExtentsDirty();
updateHighlight();
@@ -1404,11 +1415,13 @@ bool QSGItemViewPrivate::applyModelChanges()
int prevCount = itemCount;
bool removedVisible = false;
+ bool viewportChanged = !currentChanges.pendingChanges.removes().isEmpty()
+ || !currentChanges.pendingChanges.inserts().isEmpty();
FxViewItem *firstVisible = firstVisibleItem();
FxViewItem *origVisibleItemsFirst = visibleItems.count() ? visibleItems.first() : 0;
int firstItemIndex = firstVisible ? firstVisible->index : -1;
- QList<FxViewItem *> removedBeforeFirstVisible;
+ qreal removedBeforeFirstVisibleBy = 0;
const QVector<QDeclarativeChangeSet::Remove> &removals = currentChanges.pendingChanges.removes();
for (int i=0; i<removals.count(); i++) {
@@ -1439,7 +1452,7 @@ bool QSGItemViewPrivate::applyModelChanges()
++it;
} else {
if (firstVisible && item->position() < firstVisible->position() && item != visibleItems.first())
- removedBeforeFirstVisible.append(item);
+ removedBeforeFirstVisibleBy += item->size();
if (removals[i].isMove()) {
currentChanges.removedItems.insert(removals[i].moveKey(item->index), item);
} else {
@@ -1458,40 +1471,54 @@ bool QSGItemViewPrivate::applyModelChanges()
const QVector<QDeclarativeChangeSet::Insert> &insertions = currentChanges.pendingChanges.inserts();
bool addedVisible = false;
- QList<FxViewItem *> addedItems;
- QList<FxViewItem *> movedBackwards;
+ InsertionsResult insertResult;
+ bool allInsertionsBeforeVisible = true;
for (int i=0; i<insertions.count(); i++) {
bool wasEmpty = visibleItems.isEmpty();
- if (applyInsertionChange(insertions[i], &movedBackwards, &addedItems, firstVisible))
+ if (applyInsertionChange(insertions[i], firstVisible, &insertResult))
addedVisible = true;
+ if (insertions[i].index >= visibleIndex)
+ allInsertionsBeforeVisible = false;
if (wasEmpty && !visibleItems.isEmpty())
resetFirstItemPosition();
itemCount += insertions[i].count;
- updateVisibleIndex();
}
- for (int i=0; i<addedItems.count(); ++i)
- addedItems.at(i)->attached->emitAdd();
+ for (int i=0; i<insertResult.addedItems.count(); ++i)
+ insertResult.addedItems.at(i)->attached->emitAdd();
- // if first visible item is moving but another item is moving up to replace it,
- // do this positioning now to avoid shifting all content forwards
+ // if the first visible item has moved, ensure another one takes its place
+ // so that we avoid shifting all content forwards
+ // (if an item is removed from before the first visible, the first visible should not move upwards)
if (firstVisible && firstItemIndex >= 0) {
- for (int i=0; i<movedBackwards.count(); i++) {
- if (movedBackwards[i]->index == firstItemIndex) {
- resetItemPosition(movedBackwards[i], firstVisible);
- movedBackwards.removeAt(i);
+ bool found = false;
+ for (int i=0; i<insertResult.movedBackwards.count(); i++) {
+ if (insertResult.movedBackwards[i]->index == firstItemIndex) {
+ // an item has moved backwards up to the first visible's position
+ resetItemPosition(insertResult.movedBackwards[i], firstVisible);
+ insertResult.movedBackwards.removeAt(i);
+ found = true;
break;
}
}
+ if (!found && !allInsertionsBeforeVisible) {
+ // first visible item has moved forward, another visible item takes its place
+ FxViewItem *item = visibleItem(firstItemIndex);
+ if (item)
+ resetItemPosition(item, firstVisible);
+ }
}
// Ensure we don't cause an ugly list scroll
if (firstVisible && visibleItems.count() && visibleItems.first() != firstVisible) {
// ensure first item is placed at correct postion if moving backward
// since it will be used to position all subsequent items
- if (movedBackwards.count() && origVisibleItemsFirst)
+ if (insertResult.movedBackwards.count() && origVisibleItemsFirst)
resetItemPosition(visibleItems.first(), origVisibleItemsFirst);
- moveItemBy(visibleItems.first(), removedBeforeFirstVisible, movedBackwards);
+ qreal moveBackwardsBy = insertResult.sizeAddedBeforeVisible;
+ for (int i=0; i<insertResult.movedBackwards.count(); i++)
+ moveBackwardsBy += insertResult.movedBackwards[i]->size();
+ moveItemBy(visibleItems.first(), removedBeforeFirstVisibleBy, moveBackwardsBy);
}
// Whatever removed/moved items remain are no longer visible items.
@@ -1516,8 +1543,12 @@ bool QSGItemViewPrivate::applyModelChanges()
if (prevCount != itemCount)
emit q->countChanged();
+ bool visibleAffected = removedVisible || addedVisible || !currentChanges.pendingChanges.changes().isEmpty();
+ if (!visibleAffected && viewportChanged)
+ updateViewport();
+
inApplyModelChanges = false;
- return removedVisible || addedVisible || !currentChanges.pendingChanges.changes().isEmpty();
+ return visibleAffected;
}
FxViewItem *QSGItemViewPrivate::createItem(int modelIndex)
@@ -1534,9 +1565,11 @@ FxViewItem *QSGItemViewPrivate::createItem(int modelIndex)
if (model->completePending()) {
// complete
viewItem->item->setZ(1);
+ QDeclarative_setParent_noEvent(viewItem->item, q->contentItem());
viewItem->item->setParentItem(q->contentItem());
model->completeItem();
} else {
+ QDeclarative_setParent_noEvent(viewItem->item, q->contentItem());
viewItem->item->setParentItem(q->contentItem());
}
// do other set up for the new item that should not happen
@@ -1578,7 +1611,9 @@ QSGItem *QSGItemViewPrivate::createComponentItem(QDeclarativeComponent *componen
QSGItem *item = 0;
if (component) {
- QDeclarativeContext *context = new QDeclarativeContext(qmlContext(q));
+ QDeclarativeContext *creationContext = component->creationContext();
+ QDeclarativeContext *context = new QDeclarativeContext(
+ creationContext ? creationContext : qmlContext(q));
QObject *nobj = component->create(context);
if (nobj) {
QDeclarative_setParent_noEvent(context, nobj);
diff --git a/src/declarative/items/qsgitemview_p.h b/src/declarative/items/qsgitemview_p.h
index 9d25eab914..7b8efbbda0 100644
--- a/src/declarative/items/qsgitemview_p.h
+++ b/src/declarative/items/qsgitemview_p.h
@@ -154,6 +154,7 @@ public:
virtual void setContentX(qreal pos);
virtual void setContentY(qreal pos);
+ virtual qreal xOrigin() const;
signals:
void modelChanged();
diff --git a/src/declarative/items/qsgitemview_p_p.h b/src/declarative/items/qsgitemview_p_p.h
index 73cb68c50b..5eaa84c6b2 100644
--- a/src/declarative/items/qsgitemview_p_p.h
+++ b/src/declarative/items/qsgitemview_p_p.h
@@ -101,6 +101,14 @@ class QSGItemViewPrivate : public QSGFlickablePrivate
public:
QSGItemViewPrivate();
+ struct InsertionsResult {
+ QList<FxViewItem *> addedItems;
+ QList<FxViewItem *> movedBackwards;
+ qreal sizeAddedBeforeVisible;
+
+ InsertionsResult() : sizeAddedBeforeVisible(0) {}
+ };
+
enum BufferMode { NoBuffer = 0x00, BufferBefore = 0x01, BufferAfter = 0x02 };
enum MovementReason { Other, SetIndex, Mouse };
@@ -142,6 +150,13 @@ public:
void checkVisible() const;
+ void markExtentsDirty() {
+ if (layoutOrientation() == Qt::Vertical)
+ vData.markExtentsDirty();
+ else
+ hData.markExtentsDirty();
+ }
+
QDeclarativeGuard<QSGVisualModel> model;
QVariant modelVariant;
int itemCount;
@@ -188,8 +203,6 @@ public:
bool autoHighlight : 1;
bool highlightRangeStartValid : 1;
bool highlightRangeEndValid : 1;
- mutable bool minExtentDirty : 1;
- mutable bool maxExtentDirty : 1;
protected:
virtual Qt::Orientation layoutOrientation() const = 0;
@@ -222,11 +235,11 @@ protected:
virtual void repositionPackageItemAt(QSGItem *item, int index) = 0;
virtual void resetItemPosition(FxViewItem *item, FxViewItem *toItem) = 0;
virtual void resetFirstItemPosition() = 0;
- virtual void moveItemBy(FxViewItem *item, const QList<FxViewItem *> &, const QList<FxViewItem *> &) = 0;
+ virtual void moveItemBy(FxViewItem *item, qreal forwards, qreal backwards) = 0;
virtual void layoutVisibleItems() = 0;
virtual void changedVisibleIndex(int newIndex) = 0;
- virtual bool applyInsertionChange(const QDeclarativeChangeSet::Insert &, QList<FxViewItem *> *, QList<FxViewItem *> *, FxViewItem *) = 0;
+ virtual bool applyInsertionChange(const QDeclarativeChangeSet::Insert &, FxViewItem *, InsertionsResult *) = 0;
virtual void initializeViewItem(FxViewItem *) {}
virtual void initializeCurrentItem() {}
diff --git a/src/declarative/items/qsglistview.cpp b/src/declarative/items/qsglistview.cpp
index 5ad7d5b2eb..34e23d1a7b 100644
--- a/src/declarative/items/qsglistview.cpp
+++ b/src/declarative/items/qsglistview.cpp
@@ -52,9 +52,14 @@
#include <private/qdeclarativesmoothedanimation_p_p.h>
#include <private/qlistmodelinterface_p.h>
+#include "qplatformdefs.h"
QT_BEGIN_NAMESPACE
+#ifndef QML_FLICK_SNAPONETHRESHOLD
+#define QML_FLICK_SNAPONETHRESHOLD 30
+#endif
+
class FxListItemSG;
class QSGListViewPrivate : public QSGItemViewPrivate
@@ -72,7 +77,6 @@ public:
virtual qreal originPosition() const;
virtual qreal lastPosition() const;
- FxViewItem *nextVisibleItem() const;
FxViewItem *itemBefore(int modelIndex) const;
QString sectionAt(int modelIndex);
qreal snapPosAt(qreal pos);
@@ -91,7 +95,7 @@ public:
virtual void repositionPackageItemAt(QSGItem *item, int index);
virtual void resetItemPosition(FxViewItem *item, FxViewItem *toItem);
virtual void resetFirstItemPosition();
- virtual void moveItemBy(FxViewItem *item, const QList<FxViewItem *> &items, const QList<FxViewItem *> &movedBackwards);
+ virtual void moveItemBy(FxViewItem *item, qreal forwards, qreal backwards);
virtual void createHighlight();
virtual void updateHighlight();
@@ -99,7 +103,7 @@ public:
virtual void setPosition(qreal pos);
virtual void layoutVisibleItems();
- bool applyInsertionChange(const QDeclarativeChangeSet::Insert &, QList<FxViewItem *> *, QList<FxViewItem *> *, FxViewItem *firstVisible);
+ bool applyInsertionChange(const QDeclarativeChangeSet::Insert &, FxViewItem *firstVisible, InsertionsResult *);
virtual void updateSections();
QSGItem *getSectionItem(const QString &section);
@@ -175,7 +179,7 @@ public:
QSGViewSection::QSGViewSection(QSGListView *parent)
: QObject(parent), m_criteria(FullString), m_delegate(0), m_labelPositioning(InlineLabels)
- , m_view(QSGListViewPrivate::get(parent))
+ , m_view(parent ? QSGListViewPrivate::get(parent) : 0)
{
}
@@ -331,22 +335,6 @@ bool QSGListViewPrivate::isRightToLeft() const
return orient == QSGListView::Horizontal && q->effectiveLayoutDirection() == Qt::RightToLeft;
}
-FxViewItem *QSGListViewPrivate::nextVisibleItem() const
-{
- const qreal pos = isRightToLeft() ? -position()-size() : position();
- bool foundFirst = false;
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxViewItem *item = visibleItems.at(i);
- if (item->index != -1) {
- if (foundFirst)
- return item;
- else if (item->position() < pos && item->endPosition() >= pos)
- foundFirst = true;
- }
- }
- return 0;
-}
-
// Returns the item before modelIndex, if created.
// May return an item marked for removal.
FxViewItem *QSGListViewPrivate::itemBefore(int modelIndex) const
@@ -732,6 +720,8 @@ void QSGListViewPrivate::repositionPackageItemAt(QSGItem *item, int index)
void QSGListViewPrivate::resetItemPosition(FxViewItem *item, FxViewItem *toItem)
{
+ if (item == toItem)
+ return;
static_cast<FxListItemSG*>(item)->setPosition(toItem->position());
}
@@ -741,14 +731,10 @@ void QSGListViewPrivate::resetFirstItemPosition()
item->setPosition(0);
}
-void QSGListViewPrivate::moveItemBy(FxViewItem *item, const QList<FxViewItem *> &forwards, const QList<FxViewItem *> &backwards)
+void QSGListViewPrivate::moveItemBy(FxViewItem *item, qreal forwards, qreal backwards)
{
- qreal pos = 0;
- for (int i=0; i<forwards.count(); i++)
- pos += forwards[i]->size();
- for (int i=0; i<backwards.count(); i++)
- pos -= backwards[i]->size();
- static_cast<FxListItemSG*>(item)->setPosition(item->position() + pos);
+ qreal diff = forwards - backwards;
+ static_cast<FxListItemSG*>(item)->setPosition(item->position() + diff);
}
void QSGListViewPrivate::createHighlight()
@@ -846,7 +832,9 @@ QSGItem * QSGListViewPrivate::getSectionItem(const QString &section)
QDeclarativeContext *context = QDeclarativeEngine::contextForObject(sectionItem)->parentContext();
context->setContextProperty(QLatin1String("section"), section);
} else {
- QDeclarativeContext *context = new QDeclarativeContext(qmlContext(q));
+ QDeclarativeContext *creationContext = sectionCriteria->delegate()->creationContext();
+ QDeclarativeContext *context = new QDeclarativeContext(
+ creationContext ? creationContext : qmlContext(q));
context->setContextProperty(QLatin1String("section"), section);
QObject *nobj = sectionCriteria->delegate()->beginCreate(context);
if (nobj) {
@@ -1265,62 +1253,52 @@ void QSGListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
correctFlick = false;
fixupMode = moveReason == Mouse ? fixupMode : Immediate;
+ bool strictHighlightRange = haveHighlightRange && highlightRange == QSGListView::StrictlyEnforceRange;
- qreal highlightStart;
- qreal highlightEnd;
- qreal viewPos;
- if (isRightToLeft()) {
- // Handle Right-To-Left exceptions
- viewPos = -position()-size();
- highlightStart = highlightRangeStartValid ? size() - highlightRangeEnd : highlightRangeStart;
- highlightEnd = highlightRangeEndValid ? size() - highlightRangeStart : highlightRangeEnd;
- } else {
- viewPos = position();
- highlightStart = highlightRangeStart;
- highlightEnd = highlightRangeEnd;
- }
-
- if (currentItem && haveHighlightRange && highlightRange == QSGListView::StrictlyEnforceRange
- && moveReason != QSGListViewPrivate::SetIndex) {
- updateHighlight();
- qreal pos = static_cast<FxListItemSG*>(currentItem)->itemPosition();
- if (viewPos < pos + static_cast<FxListItemSG*>(currentItem)->itemSize() - highlightEnd)
- viewPos = pos + static_cast<FxListItemSG*>(currentItem)->itemSize() - highlightEnd;
- if (viewPos > pos - highlightStart)
- viewPos = pos - highlightStart;
- if (isRightToLeft())
- viewPos = -viewPos-size();
+ qreal viewPos = isRightToLeft() ? -position()-size() : position();
- timeline.reset(data.move);
- if (viewPos != position()) {
- if (fixupMode != Immediate) {
- timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- data.fixingUp = true;
- } else {
- timeline.set(data.move, -viewPos);
- }
- }
- vTime = timeline.time();
- } else if (snapMode != QSGListView::NoSnap && moveReason != QSGListViewPrivate::SetIndex) {
+ if (snapMode != QSGListView::NoSnap && moveReason != QSGListViewPrivate::SetIndex) {
qreal tempPosition = isRightToLeft() ? -position()-size() : position();
- FxViewItem *topItem = snapItemAt(tempPosition+highlightStart);
- FxViewItem *bottomItem = snapItemAt(tempPosition+highlightEnd);
+ if (snapMode == QSGListView::SnapOneItem && moveReason == Mouse) {
+ // if we've been dragged < averageSize/2 then bias towards the next item
+ qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
+ qreal bias = 0;
+ if (data.velocity > 0 && dist > QML_FLICK_SNAPONETHRESHOLD && dist < averageSize/2)
+ bias = averageSize/2;
+ else if (data.velocity < 0 && dist < -QML_FLICK_SNAPONETHRESHOLD && dist > -averageSize/2)
+ bias = -averageSize/2;
+ if (isRightToLeft())
+ bias = -bias;
+ tempPosition -= bias;
+ }
+ FxViewItem *topItem = snapItemAt(tempPosition+highlightRangeStart);
+ if (!topItem && strictHighlightRange && currentItem) {
+ // StrictlyEnforceRange always keeps an item in range
+ updateHighlight();
+ topItem = currentItem;
+ }
+ FxViewItem *bottomItem = snapItemAt(tempPosition+highlightRangeEnd);
+ if (!bottomItem && strictHighlightRange && currentItem) {
+ // StrictlyEnforceRange always keeps an item in range
+ updateHighlight();
+ bottomItem = currentItem;
+ }
qreal pos;
- bool isInBounds = -position() > maxExtent && -position() < minExtent;
- if (topItem && isInBounds) {
- if (topItem->index == 0 && header && tempPosition+highlightStart < header->position()+headerSize()/2) {
- pos = isRightToLeft() ? - header->position() + highlightStart - size() : header->position() - highlightStart;
+ bool isInBounds = -position() > maxExtent && -position() <= minExtent;
+ if (topItem && (isInBounds || strictHighlightRange)) {
+ if (topItem->index == 0 && header && tempPosition+highlightRangeStart < header->position()+header->size()/2 && !strictHighlightRange) {
+ pos = isRightToLeft() ? - header->position() + highlightRangeStart - size() : header->position() - highlightRangeStart;
} else {
if (isRightToLeft())
- pos = qMax(qMin(-topItem->position() + highlightStart - size(), -maxExtent), -minExtent);
+ pos = qMax(qMin(-topItem->position() + highlightRangeStart - size(), -maxExtent), -minExtent);
else
- pos = qMax(qMin(topItem->position() - highlightStart, -maxExtent), -minExtent);
+ pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent);
}
} else if (bottomItem && isInBounds) {
if (isRightToLeft())
- pos = qMax(qMin(-bottomItem->position() + highlightStart - size(), -maxExtent), -minExtent);
+ pos = qMax(qMin(-bottomItem->position() + highlightRangeEnd - size(), -maxExtent), -minExtent);
else
- pos = qMax(qMin(bottomItem->position() - highlightStart, -maxExtent), -minExtent);
+ pos = qMax(qMin(bottomItem->position() - highlightRangeEnd, -maxExtent), -minExtent);
} else {
QSGItemViewPrivate::fixup(data, minExtent, maxExtent);
return;
@@ -1337,6 +1315,26 @@ void QSGListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
}
vTime = timeline.time();
}
+ } else if (currentItem && strictHighlightRange && moveReason != QSGListViewPrivate::SetIndex) {
+ updateHighlight();
+ qreal pos = static_cast<FxListItemSG*>(currentItem)->itemPosition();
+ if (viewPos < pos + static_cast<FxListItemSG*>(currentItem)->itemSize() - highlightRangeEnd)
+ viewPos = pos + static_cast<FxListItemSG*>(currentItem)->itemSize() - highlightRangeEnd;
+ if (viewPos > pos - highlightRangeStart)
+ viewPos = pos - highlightRangeStart;
+ if (isRightToLeft())
+ viewPos = -viewPos-size();
+
+ timeline.reset(data.move);
+ if (viewPos != position()) {
+ if (fixupMode != Immediate) {
+ timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
+ data.fixingUp = true;
+ } else {
+ timeline.set(data.move, -viewPos);
+ }
+ }
+ vTime = timeline.time();
} else {
QSGItemViewPrivate::fixup(data, minExtent, maxExtent);
}
@@ -1358,12 +1356,19 @@ void QSGListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent,
}
qreal maxDistance = 0;
qreal dataValue = isRightToLeft() ? -data.move.value()+size() : data.move.value();
+
// -ve velocity means list is moving up/left
if (velocity > 0) {
if (data.move.value() < minExtent) {
- if (snapMode == QSGListView::SnapOneItem) {
- if (FxViewItem *item = isRightToLeft() ? nextVisibleItem() : firstVisibleItem())
- maxDistance = qAbs(item->position() + dataValue);
+ if (snapMode == QSGListView::SnapOneItem && !hData.flicking && !vData.flicking) {
+ // if we've been dragged < averageSize/2 then bias towards the next item
+ qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
+ qreal bias = dist < averageSize/2 ? averageSize/2 : 0;
+ if (isRightToLeft())
+ bias = -bias;
+ data.flickTarget = -snapPosAt(-(dataValue - highlightRangeStart) - bias) + highlightRangeStart;
+ maxDistance = qAbs(data.flickTarget - data.move.value());
+ velocity = maxVelocity;
} else {
maxDistance = qAbs(minExtent - data.move.value());
}
@@ -1372,9 +1377,15 @@ void QSGListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent,
data.flickTarget = minExtent;
} else {
if (data.move.value() > maxExtent) {
- if (snapMode == QSGListView::SnapOneItem) {
- if (FxViewItem *item = isRightToLeft() ? firstVisibleItem() : nextVisibleItem())
- maxDistance = qAbs(item->position() + dataValue);
+ if (snapMode == QSGListView::SnapOneItem && !hData.flicking && !vData.flicking) {
+ // if we've been dragged < averageSize/2 then bias towards the next item
+ qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
+ qreal bias = -dist < averageSize/2 ? averageSize/2 : 0;
+ if (isRightToLeft())
+ bias = -bias;
+ data.flickTarget = -snapPosAt(-(dataValue - highlightRangeStart) + bias) + highlightRangeStart;
+ maxDistance = qAbs(data.flickTarget - data.move.value());
+ velocity = -maxVelocity;
} else {
maxDistance = qAbs(maxExtent - data.move.value());
}
@@ -1383,7 +1394,6 @@ void QSGListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent,
data.flickTarget = maxExtent;
}
bool overShoot = boundsBehavior == QSGFlickable::DragAndOvershootBounds;
- qreal highlightStart = isRightToLeft() && highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart;
if (maxDistance > 0 || overShoot) {
// These modes require the list to stop exactly on an item boundary.
// The initial flick will estimate the boundary to stop on.
@@ -1396,7 +1406,7 @@ void QSGListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent,
else
v = maxVelocity;
}
- if (!flickingHorizontally && !flickingVertically) {
+ if (!hData.flicking && !vData.flicking) {
// the initial flick - estimate boundary
qreal accel = deceleration;
qreal v2 = v * v;
@@ -1408,8 +1418,10 @@ void QSGListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent,
if (v > 0)
dist = -dist;
if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QSGListView::SnapOneItem) {
- qreal distTemp = isRightToLeft() ? -dist : dist;
- data.flickTarget = -snapPosAt(-(dataValue - highlightStart) + distTemp) + highlightStart;
+ if (snapMode != QSGListView::SnapOneItem) {
+ qreal distTemp = isRightToLeft() ? -dist : dist;
+ data.flickTarget = -snapPosAt(-(dataValue - highlightRangeStart) + distTemp) + highlightRangeStart;
+ }
data.flickTarget = isRightToLeft() ? -data.flickTarget+size() : data.flickTarget;
if (overShoot) {
if (data.flickTarget >= minExtent) {
@@ -1446,14 +1458,14 @@ void QSGListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent,
timeline.reset(data.move);
timeline.accel(data.move, v, accel, maxDistance + overshootDist);
timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this));
- if (!flickingHorizontally && q->xflick()) {
- flickingHorizontally = true;
+ if (!hData.flicking && q->xflick()) {
+ hData.flicking = true;
emit q->flickingChanged();
emit q->flickingHorizontallyChanged();
emit q->flickStarted();
}
- if (!flickingVertically && q->yflick()) {
- flickingVertically = true;
+ if (!vData.flicking && q->yflick()) {
+ vData.flicking = true;
emit q->flickingChanged();
emit q->flickingVerticallyChanged();
emit q->flickStarted();
@@ -1464,7 +1476,7 @@ void QSGListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent,
qreal newtarget = data.flickTarget;
if (snapMode != QSGListView::NoSnap || highlightRange == QSGListView::StrictlyEnforceRange) {
qreal tempFlickTarget = isRightToLeft() ? -data.flickTarget+size() : data.flickTarget;
- newtarget = -snapPosAt(-(tempFlickTarget - highlightStart)) + highlightStart;
+ newtarget = -snapPosAt(-(tempFlickTarget - highlightRangeStart)) + highlightRangeStart;
newtarget = isRightToLeft() ? -newtarget+size() : newtarget;
}
if (velocity < 0 && newtarget <= maxExtent)
@@ -2141,29 +2153,17 @@ void QSGListView::viewportMoved()
d->inViewportMoved = true;
d->lazyRelease = true;
d->refill();
- if (d->flickingHorizontally || d->flickingVertically || d->movingHorizontally || d->movingVertically)
+ if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving)
d->moveReason = QSGListViewPrivate::Mouse;
if (d->moveReason != QSGListViewPrivate::SetIndex) {
if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) {
// reposition highlight
qreal pos = d->highlight->position();
- qreal viewPos;
- qreal highlightStart;
- qreal highlightEnd;
- if (d->isRightToLeft()) {
- // Handle Right-To-Left exceptions
- viewPos = -d->position()-d->size();
- highlightStart = d->highlightRangeStartValid ? d->size()-d->highlightRangeEnd : d->highlightRangeStart;
- highlightEnd = d->highlightRangeEndValid ? d->size()-d->highlightRangeStart : d->highlightRangeEnd;
- } else {
- viewPos = d->position();
- highlightStart = d->highlightRangeStart;
- highlightEnd = d->highlightRangeEnd;
- }
- if (pos > viewPos + highlightEnd - d->highlight->size())
- pos = viewPos + highlightEnd - d->highlight->size();
- if (pos < viewPos + highlightStart)
- pos = viewPos + highlightStart;
+ qreal viewPos = d->isRightToLeft() ? -d->position()-d->size() : d->position();
+ if (pos > viewPos + d->highlightRangeEnd - d->highlight->size())
+ pos = viewPos + d->highlightRangeEnd - d->highlight->size();
+ if (pos < viewPos + d->highlightRangeStart)
+ pos = viewPos + d->highlightRangeStart;
if (pos != d->highlight->position()) {
d->highlightPosAnimator->stop();
static_cast<FxListItemSG*>(d->highlight)->setPosition(pos);
@@ -2179,7 +2179,7 @@ void QSGListView::viewportMoved()
}
}
- if ((d->flickingHorizontally || d->flickingVertically) && d->correctFlick && !d->inFlickCorrection) {
+ if ((d->hData.flicking || d->vData.flicking) && d->correctFlick && !d->inFlickCorrection) {
d->inFlickCorrection = true;
// Near an end and it seems that the extent has changed?
// Recalculate the flick so that we don't end up in an odd position.
@@ -2323,7 +2323,7 @@ void QSGListView::updateSections()
}
}
-bool QSGListViewPrivate::applyInsertionChange(const QDeclarativeChangeSet::Insert &change, QList<FxViewItem *> *movedBackwards, QList<FxViewItem *> *addedItems, FxViewItem *firstVisible)
+bool QSGListViewPrivate::applyInsertionChange(const QDeclarativeChangeSet::Insert &change, FxViewItem *firstVisible, InsertionsResult *insertResult)
{
Q_Q(QSGListView);
@@ -2366,27 +2366,34 @@ bool QSGListViewPrivate::applyInsertionChange(const QDeclarativeChangeSet::Inser
: visibleItems.last()->endPosition()+spacing;
}
- int prevAddedCount = addedItems->count();
+ int prevAddedCount = insertResult->addedItems.count();
if (firstVisible && pos < firstVisible->position()) {
// Insert items before the visible item.
int insertionIdx = index;
int i = 0;
int from = tempPos - buffer;
- for (i = count-1; i >= 0 && pos > from; --i) {
- FxViewItem *item = 0;
- if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i)))) {
- if (item->index > modelIndex + i)
- movedBackwards->append(item);
- item->index = modelIndex + i;
- }
- if (!item)
- item = createItem(modelIndex + i);
+ for (i = count-1; i >= 0; --i) {
+ if (pos > from) {
+ insertResult->sizeAddedBeforeVisible += averageSize;
+ pos -= averageSize;
+ } else {
+ FxViewItem *item = 0;
+ if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i)))) {
+ if (item->index > modelIndex + i)
+ insertResult->movedBackwards.append(item);
+ item->index = modelIndex + i;
+ }
+ if (!item)
+ item = createItem(modelIndex + i);
- visibleItems.insert(insertionIdx, item);
- if (!change.isMove())
- addedItems->append(item);
- pos -= item->size() + spacing;
+ visibleItems.insert(insertionIdx, item);
+ if (!change.isMove()) {
+ insertResult->addedItems.append(item);
+ insertResult->sizeAddedBeforeVisible += item->size();
+ }
+ pos -= item->size() + spacing;
+ }
index++;
}
} else {
@@ -2396,7 +2403,7 @@ bool QSGListViewPrivate::applyInsertionChange(const QDeclarativeChangeSet::Inser
FxViewItem *item = 0;
if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i)))) {
if (item->index > modelIndex + i)
- movedBackwards->append(item);
+ insertResult->movedBackwards.append(item);
item->index = modelIndex + i;
}
if (!item)
@@ -2404,7 +2411,7 @@ bool QSGListViewPrivate::applyInsertionChange(const QDeclarativeChangeSet::Inser
visibleItems.insert(index, item);
if (!change.isMove())
- addedItems->append(item);
+ insertResult->addedItems.append(item);
pos += item->size() + spacing;
++index;
}
@@ -2416,7 +2423,9 @@ bool QSGListViewPrivate::applyInsertionChange(const QDeclarativeChangeSet::Inser
item->index += count;
}
- return addedItems->count() > prevAddedCount;
+ updateVisibleIndex();
+
+ return insertResult->addedItems.count() > prevAddedCount;
}
diff --git a/src/declarative/items/qsgloader.cpp b/src/declarative/items/qsgloader.cpp
index 0a0a3b9cc5..e655e179cd 100644
--- a/src/declarative/items/qsgloader.cpp
+++ b/src/declarative/items/qsgloader.cpp
@@ -53,13 +53,15 @@
QT_BEGIN_NAMESPACE
QSGLoaderPrivate::QSGLoaderPrivate()
- : item(0), component(0), ownComponent(false), updatingSize(false),
- itemWidthValid(false), itemHeightValid(false), active(true)
+ : item(0), component(0), itemContext(0), incubator(0), updatingSize(false),
+ itemWidthValid(false), itemHeightValid(false),
+ active(true), loadingFromSource(false), asynchronous(false)
{
}
QSGLoaderPrivate::~QSGLoaderPrivate()
{
+ delete incubator;
disposeInitialPropertyValues();
}
@@ -79,10 +81,12 @@ void QSGLoaderPrivate::clear()
{
disposeInitialPropertyValues();
- if (ownComponent) {
+ if (incubator)
+ incubator->clear();
+
+ if (loadingFromSource && component) {
component->deleteLater();
component = 0;
- ownComponent = false;
}
source = QUrl();
@@ -266,7 +270,6 @@ void QSGLoader::setActive(bool newVal)
} else {
loadFromSourceComponent();
}
- d->disposeInitialPropertyValues(); // release persistent handles
} else {
if (d->item) {
QSGItemPrivate *p = QSGItemPrivate::get(d->item);
@@ -340,11 +343,10 @@ void QSGLoader::loadFromSource()
return;
}
- d->component = new QDeclarativeComponent(qmlEngine(this), d->source, this);
- d->ownComponent = true;
-
- if (isComponentComplete())
+ if (isComponentComplete()) {
+ d->component = new QDeclarativeComponent(qmlEngine(this), d->source, this);
d->load();
+ }
}
/*!
@@ -384,7 +386,6 @@ void QSGLoader::setSourceComponent(QDeclarativeComponent *comp)
d->clear();
d->component = comp;
- d->ownComponent = false;
d->loadingFromSource = false;
if (d->active)
@@ -489,6 +490,7 @@ void QSGLoader::setSource(QDeclarativeV8Function *args)
d->clear();
QUrl sourceUrl = d->resolveSourceUrl(args);
if (!ipv.IsEmpty()) {
+ d->disposeInitialPropertyValues();
d->initialPropertyValues = qPersistentNew(ipv);
d->qmlGlobalForIpv = qPersistentNew(args->qmlGlobal());
}
@@ -520,7 +522,7 @@ void QSGLoaderPrivate::load()
q, SIGNAL(progressChanged()));
emit q->statusChanged();
emit q->progressChanged();
- if (ownComponent)
+ if (loadingFromSource)
emit q->sourceChanged();
else
emit q->sourceComponentChanged();
@@ -528,69 +530,106 @@ void QSGLoaderPrivate::load()
}
}
-void QSGLoaderPrivate::_q_sourceLoaded()
+void QSGLoaderIncubator::setInitialState(QObject *o)
+{
+ loader->setInitialState(o);
+}
+
+void QSGLoaderPrivate::setInitialState(QObject *obj)
{
Q_Q(QSGLoader);
- if (component) {
- if (!component->errors().isEmpty()) {
- QDeclarativeEnginePrivate::warning(qmlEngine(q), component->errors());
- if (ownComponent)
- emit q->sourceChanged();
- else
- emit q->sourceComponentChanged();
- emit q->statusChanged();
- emit q->progressChanged();
- return;
- }
+ QSGItem *item = qobject_cast<QSGItem*>(obj);
+ if (item) {
+ QDeclarative_setParent_noEvent(itemContext, obj);
+ QDeclarative_setParent_noEvent(item, q);
+ item->setParentItem(q);
+ }
- QDeclarativeContext *creationContext = component->creationContext();
- if (!creationContext) creationContext = qmlContext(q);
- QDeclarativeContext *ctxt = new QDeclarativeContext(creationContext);
- ctxt->setContextObject(q);
-
- QDeclarativeGuard<QDeclarativeComponent> c = component;
- QObject *obj = component->beginCreate(ctxt);
- if (component != c) {
- // component->create could trigger a change in source that causes
- // component to be set to something else. In that case we just
- // need to cleanup.
- if (c)
- completeCreateWithInitialPropertyValues(c, obj, initialPropertyValues, qmlGlobalForIpv);
- delete obj;
- delete ctxt;
- return;
- }
- if (obj) {
- item = qobject_cast<QSGItem *>(obj);
- if (item) {
- QDeclarative_setParent_noEvent(ctxt, obj);
- QDeclarative_setParent_noEvent(item, q);
- item->setParentItem(q);
-// item->setFocus(true);
- initResize();
- } else {
- qmlInfo(q) << QSGLoader::tr("Loader does not support loading non-visual elements.");
- delete obj;
- delete ctxt;
- }
+ if (initialPropertyValues.IsEmpty())
+ return;
+
+ QDeclarativeComponentPrivate *d = QDeclarativeComponentPrivate::get(component);
+ Q_ASSERT(d && d->engine);
+ d->initializeObjectWithInitialProperties(qmlGlobalForIpv, initialPropertyValues, obj);
+}
+
+void QSGLoaderIncubator::statusChanged(Status status)
+{
+ loader->incubatorStateChanged(status);
+}
+
+void QSGLoaderPrivate::incubatorStateChanged(QDeclarativeIncubator::Status status)
+{
+ Q_Q(QSGLoader);
+ if (status == QDeclarativeIncubator::Loading || status == QDeclarativeIncubator::Null)
+ return;
+
+ if (status == QDeclarativeIncubator::Ready) {
+ QObject *obj = incubator->object();
+ item = qobject_cast<QSGItem*>(obj);
+ if (item) {
+ initResize();
} else {
- if (!component->errors().isEmpty())
- QDeclarativeEnginePrivate::warning(qmlEngine(q), component->errors());
+ qmlInfo(q) << QSGLoader::tr("Loader does not support loading non-visual elements.");
+ delete itemContext;
+ itemContext = 0;
delete obj;
- delete ctxt;
- source = QUrl();
}
- completeCreateWithInitialPropertyValues(component, obj, initialPropertyValues, qmlGlobalForIpv);
- if (ownComponent)
+ } else if (status == QDeclarativeIncubator::Error) {
+ if (!incubator->errors().isEmpty())
+ QDeclarativeEnginePrivate::warning(qmlEngine(q), incubator->errors());
+ delete itemContext;
+ itemContext = 0;
+ delete incubator->object();
+ source = QUrl();
+ }
+ if (loadingFromSource)
+ emit q->sourceChanged();
+ else
+ emit q->sourceComponentChanged();
+ emit q->statusChanged();
+ emit q->progressChanged();
+ emit q->itemChanged();
+ emit q->loaded();
+ disposeInitialPropertyValues(); // cleanup
+}
+
+void QSGLoaderPrivate::_q_sourceLoaded()
+{
+ Q_Q(QSGLoader);
+ if (!component || !component->errors().isEmpty()) {
+ if (component)
+ QDeclarativeEnginePrivate::warning(qmlEngine(q), component->errors());
+ if (loadingFromSource)
emit q->sourceChanged();
else
emit q->sourceComponentChanged();
emit q->statusChanged();
emit q->progressChanged();
- emit q->itemChanged();
- emit q->loaded();
+ disposeInitialPropertyValues(); // cleanup
+ return;
}
+
+ QDeclarativeContext *creationContext = component->creationContext();
+ if (!creationContext) creationContext = qmlContext(q);
+ itemContext = new QDeclarativeContext(creationContext);
+ itemContext->setContextObject(q);
+
+ if (incubator) {
+ bool async = incubator->incubationMode() == QDeclarativeIncubator::Asynchronous;
+ if (asynchronous != async) {
+ delete incubator;
+ incubator = 0;
+ }
+ }
+ if (!incubator)
+ incubator = new QSGLoaderIncubator(this, asynchronous ? QDeclarativeIncubator::Asynchronous : QDeclarativeIncubator::AsynchronousIfNested);
+
+ component->create(*incubator, itemContext);
+
+ if (incubator->status() == QDeclarativeIncubator::Loading)
+ emit q->statusChanged();
}
/*!
@@ -640,8 +679,29 @@ QSGLoader::Status QSGLoader::status() const
if (!d->active)
return Null;
- if (d->component)
- return static_cast<QSGLoader::Status>(d->component->status());
+ if (d->component) {
+ switch (d->component->status()) {
+ case QDeclarativeComponent::Loading:
+ return Loading;
+ case QDeclarativeComponent::Error:
+ return Error;
+ case QDeclarativeComponent::Null:
+ return Null;
+ default:
+ break;
+ }
+ }
+
+ if (d->incubator) {
+ switch (d->incubator->status()) {
+ case QDeclarativeIncubator::Loading:
+ return Loading;
+ case QDeclarativeIncubator::Error:
+ return Error;
+ default:
+ break;
+ }
+ }
if (d->item)
return Ready;
@@ -653,7 +713,12 @@ void QSGLoader::componentComplete()
{
Q_D(QSGLoader);
QSGItem::componentComplete();
- d->load();
+ if (active()) {
+ if (d->loadingFromSource) {
+ d->component = new QDeclarativeComponent(qmlEngine(this), d->source, this);
+ }
+ d->load();
+ }
}
/*!
@@ -686,6 +751,30 @@ qreal QSGLoader::progress() const
return 0.0;
}
+/*!
+\qmlproperty bool QtQuick2::Loader::asynchronous
+
+This property holds whether the component will be instantiated asynchronously.
+
+Note that this property affects object instantiation only; it is unrelated to
+loading a component asynchronously via a network.
+*/
+bool QSGLoader::asynchronous() const
+{
+ Q_D(const QSGLoader);
+ return d->asynchronous;
+}
+
+void QSGLoader::setAsynchronous(bool a)
+{
+ Q_D(QSGLoader);
+ if (d->asynchronous == a)
+ return;
+
+ d->asynchronous = a;
+ emit asynchronousChanged();
+}
+
void QSGLoaderPrivate::_q_updateSize(bool loaderGeometryChanged)
{
Q_Q(QSGLoader);
@@ -759,18 +848,6 @@ v8::Handle<v8::Object> QSGLoaderPrivate::extractInitialPropertyValues(QDeclarati
return valuemap;
}
-void QSGLoaderPrivate::completeCreateWithInitialPropertyValues(QDeclarativeComponent *component, QObject *object, v8::Handle<v8::Object> initialPropertyValues, v8::Handle<v8::Object> qmlGlobal)
-{
- if (initialPropertyValues.IsEmpty()) {
- component->completeCreate();
- return;
- }
-
- QDeclarativeComponentPrivate *d = QDeclarativeComponentPrivate::get(component);
- Q_ASSERT(d && d->engine);
- d->completeCreateObjectWithInitialProperties(qmlGlobal, initialPropertyValues, object);
-}
-
#include <moc_qsgloader_p.cpp>
QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgloader_p.h b/src/declarative/items/qsgloader_p.h
index c3ce1607e0..3a41e79915 100644
--- a/src/declarative/items/qsgloader_p.h
+++ b/src/declarative/items/qsgloader_p.h
@@ -63,6 +63,7 @@ class Q_AUTOTEST_EXPORT QSGLoader : public QSGImplicitSizeItem
Q_PROPERTY(QSGItem *item READ item NOTIFY itemChanged)
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
+ Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged)
public:
QSGLoader(QSGItem *parent = 0);
@@ -84,6 +85,9 @@ public:
Status status() const;
qreal progress() const;
+ bool asynchronous() const;
+ void setAsynchronous(bool a);
+
QSGItem *item() const;
Q_SIGNALS:
@@ -94,6 +98,7 @@ Q_SIGNALS:
void statusChanged();
void progressChanged();
void loaded();
+ void asynchronousChanged();
protected:
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
diff --git a/src/declarative/items/qsgloader_p_p.h b/src/declarative/items/qsgloader_p_p.h
index 732ec8679d..36059ca51a 100644
--- a/src/declarative/items/qsgloader_p_p.h
+++ b/src/declarative/items/qsgloader_p_p.h
@@ -57,11 +57,27 @@
#include "qsgloader_p.h"
#include "qsgimplicitsizeitem_p_p.h"
#include "qsgitemchangelistener_p.h"
+#include <qdeclarativeincubator.h>
#include <private/qv8_p.h>
QT_BEGIN_NAMESPACE
+
+class QSGLoaderPrivate;
+class QSGLoaderIncubator : public QDeclarativeIncubator
+{
+public:
+ QSGLoaderIncubator(QSGLoaderPrivate *l, IncubationMode mode) : QDeclarativeIncubator(mode), loader(l) {}
+
+protected:
+ virtual void statusChanged(Status);
+ virtual void setInitialState(QObject *);
+
+private:
+ QSGLoaderPrivate *loader;
+};
+
class QDeclarativeContext;
class QSGLoaderPrivate : public QSGImplicitSizeItemPrivate, public QSGItemChangeListener
{
@@ -76,22 +92,25 @@ public:
void initResize();
void load();
+ void incubatorStateChanged(QDeclarativeIncubator::Status status);
+ void setInitialState(QObject *o);
void disposeInitialPropertyValues();
QUrl resolveSourceUrl(QDeclarativeV8Function *args);
v8::Handle<v8::Object> extractInitialPropertyValues(QDeclarativeV8Function *args, QObject *loader, bool *error);
- void completeCreateWithInitialPropertyValues(QDeclarativeComponent *component, QObject *object, v8::Handle<v8::Object> initialPropertyValues, v8::Handle<v8::Object> qmlGlobal);
QUrl source;
QSGItem *item;
QDeclarativeComponent *component;
+ QDeclarativeContext *itemContext;
+ QSGLoaderIncubator *incubator;
v8::Persistent<v8::Object> initialPropertyValues;
v8::Persistent<v8::Object> qmlGlobalForIpv;
- bool ownComponent : 1;
bool updatingSize: 1;
bool itemWidthValid : 1;
bool itemHeightValid : 1;
bool active : 1;
bool loadingFromSource : 1;
+ bool asynchronous : 1;
void _q_sourceLoaded();
void _q_updateSize(bool loaderGeometryChanged = true);
diff --git a/src/declarative/items/qsgmousearea.cpp b/src/declarative/items/qsgmousearea.cpp
index cae0be60c5..a401b52e95 100644
--- a/src/declarative/items/qsgmousearea.cpp
+++ b/src/declarative/items/qsgmousearea.cpp
@@ -42,8 +42,8 @@
#include "qsgmousearea_p.h"
#include "qsgmousearea_p_p.h"
#include "qsgcanvas.h"
-#include "qsgevent.h"
#include "qsgevents_p_p.h"
+#include "qsgdrag_p.h"
#include <QtGui/qevent.h>
#include <QtGui/qguiapplication.h>
@@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE
static const int PressAndHoldDelay = 800;
QSGDrag::QSGDrag(QObject *parent)
-: QObject(parent), _target(0), _dropItem(0), _grabItem(0), _axis(XandYAxis), _xmin(-FLT_MAX),
+: QObject(parent), _target(0), _axis(XandYAxis), _xmin(-FLT_MAX),
_xmax(FLT_MAX), _ymin(-FLT_MAX), _ymax(FLT_MAX), _active(false), _filterChildren(false)
{
}
@@ -85,64 +85,6 @@ void QSGDrag::resetTarget()
emit targetChanged();
}
-/*!
- \qmlproperty Item QtQuick2::MouseArea::drag.dropItem
-
- This property holds the item an active drag will be dropped on if released
- at the current position.
-*/
-
-QSGItem *QSGDrag::dropItem() const
-{
- return _dropItem;
-}
-
-void QSGDrag::setDropItem(QSGItem *item)
-{
- if (_dropItem != item) {
- _dropItem = item;
- emit dropItemChanged();
- }
-}
-
-QSGItem *QSGDrag::grabItem() const
-{
- return _grabItem;
-}
-
-void QSGDrag::setGrabItem(QSGItem *item)
-{
- _grabItem = item;
-}
-
-/*!
- \qmlproperty variant QtQuick2::MouseArea::drag.data
-
- This property holds the data sent to recipients of drag events generated
- by a MouseArea.
-*/
-
-QVariant QSGDrag::data() const
-{
- return _data;
-}
-
-void QSGDrag::setData(const QVariant &data)
-{
- if (_data != data) {
- _data = data;
- emit dataChanged();
- }
-}
-
-void QSGDrag::resetData()
-{
- if (!_data.isNull()) {
- _data = QVariant();
- emit dataChanged();
- }
-}
-
QSGDrag::Axis QSGDrag::axis() const
{
return _axis;
@@ -234,29 +176,14 @@ void QSGDrag::setFilterChildren(bool filter)
emit filterChildrenChanged();
}
-/*!
- \qmlproperty stringlist QtQuick2::MouseArea::drag.keys
-
- This property holds a list of keys drag recipients can use to identify the
- source or data type of a drag event.
-*/
-
-QStringList QSGDrag::keys() const
+QSGDragAttached *QSGDrag::qmlAttachedProperties(QObject *obj)
{
- return _keys;
-}
-
-void QSGDrag::setKeys(const QStringList &keys)
-{
- if (_keys != keys) {
- _keys = keys;
- emit keysChanged();
- }
+ return new QSGDragAttached(obj);
}
QSGMouseAreaPrivate::QSGMouseAreaPrivate()
: absorb(true), hovered(false), pressed(false), longPress(false),
- moved(false), stealMouse(false), doubleClick(false), preventStealing(false), dragRejected(false),
+ moved(false), stealMouse(false), doubleClick(false), preventStealing(false),
drag(0)
{
}
@@ -336,7 +263,7 @@ bool QSGMouseAreaPrivate::propagateHelper(QSGMouseEvent *ev, QSGItem *item,const
QSGMouseArea* ma = qobject_cast<QSGMouseArea*>(item);
if (ma && ma != q && itemPrivate->acceptedMouseButtons & ev->button()) {
- switch(sig){
+ switch (sig) {
case Click:
if (!ma->d_func()->isClickConnected())
return false;
@@ -355,7 +282,7 @@ bool QSGMouseAreaPrivate::propagateHelper(QSGMouseEvent *ev, QSGItem *item,const
ev->setX(p.x());
ev->setY(p.y());
ev->setAccepted(true);//It is connected, they have to explicitly ignore to let it slide
- switch(sig){
+ switch (sig) {
case Click: emit ma->clicked(ev); break;
case DoubleClick: emit ma->doubleClicked(ev); break;
case PressAndHold: emit ma->pressAndHold(ev); break;
@@ -708,7 +635,6 @@ void QSGMouseArea::mousePressEvent(QMouseEvent *event)
QSGItem::mousePressEvent(event);
else {
d->longPress = false;
- d->dragRejected = false;
d->saveEvent(event);
if (d->drag) {
d->dragX = drag()->axis() & QSGDrag::XAxis;
@@ -744,7 +670,6 @@ void QSGMouseArea::mouseMoveEvent(QMouseEvent *event)
setHovered(true);
if (d->drag && d->drag->target()) {
-
if (!d->moved) {
d->targetStartPos = d->drag->target()->parentItem()
? d->drag->target()->parentItem()->mapToScene(d->drag->target()->pos())
@@ -765,36 +690,22 @@ void QSGMouseArea::mouseMoveEvent(QMouseEvent *event)
qreal dx = qAbs(curLocalPos.x() - startLocalPos.x());
qreal dy = qAbs(curLocalPos.y() - startLocalPos.y());
- if (keepMouseGrab() && d->stealMouse && !d->dragRejected && !d->drag->active()) {
- QSGMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress);
- d->drag->emitDragged(&me);
- if (me.isAccepted()) {
- d->drag->setActive(true);
- QSGDragEvent dragEvent(
- QSGEvent::SGDragEnter,
- d->startScene,
- d->drag->data(),
- d->drag->keys());
- QCoreApplication::sendEvent(canvas(), &dragEvent);
-
- d->drag->setGrabItem(dragEvent.grabItem());
- d->drag->setDropItem(dragEvent.dropItem());
- } else {
- d->dragRejected = true;
- }
- }
+ if (keepMouseGrab() && d->stealMouse && !d->drag->active())
+ d->drag->setActive(true);
QPointF startPos = d->drag->target()->parentItem()
? d->drag->target()->parentItem()->mapFromScene(d->targetStartPos)
: d->targetStartPos;
+ QPointF dragPos = d->drag->target()->pos();
+
if (d->dragX && d->drag->active()) {
qreal x = (curLocalPos.x() - startLocalPos.x()) + startPos.x();
if (x < drag()->xmin())
x = drag()->xmin();
else if (x > drag()->xmax())
x = drag()->xmax();
- drag()->target()->setX(x);
+ dragPos.setX(x);
}
if (d->dragY && d->drag->active()) {
qreal y = (curLocalPos.y() - startLocalPos.y()) + startPos.y();
@@ -802,8 +713,9 @@ void QSGMouseArea::mouseMoveEvent(QMouseEvent *event)
y = drag()->ymin();
else if (y > drag()->ymax())
y = drag()->ymax();
- drag()->target()->setY(y);
+ dragPos.setY(y);
}
+ d->drag->target()->setPos(dragPos);
if (!keepMouseGrab()) {
if ((!d->dragY && dy < dragThreshold && d->dragX && dx > dragThreshold)
@@ -815,18 +727,6 @@ void QSGMouseArea::mouseMoveEvent(QMouseEvent *event)
}
d->moved = true;
-
- if (d->drag->active()) {
- QSGDragEvent dragEvent(
- QSGEvent::SGDragMove,
- event->windowPos(),
- d->drag->data(),
- d->drag->keys(),
- d->drag->grabItem());
- QCoreApplication::sendEvent(canvas(), &dragEvent);
- d->drag->setGrabItem(dragEvent.grabItem());
- d->drag->setDropItem(dragEvent.dropItem());
- }
}
QSGMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress);
emit mouseXChanged(&me);
@@ -845,24 +745,8 @@ void QSGMouseArea::mouseReleaseEvent(QMouseEvent *event)
} else {
d->saveEvent(event);
setPressed(false);
- if (d->drag && d->drag->active()) {
- QSGDragEvent dragEvent(
- QSGEvent::SGDragDrop,
- event->windowPos(),
- d->drag->data(),
- d->drag->keys(),
- d->drag->grabItem());
- QCoreApplication::sendEvent(canvas(), &dragEvent);
- d->drag->setGrabItem(0);
- if (dragEvent.isAccepted()) {
- d->drag->setDropItem(dragEvent.dropItem());
- d->drag->emitDropped(dragEvent.dropItem());
- } else {
- d->drag->emitCanceled();
- }
- d->drag->setDropItem(0);
+ if (d->drag)
d->drag->setActive(false);
- }
// If we don't accept hover, we need to reset containsMouse.
if (!acceptHoverEvents())
setHovered(false);
diff --git a/src/declarative/items/qsgmousearea_p.h b/src/declarative/items/qsgmousearea_p.h
index 0ec9c6b335..f0edf41777 100644
--- a/src/declarative/items/qsgmousearea_p.h
+++ b/src/declarative/items/qsgmousearea_p.h
@@ -53,6 +53,7 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
+class QSGDragAttached;
class QSGMouseEvent;
class Q_AUTOTEST_EXPORT QSGDrag : public QObject
{
@@ -60,8 +61,6 @@ class Q_AUTOTEST_EXPORT QSGDrag : public QObject
Q_ENUMS(Axis)
Q_PROPERTY(QSGItem *target READ target WRITE setTarget NOTIFY targetChanged RESET resetTarget)
- Q_PROPERTY(QSGItem *dropItem READ dropItem NOTIFY dropItemChanged)
- Q_PROPERTY(QVariant data READ data WRITE setData NOTIFY dataChanged RESET resetData)
Q_PROPERTY(Axis axis READ axis WRITE setAxis NOTIFY axisChanged)
Q_PROPERTY(qreal minimumX READ xmin WRITE setXmin NOTIFY minimumXChanged)
Q_PROPERTY(qreal maximumX READ xmax WRITE setXmax NOTIFY maximumXChanged)
@@ -69,7 +68,6 @@ class Q_AUTOTEST_EXPORT QSGDrag : public QObject
Q_PROPERTY(qreal maximumY READ ymax WRITE setYmax NOTIFY maximumYChanged)
Q_PROPERTY(bool active READ active NOTIFY activeChanged)
Q_PROPERTY(bool filterChildren READ filterChildren WRITE setFilterChildren NOTIFY filterChildrenChanged)
- Q_PROPERTY(QStringList keys READ keys WRITE setKeys NOTIFY keysChanged)
//### consider drag and drop
public:
@@ -77,19 +75,9 @@ public:
~QSGDrag();
QSGItem *target() const;
- void setTarget(QSGItem *);
+ void setTarget(QSGItem *target);
void resetTarget();
- QSGItem *dropItem() const;
- void setDropItem(QSGItem *item);
-
- QSGItem *grabItem() const;
- void setGrabItem(QSGItem *grabItem);
-
- QVariant data() const;
- void setData(const QVariant &data);
- void resetData();
-
enum Axis { XAxis=0x01, YAxis=0x02, XandYAxis=0x03 };
Axis axis() const;
void setAxis(Axis);
@@ -109,17 +97,10 @@ public:
bool filterChildren() const;
void setFilterChildren(bool);
- QStringList keys() const;
- void setKeys(const QStringList &keys);
-
- void emitDragged(QSGMouseEvent *event) { emit dragged(event); }
- void emitDropped(QSGItem *dropItem) { emit dropped(dropItem); }
- void emitCanceled() { emit canceled(); }
+ static QSGDragAttached *qmlAttachedProperties(QObject *obj);
Q_SIGNALS:
void targetChanged();
- void dropItemChanged();
- void dataChanged();
void axisChanged();
void minimumXChanged();
void maximumXChanged();
@@ -127,17 +108,9 @@ Q_SIGNALS:
void maximumYChanged();
void activeChanged();
void filterChildrenChanged();
- void keysChanged();
- void dragged(QSGMouseEvent *mouse);
- void dropped(QSGItem *dropItem);
- void canceled();
private:
- QStringList _keys;
- QVariant _data;
QSGItem *_target;
- QSGItem *_dropItem;
- QSGItem *_grabItem;
Axis _axis;
qreal _xmin;
qreal _xmax;
@@ -149,7 +122,8 @@ private:
};
class QSGMouseAreaPrivate;
-class Q_AUTOTEST_EXPORT QSGMouseArea : public QSGItem
+// used in QtLocation
+class Q_DECLARATIVE_EXPORT QSGMouseArea : public QSGItem
{
Q_OBJECT
@@ -244,6 +218,7 @@ private:
QT_END_NAMESPACE
QML_DECLARE_TYPE(QSGDrag)
+QML_DECLARE_TYPEINFO(QSGDrag, QML_HAS_ATTACHED_PROPERTIES)
QML_DECLARE_TYPE(QSGMouseArea)
QT_END_HEADER
diff --git a/src/declarative/items/qsgmousearea_p_p.h b/src/declarative/items/qsgmousearea_p_p.h
index 2ec1eda3f7..6cf663ac6d 100644
--- a/src/declarative/items/qsgmousearea_p_p.h
+++ b/src/declarative/items/qsgmousearea_p_p.h
@@ -95,7 +95,6 @@ public:
bool stealMouse : 1;
bool doubleClick : 1;
bool preventStealing : 1;
- bool dragRejected : 1;
QSGDrag *drag;
QPointF startScene;
QPointF targetStartPos;
diff --git a/src/declarative/items/qsgninepatchnode.cpp b/src/declarative/items/qsgninepatchnode.cpp
index 7be58991df..3658b3cb98 100644
--- a/src/declarative/items/qsgninepatchnode.cpp
+++ b/src/declarative/items/qsgninepatchnode.cpp
@@ -54,6 +54,9 @@ QSGNinePatchNode::QSGNinePatchNode()
setMaterial(&m_materialO);
setGeometry(&m_geometry);
m_geometry.setDrawingMode(GL_TRIANGLES);
+#ifdef QML_RUNTIME_TESTING
+ description = QLatin1String("borderimage");
+#endif
}
void QSGNinePatchNode::setInnerRect(const QRectF &rect)
@@ -142,6 +145,9 @@ void QSGNinePatchNode::update()
float tw = m_material.texture()->textureSize().width();
float th = m_material.texture()->textureSize().height();
+ QRectF textureSubRect = m_material.texture()->textureSubRect();
+ QSize textureSize = m_material.texture()->textureSize();
+
float rightBorder = tw - m_innerRect.right();
float bottomBorder = th - m_innerRect.bottom();
@@ -199,26 +205,26 @@ void QSGNinePatchNode::update()
float yTexChunk1 = m_innerRect.top() / th;
float yTexChunk2 = m_innerRect.bottom() / th;
- fillRow(v, 0, 0, xChunkCount, xChunkSize);
- fillRow(v, m_innerRect.y(), yTexChunk1, xChunkCount, xChunkSize);
+ fillRow(v, 0, 0, xChunkCount, xChunkSize, textureSubRect, textureSize);
+ fillRow(v, m_innerRect.y(), yTexChunk1, xChunkCount, xChunkSize, textureSubRect, textureSize);
for (int yc=0; yc<yChunkCount; ++yc) {
float yy = m_innerRect.y() + yChunkSize * yc;
- fillRow(v, yy, yTexChunk1, xChunkCount, xChunkSize);
+ fillRow(v, yy, yTexChunk1, xChunkCount, xChunkSize, textureSubRect, textureSize);
// Special case the last one
if (yc == yChunkCount - 1) {
float t = m_verticalTileMode == QSGBorderImage::Repeat
? yTexChunk1 + (yTexChunk2 - yTexChunk1) * (m_targetRect.height() - bottomBorder - yy) / yChunkSize
: yTexChunk2;
- fillRow(v, m_targetRect.height() - bottomBorder, t, xChunkCount, xChunkSize);
+ fillRow(v, m_targetRect.height() - bottomBorder, t, xChunkCount, xChunkSize, textureSubRect, textureSize);
} else {
- fillRow(v, yy + yChunkSize, yTexChunk2, xChunkCount, xChunkSize);
+ fillRow(v, yy + yChunkSize, yTexChunk2, xChunkCount, xChunkSize, textureSubRect, textureSize);
}
}
- fillRow(v, m_targetRect.height() - bottomBorder, yTexChunk2, xChunkCount, xChunkSize);
- fillRow(v, m_targetRect.height(), 1, xChunkCount, xChunkSize);
+ fillRow(v, m_targetRect.height() - bottomBorder, yTexChunk2, xChunkCount, xChunkSize, textureSubRect, textureSize);
+ fillRow(v, m_targetRect.height(), 1, xChunkCount, xChunkSize, textureSubRect, textureSize);
if (m_mirror) {
v = m_geometry.vertexDataAsTexturedPoint2D();
@@ -261,14 +267,18 @@ void QSGNinePatchNode::update()
markDirty(QSGNode::DirtyGeometry);
}
-void QSGNinePatchNode::fillRow(QSGGeometry::TexturedPoint2D *&v, float y, float ty, int xChunkCount, float xChunkSize)
+void QSGNinePatchNode::fillRow(QSGGeometry::TexturedPoint2D *&v, float y, float ty, int xChunkCount, float xChunkSize,
+ const QRectF &tsr, // texture sub rect, for atlasses
+ const QSize &ts) // texture size in pixels
{
- float tw = m_material.texture()->textureSize().width();
+ ty = tsr.y() + ty * tsr.width();
+
+ float tw = ts.width();
float rightBorder = tw - m_innerRect.right();
- float xTexChunk1 = m_innerRect.left() / tw;
- float xTexChunk2 = m_innerRect.right() / tw;
+ float xTexChunk1 = tsr.left() + tsr.width() * m_innerRect.left() / tw;
+ float xTexChunk2 = tsr.left() + tsr.width() * m_innerRect.right() / tw;
- v++->set(0, y, 0, ty);
+ v++->set(0, y, tsr.left(), ty);
v++->set(m_innerRect.x(), y, xTexChunk1, ty);
for (int xc=0; xc<xChunkCount; ++xc) {
@@ -288,5 +298,5 @@ void QSGNinePatchNode::fillRow(QSGGeometry::TexturedPoint2D *&v, float y, float
}
v++->set(m_targetRect.width() - rightBorder, y, xTexChunk2, ty);
- v++->set(m_targetRect.width(), y, 1, ty);
+ v++->set(m_targetRect.width(), y, tsr.right(), ty);
}
diff --git a/src/declarative/items/qsgninepatchnode_p.h b/src/declarative/items/qsgninepatchnode_p.h
index 0062d0b8c2..fd0a0c5477 100644
--- a/src/declarative/items/qsgninepatchnode_p.h
+++ b/src/declarative/items/qsgninepatchnode_p.h
@@ -81,7 +81,7 @@ public:
void update();
private:
- void fillRow(QSGGeometry::TexturedPoint2D *&v, float y, float ty, int xChunkCount, float xChunkSize);
+ void fillRow(QSGGeometry::TexturedPoint2D *&v, float y, float ty, int xChunkCount, float xChunkSize, const QRectF &tsr, const QSize &ts);
QRectF m_targetRect;
QRectF m_innerRect;
QSGOpaqueTextureMaterial m_material;
diff --git a/src/declarative/items/qsgpainteditem.cpp b/src/declarative/items/qsgpainteditem.cpp
index 19d2a9a59a..16c3b3df95 100644
--- a/src/declarative/items/qsgpainteditem.cpp
+++ b/src/declarative/items/qsgpainteditem.cpp
@@ -54,6 +54,8 @@ QT_BEGIN_NAMESPACE
\brief The QSGPaintedItem class provides a way to use the QPainter API in the
QML Scene Graph.
+ \inmodule QtDeclarative
+
The QSGPaintedItem makes it possible to use the QPainter API with the QML Scene Graph.
It sets up a textured rectangle in the Scene Graph and uses a QPainter to paint
onto the texture. The render target can be either a QImage or a QOpenGLFramebufferObject.
diff --git a/src/declarative/items/qsgpathview.cpp b/src/declarative/items/qsgpathview.cpp
index 10161e50c1..5e2ad84e3b 100644
--- a/src/declarative/items/qsgpathview.cpp
+++ b/src/declarative/items/qsgpathview.cpp
@@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
inline qreal qmlMod(qreal x, qreal y)
{
#ifdef QT_USE_MATH_H_FLOATS
- if(sizeof(qreal) == sizeof(float))
+ if (sizeof(qreal) == sizeof(float))
return fmodf(float(x), float(y));
else
#endif
@@ -101,16 +101,9 @@ void QSGPathViewPrivate::init()
q->setAcceptedMouseButtons(Qt::LeftButton);
q->setFlag(QSGItem::ItemIsFocusScope);
q->setFiltersChildMouseEvents(true);
- q->connect(&tl, SIGNAL(updated()), q, SLOT(ticked()));
+ FAST_CONNECT(&tl, SIGNAL(updated()), q, SLOT(ticked()))
lastPosTime.invalidate();
- static int timelineCompletedIdx = -1;
- static int movementEndingIdx = -1;
- if (timelineCompletedIdx == -1) {
- timelineCompletedIdx = QDeclarativeTimeLine::staticMetaObject.indexOfSignal("completed()");
- movementEndingIdx = QSGPathView::staticMetaObject.indexOfSlot("movementEnding()");
- }
- QMetaObject::connect(&tl, timelineCompletedIdx,
- q, movementEndingIdx, Qt::DirectConnection);
+ FAST_CONNECT(&tl, SIGNAL(completed()), q, SLOT(movementEnding()))
}
QSGItem *QSGPathViewPrivate::getItem(int modelIndex, bool onPath)
@@ -122,7 +115,7 @@ QSGItem *QSGPathViewPrivate::getItem(int modelIndex, bool onPath)
if (!attType) {
// pre-create one metatype to share with all attached objects
attType = new QDeclarativeOpenMetaObjectType(&QSGPathViewAttached::staticMetaObject, qmlEngine(q));
- foreach(const QString &attr, path->attributes())
+ foreach (const QString &attr, path->attributes())
attType->createProperty(attr.toUtf8());
}
qPathViewAttachedType = attType;
@@ -218,7 +211,9 @@ void QSGPathViewPrivate::createHighlight()
QSGItem *item = 0;
if (highlightComponent) {
- QDeclarativeContext *highlightContext = new QDeclarativeContext(qmlContext(q));
+ QDeclarativeContext *creationContext = highlightComponent->creationContext();
+ QDeclarativeContext *highlightContext = new QDeclarativeContext(
+ creationContext ? creationContext : qmlContext(q));
QObject *nobj = highlightComponent->create(highlightContext);
if (nobj) {
QDeclarative_setParent_noEvent(highlightContext, nobj);
@@ -327,7 +322,7 @@ void QSGPathViewPrivate::updateItem(QSGItem *item, qreal percent)
if (qFuzzyCompare(att->m_percent, percent))
return;
att->m_percent = percent;
- foreach(const QString &attr, path->attributes())
+ foreach (const QString &attr, path->attributes())
att->setValue(attr.toUtf8(), path->attributeAt(attr, percent));
}
QPointF pf = path->pointAt(percent);
@@ -517,6 +512,8 @@ void QSGPathView::setModel(const QVariant &model)
if (!d->ownModel) {
d->model = new QSGVisualDataModel(qmlContext(this));
d->ownModel = true;
+ if (isComponentComplete())
+ static_cast<QSGVisualDataModel *>(d->model.data())->componentComplete();
}
if (QSGVisualDataModel *dataModel = qobject_cast<QSGVisualDataModel*>(d->model))
dataModel->setModel(model);
@@ -1265,7 +1262,7 @@ bool QSGPathView::sendMouseEvent(QMouseEvent *event)
event->button(), event->buttons(), event->modifiers());
mouseEvent.setAccepted(false);
- switch(mouseEvent.type()) {
+ switch (mouseEvent.type()) {
case QEvent::MouseMove:
d->handleMouseMoveEvent(&mouseEvent);
break;
@@ -1332,7 +1329,11 @@ void QSGPathView::updatePolish()
void QSGPathView::componentComplete()
{
Q_D(QSGPathView);
+ if (d->model && d->ownModel)
+ static_cast<QSGVisualDataModel *>(d->model.data())->componentComplete();
+
QSGItem::componentComplete();
+
d->createHighlight();
// It is possible that a refill has already happended to to Path
// bindings being handled in the componentComplete(). If so
@@ -1342,6 +1343,9 @@ void QSGPathView::componentComplete()
d->regenerate();
}
d->updateHighlight();
+
+ if (d->modelCount)
+ emit countChanged();
}
void QSGPathView::refill()
@@ -1577,7 +1581,7 @@ void QSGPathView::createdItem(int index, QSGItem *item)
if (!d->attType) {
// pre-create one metatype to share with all attached objects
d->attType = new QDeclarativeOpenMetaObjectType(&QSGPathViewAttached::staticMetaObject, qmlEngine(this));
- foreach(const QString &attr, d->path->attributes())
+ foreach (const QString &attr, d->path->attributes())
d->attType->createProperty(attr.toUtf8());
}
qPathViewAttachedType = d->attType;
diff --git a/src/declarative/items/qsgpathview_p_p.h b/src/declarative/items/qsgpathview_p_p.h
index 520de429fe..10549d9709 100644
--- a/src/declarative/items/qsgpathview_p_p.h
+++ b/src/declarative/items/qsgpathview_p_p.h
@@ -64,6 +64,7 @@
#include <private/qdeclarativeanimation_p_p.h>
#include <private/qdeclarativeguard_p.h>
+#include <private/qdeclarativetimeline_p_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/items/qsgpincharea.cpp b/src/declarative/items/qsgpincharea.cpp
index d02477ee34..2dbe683f26 100644
--- a/src/declarative/items/qsgpincharea.cpp
+++ b/src/declarative/items/qsgpincharea.cpp
@@ -516,7 +516,7 @@ bool QSGPinchArea::sendMouseEvent(QMouseEvent *event)
event->button(), event->buttons(), event->modifiers());
mouseEvent.setAccepted(false);
- switch(mouseEvent.type()) {
+ switch (mouseEvent.type()) {
case QEvent::MouseMove:
mouseMoveEvent(&mouseEvent);
break;
diff --git a/src/declarative/items/qsgpositioners.cpp b/src/declarative/items/qsgpositioners.cpp
index 0401494d3b..eaca2101e2 100644
--- a/src/declarative/items/qsgpositioners.cpp
+++ b/src/declarative/items/qsgpositioners.cpp
@@ -252,7 +252,7 @@ void QSGBasePositioner::prePositioning()
void QSGBasePositioner::positionX(int x, const PositionedItem &target)
{
Q_D(QSGBasePositioner);
- if(d->type == Horizontal || d->type == Both){
+ if (d->type == Horizontal || d->type == Both) {
if (target.isNew) {
if (!d->addTransition || !d->addTransition->enabled())
target.item->setX(x);
@@ -270,7 +270,7 @@ void QSGBasePositioner::positionX(int x, const PositionedItem &target)
void QSGBasePositioner::positionY(int y, const PositionedItem &target)
{
Q_D(QSGBasePositioner);
- if(d->type == Vertical || d->type == Both){
+ if (d->type == Vertical || d->type == Both) {
if (target.isNew) {
if (!d->addTransition || !d->addTransition->enabled())
target.item->setY(y);
@@ -541,7 +541,7 @@ void QSGColumn::doPositioning(QSizeF *contentSize)
if (!child.item || !child.isVisible)
continue;
- if(child.item->y() != voffset)
+ if (child.item->y() != voffset)
positionY(voffset, child);
contentSize->setWidth(qMax(contentSize->width(), child.item->width()));
@@ -1081,8 +1081,8 @@ void QSGGrid::doPositioning(QSizeF *contentSize)
//Is allocating the extra QPODVector too much overhead?
QPODVector<PositionedItem, 8> visibleItems;//we aren't concerned with invisible items
visibleItems.reserve(positionedItems.count());
- for(int i=0; i<positionedItems.count(); i++)
- if(positionedItems[i].item && positionedItems[i].isVisible)
+ for (int i=0; i<positionedItems.count(); i++)
+ if (positionedItems[i].item && positionedItems[i].isVisible)
visibleItems.append(positionedItems[i]);
int numVisible = visibleItems.count();
@@ -1095,7 +1095,7 @@ void QSGGrid::doPositioning(QSizeF *contentSize)
c = (numVisible+(m_rows-1))/m_rows;
}
- if(r==0 || c==0)
+ if (r==0 || c==0)
return; //Nothing to do
QList<int> maxColWidth;
diff --git a/src/declarative/items/qsgrepeater.cpp b/src/declarative/items/qsgrepeater.cpp
index 0037ea10eb..10adb75893 100644
--- a/src/declarative/items/qsgrepeater.cpp
+++ b/src/declarative/items/qsgrepeater.cpp
@@ -206,6 +206,8 @@ void QSGRepeater::setModel(const QVariant &model)
if (!d->ownModel) {
d->model = new QSGVisualDataModel(qmlContext(this));
d->ownModel = true;
+ if (isComponentComplete())
+ static_cast<QSGVisualDataModel *>(d->model)->componentComplete();
}
if (QSGVisualDataModel *dataModel = qobject_cast<QSGVisualDataModel*>(d->model))
dataModel->setModel(model);
@@ -314,8 +316,13 @@ QSGItem *QSGRepeater::itemAt(int index) const
void QSGRepeater::componentComplete()
{
+ Q_D(QSGRepeater);
+ if (d->model && d->ownModel)
+ static_cast<QSGVisualDataModel *>(d->model)->componentComplete();
QSGItem::componentComplete();
regenerate();
+ if (d->model && d->model->count())
+ emit countChanged();
}
void QSGRepeater::itemChange(ItemChange change, const ItemChangeData &value)
diff --git a/src/declarative/items/qsgscalegrid.cpp b/src/declarative/items/qsgscalegrid.cpp
index e1b76c4158..1c4ce8d289 100644
--- a/src/declarative/items/qsgscalegrid.cpp
+++ b/src/declarative/items/qsgscalegrid.cpp
@@ -129,7 +129,7 @@ QSGGridScaledImage::QSGGridScaledImage(QIODevice *data)
QString imgFile;
QByteArray raw;
- while(raw = data->readLine(), !raw.isEmpty()) {
+ while (raw = data->readLine(), !raw.isEmpty()) {
QString line = QString::fromUtf8(raw.trimmed());
if (line.isEmpty() || line.startsWith(QLatin1Char('#')))
continue;
diff --git a/src/declarative/items/qsgshadereffect.cpp b/src/declarative/items/qsgshadereffect.cpp
index f4ad80ea1e..f84d023906 100644
--- a/src/declarative/items/qsgshadereffect.cpp
+++ b/src/declarative/items/qsgshadereffect.cpp
@@ -49,8 +49,8 @@
#include <private/qsgtextureprovider_p.h>
#include "qsgcanvas.h"
-#include <qsgimage_p.h>
-#include <qsgshadereffectsource_p.h>
+#include "qsgimage_p.h"
+#include "qsgshadereffectsource_p.h"
#include <QtCore/qsignalmapper.h>
#include <QtGui/qopenglframebufferobject.h>
@@ -621,7 +621,7 @@ QSGNode *QSGShaderEffect::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
QVector<QPair<QByteArray, QSGTextureProvider *> > textures;
const QVector<QPair<QByteArray, QSGTextureProvider *> > &oldTextures = material->textureProviders();
- for (QSet<QByteArray>::const_iterator it = m_source.uniformNames.begin();
+ for (QSet<QByteArray>::const_iterator it = m_source.uniformNames.begin();
it != m_source.uniformNames.end(); ++it) {
values.append(qMakePair(*it, property(*it)));
}
diff --git a/src/declarative/items/qsgshadereffect_p.h b/src/declarative/items/qsgshadereffect_p.h
index a8c3f084e4..08af5f6bff 100644
--- a/src/declarative/items/qsgshadereffect_p.h
+++ b/src/declarative/items/qsgshadereffect_p.h
@@ -89,7 +89,7 @@ public:
QByteArray fragmentShader() const { return m_source.fragmentCode; }
void setFragmentShader(const QByteArray &code);
-
+
QByteArray vertexShader() const { return m_source.vertexCode; }
void setVertexShader(const QByteArray &code);
diff --git a/src/declarative/items/qsgshadereffectsource.cpp b/src/declarative/items/qsgshadereffectsource.cpp
index 3b0983863f..4bbabe1701 100644
--- a/src/declarative/items/qsgshadereffectsource.cpp
+++ b/src/declarative/items/qsgshadereffectsource.cpp
@@ -419,7 +419,7 @@ QImage QSGShaderEffectTexture::toImage() const
The complex element can be rendered once into the texture, which can
then be animated freely without the need to render the complex element
again every frame.
- \o an opacity layer.
+ \o an opacity layer.
ShaderEffectSource allows you to apply an opacity to elements as a group
rather than each element individually.
\endlist
diff --git a/src/declarative/items/qsgshadereffectsource_p.h b/src/declarative/items/qsgshadereffectsource_p.h
index 66624126c7..5d65b26cca 100644
--- a/src/declarative/items/qsgshadereffectsource_p.h
+++ b/src/declarative/items/qsgshadereffectsource_p.h
@@ -77,7 +77,7 @@ private Q_SLOTS:
void markDirtyTexture();
};
-class QSGShaderEffectTexture : public QSGDynamicTexture
+class Q_DECLARATIVE_EXPORT QSGShaderEffectTexture : public QSGDynamicTexture
{
Q_OBJECT
public:
@@ -152,7 +152,7 @@ private:
uint m_grab : 1;
};
-class QSGShaderEffectSource : public QSGItem
+class Q_DECLARATIVE_EXPORT QSGShaderEffectSource : public QSGItem
{
Q_OBJECT
Q_PROPERTY(WrapMode wrapMode READ wrapMode WRITE setWrapMode NOTIFY wrapModeChanged)
diff --git a/src/declarative/items/qsgsprite.cpp b/src/declarative/items/qsgsprite.cpp
index 63d1951b7c..afd32a651f 100644
--- a/src/declarative/items/qsgsprite.cpp
+++ b/src/declarative/items/qsgsprite.cpp
@@ -44,12 +44,86 @@
QT_BEGIN_NAMESPACE
+/*!
+ \qmlclass Sprite QSGSprite
+ \inqmlmodule QtQuick 2
+ \brief The Sprite element represents a sprite animation
+
+*/
+/*!
+ \qmlproperty int QtQuick2::Sprite::duration
+
+ Time between frames.
+*/
+/*!
+ \qmlproperty int QtQuick2::Sprite::durationVariation
+
+ The time between frames can vary by up to this amount.
+
+ Default is 0.
+*/
+
+/*!
+ \qmlproperty string QtQuick2::Sprite::name
+
+ The name of this sprite, for use in the to property of other sprites.
+*/
+/*!
+ \qmlproperty QVariantMap QtQuick2::Sprite::to
+
+ A list of other sprites and weighted transitions to them,
+ for example {"a":1, "b":2, "c":0} would specify that one-third should
+ transition to sprite "a" when this sprite is done, and two-thirds should
+ transition to sprite "b" when this sprite is done. As the transitions are
+ chosen randomly, these proportions will not be exact. With "c":0 in the list,
+ no sprites will randomly transition to "c", but it wll be a valid path if a sprite
+ goal is set.
+
+ If no list is specified, or the sum of weights in the list is zero, then the sprite
+ will repeat itself after completing.
+*/
+/*!
+ \qmlproperty int QtQuick2::Sprite::frames
+
+ Number of frames in this sprite.
+*/
+/*!
+ \qmlproperty int QtQuick2::Sprite::frameHeight
+
+ Height of a single frame in this sprite.
+*/
+/*!
+ \qmlproperty int QtQuick2::Sprite::frameWidth
+
+ Width of a single frame in this sprite.
+*/
+/*!
+ \qmlproperty url QtQuick2::Sprite::source
+
+ The image source for the animation.
+
+ If frameHeight and frameWidth are not specified, it is assumed to be a single long row of square frames.
+ Otherwise, it can be multiple contiguous rows or rectangluar frames, when one row runs out the next will be used.
+*/
+ Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
+ Q_PROPERTY(int durationVariation READ durationVariance WRITE setDurationVariance NOTIFY durationVarianceChanged)
+ Q_PROPERTY(QVariantMap to READ to WRITE setTo NOTIFY toChanged)
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+ Q_PROPERTY(qreal speedModifiesDuration READ speedModifer WRITE setSpeedModifier NOTIFY speedModifierChanged)
+ Q_PROPERTY(int frames READ frames WRITE setFrames NOTIFY framesChanged)
+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ //If frame height or width is not specified, it is assumed to be a single long row of square frames.
+ //Otherwise, it can be multiple contiguous rows, when one row runs out the next will be used.
+ Q_PROPERTY(int frameHeight READ frameHeight WRITE setFrameHeight NOTIFY frameHeightChanged)
+ Q_PROPERTY(int frameWidth READ frameWidth WRITE setFrameWidth NOTIFY frameWidthChanged)
+
QSGSprite::QSGSprite(QObject *parent) :
QSGStochasticState(parent)
, m_generatedCount(0)
, m_framesPerRow(0)
, m_frameHeight(0)
, m_frameWidth(0)
+ , m_rowY(0)
{
}
diff --git a/src/declarative/items/qsgsprite_p.h b/src/declarative/items/qsgsprite_p.h
index ed7c6c4be4..58b6c13f97 100644
--- a/src/declarative/items/qsgsprite_p.h
+++ b/src/declarative/items/qsgsprite_p.h
@@ -127,6 +127,7 @@ private:
QUrl m_source;
int m_frameHeight;
int m_frameWidth;
+ int m_rowY;
};
diff --git a/src/declarative/items/qsgspriteengine.cpp b/src/declarative/items/qsgspriteengine.cpp
index f02d229fef..a376a06483 100644
--- a/src/declarative/items/qsgspriteengine.cpp
+++ b/src/declarative/items/qsgspriteengine.cpp
@@ -148,6 +148,28 @@ int QSGSpriteEngine::spriteDuration(int sprite)
return rowDuration;
}
+int QSGSpriteEngine::spriteY(int sprite)
+{
+ int state = m_things[sprite];
+ if (!m_sprites[state]->m_generatedCount)
+ return m_sprites[state]->m_rowY;
+ int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow;
+ int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
+ return m_sprites[state]->m_rowY + m_sprites[state]->m_frameHeight * extra;
+}
+
+int QSGSpriteEngine::spriteWidth(int sprite)
+{
+ int state = m_things[sprite];
+ return m_sprites[state]->m_frameWidth;
+}
+
+int QSGSpriteEngine::spriteHeight(int sprite)
+{
+ int state = m_things[sprite];
+ return m_sprites[state]->m_frameHeight;
+}
+
int QSGSpriteEngine::spriteCount()//TODO: Actually image state count, need to rename these things to make sense together
{
return m_imageStateCount;
@@ -175,12 +197,12 @@ void QSGStochasticEngine::setGoal(int state, int sprite, bool jump)
QImage QSGSpriteEngine::assembledImage()
{
- int frameHeight = 0;
- int frameWidth = 0;
+ int h = 0;
+ int w = 0;
m_maxFrames = 0;
m_imageStateCount = 0;
+ int maxSize = 0;
- int maxSize;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
foreach (QSGStochasticState* s, m_states){
QSGSprite* sprite = qobject_cast<QSGSprite*>(s);
@@ -201,60 +223,48 @@ QImage QSGSpriteEngine::assembledImage()
}
//Check that the frame sizes are the same within one engine
- int imgWidth = state->frameWidth();
- if (!imgWidth)
- imgWidth = img.width() / state->frames();
- if (frameWidth){
- if (imgWidth != frameWidth){
- qWarning() << "SpriteEngine: Irregular frame width..." << state->source().toLocalFile();
- return QImage();
- }
- }else{
- frameWidth = imgWidth;
- }
+ if (!state->m_frameWidth)
+ state->m_frameWidth = img.width() / state->frames();
- int imgHeight = state->frameHeight();
- if (!imgHeight)
- imgHeight = img.height();
- if (frameHeight){
- if (imgHeight!=frameHeight){
- qWarning() << "SpriteEngine: Irregular frame height..." << state->source().toLocalFile();
- return QImage();
- }
- }else{
- frameHeight = imgHeight;
- }
+ if (!state->m_frameHeight)
+ state->m_frameHeight = img.height();
- if (state->frames() * frameWidth > maxSize){
+ if (state->frames() * state->frameWidth() > maxSize){
struct helper{
static int divRoundUp(int a, int b){return (a+b-1)/b;}
};
- int rowsNeeded = helper::divRoundUp(state->frames(), helper::divRoundUp(maxSize, frameWidth));
- if (rowsNeeded * frameHeight > maxSize){
+ int rowsNeeded = helper::divRoundUp(state->frames(), helper::divRoundUp(maxSize, state->frameWidth()));
+ if (rowsNeeded * state->frameHeight() > maxSize){
qWarning() << "SpriteEngine: Animation too large to fit in one texture..." << state->source().toLocalFile();
qWarning() << "SpriteEngine: Your texture max size today is " << maxSize;
}
state->m_generatedCount = rowsNeeded;
+ h += state->frameHeight() * rowsNeeded;
+ w = qMax(w, helper::divRoundUp(maxSize, state->frameWidth()));
m_imageStateCount += rowsNeeded;
}else{
+ h += state->frameHeight();
+ w = qMax(w, state->frameWidth() * state->frames());
m_imageStateCount++;
}
}
//maxFrames is max number in a line of the texture
- if (m_maxFrames * frameWidth > maxSize)
- m_maxFrames = maxSize/frameWidth;
- QImage image(frameWidth * m_maxFrames, frameHeight * m_imageStateCount, QImage::Format_ARGB32);
+ QImage image(w, h, QImage::Format_ARGB32);
image.fill(0);
QPainter p(&image);
int y = 0;
foreach (QSGSprite* state, m_sprites){
QImage img(state->source().toLocalFile());
+ int frameWidth = state->m_frameWidth;
+ int frameHeight = state->m_frameHeight;
if (img.height() == frameHeight && img.width() < maxSize){//Simple case
p.drawImage(0,y,img);
+ state->m_rowY = y;
y += frameHeight;
- }else{
+ }else{//Chopping up image case
state->m_framesPerRow = image.width()/frameWidth;
+ state->m_rowY = y;
int x = 0;
int curX = 0;
int curY = 0;
@@ -435,7 +445,7 @@ int QSGStochasticEngine::goalSeek(int curIdx, int spriteIdx, int dist)
return *(options.begin());
int option = -1;
qreal r =(qreal) qrand() / (qreal) RAND_MAX;
- qreal total;
+ qreal total = 0;
for (QSet<int>::const_iterator iter=options.constBegin();
iter!=options.constEnd(); iter++)
total += curState->m_to.value(m_states[(*iter)]->name()).toReal();
diff --git a/src/declarative/items/qsgspriteengine_p.h b/src/declarative/items/qsgspriteengine_p.h
index b2a06f2c87..8140b3814d 100644
--- a/src/declarative/items/qsgspriteengine_p.h
+++ b/src/declarative/items/qsgspriteengine_p.h
@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
class QSGSprite;
-class QSGStochasticState : public QObject //For internal use
+class Q_AUTOTEST_EXPORT QSGStochasticState : public QObject //For internal use
{
Q_OBJECT
Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
@@ -188,7 +188,7 @@ private:
friend class QSGStochasticEngine;
};
-class QSGStochasticEngine : public QObject
+class Q_AUTOTEST_EXPORT QSGStochasticEngine : public QObject
{
Q_OBJECT
//TODO: Optimize single state case?
@@ -277,6 +277,10 @@ public:
int spriteStart(int sprite=0);
int spriteFrames(int sprite=0);
int spriteDuration(int sprite=0);
+ int spriteX(int /* sprite */ = 0) { return 0; }//Currently all rows are 0 aligned, if we get more space efficient we might change this
+ int spriteY(int sprite=0);
+ int spriteWidth(int sprite=0);
+ int spriteHeight(int sprite=0);
int spriteCount();//Like state count, but for the image states
int maxFrames();
QImage assembledImage();
diff --git a/src/declarative/items/qsgspriteimage.cpp b/src/declarative/items/qsgspriteimage.cpp
index 8f3256efb6..f6cd35f4f3 100644
--- a/src/declarative/items/qsgspriteimage.cpp
+++ b/src/declarative/items/qsgspriteimage.cpp
@@ -55,6 +55,47 @@
QT_BEGIN_NAMESPACE
+static const char vertexShaderCode[] =
+ "attribute highp vec2 vTex;\n"
+ "uniform highp vec4 animData;// interpolate(bool), duration, frameCount (this anim), timestamp (this anim)\n"
+ "uniform highp vec4 animPos;//sheet x,y, width/height of this anim\n"
+ "uniform highp vec4 animSheetSize; //width/height of whole sheet, width/height of element\n"
+ "\n"
+ "uniform highp mat4 qt_Matrix;\n"
+ "uniform highp float timestamp;\n"
+ "\n"
+ "varying highp vec4 fTexS;\n"
+ "varying lowp float progress;\n"
+ "\n"
+ "\n"
+ "void main() {\n"
+ " //Calculate frame location in texture\n"
+ " highp float frameIndex = mod((((timestamp - animData.w)*1000.)/animData.y),animData.z);\n"
+ " progress = mod((timestamp - animData.w)*1000., animData.y) / animData.y;\n"
+ "\n"
+ " frameIndex = floor(frameIndex);\n"
+ " fTexS.xy = vec2(((frameIndex + vTex.x) * animPos.z / animSheetSize.x), ((animPos.y + vTex.y * animPos.w) / animSheetSize.y));\n"
+ "\n"
+ " //Next frame is also passed, for interpolation\n"
+ " //### Should the next anim be precalculated to allow for interpolation there?\n"
+ " if (animData.x == 1.0 && frameIndex != animData.z - 1.)//Can't do it for the last frame though, this anim may not loop\n"
+ " frameIndex = mod(frameIndex+1., animData.z);\n"
+ " fTexS.zw = vec2(((frameIndex + vTex.x) * animPos.z / animSheetSize.x), ((animPos.y + vTex.y * animPos.w) / animSheetSize.y));\n"
+ "\n"
+ " gl_Position = qt_Matrix * vec4(animSheetSize.z * vTex.x, animSheetSize.w * vTex.y, 0, 1);\n"
+ "}\n";
+
+static const char fragmentShaderCode[] =
+ "uniform sampler2D texture;\n"
+ "uniform lowp float qt_Opacity;\n"
+ "\n"
+ "varying highp vec4 fTexS;\n"
+ "varying lowp float progress;\n"
+ "\n"
+ "void main() {\n"
+ " gl_FragColor = mix(texture2D(texture, fTexS.xy), texture2D(texture, fTexS.zw), progress) * qt_Opacity;\n"
+ "}\n";
+
class QSGSpriteMaterial : public QSGMaterial
{
public:
@@ -70,20 +111,34 @@ public:
QSGTexture *texture;
qreal timestamp;
- qreal timelength;
- int framecount;
- int animcount;
- int width;
- int height;
+ float interpolate;
+ float frameDuration;
+ float frameCount;
+ float animT;
+ float animX;
+ float animY;
+ float animWidth;
+ float animHeight;
+ float sheetWidth;
+ float sheetHeight;
+ float elementWidth;
+ float elementHeight;
};
QSGSpriteMaterial::QSGSpriteMaterial()
: timestamp(0)
- , timelength(1)
- , framecount(1)
- , animcount(1)
- , width(0)
- , height(0)
+ , interpolate(1.0f)
+ , frameDuration(1.0f)
+ , frameCount(1.0f)
+ , animT(0.0f)
+ , animX(0.0f)
+ , animY(0.0f)
+ , animWidth(1.0f)
+ , animHeight(1.0f)
+ , sheetWidth(1.0f)
+ , sheetHeight(1.0f)
+ , elementWidth(1.0f)
+ , elementHeight(1.0f)
{
setFlag(Blending, true);
}
@@ -98,16 +153,6 @@ class SpriteMaterialData : public QSGMaterialShader
public:
SpriteMaterialData(const char *vertexFile = 0, const char *fragmentFile = 0)
{
- QFile vf(vertexFile ? vertexFile : ":defaultshaders/spriteimagevertex.shader");
- vf.open(QFile::ReadOnly);
- m_vertex_code = vf.readAll();
-
- QFile ff(fragmentFile ? fragmentFile : ":defaultshaders/spriteimagefragment.shader");
- ff.open(QFile::ReadOnly);
- m_fragment_code = ff.readAll();
-
- Q_ASSERT(!m_vertex_code.isNull());
- Q_ASSERT(!m_fragment_code.isNull());
}
void deactivate() {
@@ -125,52 +170,44 @@ public:
program()->setUniformValue(m_opacity_id, state.opacity());
program()->setUniformValue(m_timestamp_id, (float) m->timestamp);
- program()->setUniformValue(m_framecount_id, (float) m->framecount);
- program()->setUniformValue(m_animcount_id, (float) m->animcount);
- program()->setUniformValue(m_width_id, (float) m->width);
- program()->setUniformValue(m_height_id, (float) m->height);
+ program()->setUniformValue(m_animData_id, m->interpolate, m->frameDuration, m->frameCount, m->animT);
+ program()->setUniformValue(m_animPos_id, m->animX, m->animY, m->animWidth, m->animHeight);
+ program()->setUniformValue(m_animSheetSize_id, m->sheetWidth, m->sheetHeight, m->elementWidth, m->elementHeight);
if (state.isMatrixDirty())
program()->setUniformValue(m_matrix_id, state.combinedMatrix());
}
virtual void initialize() {
- m_matrix_id = program()->uniformLocation("matrix");
- m_opacity_id = program()->uniformLocation("opacity");
+ m_matrix_id = program()->uniformLocation("qt_Matrix");
+ m_opacity_id = program()->uniformLocation("qt_Opacity");
m_timestamp_id = program()->uniformLocation("timestamp");
- m_framecount_id = program()->uniformLocation("framecount");
- m_animcount_id = program()->uniformLocation("animcount");
- m_width_id = program()->uniformLocation("width");
- m_height_id = program()->uniformLocation("height");
+ m_animData_id = program()->uniformLocation("animData");
+ m_animPos_id = program()->uniformLocation("animPos");
+ m_animSheetSize_id = program()->uniformLocation("animSheetSize");
}
- virtual const char *vertexShader() const { return m_vertex_code.constData(); }
- virtual const char *fragmentShader() const { return m_fragment_code.constData(); }
+ virtual const char *vertexShader() const { return vertexShaderCode; }
+ virtual const char *fragmentShader() const { return fragmentShaderCode; }
virtual char const *const *attributeNames() const {
static const char *attr[] = {
"vTex",
- "vAnimData",
0
};
return attr;
}
- virtual bool isColorTable() const { return false; }
-
int m_matrix_id;
int m_opacity_id;
int m_timestamp_id;
- int m_framecount_id;
- int m_animcount_id;
- int m_width_id;
- int m_height_id;
-
- QByteArray m_vertex_code;
- QByteArray m_fragment_code;
+ int m_animData_id;
+ int m_animPos_id;
+ int m_animSheetSize_id;
static float chunkOfBytes[1024];
};
+
float SpriteMaterialData::chunkOfBytes[1024];
QSGMaterialShader *QSGSpriteMaterial::createShader() const
@@ -181,10 +218,6 @@ QSGMaterialShader *QSGSpriteMaterial::createShader() const
struct SpriteVertex {
float tx;
float ty;
- float animIdx;
- float frameDuration;
- float frameCount;
- float animT;
};
struct SpriteVertices {
@@ -194,6 +227,35 @@ struct SpriteVertices {
SpriteVertex v4;
};
+/*!
+ \qmlclass SpriteImage QSGSpriteImage
+ \inqmlmodule QtQuick 2
+ \inherits Item
+ \brief The SpriteImage element draws a sprite animation
+
+*/
+/*!
+ \qmlproperty bool QtQuick2::SpriteImage::running
+
+ Whether the sprite is animating or not.
+
+ Default is true
+*/
+/*!
+ \qmlproperty bool QtQuick2::SpriteImage::interpolate
+
+ If true, interpolation will occur between sprite frames to make the
+ animation appear smoother.
+
+ Default is true.
+*/
+/*!
+ \qmlproperty list<Sprite> QtQuick2::SpriteImage::sprites
+
+ The sprite or sprites to draw. Sprites will be scaled to the size of this element.
+*/
+
+//TODO: Implicitly size element to size of first sprite?
QSGSpriteImage::QSGSpriteImage(QSGItem *parent) :
QSGItem(parent)
, m_node(0)
@@ -201,6 +263,7 @@ QSGSpriteImage::QSGSpriteImage(QSGItem *parent) :
, m_spriteEngine(0)
, m_pleaseReset(false)
, m_running(true)
+ , m_interpolate(true)
{
setFlag(ItemHasContents);
connect(this, SIGNAL(runningChanged(bool)),
@@ -215,9 +278,9 @@ QDeclarativeListProperty<QSGSprite> QSGSpriteImage::sprites()
void QSGSpriteImage::createEngine()
{
//TODO: delay until component complete
- if(m_spriteEngine)
+ if (m_spriteEngine)
delete m_spriteEngine;
- if(m_sprites.count())
+ if (m_sprites.count())
m_spriteEngine = new QSGSpriteEngine(m_sprites, this);
else
m_spriteEngine = 0;
@@ -226,13 +289,12 @@ void QSGSpriteImage::createEngine()
static QSGGeometry::Attribute SpriteImage_Attributes[] = {
QSGGeometry::Attribute::create(0, 2, GL_FLOAT), // tex
- QSGGeometry::Attribute::create(1, 4, GL_FLOAT) // animData
};
static QSGGeometry::AttributeSet SpriteImage_AttributeSet =
{
- 2, // Attribute Count
- (4 + 2) * sizeof(float),
+ 1, // Attribute Count
+ 2 * sizeof(float),
SpriteImage_Attributes
};
@@ -243,19 +305,26 @@ QSGGeometryNode* QSGSpriteImage::buildNode()
return 0;
}
- if (m_material) {
- delete m_material;
- m_material = 0;
- }
-
m_material = new QSGSpriteMaterial();
QImage image = m_spriteEngine->assembledImage();
- if(image.isNull())
+ if (image.isNull())
return 0;
m_material->texture = sceneGraphEngine()->createTextureFromImage(image);
m_material->texture->setFiltering(QSGTexture::Linear);
- m_material->framecount = m_spriteEngine->maxFrames();
+ m_spriteEngine->start(0);
+ m_material->interpolate = m_interpolate ? 1.0 : 0.0;
+ m_material->frameCount = m_spriteEngine->spriteFrames();
+ m_material->frameDuration = m_spriteEngine->spriteDuration();
+ m_material->animT = 0;
+ m_material->animX = m_spriteEngine->spriteX();
+ m_material->animY = m_spriteEngine->spriteY();
+ m_material->animWidth = m_spriteEngine->spriteWidth();
+ m_material->animHeight = m_spriteEngine->spriteHeight();
+ m_material->sheetWidth = image.width();
+ m_material->sheetHeight = image.height();
+ m_material->elementWidth = width();
+ m_material->elementHeight = height();
int vCount = 4;
int iCount = 6;
@@ -263,11 +332,6 @@ QSGGeometryNode* QSGSpriteImage::buildNode()
g->setDrawingMode(GL_TRIANGLES);
SpriteVertices *p = (SpriteVertices *) g->vertexData();
- m_spriteEngine->start(0);
- p->v1.animT = p->v2.animT = p->v3.animT = p->v4.animT = 0;
- p->v1.animIdx = p->v2.animIdx = p->v3.animIdx = p->v4.animIdx = 0;
- p->v1.frameCount = p->v2.frameCount = p->v3.frameCount = p->v4.frameCount = m_spriteEngine->spriteFrames();
- p->v1.frameDuration = p->v2.frameDuration = p->v3.frameDuration = p->v4.frameDuration = m_spriteEngine->spriteDuration();
p->v1.tx = 0;
p->v1.ty = 0;
@@ -294,6 +358,7 @@ QSGGeometryNode* QSGSpriteImage::buildNode()
m_node = new QSGGeometryNode();
m_node->setGeometry(g);
m_node->setMaterial(m_material);
+ m_node->setFlag(QSGGeometryNode::OwnsMaterial);
return m_node;
}
@@ -304,7 +369,7 @@ void QSGSpriteImage::reset()
QSGNode *QSGSpriteImage::updatePaintNode(QSGNode *, UpdatePaintNodeData *)
{
- if(m_pleaseReset){
+ if (m_pleaseReset) {
delete m_node;
delete m_material;
@@ -315,7 +380,7 @@ QSGNode *QSGSpriteImage::updatePaintNode(QSGNode *, UpdatePaintNodeData *)
prepareNextFrame();
- if(m_running){
+ if (m_running) {
update();
if (m_node)
m_node->markDirty(QSGNode::DirtyMaterial);
@@ -334,19 +399,22 @@ void QSGSpriteImage::prepareNextFrame()
uint timeInt = m_timestamp.elapsed();
qreal time = timeInt / 1000.;
m_material->timestamp = time;
- m_material->animcount = m_spriteEngine->spriteCount();
- m_material->height = height();
- m_material->width = width();
+ m_material->elementHeight = height();
+ m_material->elementWidth = width();
+ m_material->interpolate = m_interpolate;
//Advance State
SpriteVertices *p = (SpriteVertices *) m_node->geometry()->vertexData();
m_spriteEngine->updateSprites(timeInt);
- int curIdx = m_spriteEngine->spriteState();
- if(curIdx != p->v1.animIdx){
- p->v1.animIdx = p->v2.animIdx = p->v3.animIdx = p->v4.animIdx = curIdx;
- p->v1.animT = p->v2.animT = p->v3.animT = p->v4.animT = m_spriteEngine->spriteStart()/1000.0;
- p->v1.frameCount = p->v2.frameCount = p->v3.frameCount = p->v4.frameCount = m_spriteEngine->spriteFrames();
- p->v1.frameDuration = p->v2.frameDuration = p->v3.frameDuration = p->v4.frameDuration = m_spriteEngine->spriteDuration();
+ int curY = m_spriteEngine->spriteY();
+ if (curY != m_material->animY){
+ m_material->animT = m_spriteEngine->spriteStart()/1000.0;
+ m_material->frameCount = m_spriteEngine->spriteFrames();
+ m_material->frameDuration = m_spriteEngine->spriteDuration();
+ m_material->animX = m_spriteEngine->spriteX();
+ m_material->animY = m_spriteEngine->spriteY();
+ m_material->animWidth = m_spriteEngine->spriteWidth();
+ m_material->animHeight = m_spriteEngine->spriteHeight();
}
}
diff --git a/src/declarative/items/qsgspriteimage_p.h b/src/declarative/items/qsgspriteimage_p.h
index c2179cf121..84c5b50136 100644
--- a/src/declarative/items/qsgspriteimage_p.h
+++ b/src/declarative/items/qsgspriteimage_p.h
@@ -60,6 +60,7 @@ class QSGSpriteImage : public QSGItem
{
Q_OBJECT
Q_PROPERTY(bool running READ running WRITE setRunning NOTIFY runningChanged)
+ Q_PROPERTY(bool interpolate READ interpolate WRITE setInterpolate NOTIFY interpolateChanged)
//###try to share similar spriteEngines for less overhead?
Q_PROPERTY(QDeclarativeListProperty<QSGSprite> sprites READ sprites)
Q_CLASSINFO("DefaultProperty", "sprites")
@@ -74,10 +75,15 @@ public:
return m_running;
}
-signals:
+ bool interpolate() const
+ {
+ return m_interpolate;
+ }
+signals:
void runningChanged(bool arg);
+ void interpolateChanged(bool arg);
public slots:
@@ -89,6 +95,14 @@ void setRunning(bool arg)
}
}
+void setInterpolate(bool arg)
+{
+ if (m_interpolate != arg) {
+ m_interpolate = arg;
+ emit interpolateChanged(arg);
+ }
+}
+
private slots:
void createEngine();
protected:
@@ -105,6 +119,7 @@ private:
int m_maxFrames;
bool m_pleaseReset;
bool m_running;
+ bool m_interpolate;
};
QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgtext.cpp b/src/declarative/items/qsgtext.cpp
index f936c3f32b..6c55e82802 100644
--- a/src/declarative/items/qsgtext.cpp
+++ b/src/declarative/items/qsgtext.cpp
@@ -104,13 +104,13 @@ QSGTextPrivate::QSGTextPrivate()
maximumLineCountValid(false),
texture(0),
imageCacheDirty(false), updateOnComponentComplete(true),
- richText(false), singleline(false), cacheAllTextAsImage(true), internalWidthUpdate(false),
+ richText(false), styledText(false), singleline(false), cacheAllTextAsImage(true), internalWidthUpdate(false),
requireImplicitWidth(false), truncated(false), hAlignImplicit(true), rightToLeftText(false),
- layoutTextElided(false), richTextAsImage(false), textureImageCacheDirty(false), naturalWidth(0),
- doc(0), nodeType(NodeIsNull)
+ layoutTextElided(false), richTextAsImage(false), textureImageCacheDirty(false), textHasChanged(true),
+ naturalWidth(0), doc(0), textLine(0), nodeType(NodeIsNull)
#if defined(Q_OS_MAC)
- , layoutThread(0)
+, layoutThread(0), paintingThread(0)
#endif
{
@@ -203,6 +203,7 @@ QSet<QUrl> QSGTextDocumentWithImageResources::errors;
QSGTextPrivate::~QSGTextPrivate()
{
+ delete textLine; textLine = 0;
}
qreal QSGTextPrivate::getImplicitWidth() const
@@ -230,7 +231,7 @@ void QSGTextPrivate::updateLayout()
if (!richText) {
layout.clearLayout();
layout.setFont(font);
- if (format != QSGText::StyledText) {
+ if (!styledText) {
QString tmp = text;
tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
singleline = !tmp.contains(QChar::LineSeparator);
@@ -248,7 +249,10 @@ void QSGTextPrivate::updateLayout()
layout.setText(tmp);
} else {
singleline = false;
- QDeclarativeStyledText::parse(text, layout);
+ if (textHasChanged) {
+ QDeclarativeStyledText::parse(text, layout);
+ textHasChanged = false;
+ }
}
} else {
ensureDoc();
@@ -258,7 +262,7 @@ void QSGTextPrivate::updateLayout()
blockFormat.setLineHeight((lineHeightMode == QSGText::FixedHeight ? lineHeight : lineHeight * 100), type);
for (QTextBlock it = doc->begin(); it != doc->end(); it = it.next()) {
QTextCursor cursor(it);
- cursor.setBlockFormat(blockFormat);
+ cursor.mergeBlockFormat(blockFormat);
}
}
@@ -362,6 +366,157 @@ void QSGTextPrivate::updateSize()
q->update();
}
+QSGTextLine::QSGTextLine()
+ : QObject(), m_line(0), m_height(0)
+{
+}
+
+void QSGTextLine::setLine(QTextLine *line)
+{
+ m_line = line;
+}
+
+int QSGTextLine::number() const
+{
+ if (m_line)
+ return m_line->lineNumber();
+ return 0;
+}
+
+qreal QSGTextLine::width() const
+{
+ if (m_line)
+ return m_line->width();
+ return 0;
+}
+
+void QSGTextLine::setWidth(qreal width)
+{
+ if (m_line)
+ m_line->setLineWidth(width);
+}
+
+qreal QSGTextLine::height() const
+{
+ if (m_height)
+ return m_height;
+ if (m_line)
+ return m_line->height();
+ return 0;
+}
+
+void QSGTextLine::setHeight(qreal height)
+{
+ if (m_line)
+ m_line->setPosition(QPointF(m_line->x(), m_line->y() - m_line->height() + height));
+ m_height = height;
+}
+
+qreal QSGTextLine::x() const
+{
+ if (m_line)
+ return m_line->x();
+ return 0;
+}
+
+void QSGTextLine::setX(qreal x)
+{
+ if (m_line)
+ m_line->setPosition(QPointF(x, m_line->y()));
+}
+
+qreal QSGTextLine::y() const
+{
+ if (m_line)
+ return m_line->y();
+ return 0;
+}
+
+void QSGTextLine::setY(qreal y)
+{
+ if (m_line)
+ m_line->setPosition(QPointF(m_line->x(), y));
+}
+
+void QSGText::doLayout()
+{
+ Q_D(QSGText);
+ d->updateSize();
+}
+
+/*!
+ \qmlsignal QtQuick2::Text::onLineLaidOut(line)
+
+ This handler is called for every line during the layout process.
+ This gives the opportunity to position and resize a line as it is being laid out.
+ It can for example be used to create columns or lay out text around objects.
+
+ The properties of a line are:
+ \list
+ \o number (read-only)
+ \o x
+ \o y
+ \o width
+ \o height
+ \endlist
+
+ For example, this will move the first 5 lines of a text element by 100 pixels to the right:
+ \code
+ onLineLaidOut: {
+ if (line.number < 5) {
+ line.x = line.x + 100
+ line.width = line.width - 100
+ }
+ }
+ \endcode
+*/
+
+bool QSGTextPrivate::isLineLaidOutConnected()
+{
+ static int idx = this->signalIndex("lineLaidOut(QSGTextLine*)");
+ return this->isSignalConnected(idx);
+}
+
+void QSGTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height, qreal elideWidth = 0)
+{
+ Q_Q(QSGText);
+
+#if defined(Q_OS_MAC)
+ if (QThread::currentThread() != paintingThread) {
+#endif
+ if (!line.lineNumber())
+ linesRects.clear();
+
+ if (!textLine)
+ textLine = new QSGTextLine;
+ textLine->setLine(&line);
+ textLine->setY(height);
+ textLine->setHeight(0);
+
+ // use the text item's width by default if it has one and wrap is on
+ if (q->widthValid() && q->wrapMode() != QSGText::NoWrap)
+ textLine->setWidth(q->width() - elideWidth);
+ else
+ textLine->setWidth(INT_MAX);
+ if (lineHeight != 1.0)
+ textLine->setHeight((lineHeightMode == QSGText::FixedHeight) ? lineHeight : line.height() * lineHeight);
+
+ emit q->lineLaidOut(textLine);
+
+ linesRects << QRectF(textLine->x(), textLine->y(), textLine->width(), textLine->height());
+ height += textLine->height();
+
+#if defined(Q_OS_MAC)
+ } else {
+ if (line.lineNumber() < linesRects.count()) {
+ QRectF r = linesRects.at(line.lineNumber());
+ line.setLineWidth(r.width());
+ line.setPosition(r.topLeft());
+ }
+ }
+#endif
+}
+
/*!
Lays out the QSGTextPrivate::layout QTextLayout in the constraints of the QSGText.
@@ -420,6 +575,9 @@ QRect QSGTextPrivate::setupTextLayout()
layout.setText(elidedText);
}
+ qreal height = 0;
+ bool customLayout = isLineLaidOutConnected();
+
if (maximumLineCountValid) {
layout.beginLayout();
if (!lineWidth)
@@ -432,17 +590,23 @@ QRect QSGTextPrivate::setupTextLayout()
break;
visibleCount++;
- if (lineWidth)
+
+ if (customLayout)
+ setupCustomLineGeometry(line, height);
+ else if (lineWidth)
line.setLineWidth(lineWidth);
visibleTextLength += line.textLength();
if (--linesLeft == 0) {
if (visibleTextLength < text.length()) {
truncate = true;
- if (elideMode==QSGText::ElideRight && q->widthValid()) {
+ if (elideMode == QSGText::ElideRight && q->widthValid()) {
qreal elideWidth = fm.width(elideChar);
// Need to correct for alignment
- line.setLineWidth(lineWidth-elideWidth);
+ if (customLayout)
+ setupCustomLineGeometry(line, height, elideWidth);
+ else
+ line.setLineWidth(lineWidth - elideWidth);
if (layout.text().mid(line.textStart(), line.textLength()).isRightToLeft()) {
line.setPosition(QPointF(line.position().x() + elideWidth, line.position().y()));
elidePos.setX(line.naturalTextRect().left() - elideWidth);
@@ -468,18 +632,23 @@ QRect QSGTextPrivate::setupTextLayout()
if (!line.isValid())
break;
visibleCount++;
- if (lineWidth)
- line.setLineWidth(lineWidth);
+ if (customLayout)
+ setupCustomLineGeometry(line, height);
+ else {
+ if (lineWidth)
+ line.setLineWidth(lineWidth);
+ }
}
layout.endLayout();
}
- qreal height = 0;
+ height = 0;
QRectF br;
for (int i = 0; i < layout.lineCount(); ++i) {
QTextLine line = layout.lineAt(i);
// set line spacing
- line.setPosition(QPointF(line.position().x(), height));
+ if (!customLayout)
+ line.setPosition(QPointF(line.position().x(), height));
if (elideText && i == layout.lineCount()-1) {
elidePos.setY(height + fm.ascent());
br = br.united(QRectF(elidePos, QSizeF(fm.width(elideChar), fm.ascent())));
@@ -487,7 +656,8 @@ QRect QSGTextPrivate::setupTextLayout()
br = br.united(line.naturalTextRect());
height += (lineHeightMode == QSGText::FixedHeight) ? lineHeight : line.height() * lineHeight;
}
- br.setHeight(height);
+ if (!customLayout)
+ br.setHeight(height);
if (!q->widthValid())
naturalWidth = br.width();
@@ -586,7 +756,7 @@ void QSGTextPrivate::invalidateImageCache()
{
Q_Q(QSGText);
- if(richTextAsImage || cacheAllTextAsImage || (qmlDisableDistanceField() && style != QSGText::Normal)){//If actually using the image cache
+ if (richTextAsImage || cacheAllTextAsImage || (qmlDisableDistanceField() && style != QSGText::Normal)) { // If actually using the image cache
if (imageCacheDirty)
return;
@@ -894,8 +1064,8 @@ QSGText::~QSGText()
\list
\o Font.MixedCase - This is the normal text rendering option where no capitalization change is applied.
\o Font.AllUppercase - This alters the text to be rendered in all uppercase type.
- \o Font.AllLowercase - This alters the text to be rendered in all lowercase type.
- \o Font.SmallCaps - This alters the text to be rendered in small-caps type.
+ \o Font.AllLowercase - This alters the text to be rendered in all lowercase type.
+ \o Font.SmallCaps - This alters the text to be rendered in small-caps type.
\o Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character.
\endlist
@@ -937,7 +1107,7 @@ void QSGText::setFont(const QFont &font)
The text to display. Text supports both plain and rich text strings.
The item will try to automatically determine whether the text should
- be treated as rich text. This determination is made using Qt::mightBeRichText().
+ be treated as styled text. This determination is made using Qt::mightBeRichText().
*/
QString QSGText::text() const
{
@@ -951,19 +1121,21 @@ void QSGText::setText(const QString &n)
if (d->text == n)
return;
- d->richText = d->format == RichText || (d->format == AutoText && Qt::mightBeRichText(n));
+ d->richText = d->format == RichText;
+ d->styledText = d->format == StyledText || (d->format == AutoText && Qt::mightBeRichText(n));
d->text = n;
if (isComponentComplete()) {
if (d->richText) {
d->ensureDoc();
d->doc->setText(n);
d->rightToLeftText = d->doc->toPlainText().isRightToLeft();
- d->richTextAsImage = QSGTextNode::isComplexRichText(d->doc);
+ d->richTextAsImage = enableImageCache();
} else {
d->rightToLeftText = d->text.isRightToLeft();
}
d->determineHorizontalAlignment();
}
+ d->textHasChanged = true;
d->updateLayout();
emit textChanged(d->text);
}
@@ -1316,13 +1488,13 @@ void QSGText::resetMaximumLineCount()
\list
\o Text.AutoText (default)
\o Text.PlainText
- \o Text.RichText
\o Text.StyledText
+ \o Text.RichText
\endlist
If the text format is \c Text.AutoText the text element
will automatically determine whether the text should be treated as
- rich text. This determination is made using Qt::mightBeRichText().
+ styled text. This determination is made using Qt::mightBeRichText().
Text.StyledText is an optimized format supporting some basic text
styling markup, in the style of html 3.2:
@@ -1379,14 +1551,18 @@ void QSGText::setTextFormat(TextFormat format)
return;
d->format = format;
bool wasRich = d->richText;
- d->richText = format == RichText || (format == AutoText && Qt::mightBeRichText(d->text));
+ d->richText = format == RichText;
+ d->styledText = format == StyledText || (format == AutoText && Qt::mightBeRichText(d->text));
if (!wasRich && d->richText && isComponentComplete()) {
d->ensureDoc();
d->doc->setText(d->text);
- d->richTextAsImage = QSGTextNode::isComplexRichText(d->doc);
+ d->rightToLeftText = d->doc->toPlainText().isRightToLeft();
+ d->richTextAsImage = enableImageCache();
+ } else {
+ d->rightToLeftText = d->text.isRightToLeft();
}
-
+ d->determineHorizontalAlignment();
d->updateLayout();
emit textFormatChanged(d->format);
@@ -1495,7 +1671,8 @@ QSGNode *QSGText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
// We need to make sure the layout is done in the current thread
#if defined(Q_OS_MAC)
- if (d->layoutThread != QThread::currentThread())
+ d->paintingThread = QThread::currentThread();
+ if (d->layoutThread != d->paintingThread)
d->updateLayout();
#endif
@@ -1550,7 +1727,6 @@ QSGNode *QSGText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
node->setMatrix(QMatrix4x4());
if (d->richText) {
-
d->ensureDoc();
node->addTextDocument(bounds.topLeft(), d->doc, QColor(), d->style, d->styleColor);
@@ -1674,7 +1850,7 @@ void QSGText::componentComplete()
d->ensureDoc();
d->doc->setText(d->text);
d->rightToLeftText = d->doc->toPlainText().isRightToLeft();
- d->richTextAsImage = QSGTextNode::isComplexRichText(d->doc);
+ d->richTextAsImage = enableImageCache();
} else {
d->rightToLeftText = d->text.isRightToLeft();
}
@@ -1683,18 +1859,49 @@ void QSGText::componentComplete()
}
}
+
+QString QSGTextPrivate::anchorAt(const QPointF &mousePos)
+{
+ if (styledText) {
+ for (int i = 0; i < layout.lineCount(); ++i) {
+ QTextLine line = layout.lineAt(i);
+ if (line.naturalTextRect().contains(mousePos)) {
+ int charPos = line.xToCursor(mousePos.x());
+ foreach (const QTextLayout::FormatRange &formatRange, layout.additionalFormats()) {
+ if (formatRange.format.isAnchor()
+ && charPos >= formatRange.start
+ && charPos <= formatRange.start + formatRange.length) {
+ return formatRange.format.anchorHref();
+ }
+ }
+ break;
+ }
+ }
+ }
+ return QString();
+}
+
+bool QSGTextPrivate::isLinkActivatedConnected()
+{
+ static int idx = this->signalIndex("linkActivated(QString)");
+ return this->isSignalConnected(idx);
+}
+
/*! \internal */
void QSGText::mousePressEvent(QMouseEvent *event)
{
Q_D(QSGText);
- if (!d->richText || !d->doc || d->doc->documentLayout()->anchorAt(event->localPos()).isEmpty()) {
- event->setAccepted(false);
- d->activeLink.clear();
- } else {
- d->activeLink = d->doc->documentLayout()->anchorAt(event->localPos());
+ if (d->isLinkActivatedConnected()) {
+ if (d->styledText)
+ d->activeLink = d->anchorAt(event->localPos());
+ else if (d->richText && d->doc)
+ d->activeLink = d->doc->documentLayout()->anchorAt(event->localPos());
}
+ if (d->activeLink.isEmpty())
+ event->setAccepted(false);
+
// ### may malfunction if two of the same links are clicked & dragged onto each other)
if (!event->isAccepted())
@@ -1707,8 +1914,17 @@ void QSGText::mouseReleaseEvent(QMouseEvent *event)
{
Q_D(QSGText);
- // ### confirm the link, and send a signal out
- if (d->richText && d->doc && d->activeLink == d->doc->documentLayout()->anchorAt(event->localPos()))
+ // ### confirm the link, and send a signal out
+
+ QString link;
+ if (d->isLinkActivatedConnected()) {
+ if (d->styledText)
+ link = d->anchorAt(event->localPos());
+ else if (d->richText && d->doc)
+ link = d->doc->documentLayout()->anchorAt(event->localPos());
+ }
+
+ if (!link.isEmpty() && d->activeLink == link)
emit linkActivated(d->activeLink);
else
event->setAccepted(false);
diff --git a/src/declarative/items/qsgtext_p.h b/src/declarative/items/qsgtext_p.h
index 725eeb27c4..aa07c8a25e 100644
--- a/src/declarative/items/qsgtext_p.h
+++ b/src/declarative/items/qsgtext_p.h
@@ -55,6 +55,7 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
class QSGTextPrivate;
+class QSGTextLine;
class Q_DECLARATIVE_PRIVATE_EXPORT QSGText : public QSGImplicitSizeItem
{
Q_OBJECT
@@ -172,6 +173,7 @@ public:
qreal paintedHeight() const;
QRectF boundingRect() const;
+ Q_INVOKABLE void doLayout();
Q_SIGNALS:
void textChanged(const QString &text);
@@ -192,6 +194,7 @@ Q_SIGNALS:
void lineHeightChanged(qreal lineHeight);
void lineHeightModeChanged(LineHeightMode mode);
void effectiveHorizontalAlignmentChanged();
+ void lineLaidOut(QSGTextLine *line);
protected:
void mousePressEvent(QMouseEvent *event);
@@ -206,9 +209,43 @@ private:
Q_DECLARE_PRIVATE(QSGText)
};
+class QTextLine;
+class Q_AUTOTEST_EXPORT QSGTextLine : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int number READ number)
+ Q_PROPERTY(qreal width READ width WRITE setWidth)
+ Q_PROPERTY(qreal height READ height WRITE setHeight)
+ Q_PROPERTY(qreal x READ x WRITE setX)
+ Q_PROPERTY(qreal y READ y WRITE setY)
+
+public:
+ QSGTextLine();
+
+ void setLine(QTextLine* line);
+ int number() const;
+
+ qreal width() const;
+ void setWidth(qreal width);
+
+ qreal height() const;
+ void setHeight(qreal height);
+
+ qreal x() const;
+ void setX(qreal x);
+
+ qreal y() const;
+ void setY(qreal y);
+
+private:
+ QTextLine *m_line;
+ qreal m_height;
+};
+
QT_END_NAMESPACE
QML_DECLARE_TYPE(QSGText)
+QML_DECLARE_TYPE(QSGTextLine)
QT_END_HEADER
diff --git a/src/declarative/items/qsgtext_p_p.h b/src/declarative/items/qsgtext_p_p.h
index 40c986142c..8b83263f6f 100644
--- a/src/declarative/items/qsgtext_p_p.h
+++ b/src/declarative/items/qsgtext_p_p.h
@@ -80,6 +80,7 @@ public:
bool setHAlign(QSGText::HAlignment, bool forceAlign = false);
void mirrorChange();
QTextDocument *textDocument();
+ bool isLineLaidOutConnected();
QString text;
QFont font;
@@ -110,6 +111,7 @@ public:
bool imageCacheDirty:1;
bool updateOnComponentComplete:1;
bool richText:1;
+ bool styledText:1;
bool singleline:1;
bool cacheAllTextAsImage:1;
bool internalWidthUpdate:1;
@@ -120,6 +122,7 @@ public:
bool layoutTextElided:1;
bool richTextAsImage:1;
bool textureImageCacheDirty:1;
+ bool textHasChanged:1;
QRect layedOutTextRect;
QSize paintedSize;
@@ -131,9 +134,14 @@ public:
QSGTextDocumentWithImageResources *doc;
QRect setupTextLayout();
+ void setupCustomLineGeometry(QTextLine &line, qreal &height, qreal elideWidth);
QPixmap textLayoutImage(bool drawStyle);
void drawTextLayout(QPainter *p, const QPointF &pos, bool drawStyle);
+ bool isLinkActivatedConnected();
+ QString anchorAt(const QPointF &pos);
QTextLayout layout;
+ QList<QRectF> linesRects;
+ QSGTextLine *textLine;
static QPixmap drawOutline(const QPixmap &source, const QPixmap &styleSource);
static QPixmap drawOutline(const QPixmap &source, const QPixmap &styleSource, int yOffset);
@@ -151,6 +159,7 @@ public:
#if defined(Q_OS_MAC)
QThread *layoutThread;
+ QThread *paintingThread;
#endif
};
diff --git a/src/declarative/items/qsgtextedit.cpp b/src/declarative/items/qsgtextedit.cpp
index af018aef8c..bbc751f99c 100644
--- a/src/declarative/items/qsgtextedit.cpp
+++ b/src/declarative/items/qsgtextedit.cpp
@@ -63,6 +63,7 @@
QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
+DEFINE_BOOL_CONFIG_OPTION(qmlEnableImageCache, QML_ENABLE_TEXT_IMAGE_CACHE)
/*!
\qmlclass TextEdit QSGTextEdit
@@ -230,8 +231,8 @@ QString QSGTextEdit::text() const
\list
\o Font.MixedCase - This is the normal text rendering option where no capitalization change is applied.
\o Font.AllUppercase - This alters the text to be rendered in all uppercase type.
- \o Font.AllLowercase - This alters the text to be rendered in all lowercase type.
- \o Font.SmallCaps - This alters the text to be rendered in small-caps type.
+ \o Font.AllLowercase - This alters the text to be rendered in all lowercase type.
+ \o Font.SmallCaps - This alters the text to be rendered in small-caps type.
\o Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character.
\endlist
@@ -260,7 +261,7 @@ void QSGTextEdit::setText(const QString &text)
#else
d->control->setPlainText(text);
#endif
- d->isComplexRichText = QSGTextNode::isComplexRichText(d->document);
+ d->useImageFallback = qmlEnableImageCache();
} else {
d->control->setPlainText(text);
}
@@ -330,7 +331,7 @@ void QSGTextEdit::setTextFormat(TextFormat format)
d->control->setPlainText(d->text);
#endif
updateSize();
- d->isComplexRichText = QSGTextNode::isComplexRichText(d->document);
+ d->useImageFallback = qmlEnableImageCache();
}
d->format = format;
d->control->setAcceptRichText(d->format != PlainText);
@@ -360,7 +361,7 @@ void QSGTextEdit::setFont(const QFont &font)
if (oldFont != d->font) {
d->document->setDefaultFont(d->font);
- if(d->cursor){
+ if (d->cursor) {
d->cursor->setHeight(QFontMetrics(d->font).height());
moveCursorDelegate();
}
@@ -865,8 +866,8 @@ QDeclarativeComponent* QSGTextEdit::cursorDelegate() const
void QSGTextEdit::setCursorDelegate(QDeclarativeComponent* c)
{
Q_D(QSGTextEdit);
- if(d->cursorComponent){
- if(d->cursor){
+ if (d->cursorComponent) {
+ if (d->cursor) {
d->control->setCursorWidth(-1);
updateCursor();
delete d->cursor;
@@ -874,10 +875,10 @@ void QSGTextEdit::setCursorDelegate(QDeclarativeComponent* c)
}
}
d->cursorComponent = c;
- if(c && c->isReady()){
+ if (c && c->isReady()) {
loadCursorDelegate();
- }else{
- if(c)
+ } else {
+ if (c)
connect(c, SIGNAL(statusChanged()),
this, SLOT(loadCursorDelegate()));
}
@@ -888,10 +889,12 @@ void QSGTextEdit::setCursorDelegate(QDeclarativeComponent* c)
void QSGTextEdit::loadCursorDelegate()
{
Q_D(QSGTextEdit);
- if(d->cursorComponent->isLoading())
+ if (d->cursorComponent->isLoading())
return;
- d->cursor = qobject_cast<QSGItem*>(d->cursorComponent->create(qmlContext(this)));
- if(d->cursor){
+ QDeclarativeContext *creationContext = d->cursorComponent->creationContext();
+ QObject *object = d->cursorComponent->create(creationContext ? creationContext : qmlContext(this));
+ d->cursor = qobject_cast<QSGItem*>(object);
+ if (d->cursor) {
d->control->setCursorWidth(0);
updateCursor();
QDeclarative_setParent_noEvent(d->cursor, this);
@@ -899,6 +902,7 @@ void QSGTextEdit::loadCursorDelegate()
d->cursor->setHeight(QFontMetrics(d->font).height());
moveCursorDelegate();
}else{
+ delete object;
qmlInfo(this) << "Error loading cursor delegate.";
}
}
@@ -1035,9 +1039,8 @@ void QSGTextEdit::componentComplete()
Q_D(QSGTextEdit);
QSGImplicitSizeItem::componentComplete();
- if (d->richText) {
- d->isComplexRichText = QSGTextNode::isComplexRichText(d->document);
- }
+ if (d->richText)
+ d->useImageFallback = qmlEnableImageCache();
if (d->dirty) {
d->determineHorizontalAlignment();
@@ -1332,16 +1335,9 @@ void QSGTextEdit::mousePressEvent(QMouseEvent *event)
if (d->focusOnPress){
bool hadActiveFocus = hasActiveFocus();
forceActiveFocus();
- if (d->showInputPanelOnFocus) {
- if (hasActiveFocus() && hadActiveFocus && !isReadOnly()) {
- // re-open input panel on press if already focused
- openSoftwareInputPanel();
- }
- } else { // show input panel on click
- if (hasActiveFocus() && !hadActiveFocus) {
- d->clickCausedFocus = true;
- }
- }
+ // re-open input panel on press if already focused
+ if (hasActiveFocus() && hadActiveFocus && !isReadOnly())
+ openSoftwareInputPanel();
}
d->control->processEvent(event, QPointF(0, -d->yoff));
if (!event->isAccepted())
@@ -1356,16 +1352,6 @@ void QSGTextEdit::mouseReleaseEvent(QMouseEvent *event)
{
Q_D(QSGTextEdit);
d->control->processEvent(event, QPointF(0, -d->yoff));
- if (!d->showInputPanelOnFocus) { // input panel on click
- if (d->focusOnPress && !isReadOnly() && boundingRect().contains(event->localPos())) {
- // ### refactor: port properly
- qDebug("QSGTextEdit: virtual keyboard handling not implemented");
-// if (canvas() && canvas() == qApp->focusWidget()) {
-// qt_widget_private(canvas())->handleSoftwareInputPanel(event->button(), d->clickCausedFocus);
-// }
- }
- }
- d->clickCausedFocus = false;
if (!event->isAccepted())
QSGImplicitSizeItem::mouseReleaseEvent(event);
@@ -1446,7 +1432,7 @@ void QSGTextEdit::updateImageCache(const QRectF &)
Q_D(QSGTextEdit);
// Do we really need the image cache?
- if (!d->richText || !d->isComplexRichText) {
+ if (!d->richText || !d->useImageFallback) {
if (!d->pixmapCache.isNull())
d->pixmapCache = QPixmap();
return;
@@ -1478,7 +1464,7 @@ QSGNode *QSGTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *upd
Q_D(QSGTextEdit);
QSGNode *currentNode = oldNode;
- if (d->richText && d->isComplexRichText) {
+ if (d->richText && d->useImageFallback) {
QSGImageNode *node = 0;
if (oldNode == 0 || d->nodeType != QSGTextEditPrivate::NodeIsTexture) {
delete oldNode;
@@ -1530,7 +1516,8 @@ QSGNode *QSGTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *upd
QColor selectedTextColor = d->control->palette().color(QPalette::HighlightedText);
node->addTextDocument(bounds.topLeft(), d->document, d->color, QSGText::Normal, QColor(),
selectionColor, selectedTextColor, selectionStart(),
- selectionEnd() - 1);
+ selectionEnd() - 1); // selectionEnd() returns first char after
+ // selection
#if defined(Q_WS_MAC)
// We also need to make sure the document layout is redone when
@@ -1678,7 +1665,7 @@ void QSGTextEdit::moveCursorDelegate()
d->determineHorizontalAlignment();
updateMicroFocus();
emit cursorRectangleChanged();
- if(!d->cursor)
+ if (!d->cursor)
return;
QRectF cursorRect = cursorRectangle();
d->cursor->setX(cursorRect.x());
@@ -1696,20 +1683,20 @@ void QSGTextEditPrivate::updateSelection()
cursor.setPosition(lastSelectionEnd, QTextCursor::KeepAnchor);
cursor.endEditBlock();
control->setTextCursor(cursor);
- if(startChange)
+ if (startChange)
q->selectionStartChanged();
- if(endChange)
+ if (endChange)
q->selectionEndChanged();
}
void QSGTextEdit::updateSelectionMarkers()
{
Q_D(QSGTextEdit);
- if(d->lastSelectionStart != d->control->textCursor().selectionStart()){
+ if (d->lastSelectionStart != d->control->textCursor().selectionStart()) {
d->lastSelectionStart = d->control->textCursor().selectionStart();
emit selectionStartChanged();
}
- if(d->lastSelectionEnd != d->control->textCursor().selectionEnd()){
+ if (d->lastSelectionEnd != d->control->textCursor().selectionEnd()) {
d->lastSelectionEnd = d->control->textCursor().selectionEnd();
emit selectionEndChanged();
}
@@ -1720,9 +1707,9 @@ QRectF QSGTextEdit::boundingRect() const
Q_D(const QSGTextEdit);
QRectF r = QSGImplicitSizeItem::boundingRect();
int cursorWidth = 1;
- if(d->cursor)
+ if (d->cursor)
cursorWidth = d->cursor->width();
- if(!d->document->isEmpty())
+ if (!d->document->isEmpty())
cursorWidth += 3;// ### Need a better way of accounting for space between char and cursor
// Could include font max left/right bearings to either side of rectangle.
@@ -1964,19 +1951,16 @@ void QSGTextEdit::openSoftwareInputPanel()
\endcode
*/
void QSGTextEdit::closeSoftwareInputPanel()
-{
+{
if (qGuiApp)
- qGuiApp->inputPanel()->show();
+ qGuiApp->inputPanel()->hide();
}
void QSGTextEdit::focusInEvent(QFocusEvent *event)
{
Q_D(const QSGTextEdit);
- if (d->showInputPanelOnFocus) {
- if (d->focusOnPress && !isReadOnly()) {
- openSoftwareInputPanel();
- }
- }
+ if (d->focusOnPress && !isReadOnly())
+ openSoftwareInputPanel();
QSGImplicitSizeItem::focusInEvent(event);
}
@@ -1985,7 +1969,7 @@ void QSGTextEdit::q_canPasteChanged()
Q_D(QSGTextEdit);
bool old = d->canPaste;
d->canPaste = d->control->canPaste();
- if(old!=d->canPaste)
+ if (old!=d->canPaste)
emit canPasteChanged();
}
diff --git a/src/declarative/items/qsgtextedit_p.h b/src/declarative/items/qsgtextedit_p.h
index b07292b296..fced11808f 100644
--- a/src/declarative/items/qsgtextedit_p.h
+++ b/src/declarative/items/qsgtextedit_p.h
@@ -274,7 +274,7 @@ private:
void updateImageCache(const QRectF &rect = QRectF());
protected:
- virtual void geometryChanged(const QRectF &newGeometry,
+ virtual void geometryChanged(const QRectF &newGeometry,
const QRectF &oldGeometry);
bool event(QEvent *);
diff --git a/src/declarative/items/qsgtextedit_p_p.h b/src/declarative/items/qsgtextedit_p_p.h
index 326e0a342a..51904d1cde 100644
--- a/src/declarative/items/qsgtextedit_p_p.h
+++ b/src/declarative/items/qsgtextedit_p_p.h
@@ -72,19 +72,13 @@ public:
QSGTextEditPrivate()
: color("black"), hAlign(QSGTextEdit::AlignLeft), vAlign(QSGTextEdit::AlignTop),
documentDirty(true), dirty(false), richText(false), cursorVisible(false), focusOnPress(true),
- showInputPanelOnFocus(true), clickCausedFocus(false), persistentSelection(true),
- requireImplicitWidth(false), selectByMouse(false), canPaste(false),
- hAlignImplicit(true), rightToLeftText(false), isComplexRichText(false),
+ persistentSelection(true), requireImplicitWidth(false), selectByMouse(false), canPaste(false),
+ hAlignImplicit(true), rightToLeftText(false), useImageFallback(false),
textMargin(0.0), lastSelectionStart(0), lastSelectionEnd(0), cursorComponent(0), cursor(0),
format(QSGTextEdit::AutoText), document(0), wrapMode(QSGTextEdit::NoWrap),
mouseSelectionMode(QSGTextEdit::SelectCharacters),
lineCount(0), yoff(0), nodeType(NodeIsNull), texture(0)
{
-#ifdef Q_OS_SYMBIAN
- if (QSysInfo::symbianVersion() == QSysInfo::SV_SF_1 || QSysInfo::symbianVersion() == QSysInfo::SV_SF_3) {
- showInputPanelOnFocus = false;
- }
-#endif
}
void init();
@@ -113,15 +107,13 @@ public:
bool richText : 1;
bool cursorVisible : 1;
bool focusOnPress : 1;
- bool showInputPanelOnFocus : 1;
- bool clickCausedFocus : 1;
bool persistentSelection : 1;
bool requireImplicitWidth:1;
bool selectByMouse:1;
bool canPaste:1;
bool hAlignImplicit:1;
bool rightToLeftText:1;
- bool isComplexRichText:1;
+ bool useImageFallback:1;
qreal textMargin;
int lastSelectionStart;
diff --git a/src/declarative/items/qsgtextinput.cpp b/src/declarative/items/qsgtextinput.cpp
index ab6be666d8..6d0fa47d4f 100644
--- a/src/declarative/items/qsgtextinput.cpp
+++ b/src/declarative/items/qsgtextinput.cpp
@@ -49,7 +49,7 @@
#include <QtDeclarative/qdeclarativeinfo.h>
#include <QtGui/qevent.h>
#include <QTextBoundaryFinder>
-#include <qsgtextnode_p.h>
+#include "qsgtextnode_p.h"
#include <qsgsimplerectnode.h>
#include <QtGui/qstylehints.h>
@@ -103,7 +103,7 @@ QString QSGTextInput::text() const
void QSGTextInput::setText(const QString &s)
{
Q_D(QSGTextInput);
- if(s == text())
+ if (s == text())
return;
d->control->setText(s);
}
@@ -203,8 +203,8 @@ void QSGTextInput::setText(const QString &s)
\list
\o Font.MixedCase - This is the normal text rendering option where no capitalization change is applied.
\o Font.AllUppercase - This alters the text to be rendered in all uppercase type.
- \o Font.AllLowercase - This alters the text to be rendered in all lowercase type.
- \o Font.SmallCaps - This alters the text to be rendered in small-caps type.
+ \o Font.AllLowercase - This alters the text to be rendered in all lowercase type.
+ \o Font.SmallCaps - This alters the text to be rendered in small-caps type.
\o Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character.
\endlist
@@ -237,7 +237,7 @@ void QSGTextInput::setFont(const QFont &font)
d->control->setFont(d->font);
updateSize();
updateCursorRectangle();
- if(d->cursorItem){
+ if (d->cursorItem) {
d->cursorItem->setHeight(QFontMetrics(d->font).height());
}
}
@@ -795,7 +795,7 @@ void QSGTextInput::setValidator(QValidator* v)
return;
d->control->setValidator(v);
- if(!d->control->hasAcceptableInput()){
+ if (!d->control->hasAcceptableInput()) {
d->oldValidity = false;
emit acceptableInputChanged();
}
@@ -935,10 +935,10 @@ void QSGTextInput::setCursorDelegate(QDeclarativeComponent* c)
return;
d->cursorComponent = c;
- if(!c){
+ if (!c) {
//note that the components are owned by something else
delete d->cursorItem;
- }else{
+ } else {
d->startCreatingCursor();
}
@@ -948,12 +948,12 @@ void QSGTextInput::setCursorDelegate(QDeclarativeComponent* c)
void QSGTextInputPrivate::startCreatingCursor()
{
Q_Q(QSGTextInput);
- if(cursorComponent->isReady()){
+ if (cursorComponent->isReady()) {
q->createCursor();
- }else if(cursorComponent->isLoading()){
+ } else if (cursorComponent->isLoading()) {
q->connect(cursorComponent, SIGNAL(statusChanged(int)),
q, SLOT(createCursor()));
- }else {//isError
+ } else { // isError
qmlInfo(q, cursorComponent->errors()) << QSGTextInput::tr("Could not load cursor delegate");
}
}
@@ -961,18 +961,21 @@ void QSGTextInputPrivate::startCreatingCursor()
void QSGTextInput::createCursor()
{
Q_D(QSGTextInput);
- if(d->cursorComponent->isError()){
+ if (d->cursorComponent->isError()) {
qmlInfo(this, d->cursorComponent->errors()) << tr("Could not load cursor delegate");
return;
}
- if(!d->cursorComponent->isReady())
+ if (!d->cursorComponent->isReady())
return;
- if(d->cursorItem)
+ if (d->cursorItem)
delete d->cursorItem;
- d->cursorItem = qobject_cast<QSGItem*>(d->cursorComponent->create());
- if(!d->cursorItem){
+ QDeclarativeContext *creationContext = d->cursorComponent->creationContext();
+ QObject *object = d->cursorComponent->create(creationContext ? creationContext : qmlContext(this));
+ d->cursorItem = qobject_cast<QSGItem*>(object);
+ if (!d->cursorItem) {
+ delete object;
qmlInfo(this, d->cursorComponent->errors()) << tr("Could not instantiate cursor delegate");
return;
}
@@ -1088,6 +1091,10 @@ void QSGTextInput::mouseDoubleClickEvent(QMouseEvent *event)
int cursor = d->xToPos(event->localPos().x());
d->control->selectWordAtPos(cursor);
event->setAccepted(true);
+ if (!d->hasPendingTripleClick()) {
+ d->tripleClickStartPoint = event->localPos().toPoint();
+ d->tripleClickTimer.start();
+ }
} else {
QSGImplicitSizeItem::mouseDoubleClickEvent(event);
}
@@ -1098,24 +1105,24 @@ void QSGTextInput::mousePressEvent(QMouseEvent *event)
Q_D(QSGTextInput);
if (d->sendMouseEventToInputContext(event))
return;
- if(d->focusOnPress){
+ if (d->focusOnPress) {
bool hadActiveFocus = hasActiveFocus();
forceActiveFocus();
- if (d->showInputPanelOnFocus) {
- if (hasActiveFocus() && hadActiveFocus && !isReadOnly()) {
- // re-open input panel on press if already focused
- openSoftwareInputPanel();
- }
- } else { // show input panel on click
- if (hasActiveFocus() && !hadActiveFocus) {
- d->clickCausedFocus = true;
- }
- }
+ // re-open input panel on press if already focused
+ if (hasActiveFocus() && hadActiveFocus && !isReadOnly())
+ openSoftwareInputPanel();
}
if (d->selectByMouse) {
setKeepMouseGrab(false);
d->selectPressed = true;
d->pressPos = event->localPos();
+ QPoint distanceVector = d->pressPos.toPoint() - d->tripleClickStartPoint;
+ if (d->hasPendingTripleClick()
+ && distanceVector.manhattanLength() < qApp->styleHints()->startDragDistance()) {
+ event->setAccepted(true);
+ selectAll();
+ return;
+ }
}
bool mark = (event->modifiers() & Qt::ShiftModifier) && d->selectByMouse;
int cursor = d->xToPos(event->localPos().x());
@@ -1147,16 +1154,6 @@ void QSGTextInput::mouseReleaseEvent(QMouseEvent *event)
d->selectPressed = false;
setKeepMouseGrab(false);
}
- if (!d->showInputPanelOnFocus) { // input panel on click
- if (d->focusOnPress && !isReadOnly() && boundingRect().contains(event->localPos())) {
- if (canvas() && canvas() == QGuiApplication::activeWindow()) {
- // ### refactor: implement virtual keyboard properly..
- qDebug("QSGTextInput: virtual keyboard no implemented...");
-// qt_widget_private(canvas())->handleSoftwareInputPanel(event->button(), d->clickCausedFocus);
- }
- }
- }
- d->clickCausedFocus = false;
d->control->processEvent(event);
if (!event->isAccepted())
QSGImplicitSizeItem::mouseReleaseEvent(event);
@@ -1200,7 +1197,7 @@ bool QSGTextInput::event(QEvent* ev)
Q_D(QSGTextInput);
//Anything we don't deal with ourselves, pass to the control
bool handled = false;
- switch(ev->type()){
+ switch (ev->type()) {
case QEvent::KeyPress:
case QEvent::KeyRelease://###Should the control be doing anything with release?
case QEvent::InputMethod:
@@ -1212,7 +1209,7 @@ bool QSGTextInput::event(QEvent* ev)
default:
handled = d->control->processEvent(ev);
}
- if(!handled)
+ if (!handled)
handled = QSGImplicitSizeItem::event(ev);
return handled;
}
@@ -1350,7 +1347,7 @@ QSGNode *QSGTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *da
QVariant QSGTextInput::inputMethodQuery(Qt::InputMethodQuery property) const
{
Q_D(const QSGTextInput);
- switch(property) {
+ switch (property) {
case Qt::ImEnabled:
return QVariant((bool)(flags() & ItemAcceptsInputMethod));
case Qt::ImHints:
@@ -1362,10 +1359,12 @@ QVariant QSGTextInput::inputMethodQuery(Qt::InputMethodQuery property) const
case Qt::ImCursorPosition:
return QVariant(d->control->cursor());
case Qt::ImSurroundingText:
- if (d->control->echoMode() == QLineControl::PasswordEchoOnEdit && !d->control->passwordEchoEditing())
+ if (d->control->echoMode() == QLineControl::PasswordEchoOnEdit
+ && !d->control->passwordEchoEditing()) {
return QVariant(displayText());
- else
+ } else {
return QVariant(text());
+ }
case Qt::ImCurrentSelection:
return QVariant(selectedText());
case Qt::ImMaximumTextLength:
@@ -1502,7 +1501,7 @@ QString QSGTextInput::passwordCharacter() const
void QSGTextInput::setPasswordCharacter(const QString &str)
{
Q_D(QSGTextInput);
- if(str.length() < 1)
+ if (str.length() < 1)
return;
d->control->setPasswordCharacter(str.constData()[0]);
EchoMode echoMode_ = echoMode();
@@ -1786,11 +1785,8 @@ void QSGTextInput::closeSoftwareInputPanel()
void QSGTextInput::focusInEvent(QFocusEvent *event)
{
Q_D(const QSGTextInput);
- if (d->showInputPanelOnFocus) {
- if (d->focusOnPress && !isReadOnly()) {
- openSoftwareInputPanel();
- }
- }
+ if (d->focusOnPress && !isReadOnly())
+ openSoftwareInputPanel();
QSGImplicitSizeItem::focusInEvent(event);
}
@@ -1801,7 +1797,7 @@ void QSGTextInput::itemChange(ItemChange change, const ItemChangeData &value)
bool hasFocus = value.boolValue;
d->focused = hasFocus;
setCursorVisible(hasFocus); // ### refactor: && d->canvas && d->canvas->hasFocus()
- if(echoMode() == QSGTextInput::PasswordEchoOnEdit && !hasFocus)
+ if (echoMode() == QSGTextInput::PasswordEchoOnEdit && !hasFocus)
d->control->updatePasswordEchoEditing(false);//QLineControl sets it on key events, but doesn't deal with focus events
if (!hasFocus)
d->control->deselect();
@@ -1862,6 +1858,7 @@ void QSGTextInputPrivate::init()
q->connect(control, SIGNAL(displayTextChanged(QString)),
q, SLOT(updateRect()));
q->updateSize();
+ imHints &= ~Qt::ImhMultiLine;
oldValidity = control->hasAcceptableInput();
lastSelectionStart = 0;
lastSelectionEnd = 0;
@@ -1887,12 +1884,12 @@ void QSGTextInput::cursorPosChanged()
d->control->resetCursorBlinkTimer();
#endif
- if(!d->control->hasSelectedText()){
- if(d->lastSelectionStart != d->control->cursor()){
+ if (!d->control->hasSelectedText()) {
+ if (d->lastSelectionStart != d->control->cursor()) {
d->lastSelectionStart = d->control->cursor();
emit selectionStartChanged();
}
- if(d->lastSelectionEnd != d->control->cursor()){
+ if (d->lastSelectionEnd != d->control->cursor()) {
d->lastSelectionEnd = d->control->cursor();
emit selectionEndChanged();
}
@@ -1917,15 +1914,15 @@ void QSGTextInput::selectionChanged()
updateRect();//TODO: Only update rect in selection
emit selectedTextChanged();
- if(d->lastSelectionStart != d->control->selectionStart()){
+ if (d->lastSelectionStart != d->control->selectionStart()) {
d->lastSelectionStart = d->control->selectionStart();
- if(d->lastSelectionStart == -1)
+ if (d->lastSelectionStart == -1)
d->lastSelectionStart = d->control->cursor();
emit selectionStartChanged();
}
- if(d->lastSelectionEnd != d->control->selectionEnd()){
+ if (d->lastSelectionEnd != d->control->selectionEnd()) {
d->lastSelectionEnd = d->control->selectionEnd();
- if(d->lastSelectionEnd == -1)
+ if (d->lastSelectionEnd == -1)
d->lastSelectionEnd = d->control->cursor();
emit selectionEndChanged();
}
@@ -1940,7 +1937,7 @@ void QSGTextInput::q_textChanged()
d->determineHorizontalAlignment();
d->updateHorizontalScroll();
updateMicroFocus();
- if(hasAcceptableInput() != d->oldValidity){
+ if (hasAcceptableInput() != d->oldValidity) {
d->oldValidity = hasAcceptableInput();
emit acceptableInputChanged();
}
@@ -1991,7 +1988,7 @@ void QSGTextInput::updateSize(bool needsRedraw)
int h = height();
setImplicitHeight(d->control->height()-1); // -1 to counter QLineControl's +1 which is not consistent with Text.
setImplicitWidth(d->calculateTextWidth());
- if(w==width() && h==height() && needsRedraw)
+ if (w==width() && h==height() && needsRedraw)
update();
}
@@ -2002,7 +1999,7 @@ void QSGTextInput::q_canPasteChanged()
#ifndef QT_NO_CLIPBOARD
d->canPaste = !d->control->isReadOnly() && QGuiApplication::clipboard()->text().length() != 0;
#endif
- if(d->canPaste != old)
+ if (d->canPaste != old)
emit canPasteChanged();
}
diff --git a/src/declarative/items/qsgtextinput_p_p.h b/src/declarative/items/qsgtextinput_p_p.h
index 49680ced6d..ed2395bb0e 100644
--- a/src/declarative/items/qsgtextinput_p_p.h
+++ b/src/declarative/items/qsgtextinput_p_p.h
@@ -50,7 +50,10 @@
#include <private/qlinecontrol_p.h>
#include <QtDeclarative/qdeclarative.h>
+#include <QtCore/qelapsedtimer.h>
#include <QtCore/qpointer.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qstylehints.h>
//
@@ -85,8 +88,6 @@ public:
, oldValidity(false)
, focused(false)
, focusOnPress(true)
- , showInputPanelOnFocus(true)
- , clickCausedFocus(false)
, cursorVisible(false)
, autoScroll(true)
, selectByMouse(false)
@@ -95,11 +96,6 @@ public:
, selectPressed(false)
, textLayoutDirty(true)
{
-#ifdef Q_OS_SYMBIAN
- if (QSysInfo::symbianVersion() == QSysInfo::SV_SF_1 || QSysInfo::symbianVersion() == QSysInfo::SV_SF_3) {
- showInputPanelOnFocus = false;
- }
-#endif
}
~QSGTextInputPrivate()
@@ -142,6 +138,8 @@ public:
QPointer<QSGItem> cursorItem;
QPointF pressPos;
QSGTextNode *textNode;
+ QElapsedTimer tripleClickTimer;
+ QPoint tripleClickStartPoint;
int lastSelectionStart;
int lastSelectionEnd;
@@ -153,8 +151,6 @@ public:
bool oldValidity:1;
bool focused:1;
bool focusOnPress:1;
- bool showInputPanelOnFocus:1;
- bool clickCausedFocus:1;
bool cursorVisible:1;
bool autoScroll:1;
bool selectByMouse:1;
@@ -166,6 +162,9 @@ public:
static inline QSGTextInputPrivate *get(QSGTextInput *t) {
return t->d_func();
}
+ bool hasPendingTripleClick() const {
+ return !tripleClickTimer.hasExpired(qApp->styleHints()->mouseDoubleClickInterval());
+ }
};
QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgtextnode.cpp b/src/declarative/items/qsgtextnode.cpp
index 3af7e54b2f..f712bd768e 100644
--- a/src/declarative/items/qsgtextnode.cpp
+++ b/src/declarative/items/qsgtextnode.cpp
@@ -54,10 +54,14 @@
#include <qabstracttextdocumentlayout.h>
#include <qxmlstream.h>
#include <qrawfont.h>
+#include <qtexttable.h>
+#include <qtextlist.h>
#include <private/qdeclarativestyledtext_p.h>
#include <private/qfont_p.h>
#include <private/qfontengine_p.h>
#include <private/qrawfont_p.h>
+#include <private/qtextimagehandler_p.h>
+#include <private/qtextdocumentlayout_p.h>
#include <qhash.h>
QT_BEGIN_NAMESPACE
@@ -75,6 +79,7 @@ QSGTextNode::QSGTextNode(QSGContext *context)
QSGTextNode::~QSGTextNode()
{
+ qDeleteAll(m_textures);
}
#if 0
@@ -169,16 +174,28 @@ namespace {
: selectionState(Unselected)
, clipNode(0)
, decorations(QSGTextNode::NoDecoration)
+ , ascent(0.0)
, leftChildIndex(-1)
, rightChildIndex(-1)
{
}
+ BinaryTreeNode(const QRectF &brect, const QImage &i, SelectionState selState, qreal a)
+ : boundingRect(brect)
+ , selectionState(selState)
+ , clipNode(0)
+ , decorations(QSGTextNode::NoDecoration)
+ , image(i)
+ , ascent(a)
+ , leftChildIndex(-1)
+ , rightChildIndex(-1)
+ {
+ }
+
BinaryTreeNode(const QGlyphRun &g, SelectionState selState, const QRectF &brect,
- const QSGTextNode::Decorations &decs,
- const QColor &c, const QColor &bc,
- const QPointF &pos)
+ const QSGTextNode::Decorations &decs, const QColor &c, const QColor &bc,
+ const QPointF &pos, qreal a)
: glyphRun(g)
, boundingRect(brect)
, selectionState(selState)
@@ -187,6 +204,7 @@ namespace {
, color(c)
, backgroundColor(bc)
, position(pos)
+ , ascent(a)
, leftChildIndex(-1)
, rightChildIndex(-1)
{
@@ -200,18 +218,28 @@ namespace {
QColor color;
QColor backgroundColor;
QPointF position;
+ QImage image;
+ qreal ascent;
int leftChildIndex;
int rightChildIndex;
static void insert(QVarLengthArray<BinaryTreeNode> *binaryTree,
+ const QRectF &rect,
+ const QImage &image,
+ qreal ascent,
+ SelectionState selectionState)
+ {
+ insert(binaryTree, BinaryTreeNode(rect, image, selectionState, ascent));
+ }
+
+ static void insert(QVarLengthArray<BinaryTreeNode> *binaryTree,
const QGlyphRun &glyphRun,
SelectionState selectionState,
const QColor &textColor,
const QColor &backgroundColor,
const QPointF &position)
{
- int newIndex = binaryTree->size();
QRectF searchRect = glyphRun.boundingRect();
searchRect.translate(position);
@@ -224,15 +252,23 @@ namespace {
decorations |= (glyphRun.strikeOut() ? QSGTextNode::StrikeOut : QSGTextNode::NoDecoration);
decorations |= (backgroundColor.isValid() ? QSGTextNode::Background : QSGTextNode::NoDecoration);
- binaryTree->append(BinaryTreeNode(glyphRun, selectionState, searchRect, decorations,
- textColor, backgroundColor, position));
+ qreal ascent = glyphRun.rawFont().ascent();
+ insert(binaryTree, BinaryTreeNode(glyphRun, selectionState, searchRect, decorations,
+ textColor, backgroundColor, position, ascent));
+ }
+
+ static void insert(QVarLengthArray<BinaryTreeNode> *binaryTree,
+ const BinaryTreeNode &binaryTreeNode)
+ {
+ int newIndex = binaryTree->size();
+ binaryTree->append(binaryTreeNode);
if (newIndex == 0)
return;
int searchIndex = 0;
forever {
BinaryTreeNode *node = binaryTree->data() + searchIndex;
- if (searchRect.left() < node->boundingRect.left()) {
+ if (binaryTreeNode.boundingRect.left() < node->boundingRect.left()) {
if (node->leftChildIndex < 0) {
node->leftChildIndex = newIndex;
break;
@@ -285,6 +321,16 @@ namespace {
m_currentLine = currentLine;
}
+ void addBorder(const QRectF &rect, qreal border, QTextFrameFormat::BorderStyle borderStyle,
+ const QBrush &borderBrush);
+ void addFrameDecorations(QTextDocument *document, QTextFrame *frame);
+ void addImage(const QRectF &rect, const QImage &image, qreal ascent,
+ BinaryTreeNode::SelectionState selectionState,
+ QTextFrameFormat::Position layoutPosition);
+ void addTextObject(const QPointF &position, const QTextCharFormat &format,
+ BinaryTreeNode::SelectionState selectionState,
+ QTextDocument *textDocument, int pos,
+ QTextFrameFormat::Position layoutPosition = QTextFrameFormat::InFlow);
void addSelectedGlyphs(const QGlyphRun &glyphRun);
void addUnselectedGlyphs(const QGlyphRun &glyphRun);
void addGlyphsInRange(int rangeStart, int rangeEnd,
@@ -349,11 +395,14 @@ namespace {
QTextLine m_currentLine;
bool m_hasSelection;
+ QList<QPair<QRectF, QColor> > m_backgrounds;
QList<QRectF> m_selectionRects;
QVarLengthArray<BinaryTreeNode> m_currentLineTree;
QList<TextDecoration> m_lines;
QVector<BinaryTreeNode> m_processedNodes;
+
+ QList<QPair<QRectF, QImage> > m_images;
};
void SelectionEngine::addTextDecorations(const QVarLengthArray<TextDecoration> &textDecorations,
@@ -410,7 +459,6 @@ namespace {
QVarLengthArray<TextDecoration> pendingUnderlines;
QVarLengthArray<TextDecoration> pendingOverlines;
QVarLengthArray<TextDecoration> pendingStrikeOuts;
- QVarLengthArray<TextDecoration> pendingBackgrounds;
if (!sortedIndexes.isEmpty()) {
QSGClipNode *currentClipNode = m_hasSelection ? new QSGClipNode : 0;
bool currentClipNodeUsed = false;
@@ -444,11 +492,8 @@ namespace {
if (currentDecorations & QSGTextNode::StrikeOut)
pendingStrikeOuts.append(textDecoration);
- if (currentDecorations & QSGTextNode::Background) {
- pendingBackgrounds.append(TextDecoration(BinaryTreeNode::Unselected,
- decorationRect,
- lastBackgroundColor));
- }
+ if (currentDecorations & QSGTextNode::Background)
+ m_backgrounds.append(qMakePair(decorationRect, lastBackgroundColor));
}
// If we've reached an unselected node from a selected node, we add the
@@ -500,13 +545,6 @@ namespace {
decorationRect = node->boundingRect;
- if (!pendingBackgrounds.isEmpty()) {
- addTextDecorations(pendingBackgrounds, -m_currentLine.ascent(),
- m_currentLine.height());
-
- pendingBackgrounds.clear();
- }
-
// If previous item(s) had underline and current does not, then we add the
// pending lines to the lists and likewise for overlines and strikeouts
if (!pendingUnderlines.isEmpty()
@@ -567,12 +605,6 @@ namespace {
}
}
- // If there are pending decorations, we need to add them
- if (!pendingBackgrounds.isEmpty()) {
- addTextDecorations(pendingBackgrounds, -m_currentLine.ascent(),
- m_currentLine.height());
- }
-
if (!pendingUnderlines.isEmpty())
addTextDecorations(pendingUnderlines, underlineOffset, underlineThickness);
@@ -588,6 +620,72 @@ namespace {
m_hasSelection = false;
}
+ void SelectionEngine::addImage(const QRectF &rect, const QImage &image, qreal ascent,
+ BinaryTreeNode::SelectionState selectionState,
+ QTextFrameFormat::Position layoutPosition)
+ {
+ QRectF searchRect = rect;
+ if (layoutPosition == QTextFrameFormat::InFlow) {
+ if (m_currentLineTree.isEmpty()) {
+ searchRect.moveTopLeft(m_position);
+ } else {
+ const BinaryTreeNode *lastNode = m_currentLineTree.data() + m_currentLineTree.size() - 1;
+ if (lastNode->glyphRun.isRightToLeft()) {
+ QPointF lastPos = lastNode->boundingRect.topLeft();
+ searchRect.moveTopRight(lastPos - QPointF(0, ascent));
+ } else {
+ QPointF lastPos = lastNode->boundingRect.topRight();
+ searchRect.moveTopLeft(lastPos - QPointF(0, ascent));
+ }
+ }
+ }
+
+ BinaryTreeNode::insert(&m_currentLineTree, searchRect, image, ascent, selectionState);
+ }
+
+ void SelectionEngine::addTextObject(const QPointF &position, const QTextCharFormat &format,
+ BinaryTreeNode::SelectionState selectionState,
+ QTextDocument *textDocument, int pos,
+ QTextFrameFormat::Position layoutPosition)
+ {
+ QTextObjectInterface *handler = textDocument->documentLayout()->handlerForObject(format.objectType());
+ if (handler != 0) {
+ QImage image;
+ QSizeF size = handler->intrinsicSize(textDocument, pos, format);
+
+ if (format.objectType() == QTextFormat::ImageObject) {
+ QTextImageFormat imageFormat = format.toImageFormat();
+ QTextImageHandler *imageHandler = static_cast<QTextImageHandler *>(handler);
+ image = imageHandler->image(textDocument, imageFormat);
+ }
+
+ if (image.isNull()) {
+ image = QImage(size.toSize(), QImage::Format_ARGB32_Premultiplied);
+ image.fill(Qt::transparent);
+ {
+ QPainter painter(&image);
+ handler->drawObject(&painter, image.rect(), textDocument, pos, format);
+ }
+ }
+
+ qreal ascent;
+ QFontMetrics m(format.font());
+ switch (format.verticalAlignment())
+ {
+ case QTextCharFormat::AlignMiddle:
+ ascent = size.height() / 2 - 1;
+ break;
+ case QTextCharFormat::AlignBaseline:
+ ascent = size.height() - m.descent() - 1;
+ break;
+ default:
+ ascent = size.height() - 1;
+ }
+
+ addImage(QRectF(position, size), image, ascent, selectionState, layoutPosition);
+ }
+ }
+
void SelectionEngine::addUnselectedGlyphs(const QGlyphRun &glyphRun)
{
BinaryTreeNode::insert(&m_currentLineTree, glyphRun, BinaryTreeNode::Unselected,
@@ -661,37 +759,46 @@ namespace {
m_backgroundColor = backgroundColor;
}
- bool hasSelection = selectionStart >= 0
- && selectionEnd >= 0
+ bool hasSelection = selectionEnd >= 0
&& selectionStart <= selectionEnd;
QTextLine &line = m_currentLine;
int rangeEnd = rangeStart + rangeLength;
if (!hasSelection || (selectionStart > rangeEnd || selectionEnd < rangeStart)) {
QList<QGlyphRun> glyphRuns = line.glyphRuns(rangeStart, rangeLength);
- for (int j=0; j<glyphRuns.size(); ++j)
- addUnselectedGlyphs(glyphRuns.at(j));
+ for (int j=0; j<glyphRuns.size(); ++j) {
+ const QGlyphRun &glyphRun = glyphRuns.at(j);
+ addUnselectedGlyphs(glyphRun);
+ }
} else {
if (rangeStart < selectionStart) {
QList<QGlyphRun> glyphRuns = line.glyphRuns(rangeStart,
qMin(selectionStart - rangeStart,
rangeLength));
- for (int j=0; j<glyphRuns.size(); ++j)
- addUnselectedGlyphs(glyphRuns.at(j));
+ for (int j=0; j<glyphRuns.size(); ++j) {
+ const QGlyphRun &glyphRun = glyphRuns.at(j);
+ addUnselectedGlyphs(glyphRun);
+ }
}
- if (rangeEnd >= selectionStart && selectionStart >= rangeStart) {
- QList<QGlyphRun> glyphRuns = line.glyphRuns(selectionStart, selectionEnd - selectionStart + 1);
+ if (rangeEnd > selectionStart) {
+ int start = qMax(selectionStart, rangeStart);
+ int length = qMin(selectionEnd - start + 1, rangeEnd - start);
+ QList<QGlyphRun> glyphRuns = line.glyphRuns(start, length);
- for (int j=0; j<glyphRuns.size(); ++j)
- addSelectedGlyphs(glyphRuns.at(j));
+ for (int j=0; j<glyphRuns.size(); ++j) {
+ const QGlyphRun &glyphRun = glyphRuns.at(j);
+ addSelectedGlyphs(glyphRun);
+ }
}
if (selectionEnd >= rangeStart && selectionEnd < rangeEnd) {
- QList<QGlyphRun> glyphRuns = line.glyphRuns(selectionEnd + 1, rangeEnd - selectionEnd);
- for (int j=0; j<glyphRuns.size(); ++j)
- addUnselectedGlyphs(glyphRuns.at(j));
+ QList<QGlyphRun> glyphRuns = line.glyphRuns(selectionEnd + 1, rangeEnd - selectionEnd - 1);
+ for (int j=0; j<glyphRuns.size(); ++j) {
+ const QGlyphRun &glyphRun = glyphRuns.at(j);
+ addUnselectedGlyphs(glyphRun);
+ }
}
}
@@ -702,6 +809,66 @@ namespace {
m_textColor = oldColor;
}
+ void SelectionEngine::addBorder(const QRectF &rect, qreal border,
+ QTextFrameFormat::BorderStyle borderStyle,
+ const QBrush &borderBrush)
+ {
+ QColor color = borderBrush.color();
+
+ // Currently we don't support other styles than solid
+ Q_UNUSED(borderStyle);
+
+ m_backgrounds.append(qMakePair(QRectF(rect.left(), rect.top(), border, rect.height() + border), color));
+ m_backgrounds.append(qMakePair(QRectF(rect.left() + border, rect.top(), rect.width(), border), color));
+ m_backgrounds.append(qMakePair(QRectF(rect.right(), rect.top() + border, border, rect.height() - border), color));
+ m_backgrounds.append(qMakePair(QRectF(rect.left() + border, rect.bottom(), rect.width(), border), color));
+ }
+
+ void SelectionEngine::addFrameDecorations(QTextDocument *document, QTextFrame *frame)
+ {
+ QTextDocumentLayout *documentLayout = qobject_cast<QTextDocumentLayout *>(document->documentLayout());
+ QTextFrameFormat frameFormat = frame->format().toFrameFormat();
+
+ QTextTable *table = qobject_cast<QTextTable *>(frame);
+ QRectF boundingRect = table == 0
+ ? documentLayout->frameBoundingRect(frame)
+ : documentLayout->tableBoundingRect(table);
+
+ QBrush bg = frame->frameFormat().background();
+ if (bg.style() != Qt::NoBrush)
+ m_backgrounds.append(qMakePair(boundingRect, bg.color()));
+
+ if (!frameFormat.hasProperty(QTextFormat::FrameBorder))
+ return;
+
+ qreal borderWidth = frameFormat.border();
+ if (qFuzzyIsNull(borderWidth))
+ return;
+
+ QBrush borderBrush = frameFormat.borderBrush();
+ QTextFrameFormat::BorderStyle borderStyle = frameFormat.borderStyle();
+ if (borderStyle == QTextFrameFormat::BorderStyle_None)
+ return;
+
+ addBorder(boundingRect.adjusted(frameFormat.leftMargin(), frameFormat.topMargin(),
+ -frameFormat.rightMargin(), -frameFormat.bottomMargin()),
+ borderWidth, borderStyle, borderBrush);
+ if (table != 0) {
+ int rows = table->rows();
+ int columns = table->columns();
+
+ for (int row=0; row<rows; ++row) {
+ for (int column=0; column<columns; ++column) {
+ QTextTableCell cell = table->cellAt(row, column);
+
+ QRectF cellRect = documentLayout->tableCellBoundingRect(table, cell);
+ addBorder(cellRect.adjusted(-borderWidth, -borderWidth, 0, 0), borderWidth,
+ borderStyle, borderBrush);
+ }
+ }
+ }
+ }
+
void SelectionEngine::addToSceneGraph(QSGTextNode *parentNode,
QSGText::TextStyle style,
const QColor &styleColor)
@@ -709,6 +876,14 @@ namespace {
if (m_currentLine.isValid())
processCurrentLine();
+
+ for (int i=0; i<m_backgrounds.size(); ++i) {
+ const QRectF &rect = m_backgrounds.at(i).first;
+ const QColor &color = m_backgrounds.at(i).second;
+
+ parentNode->appendChildNode(new QSGSimpleRectNode(rect, color));
+ }
+
// First, prepend all selection rectangles to the tree
for (int i=0; i<m_selectionRects.size(); ++i) {
const QRectF &rect = m_selectionRects.at(i);
@@ -734,35 +909,44 @@ namespace {
for (int i=0; i<m_processedNodes.size(); ++i) {
BinaryTreeNode *node = m_processedNodes.data() + i;
- QGlyphRun glyphRun = node->glyphRun;
- QRawFont rawFont = glyphRun.rawFont();
- QRawFontPrivate *rawFontD = QRawFontPrivate::get(rawFont);
+ if (node->image.isNull()) {
+ QGlyphRun glyphRun = node->glyphRun;
+ QRawFont rawFont = glyphRun.rawFont();
+ QRawFontPrivate *rawFontD = QRawFontPrivate::get(rawFont);
- QFontEngine *fontEngine = rawFontD->fontEngine;
+ QFontEngine *fontEngine = rawFontD->fontEngine;
- KeyType key(qMakePair(fontEngine,
- qMakePair(node->clipNode,
- qMakePair(node->color.rgba(), int(node->selectionState)))));
+ KeyType key(qMakePair(fontEngine,
+ qMakePair(node->clipNode,
+ qMakePair(node->color.rgba(), int(node->selectionState)))));
- BinaryTreeNode *otherNode = map.value(key, 0);
- if (otherNode != 0) {
- QGlyphRun &otherGlyphRun = otherNode->glyphRun;
+ BinaryTreeNode *otherNode = map.value(key, 0);
+ if (otherNode != 0) {
+ QGlyphRun &otherGlyphRun = otherNode->glyphRun;
- QVector<quint32> otherGlyphIndexes = otherGlyphRun.glyphIndexes();
- QVector<QPointF> otherGlyphPositions = otherGlyphRun.positions();
+ QVector<quint32> otherGlyphIndexes = otherGlyphRun.glyphIndexes();
+ QVector<QPointF> otherGlyphPositions = otherGlyphRun.positions();
- otherGlyphIndexes += glyphRun.glyphIndexes();
+ otherGlyphIndexes += glyphRun.glyphIndexes();
- QVector<QPointF> glyphPositions = glyphRun.positions();
- for (int j=0; j<glyphPositions.size(); ++j) {
- otherGlyphPositions += glyphPositions.at(j) + (node->position - otherNode->position);
- }
+ QVector<QPointF> glyphPositions = glyphRun.positions();
+ for (int j=0; j<glyphPositions.size(); ++j) {
+ otherGlyphPositions += glyphPositions.at(j) + (node->position - otherNode->position);
+ }
- otherGlyphRun.setGlyphIndexes(otherGlyphIndexes);
- otherGlyphRun.setPositions(otherGlyphPositions);
+ otherGlyphRun.setGlyphIndexes(otherGlyphIndexes);
+ otherGlyphRun.setPositions(otherGlyphPositions);
+ } else {
+ map.insert(key, node);
+ }
} else {
- map.insert(key, node);
+ parentNode->addImage(node->boundingRect, node->image);
+ if (node->selectionState == BinaryTreeNode::Selected) {
+ QColor color = m_selectionColor;
+ color.setAlpha(128);
+ parentNode->appendChildNode(new QSGSimpleRectNode(node->boundingRect, color));
+ }
}
}
@@ -840,77 +1024,199 @@ void QSGTextNode::mergeFormats(QTextLayout *textLayout,
}
+namespace {
+
+ class ProtectedLayoutAccessor: public QAbstractTextDocumentLayout
+ {
+ public:
+ inline QTextCharFormat formatAccessor(int pos)
+ {
+ return format(pos);
+ }
+ };
+
+}
+
+void QSGTextNode::addImage(const QRectF &rect, const QImage &image)
+{
+ QSGImageNode *node = m_context->createImageNode();
+ QSGTexture *texture = m_context->createTexture(image);
+ m_textures.append(texture);
+ node->setTargetRect(rect);
+ node->setTexture(texture);
+ appendChildNode(node);
+ node->update();
+}
+
void QSGTextNode::addTextDocument(const QPointF &, QTextDocument *textDocument,
const QColor &textColor,
QSGText::TextStyle style, const QColor &styleColor,
const QColor &selectionColor, const QColor &selectedTextColor,
int selectionStart, int selectionEnd)
{
- QTextFrame *textFrame = textDocument->rootFrame();
- QPointF position = textDocument->documentLayout()->frameBoundingRect(textFrame).topLeft();
-
SelectionEngine engine;
engine.setTextColor(textColor);
engine.setSelectedTextColor(selectedTextColor);
engine.setSelectionColor(selectionColor);
- QTextFrame::iterator it = textFrame->begin();
- while (!it.atEnd()) {
- Q_ASSERT(!engine.currentLine().isValid());
-
- QTextBlock block = it.currentBlock();
- int preeditLength = block.isValid() ? block.layout()->preeditAreaText().length() : 0;
- int preeditPosition = block.isValid() ? block.layout()->preeditAreaPosition() : -1;
-
- QVarLengthArray<QTextLayout::FormatRange> colorChanges;
- mergeFormats(block.layout(), &colorChanges);
-
- QTextBlock::iterator blockIterator = block.begin();
- int textPos = block.position();
- while (!blockIterator.atEnd()) {
- QTextFragment fragment = blockIterator.fragment();
- if (fragment.text().isEmpty())
- continue;
+ QList<QTextFrame *> frames;
+ frames.append(textDocument->rootFrame());
+ while (!frames.isEmpty()) {
+ QTextFrame *textFrame = frames.takeFirst();
+ frames.append(textFrame->childFrames());
+
+ engine.addFrameDecorations(textDocument, textFrame);
+
+ if (textFrame->firstPosition() > textFrame->lastPosition()
+ && textFrame->frameFormat().position() != QTextFrameFormat::InFlow) {
+ const int pos = textFrame->firstPosition() - 1;
+ ProtectedLayoutAccessor *a = static_cast<ProtectedLayoutAccessor *>(textDocument->documentLayout());
+ QTextCharFormat format = a->formatAccessor(pos);
+ QRectF rect = a->frameBoundingRect(textFrame);
+
+ QTextBlock block = textFrame->firstCursorPosition().block();
+ engine.setCurrentLine(block.layout()->lineForTextPosition(pos - block.position()));
+ engine.addTextObject(rect.topLeft(), format, BinaryTreeNode::Unselected, textDocument,
+ pos, textFrame->frameFormat().position());
+ } else {
+ QTextFrame::iterator it = textFrame->begin();
+
+ while (!it.atEnd()) {
+ Q_ASSERT(!engine.currentLine().isValid());
+
+ QTextBlock block = it.currentBlock();
+ int preeditLength = block.isValid() ? block.layout()->preeditAreaText().length() : 0;
+ int preeditPosition = block.isValid() ? block.layout()->preeditAreaPosition() : -1;
+
+ QVarLengthArray<QTextLayout::FormatRange> colorChanges;
+ mergeFormats(block.layout(), &colorChanges);
+
+ QPointF blockPosition = textDocument->documentLayout()->blockBoundingRect(block).topLeft();
+ if (QTextList *textList = block.textList()) {
+ QPointF pos = blockPosition;
+ QTextLayout *layout = block.layout();
+ if (layout->lineCount() > 0) {
+ QTextLine firstLine = layout->lineAt(0);
+ Q_ASSERT(firstLine.isValid());
+
+ engine.setCurrentLine(firstLine);
+
+ QRectF textRect = firstLine.naturalTextRect();
+ pos += textRect.topLeft();
+ if (block.textDirection() == Qt::RightToLeft)
+ pos.rx() += textRect.width();
+
+ const QTextCharFormat charFormat = block.charFormat();
+ QFont font(charFormat.font());
+ QFontMetricsF fontMetrics(font);
+ QTextListFormat listFormat = textList->format();
+
+ QString listItemBullet;
+ switch (listFormat.style()) {
+ case QTextListFormat::ListCircle:
+ listItemBullet = QChar(0x25E6); // White bullet
+ break;
+ case QTextListFormat::ListSquare:
+ listItemBullet = QChar(0x25AA); // Black small square
+ break;
+ case QTextListFormat::ListDecimal:
+ case QTextListFormat::ListLowerAlpha:
+ case QTextListFormat::ListUpperAlpha:
+ case QTextListFormat::ListLowerRoman:
+ case QTextListFormat::ListUpperRoman:
+ listItemBullet = textList->itemText(block);
+ break;
+ default:
+ listItemBullet = QChar(0x2022); // Black bullet
+ break;
+ };
+
+ QSizeF size(fontMetrics.width(listItemBullet), fontMetrics.height());
+ qreal xoff = fontMetrics.width(QLatin1Char(' '));
+ if (block.textDirection() == Qt::LeftToRight)
+ xoff = -xoff - size.width();
+ engine.setPosition(pos + QPointF(xoff, 0));
+
+ QTextLayout layout;
+ layout.setFont(font);
+ layout.setText(listItemBullet); // Bullet
+ layout.beginLayout();
+ QTextLine line = layout.createLine();
+ line.setPosition(QPointF(0, 0));
+ layout.endLayout();
+
+ QList<QGlyphRun> glyphRuns = layout.glyphRuns();
+ for (int i=0; i<glyphRuns.size(); ++i)
+ engine.addUnselectedGlyphs(glyphRuns.at(i));
+ }
+ }
- QPointF blockPosition = textDocument->documentLayout()->blockBoundingRect(block).topLeft();
- engine.setPosition(position + blockPosition);
+ int textPos = block.position();
+ QTextBlock::iterator blockIterator = block.begin();
+ while (!blockIterator.atEnd()) {
+ QTextFragment fragment = blockIterator.fragment();
+ QString text = fragment.text();
+ if (text.isEmpty())
+ continue;
+
+ QTextCharFormat charFormat = fragment.charFormat();
+ engine.setPosition(blockPosition);
+ if (text.contains(QChar::ObjectReplacementCharacter)) {
+ QTextFrame *frame = qobject_cast<QTextFrame *>(textDocument->objectForFormat(charFormat));
+ if (frame && frame->frameFormat().position() == QTextFrameFormat::InFlow) {
+ BinaryTreeNode::SelectionState selectionState =
+ (selectionStart < textPos + text.length()
+ && selectionEnd >= textPos)
+ ? BinaryTreeNode::Selected
+ : BinaryTreeNode::Unselected;
+
+ engine.addTextObject(QPointF(), charFormat, selectionState, textDocument, textPos);
+ }
+ textPos += text.length();
+ } else {
+ if (!textColor.isValid())
+ engine.setTextColor(charFormat.foreground().color());
+
+ int fragmentEnd = textPos + fragment.length();
+ if (preeditPosition >= 0
+ && preeditPosition >= textPos
+ && preeditPosition < fragmentEnd) {
+ fragmentEnd += preeditLength;
+ }
- QTextCharFormat charFormat = fragment.charFormat();
- if (!textColor.isValid())
- engine.setTextColor(charFormat.foreground().color());
+ while (textPos < fragmentEnd) {
+ int blockRelativePosition = textPos - block.position();
+ QTextLine line = block.layout()->lineForTextPosition(blockRelativePosition);
+ if (!engine.currentLine().isValid()
+ || line.lineNumber() != engine.currentLine().lineNumber()) {
+ engine.setCurrentLine(line);
+ }
- int fragmentEnd = textPos + fragment.length();
- if (preeditPosition >= 0
- && preeditPosition >= textPos
- && preeditPosition < fragmentEnd) {
- fragmentEnd += preeditLength;
- }
+ Q_ASSERT(line.textLength() > 0);
+ int lineEnd = line.textStart() + block.position() + line.textLength();
- while (textPos < fragmentEnd) {
- int blockRelativePosition = textPos - block.position();
- QTextLine line = block.layout()->lineForTextPosition(blockRelativePosition);
- Q_ASSERT(line.textLength() > 0);
- if (!engine.currentLine().isValid() || line.lineNumber() != engine.currentLine().lineNumber())
- engine.setCurrentLine(line);
+ int len = qMin(lineEnd - textPos, fragmentEnd - textPos);
+ Q_ASSERT(len > 0);
- int lineEnd = line.textStart() + block.position() + line.textLength();
+ int currentStepEnd = textPos + len;
- int len = qMin(lineEnd - textPos, fragmentEnd - textPos);
- Q_ASSERT(len > 0);
+ engine.addGlyphsForRanges(colorChanges,
+ textPos - block.position(),
+ currentStepEnd - block.position(),
+ selectionStart - block.position(),
+ selectionEnd - block.position());
- int currentStepEnd = textPos + len;
+ textPos = currentStepEnd;
+ }
+ }
- engine.addGlyphsForRanges(colorChanges, textPos, currentStepEnd,
- selectionStart, selectionEnd);
+ ++blockIterator;
+ }
- textPos = currentStepEnd;
+ engine.setCurrentLine(QTextLine()); // Reset current line because the text layout changed
+ ++it;
}
-
- ++blockIterator;
}
-
- engine.setCurrentLine(QTextLine()); // Reset current line because the text layout changed
- ++it;
}
engine.addToSceneGraph(this, style, styleColor);
@@ -953,143 +1259,6 @@ void QSGTextNode::addTextLayout(const QPointF &position, QTextLayout *textLayout
engine.addToSceneGraph(this, style, styleColor);
}
-
-/*!
- Returns true if \a text contains any HTML tags, attributes or CSS properties which are unrelated
- to text, fonts or text layout. Otherwise the function returns false. If the return value is
- false, \a text is considered to be easily representable in the scenegraph. If it returns true,
- then the text should be prerendered into a pixmap before it's displayed on screen.
-*/
-bool QSGTextNode::isComplexRichText(QTextDocument *doc)
-{
- if (doc == 0)
- return false;
-
- static QSet<QString> supportedTags;
- if (supportedTags.isEmpty()) {
- supportedTags.insert(QLatin1String("i"));
- supportedTags.insert(QLatin1String("b"));
- supportedTags.insert(QLatin1String("u"));
- supportedTags.insert(QLatin1String("div"));
- supportedTags.insert(QLatin1String("big"));
- supportedTags.insert(QLatin1String("blockquote"));
- supportedTags.insert(QLatin1String("body"));
- supportedTags.insert(QLatin1String("br"));
- supportedTags.insert(QLatin1String("center"));
- supportedTags.insert(QLatin1String("cite"));
- supportedTags.insert(QLatin1String("code"));
- supportedTags.insert(QLatin1String("tt"));
- supportedTags.insert(QLatin1String("dd"));
- supportedTags.insert(QLatin1String("dfn"));
- supportedTags.insert(QLatin1String("em"));
- supportedTags.insert(QLatin1String("font"));
- supportedTags.insert(QLatin1String("h1"));
- supportedTags.insert(QLatin1String("h2"));
- supportedTags.insert(QLatin1String("h3"));
- supportedTags.insert(QLatin1String("h4"));
- supportedTags.insert(QLatin1String("h5"));
- supportedTags.insert(QLatin1String("h6"));
- supportedTags.insert(QLatin1String("head"));
- supportedTags.insert(QLatin1String("html"));
- supportedTags.insert(QLatin1String("meta"));
- supportedTags.insert(QLatin1String("nobr"));
- supportedTags.insert(QLatin1String("p"));
- supportedTags.insert(QLatin1String("pre"));
- supportedTags.insert(QLatin1String("qt"));
- supportedTags.insert(QLatin1String("s"));
- supportedTags.insert(QLatin1String("samp"));
- supportedTags.insert(QLatin1String("small"));
- supportedTags.insert(QLatin1String("span"));
- supportedTags.insert(QLatin1String("strong"));
- supportedTags.insert(QLatin1String("sub"));
- supportedTags.insert(QLatin1String("sup"));
- supportedTags.insert(QLatin1String("title"));
- supportedTags.insert(QLatin1String("var"));
- supportedTags.insert(QLatin1String("style"));
- }
-
- static QSet<QCss::Property> supportedCssProperties;
- if (supportedCssProperties.isEmpty()) {
- supportedCssProperties.insert(QCss::Color);
- supportedCssProperties.insert(QCss::Float);
- supportedCssProperties.insert(QCss::Font);
- supportedCssProperties.insert(QCss::FontFamily);
- supportedCssProperties.insert(QCss::FontSize);
- supportedCssProperties.insert(QCss::FontStyle);
- supportedCssProperties.insert(QCss::FontWeight);
- supportedCssProperties.insert(QCss::Margin);
- supportedCssProperties.insert(QCss::MarginBottom);
- supportedCssProperties.insert(QCss::MarginLeft);
- supportedCssProperties.insert(QCss::MarginRight);
- supportedCssProperties.insert(QCss::MarginTop);
- supportedCssProperties.insert(QCss::TextDecoration);
- supportedCssProperties.insert(QCss::TextIndent);
- supportedCssProperties.insert(QCss::TextUnderlineStyle);
- supportedCssProperties.insert(QCss::VerticalAlignment);
- supportedCssProperties.insert(QCss::Whitespace);
- supportedCssProperties.insert(QCss::Padding);
- supportedCssProperties.insert(QCss::PaddingLeft);
- supportedCssProperties.insert(QCss::PaddingRight);
- supportedCssProperties.insert(QCss::PaddingTop);
- supportedCssProperties.insert(QCss::PaddingBottom);
- supportedCssProperties.insert(QCss::PageBreakBefore);
- supportedCssProperties.insert(QCss::PageBreakAfter);
- supportedCssProperties.insert(QCss::Width);
- supportedCssProperties.insert(QCss::Height);
- supportedCssProperties.insert(QCss::MinimumWidth);
- supportedCssProperties.insert(QCss::MinimumHeight);
- supportedCssProperties.insert(QCss::MaximumWidth);
- supportedCssProperties.insert(QCss::MaximumHeight);
- supportedCssProperties.insert(QCss::Left);
- supportedCssProperties.insert(QCss::Right);
- supportedCssProperties.insert(QCss::Top);
- supportedCssProperties.insert(QCss::Bottom);
- supportedCssProperties.insert(QCss::Position);
- supportedCssProperties.insert(QCss::TextAlignment);
- supportedCssProperties.insert(QCss::FontVariant);
- }
-
- QXmlStreamReader reader(doc->toHtml("utf-8"));
- while (!reader.atEnd()) {
- reader.readNext();
-
- if (reader.isStartElement()) {
- if (!supportedTags.contains(reader.name().toString().toLower()))
- return true;
-
- QXmlStreamAttributes attributes = reader.attributes();
- if (attributes.hasAttribute(QLatin1String("bgcolor")))
- return true;
- if (attributes.hasAttribute(QLatin1String("style"))) {
- QCss::StyleSheet styleSheet;
- QCss::Parser(attributes.value(QLatin1String("style")).toString()).parse(&styleSheet);
-
- QVector<QCss::Declaration> decls;
- for (int i=0; i<styleSheet.pageRules.size(); ++i)
- decls += styleSheet.pageRules.at(i).declarations;
-
- QVector<QCss::StyleRule> styleRules =
- styleSheet.styleRules
- + styleSheet.idIndex.values().toVector()
- + styleSheet.nameIndex.values().toVector();
- for (int i=0; i<styleSheet.mediaRules.size(); ++i)
- styleRules += styleSheet.mediaRules.at(i).styleRules;
-
- for (int i=0; i<styleRules.size(); ++i)
- decls += styleRules.at(i).declarations;
-
- for (int i=0; i<decls.size(); ++i) {
- if (!supportedCssProperties.contains(decls.at(i).d->propertyId))
- return true;
- }
-
- }
- }
- }
-
- return reader.hasError();
-}
-
void QSGTextNode::deleteContent()
{
while (firstChild() != 0)
diff --git a/src/declarative/items/qsgtextnode_p.h b/src/declarative/items/qsgtextnode_p.h
index b8e8cd6e4b..7a9462c24e 100644
--- a/src/declarative/items/qsgtextnode_p.h
+++ b/src/declarative/items/qsgtextnode_p.h
@@ -43,7 +43,7 @@
#define QSGTEXTNODE_P_H
#include <qsgnode.h>
-#include <qsgtext_p.h>
+#include "qsgtext_p.h"
#include <qglyphrun.h>
#include <QtGui/qcolor.h>
@@ -60,6 +60,7 @@ class QSGContext;
class QRawFont;
class QSGSimpleRectNode;
class QSGClipNode;
+class QSGTexture;
class QSGTextNode : public QSGTransformNode
{
@@ -94,12 +95,14 @@ public:
QSGGlyphNode *addGlyphs(const QPointF &position, const QGlyphRun &glyphs, const QColor &color,
QSGText::TextStyle style = QSGText::Normal, const QColor &styleColor = QColor(),
QSGNode *parentNode = 0);
+ void addImage(const QRectF &rect, const QImage &image);
private:
void mergeFormats(QTextLayout *textLayout, QVarLengthArray<QTextLayout::FormatRange> *mergedFormats);
QSGContext *m_context;
QSGSimpleRectNode *m_cursorNode;
+ QList<QSGTexture *> m_textures;
};
QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgtranslate.cpp b/src/declarative/items/qsgtranslate.cpp
index 1de5c6c3ea..577cf4d427 100644
--- a/src/declarative/items/qsgtranslate.cpp
+++ b/src/declarative/items/qsgtranslate.cpp
@@ -296,7 +296,8 @@ void QSGRotation::setAxis(Qt::Axis axis)
}
}
-struct QGraphicsRotation {
+class QGraphicsRotation {
+public:
static inline void projectedRotate(QMatrix4x4 *matrix, qreal angle, qreal x, qreal y, qreal z)
{
matrix->projectedRotate(angle, x, y, z);
diff --git a/src/declarative/items/qsgview.cpp b/src/declarative/items/qsgview.cpp
index 236fd4ec1f..841c8ebe31 100644
--- a/src/declarative/items/qsgview.cpp
+++ b/src/declarative/items/qsgview.cpp
@@ -62,9 +62,14 @@ DEFINE_BOOL_CONFIG_OPTION(frameRateDebug, QML_SHOW_FRAMERATE)
void QSGViewPrivate::init()
{
+ Q_Q(QSGView);
+
QDeclarativeEnginePrivate::get(&engine)->sgContext = QSGCanvasPrivate::context;
- QDeclarativeInspectorService::instance()->addView(q_func());
+ engine.setIncubationController(q->incubationController());
+
+ if (QDeclarativeDebugService::isDebuggingEnabled())
+ QDeclarativeInspectorService::instance()->addView(q);
}
QSGViewPrivate::QSGViewPrivate()
@@ -74,7 +79,8 @@ QSGViewPrivate::QSGViewPrivate()
QSGViewPrivate::~QSGViewPrivate()
{
- QDeclarativeInspectorService::instance()->removeView(q_func());
+ if (QDeclarativeDebugService::isDebuggingEnabled())
+ QDeclarativeInspectorService::instance()->removeView(q_func());
delete root;
}
@@ -264,7 +270,7 @@ void QSGView::continueExecute()
QObject *obj = d->component->create();
- if(d->component->isError()) {
+ if (d->component->isError()) {
QList<QDeclarativeError> errorList = d->component->errors();
foreach (const QDeclarativeError &error, errorList) {
qWarning() << error;
diff --git a/src/declarative/items/qsgview_p.h b/src/declarative/items/qsgview_p.h
index 3f8d69e8c0..f2b962c28e 100644
--- a/src/declarative/items/qsgview_p.h
+++ b/src/declarative/items/qsgview_p.h
@@ -48,9 +48,8 @@
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qtimer.h>
#include <QtCore/qpointer.h>
-#include <QtDeclarative/qsgview.h>
#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/private/qsgcanvas_p.h>
+#include "qsgcanvas_p.h"
#include "qsgitemchangelistener_p.h"
diff --git a/src/declarative/items/qsgvisualadaptormodel.cpp b/src/declarative/items/qsgvisualadaptormodel.cpp
index 3eb6214e47..4e3a1a6dc3 100644
--- a/src/declarative/items/qsgvisualadaptormodel.cpp
+++ b/src/declarative/items/qsgvisualadaptormodel.cpp
@@ -64,10 +64,10 @@
#include <QtCore/qhash.h>
#include <QtCore/qlist.h>
-QT_BEGIN_NAMESPACE
-
Q_DECLARE_METATYPE(QModelIndex)
+QT_BEGIN_NAMESPACE
+
class VDMDelegateDataType : public QDeclarativeRefCount
{
public:
diff --git a/src/declarative/items/qsgvisualadaptormodel_p.h b/src/declarative/items/qsgvisualadaptormodel_p.h
index bc9d3881fc..43af78b37e 100644
--- a/src/declarative/items/qsgvisualadaptormodel_p.h
+++ b/src/declarative/items/qsgvisualadaptormodel_p.h
@@ -45,7 +45,7 @@
#include <QtCore/qobject.h>
#include <QtCore/qabstractitemmodel.h>
-#include <QtDeclarative/private/qdeclarativerefcount_p.h>
+#include <private/qdeclarativerefcount_p.h>
QT_BEGIN_HEADER
diff --git a/src/declarative/items/qsgvisualdatamodel.cpp b/src/declarative/items/qsgvisualdatamodel.cpp
index 09f5d5d917..47edc5d8f0 100644
--- a/src/declarative/items/qsgvisualdatamodel.cpp
+++ b/src/declarative/items/qsgvisualdatamodel.cpp
@@ -58,8 +58,10 @@
#include <private/qdeclarativeglobal_p.h>
#include <private/qmetaobjectbuilder_p.h>
#include <private/qdeclarativeproperty_p.h>
-#include <private/qdeclarativechangeset_p.h>
#include <private/qsgvisualadaptormodel_p.h>
+#include <private/qdeclarativechangeset_p.h>
+#include <private/qdeclarativelistcompositor_p.h>
+#include <private/qdeclarativeengine_p.h>
#include <private/qobject_p.h>
#include <QtCore/qhash.h>
@@ -67,10 +69,56 @@
QT_BEGIN_NAMESPACE
+typedef QDeclarativeListCompositor Compositor;
+
+class QSGVisualDataGroupEmitter
+{
+public:
+ virtual void emitModelUpdated(const QDeclarativeChangeSet &changeSet, bool reset) = 0;
+ virtual void createdPackage(int, QDeclarativePackage *) {}
+ virtual void destroyingPackage(QDeclarativePackage *) {}
+
+ QIntrusiveListNode emitterNode;
+};
+
+typedef QIntrusiveList<QSGVisualDataGroupEmitter, &QSGVisualDataGroupEmitter::emitterNode> QSGVisualDataGroupEmitterList;
+
+//---------------------------------------------------------------------------
+
+class QSGVisualDataGroupPrivate : public QObjectPrivate
+{
+public:
+ Q_DECLARE_PUBLIC(QSGVisualDataGroup)
+
+ QSGVisualDataGroupPrivate() : group(Compositor::Cache), defaultInclude(false) {}
+
+ static QSGVisualDataGroupPrivate *get(QSGVisualDataGroup *group) {
+ return static_cast<QSGVisualDataGroupPrivate *>(QObjectPrivate::get(group)); }
+
+ void setModel(QSGVisualDataModel *model, Compositor::Group group);
+ void emitChanges(QV8Engine *engine);
+ void emitModelUpdated(bool reset);
+
+ void createdPackage(int index, QDeclarativePackage *package);
+ void destroyingPackage(QDeclarativePackage *package);
+
+ bool parseGroupArgs(QDeclarativeV8Function *args, int *index, int *count, int *groups) const;
+
+ Compositor::Group group;
+ QDeclarativeGuard<QSGVisualDataModel> model;
+ QSGVisualDataGroupEmitterList emitters;
+ QDeclarativeChangeSet changeSet;
+ QString name;
+ bool defaultInclude;
+};
+
+//---------------------------------------------------------------------------
+
+class QSGVisualDataModelCacheItem;
+class QSGVisualDataModelCacheMetaType;
class QSGVisualDataModelParts;
-class QSGVisualDataModelData;
-class QSGVisualDataModelDataMetaObject;
-class QSGVisualDataModelPrivate : public QObjectPrivate
+
+class QSGVisualDataModelPrivate : public QObjectPrivate, public QSGVisualDataGroupEmitter
{
Q_DECLARE_PUBLIC(QSGVisualDataModel)
public:
@@ -83,88 +131,92 @@ public:
void init();
void connectModel(QSGVisualAdaptorModel *model);
- QObject *object(int index, bool complete);
+ QObject *object(Compositor::Group group, int index, bool complete, bool reference);
+ void destroy(QObject *object);
QSGVisualDataModel::ReleaseFlags release(QObject *object);
- QString stringValue(int index, const QString &name);
- void emitCreatedPackage(int index, QDeclarativePackage *package) {
- emit q_func()->createdPackage(index, package); }
- void emitDestroyingPackage(QDeclarativePackage *package) {
- emit q_func()->destroyingPackage(package); }
-
+ QString stringValue(Compositor::Group group, int index, const QString &name);
+ int cacheIndexOf(QObject *object) const;
+ void emitCreatedPackage(Compositor::iterator at, QDeclarativePackage *package);
+ void emitCreatedItem(Compositor::iterator at, QSGItem *item) {
+ emit q_func()->createdItem(at.index[m_compositorGroup], item); }
+ void emitDestroyingPackage(QDeclarativePackage *package);
+ void emitDestroyingItem(QSGItem *item) { emit q_func()->destroyingItem(item); }
+
+ void updateFilterGroup();
+
+ void addGroups(Compositor::Group group, int index, int count, int groupFlags);
+ void removeGroups(Compositor::Group group, int index, int count, int groupFlags);
+ void setGroups(Compositor::Group group, int index, int count, int groupFlags);
+
+ void itemsInserted(
+ const QVector<Compositor::Insert> &inserts,
+ QVarLengthArray<QVector<QDeclarativeChangeSet::Insert>, Compositor::MaximumGroupCount> *translatedInserts,
+ QHash<int, QList<QSGVisualDataModelCacheItem *> > *movedItems = 0);
+ void itemsInserted(const QVector<Compositor::Insert> &inserts);
+ void itemsRemoved(
+ const QVector<Compositor::Remove> &removes,
+ QVarLengthArray<QVector<QDeclarativeChangeSet::Remove>, Compositor::MaximumGroupCount> *translatedRemoves,
+ QHash<int, QList<QSGVisualDataModelCacheItem *> > *movedItems = 0);
+ void itemsRemoved(const QVector<Compositor::Remove> &removes);
+ void itemsMoved(
+ const QVector<Compositor::Remove> &removes, const QVector<Compositor::Insert> &inserts);
+ void itemsChanged(const QVector<Compositor::Change> &changes);
+ template <typename T> static v8::Local<v8::Array> buildChangeList(const QVector<T> &changes);
void emitChanges();
+ void emitModelUpdated(const QDeclarativeChangeSet &changeSet, bool reset);
+
+
+ static void group_append(QDeclarativeListProperty<QSGVisualDataGroup> *property, QSGVisualDataGroup *group);
+ static int group_count(QDeclarativeListProperty<QSGVisualDataGroup> *property);
+ static QSGVisualDataGroup *group_at(QDeclarativeListProperty<QSGVisualDataGroup> *property, int index);
QSGVisualAdaptorModel *m_adaptorModel;
QDeclarativeComponent *m_delegate;
+ QSGVisualDataModelCacheMetaType *m_cacheMetaType;
QDeclarativeGuard<QDeclarativeContext> m_context;
- struct ObjectRef {
- ObjectRef(QObject *object=0) : obj(object), ref(1) {}
- QObject *obj;
- int ref;
- };
- class Cache : public QHash<int, ObjectRef> {
- public:
- QObject *getItem(int index) {
- QObject *item = 0;
- QHash<int,ObjectRef>::iterator it = find(index);
- if (it != end()) {
- (*it).ref++;
- item = (*it).obj;
- }
- return item;
- }
- QObject *item(int index) {
- QObject *item = 0;
- QHash<int, ObjectRef>::const_iterator it = find(index);
- if (it != end())
- item = (*it).obj;
- return item;
- }
- void insertItem(int index, QObject *obj) {
- insert(index, ObjectRef(obj));
- }
- bool releaseItem(QObject *obj) {
- QHash<int, ObjectRef>::iterator it = begin();
- for (; it != end(); ++it) {
- ObjectRef &objRef = *it;
- if (objRef.obj == obj) {
- if (--objRef.ref == 0) {
- erase(it);
- return true;
- }
- break;
- }
- }
- return false;
- }
- };
-
- Cache m_cache;
- QHash<QObject *, QDeclarativePackage*> m_packaged;
-
+ QList<QSGVisualDataModelCacheItem *> m_cache;
QSGVisualDataModelParts *m_parts;
- friend class QSGVisualItemParts;
+ QSGVisualDataGroupEmitterList m_pendingParts;
- friend class QSGVisualDataModelData;
+ QDeclarativeListCompositor m_compositor;
+ QDeclarativeListCompositor::Group m_compositorGroup;
+ bool m_complete : 1;
bool m_delegateValidated : 1;
bool m_completePending : 1;
bool m_reset : 1;
+ bool m_transaction : 1;
- QDeclarativeChangeSet m_absoluteChangeSet;
-
+ QString m_filterGroup;
QList<QByteArray> watchedRoles;
+
+ union {
+ struct {
+ QSGVisualDataGroup *m_cacheItems;
+ QSGVisualDataGroup *m_items;
+ QSGVisualDataGroup *m_persistedItems;
+ };
+ QSGVisualDataGroup *m_groups[Compositor::MaximumGroupCount];
+ };
+ int m_groupCount;
};
//---------------------------------------------------------------------------
-class QSGVisualPartsModel : public QSGVisualModel
+class QSGVisualPartsModel : public QSGVisualModel, public QSGVisualDataGroupEmitter
{
Q_OBJECT
-
+ Q_PROPERTY(QString filterOnGroup READ filterGroup WRITE setFilterGroup NOTIFY filterGroupChanged RESET resetFilterGroup)
public:
QSGVisualPartsModel(QSGVisualDataModel *model, const QString &part, QObject *parent = 0);
~QSGVisualPartsModel();
+ QString filterGroup() const;
+ void setFilterGroup(const QString &group);
+ void resetFilterGroup();
+ void updateFilterGroup();
+ void updateFilterGroup(Compositor::Group group, const QDeclarativeChangeSet &changeSet);
+
int count() const;
bool isValid() const;
QSGItem *item(int index, bool complete=true);
@@ -176,15 +228,22 @@ public:
int indexOf(QSGItem *item, QObject *objectContext) const;
-public Q_SLOTS:
+ void emitModelUpdated(const QDeclarativeChangeSet &changeSet, bool reset);
+
void createdPackage(int index, QDeclarativePackage *package);
void destroyingPackage(QDeclarativePackage *package);
+Q_SIGNALS:
+ void filterGroupChanged();
+
private:
QSGVisualDataModel *m_model;
QHash<QObject *, QDeclarativePackage *> m_packaged;
QString m_part;
+ QString m_filterGroup;
QList<QByteArray> m_watchedRoles;
+ Compositor::Group m_compositorGroup;
+ bool m_inheritGroup;
};
class QSGVisualDataModelPartsMetaObject : public QDeclarativeOpenMetaObject
@@ -203,9 +262,8 @@ Q_OBJECT
public:
QSGVisualDataModelParts(QSGVisualDataModel *parent);
-private:
- friend class QSGVisualDataModelPartsMetaObject;
QSGVisualDataModel *model;
+ QList<QSGVisualPartsModel *> models;
};
void QSGVisualDataModelPartsMetaObject::propertyCreated(int, QMetaPropertyBuilder &prop)
@@ -215,10 +273,10 @@ void QSGVisualDataModelPartsMetaObject::propertyCreated(int, QMetaPropertyBuilde
QVariant QSGVisualDataModelPartsMetaObject::initialValue(int id)
{
+ QSGVisualDataModelParts *parts = static_cast<QSGVisualDataModelParts *>(object());
QSGVisualPartsModel *m = new QSGVisualPartsModel(
- static_cast<QSGVisualDataModelParts *>(object())->model,
- QString::fromUtf8(name(id)),
- object());
+ parts->model, QString::fromUtf8(name(id)), parts);
+ parts->models.append(m);
return QVariant::fromValue(static_cast<QObject *>(m));
}
@@ -228,19 +286,96 @@ QSGVisualDataModelParts::QSGVisualDataModelParts(QSGVisualDataModel *parent)
new QSGVisualDataModelPartsMetaObject(this);
}
-QSGVisualDataModelPrivate::QSGVisualDataModelPrivate(QDeclarativeContext *ctxt)
- : m_adaptorModel(0)
- , m_delegate(0)
- , m_context(ctxt)
- , m_parts(0)
- , m_delegateValidated(false)
- , m_completePending(false)
- , m_reset(false)
+//---------------------------------------------------------------------------
+
+class QSGVisualDataModelCacheMetaType : public QDeclarativeRefCount
{
-}
+public:
+ QSGVisualDataModelCacheMetaType(QV8Engine *engine, QSGVisualDataModel *model, const QStringList &groupNames);
+ ~QSGVisualDataModelCacheMetaType();
+
+ int parseGroups(const QStringList &groupNames) const;
+ int parseGroups(QV8Engine *engine, const v8::Local<v8::Value> &groupNames) const;
+
+ static v8::Handle<v8::Value> get_model(v8::Local<v8::String>, const v8::AccessorInfo &info);
+ static v8::Handle<v8::Value> get_groups(v8::Local<v8::String>, const v8::AccessorInfo &info);
+ static void set_groups(
+ v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info);
+ static v8::Handle<v8::Value> get_member(v8::Local<v8::String>, const v8::AccessorInfo &info);
+ static void set_member(
+ v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info);
+ static v8::Handle<v8::Value> get_index(v8::Local<v8::String>, const v8::AccessorInfo &info);
+
+ QDeclarativeGuard<QSGVisualDataModel> model;
+ const int groupCount;
+ const int memberPropertyOffset;
+ const int indexPropertyOffset;
+ QV8Engine * const v8Engine;
+ QMetaObject *metaObject;
+ const QStringList groupNames;
+ v8::Persistent<v8::Function> constructor;
+};
+
+class QSGVisualDataModelCacheItem : public QV8ObjectResource
+{
+ V8_RESOURCE_TYPE(VisualDataItemType)
+public:
+ QSGVisualDataModelCacheItem(QSGVisualDataModelCacheMetaType *metaType)
+ : QV8ObjectResource(metaType->v8Engine)
+ , metaType(metaType)
+ , object(0)
+ , attached(0)
+ , objectRef(0)
+ , scriptRef(0)
+ , groups(0)
+ {
+ metaType->addref();
+ }
+
+ ~QSGVisualDataModelCacheItem()
+ {
+ Q_ASSERT(scriptRef == 0);
+ Q_ASSERT(objectRef == 0);
+ Q_ASSERT(!object);
+
+ metaType->release();
+ }
+
+ void referenceObject() { ++objectRef; }
+ bool releaseObject() { return --objectRef == 0 && !(groups & Compositor::PersistedFlag); }
+ bool isObjectReferenced() const { return objectRef == 0 && !(groups & Compositor::PersistedFlag); }
+
+ bool isReferenced() const { return objectRef || scriptRef || (groups & Compositor::PersistedFlag); }
+
+ void Dispose();
+
+ QSGVisualDataModelCacheMetaType * const metaType;
+ QDeclarativeGuard<QObject> object;
+ QSGVisualDataModelAttached *attached;
+ int objectRef;
+ int scriptRef;
+ int groups;
+ int index[Compositor::MaximumGroupCount];
+};
+
+class QSGVisualDataModelAttachedMetaObject : public QAbstractDynamicMetaObject
+{
+public:
+ QSGVisualDataModelAttachedMetaObject(
+ QSGVisualDataModelAttached *attached, QSGVisualDataModelCacheMetaType *metaType);
+ ~QSGVisualDataModelAttachedMetaObject();
+
+ int metaCall(QMetaObject::Call, int _id, void **);
+
+private:
+ QSGVisualDataModelAttached *attached;
+ QSGVisualDataModelCacheMetaType *metaType;
+};
//---------------------------------------------------------------------------
+QHash<QObject*, QSGVisualDataModelAttached*> QSGVisualDataModelAttached::attachedProperties;
+
/*!
\qmlclass VisualDataModel QSGVisualDataModel
\inqmlmodule QtQuick 2
@@ -261,6 +396,25 @@ QSGVisualDataModelPrivate::QSGVisualDataModelPrivate(QDeclarativeContext *ctxt)
\snippet doc/src/snippets/declarative/visualdatamodel.qml 0
*/
+QSGVisualDataModelPrivate::QSGVisualDataModelPrivate(QDeclarativeContext *ctxt)
+ : m_adaptorModel(0)
+ , m_delegate(0)
+ , m_cacheMetaType(0)
+ , m_context(ctxt)
+ , m_parts(0)
+ , m_compositorGroup(Compositor::Cache)
+ , m_complete(false)
+ , m_delegateValidated(false)
+ , m_completePending(false)
+ , m_reset(false)
+ , m_transaction(false)
+ , m_filterGroup(QStringLiteral("items"))
+ , m_cacheItems(0)
+ , m_items(0)
+ , m_groupCount(3)
+{
+}
+
void QSGVisualDataModelPrivate::connectModel(QSGVisualAdaptorModel *model)
{
Q_Q(QSGVisualDataModel);
@@ -275,9 +429,15 @@ void QSGVisualDataModelPrivate::connectModel(QSGVisualAdaptorModel *model)
void QSGVisualDataModelPrivate::init()
{
Q_Q(QSGVisualDataModel);
+ m_compositor.setRemoveGroups(Compositor::GroupMask & ~Compositor::PersistedFlag);
+
m_adaptorModel = new QSGVisualAdaptorModel;
QObject::connect(m_adaptorModel, SIGNAL(rootIndexChanged()), q, SIGNAL(rootIndexChanged()));
- connectModel(m_adaptorModel);
+
+ m_items = new QSGVisualDataGroup(QStringLiteral("items"), q, Compositor::Default, q);
+ m_items->setDefaultInclude(true);
+ m_persistedItems = new QSGVisualDataGroup(QStringLiteral("persistedItems"), q, Compositor::Persisted, q);
+ QSGVisualDataGroupPrivate::get(m_items)->emitters.insert(this);
}
QSGVisualDataModel::QSGVisualDataModel()
@@ -297,7 +457,83 @@ QSGVisualDataModel::QSGVisualDataModel(QDeclarativeContext *ctxt, QObject *paren
QSGVisualDataModel::~QSGVisualDataModel()
{
Q_D(QSGVisualDataModel);
+ foreach (QSGVisualDataModelCacheItem *cacheItem, d->m_cache) {
+ cacheItem->object = 0;
+ cacheItem->objectRef = 0;
+ if (!cacheItem->isReferenced())
+ delete cacheItem;
+ }
+
delete d->m_adaptorModel;
+ if (d->m_cacheMetaType)
+ d->m_cacheMetaType->release();
+}
+
+
+void QSGVisualDataModel::classBegin()
+{
+}
+
+void QSGVisualDataModel::componentComplete()
+{
+ Q_D(QSGVisualDataModel);
+ d->m_complete = true;
+
+ int defaultGroups = 0;
+ QStringList groupNames;
+ groupNames.append(QStringLiteral("items"));
+ groupNames.append(QStringLiteral("persistedItems"));
+ if (QSGVisualDataGroupPrivate::get(d->m_items)->defaultInclude)
+ defaultGroups |= Compositor::DefaultFlag;
+ if (QSGVisualDataGroupPrivate::get(d->m_persistedItems)->defaultInclude)
+ defaultGroups |= Compositor::PersistedFlag;
+ for (int i = 3; i < d->m_groupCount; ++i) {
+ QString name = d->m_groups[i]->name();
+ if (name.isEmpty()) {
+ d->m_groups[i] = d->m_groups[d->m_groupCount - 1];
+ --d->m_groupCount;
+ --i;
+ } else if (name.at(0).isUpper()) {
+ qmlInfo(d->m_groups[i]) << QSGVisualDataGroup::tr("Group names must start with a lower case letter");
+ d->m_groups[i] = d->m_groups[d->m_groupCount - 1];
+ --d->m_groupCount;
+ --i;
+ } else {
+ groupNames.append(name);
+
+ QSGVisualDataGroupPrivate *group = QSGVisualDataGroupPrivate::get(d->m_groups[i]);
+ group->setModel(this, Compositor::Group(i));
+ if (group->defaultInclude)
+ defaultGroups |= (1 << i);
+ }
+ }
+ if (!d->m_context)
+ d->m_context = qmlContext(this);
+
+ d->m_cacheMetaType = new QSGVisualDataModelCacheMetaType(
+ QDeclarativeEnginePrivate::getV8Engine(d->m_context->engine()), this, groupNames);
+
+ d->m_compositor.setGroupCount(d->m_groupCount);
+ d->m_compositor.setDefaultGroups(defaultGroups);
+ d->updateFilterGroup();
+
+ while (!d->m_pendingParts.isEmpty())
+ static_cast<QSGVisualPartsModel *>(d->m_pendingParts.first())->updateFilterGroup();
+
+ d->connectModel(d->m_adaptorModel);
+ QVector<Compositor::Insert> inserts;
+ d->m_reset = true;
+ d->m_compositor.append(
+ d->m_adaptorModel,
+ 0,
+ qMax(0, d->m_adaptorModel->count()),
+ defaultGroups | Compositor::AppendFlag | Compositor::PrependFlag,
+ &inserts);
+ d->itemsInserted(inserts);
+ d->emitChanges();
+
+ if (d->m_adaptorModel->canFetchMore())
+ QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
}
/*!
@@ -324,7 +560,7 @@ void QSGVisualDataModel::setModel(const QVariant &model)
{
Q_D(QSGVisualDataModel);
d->m_adaptorModel->setModel(model, d->m_context ? d->m_context->engine() : qmlEngine(this));
- if (d->m_adaptorModel->canFetchMore())
+ if (d->m_complete && d->m_adaptorModel->canFetchMore())
QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
}
@@ -344,13 +580,26 @@ QDeclarativeComponent *QSGVisualDataModel::delegate() const
void QSGVisualDataModel::setDelegate(QDeclarativeComponent *delegate)
{
Q_D(QSGVisualDataModel);
+ if (d->m_transaction) {
+ qmlInfo(this) << tr("The delegate of a VisualDataModel cannot be changed within onUpdated.");
+ return;
+ }
bool wasValid = d->m_delegate != 0;
d->m_delegate = delegate;
d->m_delegateValidated = false;
- if (!wasValid && d->m_adaptorModel->count() && d->m_delegate)
- _q_itemsInserted(0, d->m_adaptorModel->count());
- if (wasValid && !d->m_delegate && d->m_adaptorModel->count())
- _q_itemsRemoved(0, d->m_adaptorModel->count());
+ if (wasValid && d->m_complete) {
+ for (int i = 1; i < d->m_groupCount; ++i) {
+ QSGVisualDataGroupPrivate::get(d->m_groups[i])->changeSet.remove(
+ 0, d->m_compositor.count(Compositor::Group(i)));
+ }
+ }
+ if (d->m_complete && d->m_delegate) {
+ for (int i = 1; i < d->m_groupCount; ++i) {
+ QSGVisualDataGroupPrivate::get(d->m_groups[i])->changeSet.insert(
+ 0, d->m_compositor.count(Compositor::Group(i)));
+ }
+ }
+ d->emitChanges();
}
/*!
@@ -430,31 +679,51 @@ QVariant QSGVisualDataModel::parentModelIndex() const
return d->m_adaptorModel->parentModelIndex();
}
+/*!
+ \qmlproperty int QtQuick2::VisualDataModel::count
+*/
+
int QSGVisualDataModel::count() const
{
Q_D(const QSGVisualDataModel);
if (!d->m_delegate)
return 0;
- return d->m_adaptorModel->count();
+ return d->m_compositor.count(d->m_compositorGroup);
+}
+
+void QSGVisualDataModelPrivate::destroy(QObject *object)
+{
+ QObjectPrivate *p = QObjectPrivate::get(object);
+ Q_ASSERT(p->declarativeData);
+ QDeclarativeData *data = static_cast<QDeclarativeData*>(p->declarativeData);
+ if (data->ownContext && data->context)
+ data->context->clearContext();
+ object->deleteLater();
}
QSGVisualDataModel::ReleaseFlags QSGVisualDataModelPrivate::release(QObject *object)
{
QSGVisualDataModel::ReleaseFlags stat = 0;
-
- if (m_cache.releaseItem(object)) {
- // Remove any bindings to avoid warnings due to parent change.
- QObjectPrivate *p = QObjectPrivate::get(object);
- Q_ASSERT(p->declarativeData);
- QDeclarativeData *d = static_cast<QDeclarativeData*>(p->declarativeData);
- if (d->ownContext && d->context)
- d->context->clearContext();
- stat |= QSGVisualDataModel::Destroyed;
- object->deleteLater();
- } else {
- stat |= QSGVisualDataModel::Referenced;
+ if (!object)
+ return stat;
+
+ int cacheIndex = cacheIndexOf(object);
+ if (cacheIndex != -1) {
+ QSGVisualDataModelCacheItem *cacheItem = m_cache.at(cacheIndex);
+ if (cacheItem->releaseObject()) {
+ destroy(object);
+ cacheItem->object = 0;
+ stat |= QSGVisualModel::Destroyed;
+ if (!cacheItem->isReferenced()) {
+ m_compositor.clearFlags(Compositor::Cache, cacheIndex, 1, Compositor::CacheFlag);
+ m_cache.removeAt(cacheIndex);
+ delete cacheItem;
+ Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
+ }
+ } else {
+ stat |= QSGVisualDataModel::Referenced;
+ }
}
-
return stat;
}
@@ -471,6 +740,172 @@ QSGVisualDataModel::ReleaseFlags QSGVisualDataModel::release(QSGItem *item)
return stat;
}
+void QSGVisualDataModelPrivate::group_append(
+ QDeclarativeListProperty<QSGVisualDataGroup> *property, QSGVisualDataGroup *group)
+{
+ QSGVisualDataModelPrivate *d = static_cast<QSGVisualDataModelPrivate *>(property->data);
+ if (d->m_complete)
+ return;
+ if (d->m_groupCount == 11) {
+ qmlInfo(d->q_func()) << QSGVisualDataModel::tr("The maximum number of supported VisualDataGroups is 8");
+ return;
+ }
+ d->m_groups[d->m_groupCount] = group;
+ d->m_groupCount += 1;
+}
+
+int QSGVisualDataModelPrivate::group_count(
+ QDeclarativeListProperty<QSGVisualDataGroup> *property)
+{
+ QSGVisualDataModelPrivate *d = static_cast<QSGVisualDataModelPrivate *>(property->data);
+ return d->m_groupCount - 1;
+}
+
+QSGVisualDataGroup *QSGVisualDataModelPrivate::group_at(
+ QDeclarativeListProperty<QSGVisualDataGroup> *property, int index)
+{
+ QSGVisualDataModelPrivate *d = static_cast<QSGVisualDataModelPrivate *>(property->data);
+ return index >= 0 && index < d->m_groupCount - 1
+ ? d->m_groups[index - 1]
+ : 0;
+}
+
+/*!
+ \qmlproperty list<VisualDataGroup> QtQuick2::VisualDataModel::groups
+
+ This property holds a visual data model's group definitions.
+
+ Groups define a sub-set of the items in a visual data model and can be used to filter
+ a model.
+
+ For every group defined in a VisualDataModel two attached properties are added to each
+ delegate item. The first of the form VisualDataModel.in\e{GroupName} holds whether the
+ item belongs to the group and the second VisualDataModel.\e{groupName}Index holds the
+ index of the item in that group.
+
+ The following example illustrates using groups to select items in a model.
+
+ \snippet doc/src/snippets/declarative/visualdatagroup.qml 0
+*/
+
+QDeclarativeListProperty<QSGVisualDataGroup> QSGVisualDataModel::groups()
+{
+ Q_D(QSGVisualDataModel);
+ return QDeclarativeListProperty<QSGVisualDataGroup>(
+ this,
+ d,
+ QSGVisualDataModelPrivate::group_append,
+ QSGVisualDataModelPrivate::group_count,
+ QSGVisualDataModelPrivate::group_at);
+}
+
+/*!
+ \qmlproperty VisualDataGroup QtQuick2::VisualDataModel::items
+
+ This property holds visual data model's default group to which all new items are added.
+*/
+
+QSGVisualDataGroup *QSGVisualDataModel::items()
+{
+ Q_D(QSGVisualDataModel);
+ return d->m_items;
+}
+
+/*!
+ \qmlproperty VisualDataGroup QtQuick2::VisualDataModel::persistedItems
+
+ This property holds visual data model's persisted items group.
+
+ Items in this group are not destroyed when released by a view, instead they are persisted
+ until removed from the group.
+
+ An item can be removed from the persistedItems group by setting the
+ VisualDataModel.inPersistedItems property to false. If the item is not referenced by a view
+ at that time it will be destroyed. Adding an item to this group will not create a new
+ instance.
+
+ Items returned by the \l QtQuick2::VisualDataGroup::create() function are automatically added
+ to this group.
+*/
+
+QSGVisualDataGroup *QSGVisualDataModel::persistedItems()
+{
+ Q_D(QSGVisualDataModel);
+ return d->m_persistedItems;
+}
+
+/*!
+ \qmlproperty string QtQuick2::VisualDataModel::filterOnGroup
+
+ This property holds the name of the group used to filter the visual data model.
+
+ Only items which belong to this group are visible to a view.
+
+ By default this is the \l items group.
+*/
+
+QString QSGVisualDataModel::filterGroup() const
+{
+ Q_D(const QSGVisualDataModel);
+ return d->m_filterGroup;
+}
+
+void QSGVisualDataModel::setFilterGroup(const QString &group)
+{
+ Q_D(QSGVisualDataModel);
+
+ if (d->m_transaction) {
+ qmlInfo(this) << tr("The group of a VisualDataModel cannot be changed within onChanged");
+ return;
+ }
+
+ if (d->m_filterGroup != group) {
+ d->m_filterGroup = group;
+ d->updateFilterGroup();
+ emit filterGroupChanged();
+ }
+}
+
+void QSGVisualDataModel::resetFilterGroup()
+{
+ setFilterGroup(QStringLiteral("items"));
+}
+
+void QSGVisualDataModelPrivate::updateFilterGroup()
+{
+ Q_Q(QSGVisualDataModel);
+ if (!m_cacheMetaType)
+ return;
+
+ QDeclarativeListCompositor::Group previousGroup = m_compositorGroup;
+ m_compositorGroup = Compositor::Default;
+ for (int i = 1; i < m_groupCount; ++i) {
+ if (m_filterGroup == m_cacheMetaType->groupNames.at(i - 1)) {
+ m_compositorGroup = Compositor::Group(i);
+ break;
+ }
+ }
+
+ QSGVisualDataGroupPrivate::get(m_groups[m_compositorGroup])->emitters.insert(this);
+ if (m_compositorGroup != previousGroup) {
+ QVector<QDeclarativeChangeSet::Remove> removes;
+ QVector<QDeclarativeChangeSet::Insert> inserts;
+ m_compositor.transition(previousGroup, m_compositorGroup, &removes, &inserts);
+
+ QDeclarativeChangeSet changeSet;
+ changeSet.apply(removes, inserts);
+ emit q->modelUpdated(changeSet, false);
+
+ if (changeSet.difference() != 0)
+ emit q->countChanged();
+
+ if (m_parts) {
+ foreach (QSGVisualPartsModel *model, m_parts->models)
+ model->updateFilterGroup(m_compositorGroup, changeSet);
+ }
+ }
+}
+
/*!
\qmlproperty object QtQuick2::VisualDataModel::parts
@@ -507,18 +942,38 @@ QObject *QSGVisualDataModel::parts()
return d->m_parts;
}
-QObject *QSGVisualDataModelPrivate::object(int index, bool complete)
+void QSGVisualDataModelPrivate::emitCreatedPackage(Compositor::iterator at, QDeclarativePackage *package)
+{
+ for (int i = 1; i < m_groupCount; ++i)
+ QSGVisualDataGroupPrivate::get(m_groups[i])->createdPackage(at.index[i], package);
+}
+
+void QSGVisualDataModelPrivate::emitDestroyingPackage(QDeclarativePackage *package)
+{
+ for (int i = 1; i < m_groupCount; ++i)
+ QSGVisualDataGroupPrivate::get(m_groups[i])->destroyingPackage(package);
+}
+
+QObject *QSGVisualDataModelPrivate::object(Compositor::Group group, int index, bool complete, bool reference)
{
Q_Q(QSGVisualDataModel);
- if (m_adaptorModel->count() <= 0 || !m_delegate)
- return 0;
- QObject *nobj = m_cache.getItem(index);
- bool needComplete = false;
- if (!nobj) {
- QObject *data = m_adaptorModel->data(index);
+ Compositor::iterator it = m_compositor.find(group, index);
+ QSGVisualDataModelCacheItem *cacheItem = it->inCache() ? m_cache.at(it.cacheIndex) : 0;
+
+ if (!cacheItem) {
+ cacheItem = new QSGVisualDataModelCacheItem(m_cacheMetaType);
+ for (int i = 0; i < m_groupCount; ++i)
+ cacheItem->index[i] = it.index[i];
+ cacheItem->groups = it->flags & Compositor::GroupMask;
+ }
+
+ if (!cacheItem->object) {
+ QObject *data = m_adaptorModel->data(it.modelIndex());
+
+ QDeclarativeContext *creationContext = m_delegate->creationContext();
QDeclarativeContext *rootContext = new QDeclarativeContext(
- m_context ? m_context.data() : qmlContext(q));
+ creationContext ? creationContext : m_context.data());
QDeclarativeContext *ctxt = rootContext;
if (m_adaptorModel->flags() & QSGVisualAdaptorModel::ProxiedObject) {
if (QSGVisualAdaptorModelProxyInterface *proxy = qobject_cast<QSGVisualAdaptorModelProxyInterface *>(data)) {
@@ -532,42 +987,64 @@ QObject *QSGVisualDataModelPrivate::object(int index, bool complete)
ctxt->setContextObject(data);
m_completePending = false;
- nobj = m_delegate->beginCreate(ctxt);
- if (complete) {
- m_delegate->completeCreate();
- } else {
- m_completePending = true;
- needComplete = true;
- }
- if (nobj) {
- QDeclarative_setParent_noEvent(rootContext, nobj);
- m_cache.insertItem(index, nobj);
- if (QDeclarativePackage *package = qobject_cast<QDeclarativePackage *>(nobj))
- emitCreatedPackage(index, package);
+ cacheItem->object = m_delegate->beginCreate(ctxt);
+
+ if (cacheItem->object) {
+ QDeclarative_setParent_noEvent(rootContext, cacheItem->object);
+ if (!it->inCache()) {
+ m_cache.insert(it.cacheIndex, cacheItem);
+ m_compositor.setFlags(it, 1, Compositor::CacheFlag);
+ Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
+ }
+
+ cacheItem->attached = QSGVisualDataModelAttached::properties(cacheItem->object);
+ cacheItem->attached->m_cacheItem = cacheItem;
+ new QSGVisualDataModelAttachedMetaObject(cacheItem->attached, m_cacheMetaType);
+ cacheItem->attached->emitChanges();
+
+ if (QDeclarativePackage *package = qobject_cast<QDeclarativePackage *>(cacheItem->object)) {
+ emitCreatedPackage(it, package);
+ } else if (!reference) {
+ if (QSGItem *item = qobject_cast<QSGItem *>(cacheItem->object))
+ emitCreatedItem(it, item);
+ }
+
+ m_completePending = !complete;
+ if (complete)
+ m_delegate->completeCreate();
} else {
delete rootContext;
+ if (!it->inCache())
+ delete cacheItem;
qmlInfo(q, m_delegate->errors()) << "Error creating delegate";
+ return 0;
}
}
- if (index == m_adaptorModel->count() -1 && m_adaptorModel->canFetchMore())
+ if (index == m_compositor.count(group) - 1 && m_adaptorModel->canFetchMore())
QCoreApplication::postEvent(q, new QEvent(QEvent::UpdateRequest));
-
- return nobj;
+ if (reference)
+ cacheItem->referenceObject();
+ return cacheItem->object;
}
QSGItem *QSGVisualDataModel::item(int index, bool complete)
{
Q_D(QSGVisualDataModel);
- QObject *object = d->object(index, complete);
+ if (!d->m_delegate || index < 0 || index >= d->m_compositor.count(d->m_compositorGroup)) {
+ qWarning() << "VisualDataModel::item: index out range" << index << d->m_compositor.count(d->m_compositorGroup);
+ return 0;
+ }
+
+ QObject *object = d->object(d->m_compositorGroup, index, complete, true);
if (QSGItem *item = qobject_cast<QSGItem *>(object))
return item;
-
- if (completePending())
+ if (d->m_completePending)
completeItem();
d->release(object);
if (!d->m_delegateValidated) {
- qmlInfo(d->m_delegate) << tr("Delegate component must be Item type.");
+ if (object)
+ qmlInfo(d->m_delegate) << QSGVisualDataModel::tr("Delegate component must be Item type.");
d->m_delegateValidated = true;
}
return 0;
@@ -586,21 +1063,37 @@ void QSGVisualDataModel::completeItem()
d->m_completePending = false;
}
-QString QSGVisualDataModelPrivate::stringValue(int index, const QString &name)
+QString QSGVisualDataModelPrivate::stringValue(Compositor::Group group, int index, const QString &name)
{
- return m_adaptorModel->stringValue(index, name);
+ Compositor::iterator it = m_compositor.find(group, index);
+ if (QSGVisualAdaptorModel *model = it.list<QSGVisualAdaptorModel>()) {
+ return model->stringValue(it.modelIndex(), name);
+ }
+ return QString();
}
QString QSGVisualDataModel::stringValue(int index, const QString &name)
{
Q_D(QSGVisualDataModel);
- return d->stringValue(index, name);
+ return d->stringValue(d->m_compositorGroup, index, name);
+}
+
+int QSGVisualDataModelPrivate::cacheIndexOf(QObject *object) const
+{
+ for (int cacheIndex = 0; cacheIndex < m_cache.count(); ++cacheIndex) {
+ if (m_cache.at(cacheIndex)->object == object)
+ return cacheIndex;
+ }
+ return -1;
}
int QSGVisualDataModel::indexOf(QSGItem *item, QObject *) const
{
Q_D(const QSGVisualDataModel);
- return d->m_adaptorModel->indexOf(item);
+ const int cacheIndex = d->cacheIndexOf(item);
+ return cacheIndex != -1
+ ? d->m_cache.at(cacheIndex)->index[d->m_compositorGroup]
+ : -1;
}
void QSGVisualDataModel::setWatchedRoles(QList<QByteArray> roles)
@@ -610,6 +1103,36 @@ void QSGVisualDataModel::setWatchedRoles(QList<QByteArray> roles)
d->watchedRoles = roles;
}
+void QSGVisualDataModelPrivate::addGroups(Compositor::Group group, int index, int count, int groupFlags)
+{
+ QVector<Compositor::Insert> inserts;
+ m_compositor.setFlags(group, index, count, groupFlags, &inserts);
+ itemsInserted(inserts);
+ emitChanges();
+}
+
+void QSGVisualDataModelPrivate::removeGroups(Compositor::Group group, int index, int count, int groupFlags)
+{
+ QVector<Compositor::Remove> removes;
+ m_compositor.clearFlags(group, index, count, groupFlags, &removes);
+ itemsRemoved(removes);
+ emitChanges();
+}
+
+void QSGVisualDataModelPrivate::setGroups(Compositor::Group group, int index, int count, int groupFlags)
+{
+ QVector<Compositor::Insert> inserts;
+ m_compositor.setFlags(group, index, count, groupFlags, &inserts);
+ itemsInserted(inserts);
+
+ const int removeFlags = ~groupFlags & Compositor::GroupMask;
+ QVector<Compositor::Remove> removes;
+ m_compositor.clearFlags(group, index, count, removeFlags, &removes);
+ itemsRemoved(removes);
+
+ emitChanges();
+}
+
bool QSGVisualDataModel::event(QEvent *e)
{
Q_D(QSGVisualDataModel);
@@ -618,115 +1141,301 @@ bool QSGVisualDataModel::event(QEvent *e)
return QSGVisualModel::event(e);
}
+void QSGVisualDataModelPrivate::itemsChanged(const QVector<Compositor::Change> &changes)
+{
+ if (!m_delegate)
+ return;
+
+ QVarLengthArray<QVector<QDeclarativeChangeSet::Change>, Compositor::MaximumGroupCount> translatedChanges(m_groupCount);
+
+ foreach (const Compositor::Change &change, changes) {
+ for (int i = 1; i < m_groupCount; ++i) {
+ if (change.inGroup(i)) {
+ translatedChanges[i].append(
+ QDeclarativeChangeSet::Change(change.index[i], change.count));
+ }
+ }
+ }
+
+ for (int i = 1; i < m_groupCount; ++i)
+ QSGVisualDataGroupPrivate::get(m_groups[i])->changeSet.apply(translatedChanges.at(i));
+}
+
void QSGVisualDataModel::_q_itemsChanged(int index, int count)
{
Q_D(QSGVisualDataModel);
- if (!d->m_delegate)
+ if (count <= 0)
return;
- d->m_absoluteChangeSet.change(index, count);
+ QVector<Compositor::Change> changes;
+ d->m_compositor.listItemsChanged(d->m_adaptorModel, index, count, &changes);
+ d->itemsChanged(changes);
d->emitChanges();
}
+void QSGVisualDataModelPrivate::itemsInserted(
+ const QVector<Compositor::Insert> &inserts,
+ QVarLengthArray<QVector<QDeclarativeChangeSet::Insert>, Compositor::MaximumGroupCount> *translatedInserts,
+ QHash<int, QList<QSGVisualDataModelCacheItem *> > *movedItems)
+{
+ int cacheIndex = 0;
+
+ int inserted[Compositor::MaximumGroupCount];
+ for (int i = 1; i < m_groupCount; ++i)
+ inserted[i] = 0;
+
+ foreach (const Compositor::Insert &insert, inserts) {
+ for (; cacheIndex < insert.cacheIndex; ++cacheIndex) {
+ QSGVisualDataModelCacheItem *cacheItem = m_cache.at(cacheIndex);
+ if (!cacheItem->groups)
+ continue;
+ for (int i = 1; i < m_groupCount; ++i)
+ cacheItem->index[i] += inserted[i];
+ }
+ for (int i = 1; i < m_groupCount; ++i) {
+ if (insert.inGroup(i)) {
+ (*translatedInserts)[i].append(
+ QDeclarativeChangeSet::Insert(insert.index[i], insert.count, insert.moveId));
+ inserted[i] += insert.count;
+ }
+ }
+
+ if (!insert.inCache())
+ continue;
+
+ if (movedItems && insert.isMove()) {
+ QList<QSGVisualDataModelCacheItem *> items = movedItems->take(insert.moveId);
+ Q_ASSERT(items.count() == insert.count);
+ m_cache = m_cache.mid(0, insert.cacheIndex) + items + m_cache.mid(insert.cacheIndex);
+ }
+ if (insert.inGroup()) {
+ for (int offset = 0; cacheIndex < insert.cacheIndex + insert.count; ++cacheIndex, ++offset) {
+ QSGVisualDataModelCacheItem *cacheItem = m_cache.at(cacheIndex);
+ cacheItem->groups |= insert.flags & Compositor::GroupMask;
+ for (int i = 1; i < m_groupCount; ++i) {
+ cacheItem->index[i] = cacheItem->groups & (1 << i)
+ ? insert.index[i] + offset
+ : insert.index[i];
+ }
+ }
+ } else {
+ cacheIndex = insert.cacheIndex + insert.count;
+ }
+ }
+ for (; cacheIndex < m_cache.count(); ++cacheIndex) {
+ QSGVisualDataModelCacheItem *cacheItem = m_cache.at(cacheIndex);
+ if (!cacheItem->groups)
+ continue;
+ for (int i = 1; i < m_groupCount; ++i)
+ cacheItem->index[i] += inserted[i];
+ }
+}
+
+void QSGVisualDataModelPrivate::itemsInserted(const QVector<Compositor::Insert> &inserts)
+{
+ QVarLengthArray<QVector<QDeclarativeChangeSet::Insert>, Compositor::MaximumGroupCount> translatedInserts(m_groupCount);
+ itemsInserted(inserts, &translatedInserts);
+ Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
+ if (!m_delegate)
+ return;
+
+ for (int i = 1; i < m_groupCount; ++i)
+ QSGVisualDataGroupPrivate::get(m_groups[i])->changeSet.apply(translatedInserts.at(i));
+}
+
void QSGVisualDataModel::_q_itemsInserted(int index, int count)
{
+
Q_D(QSGVisualDataModel);
- if (!d->m_delegate)
+ if (count <= 0)
return;
+ QVector<Compositor::Insert> inserts;
+ d->m_compositor.listItemsInserted(d->m_adaptorModel, index, count, &inserts);
+ d->itemsInserted(inserts);
+ d->emitChanges();
+}
- // XXX - highly inefficient
- QHash<int,QSGVisualDataModelPrivate::ObjectRef> items;
- for (QHash<int,QSGVisualDataModelPrivate::ObjectRef>::Iterator iter = d->m_cache.begin();
- iter != d->m_cache.end(); ) {
+void QSGVisualDataModelPrivate::itemsRemoved(
+ const QVector<Compositor::Remove> &removes,
+ QVarLengthArray<QVector<QDeclarativeChangeSet::Remove>, Compositor::MaximumGroupCount> *translatedRemoves,
+ QHash<int, QList<QSGVisualDataModelCacheItem *> > *movedItems)
+{
+ int cacheIndex = 0;
+ int removedCache = 0;
+
+ int removed[Compositor::MaximumGroupCount];
+ for (int i = 1; i < m_groupCount; ++i)
+ removed[i] = 0;
+
+ foreach (const Compositor::Remove &remove, removes) {
+ for (; cacheIndex < remove.cacheIndex; ++cacheIndex) {
+ QSGVisualDataModelCacheItem *cacheItem = m_cache.at(cacheIndex);
+ if (!cacheItem->groups)
+ continue;
+ for (int i = 1; i < m_groupCount; ++i)
+ cacheItem->index[i] -= removed[i];
+ }
+ for (int i = 1; i < m_groupCount; ++i) {
+ if (remove.inGroup(i)) {
+ (*translatedRemoves)[i].append(
+ QDeclarativeChangeSet::Remove(remove.index[i], remove.count, remove.moveId));
+ removed[i] += remove.count;
+ }
+ }
- if (iter.key() >= index) {
- QSGVisualDataModelPrivate::ObjectRef objRef = *iter;
- int index = iter.key() + count;
- iter = d->m_cache.erase(iter);
+ if (!remove.inCache())
+ continue;
- items.insert(index, objRef);
+ if (movedItems && remove.isMove()) {
+ movedItems->insert(remove.moveId, m_cache.mid(remove.cacheIndex, remove.count));
+ QList<QSGVisualDataModelCacheItem *>::iterator begin = m_cache.begin() + remove.cacheIndex;
+ QList<QSGVisualDataModelCacheItem *>::iterator end = begin + remove.count;
+ m_cache.erase(begin, end);
} else {
- ++iter;
+ for (; cacheIndex < remove.cacheIndex + remove.count - removedCache; ++cacheIndex) {
+ QSGVisualDataModelCacheItem *cacheItem = m_cache.at(cacheIndex);
+ if (remove.inGroup(Compositor::Persisted) && cacheItem->objectRef == 0) {
+ destroy(cacheItem->object);
+ if (QDeclarativePackage *package = qobject_cast<QDeclarativePackage *>(cacheItem->object))
+ emitDestroyingPackage(package);
+ else if (QSGItem *item = qobject_cast<QSGItem *>(cacheItem->object))
+ emitDestroyingItem(item);
+ cacheItem->object = 0;
+ }
+ if (remove.groups() == cacheItem->groups && !cacheItem->isReferenced()) {
+ m_compositor.clearFlags(Compositor::Cache, cacheIndex, 1, Compositor::CacheFlag);
+ m_cache.removeAt(cacheIndex);
+ delete cacheItem;
+ --cacheIndex;
+ ++removedCache;
+ Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
+ } else if (remove.groups() == cacheItem->groups) {
+ cacheItem->groups = 0;
+ for (int i = 1; i < m_groupCount; ++i)
+ cacheItem->index[i] = -1;
+ } else {
+ for (int i = 1; i < m_groupCount; ++i) {
+ if (remove.inGroup(i))
+ cacheItem->index[i] = remove.index[i];
+ }
+ cacheItem->groups &= ~remove.flags & Compositor::GroupMask;
+ }
+ }
}
}
- d->m_cache.unite(items);
- d->m_absoluteChangeSet.insert(index, count);
- d->emitChanges();
- emit countChanged();
+ for (; cacheIndex < m_cache.count(); ++cacheIndex) {
+ QSGVisualDataModelCacheItem *cacheItem = m_cache.at(cacheIndex);
+ if (!cacheItem->groups)
+ continue;
+ for (int i = 1; i < m_groupCount; ++i)
+ cacheItem->index[i] -= removed[i];
+ }
+}
+
+void QSGVisualDataModelPrivate::itemsRemoved(const QVector<Compositor::Remove> &removes)
+{
+ QVarLengthArray<QVector<QDeclarativeChangeSet::Remove>, Compositor::MaximumGroupCount> translatedRemoves(m_groupCount);
+ itemsRemoved(removes, &translatedRemoves);
+ Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
+ if (!m_delegate)
+ return;
+
+ for (int i = 1; i < m_groupCount; ++i)
+ QSGVisualDataGroupPrivate::get(m_groups[i])->changeSet.apply(translatedRemoves.at(i));
}
void QSGVisualDataModel::_q_itemsRemoved(int index, int count)
{
Q_D(QSGVisualDataModel);
- if (!d->m_delegate)
+ if (count <= 0)
return;
- // XXX - highly inefficient
- QHash<int, QSGVisualDataModelPrivate::ObjectRef> items;
- for (QHash<int, QSGVisualDataModelPrivate::ObjectRef>::Iterator iter = d->m_cache.begin();
- iter != d->m_cache.end(); ) {
- if (iter.key() >= index && iter.key() < index + count) {
- QSGVisualDataModelPrivate::ObjectRef objRef = *iter;
- iter = d->m_cache.erase(iter);
- items.insertMulti(-1, objRef); //XXX perhaps better to maintain separately
- } else if (iter.key() >= index + count) {
- QSGVisualDataModelPrivate::ObjectRef objRef = *iter;
- int index = iter.key() - count;
- iter = d->m_cache.erase(iter);
- items.insert(index, objRef);
- } else {
- ++iter;
- }
- }
- d->m_cache.unite(items);
- d->m_absoluteChangeSet.remove(index, count);
+ QVector<Compositor::Remove> removes;
+ d->m_compositor.listItemsRemoved(d->m_adaptorModel, index, count, &removes);
+ d->itemsRemoved(removes);
d->emitChanges();
- emit countChanged();
+}
+
+void QSGVisualDataModelPrivate::itemsMoved(
+ const QVector<Compositor::Remove> &removes, const QVector<Compositor::Insert> &inserts)
+{
+ QHash<int, QList<QSGVisualDataModelCacheItem *> > movedItems;
+
+ QVarLengthArray<QVector<QDeclarativeChangeSet::Remove>, Compositor::MaximumGroupCount> translatedRemoves(m_groupCount);
+ itemsRemoved(removes, &translatedRemoves, &movedItems);
+
+ QVarLengthArray<QVector<QDeclarativeChangeSet::Insert>, Compositor::MaximumGroupCount> translatedInserts(m_groupCount);
+ itemsInserted(inserts, &translatedInserts, &movedItems);
+ Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
+ Q_ASSERT(movedItems.isEmpty());
+ if (!m_delegate)
+ return;
+
+ for (int i = 1; i < m_groupCount; ++i) {
+ QSGVisualDataGroupPrivate::get(m_groups[i])->changeSet.apply(
+ translatedRemoves.at(i),
+ translatedInserts.at(i));
+ }
}
void QSGVisualDataModel::_q_itemsMoved(int from, int to, int count)
{
Q_D(QSGVisualDataModel);
- if (!d->m_delegate)
+ if (count <= 0)
return;
- // XXX - highly inefficient
- QHash<int,QSGVisualDataModelPrivate::ObjectRef> items;
- for (QHash<int,QSGVisualDataModelPrivate::ObjectRef>::Iterator iter = d->m_cache.begin();
- iter != d->m_cache.end(); ) {
- if (iter.key() >= from && iter.key() < from + count) {
- QSGVisualDataModelPrivate::ObjectRef objRef = *iter;
- int index = iter.key() - from + to;
- items.insert(index, objRef);
- iter = d->m_cache.erase(iter);
- } else {
- ++iter;
- }
- }
- for (QHash<int,QSGVisualDataModelPrivate::ObjectRef>::Iterator iter = d->m_cache.begin();
- iter != d->m_cache.end(); ) {
- int diff = from > to ? count : -count;
- if (iter.key() >= qMin(from,to) && iter.key() < qMax(from+count,to+count)) {
- QSGVisualDataModelPrivate::ObjectRef objRef = *iter;
- int index = iter.key() + diff;
- iter = d->m_cache.erase(iter);
- items.insert(index, objRef);
- } else {
- ++iter;
- }
- }
- d->m_cache.unite(items);
- d->m_absoluteChangeSet.move(from, to, count);
+ QVector<Compositor::Remove> removes;
+ QVector<Compositor::Insert> inserts;
+ d->m_compositor.listItemsMoved(d->m_adaptorModel, from, to, count, &removes, &inserts);
+ d->itemsMoved(removes, inserts);
d->emitChanges();
}
-void QSGVisualDataModelPrivate::emitChanges()
+template <typename T> v8::Local<v8::Array>
+QSGVisualDataModelPrivate::buildChangeList(const QVector<T> &changes)
+{
+ v8::Local<v8::Array> indexes = v8::Array::New(changes.count());
+ v8::Local<v8::String> indexKey = v8::String::New("index");
+ v8::Local<v8::String> countKey = v8::String::New("count");
+ v8::Local<v8::String> moveIdKey = v8::String::New("moveId");
+
+ for (int i = 0; i < changes.count(); ++i) {
+ v8::Local<v8::Object> object = v8::Object::New();
+ object->Set(indexKey, v8::Integer::New(changes.at(i).index));
+ object->Set(countKey, v8::Integer::New(changes.at(i).count));
+ object->Set(moveIdKey, changes.at(i).moveId != -1 ? v8::Integer::New(changes.at(i).count) : v8::Undefined());
+ indexes->Set(i, object);
+ }
+ return indexes;
+}
+
+void QSGVisualDataModelPrivate::emitModelUpdated(const QDeclarativeChangeSet &changeSet, bool reset)
{
Q_Q(QSGVisualDataModel);
- if (!m_absoluteChangeSet.isEmpty()) {
- emit q->modelUpdated(m_absoluteChangeSet, m_reset);
- m_absoluteChangeSet.clear();
- m_reset = false;
+ emit q->modelUpdated(changeSet, reset);
+ if (changeSet.difference() != 0)
+ emit q->countChanged();
+}
+
+void QSGVisualDataModelPrivate::emitChanges()
+{
+ if (m_transaction || !m_complete)
+ return;
+
+ m_transaction = true;
+ QV8Engine *engine = QDeclarativeEnginePrivate::getV8Engine(m_context->engine());
+ for (int i = 1; i < m_groupCount; ++i)
+ QSGVisualDataGroupPrivate::get(m_groups[i])->emitChanges(engine);
+ m_transaction = false;
+
+ const bool reset = m_reset;
+ m_reset = false;
+ for (int i = 1; i < m_groupCount; ++i)
+ QSGVisualDataGroupPrivate::get(m_groups[i])->emitModelUpdated(reset);
+
+ foreach (QSGVisualDataModelCacheItem *cacheItem, m_cache) {
+ if (cacheItem->object)
+ cacheItem->attached->emitChanges();
}
}
@@ -735,35 +1444,980 @@ void QSGVisualDataModel::_q_modelReset(int oldCount, int newCount)
Q_D(QSGVisualDataModel);
if (!d->m_delegate)
return;
- d->m_absoluteChangeSet.remove(0, oldCount);
- d->m_absoluteChangeSet.insert(0, newCount);
+
+ QVector<Compositor::Remove> removes;
+ QVector<Compositor::Insert> inserts;
+ if (oldCount)
+ d->m_compositor.listItemsRemoved(d->m_adaptorModel, 0, oldCount, &removes);
+ if (newCount)
+ d->m_compositor.listItemsInserted(d->m_adaptorModel, 0, newCount, &inserts);
+ d->itemsMoved(removes, inserts);
d->m_reset = true;
d->emitChanges();
- emit countChanged();
+}
+
+QSGVisualDataModelAttached *QSGVisualDataModel::qmlAttachedProperties(QObject *obj)
+{
+ return QSGVisualDataModelAttached::properties(obj);
}
//============================================================================
+QSGVisualDataModelCacheMetaType::QSGVisualDataModelCacheMetaType(
+ QV8Engine *engine, QSGVisualDataModel *model, const QStringList &groupNames)
+ : model(model)
+ , groupCount(groupNames.count() + 1)
+ , memberPropertyOffset(QSGVisualDataModelAttached::staticMetaObject.propertyCount())
+ , indexPropertyOffset(QSGVisualDataModelAttached::staticMetaObject.propertyCount() + groupNames.count())
+ , v8Engine(engine)
+ , metaObject(0)
+ , groupNames(groupNames)
+{
+ QMetaObjectBuilder builder;
+ builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
+ builder.setClassName(QSGVisualDataModelAttached::staticMetaObject.className());
+ builder.setSuperClass(&QSGVisualDataModelAttached::staticMetaObject);
+
+ v8::HandleScope handleScope;
+ v8::Context::Scope contextScope(engine->context());
+ v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
+ ft->InstanceTemplate()->SetHasExternalResource(true);
+ ft->PrototypeTemplate()->SetAccessor(v8::String::New("model"), get_model);
+ ft->PrototypeTemplate()->SetAccessor(v8::String::New("groups"), get_groups, set_groups);
+
+ int notifierId = 0;
+ for (int i = 0; i < groupNames.count(); ++i, ++notifierId) {
+ QString propertyName = QStringLiteral("in") + groupNames.at(i);
+ propertyName.replace(2, 1, propertyName.at(2).toUpper());
+ builder.addSignal("__" + propertyName.toUtf8() + "Changed()");
+ QMetaPropertyBuilder propertyBuilder = builder.addProperty(
+ propertyName.toUtf8(), "bool", notifierId);
+ propertyBuilder.setWritable(true);
+
+ ft->PrototypeTemplate()->SetAccessor(
+ engine->toString(propertyName), get_member, set_member, v8::Int32::New(i + 1));
+ }
+ for (int i = 0; i < groupNames.count(); ++i, ++notifierId) {
+ const QString propertyName = groupNames.at(i) + QStringLiteral("Index");
+ builder.addSignal("__" + propertyName.toUtf8() + "Changed()");
+ QMetaPropertyBuilder propertyBuilder = builder.addProperty(
+ propertyName.toUtf8(), "int", notifierId);
+ propertyBuilder.setWritable(true);
+
+ ft->PrototypeTemplate()->SetAccessor(
+ engine->toString(propertyName), get_index, 0, v8::Int32::New(i + 1));
+ }
+
+ metaObject = builder.toMetaObject();
+
+ constructor = qPersistentNew<v8::Function>(ft->GetFunction());
+}
+
+QSGVisualDataModelCacheMetaType::~QSGVisualDataModelCacheMetaType()
+{
+ qFree(metaObject);
+ qPersistentDispose(constructor);
+}
+
+int QSGVisualDataModelCacheMetaType::parseGroups(const QStringList &groups) const
+{
+ int groupFlags = 0;
+ foreach (const QString &groupName, groups) {
+ int index = groupNames.indexOf(groupName);
+ if (index != -1)
+ groupFlags |= 2 << index;
+ }
+ return groupFlags;
+}
+
+int QSGVisualDataModelCacheMetaType::parseGroups(QV8Engine *engine, const v8::Local<v8::Value> &groups) const
+{
+ int groupFlags = 0;
+ if (groups->IsString()) {
+ const QString groupName = engine->toString(groups);
+ int index = groupNames.indexOf(groupName);
+ if (index != -1)
+ groupFlags |= 2 << index;
+ } else if (groups->IsArray()) {
+ v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(groups);
+ for (uint i = 0; i < array->Length(); ++i) {
+ const QString groupName = engine->toString(array->Get(i));
+ int index = groupNames.indexOf(groupName);
+ if (index != -1)
+ groupFlags |= 2 << index;
+ }
+ }
+ return groupFlags;
+}
+
+v8::Handle<v8::Value> QSGVisualDataModelCacheMetaType::get_model(
+ v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ QSGVisualDataModelCacheItem *cacheItem = v8_resource_cast<QSGVisualDataModelCacheItem>(info.This());
+ if (!cacheItem)
+ V8THROW_ERROR("Not a valid VisualData object");
+ if (!cacheItem->metaType->model)
+ return v8::Undefined();
+ QObject *data = 0;
+
+ QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(cacheItem->metaType->model);
+ for (int i = 1; i < cacheItem->metaType->groupCount; ++i) {
+ if (cacheItem->groups & (1 << i)) {
+ Compositor::iterator it = model->m_compositor.find(
+ Compositor::Group(i), cacheItem->index[i]);
+ if (QSGVisualAdaptorModel *list = it.list<QSGVisualAdaptorModel>())
+ data = list->data(it.modelIndex());
+ break;
+ }
+ }
+ if (!data)
+ return v8::Undefined();
+ return cacheItem->engine->newQObject(data);
+}
+
+v8::Handle<v8::Value> QSGVisualDataModelCacheMetaType::get_groups(
+ v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ QSGVisualDataModelCacheItem *cacheItem = v8_resource_cast<QSGVisualDataModelCacheItem>(info.This());
+ if (!cacheItem)
+ V8THROW_ERROR("Not a valid VisualData object");
+
+ QStringList groups;
+ for (int i = 1; i < cacheItem->metaType->groupCount; ++i) {
+ if (cacheItem->groups & (1 << i))
+ groups.append(cacheItem->metaType->groupNames.at(i - 1));
+ }
+
+ return cacheItem->engine->fromVariant(groups);
+}
+
+void QSGVisualDataModelCacheMetaType::set_groups(
+ v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+ QSGVisualDataModelCacheItem *cacheItem = v8_resource_cast<QSGVisualDataModelCacheItem>(info.This());
+ if (!cacheItem)
+ V8THROW_ERROR_SETTER("Not a valid VisualData object");
+
+ if (!cacheItem->metaType->model)
+ return;
+ QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(cacheItem->metaType->model);
+
+ const int groupFlags = model->m_cacheMetaType->parseGroups(cacheItem->engine, value);
+ for (int i = 1; i < cacheItem->metaType->groupCount; ++i) {
+ if (cacheItem->groups & (1 << i)) {
+ model->setGroups(Compositor::Group(i), cacheItem->index[i], 1, groupFlags);
+ break;
+ }
+ }
+}
+
+v8::Handle<v8::Value> QSGVisualDataModelCacheMetaType::get_member(
+ v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ QSGVisualDataModelCacheItem *cacheItem = v8_resource_cast<QSGVisualDataModelCacheItem>(info.This());
+ if (!cacheItem)
+ V8THROW_ERROR("Not a valid VisualData object");
+
+ return v8::Boolean::New(cacheItem->groups & (1 << info.Data()->Int32Value()));
+}
+
+void QSGVisualDataModelCacheMetaType::set_member(
+ v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+ QSGVisualDataModelCacheItem *cacheItem = v8_resource_cast<QSGVisualDataModelCacheItem>(info.This());
+ if (!cacheItem)
+ V8THROW_ERROR_SETTER("Not a valid VisualData object");
+
+ if (!cacheItem->metaType->model)
+ return;
+ QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(cacheItem->metaType->model);
+
+ Compositor::Group group = Compositor::Group(info.Data()->Int32Value());
+ const bool member = value->BooleanValue();
+ const int groupFlag = (1 << group);
+ if (member == ((cacheItem->groups & groupFlag) != 0))
+ return;
+
+ for (int i = 1; i < cacheItem->metaType->groupCount; ++i) {
+ if (cacheItem->groups & (1 << i)) {
+ if (member)
+ model->addGroups(Compositor::Group(i), cacheItem->index[i], 1, groupFlag);
+ else
+ model->removeGroups(Compositor::Group(i), cacheItem->index[i], 1, groupFlag);
+ break;
+ }
+ }
+}
+
+v8::Handle<v8::Value> QSGVisualDataModelCacheMetaType::get_index(
+ v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+ QSGVisualDataModelCacheItem *cacheItem = v8_resource_cast<QSGVisualDataModelCacheItem>(info.This());
+ if (!cacheItem)
+ V8THROW_ERROR("Not a valid VisualData object");
+
+ return v8::Integer::New(cacheItem->index[info.Data()->Int32Value()]);
+}
+
+
+//---------------------------------------------------------------------------
+
+void QSGVisualDataModelCacheItem::Dispose()
+{
+ --scriptRef;
+ if (isReferenced())
+ return;
+
+ if (metaType->model) {
+ QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(metaType->model);
+ const int cacheIndex = model->m_cache.indexOf(this);
+ if (cacheIndex != -1) {
+ model->m_compositor.clearFlags(Compositor::Cache, cacheIndex, 1, Compositor::CacheFlag);
+ model->m_cache.removeAt(cacheIndex);
+ }
+ }
+ delete this;
+}
+
+//---------------------------------------------------------------------------
+
+QSGVisualDataModelAttachedMetaObject::QSGVisualDataModelAttachedMetaObject(
+ QSGVisualDataModelAttached *attached, QSGVisualDataModelCacheMetaType *metaType)
+ : attached(attached)
+ , metaType(metaType)
+{
+ metaType->addref();
+ *static_cast<QMetaObject *>(this) = *metaType->metaObject;
+ QObjectPrivate::get(attached)->metaObject = this;
+}
+
+QSGVisualDataModelAttachedMetaObject::~QSGVisualDataModelAttachedMetaObject()
+{
+ metaType->release();
+}
+
+int QSGVisualDataModelAttachedMetaObject::metaCall(QMetaObject::Call call, int _id, void **arguments)
+{
+ if (call == QMetaObject::ReadProperty) {
+ if (_id >= metaType->indexPropertyOffset) {
+ Compositor::Group group = Compositor::Group(_id - metaType->indexPropertyOffset + 1);
+ *static_cast<int *>(arguments[0]) = attached->m_cacheItem->index[group];
+ return -1;
+ } else if (_id >= metaType->memberPropertyOffset) {
+ Compositor::Group group = Compositor::Group(_id - metaType->memberPropertyOffset + 1);
+ *static_cast<bool *>(arguments[0]) = attached->m_cacheItem->groups & (1 << group);
+ return -1;
+ }
+ } else if (call == QMetaObject::WriteProperty) {
+ if (_id >= metaType->memberPropertyOffset) {
+ if (!metaType->model)
+ return -1;
+ Compositor::Group group = Compositor::Group(_id - metaType->memberPropertyOffset + 1);
+ const bool member = attached->m_cacheItem->groups & (1 << group);
+ if (member != *static_cast<bool *>(arguments[0])) {
+ QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(metaType->model);
+ const int cacheIndex = model->m_cache.indexOf(attached->m_cacheItem);
+ if (member)
+ model->removeGroups(Compositor::Cache, cacheIndex, 1, (1 << group));
+ else
+ model->addGroups(Compositor::Cache, cacheIndex, 1, (1 << group));
+ }
+ return -1;
+ }
+ }
+ return attached->qt_metacall(call, _id, arguments);
+}
+
+/*!
+ \qmlattachedproperty int QtQuick2::VisualDataModel::model
+
+ This attached property holds the visual data model this delegate instance belongs to.
+
+ It is attached to each instance of the delegate.
+*/
+
+QSGVisualDataModel *QSGVisualDataModelAttached::model() const
+{
+ return m_cacheItem ? m_cacheItem->metaType->model : 0;
+}
+
+/*!
+ \qmlattachedproperty stringlist QtQuick2::VisualDataModel::groups
+
+ This attached property holds the name of VisualDataGroups the item belongs to.
+
+ It is attached to each instance of the delegate.
+*/
+
+QStringList QSGVisualDataModelAttached::groups() const
+{
+ QStringList groups;
+
+ if (!m_cacheItem)
+ return groups;
+ for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i) {
+ if (m_cacheItem->groups & (1 << i))
+ groups.append(m_cacheItem->metaType->groupNames.at(i - 1));
+ }
+ return groups;
+}
+
+void QSGVisualDataModelAttached::setGroups(const QStringList &groups)
+{
+ if (!m_cacheItem)
+ return;
+
+ QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(m_cacheItem->metaType->model);
+
+ const int cacheIndex = model->m_cache.indexOf(m_cacheItem);
+ const int groupFlags = model->m_cacheMetaType->parseGroups(groups);
+ model->setGroups(Compositor::Cache, cacheIndex, 1, groupFlags);
+}
+
+/*!
+ \qmlattachedproperty int QtQuick2::VisualDataModel::inItems
+
+ This attached property holds whether the item belongs to the default \l items VisualDataGroup.
+
+ Changing this property will add or remove the item from the items group.
+
+ It is attached to each instance of the delegate.
+*/
+
+/*!
+ \qmlattachedproperty int QtQuick2::VisualDataModel::itemsIndex
+
+ This attached property holds the index of the item in the default \l items VisualDataGroup.
+
+ It is attached to each instance of the delegate.
+*/
+
+/*!
+ \qmlattachedproperty int QtQuick2::VisualDataModel::inPersistedItems
+
+ This attached property holds whether the item belongs to the \l persistedItems VisualDataGroup.
+
+ Changing this property will add or remove the item from the items group. Change with caution
+ as removing an item from the persistedItems group will destroy the current instance if it is
+ not referenced by a model.
+
+ It is attached to each instance of the delegate.
+*/
+
+/*!
+ \qmlattachedproperty int QtQuick2::VisualDataModel::persistedItemsIndex
+
+ This attached property holds the index of the item in the \l persistedItems VisualDataGroup.
+
+ It is attached to each instance of the delegate.
+*/
+
+void QSGVisualDataModelAttached::emitChanges()
+{
+ if (m_modelChanged) {
+ m_modelChanged = false;
+ emit modelChanged();
+ }
+
+ const int groupChanges = m_previousGroups ^ m_cacheItem->groups;
+ m_previousGroups = m_cacheItem->groups;
+
+ int indexChanges = 0;
+ for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i) {
+ if (m_previousIndex[i] != m_cacheItem->index[i]) {
+ m_previousIndex[i] = m_cacheItem->index[i];
+ indexChanges |= (1 << i);
+ }
+ }
+
+ int notifierId = 0;
+ const QMetaObject *meta = metaObject();
+ for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i, ++notifierId) {
+ if (groupChanges & (1 << i))
+ QMetaObject::activate(this, meta, notifierId, 0);
+ }
+ for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i, ++notifierId) {
+ if (indexChanges & (1 << i))
+ QMetaObject::activate(this, meta, notifierId, 0);
+ }
+
+ if (groupChanges)
+ emit groupsChanged();
+}
+
+//============================================================================
+
+void QSGVisualDataGroupPrivate::setModel(QSGVisualDataModel *m, Compositor::Group g)
+{
+ Q_ASSERT(!model);
+ model = m;
+ group = g;
+}
+
+void QSGVisualDataGroupPrivate::emitChanges(QV8Engine *engine)
+{
+ Q_Q(QSGVisualDataGroup);
+ static int idx = signalIndex("changed(QDeclarativeV8Handle,QDeclarativeV8Handle)");
+ if (isSignalConnected(idx)) {
+ v8::HandleScope handleScope;
+ v8::Context::Scope contextScope(engine->context());
+ v8::Local<v8::Array> removed = QSGVisualDataModelPrivate::buildChangeList(changeSet.removes());
+ v8::Local<v8::Array> inserted = QSGVisualDataModelPrivate::buildChangeList(changeSet.inserts());
+ emit q->changed(
+ QDeclarativeV8Handle::fromHandle(removed), QDeclarativeV8Handle::fromHandle(inserted));
+ }
+ if (changeSet.difference() != 0)
+ emit q->countChanged();
+}
+
+void QSGVisualDataGroupPrivate::emitModelUpdated(bool reset)
+{
+ for (QSGVisualDataGroupEmitterList::iterator it = emitters.begin(); it != emitters.end(); ++it)
+ it->emitModelUpdated(changeSet, reset);
+ changeSet.clear();
+}
+
+void QSGVisualDataGroupPrivate::createdPackage(int index, QDeclarativePackage *package)
+{
+ for (QSGVisualDataGroupEmitterList::iterator it = emitters.begin(); it != emitters.end(); ++it)
+ it->createdPackage(index, package);
+}
+
+void QSGVisualDataGroupPrivate::destroyingPackage(QDeclarativePackage *package)
+{
+ for (QSGVisualDataGroupEmitterList::iterator it = emitters.begin(); it != emitters.end(); ++it)
+ it->destroyingPackage(package);
+}
+
+/*!
+ \qmlclass VisualDataGroup QSGVisualDataGroup
+ \inqmlmodule QtQuick 2
+ \ingroup qml-working-with-data
+ \brief The VisualDataGroup encapsulates a filtered set of visual data items.
+
+*/
+
+QSGVisualDataGroup::QSGVisualDataGroup(QObject *parent)
+ : QObject(*new QSGVisualDataGroupPrivate, parent)
+{
+}
+
+QSGVisualDataGroup::QSGVisualDataGroup(
+ const QString &name, QSGVisualDataModel *model, int index, QObject *parent)
+ : QObject(*new QSGVisualDataGroupPrivate, parent)
+{
+ Q_D(QSGVisualDataGroup);
+ d->name = name;
+ d->setModel(model, Compositor::Group(index));
+}
+
+QSGVisualDataGroup::~QSGVisualDataGroup()
+{
+}
+
+/*!
+ \qmlproperty string QtQuick2::VisualDataGroup::name
+
+ This property holds the name of the group.
+
+ Each group in a model must have a unique name starting with a lower case letter.
+*/
+
+QString QSGVisualDataGroup::name() const
+{
+ Q_D(const QSGVisualDataGroup);
+ return d->name;
+}
+
+void QSGVisualDataGroup::setName(const QString &name)
+{
+ Q_D(QSGVisualDataGroup);
+ if (d->model)
+ return;
+ if (d->name != name) {
+ d->name = name;
+ emit nameChanged();
+ }
+}
+
+/*!
+ \qmlproperty int QtQuick2::VisualDataGroup::count
+
+ This property holds the number of items in the group.
+*/
+
+int QSGVisualDataGroup::count() const
+{
+ Q_D(const QSGVisualDataGroup);
+ if (!d->model)
+ return 0;
+ return QSGVisualDataModelPrivate::get(d->model)->m_compositor.count(d->group);
+}
+
+/*!
+ \qmlproperty bool QtQuick2::VisualDataGroup::includeByDefault
+
+ This property holds whether new items are assigned to this group by default.
+*/
+
+bool QSGVisualDataGroup::defaultInclude() const
+{
+ Q_D(const QSGVisualDataGroup);
+ return d->defaultInclude;
+}
+
+void QSGVisualDataGroup::setDefaultInclude(bool include)
+{
+ Q_D(QSGVisualDataGroup);
+ if (d->defaultInclude != include) {
+ d->defaultInclude = include;
+
+ if (d->model) {
+ if (include)
+ QSGVisualDataModelPrivate::get(d->model)->m_compositor.setDefaultGroup(d->group);
+ else
+ QSGVisualDataModelPrivate::get(d->model)->m_compositor.clearDefaultGroup(d->group);
+ }
+ emit defaultIncludeChanged();
+ }
+}
+
+/*!
+ \qmlmethod var QtQuick2::VisualDataGroup::get(int index)
+
+ Returns a javascript object describing the item at \a index in the group.
+
+ The returned object contains the same information that is available to a delegate from the
+ VisualDataModel attached as well as the model for that item. It has the properties:
+
+ \list
+ \o \b model The model data of the item. This is the same as the model context property in
+ a delegate
+ \o \b groups A list the of names of groups the item is a member of. This property can be
+ written to change the item's membership.
+ \o \b inItems Whether the item belongs to the \l {QtQuick2::VisualDataModel::items}{items} group.
+ Writing to this property will add or remove the item from the group.
+ \o \b itemsIndex The index of the item within the \l {QtQuick2::VisualDataModel::items}{items} group.
+ \o \b {in\i{GroupName}} Whether the item belongs to the dynamic group \i groupName. Writing to
+ this property will add or remove the item from the group.
+ \o \b {\i{groupName}Index} The index of the item within the dynamic group \i groupName.
+ \endlist
+*/
+
+QDeclarativeV8Handle QSGVisualDataGroup::get(int index)
+{
+ Q_D(QSGVisualDataGroup);
+ if (!d->model)
+ return QDeclarativeV8Handle::fromHandle(v8::Undefined());;
+
+ QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(d->model);
+ if (index < 0 || index >= model->m_compositor.count(d->group)) {
+ qmlInfo(this) << tr("get: index out of range");
+ return QDeclarativeV8Handle::fromHandle(v8::Undefined());
+ }
+
+ Compositor::iterator it = model->m_compositor.find(d->group, index);
+ QSGVisualDataModelCacheItem *cacheItem = it->inCache()
+ ? model->m_cache.at(it.cacheIndex)
+ : 0;
+
+ if (!cacheItem) {
+ cacheItem = new QSGVisualDataModelCacheItem(model->m_cacheMetaType);
+ for (int i = 0; i < model->m_groupCount; ++i)
+ cacheItem->index[i] = it.index[i];
+ cacheItem->groups = it->flags & Compositor::GroupMask;
+
+ model->m_cache.insert(it.cacheIndex, cacheItem);
+ model->m_compositor.setFlags(it, 1, Compositor::CacheFlag);
+ }
+
+ ++cacheItem->scriptRef;
+
+ v8::Local<v8::Object> rv = model->m_cacheMetaType->constructor->NewInstance();
+ rv->SetExternalResource(cacheItem);
+ return QDeclarativeV8Handle::fromHandle(rv);
+}
+
+/*!
+ \qmlmethod QtQuick2::VisualDataGroup::create(int index)
+
+ Returns a reference to the instantiated item at \a index in the group.
+
+ All items returned by create are added to the persistedItems group. Items in this
+ group remain instantiated when not referenced by any view.
+*/
+
+QObject *QSGVisualDataGroup::create(int index)
+{
+ Q_D(QSGVisualDataGroup);
+ if (!d->model)
+ return 0;
+
+ QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(d->model);
+ if (index < 0 || index >= model->m_compositor.count(d->group)) {
+ qmlInfo(this) << tr("create: index out of range");
+ return 0;
+ }
+
+ QObject *object = model->object(d->group, index, true, false);
+ if (object)
+ model->addGroups(d->group, index, 1, Compositor::PersistedFlag);
+ return object;
+}
+
+/*!
+ \qmlmethod QtQuick2::VisualDataGroup::remove(int index, int count)
+
+ Removes \a count items starting at \a index from the group.
+*/
+
+void QSGVisualDataGroup::remove(QDeclarativeV8Function *args)
+{
+ Q_D(QSGVisualDataGroup);
+ if (!d->model)
+ return;
+ int index = -1;
+ int count = 1;
+
+ if (args->Length() == 0)
+ return;
+
+ int i = 0;
+ v8::Local<v8::Value> v = (*args)[i];
+ if (!v->IsInt32())
+ return;
+ index = v->Int32Value();
+
+ if (++i < args->Length()) {
+ v = (*args)[i];
+ if (v->IsInt32())
+ count = v->Int32Value();
+ }
+
+ QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(d->model);
+ if (count < 0) {
+ qmlInfo(this) << tr("remove: invalid count");
+ } else if (index < 0 || index + count > model->m_compositor.count(d->group)) {
+ qmlInfo(this) << tr("remove: index out of range");
+ } else if (count > 0) {
+ model->removeGroups(d->group, index, count, 1 << d->group);
+ }
+}
+
+bool QSGVisualDataGroupPrivate::parseGroupArgs(
+ QDeclarativeV8Function *args, int *index, int *count, int *groups) const
+{
+ if (!model)
+ return false;
+
+ if (args->Length() < 2)
+ return false;
+
+ int i = 0;
+ v8::Local<v8::Value> v = (*args)[i];
+ if (!v->IsInt32())
+ return false;
+ *index = v->Int32Value();
+
+ v = (*args)[++i];
+ if (v->IsInt32()) {
+ *count = v->Int32Value();
+
+ if (++i == args->Length())
+ return false;
+ v = (*args)[i];
+ }
+
+ *groups = QSGVisualDataModelPrivate::get(model)->m_cacheMetaType->parseGroups(args->engine(), v);
+
+ return true;
+}
+
+/*!
+ \qmlmethod QtQuick2::VisualDataGroup::addGroups(int index, int count, stringlist groups)
+
+ Adds \a count items starting at \a index to \a groups.
+*/
+
+void QSGVisualDataGroup::addGroups(QDeclarativeV8Function *args)
+{
+ Q_D(QSGVisualDataGroup);
+ int index = -1;
+ int count = 1;
+ int groups = 0;
+
+ if (!d->parseGroupArgs(args, &index, &count, &groups))
+ return;
+
+ QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(d->model);
+ if (count < 0) {
+ qmlInfo(this) << tr("addGroups: invalid count");
+ } else if (index < 0 || index + count > model->m_compositor.count(d->group)) {
+ qmlInfo(this) << tr("addGroups: index out of range");
+ } else if (count > 0 && groups) {
+ model->addGroups(d->group, index, count, groups);
+ }
+}
+
+/*!
+ \qmlmethod QtQuick2::VisualDataGroup::removeGroups(int index, int count, stringlist groups)
+
+ Removes \a count items starting at \a index from \a groups.
+*/
+
+void QSGVisualDataGroup::removeGroups(QDeclarativeV8Function *args)
+{
+ Q_D(QSGVisualDataGroup);
+ int index = -1;
+ int count = 1;
+ int groups = 0;
+
+ if (!d->parseGroupArgs(args, &index, &count, &groups))
+ return;
+
+ QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(d->model);
+ if (count < 0) {
+ qmlInfo(this) << tr("removeGroups: invalid count");
+ } else if (index < 0 || index + count > model->m_compositor.count(d->group)) {
+ qmlInfo(this) << tr("removeGroups: index out of range");
+ } else if (count > 0 && groups) {
+ model->removeGroups(d->group, index, count, groups);
+ }
+}
+
+/*!
+ \qmlmethod QtQuick2::VisualDataGroup::setGroups(int index, int count, stringlist groups)
+
+ Sets the \a groups \a count items starting at \a index belong to.
+*/
+
+void QSGVisualDataGroup::setGroups(QDeclarativeV8Function *args)
+{
+ Q_D(QSGVisualDataGroup);
+ int index = -1;
+ int count = 1;
+ int groups = 0;
+
+ if (!d->parseGroupArgs(args, &index, &count, &groups))
+ return;
+
+ QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(d->model);
+ if (count < 0) {
+ qmlInfo(this) << tr("setGroups: invalid count");
+ } else if (index < 0 || index + count > model->m_compositor.count(d->group)) {
+ qmlInfo(this) << tr("setGroups: index out of range");
+ } else if (count > 0) {
+ model->setGroups(d->group, index, count, groups);
+ }
+}
+
+/*!
+ \qmlmethod QtQuick2::VisualDataGroup::setGroups(int index, int count, stringlist groups)
+
+ Sets the \a groups \a count items starting at \a index belong to.
+*/
+
+/*!
+ \qmlmethod QtQuick2::VisualDataGroup::move(int from, int to, int count)
+
+ Moves \a count at \a from in a group \a to a new position.
+*/
+
+void QSGVisualDataGroup::move(QDeclarativeV8Function *args)
+{
+ Q_D(QSGVisualDataGroup);
+
+ if (args->Length() < 2)
+ return;
+
+ Compositor::Group fromGroup = d->group;
+ Compositor::Group toGroup = d->group;
+ int from = -1;
+ int to = -1;
+ int count = 1;
+
+ int i = 0;
+ v8::Local<v8::Value> v = (*args)[i];
+ if (QSGVisualDataGroup *group = qobject_cast<QSGVisualDataGroup *>(args->engine()->toQObject(v))) {
+ QSGVisualDataGroupPrivate *g_d = QSGVisualDataGroupPrivate::get(group);
+ if (g_d->model != d->model)
+ return;
+ fromGroup = g_d->group;
+ v = (*args)[++i];
+ }
+
+ if (!v->IsInt32())
+ return;
+ from = v->Int32Value();
+
+ if (++i == args->Length())
+ return;
+ v = (*args)[i];
+
+ if (QSGVisualDataGroup *group = qobject_cast<QSGVisualDataGroup *>(args->engine()->toQObject(v))) {
+ QSGVisualDataGroupPrivate *g_d = QSGVisualDataGroupPrivate::get(group);
+ if (g_d->model != d->model)
+ return;
+ toGroup = g_d->group;
+
+ if (++i == args->Length())
+ return;
+ v = (*args)[i];
+ }
+
+ if (!v->IsInt32())
+ return;
+ to = v->Int32Value();
+
+ if (++i < args->Length()) {
+ v = (*args)[i];
+ if (v->IsInt32())
+ count = v->Int32Value();
+ }
+
+ QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(d->model);
+
+ if (count < 0) {
+ qmlInfo(this) << tr("move: invalid count");
+ } else if (from < 0 || from + count > model->m_compositor.count(fromGroup)) {
+ qmlInfo(this) << tr("move: from index out of range");
+ } else if (!model->m_compositor.verifyMoveTo(fromGroup, from, toGroup, to, count)) {
+ qmlInfo(this) << tr("move: to index out of range");
+ } else if (count > 0) {
+ QVector<Compositor::Remove> removes;
+ QVector<Compositor::Insert> inserts;
+
+ model->m_compositor.move(fromGroup, from, toGroup, to, count, &removes, &inserts);
+ model->itemsMoved(removes, inserts);
+ model->emitChanges();
+ }
+}
+
+/*!
+ \qmlsignal QtQuick2::VisualDataGroup::onChanged(array removed, array inserted)
+
+ This handler is called when items have been removed from or inserted into the group.
+
+ Each object in the \a removed and \a inserted arrays has two values; the \e index of the first
+ item inserted or removed and a \e count of the number of consecutive items inserted or removed.
+
+ Each index is adjusted for previous changes with all removed items preceding any inserted
+ items.
+*/
+
+//============================================================================
+
QSGVisualPartsModel::QSGVisualPartsModel(QSGVisualDataModel *model, const QString &part, QObject *parent)
: QSGVisualModel(*new QObjectPrivate, parent)
, m_model(model)
, m_part(part)
+ , m_compositorGroup(Compositor::Cache)
+ , m_inheritGroup(true)
{
- connect(m_model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
- this, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)));
- connect(m_model, SIGNAL(createdPackage(int,QDeclarativePackage*)),
- this, SLOT(createdPackage(int,QDeclarativePackage*)));
- connect(m_model, SIGNAL(destroyingPackage(QDeclarativePackage*)),
- this, SLOT(destroyingPackage(QDeclarativePackage*)));
+ QSGVisualDataModelPrivate *d = QSGVisualDataModelPrivate::get(m_model);
+ if (d->m_cacheMetaType) {
+ QSGVisualDataGroupPrivate::get(d->m_groups[1])->emitters.insert(this);
+ m_compositorGroup = Compositor::Default;
+ } else {
+ d->m_pendingParts.insert(this);
+ }
}
QSGVisualPartsModel::~QSGVisualPartsModel()
{
}
+QString QSGVisualPartsModel::filterGroup() const
+{
+ if (m_inheritGroup)
+ return m_model->filterGroup();
+ return m_filterGroup;
+}
+
+void QSGVisualPartsModel::setFilterGroup(const QString &group)
+{
+ if (QSGVisualDataModelPrivate::get(m_model)->m_transaction) {
+ qmlInfo(this) << tr("The group of a VisualDataModel cannot be changed within onChanged");
+ return;
+ }
+
+ if (m_filterGroup != group || m_inheritGroup) {
+ m_filterGroup = group;
+ m_inheritGroup = false;
+ updateFilterGroup();
+
+ emit filterGroupChanged();
+ }
+}
+
+void QSGVisualPartsModel::resetFilterGroup()
+{
+ if (!m_inheritGroup) {
+ m_inheritGroup = true;
+ updateFilterGroup();
+ emit filterGroupChanged();
+ }
+}
+
+void QSGVisualPartsModel::updateFilterGroup()
+{
+ QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(m_model);
+ if (!model->m_cacheMetaType)
+ return;
+
+ if (m_inheritGroup)
+ return;
+
+ QDeclarativeListCompositor::Group previousGroup = model->m_compositorGroup;
+ m_compositorGroup = Compositor::Default;
+ QSGVisualDataGroupPrivate::get(model->m_groups[Compositor::Default])->emitters.insert(this);
+ for (int i = 1; i < model->m_groupCount; ++i) {
+ if (m_filterGroup == model->m_cacheMetaType->groupNames.at(i - 1)) {
+ m_compositorGroup = Compositor::Group(i);
+ break;
+ }
+ }
+
+ QSGVisualDataGroupPrivate::get(model->m_groups[m_compositorGroup])->emitters.insert(this);
+ if (m_compositorGroup != previousGroup) {
+ QVector<QDeclarativeChangeSet::Remove> removes;
+ QVector<QDeclarativeChangeSet::Insert> inserts;
+ model->m_compositor.transition(previousGroup, m_compositorGroup, &removes, &inserts);
+
+ QDeclarativeChangeSet changeSet;
+ changeSet.apply(removes, inserts);
+ if (!changeSet.isEmpty())
+ emit modelUpdated(changeSet, false);
+
+ if (changeSet.difference() != 0)
+ emit countChanged();
+ }
+}
+
+void QSGVisualPartsModel::updateFilterGroup(
+ Compositor::Group group, const QDeclarativeChangeSet &changeSet)
+{
+ if (!m_inheritGroup)
+ return;
+
+ m_compositorGroup = group;
+ QSGVisualDataGroupPrivate::get(QSGVisualDataModelPrivate::get(m_model)->m_groups[m_compositorGroup])->emitters.insert(this);
+
+ if (!changeSet.isEmpty())
+ emit modelUpdated(changeSet, false);
+
+ if (changeSet.difference() != 0)
+ emit countChanged();
+
+ emit filterGroupChanged();
+}
+
int QSGVisualPartsModel::count() const
{
- return m_model->count();
+ QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(m_model);
+ return model->m_delegate
+ ? model->m_compositor.count(m_compositorGroup)
+ : 0;
}
bool QSGVisualPartsModel::isValid() const
@@ -775,7 +2429,12 @@ QSGItem *QSGVisualPartsModel::item(int index, bool complete)
{
QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(m_model);
- QObject *object = model->object(index, complete);
+ if (!model->m_delegate || index < 0 || index >= model->m_compositor.count(m_compositorGroup)) {
+ qWarning() << "VisualDataModel::item: index out range" << index << model->m_compositor.count(m_compositorGroup);
+ return 0;
+ }
+
+ QObject *object = model->object(m_compositorGroup, index, complete, true);
if (QDeclarativePackage *package = qobject_cast<QDeclarativePackage *>(object)) {
QObject *part = package->part(m_part);
@@ -791,7 +2450,8 @@ QSGItem *QSGVisualPartsModel::item(int index, bool complete)
m_model->completeItem();
model->release(object);
if (!model->m_delegateValidated) {
- qmlInfo(model->m_delegate) << tr("Delegate component must be Package type.");
+ if (object)
+ qmlInfo(model->m_delegate) << tr("Delegate component must be Package type.");
model->m_delegateValidated = true;
}
@@ -828,7 +2488,7 @@ void QSGVisualPartsModel::completeItem()
QString QSGVisualPartsModel::stringValue(int index, const QString &role)
{
- return QSGVisualDataModelPrivate::get(m_model)->stringValue(index, role);
+ return QSGVisualDataModelPrivate::get(m_model)->stringValue(m_compositorGroup, index, role);
}
void QSGVisualPartsModel::setWatchedRoles(QList<QByteArray> roles)
@@ -840,11 +2500,15 @@ void QSGVisualPartsModel::setWatchedRoles(QList<QByteArray> roles)
int QSGVisualPartsModel::indexOf(QSGItem *item, QObject *) const
{
- const QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(m_model);
QHash<QObject *, QDeclarativePackage *>::const_iterator it = m_packaged.find(item);
- return it != m_packaged.end()
- ? model->m_adaptorModel->indexOf(*it)
- : -1;
+ if (it != m_packaged.end()) {
+ const QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(m_model);
+ const int cacheIndex = model->cacheIndexOf(*it);
+ return cacheIndex != -1
+ ? model->m_cache.at(cacheIndex)->index[m_compositorGroup]
+ : -1;
+ }
+ return -1;
}
void QSGVisualPartsModel::createdPackage(int index, QDeclarativePackage *package)
@@ -861,6 +2525,14 @@ void QSGVisualPartsModel::destroyingPackage(QDeclarativePackage *package)
}
}
+void QSGVisualPartsModel::emitModelUpdated(const QDeclarativeChangeSet &changeSet, bool reset)
+{
+ emit modelUpdated(changeSet, reset);
+ if (changeSet.difference() != 0)
+ emit countChanged();
+}
+
+
QT_END_NAMESPACE
#include <qsgvisualdatamodel.moc>
diff --git a/src/declarative/items/qsgvisualdatamodel_p.h b/src/declarative/items/qsgvisualdatamodel_p.h
index d3f1d18f65..896c51c22a 100644
--- a/src/declarative/items/qsgvisualdatamodel_p.h
+++ b/src/declarative/items/qsgvisualdatamodel_p.h
@@ -1,3 +1,4 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -42,8 +43,14 @@
#ifndef QSGVISUALDATAMODEL_P_H
#define QSGVISUALDATAMODEL_P_H
+#include <private/qdeclarativelistcompositor_p.h>
#include <private/qsgvisualitemmodel_p.h>
+
+
#include <QtCore/qabstractitemmodel.h>
+#include <QtCore/qstringlist.h>
+
+#include <private/qv8engine_p.h>
QT_BEGIN_HEADER
@@ -53,24 +60,39 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
+
+class QDeclarativeChangeSet;
class QDeclarativeComponent;
class QDeclarativePackage;
+class QDeclarativeV8Function;
+class QSGVisualDataGroup;
+class QSGVisualDataModelAttached;
class QSGVisualDataModelPrivate;
-class Q_DECLARATIVE_EXPORT QSGVisualDataModel : public QSGVisualModel
+
+
+class Q_DECLARATIVE_EXPORT QSGVisualDataModel : public QSGVisualModel, public QDeclarativeParserStatus
{
Q_OBJECT
Q_DECLARE_PRIVATE(QSGVisualDataModel)
Q_PROPERTY(QVariant model READ model WRITE setModel)
Q_PROPERTY(QDeclarativeComponent *delegate READ delegate WRITE setDelegate)
+ Q_PROPERTY(QString filterOnGroup READ filterGroup WRITE setFilterGroup NOTIFY filterGroupChanged RESET resetFilterGroup)
+ Q_PROPERTY(QSGVisualDataGroup *items READ items CONSTANT)
+ Q_PROPERTY(QSGVisualDataGroup *persistedItems READ persistedItems CONSTANT)
+ Q_PROPERTY(QDeclarativeListProperty<QSGVisualDataGroup> groups READ groups CONSTANT)
Q_PROPERTY(QObject *parts READ parts CONSTANT)
Q_PROPERTY(QVariant rootIndex READ rootIndex WRITE setRootIndex NOTIFY rootIndexChanged)
Q_CLASSINFO("DefaultProperty", "delegate")
+ Q_INTERFACES(QDeclarativeParserStatus)
public:
QSGVisualDataModel();
QSGVisualDataModel(QDeclarativeContext *, QObject *parent=0);
virtual ~QSGVisualDataModel();
+ void classBegin();
+ void componentComplete();
+
QVariant model() const;
void setModel(const QVariant &);
@@ -94,13 +116,22 @@ public:
int indexOf(QSGItem *item, QObject *objectContext) const;
+ QString filterGroup() const;
+ void setFilterGroup(const QString &group);
+ void resetFilterGroup();
+
+ QSGVisualDataGroup *items();
+ QSGVisualDataGroup *persistedItems();
+ QDeclarativeListProperty<QSGVisualDataGroup> groups();
QObject *parts();
bool event(QEvent *);
+ static QSGVisualDataModelAttached *qmlAttachedProperties(QObject *obj);
+
Q_SIGNALS:
- void createdPackage(int index, QDeclarativePackage *package);
- void destroyingPackage(QDeclarativePackage *package);
+ void filterGroupChanged();
+ void defaultGroupsChanged();
void rootIndexChanged();
private Q_SLOTS:
@@ -113,9 +144,98 @@ private:
Q_DISABLE_COPY(QSGVisualDataModel)
};
+class QSGVisualDataGroupPrivate;
+class Q_AUTOTEST_EXPORT QSGVisualDataGroup : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int count READ count NOTIFY countChanged)
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+ Q_PROPERTY(bool includeByDefault READ defaultInclude WRITE setDefaultInclude NOTIFY defaultIncludeChanged)
+public:
+ QSGVisualDataGroup(QObject *parent = 0);
+ QSGVisualDataGroup(const QString &name, QSGVisualDataModel *model, int compositorType, QObject *parent = 0);
+ ~QSGVisualDataGroup();
+
+ QString name() const;
+ void setName(const QString &name);
+
+ int count() const;
+
+ bool defaultInclude() const;
+ void setDefaultInclude(bool include);
+
+ Q_INVOKABLE QDeclarativeV8Handle get(int index);
+ Q_INVOKABLE QObject *create(int index);
+
+public Q_SLOTS:
+ void remove(QDeclarativeV8Function *);
+ void addGroups(QDeclarativeV8Function *);
+ void removeGroups(QDeclarativeV8Function *);
+ void setGroups(QDeclarativeV8Function *);
+ void move(QDeclarativeV8Function *);
+
+Q_SIGNALS:
+ void countChanged();
+ void nameChanged();
+ void defaultIncludeChanged();
+ void changed(const QDeclarativeV8Handle &removed, const QDeclarativeV8Handle &inserted);
+private:
+ Q_DECLARE_PRIVATE(QSGVisualDataGroup)
+};
+
+class QSGVisualDataModelCacheItem;
+class QSGVisualDataModelAttachedMetaObject;
+class QSGVisualDataModelAttached : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QSGVisualDataModel *model READ model NOTIFY modelChanged)
+ Q_PROPERTY(QStringList groups READ groups WRITE setGroups NOTIFY groupsChanged)
+public:
+ QSGVisualDataModelAttached(QObject *parent)
+ : QObject(parent)
+ , m_cacheItem(0)
+ , m_previousGroups(0)
+ , m_modelChanged(false)
+ {}
+ ~QSGVisualDataModelAttached() { attachedProperties.remove(parent()); }
+
+ QSGVisualDataModel *model() const;
+
+ QStringList groups() const;
+ void setGroups(const QStringList &groups);
+
+ void emitChanges();
+
+ static QSGVisualDataModelAttached *properties(QObject *obj)
+ {
+ QSGVisualDataModelAttached *rv = attachedProperties.value(obj);
+ if (!rv) {
+ rv = new QSGVisualDataModelAttached(obj);
+ attachedProperties.insert(obj, rv);
+ }
+ return rv;
+ }
+
+Q_SIGNALS:
+ void modelChanged();
+ void groupsChanged();
+
+public:
+ QSGVisualDataModelCacheItem *m_cacheItem;
+ int m_previousGroups;
+ int m_previousIndex[QDeclarativeListCompositor::MaximumGroupCount];
+ bool m_modelChanged;
+
+ static QHash<QObject*, QSGVisualDataModelAttached*> attachedProperties;
+
+ friend class QSGVisualDataModelAttachedMetaObject;
+};
+
QT_END_NAMESPACE
QML_DECLARE_TYPE(QSGVisualDataModel)
+QML_DECLARE_TYPEINFO(QSGVisualDataModel, QML_HAS_ATTACHED_PROPERTIES)
+QML_DECLARE_TYPE(QSGVisualDataGroup)
QT_END_HEADER
diff --git a/src/declarative/particles/defaultshaders/coloredfragment.shader b/src/declarative/particles/defaultshaders/coloredfragment.shader
deleted file mode 100644
index 4ae2643598..0000000000
--- a/src/declarative/particles/defaultshaders/coloredfragment.shader
+++ /dev/null
@@ -1,9 +0,0 @@
-uniform sampler2D texture;
-uniform lowp float qt_Opacity;
-
-varying lowp vec4 fColor;
-
-void main() {
- gl_FragColor = (texture2D(texture, gl_PointCoord)) * fColor * qt_Opacity;
-}
-
diff --git a/src/declarative/particles/defaultshaders/coloredvertex.shader b/src/declarative/particles/defaultshaders/coloredvertex.shader
deleted file mode 100644
index 5b8339276c..0000000000
--- a/src/declarative/particles/defaultshaders/coloredvertex.shader
+++ /dev/null
@@ -1,44 +0,0 @@
-attribute highp vec2 vPos;
-attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize
-attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration
-attribute lowp vec4 vColor;
-
-uniform highp mat4 qt_Matrix;
-uniform highp float timestamp;
-uniform highp float entry;
-
-varying lowp vec4 fColor;
-
-void main() {
- highp float size = vData.z;
- highp float endSize = vData.w;
-
- highp float t = (timestamp - vData.x) / vData.y;
-
- highp float currentSize = mix(size, endSize, t * t);
-
- if (t < 0. || t > 1.)
- currentSize = 0.;
-
- lowp float fFade = 1.;
-
- if (entry == 1.){
- highp float fadeIn = min(t * 10., 1.);
- highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
- fFade = fadeIn * fadeOut;
- }else if(entry == 2.){
- highp float sizeIn = min(t * 10., 1.);
- highp float sizeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
- currentSize = currentSize * sizeIn * sizeOut;
- }
-
- gl_PointSize = currentSize;
-
- highp vec2 pos = vPos
- + vVec.xy * t * vData.y // apply speed vector..
- + 0.5 * vVec.zw * pow(t * vData.y, 2.);
-
- gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);
-
- fColor = vColor * (fFade);
-}
diff --git a/src/declarative/particles/defaultshaders/defaultFadeInOut.png b/src/declarative/particles/defaultshaders/defaultFadeInOut.png
deleted file mode 100644
index 89c04eaefe..0000000000
--- a/src/declarative/particles/defaultshaders/defaultFadeInOut.png
+++ /dev/null
Binary files differ
diff --git a/src/declarative/particles/defaultshaders/deformablefragment.shader b/src/declarative/particles/defaultshaders/deformablefragment.shader
deleted file mode 100644
index 1ac25ba208..0000000000
--- a/src/declarative/particles/defaultshaders/deformablefragment.shader
+++ /dev/null
@@ -1,9 +0,0 @@
-uniform sampler2D texture;
-uniform lowp float qt_Opacity;
-
-varying highp vec2 fTex;
-varying lowp vec4 fColor;
-
-void main() {
- gl_FragColor = (texture2D(texture, fTex)) * fColor * qt_Opacity;
-}
diff --git a/src/declarative/particles/defaultshaders/deformablevertex.shader b/src/declarative/particles/defaultshaders/deformablevertex.shader
deleted file mode 100644
index ab6acde36d..0000000000
--- a/src/declarative/particles/defaultshaders/deformablevertex.shader
+++ /dev/null
@@ -1,65 +0,0 @@
-attribute highp vec2 vPos;
-attribute highp vec2 vTex;
-attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize
-attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration
-attribute highp vec4 vDeformVec; //x,y x unit vector; z,w = y unit vector
-attribute highp vec3 vRotation; //x = radians of rotation, y=rotation speed, z= bool autoRotate
-attribute lowp vec4 vColor;
-
-uniform highp mat4 qt_Matrix;
-uniform highp float timestamp;
-uniform highp float entry;
-
-varying highp vec2 fTex;
-varying lowp vec4 fColor;
-
-void main() {
- fTex = vTex;
- highp float size = vData.z;
- highp float endSize = vData.w;
-
- highp float t = (timestamp - vData.x) / vData.y;
-
- highp float currentSize = mix(size, endSize, t * t);
-
- if (t < 0. || t > 1.)
- currentSize = 0.;
-
- lowp float fFade = 1.;
-
- if (entry == 1.){
- highp float fadeIn = min(t * 10., 1.);
- highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
- fFade = fadeIn * fadeOut;
- }else if(entry == 2.){
- highp float sizeIn = min(t * 10., 1.);
- highp float sizeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
- currentSize = currentSize * sizeIn * sizeOut;
- }
-
- highp vec2 pos;
- highp float rotation = vRotation.x + vRotation.y * t * vData.y;
- if(vRotation.z == 1.0){
- highp vec2 curVel = vVec.zw * t * vData.y + vVec.xy;
- rotation += atan(curVel.y, curVel.x);
- }
- highp vec2 trigCalcs = vec2(cos(rotation), sin(rotation));
- highp vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5);
- highp vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5);
- highp vec2 xRotatedDeform;
- xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y;
- xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y;
- highp vec2 yRotatedDeform;
- yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y;
- yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y;
- pos = vPos
- + xRotatedDeform
- + yRotatedDeform
- //- vec2(1,1) * currentSize * 0.5 // 'center'
- + vVec.xy * t * vData.y // apply speed
- + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration
-
- gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);
-
- fColor = vColor * fFade;
-}
diff --git a/src/declarative/particles/defaultshaders/identitytable.png b/src/declarative/particles/defaultshaders/identitytable.png
deleted file mode 100644
index 2cada1bfad..0000000000
--- a/src/declarative/particles/defaultshaders/identitytable.png
+++ /dev/null
Binary files differ
diff --git a/src/declarative/particles/defaultshaders/imagefragment.shader b/src/declarative/particles/defaultshaders/imagefragment.shader
deleted file mode 100644
index c2341fe6ff..0000000000
--- a/src/declarative/particles/defaultshaders/imagefragment.shader
+++ /dev/null
@@ -1,45 +0,0 @@
-uniform sampler2D texture;
-uniform lowp float qt_Opacity;
-
-#ifdef SPRITE
-varying highp vec4 fTexS;
-#else
-#ifdef DEFORM //First non-pointsprite
-varying highp vec2 fTex;
-#endif
-#endif
-#ifdef COLOR
-varying lowp vec4 fColor;
-#else
-varying lowp float fFade;
-#endif
-#ifdef TABLE
-varying lowp vec2 tt;
-uniform sampler2D colortable;
-#endif
-
-void main() {
-#ifdef SPRITE
- gl_FragColor = mix(texture2D(texture, fTexS.xy), texture2D(texture, fTexS.zw), tt.y)
- * fColor
- * texture2D(colortable, tt)
- * qt_Opacity;
-#else
-#ifdef TABLE
- gl_FragColor = texture2D(texture, fTex)
- * fColor
- * texture2D(colortable, tt)
- * qt_Opacity;
-#else
-#ifdef DEFORM
- gl_FragColor = (texture2D(texture, fTex)) * fColor * qt_Opacity;
-#else
-#ifdef COLOR
- gl_FragColor = (texture2D(texture, gl_PointCoord)) * fColor * qt_Opacity;
-#else
- gl_FragColor = texture2D(texture, gl_PointCoord) * (fFade * qt_Opacity);
-#endif //COLOR
-#endif //DEFORM
-#endif //TABLE
-#endif //SPRITE
-}
diff --git a/src/declarative/particles/defaultshaders/imagevertex.shader b/src/declarative/particles/defaultshaders/imagevertex.shader
deleted file mode 100644
index 9967ef85a2..0000000000
--- a/src/declarative/particles/defaultshaders/imagevertex.shader
+++ /dev/null
@@ -1,126 +0,0 @@
-attribute highp vec2 vPos;
-attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize
-attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration
-uniform highp float entry;
-#ifdef COLOR
-attribute lowp vec4 vColor;
-#endif
-#ifdef DEFORM
-attribute highp vec2 vTex;
-attribute highp vec4 vDeformVec; //x,y x unit vector; z,w = y unit vector
-attribute highp vec3 vRotation; //x = radians of rotation, y=rotation speed, z= bool autoRotate
-#endif
-#ifdef SPRITE
-attribute highp vec4 vAnimData;// idx, duration, frameCount (this anim), timestamp (this anim)
-uniform highp float framecount; //maximum of all anims
-uniform highp float animcount;
-#endif
-
-uniform highp mat4 qt_Matrix;
-uniform highp float timestamp;
-#ifdef TABLE
-varying lowp vec2 tt;//y is progress if Sprite mode
-uniform highp float sizetable[64];
-uniform highp float opacitytable[64];
-#endif
-#ifdef SPRITE
-varying highp vec4 fTexS;
-#else
-#ifdef DEFORM
-varying highp vec2 fTex;
-#endif
-#endif
-#ifdef COLOR
-varying lowp vec4 fColor;
-#else
-varying lowp float fFade;
-#endif
-
-
-void main() {
-
- highp float t = (timestamp - vData.x) / vData.y;
- if (t < 0. || t > 1.){
-#ifdef DEFORM //Not point sprites
- gl_Position = qt_Matrix * vec4(vPos.x, vPos.y, 0., 1.);
-#else
- gl_PointSize = 0.;
-#endif
- return;
- }
-#ifdef SPRITE
- //Calculate frame location in texture
- highp float frameIndex = mod((((timestamp - vAnimData.w)*1000.)/vAnimData.y),vAnimData.z);
- tt.y = mod((timestamp - vAnimData.w)*1000., vAnimData.y) / vAnimData.y;
-
- frameIndex = floor(frameIndex);
- fTexS.xy = vec2(((frameIndex + vTex.x) / framecount), ((vAnimData.x + vTex.y) / animcount));
-
- //Next frame is also passed, for interpolation
- //### Should the next anim be precalculated to allow for interpolation there?
- if(frameIndex != vAnimData.z - 1.)//Can't do it for the last frame though, this anim may not loop
- frameIndex = mod(frameIndex+1., vAnimData.z);
- fTexS.zw = vec2(((frameIndex + vTex.x) / framecount), ((vAnimData.x + vTex.y) / animcount));
-#else
-#ifdef DEFORM
- fTex = vTex;
-#endif
-#endif
- highp float currentSize = mix(vData.z, vData.w, t * t);
- lowp float fade = 1.;
- highp float fadeIn = min(t * 10., 1.);
- highp float fadeOut = 1. - clamp((t - 0.75) * 4.,0., 1.);
-
-#ifdef TABLE
- currentSize = currentSize * sizetable[int(floor(t*64.))];
- fade = fade * opacitytable[int(floor(t*64.))];
-#endif
-
- if (entry == 1.)
- fade = fade * fadeIn * fadeOut;
- else if(entry == 2.)
- currentSize = currentSize * fadeIn * fadeOut;
-
- highp vec2 pos;
-#ifdef DEFORM
- highp float rotation = vRotation.x + vRotation.y * t * vData.y;
- if(vRotation.z == 1.0){
- highp vec2 curVel = vVec.zw * t * vData.y + vVec.xy;
- rotation += atan(curVel.y, curVel.x);
- }
- highp vec2 trigCalcs = vec2(cos(rotation), sin(rotation));
- highp vec4 deform = vDeformVec * currentSize * (vTex.xxyy - 0.5);
- highp vec4 rotatedDeform = deform.xxzz * trigCalcs.xyxy;
- rotatedDeform = rotatedDeform + (deform.yyww * trigCalcs.yxyx * vec4(-1.,1.,-1.,1.));
- /* The readable version:
- highp vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5);
- highp vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5);
- highp vec2 xRotatedDeform;
- xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y;
- xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y;
- highp vec2 yRotatedDeform;
- yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y;
- yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y;
- */
- pos = vPos
- + rotatedDeform.xy
- + rotatedDeform.zw
- + vVec.xy * t * vData.y // apply speed
- + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration
-#else
- pos = vPos
- + vVec.xy * t * vData.y // apply speed vector..
- + 0.5 * vVec.zw * pow(t * vData.y, 2.);
- gl_PointSize = currentSize;
-#endif
- gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);
-
-#ifdef COLOR
- fColor = vColor * fade;
-#else
- fFade = fade;
-#endif
-#ifdef TABLE
- tt.x = t;
-#endif
-}
diff --git a/src/declarative/particles/defaultshaders/simplefragment.shader b/src/declarative/particles/defaultshaders/simplefragment.shader
deleted file mode 100644
index 9b445da52f..0000000000
--- a/src/declarative/particles/defaultshaders/simplefragment.shader
+++ /dev/null
@@ -1,8 +0,0 @@
-uniform sampler2D texture;
-uniform lowp float qt_Opacity;
-
-varying lowp float fFade;
-
-void main() {
- gl_FragColor = texture2D(texture, gl_PointCoord) * (fFade * qt_Opacity);
-}
diff --git a/src/declarative/particles/defaultshaders/simplevertex.shader b/src/declarative/particles/defaultshaders/simplevertex.shader
deleted file mode 100644
index c287e159a5..0000000000
--- a/src/declarative/particles/defaultshaders/simplevertex.shader
+++ /dev/null
@@ -1,39 +0,0 @@
-attribute highp vec2 vPos;
-attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize
-attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration
-
-uniform highp mat4 qt_Matrix;
-uniform highp float timestamp;
-uniform highp float entry;
-
-varying lowp float fFade;
-
-void main() {
- highp float t = (timestamp - vData.x) / vData.y;
-
- highp float currentSize = mix(vData.z, vData.w, t * t);
-
- if (t < 0. || t > 1.)
- currentSize = 0.;
-
- fFade = 1.;
-
- if (entry == 1.){
- highp float fadeIn = min(t * 10., 1.);
- highp float fadeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
- fFade = fadeIn * fadeOut;
- }else if(entry == 2.){
- highp float sizeIn = min(t * 10., 1.);
- highp float sizeOut = 1. - max(0., min((t - 0.75) * 4., 1.));
- currentSize = currentSize * sizeIn * sizeOut;
- }
-
- gl_PointSize = currentSize;
-
- highp vec2 pos = vPos
- + vVec.xy * t * vData.y // apply speed vector..
- + 0.5 * vVec.zw * pow(t * vData.y, 2.);
-
- gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);
-
-}
diff --git a/src/declarative/particles/defaultshaders/spritefragment.shader b/src/declarative/particles/defaultshaders/spritefragment.shader
deleted file mode 100644
index 86002f03fb..0000000000
--- a/src/declarative/particles/defaultshaders/spritefragment.shader
+++ /dev/null
@@ -1,17 +0,0 @@
-uniform sampler2D texture;
-uniform sampler2D colortable;
-uniform sampler2D opacitytable;
-uniform lowp float qt_Opacity;
-
-varying highp vec2 fTexA;
-varying highp vec2 fTexB;
-varying lowp float progress;
-varying lowp vec4 fColor;
-varying lowp float tt;
-
-void main() {
- gl_FragColor = mix(texture2D(texture, fTexA), texture2D(texture, fTexB), progress)
- * fColor
- * texture2D(colortable, vec2(tt, 0.5))
- * (texture2D(opacitytable, vec2(tt, 0.5)).w * qt_Opacity);
-}
diff --git a/src/declarative/particles/defaultshaders/spriteimagefragment.shader b/src/declarative/particles/defaultshaders/spriteimagefragment.shader
deleted file mode 100644
index ecd62cf390..0000000000
--- a/src/declarative/particles/defaultshaders/spriteimagefragment.shader
+++ /dev/null
@@ -1,9 +0,0 @@
-uniform sampler2D texture;
-
-varying highp vec2 fTexA;
-varying highp vec2 fTexB;
-varying lowp float progress;
-
-void main() {
- gl_FragColor = mix(texture2D(texture, fTexA), texture2D(texture, fTexB), progress);
-}
diff --git a/src/declarative/particles/defaultshaders/spriteimagevertex.shader b/src/declarative/particles/defaultshaders/spriteimagevertex.shader
deleted file mode 100644
index 27de2ada6a..0000000000
--- a/src/declarative/particles/defaultshaders/spriteimagevertex.shader
+++ /dev/null
@@ -1,52 +0,0 @@
-attribute highp vec2 vTex;
-attribute highp vec4 vAnimData;// idx, duration, frameCount (this anim), timestamp (this anim)
-
-uniform highp mat4 matrix;
-uniform highp float timestamp;
-uniform lowp float opacity;
-uniform highp float framecount; //maximum of all anims
-uniform highp float animcount;
-uniform highp float width;
-uniform highp float height;
-
-varying highp vec2 fTexA;
-varying highp vec2 fTexB;
-varying lowp float progress;
-
-
-void main() {
- //Calculate frame location in texture
- highp float frameIndex = mod((((timestamp - vAnimData.w)*1000.)/vAnimData.y),vAnimData.z);
- progress = mod((timestamp - vAnimData.w)*1000., vAnimData.y) / vAnimData.y;
-
- frameIndex = floor(frameIndex);
- highp vec2 frameTex;
- if(vTex.x == 0.)
- frameTex.x = (frameIndex/framecount);
- else
- frameTex.x = 1. * ((frameIndex + 1.)/framecount);
-
- if(vTex.y == 0.)
- frameTex.y = (vAnimData.x/animcount);
- else
- frameTex.y = 1. * ((vAnimData.x + 1.)/animcount);
-
- fTexA = frameTex;
- //Next frame is also passed, for interpolation
- if(frameIndex != vAnimData.z - 1.)//Can't do it for the last frame though, this anim may not loop
- frameIndex = mod(frameIndex+1., vAnimData.z);
-
- if(vTex.x == 0.)
- frameTex.x = (frameIndex/framecount);
- else
- frameTex.x = 1. * ((frameIndex + 1.)/framecount);
-
- if(vTex.y == 0.)
- frameTex.y = (vAnimData.x/animcount);
- else
- frameTex.y = 1. * ((vAnimData.x + 1.)/animcount);
- fTexB = frameTex;
-
-
- gl_Position = matrix * vec4(width * vTex.x, height * vTex.y, 0, 1);
-}
diff --git a/src/declarative/particles/defaultshaders/spritevertex.shader b/src/declarative/particles/defaultshaders/spritevertex.shader
deleted file mode 100644
index 96ce3454b8..0000000000
--- a/src/declarative/particles/defaultshaders/spritevertex.shader
+++ /dev/null
@@ -1,113 +0,0 @@
-attribute highp vec2 vPos;
-attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize
-attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration
-#ifdef COLOR
-attribute lowp vec4 vColor;
-#endif
-#ifdef DEFORM
-attribute highp vec2 vTex;
-attribute highp vec4 vDeformVec; //x,y x unit vector; z,w = y unit vector
-attribute highp vec3 vRotation; //x = radians of rotation, y=rotation speed, z= bool autoRotate
-#endif
-#ifdef SPRITE
-attribute highp vec4 vAnimData;// idx, duration, frameCount (this anim), timestamp (this anim)
-uniform highp float framecount; //maximum of all anims
-uniform highp float animcount;
-#endif
-
-uniform highp mat4 qt_Matrix;
-uniform highp float timestamp;
-#ifdef TABLE
-varying lowp float tt;
-#endif
-#ifdef SPRITE
-varying lowp float progress;
-varying highp vec2 fTexA;
-varying highp vec2 fTexB;
-#elseif DEFORM
-varying highp vec2 fTex;
-#endif
-#ifdef COLOR
-varying lowp vec4 fColor;
-#endif
-
-
-void main() {
-
- highp float t = (timestamp - vData.x) / vData.y;
-#ifdef SPRITE
- //Calculate frame location in texture
- highp float frameIndex = mod((((timestamp - vAnimData.w)*1000.)/vAnimData.y),vAnimData.z);
- progress = mod((timestamp - vAnimData.w)*1000., vAnimData.y) / vAnimData.y;
-
- frameIndex = floor(frameIndex);
- highp vec2 frameTex = vTex;
- if(vTex.x == 0.)
- frameTex.x = (frameIndex/framecount);
- else
- frameTex.x = 1. * ((frameIndex + 1.)/framecount);
-
- if(vTex.y == 0.)
- frameTex.y = (vAnimData.x/animcount);
- else
- frameTex.y = 1. * ((vAnimData.x + 1.)/animcount);
-
- fTexA = frameTex;
- //Next frame is also passed, for interpolation
- //### Should the next anim be precalculated to allow for interpolation there?
- if(frameIndex != vAnimData.z - 1.)//Can't do it for the last frame though, this anim may not loop
- frameIndex = mod(frameIndex+1., vAnimData.z);
-
- if(vTex.x == 0.)
- frameTex.x = (frameIndex/framecount);
- else
- frameTex.x = 1. * ((frameIndex + 1.)/framecount);
-
- if(vTex.y == 0.)
- frameTex.y = (vAnimData.x/animcount);
- else
- frameTex.y = 1. * ((vAnimData.x + 1.)/animcount);
- fTexB = frameTex;
-#endif
-
- highp float currentSize = mix(vData.z, vData.w, t * t);
-
- if (t < 0. || t > 1.)
- currentSize = 0.;
-
- highp vec2 pos;
-#ifdef DEFORM
- highp float rotation = vRotation.x + vRotation.y * t * vData.y;
- if(vRotation.z == 1.0){
- highp vec2 curVel = vVec.zw * t * vData.y + vVec.xy;
- rotation += atan(curVel.y, curVel.x);
- }
- highp vec2 trigCalcs = vec2(cos(rotation), sin(rotation));
- highp vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5);
- highp vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5);
- highp vec2 xRotatedDeform;
- xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y;
- xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y;
- highp vec2 yRotatedDeform;
- yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y;
- yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y;
- pos = vPos
- + xRotatedDeform
- + yRotatedDeform
- //- vec2(1,1) * currentSize * 0.5 // 'center'
- + vVec.xy * t * vData.y // apply speed
- + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration
-#else
- pos = vPos
- + vVec.xy * t * vData.y // apply speed vector..
- + 0.5 * vVec.zw * pow(t * vData.y, 2.);
-#endif
- gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);
-
-#ifdef COLOR
- fColor = vColor;
-#endif
-#ifdef TABLE
- tt = t;
-#endif
-}
diff --git a/src/declarative/particles/defaultshaders/tabledfragment.shader b/src/declarative/particles/defaultshaders/tabledfragment.shader
deleted file mode 100644
index e92d8050eb..0000000000
--- a/src/declarative/particles/defaultshaders/tabledfragment.shader
+++ /dev/null
@@ -1,23 +0,0 @@
-uniform sampler2D texture;
-uniform sampler2D colortable;
-uniform sampler2D opacitytable;
-uniform sampler2D sizetable;
-uniform lowp float qt_Opacity;
-
-varying highp vec2 fTex;
-varying lowp vec4 fColor;
-varying lowp float tt;
-
-void main() {
- highp vec2 tex = (((fTex - 0.5) / texture2D(sizetable, vec2(tt, 0.5)).w) + 0.5);
- lowp vec4 color;
- if(tex.x < 1.0 && tex.x > 0.0 && tex.y < 1.0 && tex.y > 0.0){//No CLAMP_TO_BORDER in ES2, so have to do it ourselves
- color = texture2D(texture, tex);
- }else{
- color = vec4(0.,0.,0.,0.);
- }
- gl_FragColor = color
- * fColor
- * texture2D(colortable, vec2(tt, 0.5))
- * (texture2D(opacitytable, vec2(tt, 0.5)).w * qt_Opacity);
-}
diff --git a/src/declarative/particles/defaultshaders/tabledvertex.shader b/src/declarative/particles/defaultshaders/tabledvertex.shader
deleted file mode 100644
index ef3c35da82..0000000000
--- a/src/declarative/particles/defaultshaders/tabledvertex.shader
+++ /dev/null
@@ -1,56 +0,0 @@
-attribute highp vec2 vPos;
-attribute highp vec2 vTex;
-attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize
-attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration
-attribute lowp vec4 vColor;
-attribute highp vec4 vDeformVec; //x,y x unit vector; z,w = y unit vector
-attribute highp vec3 vRotation; //x = radians of rotation, y=rotation speed, z= bool autoRotate
-
-uniform highp mat4 qt_Matrix;
-uniform highp float timestamp;
-
-varying lowp float tt;
-varying highp vec2 fTex;
-varying lowp float progress;
-varying lowp vec4 fColor;
-
-
-void main() {
- fTex = vTex;
- highp float size = vData.z;
- highp float endSize = vData.w;
-
- highp float t = (timestamp - vData.x) / vData.y;
-
- highp float currentSize = mix(size, endSize, t * t);
- if (t < 0. || t > 1.)
- currentSize = 0.;
-
- highp vec2 pos;
- highp float rotation = vRotation.x + vRotation.y * t * vData.y;
- if(vRotation.z == 1.0){
- highp vec2 curVel = vVec.zw * t * vData.y + vVec.xy;
- rotation += atan(curVel.y, curVel.x);
- }
- highp vec2 trigCalcs = vec2(cos(rotation), sin(rotation));
- highp vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5);
- highp vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5);
- highp vec2 xRotatedDeform;
- xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y;
- xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y;
- highp vec2 yRotatedDeform;
- yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y;
- yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y;
- pos = vPos
- + xRotatedDeform
- + yRotatedDeform
- //- vec2(1,1) * currentSize * 0.5 // 'center'
- + vVec.xy * t * vData.y // apply speed
- + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration
-
- gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);
-
- fColor = vColor;
- tt = t;
-
-}
diff --git a/src/declarative/particles/defaultshaders/noise.png b/src/declarative/particles/particleresources/noise.png
index 3c723e1a5a..3c723e1a5a 100644
--- a/src/declarative/particles/defaultshaders/noise.png
+++ b/src/declarative/particles/particleresources/noise.png
Binary files differ
diff --git a/src/declarative/particles/particles.pri b/src/declarative/particles/particles.pri
index 8676e52172..a3a8c90d85 100644
--- a/src/declarative/particles/particles.pri
+++ b/src/declarative/particles/particles.pri
@@ -1,5 +1,3 @@
-INCLUDEPATH += $$PWD
-
HEADERS += \
$$PWD/qsgangledirection_p.h \
$$PWD/qsgcustomparticle_p.h \
@@ -30,7 +28,9 @@ HEADERS += \
$$PWD/qsgcumulativedirection_p.h \
$$PWD/qsgv8particledata_p.h \
$$PWD/qsgrectangleextruder_p.h \
- $$PWD/qsgparticlegroup_p.h
+ $$PWD/qsgparticlegroup_p.h \
+ $$PWD/qsggroupgoal_p.h \
+ $$PWD/qsgmove_p.h
SOURCES += \
$$PWD/qsgangledirection.cpp \
@@ -62,7 +62,9 @@ SOURCES += \
$$PWD/qsgcumulativedirection.cpp \
$$PWD/qsgv8particledata.cpp \
$$PWD/qsgrectangleextruder.cpp \
- $$PWD/qsgparticlegroup.cpp
+ $$PWD/qsgparticlegroup.cpp \
+ $$PWD/qsggroupgoal.cpp \
+ $$PWD/qsgmove.cpp
RESOURCES += \
$$PWD/particles.qrc
diff --git a/src/declarative/particles/particles.qrc b/src/declarative/particles/particles.qrc
index db00a57453..344f9489a4 100644
--- a/src/declarative/particles/particles.qrc
+++ b/src/declarative/particles/particles.qrc
@@ -1,11 +1,5 @@
<RCC>
<qresource prefix="/">
- <file>defaultshaders/imagefragment.shader</file>
- <file>defaultshaders/imagevertex.shader</file>
- <file>defaultshaders/spriteimagefragment.shader</file>
- <file>defaultshaders/spriteimagevertex.shader</file>
- <file>defaultshaders/identitytable.png</file>
- <file>defaultshaders/defaultFadeInOut.png</file>
- <file>defaultshaders/noise.png</file>
+ <file>particleresources/noise.png</file>
</qresource>
</RCC>
diff --git a/src/declarative/particles/qsgage.cpp b/src/declarative/particles/qsgage.cpp
index 0caa8be99c..da7736a818 100644
--- a/src/declarative/particles/qsgage.cpp
+++ b/src/declarative/particles/qsgage.cpp
@@ -86,7 +86,7 @@ bool QSGAgeAffector::affectParticle(QSGParticleData *d, qreal dt)
{
Q_UNUSED(dt);
if (d->stillAlive()){
- qreal curT = (qreal)m_system->m_timeInt/1000.0;
+ qreal curT = (qreal)m_system->timeInt/1000.0;
qreal ttl = (qreal)m_lifeLeft/1000.0;
if (!m_advancePosition && ttl > 0){
qreal x = d->curX();
diff --git a/src/declarative/particles/qsgcumulativedirection_p.h b/src/declarative/particles/qsgcumulativedirection_p.h
index a77f50fd5b..651e21ae65 100644
--- a/src/declarative/particles/qsgcumulativedirection_p.h
+++ b/src/declarative/particles/qsgcumulativedirection_p.h
@@ -61,4 +61,9 @@ public:
private:
QList<QSGDirection*> m_directions;
};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
#endif // QSGCUMULATIVEDIRECTION_P_H
diff --git a/src/declarative/particles/qsgcustomaffector.cpp b/src/declarative/particles/qsgcustomaffector.cpp
index 77da5c58a6..9f8db2c74a 100644
--- a/src/declarative/particles/qsgcustomaffector.cpp
+++ b/src/declarative/particles/qsgcustomaffector.cpp
@@ -81,8 +81,8 @@ void QSGCustomAffector::affectSystem(qreal dt)
updateOffsets();
QList<QSGParticleData*> toAffect;
- foreach (QSGParticleGroupData* gd, m_system->m_groupData)
- if (activeGroup(m_system->m_groupData.key(gd)))
+ foreach (QSGParticleGroupData* gd, m_system->groupData)
+ if (activeGroup(m_system->groupData.key(gd)))
foreach (QSGParticleData* d, gd->data)
if (shouldAffect(d))
toAffect << d;
diff --git a/src/declarative/particles/qsgcustomparticle.cpp b/src/declarative/particles/qsgcustomparticle.cpp
index 174942d7ff..89e465b58a 100644
--- a/src/declarative/particles/qsgcustomparticle.cpp
+++ b/src/declarative/particles/qsgcustomparticle.cpp
@@ -79,7 +79,7 @@ static const char qt_particles_default_fragment_code[] =
"varying highp vec2 qt_TexCoord0; \n"
"uniform lowp float qt_Opacity; \n"
"void main() { \n"
- " gl_FragColor = texture2D(source, fTex) * qt_Opacity; \n"
+ " gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity; \n"
"}";
static QSGGeometry::Attribute PlainParticle_Attributes[] = {
@@ -130,7 +130,6 @@ struct PlainVertices {
QSGCustomParticle::QSGCustomParticle(QSGItem* parent)
: QSGParticlePainter(parent)
- , m_pleaseReset(true)
, m_dirtyData(true)
, m_material(0)
, m_rootNode(0)
@@ -430,9 +429,8 @@ QSGNode *QSGCustomParticle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat
prepareNextFrame();
if (m_rootNode) {
update();
- //### Should I be using dirty geometry too/instead?
foreach (QSGGeometryNode* node, m_nodes)
- node->markDirty(QSGNode::DirtyMaterial);//done in buildData?
+ node->markDirty(QSGNode::DirtyGeometry);//done in buildData?
}
}
@@ -479,13 +477,21 @@ QSGShaderEffectNode* QSGCustomParticle::buildCustomNodes()
s.vertexCode = qt_particles_template_vertex_code + s.vertexCode;
m_material->setProgramSource(s);
foreach (const QString &str, m_groups){
- int gIdx = m_system->m_groupIds[str];
- int count = m_system->m_groupData[gIdx]->size();
+ int gIdx = m_system->groupIds[str];
+ int count = m_system->groupData[gIdx]->size();
+
+ QSGShaderEffectNode* node = new QSGShaderEffectNode();
+ m_nodes.insert(gIdx, node);
+
+ node->setMaterial(m_material);
+ node->markDirty(QSGNode::DirtyMaterial);
+
//Create Particle Geometry
int vCount = count * 4;
int iCount = count * 6;
QSGGeometry *g = new QSGGeometry(PlainParticle_AttributeSet, vCount, iCount);
g->setDrawingMode(GL_TRIANGLES);
+ node->setGeometry(g);
PlainVertex *vertices = (PlainVertex *) g->vertexData();
for (int p=0; p < count; ++p) {
commit(gIdx, p);
@@ -513,14 +519,6 @@ QSGShaderEffectNode* QSGCustomParticle::buildCustomNodes()
indices[5] = o + 2;
indices += 6;
}
-
- QSGShaderEffectNode* node = new QSGShaderEffectNode();
-
- node->setGeometry(g);
- node->setMaterial(m_material);
- node->markDirty(QSGNode::DirtyMaterial);
-
- m_nodes.insert(gIdx, node);
}
foreach (QSGShaderEffectNode* node, m_nodes){
if (node == *(m_nodes.begin()))
@@ -568,7 +566,7 @@ void QSGCustomParticle::buildData()
void QSGCustomParticle::initialize(int gIdx, int pIdx)
{
- QSGParticleData* datum = m_system->m_groupData[gIdx]->data[pIdx];
+ QSGParticleData* datum = m_system->groupData[gIdx]->data[pIdx];
datum->r = rand()/(qreal)RAND_MAX;
}
@@ -577,7 +575,7 @@ void QSGCustomParticle::commit(int gIdx, int pIdx)
if (m_nodes[gIdx] == 0)
return;
- QSGParticleData* datum = m_system->m_groupData[gIdx]->data[pIdx];
+ QSGParticleData* datum = m_system->groupData[gIdx]->data[pIdx];
PlainVertices *particles = (PlainVertices *) m_nodes[gIdx]->geometry()->vertexData();
PlainVertex *vertices = (PlainVertex *)&particles[pIdx];
for (int i=0; i<4; ++i) {
diff --git a/src/declarative/particles/qsgcustomparticle_p.h b/src/declarative/particles/qsgcustomparticle_p.h
index f51e576d34..99f63d5178 100644
--- a/src/declarative/particles/qsgcustomparticle_p.h
+++ b/src/declarative/particles/qsgcustomparticle_p.h
@@ -42,7 +42,7 @@
#ifndef CUSTOM_PARTICLE_H
#define CUSTOM_PARTICLE_H
#include "qsgparticlepainter_p.h"
-#include <QtDeclarative/private/qsgshadereffectnode_p.h>
+#include <private/qsgshadereffectnode_p.h>
#include <QSignalMapper>
QT_BEGIN_HEADER
@@ -98,8 +98,6 @@ protected:
private:
void buildData();
-
- bool m_pleaseReset;
bool m_dirtyData;
QSGShaderEffectProgram m_source;
struct SourceData
diff --git a/src/declarative/particles/qsgfriction.cpp b/src/declarative/particles/qsgfriction.cpp
index 031fc896bf..44b08e3dc0 100644
--- a/src/declarative/particles/qsgfriction.cpp
+++ b/src/declarative/particles/qsgfriction.cpp
@@ -54,6 +54,10 @@ QT_BEGIN_NAMESPACE
A drag will be applied to moving objects which is this factor of their current velocity.
*/
+static qreal sign(qreal a)
+{
+ return a >= 0 ? 1 : -1;
+}
QSGFrictionAffector::QSGFrictionAffector(QSGItem *parent) :
QSGParticleAffector(parent), m_factor(0.0)
@@ -66,8 +70,17 @@ bool QSGFrictionAffector::affectParticle(QSGParticleData *d, qreal dt)
return false;
qreal curVX = d->curVX();
qreal curVY = d->curVY();
- d->setInstantaneousVX(curVX + (curVX * m_factor * -1 * dt));
- d->setInstantaneousVY(curVY + (curVY * m_factor * -1 * dt));
+ qreal newVX = curVX + (curVX * m_factor * -1 * dt);
+ qreal newVY = curVY + (curVY * m_factor * -1 * dt);
+
+ //Since we're modelling a continuous function, it will never pass 0.
+ if (sign(curVX) != sign(newVX))
+ newVX = 0;
+ if (sign(curVY) != sign(newVY))
+ newVY = 0;
+
+ d->setInstantaneousVX(newVX);
+ d->setInstantaneousVY(newVY);
return true;
}
QT_END_NAMESPACE
diff --git a/src/declarative/particles/qsggravity.cpp b/src/declarative/particles/qsggravity.cpp
index d775b49d6f..dd47f66443 100644
--- a/src/declarative/particles/qsggravity.cpp
+++ b/src/declarative/particles/qsggravity.cpp
@@ -50,7 +50,8 @@ const qreal CONV = 0.017453292520444443;
\brief The Gravity element allows you to set a constant accleration in an angle
This element will set the acceleration of all affected particles to a vector of
- the specified magnitude in the specified angle.
+ the specified magnitude in the specified angle. If the angle or acceleration is
+ not varying, it is more efficient to set the specified acceleration on the Emitter.
This element models the gravity of a massive object whose center of
gravity is far away (and thus the gravitational pull is effectively constant
@@ -77,6 +78,8 @@ QSGGravityAffector::QSGGravityAffector(QSGItem *parent) :
connect(this, SIGNAL(angleChanged(qreal)),
this, SLOT(recalc()));
recalc();
+ qWarning() << "Gravity has been deprecated. Use Move instead."
+ << "The difference is that you can specify the acceleration with a StochasticDirection instead of just an angle/magnitude pair";
}
void QSGGravityAffector::recalc()
diff --git a/src/declarative/particles/qsggroupgoal.cpp b/src/declarative/particles/qsggroupgoal.cpp
new file mode 100644
index 0000000000..f380101bd6
--- /dev/null
+++ b/src/declarative/particles/qsggroupgoal.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Declarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsggroupgoal_p.h"
+#include <private/qsgspriteengine_p.h>
+#include <private/qsgsprite_p.h>
+#include "qsgimageparticle_p.h"
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmlclass GroupGoal QSGGroupGoalAffector
+ \inqmlmodule QtQuick.Particles 2
+ \inherits Affector
+ \brief The GroupGoal Affector allows you to change the state of a group of a particle.
+
+*/
+/*!
+ \qmlproperty string QtQuick.Particles2::GroupGoal::goalState
+
+ The name of the group which the affected particles should move to.
+
+ Groups can have defined durations and transitions between them, setting goalState
+ will cause it to disregard any path weightings (including 0) and head down the path
+ which will reach the goalState quickest. It will pass through intermediate groups
+ on that path for their respective durations.
+*/
+/*!
+ \qmlproperty bool QtQuick.Particles2::GroupGoal::jump
+
+ If true, affected particles will jump directly to the target group instead of taking the
+ the shortest valid path to get there. They will also not finish their current state,
+ but immediately move to the beginning of the goal state.
+
+ Default is false.
+*/
+
+QSGGroupGoalAffector::QSGGroupGoalAffector(QSGItem *parent) :
+ QSGParticleAffector(parent), m_jump(false)
+{
+}
+
+void QSGGroupGoalAffector::setGoalState(QString arg)
+{
+ if (m_goalState != arg) {
+ m_goalState = arg;
+ emit goalStateChanged(arg);
+ }
+}
+
+bool QSGGroupGoalAffector::affectParticle(QSGParticleData *d, qreal dt)
+{
+ Q_UNUSED(dt);
+ QSGStochasticEngine *engine = m_system->stateEngine;
+ bool notUsingEngine = false;
+ if (!engine)
+ notUsingEngine = true;
+
+ int index = d->systemIndex;
+ int goalIdx = m_system->groupIds[m_goalState];
+ if (notUsingEngine){//no stochastic states defined. So cut out the engine
+ //TODO: It's possible to move to a group that is intermediate and not used by painters or emitters - but right now that will redirect to the default group
+ m_system->moveGroups(d, goalIdx);
+ return true;
+ }else if (engine->curState(index) != goalIdx){
+ engine->setGoal(goalIdx, index, m_jump);
+ return true;
+ }
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/inputcontext/plugin.cpp b/src/declarative/particles/qsggroupgoal_p.h
index 70fed2e241..6357c3f13a 100644
--- a/src/imports/inputcontext/plugin.cpp
+++ b/src/declarative/particles/qsggroupgoal_p.h
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the examples of the Qt Toolkit.
+** This file is part of the Declarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -39,41 +39,64 @@
**
****************************************************************************/
-#include "declarativeinputcontext.h"
-#include "inputcontextfilter.h"
-#include "inputcontextmodule.h"
+#ifndef GROUPGOALAFFECTOR_H
+#define GROUPGOALAFFECTOR_H
+#include "qsgparticleaffector_p.h"
-#include <QtDeclarative/qdeclarativeextensionplugin.h>
-#include <QtWidgets/qapplication.h>
+QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-static QObject *createContext(QDeclarativeEngine *, QJSEngine *)
-{
- return new InputContextModule;
-}
+QT_MODULE(Declarative)
+
+class QSGStochasticEngine;
-class InputContextQmlPlugin : public QDeclarativeExtensionPlugin
+class QSGGroupGoalAffector : public QSGParticleAffector
{
Q_OBJECT
+ Q_PROPERTY(QString goalState READ goalState WRITE setGoalState NOTIFY goalStateChanged)
+ Q_PROPERTY(bool jump READ jump WRITE setJump NOTIFY jumpChanged)
public:
- virtual void registerTypes(const char *uri)
+ explicit QSGGroupGoalAffector(QSGItem *parent = 0);
+
+ QString goalState() const
{
- Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.inputcontext"));
+ return m_goalState;
+ }
+
+ bool jump() const
+ {
+ return m_jump;
+ }
- qApp->setInputContext(new DeclarativeInputContext);
+protected:
+ virtual bool affectParticle(QSGParticleData *d, qreal dt);
- qmlRegisterModuleApi(uri, 1, 0, createContext);
- qmlRegisterType<InputContextMouseHandler>(uri, 1, 0, "MouseHandler");
- qmlRegisterType<InputContextMouseFilter>(uri, 1, 0, "MouseFilter");
- qmlRegisterType<InputContextKeyFilter>(uri, 1, 0, "KeyFilter");
- qmlRegisterType<InputContextMouseEvent>();
- qmlRegisterType<InputContextKeyEvent>();
+signals:
+
+ void goalStateChanged(QString arg);
+
+ void jumpChanged(bool arg);
+
+public slots:
+
+ void setGoalState(QString arg);
+
+ void setJump(bool arg)
+ {
+ if (m_jump != arg) {
+ m_jump = arg;
+ emit jumpChanged(arg);
+ }
}
+
+private:
+ QString m_goalState;
+ bool m_jump;
};
QT_END_NAMESPACE
-Q_EXPORT_PLUGIN2(InputContext, QT_PREPEND_NAMESPACE(InputContextQmlPlugin));
+QT_END_HEADER
-#include "plugin.moc"
+#endif // GROUPGOALAFFECTOR_H
diff --git a/src/declarative/particles/qsgimageparticle.cpp b/src/declarative/particles/qsgimageparticle.cpp
index 872624ee51..02b3a7a92a 100644
--- a/src/declarative/particles/qsgimageparticle.cpp
+++ b/src/declarative/particles/qsgimageparticle.cpp
@@ -47,10 +47,11 @@
#include <QFile>
#include "qsgimageparticle_p.h"
#include "qsgparticleemitter_p.h"
-#include "qsgsprite_p.h"
-#include "qsgspriteengine_p.h"
+#include <private/qsgsprite_p.h>
+#include <private/qsgspriteengine_p.h>
#include <QOpenGLFunctions>
#include <qsgengine.h>
+#include <private/qsgtexture_p.h>
QT_BEGIN_NAMESPACE
//###Switch to define later, for now user-friendly (no compilation) debugging is worth it
@@ -65,6 +66,186 @@ DEFINE_BOOL_CONFIG_OPTION(qmlParticlesDebug, QML_PARTICLES_DEBUG)
//TODO: Make it larger on desktop? Requires fixing up shader code with the same define
#define UNIFORM_ARRAY_SIZE 64
+static const char vertexShaderCode[] =
+ "attribute highp vec2 vPos;\n"
+ "attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize\n"
+ "attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration\n"
+ "uniform highp float entry;\n"
+ "#ifdef COLOR\n"
+ "attribute lowp vec4 vColor;\n"
+ "#endif\n"
+ "#ifdef DEFORM\n"
+ "attribute highp vec2 vTex;\n"
+ "attribute highp vec4 vDeformVec; //x,y x unit vector; z,w = y unit vector\n"
+ "attribute highp vec3 vRotation; //x = radians of rotation, y=rotation speed, z= bool autoRotate\n"
+ "#endif\n"
+ "#ifdef SPRITE\n"
+ "attribute highp vec4 vAnimData;// interpolate(bool), duration, frameCount (this anim), timestamp (this anim)\n"
+ "attribute highp vec4 vAnimPos;//sheet x,y, width/height of this anim\n"
+ "uniform highp vec2 animSheetSize; //width/height of whole sheet\n"
+ "#endif\n"
+ "\n"
+ "uniform highp mat4 qt_Matrix;\n"
+ "uniform highp float timestamp;\n"
+ "#ifdef TABLE\n"
+ "varying lowp vec2 tt;//y is progress if Sprite mode\n"
+ "uniform highp float sizetable[64];\n"
+ "uniform highp float opacitytable[64];\n"
+ "#endif\n"
+ "#ifdef SPRITE\n"
+ "varying highp vec4 fTexS;\n"
+ "#else\n"
+ "#ifdef DEFORM\n"
+ "varying highp vec2 fTex;\n"
+ "#endif\n"
+ "#endif\n"
+ "#ifdef COLOR\n"
+ "varying lowp vec4 fColor;\n"
+ "#else\n"
+ "varying lowp float fFade;\n"
+ "#endif\n"
+ "\n"
+ "\n"
+ "void main() {\n"
+ "\n"
+ " highp float t = (timestamp - vData.x) / vData.y;\n"
+ " if (t < 0. || t > 1.){\n"
+ "#ifdef DEFORM //Not point sprites\n"
+ " gl_Position = qt_Matrix * vec4(vPos.x, vPos.y, 0., 1.);\n"
+ "#else\n"
+ " gl_PointSize = 0.;\n"
+ "#endif\n"
+ " return;\n"
+ " }\n"
+ "#ifdef SPRITE\n"
+ " //Calculate frame location in texture\n"
+ " highp float frameIndex = mod((((timestamp - vAnimData.w)*1000.)/vAnimData.y),vAnimData.z);\n"
+ " tt.y = mod((timestamp - vAnimData.w)*1000., vAnimData.y) / vAnimData.y;\n"
+ "\n"
+ " frameIndex = floor(frameIndex);\n"
+ " fTexS.xy = vec2(((frameIndex + vTex.x) * vAnimPos.z / animSheetSize.x), ((vAnimPos.y + vTex.y * vAnimPos.w) / animSheetSize.y));\n"
+ "\n"
+ " //Next frame is also passed, for interpolation\n"
+ " //### Should the next anim be precalculated to allow for interpolation there?\n"
+ " if (vAnimData.x == 1.0 && frameIndex != vAnimData.z - 1.)//Can't do it for the last frame though, this anim may not loop\n"
+ " frameIndex = mod(frameIndex+1., vAnimData.z);\n"
+ " fTexS.zw = vec2(((frameIndex + vTex.x) * vAnimPos.z / animSheetSize.x), ((vAnimPos.y + vTex.y * vAnimPos.w) / animSheetSize.y));\n"
+ "#else\n"
+ "#ifdef DEFORM\n"
+ " fTex = vTex;\n"
+ "#endif\n"
+ "#endif\n"
+ " highp float currentSize = mix(vData.z, vData.w, t * t);\n"
+ " lowp float fade = 1.;\n"
+ " highp float fadeIn = min(t * 10., 1.);\n"
+ " highp float fadeOut = 1. - clamp((t - 0.75) * 4.,0., 1.);\n"
+ "\n"
+ "#ifdef TABLE\n"
+ " currentSize = currentSize * sizetable[int(floor(t*64.))];\n"
+ " fade = fade * opacitytable[int(floor(t*64.))];\n"
+ "#endif\n"
+ "\n"
+ " if (entry == 1.)\n"
+ " fade = fade * fadeIn * fadeOut;\n"
+ " else if (entry == 2.)\n"
+ " currentSize = currentSize * fadeIn * fadeOut;\n"
+ "\n"
+ " if (currentSize <= 0)//Sizes too small look jittery as they move\n"
+ " currentSize = 0;\n"
+ " else if (currentSize < 3)\n"
+ " currentSize = 3;\n"
+ "\n"
+ " highp vec2 pos;\n"
+ "#ifdef DEFORM\n"
+ " highp float rotation = vRotation.x + vRotation.y * t * vData.y;\n"
+ " if (vRotation.z == 1.0){\n"
+ " highp vec2 curVel = vVec.zw * t * vData.y + vVec.xy;\n"
+ " rotation += atan(curVel.y, curVel.x);\n"
+ " }\n"
+ " highp vec2 trigCalcs = vec2(cos(rotation), sin(rotation));\n"
+ " highp vec4 deform = vDeformVec * currentSize * (vTex.xxyy - 0.5);\n"
+ " highp vec4 rotatedDeform = deform.xxzz * trigCalcs.xyxy;\n"
+ " rotatedDeform = rotatedDeform + (deform.yyww * trigCalcs.yxyx * vec4(-1.,1.,-1.,1.));\n"
+ " /* The readable version:\n"
+ " highp vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5);\n"
+ " highp vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5);\n"
+ " highp vec2 xRotatedDeform;\n"
+ " xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y;\n"
+ " xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y;\n"
+ " highp vec2 yRotatedDeform;\n"
+ " yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y;\n"
+ " yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y;\n"
+ " */\n"
+ " pos = vPos\n"
+ " + rotatedDeform.xy\n"
+ " + rotatedDeform.zw\n"
+ " + vVec.xy * t * vData.y // apply speed\n"
+ " + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration\n"
+ "#else\n"
+ " pos = vPos\n"
+ " + vVec.xy * t * vData.y // apply speed vector..\n"
+ " + 0.5 * vVec.zw * pow(t * vData.y, 2.);\n"
+ " gl_PointSize = currentSize;\n"
+ "#endif\n"
+ " gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);\n"
+ "\n"
+ "#ifdef COLOR\n"
+ " fColor = vColor * fade;\n"
+ "#else\n"
+ " fFade = fade;\n"
+ "#endif\n"
+ "#ifdef TABLE\n"
+ " tt.x = t;\n"
+ "#endif\n"
+ "}\n";
+
+static const char fragmentShaderCode[] =
+ "uniform sampler2D texture;\n"
+ "uniform lowp float qt_Opacity;\n"
+ "\n"
+ "#ifdef SPRITE\n"
+ "varying highp vec4 fTexS;\n"
+ "#else\n"
+ "#ifdef DEFORM //First non-pointsprite\n"
+ "varying highp vec2 fTex;\n"
+ "#endif\n"
+ "#endif\n"
+ "#ifdef COLOR\n"
+ "varying lowp vec4 fColor;\n"
+ "#else\n"
+ "varying lowp float fFade;\n"
+ "#endif\n"
+ "#ifdef TABLE\n"
+ "varying lowp vec2 tt;\n"
+ "uniform sampler2D colortable;\n"
+ "#endif\n"
+ "\n"
+ "void main() {\n"
+ "#ifdef SPRITE\n"
+ " gl_FragColor = mix(texture2D(texture, fTexS.xy), texture2D(texture, fTexS.zw), tt.y)\n"
+ " * fColor\n"
+ " * texture2D(colortable, tt)\n"
+ " * qt_Opacity;\n"
+ "#else\n"
+ "#ifdef TABLE\n"
+ " gl_FragColor = texture2D(texture, fTex)\n"
+ " * fColor\n"
+ " * texture2D(colortable, tt)\n"
+ " * qt_Opacity;\n"
+ "#else\n"
+ "#ifdef DEFORM\n"
+ " gl_FragColor = (texture2D(texture, fTex)) * fColor * qt_Opacity;\n"
+ "#else\n"
+ "#ifdef COLOR\n"
+ " gl_FragColor = (texture2D(texture, gl_PointCoord)) * fColor * qt_Opacity;\n"
+ "#else\n"
+ " gl_FragColor = texture2D(texture, gl_PointCoord) * (fFade * qt_Opacity);\n"
+ "#endif //COLOR\n"
+ "#endif //DEFORM\n"
+ "#endif //TABLE\n"
+ "#endif //SPRITE\n"
+ "}\n";
+
const qreal CONV = 0.017453292519943295;
class ImageMaterialData
{
@@ -85,11 +266,9 @@ class ImageMaterialData
qreal timestamp;
qreal entry;
- qreal framecount;
- qreal animcount;
+ QSizeF animSheetSize;
};
-//TODO: Move shaders inline once they've stablilized
class TabledMaterialData : public ImageMaterialData {};
class TabledMaterial : public QSGSimpleMaterialShader<TabledMaterialData>
{
@@ -98,17 +277,13 @@ class TabledMaterial : public QSGSimpleMaterialShader<TabledMaterialData>
public:
TabledMaterial()
{
- QFile vf(QStringLiteral(":defaultshaders/imagevertex.shader"));
- vf.open(QFile::ReadOnly);
m_vertex_code = QByteArray(SHADER_DEFINES)
+ QByteArray("#define TABLE\n#define DEFORM\n#define COLOR\n")
- + vf.readAll();
+ + vertexShaderCode;
- QFile ff(QStringLiteral(":defaultshaders/imagefragment.shader"));
- ff.open(QFile::ReadOnly);
m_fragment_code = QByteArray(SHADER_DEFINES)
+ QByteArray("#define TABLE\n#define DEFORM\n#define COLOR\n")
- + ff.readAll();
+ + fragmentShaderCode;
Q_ASSERT(!m_vertex_code.isNull());
Q_ASSERT(!m_fragment_code.isNull());
@@ -142,8 +317,6 @@ public:
d->texture->bind();
program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
- program()->setUniformValue("framecount", (float) 1);
- program()->setUniformValue("animcount", (float) 1);
program()->setUniformValue(m_entry_id, (float) d->entry);
program()->setUniformValueArray(m_sizetable_id, (float*) d->sizeTable, UNIFORM_ARRAY_SIZE, 1);
program()->setUniformValueArray(m_opacitytable_id, (float*) d->opacityTable, UNIFORM_ARRAY_SIZE, 1);
@@ -166,17 +339,13 @@ class DeformableMaterial : public QSGSimpleMaterialShader<DeformableMaterialData
public:
DeformableMaterial()
{
- QFile vf(QStringLiteral(":defaultshaders/imagevertex.shader"));
- vf.open(QFile::ReadOnly);
m_vertex_code = QByteArray(SHADER_DEFINES)
+ QByteArray("#define DEFORM\n#define COLOR\n")
- + vf.readAll();
+ + vertexShaderCode;
- QFile ff(QStringLiteral(":defaultshaders/imagefragment.shader"));
- ff.open(QFile::ReadOnly);
m_fragment_code = QByteArray(SHADER_DEFINES)
+ QByteArray("#define DEFORM\n#define COLOR\n")
- + ff.readAll();
+ + fragmentShaderCode;
Q_ASSERT(!m_vertex_code.isNull());
Q_ASSERT(!m_fragment_code.isNull());
@@ -222,17 +391,13 @@ class SpriteMaterial : public QSGSimpleMaterialShader<SpriteMaterialData>
public:
SpriteMaterial()
{
- QFile vf(QStringLiteral(":defaultshaders/imagevertex.shader"));
- vf.open(QFile::ReadOnly);
m_vertex_code = QByteArray(SHADER_DEFINES)
+ QByteArray("#define SPRITE\n#define TABLE\n#define DEFORM\n#define COLOR\n")
- + vf.readAll();
+ + vertexShaderCode;
- QFile ff(QStringLiteral(":defaultshaders/imagefragment.shader"));
- ff.open(QFile::ReadOnly);
m_fragment_code = QByteArray(SHADER_DEFINES)
+ QByteArray("#define SPRITE\n#define TABLE\n#define DEFORM\n#define COLOR\n")
- + ff.readAll();
+ + fragmentShaderCode;
Q_ASSERT(!m_vertex_code.isNull());
Q_ASSERT(!m_fragment_code.isNull());
@@ -243,7 +408,7 @@ public:
QList<QByteArray> attributes() const {
return QList<QByteArray>() << "vPos" << "vTex" << "vData" << "vVec"
- << "vColor" << "vDeformVec" << "vRotation" << "vAnimData";
+ << "vColor" << "vDeformVec" << "vRotation" << "vAnimData" << "vAnimPos";
};
void initialize() {
@@ -253,8 +418,7 @@ public:
program()->setUniformValue("colortable", 1);
glFuncs = QOpenGLContext::currentContext()->functions();
m_timestamp_id = program()->uniformLocation("timestamp");
- m_framecount_id = program()->uniformLocation("framecount");
- m_animcount_id = program()->uniformLocation("animcount");
+ m_animsize_id = program()->uniformLocation("animSheetSize");
m_entry_id = program()->uniformLocation("entry");
m_sizetable_id = program()->uniformLocation("sizetable");
m_opacitytable_id = program()->uniformLocation("opacitytable");
@@ -269,16 +433,14 @@ public:
d->texture->bind();
program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
- program()->setUniformValue(m_framecount_id, (float) d->framecount);
- program()->setUniformValue(m_animcount_id, (float) d->animcount);
+ program()->setUniformValue(m_animsize_id, d->animSheetSize);
program()->setUniformValue(m_entry_id, (float) d->entry);
program()->setUniformValueArray(m_sizetable_id, (float*) d->sizeTable, 64, 1);
program()->setUniformValueArray(m_opacitytable_id, (float*) d->opacityTable, UNIFORM_ARRAY_SIZE, 1);
}
int m_timestamp_id;
- int m_framecount_id;
- int m_animcount_id;
+ int m_animsize_id;
int m_entry_id;
int m_sizetable_id;
int m_opacitytable_id;
@@ -295,17 +457,13 @@ class ColoredMaterial : public QSGSimpleMaterialShader<ColoredMaterialData>
public:
ColoredMaterial()
{
- QFile vf(QStringLiteral(":defaultshaders/imagevertex.shader"));
- vf.open(QFile::ReadOnly);
m_vertex_code = QByteArray(SHADER_DEFINES)
+ QByteArray("#define COLOR\n")
- + vf.readAll();
+ + vertexShaderCode;
- QFile ff(QStringLiteral(":defaultshaders/imagefragment.shader"));
- ff.open(QFile::ReadOnly);
m_fragment_code = QByteArray(SHADER_DEFINES)
+ QByteArray("#define COLOR\n")
- + ff.readAll();
+ + fragmentShaderCode;
Q_ASSERT(!m_vertex_code.isNull());
Q_ASSERT(!m_fragment_code.isNull());
@@ -366,15 +524,11 @@ class SimpleMaterial : public QSGSimpleMaterialShader<SimpleMaterialData>
public:
SimpleMaterial()
{
- QFile vf(QStringLiteral(":defaultshaders/imagevertex.shader"));
- vf.open(QFile::ReadOnly);
m_vertex_code = QByteArray(SHADER_DEFINES)
- + vf.readAll();
+ + vertexShaderCode;
- QFile ff(QStringLiteral(":defaultshaders/imagefragment.shader"));
- ff.open(QFile::ReadOnly);
m_fragment_code = QByteArray(SHADER_DEFINES)
- + ff.readAll();
+ + fragmentShaderCode;
Q_ASSERT(!m_vertex_code.isNull());
Q_ASSERT(!m_fragment_code.isNull());
@@ -478,6 +632,9 @@ void fillUniformArrayFromImage(float* array, const QImage& img, int size)
\qmlproperty list<Sprite> QtQuick.Particles2::ImageParticle::sprites
The sprite or sprites used to draw this particle.
+
+ Note that the sprite image will be scaled to a square based on the size of
+ the particle being rendered.
*/
/*!
\qmlproperty url QtQuick.Particles2::ImageParticle::colorTable
@@ -630,11 +787,18 @@ void fillUniformArrayFromImage(float* array, const QImage& img, int size)
Default value is Fade.
*/
+/*!
+ \qmlproperty bool QtQuick.Particles2::ImageParticle::spritesInterpolate
+
+ If set to true, sprite particles will interpolate between sprite frames each rendered frame, making
+ the sprites look smoother.
+
+ Default is true.
+*/
QSGImageParticle::QSGImageParticle(QSGItem* parent)
: QSGParticlePainter(parent)
- , m_do_reset(false)
, m_color_variation(0.0)
, m_rootNode(0)
, m_material(0)
@@ -651,6 +815,7 @@ QSGImageParticle::QSGImageParticle(QSGItem* parent)
, m_xVector(0)
, m_yVector(0)
, m_spriteEngine(0)
+ , m_spritesInterpolate(true)
, m_explicitColor(false)
, m_explicitRotation(false)
, m_explicitDeformation(false)
@@ -865,6 +1030,14 @@ void QSGImageParticle::setYVector(QSGDirection* arg)
reset();
}
+void QSGImageParticle::setSpritesInterpolate(bool arg)
+{
+ if (m_spritesInterpolate != arg) {
+ m_spritesInterpolate = arg;
+ emit spritesInterpolateChanged(arg);
+ }
+}
+
void QSGImageParticle::setBloat(bool arg)
{
if (m_bloat != arg) {
@@ -889,7 +1062,7 @@ void QSGImageParticle::resetColor()
{
m_explicitColor = false;
foreach (const QString &str, m_groups)
- foreach (QSGParticleData* d, m_system->m_groupData[m_system->m_groupIds[str]]->data)
+ foreach (QSGParticleData* d, m_system->groupData[m_system->groupIds[str]]->data)
if (d->colorOwner == this)
d->colorOwner = 0;
m_color = QColor();
@@ -905,7 +1078,7 @@ void QSGImageParticle::resetRotation()
{
m_explicitRotation = false;
foreach (const QString &str, m_groups)
- foreach (QSGParticleData* d, m_system->m_groupData[m_system->m_groupIds[str]]->data)
+ foreach (QSGParticleData* d, m_system->groupData[m_system->groupIds[str]]->data)
if (d->rotationOwner == this)
d->rotationOwner = 0;
m_rotation = 0;
@@ -919,7 +1092,7 @@ void QSGImageParticle::resetDeformation()
{
m_explicitDeformation = false;
foreach (const QString &str, m_groups)
- foreach (QSGParticleData* d, m_system->m_groupData[m_system->m_groupIds[str]]->data)
+ foreach (QSGParticleData* d, m_system->groupData[m_system->groupIds[str]]->data)
if (d->deformationOwner == this)
d->deformationOwner = 0;
if (m_xVector)
@@ -1001,13 +1174,14 @@ static QSGGeometry::Attribute SpriteParticle_Attributes[] = {
QSGGeometry::Attribute::create(4, 4, GL_UNSIGNED_BYTE), // Colors
QSGGeometry::Attribute::create(5, 4, GL_FLOAT), // DeformationVectors
QSGGeometry::Attribute::create(6, 3, GL_FLOAT), // Rotation
- QSGGeometry::Attribute::create(7, 4, GL_FLOAT) // Anim Data
+ QSGGeometry::Attribute::create(7, 4, GL_FLOAT), // Anim Data
+ QSGGeometry::Attribute::create(8, 4, GL_FLOAT) // Anim Pos
};
static QSGGeometry::AttributeSet SpriteParticle_AttributeSet =
{
- 8, // Attribute Count
- (2 + 2 + 4 + 4 + 4 + 4 + 3) * sizeof(float) + 4 * sizeof(uchar),
+ 9, // Attribute Count
+ (2 + 2 + 4 + 4 + 4 + 4 + 4 + 3) * sizeof(float) + 4 * sizeof(uchar),
SpriteParticle_Attributes
};
@@ -1022,7 +1196,7 @@ void QSGImageParticle::clearShadows()
//Only call if you need to, may initialize the whole array first time
QSGParticleData* QSGImageParticle::getShadowDatum(QSGParticleData* datum)
{
- QSGParticleGroupData* gd = m_system->m_groupData[datum->group];
+ QSGParticleGroupData* gd = m_system->groupData[datum->group];
if (!m_shadowData.contains(datum->group)) {
QVector<QSGParticleData*> data;
for (int i=0; i<gd->size(); i++){
@@ -1066,8 +1240,8 @@ QSGGeometryNode* QSGImageParticle::buildParticleNodes()
}
foreach (const QString &str, m_groups){//For sharing higher levels, need to have highest used so it renders
- int gIdx = m_system->m_groupIds[str];
- foreach (QSGParticlePainter* p, m_system->m_groupData[gIdx]->painters){
+ int gIdx = m_system->groupIds[str];
+ foreach (QSGParticlePainter* p, m_system->groupData[gIdx]->painters){
QSGImageParticle* other = qobject_cast<QSGImageParticle*>(p);
if (other){
if (other->perfLevel > perfLevel) {
@@ -1115,7 +1289,7 @@ QSGGeometryNode* QSGImageParticle::buildParticleNodes()
switch (perfLevel) {//Fallthrough intended
case Sprites:
m_material = SpriteMaterial::createMaterial();
- getState<ImageMaterialData>(m_material)->framecount = m_spriteEngine->maxFrames();
+ getState<ImageMaterialData>(m_material)->animSheetSize = QSizeF(image.size());
m_spriteEngine->setCount(m_count);
case Tabled:
if (!m_material)
@@ -1123,10 +1297,12 @@ QSGGeometryNode* QSGImageParticle::buildParticleNodes()
colortable = QImage(m_colortable_name.toLocalFile());
sizetable = QImage(m_sizetable_name.toLocalFile());
opacitytable = QImage(m_opacitytable_name.toLocalFile());
- if (colortable.isNull())
- colortable = QImage(QStringLiteral(":defaultshaders/identitytable.png"));
+ if (colortable.isNull()){
+ colortable = QImage(1,1,QImage::Format_ARGB32);
+ colortable.fill(Qt::white);
+ }
Q_ASSERT(!colortable.isNull());
- getState<ImageMaterialData>(m_material)->colorTable = sceneGraphEngine()->createTextureFromImage(colortable);
+ getState<ImageMaterialData>(m_material)->colorTable = QSGPlainTexture::fromImage(colortable);
fillUniformArrayFromImage(getState<ImageMaterialData>(m_material)->sizeTable, sizetable, UNIFORM_ARRAY_SIZE);
fillUniformArrayFromImage(getState<ImageMaterialData>(m_material)->opacityTable, opacitytable, UNIFORM_ARRAY_SIZE);
case Deformable:
@@ -1138,17 +1314,18 @@ QSGGeometryNode* QSGImageParticle::buildParticleNodes()
default://Also Simple
if (!m_material)
m_material = SimpleMaterial::createMaterial();
- getState<ImageMaterialData>(m_material)->texture = sceneGraphEngine()->createTextureFromImage(image);
+ getState<ImageMaterialData>(m_material)->texture = QSGPlainTexture::fromImage(image);
getState<ImageMaterialData>(m_material)->texture->setFiltering(QSGTexture::Linear);
getState<ImageMaterialData>(m_material)->entry = (qreal) m_entryEffect;
m_material->setFlag(QSGMaterial::Blending);
}
foreach (const QString &str, m_groups){
- int gIdx = m_system->m_groupIds[str];
- int count = m_system->m_groupData[gIdx]->size();
+ int gIdx = m_system->groupIds[str];
+ int count = m_system->groupData[gIdx]->size();
QSGGeometryNode* node = new QSGGeometryNode();
node->setMaterial(m_material);
+ node->markDirty(QSGNode::DirtyMaterial);
m_nodes.insert(gIdx, node);
m_idxStarts.insert(gIdx, m_lastIdxStart);
@@ -1238,9 +1415,8 @@ QSGNode *QSGImageParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *)
prepareNextFrame();
if (m_rootNode) {
update();
- //### Should I be using dirty geometry too/instead?
foreach (QSGGeometryNode* node, m_nodes)
- node->markDirty(QSGNode::DirtyMaterial);
+ node->markDirty(QSGNode::DirtyGeometry);
}
}
@@ -1258,8 +1434,8 @@ void QSGImageParticle::prepareNextFrame()
qDebug() << "QSGImageParticle Nodes: ";
int count = 0;
foreach(int i, m_nodes.keys()){
- qDebug() << "Group " << i << " (" << m_system->m_groupData[i]->size() << " particles)";
- count += m_system->m_groupData[i]->size();
+ qDebug() << "Group " << i << " (" << m_system->groupData[i]->size() << " particles)";
+ count += m_system->groupData[i]->size();
}
qDebug() << "Total count: " << count;
}
@@ -1271,22 +1447,24 @@ void QSGImageParticle::prepareNextFrame()
switch (perfLevel){//Fall-through intended
case Sprites:
//Advance State
- getState<ImageMaterialData>(m_material)->animcount = m_spriteEngine->spriteCount();
m_spriteEngine->updateSprites(timeStamp);
foreach (const QString &str, m_groups){
- int gIdx = m_system->m_groupIds[str];
- int count = m_system->m_groupData[gIdx]->size();
+ int gIdx = m_system->groupIds[str];
+ int count = m_system->groupData[gIdx]->size();
Vertices<SpriteVertex>* particles = (Vertices<SpriteVertex> *) m_nodes[gIdx]->geometry()->vertexData();
for (int i=0; i < count; i++){
int spriteIdx = m_idxStarts[gIdx] + i;
Vertices<SpriteVertex> &p = particles[i];
- int curIdx = m_spriteEngine->spriteState(spriteIdx);
- if (curIdx != p.v1.animIdx){
- p.v1.animIdx = p.v2.animIdx = p.v3.animIdx = p.v4.animIdx = curIdx;
+ int curY = m_spriteEngine->spriteY(spriteIdx);//Y is fixed per sprite row, used to distinguish rows here
+ if (curY != p.v1.animY){
p.v1.animT = p.v2.animT = p.v3.animT = p.v4.animT = m_spriteEngine->spriteStart(spriteIdx)/1000.0;
p.v1.frameCount = p.v2.frameCount = p.v3.frameCount = p.v4.frameCount = m_spriteEngine->spriteFrames(spriteIdx);
p.v1.frameDuration = p.v2.frameDuration = p.v3.frameDuration = p.v4.frameDuration = m_spriteEngine->spriteDuration(spriteIdx);
+ p.v1.animX = p.v2.animX = p.v3.animX = p.v4.animX = m_spriteEngine->spriteX(spriteIdx);
+ p.v1.animY = p.v2.animY = p.v3.animY = p.v4.animY = m_spriteEngine->spriteY(spriteIdx);
+ p.v1.animWidth = p.v2.animWidth = p.v3.animWidth = p.v4.animWidth = m_spriteEngine->spriteWidth(spriteIdx);
+ p.v1.animHeight = p.v2.animHeight = p.v3.animHeight = p.v4.animHeight = m_spriteEngine->spriteHeight(spriteIdx);
}
}
}
@@ -1299,6 +1477,8 @@ void QSGImageParticle::prepareNextFrame()
break;
}
+ foreach (QSGGeometryNode* node, m_nodes)
+ node->markDirty(QSGNode::DirtyMaterial);
}
void QSGImageParticle::reloadColor(const Color4ub &c, QSGParticleData* d)
@@ -1310,7 +1490,7 @@ void QSGImageParticle::reloadColor(const Color4ub &c, QSGParticleData* d)
void QSGImageParticle::initialize(int gIdx, int pIdx)
{
Color4ub color;
- QSGParticleData* datum = m_system->m_groupData[gIdx]->data[pIdx];
+ QSGParticleData* datum = m_system->groupData[gIdx]->data[pIdx];
qreal redVariation = m_color_variation + m_redVariation;
qreal greenVariation = m_color_variation + m_greenVariation;
qreal blueVariation = m_color_variation + m_blueVariation;
@@ -1326,14 +1506,19 @@ void QSGImageParticle::initialize(int gIdx, int pIdx)
datum->animationOwner = this;
QSGParticleData* writeTo = (datum->animationOwner == this ? datum : getShadowDatum(datum));
writeTo->animT = writeTo->t;
- writeTo->animIdx = 0;
+ //writeTo->animInterpolate = m_spritesInterpolate;
if (m_spriteEngine){
m_spriteEngine->start(spriteIdx);
writeTo->frameCount = m_spriteEngine->spriteFrames(spriteIdx);
writeTo->frameDuration = m_spriteEngine->spriteDuration(spriteIdx);
+ writeTo->animX = m_spriteEngine->spriteX(spriteIdx);
+ writeTo->animY = m_spriteEngine->spriteY(spriteIdx);
+ writeTo->animWidth = m_spriteEngine->spriteWidth(spriteIdx);
+ writeTo->animHeight = m_spriteEngine->spriteHeight(spriteIdx);
}else{
writeTo->frameCount = 1;
writeTo->frameDuration = 9999;
+ writeTo->animX = writeTo->animY = writeTo->animWidth = writeTo->animHeight = 0;
}
}
case Tabled:
@@ -1409,7 +1594,7 @@ void QSGImageParticle::commit(int gIdx, int pIdx)
QSGGeometryNode *node = m_nodes[gIdx];
if (!node)
return;
- QSGParticleData* datum = m_system->m_groupData[gIdx]->data[pIdx];
+ QSGParticleData* datum = m_system->groupData[gIdx]->data[pIdx];
node->setFlag(QSGNode::OwnsGeometry, false);
SpriteVertex *spriteVertices = (SpriteVertex *) node->geometry()->vertexData();
DeformableVertex *deformableVertices = (DeformableVertex *) node->geometry()->vertexData();
@@ -1451,17 +1636,24 @@ void QSGImageParticle::commit(int gIdx, int pIdx)
spriteVertices[i].rotationSpeed = datum->rotationSpeed;
spriteVertices[i].autoRotate = datum->autoRotate;
}
+ spriteVertices[i].animInterpolate = m_spritesInterpolate ? 1.0 : 0.0;//### Shadow? In particleData? Or uniform?
if (m_explicitAnimation && datum->animationOwner != this) {
QSGParticleData* shadow = getShadowDatum(datum);
- spriteVertices[i].animIdx = shadow->animIdx;
spriteVertices[i].frameDuration = shadow->frameDuration;
spriteVertices[i].frameCount = shadow->frameCount;
spriteVertices[i].animT = shadow->animT;
+ spriteVertices[i].animX = shadow->animX;
+ spriteVertices[i].animY = shadow->animY;
+ spriteVertices[i].animWidth = shadow->animWidth;
+ spriteVertices[i].animHeight = shadow->animHeight;
} else {
- spriteVertices[i].animIdx = datum->animIdx;
spriteVertices[i].frameDuration = datum->frameDuration;
spriteVertices[i].frameCount = datum->frameCount;
spriteVertices[i].animT = datum->animT;
+ spriteVertices[i].animX = datum->animX;
+ spriteVertices[i].animY = datum->animY;
+ spriteVertices[i].animWidth = datum->animWidth;
+ spriteVertices[i].animHeight = datum->animHeight;
}
if (m_explicitColor && datum->colorOwner != this) {
QSGParticleData* shadow = getShadowDatum(datum);
diff --git a/src/declarative/particles/qsgimageparticle_p.h b/src/declarative/particles/qsgimageparticle_p.h
index ccf5cf7702..89796da356 100644
--- a/src/declarative/particles/qsgimageparticle_p.h
+++ b/src/declarative/particles/qsgimageparticle_p.h
@@ -130,10 +130,14 @@ struct SpriteVertex {
float rotation;
float rotationSpeed;
float autoRotate;//Assumed that GPUs prefer floats to bools
- float animIdx;
+ float animInterpolate;
float frameDuration;
float frameCount;
float animT;
+ float animX;
+ float animY;
+ float animWidth;
+ float animHeight;
};
template <typename Vertex>
@@ -177,6 +181,7 @@ class QSGImageParticle : public QSGParticlePainter
//yVector is the same, but top-left to bottom-left. The particle is always a parallelogram.
Q_PROPERTY(QSGDirection* yVector READ yVector WRITE setYVector NOTIFY yVectorChanged RESET resetDeformation)
Q_PROPERTY(QDeclarativeListProperty<QSGSprite> sprites READ sprites)
+ Q_PROPERTY(bool spritesInterpolate READ spritesInterpolate WRITE setSpritesInterpolate NOTIFY spritesInterpolateChanged)
Q_PROPERTY(EntryEffect entryEffect READ entryEffect WRITE setEntryEffect NOTIFY entryEffectChanged)
Q_PROPERTY(bool bloat READ bloat WRITE setBloat NOTIFY bloatChanged)//Just a debugging property to bypass optimizations
@@ -248,6 +253,8 @@ public:
QSGDirection* yVector() const { return m_yVector; }
+ bool spritesInterpolate() const { return m_spritesInterpolate; }
+
bool bloat() const { return m_bloat; }
EntryEffect entryEffect() const { return m_entryEffect; }
@@ -291,6 +298,8 @@ signals:
void yVectorChanged(QSGDirection* arg);
+ void spritesInterpolateChanged(bool arg);
+
void bloatChanged(bool arg);
void entryEffectChanged(EntryEffect arg);
@@ -321,6 +330,8 @@ public slots:
void setYVector(QSGDirection* arg);
+ void setSpritesInterpolate(bool arg);
+
void setBloat(bool arg);
void setEntryEffect(EntryEffect arg);
@@ -338,8 +349,6 @@ private slots:
void createEngine(); //### method invoked by sprite list changing (in engine.h) - pretty nasty
private:
- bool m_do_reset;
-
QUrl m_image_name;
QUrl m_colortable_name;
QUrl m_sizetable_name;
@@ -374,6 +383,7 @@ private:
QList<QSGSprite*> m_sprites;
QSGSpriteEngine* m_spriteEngine;
+ bool m_spritesInterpolate;
bool m_explicitColor;
bool m_explicitRotation;
diff --git a/src/declarative/particles/qsgitemparticle.cpp b/src/declarative/particles/qsgitemparticle.cpp
index 2572d67783..20bd18d146 100644
--- a/src/declarative/particles/qsgitemparticle.cpp
+++ b/src/declarative/particles/qsgitemparticle.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
#include "qsgitemparticle_p.h"
-#include <QtDeclarative/private/qsgvisualitemmodel_p.h>
+#include <private/qsgvisualitemmodel_p.h>
#include <qsgnode.h>
#include <QTimer>
#include <QDeclarativeComponent>
@@ -138,7 +138,7 @@ void QSGItemParticle::give(QSGItem *item)
void QSGItemParticle::initialize(int gIdx, int pIdx)
{
- m_loadables << m_system->m_groupData[gIdx]->data[pIdx];//defer to other thread
+ m_loadables << m_system->groupData[gIdx]->data[pIdx];//defer to other thread
}
void QSGItemParticle::commit(int, int)
@@ -227,11 +227,11 @@ void QSGItemParticle::prepareNextFrame()
//TODO: Size, better fade?
foreach (const QString &str, m_groups){
- int gIdx = m_system->m_groupIds[str];
- int count = m_system->m_groupData[gIdx]->size();
+ int gIdx = m_system->groupIds[str];
+ int count = m_system->groupData[gIdx]->size();
for (int i=0; i<count; i++){
- QSGParticleData* data = m_system->m_groupData[gIdx]->data[i];
+ QSGParticleData* data = m_system->groupData[gIdx]->data[i];
QSGItem* item = data->delegate;
if (!item)
continue;
diff --git a/src/declarative/particles/qsgmove.cpp b/src/declarative/particles/qsgmove.cpp
new file mode 100644
index 0000000000..e885685d6d
--- /dev/null
+++ b/src/declarative/particles/qsgmove.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Declarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsgmove_p.h"
+#include <cmath>
+QT_BEGIN_NAMESPACE
+const qreal CONV = 0.017453292520444443;
+/*!
+ \qmlclass Move QSGMoveAffector
+ \inqmlmodule QtQuick.Particles 2
+ \inherits Affector
+ \brief The Move element allows you to set a new position, speed or acceleration on particles
+
+ You'll often want to set the 'once' property to true for efficiency in the case where you just
+ want to set the parameter. Otherwise, the parameter will be needlessly set to the same thing
+ every simulation cycle.
+*/
+
+/*!
+ \qmlproperty StochasticDirection QtQuick.Particles2::Move::position
+
+ Affected particles will have their position set to this direction,
+ relative to the ParticleSystem. When interpreting directions as points,
+ imagine it as an arrow with the base at the 0,0 of the ParticleSystem and the
+ tip at where the specified position will be.
+*/
+
+/*!
+ \qmlproperty StochasticDirection QtQuick.Particles2::Move::speed
+
+ Affected particles will have their speed set to this direction.
+*/
+
+
+/*!
+ \qmlproperty StochasticDirection QtQuick.Particles2::Move::acceleration
+
+ Affected particles will have their acceleration set to this direction.
+*/
+
+
+/*!
+ \qmlproperty bool QtQuick.Particles2::Move::relative
+
+ Whether the affected particles have their existing position/speed/acceleration added
+ to the new one.
+*/
+
+QSGMoveAffector::QSGMoveAffector(QSGItem *parent)
+ : QSGParticleAffector(parent)
+ , m_position(&m_nullVector)
+ , m_speed(&m_nullVector)
+ , m_acceleration(&m_nullVector)
+ , m_relative(false)
+{
+}
+
+bool QSGMoveAffector::affectParticle(QSGParticleData *d, qreal dt)
+{
+ Q_UNUSED(dt);
+ bool changed = false;
+ QPointF curPos(d->curX(), d->curY());
+
+ if (m_position != &m_nullVector){
+ QPointF pos = m_position->sample(curPos);
+ if (m_relative)
+ pos += curPos;
+ d->setInstantaneousX(pos.x());
+ d->setInstantaneousY(pos.y());
+ changed = true;
+ }
+
+ if (m_speed != &m_nullVector){
+ QPointF pos = m_speed->sample(curPos);
+ if (m_relative)
+ pos += QPointF(d->curVX(), d->curVY());
+ d->setInstantaneousVX(pos.x());
+ d->setInstantaneousVY(pos.y());
+ changed = true;
+ }
+
+ if (m_acceleration != &m_nullVector){
+ QPointF pos = m_acceleration->sample(curPos);
+ if (m_relative)
+ pos += QPointF(d->curAX(), d->curAY());
+ d->setInstantaneousAX(pos.x());
+ d->setInstantaneousAY(pos.y());
+ changed = true;
+ }
+
+ return changed;
+}
+QT_END_NAMESPACE
diff --git a/src/declarative/particles/qsgmove_p.h b/src/declarative/particles/qsgmove_p.h
new file mode 100644
index 0000000000..2f7fc831f5
--- /dev/null
+++ b/src/declarative/particles/qsgmove_p.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Declarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MOVEAFFECTOR_H
+#define MOVEAFFECTOR_H
+#include "qsgparticleaffector_p.h"
+#include "qsgdirection_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+
+class QSGMoveAffector : public QSGParticleAffector
+{
+ Q_OBJECT
+ Q_PROPERTY(bool relative READ relative WRITE setRelative NOTIFY relativeChanged)
+ Q_PROPERTY(QSGDirection *position READ position WRITE setPosition NOTIFY positionChanged RESET positionReset)
+ Q_PROPERTY(QSGDirection *speed READ speed WRITE setSpeed NOTIFY speedChanged RESET speedReset)
+ Q_PROPERTY(QSGDirection *acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged RESET accelerationReset)
+
+public:
+ explicit QSGMoveAffector(QSGItem *parent = 0);
+ QSGDirection * position() const
+ {
+ return m_position;
+ }
+
+ QSGDirection * speed() const
+ {
+ return m_speed;
+ }
+
+ QSGDirection * acceleration() const
+ {
+ return m_acceleration;
+ }
+
+ void positionReset()
+ {
+ m_position = &m_nullVector;
+ }
+
+ void speedReset()
+ {
+ m_speed = &m_nullVector;
+ }
+
+ void accelerationReset()
+ {
+ m_acceleration = &m_nullVector;
+ }
+
+ bool relative() const
+ {
+ return m_relative;
+ }
+
+protected:
+ virtual bool affectParticle(QSGParticleData *d, qreal dt);
+signals:
+ void positionChanged(QSGDirection * arg);
+
+ void speedChanged(QSGDirection * arg);
+
+ void accelerationChanged(QSGDirection * arg);
+
+ void relativeChanged(bool arg);
+
+public slots:
+ void setPosition(QSGDirection * arg)
+ {
+ if (m_position != arg) {
+ m_position = arg;
+ emit positionChanged(arg);
+ }
+ }
+
+ void setSpeed(QSGDirection * arg)
+ {
+ if (m_speed != arg) {
+ m_speed = arg;
+ emit speedChanged(arg);
+ }
+ }
+
+ void setAcceleration(QSGDirection * arg)
+ {
+ if (m_acceleration != arg) {
+ m_acceleration = arg;
+ emit accelerationChanged(arg);
+ }
+ }
+
+ void setRelative(bool arg)
+ {
+ if (m_relative != arg) {
+ m_relative = arg;
+ emit relativeChanged(arg);
+ }
+ }
+
+private slots:
+private:
+ QSGDirection * m_position;
+ QSGDirection * m_speed;
+ QSGDirection * m_acceleration;
+
+ QSGDirection m_nullVector;
+ bool m_relative;
+};
+
+QT_END_NAMESPACE
+QT_END_HEADER
+#endif // MOVEAFFECTOR_H
diff --git a/src/declarative/particles/qsgparticleaffector.cpp b/src/declarative/particles/qsgparticleaffector.cpp
index 12b81351d7..24bddea5f7 100644
--- a/src/declarative/particles/qsgparticleaffector.cpp
+++ b/src/declarative/particles/qsgparticleaffector.cpp
@@ -150,7 +150,7 @@ bool QSGParticleAffector::activeGroup(int g) {
if (m_updateIntSet){
m_groupIds.clear();
foreach (const QString &p, m_groups)
- m_groupIds << m_system->m_groupIds[p];//###Can this occur before group ids are properly assigned?
+ m_groupIds << m_system->groupIds[p];//###Can this occur before group ids are properly assigned?
m_updateIntSet = false;
}
return m_groupIds.isEmpty() || m_groupIds.contains(g);
@@ -178,7 +178,7 @@ bool QSGParticleAffector::shouldAffect(QSGParticleData* d)
void QSGParticleAffector::postAffect(QSGParticleData* d)
{
- m_system->m_needsReset << d;
+ m_system->needsReset << d;
if (m_onceOff)
m_onceOffed << qMakePair(d->group, d->index);
if (isAffectedConnected())
@@ -192,8 +192,8 @@ void QSGParticleAffector::affectSystem(qreal dt)
//If not reimplemented, calls affect particle per particle
//But only on particles in targeted system/area
updateOffsets();//### Needed if an ancestor is transformed.
- foreach (QSGParticleGroupData* gd, m_system->m_groupData)
- if (activeGroup(m_system->m_groupData.key(gd)))
+ foreach (QSGParticleGroupData* gd, m_system->groupData)
+ if (activeGroup(m_system->groupData.key(gd)))
foreach (QSGParticleData* d, gd->data)
if (shouldAffect(d))
if (affectParticle(d, dt))
@@ -208,7 +208,7 @@ bool QSGParticleAffector::affectParticle(QSGParticleData *, qreal )
void QSGParticleAffector::reset(QSGParticleData* pd)
{//TODO: This, among other ones, should be restructured so they don't all need to remember to call the superclass
if (m_onceOff)
- if (m_groups.isEmpty() || m_groupIds.contains(pd->group))
+ if (activeGroup(pd->group))
m_onceOffed.remove(qMakePair(pd->group, pd->index));
}
@@ -224,7 +224,7 @@ bool QSGParticleAffector::isColliding(QSGParticleData *d)
qreal myCurY = d->curY();
qreal myCurSize = d->curSize()/2;
foreach (const QString &group, m_whenCollidingWith){
- foreach (QSGParticleData* other, m_system->m_groupData[m_system->m_groupIds[group]]->data){
+ foreach (QSGParticleData* other, m_system->groupData[m_system->groupIds[group]]->data){
if (!other->stillAlive())
continue;
qreal otherCurX = other->curX();
diff --git a/src/declarative/particles/qsgparticleemitter.cpp b/src/declarative/particles/qsgparticleemitter.cpp
index bdd008a5bb..e453888b03 100644
--- a/src/declarative/particles/qsgparticleemitter.cpp
+++ b/src/declarative/particles/qsgparticleemitter.cpp
@@ -227,13 +227,13 @@ QSGParticleEmitter::QSGParticleEmitter(QSGItem *parent) :
, m_particleEndSize(-1)
, m_particleSizeVariation(0)
, m_startTime(0)
+ , m_overwrite(true)
, m_pulseLeft(0)
, m_maxParticleCount(-1)
, m_speed_from_movement(0)
, m_reset_last(true)
, m_last_timestamp(-1)
, m_last_emission(0)
- , m_overwrite(true)
{
//TODO: Reset speed/acc back to null vector? Or allow null pointer?
@@ -375,6 +375,9 @@ void QSGParticleEmitter::emitWindow(int timeStamp)
qreal time = timeStamp / 1000.;
qreal particleRatio = 1. / m_particlesPerSecond;
qreal pt = m_last_emission;
+ qreal maxLife = (m_particleDuration + m_particleDurationVariation)/1000.0;
+ if (pt + maxLife < time)//We missed so much, that we should skip emiting particles that are dead by now
+ pt = time - maxLife;
qreal opt = pt; // original particle time
qreal dt = time - m_last_timestamp; // timestamp delta...
@@ -402,7 +405,7 @@ void QSGParticleEmitter::emitWindow(int timeStamp)
while ((pt < time && m_emitCap) || !m_burstQueue.isEmpty()) {
//int pos = m_last_particle % m_particle_count;
- QSGParticleData* datum = m_system->newDatum(m_system->m_groupIds[m_group], !m_overwrite);
+ QSGParticleData* datum = m_system->newDatum(m_system->groupIds[m_group], !m_overwrite);
if (datum){//actually emit(otherwise we've been asked to skip this one)
datum->e = this;//###useful?
qreal t = 1 - (pt - opt) / dt;
diff --git a/src/declarative/particles/qsgparticlegroup_p.h b/src/declarative/particles/qsgparticlegroup_p.h
index 346b4ab77e..26bed55785 100644
--- a/src/declarative/particles/qsgparticlegroup_p.h
+++ b/src/declarative/particles/qsgparticlegroup_p.h
@@ -40,10 +40,12 @@
****************************************************************************/
#ifndef QSGPARTICLEGROUP
#define QSGPARTICLEGROUP
-#include "qsgspriteengine_p.h"
+#include <private/qsgspriteengine_p.h>
#include "qsgparticlesystem_p.h"
#include "qdeclarativeparserstatus.h"
+QT_BEGIN_NAMESPACE
+
class QSGParticleGroup : public QSGStochasticState, public QDeclarativeParserStatus
{
Q_OBJECT
@@ -55,6 +57,7 @@ class QSGParticleGroup : public QSGStochasticState, public QDeclarativeParserSta
//Intercept children requests and assign to the group & system
Q_PROPERTY(QDeclarativeListProperty<QObject> particleChildren READ particleChildren DESIGNABLE false)//### Hidden property for in-state system definitions - ought not to be used in actual "Sprite" states
Q_CLASSINFO("DefaultProperty", "particleChildren")
+ Q_INTERFACES(QDeclarativeParserStatus)
public:
explicit QSGParticleGroup(QObject* parent = 0);
@@ -104,4 +107,6 @@ private:
QList<QObject*> m_delayedRedirects;
};
+QT_END_NAMESPACE
+
#endif
diff --git a/src/declarative/particles/qsgparticlepainter.cpp b/src/declarative/particles/qsgparticlepainter.cpp
index 1b3453afe6..4f6b18c973 100644
--- a/src/declarative/particles/qsgparticlepainter.cpp
+++ b/src/declarative/particles/qsgparticlepainter.cpp
@@ -65,7 +65,7 @@ QT_BEGIN_NAMESPACE
*/
QSGParticlePainter::QSGParticlePainter(QSGItem *parent) :
QSGItem(parent),
- m_system(0), m_count(0), m_sentinel(new QSGParticleData(0))
+ m_system(0), m_count(0), m_pleaseReset(true), m_sentinel(new QSGParticleData(0))
{
}
@@ -73,8 +73,6 @@ void QSGParticlePainter::componentComplete()
{
if (!m_system && qobject_cast<QSGParticleSystem*>(parentItem()))
setSystem(qobject_cast<QSGParticleSystem*>(parentItem()));
- if (!m_system)
- qWarning() << "ParticlePainter created without a particle system specified";//TODO: useful QML warnings, like line number?
QSGItem::componentComplete();
}
@@ -134,8 +132,8 @@ void QSGParticlePainter::calcSystemOffset(bool resetPending)
if (lastOffset != m_systemOffset && !resetPending){
//Reload all particles//TODO: Necessary?
foreach (const QString &g, m_groups){
- int gId = m_system->m_groupIds[g];
- foreach (QSGParticleData* d, m_system->m_groupData[gId]->data)
+ int gId = m_system->groupIds[g];
+ foreach (QSGParticleData* d, m_system->groupData[gId]->data)
reload(d);
}
}
diff --git a/src/declarative/particles/qsgparticlepainter_p.h b/src/declarative/particles/qsgparticlepainter_p.h
index 4b627e9457..78e0127eac 100644
--- a/src/declarative/particles/qsgparticlepainter_p.h
+++ b/src/declarative/particles/qsgparticlepainter_p.h
@@ -119,7 +119,7 @@ protected:
QSGParticleSystem* m_system;
friend class QSGParticleSystem;
int m_count;
- bool m_pleaseReset;
+ bool m_pleaseReset;//Used by subclasses, but it's a nice optimization to know when stuff isn't going to matter.
QStringList m_groups;
QPointF m_systemOffset;
diff --git a/src/declarative/particles/qsgparticlesmodule.cpp b/src/declarative/particles/qsgparticlesmodule.cpp
index f880842acb..fe2dec9c48 100644
--- a/src/declarative/particles/qsgparticlesmodule.cpp
+++ b/src/declarative/particles/qsgparticlesmodule.cpp
@@ -68,6 +68,8 @@
#include "qsgcustomaffector_p.h"
#include "qsgrectangleextruder_p.h"
#include "qsgparticlegroup_p.h"
+#include "qsggroupgoal_p.h"
+#include "qsgmove_p.h"
QT_BEGIN_NAMESPACE
@@ -102,14 +104,20 @@ void QSGParticlesModule::defineModule()
qmlRegisterType<QSGGravityAffector>(uri, 2, 0, "Gravity");
qmlRegisterType<QSGAgeAffector>(uri, 2, 0, "Age");
qmlRegisterType<QSGSpriteGoalAffector>(uri, 2, 0, "SpriteGoal");
+ qmlRegisterType<QSGGroupGoalAffector>(uri, 2, 0, "GroupGoal");
qmlRegisterType<QSGTurbulenceAffector>(uri, 2, 0 , "Turbulence");
qmlRegisterType<QSGTargetAffector>(uri, 2, 0 , "Target");
+ qmlRegisterType<QSGMoveAffector>(uri, 2, 0, "Move");
//Exposed just for completeness
- qmlRegisterUncreatableType<QSGParticleAffector>(uri, 2, 0, "ParticleAffector", "Abstract type. Use one of the inheriting types instead.");
- qmlRegisterUncreatableType<QSGParticlePainter>(uri, 2, 0, "ParticlePainter", "Abstract type. Use one of the inheriting types instead.");
- qmlRegisterUncreatableType<QSGParticleExtruder>(uri, 2, 0, "ParticleExtruder", "Abstract type. Use one of the inheriting types instead.");
- qmlRegisterUncreatableType<QSGDirection>(uri, 2, 0, "NullVector", "Abstract type. Use one of the inheriting types instead.");
+ qmlRegisterUncreatableType<QSGParticleAffector>(uri, 2, 0, "ParticleAffector",
+ QStringLiteral("Abstract type. Use one of the inheriting types instead."));
+ qmlRegisterUncreatableType<QSGParticlePainter>(uri, 2, 0, "ParticlePainter",
+ QStringLiteral("Abstract type. Use one of the inheriting types instead."));
+ qmlRegisterUncreatableType<QSGParticleExtruder>(uri, 2, 0, "ParticleExtruder",
+ QStringLiteral("Abstract type. Use one of the inheriting types instead."));
+ qmlRegisterUncreatableType<QSGDirection>(uri, 2, 0, "NullVector",
+ QStringLiteral("Abstract type. Use one of the inheriting types instead."));
}
QT_END_NAMESPACE
diff --git a/src/declarative/particles/qsgparticlesystem.cpp b/src/declarative/particles/qsgparticlesystem.cpp
index 8fd96f8652..cdf21ba5c3 100644
--- a/src/declarative/particles/qsgparticlesystem.cpp
+++ b/src/declarative/particles/qsgparticlesystem.cpp
@@ -44,8 +44,8 @@
#include "qsgparticleemitter_p.h"
#include "qsgparticleaffector_p.h"
#include "qsgparticlepainter_p.h"
-#include "qsgspriteengine_p.h"
-#include "qsgsprite_p.h"
+#include <private/qsgspriteengine_p.h>
+#include <private/qsgsprite_p.h>
#include "qsgv8particledata_p.h"
#include "qsgparticlegroup_p.h"
@@ -88,9 +88,9 @@ DEFINE_BOOL_CONFIG_OPTION(qmlParticlesDebug, QML_PARTICLES_DEBUG)
*/
/*!
- \qmlproperty bool QtQuick.Particles2::ParticleSystem::clear
+ \qmlproperty bool QtQuick.Particles2::ParticleSystem::empty
- clear is set to true when there are no live particles left in the system.
+ empty is set to true when there are no live particles left in the system.
You can use this to pause the system, keeping it from spending any time updating,
but you will need to resume it in order for additional particles to be generated
@@ -300,7 +300,7 @@ int QSGParticleGroupData::size()
QString QSGParticleGroupData::name()//### Worth caching as well?
{
- return m_system->m_groupIds.key(index);
+ return m_system->groupIds.key(index);
}
void QSGParticleGroupData::setSize(int newSize){
@@ -358,7 +358,7 @@ QSGParticleData* QSGParticleGroupData::newDatum(bool respectsLimits)
bool QSGParticleGroupData::recycle()
{
- while (dataHeap.top() <= m_system->m_timeInt){
+ while (dataHeap.top() <= m_system->timeInt){
foreach (QSGParticleData* datum, dataHeap.pop()){
if (!datum->stillAlive()){
reusableIndexes << datum->index;
@@ -376,7 +376,7 @@ void QSGParticleGroupData::prepareRecycler(QSGParticleData* d){
if (d->lifeSpan*1000 < m_system->maxLife){
dataHeap.insert(d);
} else {
- while ((roundedTime(d->t) + 2*m_system->maxLife/3) <= m_system->m_timeInt)
+ while ((roundedTime(d->t) + 2*m_system->maxLife/3) <= m_system->timeInt)
d->extendLife(m_system->maxLife/3000.0);
dataHeap.insertTimed(d, roundedTime(d->t) + 2*m_system->maxLife/3);
}
@@ -388,11 +388,11 @@ QSGParticleData::QSGParticleData(QSGParticleSystem* sys)
, system(sys)
, index(0)
, systemIndex(-1)
- , v8Datum(0)
, colorOwner(0)
, rotationOwner(0)
, deformationOwner(0)
, animationOwner(0)
+ , v8Datum(0)
{
x = 0;
y = 0;
@@ -415,6 +415,10 @@ QSGParticleData::QSGParticleData(QSGParticleSystem* sys)
frameDuration = 1;
frameCount = 1;
animT = -1;
+ animX = 0;
+ animY = 0;
+ animWidth = 1;
+ animHeight = 1;
color.r = 255;
color.g = 255;
color.b = 255;
@@ -447,6 +451,10 @@ void QSGParticleData::clone(const QSGParticleData& other)
frameDuration = other.frameDuration;
frameCount = other.frameCount;
animT = other.animT;
+ animX = other.animX;
+ animY = other.animY;
+ animWidth = other.animWidth;
+ animHeight = other.animHeight;
color.r = other.color.r;
color.g = other.color.g;
color.b = other.color.b;
@@ -470,7 +478,7 @@ QDeclarativeV8Handle QSGParticleData::v8Value()
//sets the x accleration without affecting the instantaneous x velocity or position
void QSGParticleData::setInstantaneousAX(qreal ax)
{
- qreal t = (system->m_timeInt / 1000.0) - this->t;
+ qreal t = (system->timeInt / 1000.0) - this->t;
qreal vx = (this->vx + t*this->ax) - t*ax;
qreal ex = this->x + this->vx * t + 0.5 * this->ax * t * t;
qreal x = ex - t*vx - 0.5 * t*t*ax;
@@ -483,7 +491,7 @@ void QSGParticleData::setInstantaneousAX(qreal ax)
//sets the x velocity without affecting the instantaneous x postion
void QSGParticleData::setInstantaneousVX(qreal vx)
{
- qreal t = (system->m_timeInt / 1000.0) - this->t;
+ qreal t = (system->timeInt / 1000.0) - this->t;
qreal evx = vx - t*this->ax;
qreal ex = this->x + this->vx * t + 0.5 * this->ax * t * t;
qreal x = ex - t*evx - 0.5 * t*t*this->ax;
@@ -495,14 +503,14 @@ void QSGParticleData::setInstantaneousVX(qreal vx)
//sets the instantaneous x postion
void QSGParticleData::setInstantaneousX(qreal x)
{
- qreal t = (system->m_timeInt / 1000.0) - this->t;
+ qreal t = (system->timeInt / 1000.0) - this->t;
this->x = x - t*this->vx - 0.5 * t*t*this->ax;
}
//sets the y accleration without affecting the instantaneous y velocity or position
void QSGParticleData::setInstantaneousAY(qreal ay)
{
- qreal t = (system->m_timeInt / 1000.0) - this->t;
+ qreal t = (system->timeInt / 1000.0) - this->t;
qreal vy = (this->vy + t*this->ay) - t*ay;
qreal ey = this->y + this->vy * t + 0.5 * this->ay * t * t;
qreal y = ey - t*vy - 0.5 * t*t*ay;
@@ -515,7 +523,7 @@ void QSGParticleData::setInstantaneousAY(qreal ay)
//sets the y velocity without affecting the instantaneous y position
void QSGParticleData::setInstantaneousVY(qreal vy)
{
- qreal t = (system->m_timeInt / 1000.0) - this->t;
+ qreal t = (system->timeInt / 1000.0) - this->t;
qreal evy = vy - t*this->ay;
qreal ey = this->y + this->vy * t + 0.5 * this->ay * t * t;
qreal y = ey - t*evy - 0.5 * t*t*this->ay;
@@ -527,31 +535,31 @@ void QSGParticleData::setInstantaneousVY(qreal vy)
//sets the instantaneous Y position
void QSGParticleData::setInstantaneousY(qreal y)
{
- qreal t = (system->m_timeInt / 1000.0) - this->t;
+ qreal t = (system->timeInt / 1000.0) - this->t;
this->y = y - t*this->vy - 0.5 * t*t*this->ay;
}
qreal QSGParticleData::curX() const
{
- qreal t = (system->m_timeInt / 1000.0) - this->t;
+ qreal t = (system->timeInt / 1000.0) - this->t;
return this->x + this->vx * t + 0.5 * this->ax * t * t;
}
qreal QSGParticleData::curVX() const
{
- qreal t = (system->m_timeInt / 1000.0) - this->t;
+ qreal t = (system->timeInt / 1000.0) - this->t;
return this->vx + t*this->ax;
}
qreal QSGParticleData::curY() const
{
- qreal t = (system->m_timeInt / 1000.0) - this->t;
+ qreal t = (system->timeInt / 1000.0) - this->t;
return y + vy * t + 0.5 * ay * t * t;
}
qreal QSGParticleData::curVY() const
{
- qreal t = (system->m_timeInt / 1000.0) - this->t;
+ qreal t = (system->timeInt / 1000.0) - this->t;
return vy + t*ay;
}
@@ -562,14 +570,14 @@ void QSGParticleData::debugDump()
<< "Vel: " << vx << "," << vy
<< "Acc: " << ax << "," << ay
<< "Size: " << size << "," << endSize
- << "Time: " << t << "," <<lifeSpan << ";" << (system->m_timeInt / 1000.0) ;
+ << "Time: " << t << "," <<lifeSpan << ";" << (system->timeInt / 1000.0) ;
}
bool QSGParticleData::stillAlive()
{
if (!system)
return false;
- return (t + lifeSpan - EPSILON) > ((qreal)system->m_timeInt/1000.0);
+ return (t + lifeSpan - EPSILON) > ((qreal)system->timeInt/1000.0);
}
float QSGParticleData::curSize()
@@ -583,7 +591,7 @@ float QSGParticleData::lifeLeft()
{
if (!system)
return 0.0f;
- return (t + lifeSpan) - (system->m_timeInt/1000.0);
+ return (t + lifeSpan) - (system->timeInt/1000.0);
}
void QSGParticleData::extendLife(float time)
@@ -596,7 +604,7 @@ void QSGParticleData::extendLife(float time)
t += time;
animT += time;
- qreal elapsed = (system->m_timeInt / 1000.0) - t;
+ qreal elapsed = (system->timeInt / 1000.0) - t;
qreal evy = newVY - elapsed*ay;
qreal ey = newY - elapsed*evy - 0.5 * elapsed*elapsed*ay;
qreal evx = newVX - elapsed*ax;
@@ -609,8 +617,13 @@ void QSGParticleData::extendLife(float time)
}
QSGParticleSystem::QSGParticleSystem(QSGItem *parent) :
- QSGItem(parent), m_particle_count(0), m_running(true), m_paused(false)
- , m_nextIndex(0), m_componentComplete(false), m_stateEngine(0)
+ QSGItem(parent),
+ stateEngine(0),
+ m_running(true),
+ particleCount(0),
+ m_nextIndex(0),
+ m_componentComplete(false),
+ m_paused(false)
{
connect(&m_painterMapper, SIGNAL(mapped(QObject*)),
this, SLOT(loadPainter(QObject*)));
@@ -620,7 +633,7 @@ QSGParticleSystem::QSGParticleSystem(QSGItem *parent) :
QSGParticleSystem::~QSGParticleSystem()
{
- foreach (QSGParticleGroupData* gd, m_groupData)
+ foreach (QSGParticleGroupData* gd, groupData)
delete gd;
if (m_animation)
@@ -632,13 +645,13 @@ void QSGParticleSystem::initGroups()
m_reusableIndexes.clear();
m_nextIndex = 0;
- qDeleteAll(m_groupData);
- m_groupData.clear();
- m_groupIds.clear();
+ qDeleteAll(groupData);
+ groupData.clear();
+ groupIds.clear();
QSGParticleGroupData* gd = new QSGParticleGroupData(0, this);//Default group
- m_groupData.insert(0,gd);
- m_groupIds.insert("",0);
+ groupData.insert(0,gd);
+ groupIds.insert(QString(), 0);
m_nextGroupId = 1;
}
@@ -757,14 +770,14 @@ void QSGParticleSystem::reset()
if (!m_componentComplete)
return;
- m_timeInt = 0;
+ timeInt = 0;
//Clear guarded pointers which have been deleted
int cleared = 0;
cleared += m_emitters.removeAll(0);
cleared += m_painters.removeAll(0);
cleared += m_affectors.removeAll(0);
- m_bySysIdx.resize(0);
+ bySysIdx.resize(0);
initGroups();//Also clears all logical particles
if (!m_running)
@@ -781,15 +794,16 @@ void QSGParticleSystem::reset()
}
//### Do affectors need reset too?
-
- if (m_running) {//reset restarts animation (if running)
+ if (m_animation) {//Animation is explicitly disabled in benchmarks
+ //reset restarts animation (if running)
if ((m_animation->state() == QAbstractAnimation2::Running))
m_animation->stop();
m_animation->start();
if (m_paused)
m_animation->pause();
}
- m_initialized = true;
+
+ initialized = true;
}
@@ -800,25 +814,25 @@ void QSGParticleSystem::loadPainter(QObject *p)
QSGParticlePainter* painter = qobject_cast<QSGParticlePainter*>(p);
Q_ASSERT(painter);//XXX
- foreach (QSGParticleGroupData* sg, m_groupData)
+ foreach (QSGParticleGroupData* sg, groupData)
sg->painters.remove(painter);
int particleCount = 0;
if (painter->groups().isEmpty()){//Uses default particle
QStringList def;
- def << "";
+ def << QString();
painter->setGroups(def);
- particleCount += m_groupData[0]->size();
- m_groupData[0]->painters << painter;
+ particleCount += groupData[0]->size();
+ groupData[0]->painters << painter;
}else{
foreach (const QString &group, painter->groups()){
- if (group != QLatin1String("") && !m_groupIds[group]){//new group
+ if (group != QLatin1String("") && !groupIds[group]){//new group
int id = m_nextGroupId++;
QSGParticleGroupData* gd = new QSGParticleGroupData(id, this);
- m_groupIds.insert(group, id);
- m_groupData.insert(id, gd);
+ groupIds.insert(group, id);
+ groupData.insert(id, gd);
}
- particleCount += m_groupData[m_groupIds[group]]->size();
- m_groupData[m_groupIds[group]]->painters << painter;
+ particleCount += groupData[groupIds[group]]->size();
+ groupData[groupIds[group]]->painters << painter;
}
}
painter->setCount(particleCount);
@@ -837,36 +851,36 @@ void QSGParticleSystem::emittersChanged()
QList<int> previousSizes;
QList<int> newSizes;
for (int i=0; i<m_nextGroupId; i++){
- previousSizes << m_groupData[i]->size();
+ previousSizes << groupData[i]->size();
newSizes << 0;
}
foreach (QSGParticleEmitter* e, m_emitters){//Populate groups and set sizes.
- if (!m_groupIds.contains(e->group())
- || (!e->group().isEmpty() && !m_groupIds[e->group()])){//or it was accidentally inserted by a failed lookup earlier
+ if (!groupIds.contains(e->group())
+ || (!e->group().isEmpty() && !groupIds[e->group()])){//or it was accidentally inserted by a failed lookup earlier
int id = m_nextGroupId++;
QSGParticleGroupData* gd = new QSGParticleGroupData(id, this);
- m_groupIds.insert(e->group(), id);
- m_groupData.insert(id, gd);
+ groupIds.insert(e->group(), id);
+ groupData.insert(id, gd);
previousSizes << 0;
newSizes << 0;
}
- newSizes[m_groupIds[e->group()]] += e->particleCount();
+ newSizes[groupIds[e->group()]] += e->particleCount();
//###: Cull emptied groups?
}
//TODO: Garbage collection?
- m_particle_count = 0;
+ particleCount = 0;
for (int i=0; i<m_nextGroupId; i++){
- m_groupData[i]->setSize(qMax(newSizes[i], previousSizes[i]));
- m_particle_count += m_groupData[i]->size();
+ groupData[i]->setSize(qMax(newSizes[i], previousSizes[i]));
+ particleCount += groupData[i]->size();
}
if (m_debugMode)
- qDebug() << "Particle system emitters changed. New particle count: " << m_particle_count;
+ qDebug() << "Particle system emitters changed. New particle count: " << particleCount;
- if (m_particle_count > m_bySysIdx.size())//New datum requests haven't updated it
- m_bySysIdx.resize(m_particle_count);
+ if (particleCount > bySysIdx.size())//New datum requests haven't updated it
+ bySysIdx.resize(particleCount);
foreach (QSGParticlePainter *p, m_painters)
loadPainter(p);
@@ -880,19 +894,19 @@ void QSGParticleSystem::createEngine()
{
if (!m_componentComplete)
return;
- if (m_stateEngine && m_debugMode)
+ if (stateEngine && m_debugMode)
qDebug() << "Resetting Existing Sprite Engine...";
//### Solve the losses if size/states go down
foreach (QSGParticleGroup* group, m_groups){
bool exists = false;
- foreach (const QString &name, m_groupIds.keys())
+ foreach (const QString &name, groupIds.keys())
if (group->name() == name)
exists = true;
if (!exists){
int id = m_nextGroupId++;
QSGParticleGroupData* gd = new QSGParticleGroupData(id, this);
- m_groupIds.insert(group->name(), id);
- m_groupData.insert(id, gd);
+ groupIds.insert(group->name(), id);
+ groupData.insert(id, gd);
}
}
@@ -901,7 +915,7 @@ void QSGParticleSystem::createEngine()
QList<QSGParticleGroup*> newList;
for (int i=0; i<m_nextGroupId; i++){
bool exists = false;
- QString name = m_groupData[i]->name();
+ QString name = groupData[i]->name();
foreach (QSGParticleGroup* existing, m_groups){
if (existing->name() == name){
newList << existing;
@@ -918,35 +932,41 @@ void QSGParticleSystem::createEngine()
foreach (QSGParticleGroup* g, m_groups)
states << (QSGStochasticState*)g;
- if (!m_stateEngine)
- m_stateEngine = new QSGStochasticEngine(this);
- m_stateEngine->setCount(m_particle_count);
- m_stateEngine->m_states = states;
+ if (!stateEngine)
+ stateEngine = new QSGStochasticEngine(this);
+ stateEngine->setCount(particleCount);
+ stateEngine->m_states = states;
- connect(m_stateEngine, SIGNAL(stateChanged(int)),
+ connect(stateEngine, SIGNAL(stateChanged(int)),
this, SLOT(particleStateChange(int)));
}else{
- if (m_stateEngine)
- delete m_stateEngine;
- m_stateEngine = 0;
+ if (stateEngine)
+ delete stateEngine;
+ stateEngine = 0;
}
}
void QSGParticleSystem::particleStateChange(int idx)
{
- moveGroups(m_bySysIdx[idx], m_stateEngine->curState(idx));
+ moveGroups(bySysIdx[idx], stateEngine->curState(idx));
}
void QSGParticleSystem::moveGroups(QSGParticleData *d, int newGIdx)
{
+ if (!d || newGIdx == d->group)
+ return;
+
QSGParticleData* pd = newDatum(newGIdx, false, d->systemIndex);
+ if (!pd)
+ return;
+
pd->clone(*d);
finishNewDatum(pd);
d->systemIndex = -1;
- m_groupData[d->group]->kill(d);
+ groupData[d->group]->kill(d);
}
int QSGParticleSystem::nextSystemIndex()
@@ -956,10 +976,10 @@ int QSGParticleSystem::nextSystemIndex()
m_reusableIndexes.remove(ret);
return ret;
}
- if (m_nextIndex >= m_bySysIdx.size()){
- m_bySysIdx.resize(m_bySysIdx.size() < 10 ? 10 : m_bySysIdx.size()*1.1);//###+1,10%,+10? Choose something non-arbitrarily
- if (m_stateEngine)
- m_stateEngine->setCount(m_bySysIdx.size());
+ if (m_nextIndex >= bySysIdx.size()){
+ bySysIdx.resize(bySysIdx.size() < 10 ? 10 : bySysIdx.size()*1.1);//###+1,10%,+10? Choose something non-arbitrarily
+ if (stateEngine)
+ stateEngine->setCount(bySysIdx.size());
}
return m_nextIndex++;
@@ -967,9 +987,9 @@ int QSGParticleSystem::nextSystemIndex()
QSGParticleData* QSGParticleSystem::newDatum(int groupId, bool respectLimits, int sysIndex)
{
- Q_ASSERT(groupId < m_groupData.count());//XXX shouldn't really be an assert
+ Q_ASSERT(groupId < groupData.count());//XXX shouldn't really be an assert
- QSGParticleData* ret = m_groupData[groupId]->newDatum(respectLimits);
+ QSGParticleData* ret = groupData[groupId]->newDatum(respectLimits);
if (!ret){
return 0;
}
@@ -978,17 +998,17 @@ QSGParticleData* QSGParticleSystem::newDatum(int groupId, bool respectLimits, in
ret->systemIndex = nextSystemIndex();
}else{
if (ret->systemIndex != -1){
- if (m_stateEngine)
- m_stateEngine->stop(ret->systemIndex);
+ if (stateEngine)
+ stateEngine->stop(ret->systemIndex);
m_reusableIndexes << ret->systemIndex;
- m_bySysIdx[ret->systemIndex] = 0;
+ bySysIdx[ret->systemIndex] = 0;
}
ret->systemIndex = sysIndex;
}
- m_bySysIdx[ret->systemIndex] = ret;
+ bySysIdx[ret->systemIndex] = ret;
- if (m_stateEngine)
- m_stateEngine->start(ret->systemIndex, ret->group);
+ if (stateEngine)
+ stateEngine->start(ret->systemIndex, ret->group);
m_empty = false;
return ret;
@@ -1008,44 +1028,44 @@ void QSGParticleSystem::emitParticle(QSGParticleData* pd)
void QSGParticleSystem::finishNewDatum(QSGParticleData *pd){
Q_ASSERT(pd);
- m_groupData[pd->group]->prepareRecycler(pd);
+ groupData[pd->group]->prepareRecycler(pd);
foreach (QSGParticleAffector *a, m_affectors)
if (a && a->m_needsReset)
a->reset(pd);
- foreach (QSGParticlePainter* p, m_groupData[pd->group]->painters)
+ foreach (QSGParticlePainter* p, groupData[pd->group]->painters)
if (p)
p->load(pd);
}
void QSGParticleSystem::updateCurrentTime( int currentTime )
{
- if (!m_initialized)
+ if (!initialized)
return;//error in initialization
//### Elapsed time never shrinks - may cause problems if left emitting for weeks at a time.
- qreal dt = m_timeInt / 1000.;
- m_timeInt = currentTime;
- qreal time = m_timeInt / 1000.;
+ qreal dt = timeInt / 1000.;
+ timeInt = currentTime;
+ qreal time = timeInt / 1000.;
dt = time - dt;
- m_needsReset.clear();
+ needsReset.clear();
bool oldClear = m_empty;
m_empty = true;
- foreach (QSGParticleGroupData* gd, m_groupData)//Recycle all groups and see if they're out of live particles
+ foreach (QSGParticleGroupData* gd, groupData)//Recycle all groups and see if they're out of live particles
m_empty = gd->recycle() && m_empty;
- if (m_stateEngine)
- m_stateEngine->updateSprites(m_timeInt);
+ if (stateEngine)
+ stateEngine->updateSprites(timeInt);
foreach (QSGParticleEmitter* emitter, m_emitters)
if (emitter)
- emitter->emitWindow(m_timeInt);
+ emitter->emitWindow(timeInt);
foreach (QSGParticleAffector* a, m_affectors)
if (a)
a->affectSystem(dt);
- foreach (QSGParticleData* d, m_needsReset)
- foreach (QSGParticlePainter* p, m_groupData[d->group]->painters)
+ foreach (QSGParticleData* d, needsReset)
+ foreach (QSGParticlePainter* p, groupData[d->group]->painters)
if (p && d)
p->reload(d);
@@ -1057,11 +1077,11 @@ int QSGParticleSystem::systemSync(QSGParticlePainter* p)
{
if (!m_running)
return 0;
- if (!m_initialized)
+ if (!initialized)
return 0;//error in initialization
p->performPendingCommits();
- return m_timeInt;
+ return timeInt;
}
-QT_END_NAMESPACE
+QT_END_NAMESPACE \ No newline at end of file
diff --git a/src/declarative/particles/qsgparticlesystem_p.h b/src/declarative/particles/qsgparticlesystem_p.h
index b129dfb076..a61147545e 100644
--- a/src/declarative/particles/qsgparticlesystem_p.h
+++ b/src/declarative/particles/qsgparticlesystem_p.h
@@ -48,8 +48,8 @@
#include <QHash>
#include <QPointer>
#include <QSignalMapper>
-#include <QtDeclarative/private/qsgsprite_p.h>
#include "private/qabstractanimation2_p.h"
+#include <private/qsgsprite_p.h>
#include <QtDeclarative/qdeclarative.h>
#include <private/qv8engine_p.h> //For QDeclarativeV8Handle
@@ -103,7 +103,7 @@ private:
QHash<int,int> m_lookups;
};
-class QSGParticleGroupData{
+class Q_AUTOTEST_EXPORT QSGParticleGroupData {
public:
QSGParticleGroupData(int id, QSGParticleSystem* sys);
~QSGParticleGroupData();
@@ -143,7 +143,7 @@ struct Color4ub {
uchar a;
};
-class QSGParticleData{
+class Q_AUTOTEST_EXPORT QSGParticleData {
public:
//TODO: QObject like memory management (without the cost, just attached to system)
QSGParticleData(QSGParticleSystem* sys);
@@ -203,6 +203,10 @@ public:
float frameDuration;
float frameCount;
float animT;
+ float animX;
+ float animY;
+ float animWidth;
+ float animHeight;
float r;
QSGItem* delegate;
int modelIndex;
@@ -225,7 +229,7 @@ private:
QSGV8ParticleData* v8Datum;
};
-class QSGParticleSystem : public QSGItem
+class Q_AUTOTEST_EXPORT QSGParticleSystem : public QSGItem
{
Q_OBJECT
Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
@@ -236,13 +240,12 @@ public:
explicit QSGParticleSystem(QSGItem *parent = 0);
~QSGParticleSystem();
- //TODO: Hook up running and temporal manipulators to the animation
bool isRunning() const
{
return m_running;
}
- int count(){ return m_particle_count; }
+ int count(){ return particleCount; }
static const int maxLife = 600000;
@@ -274,13 +277,13 @@ protected:
private slots:
void emittersChanged();
void loadPainter(QObject* p);
- void createEngine(); //### method invoked by sprite list changing (in engine.h) - pretty nasty
+ void createEngine(); //Not invoked by sprite engine, unlike Sprite uses
void particleStateChange(int idx);
-public://###but only really for related class usage. Perhaps we should all be friends?
+public:
//These can be called multiple times per frame, performance critical
void emitParticle(QSGParticleData* p);
- QSGParticleData* newDatum(int groupId, bool respectLimits = true, int sysIdx = -1);//TODO: implement respectLimits in emitters (which means interacting with maxCount?)
+ QSGParticleData* newDatum(int groupId, bool respectLimits = true, int sysIdx = -1);
void finishNewDatum(QSGParticleData*);
void moveGroups(QSGParticleData *d, int newGIdx);
int nextSystemIndex();
@@ -288,21 +291,27 @@ public://###but only really for related class usage. Perhaps we should all be fr
//This one only once per painter per frame
int systemSync(QSGParticlePainter* p);
- QSet<QSGParticleData*> m_needsReset;
- QVector<QSGParticleData*> m_bySysIdx; //Another reference to the data (data owned by group), but by sysIdx
- QHash<QString, int> m_groupIds;
- QHash<int, QSGParticleGroupData*> m_groupData;
- QSGStochasticEngine* m_stateEngine;
+ //Data members here for ease of related class and auto-test usage. Not "public" API. TODO: d_ptrize
+ QSet<QSGParticleData*> needsReset;
+ QVector<QSGParticleData*> bySysIdx; //Another reference to the data (data owned by group), but by sysIdx
+ QHash<QString, int> groupIds;
+ QHash<int, QSGParticleGroupData*> groupData;
+ QSGStochasticEngine* stateEngine;
+
+ //Also only here for auto-test usage
+ void updateCurrentTime( int currentTime );
+ QSGParticleSystemAnimation* m_animation;
+ bool m_running;
- int m_timeInt;
- bool m_initialized;
+ int timeInt;
+ bool initialized;
+ int particleCount;
void registerParticlePainter(QSGParticlePainter* p);
void registerParticleEmitter(QSGParticleEmitter* e);
void registerParticleAffector(QSGParticleAffector* a);
void registerParticleGroup(QSGParticleGroup* g);
- int m_particle_count;
static void statePropertyRedirect(QDeclarativeListProperty<QObject> *prop, QObject *value);
static void stateRedirect(QSGParticleGroup* group, QSGParticleSystem* sys, QObject *value);
bool isPaused() const
@@ -318,7 +327,6 @@ public://###but only really for related class usage. Perhaps we should all be fr
private:
void initializeSystem();
void initGroups();
- bool m_running;
QList<QPointer<QSGParticleEmitter> > m_emitters;
QList<QPointer<QSGParticleAffector> > m_affectors;
QList<QPointer<QSGParticlePainter> > m_painters;
@@ -331,9 +339,6 @@ private:
QSignalMapper m_painterMapper;
QSignalMapper m_emitterMapper;
- friend class QSGParticleSystemAnimation;
- void updateCurrentTime( int currentTime );
- QSGParticleSystemAnimation* m_animation;
bool m_paused;
bool m_debugMode;
bool m_allDead;
@@ -375,4 +380,3 @@ QT_END_HEADER
#endif // PARTICLESYSTEM_H
-
diff --git a/src/declarative/particles/qsgpointattractor.cpp b/src/declarative/particles/qsgpointattractor.cpp
index 8c2632f2c8..093e55b16c 100644
--- a/src/declarative/particles/qsgpointattractor.cpp
+++ b/src/declarative/particles/qsgpointattractor.cpp
@@ -56,7 +56,6 @@ QT_BEGIN_NAMESPACE
Note that Attractor has the standard Item x,y,width and height properties.
Like other affectors, these represent the affected area. They
do not represent the 0x0 point which is the target of the attraction.
-
*/
@@ -69,8 +68,8 @@ QT_BEGIN_NAMESPACE
/*!
\qmlproperty real QtQuick.Particles2::PointAttractor::pointY
- The x coordinate of the attracting point. This is relative
- to the x coordinate of the Attractor.
+ The y coordinate of the attracting point. This is relative
+ to the y coordinate of the Attractor.
*/
/*!
\qmlproperty real QtQuick.Particles2::PointAttractor::strength
@@ -116,8 +115,8 @@ bool QSGAttractorAffector::affectParticle(QSGParticleData *d, qreal dt)
{
if (m_strength == 0.0)
return false;
- qreal dx = m_x - d->curX();
- qreal dy = m_y - d->curY();
+ qreal dx = m_x+m_offset.x() - d->curX();
+ qreal dy = m_y+m_offset.y() - d->curY();
qreal r = sqrt((dx*dx) + (dy*dy));
qreal theta = atan2(dy,dx);
qreal ds = 0;
diff --git a/src/declarative/particles/qsgrectangleextruder.cpp b/src/declarative/particles/qsgrectangleextruder.cpp
index accc88fcdb..fde227c5b8 100644
--- a/src/declarative/particles/qsgrectangleextruder.cpp
+++ b/src/declarative/particles/qsgrectangleextruder.cpp
@@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE
*/
QSGRectangleExtruder::QSGRectangleExtruder(QObject *parent) :
- QObject(parent), m_fill(true)
+ QSGParticleExtruder(parent), m_fill(true)
{
}
diff --git a/src/declarative/particles/qsgrectangleextruder_p.h b/src/declarative/particles/qsgrectangleextruder_p.h
index 5795375c84..9cc51b2cb7 100644
--- a/src/declarative/particles/qsgrectangleextruder_p.h
+++ b/src/declarative/particles/qsgrectangleextruder_p.h
@@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
-class QSGRectangleExtruder : public QObject
+class QSGRectangleExtruder : public QSGParticleExtruder
{
Q_OBJECT
Q_PROPERTY(bool fill READ fill WRITE setFill NOTIFY fillChanged)
diff --git a/src/declarative/particles/qsgspritegoal.cpp b/src/declarative/particles/qsgspritegoal.cpp
index ec2be02326..260929f28f 100644
--- a/src/declarative/particles/qsgspritegoal.cpp
+++ b/src/declarative/particles/qsgspritegoal.cpp
@@ -40,8 +40,8 @@
****************************************************************************/
#include "qsgspritegoal_p.h"
-#include "private/qsgspriteengine_p.h"
-#include "private/qsgsprite_p.h"
+#include <private/qsgspriteengine_p.h>
+#include <private/qsgsprite_p.h>
#include "qsgimageparticle_p.h"
#include <QDebug>
@@ -51,28 +51,48 @@ QT_BEGIN_NAMESPACE
\qmlclass SpriteGoal QSGSpriteGoalAffector
\inqmlmodule QtQuick.Particles 2
\inherits Affector
- \brief The SpriteGoal Affector allows you to change the state of a sprite or group of a particle.
+ \brief The SpriteGoal Affector allows you to change the state of a sprite particle.
*/
/*!
\qmlproperty string QtQuick.Particles2::SpriteGoal::goalState
+
+ The name of the Sprite which the affected particles should move to.
+
+ Sprite states have defined durations and transitions between them, setting goalState
+ will cause it to disregard any path weightings (including 0) and head down the path
+ which will reach the goalState quickest. It will pass through intermediate states
+ on that path.
*/
/*!
\qmlproperty bool QtQuick.Particles2::SpriteGoal::jump
+
+ If true, affected sprites will jump directly to the goal state instead of taking the
+ the shortest valid path to get there. They will also not finish their current state,
+ but immediately move to the beginning of the goal state.
+
+ Default is false.
*/
/*!
\qmlproperty bool QtQuick.Particles2::SpriteGoal::systemStates
+
+ deprecated, use GroupGoal instead
*/
QSGSpriteGoalAffector::QSGSpriteGoalAffector(QSGItem *parent) :
- QSGParticleAffector(parent), m_goalIdx(-1), m_jump(false), m_systemStates(false), m_lastEngine(0), m_notUsingEngine(false)
+ QSGParticleAffector(parent),
+ m_goalIdx(-1),
+ m_lastEngine(0),
+ m_jump(false),
+ m_systemStates(false),
+ m_notUsingEngine(false)
{
}
void QSGSpriteGoalAffector::updateStateIndex(QSGStochasticEngine* e)
{
if (m_systemStates){
- m_goalIdx = m_system->m_groupIds[m_goalState];
+ m_goalIdx = m_system->groupIds[m_goalState];
}else{
m_lastEngine = e;
for (int i=0; i<e->stateCount(); i++){
@@ -103,11 +123,11 @@ bool QSGSpriteGoalAffector::affectParticle(QSGParticleData *d, qreal dt)
QSGStochasticEngine *engine = 0;
if (!m_systemStates){
//TODO: Affect all engines
- foreach (QSGParticlePainter *p, m_system->m_groupData[d->group]->painters)
+ foreach (QSGParticlePainter *p, m_system->groupData[d->group]->painters)
if (qobject_cast<QSGImageParticle*>(p))
engine = qobject_cast<QSGImageParticle*>(p)->spriteEngine();
}else{
- engine = m_system->m_stateEngine;
+ engine = m_system->stateEngine;
if (!engine)
m_notUsingEngine = true;
}
@@ -124,7 +144,6 @@ bool QSGSpriteGoalAffector::affectParticle(QSGParticleData *d, qreal dt)
m_system->moveGroups(d, m_goalIdx);
}else if (engine->curState(index) != m_goalIdx){
engine->setGoal(m_goalIdx, index, m_jump);
- emit affected(QPointF(d->curX(), d->curY()));//###Expensive if unconnected? Move to Affector?
return true; //Doesn't affect particle data, but necessary for onceOff
}
return false;
diff --git a/src/declarative/particles/qsgspritegoal_p.h b/src/declarative/particles/qsgspritegoal_p.h
index 043970b90b..7f20b1ed8a 100644
--- a/src/declarative/particles/qsgspritegoal_p.h
+++ b/src/declarative/particles/qsgspritegoal_p.h
@@ -42,6 +42,7 @@
#ifndef SPRITEGOALAFFECTOR_H
#define SPRITEGOALAFFECTOR_H
#include "qsgparticleaffector_p.h"
+#include <QtDeclarative/qdeclarativeinfo.h>
QT_BEGIN_HEADER
@@ -82,7 +83,6 @@ signals:
void jumpChanged(bool arg);
- void affected(const QPointF &pos);
void systemStatesChanged(bool arg);
public slots:
@@ -100,6 +100,8 @@ void setJump(bool arg)
void setSystemStates(bool arg)
{
if (m_systemStates != arg) {
+ //TODO: GroupGoal was added (and this deprecated) Oct 4 - remove it in a few weeks.
+ qmlInfo(this) << "systemStates is deprecated and will be removed soon. Use GroupGoal instead.";
m_systemStates = arg;
emit systemStatesChanged(arg);
}
diff --git a/src/declarative/particles/qsgtrailemitter.cpp b/src/declarative/particles/qsgtrailemitter.cpp
index 51d9875d53..4298908c89 100644
--- a/src/declarative/particles/qsgtrailemitter.cpp
+++ b/src/declarative/particles/qsgtrailemitter.cpp
@@ -91,13 +91,26 @@ QSGTrailEmitter::QSGTrailEmitter(QSGItem *parent) :
\qmlproperty Shape QtQuick.Particles2::TrailEmitter::emitShape
As the area of a TrailEmitter is the area it follows, a separate shape can be provided
- to be the shape it emits out of.
+ to be the shape it emits out of. This shape has width and height specified by emitWidth
+ and emitHeight, and is centered on the followed particle's position.
+
+ The default shape is a filled Rectangle.
*/
/*!
\qmlproperty real QtQuick.Particles2::TrailEmitter::emitWidth
+
+ The width in pixels the emitShape is scaled to. If set to TrailEmitter.ParticleSize,
+ the width will be the current size of the particle being followed.
+
+ Default is 0.
*/
/*!
\qmlproperty real QtQuick.Particles2::TrailEmitter::emitHeight
+
+ The height in pixels the emitShape is scaled to. If set to TrailEmitter.ParticleSize,
+ the height will be the current size of the particle being followed.
+
+ Default is 0.
*/
/*!
\qmlproperty real QtQuick.Particles2::TrailEmitter::emitRatePerParticle
@@ -120,7 +133,7 @@ bool QSGTrailEmitter::isEmitFollowConnected()
void QSGTrailEmitter::recalcParticlesPerSecond(){
if (!m_system)
return;
- m_followCount = m_system->m_groupData[m_system->m_groupIds[m_follow]]->size();
+ m_followCount = m_system->groupData[m_system->groupIds[m_follow]]->size();
if (!m_followCount){
setParticlesPerSecond(1);//XXX: Fix this horrendous hack, needed so they aren't turned off from start (causes crashes - test that when gone you don't crash with 0 PPPS)
}else{
@@ -141,7 +154,7 @@ void QSGTrailEmitter::emitWindow(int timeStamp)
return;
if (!m_enabled && !m_pulseLeft && m_burstQueue.isEmpty())
return;
- if (m_followCount != m_system->m_groupData[m_system->m_groupIds[m_follow]]->size()){
+ if (m_followCount != m_system->groupData[m_system->groupIds[m_follow]]->size()){
qreal oldPPS = m_particlesPerSecond;
recalcParticlesPerSecond();
if (m_particlesPerSecond != oldPPS)
@@ -160,14 +173,15 @@ void QSGTrailEmitter::emitWindow(int timeStamp)
qreal time = timeStamp / 1000.;
qreal particleRatio = 1. / m_particlesPerParticlePerSecond;
qreal pt;
+ qreal maxLife = (m_particleDuration + m_particleDurationVariation)/1000.0;
//Have to map it into this system, because particlesystem automaps it back
QPointF offset = m_system->mapFromItem(this, QPointF(0, 0));
qreal sizeAtEnd = m_particleEndSize >= 0 ? m_particleEndSize : m_particleSize;
- int gId = m_system->m_groupIds[m_follow];
- int gId2 = m_system->m_groupIds[m_group];
- foreach (QSGParticleData *d, m_system->m_groupData[gId]->data){
+ int gId = m_system->groupIds[m_follow];
+ int gId2 = m_system->groupIds[m_group];
+ foreach (QSGParticleData *d, m_system->groupData[gId]->data){
if (!d || !d->stillAlive()){
m_lastEmission[d->index] = time; //Should only start emitting when it returns to life
continue;
@@ -175,6 +189,8 @@ void QSGTrailEmitter::emitWindow(int timeStamp)
pt = m_lastEmission[d->index];
if (pt < d->t)
pt = d->t;
+ if (pt + maxLife < time)//We missed so much, that we should skip emiting particles that are dead by now
+ pt = time - maxLife;
if ((width() || height()) && !effectiveExtruder()->contains(QRectF(offset.x(), offset.y(), width(), height()),QPointF(d->curX(), d->curY()))){
m_lastEmission[d->index] = time;//jump over this time period without emitting, because it's outside
@@ -199,17 +215,12 @@ void QSGTrailEmitter::emitWindow(int timeStamp)
// Note that burst location doesn't get used for follow emitter
qreal followT = pt - d->t;
qreal followT2 = followT * followT * 0.5;
- //qreal sizeOffset = d->size/2;//TODO: Current size? As an option
- //TODO: Set variations
+ qreal eW = m_emitterXVariation < 0 ? d->curSize() : m_emitterXVariation;
+ qreal eH = m_emitterYVariation < 0 ? d->curSize() : m_emitterYVariation;
//Subtract offset, because PS expects this in emitter coordinates
- QRectF boundsRect(d->x - offset.x() + d->vx * followT + d->ax * followT2 - m_emitterXVariation/2,
- d->y - offset.y() + d->vy * followT + d->ay * followT2 - m_emitterYVariation/2,
- m_emitterXVariation,
- m_emitterYVariation);
- // QRectF boundsRect(d->x + d->vx * followT + d->ax * followT2 + offset.x() - sizeOffset,
- // d->y + d->vy * followT + d->ay * followT2 + offset.y() - sizeOffset,
- // sizeOffset*2,
- // sizeOffset*2);
+ QRectF boundsRect(d->x - offset.x() + d->vx * followT + d->ax * followT2 - eW/2,
+ d->y - offset.y() + d->vy * followT + d->ay * followT2 - eH/2,
+ eW, eH);
QSGParticleExtruder* effectiveEmissionExtruder = m_emissionExtruder ? m_emissionExtruder : m_defaultEmissionExtruder;
const QPointF &newPos = effectiveEmissionExtruder->extrude(boundsRect);
diff --git a/src/declarative/particles/qsgtrailemitter_p.h b/src/declarative/particles/qsgtrailemitter_p.h
index e0103afdc0..255dd85cef 100644
--- a/src/declarative/particles/qsgtrailemitter_p.h
+++ b/src/declarative/particles/qsgtrailemitter_p.h
@@ -57,13 +57,15 @@ class QSGTrailEmitter : public QSGParticleEmitter
Q_PROPERTY(QString follow READ follow WRITE setFollow NOTIFY followChanged)
Q_PROPERTY(int emitRatePerParticle READ particlesPerParticlePerSecond WRITE setParticlesPerParticlePerSecond NOTIFY particlesPerParticlePerSecondChanged)
- //TODO: Document that TrailEmitter's box is where it follows. It emits in a rect centered on the followed particle
- //TODO: A set of properties that can involve the particle size of the followed
Q_PROPERTY(QSGParticleExtruder* emitShape READ emissonShape WRITE setEmissionShape NOTIFY emissionShapeChanged)
Q_PROPERTY(qreal emitHeight READ emitterYVariation WRITE setEmitterYVariation NOTIFY emitterYVariationChanged)
Q_PROPERTY(qreal emitWidth READ emitterXVariation WRITE setEmitterXVariation NOTIFY emitterXVariationChanged)
+ Q_ENUMS(EmitSize)
public:
+ enum EmitSize {
+ ParticleSize = -2//Anything less than 0 will do
+ };
explicit QSGTrailEmitter(QSGItem *parent = 0);
virtual void emitWindow(int timeStamp);
virtual void reset();
diff --git a/src/declarative/particles/qsgturbulence.cpp b/src/declarative/particles/qsgturbulence.cpp
index ac1306bd82..30d36cccb9 100644
--- a/src/declarative/particles/qsgturbulence.cpp
+++ b/src/declarative/particles/qsgturbulence.cpp
@@ -140,7 +140,7 @@ void QSGTurbulenceAffector::initializeGrid()
if (!m_noiseSource.isEmpty())
image = QImage(m_noiseSource.toLocalFile()).scaled(QSize(m_gridSize, m_gridSize));
if (image.isNull())
- image = QImage(":defaultshaders/noise.png").scaled(QSize(m_gridSize, m_gridSize));
+ image = QImage(QStringLiteral(":particleresources/noise.png")).scaled(QSize(m_gridSize, m_gridSize));
for (int i=0; i<m_gridSize; i++)
for (int j=0; j<m_gridSize; j++)
@@ -185,8 +185,8 @@ void QSGTurbulenceAffector::affectSystem(qreal dt)
updateOffsets();//### Needed if an ancestor is transformed.
QRect boundsRect(0,0,m_gridSize,m_gridSize);
- foreach (QSGParticleGroupData *gd, m_system->m_groupData){
- if (!activeGroup(m_system->m_groupData.key(gd)))
+ foreach (QSGParticleGroupData *gd, m_system->groupData){
+ if (!activeGroup(m_system->groupData.key(gd)))
continue;
foreach (QSGParticleData *d, gd->data){
if (!shouldAffect(d))
diff --git a/src/declarative/qml/ftw/ftw.pri b/src/declarative/qml/ftw/ftw.pri
index d6e7df53b2..c7750468d9 100644
--- a/src/declarative/qml/ftw/ftw.pri
+++ b/src/declarative/qml/ftw/ftw.pri
@@ -1,9 +1,6 @@
-INCLUDEPATH += $$PWD
-
HEADERS += \
$$PWD/qbitfield_p.h \
$$PWD/qintrusivelist_p.h \
- $$PWD/qmetaobjectbuilder_p.h \
$$PWD/qpodvector_p.h \
$$PWD/qhashedstring_p.h \
$$PWD/qdeclarativerefcount_p.h \
@@ -11,12 +8,14 @@ HEADERS += \
$$PWD/qfieldlist_p.h \
$$PWD/qfastmetabuilder_p.h \
$$PWD/qhashfield_p.h \
+ $$PWD/qdeclarativethread_p.h \
+ $$PWD/qfinitestack_p.h \
+ $$PWD/qrecursionwatcher_p.h \
SOURCES += \
$$PWD/qintrusivelist.cpp \
- $$PWD/qmetaobjectbuilder.cpp \
$$PWD/qhashedstring.cpp \
- $$PWD/qdeclarativerefcount.cpp \
$$PWD/qdeclarativepool.cpp \
$$PWD/qfastmetabuilder.cpp \
+ $$PWD/qdeclarativethread.cpp \
diff --git a/src/declarative/qml/ftw/qdeclarativerefcount_p.h b/src/declarative/qml/ftw/qdeclarativerefcount_p.h
index 381327098c..b9b32b24ac 100644
--- a/src/declarative/qml/ftw/qdeclarativerefcount_p.h
+++ b/src/declarative/qml/ftw/qdeclarativerefcount_p.h
@@ -54,6 +54,7 @@
//
#include <QtCore/qglobal.h>
+#include <QtCore/qatomic.h>
QT_BEGIN_HEADER
@@ -61,16 +62,19 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
-class Q_DECLARATIVE_EXPORT QDeclarativeRefCount
+class QDeclarativeRefCount
{
public:
- QDeclarativeRefCount();
- virtual ~QDeclarativeRefCount();
- void addref();
- void release();
+ inline QDeclarativeRefCount();
+ inline virtual ~QDeclarativeRefCount();
+ inline void addref();
+ inline void release();
+
+protected:
+ inline virtual void destroy();
private:
- int refCount;
+ QAtomicInt refCount;
};
template<class T>
@@ -92,10 +96,40 @@ public:
inline operator T*() const { return o; }
inline T* data() const { return o; }
+ inline QDeclarativeRefPointer<T> &take(T *);
+
private:
T *o;
};
+QDeclarativeRefCount::QDeclarativeRefCount()
+: refCount(1)
+{
+}
+
+QDeclarativeRefCount::~QDeclarativeRefCount()
+{
+ Q_ASSERT(refCount.load() == 0);
+}
+
+void QDeclarativeRefCount::addref()
+{
+ Q_ASSERT(refCount.load() > 0);
+ refCount.ref();
+}
+
+void QDeclarativeRefCount::release()
+{
+ Q_ASSERT(refCount.load() > 0);
+ if (!refCount.deref())
+ destroy();
+}
+
+void QDeclarativeRefCount::destroy()
+{
+ delete this;
+}
+
template<class T>
QDeclarativeRefPointer<T>::QDeclarativeRefPointer()
: o(0)
@@ -140,6 +174,18 @@ QDeclarativeRefPointer<T> &QDeclarativeRefPointer<T>::operator=(T *other)
return *this;
}
+/*!
+Takes ownership of \a other. take() does *not* add a reference, as it assumes ownership
+of the callers reference of other.
+*/
+template<class T>
+QDeclarativeRefPointer<T> &QDeclarativeRefPointer<T>::take(T *other)
+{
+ if (o) o->release();
+ o = other;
+ return *this;
+}
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/declarative/qml/ftw/qdeclarativethread.cpp b/src/declarative/qml/ftw/qdeclarativethread.cpp
new file mode 100644
index 0000000000..4a21c90bf1
--- /dev/null
+++ b/src/declarative/qml/ftw/qdeclarativethread.cpp
@@ -0,0 +1,359 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativethread_p.h"
+
+#include <private/qfieldlist_p.h>
+
+#include <QtCore/qmutex.h>
+#include <QtCore/qthread.h>
+#include <QtCore/qcoreevent.h>
+#include <QtCore/qwaitcondition.h>
+#include <QtCore/qcoreapplication.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeThreadPrivate : public QThread
+{
+public:
+ QDeclarativeThreadPrivate(QDeclarativeThread *);
+ QDeclarativeThread *q;
+
+ virtual void run();
+
+ inline void lock() { _mutex.lock(); }
+ inline void unlock() { _mutex.unlock(); }
+ inline void wait() { _wait.wait(&_mutex); }
+ inline void wakeOne() { _wait.wakeOne(); }
+ inline void wakeAll() { _wait.wakeAll(); }
+
+ quint32 m_threadProcessing:1; // Set when the thread is processing messages
+ quint32 m_mainProcessing:1; // Set when the main thread is processing messages
+ quint32 m_shutdown:1; // Set by main thread to request a shutdown
+ quint32 m_mainThreadWaiting:1; // Set by main thread if it is waiting for the message queue to empty
+
+ typedef QFieldList<QDeclarativeThread::Message, &QDeclarativeThread::Message::next> MessageList;
+ MessageList threadList;
+ MessageList mainList;
+
+ QDeclarativeThread::Message *mainSync;
+
+ void triggerMainEvent();
+ void triggerThreadEvent();
+
+ void mainEvent();
+ void threadEvent();
+
+protected:
+ virtual bool event(QEvent *);
+
+private:
+ struct MainObject : public QObject {
+ MainObject(QDeclarativeThreadPrivate *p);
+ virtual bool event(QEvent *e);
+ QDeclarativeThreadPrivate *p;
+ };
+ MainObject m_mainObject;
+
+ QMutex _mutex;
+ QWaitCondition _wait;
+};
+
+QDeclarativeThreadPrivate::MainObject::MainObject(QDeclarativeThreadPrivate *p)
+: p(p)
+{
+}
+
+// Trigger mainEvent in main thread. Must be called from thread.
+void QDeclarativeThreadPrivate::triggerMainEvent()
+{
+ Q_ASSERT(q->isThisThread());
+ QCoreApplication::postEvent(&m_mainObject, new QEvent(QEvent::User));
+}
+
+// Trigger even in thread. Must be called from main thread.
+void QDeclarativeThreadPrivate::triggerThreadEvent()
+{
+ Q_ASSERT(!q->isThisThread());
+ QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+}
+
+bool QDeclarativeThreadPrivate::MainObject::event(QEvent *e)
+{
+ if (e->type() == QEvent::User)
+ p->mainEvent();
+ return QObject::event(e);
+}
+
+QDeclarativeThreadPrivate::QDeclarativeThreadPrivate(QDeclarativeThread *q)
+: q(q), m_threadProcessing(false), m_mainProcessing(false), m_shutdown(false),
+ m_mainThreadWaiting(false), mainSync(0), m_mainObject(this)
+{
+}
+
+bool QDeclarativeThreadPrivate::event(QEvent *e)
+{
+ if (e->type() == QEvent::User)
+ threadEvent();
+ return QThread::event(e);
+}
+
+void QDeclarativeThreadPrivate::run()
+{
+ lock();
+
+ wakeOne();
+
+ unlock();
+
+ q->startupThread();
+ exec();
+}
+
+void QDeclarativeThreadPrivate::mainEvent()
+{
+ lock();
+
+ m_mainProcessing = true;
+
+ while (!mainList.isEmpty() || mainSync) {
+ bool isSync = mainSync != 0;
+ QDeclarativeThread::Message *message = isSync?mainSync:mainList.takeFirst();
+ unlock();
+
+ message->call(q);
+ delete message;
+
+ lock();
+
+ if (isSync) {
+ mainSync = 0;
+ wakeOne();
+ }
+ }
+
+ m_mainProcessing = false;
+
+ unlock();
+}
+
+void QDeclarativeThreadPrivate::threadEvent()
+{
+ lock();
+
+ if (m_shutdown) {
+ quit();
+ wakeOne();
+ unlock();
+ q->shutdownThread();
+ } else {
+ m_threadProcessing = true;
+
+ while (!threadList.isEmpty()) {
+ QDeclarativeThread::Message *message = threadList.first();
+
+ unlock();
+
+ message->call(q);
+
+ lock();
+
+ delete threadList.takeFirst();
+ }
+
+ wakeOne();
+
+ m_threadProcessing = false;
+
+ unlock();
+ }
+}
+
+QDeclarativeThread::QDeclarativeThread()
+: d(new QDeclarativeThreadPrivate(this))
+{
+ d->lock();
+ d->start();
+ d->wait();
+ d->unlock();
+ d->moveToThread(d);
+
+}
+
+QDeclarativeThread::~QDeclarativeThread()
+{
+ delete d;
+}
+
+void QDeclarativeThread::shutdown()
+{
+ d->lock();
+ Q_ASSERT(!d->m_shutdown);
+ d->m_shutdown = true;
+ if (d->threadList.isEmpty() && d->m_threadProcessing == false)
+ d->triggerThreadEvent();
+ d->wait();
+ d->unlock();
+ d->QThread::wait();
+}
+
+void QDeclarativeThread::lock()
+{
+ d->lock();
+}
+
+void QDeclarativeThread::unlock()
+{
+ d->unlock();
+}
+
+void QDeclarativeThread::wakeOne()
+{
+ d->wakeOne();
+}
+
+void QDeclarativeThread::wakeAll()
+{
+ d->wakeAll();
+}
+
+void QDeclarativeThread::wait()
+{
+ d->wait();
+}
+
+bool QDeclarativeThread::isThisThread() const
+{
+ return QThread::currentThread() == d;
+}
+
+QThread *QDeclarativeThread::thread() const
+{
+ return const_cast<QThread *>(static_cast<const QThread *>(d));
+}
+
+// Called when the thread starts. Do startup stuff in here.
+void QDeclarativeThread::startupThread()
+{
+}
+
+// Called when the thread shuts down. Do cleanup in here.
+void QDeclarativeThread::shutdownThread()
+{
+}
+
+void QDeclarativeThread::internalCallMethodInThread(Message *message)
+{
+ Q_ASSERT(!isThisThread());
+ d->lock();
+ Q_ASSERT(d->m_mainThreadWaiting == false);
+
+ bool wasEmpty = d->threadList.isEmpty();
+ d->threadList.append(message);
+ if (wasEmpty && d->m_threadProcessing == false)
+ d->triggerThreadEvent();
+
+ d->m_mainThreadWaiting = true;
+
+ do {
+ if (d->mainSync) {
+ QDeclarativeThread::Message *message = d->mainSync;
+ unlock();
+ message->call(this);
+ delete message;
+ lock();
+ d->mainSync = 0;
+ wakeOne();
+ } else {
+ d->wait();
+ }
+ } while (d->mainSync || !d->threadList.isEmpty());
+
+ d->m_mainThreadWaiting = false;
+ d->unlock();
+}
+
+void QDeclarativeThread::internalCallMethodInMain(Message *message)
+{
+ Q_ASSERT(isThisThread());
+
+ d->lock();
+
+ Q_ASSERT(d->mainSync == 0);
+ d->mainSync = message;
+
+ if (d->m_mainThreadWaiting) {
+ d->wakeOne();
+ } else if (d->m_mainProcessing) {
+ // Do nothing - it is already looping
+ } else {
+ d->triggerMainEvent();
+ }
+
+ while (d->mainSync && !d->m_shutdown)
+ d->wait();
+
+ d->unlock();
+}
+
+void QDeclarativeThread::internalPostMethodToThread(Message *message)
+{
+ Q_ASSERT(!isThisThread());
+ d->lock();
+ bool wasEmpty = d->threadList.isEmpty();
+ d->threadList.append(message);
+ if (wasEmpty && d->m_threadProcessing == false)
+ d->triggerThreadEvent();
+ d->unlock();
+}
+
+void QDeclarativeThread::internalPostMethodToMain(Message *message)
+{
+ Q_ASSERT(isThisThread());
+ d->lock();
+ bool wasEmpty = d->mainList.isEmpty();
+ d->mainList.append(message);
+ if (wasEmpty && d->m_mainProcessing == false)
+ d->triggerMainEvent();
+ d->unlock();
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/ftw/qdeclarativethread_p.h b/src/declarative/qml/ftw/qdeclarativethread_p.h
new file mode 100644
index 0000000000..2f5815568e
--- /dev/null
+++ b/src/declarative/qml/ftw/qdeclarativethread_p.h
@@ -0,0 +1,318 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVETHREAD_P_H
+#define QDECLARATIVETHREAD_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#include <QtCore/qglobal.h>
+
+#include <private/qintrusivelist_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QThread;
+
+class QDeclarativeThreadPrivate;
+class QDeclarativeThread
+{
+public:
+ QDeclarativeThread();
+ virtual ~QDeclarativeThread();
+ void shutdown();
+
+ void lock();
+ void unlock();
+ void wakeOne();
+ void wakeAll();
+ void wait();
+
+ QThread *thread() const;
+ bool isThisThread() const;
+
+ // Synchronously invoke a method in the thread
+ template<class O>
+ inline void callMethodInThread(void (O::*Member)());
+ template<typename T, class V, class O>
+ inline void callMethodInThread(void (O::*Member)(V), const T &);
+ template<typename T, typename T2, class V, class V2, class O>
+ inline void callMethodInThread(void (O::*Member)(V, V2), const T &, const T2 &);
+
+ // Synchronously invoke a method in the main thread. If the main thread is
+ // blocked in a callMethodInThread() call, the call is made from within that
+ // call.
+ template<class O>
+ inline void callMethodInMain(void (O::*Member)());
+ template<typename T, class V, class O>
+ inline void callMethodInMain(void (O::*Member)(V), const T &);
+ template<typename T, typename T2, class V, class V2, class O>
+ inline void callMethodInMain(void (O::*Member)(V, V2), const T &, const T2 &);
+
+ // Asynchronously invoke a method in the thread.
+ template<class O>
+ inline void postMethodToThread(void (O::*Member)());
+ template<typename T, class V, class O>
+ inline void postMethodToThread(void (O::*Member)(V), const T &);
+ template<typename T, typename T2, class V, class V2, class O>
+ inline void postMethodToThread(void (O::*Member)(V, V2), const T &, const T2 &);
+
+ // Asynchronously invoke a method in the main thread.
+ template<class O>
+ inline void postMethodToMain(void (O::*Member)());
+ template<typename T, class V, class O>
+ inline void postMethodToMain(void (O::*Member)(V), const T &);
+ template<typename T, typename T2, class V, class V2, class O>
+ inline void postMethodToMain(void (O::*Member)(V, V2), const T &, const T2 &);
+
+protected:
+ virtual void startupThread();
+ virtual void shutdownThread();
+
+private:
+ friend class QDeclarativeThreadPrivate;
+
+ struct Message {
+ Message() : next(0) {}
+ virtual ~Message() {}
+ Message *next;
+ virtual void call(QDeclarativeThread *) = 0;
+ };
+ void internalCallMethodInThread(Message *);
+ void internalCallMethodInMain(Message *);
+ void internalPostMethodToThread(Message *);
+ void internalPostMethodToMain(Message *);
+ QDeclarativeThreadPrivate *d;
+};
+
+template<class O>
+void QDeclarativeThread::callMethodInThread(void (O::*Member)())
+{
+ struct I : public Message {
+ void (O::*Member)();
+ I(void (O::*Member)()) : Member(Member) {}
+ virtual void call(QDeclarativeThread *thread) {
+ O *me = static_cast<O *>(thread);
+ (me->*Member)();
+ }
+ };
+ internalCallMethodInThread(new I(Member));
+}
+
+template<typename T, class V, class O>
+void QDeclarativeThread::callMethodInThread(void (O::*Member)(V), const T &arg)
+{
+ struct I : public Message {
+ void (O::*Member)(V);
+ T arg;
+ I(void (O::*Member)(V), const T &arg) : Member(Member), arg(arg) {}
+ virtual void call(QDeclarativeThread *thread) {
+ O *me = static_cast<O *>(thread);
+ (me->*Member)(arg);
+ }
+ };
+ internalCallMethodInThread(new I(Member, arg));
+}
+
+template<typename T, typename T2, class V, class V2, class O>
+void QDeclarativeThread::callMethodInThread(void (O::*Member)(V, V2), const T &arg, const T2 &arg2)
+{
+ struct I : public Message {
+ void (O::*Member)(V, V2);
+ T arg;
+ T2 arg2;
+ I(void (O::*Member)(V, V2), const T &arg, const T2 &arg2) : Member(Member), arg(arg), arg2(arg2) {}
+ virtual void call(QDeclarativeThread *thread) {
+ O *me = static_cast<O *>(thread);
+ (me->*Member)(arg, arg2);
+ }
+ };
+ internalCallMethodInThread(new I(Member, arg, arg2));
+}
+
+template<class O>
+void QDeclarativeThread::callMethodInMain(void (O::*Member)())
+{
+ struct I : public Message {
+ void (O::*Member)();
+ I(void (O::*Member)()) : Member(Member) {}
+ virtual void call(QDeclarativeThread *thread) {
+ O *me = static_cast<O *>(thread);
+ (me->*Member)();
+ }
+ };
+ internalCallMethodInMain(new I(Member));
+}
+
+template<typename T, class V, class O>
+void QDeclarativeThread::callMethodInMain(void (O::*Member)(V), const T &arg)
+{
+ struct I : public Message {
+ void (O::*Member)(V);
+ T arg;
+ I(void (O::*Member)(V), const T &arg) : Member(Member), arg(arg) {}
+ virtual void call(QDeclarativeThread *thread) {
+ O *me = static_cast<O *>(thread);
+ (me->*Member)(arg);
+ }
+ };
+ internalCallMethodInMain(new I(Member, arg));
+}
+
+template<typename T, typename T2, class V, class V2, class O>
+void QDeclarativeThread::callMethodInMain(void (O::*Member)(V, V2), const T &arg, const T2 &arg2)
+{
+ struct I : public Message {
+ void (O::*Member)(V, V2);
+ T arg;
+ T2 arg2;
+ I(void (O::*Member)(V, V2), const T &arg, const T2 &arg2) : Member(Member), arg(arg), arg2(arg2) {}
+ virtual void call(QDeclarativeThread *thread) {
+ O *me = static_cast<O *>(thread);
+ (me->*Member)(arg, arg2);
+ }
+ };
+ internalCallMethodInMain(new I(Member, arg, arg2));
+}
+
+template<class O>
+void QDeclarativeThread::postMethodToThread(void (O::*Member)())
+{
+ struct I : public Message {
+ void (O::*Member)();
+ I(void (O::*Member)()) : Member(Member) {}
+ virtual void call(QDeclarativeThread *thread) {
+ O *me = static_cast<O *>(thread);
+ (me->*Member)();
+ }
+ };
+ internalPostMethodToThread(new I(Member));
+}
+
+template<typename T, class V, class O>
+void QDeclarativeThread::postMethodToThread(void (O::*Member)(V), const T &arg)
+{
+ struct I : public Message {
+ void (O::*Member)(V);
+ T arg;
+ I(void (O::*Member)(V), const T &arg) : Member(Member), arg(arg) {}
+ virtual void call(QDeclarativeThread *thread) {
+ O *me = static_cast<O *>(thread);
+ (me->*Member)(arg);
+ }
+ };
+ internalPostMethodToThread(new I(Member, arg));
+}
+
+template<typename T, typename T2, class V, class V2, class O>
+void QDeclarativeThread::postMethodToThread(void (O::*Member)(V, V2), const T &arg, const T2 &arg2)
+{
+ struct I : public Message {
+ void (O::*Member)(V, V2);
+ T arg;
+ T2 arg2;
+ I(void (O::*Member)(V, V2), const T &arg, const T2 &arg2) : Member(Member), arg(arg), arg2(arg2) {}
+ virtual void call(QDeclarativeThread *thread) {
+ O *me = static_cast<O *>(thread);
+ (me->*Member)(arg, arg2);
+ }
+ };
+ internalPostMethodToThread(new I(Member, arg, arg2));
+}
+
+template<class O>
+void QDeclarativeThread::postMethodToMain(void (O::*Member)())
+{
+ struct I : public Message {
+ void (O::*Member)();
+ I(void (O::*Member)()) : Member(Member) {}
+ virtual void call(QDeclarativeThread *thread) {
+ O *me = static_cast<O *>(thread);
+ (me->*Member)();
+ }
+ };
+ internalPostMethodToMain(new I(Member));
+}
+
+template<typename T, class V, class O>
+void QDeclarativeThread::postMethodToMain(void (O::*Member)(V), const T &arg)
+{
+ struct I : public Message {
+ void (O::*Member)(V);
+ T arg;
+ I(void (O::*Member)(V), const T &arg) : Member(Member), arg(arg) {}
+ virtual void call(QDeclarativeThread *thread) {
+ O *me = static_cast<O *>(thread);
+ (me->*Member)(arg);
+ }
+ };
+ internalPostMethodToMain(new I(Member, arg));
+}
+
+template<typename T, typename T2, class V, class V2, class O>
+void QDeclarativeThread::postMethodToMain(void (O::*Member)(V, V2), const T &arg, const T2 &arg2)
+{
+ struct I : public Message {
+ void (O::*Member)(V, V2);
+ T arg;
+ T2 arg2;
+ I(void (O::*Member)(V, V2), const T &arg, const T2 &arg2) : Member(Member), arg(arg), arg2(arg2) {}
+ virtual void call(QDeclarativeThread *thread) {
+ O *me = static_cast<O *>(thread);
+ (me->*Member)(arg, arg2);
+ }
+ };
+ internalPostMethodToMain(new I(Member, arg, arg2));
+}
+
+QT_END_NAMESPACE
+
+#endif // QDECLARATIVETHREAD_P_H
diff --git a/src/declarative/qml/ftw/qfieldlist_p.h b/src/declarative/qml/ftw/qfieldlist_p.h
index ff6b89b96f..f0efd16a20 100644
--- a/src/declarative/qml/ftw/qfieldlist_p.h
+++ b/src/declarative/qml/ftw/qfieldlist_p.h
@@ -61,6 +61,8 @@ class QFieldList
public:
inline QFieldList();
inline N *first() const;
+ inline N *takeFirst();
+
inline void append(N *);
inline void prepend(N *);
@@ -73,6 +75,8 @@ public:
inline void prepend(QFieldList<N, nextMember> &);
inline void insertAfter(N *, QFieldList<N, nextMember> &);
+ inline void copyAndClear(QFieldList<N, nextMember> &);
+
static inline N *next(N *v);
private:
@@ -94,6 +98,21 @@ N *QFieldList<N, nextMember>::first() const
}
template<class N, N *N::*nextMember>
+N *QFieldList<N, nextMember>::takeFirst()
+{
+ N *value = _first;
+ if (value) {
+ _first = next(value);
+ if (_last == value) {
+ Q_ASSERT(_first == 0);
+ _last = 0;
+ }
+ --_count;
+ }
+ return value;
+}
+
+template<class N, N *N::*nextMember>
void QFieldList<N, nextMember>::append(N *v)
{
Q_ASSERT(v->*nextMember == 0);
@@ -207,4 +226,14 @@ void QFieldList<N, nextMember>::insertAfter(N *after, QFieldList<N, nextMember>
}
}
+template<class N, N *N::*nextMember>
+void QFieldList<N, nextMember>::copyAndClear(QFieldList<N, nextMember> &o)
+{
+ _first = o._first;
+ _last = o._last;
+ _count = o._count;
+ o._first = o._last = 0;
+ o._count = 0;
+}
+
#endif // QFIELDLIST_P_H
diff --git a/src/declarative/qml/ftw/qfinitestack_p.h b/src/declarative/qml/ftw/qfinitestack_p.h
new file mode 100644
index 0000000000..de9d833762
--- /dev/null
+++ b/src/declarative/qml/ftw/qfinitestack_p.h
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFINITESTACK_P_H
+#define QFINITESTACK_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+template<typename T>
+struct QFiniteStack {
+ inline QFiniteStack();
+ inline ~QFiniteStack();
+
+ inline void deallocate();
+ inline void allocate(int size);
+
+ inline bool isEmpty() const;
+ inline const T &top() const;
+ inline T &top();
+ inline void push(const T &o);
+ inline T pop();
+ inline int count() const;
+ inline const T &at(int index) const;
+ inline T &operator[](int index);
+private:
+ T *_array;
+ int _alloc;
+ int _size;
+};
+
+template<typename T>
+QFiniteStack<T>::QFiniteStack()
+: _array(0), _alloc(0), _size(0)
+{
+}
+
+template<typename T>
+QFiniteStack<T>::~QFiniteStack()
+{
+ deallocate();
+}
+
+template<typename T>
+bool QFiniteStack<T>::isEmpty() const
+{
+ return _size == 0;
+}
+
+template<typename T>
+const T &QFiniteStack<T>::top() const
+{
+ return _array[_size - 1];
+}
+
+template<typename T>
+T &QFiniteStack<T>::top()
+{
+ return _array[_size - 1];
+}
+
+template<typename T>
+void QFiniteStack<T>::push(const T &o)
+{
+ if (QTypeInfo<T>::isComplex) {
+ new (_array + _size++) T(o);
+ } else {
+ _array[_size++] = o;
+ }
+}
+
+template<typename T>
+T QFiniteStack<T>::pop()
+{
+ --_size;
+
+ if (QTypeInfo<T>::isComplex) {
+ T rv = _array[_size];
+ (_array + _size)->~T();
+ return rv;
+ } else {
+ return _array[_size];
+ }
+}
+
+template<typename T>
+int QFiniteStack<T>::count() const
+{
+ return _size;
+}
+
+template<typename T>
+const T &QFiniteStack<T>::at(int index) const
+{
+ return _array[index];
+}
+
+template<typename T>
+T &QFiniteStack<T>::operator[](int index)
+{
+ return _array[index];
+}
+
+template<typename T>
+void QFiniteStack<T>::allocate(int size)
+{
+ Q_ASSERT(_array == 0);
+ Q_ASSERT(_alloc == 0);
+ Q_ASSERT(_size == 0);
+
+ if (!size) return;
+
+ _array = (T *)qMalloc(size * sizeof(T));
+ _alloc = size;
+}
+
+template<typename T>
+void QFiniteStack<T>::deallocate()
+{
+ if (QTypeInfo<T>::isComplex) {
+ T *i = _array + _size;
+ while (i != _array)
+ (--i)->~T();
+ }
+
+ qFree(_array);
+
+ _array = 0;
+ _alloc = 0;
+ _size = 0;
+}
+
+QT_END_NAMESPACE
+
+#endif // QFINITESTACK_P_H
+
diff --git a/src/declarative/qml/ftw/qmetaobjectbuilder.cpp b/src/declarative/qml/ftw/qmetaobjectbuilder.cpp
deleted file mode 100644
index e52b9e1172..0000000000
--- a/src/declarative/qml/ftw/qmetaobjectbuilder.cpp
+++ /dev/null
@@ -1,2605 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "private/qmetaobjectbuilder_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QMetaObjectBuilder
- \internal
- \brief The QMetaObjectBuilder class supports building QMetaObject objects at runtime.
-
-*/
-
-/*!
- \enum QMetaObjectBuilder::AddMember
- This enum defines which members of QMetaObject should be copied by QMetaObjectBuilder::addMetaObject()
-
- \value ClassName Add the class name.
- \value SuperClass Add the super class.
- \value Methods Add methods that aren't signals or slots.
- \value Signals Add signals.
- \value Slots Add slots.
- \value Constructors Add constructors.
- \value Properties Add properties.
- \value Enumerators Add enumerators.
- \value ClassInfos Add items of class information.
- \value RelatedMetaObjects Add related meta objects.
- \value StaticMetacall Add the static metacall function.
- \value PublicMethods Add public methods (ignored for signals).
- \value ProtectedMethods Add protected methods (ignored for signals).
- \value PrivateMethods All private methods (ignored for signals).
- \value AllMembers Add all members.
- \value AllPrimaryMembers Add everything except the class name, super class, and static metacall function.
-*/
-
-// copied from moc's generator.cpp
-uint qvariant_nameToType(const char* name)
-{
- if (!name)
- return 0;
-
- if (strcmp(name, "QVariant") == 0)
- return 0xffffffff;
- if (strcmp(name, "QCString") == 0)
- return QMetaType::QByteArray;
- if (strcmp(name, "Q_LLONG") == 0)
- return QMetaType::LongLong;
- if (strcmp(name, "Q_ULLONG") == 0)
- return QMetaType::ULongLong;
- if (strcmp(name, "QIconSet") == 0)
- return QMetaType::QIcon;
-
- uint tp = QMetaType::type(name);
- return tp < QMetaType::User ? tp : 0;
-}
-
-/*
- Returns true if the type is a QVariant types.
-*/
-bool isVariantType(const char* type)
-{
- return qvariant_nameToType(type) != 0;
-}
-
-// copied from qmetaobject_p.h
-// do not touch without touching the moc as well
-enum PropertyFlags {
- Invalid = 0x00000000,
- Readable = 0x00000001,
- Writable = 0x00000002,
- Resettable = 0x00000004,
- EnumOrFlag = 0x00000008,
- StdCppSet = 0x00000100,
-// Override = 0x00000200,
- Constant = 0x00000400,
- Final = 0x00000800,
- Designable = 0x00001000,
- ResolveDesignable = 0x00002000,
- Scriptable = 0x00004000,
- ResolveScriptable = 0x00008000,
- Stored = 0x00010000,
- ResolveStored = 0x00020000,
- Editable = 0x00040000,
- ResolveEditable = 0x00080000,
- User = 0x00100000,
- ResolveUser = 0x00200000,
- Notify = 0x00400000,
- Revisioned = 0x00800000
-};
-
-enum MethodFlags {
- AccessPrivate = 0x00,
- AccessProtected = 0x01,
- AccessPublic = 0x02,
- AccessMask = 0x03, //mask
-
- MethodMethod = 0x00,
- MethodSignal = 0x04,
- MethodSlot = 0x08,
- MethodConstructor = 0x0c,
- MethodTypeMask = 0x0c,
-
- MethodCompatibility = 0x10,
- MethodCloned = 0x20,
- MethodScriptable = 0x40,
- MethodRevisioned = 0x80
-};
-
-struct QMetaObjectPrivate
-{
- int revision;
- int className;
- int classInfoCount, classInfoData;
- int methodCount, methodData;
- int propertyCount, propertyData;
- int enumeratorCount, enumeratorData;
- int constructorCount, constructorData;
- int flags;
- int signalCount;
-};
-
-static inline const QMetaObjectPrivate *priv(const uint* data)
-{ return reinterpret_cast<const QMetaObjectPrivate*>(data); }
-// end of copied lines from qmetaobject.cpp
-
-class QMetaMethodBuilderPrivate
-{
-public:
- QMetaMethodBuilderPrivate
- (QMetaMethod::MethodType _methodType,
- const QByteArray& _signature,
- const QByteArray& _returnType = QByteArray(),
- QMetaMethod::Access _access = QMetaMethod::Public)
- : signature(QMetaObject::normalizedSignature(_signature.constData())),
- returnType(QMetaObject::normalizedType(_returnType)),
- attributes(((int)_access) | (((int)_methodType) << 2))
- {
- }
-
- QByteArray signature;
- QByteArray returnType;
- QList<QByteArray> parameterNames;
- QByteArray tag;
- int attributes;
-
- QMetaMethod::MethodType methodType() const
- {
- return (QMetaMethod::MethodType)((attributes & MethodTypeMask) >> 2);
- }
-
- QMetaMethod::Access access() const
- {
- return (QMetaMethod::Access)(attributes & AccessMask);
- }
-
- void setAccess(QMetaMethod::Access value)
- {
- attributes = ((attributes & ~AccessMask) | (int)value);
- }
-};
-
-class QMetaPropertyBuilderPrivate
-{
-public:
- QMetaPropertyBuilderPrivate
- (const QByteArray& _name, const QByteArray& _type, int notifierIdx=-1)
- : name(_name),
- type(QMetaObject::normalizedType(_type.constData())),
- flags(Readable | Writable | Scriptable), notifySignal(-1)
- {
- if (notifierIdx >= 0) {
- flags |= Notify;
- notifySignal = notifierIdx;
- }
- }
-
- QByteArray name;
- QByteArray type;
- int flags;
- int notifySignal;
-
- bool flag(int f) const
- {
- return ((flags & f) != 0);
- }
-
- void setFlag(int f, bool value)
- {
- if (value)
- flags |= f;
- else
- flags &= ~f;
- }
-};
-
-class QMetaEnumBuilderPrivate
-{
-public:
- QMetaEnumBuilderPrivate(const QByteArray& _name)
- : name(_name), isFlag(false)
- {
- }
-
- QByteArray name;
- bool isFlag;
- QList<QByteArray> keys;
- QList<int> values;
-};
-
-class QMetaObjectBuilderPrivate
-{
-public:
- QMetaObjectBuilderPrivate()
- : flags(0)
- {
- superClass = &QObject::staticMetaObject;
- staticMetacallFunction = 0;
- }
-
- QByteArray className;
- const QMetaObject *superClass;
- QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction;
- QList<QMetaMethodBuilderPrivate> methods;
- QList<QMetaMethodBuilderPrivate> constructors;
- QList<QMetaPropertyBuilderPrivate> properties;
- QList<QByteArray> classInfoNames;
- QList<QByteArray> classInfoValues;
- QList<QMetaEnumBuilderPrivate> enumerators;
-#ifdef Q_NO_DATA_RELOCATION
- QList<QMetaObjectAccessor> relatedMetaObjects;
-#else
- QList<const QMetaObject *> relatedMetaObjects;
-#endif
- int flags;
-};
-
-/*!
- Constructs a new QMetaObjectBuilder.
-*/
-QMetaObjectBuilder::QMetaObjectBuilder()
-{
- d = new QMetaObjectBuilderPrivate();
-}
-
-/*!
- Constructs a new QMetaObjectBuilder which is a copy of the
- meta object information in \a prototype. Note: the super class
- contents for \a prototype are not copied, only the immediate
- class that is defined by \a prototype.
-
- The \a members parameter indicates which members of \a prototype
- should be added. The default is AllMembers.
-
- \sa addMetaObject()
-*/
-QMetaObjectBuilder::QMetaObjectBuilder
- (const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members)
-{
- d = new QMetaObjectBuilderPrivate();
- addMetaObject(prototype, members);
-}
-
-/*!
- Destroys this meta object builder.
-*/
-QMetaObjectBuilder::~QMetaObjectBuilder()
-{
- delete d;
-}
-
-/*!
- Returns the name of the class being constructed by this
- meta object builder. The default value is an empty QByteArray.
-
- \sa setClassName(), superClass()
-*/
-QByteArray QMetaObjectBuilder::className() const
-{
- return d->className;
-}
-
-/*!
- Sets the \a name of the class being constructed by this
- meta object builder.
-
- \sa className(), setSuperClass()
-*/
-void QMetaObjectBuilder::setClassName(const QByteArray& name)
-{
- d->className = name;
-}
-
-/*!
- Returns the superclass meta object of the class being constructed
- by this meta object builder. The default value is the meta object
- for QObject.
-
- \sa setSuperClass(), className()
-*/
-const QMetaObject *QMetaObjectBuilder::superClass() const
-{
- return d->superClass;
-}
-
-/*!
- Sets the superclass meta object of the class being constructed
- by this meta object builder to \a meta. The \a meta parameter
- must not be null.
-
- \sa superClass(), setClassName()
-*/
-void QMetaObjectBuilder::setSuperClass(const QMetaObject *meta)
-{
- Q_ASSERT(meta);
- d->superClass = meta;
-}
-
-/*!
- Returns the flags of the class being constructed by this meta object
- builder.
-
- \sa setFlags()
-*/
-QMetaObjectBuilder::MetaObjectFlags QMetaObjectBuilder::flags() const
-{
- return (QMetaObjectBuilder::MetaObjectFlags)d->flags;
-}
-
-/*!
- Sets the \a flags of the class being constructed by this meta object
- builder.
-
- \sa flags()
-*/
-void QMetaObjectBuilder::setFlags(MetaObjectFlags flags)
-{
- d->flags = flags;
-}
-
-/*!
- Returns the number of methods in this class, excluding the number
- of methods in the base class. These include signals and slots
- as well as normal member functions.
-
- \sa addMethod(), method(), removeMethod(), indexOfMethod()
-*/
-int QMetaObjectBuilder::methodCount() const
-{
- return d->methods.size();
-}
-
-/*!
- Returns the number of constructors in this class.
-
- \sa addConstructor(), constructor(), removeConstructor(), indexOfConstructor()
-*/
-int QMetaObjectBuilder::constructorCount() const
-{
- return d->constructors.size();
-}
-
-/*!
- Returns the number of properties in this class, excluding the number
- of properties in the base class.
-
- \sa addProperty(), property(), removeProperty(), indexOfProperty()
-*/
-int QMetaObjectBuilder::propertyCount() const
-{
- return d->properties.size();
-}
-
-/*!
- Returns the number of enumerators in this class, excluding the
- number of enumerators in the base class.
-
- \sa addEnumerator(), enumerator(), removeEnumerator()
- \sa indexOfEnumerator()
-*/
-int QMetaObjectBuilder::enumeratorCount() const
-{
- return d->enumerators.size();
-}
-
-/*!
- Returns the number of items of class information in this class,
- exclusing the number of items of class information in the base class.
-
- \sa addClassInfo(), classInfoName(), classInfoValue(), removeClassInfo()
- \sa indexOfClassInfo()
-*/
-int QMetaObjectBuilder::classInfoCount() const
-{
- return d->classInfoNames.size();
-}
-
-/*!
- Returns the number of related meta objects that are associated
- with this class.
-
- Related meta objects are used when resolving the enumerated type
- associated with a property, where the enumerated type is in a
- different class from the property.
-
- \sa addRelatedMetaObject(), relatedMetaObject()
- \sa removeRelatedMetaObject()
-*/
-int QMetaObjectBuilder::relatedMetaObjectCount() const
-{
- return d->relatedMetaObjects.size();
-}
-
-/*!
- Adds a new public method to this class with the specified \a signature.
- Returns an object that can be used to adjust the other attributes
- of the method. The \a signature will be normalized before it is
- added to the class.
-
- \sa method(), methodCount(), removeMethod(), indexOfMethod()
-*/
-QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QByteArray& signature)
-{
- int index = d->methods.size();
- d->methods.append(QMetaMethodBuilderPrivate(QMetaMethod::Method, signature));
- return QMetaMethodBuilder(this, index);
-}
-
-/*!
- Adds a new public method to this class with the specified
- \a signature and \a returnType. Returns an object that can be
- used to adjust the other attributes of the method. The \a signature
- and \a returnType will be normalized before they are added to
- the class. If \a returnType is empty, then it indicates that
- the method has \c{void} as its return type.
-
- \sa method(), methodCount(), removeMethod(), indexOfMethod()
-*/
-QMetaMethodBuilder QMetaObjectBuilder::addMethod
- (const QByteArray& signature, const QByteArray& returnType)
-{
- int index = d->methods.size();
- d->methods.append(QMetaMethodBuilderPrivate
- (QMetaMethod::Method, signature, returnType));
- return QMetaMethodBuilder(this, index);
-}
-
-/*!
- Adds a new public method to this class that has the same information as
- \a prototype. This is used to clone the methods of an existing
- QMetaObject. Returns an object that can be used to adjust the
- attributes of the method.
-
- This function will detect if \a prototype is an ordinary method,
- signal, slot, or constructor and act accordingly.
-
- \sa method(), methodCount(), removeMethod(), indexOfMethod()
-*/
-QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QMetaMethod& prototype)
-{
- QMetaMethodBuilder method;
- if (prototype.methodType() == QMetaMethod::Method)
- method = addMethod(prototype.signature());
- else if (prototype.methodType() == QMetaMethod::Signal)
- method = addSignal(prototype.signature());
- else if (prototype.methodType() == QMetaMethod::Slot)
- method = addSlot(prototype.signature());
- else if (prototype.methodType() == QMetaMethod::Constructor)
- method = addConstructor(prototype.signature());
- method.setReturnType(prototype.typeName());
- method.setParameterNames(prototype.parameterNames());
- method.setTag(prototype.tag());
- method.setAccess(prototype.access());
- method.setAttributes(prototype.attributes());
- return method;
-}
-
-/*!
- Adds a new public slot to this class with the specified \a signature.
- Returns an object that can be used to adjust the other attributes
- of the slot. The \a signature will be normalized before it is
- added to the class.
-
- \sa addMethod(), addSignal(), indexOfSlot()
-*/
-QMetaMethodBuilder QMetaObjectBuilder::addSlot(const QByteArray& signature)
-{
- int index = d->methods.size();
- d->methods.append(QMetaMethodBuilderPrivate(QMetaMethod::Slot, signature));
- return QMetaMethodBuilder(this, index);
-}
-
-/*!
- Adds a new signal to this class with the specified \a signature.
- Returns an object that can be used to adjust the other attributes
- of the signal. The \a signature will be normalized before it is
- added to the class.
-
- \sa addMethod(), addSlot(), indexOfSignal()
-*/
-QMetaMethodBuilder QMetaObjectBuilder::addSignal(const QByteArray& signature)
-{
- int index = d->methods.size();
- d->methods.append(QMetaMethodBuilderPrivate
- (QMetaMethod::Signal, signature, QByteArray(), QMetaMethod::Protected));
- return QMetaMethodBuilder(this, index);
-}
-
-/*!
- Adds a new constructor to this class with the specified \a signature.
- Returns an object that can be used to adjust the other attributes
- of the constructor. The \a signature will be normalized before it is
- added to the class.
-
- \sa constructor(), constructorCount(), removeConstructor()
- \sa indexOfConstructor()
-*/
-QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QByteArray& signature)
-{
- int index = d->constructors.size();
- d->constructors.append(QMetaMethodBuilderPrivate(QMetaMethod::Constructor, signature));
- return QMetaMethodBuilder(this, -(index + 1));
-}
-
-/*!
- Adds a new constructor to this class that has the same information as
- \a prototype. This is used to clone the constructors of an existing
- QMetaObject. Returns an object that can be used to adjust the
- attributes of the constructor.
-
- This function requires that \a prototype be a constructor.
-
- \sa constructor(), constructorCount(), removeConstructor()
- \sa indexOfConstructor()
-*/
-QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QMetaMethod& prototype)
-{
- Q_ASSERT(prototype.methodType() == QMetaMethod::Constructor);
- QMetaMethodBuilder ctor = addConstructor(prototype.signature());
- ctor.setReturnType(prototype.typeName());
- ctor.setParameterNames(prototype.parameterNames());
- ctor.setTag(prototype.tag());
- ctor.setAccess(prototype.access());
- ctor.setAttributes(prototype.attributes());
- return ctor;
-}
-
-/*!
- Adds a new readable/writable property to this class with the
- specified \a name and \a type. Returns an object that can be used
- to adjust the other attributes of the property. The \a type will
- be normalized before it is added to the class. \a notifierId will
- be registered as the property's \e notify signal.
-
- \sa property(), propertyCount(), removeProperty(), indexOfProperty()
-*/
-QMetaPropertyBuilder QMetaObjectBuilder::addProperty
- (const QByteArray& name, const QByteArray& type, int notifierId)
-{
- int index = d->properties.size();
- d->properties.append(QMetaPropertyBuilderPrivate(name, type, notifierId));
- return QMetaPropertyBuilder(this, index);
-}
-
-/*!
- Adds a new property to this class that has the same information as
- \a prototype. This is used to clone the properties of an existing
- QMetaObject. Returns an object that can be used to adjust the
- attributes of the property.
-
- \sa property(), propertyCount(), removeProperty(), indexOfProperty()
-*/
-QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty& prototype)
-{
- QMetaPropertyBuilder property = addProperty(prototype.name(), prototype.typeName());
- property.setReadable(prototype.isReadable());
- property.setWritable(prototype.isWritable());
- property.setResettable(prototype.isResettable());
- property.setDesignable(prototype.isDesignable());
- property.setScriptable(prototype.isScriptable());
- property.setStored(prototype.isStored());
- property.setEditable(prototype.isEditable());
- property.setUser(prototype.isUser());
- property.setStdCppSet(prototype.hasStdCppSet());
- property.setEnumOrFlag(prototype.isEnumType());
- property.setConstant(prototype.isConstant());
- property.setFinal(prototype.isFinal());
- if (prototype.hasNotifySignal()) {
- // Find an existing method for the notify signal, or add a new one.
- QMetaMethod method = prototype.notifySignal();
- int index = indexOfMethod(method.signature());
- if (index == -1)
- index = addMethod(method).index();
- d->properties[property._index].notifySignal = index;
- d->properties[property._index].setFlag(Notify, true);
- }
- return property;
-}
-
-/*!
- Adds a new enumerator to this class with the specified
- \a name. Returns an object that can be used to adjust
- the other attributes of the enumerator.
-
- \sa enumerator(), enumeratorCount(), removeEnumerator(),
- \sa indexOfEnumerator()
-*/
-QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QByteArray& name)
-{
- int index = d->enumerators.size();
- d->enumerators.append(QMetaEnumBuilderPrivate(name));
- return QMetaEnumBuilder(this, index);
-}
-
-/*!
- Adds a new enumerator to this class that has the same information as
- \a prototype. This is used to clone the enumerators of an existing
- QMetaObject. Returns an object that can be used to adjust the
- attributes of the enumerator.
-
- \sa enumerator(), enumeratorCount(), removeEnumerator(),
- \sa indexOfEnumerator()
-*/
-QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QMetaEnum& prototype)
-{
- QMetaEnumBuilder en = addEnumerator(prototype.name());
- en.setIsFlag(prototype.isFlag());
- int count = prototype.keyCount();
- for (int index = 0; index < count; ++index)
- en.addKey(prototype.key(index), prototype.value(index));
- return en;
-}
-
-/*!
- Adds \a name and \a value as an item of class information to this class.
- Returns the index of the new item of class information.
-
- \sa classInfoCount(), classInfoName(), classInfoValue(), removeClassInfo()
- \sa indexOfClassInfo()
-*/
-int QMetaObjectBuilder::addClassInfo(const QByteArray& name, const QByteArray& value)
-{
- int index = d->classInfoNames.size();
- d->classInfoNames += name;
- d->classInfoValues += value;
- return index;
-}
-
-/*!
- Adds \a meta to this class as a related meta object. Returns
- the index of the new related meta object entry.
-
- Related meta objects are used when resolving the enumerated type
- associated with a property, where the enumerated type is in a
- different class from the property.
-
- \sa relatedMetaObjectCount(), relatedMetaObject()
- \sa removeRelatedMetaObject()
-*/
-#ifdef Q_NO_DATA_RELOCATION
-int QMetaObjectBuilder::addRelatedMetaObject(const QMetaObjectAccessor &meta)
-#else
-int QMetaObjectBuilder::addRelatedMetaObject(const QMetaObject *meta)
-#endif
-{
- Q_ASSERT(meta);
- int index = d->relatedMetaObjects.size();
- d->relatedMetaObjects.append(meta);
- return index;
-}
-
-/*!
- Adds the contents of \a prototype to this meta object builder.
- This function is useful for cloning the contents of an existing QMetaObject.
-
- The \a members parameter indicates which members of \a prototype
- should be added. The default is AllMembers.
-*/
-void QMetaObjectBuilder::addMetaObject
- (const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members)
-{
- Q_ASSERT(prototype);
- int index;
-
- if ((members & ClassName) != 0)
- d->className = prototype->className();
-
- if ((members & SuperClass) != 0)
- d->superClass = prototype->superClass();
-
- if ((members & (Methods | Signals | Slots)) != 0) {
- for (index = prototype->methodOffset(); index < prototype->methodCount(); ++index) {
- QMetaMethod method = prototype->method(index);
- if (method.methodType() != QMetaMethod::Signal) {
- if (method.access() == QMetaMethod::Public && (members & PublicMethods) == 0)
- continue;
- if (method.access() == QMetaMethod::Private && (members & PrivateMethods) == 0)
- continue;
- if (method.access() == QMetaMethod::Protected && (members & ProtectedMethods) == 0)
- continue;
- }
- if (method.methodType() == QMetaMethod::Method && (members & Methods) != 0) {
- addMethod(method);
- } else if (method.methodType() == QMetaMethod::Signal &&
- (members & Signals) != 0) {
- addMethod(method);
- } else if (method.methodType() == QMetaMethod::Slot &&
- (members & Slots) != 0) {
- addMethod(method);
- }
- }
- }
-
- if ((members & Constructors) != 0) {
- for (index = 0; index < prototype->constructorCount(); ++index)
- addConstructor(prototype->constructor(index));
- }
-
- if ((members & Properties) != 0) {
- for (index = prototype->propertyOffset(); index < prototype->propertyCount(); ++index)
- addProperty(prototype->property(index));
- }
-
- if ((members & Enumerators) != 0) {
- for (index = prototype->enumeratorOffset(); index < prototype->enumeratorCount(); ++index)
- addEnumerator(prototype->enumerator(index));
- }
-
- if ((members & ClassInfos) != 0) {
- for (index = prototype->classInfoOffset(); index < prototype->classInfoCount(); ++index) {
- QMetaClassInfo ci = prototype->classInfo(index);
- addClassInfo(ci.name(), ci.value());
- }
- }
-
- if ((members & RelatedMetaObjects) != 0) {
-#ifdef Q_NO_DATA_RELOCATION
- const QMetaObjectAccessor *objects = 0;
-#else
- const QMetaObject **objects;
- if (priv(prototype->d.data)->revision < 2) {
- objects = (const QMetaObject **)(prototype->d.extradata);
- } else
-#endif
- {
- const QMetaObjectExtraData *extra = (const QMetaObjectExtraData *)(prototype->d.extradata);
- if (extra)
- objects = extra->objects;
- else
- objects = 0;
- }
- if (objects) {
- while (*objects != 0) {
- addRelatedMetaObject(*objects);
- ++objects;
- }
- }
- }
-
- if ((members & StaticMetacall) != 0) {
- if (priv(prototype->d.data)->revision >= 6) {
- const QMetaObjectExtraData *extra =
- (const QMetaObjectExtraData *)(prototype->d.extradata);
- if (extra && extra->static_metacall)
- setStaticMetacallFunction(extra->static_metacall);
- }
- }
-}
-
-/*!
- Returns the method at \a index in this class.
-
- \sa methodCount(), addMethod(), removeMethod(), indexOfMethod()
-*/
-QMetaMethodBuilder QMetaObjectBuilder::method(int index) const
-{
- if (index >= 0 && index < d->methods.size())
- return QMetaMethodBuilder(this, index);
- else
- return QMetaMethodBuilder();
-}
-
-/*!
- Returns the constructor at \a index in this class.
-
- \sa methodCount(), addMethod(), removeMethod(), indexOfConstructor()
-*/
-QMetaMethodBuilder QMetaObjectBuilder::constructor(int index) const
-{
- if (index >= 0 && index < d->constructors.size())
- return QMetaMethodBuilder(this, -(index + 1));
- else
- return QMetaMethodBuilder();
-}
-
-/*!
- Returns the property at \a index in this class.
-
- \sa methodCount(), addMethod(), removeMethod(), indexOfProperty()
-*/
-QMetaPropertyBuilder QMetaObjectBuilder::property(int index) const
-{
- if (index >= 0 && index < d->properties.size())
- return QMetaPropertyBuilder(this, index);
- else
- return QMetaPropertyBuilder();
-}
-
-/*!
- Returns the enumerator at \a index in this class.
-
- \sa enumeratorCount(), addEnumerator(), removeEnumerator()
- \sa indexOfEnumerator()
-*/
-QMetaEnumBuilder QMetaObjectBuilder::enumerator(int index) const
-{
- if (index >= 0 && index < d->enumerators.size())
- return QMetaEnumBuilder(this, index);
- else
- return QMetaEnumBuilder();
-}
-
-/*!
- Returns the related meta object at \a index in this class.
-
- Related meta objects are used when resolving the enumerated type
- associated with a property, where the enumerated type is in a
- different class from the property.
-
- \sa relatedMetaObjectCount(), addRelatedMetaObject()
- \sa removeRelatedMetaObject()
-*/
-const QMetaObject *QMetaObjectBuilder::relatedMetaObject(int index) const
-{
- if (index >= 0 && index < d->relatedMetaObjects.size())
-#ifdef Q_NO_DATA_RELOCATION
- return &((*(d->relatedMetaObjects[index]))());
-#else
- return d->relatedMetaObjects[index];
-#endif
- else
- return 0;
-}
-
-/*!
- Returns the name of the item of class information at \a index
- in this class.
-
- \sa classInfoCount(), addClassInfo(), classInfoValue(), removeClassInfo()
- \sa indexOfClassInfo()
-*/
-QByteArray QMetaObjectBuilder::classInfoName(int index) const
-{
- if (index >= 0 && index < d->classInfoNames.size())
- return d->classInfoNames[index];
- else
- return QByteArray();
-}
-
-/*!
- Returns the value of the item of class information at \a index
- in this class.
-
- \sa classInfoCount(), addClassInfo(), classInfoName(), removeClassInfo()
- \sa indexOfClassInfo()
-*/
-QByteArray QMetaObjectBuilder::classInfoValue(int index) const
-{
- if (index >= 0 && index < d->classInfoValues.size())
- return d->classInfoValues[index];
- else
- return QByteArray();
-}
-
-/*!
- Removes the method at \a index from this class. The indices of
- all following methods will be adjusted downwards by 1. If the
- method is registered as a notify signal on a property, then the
- notify signal will be removed from the property.
-
- \sa methodCount(), addMethod(), method(), indexOfMethod()
-*/
-void QMetaObjectBuilder::removeMethod(int index)
-{
- if (index >= 0 && index < d->methods.size()) {
- d->methods.removeAt(index);
- for (int prop = 0; prop < d->properties.size(); ++prop) {
- // Adjust the indices of property notify signal references.
- if (d->properties[prop].notifySignal == index) {
- d->properties[prop].notifySignal = -1;
- d->properties[prop].setFlag(Notify, false);
- } else if (d->properties[prop].notifySignal > index)
- (d->properties[prop].notifySignal)--;
- }
- }
-}
-
-/*!
- Removes the constructor at \a index from this class. The indices of
- all following constructors will be adjusted downwards by 1.
-
- \sa constructorCount(), addConstructor(), constructor()
- \sa indexOfConstructor()
-*/
-void QMetaObjectBuilder::removeConstructor(int index)
-{
- if (index >= 0 && index < d->constructors.size())
- d->constructors.removeAt(index);
-}
-
-/*!
- Removes the property at \a index from this class. The indices of
- all following properties will be adjusted downwards by 1.
-
- \sa propertyCount(), addProperty(), property(), indexOfProperty()
-*/
-void QMetaObjectBuilder::removeProperty(int index)
-{
- if (index >= 0 && index < d->properties.size())
- d->properties.removeAt(index);
-}
-
-/*!
- Removes the enumerator at \a index from this class. The indices of
- all following enumerators will be adjusted downwards by 1.
-
- \sa enumertorCount(), addEnumerator(), enumerator()
- \sa indexOfEnumerator()
-*/
-void QMetaObjectBuilder::removeEnumerator(int index)
-{
- if (index >= 0 && index < d->enumerators.size())
- d->enumerators.removeAt(index);
-}
-
-/*!
- Removes the item of class information at \a index from this class.
- The indices of all following items will be adjusted downwards by 1.
-
- \sa classInfoCount(), addClassInfo(), classInfoName(), classInfoValue()
- \sa indexOfClassInfo()
-*/
-void QMetaObjectBuilder::removeClassInfo(int index)
-{
- if (index >= 0 && index < d->classInfoNames.size()) {
- d->classInfoNames.removeAt(index);
- d->classInfoValues.removeAt(index);
- }
-}
-
-/*!
- Removes the related meta object at \a index from this class.
- The indices of all following related meta objects will be adjusted
- downwards by 1.
-
- Related meta objects are used when resolving the enumerated type
- associated with a property, where the enumerated type is in a
- different class from the property.
-
- \sa relatedMetaObjectCount(), addRelatedMetaObject()
- \sa relatedMetaObject()
-*/
-void QMetaObjectBuilder::removeRelatedMetaObject(int index)
-{
- if (index >= 0 && index < d->relatedMetaObjects.size())
- d->relatedMetaObjects.removeAt(index);
-}
-
-/*!
- Finds a method with the specified \a signature and returns its index;
- otherwise returns -1. The \a signature will be normalized by this method.
-
- \sa method(), methodCount(), addMethod(), removeMethod()
-*/
-int QMetaObjectBuilder::indexOfMethod(const QByteArray& signature)
-{
- QByteArray sig = QMetaObject::normalizedSignature(signature);
- for (int index = 0; index < d->methods.size(); ++index) {
- if (sig == d->methods[index].signature)
- return index;
- }
- return -1;
-}
-
-/*!
- Finds a signal with the specified \a signature and returns its index;
- otherwise returns -1. The \a signature will be normalized by this method.
-
- \sa indexOfMethod(), indexOfSlot()
-*/
-int QMetaObjectBuilder::indexOfSignal(const QByteArray& signature)
-{
- QByteArray sig = QMetaObject::normalizedSignature(signature);
- for (int index = 0; index < d->methods.size(); ++index) {
- if (sig == d->methods[index].signature &&
- d->methods[index].methodType() == QMetaMethod::Signal)
- return index;
- }
- return -1;
-}
-
-/*!
- Finds a slot with the specified \a signature and returns its index;
- otherwise returns -1. The \a signature will be normalized by this method.
-
- \sa indexOfMethod(), indexOfSignal()
-*/
-int QMetaObjectBuilder::indexOfSlot(const QByteArray& signature)
-{
- QByteArray sig = QMetaObject::normalizedSignature(signature);
- for (int index = 0; index < d->methods.size(); ++index) {
- if (sig == d->methods[index].signature &&
- d->methods[index].methodType() == QMetaMethod::Slot)
- return index;
- }
- return -1;
-}
-
-/*!
- Finds a constructor with the specified \a signature and returns its index;
- otherwise returns -1. The \a signature will be normalized by this method.
-
- \sa constructor(), constructorCount(), addConstructor(), removeConstructor()
-*/
-int QMetaObjectBuilder::indexOfConstructor(const QByteArray& signature)
-{
- QByteArray sig = QMetaObject::normalizedSignature(signature);
- for (int index = 0; index < d->constructors.size(); ++index) {
- if (sig == d->constructors[index].signature)
- return index;
- }
- return -1;
-}
-
-/*!
- Finds a property with the specified \a name and returns its index;
- otherwise returns -1.
-
- \sa property(), propertyCount(), addProperty(), removeProperty()
-*/
-int QMetaObjectBuilder::indexOfProperty(const QByteArray& name)
-{
- for (int index = 0; index < d->properties.size(); ++index) {
- if (name == d->properties[index].name)
- return index;
- }
- return -1;
-}
-
-/*!
- Finds an enumerator with the specified \a name and returns its index;
- otherwise returns -1.
-
- \sa enumertor(), enumeratorCount(), addEnumerator(), removeEnumerator()
-*/
-int QMetaObjectBuilder::indexOfEnumerator(const QByteArray& name)
-{
- for (int index = 0; index < d->enumerators.size(); ++index) {
- if (name == d->enumerators[index].name)
- return index;
- }
- return -1;
-}
-
-/*!
- Finds an item of class information with the specified \a name and
- returns its index; otherwise returns -1.
-
- \sa classInfoName(), classInfoValue(), classInfoCount(), addClassInfo()
- \sa removeClassInfo()
-*/
-int QMetaObjectBuilder::indexOfClassInfo(const QByteArray& name)
-{
- for (int index = 0; index < d->classInfoNames.size(); ++index) {
- if (name == d->classInfoNames[index])
- return index;
- }
- return -1;
-}
-
-// Align on a specific type boundary.
-#define ALIGN(size,type) \
- (size) = ((size) + sizeof(type) - 1) & ~(sizeof(type) - 1)
-
-// Build a string into a QMetaObject representation. Returns the
-// position in the string table where the string was placed.
-static int buildString
- (char *buf, char *str, int *offset, const QByteArray& value, int empty)
-{
- if (value.size() == 0 && empty >= 0)
- return empty;
- if (buf) {
- memcpy(str + *offset, value.constData(), value.size());
- str[*offset + value.size()] = '\0';
- }
- int posn = *offset;
- *offset += value.size() + 1;
- return posn;
-}
-
-// Build the parameter array string for a method.
-static QByteArray buildParameterNames
- (const QByteArray& signature, const QList<QByteArray>& parameterNames)
-{
- // If the parameter name list is specified, then concatenate them.
- if (!parameterNames.isEmpty()) {
- QByteArray names;
- bool first = true;
- foreach (const QByteArray &name, parameterNames) {
- if (first)
- first = false;
- else
- names += (char)',';
- names += name;
- }
- return names;
- }
-
- // Count commas in the signature, excluding those inside template arguments.
- int index = signature.indexOf('(');
- if (index < 0)
- return QByteArray();
- ++index;
- if (index >= signature.size())
- return QByteArray();
- if (signature[index] == ')')
- return QByteArray();
- int count = 1;
- int brackets = 0;
- while (index < signature.size() && signature[index] != ',') {
- char ch = signature[index++];
- if (ch == '<')
- ++brackets;
- else if (ch == '>')
- --brackets;
- else if (ch == ',' && brackets <= 0)
- ++count;
- }
- return QByteArray(count - 1, ',');
-}
-
-// Build a QMetaObject in "buf" based on the information in "d".
-// If "buf" is null, then return the number of bytes needed to
-// build the QMetaObject. Returns -1 if the metaobject if
-// relocatable is set, but the metaobject contains extradata.
-static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
- bool relocatable)
-{
- int size = 0;
- int dataIndex;
- int enumIndex;
- int index;
- bool hasNotifySignals = false;
-
- if (relocatable &&
- (d->relatedMetaObjects.size() > 0 || d->staticMetacallFunction))
- return -1;
-
- // Create the main QMetaObject structure at the start of the buffer.
- QMetaObject *meta = reinterpret_cast<QMetaObject *>(buf);
- size += sizeof(QMetaObject);
- ALIGN(size, int);
- if (buf) {
- if (!relocatable) meta->d.superdata = d->superClass;
- meta->d.extradata = 0;
- }
-
- // Populate the QMetaObjectPrivate structure.
- QMetaObjectPrivate *pmeta
- = reinterpret_cast<QMetaObjectPrivate *>(buf + size);
- int pmetaSize = size;
- dataIndex = 14; // Number of fields in the QMetaObjectPrivate.
- for (index = 0; index < d->properties.size(); ++index) {
- if (d->properties[index].notifySignal != -1) {
- hasNotifySignals = true;
- break;
- }
- }
- if (buf) {
- pmeta->revision = 4;
- pmeta->flags = d->flags;
- pmeta->className = 0; // Class name is always the first string.
- //pmeta->signalCount is handled in the "output method loop" as an optimization.
-
- pmeta->classInfoCount = d->classInfoNames.size();
- pmeta->classInfoData = dataIndex;
- dataIndex += 2 * d->classInfoNames.size();
-
- pmeta->methodCount = d->methods.size();
- pmeta->methodData = dataIndex;
- dataIndex += 5 * d->methods.size();
-
- pmeta->propertyCount = d->properties.size();
- pmeta->propertyData = dataIndex;
- dataIndex += 3 * d->properties.size();
- if (hasNotifySignals)
- dataIndex += d->properties.size();
-
- pmeta->enumeratorCount = d->enumerators.size();
- pmeta->enumeratorData = dataIndex;
- dataIndex += 4 * d->enumerators.size();
-
- pmeta->constructorCount = d->constructors.size();
- pmeta->constructorData = dataIndex;
- dataIndex += 5 * d->constructors.size();
- } else {
- dataIndex += 2 * d->classInfoNames.size();
- dataIndex += 5 * d->methods.size();
- dataIndex += 3 * d->properties.size();
- if (hasNotifySignals)
- dataIndex += d->properties.size();
- dataIndex += 4 * d->enumerators.size();
- dataIndex += 5 * d->constructors.size();
- }
-
- // Allocate space for the enumerator key names and values.
- enumIndex = dataIndex;
- for (index = 0; index < d->enumerators.size(); ++index) {
- QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]);
- dataIndex += 2 * enumerator->keys.size();
- }
-
- // Zero terminator at the end of the data offset table.
- ++dataIndex;
-
- // Find the start of the data and string tables.
- int *data = reinterpret_cast<int *>(pmeta);
- size += dataIndex * sizeof(int);
- char *str = reinterpret_cast<char *>(buf + size);
- if (buf) {
- if (relocatable) {
- meta->d.stringdata = reinterpret_cast<const char *>((quintptr)size);
- meta->d.data = reinterpret_cast<uint *>((quintptr)pmetaSize);
- } else {
- meta->d.stringdata = str;
- meta->d.data = reinterpret_cast<uint *>(data);
- }
- }
-
- // Reset the current data position to just past the QMetaObjectPrivate.
- dataIndex = 14;
-
- // Add the class name to the string table.
- int offset = 0;
- buildString(buf, str, &offset, d->className, -1);
-
- // Add a common empty string, which is used to indicate "void"
- // method returns, empty tag strings, etc.
- int empty = buildString(buf, str, &offset, QByteArray(), -1);
-
- // Output the class infos,
- for (index = 0; index < d->classInfoNames.size(); ++index) {
- int name = buildString(buf, str, &offset, d->classInfoNames[index], empty);
- int value = buildString(buf, str, &offset, d->classInfoValues[index], empty);
- if (buf) {
- data[dataIndex] = name;
- data[dataIndex + 1] = value;
- }
- dataIndex += 2;
- }
-
- // Output the methods in the class.
- for (index = 0; index < d->methods.size(); ++index) {
- QMetaMethodBuilderPrivate *method = &(d->methods[index]);
- int sig = buildString(buf, str, &offset, method->signature, empty);
- int params;
- QByteArray names = buildParameterNames
- (method->signature, method->parameterNames);
- params = buildString(buf, str, &offset, names, empty);
- int ret = buildString(buf, str, &offset, method->returnType, empty);
- int tag = buildString(buf, str, &offset, method->tag, empty);
- int attrs = method->attributes;
- if (buf) {
- data[dataIndex] = sig;
- data[dataIndex + 1] = params;
- data[dataIndex + 2] = ret;
- data[dataIndex + 3] = tag;
- data[dataIndex + 4] = attrs;
- if (method->methodType() == QMetaMethod::Signal)
- pmeta->signalCount++;
- }
- dataIndex += 5;
- }
-
- // Output the properties in the class.
- for (index = 0; index < d->properties.size(); ++index) {
- QMetaPropertyBuilderPrivate *prop = &(d->properties[index]);
- int name = buildString(buf, str, &offset, prop->name, empty);
- int type = buildString(buf, str, &offset, prop->type, empty);
- int flags = prop->flags;
-
- if (!isVariantType(prop->type)) {
- flags |= EnumOrFlag;
- } else {
- flags |= qvariant_nameToType(prop->type) << 24;
- }
-
- if (buf) {
- data[dataIndex] = name;
- data[dataIndex + 1] = type;
- data[dataIndex + 2] = flags;
- }
- dataIndex += 3;
- }
- if (hasNotifySignals) {
- for (index = 0; index < d->properties.size(); ++index) {
- QMetaPropertyBuilderPrivate *prop = &(d->properties[index]);
- if (buf) {
- if (prop->notifySignal != -1)
- data[dataIndex] = prop->notifySignal;
- else
- data[dataIndex] = 0;
- }
- ++dataIndex;
- }
- }
-
- // Output the enumerators in the class.
- for (index = 0; index < d->enumerators.size(); ++index) {
- QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]);
- int name = buildString(buf, str, &offset, enumerator->name, empty);
- int isFlag = (int)(enumerator->isFlag);
- int count = enumerator->keys.size();
- int enumOffset = enumIndex;
- if (buf) {
- data[dataIndex] = name;
- data[dataIndex + 1] = isFlag;
- data[dataIndex + 2] = count;
- data[dataIndex + 3] = enumOffset;
- }
- for (int key = 0; key < count; ++key) {
- int keyIndex = buildString(buf, str, &offset, enumerator->keys[key], empty);
- if (buf) {
- data[enumOffset++] = keyIndex;
- data[enumOffset++] = enumerator->values[key];
- }
- }
- dataIndex += 4;
- enumIndex += 2 * count;
- }
-
- // Output the constructors in the class.
- for (index = 0; index < d->constructors.size(); ++index) {
- QMetaMethodBuilderPrivate *method = &(d->constructors[index]);
- int sig = buildString(buf, str, &offset, method->signature, empty);
- int params;
- QByteArray names = buildParameterNames
- (method->signature, method->parameterNames);
- params = buildString(buf, str, &offset, names, empty);
- int ret = buildString(buf, str, &offset, method->returnType, empty);
- int tag = buildString(buf, str, &offset, method->tag, empty);
- int attrs = method->attributes;
- if (buf) {
- data[dataIndex] = sig;
- data[dataIndex + 1] = params;
- data[dataIndex + 2] = ret;
- data[dataIndex + 3] = tag;
- data[dataIndex + 4] = attrs;
- }
- dataIndex += 5;
- }
-
- // One more empty string to act as a terminator.
- buildString(buf, str, &offset, QByteArray(), -1);
- size += offset;
-
- // Output the zero terminator in the data array.
- if (buf)
- data[enumIndex] = 0;
-
- // Create the extradata block if we need one.
- if (d->relatedMetaObjects.size() > 0 || d->staticMetacallFunction) {
- ALIGN(size, QMetaObject **);
- ALIGN(size, QMetaObjectBuilder::StaticMetacallFunction);
- QMetaObjectExtraData *extra =
- reinterpret_cast<QMetaObjectExtraData *>(buf + size);
- size += sizeof(QMetaObjectExtraData);
- ALIGN(size, QMetaObject *);
-#ifdef Q_NO_DATA_RELOCATION
- QMetaObjectAccessor *objects =
- reinterpret_cast<QMetaObjectAccessor *>(buf + size);
-#else
- const QMetaObject **objects =
- reinterpret_cast<const QMetaObject **>(buf + size);
-#endif
- if (buf) {
- if (d->relatedMetaObjects.size() > 0) {
- extra->objects = objects;
- for (index = 0; index < d->relatedMetaObjects.size(); ++index)
- objects[index] = d->relatedMetaObjects[index];
- objects[index] = 0;
- } else {
- extra->objects = 0;
- }
- extra->static_metacall = d->staticMetacallFunction;
- meta->d.extradata = reinterpret_cast<void *>(extra);
- }
- if (d->relatedMetaObjects.size() > 0)
- size += sizeof(QMetaObject *) * (d->relatedMetaObjects.size() + 1);
- }
-
- // Align the final size and return it.
- ALIGN(size, void *);
- return size;
-}
-
-/*!
- Converts this meta object builder into a concrete QMetaObject.
- The return value should be deallocated using qFree() once it
- is no longer needed.
-
- The returned meta object is a snapshot of the state of the
- QMetaObjectBuilder. Any further modifications to the QMetaObjectBuilder
- will not be reflected in previous meta objects returned by
- this method.
-*/
-QMetaObject *QMetaObjectBuilder::toMetaObject() const
-{
- int size = buildMetaObject(d, 0, false);
- char *buf = reinterpret_cast<char *>(qMalloc(size));
- memset(buf, 0, size);
- buildMetaObject(d, buf, false);
- return reinterpret_cast<QMetaObject *>(buf);
-}
-
-/*
- \internal
-
- Converts this meta object builder into relocatable data. This data can
- be stored, copied and later passed to fromRelocatableData() to create a
- concrete QMetaObject.
-
- The data is specific to the architecture on which it was created, but is not
- specific to the process that created it. Not all meta object builder's can
- be converted to data in this way. If \a ok is provided, it will be set to
- true if the conversion succeeds, and false otherwise. If a
- staticMetacallFunction() or any relatedMetaObject()'s are specified the
- conversion to relocatable data will fail.
-*/
-QByteArray QMetaObjectBuilder::toRelocatableData(bool *ok) const
-{
- int size = buildMetaObject(d, 0, true);
- if (size == -1) {
- if (ok) *ok = false;
- return QByteArray();
- }
-
- QByteArray data;
- data.resize(size);
- char *buf = data.data();
- memset(buf, 0, size);
- buildMetaObject(d, buf, true);
- if (ok) *ok = true;
- return data;
-}
-
-/*
- \internal
-
- Sets the \a data returned from toRelocatableData() onto a concrete
- QMetaObject instance, \a output. As the meta object's super class is not
- saved in the relocatable data, it must be passed as \a superClass.
-*/
-void QMetaObjectBuilder::fromRelocatableData(QMetaObject *output,
- const QMetaObject *superclass,
- const QByteArray &data)
-{
- if (!output)
- return;
-
- const char *buf = data.constData();
- const QMetaObject *dataMo = reinterpret_cast<const QMetaObject *>(buf);
-
- quintptr stringdataOffset = (quintptr)dataMo->d.stringdata;
- quintptr dataOffset = (quintptr)dataMo->d.data;
-
- output->d.superdata = superclass;
- output->d.stringdata = buf + stringdataOffset;
- output->d.data = reinterpret_cast<const uint *>(buf + dataOffset);
-}
-
-/*!
- \typedef QMetaObjectBuilder::StaticMetacallFunction
-
- Typedef for static metacall functions. The three parameters are
- the call type value, the constructor index, and the
- array of parameters.
-*/
-
-/*!
- Returns the static metacall function to use to construct objects
- of this class. The default value is null.
-
- \sa setStaticMetacallFunction()
-*/
-QMetaObjectBuilder::StaticMetacallFunction QMetaObjectBuilder::staticMetacallFunction() const
-{
- return d->staticMetacallFunction;
-}
-
-/*!
- Sets the static metacall function to use to construct objects
- of this class to \a value. The default value is null.
-
- \sa staticMetacallFunction()
-*/
-void QMetaObjectBuilder::setStaticMetacallFunction
- (QMetaObjectBuilder::StaticMetacallFunction value)
-{
- d->staticMetacallFunction = value;
-}
-
-#ifndef QT_NO_DATASTREAM
-
-/*!
- Serializes the contents of the meta object builder onto \a stream.
-
- \sa deserialize()
-*/
-void QMetaObjectBuilder::serialize(QDataStream& stream) const
-{
- int index;
-
- // Write the class and super class names.
- stream << d->className;
- if (d->superClass)
- stream << QByteArray(d->superClass->className());
- else
- stream << QByteArray();
-
- // Write the counts for each type of class member.
- stream << d->classInfoNames.size();
- stream << d->methods.size();
- stream << d->properties.size();
- stream << d->enumerators.size();
- stream << d->constructors.size();
- stream << d->relatedMetaObjects.size();
-
- // Write the items of class information.
- for (index = 0; index < d->classInfoNames.size(); ++index) {
- stream << d->classInfoNames[index];
- stream << d->classInfoValues[index];
- }
-
- // Write the methods.
- for (index = 0; index < d->methods.size(); ++index) {
- const QMetaMethodBuilderPrivate *method = &(d->methods[index]);
- stream << method->signature;
- stream << method->returnType;
- stream << method->parameterNames;
- stream << method->tag;
- stream << method->attributes;
- }
-
- // Write the properties.
- for (index = 0; index < d->properties.size(); ++index) {
- const QMetaPropertyBuilderPrivate *property = &(d->properties[index]);
- stream << property->name;
- stream << property->type;
- stream << property->flags;
- stream << property->notifySignal;
- }
-
- // Write the enumerators.
- for (index = 0; index < d->enumerators.size(); ++index) {
- const QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]);
- stream << enumerator->name;
- stream << enumerator->isFlag;
- stream << enumerator->keys;
- stream << enumerator->values;
- }
-
- // Write the constructors.
- for (index = 0; index < d->constructors.size(); ++index) {
- const QMetaMethodBuilderPrivate *method = &(d->constructors[index]);
- stream << method->signature;
- stream << method->returnType;
- stream << method->parameterNames;
- stream << method->tag;
- stream << method->attributes;
- }
-
- // Write the related meta objects.
-#ifdef Q_NO_DATA_RELOCATION
- //### What do we do here?
-#else
- for (index = 0; index < d->relatedMetaObjects.size(); ++index) {
- const QMetaObject *meta = d->relatedMetaObjects[index];
- stream << QByteArray(meta->className());
- }
-#endif
-
- // Add an extra empty QByteArray for additional data in future versions.
- // This should help maintain backwards compatibility, allowing older
- // versions to read newer data.
- stream << QByteArray();
-}
-
-// Resolve a class name using the name reference map.
-static const QMetaObject *resolveClassName
- (const QMap<QByteArray, const QMetaObject *>& references,
- const QByteArray& name)
-{
- if (name == QByteArray("QObject"))
- return &QObject::staticMetaObject;
- else
- return references.value(name, 0);
-}
-
-/*!
- Deserializes a meta object builder from \a stream into
- this meta object builder.
-
- The \a references parameter specifies a mapping from class names
- to QMetaObject instances for resolving the super class name and
- related meta objects in the object that is deserialized.
- The meta object for QObject is implicitly added to \a references
- and does not need to be supplied.
-
- The QDataStream::status() value on \a stream will be set to
- QDataStream::ReadCorruptData if the input data is corrupt.
- The status will be set to QDataStream::ReadPastEnd if the
- input was exhausted before the full meta object was read.
-
- \sa serialize()
-*/
-void QMetaObjectBuilder::deserialize
- (QDataStream& stream,
- const QMap<QByteArray, const QMetaObject *>& references)
-{
- QByteArray name;
- const QMetaObject *cl;
- int index;
-
- // Clear all members in the builder to their default states.
- d->className.clear();
- d->superClass = &QObject::staticMetaObject;
- d->classInfoNames.clear();
- d->classInfoValues.clear();
- d->methods.clear();
- d->properties.clear();
- d->enumerators.clear();
- d->constructors.clear();
- d->relatedMetaObjects.clear();
- d->staticMetacallFunction = 0;
-
- // Read the class and super class names.
- stream >> d->className;
- stream >> name;
- if (name.isEmpty()) {
- d->superClass = 0;
- } else if ((cl = resolveClassName(references, name)) != 0) {
- d->superClass = cl;
- } else {
- stream.setStatus(QDataStream::ReadCorruptData);
- return;
- }
-
- // Read the counts for each type of class member.
- int classInfoCount, methodCount, propertyCount;
- int enumeratorCount, constructorCount, relatedMetaObjectCount;
- stream >> classInfoCount;
- stream >> methodCount;
- stream >> propertyCount;
- stream >> enumeratorCount;
- stream >> constructorCount;
- stream >> relatedMetaObjectCount;
- if (classInfoCount < 0 || methodCount < 0 ||
- propertyCount < 0 || enumeratorCount < 0 ||
- constructorCount < 0 || relatedMetaObjectCount < 0) {
- stream.setStatus(QDataStream::ReadCorruptData);
- return;
- }
-
- // Read the items of class information.
- for (index = 0; index < classInfoCount; ++index) {
- if (stream.status() != QDataStream::Ok)
- return;
- QByteArray value;
- stream >> name;
- stream >> value;
- addClassInfo(name, value);
- }
-
- // Read the member methods.
- for (index = 0; index < methodCount; ++index) {
- if (stream.status() != QDataStream::Ok)
- return;
- stream >> name;
- addMethod(name);
- QMetaMethodBuilderPrivate *method = &(d->methods[index]);
- stream >> method->returnType;
- stream >> method->parameterNames;
- stream >> method->tag;
- stream >> method->attributes;
- if (method->methodType() == QMetaMethod::Constructor) {
- // Cannot add a constructor in this set of methods.
- stream.setStatus(QDataStream::ReadCorruptData);
- return;
- }
- }
-
- // Read the properties.
- for (index = 0; index < propertyCount; ++index) {
- if (stream.status() != QDataStream::Ok)
- return;
- QByteArray type;
- stream >> name;
- stream >> type;
- addProperty(name, type);
- QMetaPropertyBuilderPrivate *property = &(d->properties[index]);
- stream >> property->flags;
- stream >> property->notifySignal;
- if (property->notifySignal < -1 ||
- property->notifySignal >= d->methods.size()) {
- // Notify signal method index is out of range.
- stream.setStatus(QDataStream::ReadCorruptData);
- return;
- }
- if (property->notifySignal >= 0 &&
- d->methods[property->notifySignal].methodType() != QMetaMethod::Signal) {
- // Notify signal method index does not refer to a signal.
- stream.setStatus(QDataStream::ReadCorruptData);
- return;
- }
- }
-
- // Read the enumerators.
- for (index = 0; index < enumeratorCount; ++index) {
- if (stream.status() != QDataStream::Ok)
- return;
- stream >> name;
- addEnumerator(name);
- QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]);
- stream >> enumerator->isFlag;
- stream >> enumerator->keys;
- stream >> enumerator->values;
- if (enumerator->keys.size() != enumerator->values.size()) {
- // Mismatch between number of keys and number of values.
- stream.setStatus(QDataStream::ReadCorruptData);
- return;
- }
- }
-
- // Read the constructor methods.
- for (index = 0; index < constructorCount; ++index) {
- if (stream.status() != QDataStream::Ok)
- return;
- stream >> name;
- addConstructor(name);
- QMetaMethodBuilderPrivate *method = &(d->constructors[index]);
- stream >> method->returnType;
- stream >> method->parameterNames;
- stream >> method->tag;
- stream >> method->attributes;
- if (method->methodType() != QMetaMethod::Constructor) {
- // The type must be Constructor.
- stream.setStatus(QDataStream::ReadCorruptData);
- return;
- }
- }
-
- // Read the related meta objects.
-#ifdef Q_NO_DATA_RELOCATION
- //### What do we do here
-#else
- for (index = 0; index < relatedMetaObjectCount; ++index) {
- if (stream.status() != QDataStream::Ok)
- return;
- stream >> name;
- cl = resolveClassName(references, name);
- if (!cl) {
- stream.setStatus(QDataStream::ReadCorruptData);
- return;
- }
- addRelatedMetaObject(cl);
- }
-#endif
-
- // Read the extra data block, which is reserved for future use.
- stream >> name;
-}
-
-#endif // !QT_NO_DATASTREAM
-
-/*!
- \class QMetaMethodBuilder
- \internal
- \brief The QMetaMethodBuilder class enables modifications to a method definition on a meta object builder.
-*/
-
-QMetaMethodBuilderPrivate *QMetaMethodBuilder::d_func() const
-{
- // Positive indices indicate methods, negative indices indicate constructors.
- if (_mobj && _index >= 0 && _index < _mobj->d->methods.size())
- return &(_mobj->d->methods[_index]);
- else if (_mobj && -_index >= 1 && -_index <= _mobj->d->constructors.size())
- return &(_mobj->d->constructors[(-_index) - 1]);
- else
- return 0;
-}
-
-/*!
- \fn QMetaMethodBuilder::QMetaMethodBuilder()
- \internal
-*/
-
-/*!
- Returns the index of this method within its QMetaObjectBuilder.
-*/
-int QMetaMethodBuilder::index() const
-{
- if (_index >= 0)
- return _index; // Method, signal, or slot
- else
- return (-_index) - 1; // Constructor
-}
-
-/*!
- Returns the type of this method (signal, slot, method, or constructor).
-*/
-QMetaMethod::MethodType QMetaMethodBuilder::methodType() const
-{
- QMetaMethodBuilderPrivate *d = d_func();
- if (d)
- return d->methodType();
- else
- return QMetaMethod::Method;
-}
-
-/*!
- Returns the signature of this method.
-
- \sa parameterNames(), returnType()
-*/
-QByteArray QMetaMethodBuilder::signature() const
-{
- QMetaMethodBuilderPrivate *d = d_func();
- if (d)
- return d->signature;
- else
- return QByteArray();
-}
-
-/*!
- Returns the return type for this method; empty if the method's
- return type is \c{void}.
-
- \sa setReturnType(), signature()
-*/
-QByteArray QMetaMethodBuilder::returnType() const
-{
- QMetaMethodBuilderPrivate *d = d_func();
- if (d)
- return d->returnType;
- else
- return QByteArray();
-}
-
-/*!
- Sets the return type for this method to \a value. If \a value
- is empty, then the method's return type is \c{void}. The \a value
- will be normalized before it is added to the method.
-
- \sa returnType(), signature()
-*/
-void QMetaMethodBuilder::setReturnType(const QByteArray& value)
-{
- QMetaMethodBuilderPrivate *d = d_func();
- if (d)
- d->returnType = QMetaObject::normalizedType(value);
-}
-
-/*!
- Returns the list of parameter names for this method.
-
- \sa setParameterNames()
-*/
-QList<QByteArray> QMetaMethodBuilder::parameterNames() const
-{
- QMetaMethodBuilderPrivate *d = d_func();
- if (d)
- return d->parameterNames;
- else
- return QList<QByteArray>();
-}
-
-/*!
- Sets the list of parameter names for this method to \a value.
-
- \sa parameterNames()
-*/
-void QMetaMethodBuilder::setParameterNames(const QList<QByteArray>& value)
-{
- QMetaMethodBuilderPrivate *d = d_func();
- if (d)
- d->parameterNames = value;
-}
-
-/*!
- Returns the tag associated with this method.
-
- \sa setTag()
-*/
-QByteArray QMetaMethodBuilder::tag() const
-{
- QMetaMethodBuilderPrivate *d = d_func();
- if (d)
- return d->tag;
- else
- return QByteArray();
-}
-
-/*!
- Sets the tag associated with this method to \a value.
-
- \sa setTag()
-*/
-void QMetaMethodBuilder::setTag(const QByteArray& value)
-{
- QMetaMethodBuilderPrivate *d = d_func();
- if (d)
- d->tag = value;
-}
-
-/*!
- Returns the access specification of this method (private, protected,
- or public). The default value is QMetaMethod::Public for methods,
- slots, and constructors. The default value is QMetaMethod::Protected
- for signals.
-
- \sa setAccess()
-*/
-QMetaMethod::Access QMetaMethodBuilder::access() const
-{
- QMetaMethodBuilderPrivate *d = d_func();
- if (d)
- return d->access();
- else
- return QMetaMethod::Public;
-}
-
-/*!
- Sets the access specification of this method (private, protected,
- or public) to \a value. If the method is a signal, this function
- will be ignored.
-
- \sa access()
-*/
-void QMetaMethodBuilder::setAccess(QMetaMethod::Access value)
-{
- QMetaMethodBuilderPrivate *d = d_func();
- if (d && d->methodType() != QMetaMethod::Signal)
- d->setAccess(value);
-}
-
-/*!
- Returns the additional attributes for this method.
-
- \sa setAttributes()
-*/
-int QMetaMethodBuilder::attributes() const
-{
- QMetaMethodBuilderPrivate *d = d_func();
- if (d)
- return (d->attributes >> 4);
- else
- return 0;
-}
-
-/*!
- Sets the additional attributes for this method to \a value.
-
- \sa attributes()
-*/
-void QMetaMethodBuilder::setAttributes(int value)
-{
- QMetaMethodBuilderPrivate *d = d_func();
- if (d)
- d->attributes = ((d->attributes & 0x0f) | (value << 4));
-}
-
-/*!
- \class QMetaPropertyBuilder
- \internal
- \brief The QMetaPropertyBuilder class enables modifications to a property definition on a meta object builder.
-*/
-
-QMetaPropertyBuilderPrivate *QMetaPropertyBuilder::d_func() const
-{
- if (_mobj && _index >= 0 && _index < _mobj->d->properties.size())
- return &(_mobj->d->properties[_index]);
- else
- return 0;
-}
-
-/*!
- \fn QMetaPropertyBuilder::QMetaPropertyBuilder()
- \internal
-*/
-
-/*!
- \fn int QMetaPropertyBuilder::index() const
-
- Returns the index of this property within its QMetaObjectBuilder.
-*/
-
-/*!
- Returns the name associated with this property.
-
- \sa type()
-*/
-QByteArray QMetaPropertyBuilder::name() const
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- return d->name;
- else
- return QByteArray();
-}
-
-/*!
- Returns the type associated with this property.
-
- \sa name()
-*/
-QByteArray QMetaPropertyBuilder::type() const
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- return d->type;
- else
- return QByteArray();
-}
-
-/*!
- Returns true if this property has a notify signal; false otherwise.
-
- \sa notifySignal(), setNotifySignal(), removeNotifySignal()
-*/
-bool QMetaPropertyBuilder::hasNotifySignal() const
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- return d->flag(Notify);
- else
- return false;
-}
-
-/*!
- Returns the notify signal associated with this property.
-
- \sa hasNotifySignal(), setNotifySignal(), removeNotifySignal()
-*/
-QMetaMethodBuilder QMetaPropertyBuilder::notifySignal() const
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d && d->notifySignal >= 0)
- return QMetaMethodBuilder(_mobj, d->notifySignal);
- else
- return QMetaMethodBuilder();
-}
-
-/*!
- Sets the notify signal associated with this property to \a value.
-
- \sa hasNotifySignal(), notifySignal(), removeNotifySignal()
-*/
-void QMetaPropertyBuilder::setNotifySignal(const QMetaMethodBuilder& value)
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d) {
- if (value._mobj) {
- d->notifySignal = value._index;
- d->setFlag(Notify, true);
- } else {
- d->notifySignal = -1;
- d->setFlag(Notify, false);
- }
- }
-}
-
-/*!
- Removes the notify signal from this property.
-
- \sa hasNotifySignal(), notifySignal(), setNotifySignal()
-*/
-void QMetaPropertyBuilder::removeNotifySignal()
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d) {
- d->notifySignal = -1;
- d->setFlag(Notify, false);
- }
-}
-
-/*!
- Returns true if this property is readable; otherwise returns false.
- The default value is true.
-
- \sa setReadable(), isWritable()
-*/
-bool QMetaPropertyBuilder::isReadable() const
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- return d->flag(Readable);
- else
- return false;
-}
-
-/*!
- Returns true if this property is writable; otherwise returns false.
- The default value is true.
-
- \sa setWritable(), isReadable()
-*/
-bool QMetaPropertyBuilder::isWritable() const
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- return d->flag(Writable);
- else
- return false;
-}
-
-/*!
- Returns true if this property can be reset to a default value; otherwise
- returns false. The default value is false.
-
- \sa setResettable()
-*/
-bool QMetaPropertyBuilder::isResettable() const
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- return d->flag(Resettable);
- else
- return false;
-}
-
-/*!
- Returns true if this property is designable; otherwise returns false.
- This default value is false.
-
- \sa setDesignable(), isScriptable(), isStored()
-*/
-bool QMetaPropertyBuilder::isDesignable() const
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- return d->flag(Designable);
- else
- return false;
-}
-
-/*!
- Returns true if the property is scriptable; otherwise returns false.
- This default value is true.
-
- \sa setScriptable(), isDesignable(), isStored()
-*/
-bool QMetaPropertyBuilder::isScriptable() const
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- return d->flag(Scriptable);
- else
- return false;
-}
-
-/*!
- Returns true if the property is stored; otherwise returns false.
- This default value is false.
-
- \sa setStored(), isDesignable(), isScriptable()
-*/
-bool QMetaPropertyBuilder::isStored() const
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- return d->flag(Stored);
- else
- return false;
-}
-
-/*!
- Returns true if the property is editable; otherwise returns false.
- This default value is false.
-
- \sa setEditable(), isDesignable(), isScriptable(), isStored()
-*/
-bool QMetaPropertyBuilder::isEditable() const
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- return d->flag(Editable);
- else
- return false;
-}
-
-/*!
- Returns true if this property is designated as the \c USER
- property, i.e., the one that the user can edit or that is
- significant in some other way. Otherwise it returns
- false. This default value is false.
-
- \sa setUser(), isDesignable(), isScriptable()
-*/
-bool QMetaPropertyBuilder::isUser() const
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- return d->flag(User);
- else
- return false;
-}
-
-/*!
- Returns true if the property has a C++ setter function that
- follows Qt's standard "name" / "setName" pattern. Designer and uic
- query hasStdCppSet() in order to avoid expensive
- QObject::setProperty() calls. All properties in Qt [should] follow
- this pattern. The default value is false.
-
- \sa setStdCppSet()
-*/
-bool QMetaPropertyBuilder::hasStdCppSet() const
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- return d->flag(StdCppSet);
- else
- return false;
-}
-
-/*!
- Returns true if the property is an enumerator or flag type;
- otherwise returns false. This default value is false.
-
- \sa setEnumOrFlag()
-*/
-bool QMetaPropertyBuilder::isEnumOrFlag() const
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- return d->flag(EnumOrFlag);
- else
- return false;
-}
-
-/*!
- Returns true if the property is constant; otherwise returns false.
- The default value is false.
-*/
-bool QMetaPropertyBuilder::isConstant() const
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- return d->flag(Constant);
- else
- return false;
-}
-
-/*!
- Returns true if the property is final; otherwise returns false.
- The default value is false.
-*/
-bool QMetaPropertyBuilder::isFinal() const
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- return d->flag(Final);
- else
- return false;
-}
-
-/*!
- Sets this property to readable if \a value is true.
-
- \sa isReadable(), setWritable()
-*/
-void QMetaPropertyBuilder::setReadable(bool value)
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- d->setFlag(Readable, value);
-}
-
-/*!
- Sets this property to writable if \a value is true.
-
- \sa isWritable(), setReadable()
-*/
-void QMetaPropertyBuilder::setWritable(bool value)
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- d->setFlag(Writable, value);
-}
-
-/*!
- Sets this property to resettable if \a value is true.
-
- \sa isResettable()
-*/
-void QMetaPropertyBuilder::setResettable(bool value)
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- d->setFlag(Resettable, value);
-}
-
-/*!
- Sets this property to designable if \a value is true.
-
- \sa isDesignable(), setScriptable(), setStored()
-*/
-void QMetaPropertyBuilder::setDesignable(bool value)
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- d->setFlag(Designable, value);
-}
-
-/*!
- Sets this property to scriptable if \a value is true.
-
- \sa isScriptable(), setDesignable(), setStored()
-*/
-void QMetaPropertyBuilder::setScriptable(bool value)
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- d->setFlag(Scriptable, value);
-}
-
-/*!
- Sets this property to storable if \a value is true.
-
- \sa isStored(), setDesignable(), setScriptable()
-*/
-void QMetaPropertyBuilder::setStored(bool value)
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- d->setFlag(Stored, value);
-}
-
-/*!
- Sets this property to editable if \a value is true.
-
- \sa isEditable(), setDesignable(), setScriptable(), setStored()
-*/
-void QMetaPropertyBuilder::setEditable(bool value)
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- d->setFlag(Editable, value);
-}
-
-/*!
- Sets the \c USER flag on this property to \a value.
-
- \sa isUser(), setDesignable(), setScriptable()
-*/
-void QMetaPropertyBuilder::setUser(bool value)
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- d->setFlag(User, value);
-}
-
-/*!
- Sets the C++ setter flag on this property to \a value, which is
- true if the property has a C++ setter function that follows Qt's
- standard "name" / "setName" pattern.
-
- \sa hasStdCppSet()
-*/
-void QMetaPropertyBuilder::setStdCppSet(bool value)
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- d->setFlag(StdCppSet, value);
-}
-
-/*!
- Sets this property to be of an enumerator or flag type if
- \a value is true.
-
- \sa isEnumOrFlag()
-*/
-void QMetaPropertyBuilder::setEnumOrFlag(bool value)
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- d->setFlag(EnumOrFlag, value);
-}
-
-/*!
- Sets the \c CONSTANT flag on this property to \a value.
-
- \sa isConstant()
-*/
-void QMetaPropertyBuilder::setConstant(bool value)
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- d->setFlag(Constant, value);
-}
-
-/*!
- Sets the \c FINAL flag on this property to \a value.
-
- \sa isFinal()
-*/
-void QMetaPropertyBuilder::setFinal(bool value)
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- d->setFlag(Final, value);
-}
-
-
-/*!
- \class QMetaEnumBuilder
- \internal
- \brief The QMetaEnumBuilder class enables modifications to an enumerator definition on a meta object builder.
-*/
-
-QMetaEnumBuilderPrivate *QMetaEnumBuilder::d_func() const
-{
- if (_mobj && _index >= 0 && _index < _mobj->d->enumerators.size())
- return &(_mobj->d->enumerators[_index]);
- else
- return 0;
-}
-
-/*!
- \fn QMetaEnumBuilder::QMetaEnumBuilder()
- \internal
-*/
-
-/*!
- \fn int QMetaEnumBuilder::index() const
-
- Returns the index of this enumerator within its QMetaObjectBuilder.
-*/
-
-/*!
- Returns the name of the enumerator (without the scope).
-*/
-QByteArray QMetaEnumBuilder::name() const
-{
- QMetaEnumBuilderPrivate *d = d_func();
- if (d)
- return d->name;
- else
- return QByteArray();
-}
-
-/*!
- Returns true if this enumerator is used as a flag; otherwise returns
- false.
-
- \sa setIsFlag()
-*/
-bool QMetaEnumBuilder::isFlag() const
-{
- QMetaEnumBuilderPrivate *d = d_func();
- if (d)
- return d->isFlag;
- else
- return false;
-}
-
-/*!
- Sets this enumerator to be used as a flag if \a value is true.
-
- \sa isFlag()
-*/
-void QMetaEnumBuilder::setIsFlag(bool value)
-{
- QMetaEnumBuilderPrivate *d = d_func();
- if (d)
- d->isFlag = value;
-}
-
-/*!
- Returns the number of keys.
-
- \sa key(), addKey()
-*/
-int QMetaEnumBuilder::keyCount() const
-{
- QMetaEnumBuilderPrivate *d = d_func();
- if (d)
- return d->keys.size();
- else
- return 0;
-}
-
-/*!
- Returns the key with the given \a index, or an empty QByteArray
- if no such key exists.
-
- \sa keyCount(), addKey(), value()
-*/
-QByteArray QMetaEnumBuilder::key(int index) const
-{
- QMetaEnumBuilderPrivate *d = d_func();
- if (d && index >= 0 && index < d->keys.size())
- return d->keys[index];
- else
- return QByteArray();
-}
-
-/*!
- Returns the value with the given \a index; or returns -1 if there
- is no such value.
-
- \sa keyCount(), addKey(), key()
-*/
-int QMetaEnumBuilder::value(int index) const
-{
- QMetaEnumBuilderPrivate *d = d_func();
- if (d && index >= 0 && index < d->keys.size())
- return d->values[index];
- else
- return -1;
-}
-
-/*!
- Adds a new key called \a name to this enumerator, associated
- with \a value. Returns the index of the new key.
-
- \sa keyCount(), key(), value(), removeKey()
-*/
-int QMetaEnumBuilder::addKey(const QByteArray& name, int value)
-{
- QMetaEnumBuilderPrivate *d = d_func();
- if (d) {
- int index = d->keys.size();
- d->keys += name;
- d->values += value;
- return index;
- } else {
- return -1;
- }
-}
-
-/*!
- Removes the key at \a index from this enumerator.
-
- \sa addKey()
-*/
-void QMetaEnumBuilder::removeKey(int index)
-{
- QMetaEnumBuilderPrivate *d = d_func();
- if (d && index >= 0 && index < d->keys.size()) {
- d->keys.removeAt(index);
- d->values.removeAt(index);
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/qml/ftw/qmetaobjectbuilder_p.h b/src/declarative/qml/ftw/qmetaobjectbuilder_p.h
deleted file mode 100644
index a80ba904b6..0000000000
--- a/src/declarative/qml/ftw/qmetaobjectbuilder_p.h
+++ /dev/null
@@ -1,325 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMETAOBJECTBUILDER_H
-#define QMETAOBJECTBUILDER_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of moc. This header file may change from version to version without notice,
-// or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qobject.h>
-#include <QtCore/qmetaobject.h>
-#include <QtCore/qdatastream.h>
-#include <QtCore/qmap.h>
-
-#include <private/qdeclarativeglobal_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QMetaObjectBuilderPrivate;
-class QMetaMethodBuilder;
-class QMetaMethodBuilderPrivate;
-class QMetaPropertyBuilder;
-class QMetaPropertyBuilderPrivate;
-class QMetaEnumBuilder;
-class QMetaEnumBuilderPrivate;
-
-class Q_DECLARATIVE_PRIVATE_EXPORT QMetaObjectBuilder
-{
-public:
- enum AddMember
- {
- ClassName = 0x00000001,
- SuperClass = 0x00000002,
- Methods = 0x00000004,
- Signals = 0x00000008,
- Slots = 0x00000010,
- Constructors = 0x00000020,
- Properties = 0x00000040,
- Enumerators = 0x00000080,
- ClassInfos = 0x00000100,
- RelatedMetaObjects = 0x00000200,
- StaticMetacall = 0x00000400,
- PublicMethods = 0x00000800,
- ProtectedMethods = 0x00001000,
- PrivateMethods = 0x00002000,
- AllMembers = 0x7FFFFFFF,
- AllPrimaryMembers = 0x7FFFFBFC
- };
- Q_DECLARE_FLAGS(AddMembers, AddMember)
-
- enum MetaObjectFlag {
- DynamicMetaObject = 0x01
- };
- Q_DECLARE_FLAGS(MetaObjectFlags, MetaObjectFlag)
-
- QMetaObjectBuilder();
- explicit QMetaObjectBuilder(const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members = AllMembers);
- virtual ~QMetaObjectBuilder();
-
- QByteArray className() const;
- void setClassName(const QByteArray& name);
-
- const QMetaObject *superClass() const;
- void setSuperClass(const QMetaObject *meta);
-
- MetaObjectFlags flags() const;
- void setFlags(MetaObjectFlags);
-
- int methodCount() const;
- int constructorCount() const;
- int propertyCount() const;
- int enumeratorCount() const;
- int classInfoCount() const;
- int relatedMetaObjectCount() const;
-
- QMetaMethodBuilder addMethod(const QByteArray& signature);
- QMetaMethodBuilder addMethod(const QByteArray& signature, const QByteArray& returnType);
- QMetaMethodBuilder addMethod(const QMetaMethod& prototype);
-
- QMetaMethodBuilder addSlot(const QByteArray& signature);
- QMetaMethodBuilder addSignal(const QByteArray& signature);
-
- QMetaMethodBuilder addConstructor(const QByteArray& signature);
- QMetaMethodBuilder addConstructor(const QMetaMethod& prototype);
-
- QMetaPropertyBuilder addProperty(const QByteArray& name, const QByteArray& type, int notifierId=-1);
- QMetaPropertyBuilder addProperty(const QMetaProperty& prototype);
-
- QMetaEnumBuilder addEnumerator(const QByteArray& name);
- QMetaEnumBuilder addEnumerator(const QMetaEnum& prototype);
-
- int addClassInfo(const QByteArray& name, const QByteArray& value);
-
-#ifdef Q_NO_DATA_RELOCATION
- int addRelatedMetaObject(const QMetaObjectAccessor &meta);
-#else
- int addRelatedMetaObject(const QMetaObject *meta);
-#endif
-
- void addMetaObject(const QMetaObject *prototype, QMetaObjectBuilder::AddMembers members = AllMembers);
-
- QMetaMethodBuilder method(int index) const;
- QMetaMethodBuilder constructor(int index) const;
- QMetaPropertyBuilder property(int index) const;
- QMetaEnumBuilder enumerator(int index) const;
- const QMetaObject *relatedMetaObject(int index) const;
-
- QByteArray classInfoName(int index) const;
- QByteArray classInfoValue(int index) const;
-
- void removeMethod(int index);
- void removeConstructor(int index);
- void removeProperty(int index);
- void removeEnumerator(int index);
- void removeClassInfo(int index);
- void removeRelatedMetaObject(int index);
-
- int indexOfMethod(const QByteArray& signature);
- int indexOfSignal(const QByteArray& signature);
- int indexOfSlot(const QByteArray& signature);
- int indexOfConstructor(const QByteArray& signature);
- int indexOfProperty(const QByteArray& name);
- int indexOfEnumerator(const QByteArray& name);
- int indexOfClassInfo(const QByteArray& name);
-
- typedef QMetaObjectExtraData::StaticMetacallFunction StaticMetacallFunction;
-
- QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction() const;
- void setStaticMetacallFunction(QMetaObjectBuilder::StaticMetacallFunction value);
-
- QMetaObject *toMetaObject() const;
- QByteArray toRelocatableData(bool * = 0) const;
- static void fromRelocatableData(QMetaObject *, const QMetaObject *, const QByteArray &);
-
-#ifndef QT_NO_DATASTREAM
- void serialize(QDataStream& stream) const;
- void deserialize
- (QDataStream& stream,
- const QMap<QByteArray, const QMetaObject *>& references);
-#endif
-
-private:
- Q_DISABLE_COPY(QMetaObjectBuilder)
-
- QMetaObjectBuilderPrivate *d;
-
- friend class QMetaMethodBuilder;
- friend class QMetaPropertyBuilder;
- friend class QMetaEnumBuilder;
-};
-
-class Q_DECLARATIVE_PRIVATE_EXPORT QMetaMethodBuilder
-{
-public:
- QMetaMethodBuilder() : _mobj(0), _index(0) {}
-
- int index() const;
-
- QMetaMethod::MethodType methodType() const;
- QByteArray signature() const;
-
- QByteArray returnType() const;
- void setReturnType(const QByteArray& value);
-
- QList<QByteArray> parameterNames() const;
- void setParameterNames(const QList<QByteArray>& value);
-
- QByteArray tag() const;
- void setTag(const QByteArray& value);
-
- QMetaMethod::Access access() const;
- void setAccess(QMetaMethod::Access value);
-
- int attributes() const;
- void setAttributes(int value);
-
-private:
- const QMetaObjectBuilder *_mobj;
- int _index;
-
- friend class QMetaObjectBuilder;
- friend class QMetaPropertyBuilder;
-
- QMetaMethodBuilder(const QMetaObjectBuilder *mobj, int index)
- : _mobj(mobj), _index(index) {}
-
- QMetaMethodBuilderPrivate *d_func() const;
-};
-
-class Q_DECLARATIVE_PRIVATE_EXPORT QMetaPropertyBuilder
-{
-public:
- QMetaPropertyBuilder() : _mobj(0), _index(0) {}
-
- int index() const { return _index; }
-
- QByteArray name() const;
- QByteArray type() const;
-
- bool hasNotifySignal() const;
- QMetaMethodBuilder notifySignal() const;
- void setNotifySignal(const QMetaMethodBuilder& value);
- void removeNotifySignal();
-
- bool isReadable() const;
- bool isWritable() const;
- bool isResettable() const;
- bool isDesignable() const;
- bool isScriptable() const;
- bool isStored() const;
- bool isEditable() const;
- bool isUser() const;
- bool hasStdCppSet() const;
- bool isEnumOrFlag() const;
- bool isConstant() const;
- bool isFinal() const;
-
- void setReadable(bool value);
- void setWritable(bool value);
- void setResettable(bool value);
- void setDesignable(bool value);
- void setScriptable(bool value);
- void setStored(bool value);
- void setEditable(bool value);
- void setUser(bool value);
- void setStdCppSet(bool value);
- void setEnumOrFlag(bool value);
- void setConstant(bool value);
- void setFinal(bool value);
-
-private:
- const QMetaObjectBuilder *_mobj;
- int _index;
-
- friend class QMetaObjectBuilder;
-
- QMetaPropertyBuilder(const QMetaObjectBuilder *mobj, int index)
- : _mobj(mobj), _index(index) {}
-
- QMetaPropertyBuilderPrivate *d_func() const;
-};
-
-class Q_DECLARATIVE_PRIVATE_EXPORT QMetaEnumBuilder
-{
-public:
- QMetaEnumBuilder() : _mobj(0), _index(0) {}
-
- int index() const { return _index; }
-
- QByteArray name() const;
-
- bool isFlag() const;
- void setIsFlag(bool value);
-
- int keyCount() const;
- QByteArray key(int index) const;
- int value(int index) const;
-
- int addKey(const QByteArray& name, int value);
- void removeKey(int index);
-
-private:
- const QMetaObjectBuilder *_mobj;
- int _index;
-
- friend class QMetaObjectBuilder;
-
- QMetaEnumBuilder(const QMetaObjectBuilder *mobj, int index)
- : _mobj(mobj), _index(index) {}
-
- QMetaEnumBuilderPrivate *d_func() const;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaObjectBuilder::AddMembers)
-Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaObjectBuilder::MetaObjectFlags)
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/declarative/qml/v4/qdeclarativev4bindings_p.h b/src/declarative/qml/ftw/qrecursionwatcher_p.h
index c0345ea3c4..6ad682168f 100644
--- a/src/declarative/qml/v4/qdeclarativev4bindings_p.h
+++ b/src/declarative/qml/ftw/qrecursionwatcher_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QDECLARATIVEV4BINDINGS_P_H
-#define QDECLARATIVEV4BINDINGS_P_H
+#ifndef QRECURSIONWATCHER_P_H
+#define QRECURSIONWATCHER_P_H
//
// W A R N I N G
@@ -53,41 +53,53 @@
// We mean it.
//
-#include "private/qdeclarativeexpression_p.h"
-#include "private/qdeclarativebinding_p.h"
-#include "private/qdeclarativev4instruction_p.h"
-
-QT_BEGIN_HEADER
+#include <QtCore/qglobal.h>
QT_BEGIN_NAMESPACE
-class QDeclarativeV4BindingsPrivate;
-class QDeclarativeV4Bindings : public QObject,
- public QDeclarativeAbstractExpression,
- public QDeclarativeRefCount
-{
+class QRecursionNode;
+class QRecursionNode {
public:
- QDeclarativeV4Bindings(const char *program, QDeclarativeContextData *context,
- QDeclarativeRefCount *);
- virtual ~QDeclarativeV4Bindings();
-
- QDeclarativeAbstractBinding *configBinding(int index, QObject *target, QObject *scope, int property);
-
-#ifdef QML_THREADED_INTERPRETER
- static void **getDecodeInstrTable();
-#endif
-
-protected:
- int qt_metacall(QMetaObject::Call, int, void **);
+ inline QRecursionNode();
+ bool *_r;
+};
+template<class T, QRecursionNode T::*Node>
+class QRecursionWatcher {
+public:
+ inline QRecursionWatcher(T *);
+ inline ~QRecursionWatcher();
+ inline bool hasRecursed() const;
private:
- Q_DISABLE_COPY(QDeclarativeV4Bindings)
- Q_DECLARE_PRIVATE(QDeclarativeV4Bindings)
+ T *_t;
+ bool _r;
};
-QT_END_NAMESPACE
+QRecursionNode::QRecursionNode()
+: _r(0)
+{
+}
+
+template<class T, QRecursionNode T::*Node>
+QRecursionWatcher<T, Node>::QRecursionWatcher(T *t)
+: _t(t), _r(false)
+{
+ if ((_t->*Node)._r) *(_t->*Node)._r = true;
+ (_t->*Node)._r = &_r;
+}
-QT_END_HEADER
+template<class T, QRecursionNode T::*Node>
+QRecursionWatcher<T, Node>::~QRecursionWatcher()
+{
+ if ((_t->*Node)._r == &_r) (_t->*Node)._r = 0;
+}
-#endif // QDECLARATIVEV4BINDINGS_P_H
+template<class T, QRecursionNode T::*Node>
+bool QRecursionWatcher<T, Node>::hasRecursed() const
+{
+ return _r;
+}
+
+QT_END_NAMESPACE
+#endif // QRECURSIONWATCHER_P_H
diff --git a/src/declarative/qml/parser/parser.pri b/src/declarative/qml/parser/parser.pri
index 4f1ff2fd21..3ae0a6d8eb 100644
--- a/src/declarative/qml/parser/parser.pri
+++ b/src/declarative/qml/parser/parser.pri
@@ -1,5 +1,3 @@
-INCLUDEPATH += $$PWD
-
HEADERS += \
$$PWD/qdeclarativejsast_p.h \
$$PWD/qdeclarativejsastfwd_p.h \
diff --git a/src/declarative/qml/parser/qdeclarativejsglobal_p.h b/src/declarative/qml/parser/qdeclarativejsglobal_p.h
index 83b5b95a2f..83ee2d8d27 100644
--- a/src/declarative/qml/parser/qdeclarativejsglobal_p.h
+++ b/src/declarative/qml/parser/qdeclarativejsglobal_p.h
@@ -58,7 +58,12 @@
#else // !QT_CREATOR
# define QT_QML_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
# define QT_QML_END_NAMESPACE QT_END_NAMESPACE
-# define QML_PARSER_EXPORT Q_AUTOTEST_EXPORT
+# if defined(QT_BUILD_QMLDEVTOOLS_LIB) || defined(QT_QMLDEVTOOLS_LIB)
+ // QmlDevTools is a static library
+# define QML_PARSER_EXPORT
+# else
+# define QML_PARSER_EXPORT Q_AUTOTEST_EXPORT
+# endif
#endif // QT_CREATOR
#endif // QDECLARATIVEJSGLOBAL_P_H
diff --git a/src/declarative/qml/qdeclarative.h b/src/declarative/qml/qdeclarative.h
index 312aecbf76..566a420b9d 100644
--- a/src/declarative/qml/qdeclarative.h
+++ b/src/declarative/qml/qdeclarative.h
@@ -480,6 +480,11 @@ inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMi
may be registered into any given namespace (combination of \a uri, \a majorVersion and \a minorVersion).
This function should be used to register a module API provider function which returns a QObject as a module API.
+ A QObject module API must be imported with a qualifier, and that qualifier may be used as
+ the target in a \l Connections element or otherwise used as any other element id would.
+ One exception to this is that a QObject module API property may not be aliased (because the
+ module API qualifier does not identify an object within the same component as any other item).
+
Usage:
\code
// first, define your QObject which provides the functionality.
diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp
index 9a69a6bfd0..531842a695 100644
--- a/src/declarative/qml/qdeclarativebinding.cpp
+++ b/src/declarative/qml/qdeclarativebinding.cpp
@@ -39,18 +39,15 @@
**
****************************************************************************/
-#include "private/qdeclarativebinding_p.h"
-#include "private/qdeclarativebinding_p_p.h"
+#include "qdeclarativebinding_p.h"
+#include "qdeclarativebinding_p_p.h"
#include "qdeclarative.h"
#include "qdeclarativecontext.h"
#include "qdeclarativeinfo.h"
-#include "private/qdeclarativecontext_p.h"
-#include "private/qdeclarativecompiler_p.h"
-#include "private/qdeclarativedata_p.h"
-#include "private/qdeclarativestringconverters_p.h"
-#include "private/qdeclarativestate_p_p.h"
-#include "private/qdeclarativedebugtrace_p.h"
+#include "qdeclarativecompiler_p.h"
+#include "qdeclarativedata_p.h"
+#include <private/qdeclarativedebugtrace_p.h>
#include <QVariant>
#include <QtCore/qdebug.h>
@@ -412,7 +409,7 @@ void QDeclarativeBindingPrivate::printBindingLoopError(QDeclarativeProperty &pro
qmlInfo(prop.object()) << QDeclarativeBinding::tr("Binding loop detected for property \"%1\"").arg(prop.name());
}
-void QDeclarativeBindingPrivate::emitValueChanged()
+void QDeclarativeBindingPrivate::expressionChanged()
{
Q_Q(QDeclarativeBinding);
q->update();
diff --git a/src/declarative/qml/qdeclarativebinding_p.h b/src/declarative/qml/qdeclarativebinding_p.h
index fedd63634b..6f545fc2c6 100644
--- a/src/declarative/qml/qdeclarativebinding_p.h
+++ b/src/declarative/qml/qdeclarativebinding_p.h
@@ -57,7 +57,7 @@
#include "qdeclarativepropertyvaluesource.h"
#include "qdeclarativeexpression.h"
#include "qdeclarativeproperty.h"
-#include "private/qdeclarativeproperty_p.h"
+#include "qdeclarativeproperty_p.h"
#include <QtCore/QObject>
#include <QtCore/QMetaProperty>
@@ -178,7 +178,7 @@ public Q_SLOTS:
protected:
~QDeclarativeBinding();
- void emitValueChanged();
+ void expressionChanged();
private:
Q_DECLARE_PRIVATE(QDeclarativeBinding)
diff --git a/src/declarative/qml/qdeclarativebinding_p_p.h b/src/declarative/qml/qdeclarativebinding_p_p.h
index dc7ec074c8..c704919f78 100644
--- a/src/declarative/qml/qdeclarativebinding_p_p.h
+++ b/src/declarative/qml/qdeclarativebinding_p_p.h
@@ -53,10 +53,10 @@
// We mean it.
//
-#include "private/qdeclarativebinding_p.h"
+#include "qdeclarativebinding_p.h"
#include "qdeclarativeproperty.h"
-#include "private/qdeclarativeexpression_p.h"
+#include "qdeclarativeexpression_p.h"
QT_BEGIN_NAMESPACE
@@ -67,7 +67,7 @@ public:
QDeclarativeBindingPrivate();
~QDeclarativeBindingPrivate();
- virtual void emitValueChanged();
+ virtual void expressionChanged();
static void printBindingLoopError(QDeclarativeProperty &prop);
diff --git a/src/declarative/qml/qdeclarativeboundsignal.cpp b/src/declarative/qml/qdeclarativeboundsignal.cpp
index 1780fb7e28..6bbbb243fc 100644
--- a/src/declarative/qml/qdeclarativeboundsignal.cpp
+++ b/src/declarative/qml/qdeclarativeboundsignal.cpp
@@ -39,18 +39,18 @@
**
****************************************************************************/
-#include "private/qdeclarativeboundsignal_p.h"
+#include "qdeclarativeboundsignal_p.h"
-#include "private/qmetaobjectbuilder_p.h"
-#include "private/qdeclarativeengine_p.h"
-#include "private/qdeclarativeexpression_p.h"
-#include "private/qdeclarativecontext_p.h"
-#include "private/qdeclarativemetatype_p.h"
+#include <private/qmetaobjectbuilder_p.h>
+#include "qdeclarativeengine_p.h"
+#include "qdeclarativeexpression_p.h"
+#include "qdeclarativecontext_p.h"
+#include "qdeclarativemetatype_p.h"
#include "qdeclarative.h"
#include "qdeclarativecontext.h"
-#include "private/qdeclarativeglobal_p.h"
-#include "private/qdeclarativedebugtrace_p.h"
-#include "private/qv8debugservice_p.h"
+#include "qdeclarativeglobal_p.h"
+#include <private/qdeclarativedebugtrace_p.h>
+#include <private/qv8debugservice_p.h>
#include <QtCore/qstringbuilder.h>
#include <QtCore/qdebug.h>
@@ -174,7 +174,7 @@ int QDeclarativeBoundSignal::qt_metacall(QMetaObject::Call c, int id, void **a)
QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::HandlingSignal);
QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::HandlingSignal, QLatin1String(m_signal.signature()) % QLatin1String(": ") % m_expression->expression());
QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::HandlingSignal, m_expression->sourceFile(), m_expression->lineNumber());
- QV8DebugService::instance()->signalEmitted(m_signal.signature());
+ QV8DebugService::instance()->signalEmitted(QString::fromAscii(m_signal.signature()));
}
m_isEvaluating = true;
if (!m_paramsValid) {
diff --git a/src/declarative/qml/qdeclarativecleanup.cpp b/src/declarative/qml/qdeclarativecleanup.cpp
index db671a392a..da7930fd07 100644
--- a/src/declarative/qml/qdeclarativecleanup.cpp
+++ b/src/declarative/qml/qdeclarativecleanup.cpp
@@ -39,9 +39,9 @@
**
****************************************************************************/
-#include "private/qdeclarativecleanup_p.h"
+#include "qdeclarativecleanup_p.h"
-#include "private/qdeclarativeengine_p.h"
+#include "qdeclarativeengine_p.h"
QT_BEGIN_NAMESPACE
@@ -50,22 +50,43 @@ QT_BEGIN_NAMESPACE
\class QDeclarativeCleanup
\brief The QDeclarativeCleanup provides a callback when a QDeclarativeEngine is deleted.
-Any object that needs cleanup to occur before the QDeclarativeEngine's QScriptEngine is
+Any object that needs cleanup to occur before the QDeclarativeEngine's V8 engine is
destroyed should inherit from QDeclarativeCleanup. The clear() virtual method will be
-called by QDeclarativeEngine just before it deletes the QScriptEngine.
+called by QDeclarativeEngine just before it destroys the context.
*/
-/*!
-\internal
+/*
+Create a QDeclarativeCleanup that is not associated with any engine.
+*/
+QDeclarativeCleanup::QDeclarativeCleanup()
+: prev(0), next(0), engine(0)
+{
+}
+
+/*!
Create a QDeclarativeCleanup for \a engine
*/
QDeclarativeCleanup::QDeclarativeCleanup(QDeclarativeEngine *engine)
-: prev(0), next(0)
+: prev(0), next(0), engine(0)
{
if (!engine)
return;
+ addToEngine(engine);
+}
+
+/*!
+Adds this object to \a engine's cleanup list. hasEngine() must be false
+before calling this method.
+*/
+void QDeclarativeCleanup::addToEngine(QDeclarativeEngine *engine)
+{
+ Q_ASSERT(engine);
+ Q_ASSERT(QDeclarativeEnginePrivate::isEngineThread(engine));
+
+ this->engine = engine;
+
QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine);
if (p->cleanup) next = p->cleanup;
@@ -75,13 +96,23 @@ QDeclarativeCleanup::QDeclarativeCleanup(QDeclarativeEngine *engine)
}
/*!
+\fn bool QDeclarativeCleanup::hasEngine() const
+
+Returns true if this QDeclarativeCleanup is associated with an engine, otherwise false.
+*/
+
+/*!
\internal
*/
QDeclarativeCleanup::~QDeclarativeCleanup()
{
+ Q_ASSERT(!prev || engine);
+ Q_ASSERT(!prev || QDeclarativeEnginePrivate::isEngineThread(engine));
+
if (prev) *prev = next;
if (next) next->prev = prev;
prev = 0;
next = 0;
}
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecleanup_p.h b/src/declarative/qml/qdeclarativecleanup_p.h
index 1efe564edc..272b0c81e5 100644
--- a/src/declarative/qml/qdeclarativecleanup_p.h
+++ b/src/declarative/qml/qdeclarativecleanup_p.h
@@ -63,9 +63,12 @@ class QDeclarativeEngine;
class Q_DECLARATIVE_EXPORT QDeclarativeCleanup
{
public:
+ QDeclarativeCleanup();
QDeclarativeCleanup(QDeclarativeEngine *);
virtual ~QDeclarativeCleanup();
+ bool hasEngine() const { return prev != 0; }
+ void addToEngine(QDeclarativeEngine *);
protected:
virtual void clear() = 0;
@@ -73,6 +76,9 @@ private:
friend class QDeclarativeEnginePrivate;
QDeclarativeCleanup **prev;
QDeclarativeCleanup *next;
+
+ // Only used for asserts
+ QDeclarativeEngine *engine;
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecompileddata.cpp b/src/declarative/qml/qdeclarativecompileddata.cpp
index a1bdca26fa..cc976de500 100644
--- a/src/declarative/qml/qdeclarativecompileddata.cpp
+++ b/src/declarative/qml/qdeclarativecompileddata.cpp
@@ -39,14 +39,14 @@
**
****************************************************************************/
-#include "private/qdeclarativecompiler_p.h"
+#include "qdeclarativecompiler_p.h"
#include "qdeclarativeengine.h"
#include "qdeclarativecomponent.h"
-#include "private/qdeclarativecomponent_p.h"
+#include "qdeclarativecomponent_p.h"
#include "qdeclarativecontext.h"
-#include "private/qdeclarativecontext_p.h"
+#include "qdeclarativecontext_p.h"
#ifdef QML_THREADED_VME_INTERPRETER
-#include "private/qdeclarativevme_p.h"
+#include "qdeclarativevme_p.h"
#endif
#include <QtCore/qdebug.h>
@@ -101,13 +101,25 @@ int QDeclarativeCompiledData::indexForUrl(const QUrl &data)
}
QDeclarativeCompiledData::QDeclarativeCompiledData(QDeclarativeEngine *engine)
-: QDeclarativeCleanup(engine), importCache(0), root(0), rootPropertyCache(0)
+: engine(engine), importCache(0), root(0), rootPropertyCache(0)
{
+ Q_ASSERT(engine);
+
bytecode.reserve(1024);
}
+void QDeclarativeCompiledData::destroy()
+{
+ if (engine && hasEngine())
+ QDeclarativeEnginePrivate::deleteInEngineThread(engine, this);
+ else
+ delete this;
+}
+
QDeclarativeCompiledData::~QDeclarativeCompiledData()
{
+ clear();
+
for (int ii = 0; ii < types.count(); ++ii) {
if (types.at(ii).component)
types.at(ii).component->release();
@@ -129,18 +141,13 @@ QDeclarativeCompiledData::~QDeclarativeCompiledData()
if (rootPropertyCache)
rootPropertyCache->release();
-
- qDeleteAll(cachedClosures);
-
- for (int ii = 0; ii < v8bindings.count(); ++ii)
- qPersistentDispose(v8bindings[ii]);
}
void QDeclarativeCompiledData::clear()
{
- qDeleteAll(cachedClosures);
- for (int ii = 0; ii < cachedClosures.count(); ++ii)
- cachedClosures[ii] = 0;
+ for (int ii = 0; ii < v8bindings.count(); ++ii)
+ qPersistentDispose(v8bindings[ii]);
+ v8bindings.clear();
}
const QMetaObject *QDeclarativeCompiledData::TypeReference::metaObject() const
@@ -246,4 +253,10 @@ QDeclarativeInstruction::Type QDeclarativeCompiledData::instructionType(const QD
#endif
}
+void QDeclarativeCompiledData::initialize(QDeclarativeEngine *engine)
+{
+ Q_ASSERT(!hasEngine());
+ QDeclarativeCleanup::addToEngine(engine);
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index fe0375fcff..06d543ab36 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -39,29 +39,29 @@
**
****************************************************************************/
-#include "private/qdeclarativecompiler_p.h"
+#include "qdeclarativecompiler_p.h"
#include "qdeclarativepropertyvaluesource.h"
#include "qdeclarativecomponent.h"
-#include "private/qmetaobjectbuilder_p.h"
-#include "private/qfastmetabuilder_p.h"
-#include "private/qdeclarativestringconverters_p.h"
-#include "private/qdeclarativeengine_p.h"
+#include <private/qmetaobjectbuilder_p.h>
+#include <private/qfastmetabuilder_p.h>
+#include "qdeclarativestringconverters_p.h"
+#include "qdeclarativeengine_p.h"
#include "qdeclarativeengine.h"
#include "qdeclarativecontext.h"
-#include "private/qdeclarativemetatype_p.h"
-#include "private/qdeclarativecustomparser_p_p.h"
-#include "private/qdeclarativecontext_p.h"
-#include "private/qdeclarativecomponent_p.h"
-#include "parser/qdeclarativejsast_p.h"
-#include "private/qdeclarativevmemetaobject_p.h"
-#include "private/qdeclarativeexpression_p.h"
-#include "private/qdeclarativeproperty_p.h"
-#include "private/qdeclarativerewrite_p.h"
+#include "qdeclarativemetatype_p.h"
+#include "qdeclarativecustomparser_p_p.h"
+#include "qdeclarativecontext_p.h"
+#include "qdeclarativecomponent_p.h"
+#include <private/qdeclarativejsast_p.h>
+#include "qdeclarativevmemetaobject_p.h"
+#include "qdeclarativeexpression_p.h"
+#include "qdeclarativeproperty_p.h"
+#include "qdeclarativerewrite_p.h"
#include "qdeclarativescriptstring.h"
-#include "private/qdeclarativeglobal_p.h"
-#include "private/qdeclarativebinding_p.h"
-#include "private/qdeclarativev4compiler_p.h"
+#include "qdeclarativeglobal_p.h"
+#include "qdeclarativebinding_p.h"
+#include <private/qv4compiler_p.h>
#include <QColor>
#include <QDebug>
@@ -380,26 +380,54 @@ void QDeclarativeCompiler::genLiteralAssignment(QDeclarativeScript::Property *pr
if (v->value.isNumber()) {
double n = v->value.asNumber();
if (double(int(n)) == n) {
- Instruction::StoreVariantInteger instr;
+ if (prop->core.isVMEProperty()) {
+ Instruction::StoreVarInteger instr;
+ instr.propertyIndex = prop->index;
+ instr.value = int(n);
+ output->addInstruction(instr);
+ } else {
+ Instruction::StoreVariantInteger instr;
+ instr.propertyIndex = prop->index;
+ instr.value = int(n);
+ output->addInstruction(instr);
+ }
+ } else {
+ if (prop->core.isVMEProperty()) {
+ Instruction::StoreVarDouble instr;
+ instr.propertyIndex = prop->index;
+ instr.value = n;
+ output->addInstruction(instr);
+ } else {
+ Instruction::StoreVariantDouble instr;
+ instr.propertyIndex = prop->index;
+ instr.value = n;
+ output->addInstruction(instr);
+ }
+ }
+ } else if (v->value.isBoolean()) {
+ if (prop->core.isVMEProperty()) {
+ Instruction::StoreVarBool instr;
instr.propertyIndex = prop->index;
- instr.value = int(n);
+ instr.value = v->value.asBoolean();
output->addInstruction(instr);
} else {
- Instruction::StoreVariantDouble instr;
+ Instruction::StoreVariantBool instr;
instr.propertyIndex = prop->index;
- instr.value = n;
+ instr.value = v->value.asBoolean();
output->addInstruction(instr);
}
- } else if(v->value.isBoolean()) {
- Instruction::StoreVariantBool instr;
- instr.propertyIndex = prop->index;
- instr.value = v->value.asBoolean();
- output->addInstruction(instr);
} else {
- Instruction::StoreVariant instr;
- instr.propertyIndex = prop->index;
- instr.value = output->indexForString(v->value.asString());
- output->addInstruction(instr);
+ if (prop->core.isVMEProperty()) {
+ Instruction::StoreVar instr;
+ instr.propertyIndex = prop->index;
+ instr.value = output->indexForString(v->value.asString());
+ output->addInstruction(instr);
+ } else {
+ Instruction::StoreVariant instr;
+ instr.propertyIndex = prop->index;
+ instr.value = output->indexForString(v->value.asString());
+ output->addInstruction(instr);
+ }
}
}
break;
@@ -650,7 +678,14 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
Q_ASSERT(out);
reset(out);
- output = out;
+ QDeclarativeScript::Object *root = unit->parser().tree();
+ Q_ASSERT(root);
+
+ this->engine = engine;
+ this->enginePrivate = QDeclarativeEnginePrivate::get(engine);
+ this->unit = unit;
+ this->unitRoot = root;
+ this->output = out;
// Compile types
const QList<QDeclarativeTypeData::TypeReference> &resolvedTypes = unit->resolvedTypes();
@@ -673,12 +708,10 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
if (ref.type->containsRevisionedAttributes()) {
QDeclarativeError cacheError;
- ref.typePropertyCache =
- QDeclarativeEnginePrivate::get(engine)->cache(ref.type, resolvedTypes.at(ii).minorVersion, cacheError);
-
- if (!ref.typePropertyCache) {
+ ref.typePropertyCache = enginePrivate->cache(ref.type, resolvedTypes.at(ii).minorVersion,
+ cacheError);
+ if (!ref.typePropertyCache)
COMPILE_EXCEPTION(parserRef->refObjects.first(), cacheError.description());
- }
ref.typePropertyCache->addref();
}
@@ -689,13 +722,6 @@ bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
out->types << ref;
}
- QDeclarativeScript::Object *root = unit->parser().tree();
- Q_ASSERT(root);
-
- this->engine = engine;
- this->enginePrivate = QDeclarativeEnginePrivate::get(engine);
- this->unit = unit;
- this->unitRoot = root;
compileTree(root);
if (!isError()) {
@@ -731,20 +757,12 @@ void QDeclarativeCompiler::compileTree(QDeclarativeScript::Object *tree)
foreach (const QDeclarativeTypeData::ScriptReference &script, unit->resolvedScripts()) {
importedScriptIndexes.append(script.qualifier);
-
- Instruction::StoreImportedScript import;
- import.value = output->scripts.count();
-
- QDeclarativeScriptData *scriptData = script.script->scriptData();
- scriptData->addref();
- output->scripts << scriptData;
- output->addInstruction(import);
}
// We generate the importCache before we build the tree so that
// it can be used in the binding compiler. Given we "expect" the
// QML compilation to succeed, this isn't a waste.
- output->importCache = new QDeclarativeTypeNameCache(engine);
+ output->importCache = new QDeclarativeTypeNameCache();
for (int ii = 0; ii < importedScriptIndexes.count(); ++ii)
output->importCache->add(importedScriptIndexes.at(ii), ii);
unit->imports().populateCache(output->importCache, engine);
@@ -753,15 +771,27 @@ void QDeclarativeCompiler::compileTree(QDeclarativeScript::Object *tree)
return;
Instruction::Init init;
- init.bindingsSize = compileState->bindings.count();
+ init.bindingsSize = compileState->totalBindingsCount;
init.parserStatusSize = compileState->parserStatusCount;
init.contextCache = genContextCache();
+ init.objectStackSize = compileState->objectDepth.maxDepth();
+ init.listStackSize = compileState->listDepth.maxDepth();
if (compileState->compiledBindingData.isEmpty())
init.compiledBinding = -1;
else
init.compiledBinding = output->indexForByteArray(compileState->compiledBindingData);
output->addInstruction(init);
+ foreach (const QDeclarativeTypeData::ScriptReference &script, unit->resolvedScripts()) {
+ Instruction::StoreImportedScript import;
+ import.value = output->scripts.count();
+
+ QDeclarativeScriptData *scriptData = script.script->scriptData();
+ scriptData->addref();
+ output->scripts << scriptData;
+ output->addInstruction(import);
+ }
+
if (!compileState->v8BindingProgram.isEmpty()) {
Instruction::InitV8Bindings bindings;
bindings.program = output->indexForString(compileState->v8BindingProgram);
@@ -805,8 +835,7 @@ bool QDeclarativeCompiler::buildObject(QDeclarativeScript::Object *obj, const Bi
componentStats->componentStat.objects++;
Q_ASSERT (obj->type != -1);
- const QDeclarativeCompiledData::TypeReference &tr =
- output->types.at(obj->type);
+ const QDeclarativeCompiledData::TypeReference &tr = output->types.at(obj->type);
obj->metatype = tr.metaObject();
if (tr.type)
@@ -818,6 +847,20 @@ bool QDeclarativeCompiler::buildObject(QDeclarativeScript::Object *obj, const Bi
return true;
}
+ if (tr.component) {
+ typedef QDeclarativeInstruction I;
+ const I *init = ((const I *)tr.component->bytecode.constData());
+ Q_ASSERT(init && tr.component->instructionType(init) == QDeclarativeInstruction::Init);
+
+ // Adjust stack depths to include nested components
+ compileState->objectDepth.pushPop(init->init.objectStackSize);
+ compileState->listDepth.pushPop(init->init.listStackSize);
+ compileState->parserStatusCount += init->init.parserStatusSize;
+ compileState->totalBindingsCount += init->init.bindingsSize;
+ }
+
+ compileState->objectDepth.push();
+
// Object instantiations reset the binding context
BindingContext objCtxt(obj);
@@ -1006,6 +1049,8 @@ bool QDeclarativeCompiler::buildObject(QDeclarativeScript::Object *obj, const Bi
}
}
+ compileState->objectDepth.pop();
+
return true;
}
@@ -1031,23 +1076,35 @@ void QDeclarativeCompiler::genObject(QDeclarativeScript::Object *obj)
} else {
- Instruction::CreateObject create;
- create.line = obj->location.start.line;
- create.column = obj->location.start.column;
- create.data = -1;
- if (!obj->custom.isEmpty())
- create.data = output->indexForByteArray(obj->custom);
- create.type = obj->type;
- if (!output->types.at(create.type).type &&
- !obj->bindingBitmask.isEmpty()) {
- Q_ASSERT(obj->bindingBitmask.size() % 4 == 0);
- create.bindingBits =
- output->indexForByteArray(obj->bindingBitmask);
+ if (output->types.at(obj->type).type) {
+ Instruction::CreateCppObject create;
+ create.line = obj->location.start.line;
+ create.column = obj->location.start.column;
+ create.data = -1;
+ if (!obj->custom.isEmpty())
+ create.data = output->indexForByteArray(obj->custom);
+ create.type = obj->type;
+ create.isRoot = (compileState->root == obj);
+ output->addInstruction(create);
} else {
- create.bindingBits = -1;
- }
- output->addInstruction(create);
+ Instruction::CreateQMLObject create;
+ create.type = obj->type;
+ create.isRoot = (compileState->root == obj);
+ if (!obj->bindingBitmask.isEmpty()) {
+ Q_ASSERT(obj->bindingBitmask.size() % 4 == 0);
+ create.bindingBits = output->indexForByteArray(obj->bindingBitmask);
+ } else {
+ create.bindingBits = -1;
+ }
+ output->addInstruction(create);
+
+ Instruction::CompleteQMLObject complete;
+ complete.line = obj->location.start.line;
+ complete.column = obj->location.start.column;
+ complete.isRoot = (compileState->root == obj);
+ output->addInstruction(complete);
+ }
}
// Setup the synthesized meta object if necessary
@@ -1132,12 +1189,13 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeScript::Object *obj)
int deferIdx = output->addInstruction(defer);
int nextInstructionIndex = output->nextInstructionIndex();
- Instruction::Init init;
- init.bindingsSize = compileState->bindings.count(); // XXX - bigger than necessary
- init.parserStatusSize = compileState->parserStatusCount; // XXX - bigger than necessary
- init.contextCache = -1;
- init.compiledBinding = -1;
- output->addInstruction(init);
+ Instruction::DeferInit dinit;
+ // XXX - these are now massive over allocations
+ dinit.bindingsSize = compileState->totalBindingsCount;
+ dinit.parserStatusSize = compileState->parserStatusCount;
+ dinit.objectStackSize = compileState->objectDepth.maxDepth();
+ dinit.listStackSize = compileState->listDepth.maxDepth();
+ output->addInstruction(dinit);
for (Property *prop = obj->valueProperties.first(); prop; prop = Object::PropertyList::next(prop)) {
if (!prop->isDeferred)
@@ -1269,6 +1327,7 @@ void QDeclarativeCompiler::genComponent(QDeclarativeScript::Object *obj)
create.line = root->location.start.line;
create.column = root->location.start.column;
create.endLine = root->location.end.line;
+ create.isRoot = (compileState->root == obj);
int createInstruction = output->addInstruction(create);
int nextInstructionIndex = output->nextInstructionIndex();
@@ -1276,9 +1335,11 @@ void QDeclarativeCompiler::genComponent(QDeclarativeScript::Object *obj)
compileState = componentState(root);
Instruction::Init init;
- init.bindingsSize = compileState->bindings.count();
+ init.bindingsSize = compileState->totalBindingsCount;
init.parserStatusSize = compileState->parserStatusCount;
init.contextCache = genContextCache();
+ init.objectStackSize = compileState->objectDepth.maxDepth();
+ init.listStackSize = compileState->listDepth.maxDepth();
if (compileState->compiledBindingData.isEmpty())
init.compiledBinding = -1;
else
@@ -1325,6 +1386,8 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeScript::Object *obj,
// The special "Component" element can only have the id property and a
// default property, that actually defines the component's tree
+ compileState->objectDepth.push();
+
// Find, check and set the "id" property (if any)
Property *idProp = 0;
if (obj->properties.isMany() ||
@@ -1371,6 +1434,8 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeScript::Object *obj,
// Build the component tree
COMPILE_CHECK(buildComponentFromRoot(root, ctxt));
+ compileState->objectDepth.pop();
+
return true;
}
@@ -1759,10 +1824,18 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeScript::Property *p
} else if (prop->type == QMetaType::QVariant) {
- Instruction::StoreVariantObject store;
- store.line = v->object->location.start.line;
- store.propertyIndex = prop->index;
- output->addInstruction(store);
+ if (prop->core.isVMEProperty()) {
+ Instruction::StoreVarObject store;
+ store.line = v->object->location.start.line;
+ store.propertyIndex = prop->index;
+ output->addInstruction(store);
+ } else {
+ Instruction::StoreVariantObject store;
+ store.line = v->object->location.start.line;
+ store.propertyIndex = prop->index;
+ output->addInstruction(store);
+ }
+
} else {
@@ -1797,7 +1870,7 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeScript::Property *p
store.property = genValueTypeData(prop, valueTypeProperty);
store.owner = 1;
} else {
- store.property = genPropertyData(prop);
+ store.property = prop->core;
store.owner = 0;
}
QDeclarativeType *valueType = toQmlType(v->object);
@@ -1812,7 +1885,7 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeScript::Property *p
store.property = genValueTypeData(prop, valueTypeProperty);
store.owner = 1;
} else {
- store.property = genPropertyData(prop);
+ store.property = prop->core;
store.owner = 0;
}
QDeclarativeType *valueType = toQmlType(v->object);
@@ -1849,6 +1922,7 @@ bool QDeclarativeCompiler::buildIdProperty(QDeclarativeScript::Property *prop,
void QDeclarativeCompiler::addId(const QString &id, QDeclarativeScript::Object *obj)
{
+ Q_UNUSED(id);
Q_ASSERT(!compileState->ids.value(id));
Q_ASSERT(obj->id == id);
obj->idIndex = compileState->ids.count();
@@ -1859,6 +1933,7 @@ void QDeclarativeCompiler::addBindingReference(BindingReference *ref)
{
Q_ASSERT(ref->value && !ref->value->bindingReference);
ref->value->bindingReference = ref;
+ compileState->totalBindingsCount++;
compileState->bindings.prepend(ref);
}
@@ -1892,10 +1967,14 @@ bool QDeclarativeCompiler::buildAttachedProperty(QDeclarativeScript::Property *p
Q_ASSERT(prop->value);
Q_ASSERT(prop->index != -1); // This is set in buildProperty()
+ compileState->objectDepth.push();
+
obj->addAttachedProperty(prop);
COMPILE_CHECK(buildSubObject(prop->value, ctxt.incr()));
+ compileState->objectDepth.pop();
+
return true;
}
@@ -1953,7 +2032,11 @@ bool QDeclarativeCompiler::buildGroupedProperty(QDeclarativeScript::Property *pr
obj->addGroupedProperty(prop);
+ compileState->objectDepth.push();
+
COMPILE_CHECK(buildSubObject(prop->value, ctxt.incr()));
+
+ compileState->objectDepth.pop();
}
return true;
@@ -1964,6 +2047,8 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type,
QDeclarativeScript::Object *baseObj,
const BindingContext &ctxt)
{
+ compileState->objectDepth.push();
+
if (obj->defaultProperty)
COMPILE_EXCEPTION(obj, tr("Invalid property use"));
obj->metatype = type->metaObject();
@@ -2026,6 +2111,8 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type,
obj->addValueProperty(prop);
}
+ compileState->objectDepth.pop();
+
return true;
}
@@ -2038,6 +2125,8 @@ bool QDeclarativeCompiler::buildListProperty(QDeclarativeScript::Property *prop,
{
Q_ASSERT(prop->core.isQList());
+ compileState->listDepth.push();
+
int t = prop->type;
obj->addValueProperty(prop);
@@ -2071,6 +2160,8 @@ bool QDeclarativeCompiler::buildListProperty(QDeclarativeScript::Property *prop,
}
}
+ compileState->listDepth.pop();
+
return true;
}
@@ -2180,7 +2271,7 @@ bool QDeclarativeCompiler::buildPropertyObjectAssignment(QDeclarativeScript::Pro
QDeclarativeScript::Object *root = v->object;
QDeclarativeScript::Object *component = pool->New<Object>();
component->type = componentTypeRef();
- component->typeName = "Qt/Component";
+ component->typeName = QStringLiteral("Qt/Component");
component->metatype = &QDeclarativeComponent::staticMetaObject;
component->location = root->location;
QDeclarativeScript::Value *componentValue = pool->New<Value>();
@@ -2239,7 +2330,7 @@ bool QDeclarativeCompiler::buildPropertyOnAssignment(QDeclarativeScript::Propert
buildDynamicMeta(baseObj, ForceCreation);
v->type = isPropertyValue ? Value::ValueSource : Value::ValueInterceptor;
} else {
- COMPILE_EXCEPTION(v, tr("\"%1\" cannot operate on \"%2\"").arg(QString::fromUtf8(v->object->typeName)).arg(prop->name().toString()));
+ COMPILE_EXCEPTION(v, tr("\"%1\" cannot operate on \"%2\"").arg(v->object->typeName).arg(prop->name().toString()));
}
return true;
@@ -2305,7 +2396,7 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop
unit->imports().resolveType(typeName, &type, 0, 0, 0, 0);
//handle enums on value types (where obj->typeName is empty)
- QByteArray objTypeName = obj->typeName;
+ QString objTypeName = obj->typeName;
if (objTypeName.isEmpty()) {
QDeclarativeType *objType = toQmlType(obj);
if (objType)
@@ -2374,10 +2465,10 @@ int QDeclarativeCompiler::evaluateEnum(const QByteArray& script) const
return -1;
}
-const QMetaObject *QDeclarativeCompiler::resolveType(const QByteArray& name) const
+const QMetaObject *QDeclarativeCompiler::resolveType(const QString& name) const
{
QDeclarativeType *qmltype = 0;
- if (!unit->imports().resolveType(QString::fromUtf8(name), &qmltype, 0, 0, 0, 0))
+ if (!unit->imports().resolveType(name, &qmltype, 0, 0, 0, 0))
return 0;
if (!qmltype)
return 0;
@@ -2408,7 +2499,6 @@ bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeScript::Object *obj)
QHashField methodNames;
// Check properties
- int dpCount = obj->dynamicProperties.count();
for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
const QDeclarativeScript::Object::DynamicProperty &prop = *p;
@@ -2516,11 +2606,16 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeScript::Object *obj, Dyn
const Object::DynamicProperty *defaultProperty = 0;
int aliasCount = 0;
+ int varPropCount = 0;
+ int totalPropCount = 0;
+ int firstPropertyVarIndex = 0;
for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
if (p->type == Object::DynamicProperty::Alias)
aliasCount++;
+ if (p->type == Object::DynamicProperty::Var)
+ varPropCount++;
if (p->isDefaultProperty &&
(resolveAlias || p->type != Object::DynamicProperty::Alias))
@@ -2574,6 +2669,7 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeScript::Object *obj, Dyn
int metaType;
const char *cppType;
} builtinTypes[] = {
+ { Object::DynamicProperty::Var, 0, "QVariant" },
{ Object::DynamicProperty::Variant, 0, "QVariant" },
{ Object::DynamicProperty::Int, QMetaType::Int, "int" },
{ Object::DynamicProperty::Bool, QMetaType::Bool, "bool" },
@@ -2652,6 +2748,9 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeScript::Object *obj, Dyn
typeRef = p->typeRef;
}
+ if (p->type == Object::DynamicProperty::Var)
+ continue;
+
if (buildData) {
VMD *vmd = (QDeclarativeVMEMetaData *)dynamicData.data();
vmd->propertyCount++;
@@ -2672,6 +2771,31 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeScript::Object *obj, Dyn
effectivePropertyIndex++;
}
+
+ if (varPropCount) {
+ VMD *vmd = (QDeclarativeVMEMetaData *)dynamicData.data();
+ if (buildData)
+ vmd->varPropertyCount = varPropCount;
+ firstPropertyVarIndex = effectivePropertyIndex;
+ totalPropCount = varPropCount + effectivePropertyIndex;
+ for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
+ if (p->type == Object::DynamicProperty::Var) {
+ QFastMetaBuilder::StringRef typeRef = typeRefs[p->type];
+ if (buildData) {
+ vmd->propertyCount++;
+ (vmd->propertyData() + effectivePropertyIndex)->propertyType = -1;
+ }
+
+ builder.setProperty(effectivePropertyIndex, p->nameRef, typeRef, (QMetaType::Type)-1,
+ QFastMetaBuilder::Writable, effectivePropertyIndex);
+
+ p->changedSignatureRef = builder.newString(p->name.utf8length() + strlen("Changed()"));
+ builder.setSignal(effectivePropertyIndex, p->changedSignatureRef);
+
+ effectivePropertyIndex++;
+ }
+ }
+ }
if (aliasCount) {
int aliasIndex = 0;
@@ -2859,9 +2983,19 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeScript::Object *obj, Dyn
if (obj->type != -1) {
QDeclarativePropertyCache *cache = output->types[obj->type].createPropertyCache(engine)->copy();
- cache->append(engine, &obj->extObject, QDeclarativePropertyCache::Data::NoFlags,
+ cache->append(engine, &obj->extObject,
+ QDeclarativePropertyCache::Data::NoFlags,
QDeclarativePropertyCache::Data::IsVMEFunction,
QDeclarativePropertyCache::Data::IsVMESignal);
+
+ // now we modify the flags appropriately for var properties.
+ int propertyOffset = obj->extObject.propertyOffset();
+ QDeclarativePropertyCache::Data *currPropData = 0;
+ for (int pvi = firstPropertyVarIndex; pvi < totalPropCount; ++pvi) {
+ currPropData = cache->property(pvi + propertyOffset);
+ currPropData->setFlags(currPropData->getFlags() | QDeclarativePropertyCache::Data::IsVMEProperty);
+ }
+
obj->synthCache = cache;
}
@@ -2893,7 +3027,7 @@ bool QDeclarativeCompiler::checkValidId(QDeclarativeScript::Value *v, const QStr
return true;
}
-#include <qdeclarativejsparser_p.h>
+#include <private/qdeclarativejsparser_p.h>
static QStringList astNodeToStringList(QDeclarativeJS::AST::Node *node)
{
@@ -2983,7 +3117,7 @@ bool QDeclarativeCompiler::compileAlias(QFastMetaBuilder &builder,
// update the property type
type = aliasProperty.type();
- if (type >= QVariant::UserType)
+ if (type >= (int)QVariant::UserType)
type = 0;
}
@@ -3064,12 +3198,15 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeScript::Value *bindi
store.value = ref.compiledIndex;
store.context = ref.bindingContext.stack;
store.owner = ref.bindingContext.owner;
- if (valueTypeProperty)
+ if (valueTypeProperty) {
store.property = (valueTypeProperty->index & 0xFFFF) |
((valueTypeProperty->type & 0xFF)) << 16 |
((prop->index & 0xFF) << 24);
- else
+ store.isRoot = (compileState->root == valueTypeProperty->parent);
+ } else {
store.property = prop->index;
+ store.isRoot = (compileState->root == obj);
+ }
store.line = binding->location.start.line;
output->addInstruction(store);
} else if (ref.dataType == BindingReference::V8) {
@@ -3077,6 +3214,11 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeScript::Value *bindi
store.value = ref.compiledIndex;
store.context = ref.bindingContext.stack;
store.owner = ref.bindingContext.owner;
+ if (valueTypeProperty) {
+ store.isRoot = (compileState->root == valueTypeProperty->parent);
+ } else {
+ store.isRoot = (compileState->root == obj);
+ }
store.line = binding->location.start.line;
Q_ASSERT(ref.bindingContext.owner == 0 ||
@@ -3084,7 +3226,7 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeScript::Value *bindi
if (ref.bindingContext.owner) {
store.property = genValueTypeData(prop, valueTypeProperty);
} else {
- store.property = genPropertyData(prop);
+ store.property = prop->core;
}
output->addInstruction(store);
@@ -3095,12 +3237,18 @@ void QDeclarativeCompiler::genBindingAssignment(QDeclarativeScript::Value *bindi
store.assignBinding.owner = ref.bindingContext.owner;
store.assignBinding.line = binding->location.start.line;
+ if (valueTypeProperty) {
+ store.assignBinding.isRoot = (compileState->root == valueTypeProperty->parent);
+ } else {
+ store.assignBinding.isRoot = (compileState->root == obj);
+ }
+
Q_ASSERT(ref.bindingContext.owner == 0 ||
(ref.bindingContext.owner != 0 && valueTypeProperty));
if (ref.bindingContext.owner) {
store.assignBinding.property = genValueTypeData(prop, valueTypeProperty);
} else {
- store.assignBinding.property = genPropertyData(prop);
+ store.assignBinding.property = prop->core;
}
output->addInstructionHelper(
!prop->isAlias ? QDeclarativeInstruction::StoreBinding
@@ -3123,23 +3271,14 @@ int QDeclarativeCompiler::genContextCache()
return output->contextCaches.count() - 1;
}
-int QDeclarativeCompiler::genValueTypeData(QDeclarativeScript::Property *valueTypeProp,
- QDeclarativeScript::Property *prop)
+QDeclarativePropertyCache::Data
+QDeclarativeCompiler::genValueTypeData(QDeclarativeScript::Property *valueTypeProp,
+ QDeclarativeScript::Property *prop)
{
typedef QDeclarativePropertyPrivate QDPP;
- QByteArray data = QDPP::saveValueType(prop->parent->metaObject(), prop->index,
- enginePrivate->valueTypes[prop->type]->metaObject(),
- valueTypeProp->index, engine);
-
- return output->indexForByteArray(data);
-}
-
-int QDeclarativeCompiler::genPropertyData(QDeclarativeScript::Property *prop)
-{
- typedef QDeclarativePropertyPrivate QDPP;
- QByteArray data = QDPP::saveProperty(prop->parent->metaObject(), prop->index, engine);
-
- return output->indexForByteArray(data);
+ return QDPP::saveValueType(prop->parent->metaObject(), prop->index,
+ enginePrivate->valueTypes[prop->type]->metaObject(),
+ valueTypeProp->index, engine);
}
bool QDeclarativeCompiler::completeComponentBuild()
@@ -3151,12 +3290,12 @@ bool QDeclarativeCompiler::completeComponentBuild()
aliasObject = compileState->aliasingObjects.next(aliasObject))
COMPILE_CHECK(buildDynamicMeta(aliasObject, ResolveAliases));
- QDeclarativeV4Compiler::Expression expr(unit->imports());
+ QV4Compiler::Expression expr(unit->imports());
expr.component = compileState->root;
expr.ids = &compileState->ids;
expr.importCache = output->importCache;
- QDeclarativeV4Compiler bindingCompiler;
+ QV4Compiler bindingCompiler;
QList<BindingReference*> sharedBindings;
@@ -3241,6 +3380,10 @@ bool QDeclarativeCompiler::completeComponentBuild()
if (bindingCompiler.isValid())
compileState->compiledBindingData = bindingCompiler.program();
+ // Check pop()'s matched push()'s
+ Q_ASSERT(compileState->objectDepth.depth() == 0);
+ Q_ASSERT(compileState->listDepth.depth() == 0);
+
saveComponentState();
return true;
@@ -3302,8 +3445,7 @@ void QDeclarativeCompiler::dumpStats()
*/
bool QDeclarativeCompiler::canCoerce(int to, QDeclarativeScript::Object *from)
{
- const QMetaObject *toMo =
- enginePrivate->rawMetaObjectForType(to);
+ const QMetaObject *toMo = enginePrivate->rawMetaObjectForType(to);
const QMetaObject *fromMo = from->metaObject();
while (fromMo) {
diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h
index a4def99c48..ef37335ad8 100644
--- a/src/declarative/qml/qdeclarativecompiler_p.h
+++ b/src/declarative/qml/qdeclarativecompiler_p.h
@@ -55,15 +55,15 @@
#include "qdeclarative.h"
#include "qdeclarativeerror.h"
-#include "private/qv8_p.h"
-#include "private/qdeclarativeinstruction_p.h"
-#include "private/qdeclarativescript_p.h"
-#include "private/qdeclarativeengine_p.h"
-#include "private/qbitfield_p.h"
-#include "private/qdeclarativepropertycache_p.h"
-#include "private/qdeclarativeintegercache_p.h"
-#include "private/qdeclarativetypenamecache_p.h"
-#include "private/qdeclarativetypeloader_p.h"
+#include <private/qv8_p.h>
+#include "qdeclarativeinstruction_p.h"
+#include "qdeclarativescript_p.h"
+#include "qdeclarativeengine_p.h"
+#include <private/qbitfield_p.h>
+#include "qdeclarativepropertycache_p.h"
+#include "qdeclarativeintegercache_p.h"
+#include "qdeclarativetypenamecache_p.h"
+#include "qdeclarativetypeloader_p.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qset.h>
@@ -76,12 +76,15 @@ class QDeclarativeComponent;
class QDeclarativeContext;
class QDeclarativeContextData;
-class Q_AUTOTEST_EXPORT QDeclarativeCompiledData : public QDeclarativeRefCount, public QDeclarativeCleanup
+class Q_AUTOTEST_EXPORT QDeclarativeCompiledData : public QDeclarativeRefCount,
+ public QDeclarativeCleanup
{
public:
QDeclarativeCompiledData(QDeclarativeEngine *engine);
virtual ~QDeclarativeCompiledData();
+ QDeclarativeEngine *engine;
+
QString name;
QUrl url;
QDeclarativeTypeNameCache *importCache;
@@ -96,7 +99,6 @@ public:
QDeclarativePropertyCache *typePropertyCache;
QDeclarativeCompiledData *component;
- QObject *createInstance(QDeclarativeContextData *, const QBitField &, QList<QDeclarativeError> *) const;
const QMetaObject *metaObject() const;
QDeclarativePropertyCache *propertyCache() const;
QDeclarativePropertyCache *createPropertyCache(QDeclarativeEngine *);
@@ -111,7 +113,6 @@ public:
QList<QString> primitives;
QList<QByteArray> datas;
QByteArray bytecode;
- QList<QJSValue *> cachedClosures;
QList<QDeclarativePropertyCache *> propertyCaches;
QList<QDeclarativeIntegerCache *> contextCaches;
QList<QDeclarativeScriptData *> scripts;
@@ -138,16 +139,21 @@ public:
QDeclarativeInstruction *instruction(int index);
QDeclarativeInstruction::Type instructionType(const QDeclarativeInstruction *instr);
+ bool isInitialized() const { return hasEngine(); }
+ void initialize(QDeclarativeEngine *);
+
protected:
+ virtual void destroy(); // From QDeclarativeRefCount
virtual void clear(); // From QDeclarativeCleanup
private:
+ friend class QDeclarativeCompiler;
+
int addInstructionHelper(QDeclarativeInstruction::Type type, QDeclarativeInstruction &instr);
void dump(QDeclarativeInstruction *, int idx = -1);
QDeclarativeCompiledData(const QDeclarativeCompiledData &other);
QDeclarativeCompiledData &operator=(const QDeclarativeCompiledData &other);
QByteArray packData;
- friend class QDeclarativeCompiler;
int pack(const char *, size_t);
int indexForString(const QString &);
@@ -204,16 +210,35 @@ namespace QDeclarativeCompilerTypes {
}
};
+ struct DepthStack {
+ DepthStack() : _depth(0), _maxDepth(0) {}
+ DepthStack(const DepthStack &o) : _depth(o._depth), _maxDepth(o._maxDepth) {}
+ DepthStack &operator=(const DepthStack &o) { _depth = o._depth; _maxDepth = o._maxDepth; return *this; }
+
+ int depth() const { return _depth; }
+ int maxDepth() const { return _maxDepth; }
+
+ void push() { ++_depth; _maxDepth = qMax(_depth, _maxDepth); }
+ void pop() { --_depth; Q_ASSERT(_depth >= 0); Q_ASSERT(_maxDepth > _depth); }
+
+ void pushPop(int count) { _maxDepth = qMax(_depth + count, _maxDepth); }
+ private:
+ int _depth;
+ int _maxDepth;
+ };
+
// Contains all the incremental compiler state about a component. As
// a single QML file can have multiple components defined, there may be
// more than one of these for each compile
struct ComponentCompileState : public QDeclarativePool::Class
{
ComponentCompileState()
- : parserStatusCount(0), pushedProperties(0), nested(false), v8BindingProgramLine(-1), root(0) {}
+ : parserStatusCount(0), totalBindingsCount(0), pushedProperties(0), nested(false),
+ v8BindingProgramLine(-1), root(0) {}
IdList ids;
int parserStatusCount;
+ int totalBindingsCount;
int pushedProperties;
bool nested;
@@ -222,6 +247,9 @@ namespace QDeclarativeCompilerTypes {
int v8BindingProgramLine;
int v8BindingProgramIndex;
+ DepthStack objectDepth;
+ DepthStack listDepth;
+
typedef QDeclarativeCompilerTypes::BindingReference B;
typedef QFieldList<B, &B::nextReference> BindingReferenceList;
BindingReferenceList bindings;
@@ -250,7 +278,7 @@ public:
static bool isSignalPropertyName(const QHashedStringRef &);
int evaluateEnum(const QByteArray& script) const; // for QDeclarativeCustomParser::evaluateEnum
- const QMetaObject *resolveType(const QByteArray& name) const; // for QDeclarativeCustomParser::resolveType
+ const QMetaObject *resolveType(const QString& name) const; // for QDeclarativeCustomParser::resolveType
int rewriteBinding(const QString& expression, const QString& name); // for QDeclarativeCustomParser::rewriteBinding
private:
@@ -345,8 +373,8 @@ private:
QDeclarativeScript::Property *valueTypeProperty = 0);
int genContextCache();
- int genValueTypeData(QDeclarativeScript::Property *prop, QDeclarativeScript::Property *valueTypeProp);
- int genPropertyData(QDeclarativeScript::Property *prop);
+ QDeclarativePropertyCache::Data genValueTypeData(QDeclarativeScript::Property *prop,
+ QDeclarativeScript::Property *valueTypeProp);
int componentTypeRef();
@@ -386,7 +414,6 @@ private:
QDeclarativeScript::Object *unitRoot;
QDeclarativeTypeData *unit;
-
// Compiler component statistics. Only collected if QML_COMPILER_STATS=1
struct ComponentStat
{
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index d5a55fed24..580ce5b801 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -40,23 +40,25 @@
****************************************************************************/
#include "qdeclarativecomponent.h"
-#include "private/qdeclarativecomponent_p.h"
+#include "qdeclarativecomponent_p.h"
-#include "private/qdeclarativecompiler_p.h"
-#include "private/qdeclarativecontext_p.h"
-#include "private/qdeclarativeengine_p.h"
-#include "private/qdeclarativevme_p.h"
+#include "qdeclarativecompiler_p.h"
+#include "qdeclarativecontext_p.h"
+#include "qdeclarativeengine_p.h"
+#include "qdeclarativevme_p.h"
#include "qdeclarative.h"
#include "qdeclarativeengine.h"
-#include "private/qdeclarativebinding_p.h"
-#include "private/qdeclarativebinding_p_p.h"
-#include "private/qdeclarativeglobal_p.h"
-#include "private/qdeclarativescript_p.h"
-#include "private/qdeclarativedebugtrace_p.h"
-#include "private/qdeclarativeenginedebugservice_p.h"
-
-#include "private/qv8engine_p.h"
-#include "private/qv8include_p.h"
+#include "qdeclarativebinding_p.h"
+#include "qdeclarativebinding_p_p.h"
+#include "qdeclarativeglobal_p.h"
+#include "qdeclarativescript_p.h"
+#include <private/qdeclarativedebugtrace_p.h>
+#include <private/qdeclarativeenginedebugservice_p.h>
+#include "qdeclarativeincubator.h"
+#include "qdeclarativeincubator_p.h"
+
+#include <private/qv8engine_p.h>
+#include <private/qv8include_p.h>
#include <QStack>
#include <QStringList>
@@ -65,7 +67,45 @@
QT_BEGIN_NAMESPACE
-class QByteArray;
+class QDeclarativeComponentExtension : public QV8Engine::Deletable
+{
+public:
+ QDeclarativeComponentExtension(QV8Engine *);
+ virtual ~QDeclarativeComponentExtension();
+
+ v8::Persistent<v8::Function> incubationConstructor;
+ v8::Persistent<v8::Script> initialProperties;
+ v8::Persistent<v8::Function> forceCompletion;
+};
+static V8_DEFINE_EXTENSION(QDeclarativeComponentExtension, componentExtension);
+
+/*
+ Try to do what's necessary for a reasonable display of the type
+ name, but no more (just enough for the client to do more extensive cleanup).
+
+ Should only be called when debugging is enabled.
+*/
+static inline QString buildTypeNameForDebug(const QMetaObject *metaObject)
+{
+ static const QString qmlMarker(QLatin1String("_QML"));
+ static const QChar underscore(QLatin1Char('_'));
+ static const QChar asterisk(QLatin1Char('*'));
+ QDeclarativeType *type = QDeclarativeMetaType::qmlType(metaObject);
+ QString typeName = type ? type->qmlTypeName() : QString::fromUtf8(metaObject->className());
+ if (!type) {
+ //### optimize further?
+ int marker = typeName.indexOf(qmlMarker);
+ if (marker != -1 && marker < typeName.count() - 1) {
+ if (typeName[marker + 1] == underscore) {
+ const QString className = typeName.left(marker) + asterisk;
+ type = QDeclarativeMetaType::qmlType(QMetaType::type(className.toUtf8()));
+ if (type)
+ typeName = type->qmlTypeName();
+ }
+ }
+ }
+ return typeName;
+}
/*!
\class QDeclarativeComponent
@@ -615,165 +655,6 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeComponentPrivate &dd, Q
}
/*!
- \qmlmethod object Component::createObject(Item parent, object properties)
-
- Creates and returns an object instance of this component that will have
- the given \a parent and \a properties. The \a properties argument is optional.
- Returns null if object creation fails.
-
- The object will be created in the same context as the one in which the component
- was created. This function will always return null when called on components
- which were not created in QML.
-
- If you wish to create an object without setting a parent, specify \c null for
- the \a parent value. Note that if the returned object is to be displayed, you
- must provide a valid \a parent value or set the returned object's \l{Item::parent}{parent}
- property, or else the object will not be visible.
-
- If a \a parent is not provided to createObject(), a reference to the returned object must be held so that
- it is not destroyed by the garbage collector. This is true regardless of whether \l{Item::parent} is set afterwards,
- since setting the Item parent does not change object ownership; only the graphical parent is changed.
-
- As of QtQuick 1.1, this method accepts an optional \a properties argument that specifies a
- map of initial property values for the created object. These values are applied before object
- creation is finalized. (This is more efficient than setting property values after object creation,
- particularly where large sets of property values are defined, and also allows property bindings
- to be set up before the object is created.)
-
- The \a properties argument is specified as a map of property-value items. For example, the code
- below creates an object with initial \c x and \c y values of 100 and 200, respectively:
-
- \js
- var component = Qt.createComponent("Button.qml");
- if (component.status == Component.Ready)
- component.createObject(parent, {"x": 100, "y": 100});
- \endjs
-
- Dynamically created instances can be deleted with the \c destroy() method.
- See \l {Dynamic Object Management in QML} for more information.
-*/
-
-/*!
- \internal
- A version of create which returns a scriptObject, for use in script.
- This function will only work on components created in QML.
-
- Sets graphics object parent because forgetting to do this is a frequent
- and serious problem.
-*/
-void QDeclarativeComponent::createObject(QDeclarativeV8Function *args)
-{
- Q_ASSERT(args);
-
- Q_D(QDeclarativeComponent);
-
- Q_ASSERT(d->engine);
-
- QObject *parent = args->Length()?QDeclarativeEnginePrivate::get(d->engine)->v8engine()->toQObject((*args)[0]):0;
-
- v8::Local<v8::Object> valuemap;
- if (args->Length() >= 2) {
- v8::Local<v8::Value> v = (*args)[1];
- if (!v->IsObject() || v->IsArray()) {
- qmlInfo(this) << tr("createObject: value is not an object");
- args->returnValue(v8::Null());
- return;
- }
- valuemap = v8::Local<v8::Object>::Cast(v);
- }
-
- QV8Engine *v8engine = QDeclarativeEnginePrivate::get(d->engine)->v8engine();
- QObject *retn = d->createObjectWithInitialProperties(args->qmlGlobal(), valuemap, parent);
- if (!retn)
- args->returnValue(v8::Null());
- else
- args->returnValue(v8engine->newQObject(retn));
-}
-
-QObject *QDeclarativeComponentPrivate::createObjectWithInitialProperties(v8::Handle<v8::Object> qmlGlobal, v8::Handle<v8::Object> valuemap, QObject *parentObject)
-{
- Q_Q(QDeclarativeComponent);
- Q_ASSERT(engine);
-
- QDeclarativeContext *ctxt = q->creationContext();
- if (!ctxt) ctxt = engine->rootContext();
-
- QObject *parent = parentObject;
-
- QObject *ret = q->beginCreate(ctxt);
- if (!ret) {
- q->completeCreate();
- return 0;
- }
-
- if (parent) {
- ret->setParent(parent);
-
- QList<QDeclarativePrivate::AutoParentFunction> functions = QDeclarativeMetaType::parentFunctions();
-
- bool needParent = false;
-
- for (int ii = 0; ii < functions.count(); ++ii) {
- QDeclarativePrivate::AutoParentResult res = functions.at(ii)(ret, parent);
- if (res == QDeclarativePrivate::Parented) {
- needParent = false;
- break;
- } else if (res == QDeclarativePrivate::IncompatibleParent) {
- needParent = true;
- }
- }
-
- if (needParent)
- qWarning("QDeclarativeComponent: Created graphical object was not placed in the graphics scene.");
- }
-
- return completeCreateObjectWithInitialProperties(qmlGlobal, valuemap, ret);
-}
-
-QObject *QDeclarativeComponentPrivate::completeCreateObjectWithInitialProperties(v8::Handle<v8::Object> qmlGlobal, v8::Handle<v8::Object> valuemap, QObject *toCreate)
-{
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
- QV8Engine *v8engine = ep->v8engine();
- v8::Handle<v8::Value> ov = v8engine->newQObject(toCreate);
- Q_ASSERT(ov->IsObject());
- v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(ov);
-
- if (!valuemap.IsEmpty()) {
-
-#define SET_ARGS_SOURCE \
- "(function(object, values) {"\
- "try {"\
- "for(var property in values) {"\
- "try {"\
- "var properties = property.split(\".\");"\
- "var o = object;"\
- "for (var ii = 0; ii < properties.length - 1; ++ii) {"\
- "o = o[properties[ii]];"\
- "}"\
- "o[properties[properties.length - 1]] = values[property];"\
- "} catch(e) {}"\
- "}"\
- "} catch(e) {}"\
- "})"
-
- v8::Local<v8::Script> script = v8engine->qmlModeCompile(SET_ARGS_SOURCE);
- v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(script->Run(qmlGlobal));
-
- // Try catch isn't needed as the function itself is loaded with try/catch
- v8::Handle<v8::Value> args[] = { object, valuemap };
- function->Call(v8engine->global(), 2, args);
- }
-
- completeCreate();
-
- QDeclarativeData *ddata = QDeclarativeData::get(toCreate);
- Q_ASSERT(ddata);
- ddata->setImplicitDestructible();
-
- return v8engine->toQObject(object);
-}
-
-/*!
Create an object instance from this component. Returns 0 if creation
failed. \a context specifies the context within which to create the object
instance.
@@ -799,7 +680,7 @@ QObject *QDeclarativeComponent::create(QDeclarativeContext *context)
component.
Create an object instance from this component. Returns 0 if creation
- failed. \a context specifies the context within which to create the object
+ failed. \a publicContext specifies the context within which to create the object
instance.
When QDeclarativeComponent constructs an instance, it occurs in three steps:
@@ -816,20 +697,18 @@ QObject *QDeclarativeComponent::create(QDeclarativeContext *context)
communicate information to an instantiated component, as it allows their
initial values to be configured before property bindings take effect.
*/
-QObject *QDeclarativeComponent::beginCreate(QDeclarativeContext *context)
+QObject *QDeclarativeComponent::beginCreate(QDeclarativeContext *publicContext)
{
Q_D(QDeclarativeComponent);
- QObject *rv = d->beginCreate(context?QDeclarativeContextData::get(context):0, QBitField());
- if (rv) {
- QDeclarativeData *ddata = QDeclarativeData::get(rv);
- Q_ASSERT(ddata);
- ddata->indestructible = true;
- }
- return rv;
+
+ Q_ASSERT(publicContext);
+ QDeclarativeContextData *context = QDeclarativeContextData::get(publicContext);
+
+ return d->beginCreate(context);
}
QObject *
-QDeclarativeComponentPrivate::beginCreate(QDeclarativeContextData *context, const QBitField &bindings)
+QDeclarativeComponentPrivate::beginCreate(QDeclarativeContextData *context)
{
Q_Q(QDeclarativeComponent);
if (!context) {
@@ -857,105 +736,38 @@ QDeclarativeComponentPrivate::beginCreate(QDeclarativeContextData *context, cons
return 0;
}
- return begin(context, creationContext, cc, start, &state, 0, bindings);
-}
+ QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
-/*
- Try to do what's necessary for a reasonable display of the type
- name, but no more (just enough for the client to do more extensive cleanup).
+ bool isRoot = enginePriv->inProgressCreations == 0;
+ enginePriv->inProgressCreations++;
+ state.errors.clear();
+ state.completePending = true;
- Should only be called when debugging is enabled.
-*/
-static inline QString buildTypeNameForDebug(const QMetaObject *metaObject)
-{
- static const QString qmlMarker(QLatin1String("_QML"));
- static const QChar underscore(QLatin1Char('_'));
- static const QChar asterisk(QLatin1Char('*'));
- QDeclarativeType *type = QDeclarativeMetaType::qmlType(metaObject);
- QString typeName = type ? QLatin1String(type->qmlTypeName()) : QLatin1String(metaObject->className());
- if (!type) {
- //### optimize further?
- int marker = typeName.indexOf(qmlMarker);
- if (marker != -1 && marker < typeName.count() - 1) {
- if (typeName[marker + 1] == underscore) {
- const QString className = typeName.left(marker) + asterisk;
- type = QDeclarativeMetaType::qmlType(QMetaType::type(className.toLatin1()));
- if (type)
- typeName = QLatin1String(type->qmlTypeName());
- }
- }
- }
- return typeName;
-}
-
-QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *parentContext,
- QDeclarativeContextData *componentCreationContext,
- QDeclarativeCompiledData *component, int start,
- ConstructionState *state, QList<QDeclarativeError> *errors,
- const QBitField &bindings)
-{
- QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(parentContext->engine);
- bool isRoot = !enginePriv->inBeginCreate;
-
- Q_ASSERT(!isRoot || state); // Either this isn't a root component, or a state data must be provided
- Q_ASSERT((state != 0) ^ (errors != 0)); // One of state or errors (but not both) must be provided
-
- if (isRoot)
+ if (isRoot)
QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
- QDeclarativeContextData *ctxt = new QDeclarativeContextData;
- ctxt->isInternal = true;
- ctxt->url = component->url;
- ctxt->imports = component->importCache;
-
- // Nested global imports
- if (componentCreationContext && start != -1) {
- ctxt->importedScripts = componentCreationContext->importedScripts;
- for (int ii = 0; ii < ctxt->importedScripts.count(); ++ii)
- ctxt->importedScripts[ii] = qPersistentNew<v8::Object>(ctxt->importedScripts[ii]);
- }
-
- component->importCache->addref();
- ctxt->setParent(parentContext);
-
- enginePriv->inBeginCreate = true;
+ enginePriv->referenceScarceResources();
+ state.vme.init(context, cc, start, creationContext);
+ QObject *rv = state.vme.execute(&state.errors);
+ enginePriv->dereferenceScarceResources();
- QDeclarativeVME vme;
- enginePriv->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
- QObject *rv = vme.run(ctxt, component, start, bindings);
- enginePriv->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
-
- if (vme.isError()) {
- if(errors) *errors = vme.errors();
- else state->errors = vme.errors();
- }
-
- if (isRoot) {
- enginePriv->inBeginCreate = false;
-
- state->bindValues = enginePriv->bindValues;
- state->parserStatus = enginePriv->parserStatus;
- state->finalizedParserStatus = enginePriv->finalizedParserStatus;
- state->componentAttached = enginePriv->componentAttached;
- if (state->componentAttached)
- state->componentAttached->prev = &state->componentAttached;
-
- enginePriv->componentAttached = 0;
- enginePriv->bindValues.clear();
- enginePriv->parserStatus.clear();
- enginePriv->finalizedParserStatus.clear();
- state->completePending = true;
- enginePriv->inProgressCreations++;
+ if (rv) {
+ QDeclarativeData *ddata = QDeclarativeData::get(rv);
+ Q_ASSERT(ddata);
+ ddata->indestructible = true;
}
if (enginePriv->isDebugging && rv) {
- if (!parentContext->isInternal)
- parentContext->asQDeclarativeContextPrivate()->instances.append(rv);
- QDeclarativeEngineDebugService::instance()->objectCreated(parentContext->engine, rv);
+ if (!context->isInternal)
+ context->asQDeclarativeContextPrivate()->instances.append(rv);
+ QDeclarativeEngineDebugService::instance()->objectCreated(engine, rv);
if (isRoot) {
- QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, buildTypeNameForDebug(rv->metaObject()));
+ QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating,
+ buildTypeNameForDebug(rv->metaObject()));
QDeclarativeData *data = QDeclarativeData::get(rv);
- QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating, component->url, data ? data->lineNumber : -1);
+ Q_ASSERT(data);
+ QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating,
+ cc->url, data->lineNumber);
}
}
@@ -965,106 +777,23 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *parentCon
void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeEnginePrivate *enginePriv,
QObject *object, ConstructionState *state)
{
- bool isRoot = !enginePriv->inBeginCreate;
- enginePriv->inBeginCreate = true;
-
- QDeclarativeVME vme;
- vme.runDeferred(object);
-
- if (vme.isError())
- state->errors = vme.errors();
-
- if (isRoot) {
- enginePriv->inBeginCreate = false;
-
- state->bindValues = enginePriv->bindValues;
- state->parserStatus = enginePriv->parserStatus;
- state->finalizedParserStatus = enginePriv->finalizedParserStatus;
- state->componentAttached = enginePriv->componentAttached;
- if (state->componentAttached)
- state->componentAttached->prev = &state->componentAttached;
-
- enginePriv->componentAttached = 0;
- enginePriv->bindValues.clear();
- enginePriv->parserStatus.clear();
- enginePriv->finalizedParserStatus.clear();
- state->completePending = true;
- enginePriv->inProgressCreations++;
- }
+ enginePriv->inProgressCreations++;
+ state->errors.clear();
+ state->completePending = true;
+
+ state->vme.initDeferred(object);
+ state->vme.execute(&state->errors);
}
void QDeclarativeComponentPrivate::complete(QDeclarativeEnginePrivate *enginePriv, ConstructionState *state)
{
if (state->completePending) {
+ state->vme.complete();
- for (int ii = 0; ii < state->bindValues.count(); ++ii) {
- QDeclarativeEnginePrivate::SimpleList<QDeclarativeAbstractBinding> bv =
- state->bindValues.at(ii);
- for (int jj = 0; jj < bv.count; ++jj) {
- if(bv.at(jj)) {
- bv.at(jj)->m_mePtr = 0;
- bv.at(jj)->setEnabled(true, QDeclarativePropertyPrivate::BypassInterceptor |
- QDeclarativePropertyPrivate::DontRemoveBinding);
- }
- }
- QDeclarativeEnginePrivate::clear(bv);
- }
-
- for (int ii = 0; ii < state->parserStatus.count(); ++ii) {
- QDeclarativeEnginePrivate::SimpleList<QDeclarativeParserStatus> ps =
- state->parserStatus.at(ii);
-
- for (int jj = ps.count - 1; jj >= 0; --jj) {
- QDeclarativeParserStatus *status = ps.at(jj);
- if (status && status->d) {
- status->d = 0;
- status->componentComplete();
- }
- }
- QDeclarativeEnginePrivate::clear(ps);
- }
-
- for (int ii = 0; ii < state->finalizedParserStatus.count(); ++ii) {
- QPair<QDeclarativeGuard<QObject>, int> status = state->finalizedParserStatus.at(ii);
- QObject *obj = status.first;
- if (obj) {
- void *args[] = { 0 };
- QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod,
- status.second, args);
- }
- }
-
- //componentComplete() can register additional finalization objects
- //that are then never handled. Handle them manually here.
- if (1 == enginePriv->inProgressCreations) {
- for (int ii = 0; ii < enginePriv->finalizedParserStatus.count(); ++ii) {
- QPair<QDeclarativeGuard<QObject>, int> status = enginePriv->finalizedParserStatus.at(ii);
- QObject *obj = status.first;
- if (obj) {
- void *args[] = { 0 };
- QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod,
- status.second, args);
- }
- }
- enginePriv->finalizedParserStatus.clear();
- }
-
- while (state->componentAttached) {
- QDeclarativeComponentAttached *a = state->componentAttached;
- a->rem();
- QDeclarativeData *d = QDeclarativeData::get(a->parent());
- Q_ASSERT(d);
- Q_ASSERT(d->context);
- a->add(&d->context->componentAttached);
- emit a->completed();
- }
-
- state->bindValues.clear();
- state->parserStatus.clear();
- state->finalizedParserStatus.clear();
state->completePending = false;
enginePriv->inProgressCreations--;
+
if (0 == enginePriv->inProgressCreations) {
while (enginePriv->erroredBindings) {
enginePriv->warning(enginePriv->erroredBindings->error);
@@ -1121,9 +850,9 @@ QDeclarativeComponentAttached *QDeclarativeComponent::qmlAttachedProperties(QObj
if (!engine)
return a;
- if (QDeclarativeEnginePrivate::get(engine)->inBeginCreate) {
+ if (QDeclarativeEnginePrivate::get(engine)->activeVME) { // XXX should only be allowed during begin
QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine);
- a->add(&p->componentAttached);
+ a->add(&p->activeVME->componentAttached);
} else {
QDeclarativeData *d = QDeclarativeData::get(obj);
Q_ASSERT(d);
@@ -1134,4 +863,485 @@ QDeclarativeComponentAttached *QDeclarativeComponent::qmlAttachedProperties(QObj
return a;
}
+void QDeclarativeComponent::create(QDeclarativeIncubator &i, QDeclarativeContext *context,
+ QDeclarativeContext *forContext)
+{
+ Q_D(QDeclarativeComponent);
+
+ if (!context)
+ context = d->engine->rootContext();
+
+ QDeclarativeContextData *contextData = QDeclarativeContextData::get(context);
+ QDeclarativeContextData *forContextData = contextData;
+ if (forContext) forContextData = QDeclarativeContextData::get(forContext);
+
+ if (!contextData->isValid()) {
+ qWarning("QDeclarativeComponent: Cannot create a component in an invalid context");
+ return;
+ }
+
+ if (contextData->engine != d->engine) {
+ qWarning("QDeclarativeComponent: Must create component in context from the same QDeclarativeEngine");
+ return;
+ }
+
+ if (!isReady()) {
+ qWarning("QDeclarativeComponent: Component is not ready");
+ return;
+ }
+
+ i.clear();
+ QDeclarativeIncubatorPrivate *p = i.d;
+
+ QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(d->engine);
+
+ p->component = d->cc; p->component->addref();
+ p->vme.init(contextData, d->cc, d->start, d->creationContext);
+
+ enginePriv->incubate(i, forContextData);
+}
+
+class QV8IncubatorResource : public QV8ObjectResource,
+ public QDeclarativeIncubator
+{
+V8_RESOURCE_TYPE(IncubatorType)
+public:
+ QV8IncubatorResource(QV8Engine *engine, IncubationMode = Asynchronous);
+
+ static v8::Handle<v8::Value> StatusChangedGetter(v8::Local<v8::String>,
+ const v8::AccessorInfo& info);
+ static v8::Handle<v8::Value> StatusGetter(v8::Local<v8::String>,
+ const v8::AccessorInfo& info);
+ static v8::Handle<v8::Value> ObjectGetter(v8::Local<v8::String>,
+ const v8::AccessorInfo& info);
+ static v8::Handle<v8::Value> ForceCompletionGetter(v8::Local<v8::String>,
+ const v8::AccessorInfo& info);
+ static v8::Handle<v8::Value> ForceCompletion(const v8::Arguments &args);
+
+ static void StatusChangedSetter(v8::Local<v8::String>, v8::Local<v8::Value> value,
+ const v8::AccessorInfo& info);
+
+ void dispose();
+
+ v8::Persistent<v8::Object> me;
+ QDeclarativeGuard<QObject> parent;
+ v8::Persistent<v8::Value> valuemap;
+ v8::Persistent<v8::Object> qmlGlobal;
+protected:
+ virtual void statusChanged(Status);
+ virtual void setInitialState(QObject *);
+};
+
+static void QDeclarativeComponent_setQmlParent(QObject *me, QObject *parent)
+{
+ if (parent) {
+ me->setParent(parent);
+ typedef QDeclarativePrivate::AutoParentFunction APF;
+ QList<APF> functions = QDeclarativeMetaType::parentFunctions();
+
+ bool needParent = false;
+ for (int ii = 0; ii < functions.count(); ++ii) {
+ QDeclarativePrivate::AutoParentResult res = functions.at(ii)(me, parent);
+ if (res == QDeclarativePrivate::Parented) {
+ needParent = false;
+ break;
+ } else if (res == QDeclarativePrivate::IncompatibleParent) {
+ needParent = true;
+ }
+ }
+ if (needParent)
+ qWarning("QDeclarativeComponent: Created graphical object was not "
+ "placed in the graphics scene.");
+ }
+}
+
+/*!
+ \qmlmethod object Component::createObject(Item parent, object properties)
+
+ Creates and returns an object instance of this component that will have
+ the given \a parent and \a properties. The \a properties argument is optional.
+ Returns null if object creation fails.
+
+ The object will be created in the same context as the one in which the component
+ was created. This function will always return null when called on components
+ which were not created in QML.
+
+ If you wish to create an object without setting a parent, specify \c null for
+ the \a parent value. Note that if the returned object is to be displayed, you
+ must provide a valid \a parent value or set the returned object's \l{Item::parent}{parent}
+ property, or else the object will not be visible.
+
+ If a \a parent is not provided to createObject(), a reference to the returned object must be held so that
+ it is not destroyed by the garbage collector. This is true regardless of whether \l{Item::parent} is set afterwards,
+ since setting the Item parent does not change object ownership; only the graphical parent is changed.
+
+ As of QtQuick 1.1, this method accepts an optional \a properties argument that specifies a
+ map of initial property values for the created object. These values are applied before object
+ creation is finalized. (This is more efficient than setting property values after object creation,
+ particularly where large sets of property values are defined, and also allows property bindings
+ to be set up before the object is created.)
+
+ The \a properties argument is specified as a map of property-value items. For example, the code
+ below creates an object with initial \c x and \c y values of 100 and 200, respectively:
+
+ \js
+ var component = Qt.createComponent("Button.qml");
+ if (component.status == Component.Ready)
+ component.createObject(parent, {"x": 100, "y": 100});
+ \endjs
+
+ Dynamically created instances can be deleted with the \c destroy() method.
+ See \l {Dynamic Object Management in QML} for more information.
+*/
+void QDeclarativeComponent::createObject(QDeclarativeV8Function *args)
+{
+ Q_D(QDeclarativeComponent);
+ Q_ASSERT(d->engine);
+ Q_ASSERT(args);
+
+ QObject *parent = 0;
+ v8::Local<v8::Object> valuemap;
+
+ if (args->Length() >= 1)
+ parent = args->engine()->toQObject((*args)[0]);
+
+ if (args->Length() >= 2) {
+ v8::Local<v8::Value> v = (*args)[1];
+ if (!v->IsObject() || v->IsArray()) {
+ qmlInfo(this) << tr("createObject: value is not an object");
+ args->returnValue(v8::Null());
+ return;
+ }
+ valuemap = v8::Local<v8::Object>::Cast(v);
+ }
+
+ QV8Engine *v8engine = args->engine();
+
+ QDeclarativeContext *ctxt = creationContext();
+ if (!ctxt) ctxt = d->engine->rootContext();
+
+ QObject *rv = beginCreate(ctxt);
+
+ if (!rv) {
+ args->returnValue(v8::Null());
+ return;
+ }
+
+ QDeclarativeComponent_setQmlParent(rv, parent);
+
+ v8::Handle<v8::Value> ov = v8engine->newQObject(rv);
+ Q_ASSERT(ov->IsObject());
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(ov);
+
+ if (!valuemap.IsEmpty()) {
+ QDeclarativeComponentExtension *e = componentExtension(v8engine);
+ // Try catch isn't needed as the function itself is loaded with try/catch
+ v8::Handle<v8::Value> function = e->initialProperties->Run(args->qmlGlobal());
+ v8::Handle<v8::Value> args[] = { object, valuemap };
+ v8::Handle<v8::Function>::Cast(function)->Call(v8engine->global(), 2, args);
+ }
+
+ d->completeCreate();
+
+ Q_ASSERT(QDeclarativeData::get(rv));
+ QDeclarativeData::get(rv)->setImplicitDestructible();
+
+ if (!rv)
+ args->returnValue(v8::Null());
+ else
+ args->returnValue(object);
+}
+
+/*!
+ \qmlmethod object Component::incubateObject(Item parent, object properties, enum mode)
+
+ Creates an incubator for instance of this component. Incubators allow new component
+ instances to be instantiated asynchronously and not cause freezes in the UI.
+
+ The \a parent argument specifies the parent the created instance will have. Omitting the
+ parameter or passing null will create anobject with no parent. In this case, a reference
+ to the created object must be maintained by the application of the object will eventually
+ be garbage collected.
+
+ The \a properties argument is specified as a map of property-value items which will be
+ set on the created object during its construction. \a mode may be Qt.Synchronous or
+ Qt.Asynchronous and controls whether the instance is created synchronously or asynchronously.
+ The default is asynchronously. In some circumstances, even if Qt.Synchronous is specified,
+ the incubator may create the object asynchronously. This happens if the component calling
+ incubateObject() is itself being created asynchronously.
+
+ All three arguments are optional.
+
+ If successful, the method returns an incubator, otherwise null. The incubator has the following
+ properties:
+
+ \list
+ \i status The status of the incubator. Valid values are Component.Ready, Component.Loading and
+ Component.Error.
+ \i object The created object instance. Will only be available once the incubator is in the
+ Ready status.
+ \i onStatusChanged Specifies a callback function to be invoked when the status changes. The
+ status is passed as a parameter to the callback.
+ \i forceCompletion() Call to complete incubation synchronously.
+ \endlist
+
+ The following example demonstrates how to use an incubator:
+
+ \js
+ var component = Qt.createComponent("Button.qml");
+
+ var incubator = component.incubateObject(parent, { x: 10, y: 10 });
+ if (incubator.status != Component.Ready) {
+ incubator.onStatusChanged = function(status) {
+ if (status == Component.Ready) {
+ print ("Object", incubator.object, "is now ready!");
+ }
+ }
+ } else {
+ print ("Object", incubator.object, "is ready immediately!");
+ }
+ \endjs
+*/
+
+void QDeclarativeComponent::incubateObject(QDeclarativeV8Function *args)
+{
+ Q_D(QDeclarativeComponent);
+ Q_ASSERT(d->engine);
+ Q_ASSERT(args);
+
+ QObject *parent = 0;
+ v8::Local<v8::Object> valuemap;
+ QDeclarativeIncubator::IncubationMode mode = QDeclarativeIncubator::Asynchronous;
+
+ if (args->Length() >= 1)
+ parent = args->engine()->toQObject((*args)[0]);
+
+ if (args->Length() >= 2) {
+ v8::Local<v8::Value> v = (*args)[1];
+ if (v->IsNull()) {
+ } else if (!v->IsObject() || v->IsArray()) {
+ qmlInfo(this) << tr("createObject: value is not an object");
+ args->returnValue(v8::Null());
+ return;
+ } else {
+ valuemap = v8::Local<v8::Object>::Cast(v);
+ }
+ }
+
+ if (args->Length() >= 3) {
+ quint32 v = (*args)[2]->Uint32Value();
+ if (v == 0)
+ mode = QDeclarativeIncubator::Asynchronous;
+ else if (v == 1)
+ mode = QDeclarativeIncubator::AsynchronousIfNested;
+ }
+
+ QDeclarativeComponentExtension *e = componentExtension(args->engine());
+
+ QV8IncubatorResource *r = new QV8IncubatorResource(args->engine(), mode);
+ v8::Local<v8::Object> o = e->incubationConstructor->NewInstance();
+ o->SetExternalResource(r);
+
+ if (!valuemap.IsEmpty()) {
+ r->valuemap = qPersistentNew(valuemap);
+ r->qmlGlobal = qPersistentNew(args->qmlGlobal());
+ }
+ r->parent = parent;
+ r->me = qPersistentNew(o);
+
+ create(*r, creationContext());
+
+ if (r->status() == QDeclarativeIncubator::Null) {
+ r->dispose();
+ args->returnValue(v8::Null());
+ } else {
+ args->returnValue(o);
+ }
+}
+
+// XXX used by QSGLoader
+void QDeclarativeComponentPrivate::initializeObjectWithInitialProperties(v8::Handle<v8::Object> qmlGlobal, v8::Handle<v8::Object> valuemap, QObject *toCreate)
+{
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
+ QV8Engine *v8engine = ep->v8engine();
+
+ v8::HandleScope handle_scope;
+ v8::Context::Scope scope(v8engine->context());
+ v8::Handle<v8::Value> ov = v8engine->newQObject(toCreate);
+ Q_ASSERT(ov->IsObject());
+ v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(ov);
+
+ if (!valuemap.IsEmpty()) {
+ QDeclarativeComponentExtension *e = componentExtension(v8engine);
+ // Try catch isn't needed as the function itself is loaded with try/catch
+ v8::Handle<v8::Value> function = e->initialProperties->Run(qmlGlobal);
+ v8::Handle<v8::Value> args[] = { object, valuemap };
+ v8::Handle<v8::Function>::Cast(function)->Call(v8engine->global(), 2, args);
+ }
+
+ QDeclarativeData *ddata = QDeclarativeData::get(toCreate);
+ Q_ASSERT(ddata);
+ ddata->setImplicitDestructible();
+}
+
+
+QDeclarativeComponentExtension::QDeclarativeComponentExtension(QV8Engine *engine)
+{
+ v8::HandleScope handle_scope;
+ v8::Context::Scope scope(engine->context());
+
+ forceCompletion = qPersistentNew(V8FUNCTION(QV8IncubatorResource::ForceCompletion, engine));
+
+ {
+ v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
+ ft->InstanceTemplate()->SetHasExternalResource(true);
+ ft->InstanceTemplate()->SetInternalFieldCount(1);
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("onStatusChanged"),
+ QV8IncubatorResource::StatusChangedGetter,
+ QV8IncubatorResource::StatusChangedSetter);
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("status"),
+ QV8IncubatorResource::StatusGetter);
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("object"),
+ QV8IncubatorResource::ObjectGetter);
+ ft->InstanceTemplate()->SetAccessor(v8::String::New("forceCompletion"),
+ QV8IncubatorResource::ForceCompletionGetter);
+ incubationConstructor = qPersistentNew(ft->GetFunction());
+ }
+
+ {
+#define INITIALPROPERTIES_SOURCE \
+ "(function(object, values) {"\
+ "try {"\
+ "for(var property in values) {" \
+ "try {"\
+ "var properties = property.split(\".\");"\
+ "var o = object;"\
+ "for (var ii = 0; ii < properties.length - 1; ++ii) {"\
+ "o = o[properties[ii]];"\
+ "}"\
+ "o[properties[properties.length - 1]] = values[property];"\
+ "} catch(e) {}"\
+ "}"\
+ "} catch(e) {}"\
+ "})"
+ initialProperties = qPersistentNew(engine->qmlModeCompile(QLatin1String(INITIALPROPERTIES_SOURCE)));
+#undef INITIALPROPERTIES_SOURCE
+ }
+}
+
+v8::Handle<v8::Value> QV8IncubatorResource::ObjectGetter(v8::Local<v8::String>,
+ const v8::AccessorInfo& info)
+{
+ QV8IncubatorResource *r = v8_resource_check<QV8IncubatorResource>(info.This());
+ return r->engine->newQObject(r->object());
+}
+
+v8::Handle<v8::Value> QV8IncubatorResource::ForceCompletionGetter(v8::Local<v8::String>,
+ const v8::AccessorInfo& info)
+{
+ QV8IncubatorResource *r = v8_resource_check<QV8IncubatorResource>(info.This());
+ return componentExtension(r->engine)->forceCompletion;
+}
+
+v8::Handle<v8::Value> QV8IncubatorResource::ForceCompletion(const v8::Arguments &args)
+{
+ QV8IncubatorResource *r = v8_resource_cast<QV8IncubatorResource>(args.This());
+ if (!r)
+ V8THROW_TYPE("Not an incubator object");
+
+ r->forceCompletion();
+
+ return v8::Undefined();
+}
+
+v8::Handle<v8::Value> QV8IncubatorResource::StatusGetter(v8::Local<v8::String>,
+ const v8::AccessorInfo& info)
+{
+ QV8IncubatorResource *r = v8_resource_check<QV8IncubatorResource>(info.This());
+ return v8::Integer::NewFromUnsigned(r->status());
+}
+
+v8::Handle<v8::Value> QV8IncubatorResource::StatusChangedGetter(v8::Local<v8::String>,
+ const v8::AccessorInfo& info)
+{
+ return info.This()->GetInternalField(0);
+}
+
+void QV8IncubatorResource::StatusChangedSetter(v8::Local<v8::String>, v8::Local<v8::Value> value,
+ const v8::AccessorInfo& info)
+{
+ info.This()->SetInternalField(0, value);
+}
+
+QDeclarativeComponentExtension::~QDeclarativeComponentExtension()
+{
+ qPersistentDispose(incubationConstructor);
+ qPersistentDispose(initialProperties);
+}
+
+QV8IncubatorResource::QV8IncubatorResource(QV8Engine *engine, IncubationMode m)
+: QV8ObjectResource(engine), QDeclarativeIncubator(m)
+{
+}
+
+void QV8IncubatorResource::setInitialState(QObject *o)
+{
+ QDeclarativeComponent_setQmlParent(o, parent);
+
+ if (!valuemap.IsEmpty()) {
+ QDeclarativeComponentExtension *e = componentExtension(engine);
+
+ v8::HandleScope handle_scope;
+ v8::Context::Scope scope(engine->context());
+
+ v8::Handle<v8::Value> function = e->initialProperties->Run(qmlGlobal);
+ v8::Handle<v8::Value> args[] = { engine->newQObject(o), valuemap };
+ v8::Handle<v8::Function>::Cast(function)->Call(engine->global(), 2, args);
+
+ qPersistentDispose(valuemap);
+ qPersistentDispose(qmlGlobal);
+ }
+}
+
+void QV8IncubatorResource::dispose()
+{
+ qPersistentDispose(valuemap);
+ qPersistentDispose(qmlGlobal);
+ // No further status changes are forthcoming, so we no long need a self reference
+ qPersistentDispose(me);
+}
+
+void QV8IncubatorResource::statusChanged(Status s)
+{
+ if (s == Ready) {
+ Q_ASSERT(QDeclarativeData::get(object()));
+ QDeclarativeData::get(object())->setImplicitDestructible();
+ }
+
+ if (!me.IsEmpty()) { // Will be false in synchronous mode
+ v8::HandleScope scope;
+ v8::Local<v8::Value> callback = me->GetInternalField(0);
+
+ if (!callback.IsEmpty() && !callback->IsUndefined()) {
+
+ if (callback->IsFunction()) {
+ v8::Context::Scope context_scope(engine->context());
+ v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(callback);
+ v8::Handle<v8::Value> args[] = { v8::Integer::NewFromUnsigned(s) };
+ v8::TryCatch tc;
+ f->Call(me, 1, args);
+ if (tc.HasCaught()) {
+ QDeclarativeError error;
+ QDeclarativeExpressionPrivate::exceptionToError(tc.Message(), error);
+ QDeclarativeEnginePrivate::warning(QDeclarativeEnginePrivate::get(engine->engine()),
+ error);
+ }
+ }
+ }
+ }
+
+ if (s == Ready || s == Error)
+ dispose();
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecomponent.h b/src/declarative/qml/qdeclarativecomponent.h
index a3457d1446..385d3d3422 100644
--- a/src/declarative/qml/qdeclarativecomponent.h
+++ b/src/declarative/qml/qdeclarativecomponent.h
@@ -55,12 +55,15 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
-class QDeclarativeCompiledData;
class QByteArray;
-class QDeclarativeComponentPrivate;
class QDeclarativeEngine;
-class QDeclarativeComponentAttached;
+class QDeclarativeComponent;
+class QDeclarativeIncubator;
class QDeclarativeV8Function;
+class QDeclarativeCompiledData;
+class QDeclarativeComponentPrivate;
+class QDeclarativeComponentAttached;
+
class Q_DECLARATIVE_EXPORT QDeclarativeComponent : public QObject
{
Q_OBJECT
@@ -97,6 +100,9 @@ public:
virtual QObject *beginCreate(QDeclarativeContext *);
virtual void completeCreate();
+ void create(QDeclarativeIncubator &, QDeclarativeContext *context = 0,
+ QDeclarativeContext *forContext = 0);
+
QDeclarativeContext *creationContext() const;
static QDeclarativeComponentAttached *qmlAttachedProperties(QObject *);
@@ -112,6 +118,7 @@ Q_SIGNALS:
protected:
QDeclarativeComponent(QDeclarativeComponentPrivate &dd, QObject* parent);
Q_INVOKABLE void createObject(QDeclarativeV8Function *);
+ Q_INVOKABLE void incubateObject(QDeclarativeV8Function *);
private:
QDeclarativeComponent(QDeclarativeEngine *, QDeclarativeCompiledData *, int, QObject *parent);
diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h
index ba937491b7..ea68291942 100644
--- a/src/declarative/qml/qdeclarativecomponent_p.h
+++ b/src/declarative/qml/qdeclarativecomponent_p.h
@@ -55,10 +55,11 @@
#include "qdeclarativecomponent.h"
-#include "private/qv8_p.h"
-#include "private/qdeclarativeengine_p.h"
-#include "private/qdeclarativetypeloader_p.h"
-#include "private/qbitfield_p.h"
+#include <private/qv8_p.h>
+#include "qdeclarativeengine_p.h"
+#include "qdeclarativetypeloader_p.h"
+#include <private/qbitfield_p.h>
+#include "qdeclarativevme_p.h"
#include "qdeclarativeerror.h"
#include "qdeclarative.h"
@@ -84,10 +85,9 @@ class Q_AUTOTEST_EXPORT QDeclarativeComponentPrivate : public QObjectPrivate, pu
public:
QDeclarativeComponentPrivate() : typeData(0), progress(0.), start(-1), cc(0), engine(0), creationContext(0) {}
- QObject *beginCreate(QDeclarativeContextData *, const QBitField &);
+ QObject *beginCreate(QDeclarativeContextData *);
void completeCreate();
- QObject *createObjectWithInitialProperties(v8::Handle<v8::Object> qmlGlobal, v8::Handle<v8::Object> valuemap, QObject *parentObject);
- QObject *completeCreateObjectWithInitialProperties(v8::Handle<v8::Object> qmlGlobal, v8::Handle<v8::Object> valuemap, QObject *toCreate);
+ void initializeObjectWithInitialProperties(v8::Handle<v8::Object> qmlGlobal, v8::Handle<v8::Object> valuemap, QObject *toCreate);
QDeclarativeTypeData *typeData;
virtual void typeDataReady(QDeclarativeTypeData *);
@@ -102,25 +102,18 @@ public:
QDeclarativeCompiledData *cc;
struct ConstructionState {
- ConstructionState() : componentAttached(0), completePending(false) {}
- QList<QDeclarativeEnginePrivate::SimpleList<QDeclarativeAbstractBinding> > bindValues;
- QList<QDeclarativeEnginePrivate::SimpleList<QDeclarativeParserStatus> > parserStatus;
- QList<QPair<QDeclarativeGuard<QObject>, int> > finalizedParserStatus;
- QDeclarativeComponentAttached *componentAttached;
+ ConstructionState() : completePending(false) {}
+
+ QDeclarativeVME vme;
QList<QDeclarativeError> errors;
bool completePending;
};
ConstructionState state;
- static QObject *begin(QDeclarativeContextData *parentContext, QDeclarativeContextData *componentCreationContext,
- QDeclarativeCompiledData *component, int start,
- ConstructionState *state, QList<QDeclarativeError> *errors,
- const QBitField &bindings = QBitField());
static void beginDeferred(QDeclarativeEnginePrivate *enginePriv, QObject *object,
ConstructionState *state);
static void complete(QDeclarativeEnginePrivate *enginePriv, ConstructionState *state);
-
QDeclarativeEngine *engine;
QDeclarativeGuardedContextData creationContext;
@@ -155,8 +148,8 @@ Q_SIGNALS:
void destruction();
private:
+ friend class QDeclarativeVME;
friend class QDeclarativeContextData;
- friend class QDeclarativeComponentPrivate;
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp
index ff6e628c66..d4662cf43a 100644
--- a/src/declarative/qml/qdeclarativecontext.cpp
+++ b/src/declarative/qml/qdeclarativecontext.cpp
@@ -40,15 +40,15 @@
****************************************************************************/
#include "qdeclarativecontext.h"
-#include "private/qdeclarativecontext_p.h"
+#include "qdeclarativecontext_p.h"
-#include "private/qdeclarativecomponent_p.h"
-#include "private/qdeclarativeexpression_p.h"
-#include "private/qdeclarativeengine_p.h"
+#include "qdeclarativecomponent_p.h"
+#include "qdeclarativeexpression_p.h"
+#include "qdeclarativeengine_p.h"
#include "qdeclarativeengine.h"
#include "qdeclarativeinfo.h"
-#include "private/qdeclarativev4bindings_p.h"
-#include "private/qv8bindings_p.h"
+#include <private/qv4bindings_p.h>
+#include <private/qv8bindings_p.h>
#include <qjsengine.h>
#include <QtCore/qvarlengtharray.h>
@@ -510,17 +510,19 @@ QObject *QDeclarativeContextPrivate::context_at(QDeclarativeListProperty<QObject
QDeclarativeContextData::QDeclarativeContextData()
-: parent(0), engine(0), isInternal(false), ownedByParent(false), isJSContext(false), isPragmaLibraryContext(false),
- publicContext(0), propertyNames(0), contextObject(0), imports(0), childContexts(0), nextChild(0), prevChild(0),
- expressions(0), contextObjects(0), contextGuards(0), idValues(0), idValueCount(0), linkedContext(0),
- componentAttached(0), v4bindings(0), v8bindings(0)
+: parent(0), engine(0), isInternal(false), ownedByParent(false), isJSContext(false),
+ isPragmaLibraryContext(false), publicContext(0), activeVME(0), propertyNames(0), contextObject(0),
+ imports(0), childContexts(0), nextChild(0), prevChild(0), expressions(0), contextObjects(0),
+ contextGuards(0), idValues(0), idValueCount(0), linkedContext(0), componentAttached(0),
+ v4bindings(0), v8bindings(0)
{
}
QDeclarativeContextData::QDeclarativeContextData(QDeclarativeContext *ctxt)
-: parent(0), engine(0), isInternal(false), ownedByParent(false), isJSContext(false), isPragmaLibraryContext(false),
- publicContext(ctxt), propertyNames(0), contextObject(0), imports(0), childContexts(0), nextChild(0), prevChild(0),
- expressions(0), contextObjects(0), contextGuards(0), idValues(0), idValueCount(0), linkedContext(0),
+: parent(0), engine(0), isInternal(false), ownedByParent(false), isJSContext(false),
+ isPragmaLibraryContext(false), publicContext(ctxt), activeVME(0), propertyNames(0),
+ contextObject(0), imports(0), childContexts(0), nextChild(0), prevChild(0), expressions(0),
+ contextObjects(0), contextGuards(0), idValues(0), idValueCount(0), linkedContext(0),
componentAttached(0), v4bindings(0), v8bindings(0)
{
}
diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h
index 9a068bbf8d..ba4edb8e15 100644
--- a/src/declarative/qml/qdeclarativecontext_p.h
+++ b/src/declarative/qml/qdeclarativecontext_p.h
@@ -55,19 +55,19 @@
#include "qdeclarativecontext.h"
-#include "private/qdeclarativedata_p.h"
-#include "private/qdeclarativeintegercache_p.h"
-#include "private/qdeclarativetypenamecache_p.h"
-#include "private/qdeclarativenotifier_p.h"
+#include "qdeclarativedata_p.h"
+#include "qdeclarativeintegercache_p.h"
+#include "qdeclarativetypenamecache_p.h"
+#include "qdeclarativenotifier_p.h"
#include "qdeclarativelist.h"
-#include "private/qdeclarativescript_p.h"
+#include "qdeclarativescript_p.h"
#include <QtCore/qhash.h>
#include <QtDeclarative/qjsvalue.h>
#include <QtCore/qset.h>
#include <private/qobject_p.h>
-#include "private/qdeclarativeguard_p.h"
+#include "qdeclarativeguard_p.h"
#include <private/qv8_p.h>
@@ -80,7 +80,7 @@ class QDeclarativeEngine;
class QDeclarativeExpression;
class QDeclarativeExpressionPrivate;
class QDeclarativeAbstractExpression;
-class QDeclarativeV4Bindings;
+class QV4Bindings;
class QDeclarativeContextData;
class QDeclarativeContextPrivate : public QObjectPrivate
@@ -108,6 +108,7 @@ public:
static QObject *context_at(QDeclarativeListProperty<QObject> *, int);
};
+class QDeclarativeVME;
class QDeclarativeComponentAttached;
class QDeclarativeGuardedContextData;
class Q_DECLARATIVE_EXPORT QDeclarativeContextData
@@ -145,6 +146,10 @@ public:
quint32 dummy:28;
QDeclarativeContext *publicContext;
+ // VME that is constructing this context if any
+ // XXX remove if possible
+ QDeclarativeVME *activeVME;
+
// Property name cache
QDeclarativeIntegerCache *propertyNames;
@@ -201,7 +206,7 @@ public:
QDeclarativeComponentAttached *componentAttached;
// Optimized binding objects. Needed for deferred properties.
- QDeclarativeV4Bindings *v4bindings;
+ QV4Bindings *v4bindings;
QV8Bindings *v8bindings;
// Return the outermost id for obj, if any.
diff --git a/src/declarative/qml/qdeclarativecustomparser.cpp b/src/declarative/qml/qdeclarativecustomparser.cpp
index e806707a06..e783d3ac75 100644
--- a/src/declarative/qml/qdeclarativecustomparser.cpp
+++ b/src/declarative/qml/qdeclarativecustomparser.cpp
@@ -39,10 +39,10 @@
**
****************************************************************************/
-#include "private/qdeclarativecustomparser_p.h"
-#include "private/qdeclarativecustomparser_p_p.h"
+#include "qdeclarativecustomparser_p.h"
+#include "qdeclarativecustomparser_p_p.h"
-#include "private/qdeclarativecompiler_p.h"
+#include "qdeclarativecompiler_p.h"
#include <QtCore/qdebug.h>
@@ -114,7 +114,7 @@ QDeclarativeCustomParserProperty
QDeclarativeCustomParserNodePrivate::fromProperty(QDeclarativeScript::Property *p)
{
QDeclarativeCustomParserProperty prop;
- prop.d->name = p->name().toUtf8();
+ prop.d->name = p->name().toString();
prop.d->isList = p->values.isMany();
prop.d->location = p->location.start;
@@ -164,7 +164,7 @@ QDeclarativeCustomParserNode::~QDeclarativeCustomParserNode()
delete d; d = 0;
}
-QByteArray QDeclarativeCustomParserNode::name() const
+QString QDeclarativeCustomParserNode::name() const
{
return d->name;
}
@@ -204,7 +204,7 @@ QDeclarativeCustomParserProperty::~QDeclarativeCustomParserProperty()
delete d; d = 0;
}
-QByteArray QDeclarativeCustomParserProperty::name() const
+QString QDeclarativeCustomParserProperty::name() const
{
return d->name;
}
@@ -292,7 +292,7 @@ int QDeclarativeCustomParser::evaluateEnum(const QByteArray& script) const
Resolves \a name to a type, or 0 if it is not a type. This can be used
to type-check object nodes.
*/
-const QMetaObject *QDeclarativeCustomParser::resolveType(const QByteArray& name) const
+const QMetaObject *QDeclarativeCustomParser::resolveType(const QString& name) const
{
return compiler->resolveType(name);
}
@@ -302,7 +302,7 @@ const QMetaObject *QDeclarativeCustomParser::resolveType(const QByteArray& name)
used to construct the binding later. \a name
is used as the name of the rewritten function.
*/
-QDeclarativeBinding::Identifier QDeclarativeCustomParser::rewriteBinding(const QString& expression, const QByteArray& name)
+QDeclarativeBinding::Identifier QDeclarativeCustomParser::rewriteBinding(const QString& expression, const QString& name)
{
return compiler->rewriteBinding(expression, name);
}
diff --git a/src/declarative/qml/qdeclarativecustomparser_p.h b/src/declarative/qml/qdeclarativecustomparser_p.h
index 47b3ee8f8e..94b68652f4 100644
--- a/src/declarative/qml/qdeclarativecustomparser_p.h
+++ b/src/declarative/qml/qdeclarativecustomparser_p.h
@@ -53,10 +53,10 @@
// We mean it.
//
-#include "private/qdeclarativemetatype_p.h"
+#include "qdeclarativemetatype_p.h"
#include "qdeclarativeerror.h"
-#include "private/qdeclarativescript_p.h"
-#include "private/qdeclarativebinding_p.h"
+#include "qdeclarativescript_p.h"
+#include "qdeclarativebinding_p.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qxmlstream.h>
@@ -78,7 +78,7 @@ public:
QDeclarativeCustomParserProperty &operator=(const QDeclarativeCustomParserProperty &);
~QDeclarativeCustomParserProperty();
- QByteArray name() const;
+ QString name() const;
QDeclarativeScript::Location location() const;
bool isList() const;
@@ -101,7 +101,7 @@ public:
QDeclarativeCustomParserNode &operator=(const QDeclarativeCustomParserNode &);
~QDeclarativeCustomParserNode();
- QByteArray name() const;
+ QString name() const;
QDeclarativeScript::Location location() const;
QList<QDeclarativeCustomParserProperty> properties() const;
@@ -140,9 +140,9 @@ protected:
int evaluateEnum(const QByteArray&) const;
- const QMetaObject *resolveType(const QByteArray&) const;
+ const QMetaObject *resolveType(const QString&) const;
- QDeclarativeBinding::Identifier rewriteBinding(const QString&, const QByteArray&);
+ QDeclarativeBinding::Identifier rewriteBinding(const QString&, const QString&);
private:
QList<QDeclarativeError> exceptions;
diff --git a/src/declarative/qml/qdeclarativecustomparser_p_p.h b/src/declarative/qml/qdeclarativecustomparser_p_p.h
index b11cb3432d..7a9c58db23 100644
--- a/src/declarative/qml/qdeclarativecustomparser_p_p.h
+++ b/src/declarative/qml/qdeclarativecustomparser_p_p.h
@@ -53,9 +53,9 @@
// We mean it.
//
-#include "private/qdeclarativecustomparser_p.h"
+#include "qdeclarativecustomparser_p.h"
-#include "private/qdeclarativescript_p.h"
+#include "qdeclarativescript_p.h"
#include <QtCore/qglobal.h>
@@ -64,7 +64,7 @@ QT_BEGIN_NAMESPACE
class QDeclarativeCustomParserNodePrivate
{
public:
- QByteArray name;
+ QString name;
QList<QDeclarativeCustomParserProperty> properties;
QDeclarativeScript::Location location;
@@ -78,7 +78,7 @@ public:
QDeclarativeCustomParserPropertyPrivate()
: isList(false) {}
- QByteArray name;
+ QString name;
bool isList;
QDeclarativeScript::Location location;
QList<QVariant> values;
diff --git a/src/declarative/qml/qdeclarativedata_p.h b/src/declarative/qml/qdeclarativedata_p.h
index b987ffd6ea..1bebee5ef0 100644
--- a/src/declarative/qml/qdeclarativedata_p.h
+++ b/src/declarative/qml/qdeclarativedata_p.h
@@ -68,6 +68,7 @@ class QDeclarativePropertyCache;
class QDeclarativeContextData;
class QDeclarativeNotifier;
class QDeclarativeDataExtended;
+class QDeclarativeNotifierEndpoint;
// This class is structured in such a way, that simply zero'ing it is the
// default state for elemental object allocations. This is crucial in the
// workings of the QDeclarativeInstruction::CreateSimpleObject instruction.
@@ -77,22 +78,24 @@ class Q_DECLARATIVE_EXPORT QDeclarativeData : public QAbstractDeclarativeData
public:
QDeclarativeData()
: ownMemory(true), ownContext(false), indestructible(true), explicitIndestructibleSet(false),
- hasTaintedV8Object(false), context(0), outerContext(0), bindings(0), nextContextObject(0),
- prevContextObject(0), bindingBitsSize(0), bindingBits(0), lineNumber(0), columnNumber(0),
- deferredComponent(0), deferredIdx(0), v8objectid(0), propertyCache(0), guards(0),
- extendedData(0) {
+ hasTaintedV8Object(false), notifyList(0), context(0), outerContext(0), bindings(0),
+ nextContextObject(0), prevContextObject(0), bindingBitsSize(0), bindingBits(0),
+ lineNumber(0), columnNumber(0), deferredComponent(0), deferredIdx(0), v8objectid(0),
+ propertyCache(0), guards(0), extendedData(0) {
init();
- }
+ }
static inline void init() {
QAbstractDeclarativeData::destroyed = destroyed;
QAbstractDeclarativeData::parentChanged = parentChanged;
QAbstractDeclarativeData::objectNameChanged = objectNameChanged;
+ QAbstractDeclarativeData::signalEmitted = signalEmitted;
}
static void destroyed(QAbstractDeclarativeData *, QObject *);
static void parentChanged(QAbstractDeclarativeData *, QObject *, QObject *);
static void objectNameChanged(QAbstractDeclarativeData *, QObject *);
+ static void signalEmitted(QAbstractDeclarativeData *, QObject *, int, void **);
void destroyed(QObject *);
void parentChanged(QObject *, QObject *);
@@ -109,6 +112,23 @@ public:
quint32 hasTaintedV8Object:1;
quint32 dummy:27;
+ struct NotifyList {
+ quint64 connectionMask;
+
+ quint16 maximumTodoIndex;
+ quint16 notifiesSize;
+
+ QDeclarativeNotifierEndpoint *todo;
+ QDeclarativeNotifierEndpoint**notifies;
+ void layout();
+ private:
+ void layout(QDeclarativeNotifierEndpoint*);
+ };
+ NotifyList *notifyList;
+
+ inline QDeclarativeNotifierEndpoint *notify(int index);
+ void addNotify(int index, QDeclarativeNotifierEndpoint *);
+
// The context that created the C++ object
QDeclarativeContextData *context;
// The outermost context in which this object lives
@@ -163,6 +183,25 @@ private:
mutable QDeclarativeDataExtended *extendedData;
};
+QDeclarativeNotifierEndpoint *QDeclarativeData::notify(int index)
+{
+ Q_ASSERT(index <= 0xFFFF);
+
+ if (!notifyList || !(notifyList->connectionMask & (1 << (quint64(index) % 64)))) {
+ return 0;
+ } else if (index < notifyList->notifiesSize) {
+ return notifyList->notifies[index];
+ } else if (index <= notifyList->maximumTodoIndex) {
+ notifyList->layout();
+ }
+
+ if (index < notifyList->notifiesSize) {
+ return notifyList->notifies[index];
+ } else {
+ return 0;
+ }
+}
+
QT_END_NAMESPACE
#endif // QDECLARATIVEDATA_P_H
diff --git a/src/declarative/qml/qdeclarativedirparser.cpp b/src/declarative/qml/qdeclarativedirparser.cpp
index 69c323b3c6..0af6775b6e 100644
--- a/src/declarative/qml/qdeclarativedirparser.cpp
+++ b/src/declarative/qml/qdeclarativedirparser.cpp
@@ -39,9 +39,9 @@
**
****************************************************************************/
-#include "private/qdeclarativedirparser_p.h"
+#include "qdeclarativedirparser_p.h"
#include "qdeclarativeerror.h"
-#include <private/qdeclarativeglobal_p.h>
+#include "qdeclarativeglobal_p.h"
#include <QtCore/QTextStream>
#include <QtCore/QFile>
@@ -186,7 +186,7 @@ bool QDeclarativeDirParser::parse()
QString::fromUtf8("internal types require 2 arguments, but %1 were provided").arg(sectionCount - 1));
continue;
}
- Component entry(sections[1].toUtf8(), sections[2], -1, -1);
+ Component entry(sections[1], sections[2], -1, -1);
entry.internal = true;
_components.append(entry);
} else if (sections[0] == QLatin1String("typeinfo")) {
@@ -202,7 +202,7 @@ bool QDeclarativeDirParser::parse()
} else if (sectionCount == 2) {
// No version specified (should only be used for relative qmldir files)
- const Component entry(sections[0].toUtf8(), sections[1], -1, -1);
+ const Component entry(sections[0], sections[1], -1, -1);
_components.append(entry);
} else if (sectionCount == 3) {
const QString &version = sections[1];
@@ -220,7 +220,7 @@ bool QDeclarativeDirParser::parse()
const int minorVersion = version.mid(dotIndex + 1).toInt(&validVersionNumber);
if (validVersionNumber) {
- const Component entry(sections[0].toUtf8(), sections[2], majorVersion, minorVersion);
+ const Component entry(sections[0], sections[2], majorVersion, minorVersion);
_components.append(entry);
}
diff --git a/src/declarative/qml/qdeclarativedirparser_p.h b/src/declarative/qml/qdeclarativedirparser_p.h
index 8540747055..696c2e1932 100644
--- a/src/declarative/qml/qdeclarativedirparser_p.h
+++ b/src/declarative/qml/qdeclarativedirparser_p.h
@@ -98,11 +98,11 @@ public:
Component()
: majorVersion(0), minorVersion(0), internal(false) {}
- Component(const QByteArray &typeName, const QString &fileName, int majorVersion, int minorVersion)
+ Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion)
: typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion),
internal(false) {}
- QByteArray typeName;
+ QString typeName;
QString fileName;
int majorVersion;
int minorVersion;
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index f55c290aa0..3f12431767 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -39,64 +39,52 @@
**
****************************************************************************/
-#include "private/qdeclarativeengine_p.h"
+#include "qdeclarativeengine_p.h"
#include "qdeclarativeengine.h"
-#include "private/qdeclarativecontext_p.h"
-#include "private/qdeclarativecompiler_p.h"
+#include "qdeclarativecontext_p.h"
+#include "qdeclarativecompiler_p.h"
#include "qdeclarative.h"
#include "qdeclarativecontext.h"
#include "qdeclarativeexpression.h"
#include "qdeclarativecomponent.h"
-#include "private/qdeclarativebinding_p_p.h"
-#include "private/qdeclarativevme_p.h"
-#include "private/qdeclarativeenginedebugservice_p.h"
-#include "private/qdeclarativestringconverters_p.h"
-#include "private/qdeclarativexmlhttprequest_p.h"
-#include "private/qdeclarativesqldatabase_p.h"
+#include "qdeclarativebinding_p_p.h"
+#include "qdeclarativevme_p.h"
+#include <private/qdeclarativeenginedebugservice_p.h>
+#include "qdeclarativestringconverters_p.h"
+#include "qdeclarativexmlhttprequest_p.h"
+#include "qdeclarativesqldatabase_p.h"
#include "qdeclarativescriptstring.h"
-#include "private/qdeclarativeglobal_p.h"
-#include "private/qdeclarativeworkerscript_p.h"
-#include "private/qdeclarativecomponent_p.h"
+#include "qdeclarativeglobal_p.h"
+#include "qdeclarativeworkerscript_p.h"
+#include "qdeclarativecomponent_p.h"
#include "qdeclarativenetworkaccessmanagerfactory.h"
#include "qdeclarativeimageprovider.h"
-#include "private/qdeclarativedirparser_p.h"
+#include "qdeclarativedirparser_p.h"
#include "qdeclarativeextensioninterface.h"
-#include "private/qdeclarativelist_p.h"
-#include "private/qdeclarativetypenamecache_p.h"
-#include "private/qdeclarativenotifier_p.h"
-#include "private/qdeclarativedebugtrace_p.h"
-#include "private/qdeclarativeapplication_p.h"
-#include "private/qv8debugservice_p.h"
+#include "qdeclarativelist_p.h"
+#include "qdeclarativetypenamecache_p.h"
+#include "qdeclarativenotifier_p.h"
+#include <private/qdeclarativedebugtrace_p.h>
+#include <private/qdeclarativeapplication_p.h>
+#include <private/qv8debugservice_p.h>
+#include "qdeclarativeincubator.h"
+#include <private/qv8profilerservice_p.h>
#include <QtCore/qmetaobject.h>
-#include <QNetworkReply>
-#include <QNetworkRequest>
#include <QNetworkAccessManager>
-#include <QTimer>
-#include <QList>
-#include <QPair>
#include <QDebug>
#include <QMetaObject>
-#include <QStack>
-#include <QMap>
-#include <QPluginLoader>
-#include <QtGui/qfontdatabase.h>
-#include <QtCore/qlibraryinfo.h>
-#include <QtCore/qthreadstorage.h>
-#include <QtCore/qthread.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qdir.h>
#include <QtCore/qmutex.h>
-#include <QtGui/qcolor.h>
-#include <QtCore/qcryptographichash.h>
+#include <QtNetwork/qnetworkconfigmanager.h>
#include <private/qobject_p.h>
#include <private/qdeclarativeutilmodule_p.h>
#include <private/qsgitemsmodule_p.h>
#include <private/qsgparticlesmodule_p.h>
-#include <qsgtexture.h>
#ifdef Q_OS_WIN // for %APPDATA%
#include <qt_windows.h>
@@ -135,7 +123,7 @@ void qmlRegisterBaseTypes(const char *uri, int versionMajor, int versionMinor)
QObject. See the QObject documentation for further details.
*/
/*!
- \qmlproperty string QML:QtObject::objectName
+ \qmlproperty string QtObject::objectName
This property holds the QObject::objectName for this specific object instance.
This allows a C++ application to locate an item within a QML component
@@ -189,7 +177,7 @@ void QDeclarativeEnginePrivate::defineModule()
}
/*!
-\qmlclass QML:Qt QDeclarativeEnginePrivate
+\qmlclass Qt QDeclarativeEnginePrivate
\ingroup qml-utility-elements
\brief The QML global Qt object provides useful enums and functions from Qt.
@@ -224,11 +212,11 @@ data types. This is primarily useful when setting the properties of an item
when the property has one of the following types:
\list
-\o \c color - use \l{QML:Qt::rgba()}{Qt.rgba()}, \l{QML:Qt::hsla()}{Qt.hsla()}, \l{QML:Qt::darker()}{Qt.darker()}, \l{QML:Qt::lighter()}{Qt.lighter()} or \l{QML:Qt::tint()}{Qt.tint()}
-\o \c rect - use \l{QML:Qt::rect()}{Qt.rect()}
-\o \c point - use \l{QML:Qt::point()}{Qt.point()}
-\o \c size - use \l{QML:Qt::size()}{Qt.size()}
-\o \c vector3d - use \l{QML:Qt::vector3d()}{Qt.vector3d()}
+\o \c color - use \l{Qt::rgba()}{Qt.rgba()}, \l{Qt::hsla()}{Qt.hsla()}, \l{Qt::darker()}{Qt.darker()}, \l{Qt::lighter()}{Qt.lighter()} or \l{Qt::tint()}{Qt.tint()}
+\o \c rect - use \l{Qt::rect()}{Qt.rect()}
+\o \c point - use \l{Qt::point()}{Qt.point()}
+\o \c size - use \l{Qt::size()}{Qt.size()}
+\o \c vector3d - use \l{Qt::vector3d()}{Qt.vector3d()}
\endlist
There are also string based constructors for these types. See \l{qdeclarativebasictypes.html}{QML Basic Types} for more information.
@@ -238,12 +226,12 @@ There are also string based constructors for these types. See \l{qdeclarativebas
The Qt object contains several functions for formatting QDateTime, QDate and QTime values.
\list
- \o \l{QML:Qt::formatDateTime}{string Qt.formatDateTime(datetime date, variant format)}
- \o \l{QML:Qt::formatDate}{string Qt.formatDate(datetime date, variant format)}
- \o \l{QML:Qt::formatTime}{string Qt.formatTime(datetime date, variant format)}
+ \o \l{Qt::formatDateTime}{string Qt.formatDateTime(datetime date, variant format)}
+ \o \l{Qt::formatDate}{string Qt.formatDate(datetime date, variant format)}
+ \o \l{Qt::formatTime}{string Qt.formatTime(datetime date, variant format)}
\endlist
-The format specification is described at \l{QML:Qt::formatDateTime}{Qt.formatDateTime}.
+The format specification is described at \l{Qt::formatDateTime}{Qt.formatDateTime}.
\section1 Dynamic Object Creation
@@ -252,14 +240,14 @@ items from files or strings. See \l{Dynamic Object Management in QML} for an ove
of their use.
\list
- \o \l{QML:Qt::createComponent()}{object Qt.createComponent(url)}
- \o \l{QML:Qt::createQmlObject()}{object Qt.createQmlObject(string qml, object parent, string filepath)}
+ \o \l{Qt::createComponent()}{object Qt.createComponent(url)}
+ \o \l{Qt::createQmlObject()}{object Qt.createQmlObject(string qml, object parent, string filepath)}
\endlist
*/
/*!
- \qmlproperty object QML:Qt::application
+ \qmlproperty object Qt::application
\since QtQuick 1.1
The \c application object provides access to global application state
@@ -298,6 +286,13 @@ of their use.
\o Qt.RightToLeft - Text and graphics elements should be positioned
from right to left.
\endlist
+
+ \row
+ \o \c application.inputPanel
+ \o
+ This read-only property allows access to application's QInputPanel object
+ and all its properties and slots. See the QInputPanel documentation for
+ further details.
\endtable
The following example uses the \c application object to indicate
@@ -340,10 +335,10 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
: captureProperties(false), rootContext(0), isDebugging(false),
outputWarningsToStdErr(true), sharedContext(0), sharedScope(0),
cleanup(0), erroredBindings(0), inProgressCreations(0),
- workerScriptEngine(0), componentAttached(0), inBeginCreate(false),
+ workerScriptEngine(0), activeVME(0),
networkAccessManager(0), networkAccessManagerFactory(0),
scarceResourcesRefCount(0), typeLoader(e), importDatabase(e), uniqueId(1),
- sgContext(0)
+ incubatorCount(0), incubationController(0), sgContext(0), mutex(QMutex::Recursive)
{
if (!qt_QmlQtModule_registered) {
qt_QmlQtModule_registered = true;
@@ -358,8 +353,6 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
{
Q_ASSERT(inProgressCreations == 0);
- Q_ASSERT(bindValues.isEmpty());
- Q_ASSERT(parserStatus.isEmpty());
while (cleanup) {
QDeclarativeCleanup *c = cleanup;
@@ -370,6 +363,11 @@ QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
c->clear();
}
+ doDeleteInEngineThread();
+
+ if (incubationController) incubationController->d = 0;
+ incubationController = 0;
+
delete rootContext;
rootContext = 0;
@@ -385,21 +383,6 @@ QDeclarativeEnginePrivate::~QDeclarativeEnginePrivate()
}
}
-void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeAbstractBinding> &bvs)
-{
- bvs.clear();
-}
-
-void QDeclarativeEnginePrivate::clear(SimpleList<QDeclarativeParserStatus> &pss)
-{
- for (int ii = 0; ii < pss.count; ++ii) {
- QDeclarativeParserStatus *ps = pss.at(ii);
- if(ps)
- ps->d = 0;
- }
- pss.clear();
-}
-
void QDeclarativePrivate::qdeclarativeelement_destructor(QObject *o)
{
QObjectPrivate *p = QObjectPrivate::get(o);
@@ -427,9 +410,30 @@ void QDeclarativeData::objectNameChanged(QAbstractDeclarativeData *d, QObject *o
static_cast<QDeclarativeData *>(d)->objectNameChanged(o);
}
+void QDeclarativeData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int index, void **)
+{
+ QDeclarativeData *ddata = QDeclarativeData::get(object, false);
+ if (!ddata) return; // Probably being deleted
+
+ QDeclarativeNotifierEndpoint *ep = ddata->notify(index);
+ if (ep) QDeclarativeNotifier::emitNotify(ep);
+}
+
void QDeclarativeEnginePrivate::init()
{
Q_Q(QDeclarativeEngine);
+
+ static bool firstTime = true;
+ if (firstTime) {
+ // This is a nasty hack as QNetworkAccessManager will issue a
+ // BlockingQueuedConnection to the main thread if it is initialized for the
+ // first time on a non-main thread. This can cause a lockup if the main thread
+ // is blocking on the thread that initialize the network access manager.
+ QNetworkConfigurationManager man;
+
+ firstTime = false;
+ }
+
qRegisterMetaType<QVariant>("QVariant");
qRegisterMetaType<QDeclarativeScriptString>("QDeclarativeScriptString");
qRegisterMetaType<QJSValue>("QJSValue");
@@ -449,6 +453,8 @@ void QDeclarativeEnginePrivate::init()
isDebugging = true;
QDeclarativeEngineDebugService::instance()->addEngine(q);
QV8DebugService::instance()->addEngine(q);
+ QV8ProfilerService::instance()->addEngine(q);
+ QDeclarativeDebugTrace::addEngine(q);
}
}
@@ -511,8 +517,12 @@ QDeclarativeEngine::QDeclarativeEngine(QObject *parent)
QDeclarativeEngine::~QDeclarativeEngine()
{
Q_D(QDeclarativeEngine);
- if (d->isDebugging)
+ if (d->isDebugging) {
QDeclarativeEngineDebugService::instance()->remEngine(this);
+ QV8DebugService::instance()->removeEngine(this);
+ QV8ProfilerService::instance()->removeEngine(this);
+ QDeclarativeDebugTrace::removeEngine(this);
+ }
// if we are the parent of any of the qobject module api instances,
// we need to remove them from our internal list, in order to prevent
@@ -529,6 +539,9 @@ QDeclarativeEngine::~QDeclarativeEngine()
d->moduleApiInstances.remove(key);
}
}
+
+ // ensure we clean up QObjects with JS ownership
+ d->v8engine()->gc();
}
/*! \fn void QDeclarativeEngine::quit()
@@ -597,6 +610,16 @@ QDeclarativeNetworkAccessManagerFactory *QDeclarativeEngine::networkAccessManage
return d->networkAccessManagerFactory;
}
+void QDeclarativeEnginePrivate::registerFinalizeCallback(QObject *obj, int index)
+{
+ if (activeVME) {
+ activeVME->finalizeCallbacks.append(qMakePair(QDeclarativeGuard<QObject>(obj), index));
+ } else {
+ void *args[] = { 0 };
+ QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, index, args);
+ }
+}
+
QNetworkAccessManager *QDeclarativeEnginePrivate::createNetworkAccessManager(QObject *parent) const
{
QMutexLocker locker(&mutex);
@@ -912,6 +935,26 @@ QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject
return ddata->indestructible?CppOwnership:JavaScriptOwnership;
}
+bool QDeclarativeEngine::event(QEvent *e)
+{
+ Q_D(QDeclarativeEngine);
+ if (e->type() == QEvent::User)
+ d->doDeleteInEngineThread();
+
+ return QJSEngine::event(e);
+}
+
+void QDeclarativeEnginePrivate::doDeleteInEngineThread()
+{
+ QFieldList<Deletable, &Deletable::next> list;
+ mutex.lock();
+ list.copyAndClear(toDeleteInEngineThread);
+ mutex.unlock();
+
+ while (Deletable *d = list.takeFirst())
+ delete d;
+}
+
Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
{
QDeclarativeData *data = QDeclarativeData::get(object);
@@ -920,7 +963,7 @@ Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
if (QDeclarativeDebugService::isDebuggingEnabled()) {
QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
- QString typeName = type ? QLatin1String(type->qmlTypeName()) : QString::fromLatin1(object->metaObject()->className());
+ QString typeName = type ? type->qmlTypeName() : QString::fromUtf8(object->metaObject()->className());
QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, typeName);
if (data->outerContext)
QDeclarativeDebugTrace::rangeLocation(QDeclarativeDebugTrace::Creating, data->outerContext->url, data->lineNumber);
@@ -1013,6 +1056,80 @@ QDeclarativeDataExtended::~QDeclarativeDataExtended()
{
}
+void QDeclarativeData::NotifyList::layout(QDeclarativeNotifierEndpoint *endpoint)
+{
+ if (endpoint->next)
+ layout(endpoint->next);
+
+ int index = endpoint->sourceSignal;
+ index = qMin(index, 0xFFFF - 1);
+
+ endpoint->next = notifies[index];
+ if (endpoint->next) endpoint->next->prev = &endpoint->next;
+ endpoint->prev = &notifies[index];
+ notifies[index] = endpoint;
+}
+
+void QDeclarativeData::NotifyList::layout()
+{
+ Q_ASSERT(maximumTodoIndex >= notifiesSize);
+
+ if (todo) {
+ QDeclarativeNotifierEndpoint **old = notifies;
+ const int reallocSize = (maximumTodoIndex + 1) * sizeof(QDeclarativeNotifierEndpoint*);
+ notifies = (QDeclarativeNotifierEndpoint**)realloc(notifies, reallocSize);
+ const int memsetSize = (maximumTodoIndex - notifiesSize + 1) *
+ sizeof(QDeclarativeNotifierEndpoint*);
+ memset(notifies + notifiesSize, 0, memsetSize);
+
+ if (notifies != old) {
+ for (int ii = 0; ii < notifiesSize; ++ii)
+ if (notifies[ii])
+ notifies[ii]->prev = &notifies[ii];
+ }
+
+ notifiesSize = maximumTodoIndex + 1;
+
+ layout(todo);
+ }
+
+ maximumTodoIndex = 0;
+ todo = 0;
+}
+
+void QDeclarativeData::addNotify(int index, QDeclarativeNotifierEndpoint *endpoint)
+{
+ if (!notifyList) {
+ notifyList = (NotifyList *)malloc(sizeof(NotifyList));
+ notifyList->connectionMask = 0;
+ notifyList->maximumTodoIndex = 0;
+ notifyList->notifiesSize = 0;
+ notifyList->todo = 0;
+ notifyList->notifies = 0;
+ }
+
+ Q_ASSERT(!endpoint->isConnected());
+
+ index = qMin(index, 0xFFFF - 1);
+ notifyList->connectionMask |= (1 << (quint64(index) % 64));
+
+ if (index < notifyList->notifiesSize) {
+
+ endpoint->next = notifyList->notifies[index];
+ if (endpoint->next) endpoint->next->prev = &endpoint->next;
+ endpoint->prev = &notifyList->notifies[index];
+ notifyList->notifies[index] = endpoint;
+
+ } else {
+ notifyList->maximumTodoIndex = qMax(int(notifyList->maximumTodoIndex), index);
+
+ endpoint->next = notifyList->todo;
+ if (endpoint->next) endpoint->next->prev = &endpoint->next;
+ endpoint->prev = &notifyList->todo;
+ notifyList->todo = endpoint;
+ }
+}
+
QDeclarativeNotifier *QDeclarativeData::objectNameNotifier() const
{
if (!extendedData) extendedData = new QDeclarativeDataExtended;
@@ -1059,6 +1176,17 @@ void QDeclarativeData::destroyed(QObject *object)
guard->objectDestroyed(object);
}
+ if (notifyList) {
+ while (notifyList->todo)
+ notifyList->todo->disconnect();
+ for (int ii = 0; ii < notifyList->notifiesSize; ++ii) {
+ while (QDeclarativeNotifierEndpoint *ep = notifyList->notifies[ii])
+ ep->disconnect();
+ }
+ free(notifyList->notifies);
+ free(notifyList);
+ }
+
if (extendedData)
delete extendedData;
@@ -1468,6 +1596,7 @@ QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeTy
int maxMinorVersion = 0;
const QMetaObject *metaObject = type->metaObject();
+
while (metaObject) {
QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(),
type->majorVersion(), minorVersion);
@@ -1547,7 +1676,7 @@ QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeTy
if (overloadError) {
if (hasCopied) raw->release();
- error.setDescription(QLatin1String("Type ") + QString::fromUtf8(type->qmlTypeName()) + QLatin1String(" ") + QString::number(type->majorVersion()) + QLatin1String(".") + QString::number(minorVersion) + QLatin1String(" contains an illegal property \"") + overloadName + QLatin1String("\". This is an error in the type's implementation."));
+ error.setDescription(QLatin1String("Type ") + type->qmlTypeName() + QLatin1String(" ") + QString::number(type->majorVersion()) + QLatin1String(".") + QString::number(minorVersion) + QLatin1String(" contains an illegal property \"") + overloadName + QLatin1String("\". This is an error in the type's implementation."));
return 0;
}
@@ -1562,44 +1691,31 @@ QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeTy
return raw;
}
-void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
+QDeclarativeMetaType::ModuleApiInstance *
+QDeclarativeEnginePrivate::moduleApiInstance(const QDeclarativeMetaType::ModuleApi &module)
{
- QByteArray name = data->root->className();
-
- QByteArray ptr = name + '*';
- QByteArray lst = "QDeclarativeListProperty<" + name + '>';
-
- int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
- voidptr_constructor);
- int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
- voidptr_constructor);
-
- m_qmlLists.insert(lst_type, ptr_type);
- m_compositeTypes.insert(ptr_type, data);
- data->addref();
-}
+ Locker locker(this);
-bool QDeclarativeEnginePrivate::isList(int t) const
-{
- return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
-}
+ QDeclarativeMetaType::ModuleApiInstance *a = moduleApiInstances.value(module);
+ if (!a) {
+ a = new QDeclarativeMetaType::ModuleApiInstance;
+ a->scriptCallback = module.script;
+ a->qobjectCallback = module.qobject;
+ moduleApiInstances.insert(module, a);
+ }
-int QDeclarativeEnginePrivate::listType(int t) const
-{
- QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
- if (iter != m_qmlLists.end())
- return *iter;
- else
- return QDeclarativeMetaType::listType(t);
+ return a;
}
bool QDeclarativeEnginePrivate::isQObject(int t)
{
+ Locker locker(this);
return m_compositeTypes.contains(t) || QDeclarativeMetaType::isQObject(t);
}
QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
{
+ Locker locker(this);
int t = v.userType();
if (t == QMetaType::QObjectStar || m_compositeTypes.contains(t)) {
if (ok) *ok = true;
@@ -1611,6 +1727,7 @@ QObject *QDeclarativeEnginePrivate::toQObject(const QVariant &v, bool *ok) const
QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t) const
{
+ Locker locker(this);
if (m_compositeTypes.contains(t))
return QDeclarativeMetaType::Object;
else if (m_qmlLists.contains(t))
@@ -1619,8 +1736,25 @@ QDeclarativeMetaType::TypeCategory QDeclarativeEnginePrivate::typeCategory(int t
return QDeclarativeMetaType::typeCategory(t);
}
+bool QDeclarativeEnginePrivate::isList(int t) const
+{
+ Locker locker(this);
+ return m_qmlLists.contains(t) || QDeclarativeMetaType::isList(t);
+}
+
+int QDeclarativeEnginePrivate::listType(int t) const
+{
+ Locker locker(this);
+ QHash<int, int>::ConstIterator iter = m_qmlLists.find(t);
+ if (iter != m_qmlLists.end())
+ return *iter;
+ else
+ return QDeclarativeMetaType::listType(t);
+}
+
const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(int t) const
{
+ Locker locker(this);
QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
if (iter != m_compositeTypes.end()) {
return (*iter)->root;
@@ -1632,6 +1766,7 @@ const QMetaObject *QDeclarativeEnginePrivate::rawMetaObjectForType(int t) const
const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
{
+ Locker locker(this);
QHash<int, QDeclarativeCompiledData*>::ConstIterator iter = m_compositeTypes.find(t);
if (iter != m_compositeTypes.end()) {
return (*iter)->root;
@@ -1641,6 +1776,25 @@ const QMetaObject *QDeclarativeEnginePrivate::metaObjectForType(int t) const
}
}
+void QDeclarativeEnginePrivate::registerCompositeType(QDeclarativeCompiledData *data)
+{
+ QByteArray name = data->root->className();
+
+ QByteArray ptr = name + '*';
+ QByteArray lst = "QDeclarativeListProperty<" + name + '>';
+
+ int ptr_type = QMetaType::registerType(ptr.constData(), voidptr_destructor,
+ voidptr_constructor);
+ int lst_type = QMetaType::registerType(lst.constData(), voidptr_destructor,
+ voidptr_constructor);
+
+ data->addref();
+
+ Locker locker(this);
+ m_qmlLists.insert(lst_type, ptr_type);
+ m_compositeTypes.insert(ptr_type, data);
+}
+
bool QDeclarative_isFileCaseCorrect(const QString &fileName)
{
#if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
diff --git a/src/declarative/qml/qdeclarativeengine.h b/src/declarative/qml/qdeclarativeengine.h
index 25b254feaa..4d5aa34a36 100644
--- a/src/declarative/qml/qdeclarativeengine.h
+++ b/src/declarative/qml/qdeclarativeengine.h
@@ -66,6 +66,7 @@ class QScriptContext;
class QDeclarativeImageProvider;
class QNetworkAccessManager;
class QDeclarativeNetworkAccessManagerFactory;
+class QDeclarativeIncubationController;
class Q_DECLARATIVE_EXPORT QDeclarativeEngine : public QJSEngine
{
Q_PROPERTY(QString offlineStoragePath READ offlineStoragePath WRITE setOfflineStoragePath)
@@ -98,6 +99,9 @@ public:
QDeclarativeImageProvider *imageProvider(const QString &id) const;
void removeImageProvider(const QString &id);
+ void setIncubationController(QDeclarativeIncubationController *);
+ QDeclarativeIncubationController *incubationController() const;
+
void setOfflineStoragePath(const QString& dir);
QString offlineStoragePath() const;
@@ -116,6 +120,9 @@ public:
static void setObjectOwnership(QObject *, ObjectOwnership);
static ObjectOwnership objectOwnership(QObject *);
+protected:
+ virtual bool event(QEvent *);
+
Q_SIGNALS:
void quit();
void warnings(const QList<QDeclarativeError> &warnings);
diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h
index be4f714545..88eda390e3 100644
--- a/src/declarative/qml/qdeclarativeengine_p.h
+++ b/src/declarative/qml/qdeclarativeengine_p.h
@@ -55,26 +55,27 @@
#include "qdeclarativeengine.h"
-#include "private/qdeclarativetypeloader_p.h"
-#include "private/qdeclarativeimport_p.h"
-#include "private/qpodvector_p.h"
+#include "qdeclarativetypeloader_p.h"
+#include "qdeclarativeimport_p.h"
+#include <private/qpodvector_p.h>
#include "qdeclarative.h"
-#include "private/qdeclarativevaluetype_p.h"
+#include "qdeclarativevaluetype_p.h"
#include "qdeclarativecontext.h"
-#include "private/qdeclarativecontext_p.h"
+#include "qdeclarativecontext_p.h"
#include "qdeclarativeexpression.h"
#include "qdeclarativeimageprovider.h"
-#include "private/qdeclarativeproperty_p.h"
-#include "private/qdeclarativepropertycache_p.h"
-#include "private/qdeclarativemetatype_p.h"
-#include "private/qdeclarativedirparser_p.h"
-#include "private/qintrusivelist_p.h"
+#include "qdeclarativeproperty_p.h"
+#include "qdeclarativepropertycache_p.h"
+#include "qdeclarativemetatype_p.h"
+#include "qdeclarativedirparser_p.h"
+#include <private/qintrusivelist_p.h>
-#include <QtCore/qstring.h>
#include <QtCore/qlist.h>
#include <QtCore/qpair.h>
#include <QtCore/qstack.h>
#include <QtCore/qmutex.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qthread.h>
#include <private/qobject_p.h>
@@ -87,7 +88,6 @@ class QDeclarativeEngine;
class QDeclarativeContextPrivate;
class QDeclarativeExpression;
class QDeclarativeImportDatabase;
-class ScarceResourceData;
class QNetworkReply;
class QNetworkAccessManager;
class QDeclarativeNetworkAccessManagerFactory;
@@ -97,8 +97,10 @@ class QDeclarativeComponentAttached;
class QDeclarativeCleanup;
class QDeclarativeDelayedError;
class QDeclarativeWorkerScriptEngine;
+class QDeclarativeVME;
class QDir;
class QSGTexture;
+class QDeclarativeIncubator;
class QSGContext;
class Q_DECLARATIVE_EXPORT QDeclarativeEnginePrivate : public QObjectPrivate
@@ -146,42 +148,10 @@ public:
QUrl baseUrl;
- template<class T>
- struct SimpleList {
- SimpleList()
- : count(0), values(0) {}
- SimpleList(int r)
- : count(0), values(new T*[r]) {}
-
- int count;
- T **values;
-
- void append(T *v) {
- values[count++] = v;
- }
-
- T *at(int idx) const {
- return values[idx];
- }
-
- void clear() {
- delete [] values;
- }
- };
-
- static void clear(SimpleList<QDeclarativeAbstractBinding> &);
- static void clear(SimpleList<QDeclarativeParserStatus> &);
-
- QList<SimpleList<QDeclarativeAbstractBinding> > bindValues;
- QList<SimpleList<QDeclarativeParserStatus> > parserStatus;
- QList<QPair<QDeclarativeGuard<QObject>,int> > finalizedParserStatus;
- QDeclarativeComponentAttached *componentAttached;
+ typedef QPair<QDeclarativeGuard<QObject>,int> FinalizeCallback;
+ void registerFinalizeCallback(QObject *obj, int index);
- void registerFinalizedParserStatusObject(QObject *obj, int index) {
- finalizedParserStatus.append(qMakePair(QDeclarativeGuard<QObject>(obj), index));
- }
-
- bool inBeginCreate;
+ QDeclarativeVME *activeVME;
QNetworkAccessManager *createNetworkAccessManager(QObject *parent) const;
QNetworkAccessManager *getNetworkAccessManager() const;
@@ -211,32 +181,47 @@ public:
void referenceScarceResources();
void dereferenceScarceResources();
- mutable QMutex mutex;
-
QDeclarativeTypeLoader typeLoader;
QDeclarativeImportDatabase importDatabase;
QString offlineStoragePath;
mutable quint32 uniqueId;
- quint32 getUniqueId() const {
+ inline quint32 getUniqueId() const {
return uniqueId++;
}
QDeclarativeValueTypeFactory valueTypes;
- QHash<QDeclarativeMetaType::ModuleApi, QDeclarativeMetaType::ModuleApiInstance *> moduleApiInstances;
-
- QHash<const QMetaObject *, QDeclarativePropertyCache *> propertyCache;
- QHash<QPair<QDeclarativeType *, int>, QDeclarativePropertyCache *> typePropertyCache;
+ // Unfortunate workaround to avoid a circular dependency between
+ // qdeclarativeengine_p.h and qdeclarativeincubator_p.h
+ struct Incubator {
+ QIntrusiveListNode next;
+ // Unfortunate workaround for MSVC
+ QIntrusiveListNode nextWaitingFor;
+ };
+ QIntrusiveList<Incubator, &Incubator::next> incubatorList;
+ unsigned int incubatorCount;
+ QDeclarativeIncubationController *incubationController;
+ void incubate(QDeclarativeIncubator &, QDeclarativeContextData *);
+
+ // These methods may be called from any thread
+ inline bool isEngineThread() const;
+ inline static bool isEngineThread(const QDeclarativeEngine *);
+ template<typename T>
+ inline void deleteInEngineThread(T *);
+ template<typename T>
+ inline static void deleteInEngineThread(QDeclarativeEngine *, T *);
+
+ // These methods may be called from the loader thread
+ QDeclarativeMetaType::ModuleApiInstance *moduleApiInstance(const QDeclarativeMetaType::ModuleApi &module);
+
+ // These methods may be called from the loader thread
inline QDeclarativePropertyCache *cache(QObject *obj);
inline QDeclarativePropertyCache *cache(const QMetaObject *);
inline QDeclarativePropertyCache *cache(QDeclarativeType *, int, QDeclarativeError &error);
- QDeclarativePropertyCache *createCache(const QMetaObject *);
- QDeclarativePropertyCache *createCache(QDeclarativeType *, int, QDeclarativeError &error);
-
- void registerCompositeType(QDeclarativeCompiledData *);
+ // These methods may be called from the loader thread
bool isQObject(int);
QObject *toQObject(const QVariant &, bool *ok = 0) const;
QDeclarativeMetaType::TypeCategory typeCategory(int) const;
@@ -244,8 +229,7 @@ public:
int listType(int) const;
const QMetaObject *rawMetaObjectForType(int) const;
const QMetaObject *metaObjectForType(int) const;
- QHash<int, int> m_qmlLists;
- QHash<int, QDeclarativeCompiledData *> m_compositeTypes;
+ void registerCompositeType(QDeclarativeCompiledData *);
void sendQuit();
void warning(const QDeclarativeError &);
@@ -255,11 +239,12 @@ public:
static void warning(QDeclarativeEnginePrivate *, const QDeclarativeError &);
static void warning(QDeclarativeEnginePrivate *, const QList<QDeclarativeError> &);
- static QV8Engine *getV8Engine(QDeclarativeEngine *e) { return e->d_func()->v8engine(); }
- static QDeclarativeEnginePrivate *get(QDeclarativeEngine *e) { return e->d_func(); }
- static QDeclarativeEnginePrivate *get(QDeclarativeContext *c) { return (c && c->engine()) ? QDeclarativeEnginePrivate::get(c->engine()) : 0; }
- static QDeclarativeEnginePrivate *get(QDeclarativeContextData *c) { return (c && c->engine) ? QDeclarativeEnginePrivate::get(c->engine) : 0; }
- static QDeclarativeEngine *get(QDeclarativeEnginePrivate *p) { return p->q_func(); }
+ inline static QV8Engine *getV8Engine(QDeclarativeEngine *e);
+ inline static QDeclarativeEnginePrivate *get(QDeclarativeEngine *e);
+ inline static const QDeclarativeEnginePrivate *get(const QDeclarativeEngine *e);
+ inline static QDeclarativeEnginePrivate *get(QDeclarativeContext *c);
+ inline static QDeclarativeEnginePrivate *get(QDeclarativeContextData *c);
+ inline static QDeclarativeEngine *get(QDeclarativeEnginePrivate *p);
static QString urlToLocalFileOrQrc(const QUrl& url);
static QString urlToLocalFileOrQrc(const QString& url);
@@ -270,8 +255,149 @@ public:
static bool qml_debugging_enabled;
QSGContext *sgContext;
+
+ mutable QMutex mutex;
+
+private:
+ // Locker locks the QDeclarativeEnginePrivate data structures for read and write, if necessary.
+ // Currently, locking is only necessary if the threaded loader is running concurrently. If it is
+ // either idle, or is running with the main thread blocked, no locking is necessary. This way
+ // we only pay for locking when we have to.
+ // Consequently, this class should only be used to protect simple accesses or modifications of the
+ // QDeclarativeEnginePrivate structures or operations that can be guarenteed not to start activity
+ // on the loader thread.
+ // The Locker API is identical to QMutexLocker. Locker reuses the QDeclarativeEnginePrivate::mutex
+ // QMutex instance and multiple Lockers are recursive in the same thread.
+ class Locker
+ {
+ public:
+ inline Locker(const QDeclarativeEngine *);
+ inline Locker(const QDeclarativeEnginePrivate *);
+ inline ~Locker();
+
+ inline void unlock();
+ inline void relock();
+
+ private:
+ const QDeclarativeEnginePrivate *m_ep;
+ quint32 m_locked:1;
+ };
+
+ // Must be called locked
+ QDeclarativePropertyCache *createCache(const QMetaObject *);
+ QDeclarativePropertyCache *createCache(QDeclarativeType *, int, QDeclarativeError &error);
+
+ // These members must be protected by a QDeclarativeEnginePrivate::Locker as they are required by
+ // the threaded loader. Only access them through their respective accessor methods.
+ QHash<QDeclarativeMetaType::ModuleApi, QDeclarativeMetaType::ModuleApiInstance *> moduleApiInstances;
+ QHash<const QMetaObject *, QDeclarativePropertyCache *> propertyCache;
+ QHash<QPair<QDeclarativeType *, int>, QDeclarativePropertyCache *> typePropertyCache;
+ QHash<int, int> m_qmlLists;
+ QHash<int, QDeclarativeCompiledData *> m_compositeTypes;
+
+ // These members is protected by the full QDeclarativeEnginePrivate::mutex mutex
+ struct Deletable { Deletable():next(0) {} virtual ~Deletable() {} Deletable *next; };
+ QFieldList<Deletable, &Deletable::next> toDeleteInEngineThread;
+ void doDeleteInEngineThread();
};
+QDeclarativeEnginePrivate::Locker::Locker(const QDeclarativeEngine *e)
+: m_ep(QDeclarativeEnginePrivate::get(e))
+{
+ relock();
+}
+
+QDeclarativeEnginePrivate::Locker::Locker(const QDeclarativeEnginePrivate *e)
+: m_ep(e), m_locked(false)
+{
+ relock();
+}
+
+QDeclarativeEnginePrivate::Locker::~Locker()
+{
+ unlock();
+}
+
+void QDeclarativeEnginePrivate::Locker::unlock()
+{
+ if (m_locked) {
+ m_ep->mutex.unlock();
+ m_locked = false;
+ }
+}
+
+void QDeclarativeEnginePrivate::Locker::relock()
+{
+ Q_ASSERT(!m_locked);
+ if (m_ep->typeLoader.isConcurrent()) {
+ m_ep->mutex.lock();
+ m_locked = true;
+ }
+}
+
+/*!
+Returns true if the calling thread is the QDeclarativeEngine thread.
+*/
+bool QDeclarativeEnginePrivate::isEngineThread() const
+{
+ Q_Q(const QDeclarativeEngine);
+ return QThread::currentThread() == q->thread();
+}
+
+/*!
+Returns true if the calling thread is the QDeclarativeEngine \a engine thread.
+*/
+bool QDeclarativeEnginePrivate::isEngineThread(const QDeclarativeEngine *engine)
+{
+ Q_ASSERT(engine);
+ return QDeclarativeEnginePrivate::get(engine)->isEngineThread();
+}
+
+/*!
+Delete \a value in the engine thread. If the calling thread is the engine
+thread, \a value will be deleted immediately.
+
+This method should be used for *any* type that has resources that need to
+be freed in the engine thread. This is generally types that use V8 handles.
+As there is some small overhead in checking the current thread, it is best
+practice to check if any V8 handles actually need to be freed and delete
+the instance directly if not.
+*/
+template<typename T>
+void QDeclarativeEnginePrivate::deleteInEngineThread(T *value)
+{
+ Q_Q(QDeclarativeEngine);
+
+ Q_ASSERT(value);
+ if (isEngineThread()) {
+ delete value;
+ } else {
+ struct I : public Deletable {
+ I(T *value) : value(value) {}
+ ~I() { delete value; }
+ T *value;
+ };
+ I *i = new I(value);
+ mutex.lock();
+ bool wasEmpty = toDeleteInEngineThread.isEmpty();
+ toDeleteInEngineThread.append(i);
+ mutex.unlock();
+ if (wasEmpty)
+ QCoreApplication::postEvent(q, new QEvent(QEvent::User));
+ }
+}
+
+/*!
+Delete \a value in the \a engine thread. If the calling thread is the engine
+thread, \a value will be deleted immediately.
+*/
+template<typename T>
+void QDeclarativeEnginePrivate::deleteInEngineThread(QDeclarativeEngine *engine, T *value)
+{
+ Q_ASSERT(engine);
+ QDeclarativeEnginePrivate::get(engine)->deleteInEngineThread<T>(value);
+}
+
/*!
Returns a QDeclarativePropertyCache for \a obj if one is available.
@@ -279,12 +405,20 @@ If \a obj is null, being deleted or contains a dynamic meta object 0
is returned.
The returned cache is not referenced, so if it is to be stored, call addref().
+
+XXX thread There is a potential future race condition in this and all the cache()
+functions. As the QDeclarativePropertyCache is returned unreferenced, when called
+from the loader thread, it is possible that the cache will have been dereferenced
+and deleted before the loader thread has a chance to use or reference it. This
+can't currently happen as the cache holds a reference to the
+QDeclarativePropertyCache until the QDeclarativeEngine is destroyed.
*/
QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(QObject *obj)
{
if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted)
return 0;
+ Locker locker(this);
const QMetaObject *mo = obj->metaObject();
QDeclarativePropertyCache *rv = propertyCache.value(mo);
if (!rv) rv = createCache(mo);
@@ -304,6 +438,7 @@ QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(const QMetaObject *m
{
Q_ASSERT(metaObject);
+ Locker locker(this);
QDeclarativePropertyCache *rv = propertyCache.value(metaObject);
if (!rv) rv = createCache(metaObject);
return rv;
@@ -321,11 +456,42 @@ QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(QDeclarativeType *ty
if (minorVersion == -1 || !type->containsRevisionedAttributes())
return cache(type->metaObject());
+ Locker locker(this);
QDeclarativePropertyCache *rv = typePropertyCache.value(qMakePair(type, minorVersion));
if (!rv) rv = createCache(type, minorVersion, error);
return rv;
}
+QV8Engine *QDeclarativeEnginePrivate::getV8Engine(QDeclarativeEngine *e)
+{
+ return e->d_func()->v8engine();
+}
+
+QDeclarativeEnginePrivate *QDeclarativeEnginePrivate::get(QDeclarativeEngine *e)
+{
+ return e->d_func();
+}
+
+const QDeclarativeEnginePrivate *QDeclarativeEnginePrivate::get(const QDeclarativeEngine *e)
+{
+ return e->d_func();
+}
+
+QDeclarativeEnginePrivate *QDeclarativeEnginePrivate::get(QDeclarativeContext *c)
+{
+ return (c && c->engine()) ? QDeclarativeEnginePrivate::get(c->engine()) : 0;
+}
+
+QDeclarativeEnginePrivate *QDeclarativeEnginePrivate::get(QDeclarativeContextData *c)
+{
+ return (c && c->engine) ? QDeclarativeEnginePrivate::get(c->engine) : 0;
+}
+
+QDeclarativeEngine *QDeclarativeEnginePrivate::get(QDeclarativeEnginePrivate *p)
+{
+ return p->q_func();
+}
+
QT_END_NAMESPACE
#endif // QDECLARATIVEENGINE_P_H
diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp
index 4f6a71911f..d3ba92ab42 100644
--- a/src/declarative/qml/qdeclarativeexpression.cpp
+++ b/src/declarative/qml/qdeclarativeexpression.cpp
@@ -40,13 +40,13 @@
****************************************************************************/
#include "qdeclarativeexpression.h"
-#include "private/qdeclarativeexpression_p.h"
+#include "qdeclarativeexpression_p.h"
-#include "private/qdeclarativeengine_p.h"
-#include "private/qdeclarativecontext_p.h"
-#include "private/qdeclarativerewrite_p.h"
-#include "private/qdeclarativescriptstring_p.h"
-#include "private/qdeclarativecompiler_p.h"
+#include "qdeclarativeengine_p.h"
+#include "qdeclarativecontext_p.h"
+#include "qdeclarativerewrite_p.h"
+#include "qdeclarativescriptstring_p.h"
+#include "qdeclarativecompiler_p.h"
#include <QtCore/qdebug.h>
@@ -70,7 +70,7 @@ bool QDeclarativeDelayedError::addError(QDeclarativeEnginePrivate *e)
QDeclarativeJavaScriptExpression::QDeclarativeJavaScriptExpression()
: m_requiresThisObject(0), m_useSharedContext(0), m_notifyOnValueChanged(0),
- m_scopeObject(0), m_notifyObject(0), m_notifyIndex(-1)
+ m_scopeObject(0)
{
}
@@ -183,8 +183,6 @@ QDeclarativeExpressionPrivate::evalFunction(QDeclarativeContextData *ctxt, QObje
\endcode
*/
-static int QDeclarativeExpression_notifyIdx = -1;
-
/*!
Create an invalid QDeclarativeExpression.
@@ -194,11 +192,6 @@ static int QDeclarativeExpression_notifyIdx = -1;
QDeclarativeExpression::QDeclarativeExpression()
: QObject(*new QDeclarativeExpressionPrivate, 0)
{
- Q_D(QDeclarativeExpression);
-
- if (QDeclarativeExpression_notifyIdx == -1)
- QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
- d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
}
/*! \internal */
@@ -210,10 +203,6 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt,
{
Q_D(QDeclarativeExpression);
d->init(ctxt, expr, isRewritten, object, url, lineNumber);
-
- if (QDeclarativeExpression_notifyIdx == -1)
- QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
- d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
}
/*!
@@ -264,10 +253,6 @@ QDeclarativeExpression::QDeclarativeExpression(const QDeclarativeScriptString &s
if (defaultConstruction)
d->init(QDeclarativeContextData::get(script.context()), script.script(), script.scopeObject());
-
- if (QDeclarativeExpression_notifyIdx == -1)
- QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
- d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
}
/*!
@@ -285,10 +270,6 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt,
{
Q_D(QDeclarativeExpression);
d->init(QDeclarativeContextData::get(ctxt), expression, scope);
-
- if (QDeclarativeExpression_notifyIdx == -1)
- QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
- d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
}
/*!
@@ -300,10 +281,6 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QO
{
Q_D(QDeclarativeExpression);
d->init(ctxt, expression, scope);
-
- if (QDeclarativeExpression_notifyIdx == -1)
- QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
- d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
}
/*! \internal */
@@ -313,10 +290,6 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QO
{
Q_D(QDeclarativeExpression);
d->init(ctxt, expression, scope);
-
- if (QDeclarativeExpression_notifyIdx == -1)
- QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
- d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
}
/*!
@@ -335,11 +308,6 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QO
Q_D(QDeclarativeExpression);
d->init(ctxt, function, scope);
-
- if (QDeclarativeExpression_notifyIdx == -1)
- QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
-
- d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
}
/*!
@@ -436,23 +404,9 @@ void QDeclarativeJavaScriptExpression::resetNotifyOnValueChanged()
guardList.clear();
}
-void QDeclarativeJavaScriptExpression::setNotifyObject(QObject *object, int index)
-{
- guardList.clear();
-
- m_notifyObject = object;
- m_notifyIndex = index;
-
- if (!object || index == -1) {
- m_notifyObject = 0;
- m_notifyIndex = -1;
- }
-}
-
v8::Local<v8::Value> QDeclarativeJavaScriptExpression::evaluate(v8::Handle<v8::Function> function, bool *isUndefined)
{
Q_ASSERT(context() && context()->engine);
- Q_ASSERT(!notifyOnValueChanged() || (m_notifyObject && m_notifyIndex != -1));
if (function.IsEmpty() || function->IsUndefined()) {
if (isUndefined) *isUndefined = true;
@@ -518,7 +472,7 @@ v8::Local<v8::Value> QDeclarativeJavaScriptExpression::evaluate(v8::Handle<v8::F
}
if (!watcher.wasDeleted() && notifyOnValueChanged()) {
- guardList.updateGuards(m_notifyObject, m_notifyIndex, this, ep->capturedProperties);
+ guardList.updateGuards(this, ep->capturedProperties);
}
if (lastCapturedProperties.count())
@@ -531,20 +485,17 @@ v8::Local<v8::Value> QDeclarativeJavaScriptExpression::evaluate(v8::Handle<v8::F
return result;
}
-void QDeclarativeJavaScriptExpression::GuardList::updateGuards(QObject *notifyObject, int notifyIndex,
- QDeclarativeJavaScriptExpression *expression,
- const CapturedProperties &properties)
+void
+QDeclarativeJavaScriptExpression::GuardList::updateGuards(QDeclarativeJavaScriptExpression *expression,
+ const CapturedProperties &properties)
{
- Q_ASSERT(notifyObject);
- Q_ASSERT(notifyIndex != -1);
-
if (properties.count() == 0) {
clear();
return;
}
if (properties.count() != length) {
- QDeclarativeNotifierEndpoint *newGuardList = new QDeclarativeNotifierEndpoint[properties.count()];
+ Endpoint *newGuardList = new Endpoint[properties.count()];
for (int ii = 0; ii < qMin(length, properties.count()); ++ii)
endpoints[ii].copyAndClear(newGuardList[ii]);
@@ -557,53 +508,25 @@ void QDeclarativeJavaScriptExpression::GuardList::updateGuards(QObject *notifyOb
bool outputWarningHeader = false;
bool noChanges = true;
for (int ii = 0; ii < properties.count(); ++ii) {
- QDeclarativeNotifierEndpoint &guard = endpoints[ii];
+ Endpoint &guard = endpoints[ii];
const QDeclarativeEnginePrivate::CapturedProperty &property = properties.at(ii);
- guard.target = notifyObject;
- guard.targetMethod = notifyIndex;
+ guard.expression = expression;
if (property.notifier != 0) {
- if (!noChanges && guard.isConnected(property.notifier)) {
- // Nothing to do
-
+ if (guard.isConnected(property.notifier)) {
+ guard.cancelNotify();
} else {
- noChanges = false;
-
- bool existing = false;
- for (int jj = 0; !existing && jj < ii; ++jj)
- if (endpoints[jj].isConnected(property.notifier))
- existing = true;
-
- if (existing) {
- // duplicate
- guard.disconnect();
- } else {
- guard.connect(property.notifier);
- }
+ guard.connect(property.notifier);
}
-
} else if (property.notifyIndex != -1) {
- if (!noChanges && guard.isConnected(property.object, property.notifyIndex)) {
- // Nothing to do
-
- } else {
- noChanges = false;
-
- bool existing = false;
- for (int jj = 0; !existing && jj < ii; ++jj)
- if (endpoints[jj].isConnected(property.object, property.notifyIndex))
- existing = true;
-
- if (existing) {
- // duplicate
- guard.disconnect();
- } else {
- guard.connect(property.object, property.notifyIndex);
- }
+ if (guard.isConnected(property.object, property.notifyIndex)) {
+ guard.cancelNotify();
+ } else {
+ guard.connect(property.object, property.notifyIndex);
}
} else {
@@ -802,12 +725,6 @@ QDeclarativeError QDeclarativeExpression::error() const
return d->error;
}
-/*! \internal */
-void QDeclarativeExpressionPrivate::_q_notify()
-{
- emitValueChanged();
-}
-
/*!
\fn void QDeclarativeExpression::valueChanged()
@@ -816,7 +733,7 @@ void QDeclarativeExpressionPrivate::_q_notify()
calling QDeclarativeExpression::evaluate()) before this signal will be emitted.
*/
-void QDeclarativeExpressionPrivate::emitValueChanged()
+void QDeclarativeExpressionPrivate::expressionChanged()
{
Q_Q(QDeclarativeExpression);
emit q->valueChanged();
diff --git a/src/declarative/qml/qdeclarativeexpression.h b/src/declarative/qml/qdeclarativeexpression.h
index edd93a1240..ae4884ba82 100644
--- a/src/declarative/qml/qdeclarativeexpression.h
+++ b/src/declarative/qml/qdeclarativeexpression.h
@@ -106,7 +106,6 @@ private:
Q_DISABLE_COPY(QDeclarativeExpression)
Q_DECLARE_PRIVATE(QDeclarativeExpression)
- Q_PRIVATE_SLOT(d_func(), void _q_notify())
friend class QDeclarativeDebugger;
friend class QDeclarativeContext;
friend class QDeclarativeVME;
diff --git a/src/declarative/qml/qdeclarativeexpression_p.h b/src/declarative/qml/qdeclarativeexpression_p.h
index e9ee69960e..4e31efb806 100644
--- a/src/declarative/qml/qdeclarativeexpression_p.h
+++ b/src/declarative/qml/qdeclarativeexpression_p.h
@@ -147,11 +147,12 @@ public:
void setNotifyOnValueChanged(bool v);
void resetNotifyOnValueChanged();
- void setNotifyObject(QObject *, int );
inline QObject *scopeObject() const;
inline void setScopeObject(QObject *v);
+ virtual void expressionChanged() {}
+
protected:
inline virtual QString expressionIdentifier();
@@ -162,8 +163,6 @@ private:
quint32 m_dummy:29;
QObject *m_scopeObject;
- QObject *m_notifyObject;
- int m_notifyIndex;
class GuardList {
public:
@@ -172,11 +171,18 @@ private:
void inline clear();
typedef QPODVector<QDeclarativeEnginePrivate::CapturedProperty> CapturedProperties;
- void updateGuards(QObject *guardObject, int guardObjectNotifyIndex,
- QDeclarativeJavaScriptExpression *, const CapturedProperties &properties);
+ void updateGuards(QDeclarativeJavaScriptExpression *, const CapturedProperties &properties);
private:
- QDeclarativeNotifierEndpoint *endpoints;
+ struct Endpoint : public QDeclarativeNotifierEndpoint {
+ Endpoint() : expression(0) { callback = &endpointCallback; }
+ static void endpointCallback(QDeclarativeNotifierEndpoint *e) {
+ static_cast<Endpoint *>(e)->expression->expressionChanged();
+ }
+ QDeclarativeJavaScriptExpression *expression;
+ };
+
+ Endpoint *endpoints;
int length;
};
GuardList guardList;
@@ -203,7 +209,7 @@ public:
static inline QDeclarativeExpression *get(QDeclarativeExpressionPrivate *expr);
void _q_notify();
- virtual void emitValueChanged();
+ virtual void expressionChanged();
static void exceptionToError(v8::Handle<v8::Message>, QDeclarativeError &);
static v8::Persistent<v8::Function> evalFunction(QDeclarativeContextData *ctxt, QObject *scope,
@@ -222,7 +228,7 @@ public:
QString url; // This is a QString for a reason. QUrls are slooooooow...
int line;
- QByteArray name; //function name, hint for the debugger
+ QString name; //function name, hint for the debugger
QDeclarativeRefCount *dataRef;
};
diff --git a/src/declarative/qml/qdeclarativeextensioninterface.h b/src/declarative/qml/qdeclarativeextensioninterface.h
index 29e856bf49..5b621e4883 100644
--- a/src/declarative/qml/qdeclarativeextensioninterface.h
+++ b/src/declarative/qml/qdeclarativeextensioninterface.h
@@ -52,13 +52,21 @@ QT_MODULE(Declarative)
class QDeclarativeEngine;
-struct Q_DECLARATIVE_EXPORT QDeclarativeExtensionInterface
+class Q_DECLARATIVE_EXPORT QDeclarativeTypesExtensionInterface
{
- virtual ~QDeclarativeExtensionInterface() {}
+public:
+ virtual ~QDeclarativeTypesExtensionInterface() {}
virtual void registerTypes(const char *uri) = 0;
+};
+
+class Q_DECLARATIVE_EXPORT QDeclarativeExtensionInterface : public QDeclarativeTypesExtensionInterface
+{
+public:
+ virtual ~QDeclarativeExtensionInterface() {}
virtual void initializeEngine(QDeclarativeEngine *engine, const char *uri) = 0;
};
+Q_DECLARE_INTERFACE(QDeclarativeTypesExtensionInterface, "com.trolltech.Qt.QDeclarativeTypesExtensionInterface/1.0")
Q_DECLARE_INTERFACE(QDeclarativeExtensionInterface, "com.trolltech.Qt.QDeclarativeExtensionInterface/1.0")
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativeextensionplugin.h b/src/declarative/qml/qdeclarativeextensionplugin.h
index a249fba9b9..fbc609990a 100644
--- a/src/declarative/qml/qdeclarativeextensionplugin.h
+++ b/src/declarative/qml/qdeclarativeextensionplugin.h
@@ -54,10 +54,12 @@ QT_MODULE(Declarative)
class QDeclarativeEngine;
-class Q_DECLARATIVE_EXPORT QDeclarativeExtensionPlugin : public QObject, public QDeclarativeExtensionInterface
+class Q_DECLARATIVE_EXPORT QDeclarativeExtensionPlugin : public QObject,
+ public QDeclarativeExtensionInterface
{
Q_OBJECT
Q_INTERFACES(QDeclarativeExtensionInterface)
+ Q_INTERFACES(QDeclarativeTypesExtensionInterface)
public:
explicit QDeclarativeExtensionPlugin(QObject *parent = 0);
~QDeclarativeExtensionPlugin();
diff --git a/src/declarative/qml/qdeclarativefastproperties.cpp b/src/declarative/qml/qdeclarativefastproperties.cpp
index 93703e2bdc..5816b3f8cb 100644
--- a/src/declarative/qml/qdeclarativefastproperties.cpp
+++ b/src/declarative/qml/qdeclarativefastproperties.cpp
@@ -39,10 +39,10 @@
**
****************************************************************************/
-#include "private/qdeclarativefastproperties_p.h"
+#include "qdeclarativefastproperties_p.h"
-#include <private/qdeclarativedata_p.h>
-#include <private/qdeclarativenotifier_p.h>
+#include "qdeclarativedata_p.h"
+#include "qdeclarativenotifier_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativeglobal_p.h b/src/declarative/qml/qdeclarativeglobal_p.h
index 87be79f171..cc0a4b6b1d 100644
--- a/src/declarative/qml/qdeclarativeglobal_p.h
+++ b/src/declarative/qml/qdeclarativeglobal_p.h
@@ -64,6 +64,32 @@ QT_MODULE(Declarative)
return status == Yes; \
}
+#define FAST_CONNECT(Sender, Signal, Receiver, Method) \
+{ \
+ QObject *sender = (Sender); \
+ QObject *receiver = (Receiver); \
+ const char *signal = (Signal); \
+ const char *method = (Method); \
+ static int signalIdx = -1; \
+ static int methodIdx = -1; \
+ if (signalIdx < 0) { \
+ if (((int)(*signal) - '0') == QSIGNAL_CODE) \
+ signalIdx = sender->metaObject()->indexOfSignal(signal+1); \
+ else \
+ qWarning("FAST_CONNECT: Invalid signal %s. Please make sure you are using the SIGNAL macro.", signal); \
+ } \
+ if (methodIdx < 0) { \
+ int code = ((int)(*method) - '0'); \
+ if (code == QSLOT_CODE) \
+ methodIdx = receiver->metaObject()->indexOfSlot(method+1); \
+ else if (code == QSIGNAL_CODE) \
+ methodIdx = receiver->metaObject()->indexOfSignal(method+1); \
+ else \
+ qWarning("FAST_CONNECT: Invalid method %s. Please make sure you are using the SIGNAL or SLOT macro.", method); \
+ } \
+ QMetaObject::connect(sender, signalIdx, receiver, methodIdx, Qt::DirectConnection); \
+}
+
#ifdef Q_OS_SYMBIAN
#define Q_DECLARATIVE_PRIVATE_EXPORT Q_AUTOTEST_EXPORT
#else
diff --git a/src/declarative/qml/qdeclarativeguard_p.h b/src/declarative/qml/qdeclarativeguard_p.h
index 393f2b0ee7..0dc9a5a831 100644
--- a/src/declarative/qml/qdeclarativeguard_p.h
+++ b/src/declarative/qml/qdeclarativeguard_p.h
@@ -108,8 +108,12 @@ protected:
virtual void objectDestroyed(T *) {}
};
+QT_END_NAMESPACE
+
Q_DECLARE_METATYPE(QDeclarativeGuard<QObject>)
+QT_BEGIN_NAMESPACE
+
QDeclarativeGuardImpl::QDeclarativeGuardImpl()
: o(0), next(0), prev(0)
{
diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp
index 64bdaf108a..f94e9e4bae 100644
--- a/src/declarative/qml/qdeclarativeimport.cpp
+++ b/src/declarative/qml/qdeclarativeimport.cpp
@@ -52,7 +52,7 @@
#include <private/qdeclarativeengine_p.h>
#ifdef Q_OS_SYMBIAN
-#include "private/qcore_symbian_p.h"
+#include <private/qcore_symbian_p.h>
#endif
QT_BEGIN_NAMESPACE
@@ -213,19 +213,10 @@ void QDeclarativeImports::populateCache(QDeclarativeTypeNameCache *cache, QDecla
QDeclarativeMetaType::ModuleApi moduleApi = QDeclarativeMetaType::moduleApi(data.uri, data.majversion, data.minversion);
if (moduleApi.script || moduleApi.qobject) {
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
- QDeclarativeMetaType::ModuleApiInstance *a = ep->moduleApiInstances.value(moduleApi);
- if (!a) {
- a = new QDeclarativeMetaType::ModuleApiInstance;
- a->scriptCallback = moduleApi.script;
- a->qobjectCallback = moduleApi.qobject;
- ep->moduleApiInstances.insert(moduleApi, a);
- }
- import.moduleApi = a;
+ import.moduleApi = ep->moduleApiInstance(moduleApi);
}
}
}
-
-
}
/*!
@@ -1092,22 +1083,29 @@ bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QSt
return false;
}
- if (QDeclarativeExtensionInterface *iface = qobject_cast<QDeclarativeExtensionInterface *>(loader.instance())) {
+ QObject *instance = loader.instance();
+ if (QDeclarativeTypesExtensionInterface *iface = qobject_cast<QDeclarativeExtensionInterface *>(instance)) {
const QByteArray bytes = uri.toUtf8();
const char *moduleId = bytes.constData();
if (!typesRegistered) {
- // ### this code should probably be protected with a mutex.
+ // XXX thread this code should probably be protected with a mutex.
qmlEnginePluginsWithRegisteredTypes()->insert(absoluteFilePath, uri);
iface->registerTypes(moduleId);
}
if (!engineInitialized) {
- // things on the engine (eg. adding new global objects) have to be done for every engine.
-
- // protect against double initialization
+ // things on the engine (eg. adding new global objects) have to be done for every
+ // engine.
+ // XXX protect against double initialization
initializedPlugins.insert(absoluteFilePath);
- iface->initializeEngine(engine, moduleId);
+
+ QDeclarativeExtensionInterface *eiface =
+ qobject_cast<QDeclarativeExtensionInterface *>(instance);
+ if (eiface) {
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
+ ep->typeLoader.initializeEngine(eiface, moduleId);
+ }
}
} else {
if (errors) {
diff --git a/src/declarative/qml/qdeclarativeimport_p.h b/src/declarative/qml/qdeclarativeimport_p.h
index 7f0b499881..7da4aa5ca1 100644
--- a/src/declarative/qml/qdeclarativeimport_p.h
+++ b/src/declarative/qml/qdeclarativeimport_p.h
@@ -134,6 +134,7 @@ private:
const QString &baseName);
+ // XXX thread
QStringList filePluginPath;
QStringList fileImportPath;
diff --git a/src/declarative/qml/qdeclarativeincubator.cpp b/src/declarative/qml/qdeclarativeincubator.cpp
new file mode 100644
index 0000000000..05c73da3a2
--- /dev/null
+++ b/src/declarative/qml/qdeclarativeincubator.cpp
@@ -0,0 +1,686 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativeincubator.h"
+#include "qdeclarativecomponent.h"
+#include "qdeclarativeincubator_p.h"
+
+#include "qdeclarativecompiler_p.h"
+#include "qdeclarativeexpression_p.h"
+
+// XXX TODO
+// - check that the Component.onCompleted behavior is the same as 4.8 in the synchronous and
+// async if nested cases
+void QDeclarativeEnginePrivate::incubate(QDeclarativeIncubator &i, QDeclarativeContextData *forContext)
+{
+ QDeclarativeIncubatorPrivate *p = i.d;
+
+ QDeclarativeIncubator::IncubationMode mode = i.incubationMode();
+
+ if (!incubationController)
+ mode = QDeclarativeIncubator::Synchronous;
+
+ if (mode == QDeclarativeIncubator::AsynchronousIfNested) {
+ mode = QDeclarativeIncubator::Synchronous;
+
+ // Need to find the first constructing context and see if it is asynchronous
+ QDeclarativeIncubatorPrivate *parentIncubator = 0;
+ QDeclarativeContextData *cctxt = forContext;
+ while (cctxt) {
+ if (cctxt->activeVME) {
+ parentIncubator = (QDeclarativeIncubatorPrivate *)cctxt->activeVME->data;
+ break;
+ }
+ cctxt = cctxt->parent;
+ }
+
+ if (parentIncubator && parentIncubator->isAsynchronous) {
+ mode = QDeclarativeIncubator::Asynchronous;
+ p->waitingOnMe = parentIncubator;
+ parentIncubator->waitingFor.insert(p);
+ }
+ }
+
+ p->isAsynchronous = (mode != QDeclarativeIncubator::Synchronous);
+
+ inProgressCreations++;
+
+ if (mode == QDeclarativeIncubator::Synchronous) {
+ typedef QDeclarativeIncubatorPrivate IP;
+ QRecursionWatcher<IP, &IP::recursion> watcher(p);
+
+ p->changeStatus(QDeclarativeIncubator::Loading);
+
+ if (!watcher.hasRecursed()) {
+ QDeclarativeVME::Interrupt i;
+ p->incubate(i);
+ }
+ } else {
+ incubatorList.insert(p);
+ incubatorCount++;
+
+ p->changeStatus(QDeclarativeIncubator::Loading);
+
+ if (incubationController)
+ incubationController->incubatingObjectCountChanged(incubatorCount);
+ }
+}
+
+/*!
+Sets the engine's incubation \a controller. The engine can only have one active controller
+and it does not take ownership of it.
+
+\sa incubationController()
+*/
+void QDeclarativeEngine::setIncubationController(QDeclarativeIncubationController *controller)
+{
+ Q_D(QDeclarativeEngine);
+ d->incubationController = controller;
+ if (controller) controller->d = d;
+}
+
+/*!
+Returns the currently set incubation controller, or 0 if no controller has been set.
+
+\sa setIncubationController()
+*/
+QDeclarativeIncubationController *QDeclarativeEngine::incubationController() const
+{
+ Q_D(const QDeclarativeEngine);
+ return d->incubationController;
+}
+
+QDeclarativeIncubatorPrivate::QDeclarativeIncubatorPrivate(QDeclarativeIncubator *q,
+ QDeclarativeIncubator::IncubationMode m)
+: q(q), status(QDeclarativeIncubator::Null), mode(m), isAsynchronous(false), progress(Execute),
+ result(0), component(0), vme(this), waitingOnMe(0)
+{
+}
+
+QDeclarativeIncubatorPrivate::~QDeclarativeIncubatorPrivate()
+{
+}
+
+void QDeclarativeIncubatorPrivate::clear()
+{
+ if (next.isInList()) {
+ next.remove();
+ Q_ASSERT(component);
+ QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(component->engine);
+ component->release();
+ component = 0;
+ enginePriv->incubatorCount--;
+ QDeclarativeIncubationController *controller = enginePriv->incubationController;
+ if (controller)
+ controller->incubatingObjectCountChanged(enginePriv->incubatorCount);
+ } else if (component) {
+ component->release();
+ component = 0;
+ }
+
+ if (nextWaitingFor.isInList()) {
+ Q_ASSERT(waitingOnMe);
+ nextWaitingFor.remove();
+ waitingOnMe = 0;
+ }
+}
+
+/*!
+\class QDeclarativeIncubationController
+\brief QDeclarativeIncubationController instances drive the progress of QDeclarativeIncubators
+
+In order to behave asynchronously and not introduce stutters or freezes in an application,
+the process of creating objects a QDeclarativeIncubators must be driven only during the
+application's idle time. QDeclarativeIncubationController allows the application to control
+exactly when, how often and for how long this processing occurs.
+
+A QDeclarativeIncubationController derived instance should be created and set on a
+QDeclarativeEngine by calling the QDeclarativeEngine::setIncubationController() method.
+Processing is then controlled by calling the QDeclarativeIncubationController::incubateFor()
+or QDeclarativeIncubationController::incubateWhile() methods as dictated by the application's
+requirements.
+
+For example, this is an example of a incubation controller that will incubate for a maximum
+of 5 milliseconds out of every 16 milliseconds.
+
+\code
+class PeriodicIncubationController : public QObject,
+ public QDeclarativeIncubationController
+{
+public:
+ PeriodicIncubationController() {
+ startTimer(16);
+ }
+
+protected:
+ virtual void timerEvent(QTimerEvent *) {
+ incubateFor(5);
+ }
+};
+\endcode
+
+Although the previous example would work, it is not optimal. Real world incubation
+controllers should try and maximize the amount of idle time they consume - rather
+than a static amount like 5 milliseconds - while not disturbing the application.
+*/
+
+/*!
+Create a new incubation controller.
+*/
+QDeclarativeIncubationController::QDeclarativeIncubationController()
+: d(0)
+{
+}
+
+/*! \internal */
+QDeclarativeIncubationController::~QDeclarativeIncubationController()
+{
+ if (d) QDeclarativeEnginePrivate::get(d)->setIncubationController(0);
+ d = 0;
+}
+
+/*!
+Return the QDeclarativeEngine this incubation controller is set on, or 0 if it
+has not been set on any engine.
+*/
+QDeclarativeEngine *QDeclarativeIncubationController::engine() const
+{
+ return QDeclarativeEnginePrivate::get(d);
+}
+
+/*!
+Return the number of objects currently incubating.
+*/
+int QDeclarativeIncubationController::incubatingObjectCount() const
+{
+ if (d)
+ return d->incubatorCount;
+ else
+ return 0;
+}
+
+/*!
+Called when the number of incubating objects changes. \a incubatingObjectCount is the
+new number of incubating objects.
+
+The default implementation does nothing.
+*/
+void QDeclarativeIncubationController::incubatingObjectCountChanged(int incubatingObjectCount)
+{
+ Q_UNUSED(incubatingObjectCount);
+}
+
+void QDeclarativeIncubatorPrivate::incubate(QDeclarativeVME::Interrupt &i)
+{
+ typedef QDeclarativeIncubatorPrivate IP;
+ QRecursionWatcher<IP, &IP::recursion> watcher(this);
+
+ QDeclarativeEngine *engine = component->engine;
+ QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
+
+ bool guardOk = vmeGuard.isOK();
+ vmeGuard.clear();
+
+ if (!guardOk) {
+ QDeclarativeError error;
+ error.setUrl(component->url);
+ error.setDescription(QDeclarativeComponent::tr("Object destroyed during incubation"));
+ errors << error;
+ progress = QDeclarativeIncubatorPrivate::Completed;
+
+ goto finishIncubate;
+ }
+
+ if (progress == QDeclarativeIncubatorPrivate::Execute) {
+ enginePriv->referenceScarceResources();
+ QObject *tresult = vme.execute(&errors, i);
+ enginePriv->dereferenceScarceResources();
+
+ if (watcher.hasRecursed())
+ return;
+
+ result = tresult;
+ if (errors.isEmpty() && result == 0)
+ goto finishIncubate;
+
+ if (result) {
+ QDeclarativeData *ddata = QDeclarativeData::get(result);
+ Q_ASSERT(ddata);
+ ddata->indestructible = true;
+
+ q->setInitialState(result);
+ }
+
+ if (watcher.hasRecursed())
+ return;
+
+ if (errors.isEmpty())
+ progress = QDeclarativeIncubatorPrivate::Completing;
+ else
+ progress = QDeclarativeIncubatorPrivate::Completed;
+
+ changeStatus(calculateStatus());
+
+ if (watcher.hasRecursed())
+ return;
+
+ if (i.shouldInterrupt())
+ goto finishIncubate;
+ }
+
+ if (progress == QDeclarativeIncubatorPrivate::Completing) {
+ do {
+ if (watcher.hasRecursed())
+ return;
+
+ if (vme.complete(i)) {
+ progress = QDeclarativeIncubatorPrivate::Completed;
+ goto finishIncubate;
+ }
+ } while (!i.shouldInterrupt());
+ }
+
+finishIncubate:
+ if (progress == QDeclarativeIncubatorPrivate::Completed && waitingFor.isEmpty()) {
+ typedef QDeclarativeIncubatorPrivate IP;
+
+ QDeclarativeIncubatorPrivate *isWaiting = waitingOnMe;
+ clear();
+
+ if (isWaiting) {
+ QRecursionWatcher<IP, &IP::recursion> watcher(isWaiting);
+ changeStatus(calculateStatus());
+ if (!watcher.hasRecursed())
+ isWaiting->incubate(i);
+ } else {
+ changeStatus(calculateStatus());
+ }
+
+ enginePriv->inProgressCreations--;
+
+ if (0 == enginePriv->inProgressCreations) {
+ while (enginePriv->erroredBindings) {
+ enginePriv->warning(enginePriv->erroredBindings->error);
+ enginePriv->erroredBindings->removeError();
+ }
+ }
+ } else {
+ vmeGuard.guard(&vme);
+ }
+}
+
+/*!
+Incubate objects for \a msecs, or until there are no more objects to incubate.
+*/
+void QDeclarativeIncubationController::incubateFor(int msecs)
+{
+ if (!d || d->incubatorCount == 0)
+ return;
+
+ QDeclarativeVME::Interrupt i(msecs * 1000000);
+ i.reset();
+ do {
+ QDeclarativeIncubatorPrivate *p = (QDeclarativeIncubatorPrivate*)d->incubatorList.first();
+ p->incubate(i);
+ } while (d && d->incubatorCount != 0 && !i.shouldInterrupt());
+}
+
+/*!
+Incubate objects while the bool pointed to by \a flag is true, or until there are no
+more objects to incubate.
+
+Generally this method is used in conjunction with a thread or a UNIX signal that sets
+the bool pointed to by \a flag to false when it wants incubation to be interrupted.
+*/
+void QDeclarativeIncubationController::incubateWhile(bool *flag)
+{
+ if (!d || d->incubatorCount == 0)
+ return;
+
+ QDeclarativeVME::Interrupt i(flag);
+ do {
+ QDeclarativeIncubatorPrivate *p = (QDeclarativeIncubatorPrivate*)d->incubatorList.first();
+ p->incubate(i);
+ } while (d && d->incubatorCount != 0 && !i.shouldInterrupt());
+}
+
+/*!
+\class QDeclarativeIncubator
+\brief The QDeclarativeIncubator class allows QML objects to be created asynchronously.
+
+Creating QML objects - like delegates in a view, or a new page in an application - can take
+a noticable amount of time, especially on resource constrained mobile devices. When an
+application uses QDeclarativeComponent::create() directly, the QML object instance is created
+synchronously which, depending on the complexity of the object, can cause noticable pauses or
+stutters in the application.
+
+The use of QDeclarativeIncubator gives more control over the creation of a QML object,
+including allowing it to be created asynchronously using application idle time. The following
+example shows a simple use of QDeclarativeIncubator.
+
+\code
+QDeclarativeIncubator incubator;
+component->create(incubator);
+
+while (incubator.isReady()) {
+ QCoreApplication::processEvents(QEventLoop::AllEvents, 50);
+}
+
+QObject *object = incubator.object();
+\endcode
+
+Asynchronous incubators are controlled by a QDeclarativeIncubationController that is
+set on the QDeclarativeEngine, which lets the engine know when the application is idle and
+incubating objects should be processed. If an incubation controller is not set on the
+QDeclarativeEngine, QDeclarativeIncubator creates objects synchronously regardless of the
+specified IncubationMode.
+
+QDeclarativeIncubator supports three incubation modes:
+\list
+\i Synchronous The creation occurs synchronously. That is, once the
+QDeclarativeComponent::create() call returns, the incubator will already be in either the
+Error or Ready state. A synchronous incubator has no real advantage compared to using
+the synchronous creation methods on QDeclarativeComponent directly, but it may simplify an
+application's implementation to use the same API for both synchronous and asynchronous
+creations.
+
+\i Asynchronous (default) The creation occurs asynchronously, assuming a
+QDeclarativeIncubatorController is set on the QDeclarativeEngine.
+
+The incubator will remain in the Loading state until either the creation is complete or an error
+occurs. The statusChanged() callback can be used to be notified of status changes.
+
+Applications should use the Asynchronous incubation mode to create objects that are not needed
+immediately. For example, the ListView element uses Asynchronous incubation to create objects
+that are slightly off screen while the list is being scrolled. If, during asynchronous creation,
+the object is needed immediately the QDeclarativeIncubator::forceCompletion() method can be called
+to complete the creation process synchronously.
+
+\i AsynchronousIfNested The creation will occur asynchronously if part of a nested asynchronous
+creation, or synchronously if not.
+
+In most scenarios where a QML element or component wants the appearance of a synchronous
+instantiation, it should use this mode.
+
+This mode is best explained with an example. When the ListView element is first created, it needs
+to populate itself with an initial set of delegates to show. If the ListView was 400 pixels high,
+and each delegate was 100 pixels high, it would need to create four initial delegate instances. If
+the ListView used the Asynchronous incubation mode, the ListView would always be created empty and
+then, sometime later, the four initial elements would appear.
+
+Conversely, if the ListView was to use the Synchronous incubation mode it would behave correctly
+but it may introduce stutters into the application. As QML would have to stop and instantiate the
+ListView's delegates synchronously, if the ListView was part of a QML component that was being
+instantiated asynchronously this would undo much of the benefit of asynchronous instantiation.
+
+The AsynchronousIfNested mode reconciles this problem. By using AsynchronousIfNested, the ListView
+delegates are instantiated asynchronously if the ListView itself is already part of an asynchronous
+instantiation, and synchronously otherwise. In the case of a nested asynchronous instantiation, the
+outer asynchronous instantiation will not complete until after all the nested instantiations have also
+completed. This ensures that by the time the outer asynchronous instantitation completes, inner
+elements like ListView have already completed loading their initial delegates.
+
+It is almost always incorrect to use the Synchronous incubation mode - elements or components that
+want the appearance of synchronous instantiation, but without the downsides of introducing freezes
+or stutters into the application, should use the AsynchronousIfNested incubation mode.
+\endlist
+*/
+
+/*!
+Create a new incubator with the specified \a mode
+*/
+QDeclarativeIncubator::QDeclarativeIncubator(IncubationMode mode)
+: d(new QDeclarativeIncubatorPrivate(this, mode))
+{
+}
+
+/*! \internal */
+QDeclarativeIncubator::~QDeclarativeIncubator()
+{
+ clear();
+
+ delete d; d = 0;
+}
+
+/*!
+\enum QDeclarativeIncubator::IncubationMode
+
+Specifies the mode the incubator operates in. Regardless of the incubation mode, a
+QDeclarativeIncubator will behave synchronously if the QDeclarativeEngine does not have
+a QDeclarativeIncubationController set.
+
+\value Asynchronous The object will be created asynchronously.
+\value AsynchronousIfNested If the object is being created in a context that is already part
+of an asynchronous creation, this incubator will join that existing incubation and execute
+asynchronously. The existing incubation will not become Ready until both it and this
+incubation have completed. Otherwise, the incubation will execute synchronously.
+\value Synchronous The object will be created synchronously.
+*/
+
+/*!
+\enum QDeclarativeIncubator::Status
+
+Specifies the status of the QDeclarativeIncubator.
+
+\value Null Incubation is not in progress. Call QDeclarativeComponent::create() to begin incubating.
+\value Ready The object is fully created and can be accessed by calling object().
+\value Loading The object is in the process of being created.
+\value Error An error occurred. The errors can be access by calling errors().
+*/
+
+/*!
+Clears the incubator. Any in-progress incubation is aborted. If the incubator is in the
+Ready state, the created object is \b not deleted.
+*/
+void QDeclarativeIncubator::clear()
+{
+ typedef QDeclarativeIncubatorPrivate IP;
+ QRecursionWatcher<IP, &IP::recursion> watcher(d);
+
+ Status s = status();
+
+ if (s == Null)
+ return;
+
+ QDeclarativeEnginePrivate *enginePriv = 0;
+ if (s == Loading) {
+ Q_ASSERT(d->component);
+ enginePriv = QDeclarativeEnginePrivate::get(d->component->engine);
+ if (d->result) d->result->deleteLater();
+ d->result = 0;
+ }
+
+ d->clear();
+
+ d->vme.reset();
+ d->vmeGuard.clear();
+
+ Q_ASSERT(d->component == 0);
+ Q_ASSERT(d->waitingOnMe == 0);
+ Q_ASSERT(d->waitingFor.isEmpty());
+ Q_ASSERT(!d->nextWaitingFor.isInList());
+
+ d->errors.clear();
+ d->progress = QDeclarativeIncubatorPrivate::Execute;
+ d->result = 0;
+
+ if (s == Loading) {
+ Q_ASSERT(enginePriv);
+
+ enginePriv->inProgressCreations--;
+ if (0 == enginePriv->inProgressCreations) {
+ while (enginePriv->erroredBindings) {
+ enginePriv->warning(enginePriv->erroredBindings->error);
+ enginePriv->erroredBindings->removeError();
+ }
+ }
+ }
+
+ d->changeStatus(Null);
+}
+
+/*!
+Force any in-progress incubation to finish synchronously. Once this call
+returns, the incubator will not be in the Loading state.
+*/
+void QDeclarativeIncubator::forceCompletion()
+{
+ QDeclarativeVME::Interrupt i;
+ while (Loading == status()) {
+ while (Loading == status() && !d->waitingFor.isEmpty())
+ static_cast<QDeclarativeIncubatorPrivate *>(d->waitingFor.first())->incubate(i);
+ if (Loading == status())
+ d->incubate(i);
+ }
+
+}
+
+/*!
+Returns true if the incubator's status() is Null.
+*/
+bool QDeclarativeIncubator::isNull() const
+{
+ return status() == Null;
+}
+
+/*!
+Returns true if the incubator's status() is Ready.
+*/
+bool QDeclarativeIncubator::isReady() const
+{
+ return status() == Ready;
+}
+
+/*!
+Returns true if the incubator's status() is Error.
+*/
+bool QDeclarativeIncubator::isError() const
+{
+ return status() == Error;
+}
+
+/*!
+Returns true if the incubator's status() is Loading.
+*/
+bool QDeclarativeIncubator::isLoading() const
+{
+ return status() == Loading;
+}
+
+/*!
+Return the list of errors encountered while incubating the object.
+*/
+QList<QDeclarativeError> QDeclarativeIncubator::errors() const
+{
+ return d->errors;
+}
+
+/*!
+Return the incubation mode passed to the QDeclarativeIncubator constructor.
+*/
+QDeclarativeIncubator::IncubationMode QDeclarativeIncubator::incubationMode() const
+{
+ return d->mode;
+}
+
+/*!
+Return the current status of the incubator.
+*/
+QDeclarativeIncubator::Status QDeclarativeIncubator::status() const
+{
+ return d->status;
+}
+
+/*!
+Return the incubated object if the status is Ready, otherwise 0.
+*/
+QObject *QDeclarativeIncubator::object() const
+{
+ if (status() != Ready) return 0;
+ else return d->result;
+}
+
+/*!
+Called when the status of the incubator changes. \a status is the new status.
+
+The default implementation does nothing.
+*/
+void QDeclarativeIncubator::statusChanged(Status status)
+{
+ Q_UNUSED(status);
+}
+
+/*!
+Called after the object is first created, but before property bindings are
+evaluated and, if applicable, QDeclarativeParserStatus::componentComplete() is
+called. This is equivalent to the point between QDeclarativeComponent::beginCreate()
+and QDeclarativeComponent::endCreate(), and can be used to assign initial values
+to the object's properties.
+
+The default implementation does nothing.
+*/
+void QDeclarativeIncubator::setInitialState(QObject *object)
+{
+ Q_UNUSED(object);
+}
+
+void QDeclarativeIncubatorPrivate::changeStatus(QDeclarativeIncubator::Status s)
+{
+ if (s == status)
+ return;
+
+ status = s;
+ q->statusChanged(status);
+}
+
+QDeclarativeIncubator::Status QDeclarativeIncubatorPrivate::calculateStatus() const
+{
+ if (!errors.isEmpty())
+ return QDeclarativeIncubator::Error;
+ else if (result && progress == QDeclarativeIncubatorPrivate::Completed &&
+ waitingFor.isEmpty())
+ return QDeclarativeIncubator::Ready;
+ else if (component)
+ return QDeclarativeIncubator::Loading;
+ else
+ return QDeclarativeIncubator::Null;
+}
+
diff --git a/src/declarative/qml/qdeclarativeincubator.h b/src/declarative/qml/qdeclarativeincubator.h
new file mode 100644
index 0000000000..0c6bc84b43
--- /dev/null
+++ b/src/declarative/qml/qdeclarativeincubator.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEINCUBATOR_H
+#define QDECLARATIVEINCUBATOR_H
+
+#include <QtDeclarative/qdeclarativeerror.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeEngine;
+
+class QDeclarativeIncubatorPrivate;
+class Q_DECLARATIVE_EXPORT QDeclarativeIncubator
+{
+ Q_DISABLE_COPY(QDeclarativeIncubator);
+public:
+ enum IncubationMode {
+ Asynchronous,
+ AsynchronousIfNested,
+ Synchronous
+ };
+ enum Status {
+ Null,
+ Ready,
+ Loading,
+ Error
+ };
+
+ QDeclarativeIncubator(IncubationMode = Asynchronous);
+ virtual ~QDeclarativeIncubator();
+
+ void clear();
+ void forceCompletion();
+
+ bool isNull() const;
+ bool isReady() const;
+ bool isError() const;
+ bool isLoading() const;
+
+ QList<QDeclarativeError> errors() const;
+
+ IncubationMode incubationMode() const;
+
+ Status status() const;
+
+ QObject *object() const;
+
+protected:
+ virtual void statusChanged(Status);
+ virtual void setInitialState(QObject *);
+
+private:
+ friend class QDeclarativeComponent;
+ friend class QDeclarativeEnginePrivate;
+ friend class QDeclarativeIncubatorPrivate;
+ QDeclarativeIncubatorPrivate *d;
+};
+
+class QDeclarativeEnginePrivate;
+class Q_DECLARATIVE_EXPORT QDeclarativeIncubationController
+{
+ Q_DISABLE_COPY(QDeclarativeIncubationController);
+public:
+ QDeclarativeIncubationController();
+ virtual ~QDeclarativeIncubationController();
+
+ QDeclarativeEngine *engine() const;
+ int incubatingObjectCount() const;
+
+ void incubateFor(int msecs);
+ void incubateWhile(bool *flag);
+
+protected:
+ virtual void incubatingObjectCountChanged(int);
+
+private:
+ friend class QDeclarativeEngine;
+ friend class QDeclarativeEnginePrivate;
+ friend class QDeclarativeIncubatorPrivate;
+ QDeclarativeEnginePrivate *d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEINCUBATOR_H
diff --git a/src/declarative/qml/qdeclarativeincubator_p.h b/src/declarative/qml/qdeclarativeincubator_p.h
new file mode 100644
index 0000000000..eaa4ce5ecb
--- /dev/null
+++ b/src/declarative/qml/qdeclarativeincubator_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEINCUBATOR_P_H
+#define QDECLARATIVEINCUBATOR_P_H
+
+#include <private/qintrusivelist_p.h>
+#include <private/qdeclarativevme_p.h>
+#include <private/qrecursionwatcher_p.h>
+#include <private/qdeclarativeengine_p.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeCompiledData;
+class QDeclarativeIncubator;
+class QDeclarativeIncubatorPrivate : public QDeclarativeEnginePrivate::Incubator
+{
+public:
+ QDeclarativeIncubatorPrivate(QDeclarativeIncubator *q, QDeclarativeIncubator::IncubationMode m);
+ ~QDeclarativeIncubatorPrivate();
+
+ QDeclarativeIncubator *q;
+
+ QDeclarativeIncubator::Status calculateStatus() const;
+ void changeStatus(QDeclarativeIncubator::Status);
+ QDeclarativeIncubator::Status status;
+
+ QDeclarativeIncubator::IncubationMode mode;
+ bool isAsynchronous;
+
+ QList<QDeclarativeError> errors;
+
+ enum Progress { Execute, Completing, Completed };
+ Progress progress;
+
+ QObject *result;
+ QDeclarativeCompiledData *component;
+ QDeclarativeVME vme;
+ QDeclarativeVMEGuard vmeGuard;
+
+ QDeclarativeIncubatorPrivate *waitingOnMe;
+ typedef QDeclarativeEnginePrivate::Incubator QIPBase;
+ QIntrusiveList<QIPBase, &QIPBase::nextWaitingFor> waitingFor;
+
+ QRecursionNode recursion;
+
+ void clear();
+
+ void incubate(QDeclarativeVME::Interrupt &i);
+};
+
+QT_END_NAMESPACE
+
+#endif // QDECLARATIVEINCUBATOR_P_H
+
diff --git a/src/declarative/qml/qdeclarativeinfo.cpp b/src/declarative/qml/qdeclarativeinfo.cpp
index 995a6b9ad7..4f1bae002d 100644
--- a/src/declarative/qml/qdeclarativeinfo.cpp
+++ b/src/declarative/qml/qdeclarativeinfo.cpp
@@ -41,11 +41,11 @@
#include "qdeclarativeinfo.h"
-#include "private/qdeclarativedata_p.h"
+#include "qdeclarativedata_p.h"
#include "qdeclarativecontext.h"
-#include "private/qdeclarativecontext_p.h"
-#include "private/qdeclarativemetatype_p.h"
-#include "private/qdeclarativeengine_p.h"
+#include "qdeclarativecontext_p.h"
+#include "qdeclarativemetatype_p.h"
+#include "qdeclarativeengine_p.h"
#include <QCoreApplication>
@@ -120,7 +120,7 @@ QDeclarativeInfo::~QDeclarativeInfo()
QString typeName;
QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
if (type) {
- typeName = QLatin1String(type->qmlTypeName());
+ typeName = type->qmlTypeName();
int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
if (lastSlash != -1)
typeName = typeName.mid(lastSlash+1);
@@ -136,7 +136,7 @@ QDeclarativeInfo::~QDeclarativeInfo()
typeName += QLatin1Char('*');
type = QDeclarativeMetaType::qmlType(QMetaType::type(typeName.toLatin1()));
if (type) {
- typeName = QLatin1String(type->qmlTypeName());
+ typeName = type->qmlTypeName();
int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
if (lastSlash != -1)
typeName = typeName.mid(lastSlash+1);
diff --git a/src/declarative/qml/qdeclarativeinstruction.cpp b/src/declarative/qml/qdeclarativeinstruction.cpp
index 3093ddc8ac..5f8b253858 100644
--- a/src/declarative/qml/qdeclarativeinstruction.cpp
+++ b/src/declarative/qml/qdeclarativeinstruction.cpp
@@ -39,9 +39,9 @@
**
****************************************************************************/
-#include "private/qdeclarativeinstruction_p.h"
+#include "qdeclarativeinstruction_p.h"
-#include "private/qdeclarativecompiler_p.h"
+#include "qdeclarativecompiler_p.h"
#include <QtCore/qdebug.h>
@@ -57,11 +57,20 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx)
case QDeclarativeInstruction::Init:
qWarning().nospace() << idx << "\t\t" << "INIT\t\t\t" << instr->init.bindingsSize << "\t" << instr->init.parserStatusSize << "\t" << instr->init.contextCache << "\t" << instr->init.compiledBinding;
break;
+ case QDeclarativeInstruction::DeferInit:
+ qWarning().nospace() << idx << "\t\t" << "DEFER_INIT\t\t" << instr->deferInit.bindingsSize << "\t" << instr->deferInit.parserStatusSize;
+ break;
case QDeclarativeInstruction::Done:
qWarning().nospace() << idx << "\t\t" << "DONE";
break;
- case QDeclarativeInstruction::CreateObject:
- qWarning().nospace() << idx << "\t\t" << "CREATE\t\t\t" << instr->create.type << "\t" << instr->create.bindingBits << "\t\t" << types.at(instr->create.type).className;
+ case QDeclarativeInstruction::CreateCppObject:
+ qWarning().nospace() << idx << "\t\t" << "CREATECPP\t\t\t" << instr->create.type << "\t\t\t" << types.at(instr->create.type).className;
+ break;
+ case QDeclarativeInstruction::CreateQMLObject:
+ qWarning().nospace() << idx << "\t\t" << "CREATEQML\t\t\t" << instr->createQml.type << "\t" << instr->createQml.bindingBits << "\t\t" << types.at(instr->createQml.type).className;
+ break;
+ case QDeclarativeInstruction::CompleteQMLObject:
+ qWarning().nospace() << idx << "\t\t" << "COMPLETEQML";
break;
case QDeclarativeInstruction::CreateSimpleObject:
qWarning().nospace() << idx << "\t\t" << "CREATE_SIMPLE\t\t" << instr->createSimple.typeSize;
@@ -166,7 +175,7 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx)
qWarning().nospace() << idx << "\t\t" << "STORE_SCRIPT_STRING\t" << instr->storeScriptString.propertyIndex << "\t" << instr->storeScriptString.value << "\t" << instr->storeScriptString.scope << "\t" << instr->storeScriptString.bindingId;
break;
case QDeclarativeInstruction::AssignSignalObject:
- qWarning().nospace() << idx << "\t\t" << "ASSIGN_SIGNAL_OBJECT\t" << instr->assignSignalObject.signal << "\t\t\t" << datas.at(instr->assignSignalObject.signal);
+ qWarning().nospace() << idx << "\t\t" << "ASSIGN_SIGNAL_OBJECT\t" << instr->assignSignalObject.signal << "\t\t\t" << primitives.at(instr->assignSignalObject.signal);
break;
case QDeclarativeInstruction::AssignCustomType:
qWarning().nospace() << idx << "\t\t" << "ASSIGN_CUSTOMTYPE\t" << instr->assignCustomType.propertyIndex << "\t" << instr->assignCustomType.primitive << "\t" << instr->assignCustomType.type;
@@ -175,22 +184,22 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx)
qWarning().nospace() << idx << "\t\t" << "INIT_V8_BINDING\t" << instr->initV8Bindings.program << "\t" << instr->initV8Bindings.programIndex << "\t" << instr->initV8Bindings.line;
break;
case QDeclarativeInstruction::StoreBinding:
- qWarning().nospace() << idx << "\t\t" << "STORE_BINDING\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context;
+ qWarning().nospace() << idx << "\t\t" << "STORE_BINDING\t" << instr->assignBinding.property.coreIndex << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context;
break;
case QDeclarativeInstruction::StoreBindingOnAlias:
- qWarning().nospace() << idx << "\t\t" << "STORE_BINDING_ALIAS\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context;
+ qWarning().nospace() << idx << "\t\t" << "STORE_BINDING_ALIAS\t" << instr->assignBinding.property.coreIndex << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context;
break;
case QDeclarativeInstruction::StoreV4Binding:
- qWarning().nospace() << idx << "\t\t" << "STORE_COMPILED_BINDING\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context;
+ qWarning().nospace() << idx << "\t\t" << "STORE_COMPILED_BINDING\t" << instr->assignV4Binding.property << "\t" << instr->assignV4Binding.value << "\t" << instr->assignV4Binding.context;
break;
case QDeclarativeInstruction::StoreV8Binding:
- qWarning().nospace() << idx << "\t\t" << "STORE_V8_BINDING\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context;
+ qWarning().nospace() << idx << "\t\t" << "STORE_V8_BINDING\t" << instr->assignBinding.property.coreIndex << "\t" << instr->assignBinding.value << "\t" << instr->assignBinding.context;
break;
case QDeclarativeInstruction::StoreValueSource:
- qWarning().nospace() << idx << "\t\t" << "STORE_VALUE_SOURCE\t" << instr->assignValueSource.property << "\t" << instr->assignValueSource.castValue;
+ qWarning().nospace() << idx << "\t\t" << "STORE_VALUE_SOURCE\t" << instr->assignValueSource.property.coreIndex << "\t" << instr->assignValueSource.castValue;
break;
case QDeclarativeInstruction::StoreValueInterceptor:
- qWarning().nospace() << idx << "\t\t" << "STORE_VALUE_INTERCEPTOR\t" << instr->assignValueInterceptor.property << "\t" << instr->assignValueInterceptor.castValue;
+ qWarning().nospace() << idx << "\t\t" << "STORE_VALUE_INTERCEPTOR\t" << instr->assignValueInterceptor.property.coreIndex << "\t" << instr->assignValueInterceptor.castValue;
break;
case QDeclarativeInstruction::BeginObject:
qWarning().nospace() << idx << "\t\t" << "BEGIN\t\t\t" << instr->begin.castValue;
diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h
index 35de8b2a91..7b36c9a87e 100644
--- a/src/declarative/qml/qdeclarativeinstruction_p.h
+++ b/src/declarative/qml/qdeclarativeinstruction_p.h
@@ -54,13 +54,17 @@
//
#include <QtCore/qglobal.h>
+#include <private/qdeclarativepropertycache_p.h>
QT_BEGIN_NAMESPACE
#define FOR_EACH_QML_INSTR(F) \
F(Init, init) \
+ F(DeferInit, deferInit) \
F(Done, common) \
- F(CreateObject, create) \
+ F(CreateCppObject, create) \
+ F(CreateQMLObject, createQml) \
+ F(CompleteQMLObject, completeQml) \
F(CreateSimpleObject, createSimple) \
F(SetId, setId) \
F(SetDefault, common) \
@@ -70,6 +74,10 @@ QT_BEGIN_NAMESPACE
F(StoreVariantInteger, storeInteger) \
F(StoreVariantDouble, storeDouble) \
F(StoreVariantBool, storeBool) \
+ F(StoreVar, storeString) \
+ F(StoreVarInteger, storeInteger) \
+ F(StoreVarDouble, storeDouble) \
+ F(StoreVarBool, storeBool) \
F(StoreString, storeString) \
F(StoreByteArray, storeByteArray) \
F(StoreUrl, storeUrl) \
@@ -99,13 +107,14 @@ QT_BEGIN_NAMESPACE
F(InitV8Bindings, initV8Bindings) \
F(StoreBinding, assignBinding) \
F(StoreBindingOnAlias, assignBinding) \
- F(StoreV4Binding, assignBinding) \
F(StoreV8Binding, assignBinding) \
+ F(StoreV4Binding, assignV4Binding) \
F(StoreValueSource, assignValueSource) \
F(StoreValueInterceptor, assignValueInterceptor) \
F(StoreObjectQList, common) \
F(AssignObjectList, assignObjectList) \
F(StoreVariantObject, storeObject) \
+ F(StoreVarObject, storeObject) \
F(StoreInterface, storeObject) \
F(FetchAttached, fetchAttached) \
F(FetchQList, fetchQmlList) \
@@ -151,14 +160,35 @@ union QDeclarativeInstruction
int parserStatusSize;
int contextCache;
int compiledBinding;
+ int objectStackSize;
+ int listStackSize;
+ };
+ struct instr_deferInit {
+ QML_INSTR_HEADER
+ int bindingsSize;
+ int parserStatusSize;
+ int objectStackSize;
+ int listStackSize;
+ };
+ struct instr_createQml {
+ QML_INSTR_HEADER
+ int type;
+ int bindingBits;
+ bool isRoot;
+ };
+ struct instr_completeQml {
+ QML_INSTR_HEADER
+ ushort column;
+ ushort line;
+ bool isRoot;
};
struct instr_create {
QML_INSTR_HEADER
int type;
int data;
- int bindingBits;
ushort column;
ushort line;
+ bool isRoot;
};
struct instr_createSimple {
QML_INSTR_HEADER
@@ -181,13 +211,13 @@ union QDeclarativeInstruction
};
struct instr_assignValueSource {
QML_INSTR_HEADER
- int property;
+ QDeclarativePropertyCache::RawData property;
int owner;
int castValue;
};
struct instr_assignValueInterceptor {
QML_INSTR_HEADER
- int property;
+ QDeclarativePropertyCache::RawData property;
int owner;
int castValue;
};
@@ -197,12 +227,22 @@ union QDeclarativeInstruction
ushort programIndex;
ushort line;
};
- struct instr_assignBinding {
+ struct instr_assignV4Binding {
QML_INSTR_HEADER
unsigned int property;
int value;
short context;
short owner;
+ bool isRoot;
+ ushort line;
+ };
+ struct instr_assignBinding {
+ QML_INSTR_HEADER
+ QDeclarativePropertyCache::RawData property;
+ int value;
+ short context;
+ short owner;
+ bool isRoot;
ushort line;
};
struct instr_fetch {
@@ -357,6 +397,7 @@ union QDeclarativeInstruction
int metaObject;
ushort column;
ushort line;
+ bool isRoot;
};
struct instr_fetchAttached {
QML_INSTR_HEADER
@@ -425,13 +466,17 @@ union QDeclarativeInstruction
instr_common common;
instr_init init;
+ instr_deferInit deferInit;
instr_create create;
+ instr_createQml createQml;
+ instr_completeQml completeQml;
instr_createSimple createSimple;
instr_storeMeta storeMeta;
instr_setId setId;
instr_assignValueSource assignValueSource;
instr_assignValueInterceptor assignValueInterceptor;
instr_initV8Bindings initV8Bindings;
+ instr_assignV4Binding assignV4Binding;
instr_assignBinding assignBinding;
instr_fetch fetch;
instr_fetchValue fetchValue;
diff --git a/src/declarative/qml/qdeclarativeintegercache.cpp b/src/declarative/qml/qdeclarativeintegercache.cpp
index 16bf8d1dab..372c7a2b3b 100644
--- a/src/declarative/qml/qdeclarativeintegercache.cpp
+++ b/src/declarative/qml/qdeclarativeintegercache.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "private/qdeclarativeintegercache_p.h"
+#include "qdeclarativeintegercache_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativeintegercache_p.h b/src/declarative/qml/qdeclarativeintegercache_p.h
index 1ac03ada66..ee2fbc2b66 100644
--- a/src/declarative/qml/qdeclarativeintegercache_p.h
+++ b/src/declarative/qml/qdeclarativeintegercache_p.h
@@ -53,8 +53,8 @@
// We mean it.
//
-#include "private/qdeclarativerefcount_p.h"
-#include "private/qhashedstring_p.h"
+#include <private/qdeclarativerefcount_p.h>
+#include <private/qhashedstring_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativelist.cpp b/src/declarative/qml/qdeclarativelist.cpp
index 458812a896..04cef6c737 100644
--- a/src/declarative/qml/qdeclarativelist.cpp
+++ b/src/declarative/qml/qdeclarativelist.cpp
@@ -40,9 +40,9 @@
****************************************************************************/
#include "qdeclarativelist.h"
-#include "private/qdeclarativelist_p.h"
-#include "private/qdeclarativeengine_p.h"
-#include "private/qdeclarativeproperty_p.h"
+#include "qdeclarativelist_p.h"
+#include "qdeclarativeengine_p.h"
+#include "qdeclarativeproperty_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativelist_p.h b/src/declarative/qml/qdeclarativelist_p.h
index 8a69504c28..10495e990c 100644
--- a/src/declarative/qml/qdeclarativelist_p.h
+++ b/src/declarative/qml/qdeclarativelist_p.h
@@ -54,7 +54,7 @@
//
#include "qdeclarativelist.h"
-#include "private/qdeclarativeguard_p.h"
+#include "qdeclarativeguard_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp
index 4289dee907..5577993fc5 100644
--- a/src/declarative/qml/qdeclarativemetatype.cpp
+++ b/src/declarative/qml/qdeclarativemetatype.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
#include <QtDeclarative/qdeclarativeprivate.h>
-#include "private/qdeclarativemetatype_p.h"
+#include "qdeclarativemetatype_p.h"
#include <private/qdeclarativeproxymetaobject_p.h>
#include <private/qdeclarativecustomparser_p.h>
@@ -63,7 +63,6 @@
#include <qstringlist.h>
#include <qvector.h>
#include <qlocale.h>
-#include <QtCore/qcryptographichash.h>
#include <QtDeclarative/qjsvalue.h>
#include <ctype.h>
@@ -180,7 +179,7 @@ public:
bool m_isInterface : 1;
const char *m_iid;
QString m_module;
- QByteArray m_name;
+ QString m_name;
QString m_elementName;
int m_version_maj;
int m_version_min;
@@ -242,9 +241,9 @@ QDeclarativeType::QDeclarativeType(int index, const QDeclarativePrivate::Registe
QDeclarativeType::QDeclarativeType(int index, const QDeclarativePrivate::RegisterType &type)
: d(new QDeclarativeTypePrivate)
{
- QByteArray name = type.uri;
- if (type.uri) name += '/';
- name += type.elementName;
+ QString name = QString::fromUtf8(type.uri);
+ if (type.uri) name += QLatin1Char('/');
+ name += QString::fromUtf8(type.elementName);
d->m_module = QString::fromUtf8(type.uri);
d->m_name = name;
@@ -517,14 +516,14 @@ QByteArray QDeclarativeType::typeName() const
const QString &QDeclarativeType::elementName() const
{
if (d->m_elementName.isEmpty()) {
- QByteArray n = qmlTypeName();
- int idx = n.lastIndexOf('/');
- d->m_elementName = QString::fromUtf8(n.mid(idx + 1));
+ QString n = qmlTypeName();
+ int idx = n.lastIndexOf(QLatin1Char('/'));
+ d->m_elementName = n.mid(idx + 1);
}
return d->m_elementName;
}
-const QByteArray &QDeclarativeType::qmlTypeName() const
+const QString &QDeclarativeType::qmlTypeName() const
{
return d->m_name;
}
@@ -861,7 +860,7 @@ int registerInterface(const QDeclarativePrivate::RegisterInterface &interface)
data->idToType.insert(type->qListTypeId(), type);
// XXX No insertMulti, so no multi-version interfaces?
if (!type->qmlTypeName().isEmpty())
- data->nameToType.insert(QString::fromUtf8(type->qmlTypeName()), type);
+ data->nameToType.insert(type->qmlTypeName(), type);
if (data->interfaces.size() <= interface.typeId)
data->interfaces.resize(interface.typeId + 16);
@@ -895,7 +894,7 @@ int registerType(const QDeclarativePrivate::RegisterType &type)
if (dtype->qListTypeId()) data->idToType.insert(dtype->qListTypeId(), dtype);
if (!dtype->qmlTypeName().isEmpty())
- data->nameToType.insertMulti(QString::fromUtf8(dtype->qmlTypeName()), dtype);
+ data->nameToType.insertMulti(dtype->qmlTypeName(), dtype);
data->metaObjectToType.insertMulti(dtype->baseMetaObject(), dtype);
diff --git a/src/declarative/qml/qdeclarativemetatype_p.h b/src/declarative/qml/qdeclarativemetatype_p.h
index 2a6ce20bbb..39e8b850d0 100644
--- a/src/declarative/qml/qdeclarativemetatype_p.h
+++ b/src/declarative/qml/qdeclarativemetatype_p.h
@@ -137,7 +137,7 @@ class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeType
{
public:
QByteArray typeName() const;
- const QByteArray &qmlTypeName() const;
+ const QString &qmlTypeName() const;
const QString &elementName() const;
QString module() const;
diff --git a/src/declarative/qml/qdeclarativenotifier.cpp b/src/declarative/qml/qdeclarativenotifier.cpp
index 33a1660c46..842cbf00b5 100644
--- a/src/declarative/qml/qdeclarativenotifier.cpp
+++ b/src/declarative/qml/qdeclarativenotifier.cpp
@@ -39,88 +39,77 @@
**
****************************************************************************/
-#include "private/qdeclarativenotifier_p.h"
-#include "private/qdeclarativeproperty_p.h"
+#include "qdeclarativenotifier_p.h"
+#include "qdeclarativeproperty_p.h"
QT_BEGIN_NAMESPACE
void QDeclarativeNotifier::emitNotify(QDeclarativeNotifierEndpoint *endpoint)
{
- QDeclarativeNotifierEndpoint::Notifier *n = endpoint->asNotifier();
+ QDeclarativeNotifierEndpoint **oldDisconnected = endpoint->disconnected;
+ endpoint->disconnected = &endpoint;
+ endpoint->notifying = 1;
- QDeclarativeNotifierEndpoint **oldDisconnected = n->disconnected;
- n->disconnected = &endpoint;
-
- if (n->next)
- emitNotify(n->next);
+ if (endpoint->next)
+ emitNotify(endpoint->next);
if (endpoint) {
- void *args[] = { 0 };
- QMetaObject::metacall(endpoint->target, QMetaObject::InvokeMetaMethod,
- endpoint->targetMethod, args);
+ Q_ASSERT(endpoint->callback);
+
+ endpoint->callback(endpoint);
- if (endpoint)
- endpoint->asNotifier()->disconnected = oldDisconnected;
+ if (endpoint)
+ endpoint->disconnected = oldDisconnected;
}
if (oldDisconnected) *oldDisconnected = endpoint;
+ else if (endpoint) endpoint->notifying = 0;
}
void QDeclarativeNotifierEndpoint::connect(QObject *source, int sourceSignal)
{
- Signal *s = toSignal();
-
- if (s->source == source && s->sourceSignal == sourceSignal)
- return;
-
disconnect();
- QDeclarativePropertyPrivate::connect(source, sourceSignal, target, targetMethod);
-
- s->source = source;
- s->sourceSignal = sourceSignal;
+ this->source = source;
+ this->sourceSignal = sourceSignal;
+ QDeclarativePropertyPrivate::flushSignal(source, sourceSignal);
+ QDeclarativeData *ddata = QDeclarativeData::get(source, true);
+ ddata->addNotify(sourceSignal, this);
}
void QDeclarativeNotifierEndpoint::copyAndClear(QDeclarativeNotifierEndpoint &other)
{
+ if (&other == this)
+ return;
+
other.disconnect();
- other.target = target;
- other.targetMethod = targetMethod;
+ other.callback = callback;
if (!isConnected())
return;
- if (SignalType == type) {
- Signal *other_s = other.toSignal();
- Signal *s = asSignal();
-
- other_s->source = s->source;
- other_s->sourceSignal = s->sourceSignal;
- s->source = 0;
- } else if(NotifierType == type) {
- Notifier *other_n = other.toNotifier();
- Notifier *n = asNotifier();
-
- other_n->notifier = n->notifier;
- other_n->disconnected = n->disconnected;
- if (other_n->disconnected) *other_n->disconnected = &other;
-
- if (n->next) {
- other_n->next = n->next;
- n->next->asNotifier()->prev = &other_n->next;
- }
- other_n->prev = n->prev;
- *other_n->prev = &other;
-
- n->prev = 0;
- n->next = 0;
- n->disconnected = 0;
- n->notifier = 0;
- }
+ other.notifier = notifier;
+ other.sourceSignal = sourceSignal;
+ other.disconnected = disconnected;
+ other.notifying = notifying;
+ if (other.disconnected) *other.disconnected = &other;
+
+ if (next) {
+ other.next = next;
+ next->prev = &other.next;
+ }
+ other.prev = prev;
+ *other.prev = &other;
+
+ prev = 0;
+ next = 0;
+ disconnected = 0;
+ notifier = 0;
+ notifying = 0;
+ sourceSignal = -1;
}
-
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativenotifier_p.h b/src/declarative/qml/qdeclarativenotifier_p.h
index 6974ea2eed..06c0ba0918 100644
--- a/src/declarative/qml/qdeclarativenotifier_p.h
+++ b/src/declarative/qml/qdeclarativenotifier_p.h
@@ -42,7 +42,8 @@
#ifndef QDECLARATIVENOTIFIER_P_H
#define QDECLARATIVENOTIFIER_P_H
-#include "private/qdeclarativeguard_p.h"
+#include "qdeclarativedata_p.h"
+#include "qdeclarativeguard_p.h"
QT_BEGIN_NAMESPACE
@@ -55,6 +56,7 @@ public:
inline void notify();
private:
+ friend class QDeclarativeData;
friend class QDeclarativeNotifierEndpoint;
static void emitNotify(QDeclarativeNotifierEndpoint *);
@@ -65,11 +67,10 @@ class QDeclarativeNotifierEndpoint
{
public:
inline QDeclarativeNotifierEndpoint();
- inline QDeclarativeNotifierEndpoint(QObject *t, int m);
inline ~QDeclarativeNotifierEndpoint();
- QObject *target;
- int targetMethod;
+ typedef void (*Callback)(QDeclarativeNotifierEndpoint *);
+ Callback callback;
inline bool isConnected();
inline bool isConnected(QObject *source, int sourceSignal);
@@ -79,41 +80,24 @@ public:
inline void connect(QDeclarativeNotifier *);
inline void disconnect();
+ inline bool isNotifying() const;
+ inline void cancelNotify();
+
void copyAndClear(QDeclarativeNotifierEndpoint &other);
private:
+ friend class QDeclarativeData;
friend class QDeclarativeNotifier;
- struct Signal {
- QDeclarativeGuard<QObject> source;
- int sourceSignal;
- };
-
- struct Notifier {
- QDeclarativeNotifier *notifier;
- QDeclarativeNotifierEndpoint **disconnected;
-
- QDeclarativeNotifierEndpoint *next;
- QDeclarativeNotifierEndpoint **prev;
- };
-
- enum { InvalidType, SignalType, NotifierType } type;
union {
- struct {
- Signal *signal;
- union {
- char signalData[sizeof(Signal)];
- qint64 q_for_alignment_1;
- double q_for_alignment_2;
- };
- };
- Notifier notifier;
+ QDeclarativeNotifier *notifier;
+ QObject *source;
};
-
- inline Notifier *toNotifier();
- inline Notifier *asNotifier();
- inline Signal *toSignal();
- inline Signal *asSignal();
+ unsigned int notifying : 1;
+ signed int sourceSignal : 31;
+ QDeclarativeNotifierEndpoint **disconnected;
+ QDeclarativeNotifierEndpoint *next;
+ QDeclarativeNotifierEndpoint **prev;
};
QDeclarativeNotifier::QDeclarativeNotifier()
@@ -125,12 +109,13 @@ QDeclarativeNotifier::~QDeclarativeNotifier()
{
QDeclarativeNotifierEndpoint *endpoint = endpoints;
while (endpoint) {
- QDeclarativeNotifierEndpoint::Notifier *n = endpoint->asNotifier();
+ QDeclarativeNotifierEndpoint *n = endpoint;
endpoint = n->next;
n->next = 0;
n->prev = 0;
n->notifier = 0;
+ n->sourceSignal = -1;
if (n->disconnected) *n->disconnected = 0;
n->disconnected = 0;
}
@@ -143,123 +128,76 @@ void QDeclarativeNotifier::notify()
}
QDeclarativeNotifierEndpoint::QDeclarativeNotifierEndpoint()
-: target(0), targetMethod(0), type(InvalidType)
-{
-}
-
-QDeclarativeNotifierEndpoint::QDeclarativeNotifierEndpoint(QObject *t, int m)
-: target(t), targetMethod(m), type(InvalidType)
+: callback(0), notifier(0), notifying(0), sourceSignal(-1), disconnected(0), next(0), prev(0)
{
}
QDeclarativeNotifierEndpoint::~QDeclarativeNotifierEndpoint()
{
disconnect();
- if (SignalType == type) {
- Signal *s = asSignal();
- s->~Signal();
- }
}
bool QDeclarativeNotifierEndpoint::isConnected()
{
- if (SignalType == type) {
- return asSignal()->source;
- } else if (NotifierType == type) {
- return asNotifier()->notifier;
- } else {
- return false;
- }
+ return prev != 0;
}
bool QDeclarativeNotifierEndpoint::isConnected(QObject *source, int sourceSignal)
{
- return SignalType == type && asSignal()->source == source && asSignal()->sourceSignal == sourceSignal;
+ return this->sourceSignal != -1 && this->source == source && this->sourceSignal == sourceSignal;
}
bool QDeclarativeNotifierEndpoint::isConnected(QDeclarativeNotifier *notifier)
{
- return NotifierType == type && asNotifier()->notifier == notifier;
+ return sourceSignal == -1 && this->notifier == notifier;
}
void QDeclarativeNotifierEndpoint::connect(QDeclarativeNotifier *notifier)
{
- Notifier *n = toNotifier();
-
- if (n->notifier == notifier)
- return;
-
disconnect();
- n->next = notifier->endpoints;
- if (n->next) { n->next->asNotifier()->prev = &n->next; }
+ next = notifier->endpoints;
+ if (next) { next->prev = &next; }
notifier->endpoints = this;
- n->prev = &notifier->endpoints;
- n->notifier = notifier;
+ prev = &notifier->endpoints;
+ this->notifier = notifier;
}
void QDeclarativeNotifierEndpoint::disconnect()
{
- if (type == SignalType) {
- Signal *s = asSignal();
- if (s->source) {
- QMetaObject::disconnectOne(s->source, s->sourceSignal, target, targetMethod);
- s->source = 0;
- }
- } else if (type == NotifierType) {
- Notifier *n = asNotifier();
-
- if (n->next) n->next->asNotifier()->prev = n->prev;
- if (n->prev) *n->prev = n->next;
- if (n->disconnected) *n->disconnected = 0;
- n->next = 0;
- n->prev = 0;
- n->disconnected = 0;
- n->notifier = 0;
- }
-}
-
-QDeclarativeNotifierEndpoint::Notifier *QDeclarativeNotifierEndpoint::toNotifier()
-{
- if (NotifierType == type)
- return asNotifier();
-
- if (SignalType == type) {
- disconnect();
- Signal *s = asSignal();
- s->~Signal();
- }
-
- type = NotifierType;
- Notifier *n = asNotifier();
- n->next = 0;
- n->prev = 0;
- n->disconnected = 0;
- n->notifier = 0;
- return n;
+ if (next) next->prev = prev;
+ if (prev) *prev = next;
+ if (disconnected) *disconnected = 0;
+ next = 0;
+ prev = 0;
+ disconnected = 0;
+ notifier = 0;
+ notifying = 0;
+ sourceSignal = -1;
}
-QDeclarativeNotifierEndpoint::Notifier *QDeclarativeNotifierEndpoint::asNotifier()
-{
- Q_ASSERT(type == NotifierType);
- return &notifier;
-}
+/*!
+Returns true if a notify is in progress. This means that the signal or QDeclarativeNotifier
+that this endpoing is connected to has been triggered, but this endpoint's callback has not
+yet been called.
-QDeclarativeNotifierEndpoint::Signal *QDeclarativeNotifierEndpoint::toSignal()
+An in progress notify can be cancelled by calling cancelNotify.
+*/
+bool QDeclarativeNotifierEndpoint::isNotifying() const
{
- if (SignalType == type)
- return asSignal();
-
- disconnect();
- signal = new (&signalData) Signal;
- type = SignalType;
- return signal;
+ return notifying == 1;
}
-QDeclarativeNotifierEndpoint::Signal *QDeclarativeNotifierEndpoint::asSignal()
-{
- Q_ASSERT(type == SignalType);
- return signal;
+/*!
+Cancel any notifies that are in progress.
+*/
+void QDeclarativeNotifierEndpoint::cancelNotify()
+{
+ notifying = 0;
+ if (disconnected) {
+ *disconnected = 0;
+ disconnected = 0;
+ }
}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp
index acc2cfb752..7a43ef1a3e 100644
--- a/src/declarative/qml/qdeclarativeproperty.cpp
+++ b/src/declarative/qml/qdeclarativeproperty.cpp
@@ -40,21 +40,21 @@
****************************************************************************/
#include "qdeclarativeproperty.h"
-#include "private/qdeclarativeproperty_p.h"
+#include "qdeclarativeproperty_p.h"
#include "qdeclarative.h"
-#include "private/qdeclarativebinding_p.h"
+#include "qdeclarativebinding_p.h"
#include "qdeclarativecontext.h"
-#include "private/qdeclarativecontext_p.h"
-#include "private/qdeclarativeboundsignal_p.h"
+#include "qdeclarativecontext_p.h"
+#include "qdeclarativeboundsignal_p.h"
#include "qdeclarativeengine.h"
-#include "private/qdeclarativeengine_p.h"
-#include "private/qdeclarativedata_p.h"
-#include "private/qdeclarativestringconverters_p.h"
-#include "private/qdeclarativelist_p.h"
-#include "private/qdeclarativecompiler_p.h"
-#include "private/qdeclarativevmemetaobject_p.h"
-#include "private/qdeclarativeexpression_p.h"
+#include "qdeclarativeengine_p.h"
+#include "qdeclarativedata_p.h"
+#include "qdeclarativestringconverters_p.h"
+#include "qdeclarativelist_p.h"
+#include "qdeclarativecompiler_p.h"
+#include "qdeclarativevmemetaobject_p.h"
+#include "qdeclarativeexpression_p.h"
#include <QStringList>
#include <QtCore/qdebug.h>
@@ -285,11 +285,18 @@ void QDeclarativePropertyPrivate::initProperty(QObject *obj, const QString &name
QMetaProperty vtProp = typeObject->metaObject()->property(idx);
+ typedef QDeclarativePropertyCache::Data PCD;
+
+ Q_ASSERT(PCD::flagsForProperty(vtProp) <= PCD::ValueTypeFlagMask);
+ Q_ASSERT(vtProp.userType() <= 0xFF);
+ Q_ASSERT(idx <= 0xFF);
+
object = currentObject;
core = *property;
- valueType.flags = QDeclarativePropertyCache::Data::flagsForProperty(vtProp);
- valueType.valueTypeCoreIdx = idx;
- valueType.valueTypePropType = vtProp.userType();
+ core.setFlags(core.getFlags() | PCD::IsValueTypeVirtual);
+ core.valueTypeFlags = PCD::flagsForProperty(vtProp);
+ core.valueTypePropType = vtProp.userType();
+ core.valueTypeCoreIndex = idx;
return;
} else {
@@ -413,7 +420,7 @@ const char *QDeclarativeProperty::propertyTypeName() const
else valueType = QDeclarativeValueTypeFactory::valueType(d->core.propType);
Q_ASSERT(valueType);
- const char *rv = valueType->metaObject()->property(d->valueType.valueTypeCoreIdx).typeName();
+ const char *rv = valueType->metaObject()->property(d->core.valueTypeCoreIndex).typeName();
if (!ep) delete valueType;
@@ -437,8 +444,10 @@ bool QDeclarativeProperty::operator==(const QDeclarativeProperty &other) const
// from the other members
return d->object == other.d->object &&
d->core.coreIndex == other.d->core.coreIndex &&
- d->valueType.valueTypeCoreIdx == other.d->valueType.valueTypeCoreIdx &&
- d->valueType.valueTypePropType == other.d->valueType.valueTypePropType;
+ d->core.isValueTypeVirtual() == other.d->core.isValueTypeVirtual() &&
+ (!d->core.isValueTypeVirtual() ||
+ (d->core.valueTypeCoreIndex == other.d->core.valueTypeCoreIndex &&
+ d->core.valueTypePropType == other.d->core.valueTypePropType));
}
/*!
@@ -452,14 +461,14 @@ int QDeclarativeProperty::propertyType() const
bool QDeclarativePropertyPrivate::isValueType() const
{
- return valueType.valueTypeCoreIdx != -1;
+ return core.isValueTypeVirtual();
}
int QDeclarativePropertyPrivate::propertyType() const
{
uint type = this->type();
if (isValueType()) {
- return valueType.valueTypePropType;
+ return core.valueTypePropType;
} else if (type & QDeclarativeProperty::Property) {
if (core.propType == (int)QVariant::LastType)
return qMetaTypeId<QVariant>();
@@ -601,7 +610,8 @@ QString QDeclarativeProperty::name() const
else valueType = QDeclarativeValueTypeFactory::valueType(d->core.propType);
Q_ASSERT(valueType);
- rv += QString::fromUtf8(valueType->metaObject()->property(d->valueType.valueTypeCoreIdx).name());
+ const char *vtName = valueType->metaObject()->property(d->core.valueTypeCoreIndex).name();
+ rv += QString::fromUtf8(vtName);
if (!ep) delete valueType;
@@ -657,7 +667,8 @@ QDeclarativePropertyPrivate::binding(const QDeclarativeProperty &that)
if (!that.d || !that.isProperty() || !that.d->object)
return 0;
- return binding(that.d->object, that.d->core.coreIndex, that.d->valueType.valueTypeCoreIdx);
+ return binding(that.d->object, that.d->core.coreIndex,
+ that.d->core.getValueTypeCoreIndex());
}
/*!
@@ -685,7 +696,8 @@ QDeclarativePropertyPrivate::setBinding(const QDeclarativeProperty &that,
}
return that.d->setBinding(that.d->object, that.d->core.coreIndex,
- that.d->valueType.valueTypeCoreIdx, newBinding, flags);
+ that.d->core.getValueTypeCoreIndex(),
+ newBinding, flags);
}
QDeclarativeAbstractBinding *
@@ -1003,8 +1015,7 @@ QVariant QDeclarativePropertyPrivate::readValueProperty()
valueType->read(object, core.coreIndex);
- QVariant rv =
- valueType->metaObject()->property(this->valueType.valueTypeCoreIdx).read(valueType);
+ QVariant rv = valueType->metaObject()->property(core.valueTypeCoreIndex).read(valueType);
if (!ep) delete valueType;
return rv;
@@ -1070,16 +1081,25 @@ bool QDeclarativePropertyPrivate::writeEnumProperty(const QMetaProperty &prop, i
bool QDeclarativePropertyPrivate::writeValueProperty(const QVariant &value, WriteFlags flags)
{
+ return writeValueProperty(object, engine, core, value, effectiveContext(), flags);
+}
+
+bool
+QDeclarativePropertyPrivate::writeValueProperty(QObject *object, QDeclarativeEngine *engine,
+ const QDeclarativePropertyCache::Data &core,
+ const QVariant &value,
+ QDeclarativeContextData *context, WriteFlags flags)
+{
// Remove any existing bindings on this property
- if (!(flags & DontRemoveBinding) &&
- (type() & QDeclarativeProperty::Property) && object) {
+ if (!(flags & DontRemoveBinding) && object) {
QDeclarativeAbstractBinding *binding = setBinding(object, core.coreIndex,
- valueType.valueTypeCoreIdx, 0, flags);
+ core.getValueTypeCoreIndex(),
+ 0, flags);
if (binding) binding->destroy();
}
bool rv = false;
- if (isValueType()) {
+ if (core.isValueTypeVirtual()) {
QDeclarativeEnginePrivate *ep = engine?QDeclarativeEnginePrivate::get(engine):0;
QDeclarativeValueType *writeBack = 0;
@@ -1092,24 +1112,26 @@ bool QDeclarativePropertyPrivate::writeValueProperty(const QVariant &value, Writ
writeBack->read(object, core.coreIndex);
QDeclarativePropertyCache::Data data = core;
- data.setFlags(valueType.flags);
- data.coreIndex = valueType.valueTypeCoreIdx;
- data.propType = valueType.valueTypePropType;
- rv = write(writeBack, data, value, effectiveContext(), flags);
+ data.setFlags(QDeclarativePropertyCache::Data::Flag(core.valueTypeFlags));
+ data.coreIndex = core.valueTypeCoreIndex;
+ data.propType = core.valueTypePropType;
+
+ rv = write(writeBack, data, value, context, flags);
writeBack->write(object, core.coreIndex, flags);
if (!ep) delete writeBack;
} else {
- rv = write(object, core, value, effectiveContext(), flags);
+ rv = write(object, core, value, context, flags);
}
return rv;
}
-bool QDeclarativePropertyPrivate::write(QObject *object, const QDeclarativePropertyCache::Data &property,
+bool QDeclarativePropertyPrivate::write(QObject *object,
+ const QDeclarativePropertyCache::Data &property,
const QVariant &value, QDeclarativeContextData *context,
WriteFlags flags)
{
@@ -1272,33 +1294,31 @@ bool QDeclarativePropertyPrivate::write(QObject *object, const QDeclarativePrope
}
// Returns true if successful, false if an error description was set on expression
-bool QDeclarativePropertyPrivate::writeBinding(const QDeclarativeProperty &that,
+bool QDeclarativePropertyPrivate::writeBinding(QObject *object,
+ const QDeclarativePropertyCache::Data &core,
QDeclarativeJavaScriptExpression *expression,
v8::Handle<v8::Value> result, bool isUndefined,
WriteFlags flags)
{
- QV8Engine *engine = QDeclarativeEnginePrivate::getV8Engine(expression->context()->engine);
-
- QDeclarativePropertyPrivate *pp = that.d;
+ Q_ASSERT(object);
+ Q_ASSERT(core.coreIndex != -1);
- if (!pp)
- return true;
-
- QObject *object = that.object();
- int type = that.propertyType();
+ QDeclarativeContextData *context = expression->context();
+ QDeclarativeEngine *engine = context->engine;
+ QV8Engine *v8engine = QDeclarativeEnginePrivate::getV8Engine(engine);
#define QUICK_STORE(cpptype, conversion) \
{ \
cpptype o = (conversion); \
int status = -1; \
void *argv[] = { &o, 0, &status, &flags }; \
- QMetaObject::metacall(object, QMetaObject::WriteProperty, pp->core.coreIndex, argv); \
+ QMetaObject::metacall(object, QMetaObject::WriteProperty, core.coreIndex, argv); \
return true; \
} \
- if (object && pp->valueType.valueTypeCoreIdx == -1) {
- switch (type) {
+ if (!isUndefined && !core.isValueTypeVirtual()) {
+ switch (core.propType) {
case QMetaType::Int:
if (result->IsInt32())
QUICK_STORE(int, result->Int32Value())
@@ -1315,43 +1335,49 @@ bool QDeclarativePropertyPrivate::writeBinding(const QDeclarativeProperty &that,
break;
case QMetaType::QString:
if (result->IsString())
- QUICK_STORE(QString, engine->toString(result))
+ QUICK_STORE(QString, v8engine->toString(result))
break;
default:
break;
}
}
-
#undef QUICK_STORE
+ int type = core.isValueTypeVirtual()?core.valueTypePropType:core.propType;
+
QDeclarativeDeleteWatcher watcher(expression);
QVariant value;
+ bool isVmeProperty = core.isVMEProperty();
if (isUndefined) {
- } else if (that.propertyTypeCategory() == QDeclarativeProperty::List) {
- value = engine->toVariant(result, qMetaTypeId<QList<QObject *> >());
- } else if (result->IsNull() && that.propertyTypeCategory() == QDeclarativeProperty::Object) {
+ } else if (core.isQList()) {
+ value = v8engine->toVariant(result, qMetaTypeId<QList<QObject *> >());
+ } else if (result->IsNull() && core.isQObject()) {
value = QVariant::fromValue((QObject *)0);
- } else {
- value = engine->toVariant(result, type);
+ } else if (!isVmeProperty) {
+ value = v8engine->toVariant(result, type);
}
if (expression->error.isValid()) {
return false;
- } else if (isUndefined && that.isResettable()) {
- that.reset();
+ } else if (isUndefined && core.isResettable()) {
+ void *args[] = { 0 };
+ QMetaObject::metacall(object, QMetaObject::ResetProperty, core.coreIndex, args);
} else if (isUndefined && type == qMetaTypeId<QVariant>()) {
- QDeclarativePropertyPrivate::write(that, QVariant(), flags);
+ writeValueProperty(object, engine, core, QVariant(), context, flags);
} else if (isUndefined) {
expression->error.setDescription(QLatin1String("Unable to assign [undefined] to ") +
- QLatin1String(QMetaType::typeName(type)) +
- QLatin1String(" ") + that.name());
+ QLatin1String(QMetaType::typeName(type)));
return false;
} else if (result->IsFunction()) {
expression->error.setDescription(QLatin1String("Unable to assign a function to a property."));
return false;
- } else if (object && !QDeclarativePropertyPrivate::write(that, value, flags)) {
+ } else if (isVmeProperty) {
+ typedef QDeclarativeVMEMetaObject VMEMO;
+ VMEMO *vmemo = static_cast<VMEMO *>(const_cast<QMetaObject *>(object->metaObject()));
+ vmemo->setVMEProperty(core.coreIndex, result);
+ } else if (!writeValueProperty(object, engine, core, value, context, flags)) {
if (watcher.wasDeleted())
return true;
@@ -1370,6 +1396,23 @@ bool QDeclarativePropertyPrivate::writeBinding(const QDeclarativeProperty &that,
return true;
}
+bool QDeclarativePropertyPrivate::writeBinding(const QDeclarativeProperty &that,
+ QDeclarativeJavaScriptExpression *expression,
+ v8::Handle<v8::Value> result, bool isUndefined,
+ WriteFlags flags)
+{
+ QDeclarativePropertyPrivate *pp = that.d;
+
+ if (!pp)
+ return true;
+
+ QObject *object = that.object();
+ if (!object)
+ return true;
+
+ return writeBinding(object, pp->core, expression, result, isUndefined, flags);
+}
+
const QMetaObject *QDeclarativePropertyPrivate::rawMetaObjectForType(QDeclarativeEnginePrivate *engine, int userType)
{
if (engine) {
@@ -1546,7 +1589,7 @@ int QDeclarativeProperty::index() const
int QDeclarativePropertyPrivate::valueTypeCoreIndex(const QDeclarativeProperty &that)
{
- return that.d ? that.d->valueType.valueTypeCoreIdx : -1;
+ return that.d ? that.d->core.getValueTypeCoreIndex() : -1;
}
/*!
@@ -1557,73 +1600,38 @@ int QDeclarativePropertyPrivate::bindingIndex(const QDeclarativeProperty &that)
{
if (!that.d)
return -1;
- int rv = that.d->core.coreIndex;
- if (rv != -1 && that.d->valueType.valueTypeCoreIdx != -1)
- rv = rv | (that.d->valueType.valueTypeCoreIdx << 24);
- return rv;
+ return bindingIndex(that.d->core);
}
-struct SerializedData {
- bool isValueType;
- QDeclarativePropertyCache::Data core;
-};
-
-struct ValueTypeSerializedData : public SerializedData {
- QDeclarativePropertyCache::ValueTypeData valueType;
-};
-
-QByteArray QDeclarativePropertyPrivate::saveValueType(const QMetaObject *metaObject, int index,
- const QMetaObject *subObject, int subIndex,
- QDeclarativeEngine *)
+int QDeclarativePropertyPrivate::bindingIndex(const QDeclarativePropertyCache::Data &that)
{
- QMetaProperty prop = metaObject->property(index);
- QMetaProperty subProp = subObject->property(subIndex);
-
- ValueTypeSerializedData sd;
- memset(&sd, 0, sizeof(sd));
- sd.isValueType = true;
- sd.core.load(metaObject->property(index));
- sd.valueType.flags = QDeclarativePropertyCache::Data::flagsForProperty(subProp);
- sd.valueType.valueTypeCoreIdx = subIndex;
- sd.valueType.valueTypePropType = subProp.userType();
-
- QByteArray rv((const char *)&sd, sizeof(sd));
-
+ int rv = that.coreIndex;
+ if (rv != -1 && that.isValueTypeVirtual())
+ rv = rv | (that.valueTypeCoreIndex << 24);
return rv;
}
-QByteArray QDeclarativePropertyPrivate::saveProperty(const QMetaObject *metaObject, int index,
- QDeclarativeEngine *engine)
+QDeclarativePropertyCache::Data
+QDeclarativePropertyPrivate::saveValueType(const QMetaObject *metaObject, int index,
+ const QMetaObject *subObject, int subIndex,
+ QDeclarativeEngine *)
{
- SerializedData sd;
- memset(&sd, 0, sizeof(sd));
- sd.isValueType = false;
- sd.core.load(metaObject->property(index), engine);
-
- QByteArray rv((const char *)&sd, sizeof(sd));
- return rv;
-}
-
-QDeclarativeProperty
-QDeclarativePropertyPrivate::restore(const QByteArray &data, QObject *object, QDeclarativeContextData *ctxt)
-{
- QDeclarativeProperty prop;
+ QMetaProperty prop = metaObject->property(index);
+ QMetaProperty subProp = subObject->property(subIndex);
- if (data.isEmpty())
- return prop;
+ QDeclarativePropertyCache::Data core;
+ core.load(metaObject->property(index));
+ core.setFlags(core.getFlags() | QDeclarativePropertyCache::Data::IsValueTypeVirtual);
+ core.valueTypeFlags = QDeclarativePropertyCache::Data::flagsForProperty(subProp);
+ core.valueTypeCoreIndex = subIndex;
+ core.valueTypePropType = subProp.userType();
- const SerializedData *sd = (const SerializedData *)data.constData();
- if (sd->isValueType) {
- const ValueTypeSerializedData *vt = (const ValueTypeSerializedData *)sd;
- return restore(vt->core, vt->valueType, object, ctxt);
- } else {
- QDeclarativePropertyCache::ValueTypeData data;
- return restore(sd->core, data, object, ctxt);
- }
+ return core;
}
QDeclarativeProperty
-QDeclarativePropertyPrivate::restore(const QDeclarativePropertyCache::Data &data, const QDeclarativePropertyCache::ValueTypeData &valueType, QObject *object, QDeclarativeContextData *ctxt)
+QDeclarativePropertyPrivate::restore(const QDeclarativePropertyCache::Data &data,
+ QObject *object, QDeclarativeContextData *ctxt)
{
QDeclarativeProperty prop;
@@ -1633,7 +1641,6 @@ QDeclarativePropertyPrivate::restore(const QDeclarativePropertyCache::Data &data
prop.d->engine = ctxt?ctxt->engine:0;
prop.d->core = data;
- prop.d->valueType = valueType;
return prop;
}
@@ -1763,6 +1770,11 @@ bool QDeclarativePropertyPrivate::connect(const QObject *sender, int signal_inde
return QMetaObject::connect(sender, signal_index, receiver, method_index, type, types);
}
+void QDeclarativePropertyPrivate::flushSignal(const QObject *sender, int signal_index)
+{
+ flush_vme_signal(sender, signal_index);
+}
+
/*!
Return \a metaObject's [super] meta object that provides data for \a property.
*/
diff --git a/src/declarative/qml/qdeclarativeproperty_p.h b/src/declarative/qml/qdeclarativeproperty_p.h
index d05e15558f..5bfbf47c0d 100644
--- a/src/declarative/qml/qdeclarativeproperty_p.h
+++ b/src/declarative/qml/qdeclarativeproperty_p.h
@@ -84,9 +84,6 @@ public:
QDeclarativePropertyCache::Data core;
QString nameCache;
- // Describes the "virtual" value-type sub-property.
- QDeclarativePropertyCache::ValueTypeData valueType;
-
void initProperty(QObject *obj, const QString &name);
void initDefault(QObject *obj);
@@ -101,6 +98,10 @@ public:
static const QMetaObject *rawMetaObjectForType(QDeclarativeEnginePrivate *, int);
static bool writeEnumProperty(const QMetaProperty &prop, int idx, QObject *object,
const QVariant &value, int flags);
+ static bool writeValueProperty(QObject *, QDeclarativeEngine *,
+ const QDeclarativePropertyCache::Data &,
+ const QVariant &, QDeclarativeContextData *,
+ WriteFlags flags = 0);
static bool write(QObject *, const QDeclarativePropertyCache::Data &, const QVariant &,
QDeclarativeContextData *, WriteFlags flags = 0);
static void findAliasTarget(QObject *, int, QObject **, int *);
@@ -111,20 +112,18 @@ public:
QDeclarativeAbstractBinding *);
static QDeclarativeAbstractBinding *binding(QObject *, int coreIndex, int valueTypeIndex /* -1 */);
- static QByteArray saveValueType(const QMetaObject *, int,
- const QMetaObject *, int,
- QDeclarativeEngine *);
- static QByteArray saveProperty(const QMetaObject *, int,
- QDeclarativeEngine *);
-
- static QDeclarativeProperty restore(const QByteArray &, QObject *, QDeclarativeContextData *);
+ static QDeclarativePropertyCache::Data saveValueType(const QMetaObject *, int,
+ const QMetaObject *, int,
+ QDeclarativeEngine *);
static QDeclarativeProperty restore(const QDeclarativePropertyCache::Data &,
- const QDeclarativePropertyCache::ValueTypeData &,
QObject *,
QDeclarativeContextData *);
static bool equal(const QMetaObject *, const QMetaObject *);
static bool canConvert(const QMetaObject *from, const QMetaObject *to);
+ static inline QDeclarativePropertyPrivate *get(const QDeclarativeProperty &p) {
+ return p.d;
+ }
// "Public" (to QML) methods
static QDeclarativeAbstractBinding *binding(const QDeclarativeProperty &that);
@@ -139,13 +138,19 @@ public:
QDeclarativeJavaScriptExpression *expression,
v8::Handle<v8::Value> result, bool isUndefined,
WriteFlags flags);
+ static bool writeBinding(QObject *, const QDeclarativePropertyCache::Data &,
+ QDeclarativeJavaScriptExpression *expression,
+ v8::Handle<v8::Value> result, bool isUndefined,
+ WriteFlags flags);
static int valueTypeCoreIndex(const QDeclarativeProperty &that);
static int bindingIndex(const QDeclarativeProperty &that);
+ static int bindingIndex(const QDeclarativePropertyCache::Data &that);
static QMetaMethod findSignalByName(const QMetaObject *mo, const QByteArray &);
static bool connect(const QObject *sender, int signal_index,
const QObject *receiver, int method_index,
int type = 0, int *types = 0);
static const QMetaObject *metaObjectForProperty(const QMetaObject *, int);
+ static void flushSignal(const QObject *sender, int signal_index);
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativePropertyPrivate::WriteFlags)
diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp
index e35fa52eed..134c588538 100644
--- a/src/declarative/qml/qdeclarativepropertycache.cpp
+++ b/src/declarative/qml/qdeclarativepropertycache.cpp
@@ -39,11 +39,11 @@
**
****************************************************************************/
-#include "private/qdeclarativepropertycache_p.h"
+#include "qdeclarativepropertycache_p.h"
-#include "private/qdeclarativeengine_p.h"
-#include "private/qdeclarativebinding_p.h"
-#include "private/qv8engine_p.h"
+#include "qdeclarativeengine_p.h"
+#include "qdeclarativebinding_p.h"
+#include <private/qv8engine_p.h>
#include <private/qmetaobject_p.h>
@@ -200,7 +200,7 @@ void QDeclarativePropertyCache::Data::lazyLoad(const QMetaMethod &m)
Creates a new empty QDeclarativePropertyCache.
*/
QDeclarativePropertyCache::QDeclarativePropertyCache(QDeclarativeEngine *e)
-: QDeclarativeCleanup(e), engine(e), parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0)
+: engine(e), parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0)
{
Q_ASSERT(engine);
}
@@ -209,7 +209,7 @@ QDeclarativePropertyCache::QDeclarativePropertyCache(QDeclarativeEngine *e)
Creates a new QDeclarativePropertyCache of \a metaObject.
*/
QDeclarativePropertyCache::QDeclarativePropertyCache(QDeclarativeEngine *e, const QMetaObject *metaObject)
-: QDeclarativeCleanup(e), engine(e), parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0)
+: engine(e), parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0)
{
Q_ASSERT(engine);
Q_ASSERT(metaObject);
@@ -223,6 +223,16 @@ QDeclarativePropertyCache::~QDeclarativePropertyCache()
if (parent) parent->release();
parent = 0;
+ engine = 0;
+}
+
+void QDeclarativePropertyCache::destroy()
+{
+ Q_ASSERT(engine || constructor.IsEmpty());
+ if (constructor.IsEmpty())
+ delete this;
+ else
+ QDeclarativeEnginePrivate::deleteInEngineThread(engine, this);
}
// This is inherited from QDeclarativeCleanup, so it should only clear the things
@@ -305,8 +315,7 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
Data::Flag propertyFlags, Data::Flag methodFlags, Data::Flag signalFlags)
{
Q_UNUSED(revision);
-
- qPersistentDispose(constructor); // Now invalid
+ Q_ASSERT(constructor.IsEmpty()); // We should not be appending to an in-use property cache
bool dynamicMetaObject = isDynamicMetaObject(metaObject);
@@ -329,8 +338,12 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
// Extract method name
const char *signature = m.signature();
const char *cptr = signature;
- bool utf8 = false;
- while (*cptr != '(') { Q_ASSERT(*cptr != 0); utf8 |= *cptr & 0x80; ++cptr; }
+ char utf8 = 0;
+ while (*cptr != '(') {
+ Q_ASSERT(*cptr != 0);
+ utf8 |= *cptr & 0x80;
+ ++cptr;
+ }
Data *data = &methodIndexCache[ii - methodIndexCacheStart];
Data *sigdata = 0;
@@ -408,9 +421,12 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
continue;
const char *str = p.name();
- bool utf8 = false;
+ char utf8 = 0;
const char *cptr = str;
- while (*cptr != 0) { utf8 |= *cptr & 0x80; ++cptr; }
+ while (*cptr != 0) {
+ utf8 |= *cptr & 0x80;
+ ++cptr;
+ }
Data *data = &propertyIndexCache[ii - propertyIndexCacheStart];
diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h
index 33565c4d45..068db589bd 100644
--- a/src/declarative/qml/qdeclarativepropertycache_p.h
+++ b/src/declarative/qml/qdeclarativepropertycache_p.h
@@ -53,11 +53,11 @@
// We mean it.
//
-#include "private/qdeclarativerefcount_p.h"
-#include "private/qdeclarativecleanup_p.h"
-#include "private/qdeclarativenotifier_p.h"
+#include <private/qdeclarativerefcount_p.h>
+#include "qdeclarativecleanup_p.h"
+#include "qdeclarativenotifier_p.h"
-#include "private/qhashedstring_p.h"
+#include <private/qhashedstring_p.h>
#include <QtCore/qvector.h>
QT_BEGIN_NAMESPACE
@@ -74,44 +74,48 @@ public:
QDeclarativePropertyCache(QDeclarativeEngine *, const QMetaObject *);
virtual ~QDeclarativePropertyCache();
- struct Data {
- inline Data();
- inline bool operator==(const Data &);
-
+ // We have this somewhat aweful split between RawData and Data so that RawData can be
+ // used in unions. In normal code, you should always use Data which initializes RawData
+ // to an invalid state on construction.
+ struct Data;
+ struct RawData {
enum Flag {
NoFlags = 0x00000000,
+ ValueTypeFlagMask = 0x0000FFFF, // Flags in valueTypeFlags must fit in this mask
// Can apply to all properties, except IsFunction
- IsConstant = 0x00000001, // Has CONST flag
- IsWritable = 0x00000002, // Has WRITE function
- IsResettable = 0x00000004, // Has RESET function
- IsAlias = 0x00000008, // Is a QML alias to another property
- IsFinal = 0x00000010, // Has FINAL flag
- IsDirect = 0x00000020, // Exists on a C++ QMetaObject
+ IsConstant = 0x00000001, // Has CONST flag
+ IsWritable = 0x00000002, // Has WRITE function
+ IsResettable = 0x00000004, // Has RESET function
+ IsAlias = 0x00000008, // Is a QML alias to another property
+ IsFinal = 0x00000010, // Has FINAL flag
+ IsDirect = 0x00000020, // Exists on a C++ QMetaObject
// These are mutualy exclusive
- IsFunction = 0x00000040, // Is an invokable
- IsQObjectDerived = 0x00000080, // Property type is a QObject* derived type
- IsEnumType = 0x00000100, // Property type is an enum
- IsQList = 0x00000200, // Property type is a QML list
- IsQmlBinding = 0x00000400, // Property type is a QDeclarativeBinding*
- IsQJSValue = 0x00000800, // Property type is a QScriptValue
- IsV8Handle = 0x00001000, // Property type is a QDeclarativeV8Handle
+ IsFunction = 0x00000040, // Is an invokable
+ IsQObjectDerived = 0x00000080, // Property type is a QObject* derived type
+ IsEnumType = 0x00000100, // Property type is an enum
+ IsQList = 0x00000200, // Property type is a QML list
+ IsQmlBinding = 0x00000400, // Property type is a QDeclarativeBinding*
+ IsQJSValue = 0x00000800, // Property type is a QScriptValue
+ IsV8Handle = 0x00001000, // Property type is a QDeclarativeV8Handle
+ IsVMEProperty = 0x00002000, // Property type is a "var" property of VMEMO
+ IsValueTypeVirtual = 0x00004000, // Property is a value type "virtual" property
// Apply only to IsFunctions
- IsVMEFunction = 0x00002000, // Function was added by QML
- HasArguments = 0x00004000, // Function takes arguments
- IsSignal = 0x00008000, // Function is a signal
- IsVMESignal = 0x00010000, // Signal was added by QML
- IsV8Function = 0x00020000, // Function takes QDeclarativeV8Function* args
- IsSignalHandler = 0x00040000, // Function is a signal handler
+ IsVMEFunction = 0x00008000, // Function was added by QML
+ HasArguments = 0x00010000, // Function takes arguments
+ IsSignal = 0x00020000, // Function is a signal
+ IsVMESignal = 0x00040000, // Signal was added by QML
+ IsV8Function = 0x00080000, // Function takes QDeclarativeV8Function* args
+ IsSignalHandler = 0x00100000, // Function is a signal handler
// Internal QDeclarativePropertyCache flags
- NotFullyResolved = 0x00080000 // True if the type data is to be lazily resolved
+ NotFullyResolved = 0x00200000 // True if the type data is to be lazily resolved
};
Q_DECLARE_FLAGS(Flags, Flag)
- Flags getFlags() const { return flags; }
+ Flags getFlags() const { return Flag(flags); }
void setFlags(Flags f) { flags = f; }
bool isValid() const { return coreIndex != -1; }
@@ -129,6 +133,8 @@ public:
bool isQmlBinding() const { return flags & IsQmlBinding; }
bool isQJSValue() const { return flags & IsQJSValue; }
bool isV8Handle() const { return flags & IsV8Handle; }
+ bool isVMEProperty() const { return flags & IsVMEProperty; }
+ bool isValueTypeVirtual() const { return flags & IsValueTypeVirtual; }
bool isVMEFunction() const { return flags & IsVMEFunction; }
bool hasArguments() const { return flags & HasArguments; }
bool isSignal() const { return flags & IsSignal; }
@@ -142,34 +148,51 @@ public:
};
int coreIndex;
union {
- int notifyIndex; // When !IsFunction
+ int notifyIndex; // When !IsFunction
int relatedIndex; // When IsFunction
};
- uint overrideIndexIsProperty : 1;
- int overrideIndex : 31;
+ union {
+ struct { // When !IsValueTypeVirtual
+ uint overrideIndexIsProperty : 1;
+ signed int overrideIndex : 31;
+ };
+ struct { // When IsValueTypeVirtual
+ quint16 valueTypeFlags; // flags of the access property on the value type proxy object
+ quint8 valueTypePropType; // The QVariant::Type of access property on the value type
+ // proxy object
+ quint8 valueTypeCoreIndex; // The prop index of the access property on the value type
+ //proxy object
+ };
+ };
int revision;
int metaObjectOffset;
+ private:
+ friend struct Data;
+ friend class QDeclarativePropertyCache;
+ quint32 flags;
+ };
+
+ struct Data : public RawData {
+ inline Data();
+ inline Data(const RawData &);
+
+ inline bool operator==(const RawData &);
+
static Flags flagsForProperty(const QMetaProperty &, QDeclarativeEngine *engine = 0);
void load(const QMetaProperty &, QDeclarativeEngine *engine = 0);
void load(const QMetaMethod &);
QString name(QObject *);
QString name(const QMetaObject *);
+ // Returns -1 if not a value type virtual property
+ inline int getValueTypeCoreIndex() const;
+
private:
+ friend class QDeclarativePropertyCache;
void lazyLoad(const QMetaProperty &, QDeclarativeEngine *engine = 0);
void lazyLoad(const QMetaMethod &);
bool notFullyResolved() const { return flags & NotFullyResolved; }
- friend class QDeclarativePropertyCache;
- Flags flags;
- };
-
- struct ValueTypeData {
- inline ValueTypeData();
- inline bool operator==(const ValueTypeData &);
- Data::Flags flags; // flags of the access property on the value type proxy object
- int valueTypeCoreIdx; // The prop index of the access property on the value type proxy object
- int valueTypePropType; // The QVariant::Type of access property on the value type proxy object
};
void update(QDeclarativeEngine *, const QMetaObject *);
@@ -198,7 +221,9 @@ public:
static Data *property(QDeclarativeEngine *, QObject *, const QHashedV8String &, Data &);
static bool isDynamicMetaObject(const QMetaObject *);
+
protected:
+ virtual void destroy();
virtual void clear();
private:
@@ -231,18 +256,37 @@ private:
Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativePropertyCache::Data::Flags);
QDeclarativePropertyCache::Data::Data()
-: propType(0), coreIndex(-1), notifyIndex(-1), overrideIndexIsProperty(false), overrideIndex(-1),
- revision(0), metaObjectOffset(-1), flags(0)
{
+ propType = 0;
+ coreIndex = -1;
+ notifyIndex = -1;
+ overrideIndexIsProperty = false;
+ overrideIndex = -1;
+ revision = 0;
+ metaObjectOffset = -1;
+ flags = 0;
}
-bool QDeclarativePropertyCache::Data::operator==(const QDeclarativePropertyCache::Data &other)
+QDeclarativePropertyCache::Data::Data(const QDeclarativePropertyCache::RawData &d)
+{
+ *(static_cast<RawData *>(this)) = d;
+}
+
+bool QDeclarativePropertyCache::Data::operator==(const QDeclarativePropertyCache::RawData &other)
{
return flags == other.flags &&
propType == other.propType &&
coreIndex == other.coreIndex &&
notifyIndex == other.notifyIndex &&
- revision == other.revision;
+ revision == other.revision &&
+ (!isValueTypeVirtual() ||
+ (valueTypeCoreIndex == other.valueTypeCoreIndex &&
+ valueTypePropType == other.valueTypePropType));
+}
+
+int QDeclarativePropertyCache::Data::getValueTypeCoreIndex() const
+{
+ return isValueTypeVirtual()?valueTypeCoreIndex:-1;
}
QDeclarativePropertyCache::Data *
@@ -257,18 +301,6 @@ QDeclarativePropertyCache::overrideData(Data *data) const
return method(data->overrideIndex);
}
-QDeclarativePropertyCache::ValueTypeData::ValueTypeData()
-: flags(QDeclarativePropertyCache::Data::NoFlags), valueTypeCoreIdx(-1), valueTypePropType(0)
-{
-}
-
-bool QDeclarativePropertyCache::ValueTypeData::operator==(const ValueTypeData &o)
-{
- return flags == o.flags &&
- valueTypeCoreIdx == o.valueTypeCoreIdx &&
- valueTypePropType == o.valueTypePropType;
-}
-
bool QDeclarativePropertyCache::isAllowedInRevision(Data *data) const
{
return (data->metaObjectOffset == -1 && data->revision == 0) ||
diff --git a/src/declarative/qml/qdeclarativeproxymetaobject.cpp b/src/declarative/qml/qdeclarativeproxymetaobject.cpp
index 3263ae5af2..f4029fc76b 100644
--- a/src/declarative/qml/qdeclarativeproxymetaobject.cpp
+++ b/src/declarative/qml/qdeclarativeproxymetaobject.cpp
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#include "private/qdeclarativeproxymetaobject_p.h"
-#include "private/qdeclarativeproperty_p.h"
+#include "qdeclarativeproxymetaobject_p.h"
+#include "qdeclarativeproperty_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativeproxymetaobject_p.h b/src/declarative/qml/qdeclarativeproxymetaobject_p.h
index 3b199d948c..d844e4b00d 100644
--- a/src/declarative/qml/qdeclarativeproxymetaobject_p.h
+++ b/src/declarative/qml/qdeclarativeproxymetaobject_p.h
@@ -53,7 +53,7 @@
// We mean it.
//
-#include "private/qmetaobjectbuilder_p.h"
+#include <private/qmetaobjectbuilder_p.h>
#include "qdeclarative.h"
#include <QtCore/QMetaObject>
diff --git a/src/declarative/qml/qdeclarativerewrite.cpp b/src/declarative/qml/qdeclarativerewrite.cpp
index be399dd074..98bd34f9ed 100644
--- a/src/declarative/qml/qdeclarativerewrite.cpp
+++ b/src/declarative/qml/qdeclarativerewrite.cpp
@@ -39,9 +39,9 @@
**
****************************************************************************/
-#include "private/qdeclarativerewrite_p.h"
+#include "qdeclarativerewrite_p.h"
-#include "private/qdeclarativeglobal_p.h"
+#include "qdeclarativeglobal_p.h"
#include <QtCore/qdebug.h>
diff --git a/src/declarative/qml/qdeclarativescript.cpp b/src/declarative/qml/qdeclarativescript.cpp
index 55a6b2b2cf..fb4f26a781 100644
--- a/src/declarative/qml/qdeclarativescript.cpp
+++ b/src/declarative/qml/qdeclarativescript.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "private/qdeclarativescript_p.h"
+#include "qdeclarativescript_p.h"
#include "parser/qdeclarativejsengine_p.h"
#include "parser/qdeclarativejsparser_p.h"
@@ -47,7 +47,7 @@
#include "parser/qdeclarativejsmemorypool_p.h"
#include "parser/qdeclarativejsastvisitor_p.h"
#include "parser/qdeclarativejsast_p.h"
-#include "private/qdeclarativerewrite_p.h"
+#include <private/qdeclarativerewrite_p.h>
#include <QStack>
#include <QCoreApplication>
@@ -307,7 +307,6 @@ bool QDeclarativeScript::Variant::asBoolean() const
QString QDeclarativeScript::Variant::asString() const
{
if (t == String) {
- // XXX aakenned
return l->value.toString();
} else {
return asWritten.toString();
@@ -379,7 +378,6 @@ QString QDeclarativeScript::Variant::asScript() const
return escapedString(asString());
case Script:
if (AST::IdentifierExpression *i = AST::cast<AST::IdentifierExpression *>(n)) {
- // XXX aakenned
return i->name.toString();
} else
return asWritten.toString();
@@ -738,7 +736,7 @@ ProcessAST::defineObjectBinding(AST::UiQualifiedId *propertyName,
// XXX this doesn't do anything (_scope never builds up)
_scope.append(resolvableObjectType);
- obj->typeName = qualifiedNameId().toUtf8();
+ obj->typeName = qualifiedNameId();
_scope.removeLast();
obj->location = location;
@@ -922,7 +920,8 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
// { "time", strlen("time"), Object::DynamicProperty::Time, "QTime", strlen("QTime") },
// { "date", strlen("date"), Object::DynamicProperty::Date, "QDate", strlen("QDate") },
{ "date", strlen("date"), Object::DynamicProperty::DateTime, "QDateTime", strlen("QDateTime") },
- { "variant", strlen("variant"), Object::DynamicProperty::Variant, "QVariant", strlen("QVariant") }
+ { "variant", strlen("variant"), Object::DynamicProperty::Variant, "QVariant", strlen("QVariant") },
+ { "var", strlen("var"), Object::DynamicProperty::Var, "QVariant", strlen("QVariant") }
};
static const int propTypeNameToTypesCount = sizeof(propTypeNameToTypes) /
sizeof(propTypeNameToTypes[0]);
diff --git a/src/declarative/qml/qdeclarativescript_p.h b/src/declarative/qml/qdeclarativescript_p.h
index a985fd7a8a..c5b9a7e3f6 100644
--- a/src/declarative/qml/qdeclarativescript_p.h
+++ b/src/declarative/qml/qdeclarativescript_p.h
@@ -309,7 +309,7 @@ public:
int type;
// The fully-qualified name of this type
- QByteArray typeName;
+ QString typeName;
// The id assigned to the object (if any). Set by the QDeclarativeCompiler
QString id;
// The id index assigned to the object (if any). Set by the QDeclarativeCompiler
@@ -385,8 +385,8 @@ public:
{
DynamicProperty();
- enum Type { Variant, Int, Bool, Real, String, Url, Color, Time,
- Date, DateTime, Alias, Custom, CustomList };
+ enum Type { Var, Variant, Int, Bool, Real, String, Url, Color,
+ Time, Date, DateTime, Alias, Custom, CustomList };
bool isDefaultProperty;
Type type;
diff --git a/src/declarative/qml/qdeclarativesqldatabase.cpp b/src/declarative/qml/qdeclarativesqldatabase.cpp
index 687aec9448..dff87b2f78 100644
--- a/src/declarative/qml/qdeclarativesqldatabase.cpp
+++ b/src/declarative/qml/qdeclarativesqldatabase.cpp
@@ -39,12 +39,11 @@
**
****************************************************************************/
-#include "private/qdeclarativesqldatabase_p.h"
+#include "qdeclarativesqldatabase_p.h"
#include "qdeclarativeengine.h"
-#include "private/qdeclarativeengine_p.h"
-#include "private/qdeclarativerefcount_p.h"
-#include "private/qdeclarativeengine_p.h"
+#include "qdeclarativeengine_p.h"
+#include <private/qdeclarativerefcount_p.h>
#include <QtCore/qobject.h>
#include <QtSql/qsqldatabase.h>
@@ -197,6 +196,7 @@ QDeclarativeSqlDatabaseData::~QDeclarativeSqlDatabaseData()
{
qPersistentDispose(constructor);
qPersistentDispose(queryConstructor);
+ qPersistentDispose(rowsConstructor);
}
static QString qmlsqldatabase_databasesPath(QV8Engine *engine)
diff --git a/src/declarative/qml/qdeclarativestringconverters.cpp b/src/declarative/qml/qdeclarativestringconverters.cpp
index b949adf5ec..51bb3a4517 100644
--- a/src/declarative/qml/qdeclarativestringconverters.cpp
+++ b/src/declarative/qml/qdeclarativestringconverters.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "private/qdeclarativestringconverters_p.h"
+#include "qdeclarativestringconverters_p.h"
#include <QtGui/qcolor.h>
#include <QtGui/qvector3d.h>
diff --git a/src/declarative/qml/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp
index 8bb40ce7a5..982692dcb9 100644
--- a/src/declarative/qml/qdeclarativetypeloader.cpp
+++ b/src/declarative/qml/qdeclarativetypeloader.cpp
@@ -42,24 +42,117 @@
#include "qdeclarativetypeloader_p.h"
#include <private/qdeclarativeengine_p.h>
+#include <private/qdeclarativeglobal_p.h>
+#include <private/qdeclarativethread_p.h>
#include <private/qdeclarativecompiler_p.h>
#include <private/qdeclarativecomponent_p.h>
-#include <private/qdeclarativeglobal_p.h>
#include <private/qdeclarativedebugtrace_p.h>
-#include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtCore/qdebug.h>
#include <QtCore/qdir.h>
#include <QtCore/qfile.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qthread.h>
#include <QtCore/qdiriterator.h>
+#include <QtCore/qwaitcondition.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qdeclarativeextensioninterface.h>
#if defined (Q_OS_UNIX)
#include <sys/types.h>
#include <dirent.h>
#endif
+// #define DATABLOB_DEBUG
+
+#ifdef DATABLOB_DEBUG
+
+#define ASSERT_MAINTHREAD() do { if(m_thread->isThisThread()) qFatal("QDeclarativeDataLoader: Caller not in main thread"); } while(false)
+#define ASSERT_LOADTHREAD() do { if(!m_thread->isThisThread()) qFatal("QDeclarativeDataLoader: Caller not in load thread"); } while(false)
+#define ASSERT_CALLBACK() do { if(!m_manager || !m_manager->m_thread->isThisThread()) qFatal("QDeclarativeDataBlob: An API call was made outside a callback"); } while(false)
+
+#else
+
+#define ASSERT_MAINTHREAD()
+#define ASSERT_LOADTHREAD()
+#define ASSERT_CALLBACK()
+
+#endif
+
QT_BEGIN_NAMESPACE
+// This is a lame object that we need to ensure that slots connected to
+// QNetworkReply get called in the correct thread (the loader thread).
+// As QDeclarativeDataLoader lives in the main thread, and we can't use
+// Qt::DirectConnection connections from a QNetworkReply (because then
+// sender() wont work), we need to insert this object in the middle.
+class QDeclarativeDataLoaderNetworkReplyProxy : public QObject
+{
+ Q_OBJECT
+public:
+ QDeclarativeDataLoaderNetworkReplyProxy(QDeclarativeDataLoader *l);
+
+public slots:
+ void finished();
+ void downloadProgress(qint64, qint64);
+
+private:
+ QDeclarativeDataLoader *l;
+};
+
+class QDeclarativeDataLoaderThread : public QDeclarativeThread
+{
+ typedef QDeclarativeDataLoaderThread This;
+
+public:
+ QDeclarativeDataLoaderThread(QDeclarativeDataLoader *loader);
+ QNetworkAccessManager *networkAccessManager() const;
+ QDeclarativeDataLoaderNetworkReplyProxy *networkReplyProxy() const;
+
+ void load(QDeclarativeDataBlob *b);
+ void loadAsync(QDeclarativeDataBlob *b);
+ void loadWithStaticData(QDeclarativeDataBlob *b, const QByteArray &);
+ void loadWithStaticDataAsync(QDeclarativeDataBlob *b, const QByteArray &);
+ void callCompleted(QDeclarativeDataBlob *b);
+ void callDownloadProgressChanged(QDeclarativeDataBlob *b, qreal p);
+ void initializeEngine(QDeclarativeExtensionInterface *, const char *);
+
+protected:
+ virtual void shutdownThread();
+
+private:
+ void loadThread(QDeclarativeDataBlob *b);
+ void loadWithStaticDataThread(QDeclarativeDataBlob *b, const QByteArray &);
+ void callCompletedMain(QDeclarativeDataBlob *b);
+ void callDownloadProgressChangedMain(QDeclarativeDataBlob *b, qreal p);
+ void initializeEngineMain(QDeclarativeExtensionInterface *iface, const char *uri);
+
+ QDeclarativeDataLoader *m_loader;
+ mutable QNetworkAccessManager *m_networkAccessManager;
+ mutable QDeclarativeDataLoaderNetworkReplyProxy *m_networkReplyProxy;
+};
+
+
+QDeclarativeDataLoaderNetworkReplyProxy::QDeclarativeDataLoaderNetworkReplyProxy(QDeclarativeDataLoader *l)
+: l(l)
+{
+}
+
+void QDeclarativeDataLoaderNetworkReplyProxy::finished()
+{
+ Q_ASSERT(sender());
+ Q_ASSERT(qobject_cast<QNetworkReply *>(sender()));
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ l->networkReplyFinished(reply);
+}
+
+void QDeclarativeDataLoaderNetworkReplyProxy::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
+{
+ Q_ASSERT(sender());
+ Q_ASSERT(qobject_cast<QNetworkReply *>(sender()));
+ QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ l->networkReplyProgress(reply, bytesReceived, bytesTotal);
+}
/*
Returns the set of QML files in path (qmldir, *.qml, *.js). The caller
@@ -182,8 +275,8 @@ This enum describes the type of the data blob.
Create a new QDeclarativeDataBlob for \a url and of the provided \a type.
*/
QDeclarativeDataBlob::QDeclarativeDataBlob(const QUrl &url, Type type)
-: m_type(type), m_status(Null), m_progress(0), m_url(url), m_finalUrl(url), m_manager(0),
- m_redirectCount(0), m_inCallback(false), m_isDone(false)
+: m_type(type), m_url(url), m_finalUrl(url), m_manager(0), m_redirectCount(0),
+ m_inCallback(false), m_isDone(false)
{
}
@@ -208,7 +301,7 @@ Returns the blob's status.
*/
QDeclarativeDataBlob::Status QDeclarativeDataBlob::status() const
{
- return m_status;
+ return m_data.status();
}
/*!
@@ -216,7 +309,7 @@ Returns true if the status is Null.
*/
bool QDeclarativeDataBlob::isNull() const
{
- return m_status == Null;
+ return status() == Null;
}
/*!
@@ -224,7 +317,7 @@ Returns true if the status is Loading.
*/
bool QDeclarativeDataBlob::isLoading() const
{
- return m_status == Loading;
+ return status() == Loading;
}
/*!
@@ -232,7 +325,7 @@ Returns true if the status is WaitingForDependencies.
*/
bool QDeclarativeDataBlob::isWaiting() const
{
- return m_status == WaitingForDependencies;
+ return status() == WaitingForDependencies;
}
/*!
@@ -240,7 +333,7 @@ Returns true if the status is Complete.
*/
bool QDeclarativeDataBlob::isComplete() const
{
- return m_status == Complete;
+ return status() == Complete;
}
/*!
@@ -248,7 +341,7 @@ Returns true if the status is Error.
*/
bool QDeclarativeDataBlob::isError() const
{
- return m_status == Error;
+ return status() == Error;
}
/*!
@@ -256,7 +349,8 @@ Returns true if the status is Complete or Error.
*/
bool QDeclarativeDataBlob::isCompleteOrError() const
{
- return isComplete() || isError();
+ Status s = status();
+ return s == Error || s == Complete;
}
/*!
@@ -264,7 +358,9 @@ Returns the data download progress from 0 to 1.
*/
qreal QDeclarativeDataBlob::progress() const
{
- return m_progress;
+ quint8 p = m_data.progress();
+ if (p == 0xFF) return 1.;
+ else return qreal(p) / qreal(0xFF);
}
/*!
@@ -282,17 +378,23 @@ QUrl QDeclarativeDataBlob::url() const
Returns the final url of the data. Initially this is the same as
url(), but if a network redirect happens while fetching the data, this url
is updated to reflect the new location.
+
+May only be called from the load thread, or after the blob isCompleteOrError().
*/
QUrl QDeclarativeDataBlob::finalUrl() const
{
+ Q_ASSERT(isCompleteOrError() || (m_manager && m_manager->m_thread->isThisThread()));
return m_finalUrl;
}
/*!
Return the errors on this blob.
+
+May only be called from the load thread, or after the blob isCompleteOrError().
*/
QList<QDeclarativeError> QDeclarativeDataBlob::errors() const
{
+ Q_ASSERT(isCompleteOrError() || (m_manager && m_manager->m_thread->isThisThread()));
return m_errors;
}
@@ -300,11 +402,14 @@ QList<QDeclarativeError> QDeclarativeDataBlob::errors() const
Mark this blob as having \a errors.
All outstanding dependencies will be cancelled. Requests to add new dependencies
-will be ignored. Entry into the Error state is irreversable, although you can change the
-specific errors by additional calls to setError.
+will be ignored. Entry into the Error state is irreversable.
+
+The setError() method may only be called from within a QDeclarativeDataBlob callback.
*/
void QDeclarativeDataBlob::setError(const QDeclarativeError &errors)
{
+ ASSERT_CALLBACK();
+
QList<QDeclarativeError> l;
l << errors;
setError(l);
@@ -315,8 +420,13 @@ void QDeclarativeDataBlob::setError(const QDeclarativeError &errors)
*/
void QDeclarativeDataBlob::setError(const QList<QDeclarativeError> &errors)
{
- m_status = Error;
- m_errors = errors;
+ ASSERT_CALLBACK();
+
+ Q_ASSERT(status() != Error);
+ Q_ASSERT(m_errors.isEmpty());
+
+ m_errors = errors; // Must be set before the m_data fence
+ m_data.setStatus(Error);
cancelAllWaitingFor();
@@ -327,19 +437,25 @@ void QDeclarativeDataBlob::setError(const QList<QDeclarativeError> &errors)
/*!
Wait for \a blob to become complete or to error. If \a blob is already
complete or in error, or this blob is already complete, this has no effect.
+
+The setError() method may only be called from within a QDeclarativeDataBlob callback.
*/
void QDeclarativeDataBlob::addDependency(QDeclarativeDataBlob *blob)
{
+ ASSERT_CALLBACK();
+
Q_ASSERT(status() != Null);
if (!blob ||
blob->status() == Error || blob->status() == Complete ||
- status() == Error || status() == Complete ||
+ status() == Error || status() == Complete || m_isDone ||
m_waitingFor.contains(blob))
return;
blob->addref();
- m_status = WaitingForDependencies;
+
+ m_data.setStatus(WaitingForDependencies);
+
m_waitingFor.append(blob);
blob->m_waitingOnMe.append(this);
}
@@ -360,6 +476,9 @@ You can set an error in this method, but you cannot add new dependencies. Imple
should use this callback to finalize processing of data.
The default implementation does nothing.
+
+XXX Rename processData() or some such to avoid confusion between done() (processing thread)
+and completed() (main thread)
*/
void QDeclarativeDataBlob::done()
{
@@ -451,22 +570,63 @@ void QDeclarativeDataBlob::allDependenciesDone()
/*!
Called when the download progress of this blob changes. \a progress goes
from 0 to 1.
+
+This callback is only invoked if an asynchronous load for this blob is
+made. An asynchronous load is one in which the Asynchronous mode is
+specified explicitly, or one that is implicitly delayed due to a network
+operation.
+
+The default implementation does nothing.
*/
void QDeclarativeDataBlob::downloadProgressChanged(qreal progress)
{
Q_UNUSED(progress);
}
+/*!
+Invoked on the main thread sometime after done() was called on the load thread.
+
+You cannot modify the blobs state at all in this callback and cannot depend on the
+order or timeliness of these callbacks. Implementors should use this callback to notify
+dependencies on the main thread that the blob is done and not a lot else.
+
+This callback is only invoked if an asynchronous load for this blob is
+made. An asynchronous load is one in which the Asynchronous mode is
+specified explicitly, or one that is implicitly delayed due to a network
+operation.
+
+The default implementation does nothing.
+*/
+void QDeclarativeDataBlob::completed()
+{
+}
+
+
void QDeclarativeDataBlob::tryDone()
{
if (status() != Loading && m_waitingFor.isEmpty() && !m_isDone) {
- if (status() != Error)
- m_status = Complete;
-
m_isDone = true;
addref();
+
+#ifdef DATABLOB_DEBUG
+ qWarning("QDeclarativeDataBlob::done() %s", qPrintable(url().toString()));
+#endif
done();
+
+ if (status() != Error)
+ m_data.setStatus(Complete);
+
notifyAllWaitingOnMe();
+
+ // Locking is not required here, as anyone expecting callbacks must
+ // already be protected against the blob being completed (as set above);
+ if (m_data.isAsync()) {
+#ifdef DATABLOB_DEBUG
+ qWarning("QDeclarativeDataBlob: Dispatching completed");
+#endif
+ m_manager->m_thread->callCompleted(this);
+ }
+
release();
}
}
@@ -519,6 +679,170 @@ void QDeclarativeDataBlob::notifyComplete(QDeclarativeDataBlob *blob)
tryDone();
}
+#define TD_STATUS_MASK 0x0000FFFF
+#define TD_STATUS_SHIFT 0
+#define TD_PROGRESS_MASK 0x00FF0000
+#define TD_PROGRESS_SHIFT 16
+#define TD_ASYNC_MASK 0x80000000
+
+QDeclarativeDataBlob::ThreadData::ThreadData()
+: _p(0)
+{
+}
+
+QDeclarativeDataBlob::Status QDeclarativeDataBlob::ThreadData::status() const
+{
+ return QDeclarativeDataBlob::Status((_p.load() & TD_STATUS_MASK) >> TD_STATUS_SHIFT);
+}
+
+void QDeclarativeDataBlob::ThreadData::setStatus(QDeclarativeDataBlob::Status status)
+{
+ while (true) {
+ int d = _p.load();
+ int nd = (d & ~TD_STATUS_MASK) | ((status << TD_STATUS_SHIFT) & TD_STATUS_MASK);
+ if (d == nd || _p.testAndSetOrdered(d, nd)) return;
+ }
+}
+
+bool QDeclarativeDataBlob::ThreadData::isAsync() const
+{
+ return _p.load() & TD_ASYNC_MASK;
+}
+
+void QDeclarativeDataBlob::ThreadData::setIsAsync(bool v)
+{
+ while (true) {
+ int d = _p.load();
+ int nd = (d & ~TD_ASYNC_MASK) | (v?TD_ASYNC_MASK:0);
+ if (d == nd || _p.testAndSetOrdered(d, nd)) return;
+ }
+}
+
+quint8 QDeclarativeDataBlob::ThreadData::progress() const
+{
+ return quint8((_p.load() & TD_PROGRESS_MASK) >> TD_PROGRESS_SHIFT);
+}
+
+void QDeclarativeDataBlob::ThreadData::setProgress(quint8 v)
+{
+ while (true) {
+ int d = _p.load();
+ int nd = (d & ~TD_PROGRESS_MASK) | ((v << TD_PROGRESS_SHIFT) & TD_PROGRESS_MASK);
+ if (d == nd || _p.testAndSetOrdered(d, nd)) return;
+ }
+}
+
+QDeclarativeDataLoaderThread::QDeclarativeDataLoaderThread(QDeclarativeDataLoader *loader)
+: m_loader(loader), m_networkAccessManager(0), m_networkReplyProxy(0)
+{
+}
+
+QNetworkAccessManager *QDeclarativeDataLoaderThread::networkAccessManager() const
+{
+ Q_ASSERT(isThisThread());
+ if (!m_networkAccessManager) {
+ m_networkAccessManager = QDeclarativeEnginePrivate::get(m_loader->engine())->createNetworkAccessManager(0);
+ m_networkReplyProxy = new QDeclarativeDataLoaderNetworkReplyProxy(m_loader);
+ }
+
+ return m_networkAccessManager;
+}
+
+QDeclarativeDataLoaderNetworkReplyProxy *QDeclarativeDataLoaderThread::networkReplyProxy() const
+{
+ Q_ASSERT(isThisThread());
+ Q_ASSERT(m_networkReplyProxy); // Must call networkAccessManager() first
+ return m_networkReplyProxy;
+}
+
+void QDeclarativeDataLoaderThread::load(QDeclarativeDataBlob *b)
+{
+ b->addref();
+ callMethodInThread(&This::loadThread, b);
+}
+
+void QDeclarativeDataLoaderThread::loadAsync(QDeclarativeDataBlob *b)
+{
+ b->addref();
+ postMethodToThread(&This::loadThread, b);
+}
+
+void QDeclarativeDataLoaderThread::loadWithStaticData(QDeclarativeDataBlob *b, const QByteArray &d)
+{
+ b->addref();
+ callMethodInThread(&This::loadWithStaticDataThread, b, d);
+}
+
+void QDeclarativeDataLoaderThread::loadWithStaticDataAsync(QDeclarativeDataBlob *b, const QByteArray &d)
+{
+ b->addref();
+ postMethodToThread(&This::loadWithStaticDataThread, b, d);
+}
+
+void QDeclarativeDataLoaderThread::callCompleted(QDeclarativeDataBlob *b)
+{
+ b->addref();
+ postMethodToMain(&This::callCompletedMain, b);
+}
+
+void QDeclarativeDataLoaderThread::callDownloadProgressChanged(QDeclarativeDataBlob *b, qreal p)
+{
+ b->addref();
+ postMethodToMain(&This::callDownloadProgressChangedMain, b, p);
+}
+
+void QDeclarativeDataLoaderThread::initializeEngine(QDeclarativeExtensionInterface *iface,
+ const char *uri)
+{
+ callMethodInMain(&This::initializeEngineMain, iface, uri);
+}
+
+void QDeclarativeDataLoaderThread::shutdownThread()
+{
+ delete m_networkAccessManager;
+ m_networkAccessManager = 0;
+ delete m_networkReplyProxy;
+ m_networkReplyProxy = 0;
+}
+
+void QDeclarativeDataLoaderThread::loadThread(QDeclarativeDataBlob *b)
+{
+ m_loader->loadThread(b);
+ b->release();
+}
+
+void QDeclarativeDataLoaderThread::loadWithStaticDataThread(QDeclarativeDataBlob *b, const QByteArray &d)
+{
+ m_loader->loadWithStaticDataThread(b, d);
+ b->release();
+}
+
+void QDeclarativeDataLoaderThread::callCompletedMain(QDeclarativeDataBlob *b)
+{
+#ifdef DATABLOB_DEBUG
+ qWarning("QDeclarativeDataLoaderThread: %s completed() callback", qPrintable(b->url().toString()));
+#endif
+ b->completed();
+ b->release();
+}
+
+void QDeclarativeDataLoaderThread::callDownloadProgressChangedMain(QDeclarativeDataBlob *b, qreal p)
+{
+#ifdef DATABLOB_DEBUG
+ qWarning("QDeclarativeDataLoaderThread: %s downloadProgressChanged(%f) callback",
+ qPrintable(b->url().toString()), p);
+#endif
+ b->downloadProgressChanged(p);
+ b->release();
+}
+
+void QDeclarativeDataLoaderThread::initializeEngineMain(QDeclarativeExtensionInterface *iface,
+ const char *uri)
+{
+ Q_ASSERT(m_loader->engine()->thread() == QThread::currentThread());
+ iface->initializeEngine(m_loader->engine(), uri);
+}
+
/*!
\class QDeclarativeDataLoader
\brief The QDeclarativeDataLoader class abstracts loading files and their dependencies over the network.
@@ -553,7 +877,7 @@ Thus QDeclarativeDataBlob::done() will always eventually be called, even if the
Create a new QDeclarativeDataLoader for \a engine.
*/
QDeclarativeDataLoader::QDeclarativeDataLoader(QDeclarativeEngine *engine)
-: m_engine(engine)
+: m_engine(engine), m_thread(new QDeclarativeDataLoaderThread(this))
{
}
@@ -562,17 +886,105 @@ QDeclarativeDataLoader::~QDeclarativeDataLoader()
{
for (NetworkReplies::Iterator iter = m_networkReplies.begin(); iter != m_networkReplies.end(); ++iter)
(*iter)->release();
+
+ m_thread->shutdown();
+ delete m_thread;
+}
+
+void QDeclarativeDataLoader::lock()
+{
+ m_thread->lock();
+}
+
+void QDeclarativeDataLoader::unlock()
+{
+ m_thread->unlock();
}
/*!
Load the provided \a blob from the network or filesystem.
+
+The loader must be locked.
+*/
+void QDeclarativeDataLoader::load(QDeclarativeDataBlob *blob, Mode mode)
+{
+#ifdef DATABLOB_DEBUG
+ qWarning("QDeclarativeDataLoader::load(%s): %s thread", qPrintable(blob->m_url.toString()),
+ m_thread->isThisThread()?"Compile":"Engine");
+#endif
+
+ Q_ASSERT(blob->status() == QDeclarativeDataBlob::Null);
+ Q_ASSERT(blob->m_manager == 0);
+
+ blob->m_data.setStatus(QDeclarativeDataBlob::Loading);
+ blob->m_manager = this;
+
+ if (m_thread->isThisThread()) {
+ unlock();
+ loadThread(blob);
+ lock();
+ } else if (mode == PreferSynchronous) {
+ unlock();
+ m_thread->load(blob);
+ lock();
+ if (!blob->isCompleteOrError())
+ blob->m_data.setIsAsync(true);
+ } else {
+ Q_ASSERT(mode == Asynchronous);
+ blob->m_data.setIsAsync(true);
+ unlock();
+ m_thread->loadAsync(blob);
+ lock();
+ }
+}
+
+/*!
+Load the provided \a blob with \a data. The blob's URL is not used by the data loader in this case.
+
+The loader must be locked.
*/
-void QDeclarativeDataLoader::load(QDeclarativeDataBlob *blob)
+void QDeclarativeDataLoader::loadWithStaticData(QDeclarativeDataBlob *blob, const QByteArray &data, Mode mode)
{
+#ifdef DATABLOB_DEBUG
+ qWarning("QDeclarativeDataLoader::loadWithStaticData(%s, data): %s thread", qPrintable(blob->m_url.toString()),
+ m_thread->isThisThread()?"Compile":"Engine");
+#endif
+
Q_ASSERT(blob->status() == QDeclarativeDataBlob::Null);
Q_ASSERT(blob->m_manager == 0);
+
+ blob->m_data.setStatus(QDeclarativeDataBlob::Loading);
+ blob->m_manager = this;
+
+ if (m_thread->isThisThread()) {
+ unlock();
+ loadWithStaticDataThread(blob, data);
+ lock();
+ } else if (mode == PreferSynchronous) {
+ unlock();
+ m_thread->loadWithStaticData(blob, data);
+ lock();
+ if (!blob->isCompleteOrError())
+ blob->m_data.setIsAsync(true);
+ } else {
+ Q_ASSERT(mode == Asynchronous);
+ blob->m_data.setIsAsync(true);
+ unlock();
+ m_thread->loadWithStaticDataAsync(blob, data);
+ lock();
+ }
+}
- blob->m_status = QDeclarativeDataBlob::Loading;
+void QDeclarativeDataLoader::loadWithStaticDataThread(QDeclarativeDataBlob *blob, const QByteArray &data)
+{
+ ASSERT_LOADTHREAD();
+
+ setData(blob, data);
+}
+
+void QDeclarativeDataLoader::loadThread(QDeclarativeDataBlob *blob)
+{
+ ASSERT_LOADTHREAD();
if (blob->m_url.isEmpty()) {
QDeclarativeError error;
@@ -595,8 +1007,9 @@ void QDeclarativeDataLoader::load(QDeclarativeDataBlob *blob)
if (file.open(QFile::ReadOnly)) {
QByteArray data = file.readAll();
- blob->m_progress = 1.;
- blob->downloadProgressChanged(1.);
+ blob->m_data.setProgress(0xFF);
+ if (blob->m_data.isAsync())
+ m_thread->callDownloadProgressChanged(blob, 1.);
setData(blob, data);
} else {
@@ -605,12 +1018,12 @@ void QDeclarativeDataLoader::load(QDeclarativeDataBlob *blob)
} else {
- blob->m_manager = this;
- QNetworkReply *reply = m_engine->networkAccessManager()->get(QNetworkRequest(blob->m_url));
+ QNetworkReply *reply = m_thread->networkAccessManager()->get(QNetworkRequest(blob->m_url));
+ QObject *nrp = m_thread->networkReplyProxy();
QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
- this, SLOT(networkReplyProgress(qint64,qint64)));
+ nrp, SLOT(downloadProgress(qint64,qint64)));
QObject::connect(reply, SIGNAL(finished()),
- this, SLOT(networkReplyFinished()));
+ nrp, SLOT(finished()));
m_networkReplies.insert(reply, blob);
blob->addref();
@@ -619,9 +1032,10 @@ void QDeclarativeDataLoader::load(QDeclarativeDataBlob *blob)
#define DATALOADER_MAXIMUM_REDIRECT_RECURSION 16
-void QDeclarativeDataLoader::networkReplyFinished()
+void QDeclarativeDataLoader::networkReplyFinished(QNetworkReply *reply)
{
- QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ Q_ASSERT(m_thread->isThisThread());
+
reply->deleteLater();
QDeclarativeDataBlob *blob = m_networkReplies.take(reply);
@@ -636,8 +1050,9 @@ void QDeclarativeDataLoader::networkReplyFinished()
QUrl url = reply->url().resolved(redirect.toUrl());
blob->m_finalUrl = url;
- QNetworkReply *reply = m_engine->networkAccessManager()->get(QNetworkRequest(url));
- QObject::connect(reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
+ QNetworkReply *reply = m_thread->networkAccessManager()->get(QNetworkRequest(url));
+ QObject *nrp = m_thread->networkReplyProxy();
+ QObject::connect(reply, SIGNAL(finished()), nrp, SLOT(finished()));
m_networkReplies.insert(reply, blob);
return;
}
@@ -653,40 +1068,49 @@ void QDeclarativeDataLoader::networkReplyFinished()
blob->release();
}
-void QDeclarativeDataLoader::networkReplyProgress(qint64 bytesReceived, qint64 bytesTotal)
+void QDeclarativeDataLoader::networkReplyProgress(QNetworkReply *reply,
+ qint64 bytesReceived, qint64 bytesTotal)
{
- QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
+ Q_ASSERT(m_thread->isThisThread());
+
QDeclarativeDataBlob *blob = m_networkReplies.value(reply);
Q_ASSERT(blob);
if (bytesTotal != 0) {
- blob->m_progress = bytesReceived / bytesTotal;
- blob->downloadProgressChanged(blob->m_progress);
+ quint8 progress = 0xFF * (qreal(bytesReceived) / qreal(bytesTotal));
+ blob->m_data.setProgress(progress);
+ if (blob->m_data.isAsync())
+ m_thread->callDownloadProgressChanged(blob, blob->m_data.progress());
}
}
/*!
-Load the provided \a blob with \a data. The blob's URL is not used by the data loader in this case.
+Return the QDeclarativeEngine associated with this loader
*/
-void QDeclarativeDataLoader::loadWithStaticData(QDeclarativeDataBlob *blob, const QByteArray &data)
+QDeclarativeEngine *QDeclarativeDataLoader::engine() const
{
- Q_ASSERT(blob->status() == QDeclarativeDataBlob::Null);
- Q_ASSERT(blob->m_manager == 0);
-
- blob->m_status = QDeclarativeDataBlob::Loading;
-
- setData(blob, data);
+ return m_engine;
}
/*!
-Return the QDeclarativeEngine associated with this loader
+Call the initializeEngine() method on \a iface. Used by QDeclarativeImportDatabase to ensure it
+gets called in the correct thread.
*/
-QDeclarativeEngine *QDeclarativeDataLoader::engine() const
+void QDeclarativeDataLoader::initializeEngine(QDeclarativeExtensionInterface *iface,
+ const char *uri)
{
- return m_engine;
+ Q_ASSERT(m_thread->isThisThread() || engine()->thread() == QThread::currentThread());
+
+ if (m_thread->isThisThread()) {
+ m_thread->initializeEngine(iface, uri);
+ } else {
+ Q_ASSERT(engine()->thread() == QThread::currentThread());
+ iface->initializeEngine(engine(), uri);
+ }
}
+
void QDeclarativeDataLoader::setData(QDeclarativeDataBlob *blob, const QByteArray &data)
{
blob->m_inCallback = true;
@@ -696,8 +1120,8 @@ void QDeclarativeDataLoader::setData(QDeclarativeDataBlob *blob, const QByteArra
if (!blob->isError() && !blob->isWaiting())
blob->allDependenciesDone();
- if (blob->status() != QDeclarativeDataBlob::Error)
- blob->m_status = QDeclarativeDataBlob::WaitingForDependencies;
+ if (blob->status() != QDeclarativeDataBlob::Error)
+ blob->m_data.setStatus(QDeclarativeDataBlob::WaitingForDependencies);
blob->m_inCallback = false;
@@ -741,6 +1165,8 @@ QDeclarativeTypeData *QDeclarativeTypeLoader::get(const QUrl &url)
(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url).isEmpty() ||
!QDir::isRelativePath(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url))));
+ lock();
+
QDeclarativeTypeData *typeData = m_typeCache.value(url);
if (!typeData) {
@@ -750,6 +1176,9 @@ QDeclarativeTypeData *QDeclarativeTypeLoader::get(const QUrl &url)
}
typeData->addref();
+
+ unlock();
+
return typeData;
}
@@ -761,8 +1190,13 @@ The specified \a options control how the loader handles type data.
*/
QDeclarativeTypeData *QDeclarativeTypeLoader::get(const QByteArray &data, const QUrl &url, Options options)
{
+ lock();
+
QDeclarativeTypeData *typeData = new QDeclarativeTypeData(url, options, this);
QDeclarativeDataLoader::loadWithStaticData(typeData, data);
+
+ unlock();
+
return typeData;
}
@@ -775,6 +1209,8 @@ QDeclarativeScriptBlob *QDeclarativeTypeLoader::getScript(const QUrl &url)
(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url).isEmpty() ||
!QDir::isRelativePath(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url))));
+ lock();
+
QDeclarativeScriptBlob *scriptBlob = m_scriptCache.value(url);
if (!scriptBlob) {
@@ -783,6 +1219,10 @@ QDeclarativeScriptBlob *QDeclarativeTypeLoader::getScript(const QUrl &url)
QDeclarativeDataLoader::load(scriptBlob);
}
+ scriptBlob->addref();
+
+ unlock();
+
return scriptBlob;
}
@@ -795,6 +1235,8 @@ QDeclarativeQmldirData *QDeclarativeTypeLoader::getQmldir(const QUrl &url)
(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url).isEmpty() ||
!QDir::isRelativePath(QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url))));
+ lock();
+
QDeclarativeQmldirData *qmldirData = m_qmldirCache.value(url);
if (!qmldirData) {
@@ -804,6 +1246,9 @@ QDeclarativeQmldirData *QDeclarativeTypeLoader::getQmldir(const QUrl &url)
}
qmldirData->addref();
+
+ unlock();
+
return qmldirData;
}
@@ -914,6 +1359,7 @@ const QDeclarativeDirParser *QDeclarativeTypeLoader::qmlDirParser(const QString
return qmldirParser;
}
+
/*!
Clears cached information about loaded files, including any type data, scripts
and qmldir information.
@@ -1004,8 +1450,6 @@ void QDeclarativeTypeData::unregisterCallback(TypeDataCallback *callback)
void QDeclarativeTypeData::done()
{
- addref();
-
// Check all script dependencies for errors
for (int ii = 0; !isError() && ii < m_scripts.count(); ++ii) {
const ScriptReference &script = m_scripts.at(ii);
@@ -1046,14 +1490,15 @@ void QDeclarativeTypeData::done()
if (!(m_options & QDeclarativeTypeLoader::PreserveParser))
scriptParser.clear();
+}
+void QDeclarativeTypeData::completed()
+{
// Notify callbacks
while (!m_callbacks.isEmpty()) {
TypeDataCallback *callback = m_callbacks.takeFirst();
callback->typeDataReady(this);
}
-
- release();
}
void QDeclarativeTypeData::dataReceived(const QByteArray &data)
@@ -1082,7 +1527,6 @@ void QDeclarativeTypeData::dataReceived(const QByteArray &data)
ref.location = import.location.start;
ref.qualifier = import.qualifier;
ref.script = blob;
- blob->addref();
m_scripts << ref;
}
@@ -1270,15 +1714,13 @@ QDeclarativeQmldirData *QDeclarativeTypeData::qmldirForUrl(const QUrl &url)
return 0;
}
-QDeclarativeScriptData::QDeclarativeScriptData(QDeclarativeEngine *engine)
-: QDeclarativeCleanup(engine), importCache(0), pragmas(QDeclarativeScript::Object::ScriptBlock::None),
- m_loaded(false)
+QDeclarativeScriptData::QDeclarativeScriptData()
+: importCache(0), pragmas(QDeclarativeScript::Object::ScriptBlock::None), m_loaded(false)
{
}
QDeclarativeScriptData::~QDeclarativeScriptData()
{
- clear();
}
void QDeclarativeScriptData::clear()
@@ -1294,6 +1736,9 @@ void QDeclarativeScriptData::clear()
qPersistentDispose(m_program);
qPersistentDispose(m_value);
+
+ // An addref() was made when the QDeclarativeCleanup was added to the engine.
+ release();
}
QDeclarativeScriptBlob::QDeclarativeScriptBlob(const QUrl &url, QDeclarativeTypeLoader *loader)
@@ -1361,7 +1806,6 @@ void QDeclarativeScriptBlob::dataReceived(const QByteArray &data)
ref.location = import.location.start;
ref.qualifier = import.qualifier;
ref.script = blob;
- blob->addref();
m_scripts << ref;
} else {
Q_ASSERT(import.type == QDeclarativeScript::Import::Library);
@@ -1408,9 +1852,9 @@ void QDeclarativeScriptBlob::done()
return;
QDeclarativeEngine *engine = typeLoader()->engine();
- m_scriptData = new QDeclarativeScriptData(engine);
+ m_scriptData = new QDeclarativeScriptData();
m_scriptData->url = finalUrl();
- m_scriptData->importCache = new QDeclarativeTypeNameCache(engine);
+ m_scriptData->importCache = new QDeclarativeTypeNameCache();
for (int ii = 0; !isError() && ii < m_scripts.count(); ++ii) {
const ScriptReference &script = m_scripts.at(ii);
@@ -1422,13 +1866,7 @@ void QDeclarativeScriptBlob::done()
m_imports.populateCache(m_scriptData->importCache, engine);
m_scriptData->pragmas = m_pragmas;
-
- // XXX TODO: Handle errors that occur duing the script compile
- QV8Engine *v8engine = QDeclarativeEnginePrivate::get(engine)->v8engine();
- v8::HandleScope handle_scope;
- v8::Context::Scope scope(v8engine->context());
- v8::Local<v8::Script> program = v8engine->qmlModeCompile(m_source, finalUrl().toString(), 1);
- m_scriptData->m_program = qPersistentNew<v8::Script>(program);
+ m_scriptData->m_programSource = m_source;
}
QDeclarativeQmldirData::QDeclarativeQmldirData(const QUrl &url)
@@ -1451,3 +1889,4 @@ void QDeclarativeQmldirData::dataReceived(const QByteArray &data)
QT_END_NAMESPACE
+#include "qdeclarativetypeloader.moc"
diff --git a/src/declarative/qml/qdeclarativetypeloader_p.h b/src/declarative/qml/qdeclarativetypeloader_p.h
index af1a2f731e..1eaeebdbe6 100644
--- a/src/declarative/qml/qdeclarativetypeloader_p.h
+++ b/src/declarative/qml/qdeclarativetypeloader_p.h
@@ -54,17 +54,17 @@
//
#include <QtCore/qobject.h>
+#include <QtCore/qatomic.h>
#include <QtNetwork/qnetworkreply.h>
-#include <QtDeclarative/qjsvalue.h>
#include <QtDeclarative/qdeclarativeerror.h>
#include <QtDeclarative/qdeclarativeengine.h>
-#include <private/qdeclarativecleanup_p.h>
-#include <private/qdeclarativescript_p.h>
-#include <private/qdeclarativedirparser_p.h>
-#include <private/qdeclarativeimport_p.h>
-#include "private/qhashedstring_p.h"
#include <private/qv8_p.h>
+#include <private/qhashedstring_p.h>
+#include <private/qdeclarativescript_p.h>
+#include <private/qdeclarativeimport_p.h>
+#include <private/qdeclarativecleanup_p.h>
+#include <private/qdeclarativedirparser_p.h>
QT_BEGIN_NAMESPACE
@@ -76,6 +76,7 @@ class QDeclarativeCompiledData;
class QDeclarativeComponentPrivate;
class QDeclarativeTypeData;
class QDeclarativeDataLoader;
+class QDeclarativeExtensionInterface;
// Exported for QtQuick1
class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDataBlob : public QDeclarativeRefCount
@@ -115,33 +116,53 @@ public:
QList<QDeclarativeError> errors() const;
+protected:
+ // Can be called from within callbacks
void setError(const QDeclarativeError &);
void setError(const QList<QDeclarativeError> &errors);
-
void addDependency(QDeclarativeDataBlob *);
-protected:
+ // Callbacks made in load thread
virtual void dataReceived(const QByteArray &) = 0;
-
virtual void done();
virtual void networkError(QNetworkReply::NetworkError);
-
virtual void dependencyError(QDeclarativeDataBlob *);
virtual void dependencyComplete(QDeclarativeDataBlob *);
virtual void allDependenciesDone();
-
- virtual void downloadProgressChanged(qreal);
+ // Callbacks made in main thread
+ virtual void downloadProgressChanged(qreal);
+ virtual void completed();
private:
friend class QDeclarativeDataLoader;
+ friend class QDeclarativeDataLoaderThread;
+
void tryDone();
void cancelAllWaitingFor();
void notifyAllWaitingOnMe();
void notifyComplete(QDeclarativeDataBlob *);
+ struct ThreadData {
+ inline ThreadData();
+ inline QDeclarativeDataBlob::Status status() const;
+ inline void setStatus(QDeclarativeDataBlob::Status);
+ inline bool isAsync() const;
+ inline void setIsAsync(bool);
+ inline quint8 progress() const;
+ inline void setProgress(quint8);
+
+ private:
+ QAtomicInt _p;
+ };
+ ThreadData m_data;
+
+ // m_errors should *always* be written before the status is set to Error.
+ // We use the status change as a memory fence around m_errors so that locking
+ // isn't required. Once the status is set to Error (or Complete), m_errors
+ // cannot be changed.
+ QList<QDeclarativeError> m_errors;
+
Type m_type;
- Status m_status;
- qreal m_progress;
QUrl m_url;
QUrl m_finalUrl;
@@ -157,39 +178,52 @@ private:
int m_redirectCount:30;
bool m_inCallback:1;
bool m_isDone:1;
-
- QList<QDeclarativeError> m_errors;
};
+class QDeclarativeDataLoaderThread;
// Exported for QtQuick1
-class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDataLoader : public QObject
+class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeDataLoader
{
- Q_OBJECT
public:
QDeclarativeDataLoader(QDeclarativeEngine *);
~QDeclarativeDataLoader();
- void load(QDeclarativeDataBlob *);
- void loadWithStaticData(QDeclarativeDataBlob *, const QByteArray &);
+ void lock();
+ void unlock();
- QDeclarativeEngine *engine() const;
+ bool isConcurrent() const { return true; }
+
+ enum Mode { PreferSynchronous, Asynchronous };
-private slots:
- void networkReplyFinished();
- void networkReplyProgress(qint64,qint64);
+ void load(QDeclarativeDataBlob *, Mode = PreferSynchronous);
+ void loadWithStaticData(QDeclarativeDataBlob *, const QByteArray &, Mode = PreferSynchronous);
+
+ QDeclarativeEngine *engine() const;
+ void initializeEngine(QDeclarativeExtensionInterface *, const char *);
private:
+ friend class QDeclarativeDataBlob;
+ friend class QDeclarativeDataLoaderThread;
+ friend class QDeclarativeDataLoaderNetworkReplyProxy;
+
+ void loadThread(QDeclarativeDataBlob *);
+ void loadWithStaticDataThread(QDeclarativeDataBlob *, const QByteArray &);
+ void networkReplyFinished(QNetworkReply *);
+ void networkReplyProgress(QNetworkReply *, qint64, qint64);
+
+ typedef QHash<QNetworkReply *, QDeclarativeDataBlob *> NetworkReplies;
+
void setData(QDeclarativeDataBlob *, const QByteArray &);
QDeclarativeEngine *m_engine;
- typedef QHash<QNetworkReply *, QDeclarativeDataBlob *> NetworkReplies;
+ QDeclarativeDataLoaderThread *m_thread;
NetworkReplies m_networkReplies;
};
// Exported for QtQuick1
class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeTypeLoader : public QDeclarativeDataLoader
{
- Q_OBJECT
+ Q_DECLARE_TR_FUNCTIONS(QDeclarativeTypeLoader)
public:
QDeclarativeTypeLoader(QDeclarativeEngine *);
~QDeclarativeTypeLoader();
@@ -210,7 +244,6 @@ public:
QString absoluteFilePath(const QString &path);
bool directoryExists(const QString &path);
const QDeclarativeDirParser *qmlDirParser(const QString &absoluteFilePath);
-
private:
typedef QHash<QUrl, QDeclarativeTypeData *> TypeCache;
typedef QHash<QUrl, QDeclarativeScriptBlob *> ScriptCache;
@@ -275,6 +308,7 @@ public:
protected:
virtual void done();
+ virtual void completed();
virtual void dataReceived(const QByteArray &);
virtual void allDependenciesDone();
virtual void downloadProgressChanged(qreal);
@@ -303,10 +337,18 @@ private:
QDeclarativeTypeLoader *m_typeLoader;
};
-class Q_AUTOTEST_EXPORT QDeclarativeScriptData : public QDeclarativeRefCount, public QDeclarativeCleanup
+// QDeclarativeScriptData instances are created, uninitialized, by the loader in the
+// load thread. The first time they are used by the VME, they are initialized which
+// creates their v8 objects and they are referenced and added to the engine's cleanup
+// list. During QDeclarativeCleanup::clear() all v8 resources are destroyed, and the
+// reference that was created is released but final deletion only occurs once all the
+// references as released. This is all intended to ensure that the v8 resources are
+// only created and destroyed in the main thread :)
+class Q_AUTOTEST_EXPORT QDeclarativeScriptData : public QDeclarativeCleanup,
+ public QDeclarativeRefCount
{
public:
- QDeclarativeScriptData(QDeclarativeEngine *);
+ QDeclarativeScriptData();
~QDeclarativeScriptData();
QUrl url;
@@ -314,6 +356,9 @@ public:
QList<QDeclarativeScriptBlob *> scripts;
QDeclarativeScript::Object::ScriptBlock::Pragmas pragmas;
+ bool isInitialized() const { return hasEngine(); }
+ void initialize(QDeclarativeEngine *);
+
protected:
virtual void clear(); // From QDeclarativeCleanup
@@ -322,10 +367,9 @@ private:
friend class QDeclarativeScriptBlob;
bool m_loaded;
+ QString m_programSource;
v8::Persistent<v8::Script> m_program;
v8::Persistent<v8::Object> m_value;
-// QScriptProgram m_program;
-// QScriptValue m_value;
};
class Q_AUTOTEST_EXPORT QDeclarativeScriptBlob : public QDeclarativeDataBlob
diff --git a/src/declarative/qml/qdeclarativetypenamecache.cpp b/src/declarative/qml/qdeclarativetypenamecache.cpp
index b7e4259b4c..8ff6532bd5 100644
--- a/src/declarative/qml/qdeclarativetypenamecache.cpp
+++ b/src/declarative/qml/qdeclarativetypenamecache.cpp
@@ -39,27 +39,18 @@
**
****************************************************************************/
-#include "private/qdeclarativetypenamecache_p.h"
+#include "qdeclarativetypenamecache_p.h"
-#include "private/qdeclarativeengine_p.h"
+#include "qdeclarativeengine_p.h"
QT_BEGIN_NAMESPACE
-QDeclarativeTypeNameCache::QDeclarativeTypeNameCache(QDeclarativeEngine *e)
-: QDeclarativeCleanup(e), engine(e)
+QDeclarativeTypeNameCache::QDeclarativeTypeNameCache()
{
}
QDeclarativeTypeNameCache::~QDeclarativeTypeNameCache()
{
- clear();
-}
-
-void QDeclarativeTypeNameCache::clear()
-{
- m_namedImports.clear();
- m_anonymousImports.clear();
- engine = 0;
}
void QDeclarativeTypeNameCache::add(const QHashedString &name, int importedScriptIndex)
diff --git a/src/declarative/qml/qdeclarativetypenamecache_p.h b/src/declarative/qml/qdeclarativetypenamecache_p.h
index a80bb6492c..a0a3d53d87 100644
--- a/src/declarative/qml/qdeclarativetypenamecache_p.h
+++ b/src/declarative/qml/qdeclarativetypenamecache_p.h
@@ -53,9 +53,9 @@
// We mean it.
//
-#include "private/qdeclarativerefcount_p.h"
-#include "private/qdeclarativecleanup_p.h"
-#include "private/qdeclarativemetatype_p.h"
+#include <private/qdeclarativerefcount_p.h>
+#include "qdeclarativecleanup_p.h"
+#include "qdeclarativemetatype_p.h"
#include <private/qhashedstring_p.h>
@@ -65,10 +65,10 @@ QT_BEGIN_NAMESPACE
class QDeclarativeType;
class QDeclarativeEngine;
-class QDeclarativeTypeNameCache : public QDeclarativeRefCount, public QDeclarativeCleanup
+class QDeclarativeTypeNameCache : public QDeclarativeRefCount
{
public:
- QDeclarativeTypeNameCache(QDeclarativeEngine *);
+ QDeclarativeTypeNameCache();
virtual ~QDeclarativeTypeNameCache();
inline bool isEmpty() const;
@@ -94,9 +94,6 @@ public:
Result query(const QHashedV8String &, const void *importNamespace);
QDeclarativeMetaType::ModuleApiInstance *moduleApi(const void *importNamespace);
-protected:
- virtual void clear();
-
private:
friend class QDeclarativeImports;
diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp
index 3e77f4b503..9f43d0ef72 100644
--- a/src/declarative/qml/qdeclarativevaluetype.cpp
+++ b/src/declarative/qml/qdeclarativevaluetype.cpp
@@ -39,10 +39,10 @@
**
****************************************************************************/
-#include "private/qdeclarativevaluetype_p.h"
+#include "qdeclarativevaluetype_p.h"
-#include "private/qdeclarativemetatype_p.h"
-#include "private/qfont_p.h"
+#include "qdeclarativemetatype_p.h"
+#include <private/qfont_p.h>
#include <QtCore/qdebug.h>
diff --git a/src/declarative/qml/qdeclarativevaluetype_p.h b/src/declarative/qml/qdeclarativevaluetype_p.h
index 41d5e7cb8f..1feab4147b 100644
--- a/src/declarative/qml/qdeclarativevaluetype_p.h
+++ b/src/declarative/qml/qdeclarativevaluetype_p.h
@@ -54,8 +54,8 @@
//
#include "qdeclarativeproperty.h"
-#include "private/qdeclarativeproperty_p.h"
-#include "private/qdeclarativenullablevalue_p_p.h"
+#include "qdeclarativeproperty_p.h"
+#include "qdeclarativenullablevalue_p_p.h"
#include <QtCore/qobject.h>
#include <QtCore/qrect.h>
diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp
index 4ed7cf4464..b7abef4aef 100644
--- a/src/declarative/qml/qdeclarativevme.cpp
+++ b/src/declarative/qml/qdeclarativevme.cpp
@@ -39,28 +39,29 @@
**
****************************************************************************/
-#include "private/qdeclarativevme_p.h"
-
-#include "private/qdeclarativecompiler_p.h"
-#include "private/qdeclarativeboundsignal_p.h"
-#include "private/qdeclarativestringconverters_p.h"
-#include "private/qmetaobjectbuilder_p.h"
-#include "private/qfastmetabuilder_p.h"
-#include "private/qdeclarativedata_p.h"
+#include "qdeclarativevme_p.h"
+
+#include "qdeclarativecompiler_p.h"
+#include "qdeclarativeboundsignal_p.h"
+#include "qdeclarativestringconverters_p.h"
+#include <private/qmetaobjectbuilder_p.h>
+#include <private/qfastmetabuilder_p.h>
+#include "qdeclarativedata_p.h"
#include "qdeclarative.h"
-#include "private/qdeclarativecustomparser_p.h"
+#include "qdeclarativecustomparser_p.h"
#include "qdeclarativeengine.h"
#include "qdeclarativecontext.h"
#include "qdeclarativecomponent.h"
-#include "private/qdeclarativebinding_p.h"
-#include "private/qdeclarativeengine_p.h"
-#include "private/qdeclarativecomponent_p.h"
-#include "private/qdeclarativevmemetaobject_p.h"
-#include "private/qdeclarativebinding_p_p.h"
-#include "private/qdeclarativecontext_p.h"
-#include "private/qdeclarativev4bindings_p.h"
-#include "private/qv8bindings_p.h"
-#include "private/qdeclarativeglobal_p.h"
+#include "qdeclarativebinding_p.h"
+#include "qdeclarativeengine_p.h"
+#include "qdeclarativecomponent_p.h"
+#include "qdeclarativevmemetaobject_p.h"
+#include "qdeclarativebinding_p_p.h"
+#include "qdeclarativecontext_p.h"
+#include <private/qv4bindings_p.h>
+#include <private/qv8bindings_p.h>
+#include "qdeclarativeglobal_p.h"
+#include <private/qfinitestack_p.h>
#include "qdeclarativescriptstring.h"
#include "qdeclarativescriptstring_p.h"
@@ -78,78 +79,109 @@
QT_BEGIN_NAMESPACE
-// A simple stack wrapper around QVarLengthArray
-template<typename T>
-class QDeclarativeVMEStack : private QVarLengthArray<T, 128>
-{
-private:
- typedef QVarLengthArray<T, 128> VLA;
- int _index;
-
-public:
- inline QDeclarativeVMEStack();
- inline bool isEmpty() const;
- inline const T &top() const;
- inline void push(const T &o);
- inline T pop();
- inline int count() const;
- inline const T &at(int index) const;
-};
-
-// We do this so we can forward declare the type in the qdeclarativevme_p.h header
-class QDeclarativeVMEObjectStack : public QDeclarativeVMEStack<QObject *> {};
-
-QDeclarativeVME::QDeclarativeVME()
-{
-}
+using namespace QDeclarativeVMETypes;
#define VME_EXCEPTION(desc, line) \
{ \
QDeclarativeError error; \
error.setDescription(desc.trimmed()); \
error.setLine(line); \
- error.setUrl(comp->url); \
- vmeErrors << error; \
+ error.setUrl(COMP->url); \
+ *errors << error; \
goto exceptionExit; \
}
-struct ListInstance
+void QDeclarativeVME::init(QDeclarativeContextData *ctxt, QDeclarativeCompiledData *comp, int start,
+ QDeclarativeContextData *creation)
{
- ListInstance()
- : type(0) {}
- ListInstance(int t)
- : type(t) {}
+ Q_ASSERT(ctxt);
+ Q_ASSERT(comp);
- int type;
- QDeclarativeListProperty<void> qListProperty;
-};
+ if (start == -1) {
+ start = 0;
+ } else {
+ creationContext = creation;
+ }
-Q_DECLARE_TYPEINFO(ListInstance, Q_PRIMITIVE_TYPE | Q_MOVABLE_TYPE);
+ State initState;
+ initState.context = ctxt;
+ initState.compiledData = comp;
+ initState.instructionStream = comp->bytecode.constData() + start;
+ states.push(initState);
-QObject *QDeclarativeVME::run(QDeclarativeContextData *ctxt, QDeclarativeCompiledData *comp,
- int start, const QBitField &bindingSkipList)
-{
- QDeclarativeVMEObjectStack stack;
+ typedef QDeclarativeInstruction I;
+ I *i = (I *)initState.instructionStream;
- if (start == -1) start = 0;
+ Q_ASSERT(comp->instructionType(i) == I::Init);
- return run(stack, ctxt, comp, start, bindingSkipList);
+ objects.allocate(i->init.objectStackSize);
+ lists.allocate(i->init.listStackSize);
+ bindValues.allocate(i->init.bindingsSize);
+ parserStatus.allocate(i->init.parserStatusSize);
+
+ rootContext = 0;
+ engine = ctxt->engine;
}
-void QDeclarativeVME::runDeferred(QObject *object)
+bool QDeclarativeVME::initDeferred(QObject *object)
{
QDeclarativeData *data = QDeclarativeData::get(object);
if (!data || !data->context || !data->deferredComponent)
- return;
+ return false;
QDeclarativeContextData *ctxt = data->context;
QDeclarativeCompiledData *comp = data->deferredComponent;
int start = data->deferredIdx;
- QDeclarativeVMEObjectStack stack;
- stack.push(object);
- run(stack, ctxt, comp, start, QBitField());
+ State initState;
+ initState.flags = State::Deferred;
+ initState.context = ctxt;
+ initState.compiledData = comp;
+ initState.instructionStream = comp->bytecode.constData() + start;
+ states.push(initState);
+
+ typedef QDeclarativeInstruction I;
+ I *i = (I *)initState.instructionStream;
+
+ Q_ASSERT(comp->instructionType(i) == I::DeferInit);
+
+ objects.allocate(i->deferInit.objectStackSize);
+ lists.allocate(i->deferInit.listStackSize);
+ bindValues.allocate(i->deferInit.bindingsSize);
+ parserStatus.allocate(i->deferInit.parserStatusSize);
+
+ objects.push(object);
+
+ rootContext = 0;
+ engine = ctxt->engine;
+
+ return true;
+}
+
+namespace {
+struct ActiveVMERestorer
+{
+ ActiveVMERestorer(QDeclarativeVME *me, QDeclarativeEnginePrivate *ep)
+ : ep(ep), oldVME(ep->activeVME) { ep->activeVME = me; }
+ ~ActiveVMERestorer() { ep->activeVME = oldVME; }
+
+ QDeclarativeEnginePrivate *ep;
+ QDeclarativeVME *oldVME;
+};
+}
+
+QObject *QDeclarativeVME::execute(QList<QDeclarativeError> *errors, const Interrupt &interrupt)
+{
+ Q_ASSERT(states.count() >= 1);
+
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(states.at(0).context->engine);
+
+ ActiveVMERestorer restore(this, ep);
+
+ QObject *rv = run(errors, interrupt);
+
+ return rv;
}
inline bool fastHasBinding(QObject *o, int index)
@@ -166,9 +198,11 @@ static void removeBindingOnProperty(QObject *o, int index)
if (binding) binding->destroy();
}
+// XXX we probably need some form of "work count" here to prevent us checking this
+// for every instruction.
#define QML_BEGIN_INSTR_COMMON(I) { \
const QDeclarativeInstructionMeta<(int)QDeclarativeInstruction::I>::DataType &instr = QDeclarativeInstructionMeta<(int)QDeclarativeInstruction::I>::data(*genericInstr); \
- instructionStream += QDeclarativeInstructionMeta<(int)QDeclarativeInstruction::I>::Size; \
+ INSTRUCTIONSTREAM += QDeclarativeInstructionMeta<(int)QDeclarativeInstruction::I>::Size; \
Q_UNUSED(instr);
#ifdef QML_THREADED_VME_INTERPRETER
@@ -176,12 +210,15 @@ static void removeBindingOnProperty(QObject *o, int index)
QML_BEGIN_INSTR_COMMON(I)
# define QML_NEXT_INSTR(I) { \
- genericInstr = reinterpret_cast<const QDeclarativeInstruction *>(instructionStream); \
+ if (watcher.hasRecursed()) return 0; \
+ genericInstr = reinterpret_cast<const QDeclarativeInstruction *>(INSTRUCTIONSTREAM); \
goto *genericInstr->common.code; \
}
# define QML_END_INSTR(I) } \
- genericInstr = reinterpret_cast<const QDeclarativeInstruction *>(instructionStream); \
+ if (watcher.hasRecursed()) return 0; \
+ genericInstr = reinterpret_cast<const QDeclarativeInstruction *>(INSTRUCTIONSTREAM); \
+ if (interrupt.shouldInterrupt()) return 0; \
goto *genericInstr->common.code;
#else
@@ -189,16 +226,18 @@ static void removeBindingOnProperty(QObject *o, int index)
case QDeclarativeInstruction::I: \
QML_BEGIN_INSTR_COMMON(I)
-# define QML_NEXT_INSTR(I) break;
-# define QML_END_INSTR(I) } break;
+# define QML_NEXT_INSTR(I) \
+ if (watcher.hasRecursed()) return 0; \
+ break;
+# define QML_END_INSTR(I) \
+ if (watcher.hasRecursed() || interrupt.shouldInterrupt()) return 0; \
+ } break;
#endif
#define CLEAN_PROPERTY(o, index) if (fastHasBinding(o, index)) removeBindingOnProperty(o, index)
-QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
- QDeclarativeContextData *ctxt,
- QDeclarativeCompiledData *comp,
- int start, const QBitField &bindingSkipList
+QObject *QDeclarativeVME::run(QList<QDeclarativeError> *errors,
+ const Interrupt &interrupt
#ifdef QML_THREADED_VME_INTERPRETER
, void ***storeJumpTable
#endif
@@ -215,121 +254,207 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
return 0;
}
#endif
- Q_ASSERT(comp);
- Q_ASSERT(ctxt);
- const QList<QDeclarativeCompiledData::TypeReference> &types = comp->types;
- const QList<QString> &primitives = comp->primitives;
- const QList<QByteArray> &datas = comp->datas;
- const QList<QDeclarativePropertyCache *> &propertyCaches = comp->propertyCaches;
- const QList<QDeclarativeScriptData *> &scripts = comp->scripts;
- const QList<QUrl> &urls = comp->urls;
-
- QDeclarativeEnginePrivate::SimpleList<QDeclarativeAbstractBinding> bindValues;
- QDeclarativeEnginePrivate::SimpleList<QDeclarativeParserStatus> parserStatus;
+ Q_ASSERT(errors->isEmpty());
+ Q_ASSERT(states.count() >= 1);
- QDeclarativeVMEStack<ListInstance> qliststack;
+ QDeclarativeEngine *engine = states.at(0).context->engine;
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
- vmeErrors.clear();
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine);
+ // Need a v8 handle scope and execution context for StoreVar instructions.
+ v8::HandleScope handleScope;
+ v8::Context::Scope contextScope(ep->v8engine()->context());
- int status = -1; //for dbus
+ int status = -1; // needed for dbus
QDeclarativePropertyPrivate::WriteFlags flags = QDeclarativePropertyPrivate::BypassInterceptor |
QDeclarativePropertyPrivate::RemoveBindingOnAliasWrite;
- const char *instructionStream = comp->bytecode.constData() + start;
+ QRecursionWatcher<QDeclarativeVME, &QDeclarativeVME::recursion> watcher(this);
+
+#define COMP states.top().compiledData
+#define CTXT states.top().context
+#define INSTRUCTIONSTREAM states.top().instructionStream
+#define BINDINGSKIPLIST states.top().bindingSkipList
+
+#define TYPES COMP->types
+#define PRIMITIVES COMP->primitives
+#define DATAS COMP->datas
+#define PROPERTYCACHES COMP->propertyCaches
+#define SCRIPTS COMP->scripts
+#define URLS COMP->urls
#ifdef QML_THREADED_VME_INTERPRETER
- const QDeclarativeInstruction *genericInstr = reinterpret_cast<const QDeclarativeInstruction *>(instructionStream);
+ const QDeclarativeInstruction *genericInstr = reinterpret_cast<const QDeclarativeInstruction *>(INSTRUCTIONSTREAM);
goto *genericInstr->common.code;
#else
for (;;) {
- const QDeclarativeInstruction *genericInstr = reinterpret_cast<const QDeclarativeInstruction *>(instructionStream);
+ const QDeclarativeInstruction *genericInstr = reinterpret_cast<const QDeclarativeInstruction *>(INSTRUCTIONSTREAM);
switch (genericInstr->common.instructionType) {
#endif
QML_BEGIN_INSTR(Init)
- if (instr.bindingsSize)
- bindValues = QDeclarativeEnginePrivate::SimpleList<QDeclarativeAbstractBinding>(instr.bindingsSize);
- if (instr.parserStatusSize)
- parserStatus = QDeclarativeEnginePrivate::SimpleList<QDeclarativeParserStatus>(instr.parserStatusSize);
+ // Ensure that the compiled data has been initialized
+ if (!COMP->isInitialized()) COMP->initialize(engine);
+
+ QDeclarativeContextData *parentCtxt = CTXT;
+ CTXT = new QDeclarativeContextData;
+ CTXT->isInternal = true;
+ CTXT->url = COMP->url;
+ CTXT->imports = COMP->importCache;
+ CTXT->imports->addref();
+ CTXT->setParent(parentCtxt);
if (instr.contextCache != -1)
- ctxt->setIdPropertyData(comp->contextCaches.at(instr.contextCache));
+ CTXT->setIdPropertyData(COMP->contextCaches.at(instr.contextCache));
if (instr.compiledBinding != -1) {
- const char *v4data = datas.at(instr.compiledBinding).constData();
- ctxt->v4bindings = new QDeclarativeV4Bindings(v4data, ctxt, comp);
+ const char *v4data = DATAS.at(instr.compiledBinding).constData();
+ CTXT->v4bindings = new QV4Bindings(v4data, CTXT, COMP);
+ }
+ if (states.count() == 1) {
+ rootContext = CTXT;
+ rootContext->activeVME = this;
+ }
+ if (states.count() == 1 && !creationContext.isNull()) {
+ // A component that is logically created within another component instance shares the
+ // same instances of script imports. For example:
+ //
+ // import QtQuick 1.0
+ // import "test.js" as Test
+ // ListView {
+ // model: Test.getModel()
+ // delegate: Component {
+ // Text { text: Test.getValue(index); }
+ // }
+ // }
+ //
+ // Has the same "Test" instance. To implement this, we simply copy the v8 handles into
+ // the inner context. We have to create a fresh persistent handle for each to prevent
+ // double dispose. It is possible we could do this more efficiently using some form of
+ // referencing instead.
+ CTXT->importedScripts = creationContext->importedScripts;
+ for (int ii = 0; ii < CTXT->importedScripts.count(); ++ii)
+ CTXT->importedScripts[ii] = qPersistentNew<v8::Object>(CTXT->importedScripts[ii]);
}
QML_END_INSTR(Init)
+ QML_BEGIN_INSTR(DeferInit)
+ QML_END_INSTR(DeferInit)
+
QML_BEGIN_INSTR(Done)
- goto normalExit;
+ states.pop();
+
+ if (states.isEmpty())
+ goto normalExit;
QML_END_INSTR(Done)
- QML_BEGIN_INSTR(CreateObject)
- QBitField bindings;
+ QML_BEGIN_INSTR(CreateQMLObject)
+ const QDeclarativeCompiledData::TypeReference &type = TYPES.at(instr.type);
+ Q_ASSERT(type.component);
+
+ states.push(State());
+
+ State *cState = &states[states.count() - 2];
+ State *nState = &states[states.count() - 1];
+
+ nState->context = cState->context;
+ nState->compiledData = type.component;
+ nState->instructionStream = type.component->bytecode.constData();
+
if (instr.bindingBits != -1) {
- const QByteArray &bits = datas.at(instr.bindingBits);
- bindings = QBitField((const quint32*)bits.constData(),
- bits.size() * 8);
+ const QByteArray &bits = cState->compiledData->datas.at(instr.bindingBits);
+ nState->bindingSkipList = QBitField((const quint32*)bits.constData(),
+ bits.size() * 8);
}
- if (stack.isEmpty())
- bindings = bindings.united(bindingSkipList);
+ if (instr.isRoot)
+ nState->bindingSkipList = nState->bindingSkipList.united(cState->bindingSkipList);
- QObject *o =
- types.at(instr.type).createInstance(ctxt, bindings, &vmeErrors);
+ // As the state in the state stack changed, execution will continue in the new program.
+ QML_END_INSTR(CreateQMLObject)
- if (!o) {
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Unable to create object of type %1").arg(types.at(instr.type).className), instr.line);
- }
+ QML_BEGIN_INSTR(CompleteQMLObject)
+ QObject *o = objects.top();
QDeclarativeData *ddata = QDeclarativeData::get(o);
Q_ASSERT(ddata);
- if (stack.isEmpty()) {
+ if (instr.isRoot) {
if (ddata->context) {
- Q_ASSERT(ddata->context != ctxt);
+ Q_ASSERT(ddata->context != CTXT);
Q_ASSERT(ddata->outerContext);
- Q_ASSERT(ddata->outerContext != ctxt);
+ Q_ASSERT(ddata->outerContext != CTXT);
QDeclarativeContextData *c = ddata->context;
while (c->linkedContext) c = c->linkedContext;
- c->linkedContext = ctxt;
+ c->linkedContext = CTXT;
} else {
- ctxt->addObject(o);
+ CTXT->addObject(o);
}
ddata->ownContext = true;
} else if (!ddata->context) {
- ctxt->addObject(o);
+ CTXT->addObject(o);
}
ddata->setImplicitDestructible();
- ddata->outerContext = ctxt;
+ ddata->outerContext = CTXT;
+ ddata->lineNumber = instr.line;
+ ddata->columnNumber = instr.column;
+ QML_END_INSTR(CompleteQMLObject)
+
+ QML_BEGIN_INSTR(CreateCppObject)
+ const QDeclarativeCompiledData::TypeReference &type = TYPES.at(instr.type);
+ Q_ASSERT(type.type);
+
+ QObject *o = 0;
+ void *memory = 0;
+ type.type->create(&o, &memory, sizeof(QDeclarativeData));
+ QDeclarativeData *ddata = new (memory) QDeclarativeData;
+ ddata->ownMemory = false;
+ QObjectPrivate::get(o)->declarativeData = ddata;
+
+ if (type.typePropertyCache && !ddata->propertyCache) {
+ ddata->propertyCache = type.typePropertyCache;
+ ddata->propertyCache->addref();
+ }
+
+ if (!o)
+ VME_EXCEPTION(tr("Unable to create object of type %1").arg(type.className), instr.line);
+
+ if (instr.isRoot) {
+ if (ddata->context) {
+ Q_ASSERT(ddata->context != CTXT);
+ Q_ASSERT(ddata->outerContext);
+ Q_ASSERT(ddata->outerContext != CTXT);
+ QDeclarativeContextData *c = ddata->context;
+ while (c->linkedContext) c = c->linkedContext;
+ c->linkedContext = CTXT;
+ } else {
+ CTXT->addObject(o);
+ }
+
+ ddata->ownContext = true;
+ } else if (!ddata->context) {
+ CTXT->addObject(o);
+ }
+
+ ddata->setImplicitDestructible();
+ ddata->outerContext = CTXT;
ddata->lineNumber = instr.line;
ddata->columnNumber = instr.column;
if (instr.data != -1) {
QDeclarativeCustomParser *customParser =
- types.at(instr.type).type->customParser();
- customParser->setCustomData(o, datas.at(instr.data));
+ TYPES.at(instr.type).type->customParser();
+ customParser->setCustomData(o, DATAS.at(instr.data));
}
- if (!stack.isEmpty()) {
- QObject *parent = stack.top();
+ if (!objects.isEmpty()) {
+ QObject *parent = objects.top();
#if 0 // ### refactor
- if (o->isWidgetType()) {
- QWidget *widget = static_cast<QWidget*>(o);
- if (parent->isWidgetType()) {
- QWidget *parentWidget = static_cast<QWidget*>(parent);
- widget->setParent(parentWidget);
- } else {
- // TODO: parent might be a layout
- }
- } else
+ if (o->isWidgetType() && parent->isWidgetType())
+ static_cast<QWidget*>(o)->setParent(static_cast<QWidget*>(parent));
+ else
#endif
- {
QDeclarative_setParent_noEvent(o, parent);
- }
}
- stack.push(o);
- QML_END_INSTR(CreateObject)
+ objects.push(o);
+ QML_END_INSTR(CreateCppObject)
QML_BEGIN_INSTR(CreateSimpleObject)
QObject *o = (QObject *)operator new(instr.typeSize + sizeof(QDeclarativeData));
@@ -337,7 +462,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
instr.create(o);
QDeclarativeData *ddata = (QDeclarativeData *)(((const char *)o) + instr.typeSize);
- const QDeclarativeCompiledData::TypeReference &ref = types.at(instr.type);
+ const QDeclarativeCompiledData::TypeReference &ref = TYPES.at(instr.type);
if (!ddata->propertyCache && ref.typePropertyCache) {
ddata->propertyCache = ref.typePropertyCache;
ddata->propertyCache->addref();
@@ -346,87 +471,85 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
ddata->columnNumber = instr.column;
QObjectPrivate::get(o)->declarativeData = ddata;
- ddata->context = ddata->outerContext = ctxt;
- ddata->nextContextObject = ctxt->contextObjects;
+ ddata->context = ddata->outerContext = CTXT;
+ ddata->nextContextObject = CTXT->contextObjects;
if (ddata->nextContextObject)
ddata->nextContextObject->prevContextObject = &ddata->nextContextObject;
- ddata->prevContextObject = &ctxt->contextObjects;
- ctxt->contextObjects = ddata;
+ ddata->prevContextObject = &CTXT->contextObjects;
+ CTXT->contextObjects = ddata;
- QObject *parent = stack.top();
+ QObject *parent = objects.top();
QDeclarative_setParent_noEvent(o, parent);
- stack.push(o);
+ objects.push(o);
QML_END_INSTR(CreateSimpleObject)
QML_BEGIN_INSTR(SetId)
- QObject *target = stack.top();
- ctxt->setIdProperty(instr.index, target);
+ QObject *target = objects.top();
+ CTXT->setIdProperty(instr.index, target);
QML_END_INSTR(SetId)
QML_BEGIN_INSTR(SetDefault)
- ctxt->contextObject = stack.top();
+ CTXT->contextObject = objects.top();
QML_END_INSTR(SetDefault)
QML_BEGIN_INSTR(CreateComponent)
QDeclarativeComponent *qcomp =
- new QDeclarativeComponent(ctxt->engine, comp, instructionStream - comp->bytecode.constData(),
- stack.isEmpty() ? 0 : stack.top());
+ new QDeclarativeComponent(CTXT->engine, COMP, INSTRUCTIONSTREAM - COMP->bytecode.constData(),
+ objects.isEmpty() ? 0 : objects.top());
QDeclarativeData *ddata = QDeclarativeData::get(qcomp, true);
Q_ASSERT(ddata);
- ctxt->addObject(qcomp);
+ CTXT->addObject(qcomp);
- if (stack.isEmpty())
+ if (instr.isRoot)
ddata->ownContext = true;
ddata->setImplicitDestructible();
- ddata->outerContext = ctxt;
+ ddata->outerContext = CTXT;
ddata->lineNumber = instr.line;
ddata->columnNumber = instr.column;
- QDeclarativeComponentPrivate::get(qcomp)->creationContext = ctxt;
+ QDeclarativeComponentPrivate::get(qcomp)->creationContext = CTXT;
- stack.push(qcomp);
- instructionStream += instr.count;
+ objects.push(qcomp);
+ INSTRUCTIONSTREAM += instr.count;
QML_END_INSTR(CreateComponent)
QML_BEGIN_INSTR(StoreMetaObject)
- QObject *target = stack.top();
+ QObject *target = objects.top();
QMetaObject mo;
- const QByteArray &metadata = datas.at(instr.data);
+ const QByteArray &metadata = DATAS.at(instr.data);
QFastMetaBuilder::fromData(&mo, 0, metadata);
-// QMetaObjectBuilder::fromRelocatableData(&mo, 0, metadata);
-
const QDeclarativeVMEMetaData *data =
- (const QDeclarativeVMEMetaData *)datas.at(instr.aliasData).constData();
+ (const QDeclarativeVMEMetaData *)DATAS.at(instr.aliasData).constData();
- (void)new QDeclarativeVMEMetaObject(target, &mo, data, comp);
+ (void)new QDeclarativeVMEMetaObject(target, &mo, data, COMP);
if (instr.propertyCache != -1) {
QDeclarativeData *ddata = QDeclarativeData::get(target, true);
if (ddata->propertyCache) ddata->propertyCache->release();
- ddata->propertyCache = propertyCaches.at(instr.propertyCache);
+ ddata->propertyCache = PROPERTYCACHES.at(instr.propertyCache);
ddata->propertyCache->addref();
}
QML_END_INSTR(StoreMetaObject)
QML_BEGIN_INSTR(StoreVariant)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
// XXX - can be more efficient
- QVariant v = QDeclarativeStringConverters::variantFromString(primitives.at(instr.value));
+ QVariant v = QDeclarativeStringConverters::variantFromString(PRIMITIVES.at(instr.value));
void *a[] = { &v, 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.propertyIndex, a);
QML_END_INSTR(StoreVariant)
QML_BEGIN_INSTR(StoreVariantInteger)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
QVariant v(instr.value);
@@ -436,7 +559,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreVariantInteger)
QML_BEGIN_INSTR(StoreVariantDouble)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
QVariant v(instr.value);
@@ -446,7 +569,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreVariantDouble)
QML_BEGIN_INSTR(StoreVariantBool)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
QVariant v(instr.value);
@@ -455,33 +578,68 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
instr.propertyIndex, a);
QML_END_INSTR(StoreVariantBool)
+ QML_BEGIN_INSTR(StoreVar)
+ QObject *target = objects.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ // Note that we don't use QDeclarativeStringConverters::variantFromString() here, which
+ // means that automatic generation of value types from strings doesn't occur.
+ // This is a deliberate behaviour difference to variant properties.
+ v8::Handle<v8::Value> v8Value = ep->v8engine()->fromVariant(PRIMITIVES.at(instr.value));
+ static_cast<QDeclarativeVMEMetaObject *>(const_cast<QMetaObject *>(target->metaObject()))->setVMEProperty(instr.propertyIndex, v8Value);
+ QML_END_INSTR(StoreVar)
+
+ QML_BEGIN_INSTR(StoreVarInteger)
+ QObject *target = objects.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ v8::Handle<v8::Value> v8Value = v8::Integer::New(instr.value);
+ static_cast<QDeclarativeVMEMetaObject *>(const_cast<QMetaObject *>(target->metaObject()))->setVMEProperty(instr.propertyIndex, v8Value);
+ QML_END_INSTR(StoreVarInteger)
+
+ QML_BEGIN_INSTR(StoreVarDouble)
+ QObject *target = objects.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ v8::Handle<v8::Value> v8Value = v8::Number::New(instr.value);
+ static_cast<QDeclarativeVMEMetaObject *>(const_cast<QMetaObject *>(target->metaObject()))->setVMEProperty(instr.propertyIndex, v8Value);
+ QML_END_INSTR(StoreVarDouble)
+
+ QML_BEGIN_INSTR(StoreVarBool)
+ QObject *target = objects.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ v8::Handle<v8::Value> v8Value = v8::Boolean::New(instr.value);
+ static_cast<QDeclarativeVMEMetaObject *>(const_cast<QMetaObject *>(target->metaObject()))->setVMEProperty(instr.propertyIndex, v8Value);
+ QML_END_INSTR(StoreVarBool)
+
QML_BEGIN_INSTR(StoreString)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
- void *a[] = { (void *)&primitives.at(instr.value), 0, &status, &flags };
+ void *a[] = { (void *)&PRIMITIVES.at(instr.value), 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.propertyIndex, a);
QML_END_INSTR(StoreString)
QML_BEGIN_INSTR(StoreByteArray)
- QObject *target = stack.top();
- void *a[] = { (void *)&datas.at(instr.value), 0, &status, &flags };
+ QObject *target = objects.top();
+ void *a[] = { (void *)&DATAS.at(instr.value), 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.propertyIndex, a);
QML_END_INSTR(StoreByteArray)
QML_BEGIN_INSTR(StoreUrl)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
- void *a[] = { (void *)&urls.at(instr.value), 0, &status, &flags };
+ void *a[] = { (void *)&URLS.at(instr.value), 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
instr.propertyIndex, a);
QML_END_INSTR(StoreUrl)
QML_BEGIN_INSTR(StoreFloat)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
float f = instr.value;
@@ -491,7 +649,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreFloat)
QML_BEGIN_INSTR(StoreDouble)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
double d = instr.value;
@@ -501,7 +659,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreDouble)
QML_BEGIN_INSTR(StoreBool)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
void *a[] = { (void *)&instr.value, 0, &status, &flags };
@@ -510,7 +668,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreBool)
QML_BEGIN_INSTR(StoreInteger)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
void *a[] = { (void *)&instr.value, 0, &status, &flags };
@@ -519,7 +677,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreInteger)
QML_BEGIN_INSTR(StoreColor)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
QColor c = QColor::fromRgba(instr.value);
@@ -529,7 +687,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreColor)
QML_BEGIN_INSTR(StoreDate)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
QDate d = QDate::fromJulianDay(instr.value);
@@ -539,7 +697,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreDate)
QML_BEGIN_INSTR(StoreTime)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
QTime *t = (QTime *)&instr.time;
@@ -549,7 +707,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreTime)
QML_BEGIN_INSTR(StoreDateTime)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
QTime *t = (QTime *)&instr.time;
@@ -560,7 +718,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreDateTime)
QML_BEGIN_INSTR(StorePoint)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
QPoint *p = (QPoint *)&instr.point;
@@ -570,7 +728,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StorePoint)
QML_BEGIN_INSTR(StorePointF)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
QPointF *p = (QPointF *)&instr.point;
@@ -580,7 +738,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StorePointF)
QML_BEGIN_INSTR(StoreSize)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
QSize *s = (QSize *)&instr.size;
@@ -590,7 +748,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreSize)
QML_BEGIN_INSTR(StoreSizeF)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
QSizeF *s = (QSizeF *)&instr.size;
@@ -600,7 +758,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreSizeF)
QML_BEGIN_INSTR(StoreRect)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
QRect *r = (QRect *)&instr.rect;
@@ -610,7 +768,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreRect)
QML_BEGIN_INSTR(StoreRectF)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
QRectF *r = (QRectF *)&instr.rect;
@@ -620,7 +778,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreRectF)
QML_BEGIN_INSTR(StoreVector3D)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
QVector3D *v = (QVector3D *)&instr.vector;
@@ -630,7 +788,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreVector3D)
QML_BEGIN_INSTR(StoreVector4D)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
QVector4D *v = (QVector4D *)&instr.vector;
@@ -640,8 +798,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreVector4D)
QML_BEGIN_INSTR(StoreObject)
- QObject *assignObj = stack.pop();
- QObject *target = stack.top();
+ QObject *assignObj = objects.pop();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
void *a[] = { (void *)&assignObj, 0, &status, &flags };
@@ -650,10 +808,10 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreObject)
QML_BEGIN_INSTR(AssignCustomType)
- QObject *target = stack.top();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
- const QString &primitive = primitives.at(instr.primitive);
+ const QString &primitive = PRIMITIVES.at(instr.primitive);
int type = instr.type;
QDeclarativeMetaType::StringConverter converter = QDeclarativeMetaType::customStringConverter(type);
QVariant v = (*converter)(primitive);
@@ -661,7 +819,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QMetaProperty prop =
target->metaObject()->property(instr.propertyIndex);
if (v.isNull() || ((int)prop.type() != type && prop.userType() != type))
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign value %1 to property %2").arg(primitive).arg(QString::fromUtf8(prop.name())), instr.line);
+ VME_EXCEPTION(tr("Cannot assign value %1 to property %2").arg(primitive).arg(QString::fromUtf8(prop.name())), instr.line);
void *a[] = { (void *)v.data(), 0, &status, &flags };
QMetaObject::metacall(target, QMetaObject::WriteProperty,
@@ -671,55 +829,55 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_BEGIN_INSTR(AssignSignalObject)
// XXX optimize
- QObject *assign = stack.pop();
- QObject *target = stack.top();
+ QObject *assign = objects.pop();
+ QObject *target = objects.top();
int sigIdx = instr.signal;
- const QString &pr = primitives.at(sigIdx);
+ const QString &pr = PRIMITIVES.at(sigIdx);
QDeclarativeProperty prop(target, pr);
if (prop.type() & QDeclarativeProperty::SignalProperty) {
QMetaMethod method = QDeclarativeMetaType::defaultMethod(assign);
if (method.signature() == 0)
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign object type %1 with no default method").arg(QString::fromLatin1(assign->metaObject()->className())), instr.line);
+ VME_EXCEPTION(tr("Cannot assign object type %1 with no default method").arg(QString::fromLatin1(assign->metaObject()->className())), instr.line);
if (!QMetaObject::checkConnectArgs(prop.method().signature(), method.signature()))
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot connect mismatched signal/slot %1 %vs. %2").arg(QString::fromLatin1(method.signature())).arg(QString::fromLatin1(prop.method().signature())), instr.line);
+ VME_EXCEPTION(tr("Cannot connect mismatched signal/slot %1 %vs. %2").arg(QString::fromLatin1(method.signature())).arg(QString::fromLatin1(prop.method().signature())), instr.line);
QDeclarativePropertyPrivate::connect(target, prop.index(), assign, method.methodIndex());
} else {
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign an object to signal property %1").arg(pr), instr.line);
+ VME_EXCEPTION(tr("Cannot assign an object to signal property %1").arg(pr), instr.line);
}
QML_END_INSTR(AssignSignalObject)
QML_BEGIN_INSTR(StoreSignal)
- QObject *target = stack.top();
- QObject *context = stack.at(stack.count() - 1 - instr.context);
+ QObject *target = objects.top();
+ QObject *context = objects.at(objects.count() - 1 - instr.context);
QMetaMethod signal = target->metaObject()->method(instr.signalIndex);
QDeclarativeBoundSignal *bs = new QDeclarativeBoundSignal(target, signal, target);
QDeclarativeExpression *expr =
- new QDeclarativeExpression(ctxt, context, primitives.at(instr.value));
- expr->setSourceLocation(comp->name, instr.line);
- static_cast<QDeclarativeExpressionPrivate *>(QObjectPrivate::get(expr))->name = datas.at(instr.name);
+ new QDeclarativeExpression(CTXT, context, PRIMITIVES.at(instr.value));
+ expr->setSourceLocation(COMP->name, instr.line);
+ static_cast<QDeclarativeExpressionPrivate *>(QObjectPrivate::get(expr))->name = QString::fromUtf8(DATAS.at(instr.name));
bs->setExpression(expr);
QML_END_INSTR(StoreSignal)
QML_BEGIN_INSTR(StoreImportedScript)
- ctxt->importedScripts << run(ctxt, scripts.at(instr.value));
+ CTXT->importedScripts << run(CTXT, SCRIPTS.at(instr.value));
QML_END_INSTR(StoreImportedScript)
QML_BEGIN_INSTR(StoreScriptString)
- QObject *target = stack.top();
- QObject *scope = stack.at(stack.count() - 1 - instr.scope);
+ QObject *target = objects.top();
+ QObject *scope = objects.at(objects.count() - 1 - instr.scope);
QDeclarativeScriptString ss;
- ss.setContext(ctxt->asQDeclarativeContext());
+ ss.setContext(CTXT->asQDeclarativeContext());
ss.setScopeObject(scope);
- ss.setScript(primitives.at(instr.value));
+ ss.setScript(PRIMITIVES.at(instr.value));
ss.d.data()->bindingId = instr.bindingId;
ss.d.data()->lineNumber = instr.line;
@@ -729,37 +887,37 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreScriptString)
QML_BEGIN_INSTR(BeginObject)
- QObject *target = stack.top();
+ QObject *target = objects.top();
QDeclarativeParserStatus *status = reinterpret_cast<QDeclarativeParserStatus *>(reinterpret_cast<char *>(target) + instr.castValue);
- parserStatus.append(status);
- status->d = &parserStatus.values[parserStatus.count - 1];
+ parserStatus.push(status);
+ status->d = &parserStatus.top();
status->classBegin();
QML_END_INSTR(BeginObject)
QML_BEGIN_INSTR(InitV8Bindings)
- ctxt->v8bindings = new QV8Bindings(primitives.at(instr.program), instr.programIndex,
- instr.line, comp, ctxt);
+ CTXT->v8bindings = new QV8Bindings(PRIMITIVES.at(instr.program), instr.programIndex,
+ instr.line, COMP, CTXT);
QML_END_INSTR(InitV8Bindings)
QML_BEGIN_INSTR(StoreBinding)
QObject *target =
- stack.at(stack.count() - 1 - instr.owner);
+ objects.at(objects.count() - 1 - instr.owner);
QObject *context =
- stack.at(stack.count() - 1 - instr.context);
+ objects.at(objects.count() - 1 - instr.context);
QDeclarativeProperty mp =
- QDeclarativePropertyPrivate::restore(datas.at(instr.property), target, ctxt);
+ QDeclarativePropertyPrivate::restore(instr.property, target, CTXT);
int coreIndex = mp.index();
- if ((stack.count() - instr.owner) == 1 && bindingSkipList.testBit(coreIndex))
+ if (instr.isRoot && BINDINGSKIPLIST.testBit(coreIndex))
QML_NEXT_INSTR(StoreBinding);
- QDeclarativeBinding *bind = new QDeclarativeBinding(primitives.at(instr.value), true,
- context, ctxt, comp->name, instr.line);
- bindValues.append(bind);
- bind->m_mePtr = &bindValues.values[bindValues.count - 1];
+ QDeclarativeBinding *bind = new QDeclarativeBinding(PRIMITIVES.at(instr.value), true,
+ context, CTXT, COMP->name, instr.line);
+ bindValues.push(bind);
+ bind->m_mePtr = &bindValues.top();
bind->setTarget(mp);
bind->addToObject(target, QDeclarativePropertyPrivate::bindingIndex(mp));
@@ -767,22 +925,22 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_BEGIN_INSTR(StoreBindingOnAlias)
QObject *target =
- stack.at(stack.count() - 1 - instr.owner);
+ objects.at(objects.count() - 1 - instr.owner);
QObject *context =
- stack.at(stack.count() - 1 - instr.context);
+ objects.at(objects.count() - 1 - instr.context);
QDeclarativeProperty mp =
- QDeclarativePropertyPrivate::restore(datas.at(instr.property), target, ctxt);
+ QDeclarativePropertyPrivate::restore(instr.property, target, CTXT);
int coreIndex = mp.index();
- if ((stack.count() - instr.owner) == 1 && bindingSkipList.testBit(coreIndex))
+ if (instr.isRoot && BINDINGSKIPLIST.testBit(coreIndex))
QML_NEXT_INSTR(StoreBindingOnAlias);
- QDeclarativeBinding *bind = new QDeclarativeBinding(primitives.at(instr.value), true,
- context, ctxt, comp->name, instr.line);
- bindValues.append(bind);
- bind->m_mePtr = &bindValues.values[bindValues.count - 1];
+ QDeclarativeBinding *bind = new QDeclarativeBinding(PRIMITIVES.at(instr.value), true,
+ context, CTXT, COMP->name, instr.line);
+ bindValues.push(bind);
+ bind->m_mePtr = &bindValues.top();
bind->setTarget(mp);
QDeclarativeAbstractBinding *old = QDeclarativePropertyPrivate::setBindingNoEnable(target, coreIndex, QDeclarativePropertyPrivate::valueTypeCoreIndex(mp), bind);
@@ -791,59 +949,55 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_BEGIN_INSTR(StoreV4Binding)
QObject *target =
- stack.at(stack.count() - 1 - instr.owner);
+ objects.at(objects.count() - 1 - instr.owner);
QObject *scope =
- stack.at(stack.count() - 1 - instr.context);
+ objects.at(objects.count() - 1 - instr.context);
int property = instr.property;
- if (stack.count() == 1 && bindingSkipList.testBit(property & 0xFFFF))
+ if (instr.isRoot && BINDINGSKIPLIST.testBit(property & 0xFFFF))
QML_NEXT_INSTR(StoreV4Binding);
QDeclarativeAbstractBinding *binding =
- ctxt->v4bindings->configBinding(instr.value, target, scope, property);
- bindValues.append(binding);
- binding->m_mePtr = &bindValues.values[bindValues.count - 1];
+ CTXT->v4bindings->configBinding(instr.value, target, scope, property);
+ bindValues.push(binding);
+ binding->m_mePtr = &bindValues.top();
binding->addToObject(target, property);
QML_END_INSTR(StoreV4Binding)
QML_BEGIN_INSTR(StoreV8Binding)
QObject *target =
- stack.at(stack.count() - 1 - instr.owner);
+ objects.at(objects.count() - 1 - instr.owner);
QObject *scope =
- stack.at(stack.count() - 1 - instr.context);
+ objects.at(objects.count() - 1 - instr.context);
- QDeclarativeProperty mp =
- QDeclarativePropertyPrivate::restore(datas.at(instr.property), target, ctxt);
-
- int coreIndex = mp.index();
-
- if ((stack.count() - instr.owner) == 1 && bindingSkipList.testBit(coreIndex))
+ if (instr.isRoot && BINDINGSKIPLIST.testBit(instr.property.coreIndex))
QML_NEXT_INSTR(StoreV8Binding);
QDeclarativeAbstractBinding *binding =
- ctxt->v8bindings->configBinding(instr.value, target, scope, mp, instr.line);
- bindValues.append(binding);
- binding->m_mePtr = &bindValues.values[bindValues.count - 1];
- binding->addToObject(target, QDeclarativePropertyPrivate::bindingIndex(mp));
+ CTXT->v8bindings->configBinding(instr.value, target, scope,
+ instr.property, instr.line);
+ bindValues.push(binding);
+ binding->m_mePtr = &bindValues.top();
+ binding->addToObject(target, QDeclarativePropertyPrivate::bindingIndex(instr.property));
QML_END_INSTR(StoreV8Binding)
QML_BEGIN_INSTR(StoreValueSource)
- QObject *obj = stack.pop();
+ QObject *obj = objects.pop();
QDeclarativePropertyValueSource *vs = reinterpret_cast<QDeclarativePropertyValueSource *>(reinterpret_cast<char *>(obj) + instr.castValue);
- QObject *target = stack.at(stack.count() - 1 - instr.owner);
+ QObject *target = objects.at(objects.count() - 1 - instr.owner);
QDeclarativeProperty prop =
- QDeclarativePropertyPrivate::restore(datas.at(instr.property), target, ctxt);
+ QDeclarativePropertyPrivate::restore(instr.property, target, CTXT);
obj->setParent(target);
vs->setTarget(prop);
QML_END_INSTR(StoreValueSource)
QML_BEGIN_INSTR(StoreValueInterceptor)
- QObject *obj = stack.pop();
+ QObject *obj = objects.pop();
QDeclarativePropertyValueInterceptor *vi = reinterpret_cast<QDeclarativePropertyValueInterceptor *>(reinterpret_cast<char *>(obj) + instr.castValue);
- QObject *target = stack.at(stack.count() - 1 - instr.owner);
+ QObject *target = objects.at(objects.count() - 1 - instr.owner);
QDeclarativeProperty prop =
- QDeclarativePropertyPrivate::restore(datas.at(instr.property), target, ctxt);
+ QDeclarativePropertyPrivate::restore(instr.property, target, CTXT);
obj->setParent(target);
vi->setTarget(prop);
QDeclarativeVMEMetaObject *mo = static_cast<QDeclarativeVMEMetaObject *>((QMetaObject*)target->metaObject());
@@ -851,16 +1005,16 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QML_END_INSTR(StoreValueInterceptor)
QML_BEGIN_INSTR(StoreObjectQList)
- QObject *assign = stack.pop();
+ QObject *assign = objects.pop();
- const ListInstance &list = qliststack.top();
+ const List &list = lists.top();
list.qListProperty.append((QDeclarativeListProperty<void>*)&list.qListProperty, assign);
QML_END_INSTR(StoreObjectQList)
QML_BEGIN_INSTR(AssignObjectList)
// This is only used for assigning interfaces
- QObject *assign = stack.pop();
- const ListInstance &list = qliststack.top();
+ QObject *assign = objects.pop();
+ const List &list = lists.top();
int type = list.type;
@@ -870,15 +1024,15 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
if (iid)
ptr = assign->qt_metacast(iid);
if (!ptr)
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign object to list"), instr.line);
+ VME_EXCEPTION(tr("Cannot assign object to list"), instr.line);
list.qListProperty.append((QDeclarativeListProperty<void>*)&list.qListProperty, ptr);
QML_END_INSTR(AssignObjectList)
QML_BEGIN_INSTR(StoreVariantObject)
- QObject *assign = stack.pop();
- QObject *target = stack.top();
+ QObject *assign = objects.pop();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
QVariant v = QVariant::fromValue(assign);
@@ -887,9 +1041,18 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
instr.propertyIndex, a);
QML_END_INSTR(StoreVariantObject)
+ QML_BEGIN_INSTR(StoreVarObject)
+ QObject *assign = objects.pop();
+ QObject *target = objects.top();
+ CLEAN_PROPERTY(target, instr.propertyIndex);
+
+ v8::Handle<v8::Value> v8Value = ep->v8engine()->newQObject(assign);
+ static_cast<QDeclarativeVMEMetaObject *>(const_cast<QMetaObject *>(target->metaObject()))->setVMEProperty(instr.propertyIndex, v8Value);
+ QML_END_INSTR(StoreVarObject)
+
QML_BEGIN_INSTR(StoreInterface)
- QObject *assign = stack.pop();
- QObject *target = stack.top();
+ QObject *assign = objects.pop();
+ QObject *target = objects.top();
CLEAN_PROPERTY(target, instr.propertyIndex);
int coreIdx = instr.propertyIndex;
@@ -909,33 +1072,33 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
}
if (!ok)
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot assign object to interface property"), instr.line);
+ VME_EXCEPTION(tr("Cannot assign object to interface property"), instr.line);
QML_END_INSTR(StoreInterface)
QML_BEGIN_INSTR(FetchAttached)
- QObject *target = stack.top();
+ QObject *target = objects.top();
QObject *qmlObject = qmlAttachedPropertiesObjectById(instr.id, target);
if (!qmlObject)
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Unable to create attached object"), instr.line);
+ VME_EXCEPTION(tr("Unable to create attached object"), instr.line);
- stack.push(qmlObject);
+ objects.push(qmlObject);
QML_END_INSTR(FetchAttached)
QML_BEGIN_INSTR(FetchQList)
- QObject *target = stack.top();
+ QObject *target = objects.top();
- qliststack.push(ListInstance(instr.type));
+ lists.push(List(instr.type));
void *a[1];
- a[0] = (void *)&(qliststack.top().qListProperty);
+ a[0] = (void *)&(lists.top().qListProperty);
QMetaObject::metacall(target, QMetaObject::ReadProperty,
instr.property, a);
QML_END_INSTR(FetchQList)
QML_BEGIN_INSTR(FetchObject)
- QObject *target = stack.top();
+ QObject *target = objects.top();
QObject *obj = 0;
// NOTE: This assumes a cast to QObject does not alter the
@@ -946,33 +1109,33 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
instr.property, a);
if (!obj)
- VME_EXCEPTION(QCoreApplication::translate("QDeclarativeVME","Cannot set properties on %1 as it is null").arg(QString::fromUtf8(target->metaObject()->property(instr.property).name())), instr.line);
+ VME_EXCEPTION(tr("Cannot set properties on %1 as it is null").arg(QString::fromUtf8(target->metaObject()->property(instr.property).name())), instr.line);
- stack.push(obj);
+ objects.push(obj);
QML_END_INSTR(FetchObject)
QML_BEGIN_INSTR(PopQList)
- qliststack.pop();
+ lists.pop();
QML_END_INSTR(PopQList)
QML_BEGIN_INSTR(Defer)
if (instr.deferCount) {
- QObject *target = stack.top();
+ QObject *target = objects.top();
QDeclarativeData *data =
QDeclarativeData::get(target, true);
- comp->addref();
- data->deferredComponent = comp;
- data->deferredIdx = instructionStream - comp->bytecode.constData();
- instructionStream += instr.deferCount;
+ COMP->addref();
+ data->deferredComponent = COMP;
+ data->deferredIdx = INSTRUCTIONSTREAM - COMP->bytecode.constData();
+ INSTRUCTIONSTREAM += instr.deferCount;
}
QML_END_INSTR(Defer)
QML_BEGIN_INSTR(PopFetchedObject)
- stack.pop();
+ objects.pop();
QML_END_INSTR(PopFetchedObject)
QML_BEGIN_INSTR(FetchValueType)
- QObject *target = stack.top();
+ QObject *target = objects.top();
if (instr.bindingSkipList != 0) {
// Possibly need to clear bindings
@@ -994,13 +1157,13 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
QDeclarativeValueType *valueHandler = ep->valueTypes[instr.type];
valueHandler->read(target, instr.property);
- stack.push(valueHandler);
+ objects.push(valueHandler);
QML_END_INSTR(FetchValueType)
QML_BEGIN_INSTR(PopValueType)
QDeclarativeValueType *valueHandler =
- static_cast<QDeclarativeValueType *>(stack.pop());
- QObject *target = stack.top();
+ static_cast<QDeclarativeValueType *>(objects.pop());
+ QObject *target = objects.top();
valueHandler->write(target, instr.property, QDeclarativePropertyPrivate::BypassInterceptor);
QML_END_INSTR(PopValueType)
@@ -1014,67 +1177,75 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack,
}
#endif
- exceptionExit:
- Q_ASSERT(isError());
- if (!stack.isEmpty()) {
- delete stack.at(0); // ### What about failures in deferred creation?
- } else {
- ctxt->destroy();
- }
+exceptionExit:
+ Q_ASSERT(!states.isEmpty());
+ Q_ASSERT(!errors->isEmpty());
+
+ reset();
- QDeclarativeEnginePrivate::clear(bindValues);
- QDeclarativeEnginePrivate::clear(parserStatus);
return 0;
- normalExit:
- if (bindValues.count)
- ep->bindValues << bindValues;
- else if (bindValues.values)
- bindValues.clear();
+normalExit:
+ Q_ASSERT(objects.count() == 1);
- if (parserStatus.count)
- ep->parserStatus << parserStatus;
- else if (parserStatus.values)
- parserStatus.clear();
+ QObject *rv = objects.top();
- Q_ASSERT(stack.count() == 1);
- return stack.top();
-}
+ objects.deallocate();
+ lists.deallocate();
+ states.clear();
-bool QDeclarativeVME::isError() const
-{
- return !vmeErrors.isEmpty();
+ return rv;
}
-QList<QDeclarativeError> QDeclarativeVME::errors() const
+void QDeclarativeVME::reset()
{
- return vmeErrors;
+ Q_ASSERT(!states.isEmpty() || objects.isEmpty());
+
+ QRecursionWatcher<QDeclarativeVME, &QDeclarativeVME::recursion> watcher(this);
+
+ if (!objects.isEmpty() && !(states.at(0).flags & State::Deferred))
+ delete objects.at(0);
+
+ if (!rootContext.isNull())
+ rootContext->activeVME = 0;
+
+ // Remove the QDeclarativeParserStatus and QDeclarativeAbstractBinding back pointers
+ blank(parserStatus);
+ blank(bindValues);
+
+ while (componentAttached) {
+ QDeclarativeComponentAttached *a = componentAttached;
+ a->rem();
+ }
+
+ engine = 0;
+ objects.deallocate();
+ lists.deallocate();
+ bindValues.deallocate();
+ parserStatus.deallocate();
+ finalizeCallbacks.clear();
+ states.clear();
+ rootContext = 0;
+ creationContext = 0;
}
-QObject *
-QDeclarativeCompiledData::TypeReference::createInstance(QDeclarativeContextData *ctxt,
- const QBitField &bindings,
- QList<QDeclarativeError> *errors) const
+// Must be called with a handle scope and context
+void QDeclarativeScriptData::initialize(QDeclarativeEngine *engine)
{
- if (type) {
- QObject *rv = 0;
- void *memory = 0;
-
- type->create(&rv, &memory, sizeof(QDeclarativeData));
- QDeclarativeData *ddata = new (memory) QDeclarativeData;
- ddata->ownMemory = false;
- QObjectPrivate::get(rv)->declarativeData = ddata;
-
- if (typePropertyCache && !ddata->propertyCache) {
- ddata->propertyCache = typePropertyCache;
- ddata->propertyCache->addref();
- }
+ Q_ASSERT(m_program.IsEmpty());
+ Q_ASSERT(engine);
+ Q_ASSERT(!hasEngine());
- return rv;
- } else {
- Q_ASSERT(component);
- return QDeclarativeComponentPrivate::begin(ctxt, 0, component, -1, 0, errors, bindings);
- }
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
+ QV8Engine *v8engine = ep->v8engine();
+
+ // XXX Handle errors during the script compile!
+ v8::Local<v8::Script> program = v8engine->qmlModeCompile(m_programSource, url.toString(), 1);
+ m_program = qPersistentNew<v8::Script>(program);
+
+ addToEngine(engine);
+
+ addref();
}
v8::Persistent<v8::Object> QDeclarativeVME::run(QDeclarativeContextData *parentCtxt, QDeclarativeScriptData *script)
@@ -1082,6 +1253,7 @@ v8::Persistent<v8::Object> QDeclarativeVME::run(QDeclarativeContextData *parentC
if (script->m_loaded)
return qPersistentNew<v8::Object>(script->m_value);
+ Q_ASSERT(parentCtxt && parentCtxt->engine);
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(parentCtxt->engine);
QV8Engine *v8engine = ep->v8engine();
@@ -1116,8 +1288,11 @@ v8::Persistent<v8::Object> QDeclarativeVME::run(QDeclarativeContextData *parentC
ctxt->imports->addref();
}
- if (effectiveCtxt)
+ if (effectiveCtxt) {
ctxt->setParent(effectiveCtxt, true);
+ } else {
+ ctxt->engine = parentCtxt->engine; // Fix for QTBUG-21620
+ }
for (int ii = 0; ii < script->scripts.count(); ++ii) {
ctxt->importedScripts << run(ctxt, script->scripts.at(ii)->scriptData());
@@ -1126,6 +1301,9 @@ v8::Persistent<v8::Object> QDeclarativeVME::run(QDeclarativeContextData *parentC
v8::HandleScope handle_scope;
v8::Context::Scope scope(v8engine->context());
+ if (!script->isInitialized())
+ script->initialize(parentCtxt->engine);
+
v8::Local<v8::Object> qmlglobal = v8engine->qmlScope(ctxt, 0);
v8::TryCatch try_catch;
@@ -1157,55 +1335,153 @@ void **QDeclarativeVME::instructionJumpTable()
static void **jumpTable = 0;
if (!jumpTable) {
QDeclarativeVME dummy;
- QDeclarativeVMEObjectStack stack;
- dummy.run(stack, 0, 0, 0, QBitField(), &jumpTable);
+ QDeclarativeVME::Interrupt i;
+ dummy.run(0, i, &jumpTable);
}
return jumpTable;
}
#endif
-template<typename T>
-QDeclarativeVMEStack<T>::QDeclarativeVMEStack()
-: _index(-1)
+bool QDeclarativeVME::complete(const Interrupt &interrupt)
{
+ Q_ASSERT(engine ||
+ (bindValues.isEmpty() &&
+ parserStatus.isEmpty() &&
+ componentAttached == 0 &&
+ rootContext.isNull() &&
+ finalizeCallbacks.isEmpty()));
+
+ if (!engine)
+ return true;
+
+ ActiveVMERestorer restore(this, QDeclarativeEnginePrivate::get(engine));
+ QRecursionWatcher<QDeclarativeVME, &QDeclarativeVME::recursion> watcher(this);
+
+ while (!bindValues.isEmpty()) {
+ QDeclarativeAbstractBinding *b = bindValues.pop();
+
+ if(b) {
+ b->m_mePtr = 0;
+ b->setEnabled(true, QDeclarativePropertyPrivate::BypassInterceptor |
+ QDeclarativePropertyPrivate::DontRemoveBinding);
+ }
+
+ if (watcher.hasRecursed() || interrupt.shouldInterrupt())
+ return false;
+ }
+ bindValues.deallocate();
+
+ while (!parserStatus.isEmpty()) {
+ QDeclarativeParserStatus *status = parserStatus.pop();
+
+ if (status && status->d) {
+ status->d = 0;
+ status->componentComplete();
+ }
+
+ if (watcher.hasRecursed() || interrupt.shouldInterrupt())
+ return false;
+ }
+ parserStatus.deallocate();
+
+ while (componentAttached) {
+ QDeclarativeComponentAttached *a = componentAttached;
+ a->rem();
+ QDeclarativeData *d = QDeclarativeData::get(a->parent());
+ Q_ASSERT(d);
+ Q_ASSERT(d->context);
+ a->add(&d->context->componentAttached);
+ emit a->completed();
+
+ if (watcher.hasRecursed() || interrupt.shouldInterrupt())
+ return false;
+ }
+
+ if (!rootContext.isNull())
+ rootContext->activeVME = 0;
+
+ for (int ii = 0; ii < finalizeCallbacks.count(); ++ii) {
+ QDeclarativeEnginePrivate::FinalizeCallback callback = finalizeCallbacks.at(ii);
+ QObject *obj = callback.first;
+ if (obj) {
+ void *args[] = { 0 };
+ QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, callback.second, args);
+ }
+ if (watcher.hasRecursed())
+ return false;
+ }
+ finalizeCallbacks.clear();
+
+ reset();
+
+ return true;
}
-template<typename T>
-bool QDeclarativeVMEStack<T>::isEmpty() const {
- return _index == -1;
+void QDeclarativeVME::blank(QFiniteStack<QDeclarativeAbstractBinding *> &bs)
+{
+ for (int ii = 0; ii < bs.count(); ++ii) {
+ QDeclarativeAbstractBinding *b = bs.at(ii);
+ if (b) b->m_mePtr = 0;
+ }
}
-template<typename T>
-const T &QDeclarativeVMEStack<T>::top() const {
- return at(_index);
+void QDeclarativeVME::blank(QFiniteStack<QDeclarativeParserStatus *> &pss)
+{
+ for (int ii = 0; ii < pss.count(); ++ii) {
+ QDeclarativeParserStatus *ps = pss.at(ii);
+ if(ps) ps->d = 0;
+ }
}
-template<typename T>
-void QDeclarativeVMEStack<T>::push(const T &o) {
- _index++;
+QDeclarativeVMEGuard::QDeclarativeVMEGuard()
+: m_objectCount(0), m_objects(0), m_contextCount(0), m_contexts(0)
+{
+}
- Q_ASSERT(_index <= VLA::size());
- if (_index == VLA::size())
- this->append(o);
- else
- VLA::data()[_index] = o;
+QDeclarativeVMEGuard::~QDeclarativeVMEGuard()
+{
+ clear();
}
-template<typename T>
-T QDeclarativeVMEStack<T>::pop() {
- Q_ASSERT(_index >= 0);
- --_index;
- return VLA::data()[_index + 1];
+void QDeclarativeVMEGuard::guard(QDeclarativeVME *vme)
+{
+ clear();
+
+ m_objectCount = vme->objects.count();
+ m_objects = new QDeclarativeGuard<QObject>[m_objectCount];
+ for (int ii = 0; ii < m_objectCount; ++ii)
+ m_objects[ii] = vme->objects[ii];
+
+ m_contextCount = (vme->rootContext.isNull())?0:1 + vme->states.count();
+ m_contexts = new QDeclarativeGuardedContextData[m_contextCount];
+ for (int ii = 0; ii < vme->states.count(); ++ii)
+ m_contexts[ii] = vme->states.at(ii).context;
+ if (!vme->rootContext.isNull())
+ m_contexts[m_contextCount - 1] = vme->rootContext.contextData();
}
-template<typename T>
-int QDeclarativeVMEStack<T>::count() const {
- return _index + 1;
+void QDeclarativeVMEGuard::clear()
+{
+ delete [] m_objects;
+ delete [] m_contexts;
+
+ m_objectCount = 0;
+ m_objects = 0;
+ m_contextCount = 0;
+ m_contexts = 0;
}
-template<typename T>
-const T &QDeclarativeVMEStack<T>::at(int index) const {
- return VLA::data()[index];
+bool QDeclarativeVMEGuard::isOK() const
+{
+ for (int ii = 0; ii < m_objectCount; ++ii)
+ if (m_objects[ii].isNull())
+ return false;
+
+ for (int ii = 0; ii < m_contextCount; ++ii)
+ if (m_contexts[ii].isNull())
+ return false;
+
+ return true;
}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativevme_p.h b/src/declarative/qml/qdeclarativevme_p.h
index a0dae77501..b74bc547bf 100644
--- a/src/declarative/qml/qdeclarativevme_p.h
+++ b/src/declarative/qml/qdeclarativevme_p.h
@@ -54,13 +54,18 @@
//
#include "qdeclarativeerror.h"
-#include "private/qbitfield_p.h"
-#include "private/qdeclarativeinstruction_p.h"
+#include <private/qbitfield_p.h>
+#include "qdeclarativeinstruction_p.h"
+#include <private/qrecursionwatcher_p.h>
-#include <QtCore/QString>
#include <QtCore/QStack>
+#include <QtCore/QString>
+#include <QtCore/qelapsedtimer.h>
+#include <QtCore/qcoreapplication.h>
#include <private/qv8_p.h>
+#include <private/qdeclarativeengine_p.h>
+#include <private/qfinitestack_p.h>
QT_BEGIN_NAMESPACE
@@ -70,39 +75,156 @@ class QDeclarativeScriptData;
class QDeclarativeCompiledData;
class QDeclarativeCompiledData;
class QDeclarativeContextData;
-class QDeclarativeVMEObjectStack;
+
+namespace QDeclarativeVMETypes {
+ struct List
+ {
+ List() : type(0) {}
+ List(int t) : type(t) {}
+
+ int type;
+ QDeclarativeListProperty<void> qListProperty;
+ };
+}
+Q_DECLARE_TYPEINFO(QDeclarativeVMETypes::List, Q_PRIMITIVE_TYPE | Q_MOVABLE_TYPE);
class QDeclarativeVME
{
+ Q_DECLARE_TR_FUNCTIONS(QDeclarativeVME)
public:
- QDeclarativeVME();
-
- QObject *run(QDeclarativeContextData *, QDeclarativeCompiledData *,
- int start = -1, const QBitField & = QBitField());
-
- void runDeferred(QObject *);
-
- bool isError() const;
- QList<QDeclarativeError> errors() const;
+ class Interrupt {
+ public:
+ inline Interrupt();
+ inline Interrupt(bool *runWhile);
+ inline Interrupt(int nsecs);
+
+ inline void reset();
+ inline bool shouldInterrupt() const;
+ private:
+ enum Mode { None, Time, Flag };
+ Mode mode;
+ union {
+ struct {
+ QElapsedTimer timer;
+ int nsecs;
+ };
+ bool *runWhile;
+ };
+ };
+
+ QDeclarativeVME() : data(0), componentAttached(0) {}
+ QDeclarativeVME(void *data) : data(data), componentAttached(0) {}
+
+ void *data;
+ QDeclarativeComponentAttached *componentAttached;
+ QList<QDeclarativeEnginePrivate::FinalizeCallback> finalizeCallbacks;
+
+ void init(QDeclarativeContextData *, QDeclarativeCompiledData *, int start,
+ QDeclarativeContextData * = 0);
+ bool initDeferred(QObject *);
+ void reset();
+
+ QObject *execute(QList<QDeclarativeError> *errors, const Interrupt & = Interrupt());
+ bool complete(const Interrupt & = Interrupt());
private:
- v8::Persistent<v8::Object> run(QDeclarativeContextData *, QDeclarativeScriptData *);
+ friend class QDeclarativeVMEGuard;
- QObject *run(QDeclarativeVMEObjectStack &,
- QDeclarativeContextData *, QDeclarativeCompiledData *,
- int start, const QBitField &
+ QObject *run(QList<QDeclarativeError> *errors, const Interrupt &
#ifdef QML_THREADED_VME_INTERPRETER
, void ***storeJumpTable = 0
#endif
- );
- QList<QDeclarativeError> vmeErrors;
+ );
+ v8::Persistent<v8::Object> run(QDeclarativeContextData *, QDeclarativeScriptData *);
#ifdef QML_THREADED_VME_INTERPRETER
static void **instructionJumpTable();
friend class QDeclarativeCompiledData;
#endif
+
+ QDeclarativeEngine *engine;
+ QRecursionNode recursion;
+
+ QFiniteStack<QObject *> objects;
+ QFiniteStack<QDeclarativeVMETypes::List> lists;
+
+ QFiniteStack<QDeclarativeAbstractBinding *> bindValues;
+ QFiniteStack<QDeclarativeParserStatus *> parserStatus;
+ QDeclarativeGuardedContextData rootContext;
+ QDeclarativeGuardedContextData creationContext;
+
+ struct State {
+ enum Flag { Deferred = 0x00000001 };
+
+ State() : flags(0), context(0), compiledData(0), instructionStream(0) {}
+ quint32 flags;
+ QDeclarativeContextData *context;
+ QDeclarativeCompiledData *compiledData;
+ const char *instructionStream;
+ QBitField bindingSkipList;
+ };
+
+ QStack<State> states;
+
+ static void blank(QFiniteStack<QDeclarativeParserStatus *> &);
+ static void blank(QFiniteStack<QDeclarativeAbstractBinding *> &);
+};
+
+// Used to check that a QDeclarativeVME that is interrupted mid-execution
+// is still valid. Checks all the objects and contexts have not been
+// deleted.
+class QDeclarativeVMEGuard
+{
+public:
+ QDeclarativeVMEGuard();
+ ~QDeclarativeVMEGuard();
+
+ void guard(QDeclarativeVME *);
+ void clear();
+
+ bool isOK() const;
+
+private:
+ int m_objectCount;
+ QDeclarativeGuard<QObject> *m_objects;
+ int m_contextCount;
+ QDeclarativeGuardedContextData *m_contexts;
};
+QDeclarativeVME::Interrupt::Interrupt()
+: mode(None)
+{
+}
+
+QDeclarativeVME::Interrupt::Interrupt(bool *runWhile)
+: mode(Flag), runWhile(runWhile)
+{
+}
+
+QDeclarativeVME::Interrupt::Interrupt(int nsecs)
+: mode(Time), nsecs(nsecs)
+{
+}
+
+void QDeclarativeVME::Interrupt::reset()
+{
+ if (mode == Time)
+ timer.start();
+}
+
+bool QDeclarativeVME::Interrupt::shouldInterrupt() const
+{
+ if (mode == None) {
+ return false;
+ } else if (mode == Time) {
+ return timer.nsecsElapsed() > nsecs;
+ } else if (mode == Flag) {
+ return !*runWhile;
+ } else {
+ return false;
+ }
+}
+
QT_END_NAMESPACE
#endif // QDECLARATIVEVME_P_H
diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp
index bcd46f259e..9cdec020a7 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject.cpp
+++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp
@@ -39,14 +39,14 @@
**
****************************************************************************/
-#include "private/qdeclarativevmemetaobject_p.h"
+#include "qdeclarativevmemetaobject_p.h"
#include "qdeclarative.h"
-#include "private/qdeclarativerefcount_p.h"
+#include <private/qdeclarativerefcount_p.h>
#include "qdeclarativeexpression.h"
-#include "private/qdeclarativeexpression_p.h"
-#include "private/qdeclarativecontext_p.h"
-#include "private/qdeclarativebinding_p.h"
+#include "qdeclarativeexpression_p.h"
+#include "qdeclarativecontext_p.h"
+#include "qdeclarativebinding_p.h"
Q_DECLARE_METATYPE(QJSValue);
@@ -382,8 +382,9 @@ QDeclarativeVMEMetaObject::QDeclarativeVMEMetaObject(QObject *obj,
const QMetaObject *other,
const QDeclarativeVMEMetaData *meta,
QDeclarativeCompiledData *cdata)
-: object(obj), compiledData(cdata), ctxt(QDeclarativeData::get(obj, true)->outerContext),
- metaData(meta), data(0), v8methods(0), parent(0)
+: QV8GCCallback::Node(GcPrologueCallback), object(obj), compiledData(cdata),
+ ctxt(QDeclarativeData::get(obj, true)->outerContext), metaData(meta), data(0),
+ firstVarPropertyIndex(-1), varPropertiesInitialized(false), v8methods(0), parent(0)
{
compiledData->addref();
@@ -398,19 +399,23 @@ QDeclarativeVMEMetaObject::QDeclarativeVMEMetaObject(QObject *obj,
propOffset = QAbstractDynamicMetaObject::propertyOffset();
methodOffset = QAbstractDynamicMetaObject::methodOffset();
- data = new QDeclarativeVMEVariant[metaData->propertyCount];
+ data = new QDeclarativeVMEVariant[metaData->propertyCount - metaData->varPropertyCount];
aConnected.resize(metaData->aliasCount);
int list_type = qMetaTypeId<QDeclarativeListProperty<QObject> >();
// ### Optimize
- for (int ii = 0; ii < metaData->propertyCount; ++ii) {
+ for (int ii = 0; ii < metaData->propertyCount - metaData->varPropertyCount; ++ii) {
int t = (metaData->propertyData() + ii)->propertyType;
if (t == list_type) {
listProperties.append(List(methodOffset + ii));
data[ii].setValue(listProperties.count() - 1);
}
}
+
+ firstVarPropertyIndex = metaData->propertyCount - metaData->varPropertyCount;
+ if (metaData->varPropertyCount)
+ QV8GCCallback::addGcCallbackNode(this);
}
QDeclarativeVMEMetaObject::~QDeclarativeVMEMetaObject()
@@ -422,6 +427,9 @@ QDeclarativeVMEMetaObject::~QDeclarativeVMEMetaObject()
for (int ii = 0; v8methods && ii < metaData->methodCount; ++ii) {
qPersistentDispose(v8methods[ii]);
}
+
+ if (metaData->varPropertyCount)
+ qPersistentDispose(varProperties); // if not weak, will not have been cleaned up by the callback.
}
int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
@@ -468,10 +476,29 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
if (t == -1) {
- if (c == QMetaObject::ReadProperty) {
- *reinterpret_cast<QVariant *>(a[0]) = readVarPropertyAsVariant(id);
- } else if (c == QMetaObject::WriteProperty) {
- writeVarProperty(id, *reinterpret_cast<QVariant *>(a[0]));
+ if (id >= firstVarPropertyIndex) {
+ // the context can be null if accessing var properties from cpp after re-parenting an item.
+ QDeclarativeEnginePrivate *ep = (ctxt == 0 || ctxt->engine == 0) ? 0 : QDeclarativeEnginePrivate::get(ctxt->engine);
+ QV8Engine *v8e = (ep == 0) ? 0 : ep->v8engine();
+ if (v8e) {
+ v8::HandleScope handleScope;
+ v8::Context::Scope contextScope(v8e->context());
+ if (c == QMetaObject::ReadProperty) {
+ *reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id);
+ } else if (c == QMetaObject::WriteProperty) {
+ writeProperty(id, *reinterpret_cast<QVariant *>(a[0]));
+ }
+ } else if (c == QMetaObject::ReadProperty) {
+ // if the context was disposed, we just return an invalid variant from read.
+ *reinterpret_cast<QVariant *>(a[0]) = QVariant();
+ }
+ } else {
+ // don't need to set up v8 scope objects, since not accessing varProperties.
+ if (c == QMetaObject::ReadProperty) {
+ *reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id);
+ } else if (c == QMetaObject::WriteProperty) {
+ writeProperty(id, *reinterpret_cast<QVariant *>(a[0]));
+ }
}
} else {
@@ -716,54 +743,61 @@ v8::Handle<v8::Function> QDeclarativeVMEMetaObject::method(int index)
return v8methods[index];
}
-#if 0
-QScriptValue QDeclarativeVMEMetaObject::readVarProperty(int id)
+v8::Handle<v8::Value> QDeclarativeVMEMetaObject::readVarProperty(int id)
{
- if (data[id].dataType() == qMetaTypeId<QScriptValue>())
- return data[id].asQJSValue();
- else if (data[id].dataType() == QMetaType::QObjectStar)
- return QDeclarativeEnginePrivate::get(ctxt->engine)->objectClass->newQObject(data[id].asQObject());
- else
- return QDeclarativeEnginePrivate::get(ctxt->engine)->scriptValueFromVariant(data[id].asQVariant());
+ Q_ASSERT(id >= firstVarPropertyIndex);
+
+ ensureVarPropertiesAllocated();
+ return varProperties->Get(id - firstVarPropertyIndex);
}
-#endif
-QVariant QDeclarativeVMEMetaObject::readVarPropertyAsVariant(int id)
+QVariant QDeclarativeVMEMetaObject::readPropertyAsVariant(int id)
{
-#if 0
- if (data[id].dataType() == qMetaTypeId<QScriptValue>())
- return QDeclarativeEnginePrivate::get(ctxt->engine)->scriptValueToVariant(data[id].asQJSValue());
- else
-#endif
- if (data[id].dataType() == QMetaType::QObjectStar)
- return QVariant::fromValue(data[id].asQObject());
- else
- return data[id].asQVariant();
+ if (id >= firstVarPropertyIndex) {
+ ensureVarPropertiesAllocated();
+ return QDeclarativeEnginePrivate::get(ctxt->engine)->v8engine()->toVariant(varProperties->Get(id - firstVarPropertyIndex), -1);
+ } else {
+ if (data[id].dataType() == QMetaType::QObjectStar) {
+ return QVariant::fromValue(data[id].asQObject());
+ } else {
+ return data[id].asQVariant();
+ }
+ }
}
-#if 0
-void QDeclarativeVMEMetaObject::writeVarProperty(int id, const QScriptValue &value)
+void QDeclarativeVMEMetaObject::writeVarProperty(int id, v8::Handle<v8::Value> value)
{
- data[id].setValue(value);
+ Q_ASSERT(id >= firstVarPropertyIndex);
+
+ ensureVarPropertiesAllocated();
+ varProperties->Set(id - firstVarPropertyIndex, value);
activate(object, methodOffset + id, 0);
}
-#endif
-void QDeclarativeVMEMetaObject::writeVarProperty(int id, const QVariant &value)
+void QDeclarativeVMEMetaObject::writeProperty(int id, const QVariant &value)
{
- bool needActivate = false;
- if (value.userType() == QMetaType::QObjectStar) {
- QObject *o = qvariant_cast<QObject *>(value);
- needActivate = (data[id].dataType() != QMetaType::QObjectStar || data[id].asQObject() != o);
- data[id].setValue(qvariant_cast<QObject *>(value));
+ if (id >= firstVarPropertyIndex) {
+ ensureVarPropertiesAllocated();
+ QVariant currentValue = readPropertyAsVariant(id);
+ varProperties->Set(id - firstVarPropertyIndex, QDeclarativeEnginePrivate::get(ctxt->engine)->v8engine()->fromVariant(value));
+ if ((currentValue.userType() != value.userType() || currentValue != value))
+ activate(object, methodOffset + id, 0);
} else {
- needActivate = (data[id].dataType() != qMetaTypeId<QVariant>() ||
- data[id].asQVariant().userType() != value.userType() ||
- data[id].asQVariant() != value);
- data[id].setValue(value);
+ bool needActivate = false;
+ if (value.userType() == QMetaType::QObjectStar) {
+ QObject *o = qvariant_cast<QObject *>(value);
+ needActivate = (data[id].dataType() != QMetaType::QObjectStar || data[id].asQObject() != o);
+ data[id].setValue(qvariant_cast<QObject *>(value));
+ } else {
+ needActivate = (data[id].dataType() != qMetaTypeId<QVariant>() ||
+ data[id].asQVariant().userType() != value.userType() ||
+ data[id].asQVariant() != value);
+ data[id].setValue(value);
+ }
+
+ if (needActivate)
+ activate(object, methodOffset + id, 0);
}
- if (needActivate)
- activate(object, methodOffset + id, 0);
}
void QDeclarativeVMEMetaObject::listChanged(int id)
@@ -849,8 +883,7 @@ void QDeclarativeVMEMetaObject::setVmeMethod(int index, v8::Persistent<v8::Funct
v8methods[methodIndex] = value;
}
-#if 0
-QScriptValue QDeclarativeVMEMetaObject::vmeProperty(int index)
+v8::Handle<v8::Value> QDeclarativeVMEMetaObject::vmeProperty(int index)
{
if (index < propOffset) {
Q_ASSERT(parent);
@@ -859,7 +892,7 @@ QScriptValue QDeclarativeVMEMetaObject::vmeProperty(int index)
return readVarProperty(index - propOffset);
}
-void QDeclarativeVMEMetaObject::setVMEProperty(int index, const QScriptValue &v)
+void QDeclarativeVMEMetaObject::setVMEProperty(int index, v8::Handle<v8::Value> v)
{
if (index < propOffset) {
Q_ASSERT(parent);
@@ -867,7 +900,46 @@ void QDeclarativeVMEMetaObject::setVMEProperty(int index, const QScriptValue &v)
}
return writeVarProperty(index - propOffset, v);
}
-#endif
+
+void QDeclarativeVMEMetaObject::ensureVarPropertiesAllocated()
+{
+ if (!varPropertiesInitialized)
+ allocateVarPropertiesArray();
+}
+
+// see also: QV8GCCallback::garbageCollectorPrologueCallback()
+void QDeclarativeVMEMetaObject::allocateVarPropertiesArray()
+{
+ v8::HandleScope handleScope;
+ v8::Context::Scope cs(QDeclarativeEnginePrivate::get(ctxt->engine)->v8engine()->context());
+ varProperties = qPersistentNew(v8::Array::New(metaData->varPropertyCount));
+ varProperties.MakeWeak(static_cast<void*>(this), VarPropertiesWeakReferenceCallback);
+ varPropertiesInitialized = true;
+}
+
+/*
+ The "var" properties are stored in a v8::Array which will be strong persistent if the object has cpp-ownership
+ and the root QObject in the parent chain does not have JS-ownership. In the weak persistent handle case,
+ this callback will dispose the handle when the v8object which owns the lifetime of the var properties array
+ is cleared as a result of all other handles to that v8object being released.
+ See QV8GCCallback::garbageCollectorPrologueCallback() for more information.
+ */
+void QDeclarativeVMEMetaObject::VarPropertiesWeakReferenceCallback(v8::Persistent<v8::Value> object, void* parameter)
+{
+ QDeclarativeVMEMetaObject *vmemo = static_cast<QDeclarativeVMEMetaObject*>(parameter);
+ Q_ASSERT(vmemo);
+ qPersistentDispose(object);
+ vmemo->varProperties.Clear();
+}
+
+void QDeclarativeVMEMetaObject::GcPrologueCallback(QV8GCCallback::Referencer *r, QV8GCCallback::Node *node)
+{
+ QDeclarativeVMEMetaObject *vmemo = static_cast<QDeclarativeVMEMetaObject*>(node);
+ Q_ASSERT(vmemo);
+ if (!vmemo->varPropertiesInitialized || vmemo->varProperties.IsEmpty())
+ return;
+ r->addRelationship(vmemo->object, vmemo->varProperties);
+}
bool QDeclarativeVMEMetaObject::aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const
{
diff --git a/src/declarative/qml/qdeclarativevmemetaobject_p.h b/src/declarative/qml/qdeclarativevmemetaobject_p.h
index 991c79a4ef..400961b27f 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject_p.h
+++ b/src/declarative/qml/qdeclarativevmemetaobject_p.h
@@ -65,9 +65,11 @@
#include <private/qobject_p.h>
-#include "private/qdeclarativeguard_p.h"
-#include "private/qdeclarativecompiler_p.h"
-#include "private/qdeclarativecontext_p.h"
+#include "qdeclarativeguard_p.h"
+#include "qdeclarativecompiler_p.h"
+#include "qdeclarativecontext_p.h"
+
+#include <private/qv8gccallback_p.h>
#include <private/qv8_p.h>
@@ -77,6 +79,7 @@ QT_BEGIN_NAMESPACE
struct QDeclarativeVMEMetaData
{
+ short varPropertyCount;
short propertyCount;
short aliasCount;
short signalCount;
@@ -131,9 +134,11 @@ struct QDeclarativeVMEMetaData
}
};
+class QV8QObjectWrapper;
class QDeclarativeVMEVariant;
class QDeclarativeRefCount;
-class QDeclarativeVMEMetaObject : public QAbstractDynamicMetaObject
+class Q_AUTOTEST_EXPORT QDeclarativeVMEMetaObject : public QAbstractDynamicMetaObject,
+ public QV8GCCallback::Node
{
public:
QDeclarativeVMEMetaObject(QObject *obj, const QMetaObject *other, const QDeclarativeVMEMetaData *data,
@@ -145,10 +150,8 @@ public:
v8::Handle<v8::Function> vmeMethod(int index);
int vmeMethodLineNumber(int index);
void setVmeMethod(int index, v8::Persistent<v8::Function>);
-#if 0
- QScriptValue vmeProperty(int index);
- void setVMEProperty(int index, const QScriptValue &);
-#endif
+ v8::Handle<v8::Value> vmeProperty(int index);
+ void setVMEProperty(int index, v8::Handle<v8::Value> v);
void connectAliasSignal(int index);
@@ -166,6 +169,14 @@ private:
QDeclarativeVMEVariant *data;
+ v8::Persistent<v8::Array> varProperties;
+ int firstVarPropertyIndex;
+ bool varPropertiesInitialized;
+ static void VarPropertiesWeakReferenceCallback(v8::Persistent<v8::Value> object, void* parameter);
+ static void GcPrologueCallback(QV8GCCallback::Referencer *r, QV8GCCallback::Node *node);
+ inline void allocateVarPropertiesArray();
+ inline void ensureVarPropertiesAllocated();
+
void connectAlias(int aliasId);
QBitArray aConnected;
QBitArray aInterceptors;
@@ -174,12 +185,10 @@ private:
v8::Persistent<v8::Function> *v8methods;
v8::Handle<v8::Function> method(int);
-#if 0
- QScriptValue readVarProperty(int);
- void writeVarProperty(int, const QScriptValue &);
-#endif
- QVariant readVarPropertyAsVariant(int);
- void writeVarProperty(int, const QVariant &);
+ v8::Handle<v8::Value> readVarProperty(int);
+ void writeVarProperty(int, v8::Handle<v8::Value>);
+ QVariant readPropertyAsVariant(int);
+ void writeProperty(int, const QVariant &);
QAbstractDynamicMetaObject *parent;
@@ -196,6 +205,9 @@ private:
static int list_count(QDeclarativeListProperty<QObject> *);
static QObject *list_at(QDeclarativeListProperty<QObject> *, int);
static void list_clear(QDeclarativeListProperty<QObject> *);
+
+ friend class QV8GCCallback;
+ friend class QV8QObjectWrapper;
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativewatcher.cpp b/src/declarative/qml/qdeclarativewatcher.cpp
index 33f0358003..42c0b5cc72 100644
--- a/src/declarative/qml/qdeclarativewatcher.cpp
+++ b/src/declarative/qml/qdeclarativewatcher.cpp
@@ -39,15 +39,15 @@
**
****************************************************************************/
-#include "private/qdeclarativewatcher_p.h"
+#include "qdeclarativewatcher_p.h"
#include "qdeclarativeexpression.h"
#include "qdeclarativecontext.h"
#include "qdeclarative.h"
-#include <qdeclarativedebugservice_p.h>
-#include "private/qdeclarativeproperty_p.h"
-#include "private/qdeclarativevaluetype_p.h"
+#include <private/qdeclarativedebugservice_p.h>
+#include "qdeclarativeproperty_p.h"
+#include "qdeclarativevaluetype_p.h"
#include <QtCore/qmetaobject.h>
#include <QtCore/qdebug.h>
diff --git a/src/declarative/qml/qdeclarativeworkerscript.cpp b/src/declarative/qml/qdeclarativeworkerscript.cpp
index e6af0ba964..98aaddceef 100644
--- a/src/declarative/qml/qdeclarativeworkerscript.cpp
+++ b/src/declarative/qml/qdeclarativeworkerscript.cpp
@@ -39,11 +39,11 @@
**
****************************************************************************/
-#include "private/qdeclarativeworkerscript_p.h"
-#include "private/qdeclarativelistmodel_p.h"
-#include "private/qdeclarativelistmodelworkeragent_p.h"
-#include "private/qdeclarativeengine_p.h"
-#include "private/qdeclarativeexpression_p.h"
+#include "qdeclarativeworkerscript_p.h"
+#include <private/qdeclarativelistmodel_p.h>
+#include <private/qdeclarativelistmodelworkeragent_p.h>
+#include "qdeclarativeengine_p.h"
+#include "qdeclarativeexpression_p.h"
#include <QtCore/qcoreevent.h>
#include <QtCore/qcoreapplication.h>
@@ -59,6 +59,7 @@
#include <private/qv8engine_p.h>
#include <private/qv8worker_p.h>
+#include <private/qv8gccallback_p.h>
QT_BEGIN_NAMESPACE
@@ -542,7 +543,7 @@ void QDeclarativeWorkerScriptEngine::run()
d->workers.clear();
delete d->workerEngine; d->workerEngine = 0;
-
+ QV8GCCallback::releaseWorkerThreadGcPrologueCallbackData();
isolate->Exit();
isolate->Dispose();
}
diff --git a/src/declarative/qml/qdeclarativexmlhttprequest.cpp b/src/declarative/qml/qdeclarativexmlhttprequest.cpp
index 23f21c91e3..0009163036 100644
--- a/src/declarative/qml/qdeclarativexmlhttprequest.cpp
+++ b/src/declarative/qml/qdeclarativexmlhttprequest.cpp
@@ -39,17 +39,17 @@
**
****************************************************************************/
-#include "private/qdeclarativexmlhttprequest_p.h"
+#include "qdeclarativexmlhttprequest_p.h"
#include <private/qv8engine_p.h>
#include "qdeclarativeengine.h"
-#include "private/qdeclarativeengine_p.h"
-#include "private/qdeclarativerefcount_p.h"
-#include "private/qdeclarativeengine_p.h"
-#include "private/qdeclarativeexpression_p.h"
+#include "qdeclarativeengine_p.h"
+#include <private/qdeclarativerefcount_p.h>
+#include "qdeclarativeengine_p.h"
+#include "qdeclarativeexpression_p.h"
#include "qdeclarativeglobal_p.h"
-#include "qv8domerrors_p.h"
+#include <private/qv8domerrors_p.h>
#include <QtCore/qobject.h>
#include <QtDeclarative/qjsvalue.h>
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 61e3aa3ab9..b14e547f40 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -1,4 +1,3 @@
-INCLUDEPATH += $$PWD
SOURCES += \
$$PWD/qdeclarativeinstruction.cpp \
$$PWD/qdeclarativevmemetaobject.cpp \
@@ -7,6 +6,7 @@ SOURCES += \
$$PWD/qdeclarativebinding.cpp \
$$PWD/qdeclarativeproperty.cpp \
$$PWD/qdeclarativecomponent.cpp \
+ $$PWD/qdeclarativeincubator.cpp \
$$PWD/qdeclarativecontext.cpp \
$$PWD/qdeclarativecustomparser.cpp \
$$PWD/qdeclarativepropertyvaluesource.cpp \
@@ -54,6 +54,8 @@ HEADERS += \
$$PWD/qdeclarativeproperty.h \
$$PWD/qdeclarativecomponent.h \
$$PWD/qdeclarativecomponent_p.h \
+ $$PWD/qdeclarativeincubator.h \
+ $$PWD/qdeclarativeincubator_p.h \
$$PWD/qdeclarativecustomparser_p.h \
$$PWD/qdeclarativecustomparser_p_p.h \
$$PWD/qdeclarativepropertyvaluesource.h \
diff --git a/src/declarative/qml/rewriter/rewriter.pri b/src/declarative/qml/rewriter/rewriter.pri
index a9fa1b5772..e51ee5ba4e 100644
--- a/src/declarative/qml/rewriter/rewriter.pri
+++ b/src/declarative/qml/rewriter/rewriter.pri
@@ -1,4 +1,2 @@
-INCLUDEPATH += $$PWD
-
HEADERS += $$PWD/textwriter_p.h
SOURCES += $$PWD/textwriter.cpp
diff --git a/src/declarative/qml/rewriter/textwriter.cpp b/src/declarative/qml/rewriter/textwriter.cpp
index d3a68d0ecc..e4b4597ebf 100644
--- a/src/declarative/qml/rewriter/textwriter.cpp
+++ b/src/declarative/qml/rewriter/textwriter.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "private/textwriter_p.h"
+#include "textwriter_p.h"
QT_QML_BEGIN_NAMESPACE
diff --git a/src/declarative/qml/v4/qdeclarativev4instruction.cpp b/src/declarative/qml/v4/qdeclarativev4instruction.cpp
deleted file mode 100644
index dd6892369b..0000000000
--- a/src/declarative/qml/v4/qdeclarativev4instruction.cpp
+++ /dev/null
@@ -1,553 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdeclarativev4instruction_p.h"
-#include "qdeclarativev4bindings_p.h"
-
-#include <QtCore/qdebug.h>
-#include <private/qdeclarativeglobal_p.h>
-
-// Define this to do a test dump of all the instructions at startup. This is
-// helpful to test that each instruction's Instr::dump() case uses the correct
-// number of tabs etc and otherwise looks correct.
-// #define DEBUG_INSTR_DUMP
-
-QT_BEGIN_NAMESPACE
-
-DEFINE_BOOL_CONFIG_OPTION(qmlVerboseCompiler, QML_VERBOSE_COMPILER)
-
-namespace QDeclarativeJS {
-
-#ifdef DEBUG_INSTR_DUMP
-static struct DumpInstrAtStartup {
- DumpInstrAtStartup() {
-#define DUMP_INSTR_AT_STARTUP(Type, FMT) { Instr i; i.common.type = Instr::Type; i.dump(0); }
- FOR_EACH_V4_INSTR(DUMP_INSTR_AT_STARTUP);
- }
-} dump_instr_at_startup;
-#endif
-
-int Instr::size() const
-{
-#define V4_RETURN_INSTR_SIZE(I, FMT) case I: return QML_V4_INSTR_SIZE(I, FMT);
- switch (common.type) {
- FOR_EACH_V4_INSTR(V4_RETURN_INSTR_SIZE)
- }
-#undef V4_RETURN_INSTR_SIZE
- return 0;
-}
-
-void Instr::dump(int address) const
-{
- QByteArray leading;
- if (address != -1) {
- leading = QByteArray::number(address);
- leading.prepend(QByteArray(8 - leading.count(), ' '));
- leading.append("\t");
- }
-
-#define INSTR_DUMP qWarning().nospace() << leading.constData()
-
- switch (common.type) {
- case Instr::Noop:
- INSTR_DUMP << "\t" << "Noop";
- break;
- case Instr::BindingId:
- INSTR_DUMP << id.line << ":" << id.column << ":";
- break;
- case Instr::Subscribe:
- INSTR_DUMP << "\t" << "Subscribe" << "\t\t" << "Object_Reg(" << subscribeop.reg << ") Notify_Signal(" << subscribeop.index << ") -> Subscribe_Slot(" << subscribeop.offset << ")";
- break;
- case Instr::SubscribeId:
- INSTR_DUMP << "\t" << "SubscribeId" << "\t\t" << "Id_Offset(" << subscribeop.index << ") -> Subscribe_Slot(" << subscribeop.offset << ")";
- break;
- case Instr::FetchAndSubscribe:
- INSTR_DUMP << "\t" << "FetchAndSubscribe" << "\t" << "Object_Reg(" << fetchAndSubscribe.reg << ") Fast_Accessor(" << fetchAndSubscribe.function << ") -> Output_Reg(" << fetchAndSubscribe.reg << ") Subscription_Slot(" << fetchAndSubscribe.subscription << ")";
- break;
- case Instr::LoadId:
- INSTR_DUMP << "\t" << "LoadId" << "\t\t\t" << "Id_Offset(" << load.index << ") -> Output_Reg(" << load.reg << ")";
- break;
- case Instr::LoadScope:
- INSTR_DUMP << "\t" << "LoadScope" << "\t\t" << "-> Output_Reg(" << load.reg << ")";
- break;
- case Instr::LoadRoot:
- INSTR_DUMP << "\t" << "LoadRoot" << "\t\t" << "-> Output_Reg(" << load.reg << ")";
- break;
- case Instr::LoadAttached:
- INSTR_DUMP << "\t" << "LoadAttached" << "\t\t" << "Object_Reg(" << attached.reg << ") Attached_Index(" << attached.id << ") -> Output_Reg(" << attached.output << ")";
- break;
- case Instr::UnaryNot:
- INSTR_DUMP << "\t" << "UnaryNot" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::UnaryMinusReal:
- INSTR_DUMP << "\t" << "UnaryMinusReal" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::UnaryMinusInt:
- INSTR_DUMP << "\t" << "UnaryMinusInt" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::UnaryPlusReal:
- INSTR_DUMP << "\t" << "UnaryPlusReal" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::UnaryPlusInt:
- INSTR_DUMP << "\t" << "UnaryPlusInt" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::ConvertBoolToInt:
- INSTR_DUMP << "\t" << "ConvertBoolToInt" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::ConvertBoolToReal:
- INSTR_DUMP << "\t" << "ConvertBoolToReal" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::ConvertBoolToString:
- INSTR_DUMP << "\t" << "ConvertBoolToString" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::ConvertIntToBool:
- INSTR_DUMP << "\t" << "ConvertIntToBool" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::ConvertIntToReal:
- INSTR_DUMP << "\t" << "ConvertIntToReal" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::ConvertIntToString:
- INSTR_DUMP << "\t" << "ConvertIntToString" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::ConvertRealToBool:
- INSTR_DUMP << "\t" << "ConvertRealToBool" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::ConvertRealToInt:
- INSTR_DUMP << "\t" << "ConvertRealToInt" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::ConvertRealToString:
- INSTR_DUMP << "\t" << "ConvertRealToString" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::ConvertStringToBool:
- INSTR_DUMP << "\t" << "ConvertStringToBool" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::ConvertStringToInt:
- INSTR_DUMP << "\t" << "ConvertStringToInt" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::ConvertStringToReal:
- INSTR_DUMP << "\t" << "ConvertStringToReal" << "\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::MathSinReal:
- INSTR_DUMP << "\t" << "MathSinReal" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::MathCosReal:
- INSTR_DUMP << "\t" << "MathCosReal" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::MathRoundReal:
- INSTR_DUMP << "\t" << "MathRoundReal" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::MathFloorReal:
- INSTR_DUMP << "\t" << "MathFloorReal" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::MathPIReal:
- INSTR_DUMP << "\t" << "MathPIReal" << "\t\t" << "Input_Reg(" << unaryop.src << ") -> Output_Reg(" << unaryop.output << ")";
- break;
- case Instr::Real:
- INSTR_DUMP << "\t" << "Real" << "\t\t\t" << "Constant(" << real_value.value << ") -> Output_Reg(" << real_value.reg << ")";
- break;
- case Instr::Int:
- INSTR_DUMP << "\t" << "Int" << "\t\t\t" << "Constant(" << int_value.value << ") -> Output_Reg(" << int_value.reg << ")";
- break;
- case Instr::Bool:
- INSTR_DUMP << "\t" << "Bool" << "\t\t\t" << "Constant(" << bool_value.value << ") -> Output_Reg(" << bool_value.reg << ")";
- break;
- case Instr::String:
- INSTR_DUMP << "\t" << "String" << "\t\t\t" << "String_DataIndex(" << string_value.offset << ") String_Length(" << string_value.length << ") -> Output_Register(" << string_value.reg << ")";
- break;
- case Instr::EnableV4Test:
- INSTR_DUMP << "\t" << "EnableV4Test" << "\t\t" << "String_DataIndex(" << string_value.offset << ") String_Length(" << string_value.length << ")";
- break;
- case Instr::TestV4Store:
- INSTR_DUMP << "\t" << "TestV4Store" << "\t\t" << "Input_Reg(" << storetest.reg << ") Reg_Type(" << storetest.regType << ")";
- break;
- case Instr::BitAndInt:
- INSTR_DUMP << "\t" << "BitAndInt" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::BitOrInt:
- INSTR_DUMP << "\t" << "BitOrInt" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::BitXorInt:
- INSTR_DUMP << "\t" << "BitXorInt" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::AddReal:
- INSTR_DUMP << "\t" << "AddReal" << "\t\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::AddString:
- INSTR_DUMP << "\t" << "AddString" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::SubReal:
- INSTR_DUMP << "\t" << "SubReal" << "\t\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::MulReal:
- INSTR_DUMP << "\t" << "MulReal" << "\t\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::DivReal:
- INSTR_DUMP << "\t" << "DivReal" << "\t\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::ModReal:
- INSTR_DUMP << "\t" << "ModReal" << "\t\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::LShiftInt:
- INSTR_DUMP << "\t" << "LShiftInt" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::RShiftInt:
- INSTR_DUMP << "\t" << "RShiftInt" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::URShiftInt:
- INSTR_DUMP << "\t" << "URShiftInt" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::GtReal:
- INSTR_DUMP << "\t" << "GtReal" << "\t\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::LtReal:
- INSTR_DUMP << "\t" << "LtReal" << "\t\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::GeReal:
- INSTR_DUMP << "\t" << "GeReal" << "\t\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::LeReal:
- INSTR_DUMP << "\t" << "LeReal" << "\t\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::EqualReal:
- INSTR_DUMP << "\t" << "EqualReal" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::NotEqualReal:
- INSTR_DUMP << "\t" << "NotEqualReal" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::StrictEqualReal:
- INSTR_DUMP << "\t" << "StrictEqualReal" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::StrictNotEqualReal:
- INSTR_DUMP << "\t" << "StrictNotEqualReal" << "\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::GtString:
- INSTR_DUMP << "\t" << "GtString" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::LtString:
- INSTR_DUMP << "\t" << "LtString" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::GeString:
- INSTR_DUMP << "\t" << "GeString" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::LeString:
- INSTR_DUMP << "\t" << "LeString" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::EqualString:
- INSTR_DUMP << "\t" << "EqualString" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::NotEqualString:
- INSTR_DUMP << "\t" << "NotEqualString" << "\t\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::StrictEqualString:
- INSTR_DUMP << "\t" << "StrictEqualString" << "\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::StrictNotEqualString:
- INSTR_DUMP << "\t" << "StrictNotEqualString" << "\t" << "Input_Reg(" << binaryop.left << ") Input_Reg(" << binaryop.right << ") -> Output_Reg(" << binaryop.output << ")";
- break;
- case Instr::NewString:
- INSTR_DUMP << "\t" << "NewString" << "\t\t" << "Register(" << construct.reg << ")";
- break;
- case Instr::NewUrl:
- INSTR_DUMP << "\t" << "NewUrl" << "\t\t\t" << "Register(" << construct.reg << ")";
- break;
- case Instr::CleanupRegister:
- INSTR_DUMP << "\t" << "CleanupRegister" << "\t\t" << "Register(" << cleanup.reg << ")";
- break;
- case Instr::Fetch:
- INSTR_DUMP << "\t" << "Fetch" << "\t\t\t" << "Object_Reg(" << fetch.reg << ") Property_Index(" << fetch.index << ") -> Output_Reg(" << fetch.reg << ")";
- break;
- case Instr::Store:
- INSTR_DUMP << "\t" << "Store" << "\t\t\t" << "Input_Reg(" << store.reg << ") -> Object_Reg(" << store.output << ") Property_Index(" << store.index << ")";
- break;
- case Instr::Copy:
- INSTR_DUMP << "\t" << "Copy" << "\t\t\t" << "Input_Reg(" << copy.src << ") -> Output_Reg(" << copy.reg << ")";
- break;
- case Instr::Jump:
- if (jump.reg != -1) {
- INSTR_DUMP << "\t" << "Jump" << "\t\t\t" << "Address(" << (address + size() + jump.count) << ") [if false == Input_Reg(" << jump.reg << ")]";
- } else {
- INSTR_DUMP << "\t" << "Jump" << "\t\t\t" << "Address(" << (address + size() + jump.count) << ")";
- }
- break;
- case Instr::BranchFalse:
- INSTR_DUMP << "\t" << "BranchFalse" << "\t\t" << "Address(" << (address + size() + branchop.offset) << ") [if false == Input_Reg(" << branchop.reg << ")]";
- break;
- case Instr::BranchTrue:
- INSTR_DUMP << "\t" << "BranchTrue" << "\t\t" << "Address(" << (address + size() + branchop.offset) << ") [if true == Input_Reg(" << branchop.reg << ")]";
- break;
- case Instr::Branch:
- INSTR_DUMP << "\t" << "Branch" << "\t\t\t" << "Address(" << (address + size() + branchop.offset) << ")";
- break;
- case Instr::InitString:
- INSTR_DUMP << "\t" << "InitString" << "\t\t" << "String_DataIndex(" << initstring.dataIdx << ") -> String_Slot(" << initstring.offset << ")";
- break;
- case Instr::Block:
- INSTR_DUMP << "\t" << "Block" << "\t\t\t" << "Mask(" << QByteArray::number(blockop.block, 16).constData() << ")";
- break;
- default:
- INSTR_DUMP << "\t" << "Unknown";
- break;
- }
-}
-
-void Instr::noop()
-{
- common.type = Noop;
-}
-
-void Instr::load_root(quint8 reg)
-{
- common.type = LoadRoot;
- load.reg = reg;
- load.index = 0;
-}
-
-void Instr::load_scope(quint8 reg)
-{
- common.type = LoadScope;
- load.reg = reg;
- load.index = 0;
-}
-
-void Instr::load_id(quint8 reg, quint32 idIndex)
-{
- common.type = LoadId;
- load.reg = reg;
- load.index = idIndex;
-}
-
-void Instr::subscribe(qint8 reg, quint16 subscribeSlot, quint32 notifyIndex)
-{
- common.type = Instr::Subscribe;
- subscribeop.reg = reg;
- subscribeop.offset = subscribeSlot;
- subscribeop.index = notifyIndex;
-}
-
-void Instr::subscribeId(qint8 reg, quint16 subscribeSlot, quint32 idIndex)
-{
- common.type = Instr::SubscribeId;
- subscribeop.reg = reg;
- subscribeop.offset = subscribeSlot;
- subscribeop.index = idIndex;
-}
-
-void Instr::move_reg_bool(quint8 reg, bool value)
-{
- common.type = Bool;
- bool_value.reg = reg;
- bool_value.value = value;
-}
-
-void Instr::move_reg_int(quint8 reg, int value)
-{
- common.type = Int;
- int_value.reg = reg;
- int_value.value = value;
-}
-
-void Instr::move_reg_qreal(quint8 reg, qreal value)
-{
- common.type = Real;
- real_value.reg = reg;
- real_value.value = value;
-}
-
-void Instr::move_reg_reg(quint8 reg, quint8 src)
-{
- common.type = Copy;
- copy.reg = reg;
- copy.src = src;
-}
-
-void Instr::unary_not(quint8 dest, quint8 src)
-{
- common.type = UnaryNot;
- unaryop.src = src;
- unaryop.output = dest;
-}
-
-void Instr::uminus_real(quint8 dest, quint8 src)
-{
- common.type = UnaryMinusReal;
- unaryop.src = src;
- unaryop.output = dest;
-}
-
-void Instr::uminus_int(quint8 dest, quint8 src)
-{
- common.type = UnaryMinusInt;
- unaryop.src = src;
- unaryop.output = dest;
-}
-
-void Instr::uplus_real(quint8 dest, quint8 src)
-{
- common.type = UnaryPlusReal;
- unaryop.src = src;
- unaryop.output = dest;
-}
-
-void Instr::uplus_int(quint8 dest, quint8 src)
-{
- common.type = UnaryPlusInt;
- unaryop.src = src;
- unaryop.output = dest;
-}
-
-void Instr::ucompl_real(quint8 dest, quint8 src)
-{
- Q_UNUSED(dest);
- Q_UNUSED(src);
- if (qmlVerboseCompiler())
- qWarning() << "TODO" << Q_FUNC_INFO;
-}
-
-void Instr::ucompl_int(quint8 dest, quint8 src)
-{
- Q_UNUSED(dest);
- Q_UNUSED(src);
- if (qmlVerboseCompiler())
- qWarning() << "TODO" << Q_FUNC_INFO;
-}
-
-void Instr::math_sin_real(quint8 reg)
-{
- common.type = MathSinReal;
- unaryop.src = reg;
- unaryop.output = reg;
-}
-
-void Instr::math_cos_real(quint8 reg)
-{
- common.type = MathCosReal;
- unaryop.src = reg;
- unaryop.output = reg;
-}
-
-void Instr::math_round_real(quint8 reg)
-{
- common.type = MathRoundReal;
- unaryop.src = reg;
- unaryop.output = reg;
-}
-
-void Instr::math_floor_real(quint8 reg)
-{
- common.type = MathFloorReal;
- unaryop.src = reg;
- unaryop.output = reg;
-}
-
-void Instr::math_pi_real(quint8 reg)
-{
- common.type = MathPIReal;
- unaryop.src = reg;
- unaryop.output = reg;
-}
-
-void Instr::branch_true(quint8 reg, qint16 offset)
-{
- common.type = BranchTrue;
- branchop.reg = reg;
- branchop.offset = offset;
-}
-
-void Instr::branch_false(quint8 reg, qint16 offset)
-{
- common.type = BranchFalse;
- branchop.reg = reg;
- branchop.offset = offset;
-}
-
-void Instr::branch(qint16 offset)
-{
- common.type = Branch;
- branchop.offset = offset;
-}
-
-void Instr::block(quint32 mask)
-{
- common.type = Block;
- blockop.block = mask;
-}
-
-Bytecode::Bytecode()
-{
-#ifdef QML_THREADED_INTERPRETER
- decodeInstr = QDeclarativeV4Bindings::getDecodeInstrTable();
-#endif
-}
-
-void Bytecode::append(const Instr &instr)
-{
- const char *it;
-#ifdef QML_THREADED_INTERPRETER
- Instr i = instr;
- i.common.code = decodeInstr[i.common.type];
- it = (const char *) &i;
-#else
- it = (const char *) &instr;
-#endif
- d.append(it, instr.size());
-}
-
-int Bytecode::remove(int offset)
-{
- const Instr *instr = (const Instr *) (d.begin() + offset);
- const int instrSize = instr->size();
- d.remove(offset, instrSize);
- return instrSize;
-}
-
-const Instr &Bytecode::operator[](int offset) const
-{
- return *((const Instr *) (d.begin() + offset));
-}
-
-Instr &Bytecode::operator[](int offset)
-{
- return *((Instr *) (d.begin() + offset));
-}
-
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/qml/v4/qdeclarativev4bindings.cpp b/src/declarative/qml/v4/qv4bindings.cpp
index 20d79dc46d..2e8a360f36 100644
--- a/src/declarative/qml/v4/qdeclarativev4bindings.cpp
+++ b/src/declarative/qml/v4/qv4bindings.cpp
@@ -41,10 +41,10 @@
// #define REGISTER_CLEANUP_DEBUG
-#include "private/qdeclarativev4bindings_p.h"
-#include "private/qdeclarativev4program_p.h"
-#include "private/qdeclarativev4compiler_p.h"
-#include "private/qdeclarativev4compiler_p_p.h"
+#include "qv4bindings_p.h"
+#include "qv4program_p.h"
+#include "qv4compiler_p.h"
+#include "qv4compiler_p_p.h"
#include <private/qdeclarativefastproperties_p.h>
#include <private/qdeclarativedebugtrace_p.h>
@@ -187,123 +187,47 @@ void Register::init(Type type)
} // end of anonymous namespace
-class QDeclarativeV4BindingsPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QDeclarativeV4Bindings)
-
-public:
- QDeclarativeV4BindingsPrivate();
- virtual ~QDeclarativeV4BindingsPrivate();
-
- struct Binding : public QDeclarativeAbstractBinding, public QDeclarativeDelayedError {
- Binding() : enabled(false), updating(0), property(0),
- scope(0), target(0), executedBlocks(0), parent(0) {}
-
- // Inherited from QDeclarativeAbstractBinding
- virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags flags);
- virtual void update(QDeclarativePropertyPrivate::WriteFlags flags);
- virtual void destroy();
-
- int index:30;
- bool enabled:1;
- bool updating:1;
- int property;
- QObject *scope;
- QObject *target;
- quint32 executedBlocks;
-
- QDeclarativeV4BindingsPrivate *parent;
- };
-
- typedef QDeclarativeNotifierEndpoint Subscription;
- Subscription *subscriptions;
-
- void run(Binding *, QDeclarativePropertyPrivate::WriteFlags flags);
-
- QDeclarativeV4Program *program;
- QDeclarativeRefCount *dataRef;
- Binding *bindings;
-
- static int methodCount;
-
- void init();
- void run(int instr, quint32 &executedBlocks, QDeclarativeContextData *context,
- QDeclarativeDelayedError *error, QObject *scope, QObject *output,
- QDeclarativePropertyPrivate::WriteFlags storeFlags
-#ifdef QML_THREADED_INTERPRETER
- , void ***decode_instr = 0
-#endif
- );
-
-
- inline void unsubscribe(int subIndex);
- inline void subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex);
- inline void subscribe(QObject *o, int notifyIndex, int subIndex);
-
- inline static qint32 toInt32(qreal n);
- static const qreal D32;
- static quint32 toUint32(qreal n);
-};
-
-QDeclarativeV4BindingsPrivate::QDeclarativeV4BindingsPrivate()
+QV4Bindings::QV4Bindings(const char *programData,
+ QDeclarativeContextData *context,
+ QDeclarativeRefCount *ref)
: subscriptions(0), program(0), dataRef(0), bindings(0)
{
-}
-
-QDeclarativeV4BindingsPrivate::~QDeclarativeV4BindingsPrivate()
-{
- delete [] subscriptions; subscriptions = 0;
- if (dataRef) dataRef->release();
-}
-
-int QDeclarativeV4BindingsPrivate::methodCount = -1;
-
-QDeclarativeV4Bindings::QDeclarativeV4Bindings(const char *program, QDeclarativeContextData *context,
- QDeclarativeRefCount *dataRef)
-: QObject(*(new QDeclarativeV4BindingsPrivate))
-{
- Q_D(QDeclarativeV4Bindings);
-
- if (d->methodCount == -1)
- d->methodCount = QDeclarativeV4Bindings::staticMetaObject.methodCount();
-
- d->program = (QDeclarativeV4Program *)program;
- d->dataRef = dataRef;
+ program = (QV4Program *)programData;
+ dataRef = ref;
if (dataRef) dataRef->addref();
if (program) {
- d->init();
+ subscriptions = new Subscription[program->subscriptions];
+ bindings = new Binding[program->bindings];
QDeclarativeAbstractExpression::setContext(context);
}
}
-QDeclarativeV4Bindings::~QDeclarativeV4Bindings()
+QV4Bindings::~QV4Bindings()
{
- Q_D(QDeclarativeV4Bindings);
-
- delete [] d->bindings;
+ delete [] bindings;
+ delete [] subscriptions; subscriptions = 0;
+ if (dataRef) dataRef->release();
}
-QDeclarativeAbstractBinding *QDeclarativeV4Bindings::configBinding(int index, QObject *target,
- QObject *scope, int property)
+QDeclarativeAbstractBinding *QV4Bindings::configBinding(int index, QObject *target,
+ QObject *scope, int property)
{
- Q_D(QDeclarativeV4Bindings);
-
- QDeclarativeV4BindingsPrivate::Binding *rv = d->bindings + index;
+ Binding *rv = bindings + index;
rv->index = index;
rv->property = property;
rv->target = target;
rv->scope = scope;
- rv->parent = d;
+ rv->parent = this;
addref(); // This is decremented in Binding::destroy()
return rv;
}
-void QDeclarativeV4BindingsPrivate::Binding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags)
+void QV4Bindings::Binding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags)
{
if (enabled != e) {
enabled = e;
@@ -312,50 +236,47 @@ void QDeclarativeV4BindingsPrivate::Binding::setEnabled(bool e, QDeclarativeProp
}
}
-void QDeclarativeV4BindingsPrivate::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags)
+void QV4Bindings::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags)
{
QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Binding);
parent->run(this, flags);
QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Binding);
}
-void QDeclarativeV4BindingsPrivate::Binding::destroy()
+void QV4Bindings::Binding::destroy()
{
enabled = false;
removeFromObject();
clear();
removeError();
- parent->q_func()->release();
+ parent->release();
}
-int QDeclarativeV4Bindings::qt_metacall(QMetaObject::Call c, int id, void **)
+void QV4Bindings::Subscription::subscriptionCallback(QDeclarativeNotifierEndpoint *e)
{
- Q_D(QDeclarativeV4Bindings);
-
- if (c == QMetaObject::InvokeMetaMethod && id >= d->methodCount) {
- id -= d->methodCount;
+ Subscription *s = static_cast<Subscription *>(e);
+ s->bindings->subscriptionNotify(s->method);
+}
- QDeclarativeV4Program::BindingReferenceList *list = d->program->signalTable(id);
+void QV4Bindings::subscriptionNotify(int id)
+{
+ QV4Program::BindingReferenceList *list = program->signalTable(id);
- for (quint32 ii = 0; ii < list->count; ++ii) {
- QDeclarativeV4Program::BindingReference *bindingRef = list->bindings + ii;
+ for (quint32 ii = 0; ii < list->count; ++ii) {
+ QV4Program::BindingReference *bindingRef = list->bindings + ii;
- QDeclarativeV4BindingsPrivate::Binding *binding = d->bindings + bindingRef->binding;
- if (binding->executedBlocks & bindingRef->blockMask)
- d->run(binding, QDeclarativePropertyPrivate::DontRemoveBinding);
- }
+ Binding *binding = bindings + bindingRef->binding;
+ if (binding->executedBlocks & bindingRef->blockMask)
+ run(binding, QDeclarativePropertyPrivate::DontRemoveBinding);
}
- return -1;
}
-void QDeclarativeV4BindingsPrivate::run(Binding *binding, QDeclarativePropertyPrivate::WriteFlags flags)
+void QV4Bindings::run(Binding *binding, QDeclarativePropertyPrivate::WriteFlags flags)
{
- Q_Q(QDeclarativeV4Bindings);
-
if (!binding->enabled)
return;
- QDeclarativeContextData *context = q->QDeclarativeAbstractExpression::context();
+ QDeclarativeContextData *context = QDeclarativeAbstractExpression::context();
if (!context || !context->isValid())
return;
@@ -373,7 +294,7 @@ void QDeclarativeV4BindingsPrivate::run(Binding *binding, QDeclarativePropertyPr
} else {
name = QLatin1String(binding->target->metaObject()->property(binding->property).name());
}
- qmlInfo(binding->target) << QCoreApplication::translate("QDeclarativeV4Bindings", "Binding loop detected for property \"%1\"").arg(name);
+ qmlInfo(binding->target) << tr("Binding loop detected for property \"%1\"").arg(name);
return;
}
@@ -396,33 +317,29 @@ void QDeclarativeV4BindingsPrivate::run(Binding *binding, QDeclarativePropertyPr
}
-void QDeclarativeV4BindingsPrivate::unsubscribe(int subIndex)
+void QV4Bindings::unsubscribe(int subIndex)
{
- QDeclarativeV4BindingsPrivate::Subscription *sub = (subscriptions + subIndex);
+ Subscription *sub = (subscriptions + subIndex);
sub->disconnect();
}
-void QDeclarativeV4BindingsPrivate::subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex)
+void QV4Bindings::subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex)
{
- Q_Q(QDeclarativeV4Bindings);
-
unsubscribe(subIndex);
if (p->idValues[idIndex]) {
- QDeclarativeV4BindingsPrivate::Subscription *sub = (subscriptions + subIndex);
- sub->target = q;
- sub->targetMethod = methodCount + subIndex;
+ Subscription *sub = (subscriptions + subIndex);
+ sub->bindings = this;
+ sub->method = subIndex;
sub->connect(&p->idValues[idIndex].bindings);
}
}
-void QDeclarativeV4BindingsPrivate::subscribe(QObject *o, int notifyIndex, int subIndex)
+void QV4Bindings::subscribe(QObject *o, int notifyIndex, int subIndex)
{
- Q_Q(QDeclarativeV4Bindings);
-
- QDeclarativeV4BindingsPrivate::Subscription *sub = (subscriptions + subIndex);
- sub->target = q;
- sub->targetMethod = methodCount + subIndex;
+ Subscription *sub = (subscriptions + subIndex);
+ sub->bindings = this;
+ sub->method = subIndex;
if (o)
sub->connect(o, notifyIndex);
else
@@ -507,14 +424,6 @@ inline static QUrl toUrl(Register *reg, int type, QDeclarativeContextData *conte
return base;
}
-void QDeclarativeV4BindingsPrivate::init()
-{
- if (program->subscriptions)
- subscriptions = new QDeclarativeV4BindingsPrivate::Subscription[program->subscriptions];
-
- bindings = new QDeclarativeV4BindingsPrivate::Binding[program->bindings];
-}
-
static bool testCompareVariants(const QVariant &qtscriptRaw, const QVariant &v4)
{
QVariant qtscript = qtscriptRaw;
@@ -635,7 +544,7 @@ static void testBindingResult(const QString &binding, int line, int column,
iserror = true;
if (iserror) {
- qWarning().nospace() << "QDeclarativeV4: Optimization error @" << context->url.toString().toUtf8().constData() << ":" << line << ":" << column;
+ qWarning().nospace() << "QV4: Optimization error @" << context->url.toString().toUtf8().constData() << ":" << line << ":" << column;
qWarning().nospace() << " Binding: " << binding;
qWarning().nospace() << " QtScript: " << qtscriptResult.constData();
@@ -652,7 +561,7 @@ static void testBindingException(const QString &binding, int line, int column,
if (!expression.hasError()) {
QByteArray qtscriptResult = testResultToString(value, isUndefined);
- qWarning().nospace() << "QDeclarativeV4: Optimization error @" << context->url.toString().toUtf8().constData() << ":" << line << ":" << column;
+ qWarning().nospace() << "QV4: Optimization error @" << context->url.toString().toUtf8().constData() << ":" << line << ":" << column;
qWarning().nospace() << " Binding: " << binding;
qWarning().nospace() << " QtScript: " << qtscriptResult.constData();
qWarning().nospace() << " V4: exception";
@@ -660,7 +569,7 @@ static void testBindingException(const QString &binding, int line, int column,
}
static void throwException(int id, QDeclarativeDelayedError *error,
- QDeclarativeV4Program *program, QDeclarativeContextData *context,
+ QV4Program *program, QDeclarativeContextData *context,
const QString &description = QString())
{
error->error.setUrl(context->url);
@@ -680,9 +589,9 @@ static void throwException(int id, QDeclarativeDelayedError *error,
QDeclarativeEnginePrivate::warning(context->engine, error->error);
}
-const qreal QDeclarativeV4BindingsPrivate::D32 = 4294967296.0;
+const qreal QV4Bindings::D32 = 4294967296.0;
-qint32 QDeclarativeV4BindingsPrivate::toInt32(qreal n)
+qint32 QV4Bindings::toInt32(qreal n)
{
if (qIsNaN(n) || qIsInf(n) || (n == 0))
return 0;
@@ -702,7 +611,7 @@ qint32 QDeclarativeV4BindingsPrivate::toInt32(qreal n)
return qint32 (n);
}
-inline quint32 QDeclarativeV4BindingsPrivate::toUint32(qreal n)
+inline quint32 QV4Bindings::toUint32(qreal n)
{
if (qIsNaN(n) || qIsInf(n) || (n == 0))
return 0;
@@ -745,28 +654,30 @@ inline quint32 QDeclarativeV4BindingsPrivate::toUint32(qreal n)
}
#ifdef QML_THREADED_INTERPRETER
-void **QDeclarativeV4Bindings::getDecodeInstrTable()
+void **QV4Bindings::getDecodeInstrTable()
{
static void **decode_instr;
if (!decode_instr) {
- QDeclarativeV4Bindings dummy(0, 0, 0);
+ QV4Bindings *dummy = new QV4Bindings(0, 0, 0);
quint32 executedBlocks = 0;
- dummy.d_func()->run(0, executedBlocks, 0, 0, 0, 0, QDeclarativePropertyPrivate::BypassInterceptor, &decode_instr);
+ dummy->run(0, executedBlocks, 0, 0, 0, 0,
+ QDeclarativePropertyPrivate::BypassInterceptor,
+ &decode_instr);
+ dummy->release();
}
return decode_instr;
}
#endif
-void QDeclarativeV4BindingsPrivate::run(int instrIndex, quint32 &executedBlocks,
- QDeclarativeContextData *context, QDeclarativeDelayedError *error,
- QObject *scope, QObject *output, QDeclarativePropertyPrivate::WriteFlags storeFlags
+void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
+ QDeclarativeContextData *context, QDeclarativeDelayedError *error,
+ QObject *scope, QObject *output,
+ QDeclarativePropertyPrivate::WriteFlags storeFlags
#ifdef QML_THREADED_INTERPRETER
- ,void ***table
+ ,void ***table
#endif
- )
+ )
{
- Q_Q(QDeclarativeV4Bindings);
-
#ifdef QML_THREADED_INTERPRETER
if (table) {
static void *decode_instr[] = {
@@ -786,10 +697,9 @@ void QDeclarativeV4BindingsPrivate::run(int instrIndex, quint32 &executedBlocks,
executedBlocks = 0;
- QDeclarativeEnginePrivate *engine = QDeclarativeEnginePrivate::get(context->engine);
const char *code = program->instructions();
code += instrIndex * QML_V4_INSTR_SIZE(Jump, jump);
- const Instr *instr = (const Instr *) code;
+ const V4Instr *instr = reinterpret_cast<const V4Instr *>(code);
const char *data = program->data();
@@ -838,11 +748,11 @@ void QDeclarativeV4BindingsPrivate::run(int instrIndex, quint32 &executedBlocks,
reg.setUndefined();
} else {
int subIdx = instr->fetchAndSubscribe.subscription;
- QDeclarativeV4BindingsPrivate::Subscription *sub = 0;
+ Subscription *sub = 0;
if (subIdx != -1) {
sub = (subscriptions + subIdx);
- sub->target = q;
- sub->targetMethod = methodCount + subIdx;
+ sub->bindings = this;
+ sub->method = subIdx;
}
reg.init((Register::Type)instr->fetchAndSubscribe.valueType);
if (instr->fetchAndSubscribe.valueType >= FirstCleanupType)
@@ -1110,26 +1020,26 @@ void QDeclarativeV4BindingsPrivate::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(MathPIReal, unaryop)
- QML_V4_BEGIN_INSTR(Real, real_value)
+ QML_V4_BEGIN_INSTR(LoadReal, real_value)
registers[instr->real_value.reg].setqreal(instr->real_value.value);
- QML_V4_END_INSTR(Real, real_value)
+ QML_V4_END_INSTR(LoadReal, real_value)
- QML_V4_BEGIN_INSTR(Int, int_value)
+ QML_V4_BEGIN_INSTR(LoadInt, int_value)
registers[instr->int_value.reg].setint(instr->int_value.value);
- QML_V4_END_INSTR(Int, int_value)
+ QML_V4_END_INSTR(LoadInt, int_value)
- QML_V4_BEGIN_INSTR(Bool, bool_value)
+ QML_V4_BEGIN_INSTR(LoadBool, bool_value)
registers[instr->bool_value.reg].setbool(instr->bool_value.value);
- QML_V4_END_INSTR(Bool, bool_value)
+ QML_V4_END_INSTR(LoadBool, bool_value)
- QML_V4_BEGIN_INSTR(String, string_value)
+ QML_V4_BEGIN_INSTR(LoadString, string_value)
{
Register &output = registers[instr->string_value.reg];
QChar *string = (QChar *)(data + instr->string_value.offset);
new (output.getstringptr()) QString(string, instr->string_value.length);
STRING_REGISTER(instr->string_value.reg);
}
- QML_V4_END_INSTR(String, string_value)
+ QML_V4_END_INSTR(LoadString, string_value)
QML_V4_BEGIN_INSTR(EnableV4Test, string_value)
{
@@ -1501,7 +1411,7 @@ void QDeclarativeV4BindingsPrivate::run(int instrIndex, quint32 &executedBlocks,
// nothing to do
#else
default:
- qFatal("QDeclarativeV4: Unknown instruction %d encountered.", instr->common.type);
+ qFatal("QV4: Unknown instruction %d encountered.", instr->common.type);
break;
} // switch
diff --git a/src/declarative/qml/v4/qv4bindings_p.h b/src/declarative/qml/v4/qv4bindings_p.h
new file mode 100644
index 0000000000..603d05d899
--- /dev/null
+++ b/src/declarative/qml/v4/qv4bindings_p.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QV4BINDINGS_P_H
+#define QV4BINDINGS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qdeclarativeexpression_p.h"
+#include "private/qdeclarativebinding_p.h"
+#include "private/qv4instruction_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QV4Program;
+class QV4Bindings : public QDeclarativeAbstractExpression,
+ public QDeclarativeRefCount
+{
+ Q_DECLARE_TR_FUNCTIONS(QV4Bindings)
+public:
+ QV4Bindings(const char *program, QDeclarativeContextData *context,
+ QDeclarativeRefCount *);
+ virtual ~QV4Bindings();
+
+ QDeclarativeAbstractBinding *configBinding(int index, QObject *target,
+ QObject *scope, int property);
+
+#ifdef QML_THREADED_INTERPRETER
+ static void **getDecodeInstrTable();
+#endif
+
+private:
+ Q_DISABLE_COPY(QV4Bindings)
+
+ struct Binding : public QDeclarativeAbstractBinding, public QDeclarativeDelayedError {
+ Binding() : enabled(false), updating(0), property(0),
+ scope(0), target(0), executedBlocks(0), parent(0) {}
+
+ // Inherited from QDeclarativeAbstractBinding
+ virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags flags);
+ virtual void update(QDeclarativePropertyPrivate::WriteFlags flags);
+ virtual void destroy();
+
+ int index:30;
+ bool enabled:1;
+ bool updating:1;
+ int property;
+ QObject *scope;
+ QObject *target;
+ quint32 executedBlocks;
+
+ QV4Bindings *parent;
+ };
+
+ class Subscription : public QDeclarativeNotifierEndpoint
+ {
+ public:
+ Subscription() : bindings(0), method(-1) { callback = &subscriptionCallback; }
+ static void subscriptionCallback(QDeclarativeNotifierEndpoint *e);
+ QV4Bindings *bindings;
+ int method;
+ };
+ friend class Subscription;
+
+ Subscription *subscriptions;
+
+ void subscriptionNotify(int);
+ void run(Binding *, QDeclarativePropertyPrivate::WriteFlags flags);
+
+ QV4Program *program;
+ QDeclarativeRefCount *dataRef;
+ Binding *bindings;
+
+ void init();
+ void run(int instr, quint32 &executedBlocks, QDeclarativeContextData *context,
+ QDeclarativeDelayedError *error, QObject *scope, QObject *output,
+ QDeclarativePropertyPrivate::WriteFlags storeFlags
+#ifdef QML_THREADED_INTERPRETER
+ , void ***decode_instr = 0
+#endif
+ );
+
+
+ inline void unsubscribe(int subIndex);
+ inline void subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex);
+ inline void subscribe(QObject *o, int notifyIndex, int subIndex);
+
+ inline static qint32 toInt32(qreal n);
+ static const qreal D32;
+ static quint32 toUint32(qreal n);
+
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QV4BINDINGS_P_H
+
diff --git a/src/declarative/qml/v4/qdeclarativev4compiler.cpp b/src/declarative/qml/v4/qv4compiler.cpp
index fa4cd25952..ba739a9aab 100644
--- a/src/declarative/qml/v4/qdeclarativev4compiler.cpp
+++ b/src/declarative/qml/v4/qv4compiler.cpp
@@ -39,11 +39,11 @@
**
****************************************************************************/
-#include "qdeclarativev4compiler_p.h"
-#include "qdeclarativev4compiler_p_p.h"
-#include "qdeclarativev4program_p.h"
-#include "qdeclarativev4ir_p.h"
-#include "qdeclarativev4irbuilder_p.h"
+#include "qv4compiler_p.h"
+#include "qv4compiler_p_p.h"
+#include "qv4program_p.h"
+#include "qv4ir_p.h"
+#include "qv4irbuilder_p.h"
#include <private/qdeclarativejsast_p.h>
#include <private/qdeclarativefastproperties_p.h>
@@ -61,7 +61,7 @@ DEFINE_BOOL_CONFIG_OPTION(qmlBindingsTestEnv, QML_BINDINGS_TEST)
static bool qmlBindingsTest = false;
using namespace QDeclarativeJS;
-QDeclarativeV4CompilerPrivate::QDeclarativeV4CompilerPrivate()
+QV4CompilerPrivate::QV4CompilerPrivate()
: _function(0) , _block(0) , _discarded(false)
{
}
@@ -69,7 +69,7 @@ QDeclarativeV4CompilerPrivate::QDeclarativeV4CompilerPrivate()
//
// tracing
//
-void QDeclarativeV4CompilerPrivate::trace(int line, int column)
+void QV4CompilerPrivate::trace(int line, int column)
{
bytecode.clear();
@@ -106,10 +106,9 @@ void QDeclarativeV4CompilerPrivate::trace(int line, int column)
if (bytecode.isEmpty()) {
if (qmlBindingsTest || bindingsDump()) {
- Instr id;
- id.common.type = Instr::BindingId;
- id.id.column = column;
- id.id.line = line;
+ Instr::BindingId id;
+ id.column = column;
+ id.line = line;
gen(id);
}
@@ -119,11 +118,10 @@ void QDeclarativeV4CompilerPrivate::trace(int line, int column)
int offset = data.count();
data += strdata;
- Instr test;
- test.common.type = Instr::EnableV4Test;
- test.string_value.reg = 0;
- test.string_value.offset = offset;
- test.string_value.length = str.length();
+ Instr::EnableV4Test test;
+ test.reg = 0;
+ test.offset = offset;
+ test.length = str.length();
gen(test);
}
}
@@ -133,8 +131,8 @@ void QDeclarativeV4CompilerPrivate::trace(int line, int column)
qSwap(usedSubscriptionIdsChanged, usic);
int blockopIndex = bytecode.size();
- Instr blockop;
- blockop.block(currentBlockMask);
+ Instr::Block blockop;
+ blockop.block = currentBlockMask;
gen(blockop);
foreach (IR::Stmt *s, block->statements) {
@@ -169,15 +167,16 @@ void QDeclarativeV4CompilerPrivate::trace(int line, int column)
if (! _discarded) {
// back patching
foreach (const Patch &patch, patches) {
- Instr &instr = bytecode[patch.offset];
- instr.branchop.offset = patch.block->offset - patch.offset - instr.size();
+ V4Instr &instr = bytecode[patch.offset];
+ int size = V4Instr::size(instructionType(&instr));
+ instr.branchop.offset = patch.block->offset - patch.offset - size;
}
patches.clear();
}
}
-void QDeclarativeV4CompilerPrivate::trace(QVector<IR::BasicBlock *> *blocks)
+void QV4CompilerPrivate::trace(QVector<IR::BasicBlock *> *blocks)
{
for (int i = 0; i < _function->basicBlocks.size(); ++i) {
IR::BasicBlock *block = _function->basicBlocks.at(i);
@@ -195,7 +194,7 @@ void QDeclarativeV4CompilerPrivate::trace(QVector<IR::BasicBlock *> *blocks)
}
}
-void QDeclarativeV4CompilerPrivate::traceExpression(IR::Expr *e, quint8 r)
+void QV4CompilerPrivate::traceExpression(IR::Expr *e, quint8 r)
{
if (!e) {
discard();
@@ -209,24 +208,29 @@ void QDeclarativeV4CompilerPrivate::traceExpression(IR::Expr *e, quint8 r)
//
// expressions
//
-void QDeclarativeV4CompilerPrivate::visitConst(IR::Const *e)
+void QV4CompilerPrivate::visitConst(IR::Const *e)
{
- Instr i;
switch (e->type) {
- case IR::BoolType:
- i.move_reg_bool(currentReg, e->value);
+ case IR::BoolType: {
+ Instr::LoadBool i;
+ i.reg = currentReg;
+ i.value = e->value;
gen(i);
- break;
+ } break;
- case IR::IntType:
- i.move_reg_int(currentReg, e->value);
+ case IR::IntType: {
+ Instr::LoadInt i;
+ i.reg = currentReg;
+ i.value = e->value;
gen(i);
- break;
+ } break;
- case IR::RealType:
- i.move_reg_qreal(currentReg, e->value);
+ case IR::RealType: {
+ Instr::LoadReal i;
+ i.reg = currentReg;
+ i.value = e->value;
gen(i);
- break;
+ } break;
default:
if (qmlVerboseCompiler())
@@ -235,12 +239,12 @@ void QDeclarativeV4CompilerPrivate::visitConst(IR::Const *e)
}
}
-void QDeclarativeV4CompilerPrivate::visitString(IR::String *e)
+void QV4CompilerPrivate::visitString(IR::String *e)
{
registerLiteralString(currentReg, e->value);
}
-void QDeclarativeV4CompilerPrivate::visitName(IR::Name *e)
+void QV4CompilerPrivate::visitName(IR::Name *e)
{
if (e->base) {
// fetch the object and store it in reg.
@@ -251,8 +255,8 @@ void QDeclarativeV4CompilerPrivate::visitName(IR::Name *e)
if (e->storage == IR::Name::RootStorage) {
- Instr instr;
- instr.load_root(currentReg);
+ Instr::LoadRoot instr;
+ instr.reg = currentReg;
gen(instr);
if (e->symbol == IR::Name::IdObject) {
@@ -262,23 +266,26 @@ void QDeclarativeV4CompilerPrivate::visitName(IR::Name *e)
} else if (e->storage == IR::Name::ScopeStorage) {
- Instr instr;
- instr.load_scope(currentReg);
+ Instr::LoadScope instr;
+ instr.reg = currentReg;
gen(instr);
_subscribeName << contextName();
} else if (e->storage == IR::Name::IdStorage) {
- Instr instr;
- instr.load_id(currentReg, e->index);
+ Instr::LoadId instr;
+ instr.reg = currentReg;
+ instr.index = e->index;
gen(instr);
_subscribeName << QLatin1String("$$$ID_") + *e->id;
if (blockNeedsSubscription(_subscribeName)) {
- Instr sub;
- sub.subscribeId(currentReg, subscriptionIndex(_subscribeName), instr.load.index);
+ Instr::SubscribeId sub;
+ sub.reg = currentReg;
+ sub.offset = subscriptionIndex(_subscribeName);
+ sub.index = instr.index;
gen(sub);
}
@@ -299,13 +306,12 @@ void QDeclarativeV4CompilerPrivate::visitName(IR::Name *e)
case IR::Name::AttachType: {
_subscribeName << *e->id;
- Instr attached;
- attached.common.type = Instr::LoadAttached;
- attached.attached.output = currentReg;
- attached.attached.reg = currentReg;
- attached.attached.exceptionId = exceptionId(e->line, e->column);
+ Instr::LoadAttached attached;
+ attached.output = currentReg;
+ attached.reg = currentReg;
+ attached.exceptionId = exceptionId(e->line, e->column);
Q_ASSERT(e->declarativeType->attachedPropertiesId() != -1);
- attached.attached.id = e->declarativeType->attachedPropertiesId();
+ attached.id = e->declarativeType->attachedPropertiesId();
gen(attached);
} break;
@@ -349,48 +355,47 @@ void QDeclarativeV4CompilerPrivate::visitName(IR::Name *e)
break;
} // switch
- Instr fetch;
-
if (fastFetchIndex != -1) {
- fetch.common.type = Instr::FetchAndSubscribe;
- fetch.fetchAndSubscribe.reg = currentReg;
- fetch.fetchAndSubscribe.function = fastFetchIndex;
- fetch.fetchAndSubscribe.subscription = subscriptionIndex(_subscribeName);
- fetch.fetchAndSubscribe.exceptionId = exceptionId(e->line, e->column);
- fetch.fetchAndSubscribe.valueType = regType;
+ Instr::FetchAndSubscribe fetch;
+ fetch.reg = currentReg;
+ fetch.function = fastFetchIndex;
+ fetch.subscription = subscriptionIndex(_subscribeName);
+ fetch.exceptionId = exceptionId(e->line, e->column);
+ fetch.valueType = regType;
+ gen(fetch);
} else {
if (blockNeedsSubscription(_subscribeName) && prop.hasNotifySignal() && prop.notifySignalIndex() != -1) {
- Instr sub;
- sub.subscribe(currentReg, subscriptionIndex(_subscribeName), prop.notifySignalIndex());
+ Instr::Subscribe sub;
+ sub.reg = currentReg;
+ sub.offset = subscriptionIndex(_subscribeName);
+ sub.index = prop.notifySignalIndex();
gen(sub);
}
- fetch.common.type = Instr::Fetch;
- fetch.fetch.reg = currentReg;
- fetch.fetch.index = e->index;
- fetch.fetch.exceptionId = exceptionId(e->line, e->column);
- fetch.fetch.valueType = regType;
+ Instr::Fetch fetch;
+ fetch.reg = currentReg;
+ fetch.index = e->index;
+ fetch.exceptionId = exceptionId(e->line, e->column);
+ fetch.valueType = regType;
+ gen(fetch);
}
- gen(fetch);
-
} break;
} // switch
}
-void QDeclarativeV4CompilerPrivate::visitTemp(IR::Temp *e)
+void QV4CompilerPrivate::visitTemp(IR::Temp *e)
{
if (currentReg != e->index) {
- Instr i;
- i.move_reg_reg(currentReg, e->index);
+ Instr::Copy i;
+ i.reg = currentReg;
+ i.src = e->index;
gen(i);
}
}
-void QDeclarativeV4CompilerPrivate::visitUnop(IR::Unop *e)
+void QV4CompilerPrivate::visitUnop(IR::Unop *e)
{
- Instr i;
-
quint8 src = currentReg;
if (IR::Temp *temp = e->expr->asTemp()) {
@@ -407,24 +412,32 @@ void QDeclarativeV4CompilerPrivate::visitUnop(IR::Unop *e)
case IR::OpIfTrue:
convertToBool(e->expr, src);
if (src != currentReg) {
- i.move_reg_reg(currentReg, src);
+ Instr::Copy i;
+ i.reg = currentReg;
+ i.src = src;
gen(i);
}
break;
- case IR::OpNot:
+ case IR::OpNot: {
+ Instr::UnaryNot i;
convertToBool(e->expr, src);
- i.unary_not(currentReg, src);
+ i.output = currentReg;
+ i.src = src;
gen(i);
- break;
+ } break;
case IR::OpUMinus:
if (e->expr->type == IR::RealType) {
- i.uminus_real(currentReg, src);
+ Instr::UnaryMinusReal i;
+ i.output = currentReg;
+ i.src = src;
gen(i);
} else if (e->expr->type == IR::IntType) {
convertToReal(e->expr, currentReg);
- i.uminus_real(currentReg, src);
+ Instr::UnaryMinusReal i;
+ i.output = currentReg;
+ i.src = src;
gen(i);
} else {
discard();
@@ -433,11 +446,15 @@ void QDeclarativeV4CompilerPrivate::visitUnop(IR::Unop *e)
case IR::OpUPlus:
if (e->expr->type == IR::RealType) {
- i.uplus_real(currentReg, src);
+ Instr::UnaryPlusReal i;
+ i.output = currentReg;
+ i.src = src;
gen(i);
} else if (e->expr->type == IR::IntType) {
convertToReal(e->expr, currentReg);
- i.uplus_real(currentReg, src);
+ Instr::UnaryPlusReal i;
+ i.output = currentReg;
+ i.src = src;
gen(i);
} else {
discard();
@@ -445,9 +462,8 @@ void QDeclarativeV4CompilerPrivate::visitUnop(IR::Unop *e)
break;
case IR::OpCompl:
- i.ucompl_real(currentReg, src);
- gen(i);
- discard(); // ???
+ // TODO
+ discard();
break;
case IR::OpBitAnd:
@@ -476,25 +492,23 @@ void QDeclarativeV4CompilerPrivate::visitUnop(IR::Unop *e)
} // switch
}
-void QDeclarativeV4CompilerPrivate::convertToReal(IR::Expr *expr, int reg)
+void QV4CompilerPrivate::convertToReal(IR::Expr *expr, int reg)
{
if (expr->type == IR::RealType)
return;
- Instr conv;
- conv.unaryop.output = reg;
- conv.unaryop.src = reg;
-
switch (expr->type) {
- case IR::BoolType:
- conv.common.type = Instr::ConvertBoolToReal;
- gen(conv);
- break;
+ case IR::BoolType: {
+ Instr::ConvertBoolToReal i;
+ i.output = i.src = reg;
+ gen(i);
+ } break;
- case IR::IntType:
- conv.common.type = Instr::ConvertIntToReal;
- gen(conv);
- break;
+ case IR::IntType: {
+ Instr::ConvertIntToReal i;
+ i.output = i.src = reg;
+ gen(i);
+ } break;
case IR::RealType:
// nothing to do
@@ -506,29 +520,27 @@ void QDeclarativeV4CompilerPrivate::convertToReal(IR::Expr *expr, int reg)
} // switch
}
-void QDeclarativeV4CompilerPrivate::convertToInt(IR::Expr *expr, int reg)
+void QV4CompilerPrivate::convertToInt(IR::Expr *expr, int reg)
{
if (expr->type == IR::IntType)
return;
- Instr conv;
- conv.unaryop.output = reg;
- conv.unaryop.src = reg;
-
switch (expr->type) {
- case IR::BoolType:
- conv.common.type = Instr::ConvertBoolToInt;
- gen(conv);
- break;
+ case IR::BoolType: {
+ Instr::ConvertBoolToInt i;
+ i.output = i.src = reg;
+ gen(i);
+ } break;
case IR::IntType:
// nothing to do
return;
- case IR::RealType:
- conv.common.type = Instr::ConvertRealToInt;
- gen(conv);
- break;
+ case IR::RealType: {
+ Instr::ConvertRealToInt i;
+ i.output = i.src = reg;
+ gen(i);
+ } break;
default:
discard();
@@ -536,34 +548,33 @@ void QDeclarativeV4CompilerPrivate::convertToInt(IR::Expr *expr, int reg)
} // switch
}
-void QDeclarativeV4CompilerPrivate::convertToBool(IR::Expr *expr, int reg)
+void QV4CompilerPrivate::convertToBool(IR::Expr *expr, int reg)
{
if (expr->type == IR::BoolType)
return;
- Instr conv;
- conv.unaryop.output = reg;
- conv.unaryop.src = reg;
-
switch (expr->type) {
case IR::BoolType:
// nothing to do
break;
- case IR::IntType:
- conv.common.type = Instr::ConvertIntToBool;
- gen(conv);
- break;
+ case IR::IntType: {
+ Instr::ConvertIntToBool i;
+ i.output = i.src = reg;
+ gen(i);
+ } break;
- case IR::RealType:
- conv.common.type = Instr::ConvertRealToBool;
- gen(conv);
- return;
+ case IR::RealType: {
+ Instr::ConvertRealToBool i;
+ i.output = i.src = reg;
+ gen(i);
+ } return;
- case IR::StringType:
- conv.common.type = Instr::ConvertStringToBool;
- gen(conv);
- return;
+ case IR::StringType: {
+ Instr::ConvertStringToBool i;
+ i.output = i.src = reg;
+ gen(i);
+ } return;
default:
discard();
@@ -571,104 +582,104 @@ void QDeclarativeV4CompilerPrivate::convertToBool(IR::Expr *expr, int reg)
} // switch
}
-quint8 QDeclarativeV4CompilerPrivate::instructionOpcode(IR::Binop *e)
+quint8 QV4CompilerPrivate::instructionOpcode(IR::Binop *e)
{
switch (e->op) {
case IR::OpInvalid:
- return Instr::Noop;
+ return V4Instr::Noop;
case IR::OpIfTrue:
case IR::OpNot:
case IR::OpUMinus:
case IR::OpUPlus:
case IR::OpCompl:
- return Instr::Noop;
+ return V4Instr::Noop;
case IR::OpBitAnd:
- return Instr::BitAndInt;
+ return V4Instr::BitAndInt;
case IR::OpBitOr:
- return Instr::BitOrInt;
+ return V4Instr::BitOrInt;
case IR::OpBitXor:
- return Instr::BitXorInt;
+ return V4Instr::BitXorInt;
case IR::OpAdd:
if (e->type == IR::StringType)
- return Instr::AddString;
- return Instr::AddReal;
+ return V4Instr::AddString;
+ return V4Instr::AddReal;
case IR::OpSub:
- return Instr::SubReal;
+ return V4Instr::SubReal;
case IR::OpMul:
- return Instr::MulReal;
+ return V4Instr::MulReal;
case IR::OpDiv:
- return Instr::DivReal;
+ return V4Instr::DivReal;
case IR::OpMod:
- return Instr::ModReal;
+ return V4Instr::ModReal;
case IR::OpLShift:
- return Instr::LShiftInt;
+ return V4Instr::LShiftInt;
case IR::OpRShift:
- return Instr::RShiftInt;
+ return V4Instr::RShiftInt;
case IR::OpURShift:
- return Instr::URShiftInt;
+ return V4Instr::URShiftInt;
case IR::OpGt:
if (e->left->type == IR::StringType)
- return Instr::GtString;
- return Instr::GtReal;
+ return V4Instr::GtString;
+ return V4Instr::GtReal;
case IR::OpLt:
if (e->left->type == IR::StringType)
- return Instr::LtString;
- return Instr::LtReal;
+ return V4Instr::LtString;
+ return V4Instr::LtReal;
case IR::OpGe:
if (e->left->type == IR::StringType)
- return Instr::GeString;
- return Instr::GeReal;
+ return V4Instr::GeString;
+ return V4Instr::GeReal;
case IR::OpLe:
if (e->left->type == IR::StringType)
- return Instr::LeString;
- return Instr::LeReal;
+ return V4Instr::LeString;
+ return V4Instr::LeReal;
case IR::OpEqual:
if (e->left->type == IR::StringType)
- return Instr::EqualString;
- return Instr::EqualReal;
+ return V4Instr::EqualString;
+ return V4Instr::EqualReal;
case IR::OpNotEqual:
if (e->left->type == IR::StringType)
- return Instr::NotEqualString;
- return Instr::NotEqualReal;
+ return V4Instr::NotEqualString;
+ return V4Instr::NotEqualReal;
case IR::OpStrictEqual:
if (e->left->type == IR::StringType)
- return Instr::StrictEqualString;
- return Instr::StrictEqualReal;
+ return V4Instr::StrictEqualString;
+ return V4Instr::StrictEqualReal;
case IR::OpStrictNotEqual:
if (e->left->type == IR::StringType)
- return Instr::StrictNotEqualString;
- return Instr::StrictNotEqualReal;
+ return V4Instr::StrictNotEqualString;
+ return V4Instr::StrictNotEqualReal;
case IR::OpAnd:
case IR::OpOr:
- return Instr::Noop;
+ return V4Instr::Noop;
} // switch
- return Instr::Noop;
+ return V4Instr::Noop;
}
-void QDeclarativeV4CompilerPrivate::visitBinop(IR::Binop *e)
+void QV4CompilerPrivate::visitBinop(IR::Binop *e)
{
int left = currentReg;
int right = currentReg + 1;
@@ -754,54 +765,53 @@ void QDeclarativeV4CompilerPrivate::visitBinop(IR::Binop *e)
} // switch
const quint8 opcode = instructionOpcode(e);
- if (opcode != Instr::Noop) {
- Instr instr;
- instr.common.type = opcode;
+ if (opcode != V4Instr::Noop) {
+ V4Instr instr;
instr.binaryop.output = currentReg;
instr.binaryop.left = left;
instr.binaryop.right = right;
- gen(instr);
+ gen(static_cast<V4Instr::Type>(opcode), instr);
}
}
-void QDeclarativeV4CompilerPrivate::visitCall(IR::Call *call)
+void QV4CompilerPrivate::visitCall(IR::Call *call)
{
if (IR::Name *name = call->base->asName()) {
IR::Expr *arg = call->onlyArgument();
if (arg != 0 && arg->type == IR::RealType) {
traceExpression(arg, currentReg);
- Instr instr;
- instr.common.type = Instr::Noop;
-
switch (name->builtin) {
case IR::NoBuiltinSymbol:
break;
- case IR::MathSinBultinFunction:
- instr.math_sin_real(currentReg);
- break;
-
- case IR::MathCosBultinFunction:
- instr.math_cos_real(currentReg);
- break;
-
- case IR::MathRoundBultinFunction:
- instr.math_round_real(currentReg);
- break;
-
- case IR::MathFloorBultinFunction:
- instr.math_floor_real(currentReg);
- break;
+ case IR::MathSinBultinFunction: {
+ Instr::MathSinReal i;
+ i.output = i.src = currentReg;
+ gen(i);
+ } return;
+
+ case IR::MathCosBultinFunction: {
+ Instr::MathCosReal i;
+ i.output = i.src = currentReg;
+ gen(i);
+ } return;
+
+ case IR::MathRoundBultinFunction: {
+ Instr::MathRoundReal i;
+ i.output = i.src = currentReg;
+ gen(i);
+ } return;
+
+ case IR::MathFloorBultinFunction: {
+ Instr::MathFloorReal i;
+ i.output = i.src = currentReg;
+ gen(i);
+ } return;
case IR::MathPIBuiltinConstant:
break;
} // switch
-
- if (instr.common.type != Instr::Noop) {
- gen(instr);
- return;
- }
}
}
@@ -814,12 +824,12 @@ void QDeclarativeV4CompilerPrivate::visitCall(IR::Call *call)
//
// statements
//
-void QDeclarativeV4CompilerPrivate::visitExp(IR::Exp *s)
+void QV4CompilerPrivate::visitExp(IR::Exp *s)
{
traceExpression(s->expr, currentReg);
}
-void QDeclarativeV4CompilerPrivate::visitMove(IR::Move *s)
+void QV4CompilerPrivate::visitMove(IR::Move *s)
{
IR::Temp *target = s->target->asTemp();
Q_ASSERT(target != 0);
@@ -834,47 +844,47 @@ void QDeclarativeV4CompilerPrivate::visitMove(IR::Move *s)
else
traceExpression(s->source, dest);
- Instr conv;
- conv.common.type = Instr::Noop;
+ V4Instr::Type opcode = V4Instr::Noop;
if (target->type == IR::BoolType) {
switch (s->source->type) {
- case IR::IntType: conv.common.type = Instr::ConvertIntToBool; break;
- case IR::RealType: conv.common.type = Instr::ConvertRealToBool; break;
- case IR::StringType: conv.common.type = Instr::ConvertStringToBool; break;
+ case IR::IntType: opcode = V4Instr::ConvertIntToBool; break;
+ case IR::RealType: opcode = V4Instr::ConvertRealToBool; break;
+ case IR::StringType: opcode = V4Instr::ConvertStringToBool; break;
default: break;
} // switch
} else if (target->type == IR::IntType) {
switch (s->source->type) {
- case IR::BoolType: conv.common.type = Instr::ConvertBoolToInt; break;
+ case IR::BoolType: opcode = V4Instr::ConvertBoolToInt; break;
case IR::RealType: {
if (s->isMoveForReturn)
- conv.common.type = Instr::MathRoundReal;
+ opcode = V4Instr::MathRoundReal;
else
- conv.common.type = Instr::ConvertRealToInt;
+ opcode = V4Instr::ConvertRealToInt;
break;
}
- case IR::StringType: conv.common.type = Instr::ConvertStringToInt; break;
+ case IR::StringType: opcode = V4Instr::ConvertStringToInt; break;
default: break;
} // switch
} else if (target->type == IR::RealType) {
switch (s->source->type) {
- case IR::BoolType: conv.common.type = Instr::ConvertBoolToReal; break;
- case IR::IntType: conv.common.type = Instr::ConvertIntToReal; break;
- case IR::StringType: conv.common.type = Instr::ConvertStringToReal; break;
+ case IR::BoolType: opcode = V4Instr::ConvertBoolToReal; break;
+ case IR::IntType: opcode = V4Instr::ConvertIntToReal; break;
+ case IR::StringType: opcode = V4Instr::ConvertStringToReal; break;
default: break;
} // switch
} else if (target->type == IR::StringType) {
switch (s->source->type) {
- case IR::BoolType: conv.common.type = Instr::ConvertBoolToString; break;
- case IR::IntType: conv.common.type = Instr::ConvertIntToString; break;
- case IR::RealType: conv.common.type = Instr::ConvertRealToString; break;
+ case IR::BoolType: opcode = V4Instr::ConvertBoolToString; break;
+ case IR::IntType: opcode = V4Instr::ConvertIntToString; break;
+ case IR::RealType: opcode = V4Instr::ConvertRealToString; break;
default: break;
} // switch
}
- if (conv.common.type != Instr::Noop) {
+ if (opcode != V4Instr::Noop) {
+ V4Instr conv;
conv.unaryop.output = dest;
conv.unaryop.src = src;
- gen(conv);
+ gen(opcode, conv);
} else {
discard();
}
@@ -883,27 +893,28 @@ void QDeclarativeV4CompilerPrivate::visitMove(IR::Move *s)
}
}
-void QDeclarativeV4CompilerPrivate::visitJump(IR::Jump *s)
+void QV4CompilerPrivate::visitJump(IR::Jump *s)
{
patches.append(Patch(s->target, bytecode.size()));
- Instr i;
- i.branch(0); // ### backpatch
+ Instr::Branch i;
+ i.offset = 0; // ### backpatch
gen(i);
}
-void QDeclarativeV4CompilerPrivate::visitCJump(IR::CJump *s)
+void QV4CompilerPrivate::visitCJump(IR::CJump *s)
{
traceExpression(s->cond, currentReg);
patches.append(Patch(s->iftrue, bytecode.size()));
- Instr i;
- i.branch_true(currentReg, 0); // ### backpatch
+ Instr::BranchTrue i;
+ i.reg = currentReg;
+ i.offset = 0; // ### backpatch
gen(i);
}
-void QDeclarativeV4CompilerPrivate::visitRet(IR::Ret *s)
+void QV4CompilerPrivate::visitRet(IR::Ret *s)
{
Q_ASSERT(s->expr != 0);
@@ -916,33 +927,32 @@ void QDeclarativeV4CompilerPrivate::visitRet(IR::Ret *s)
}
if (qmlBindingsTest) {
- Instr test;
- test.common.type = Instr::TestV4Store;
- test.storetest.reg = storeReg;
+ Instr::TestV4Store test;
+ test.reg = storeReg;
switch (s->type) {
case IR::StringType:
- test.storetest.regType = QMetaType::QString;
+ test.regType = QMetaType::QString;
break;
case IR::UrlType:
- test.storetest.regType = QMetaType::QUrl;
+ test.regType = QMetaType::QUrl;
break;
case IR::AnchorLineType:
- test.storetest.regType = qMetaTypeId<QDeclarative1AnchorLine>();
+ test.regType = qMetaTypeId<QDeclarative1AnchorLine>();
break;
case IR::SGAnchorLineType:
- test.storetest.regType = qMetaTypeId<QSGAnchorLine>();
+ test.regType = qMetaTypeId<QSGAnchorLine>();
break;
case IR::ObjectType:
- test.storetest.regType = QMetaType::QObjectStar;
+ test.regType = QMetaType::QObjectStar;
break;
case IR::BoolType:
- test.storetest.regType = QMetaType::Bool;
+ test.regType = QMetaType::Bool;
break;
case IR::IntType:
- test.storetest.regType = QMetaType::Int;
+ test.regType = QMetaType::Int;
break;
case IR::RealType:
- test.storetest.regType = QMetaType::QReal;
+ test.regType = QMetaType::QReal;
break;
default:
discard();
@@ -951,18 +961,17 @@ void QDeclarativeV4CompilerPrivate::visitRet(IR::Ret *s)
gen(test);
}
- Instr store;
- store.common.type = Instr::Store;
- store.store.output = 0;
- store.store.index = expression->property->index;
- store.store.reg = storeReg;
- store.store.exceptionId = exceptionId(s->line, s->column);
+ Instr::Store store;
+ store.output = 0;
+ store.index = expression->property->index;
+ store.reg = storeReg;
+ store.exceptionId = exceptionId(s->line, s->column);
gen(store);
}
-void QDeclarativeV4Compiler::dump(const QByteArray &programData)
+void QV4Compiler::dump(const QByteArray &programData)
{
- const QDeclarativeV4Program *program = (const QDeclarativeV4Program *)programData.constData();
+ const QV4Program *program = (const QV4Program *)programData.constData();
qWarning() << "Program.bindings:" << program->bindings;
qWarning() << "Program.dataLength:" << program->dataLength;
@@ -971,20 +980,16 @@ void QDeclarativeV4Compiler::dump(const QByteArray &programData)
const int programSize = program->instructionCount;
const char *start = program->instructions();
- const char *code = start;
- const char *end = code + programSize;
- while (code < end) {
- Instr *instr = (Instr *) code;
- instr->dump(code - start);
- code += instr->size();
- }
+ const char *end = start + programSize;
+ Bytecode bc;
+ bc.dump(start, end);
}
/*!
Clear the state associated with attempting to compile a specific binding.
This does not clear the global "committed binding" states.
*/
-void QDeclarativeV4CompilerPrivate::resetInstanceState()
+void QV4CompilerPrivate::resetInstanceState()
{
data = committed.data;
exceptions = committed.exceptions;
@@ -1003,7 +1008,7 @@ section.
Returns the index for the committed binding.
*/
-int QDeclarativeV4CompilerPrivate::commitCompile()
+int QV4CompilerPrivate::commitCompile()
{
int rv = committed.count();
committed.offsets << committed.bytecode.count();
@@ -1016,7 +1021,7 @@ int QDeclarativeV4CompilerPrivate::commitCompile()
return rv;
}
-bool QDeclarativeV4CompilerPrivate::compile(QDeclarativeJS::AST::Node *node)
+bool QV4CompilerPrivate::compile(QDeclarativeJS::AST::Node *node)
{
resetInstanceState();
@@ -1039,7 +1044,7 @@ bool QDeclarativeV4CompilerPrivate::compile(QDeclarativeJS::AST::Node *node)
IR::Function thisFunction(&pool), *function = &thisFunction;
- QDeclarativeV4IRBuilder irBuilder(expression, engine);
+ QV4IRBuilder irBuilder(expression, engine);
if (!irBuilder(function, node))
return false;
@@ -1071,7 +1076,7 @@ bool QDeclarativeV4CompilerPrivate::compile(QDeclarativeJS::AST::Node *node)
}
// Returns a reg
-int QDeclarativeV4CompilerPrivate::registerLiteralString(quint8 reg, const QStringRef &str)
+int QV4CompilerPrivate::registerLiteralString(quint8 reg, const QStringRef &str)
{
// ### string cleanup
@@ -1079,18 +1084,17 @@ int QDeclarativeV4CompilerPrivate::registerLiteralString(quint8 reg, const QStri
int offset = data.count();
data += strdata;
- Instr string;
- string.common.type = Instr::String;
- string.string_value.reg = reg;
- string.string_value.offset = offset;
- string.string_value.length = str.length();
+ Instr::LoadString string;
+ string.reg = reg;
+ string.offset = offset;
+ string.length = str.length();
gen(string);
return reg;
}
// Returns an identifier offset
-int QDeclarativeV4CompilerPrivate::registerString(const QString &string)
+int QV4CompilerPrivate::registerString(const QString &string)
{
Q_ASSERT(!string.isEmpty());
@@ -1108,18 +1112,17 @@ int QDeclarativeV4CompilerPrivate::registerString(const QString &string)
*iter = qMakePair(registeredStrings.count(), rv);
}
- Instr reg;
- reg.common.type = Instr::InitString;
- reg.initstring.offset = iter->first;
- reg.initstring.dataIdx = iter->second;
+ Instr::InitString reg;
+ reg.offset = iter->first;
+ reg.dataIdx = iter->second;
gen(reg);
- return reg.initstring.offset;
+ return reg.offset;
}
/*!
Returns true if the current expression has not already subscribed to \a sub in currentBlockMask.
*/
-bool QDeclarativeV4CompilerPrivate::blockNeedsSubscription(const QStringList &sub)
+bool QV4CompilerPrivate::blockNeedsSubscription(const QStringList &sub)
{
QString str = sub.join(QLatin1String("."));
@@ -1134,7 +1137,7 @@ bool QDeclarativeV4CompilerPrivate::blockNeedsSubscription(const QStringList &su
return !(*uiter & currentBlockMask);
}
-int QDeclarativeV4CompilerPrivate::subscriptionIndex(const QStringList &sub)
+int QV4CompilerPrivate::subscriptionIndex(const QStringList &sub)
{
QString str = sub.join(QLatin1String("."));
int *iter = subscriptionIds.value(str);
@@ -1151,7 +1154,7 @@ int QDeclarativeV4CompilerPrivate::subscriptionIndex(const QStringList &sub)
return *iter;
}
-quint32 QDeclarativeV4CompilerPrivate::subscriptionBlockMask(const QStringList &sub)
+quint32 QV4CompilerPrivate::subscriptionBlockMask(const QStringList &sub)
{
QString str = sub.join(QLatin1String("."));
@@ -1164,7 +1167,7 @@ quint32 QDeclarativeV4CompilerPrivate::subscriptionBlockMask(const QStringList &
return *uiter;
}
-quint8 QDeclarativeV4CompilerPrivate::exceptionId(quint32 line, quint32 column)
+quint8 QV4CompilerPrivate::exceptionId(quint32 line, quint32 column)
{
quint8 rv = 0xFF;
if (exceptions.count() < 0xFF) {
@@ -1177,7 +1180,7 @@ quint8 QDeclarativeV4CompilerPrivate::exceptionId(quint32 line, quint32 column)
return rv;
}
-quint8 QDeclarativeV4CompilerPrivate::exceptionId(QDeclarativeJS::AST::ExpressionNode *n)
+quint8 QV4CompilerPrivate::exceptionId(QDeclarativeJS::AST::ExpressionNode *n)
{
quint8 rv = 0xFF;
if (n && exceptions.count() < 0xFF) {
@@ -1187,13 +1190,13 @@ quint8 QDeclarativeV4CompilerPrivate::exceptionId(QDeclarativeJS::AST::Expressio
return rv;
}
-QDeclarativeV4Compiler::QDeclarativeV4Compiler()
-: d(new QDeclarativeV4CompilerPrivate)
+QV4Compiler::QV4Compiler()
+: d(new QV4CompilerPrivate)
{
qmlBindingsTest |= qmlBindingsTestEnv();
}
-QDeclarativeV4Compiler::~QDeclarativeV4Compiler()
+QV4Compiler::~QV4Compiler()
{
delete d; d = 0;
}
@@ -1201,7 +1204,7 @@ QDeclarativeV4Compiler::~QDeclarativeV4Compiler()
/*
Returns true if any bindings were compiled.
*/
-bool QDeclarativeV4Compiler::isValid() const
+bool QV4Compiler::isValid() const
{
return !d->committed.bytecode.isEmpty();
}
@@ -1209,7 +1212,7 @@ bool QDeclarativeV4Compiler::isValid() const
/*
-1 on failure, otherwise the binding index to use.
*/
-int QDeclarativeV4Compiler::compile(const Expression &expression, QDeclarativeEnginePrivate *engine)
+int QV4Compiler::compile(const Expression &expression, QDeclarativeEnginePrivate *engine)
{
if (!expression.expression.asAST()) return false;
@@ -1229,7 +1232,7 @@ int QDeclarativeV4Compiler::compile(const Expression &expression, QDeclarativeEn
}
}
-QByteArray QDeclarativeV4CompilerPrivate::buildSignalTable() const
+QByteArray QV4CompilerPrivate::buildSignalTable() const
{
QHash<int, QList<QPair<int, quint32> > > table;
@@ -1255,7 +1258,7 @@ QByteArray QDeclarativeV4CompilerPrivate::buildSignalTable() const
return QByteArray((const char *)header.constData(), header.count() * sizeof(quint32));
}
-QByteArray QDeclarativeV4CompilerPrivate::buildExceptionData() const
+QByteArray QV4CompilerPrivate::buildExceptionData() const
{
QByteArray rv;
rv.resize(committed.exceptions.count() * sizeof(quint64));
@@ -1266,23 +1269,22 @@ QByteArray QDeclarativeV4CompilerPrivate::buildExceptionData() const
/*
Returns the compiled program.
*/
-QByteArray QDeclarativeV4Compiler::program() const
+QByteArray QV4Compiler::program() const
{
QByteArray programData;
if (isValid()) {
- QDeclarativeV4Program prog;
+ QV4Program prog;
prog.bindings = d->committed.count();
Bytecode bc;
- Instr jump;
- jump.common.type = Instr::Jump;
- jump.jump.reg = -1;
+ QV4CompilerPrivate::Instr::Jump jump;
+ jump.reg = -1;
for (int ii = 0; ii < d->committed.count(); ++ii) {
- jump.jump.count = d->committed.count() - ii - 1;
- jump.jump.count*= jump.size();
- jump.jump.count+= d->committed.offsets.at(ii);
+ jump.count = d->committed.count() - ii - 1;
+ jump.count*= V4InstrMeta<V4Instr::Jump>::Size;
+ jump.count+= d->committed.offsets.at(ii);
bc.append(jump);
}
@@ -1304,15 +1306,15 @@ QByteArray QDeclarativeV4Compiler::program() const
prog.subscriptions = d->committed.subscriptionIds.count();
prog.identifiers = d->committed.registeredStrings.count();
prog.instructionCount = bytecode.count();
- int size = sizeof(QDeclarativeV4Program) + bytecode.count();
+ int size = sizeof(QV4Program) + bytecode.count();
size += prog.dataLength;
programData.resize(size);
- memcpy(programData.data(), &prog, sizeof(QDeclarativeV4Program));
+ memcpy(programData.data(), &prog, sizeof(QV4Program));
if (prog.dataLength)
- memcpy((char *)((QDeclarativeV4Program *)programData.data())->data(), data.constData(),
+ memcpy((char *)((QV4Program *)programData.data())->data(), data.constData(),
data.size());
- memcpy((char *)((QDeclarativeV4Program *)programData.data())->instructions(), bytecode.constData(),
+ memcpy((char *)((QV4Program *)programData.data())->instructions(), bytecode.constData(),
bytecode.count());
}
@@ -1325,13 +1327,13 @@ QByteArray QDeclarativeV4Compiler::program() const
qWarning().nospace() << " " << iter->first << "\t-> " << iter->second;
}
- QDeclarativeV4Compiler::dump(programData);
+ QV4Compiler::dump(programData);
}
return programData;
}
-void QDeclarativeV4Compiler::enableBindingsTest(bool e)
+void QV4Compiler::enableBindingsTest(bool e)
{
if (e)
qmlBindingsTest = true;
diff --git a/src/declarative/qml/v4/qdeclarativev4compiler_p.h b/src/declarative/qml/v4/qv4compiler_p.h
index 0ed78bfdfc..9fafaf95af 100644
--- a/src/declarative/qml/v4/qdeclarativev4compiler_p.h
+++ b/src/declarative/qml/v4/qv4compiler_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QDECLARATIVEV4COMPILER_P_H
-#define QDECLARATIVEV4COMPILER_P_H
+#ifndef QV4COMPILER_P_H
+#define QV4COMPILER_P_H
//
// W A R N I N G
@@ -62,12 +62,12 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
class QDeclarativeTypeNameCache;
-class QDeclarativeV4CompilerPrivate;
-class Q_AUTOTEST_EXPORT QDeclarativeV4Compiler
+class QV4CompilerPrivate;
+class Q_AUTOTEST_EXPORT QV4Compiler
{
public:
- QDeclarativeV4Compiler();
- ~QDeclarativeV4Compiler();
+ QV4Compiler();
+ ~QV4Compiler();
// Returns true if bindings were compiled
bool isValid() const;
@@ -93,12 +93,12 @@ public:
static void dump(const QByteArray &);
static void enableBindingsTest(bool);
private:
- QDeclarativeV4CompilerPrivate *d;
+ QV4CompilerPrivate *d;
};
QT_END_NAMESPACE
QT_END_HEADER
-#endif // QDECLARATIVEV4COMPILER_P_H
+#endif // QV4COMPILER_P_H
diff --git a/src/declarative/qml/v4/qdeclarativev4compiler_p_p.h b/src/declarative/qml/v4/qv4compiler_p_p.h
index eab609a45d..f4dd454426 100644
--- a/src/declarative/qml/v4/qdeclarativev4compiler_p_p.h
+++ b/src/declarative/qml/v4/qv4compiler_p_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QDECLARATIVEV4COMPILER_P_P_H
-#define QDECLARATIVEV4COMPILER_P_P_H
+#ifndef QV4COMPILER_P_P_H
+#define QV4COMPILER_P_P_H
//
// W A R N I N G
@@ -53,8 +53,8 @@
// We mean it.
//
-#include "qdeclarativev4instruction_p.h"
-#include "qdeclarativev4ir_p.h"
+#include "qv4instruction_p.h"
+#include "qv4ir_p.h"
#include <private/qdeclarativescript_p.h>
#include <private/qdeclarativeimport_p.h>
#include <private/qdeclarativeengine_p.h>
@@ -141,16 +141,16 @@ private:
Container _container;
};
-class QDeclarativeV4CompilerPrivate: protected QDeclarativeJS::IR::ExprVisitor,
+class QV4CompilerPrivate: protected QDeclarativeJS::IR::ExprVisitor,
protected QDeclarativeJS::IR::StmtVisitor
{
public:
- QDeclarativeV4CompilerPrivate();
+ QV4CompilerPrivate();
void resetInstanceState();
int commitCompile();
- const QDeclarativeV4Compiler::Expression *expression;
+ const QV4Compiler::Expression *expression;
QDeclarativeEnginePrivate *engine;
QString contextName() const { return QLatin1String("$$$SCOPE_") + QString::number((quintptr)expression->context, 16); }
@@ -209,8 +209,15 @@ public:
void convertToBool(QDeclarativeJS::IR::Expr *expr, int reg);
quint8 instructionOpcode(QDeclarativeJS::IR::Binop *e);
-protected:
+ struct Instr {
+#define QML_V4_INSTR_DATA_TYPEDEF(I, FMT) typedef QDeclarativeJS::V4InstrData<QDeclarativeJS::V4Instr::I> I;
+ FOR_EACH_V4_INSTR(QML_V4_INSTR_DATA_TYPEDEF)
+#undef QML_v4_INSTR_DATA_TYPEDEF
+ private:
+ Instr();
+ };
+protected:
//
// tracing
//
@@ -218,7 +225,14 @@ protected:
void trace(QVector<QDeclarativeJS::IR::BasicBlock *> *blocks);
void traceExpression(QDeclarativeJS::IR::Expr *e, quint8 r);
- inline void gen(const QDeclarativeJS::Instr &i) { bytecode.append(i); }
+ template <int Instr>
+ inline void gen(const QDeclarativeJS::V4InstrData<Instr> &i)
+ { bytecode.append(i); }
+ inline void gen(QDeclarativeJS::V4Instr::Type type, QDeclarativeJS::V4Instr &instr)
+ { bytecode.append(type, instr); }
+
+ inline QDeclarativeJS::V4Instr::Type instructionType(const QDeclarativeJS::V4Instr *i) const
+ { return bytecode.instructionType(i); }
//
// expressions
@@ -259,5 +273,5 @@ Q_DECLARE_METATYPE(QDeclarative1AnchorLine)
QT_END_HEADER
-#endif // QDECLARATIVEV4COMPILER_P_P_H
+#endif // QV4COMPILER_P_P_H
diff --git a/src/declarative/qml/v4/qv4instruction.cpp b/src/declarative/qml/v4/qv4instruction.cpp
new file mode 100644
index 0000000000..411e96b137
--- /dev/null
+++ b/src/declarative/qml/v4/qv4instruction.cpp
@@ -0,0 +1,400 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qv4instruction_p.h"
+#include "qv4bindings_p.h"
+
+#include <QtCore/qdebug.h>
+#include <private/qdeclarativeglobal_p.h>
+
+// Define this to do a test dump of all the instructions at startup. This is
+// helpful to test that each instruction's Instr::dump() case uses the correct
+// number of tabs etc and otherwise looks correct.
+// #define DEBUG_INSTR_DUMP
+
+QT_BEGIN_NAMESPACE
+
+namespace QDeclarativeJS {
+
+#ifdef DEBUG_INSTR_DUMP
+static struct DumpInstrAtStartup {
+ DumpInstrAtStartup() {
+ Bytecode bc;
+#define DUMP_INSTR_AT_STARTUP(I, FMT) { V4InstrData<V4Instr::I> i; bc.append(i); }
+ FOR_EACH_V4_INSTR(DUMP_INSTR_AT_STARTUP);
+#undef DUMP_INSTR_AT_STARTUP
+ const char *start = bc.constData();
+ const char *end = start + bc.size();
+ bc.dump(start, end);
+ }
+} dump_instr_at_startup;
+#endif
+
+int V4Instr::size(Type type)
+{
+#define V4_RETURN_INSTR_SIZE(I, FMT) case I: return QML_V4_INSTR_SIZE(I, FMT);
+ switch (type) {
+ FOR_EACH_V4_INSTR(V4_RETURN_INSTR_SIZE)
+ }
+#undef V4_RETURN_INSTR_SIZE
+ return 0;
+}
+
+void Bytecode::dump(const V4Instr *i, int address) const
+{
+ QByteArray leading;
+ if (address != -1) {
+ leading = QByteArray::number(address);
+ leading.prepend(QByteArray(8 - leading.count(), ' '));
+ leading.append("\t");
+ }
+
+#define INSTR_DUMP qWarning().nospace() << leading.constData()
+
+ switch (instructionType(i)) {
+ case V4Instr::Noop:
+ INSTR_DUMP << "\t" << "Noop";
+ break;
+ case V4Instr::BindingId:
+ INSTR_DUMP << i->id.line << ":" << i->id.column << ":";
+ break;
+ case V4Instr::Subscribe:
+ INSTR_DUMP << "\t" << "Subscribe" << "\t\t" << "Object_Reg(" << i->subscribeop.reg << ") Notify_Signal(" << i->subscribeop.index << ") -> Subscribe_Slot(" << i->subscribeop.offset << ")";
+ break;
+ case V4Instr::SubscribeId:
+ INSTR_DUMP << "\t" << "SubscribeId" << "\t\t" << "Id_Offset(" << i->subscribeop.index << ") -> Subscribe_Slot(" << i->subscribeop.offset << ")";
+ break;
+ case V4Instr::FetchAndSubscribe:
+ INSTR_DUMP << "\t" << "FetchAndSubscribe" << "\t" << "Object_Reg(" << i->fetchAndSubscribe.reg << ") Fast_Accessor(" << i->fetchAndSubscribe.function << ") -> Output_Reg(" << i->fetchAndSubscribe.reg << ") Subscription_Slot(" << i->fetchAndSubscribe.subscription << ")";
+ break;
+ case V4Instr::LoadId:
+ INSTR_DUMP << "\t" << "LoadId" << "\t\t\t" << "Id_Offset(" << i->load.index << ") -> Output_Reg(" << i->load.reg << ")";
+ break;
+ case V4Instr::LoadScope:
+ INSTR_DUMP << "\t" << "LoadScope" << "\t\t" << "-> Output_Reg(" << i->load.reg << ")";
+ break;
+ case V4Instr::LoadRoot:
+ INSTR_DUMP << "\t" << "LoadRoot" << "\t\t" << "-> Output_Reg(" << i->load.reg << ")";
+ break;
+ case V4Instr::LoadAttached:
+ INSTR_DUMP << "\t" << "LoadAttached" << "\t\t" << "Object_Reg(" << i->attached.reg << ") Attached_Index(" << i->attached.id << ") -> Output_Reg(" << i->attached.output << ")";
+ break;
+ case V4Instr::UnaryNot:
+ INSTR_DUMP << "\t" << "UnaryNot" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::UnaryMinusReal:
+ INSTR_DUMP << "\t" << "UnaryMinusReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::UnaryMinusInt:
+ INSTR_DUMP << "\t" << "UnaryMinusInt" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::UnaryPlusReal:
+ INSTR_DUMP << "\t" << "UnaryPlusReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::UnaryPlusInt:
+ INSTR_DUMP << "\t" << "UnaryPlusInt" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::ConvertBoolToInt:
+ INSTR_DUMP << "\t" << "ConvertBoolToInt" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::ConvertBoolToReal:
+ INSTR_DUMP << "\t" << "ConvertBoolToReal" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::ConvertBoolToString:
+ INSTR_DUMP << "\t" << "ConvertBoolToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::ConvertIntToBool:
+ INSTR_DUMP << "\t" << "ConvertIntToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::ConvertIntToReal:
+ INSTR_DUMP << "\t" << "ConvertIntToReal" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::ConvertIntToString:
+ INSTR_DUMP << "\t" << "ConvertIntToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::ConvertRealToBool:
+ INSTR_DUMP << "\t" << "ConvertRealToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::ConvertRealToInt:
+ INSTR_DUMP << "\t" << "ConvertRealToInt" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::ConvertRealToString:
+ INSTR_DUMP << "\t" << "ConvertRealToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::ConvertStringToBool:
+ INSTR_DUMP << "\t" << "ConvertStringToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::ConvertStringToInt:
+ INSTR_DUMP << "\t" << "ConvertStringToInt" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::ConvertStringToReal:
+ INSTR_DUMP << "\t" << "ConvertStringToReal" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::MathSinReal:
+ INSTR_DUMP << "\t" << "MathSinReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::MathCosReal:
+ INSTR_DUMP << "\t" << "MathCosReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::MathRoundReal:
+ INSTR_DUMP << "\t" << "MathRoundReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::MathFloorReal:
+ INSTR_DUMP << "\t" << "MathFloorReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::MathPIReal:
+ INSTR_DUMP << "\t" << "MathPIReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::LoadReal:
+ INSTR_DUMP << "\t" << "LoadReal" << "\t\t" << "Constant(" << i->real_value.value << ") -> Output_Reg(" << i->real_value.reg << ")";
+ break;
+ case V4Instr::LoadInt:
+ INSTR_DUMP << "\t" << "LoadInt" << "\t\t\t" << "Constant(" << i->int_value.value << ") -> Output_Reg(" << i->int_value.reg << ")";
+ break;
+ case V4Instr::LoadBool:
+ INSTR_DUMP << "\t" << "LoadBool" << "\t\t" << "Constant(" << i->bool_value.value << ") -> Output_Reg(" << i->bool_value.reg << ")";
+ break;
+ case V4Instr::LoadString:
+ INSTR_DUMP << "\t" << "LoadString" << "\t\t" << "String_DataIndex(" << i->string_value.offset << ") String_Length(" << i->string_value.length << ") -> Output_Register(" << i->string_value.reg << ")";
+ break;
+ case V4Instr::EnableV4Test:
+ INSTR_DUMP << "\t" << "EnableV4Test" << "\t\t" << "String_DataIndex(" << i->string_value.offset << ") String_Length(" << i->string_value.length << ")";
+ break;
+ case V4Instr::TestV4Store:
+ INSTR_DUMP << "\t" << "TestV4Store" << "\t\t" << "Input_Reg(" << i->storetest.reg << ") Reg_Type(" << i->storetest.regType << ")";
+ break;
+ case V4Instr::BitAndInt:
+ INSTR_DUMP << "\t" << "BitAndInt" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::BitOrInt:
+ INSTR_DUMP << "\t" << "BitOrInt" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::BitXorInt:
+ INSTR_DUMP << "\t" << "BitXorInt" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::AddReal:
+ INSTR_DUMP << "\t" << "AddReal" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::AddString:
+ INSTR_DUMP << "\t" << "AddString" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::SubReal:
+ INSTR_DUMP << "\t" << "SubReal" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::MulReal:
+ INSTR_DUMP << "\t" << "MulReal" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::DivReal:
+ INSTR_DUMP << "\t" << "DivReal" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::ModReal:
+ INSTR_DUMP << "\t" << "ModReal" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::LShiftInt:
+ INSTR_DUMP << "\t" << "LShiftInt" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::RShiftInt:
+ INSTR_DUMP << "\t" << "RShiftInt" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::URShiftInt:
+ INSTR_DUMP << "\t" << "URShiftInt" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::GtReal:
+ INSTR_DUMP << "\t" << "GtReal" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::LtReal:
+ INSTR_DUMP << "\t" << "LtReal" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::GeReal:
+ INSTR_DUMP << "\t" << "GeReal" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::LeReal:
+ INSTR_DUMP << "\t" << "LeReal" << "\t\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::EqualReal:
+ INSTR_DUMP << "\t" << "EqualReal" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::NotEqualReal:
+ INSTR_DUMP << "\t" << "NotEqualReal" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::StrictEqualReal:
+ INSTR_DUMP << "\t" << "StrictEqualReal" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::StrictNotEqualReal:
+ INSTR_DUMP << "\t" << "StrictNotEqualReal" << "\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::GtString:
+ INSTR_DUMP << "\t" << "GtString" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::LtString:
+ INSTR_DUMP << "\t" << "LtString" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::GeString:
+ INSTR_DUMP << "\t" << "GeString" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::LeString:
+ INSTR_DUMP << "\t" << "LeString" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::EqualString:
+ INSTR_DUMP << "\t" << "EqualString" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::NotEqualString:
+ INSTR_DUMP << "\t" << "NotEqualString" << "\t\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::StrictEqualString:
+ INSTR_DUMP << "\t" << "StrictEqualString" << "\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::StrictNotEqualString:
+ INSTR_DUMP << "\t" << "StrictNotEqualString" << "\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::NewString:
+ INSTR_DUMP << "\t" << "NewString" << "\t\t" << "Register(" << i->construct.reg << ")";
+ break;
+ case V4Instr::NewUrl:
+ INSTR_DUMP << "\t" << "NewUrl" << "\t\t\t" << "Register(" << i->construct.reg << ")";
+ break;
+ case V4Instr::CleanupRegister:
+ INSTR_DUMP << "\t" << "CleanupRegister" << "\t\t" << "Register(" << i->cleanup.reg << ")";
+ break;
+ case V4Instr::Fetch:
+ INSTR_DUMP << "\t" << "Fetch" << "\t\t\t" << "Object_Reg(" << i->fetch.reg << ") Property_Index(" << i->fetch.index << ") -> Output_Reg(" << i->fetch.reg << ")";
+ break;
+ case V4Instr::Store:
+ INSTR_DUMP << "\t" << "Store" << "\t\t\t" << "Input_Reg(" << i->store.reg << ") -> Object_Reg(" << i->store.output << ") Property_Index(" << i->store.index << ")";
+ break;
+ case V4Instr::Copy:
+ INSTR_DUMP << "\t" << "Copy" << "\t\t\t" << "Input_Reg(" << i->copy.src << ") -> Output_Reg(" << i->copy.reg << ")";
+ break;
+ case V4Instr::Jump:
+ if (i->jump.reg != -1) {
+ INSTR_DUMP << "\t" << "Jump" << "\t\t\t" << "Address(" << (address + size() + i->jump.count) << ") [if false == Input_Reg(" << i->jump.reg << ")]";
+ } else {
+ INSTR_DUMP << "\t" << "Jump" << "\t\t\t" << "Address(" << (address + size() + i->jump.count) << ")";
+ }
+ break;
+ case V4Instr::BranchFalse:
+ INSTR_DUMP << "\t" << "BranchFalse" << "\t\t" << "Address(" << (address + size() + i->branchop.offset) << ") [if false == Input_Reg(" << i->branchop.reg << ")]";
+ break;
+ case V4Instr::BranchTrue:
+ INSTR_DUMP << "\t" << "BranchTrue" << "\t\t" << "Address(" << (address + size() + i->branchop.offset) << ") [if true == Input_Reg(" << i->branchop.reg << ")]";
+ break;
+ case V4Instr::Branch:
+ INSTR_DUMP << "\t" << "Branch" << "\t\t\t" << "Address(" << (address + size() + i->branchop.offset) << ")";
+ break;
+ case V4Instr::InitString:
+ INSTR_DUMP << "\t" << "InitString" << "\t\t" << "String_DataIndex(" << i->initstring.dataIdx << ") -> String_Slot(" << i->initstring.offset << ")";
+ break;
+ case V4Instr::Block:
+ INSTR_DUMP << "\t" << "Block" << "\t\t\t" << "Mask(" << QByteArray::number(i->blockop.block, 16).constData() << ")";
+ break;
+ default:
+ INSTR_DUMP << "\t" << "Unknown";
+ break;
+ }
+}
+
+void Bytecode::dump(const char *start, const char *end) const
+{
+ const char *code = start;
+ while (code < end) {
+ const V4Instr *instr = reinterpret_cast<const V4Instr *>(code);
+ dump(instr, code - start);
+ code += V4Instr::size(instructionType(instr));
+ }
+}
+
+Bytecode::Bytecode()
+{
+#ifdef QML_THREADED_INTERPRETER
+ decodeInstr = QV4Bindings::getDecodeInstrTable();
+#endif
+}
+
+V4Instr::Type Bytecode::instructionType(const V4Instr *instr) const
+{
+#ifdef QML_THREADED_INTERPRETER
+ void *code = instr->common.code;
+
+# define CHECK_V4_INSTR_CODE(I, FMT) \
+ if (decodeInstr[static_cast<int>(V4Instr::I)] == code) \
+ return V4Instr::I;
+
+ FOR_EACH_V4_INSTR(CHECK_V4_INSTR_CODE)
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid instruction address");
+ return static_cast<V4Instr::Type>(0);
+# undef CHECK_V4_INSTR_CODE
+#else
+ return static_cast<V4Instr::Type>(instr->common.type);
+#endif
+
+}
+
+void Bytecode::append(V4Instr::Type type, V4Instr &instr)
+{
+#ifdef QML_THREADED_INTERPRETER
+ instr.common.code = decodeInstr[static_cast<int>(type)];
+#else
+ instr.common.type = type;
+#endif
+ d.append(reinterpret_cast<const char *>(&instr), V4Instr::size(type));
+}
+
+int Bytecode::remove(int offset)
+{
+ const V4Instr *instr = reinterpret_cast<const V4Instr *>(d.begin() + offset);
+ const int instrSize = V4Instr::size(instructionType(instr));
+ d.remove(offset, instrSize);
+ return instrSize;
+}
+
+const V4Instr &Bytecode::operator[](int offset) const
+{
+ return *(reinterpret_cast<const V4Instr *>(d.begin() + offset));
+}
+
+V4Instr &Bytecode::operator[](int offset)
+{
+ return *(reinterpret_cast<V4Instr *>(d.begin() + offset));
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/v4/qdeclarativev4instruction_p.h b/src/declarative/qml/v4/qv4instruction_p.h
index 6efe9332d1..343df809b4 100644
--- a/src/declarative/qml/v4/qdeclarativev4instruction_p.h
+++ b/src/declarative/qml/v4/qv4instruction_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QDECLARATIVEV4INSTRUCTION_P_H
-#define QDECLARATIVEV4INSTRUCTION_P_H
+#ifndef QV4INSTRUCTION_P_H
+#define QV4INSTRUCTION_P_H
//
// W A R N I N G
@@ -94,10 +94,10 @@ QT_BEGIN_NAMESPACE
F(MathRoundReal, unaryop) \
F(MathFloorReal, unaryop) \
F(MathPIReal, unaryop) \
- F(Real, real_value) \
- F(Int, int_value) \
- F(Bool, bool_value) \
- F(String, string_value) \
+ F(LoadReal, real_value) \
+ F(LoadInt, int_value) \
+ F(LoadBool, bool_value) \
+ F(LoadString, string_value) \
F(EnableV4Test, string_value) \
F(TestV4Store, storetest) \
F(BitAndInt, binaryop) \
@@ -147,85 +147,52 @@ QT_BEGIN_NAMESPACE
#endif
#ifdef Q_ALIGNOF
-# define QML_V4_INSTR_ALIGN_MASK (Q_ALIGNOF(Instr) - 1)
+# define QML_V4_INSTR_ALIGN_MASK (Q_ALIGNOF(V4Instr) - 1)
#else
# define QML_V4_INSTR_ALIGN_MASK (sizeof(void *) - 1)
#endif
#define QML_V4_INSTR_ENUM(I, FMT) I,
#define QML_V4_INSTR_ADDR(I, FMT) &&op_##I,
-#define QML_V4_INSTR_SIZE(I, FMT) ((sizeof(Instr::instr_##FMT) + QML_V4_INSTR_ALIGN_MASK) & ~QML_V4_INSTR_ALIGN_MASK)
+#define QML_V4_INSTR_SIZE(I, FMT) ((sizeof(V4Instr::instr_##FMT) + QML_V4_INSTR_ALIGN_MASK) & ~QML_V4_INSTR_ALIGN_MASK)
#ifdef QML_THREADED_INTERPRETER
# define QML_V4_BEGIN_INSTR(I,FMT) op_##I:
-# define QML_V4_END_INSTR(I,FMT) code += QML_V4_INSTR_SIZE(I, FMT); instr = (const Instr *) code; goto *instr->common.code;
+# define QML_V4_END_INSTR(I,FMT) code += QML_V4_INSTR_SIZE(I, FMT); instr = (const V4Instr *) code; goto *instr->common.code;
# define QML_V4_INSTR_HEADER void *code;
#else
-# define QML_V4_BEGIN_INSTR(I,FMT) case Instr::I:
-# define QML_V4_END_INSTR(I,FMT) code += QML_V4_INSTR_SIZE(I, FMT); instr = (const Instr *) code; break;
-# define QML_V4_INSTR_HEADER
+# define QML_V4_BEGIN_INSTR(I,FMT) case V4Instr::I:
+# define QML_V4_END_INSTR(I,FMT) code += QML_V4_INSTR_SIZE(I, FMT); instr = (const V4Instr *) code; break;
+# define QML_V4_INSTR_HEADER quint8 type;
#endif
namespace QDeclarativeJS {
-union Instr {
- int size() const;
- void dump(int = -1) const;
- void noop();
- void load_root(quint8 reg);
- void load_scope(quint8 reg);
- void load_id(quint8 reg, quint32 idIndex);
- void subscribe(qint8 reg, quint16 offset, quint32 index);
- void subscribeId(qint8 reg, quint16 offset, quint32 index);
- void move_reg_bool(quint8 reg, bool value);
- void move_reg_int(quint8 reg, int value);
- void move_reg_qreal(quint8 reg, qreal value);
- void move_reg_reg(quint8 reg, quint8 src);
-
- void unary_not(quint8 dest, quint8 src);
- void uminus_real(quint8 dest, quint8 src);
- void uminus_int(quint8 dest, quint8 src);
- void uplus_real(quint8 dest, quint8 src);
- void uplus_int(quint8 dest, quint8 src);
- void ucompl_real(quint8 dest, quint8 src);
- void ucompl_int(quint8 dest, quint8 src);
-
- void math_sin_real(quint8 reg);
- void math_cos_real(quint8 reg);
- void math_round_real(quint8 reg);
- void math_floor_real(quint8 reg);
- void math_pi_real(quint8 reg);
- void branch_true(quint8 reg, qint16 offset);
- void branch_false(quint8 reg, qint16 offset);
- void branch(qint16 offset);
- void block(quint32 mask);
-
- enum {
+union V4Instr {
+ enum Type {
FOR_EACH_V4_INSTR(QML_V4_INSTR_ENUM)
};
+ static int size(Type type);
+
struct instr_common {
QML_V4_INSTR_HEADER
- quint8 type;
};
struct instr_id {
QML_V4_INSTR_HEADER
- quint8 type;
quint16 column;
quint32 line;
};
struct instr_init {
QML_V4_INSTR_HEADER
- quint8 type;
quint16 subscriptions;
quint16 identifiers;
};
struct instr_subscribeop {
QML_V4_INSTR_HEADER
- quint8 type;
qint8 reg;
quint16 offset;
quint32 index;
@@ -233,14 +200,12 @@ union Instr {
struct instr_load {
QML_V4_INSTR_HEADER
- quint8 type;
qint8 reg;
quint32 index;
};
struct instr_attached {
QML_V4_INSTR_HEADER
- quint8 type;
qint8 output;
qint8 reg;
quint8 exceptionId;
@@ -249,7 +214,6 @@ union Instr {
struct instr_store {
QML_V4_INSTR_HEADER
- quint8 type;
qint8 output;
qint8 reg;
quint8 exceptionId;
@@ -258,14 +222,12 @@ union Instr {
struct instr_storetest {
QML_V4_INSTR_HEADER
- quint8 type;
qint8 reg;
qint32 regType;
};
struct instr_fetchAndSubscribe {
QML_V4_INSTR_HEADER
- quint8 type;
qint8 reg;
quint8 exceptionId;
quint8 valueType;
@@ -275,7 +237,6 @@ union Instr {
struct instr_fetch{
QML_V4_INSTR_HEADER
- quint8 type;
qint8 reg;
quint8 exceptionId;
quint8 valueType;
@@ -284,41 +245,35 @@ union Instr {
struct instr_copy {
QML_V4_INSTR_HEADER
- quint8 type;
qint8 reg;
qint8 src;
};
struct instr_construct {
QML_V4_INSTR_HEADER
- quint8 type;
qint8 reg;
};
struct instr_real_value {
QML_V4_INSTR_HEADER
- quint8 type;
qint8 reg;
qreal value; // XXX Makes the instruction 12 bytes
};
struct instr_int_value {
QML_V4_INSTR_HEADER
- quint8 type;
qint8 reg;
int value;
};
struct instr_bool_value {
QML_V4_INSTR_HEADER
- quint8 type;
qint8 reg;
bool value;
};
struct instr_string_value {
QML_V4_INSTR_HEADER
- quint8 type;
qint8 reg;
quint16 length;
quint32 offset;
@@ -326,7 +281,6 @@ union Instr {
struct instr_binaryop {
QML_V4_INSTR_HEADER
- quint8 type;
qint8 output;
qint8 left;
qint8 right;
@@ -334,21 +288,18 @@ union Instr {
struct instr_unaryop {
QML_V4_INSTR_HEADER
- quint8 type;
qint8 output;
qint8 src;
};
struct instr_jump {
QML_V4_INSTR_HEADER
- quint8 type;
qint8 reg;
quint32 count;
};
struct instr_find {
QML_V4_INSTR_HEADER
- quint8 type;
qint8 reg;
qint8 src;
quint8 exceptionId;
@@ -358,27 +309,23 @@ union Instr {
struct instr_cleanup {
QML_V4_INSTR_HEADER
- quint8 type;
qint8 reg;
};
struct instr_initstring {
QML_V4_INSTR_HEADER
- quint8 type;
quint16 offset;
quint32 dataIdx;
};
struct instr_branchop {
QML_V4_INSTR_HEADER
- quint8 type;
quint8 reg;
qint16 offset;
};
struct instr_blockop {
QML_V4_INSTR_HEADER
- quint8 type;
quint32 block;
};
@@ -408,6 +355,25 @@ union Instr {
instr_blockop blockop;
};
+template<int N>
+struct V4InstrMeta {
+};
+
+#define QML_V4_INSTR_META_TEMPLATE(I, FMT) \
+ template<> struct V4InstrMeta<(int)V4Instr::I> { \
+ enum { Size = QML_V4_INSTR_SIZE(I, FMT) }; \
+ typedef V4Instr::instr_##FMT DataType; \
+ static const DataType &data(const V4Instr &instr) { return instr.FMT; } \
+ static void setData(V4Instr &instr, const DataType &v) { instr.FMT = v; } \
+ };
+FOR_EACH_V4_INSTR(QML_V4_INSTR_META_TEMPLATE);
+#undef QML_V4_INSTR_META_TEMPLATE
+
+template<int Instr>
+class V4InstrData : public V4InstrMeta<Instr>::DataType
+{
+};
+
class Bytecode
{
Q_DISABLE_COPY(Bytecode)
@@ -420,21 +386,27 @@ public:
int count() const { return d.count(); }
void clear() { d.clear(); }
bool isEmpty() const { return d.isEmpty(); }
- void append(const Instr &instr);
+ V4Instr::Type instructionType(const V4Instr *instr) const;
- template <typename _It>
- void append(_It it, _It last)
+ template <int Instr>
+ void append(const V4InstrData<Instr> &data)
{
- for (; it != last; ++it)
- append(*it);
+ V4Instr genericInstr;
+ V4InstrMeta<Instr>::setData(genericInstr, data);
+ return append(static_cast<V4Instr::Type>(Instr), genericInstr);
}
+ void append(V4Instr::Type type, V4Instr &instr);
int remove(int index);
- const Instr &operator[](int offset) const;
- Instr &operator[](int offset);
+ const V4Instr &operator[](int offset) const;
+ V4Instr &operator[](int offset);
+
+ void dump(const char *start, const char *end) const;
private:
+ void dump(const V4Instr *instr, int = -1) const;
+
QVarLengthArray<char, 4 * 1024> d;
#ifdef QML_THREADED_INTERPRETER
void **decodeInstr;
@@ -447,5 +419,5 @@ QT_END_NAMESPACE
QT_END_HEADER
-#endif // QDECLARATIVEV4INSTRUCTION_P_H
+#endif // QV4INSTRUCTION_P_H
diff --git a/src/declarative/qml/v4/qdeclarativev4ir.cpp b/src/declarative/qml/v4/qv4ir.cpp
index 7490efe2aa..ec3ffc92b2 100644
--- a/src/declarative/qml/v4/qdeclarativev4ir.cpp
+++ b/src/declarative/qml/v4/qv4ir.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "qdeclarativev4ir_p.h"
+#include "qv4ir_p.h"
#include <QtCore/qtextstream.h>
#include <QtCore/qdebug.h>
diff --git a/src/declarative/qml/v4/qdeclarativev4ir_p.h b/src/declarative/qml/v4/qv4ir_p.h
index 2c8f658378..9dbd22047a 100644
--- a/src/declarative/qml/v4/qdeclarativev4ir_p.h
+++ b/src/declarative/qml/v4/qv4ir_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QDECLARATIVEV4IR_P_H
-#define QDECLARATIVEV4IR_P_H
+#ifndef QV4IR_P_H
+#define QV4IR_P_H
//
// W A R N I N G
@@ -58,9 +58,9 @@
#include <private/qdeclarativescript_p.h>
#include <private/qdeclarativeimport_p.h>
#include <private/qdeclarativeengine_p.h>
-#include <private/qdeclarativev4compiler_p.h>
+#include <private/qv4compiler_p.h>
-#include <qdeclarativepool_p.h>
+#include <private/qdeclarativepool_p.h>
#include <QtCore/qvarlengtharray.h>
// #define DEBUG_IR_STRUCTURE
@@ -602,4 +602,4 @@ QT_END_NAMESPACE
QT_END_HEADER
-#endif // QDECLARATIVEV4IR_P_H
+#endif // QV4IR_P_H
diff --git a/src/declarative/qml/v4/qdeclarativev4irbuilder.cpp b/src/declarative/qml/v4/qv4irbuilder.cpp
index 51afe7597c..760c2bc23d 100644
--- a/src/declarative/qml/v4/qdeclarativev4irbuilder.cpp
+++ b/src/declarative/qml/v4/qv4irbuilder.cpp
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#include "qdeclarativev4irbuilder_p.h"
-#include "qdeclarativev4compiler_p_p.h"
+#include "qv4irbuilder_p.h"
+#include "qv4compiler_p_p.h"
#include <private/qsganchors_p_p.h> // For AnchorLine
#include <private/qdeclarativetypenamecache_p.h>
@@ -83,13 +83,13 @@ static IR::Type irTypeFromVariantType(int t, QDeclarativeEnginePrivate *engine,
}
}
-QDeclarativeV4IRBuilder::QDeclarativeV4IRBuilder(const QDeclarativeV4Compiler::Expression *expr,
+QV4IRBuilder::QV4IRBuilder(const QV4Compiler::Expression *expr,
QDeclarativeEnginePrivate *engine)
: m_expression(expr), m_engine(engine), _function(0), _block(0), _discard(false)
{
}
-bool QDeclarativeV4IRBuilder::operator()(QDeclarativeJS::IR::Function *function,
+bool QV4IRBuilder::operator()(QDeclarativeJS::IR::Function *function,
QDeclarativeJS::AST::Node *ast)
{
bool discarded = false;
@@ -129,7 +129,7 @@ bool QDeclarativeV4IRBuilder::operator()(QDeclarativeJS::IR::Function *function,
return !discarded;
}
-bool QDeclarativeV4IRBuilder::buildName(QList<QStringRef> &name,
+bool QV4IRBuilder::buildName(QList<QStringRef> &name,
AST::Node *node,
QList<AST::ExpressionNode *> *nodes)
{
@@ -152,13 +152,13 @@ bool QDeclarativeV4IRBuilder::buildName(QList<QStringRef> &name,
return true;
}
-void QDeclarativeV4IRBuilder::discard()
+void QV4IRBuilder::discard()
{
_discard = true;
}
-QDeclarativeV4IRBuilder::ExprResult
-QDeclarativeV4IRBuilder::expression(AST::ExpressionNode *ast)
+QV4IRBuilder::ExprResult
+QV4IRBuilder::expression(AST::ExpressionNode *ast)
{
ExprResult r;
if (ast) {
@@ -176,7 +176,7 @@ QDeclarativeV4IRBuilder::expression(AST::ExpressionNode *ast)
return r;
}
-void QDeclarativeV4IRBuilder::condition(AST::ExpressionNode *ast, IR::BasicBlock *iftrue, IR::BasicBlock *iffalse)
+void QV4IRBuilder::condition(AST::ExpressionNode *ast, IR::BasicBlock *iftrue, IR::BasicBlock *iffalse)
{
if (! ast)
return;
@@ -202,8 +202,8 @@ void QDeclarativeV4IRBuilder::condition(AST::ExpressionNode *ast, IR::BasicBlock
}
}
-QDeclarativeV4IRBuilder::ExprResult
-QDeclarativeV4IRBuilder::statement(AST::Statement *ast)
+QV4IRBuilder::ExprResult
+QV4IRBuilder::statement(AST::Statement *ast)
{
ExprResult r;
if (ast) {
@@ -221,12 +221,12 @@ QDeclarativeV4IRBuilder::statement(AST::Statement *ast)
return r;
}
-void QDeclarativeV4IRBuilder::sourceElement(AST::SourceElement *ast)
+void QV4IRBuilder::sourceElement(AST::SourceElement *ast)
{
accept(ast);
}
-void QDeclarativeV4IRBuilder::implicitCvt(ExprResult &expr, IR::Type type)
+void QV4IRBuilder::implicitCvt(ExprResult &expr, IR::Type type)
{
if (expr.type() == type)
return; // nothing to do
@@ -237,97 +237,97 @@ void QDeclarativeV4IRBuilder::implicitCvt(ExprResult &expr, IR::Type type)
}
// QML
-bool QDeclarativeV4IRBuilder::visit(AST::UiProgram *)
+bool QV4IRBuilder::visit(AST::UiProgram *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::UiImportList *)
+bool QV4IRBuilder::visit(AST::UiImportList *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::UiImport *)
+bool QV4IRBuilder::visit(AST::UiImport *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::UiPublicMember *)
+bool QV4IRBuilder::visit(AST::UiPublicMember *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::UiSourceElement *)
+bool QV4IRBuilder::visit(AST::UiSourceElement *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::UiObjectDefinition *)
+bool QV4IRBuilder::visit(AST::UiObjectDefinition *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::UiObjectInitializer *)
+bool QV4IRBuilder::visit(AST::UiObjectInitializer *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::UiObjectBinding *)
+bool QV4IRBuilder::visit(AST::UiObjectBinding *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::UiScriptBinding *)
+bool QV4IRBuilder::visit(AST::UiScriptBinding *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::UiArrayBinding *)
+bool QV4IRBuilder::visit(AST::UiArrayBinding *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::UiObjectMemberList *)
+bool QV4IRBuilder::visit(AST::UiObjectMemberList *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::UiArrayMemberList *)
+bool QV4IRBuilder::visit(AST::UiArrayMemberList *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::UiQualifiedId *)
+bool QV4IRBuilder::visit(AST::UiQualifiedId *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::UiSignature *)
+bool QV4IRBuilder::visit(AST::UiSignature *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::UiFormalList *)
+bool QV4IRBuilder::visit(AST::UiFormalList *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::UiFormal *)
+bool QV4IRBuilder::visit(AST::UiFormal *)
{
Q_ASSERT(!"unreachable");
return false;
@@ -335,50 +335,50 @@ bool QDeclarativeV4IRBuilder::visit(AST::UiFormal *)
// JS
-bool QDeclarativeV4IRBuilder::visit(AST::Program *)
+bool QV4IRBuilder::visit(AST::Program *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::SourceElements *)
+bool QV4IRBuilder::visit(AST::SourceElements *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::FunctionSourceElement *)
+bool QV4IRBuilder::visit(AST::FunctionSourceElement *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::StatementSourceElement *)
+bool QV4IRBuilder::visit(AST::StatementSourceElement *)
{
Q_ASSERT(!"unreachable");
return false;
}
// object literals
-bool QDeclarativeV4IRBuilder::visit(AST::PropertyNameAndValueList *)
+bool QV4IRBuilder::visit(AST::PropertyNameAndValueList *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::IdentifierPropertyName *)
+bool QV4IRBuilder::visit(AST::IdentifierPropertyName *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::StringLiteralPropertyName *)
+bool QV4IRBuilder::visit(AST::StringLiteralPropertyName *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::NumericLiteralPropertyName *)
+bool QV4IRBuilder::visit(AST::NumericLiteralPropertyName *)
{
Q_ASSERT(!"unreachable");
return false;
@@ -386,13 +386,13 @@ bool QDeclarativeV4IRBuilder::visit(AST::NumericLiteralPropertyName *)
// array literals
-bool QDeclarativeV4IRBuilder::visit(AST::ElementList *)
+bool QV4IRBuilder::visit(AST::ElementList *)
{
Q_ASSERT(!"unreachable");
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::Elision *)
+bool QV4IRBuilder::visit(AST::Elision *)
{
Q_ASSERT(!"unreachable");
return false;
@@ -400,29 +400,29 @@ bool QDeclarativeV4IRBuilder::visit(AST::Elision *)
// function calls
-bool QDeclarativeV4IRBuilder::visit(AST::ArgumentList *)
+bool QV4IRBuilder::visit(AST::ArgumentList *)
{
Q_ASSERT(!"unreachable");
return false;
}
// expressions
-bool QDeclarativeV4IRBuilder::visit(AST::ObjectLiteral *)
+bool QV4IRBuilder::visit(AST::ObjectLiteral *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::ArrayLiteral *)
+bool QV4IRBuilder::visit(AST::ArrayLiteral *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::ThisExpression *)
+bool QV4IRBuilder::visit(AST::ThisExpression *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::IdentifierExpression *ast)
+bool QV4IRBuilder::visit(AST::IdentifierExpression *ast)
{
const quint32 line = ast->identifierToken.startLine;
const quint32 column = ast->identifierToken.startColumn;
@@ -514,35 +514,35 @@ bool QDeclarativeV4IRBuilder::visit(AST::IdentifierExpression *ast)
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::NullExpression *)
+bool QV4IRBuilder::visit(AST::NullExpression *)
{
// ### TODO: cx format
_expr.code = _block->CONST(IR::NullType, 0);
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::TrueLiteral *)
+bool QV4IRBuilder::visit(AST::TrueLiteral *)
{
// ### TODO: cx format
_expr.code = _block->CONST(IR::BoolType, 1);
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::FalseLiteral *)
+bool QV4IRBuilder::visit(AST::FalseLiteral *)
{
// ### TODO: cx format
_expr.code = _block->CONST(IR::BoolType, 0);
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::StringLiteral *ast)
+bool QV4IRBuilder::visit(AST::StringLiteral *ast)
{
// ### TODO: cx format
_expr.code = _block->STRING(ast->value);
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::NumericLiteral *ast)
+bool QV4IRBuilder::visit(AST::NumericLiteral *ast)
{
if (_expr.hint == ExprResult::cx) {
_expr.format = ExprResult::cx;
@@ -553,22 +553,22 @@ bool QDeclarativeV4IRBuilder::visit(AST::NumericLiteral *ast)
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::RegExpLiteral *)
+bool QV4IRBuilder::visit(AST::RegExpLiteral *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::NestedExpression *)
+bool QV4IRBuilder::visit(AST::NestedExpression *)
{
return true; // the value of the nested expression
}
-bool QDeclarativeV4IRBuilder::visit(AST::ArrayMemberExpression *)
+bool QV4IRBuilder::visit(AST::ArrayMemberExpression *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::FieldMemberExpression *ast)
+bool QV4IRBuilder::visit(AST::FieldMemberExpression *ast)
{
if (IR::Expr *left = expression(ast->base)) {
if (IR::Name *baseName = left->asName()) {
@@ -677,22 +677,22 @@ bool QDeclarativeV4IRBuilder::visit(AST::FieldMemberExpression *ast)
return false;
}
-bool QDeclarativeV4IRBuilder::preVisit(AST::Node *)
+bool QV4IRBuilder::preVisit(AST::Node *)
{
return ! _discard;
}
-bool QDeclarativeV4IRBuilder::visit(AST::NewMemberExpression *)
+bool QV4IRBuilder::visit(AST::NewMemberExpression *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::NewExpression *)
+bool QV4IRBuilder::visit(AST::NewExpression *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::CallExpression *ast)
+bool QV4IRBuilder::visit(AST::CallExpression *ast)
{
QList<QStringRef> names;
QList<AST::ExpressionNode *> nameNodes;
@@ -729,42 +729,42 @@ bool QDeclarativeV4IRBuilder::visit(AST::CallExpression *ast)
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::PostIncrementExpression *)
+bool QV4IRBuilder::visit(AST::PostIncrementExpression *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::PostDecrementExpression *)
+bool QV4IRBuilder::visit(AST::PostDecrementExpression *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::DeleteExpression *)
+bool QV4IRBuilder::visit(AST::DeleteExpression *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::VoidExpression *)
+bool QV4IRBuilder::visit(AST::VoidExpression *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::TypeOfExpression *)
+bool QV4IRBuilder::visit(AST::TypeOfExpression *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::PreIncrementExpression *)
+bool QV4IRBuilder::visit(AST::PreIncrementExpression *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::PreDecrementExpression *)
+bool QV4IRBuilder::visit(AST::PreDecrementExpression *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::UnaryPlusExpression *ast)
+bool QV4IRBuilder::visit(AST::UnaryPlusExpression *ast)
{
ExprResult expr = expression(ast->expression);
if (expr.isNot(IR::InvalidType)) {
@@ -781,7 +781,7 @@ bool QDeclarativeV4IRBuilder::visit(AST::UnaryPlusExpression *ast)
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::UnaryMinusExpression *ast)
+bool QV4IRBuilder::visit(AST::UnaryMinusExpression *ast)
{
ExprResult expr = expression(ast->expression);
if (expr.isNot(IR::InvalidType)) {
@@ -799,7 +799,7 @@ bool QDeclarativeV4IRBuilder::visit(AST::UnaryMinusExpression *ast)
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::TildeExpression *ast)
+bool QV4IRBuilder::visit(AST::TildeExpression *ast)
{
ExprResult expr = expression(ast->expression);
if (expr.isNot(IR::InvalidType)) {
@@ -816,7 +816,7 @@ bool QDeclarativeV4IRBuilder::visit(AST::TildeExpression *ast)
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::NotExpression *ast)
+bool QV4IRBuilder::visit(AST::NotExpression *ast)
{
ExprResult expr = expression(ast->expression);
@@ -840,7 +840,7 @@ bool QDeclarativeV4IRBuilder::visit(AST::NotExpression *ast)
return false;
}
-void QDeclarativeV4IRBuilder::binop(AST::BinaryExpression *ast, ExprResult left, ExprResult right)
+void QV4IRBuilder::binop(AST::BinaryExpression *ast, ExprResult left, ExprResult right)
{
if (IR::Type t = maxType(left.type(), right.type())) {
implicitCvt(left, t);
@@ -857,7 +857,7 @@ void QDeclarativeV4IRBuilder::binop(AST::BinaryExpression *ast, ExprResult left,
}
}
-bool QDeclarativeV4IRBuilder::visit(AST::BinaryExpression *ast)
+bool QV4IRBuilder::visit(AST::BinaryExpression *ast)
{
switch (ast->op) {
case QSOperator::And: {
@@ -1071,7 +1071,7 @@ bool QDeclarativeV4IRBuilder::visit(AST::BinaryExpression *ast)
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::ConditionalExpression *ast)
+bool QV4IRBuilder::visit(AST::ConditionalExpression *ast)
{
IR::BasicBlock *iftrue = _function->newBasicBlock();
IR::BasicBlock *iffalse = _function->newBasicBlock();
@@ -1101,7 +1101,7 @@ bool QDeclarativeV4IRBuilder::visit(AST::ConditionalExpression *ast)
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::Expression *ast)
+bool QV4IRBuilder::visit(AST::Expression *ast)
{
_block->EXP(expression(ast->left));
_expr = expression(ast->right);
@@ -1111,7 +1111,7 @@ bool QDeclarativeV4IRBuilder::visit(AST::Expression *ast)
// statements
-bool QDeclarativeV4IRBuilder::visit(AST::Block *ast)
+bool QV4IRBuilder::visit(AST::Block *ast)
{
if (ast->statements && ! ast->statements->next) {
// we have one and only one statement
@@ -1121,32 +1121,32 @@ bool QDeclarativeV4IRBuilder::visit(AST::Block *ast)
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::StatementList *)
+bool QV4IRBuilder::visit(AST::StatementList *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::VariableStatement *)
+bool QV4IRBuilder::visit(AST::VariableStatement *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::VariableDeclarationList *)
+bool QV4IRBuilder::visit(AST::VariableDeclarationList *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::VariableDeclaration *)
+bool QV4IRBuilder::visit(AST::VariableDeclaration *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::EmptyStatement *)
+bool QV4IRBuilder::visit(AST::EmptyStatement *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::ExpressionStatement *ast)
+bool QV4IRBuilder::visit(AST::ExpressionStatement *ast)
{
if (ast->expression) {
// return the value of this expression
@@ -1156,7 +1156,7 @@ bool QDeclarativeV4IRBuilder::visit(AST::ExpressionStatement *ast)
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::IfStatement *ast)
+bool QV4IRBuilder::visit(AST::IfStatement *ast)
{
if (! ast->ko) {
// This is an if statement without an else branch.
@@ -1191,48 +1191,48 @@ bool QDeclarativeV4IRBuilder::visit(AST::IfStatement *ast)
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::DoWhileStatement *)
+bool QV4IRBuilder::visit(AST::DoWhileStatement *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::WhileStatement *)
+bool QV4IRBuilder::visit(AST::WhileStatement *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::ForStatement *)
+bool QV4IRBuilder::visit(AST::ForStatement *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::LocalForStatement *)
+bool QV4IRBuilder::visit(AST::LocalForStatement *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::ForEachStatement *)
+bool QV4IRBuilder::visit(AST::ForEachStatement *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::LocalForEachStatement *)
+bool QV4IRBuilder::visit(AST::LocalForEachStatement *)
{
discard();
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::ContinueStatement *)
+bool QV4IRBuilder::visit(AST::ContinueStatement *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::BreakStatement *)
+bool QV4IRBuilder::visit(AST::BreakStatement *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::ReturnStatement *ast)
+bool QV4IRBuilder::visit(AST::ReturnStatement *ast)
{
if (ast->expression) {
// return the value of the expression
@@ -1242,82 +1242,82 @@ bool QDeclarativeV4IRBuilder::visit(AST::ReturnStatement *ast)
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::WithStatement *)
+bool QV4IRBuilder::visit(AST::WithStatement *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::SwitchStatement *)
+bool QV4IRBuilder::visit(AST::SwitchStatement *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::CaseBlock *)
+bool QV4IRBuilder::visit(AST::CaseBlock *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::CaseClauses *)
+bool QV4IRBuilder::visit(AST::CaseClauses *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::CaseClause *)
+bool QV4IRBuilder::visit(AST::CaseClause *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::DefaultClause *)
+bool QV4IRBuilder::visit(AST::DefaultClause *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::LabelledStatement *)
+bool QV4IRBuilder::visit(AST::LabelledStatement *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::ThrowStatement *)
+bool QV4IRBuilder::visit(AST::ThrowStatement *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::TryStatement *)
+bool QV4IRBuilder::visit(AST::TryStatement *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::Catch *)
+bool QV4IRBuilder::visit(AST::Catch *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::Finally *)
+bool QV4IRBuilder::visit(AST::Finally *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::FunctionDeclaration *)
+bool QV4IRBuilder::visit(AST::FunctionDeclaration *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::FunctionExpression *)
+bool QV4IRBuilder::visit(AST::FunctionExpression *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::FormalParameterList *)
+bool QV4IRBuilder::visit(AST::FormalParameterList *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::FunctionBody *)
+bool QV4IRBuilder::visit(AST::FunctionBody *)
{
return false;
}
-bool QDeclarativeV4IRBuilder::visit(AST::DebuggerStatement *)
+bool QV4IRBuilder::visit(AST::DebuggerStatement *)
{
return false;
}
diff --git a/src/declarative/qml/v4/qdeclarativev4irbuilder_p.h b/src/declarative/qml/v4/qv4irbuilder_p.h
index 004e3a1a11..28df5c4245 100644
--- a/src/declarative/qml/v4/qdeclarativev4irbuilder_p.h
+++ b/src/declarative/qml/v4/qv4irbuilder_p.h
@@ -39,21 +39,21 @@
**
****************************************************************************/
-#ifndef QDECLARATIVEV4IRBUILDER_P_H
-#define QDECLARATIVEV4IRBUILDER_P_H
+#ifndef QV4IRBUILDER_P_H
+#define QV4IRBUILDER_P_H
#include <QtCore/qglobal.h>
-#include "qdeclarativev4ir_p.h"
+#include "qv4ir_p.h"
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-class QDeclarativeV4IRBuilder : public QDeclarativeJS::AST::Visitor
+class QV4IRBuilder : public QDeclarativeJS::AST::Visitor
{
public:
- QDeclarativeV4IRBuilder(const QDeclarativeV4Compiler::Expression *, QDeclarativeEnginePrivate *);
+ QV4IRBuilder(const QV4Compiler::Expression *, QDeclarativeEnginePrivate *);
bool operator()(QDeclarativeJS::IR::Function *, QDeclarativeJS::AST::Node *);
@@ -226,7 +226,7 @@ private:
QList<QDeclarativeJS::AST::ExpressionNode *> *nodes);
void discard();
- const QDeclarativeV4Compiler::Expression *m_expression;
+ const QV4Compiler::Expression *m_expression;
QDeclarativeEnginePrivate *m_engine;
QDeclarativeJS::IR::Function *_function;
@@ -240,4 +240,4 @@ QT_END_NAMESPACE
QT_END_HEADER
-#endif // QDECLARATIVEV4IRBUILDER_P_H
+#endif // QV4IRBUILDER_P_H
diff --git a/src/declarative/qml/v4/qdeclarativev4program_p.h b/src/declarative/qml/v4/qv4program_p.h
index 6874677361..d0b919f66b 100644
--- a/src/declarative/qml/v4/qdeclarativev4program_p.h
+++ b/src/declarative/qml/v4/qv4program_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QDECLARATIVEV4PROGRAM_P_H
-#define QDECLARATIVEV4PROGRAM_P_H
+#ifndef QV4PROGRAM_P_H
+#define QV4PROGRAM_P_H
//
// W A R N I N G
@@ -53,13 +53,13 @@
// We mean it.
//
-#include "qdeclarativev4instruction_p.h"
+#include "qv4instruction_p.h"
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-struct QDeclarativeV4Program {
+struct QV4Program {
quint32 bindings;
quint32 dataLength;
quint32 signalTableOffset;
@@ -98,17 +98,17 @@ enum QDeclarativeRegisterType {
QVariantType,
};
-const char *QDeclarativeV4Program::data() const
+const char *QV4Program::data() const
{
- return ((const char *)this) + sizeof(QDeclarativeV4Program);
+ return ((const char *)this) + sizeof(QV4Program);
}
-const char *QDeclarativeV4Program::instructions() const
+const char *QV4Program::instructions() const
{
return (const char *)(data() + dataLength);
}
-QDeclarativeV4Program::BindingReferenceList *QDeclarativeV4Program::signalTable(int signalIndex) const
+QV4Program::BindingReferenceList *QV4Program::signalTable(int signalIndex) const
{
quint32 *signalTable = (quint32 *)(data() + signalTableOffset);
return (BindingReferenceList *)(signalTable + signalTable[signalIndex]);
@@ -118,5 +118,5 @@ QT_END_NAMESPACE
QT_END_HEADER
-#endif // QDECLARATIVEV4PROGRAM_P_H
+#endif // QV4PROGRAM_P_H
diff --git a/src/declarative/qml/v4/v4.pri b/src/declarative/qml/v4/v4.pri
index 085f0ae443..b6784851d8 100644
--- a/src/declarative/qml/v4/v4.pri
+++ b/src/declarative/qml/v4/v4.pri
@@ -1,17 +1,15 @@
-INCLUDEPATH += $$PWD
-
HEADERS += \
- $$PWD/qdeclarativev4compiler_p.h \
- $$PWD/qdeclarativev4compiler_p_p.h \
- $$PWD/qdeclarativev4ir_p.h \
- $$PWD/qdeclarativev4irbuilder_p.h \
- $$PWD/qdeclarativev4instruction_p.h \
- $$PWD/qdeclarativev4bindings_p.h \
- $$PWD/qdeclarativev4program_p.h \
+ $$PWD/qv4compiler_p.h \
+ $$PWD/qv4compiler_p_p.h \
+ $$PWD/qv4ir_p.h \
+ $$PWD/qv4irbuilder_p.h \
+ $$PWD/qv4instruction_p.h \
+ $$PWD/qv4bindings_p.h \
+ $$PWD/qv4program_p.h \
SOURCES += \
- $$PWD/qdeclarativev4compiler.cpp \
- $$PWD/qdeclarativev4ir.cpp \
- $$PWD/qdeclarativev4irbuilder.cpp \
- $$PWD/qdeclarativev4instruction.cpp \
- $$PWD/qdeclarativev4bindings.cpp \
+ $$PWD/qv4compiler.cpp \
+ $$PWD/qv4ir.cpp \
+ $$PWD/qv4irbuilder.cpp \
+ $$PWD/qv4instruction.cpp \
+ $$PWD/qv4bindings.cpp \
diff --git a/src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp b/src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp
index 8dfc11fed8..96c51da0ef 100644
--- a/src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp
+++ b/src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp
@@ -98,17 +98,19 @@ v8::Handle<v8::Value> stringArg(const v8::Arguments &args)
if (args.Length() != 1)
V8THROW_ERROR("String.arg(): Invalid arguments");
- if (args[0]->IsUint32())
- return V8ENGINE()->toString(value.arg(args[0]->Uint32Value()));
- else if (args[0]->IsInt32())
- return V8ENGINE()->toString(value.arg(args[0]->Int32Value()));
- else if (args[0]->IsNumber())
- return V8ENGINE()->toString(value.arg(args[0]->NumberValue()));
- else if (args[0]->IsBoolean())
- return V8ENGINE()->toString(value.arg(args[0]->BooleanValue()));
+ v8::Handle<v8::Value> arg = args[0];
+ if (arg->IsUint32())
+ return V8ENGINE()->toString(value.arg(arg->Uint32Value()));
+ else if (arg->IsInt32())
+ return V8ENGINE()->toString(value.arg(arg->Int32Value()));
+ else if (arg->IsNumber())
+ return V8ENGINE()->toString(value.arg(arg->NumberValue()));
+ else if (arg->IsBoolean())
+ return V8ENGINE()->toString(value.arg(arg->BooleanValue()));
- return V8ENGINE()->toString(value.arg(V8ENGINE()->toString(args[0])));
+ return V8ENGINE()->toString(value.arg(V8ENGINE()->toString(arg)));
}
+
/*!
\qmlmethod bool Qt::isQtObject(object)
Returns true if \c object is a valid reference to a Qt or QML object, otherwise false.
diff --git a/src/declarative/qml/v8/qjsengine.cpp b/src/declarative/qml/v8/qjsengine.cpp
index 3db7fc40e0..e466afc30c 100644
--- a/src/declarative/qml/v8/qjsengine.cpp
+++ b/src/declarative/qml/v8/qjsengine.cpp
@@ -378,7 +378,7 @@ QJSValue QJSEngine::newQObject(QObject *object)
Q_D(QJSEngine);
QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
v8::HandleScope handleScope;
- return d->scriptValueFromInternal(d->newQObject(object));
+ return d->scriptValueFromInternal(d->newQObject(object, QV8Engine::JavaScriptOwnership));
}
/*!
diff --git a/src/declarative/qml/v8/qjsvalue_impl_p.h b/src/declarative/qml/v8/qjsvalue_impl_p.h
index b0ad7669d7..b7ff6a87be 100644
--- a/src/declarative/qml/v8/qjsvalue_impl_p.h
+++ b/src/declarative/qml/v8/qjsvalue_impl_p.h
@@ -51,15 +51,15 @@ public:
QGlobalStaticDeleter(QGlobalStatic<QJSValuePrivate> &_globalStatic)
: globalStatic(_globalStatic)
{
- globalStatic.pointer->ref.ref();
+ globalStatic.pointer.load()->ref.ref();
}
inline ~QGlobalStaticDeleter()
{
- if (!globalStatic.pointer->ref.deref()) { // Logic copy & paste from SharedDataPointer
- delete globalStatic.pointer;
+ if (!globalStatic.pointer.load()->ref.deref()) { // Logic copy & paste from SharedDataPointer
+ delete globalStatic.pointer.load();
}
- globalStatic.pointer = 0;
+ globalStatic.pointer.store(0);
globalStatic.destroyed = true;
}
};
diff --git a/src/declarative/qml/v8/qjsvalueiterator_impl_p.h b/src/declarative/qml/v8/qjsvalueiterator_impl_p.h
index 68075e55f3..102c7879d8 100644
--- a/src/declarative/qml/v8/qjsvalueiterator_impl_p.h
+++ b/src/declarative/qml/v8/qjsvalueiterator_impl_p.h
@@ -24,9 +24,9 @@
#ifndef QJSVALUEITERATOR_IMPL_P_H
#define QJSVALUEITERATOR_IMPL_P_H
-#include <qjsvalueiterator_p.h>
-#include <qv8engine_p.h>
-#include <qjsconverter_p.h>
+#include "qjsvalueiterator_p.h"
+#include <private/qv8engine_p.h>
+#include "qjsconverter_p.h"
inline QJSValueIteratorPrivate::QJSValueIteratorPrivate(const QJSValuePrivate* value)
: m_object(const_cast<QJSValuePrivate*>(value))
diff --git a/src/declarative/qml/v8/qv8bindings.cpp b/src/declarative/qml/v8/qv8bindings.cpp
index 3c98af2951..e1a0f4c0a2 100644
--- a/src/declarative/qml/v8/qv8bindings.cpp
+++ b/src/declarative/qml/v8/qv8bindings.cpp
@@ -51,52 +51,12 @@
QT_BEGIN_NAMESPACE
-class QV8BindingsPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QV8Bindings)
-public:
- QV8BindingsPrivate();
-
- struct Binding : public QDeclarativeJavaScriptExpression,
- public QDeclarativeAbstractBinding {
- Binding();
-
- void update() { QDeclarativeAbstractBinding::update(); }
-
- // Inherited from QDeclarativeJavaScriptExpression
- inline virtual QString expressionIdentifier();
-
- // Inherited from QDeclarativeAbstractBinding
- virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags flags);
- virtual void update(QDeclarativePropertyPrivate::WriteFlags flags);
- virtual void destroy();
- virtual void refresh();
-
- int index:30;
- bool enabled:1;
- bool updating:1;
- int line;
- QDeclarativeProperty property;
- QV8BindingsPrivate *parent;
- };
-
- QUrl url;
- int bindingsCount;
- Binding *bindings;
- v8::Persistent<v8::Array> functions;
-};
-
-QV8BindingsPrivate::QV8BindingsPrivate()
-: bindingsCount(0), bindings(0)
-{
-}
-
-QV8BindingsPrivate::Binding::Binding()
-: index(-1), enabled(false), updating(false), line(-1), parent(0)
+QV8Bindings::Binding::Binding()
+: index(-1), enabled(false), updating(false), line(-1), object(0), parent(0)
{
}
-void QV8BindingsPrivate::Binding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags)
+void QV8Bindings::Binding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags)
{
if (enabled != e) {
enabled = e;
@@ -105,12 +65,12 @@ void QV8BindingsPrivate::Binding::setEnabled(bool e, QDeclarativePropertyPrivate
}
}
-void QV8BindingsPrivate::Binding::refresh()
+void QV8Bindings::Binding::refresh()
{
update();
}
-void QV8BindingsPrivate::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags)
+void QV8Bindings::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags)
{
if (!enabled)
return;
@@ -134,8 +94,10 @@ void QV8BindingsPrivate::Binding::update(QDeclarativePropertyPrivate::WriteFlags
&isUndefined);
bool needsErrorData = false;
- if (!watcher.wasDeleted() && !error.isValid())
- needsErrorData = !QDeclarativePropertyPrivate::writeBinding(property, this, result, isUndefined, flags);
+ if (!watcher.wasDeleted() && !error.isValid()) {
+ typedef QDeclarativePropertyPrivate PP;
+ needsErrorData = !PP::writeBinding(object, property, this, result, isUndefined, flags);
+ }
if (!watcher.wasDeleted()) {
@@ -160,31 +122,35 @@ void QV8BindingsPrivate::Binding::update(QDeclarativePropertyPrivate::WriteFlags
ep->dereferenceScarceResources();
} else {
- QDeclarativeBindingPrivate::printBindingLoopError(property);
+ QDeclarativeProperty p = QDeclarativePropertyPrivate::restore(property, object, context);
+ QDeclarativeBindingPrivate::printBindingLoopError(p);
}
}
-QString QV8BindingsPrivate::Binding::expressionIdentifier()
+QString QV8Bindings::Binding::expressionIdentifier()
{
return parent->url.toString() + QLatin1String(":") + QString::number(line);
}
-void QV8BindingsPrivate::Binding::destroy()
+void QV8Bindings::Binding::expressionChanged()
+{
+ update(QDeclarativePropertyPrivate::DontRemoveBinding);
+}
+
+void QV8Bindings::Binding::destroy()
{
enabled = false;
removeFromObject();
clear();
removeError();
- parent->q_func()->release();
+ parent->release();
}
QV8Bindings::QV8Bindings(const QString &program, int index, int line,
QDeclarativeCompiledData *compiled,
QDeclarativeContextData *context)
-: QObject(*(new QV8BindingsPrivate))
+: bindingsCount(0), bindings(0)
{
- Q_D(QV8Bindings);
-
QV8Engine *engine = QDeclarativeEnginePrivate::getV8Engine(context->engine);
if (compiled->v8bindings[index].IsEmpty()) {
@@ -198,54 +164,42 @@ QV8Bindings::QV8Bindings(const QString &program, int index, int line,
compiled->v8bindings[index] = qPersistentNew(v8::Local<v8::Array>::Cast(result));
}
- d->url = compiled->url;
- d->functions = qPersistentNew(compiled->v8bindings[index]);
- d->bindingsCount = d->functions->Length();
- d->bindings = new QV8BindingsPrivate::Binding[d->bindingsCount];
+ url = compiled->url;
+ functions = qPersistentNew(compiled->v8bindings[index]);
+ bindingsCount = functions->Length();
+ bindings = new QV8Bindings::Binding[bindingsCount];
setContext(context);
}
QV8Bindings::~QV8Bindings()
{
- Q_D(QV8Bindings);
- qPersistentDispose(d->functions);
+ qPersistentDispose(functions);
- delete [] d->bindings;
- d->bindings = 0;
- d->bindingsCount = 0;
+ delete [] bindings;
+ bindings = 0;
+ bindingsCount = 0;
}
QDeclarativeAbstractBinding *QV8Bindings::configBinding(int index, QObject *target, QObject *scope,
- const QDeclarativeProperty &property, int line)
+ const QDeclarativePropertyCache::Data &p,
+ int line)
{
- Q_D(QV8Bindings);
- QV8BindingsPrivate::Binding *rv = d->bindings + index;
+ QV8Bindings::Binding *rv = bindings + index;
rv->line = line;
rv->index = index;
- rv->property = property;
+ rv->object = target;
+ rv->property = p;
rv->setContext(context());
rv->setScopeObject(scope);
rv->setUseSharedContext(true);
rv->setNotifyOnValueChanged(true);
- rv->setNotifyObject(this, index);
- rv->parent = d;
+ rv->parent = this;
addref(); // This is decremented in Binding::destroy()
return rv;
}
-int QV8Bindings::qt_metacall(QMetaObject::Call c, int id, void **)
-{
- Q_D(QV8Bindings);
-
- if (c == QMetaObject::InvokeMetaMethod) {
- QV8BindingsPrivate::Binding *binding = d->bindings + id;
- binding->update(QDeclarativePropertyPrivate::DontRemoveBinding);
- }
- return -1;
-}
-
QT_END_NAMESPACE
diff --git a/src/declarative/qml/v8/qv8bindings_p.h b/src/declarative/qml/v8/qv8bindings_p.h
index b387a50df3..f7581a41aa 100644
--- a/src/declarative/qml/v8/qv8bindings_p.h
+++ b/src/declarative/qml/v8/qv8bindings_p.h
@@ -53,9 +53,9 @@
// We mean it.
//
-#include "private/qdeclarativeexpression_p.h"
-#include "private/qdeclarativebinding_p.h"
-#include "private/qdeclarativev4instruction_p.h"
+#include <private/qdeclarativepropertycache_p.h>
+#include <private/qdeclarativeexpression_p.h>
+#include <private/qdeclarativebinding_p.h>
QT_BEGIN_HEADER
@@ -64,8 +64,7 @@ QT_BEGIN_NAMESPACE
class QDeclarativeCompiledData;
class QV8BindingsPrivate;
-class QV8Bindings : public QObject,
- public QDeclarativeAbstractExpression,
+class QV8Bindings : public QDeclarativeAbstractExpression,
public QDeclarativeRefCount
{
public:
@@ -75,14 +74,41 @@ public:
virtual ~QV8Bindings();
QDeclarativeAbstractBinding *configBinding(int index, QObject *target, QObject *scope,
- const QDeclarativeProperty &prop, int line);
-
-protected:
- int qt_metacall(QMetaObject::Call, int, void **);
+ const QDeclarativePropertyCache::Data &prop,
+ int line);
private:
Q_DISABLE_COPY(QV8Bindings)
- Q_DECLARE_PRIVATE(QV8Bindings)
+
+ struct Binding : public QDeclarativeJavaScriptExpression,
+ public QDeclarativeAbstractBinding {
+ Binding();
+
+ void update() { QDeclarativeAbstractBinding::update(); }
+
+ // Inherited from QDeclarativeJavaScriptExpression
+ inline virtual QString expressionIdentifier();
+ virtual void expressionChanged();
+
+ // Inherited from QDeclarativeAbstractBinding
+ virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags flags);
+ virtual void update(QDeclarativePropertyPrivate::WriteFlags flags);
+ virtual void destroy();
+ virtual void refresh();
+
+ int index:30;
+ bool enabled:1;
+ bool updating:1;
+ int line;
+ QObject *object;
+ QDeclarativePropertyCache::Data property;
+ QV8Bindings *parent;
+ };
+
+ QUrl url;
+ int bindingsCount;
+ Binding *bindings;
+ v8::Persistent<v8::Array> functions;
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/v8/qv8engine.cpp b/src/declarative/qml/v8/qv8engine.cpp
index 7be74f8711..7879b7c011 100644
--- a/src/declarative/qml/v8/qv8engine.cpp
+++ b/src/declarative/qml/v8/qv8engine.cpp
@@ -41,6 +41,7 @@
#include "qv8engine_p.h"
+#include "qv8gccallback_p.h"
#include "qv8contextwrapper_p.h"
#include "qv8valuetypewrapper_p.h"
#include "qv8gccallback_p.h"
@@ -135,6 +136,8 @@ QV8Engine::QV8Engine(QJSEngine* qq, QJSEngine::ContextOwnership ownership)
m_variantWrapper.init(this);
m_valueTypeWrapper.init(this);
+ QV8GCCallback::registerGcPrologueCallback();
+
{
v8::Handle<v8::Value> v = global()->Get(v8::String::New("Object"))->ToObject()->Get(v8::String::New("getOwnPropertyNames"));
m_getOwnPropertyNames = qPersistentNew<v8::Function>(v8::Handle<v8::Function>::Cast(v));
@@ -143,6 +146,7 @@ QV8Engine::QV8Engine(QJSEngine* qq, QJSEngine::ContextOwnership ownership)
QV8Engine::~QV8Engine()
{
+ Q_ASSERT_X(v8::Isolate::GetCurrent(), "QV8Engine::~QV8Engine()", "called after v8::Isolate has exited");
for (int ii = 0; ii < m_extensionData.count(); ++ii)
delete m_extensionData[ii];
m_extensionData.clear();
@@ -199,6 +203,11 @@ QVariant QV8Engine::toVariant(v8::Handle<v8::Value> value, int typeHint)
QV8ObjectResource *r = (QV8ObjectResource *)value->ToObject()->GetExternalResource();
if (r) {
switch (r->resourceType()) {
+ case QV8ObjectResource::Context2DStyleType:
+ case QV8ObjectResource::Context2DPixelArrayType:
+ case QV8ObjectResource::SignalHandlerType:
+ case QV8ObjectResource::IncubatorType:
+ case QV8ObjectResource::VisualDataItemType:
case QV8ObjectResource::ContextType:
case QV8ObjectResource::XMLHttpRequestType:
case QV8ObjectResource::DOMNodeType:
@@ -460,13 +469,7 @@ QVariant QV8Engine::toBasicVariant(v8::Handle<v8::Value> value)
int length = properties->Length();
if (length == 0)
return QVariant();
-
- QVariantMap map;
- for (int ii = 0; ii < length; ++ii) {
- v8::Handle<v8::Value> property = properties->Get(ii);
- map.insert(toString(property), toVariant(object->Get(property), -1));
- }
- return map;
+ return variantMapFromJS(object);
}
return QVariant();
@@ -502,6 +505,8 @@ void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global)
qt->Set(v8::String::New(enumerator.key(jj)), v8::Integer::New(enumerator.value(jj)));
}
}
+ qt->Set(v8::String::New("Asynchronous"), v8::Integer::New(0));
+ qt->Set(v8::String::New("Synchronous"), v8::Integer::New(1));
qt->Set(v8::String::New("include"), V8FUNCTION(QV8Include::include, this));
qt->Set(v8::String::New("isQtObject"), V8FUNCTION(isQtObject, this));
@@ -546,9 +551,21 @@ void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global)
global->Set(v8::String::New("Qt"), qt);
global->Set(v8::String::New("gc"), V8FUNCTION(QDeclarativeBuiltinFunctions::gc, this));
- v8::Local<v8::Object> string = v8::Local<v8::Object>::Cast(global->Get(v8::String::New("String")));
- v8::Local<v8::Object> stringPrototype = v8::Local<v8::Object>::Cast(string->Get(v8::String::New("prototype")));
- stringPrototype->Set(v8::String::New("arg"), V8FUNCTION(stringArg, this));
+ {
+#define STRING_ARG "(function(stringArg) { "\
+ " String.prototype.arg = (function() {"\
+ " return stringArg.apply(this, arguments);"\
+ " })"\
+ "})"
+
+ v8::Local<v8::Script> registerArg = v8::Script::New(v8::String::New(STRING_ARG), 0, 0, v8::Handle<v8::String>(), v8::Script::NativeMode);
+ v8::Local<v8::Value> result = registerArg->Run();
+ Q_ASSERT(result->IsFunction());
+ v8::Local<v8::Function> registerArgFunc = v8::Local<v8::Function>::Cast(result);
+ v8::Handle<v8::Value> args = V8FUNCTION(stringArg, this);
+ registerArgFunc->Call(v8::Local<v8::Object>::Cast(registerArgFunc), 1, &args);
+#undef STRING_ARG
+ }
qt_add_domexceptions(this);
m_xmlHttpRequestData = qt_add_qmlxmlhttprequest(this);
@@ -1372,6 +1389,26 @@ void QV8GCCallback::registerGcPrologueCallback()
}
}
+void QV8GCCallback::ThreadData::releaseStrongReferencer()
+{
+ // NOTE: must be called with a valid current isolate
+ if (!referencer.strongReferencer.IsEmpty()) {
+ qPersistentDispose(referencer.strongReferencer);
+ }
+}
+
+void QV8GCCallback::releaseWorkerThreadGcPrologueCallbackData()
+{
+ // Note that only worker-thread implementations with their
+ // own QV8Engine should explicitly release the Referencer
+ // by calling this functions.
+ Q_ASSERT_X(v8::Isolate::GetCurrent(), "QV8GCCallback::releaseWorkerThreadGcPrologueCallbackData()", "called after v8::Isolate has exited");
+ if (threadData.hasLocalData()) {
+ QV8GCCallback::ThreadData *td = threadData.localData();
+ td->releaseStrongReferencer();
+ }
+}
+
QV8GCCallback::Node::Node(PrologueCallback callback)
: prologueCallback(callback)
{
@@ -1382,6 +1419,16 @@ QV8GCCallback::Node::~Node()
node.remove();
}
+QV8GCCallback::Referencer::~Referencer()
+{
+ if (!strongReferencer.IsEmpty()) {
+ Q_ASSERT_X(v8::Isolate::GetCurrent(), "QV8GCCallback::Referencer::~Referencer()", "called after v8::Isolate has exited");
+ // automatically release the strongReferencer if it hasn't
+ // been explicitly released already.
+ qPersistentDispose(strongReferencer);
+ }
+}
+
QV8GCCallback::Referencer::Referencer()
{
v8::HandleScope handleScope;
diff --git a/src/declarative/qml/v8/qv8engine_p.h b/src/declarative/qml/v8/qv8engine_p.h
index 6fa47d8e3d..e8163fbb80 100644
--- a/src/declarative/qml/v8/qv8engine_p.h
+++ b/src/declarative/qml/v8/qv8engine_p.h
@@ -135,7 +135,8 @@ public:
QV8ObjectResource(QV8Engine *engine) : engine(engine) { Q_ASSERT(engine); }
enum ResourceType { ContextType, QObjectType, TypeType, ListType, VariantType,
ValueTypeType, XMLHttpRequestType, DOMNodeType, SQLDatabaseType,
- ListModelType, Context2DType, Context2DStyleType, Context2DPixelArrayType, ParticleDataType, SignalHandlerType};
+ ListModelType, Context2DType, Context2DStyleType, Context2DPixelArrayType,
+ ParticleDataType, SignalHandlerType, IncubatorType, VisualDataItemType };
virtual ResourceType resourceType() const = 0;
QV8Engine *engine;
@@ -227,6 +228,10 @@ public:
QV8Engine(QJSEngine* qq,QJSEngine::ContextOwnership ownership = QJSEngine::CreateNewContext);
~QV8Engine();
+ // ### TODO get rid of it, do we really need CppOwnership?
+ // This enum should be in sync with QDeclarativeEngine::ObjectOwnership
+ enum ObjectOwnership { CppOwnership, JavaScriptOwnership };
+
struct Deletable {
virtual ~Deletable() {}
};
@@ -310,6 +315,7 @@ public:
// Return a JS wrapper for the given QObject \a object
inline v8::Handle<v8::Value> newQObject(QObject *object);
+ inline v8::Handle<v8::Value> newQObject(QObject *object, const ObjectOwnership ownership);
inline bool isQObject(v8::Handle<v8::Value>);
inline QObject *toQObject(v8::Handle<v8::Value>);
@@ -510,6 +516,20 @@ v8::Handle<v8::Value> QV8Engine::newQObject(QObject *object)
return m_qobjectWrapper.newQObject(object);
}
+v8::Handle<v8::Value> QV8Engine::newQObject(QObject *object, const ObjectOwnership ownership)
+{
+ if (!object)
+ return v8::Null();
+
+ v8::Handle<v8::Value> result = newQObject(object);
+ QDeclarativeData *ddata = QDeclarativeData::get(object, true);
+ if (ownership == JavaScriptOwnership && ddata) {
+ ddata->indestructible = false;
+ ddata->explicitIndestructibleSet = true;
+ }
+ return result;
+}
+
v8::Local<v8::String> QV8Engine::toString(const QString &string)
{
return m_stringWrapper.toString(string);
diff --git a/src/declarative/qml/v8/qv8gccallback_p.h b/src/declarative/qml/v8/qv8gccallback_p.h
index 095c0e5bac..91574cb6a5 100644
--- a/src/declarative/qml/v8/qv8gccallback_p.h
+++ b/src/declarative/qml/v8/qv8gccallback_p.h
@@ -67,10 +67,11 @@ private:
public:
static void garbageCollectorPrologueCallback(v8::GCType, v8::GCCallbackFlags);
static void registerGcPrologueCallback();
+ static void releaseWorkerThreadGcPrologueCallbackData();
class Referencer {
public:
- ~Referencer() {}
+ ~Referencer();
void addRelationship(QObject *object, v8::Persistent<v8::Value> handle);
void addRelationship(QObject *object, QObject *other);
private:
@@ -100,6 +101,7 @@ private:
Referencer referencer;
bool gcPrologueCallbackRegistered;
QIntrusiveList<Node, &Node::node> gcCallbackNodes;
+ void releaseStrongReferencer();
};
static void initializeThreadData();
diff --git a/src/declarative/qml/ftw/qdeclarativerefcount.cpp b/src/declarative/qml/v8/qv8profiler_p.h
index a17d5b7142..a36eb073a3 100644
--- a/src/declarative/qml/ftw/qdeclarativerefcount.cpp
+++ b/src/declarative/qml/v8/qv8profiler_p.h
@@ -39,32 +39,4 @@
**
****************************************************************************/
-#include "private/qdeclarativerefcount_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QDeclarativeRefCount::QDeclarativeRefCount()
-: refCount(1)
-{
-}
-
-QDeclarativeRefCount::~QDeclarativeRefCount()
-{
-}
-
-void QDeclarativeRefCount::addref()
-{
- Q_ASSERT(refCount > 0);
- ++refCount;
-}
-
-void QDeclarativeRefCount::release()
-{
- Q_ASSERT(refCount > 0);
- --refCount;
- if (refCount == 0)
- delete this;
-}
-
-QT_END_NAMESPACE
-
+#include <private/v8-profiler.h>
diff --git a/src/declarative/qml/v8/qv8qobjectwrapper.cpp b/src/declarative/qml/v8/qv8qobjectwrapper.cpp
index 5b5c8be435..1dc3db7d29 100644
--- a/src/declarative/qml/v8/qv8qobjectwrapper.cpp
+++ b/src/declarative/qml/v8/qv8qobjectwrapper.cpp
@@ -56,11 +56,11 @@
#include <QtCore/qtimer.h>
#include <QtCore/qatomic.h>
-QT_BEGIN_NAMESPACE
-
Q_DECLARE_METATYPE(QJSValue);
Q_DECLARE_METATYPE(QDeclarativeV8Handle);
+QT_BEGIN_NAMESPACE
+
#if defined(__GNUC__)
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
// The code in this file does not violate strict aliasing, but GCC thinks it does
@@ -522,6 +522,9 @@ v8::Handle<v8::Value> QV8QObjectWrapper::GetProperty(QV8Engine *engine, QObject
ep->capturedProperties << CapturedProperty(object, result->coreIndex, result->notifyIndex);
}
+ if (result->isVMEProperty())
+ return static_cast<QDeclarativeVMEMetaObject *>(const_cast<QMetaObject*>(object->metaObject()))->vmeProperty(result->coreIndex);
+
if (result->isDirect()) {
return LoadPropertyDirect(engine, object, *result);
} else {
@@ -546,10 +549,9 @@ static inline void StoreProperty(QV8Engine *engine, QObject *object, QDeclarativ
int lineNumber = frame->GetLineNumber();
QString url = engine->toString(frame->GetScriptName());
- QDeclarativePropertyCache::ValueTypeData valueTypeData;
newBinding = new QDeclarativeBinding(&function, object, context);
newBinding->setSourceLocation(url, lineNumber);
- newBinding->setTarget(QDeclarativePropertyPrivate::restore(*property, valueTypeData, object, context));
+ newBinding->setTarget(QDeclarativePropertyPrivate::restore(*property, object, context));
newBinding->setEvaluateFlags(newBinding->evaluateFlags() | QDeclarativeBinding::RequiresThisObject);
}
@@ -589,6 +591,8 @@ static inline void StoreProperty(QV8Engine *engine, QObject *object, QDeclarativ
PROPERTY_STORE(double, double(value->ToNumber()->Value()));
} else if (property->propType == QMetaType::QString && value->IsString()) {
PROPERTY_STORE(QString, engine->toString(value->ToString()));
+ } else if (property->isVMEProperty()) {
+ static_cast<QDeclarativeVMEMetaObject *>(const_cast<QMetaObject *>(object->metaObject()))->setVMEProperty(property->coreIndex, value);
} else {
QVariant v;
if (property->isQList())
@@ -861,6 +865,7 @@ static void WeakQObjectInstanceCallback(v8::Persistent<v8::Value> handle, void *
v8::Local<v8::Object> QDeclarativePropertyCache::newQObject(QObject *object, QV8Engine *engine)
{
Q_ASSERT(object);
+ Q_ASSERT(this->engine);
Q_ASSERT(QDeclarativeData::get(object, false));
Q_ASSERT(QDeclarativeData::get(object, false)->propertyCache == this);
@@ -938,6 +943,8 @@ v8::Local<v8::Object> QDeclarativePropertyCache::newQObject(QObject *object, QV8
ft->InstanceTemplate()->SetHasExternalResource(true);
constructor = qPersistentNew<v8::Function>(ft->GetFunction());
}
+
+ QDeclarativeCleanup::addToEngine(this->engine);
}
v8::Local<v8::Object> result = constructor->NewInstance();
@@ -2070,3 +2077,6 @@ v8::Handle<v8::Value> MetaCallArgument::toValue(QV8Engine *engine)
return v8::Undefined();
}
}
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/qml/v8/qv8valuetypewrapper.cpp b/src/declarative/qml/v8/qv8valuetypewrapper.cpp
index e459fee71f..35037fad9f 100644
--- a/src/declarative/qml/v8/qv8valuetypewrapper.cpp
+++ b/src/declarative/qml/v8/qv8valuetypewrapper.cpp
@@ -296,13 +296,13 @@ v8::Handle<v8::Value> QV8ValueTypeWrapper::Setter(v8::Local<v8::String> property
v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(value);
QDeclarativePropertyCache::Data cacheData;
- cacheData.setFlags(QDeclarativePropertyCache::Data::IsWritable);
+ cacheData.setFlags(QDeclarativePropertyCache::Data::IsWritable |
+ QDeclarativePropertyCache::Data::IsValueTypeVirtual);
cacheData.propType = reference->object->metaObject()->property(reference->property).userType();
cacheData.coreIndex = reference->property;
-
- QDeclarativePropertyCache::ValueTypeData valueTypeData;
- valueTypeData.valueTypeCoreIdx = index;
- valueTypeData.valueTypePropType = p.userType();
+ cacheData.valueTypeFlags = 0;
+ cacheData.valueTypeCoreIndex = index;
+ cacheData.valueTypePropType = p.userType();
v8::Local<v8::StackTrace> trace =
v8::StackTrace::CurrentStackTrace(1,
@@ -314,8 +314,8 @@ v8::Handle<v8::Value> QV8ValueTypeWrapper::Setter(v8::Local<v8::String> property
newBinding = new QDeclarativeBinding(&function, reference->object, context);
newBinding->setSourceLocation(url, lineNumber);
- newBinding->setTarget(QDeclarativePropertyPrivate::restore(cacheData, valueTypeData,
- reference->object, context));
+ newBinding->setTarget(QDeclarativePropertyPrivate::restore(cacheData, reference->object,
+ context));
newBinding->setEvaluateFlags(newBinding->evaluateFlags() | QDeclarativeBinding::RequiresThisObject);
}
diff --git a/src/declarative/qml/v8/qv8variantwrapper.cpp b/src/declarative/qml/v8/qv8variantwrapper.cpp
index 4b2acfc965..671e4d33c3 100644
--- a/src/declarative/qml/v8/qv8variantwrapper.cpp
+++ b/src/declarative/qml/v8/qv8variantwrapper.cpp
@@ -41,7 +41,7 @@
#include "qv8variantwrapper_p.h"
#include "qv8engine_p.h"
-#include "qdeclarativeengine_p.h"
+#include <private/qdeclarativeengine_p.h>
QT_BEGIN_NAMESPACE
@@ -167,14 +167,14 @@ QVariant &QV8VariantWrapper::variantValue(v8::Handle<v8::Value> value)
}
v8::Handle<v8::Value> QV8VariantWrapper::Getter(v8::Local<v8::String> /* property */,
- const v8::AccessorInfo &info)
+ const v8::AccessorInfo & /* info */)
{
return v8::Handle<v8::Value>();
}
v8::Handle<v8::Value> QV8VariantWrapper::Setter(v8::Local<v8::String> /* property */,
v8::Local<v8::Value> value,
- const v8::AccessorInfo &info)
+ const v8::AccessorInfo & /* info */)
{
return value;
}
diff --git a/src/declarative/qml/v8/script.pri b/src/declarative/qml/v8/script.pri
index 68a8c64c27..587ab6f42d 100644
--- a/src/declarative/qml/v8/script.pri
+++ b/src/declarative/qml/v8/script.pri
@@ -1,6 +1,3 @@
-
-INCLUDEPATH += $$PWD
-
SOURCES += \
$$PWD/qjsengine.cpp \
$$PWD/qjsvalue.cpp \
diff --git a/src/declarative/qml/v8/v8.pri b/src/declarative/qml/v8/v8.pri
index e74265e4cb..c4372ab82a 100644
--- a/src/declarative/qml/v8/v8.pri
+++ b/src/declarative/qml/v8/v8.pri
@@ -1,11 +1,11 @@
INCLUDEPATH += $$PWD/../../../3rdparty/javascriptcore
-INCLUDEPATH += $$PWD
include(script.pri)
HEADERS += \
$$PWD/qv8_p.h \
$$PWD/qv8debug_p.h \
+ $$PWD/qv8profiler_p.h \
$$PWD/qv8stringwrapper_p.h \
$$PWD/qv8engine_p.h \
$$PWD/qv8gccallback_p.h \
diff --git a/src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp b/src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp
index a215968e2b..56a6e0e5d9 100644
--- a/src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp
+++ b/src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp
@@ -112,23 +112,23 @@ static bool nodeLessThanWithRenderOrder(QSGGeometryNode *a, QSGGeometryNode *b)
}
-IndexGeometryNodePair::IndexGeometryNodePair(int i, QSGGeometryNode *node)
+QSGDefaultRenderer::IndexGeometryNodePair::IndexGeometryNodePair(int i, QSGGeometryNode *node)
: QPair<int, QSGGeometryNode *>(i, node)
{
}
-bool IndexGeometryNodePair::operator < (const IndexGeometryNodePair &other) const
+bool QSGDefaultRenderer::IndexGeometryNodePair::operator < (const QSGDefaultRenderer::IndexGeometryNodePair &other) const
{
return nodeLessThan(second, other.second);
}
-IndexGeometryNodePairHeap::IndexGeometryNodePairHeap()
+QSGDefaultRenderer::IndexGeometryNodePairHeap::IndexGeometryNodePairHeap()
: v(64)
{
}
-void IndexGeometryNodePairHeap::insert(const IndexGeometryNodePair &x)
+void QSGDefaultRenderer::IndexGeometryNodePairHeap::insert(const QSGDefaultRenderer::IndexGeometryNodePair &x)
{
int i = v.size();
v.add(x);
@@ -138,7 +138,7 @@ void IndexGeometryNodePairHeap::insert(const IndexGeometryNodePair &x)
}
}
-IndexGeometryNodePair IndexGeometryNodePairHeap::pop()
+QSGDefaultRenderer::IndexGeometryNodePair QSGDefaultRenderer::IndexGeometryNodePairHeap::pop()
{
IndexGeometryNodePair x = top();
if (v.size() > 1)
@@ -377,7 +377,7 @@ void QSGDefaultRenderer::buildLists(QSGNode *node)
#ifdef FORCE_NO_REORDER
static bool reorder = false;
#else
- static bool reorder = !qApp->arguments().contains(QLatin1String("--no-reorder"));
+ static bool reorder = qApp->arguments().contains(QLatin1String("--reorder"));
#endif
if (reorder && node->firstChild() != node->lastChild() && (node->flags() & QSGNode::ChildrenDoNotOverlap)) {
@@ -468,7 +468,10 @@ void QSGDefaultRenderer::renderNodes(const QDataBuffer<QSGGeometryNode *> &list)
bool changeClip = geomNode->clipList() != m_currentClip;
QSGRenderer::ClipType clipType = QSGRenderer::NoClip;
if (changeClip) {
+ // The clip function relies on there not being any depth testing..
+ glDisable(GL_DEPTH_TEST);
clipType = updateStencilClip(geomNode->clipList());
+ glEnable(GL_DEPTH_TEST);
m_currentClip = geomNode->clipList();
#ifdef FORCE_NO_REORDER
glDepthMask(false);
diff --git a/src/declarative/scenegraph/coreapi/qsgdefaultrenderer_p.h b/src/declarative/scenegraph/coreapi/qsgdefaultrenderer_p.h
index 64480f02de..45cebdd7b9 100644
--- a/src/declarative/scenegraph/coreapi/qsgdefaultrenderer_p.h
+++ b/src/declarative/scenegraph/coreapi/qsgdefaultrenderer_p.h
@@ -52,35 +52,36 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
-class IndexGeometryNodePair : public QPair<int, QSGGeometryNode *>
-{
-public:
- IndexGeometryNodePair(int i, QSGGeometryNode *n);
- bool operator < (const IndexGeometryNodePair &other) const;
-};
-
-
-// Minimum heap.
-class IndexGeometryNodePairHeap
-{
-public:
- IndexGeometryNodePairHeap();
- void insert(const IndexGeometryNodePair &x);
- const IndexGeometryNodePair &top() const { return v.first(); }
- IndexGeometryNodePair pop();
- bool isEmpty() const { return v.isEmpty(); }
-private:
- static int parent(int i) { return (i - 1) >> 1; }
- static int left(int i) { return (i << 1) | 1; }
- static int right(int i) { return (i + 1) << 1; }
- QDataBuffer<IndexGeometryNodePair> v;
-};
class QSGDefaultRenderer : public QSGRenderer
{
Q_OBJECT
public:
+ class IndexGeometryNodePair : public QPair<int, QSGGeometryNode *>
+ {
+ public:
+ IndexGeometryNodePair(int i, QSGGeometryNode *n);
+ bool operator < (const IndexGeometryNodePair &other) const;
+ };
+
+
+ // Minimum heap.
+ class IndexGeometryNodePairHeap
+ {
+ public:
+ IndexGeometryNodePairHeap();
+ void insert(const IndexGeometryNodePair &x);
+ const IndexGeometryNodePair &top() const { return v.first(); }
+ IndexGeometryNodePair pop();
+ bool isEmpty() const { return v.isEmpty(); }
+ private:
+ static int parent(int i) { return (i - 1) >> 1; }
+ static int left(int i) { return (i << 1) | 1; }
+ static int right(int i) { return (i + 1) << 1; }
+ QDataBuffer<IndexGeometryNodePair> v;
+ };
+
QSGDefaultRenderer(QSGContext *context);
void render();
diff --git a/src/declarative/scenegraph/coreapi/qsgnode.cpp b/src/declarative/scenegraph/coreapi/qsgnode.cpp
index 083b073301..764071c190 100644
--- a/src/declarative/scenegraph/coreapi/qsgnode.cpp
+++ b/src/declarative/scenegraph/coreapi/qsgnode.cpp
@@ -62,6 +62,8 @@ static void qt_print_node_count()
\class QSGNode
\brief The QSGNode class is the base class for all nodes in the scene graph.
+ \inmodule QtDeclarative
+
The QSGNode class can be used as a child container. Children are added with
the appendChildNode(), prependChildNode(), insertChildNodeBefore() and
insertChildNodeAfter(). Ordering of nodes is important as geometry nodes
@@ -476,7 +478,9 @@ void QSGNode::markDirty(DirtyFlags flags)
/*!
\class QSGBasicGeometryNode
- \brief The QSGBasicGeometryNode serves as a baseclass for geometry based nodes
+ \brief The QSGBasicGeometryNode class serves as a baseclass for geometry based nodes
+
+ \inmodule QtDeclarative
The QSGBasicGeometryNode class should not be used by itself. It is only encapsulates
shared functionality between the QSGGeometryNode and QSGClipNode classes.
@@ -539,6 +543,8 @@ void QSGBasicGeometryNode::setGeometry(QSGGeometry *geometry)
\class QSGGeometryNode
\brief The QSGGeometryNode class is used for all rendered content in the scene graph.
+ \inmodule QtDeclarative
+
The QSGGeometryNode consists of geometry and material. The geometry defines the mesh,
the vertices and their structure, to be drawn. The Material defines how the shape is
filled.
@@ -704,7 +710,9 @@ void QSGGeometryNode::setInheritedOpacity(qreal opacity)
/*!
\class QSGClipNode
- \brief The QSGClipNode implements the clipping functionality in the scene graph.
+ \brief The QSGClipNode class implements the clipping functionality in the scene graph.
+
+ \inmodule QtDeclarative
Clipping applies to the node's subtree and can be nested. Multiple clip nodes will be
accumulated by intersecting all their geometries. The accumulation happens
@@ -790,7 +798,9 @@ void QSGClipNode::setClipRect(const QRectF &rect)
/*!
\class QSGTransformNode
- \brief The QSGTransformNode implements transformations in the scene graph
+ \brief The QSGTransformNode class implements transformations in the scene graph
+
+ \inmodule QtDeclarative
Transformations apply the node's subtree and can be nested. Multiple transform nodes
will be accumulated by intersecting all their matrices. The accumulation happens
@@ -909,9 +919,11 @@ void QSGRootNode::notifyNodeChange(QSGNode *node, DirtyFlags flags)
/*!
\class QSGOpacityNode
- \brief The QSGOpacityNode is used
+ \brief The QSGOpacityNode class is used to change opacity of nodes.
+
+ \inmodule QtDeclarative
- Opacity apply to its subtree and can be nested. Multiple opacity nodes
+ Opacity applies to its subtree and can be nested. Multiple opacity nodes
will be accumulated by multiplying their opacity. The accumulation happens
as part of the rendering.
@@ -926,7 +938,7 @@ void QSGRootNode::notifyNodeChange(QSGNode *node, DirtyFlags flags)
/*!
Constructs an opacity node with a default opacity of 1.
- Opacity accumulate downwards in the scene graph so a node with two
+ Opacity accumulates downwards in the scene graph so a node with two
QSGOpacityNode instances above it, both with opacity of 0.5, will have
effective opacity of 0.25.
diff --git a/src/declarative/scenegraph/coreapi/qsgnodeupdater.cpp b/src/declarative/scenegraph/coreapi/qsgnodeupdater.cpp
index 88d7e5a8bf..7bf03fd86b 100644
--- a/src/declarative/scenegraph/coreapi/qsgnodeupdater.cpp
+++ b/src/declarative/scenegraph/coreapi/qsgnodeupdater.cpp
@@ -192,6 +192,8 @@ void QSGNodeUpdater::leaveGeometryNode(QSGGeometryNode *g)
{
#ifdef QSG_UPDATER_DEBUG
qDebug() << "leave geometry" << g;
+#else
+ Q_UNUSED(g)
#endif
}
diff --git a/src/declarative/scenegraph/coreapi/qsgrenderer.cpp b/src/declarative/scenegraph/coreapi/qsgrenderer.cpp
index af118e0717..b22631afae 100644
--- a/src/declarative/scenegraph/coreapi/qsgrenderer.cpp
+++ b/src/declarative/scenegraph/coreapi/qsgrenderer.cpp
@@ -45,7 +45,7 @@
#include "qsgnodeupdater_p.h"
#include "qsggeometry_p.h"
-#include "private/qsgadaptationlayer_p.h"
+#include <private/qsgadaptationlayer_p.h>
#include <QOpenGLShaderProgram>
#include <qopenglframebufferobject.h>
@@ -486,7 +486,6 @@ QSGRenderer::ClipType QSGRenderer::updateStencilClip(const QSGClipNode *clip)
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
glEnable(GL_STENCIL_TEST);
- glDisable(GL_DEPTH_TEST);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);
@@ -519,12 +518,10 @@ QSGRenderer::ClipType QSGRenderer::updateStencilClip(const QSGClipNode *clip)
if (stencilEnabled) {
m_clip_program.disableAttributeArray(0);
- glEnable(GL_DEPTH_TEST);
glStencilFunc(GL_EQUAL, clipDepth, 0xff); // stencil test, ref, test mask
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // stencil fail, z fail, z pass
glStencilMask(0); // write mask
bindable()->reactivate();
- //glDepthMask(GL_TRUE); // must be reset correctly by caller.
} else {
glDisable(GL_STENCIL_TEST);
}
diff --git a/src/declarative/scenegraph/qsgcontext.cpp b/src/declarative/scenegraph/qsgcontext.cpp
index 430f76a0ac..d91592f2a5 100644
--- a/src/declarative/scenegraph/qsgcontext.cpp
+++ b/src/declarative/scenegraph/qsgcontext.cpp
@@ -380,6 +380,16 @@ QSGTexture *QSGContext::decodeImageToTexture(QIODevice *dev,
+QSurfaceFormat QSGContext::defaultSurfaceFormat() const
+{
+ QSurfaceFormat format;
+ format.setDepthBufferSize(24);
+ format.setStencilBufferSize(8);
+ format.setSamples(16);
+ return format;
+}
+
+
/*!
Factory function for texture objects.
diff --git a/src/declarative/scenegraph/qsgcontext_p.h b/src/declarative/scenegraph/qsgcontext_p.h
index 159e9a9cb9..3457b81d90 100644
--- a/src/declarative/scenegraph/qsgcontext_p.h
+++ b/src/declarative/scenegraph/qsgcontext_p.h
@@ -42,10 +42,12 @@
#ifndef QSGCONTEXT_H
#define QSGCONTEXT_H
-#include <QImage>
-#include <QObject>
+#include <QtCore/QObject>
#include "private/qabstractanimation2_p.h"
+#include <QtGui/QImage>
+#include <QtGui/QSurfaceFormat>
+
#include "qsgnode.h"
QT_BEGIN_HEADER
@@ -105,6 +107,8 @@ public:
virtual QSGTexture *createTexture(const QImage &image = QImage()) const;
virtual QSize minimumFBOSize() const;
+ virtual QSurfaceFormat defaultSurfaceFormat() const;
+
static QSGContext *createDefaultContext();
void scheduleTextureForCleanup(QSGTexture *texture);
@@ -129,4 +133,4 @@ QT_END_NAMESPACE
QT_END_HEADER
-#endif // QSGCONTEXT_H
+#endif // QSGCONTEXT_H \ No newline at end of file
diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp b/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp
index cb3dab959c..3586c9daa2 100644
--- a/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp
+++ b/src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp
@@ -60,6 +60,9 @@ QSGDistanceFieldGlyphNode::QSGDistanceFieldGlyphNode(QSGDistanceFieldGlyphCacheM
m_geometry.setDrawingMode(GL_TRIANGLES);
setGeometry(&m_geometry);
setPreferredAntialiasingMode(cacheManager->defaultAntialiasingMode());
+#ifdef QML_RUNTIME_TESTING
+ description = QLatin1String("glyphs");
+#endif
}
QSGDistanceFieldGlyphNode::~QSGDistanceFieldGlyphNode()
diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp b/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp
index 72c53a2ce7..1e8b668444 100644
--- a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp
+++ b/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.cpp
@@ -225,6 +225,8 @@ int QSGDistanceFieldTextMaterial::compare(const QSGMaterial *o) const
{
Q_ASSERT(o && type() == o->type());
const QSGDistanceFieldTextMaterial *other = static_cast<const QSGDistanceFieldTextMaterial *>(o);
+ if (m_glyph_cache != other->m_glyph_cache)
+ return m_glyph_cache - other->m_glyph_cache;
if (m_glyph_cache->fontScale() != other->m_glyph_cache->fontScale()) {
qreal s1 = m_glyph_cache->fontScale();
qreal s2 = other->m_glyph_cache->fontScale();
diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h b/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h
index a5bdf36d16..9004549a3a 100644
--- a/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h
+++ b/src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h
@@ -44,7 +44,7 @@
#include <private/qsgadaptationlayer_p.h>
#include "qsgtexture.h"
-#include <qsgtext_p.h>
+#include <private/qsgtext_p.h>
QT_BEGIN_HEADER
diff --git a/src/declarative/scenegraph/scenegraph.pri b/src/declarative/scenegraph/scenegraph.pri
index d29a3bc561..d4e0707ba3 100644
--- a/src/declarative/scenegraph/scenegraph.pri
+++ b/src/declarative/scenegraph/scenegraph.pri
@@ -1,4 +1,3 @@
-INCLUDEPATH += $$PWD/coreapi $$PWD/convenience $$PWD/3d
!contains(QT_CONFIG, egl):DEFINES += QT_NO_EGL
# Core API
diff --git a/src/declarative/scenegraph/util/qsgflatcolormaterial.cpp b/src/declarative/scenegraph/util/qsgflatcolormaterial.cpp
index affdcadd3b..ee73616e4f 100644
--- a/src/declarative/scenegraph/util/qsgflatcolormaterial.cpp
+++ b/src/declarative/scenegraph/util/qsgflatcolormaterial.cpp
@@ -119,9 +119,11 @@ const char *FlatColorMaterialShader::fragmentShader() const {
/*!
\class QSGFlatColorMaterial
- \brief The QSGFlatColorMaterial provides a convenient way of rendering
+ \brief The QSGFlatColorMaterial class provides a convenient way of rendering
solid colored geometry in the scene graph.
+ \inmodule QtDeclarative
+
The flat color material will fill every pixel in a geometry using
a solid color. The color can contain transparency.
diff --git a/src/declarative/scenegraph/util/qsgsimpletexturenode.cpp b/src/declarative/scenegraph/util/qsgsimpletexturenode.cpp
index 5ada8539dc..a0d6616371 100644
--- a/src/declarative/scenegraph/util/qsgsimpletexturenode.cpp
+++ b/src/declarative/scenegraph/util/qsgsimpletexturenode.cpp
@@ -58,10 +58,12 @@ static void qsgsimpletexturenode_update(QSGGeometry *g,
/*!
\class QSGSimpleTextureNode
- \brief The QSGSimpleTextureNode provided for convenience to easily draw
+ \brief The QSGSimpleTextureNode class is provided for convenience to easily draw
textured content using the QML scene graph.
- \warning The simple texture node class must have texture before being
+ \inmodule QtDeclarative
+
+ \warning The simple texture node class must have a texture before being
added to the scene graph to be rendered.
*/
diff --git a/src/declarative/scenegraph/util/qsgtexture.cpp b/src/declarative/scenegraph/util/qsgtexture.cpp
index bec325f3bb..7cd398d9e0 100644
--- a/src/declarative/scenegraph/util/qsgtexture.cpp
+++ b/src/declarative/scenegraph/util/qsgtexture.cpp
@@ -193,11 +193,33 @@ QSGTexture::~QSGTexture()
Binding a texture may also include uploading the texture data from
a previously set QImage.
+
+ \warning This function can only be called from the rendering thread.
+ */
+
+/*!
+ This function returns a copy of the current texture which is removed
+ from its atlas.
+
+ The current texture remains unchanged, so texture coordinates do not
+ need to be updated.
+
+ Removing a texture from an atlas is primarily useful when passing
+ it to a shader that operates on the texture coordinates 0-1 instead
+ of the texture subrect inside the atlas.
+
+ If the texture is not part of a texture atlas, this function returns 0.
+
+ Implementations of this function are recommended to return the same instance
+ for multiple calls to limit memory usage.
+
+ \warning This function can only be called from the rendering thread.
*/
-void QSGTexture::removeFromAtlas()
+QSGTexture *QSGTexture::removedFromAtlas() const
{
- // default textures are not in atlasses, so do nothing...
+ Q_ASSERT_X(!isAtlasTexture(), "QSGTexture::removedFromAtlas()", "Called on a non-atlas texture");
+ return 0;
}
/*!
@@ -210,6 +232,19 @@ bool QSGTexture::isAtlasTexture() const
return false;
}
+/*!
+ \fn int QSGTexture::textureId() const
+
+ Returns the OpenGL texture id for this texture.
+
+ The default value is 0, indicating that it is an invalid texture id.
+
+ The function should at all times return the correct texture id.
+
+ \warning This function can only be called from the rendering thread.
+ */
+
+
/*!
Returns the rectangle inside textureSize() that this texture
@@ -395,6 +430,22 @@ void QSGPlainTexture::setImage(const QImage &image)
m_dirty_bind_options = true;
}
+int QSGPlainTexture::textureId() const
+{
+ if (m_dirty_texture) {
+ if (m_image.isNull()) {
+ // The actual texture and id will be updated/deleted in a later bind()
+ // or ~QSGPlainTexture so just keep it minimal here.
+ return 0;
+ } else {
+ // Generate a texture id for use later and return it.
+ glGenTextures(1, &const_cast<QSGPlainTexture *>(this)->m_texture_id);
+ return m_texture_id;
+ }
+ }
+ return m_texture_id;
+}
+
void QSGPlainTexture::setTextureId(int id)
{
if (m_texture_id && m_owns_texture)
@@ -430,10 +481,10 @@ void QSGPlainTexture::bind()
m_dirty_texture = false;
- if (m_texture_id && m_owns_texture)
- glDeleteTextures(1, &m_texture_id);
if (m_image.isNull()) {
+ if (m_texture_id && m_owns_texture)
+ glDeleteTextures(1, &m_texture_id);
m_texture_id = 0;
m_texture_size = QSize();
m_has_mipmaps = false;
@@ -441,7 +492,8 @@ void QSGPlainTexture::bind()
return;
}
- glGenTextures(1, &m_texture_id);
+ if (m_texture_id == 0)
+ glGenTextures(1, &m_texture_id);
glBindTexture(GL_TEXTURE_2D, m_texture_id);
// ### TODO: check for out-of-memory situations...
diff --git a/src/declarative/scenegraph/util/qsgtexture.h b/src/declarative/scenegraph/util/qsgtexture.h
index 5506042c6a..135c5e403f 100644
--- a/src/declarative/scenegraph/util/qsgtexture.h
+++ b/src/declarative/scenegraph/util/qsgtexture.h
@@ -80,7 +80,8 @@ public:
virtual QRectF textureSubRect() const;
virtual bool isAtlasTexture() const;
- virtual void removeFromAtlas();
+
+ virtual QSGTexture *removedFromAtlas() const;
virtual void bind() = 0;
void updateBindOptions(bool force = false);
diff --git a/src/declarative/scenegraph/util/qsgtexture_p.h b/src/declarative/scenegraph/util/qsgtexture_p.h
index 22812f8640..f14508fd25 100644
--- a/src/declarative/scenegraph/util/qsgtexture_p.h
+++ b/src/declarative/scenegraph/util/qsgtexture_p.h
@@ -77,8 +77,7 @@ public:
bool ownsTexture() const { return m_owns_texture; }
void setTextureId(int id);
- int textureId() const { return m_texture_id; }
-
+ int textureId() const;
void setTextureSize(const QSize &size) { m_texture_size = size; }
QSize textureSize() const { return m_texture_size; }
@@ -93,6 +92,12 @@ public:
virtual void bind();
+ static QSGPlainTexture *fromImage(const QImage &image) {
+ QSGPlainTexture *t = new QSGPlainTexture();
+ t->setImage(image);
+ return t;
+ }
+
protected:
QImage m_image;
diff --git a/src/declarative/scenegraph/util/qsgtextureprovider.cpp b/src/declarative/scenegraph/util/qsgtextureprovider.cpp
index 49d157d480..5605f28602 100644
--- a/src/declarative/scenegraph/util/qsgtextureprovider.cpp
+++ b/src/declarative/scenegraph/util/qsgtextureprovider.cpp
@@ -41,8 +41,8 @@
#include "qsgtextureprovider_p.h"
-#include <qsgimage_p.h>
-#include <qsgshadereffectsource_p.h>
+#include <private/qsgimage_p.h>
+#include <private/qsgshadereffectsource_p.h>
#ifndef GL_CLAMP_TO_EDGE
#define GL_CLAMP_TO_EDGE 0x812F
diff --git a/src/declarative/scenegraph/util/qsgvertexcolormaterial.cpp b/src/declarative/scenegraph/util/qsgvertexcolormaterial.cpp
index 637d549279..78cef55215 100644
--- a/src/declarative/scenegraph/util/qsgvertexcolormaterial.cpp
+++ b/src/declarative/scenegraph/util/qsgvertexcolormaterial.cpp
@@ -110,9 +110,11 @@ const char *QSGVertexColorMaterialShader::fragmentShader() const {
/*!
\class QSGVertexColorMaterial
- \brief The QSGVertexColorMaterial provides a convenient way of rendering per-vertex
+ \brief The QSGVertexColorMaterial class provides a convenient way of rendering per-vertex
colored geometry in the scene graph.
+ \inmodule QtDeclarative
+
The vertex color material will give each vertex in a geometry a color. Pixels between
vertices will be linearly interpolated. The colors can contain transparency.
@@ -123,7 +125,7 @@ const char *QSGVertexColorMaterialShader::fragmentShader() const {
QSGGeometry::defaultAttributes_ColoredPoint2D() constructs an attribute set
compatible with this material.
- The vertex color material respets both current opacity and current matrix when
+ The vertex color material respects both current opacity and current matrix when
updating it's rendering state.
*/
@@ -143,7 +145,7 @@ QSGVertexColorMaterial::QSGVertexColorMaterial()
\internal
*/
-int QSGVertexColorMaterial::compare(const QSGMaterial *other) const
+int QSGVertexColorMaterial::compare(const QSGMaterial * /* other */) const
{
return 0;
}
diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp
index 870bed35ed..8ce9bdd930 100644
--- a/src/declarative/util/qdeclarativeanimation.cpp
+++ b/src/declarative/util/qdeclarativeanimation.cpp
@@ -39,23 +39,22 @@
**
****************************************************************************/
-#include "private/qdeclarativeanimation_p.h"
-#include "private/qdeclarativeanimation_p_p.h"
+#include "qdeclarativeanimation_p.h"
+#include "qdeclarativeanimation_p_p.h"
-#include "private/qdeclarativebehavior_p.h"
-#include "private/qdeclarativestateoperations_p.h"
-#include "private/qdeclarativecontext_p.h"
+#include <private/qdeclarativestateoperations_p.h>
+#include <private/qdeclarativecontext_p.h>
#include <qdeclarativepropertyvaluesource.h>
#include <qdeclarative.h>
#include <qdeclarativeinfo.h>
#include <qdeclarativeexpression.h>
-#include <qdeclarativestringconverters_p.h>
-#include <qdeclarativeglobal_p.h>
-#include <qdeclarativemetatype_p.h>
-#include <qdeclarativevaluetype_p.h>
-#include <qdeclarativeproperty_p.h>
-#include <qdeclarativeengine_p.h>
+#include <private/qdeclarativestringconverters_p.h>
+#include <private/qdeclarativeglobal_p.h>
+#include <private/qdeclarativemetatype_p.h>
+#include <private/qdeclarativevaluetype_p.h>
+#include <private/qdeclarativeproperty_p.h>
+#include <private/qdeclarativeengine_p.h>
#include <qvariant.h>
#include <qcolor.h>
@@ -197,7 +196,7 @@ void QDeclarativeAbstractAnimation::setRunning(bool r)
else if (!d->registered) {
d->registered = true;
QDeclarativeEnginePrivate *engPriv = QDeclarativeEnginePrivate::get(qmlEngine(this));
- engPriv->registerFinalizedParserStatusObject(this, this->metaObject()->indexOfSlot("componentFinalized()"));
+ engPriv->registerFinalizeCallback(this, this->metaObject()->indexOfSlot("componentFinalized()"));
}
return;
}
@@ -2475,4 +2474,4 @@ QAbstractAnimation2Pointer QDeclarativePropertyAnimation::transition(QDeclarativ
return animator;
}
-QT_END_NAMESPACE
+QT_END_NAMESPACE \ No newline at end of file
diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h
index b6022a4bec..43d4a37b99 100644
--- a/src/declarative/util/qdeclarativeanimation_p.h
+++ b/src/declarative/util/qdeclarativeanimation_p.h
@@ -454,4 +454,4 @@ QML_DECLARE_TYPE(QDeclarativeRotationAnimation)
QT_END_HEADER
-#endif // QDECLARATIVEANIMATION2_H
+#endif // QDECLARATIVEANIMATION2_H \ No newline at end of file
diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h
index b342a2b7ee..5548854bde 100644
--- a/src/declarative/util/qdeclarativeanimation_p_p.h
+++ b/src/declarative/util/qdeclarativeanimation_p_p.h
@@ -53,10 +53,9 @@
// We mean it.
//
-#include "private/qdeclarativeanimation_p.h"
+#include "qdeclarativeanimation_p.h"
-#include "private/qdeclarativenullablevalue_p_p.h"
-#include "private/qdeclarativetimeline_p_p.h"
+#include <private/qdeclarativenullablevalue_p_p.h>
#include <qdeclarative.h>
#include <qdeclarativecontext.h>
diff --git a/src/declarative/util/qdeclarativeapplication.cpp b/src/declarative/util/qdeclarativeapplication.cpp
index e03dce7f95..765f8dd2cd 100644
--- a/src/declarative/util/qdeclarativeapplication.cpp
+++ b/src/declarative/util/qdeclarativeapplication.cpp
@@ -42,6 +42,7 @@
#include "qdeclarativeapplication_p.h"
#include <private/qobject_p.h>
#include <QtGui/QGuiApplication>
+#include <QtGui/QInputPanel>
QT_BEGIN_NAMESPACE
@@ -82,6 +83,11 @@ Qt::LayoutDirection QDeclarativeApplication::layoutDirection() const
return d->layoutDirection;
}
+QObject *QDeclarativeApplication::inputPanel() const
+{
+ return qApp ? qApp->inputPanel() : 0;
+}
+
bool QDeclarativeApplication::eventFilter(QObject *obj, QEvent *event)
{
Q_UNUSED(obj)
diff --git a/src/declarative/util/qdeclarativeapplication_p.h b/src/declarative/util/qdeclarativeapplication_p.h
index 448d3199cf..aa51085f01 100644
--- a/src/declarative/util/qdeclarativeapplication_p.h
+++ b/src/declarative/util/qdeclarativeapplication_p.h
@@ -58,12 +58,14 @@ class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeApplication : public QObject
Q_OBJECT
Q_PROPERTY(bool active READ active NOTIFY activeChanged)
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection NOTIFY layoutDirectionChanged)
+ Q_PROPERTY(QObject *inputPanel READ inputPanel CONSTANT)
public:
explicit QDeclarativeApplication(QObject *parent = 0);
virtual ~QDeclarativeApplication();
bool active() const;
Qt::LayoutDirection layoutDirection() const;
+ QObject *inputPanel() const;
protected:
bool eventFilter(QObject *obj, QEvent *event);
diff --git a/src/declarative/util/qdeclarativebehavior.cpp b/src/declarative/util/qdeclarativebehavior.cpp
index f05cffabd1..633e620d8d 100644
--- a/src/declarative/util/qdeclarativebehavior.cpp
+++ b/src/declarative/util/qdeclarativebehavior.cpp
@@ -39,17 +39,17 @@
**
****************************************************************************/
-#include "private/qdeclarativebehavior_p.h"
-
#include "private/qdeclarativeanimation_p.h"
#include "private/qabstractanimation2_p.h"
#include "private/qdeclarativetransition_p.h"
+#include "qdeclarativebehavior_p.h"
+#include "qdeclarativeanimation_p.h"
#include <qdeclarativecontext.h>
#include <qdeclarativeinfo.h>
-#include <qdeclarativeproperty_p.h>
-#include <qdeclarativeguard_p.h>
-#include <qdeclarativeengine_p.h>
+#include <private/qdeclarativeproperty_p.h>
+#include <private/qdeclarativeguard_p.h>
+#include <private/qdeclarativeengine_p.h>
#include <private/qobject_p.h>
@@ -173,8 +173,10 @@ void QDeclarativeBehavior::setEnabled(bool enabled)
void QDeclarativeBehavior::write(const QVariant &value)
{
Q_D(QDeclarativeBehavior);
- qmlExecuteDeferred(this);
- if (!d->animation || !d->enabled || !d->finalized) {
+ bool bypass = !d->enabled || !d->finalized;
+ if (!bypass)
+ qmlExecuteDeferred(this);
+ if (!d->animation || bypass) {
QDeclarativePropertyPrivate::write(d->property, value, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
d->targetValue = value;
return;
@@ -220,7 +222,7 @@ void QDeclarativeBehavior::setTarget(const QDeclarativeProperty &property)
d->animation->setDefaultTarget(property);
QDeclarativeEnginePrivate *engPriv = QDeclarativeEnginePrivate::get(qmlEngine(this));
- engPriv->registerFinalizedParserStatusObject(this, this->metaObject()->indexOfSlot("componentFinalized()"));
+ engPriv->registerFinalizeCallback(this, this->metaObject()->indexOfSlot("componentFinalized()"));
}
void QDeclarativeBehavior::componentFinalized()
diff --git a/src/declarative/util/qdeclarativebehavior_p.h b/src/declarative/util/qdeclarativebehavior_p.h
index 482de32472..e980199596 100644
--- a/src/declarative/util/qdeclarativebehavior_p.h
+++ b/src/declarative/util/qdeclarativebehavior_p.h
@@ -42,9 +42,8 @@
#ifndef QDECLARATIVEBEHAVIOR_H
#define QDECLARATIVEBEHAVIOR_H
-#include "private/qdeclarativestate_p.h"
+#include <private/qdeclarativeglobal_p.h>
-#include <qdeclarativepropertyvaluesource.h>
#include <qdeclarativepropertyvalueinterceptor.h>
#include <qdeclarative.h>
#include "private/qabstractanimation2_p.h"
diff --git a/src/declarative/util/qdeclarativebind.cpp b/src/declarative/util/qdeclarativebind.cpp
index ba120b959a..20b2caa582 100644
--- a/src/declarative/util/qdeclarativebind.cpp
+++ b/src/declarative/util/qdeclarativebind.cpp
@@ -39,12 +39,12 @@
**
****************************************************************************/
-#include "private/qdeclarativebind_p.h"
+#include "qdeclarativebind_p.h"
-#include "private/qdeclarativenullablevalue_p_p.h"
-#include "private/qdeclarativeproperty_p.h"
-#include "private/qdeclarativebinding_p.h"
-#include "private/qdeclarativeguard_p.h"
+#include <private/qdeclarativenullablevalue_p_p.h>
+#include <private/qdeclarativeproperty_p.h>
+#include <private/qdeclarativebinding_p.h>
+#include <private/qdeclarativeguard_p.h>
#include <qdeclarativeengine.h>
#include <qdeclarativecontext.h>
@@ -53,8 +53,6 @@
#include <QtCore/qfile.h>
#include <QtCore/qdebug.h>
-#include <QtDeclarative/qjsvalue.h>
-#include <QtDeclarative/qjsengine.h>
#include <private/qobject_p.h>
diff --git a/src/declarative/util/qdeclarativechangeset.cpp b/src/declarative/util/qdeclarativechangeset.cpp
index d941d5e842..81cbe3e10a 100644
--- a/src/declarative/util/qdeclarativechangeset.cpp
+++ b/src/declarative/util/qdeclarativechangeset.cpp
@@ -41,8 +41,11 @@
#include "qdeclarativechangeset_p.h"
+QT_BEGIN_NAMESPACE
+
QDeclarativeChangeSet::QDeclarativeChangeSet()
: m_moveCounter(0)
+ , m_difference(0)
{
}
@@ -51,6 +54,7 @@ QDeclarativeChangeSet::QDeclarativeChangeSet(const QDeclarativeChangeSet &change
, m_inserts(changeSet.m_inserts)
, m_changes(changeSet.m_changes)
, m_moveCounter(changeSet.m_moveCounter)
+ , m_difference(0)
{
}
@@ -64,6 +68,7 @@ QDeclarativeChangeSet &QDeclarativeChangeSet::operator =(const QDeclarativeChang
m_inserts = changeSet.m_inserts;
m_changes = changeSet.m_changes;
m_moveCounter = changeSet.m_moveCounter;
+ m_difference = changeSet.m_difference;
return *this;
}
@@ -219,7 +224,8 @@ void QDeclarativeChangeSet::applyRemovals(QVector<Remove> &removals, QVector<Ins
}
if (rit->moveId != -1 && difference > 0) {
- iit = insertions.insert(iit, Insert(iit->index, difference, moveId));
+ iit = insertions.insert(iit, Insert(
+ iit->index, difference, insert->moveId != -1 ? moveId : -1));
++iit;
iit->index += difference;
iit->count -= difference;
@@ -273,7 +279,7 @@ void QDeclarativeChangeSet::applyRemovals(QVector<Remove> &removals, QVector<Ins
for (; rend != m_removes.end()
&& rit->moveId == -1
&& rend->moveId == -1
- && rit->index + rit->count > rend->index; ++rend) {
+ && rit->index + rit->count >= rend->index; ++rend) {
count += rend->count;
}
if (remove != rend) {
@@ -285,7 +291,6 @@ void QDeclarativeChangeSet::applyRemovals(QVector<Remove> &removals, QVector<Ins
index += difference;
rit->count -= difference;
removeCount += difference;
-
remove->index = rit->index;
remove->count = count;
remove = m_removes.erase(++remove, rend);
@@ -299,10 +304,10 @@ void QDeclarativeChangeSet::applyRemovals(QVector<Remove> &removals, QVector<Ins
remove = m_removes.insert(remove, Remove(rit->index, offset, moveId));
++remove;
rit->count -= offset;
+ removeCount += offset;
}
remove->index = rit->index;
index += offset;
- removeCount += offset;
++remove;
} else {
@@ -310,15 +315,14 @@ void QDeclarativeChangeSet::applyRemovals(QVector<Remove> &removals, QVector<Ins
remove = m_removes.insert(remove, Remove(rit->index, offset));
++remove;
rit->count -= offset;
+ removeCount += offset;
}
remove->index = rit->index;
index += offset;
- removeCount += offset;
++remove;
}
index += count;
- rit->count -= count;
}
if (rit->count > 0) {
@@ -329,6 +333,7 @@ void QDeclarativeChangeSet::applyRemovals(QVector<Remove> &removals, QVector<Ins
}
for (; remove != m_removes.end(); ++remove)
remove->index -= removeCount;
+ m_difference -= removeCount;
}
void QDeclarativeChangeSet::applyInsertions(QVector<Insert> &insertions)
@@ -353,6 +358,7 @@ void QDeclarativeChangeSet::applyInsertions(QVector<Insert> &insertions)
if (insert == m_inserts.end()) {
insert = m_inserts.insert(insert, *iit);
++insert;
+ insertCount += iit->count;
} else {
const int offset = index - insert->index;
if (offset < 0 || (offset == 0 && (iit->moveId != -1 || insert->moveId != -1))) {
@@ -394,6 +400,7 @@ void QDeclarativeChangeSet::applyInsertions(QVector<Insert> &insertions)
change->index += insertCount;
for (; insert != m_inserts.end(); ++insert)
insert->index += insertCount;
+ m_difference += insertCount;
}
void QDeclarativeChangeSet::applyChanges(QVector<Change> &changes)
@@ -468,3 +475,5 @@ QDebug operator <<(QDebug debug, const QDeclarativeChangeSet::Change &change)
return (debug.nospace() << "Change(" << change.index << "," << change.count << ")").space();
}
+QT_END_NAMESPACE
+
diff --git a/src/declarative/util/qdeclarativechangeset_p.h b/src/declarative/util/qdeclarativechangeset_p.h
index 67533b02d5..b7554da503 100644
--- a/src/declarative/util/qdeclarativechangeset_p.h
+++ b/src/declarative/util/qdeclarativechangeset_p.h
@@ -103,10 +103,6 @@ public:
};
QDeclarativeChangeSet();
- QDeclarativeChangeSet(
- const QVector<Remove> &removals,
- const QVector<Insert> &insertions,
- const QVector<Change> &changes = QVector<Change>());
QDeclarativeChangeSet(const QDeclarativeChangeSet &changeSet);
~QDeclarativeChangeSet();
@@ -138,8 +134,12 @@ public:
m_inserts.clear();
m_changes.clear();
m_moveCounter = 0;
+ m_difference = 0;
}
+ int moveCounter() const { return m_moveCounter; }
+ int difference() const { return m_difference; }
+
private:
void applyRemovals(QVector<Remove> &removals, QVector<Insert> &insertions);
void applyInsertions(QVector<Insert> &insertions);
@@ -149,6 +149,7 @@ private:
QVector<Insert> m_inserts;
QVector<Change> m_changes;
int m_moveCounter;
+ int m_difference;
};
inline uint qHash(const QDeclarativeChangeSet::MoveKey &key) { return qHash(qMakePair(key.moveId, key.offset)); }
diff --git a/src/declarative/util/qdeclarativeconnections.cpp b/src/declarative/util/qdeclarativeconnections.cpp
index 57bb79c302..c57363fdfe 100644
--- a/src/declarative/util/qdeclarativeconnections.cpp
+++ b/src/declarative/util/qdeclarativeconnections.cpp
@@ -39,13 +39,13 @@
**
****************************************************************************/
-#include "private/qdeclarativeconnections_p.h"
+#include "qdeclarativeconnections_p.h"
#include <qdeclarativeexpression.h>
-#include <qdeclarativeproperty_p.h>
-#include <qdeclarativeboundsignal_p.h>
+#include <private/qdeclarativeproperty_p.h>
+#include <private/qdeclarativeboundsignal_p.h>
#include <qdeclarativecontext.h>
-#include <qdeclarativecontext_p.h>
+#include <private/qdeclarativecontext_p.h>
#include <qdeclarativeinfo.h>
#include <QtCore/qdebug.h>
@@ -202,7 +202,7 @@ QDeclarativeConnectionsParser::compile(const QList<QDeclarativeCustomParserPrope
for(int ii = 0; ii < props.count(); ++ii)
{
- QString propName = QString::fromUtf8(props.at(ii).name());
+ QString propName = props.at(ii).name();
if (!propName.startsWith(QLatin1String("on")) || !propName.at(2).isUpper()) {
error(props.at(ii), QDeclarativeConnections::tr("Cannot assign to non-existent property \"%1\"").arg(propName));
return QByteArray();
diff --git a/src/declarative/util/qdeclarativeconnections_p.h b/src/declarative/util/qdeclarativeconnections_p.h
index af652fcabf..86e1341689 100644
--- a/src/declarative/util/qdeclarativeconnections_p.h
+++ b/src/declarative/util/qdeclarativeconnections_p.h
@@ -43,7 +43,6 @@
#define QDECLARATIVECONNECTIONS_H
#include <qdeclarative.h>
-#include <qdeclarativescriptstring.h>
#include <private/qdeclarativecustomparser_p.h>
#include <QtCore/qobject.h>
diff --git a/src/declarative/util/qdeclarativefontloader.cpp b/src/declarative/util/qdeclarativefontloader.cpp
index f7a7738172..e95bd11a7b 100644
--- a/src/declarative/util/qdeclarativefontloader.cpp
+++ b/src/declarative/util/qdeclarativefontloader.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "private/qdeclarativefontloader_p.h"
+#include "qdeclarativefontloader_p.h"
#include <qdeclarativecontext.h>
#include <qdeclarativeengine.h>
diff --git a/src/declarative/util/qdeclarativelistaccessor.cpp b/src/declarative/util/qdeclarativelistaccessor.cpp
index e85b1ed8d0..0063514e59 100644
--- a/src/declarative/util/qdeclarativelistaccessor.cpp
+++ b/src/declarative/util/qdeclarativelistaccessor.cpp
@@ -39,15 +39,15 @@
**
****************************************************************************/
-#include "private/qdeclarativelistaccessor_p.h"
+#include "qdeclarativelistaccessor_p.h"
-#include <qdeclarativemetatype_p.h>
+#include <private/qdeclarativemetatype_p.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qdebug.h>
// ### Remove me
-#include <qdeclarativeengine_p.h>
+#include <private/qdeclarativeengine_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/util/qdeclarativelistcompositor.cpp b/src/declarative/util/qdeclarativelistcompositor.cpp
new file mode 100644
index 0000000000..be0d543368
--- /dev/null
+++ b/src/declarative/util/qdeclarativelistcompositor.cpp
@@ -0,0 +1,1202 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativelistcompositor_p.h"
+
+#include <QtCore/qvarlengtharray.h>
+
+//#define QT_DECLARATIVE_VERIFY_MINIMAL
+//#define QT_DECLARATIVE_VERIFY_INTEGRITY
+
+#ifdef QT_DECLARATIVE_VERIFY_MINIMAL
+#define QT_DECLARATIVE_VERIFY_INTEGRITY
+static bool qt_verifyMinimal(
+ const QDeclarativeListCompositor::iterator &begin,
+ const QDeclarativeListCompositor::iterator &end)
+{
+ bool minimal = true;
+ int index = 0;
+
+ for (const QDeclarativeListCompositor::Range *range = begin->next; range != end; range = range->next, ++index) {
+ if (range->previous->list == range->list
+ && range->previous->flags == (range->flags & ~QDeclarativeListCompositor::AppendFlag)
+ && range->previous->end() == range->index) {
+ qWarning() << index << "Consecutive ranges";
+ qWarning() << *range->previous;
+ qWarning() << *range;
+ minimal = false;
+ }
+ }
+
+ return minimal;
+}
+
+#endif
+
+#ifdef QT_DECLARATIVE_VERIFY_INTEGRITY
+static bool qt_printInfo(const QDeclarativeListCompositor &compositor)
+{
+ qWarning() << compositor;
+ return true;
+}
+
+static bool qt_verifyIntegrity(
+ const QDeclarativeListCompositor::iterator &begin,
+ const QDeclarativeListCompositor::iterator &end,
+ const QDeclarativeListCompositor::iterator &cachedIt)
+{
+ bool valid = true;
+
+ int index = 0;
+ QDeclarativeListCompositor::iterator it;
+ for (it = begin; *it != *end; *it = it->next) {
+ if (it->count == 0 && !it->append()) {
+ qWarning() << index << "Empty non-append range";
+ valid = false;
+ }
+ if (it->count < 0) {
+ qWarning() << index << "Negative count";
+ valid = false;
+ }
+ if (it->list && it->flags != QDeclarativeListCompositor::CacheFlag && it->index < 0) {
+ qWarning() << index <<"Negative index";
+ valid = false;
+ }
+ if (it->previous->next != it.range) {
+ qWarning() << index << "broken list: it->previous->next != it.range";
+ valid = false;
+ }
+ if (it->next->previous != it.range) {
+ qWarning() << index << "broken list: it->next->previous != it.range";
+ valid = false;
+ }
+ if (*it == *cachedIt) {
+ for (int i = 0; i < end.groupCount; ++i) {
+ int groupIndex = it.index[i];
+ if (cachedIt->flags & (1 << i))
+ groupIndex += cachedIt.offset;
+ if (groupIndex != cachedIt.index[i]) {
+ qWarning() << index
+ << "invalid cached index"
+ << QDeclarativeListCompositor::Group(i)
+ << "Expected:"
+ << groupIndex
+ << "Actual"
+ << cachedIt.index[i]
+ << cachedIt;
+ valid = false;
+ }
+ }
+ }
+ it.incrementIndexes(it->count);
+ ++index;
+ }
+
+ for (int i = 0; i < end.groupCount; ++i) {
+ if (end.index[i] != it.index[i]) {
+ qWarning() << "Group" << i << "count invalid. Expected:" << end.index[i] << "Actual:" << it.index[i];
+ valid = false;
+ }
+ }
+ return valid;
+}
+#endif
+
+#if defined(QT_DECLARATIVE_VERIFY_MINIMAL)
+# define QT_DECLARATIVE_VERIFY_LISTCOMPOSITOR Q_ASSERT(!(!(qt_verifyIntegrity(iterator(m_ranges.next, 0, Default, m_groupCount), m_end, m_cacheIt) \
+ && qt_verifyMinimal(iterator(m_ranges.next, 0, Default, m_groupCount), m_end)) \
+ && qt_printInfo(*this)));
+#elif defined(QT_DECLARATIVE_VERIFY_INTEGRITY)
+# define QT_DECLARATIVE_VERIFY_LISTCOMPOSITOR Q_ASSERT(!(!qt_verifyIntegrity(iterator(m_ranges.next, 0, Default, m_groupCount), m_end, m_cacheIt) \
+ && qt_printInfo(*this)));
+#else
+# define QT_DECLARATIVE_VERIFY_LISTCOMPOSITOR
+#endif
+
+//#define QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(args) qDebug() << m_end.index[1] << m_end.index[0] << Q_FUNC_INFO args;
+#define QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(args)
+
+QDeclarativeListCompositor::iterator &QDeclarativeListCompositor::iterator::operator ++()
+{
+ while (!(range->flags & groupFlag)) {
+ incrementIndexes(range->count - offset);
+ offset = 0;
+ range = range->next;
+ }
+ incrementIndexes(1);
+ if (++offset == range->count) {
+ while (!((range = range->next)->flags & groupFlag))
+ incrementIndexes(range->count);
+ offset = 0;
+ }
+ return *this;
+}
+
+QDeclarativeListCompositor::iterator &QDeclarativeListCompositor::iterator::operator +=(int difference)
+{
+ Q_ASSERT(difference >= 0);
+ while (!(range->flags & groupFlag)) {
+ incrementIndexes(range->count - offset);
+ offset = 0;
+ range = range->next;
+ }
+ decrementIndexes(offset);
+ offset += difference;
+ while (offset >= range->count || !(range->flags & groupFlag)) {
+ if (range->flags & groupFlag)
+ offset -= range->count;
+ incrementIndexes(range->count);
+ range = range->next;
+ }
+ incrementIndexes(offset);
+ return *this;
+}
+
+QDeclarativeListCompositor::iterator &QDeclarativeListCompositor::iterator::operator -=(int difference)
+{
+ Q_ASSERT(difference >= 0);
+ while (!(range->flags & groupFlag)) {
+ decrementIndexes(offset);
+ range = range->previous;
+ offset = range->count;
+ }
+ decrementIndexes(offset);
+ offset -= difference;
+ while (offset < 0) {
+ range = range->previous;
+ if (range->flags & groupFlag)
+ offset += range->count;
+ decrementIndexes(range->count);
+ }
+ incrementIndexes(offset);
+ return *this;
+}
+
+QDeclarativeListCompositor::insert_iterator &QDeclarativeListCompositor::insert_iterator::operator ++()
+{
+ while (!(range->flags & groupFlag)) {
+ incrementIndexes(range->count - offset);
+ offset = 0;
+ range = range->next;
+ }
+ incrementIndexes(1);
+ if (++offset == range->count && !range->append()) {
+ while (!((range = range->next)->flags & groupFlag) ){
+ incrementIndexes(range->count);
+ }
+ offset = 0;
+ }
+ return *this;
+}
+
+QDeclarativeListCompositor::insert_iterator &QDeclarativeListCompositor::insert_iterator::operator +=(int difference)
+{
+ Q_ASSERT(difference >= 0);
+ while (!(range->flags & groupFlag) && range->flags & GroupMask) {
+ incrementIndexes(range->count - offset);
+ offset = 0;
+ range = range->next;
+ }
+ decrementIndexes(offset);
+ offset += difference;
+ while (offset > range->count
+ || (offset == range->count && !range->append() && offset > 0)
+ || (!(range->flags & groupFlag) && offset > 0)) {
+ if (range->flags & groupFlag)
+ offset -= range->count;
+ incrementIndexes(range->count);
+ range = range->next;
+ }
+ incrementIndexes(offset);
+ return *this;
+}
+
+QDeclarativeListCompositor::insert_iterator &QDeclarativeListCompositor::insert_iterator::operator -=(int difference)
+{
+ Q_ASSERT(difference >= 0);
+ while (!(range->flags & groupFlag) && range->flags & GroupMask) {
+ decrementIndexes(offset);
+ range = range->previous;
+ offset = range->count;
+ }
+ decrementIndexes(offset);
+ offset -= difference;
+ while (offset < 0) {
+ range = range->previous;
+ if (range->flags & groupFlag)
+ offset += range->count;
+ decrementIndexes(range->count);
+ }
+ incrementIndexes(offset);
+ for (Range *previous = range->previous; offset == 0 && previous->prepend(); previous = previous->previous) {
+ if (previous->append() && previous->inGroup()) {
+ offset = previous->count;
+ range = previous;
+ } else if (!previous->inGroup()) {
+ break;
+ }
+ }
+
+ return *this;
+}
+
+QDeclarativeListCompositor::QDeclarativeListCompositor()
+ : m_end(m_ranges.next, 0, Default, 2)
+ , m_cacheIt(m_end)
+ , m_groupCount(2)
+ , m_defaultFlags(PrependFlag | DefaultFlag)
+ , m_removeFlags(AppendFlag | PrependFlag | GroupMask)
+{
+}
+
+QDeclarativeListCompositor::~QDeclarativeListCompositor()
+{
+ for (Range *next, *range = m_ranges.next; range != &m_ranges; range = next) {
+ next = range->next;
+ delete range;
+ }
+}
+
+inline QDeclarativeListCompositor::Range *QDeclarativeListCompositor::insert(
+ Range *before, void *list, int index, int count, int flags)
+{
+ return new Range(before, list, index, count, flags);
+}
+
+inline QDeclarativeListCompositor::Range *QDeclarativeListCompositor::erase(
+ Range *range)
+{
+ Range *next = range->next;
+ next->previous = range->previous;
+ next->previous->next = range->next;
+ delete range;
+ return next;
+}
+
+void QDeclarativeListCompositor::setGroupCount(int count)
+{
+ m_groupCount = count;
+ m_end = iterator(&m_ranges, 0, Default, m_groupCount);
+ m_cacheIt = m_end;
+}
+
+int QDeclarativeListCompositor::count(Group group) const
+{
+ return m_end.index[group];
+}
+
+QDeclarativeListCompositor::iterator QDeclarativeListCompositor::find(Group group, int index)
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< group << index)
+ Q_ASSERT(index >=0 && index < count(group));
+ if (m_cacheIt == m_end) {
+ m_cacheIt = iterator(m_ranges.next, 0, group, m_groupCount);
+ m_cacheIt += index;
+ } else {
+ const int offset = index - m_cacheIt.index[group];
+ m_cacheIt.setGroup(group);
+ if (offset > 0) {
+ m_cacheIt += offset;
+ } else if (offset < 0) {
+ m_cacheIt -= -offset;
+ } else if (offset == 0) {
+ m_cacheIt -= 0;
+ m_cacheIt += 0;
+ }
+ }
+ Q_ASSERT(m_cacheIt.index[group] == index);
+ Q_ASSERT(m_cacheIt->inGroup(group));
+ QT_DECLARATIVE_VERIFY_LISTCOMPOSITOR
+ return m_cacheIt;
+}
+
+QDeclarativeListCompositor::iterator QDeclarativeListCompositor::find(Group group, int index) const
+{
+ return const_cast<QDeclarativeListCompositor *>(this)->find(group, index);
+}
+
+QDeclarativeListCompositor::insert_iterator QDeclarativeListCompositor::findInsertPosition(Group group, int index)
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< group << index)
+ Q_ASSERT(index >=0 && index <= count(group));
+ insert_iterator it;
+ if (m_cacheIt == m_end) {
+ m_cacheIt = iterator(m_ranges.next, 0, group, m_groupCount);
+ it += index;
+ } else {
+ const int offset = index - m_cacheIt.index[group];
+ it = m_cacheIt;
+ it.setGroup(group);
+ if (offset > 0) {
+ it += offset;
+ } else if (offset < 0) {
+ it -= -offset;
+ } else if (offset == 0) {
+ it -= 0;
+ it += 0;
+ }
+ }
+ Q_ASSERT(it.index[group] == index);
+ return it;
+}
+
+QDeclarativeListCompositor::iterator QDeclarativeListCompositor::begin(Group group)
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< group)
+ m_cacheIt = iterator(m_ranges.next, 0, group, m_groupCount);
+ m_cacheIt += 0;
+ return m_cacheIt;
+}
+
+void QDeclarativeListCompositor::append(
+ void *list, int index, int count, int flags, QVector<Insert> *inserts)
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< list << index << count << flags)
+ insert(m_end, list, index, count, flags, inserts);
+}
+
+void QDeclarativeListCompositor::insert(
+ Group group, int before, void *list, int index, int count, int flags, QVector<Insert> *inserts)
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< group << before << list << index << count << flags)
+ insert(findInsertPosition(group, before), list, index, count, flags, inserts);
+}
+
+QDeclarativeListCompositor::iterator QDeclarativeListCompositor::insert(
+ iterator before, void *list, int index, int count, int flags, QVector<Insert> *inserts)
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< before << list << index << count << flags)
+ if (inserts) {
+ inserts->append(Insert(before, count, flags & GroupMask));
+ }
+ if (before.offset > 0) {
+ *before = insert(
+ *before, before->list, before->index, before.offset, before->flags & ~AppendFlag)->next;
+ before->index += before.offset;
+ before->count -= before.offset;
+ before.offset = 0;
+ }
+
+ if (!(flags & AppendFlag) && *before != m_ranges.next
+ && before->previous->list == list
+ && before->previous->flags == flags
+ && (!list || before->previous->end() == index)) {
+ before->previous->count += count;
+ before.incrementIndexes(count, flags);
+ } else {
+ *before = insert(*before, list, index, count, flags);
+ before.offset = 0;
+ }
+
+ if (!(flags & AppendFlag) && before->next != &m_ranges
+ && before->list == before->next->list
+ && before->flags == before->next->flags
+ && (!list || before->end() == before->next->index)) {
+ before->next->index = before->index;
+ before->next->count += before->count;
+ *before = erase(*before);
+ }
+
+ m_end.incrementIndexes(count, flags);
+ m_cacheIt = before;
+ QT_DECLARATIVE_VERIFY_LISTCOMPOSITOR
+ return before;
+}
+
+void QDeclarativeListCompositor::setFlags(
+ Group group, int index, int count, int flags, QVector<Insert> *inserts)
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< group << index << count << flags)
+ setFlags(find(group, index), count, flags, inserts);
+}
+
+void QDeclarativeListCompositor::setFlags(
+ iterator from, int count, int flags, QVector<Insert> *inserts)
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< from << count << flags)
+ if (!flags || !count)
+ return;
+
+ if (from.offset > 0) {
+ *from = insert(*from, from->list, from->index, from.offset, from->flags & ~AppendFlag)->next;
+ from->index += from.offset;
+ from->count -= from.offset;
+ from.offset = 0;
+ }
+
+ for (; count > 0; *from = from->next) {
+ if (from != from.group) {
+ from.incrementIndexes(from->count);
+ continue;
+ }
+ const int difference = qMin(count, from->count);
+ count -= difference;
+
+ const int insertFlags = ~from->flags & flags;
+ const int setFlags = (from->flags | flags) & ~AppendFlag;
+ if (insertFlags && inserts)
+ inserts->append(Insert(from, difference, insertFlags | (from->flags & CacheFlag)));
+ m_end.incrementIndexes(difference, insertFlags);
+ from.incrementIndexes(difference, setFlags);
+
+ if (from->previous != &m_ranges
+ && from->previous->list == from->list
+ && (!from->list || from->previous->end() == from->index)
+ && from->previous->flags == setFlags) {
+ from->previous->count += difference;
+ from->index += difference;
+ from->count -= difference;
+ if (from->count == 0) {
+ if (from->append())
+ from->previous->flags |= AppendFlag;
+ *from = erase(*from)->previous;
+ continue;
+ }
+ } else if (difference < from->count) {
+ *from = insert(*from, from->list, from->index, difference, setFlags)->next;
+ from->index += difference;
+ from->count -= difference;
+ } else {
+ from->flags |= flags;
+ continue;
+ }
+ from.incrementIndexes(from->count);
+ }
+
+ if (from->previous != &m_ranges
+ && from->previous->list == from->list
+ && (!from->list || from->previous->end() == from->index)
+ && from->previous->flags == (from->flags & ~AppendFlag)) {
+ from.offset = from->previous->count;
+ from->previous->count += from->count;
+ from->previous->flags = from->flags;
+ *from = erase(*from)->previous;
+ }
+ m_cacheIt = from;
+ QT_DECLARATIVE_VERIFY_LISTCOMPOSITOR
+}
+
+void QDeclarativeListCompositor::clearFlags(
+ Group group, int index, int count, int flags, QVector<Remove> *removes)
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< group << index << count << flags)
+ clearFlags(find(group, index), count, flags, removes);
+}
+
+void QDeclarativeListCompositor::clearFlags(
+ iterator from, int count, int flags, QVector<Remove> *removes)
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< from << count << flags)
+ if (!flags || !count)
+ return;
+
+ const bool clearCache = flags & CacheFlag;
+
+ if (from.offset > 0) {
+ *from = insert(*from, from->list, from->index, from.offset, from->flags & ~AppendFlag)->next;
+ from->index += from.offset;
+ from->count -= from.offset;
+ from.offset = 0;
+ }
+
+ for (; count > 0; *from = from->next) {
+ if (from != from.group) {
+ from.incrementIndexes(from->count);
+ continue;
+ }
+ const int difference = qMin(count, from->count);
+ count -= difference;
+
+ const int removeFlags = from->flags & flags & ~(AppendFlag | PrependFlag);
+ const int clearedFlags = from->flags & ~(flags | AppendFlag);
+ if (removeFlags && removes) {
+ const int maskedFlags = clearCache
+ ? (removeFlags & ~CacheFlag)
+ : (removeFlags | (from->flags & CacheFlag));
+ if (maskedFlags)
+ removes->append(Remove(from, difference, maskedFlags));
+ }
+ m_end.decrementIndexes(difference, removeFlags);
+ from.incrementIndexes(difference, clearedFlags);
+
+ if (from->previous != &m_ranges
+ && from->previous->list == from->list
+ && (!from->list || clearedFlags == CacheFlag || from->previous->end() == from->index)
+ && from->previous->flags == clearedFlags) {
+ from->previous->count += difference;
+ from->index += difference;
+ from->count -= difference;
+ if (from->count == 0) {
+ if (from->append())
+ from->previous->flags |= AppendFlag;
+ *from = erase(*from)->previous;
+ } else {
+ from.incrementIndexes(from->count);
+ }
+ } else if (difference < from->count) {
+ if (clearedFlags)
+ *from = insert(*from, from->list, from->index, difference, clearedFlags)->next;
+ from->index += difference;
+ from->count -= difference;
+ from.incrementIndexes(from->count);
+ } else if (clearedFlags) {
+ from->flags &= ~flags;
+ } else {
+ *from = erase(*from)->previous;
+ }
+ }
+
+ if (*from != &m_ranges && from->previous != &m_ranges
+ && from->previous->list == from->list
+ && (!from->list || from->previous->end() == from->index)
+ && from->previous->flags == (from->flags & ~AppendFlag)) {
+ from.offset = from->previous->count;
+ from->previous->count += from->count;
+ from->previous->flags = from->flags;
+ *from = erase(*from)->previous;
+ }
+ m_cacheIt = from;
+ QT_DECLARATIVE_VERIFY_LISTCOMPOSITOR
+}
+
+void QDeclarativeListCompositor::removeList(void *list, QVector<Remove> *removes, bool destroyed)
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< list << destroyed)
+ for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
+ if (it->list == list) {
+ const int flags = it->flags & (GroupMask | CacheFlag);
+ if (flags) {
+ removes->append(Remove(it, it->count, flags));
+ m_end.decrementIndexes(it->count, flags);
+ }
+ if (destroyed)
+ it->list = 0;
+ if (it->inCache()) {
+ it->flags = CacheFlag;
+ it.cacheIndex += it->count;
+ } else {
+ *it = erase(*it)->previous;
+ }
+ } else {
+ it.incrementIndexes(it->count);
+ }
+ }
+ m_cacheIt = m_end;
+ QT_DECLARATIVE_VERIFY_LISTCOMPOSITOR
+}
+
+bool QDeclarativeListCompositor::verifyMoveTo(
+ Group fromGroup, int from, Group toGroup, int to, int count) const
+{
+ if (fromGroup != toGroup) {
+ // determine how many items from the destination group intersect with the source group.
+ iterator fromIt = find(fromGroup, from);
+
+ int intersectingCount = 0;
+
+ for (; count > 0; *fromIt = fromIt->next) {
+ if (*fromIt == &m_ranges)
+ return false;
+ if (!fromIt->inGroup(fromGroup))
+ continue;
+ if (fromIt->inGroup(toGroup))
+ intersectingCount += qMin(count, fromIt->count - fromIt.offset);
+ count -= fromIt->count - fromIt.offset;
+ fromIt.offset = 0;
+ }
+ count = intersectingCount;
+ }
+
+ return to >= 0 && to + count <= m_end.index[toGroup];
+}
+
+void QDeclarativeListCompositor::move(
+ Group fromGroup,
+ int from,
+ Group toGroup,
+ int to,
+ int count,
+ QVector<Remove> *removes,
+ QVector<Insert> *inserts)
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< fromGroup << from << toGroup << to << count)
+ Q_ASSERT(count != 0);
+ Q_ASSERT(from >=0 && from + count <= m_end.index[toGroup]);
+ Q_ASSERT(verifyMoveTo(fromGroup, from, toGroup, to, count));
+
+ iterator fromIt = find(fromGroup, from);
+ if (fromIt.offset > 0) {
+ *fromIt = insert(
+ *fromIt, fromIt->list, fromIt->index, fromIt.offset, fromIt->flags & ~AppendFlag)->next;
+ fromIt->index += fromIt.offset;
+ fromIt->count -= fromIt.offset;
+ fromIt.offset = 0;
+ }
+
+ Range movedFlags;
+ for (int moveId = 0; count > 0;) {
+ if (fromIt != fromIt.group) {
+ fromIt.incrementIndexes(fromIt->count);
+ *fromIt = fromIt->next;
+ continue;
+ }
+ int difference = qMin(count, fromIt->count);
+
+ new Range(
+ &movedFlags,
+ fromIt->list,
+ fromIt->index,
+ difference,
+ fromIt->flags & ~(PrependFlag | AppendFlag));
+ if (removes)
+ removes->append(Remove(fromIt, difference, fromIt->flags, moveId++));
+ count -= difference;
+ fromIt->count -= difference;
+
+ int removeIndex = fromIt->index;
+ if (fromIt->prepend()
+ && fromIt->previous != &m_ranges
+ && fromIt->previous->flags == PrependFlag
+ && fromIt->previous->list == fromIt->list
+ && fromIt->previous->end() == fromIt->index) {
+ fromIt->previous->count += difference;
+ } else if (fromIt->prepend()) {
+ *fromIt = insert(*fromIt, fromIt->list, removeIndex, difference, PrependFlag)->next;
+ }
+ fromIt->index += difference;
+
+ if (fromIt->count == 0) {
+ if (fromIt->append())
+ fromIt->previous->flags |= AppendFlag;
+ *fromIt = erase(*fromIt);
+ } else if (count > 0) {
+ *fromIt = fromIt->next;
+ }
+ }
+
+ if (*fromIt != m_ranges.next
+ && *fromIt != &m_ranges
+ && fromIt->previous->list == fromIt->list
+ && (!fromIt->list || fromIt->previous->end() == fromIt->index)
+ && fromIt->previous->flags == (fromIt->flags & ~AppendFlag)) {
+ if (fromIt == fromIt.group)
+ fromIt.offset = fromIt->previous->count;
+ fromIt.offset = fromIt->previous->count;
+ fromIt->previous->count += fromIt->count;
+ fromIt->previous->flags = fromIt->flags;
+ *fromIt = erase(*fromIt)->previous;
+ }
+
+ insert_iterator toIt = fromIt;
+ toIt.setGroup(toGroup);
+ const int difference = to - toIt.index[toGroup];
+ if (difference > 0)
+ toIt += difference;
+ else
+ toIt -= -difference;
+
+ if (toIt.offset > 0) {
+ *toIt = insert(*toIt, toIt->list, toIt->index, toIt.offset, toIt->flags & ~AppendFlag)->next;
+ toIt->index += toIt.offset;
+ toIt->count -= toIt.offset;
+ toIt.offset = 0;
+ }
+
+ for (Range *range = movedFlags.previous; range != &movedFlags; range = range->previous) {
+ if (*toIt != &m_ranges
+ && range->list == toIt->list
+ && (!range->list || range->end() == toIt->index)
+ && range->flags == (toIt->flags & ~AppendFlag)) {
+ toIt->index -= range->count;
+ toIt->count += range->count;
+ } else {
+ *toIt = insert(*toIt, range->list, range->index, range->count, range->flags);
+ }
+ }
+
+ if (*toIt != m_ranges.next
+ && toIt->previous->list == toIt->list
+ && (!toIt->list || (toIt->previous->end() == toIt->index && toIt->previous->flags == (toIt->flags & ~AppendFlag)))) {
+ toIt.offset = toIt->previous->count;
+ toIt->previous->count += toIt->count;
+ toIt->previous->flags = toIt->flags;
+ *toIt = erase(*toIt)->previous;
+ }
+ Insert insert(toIt, 0, 0, 0);
+ for (Range *next, *range = movedFlags.next; range != &movedFlags; range = next) {
+ insert.count = range->count;
+ insert.flags = range->flags;
+ if (inserts)
+ inserts->append(insert);
+ for (int i = 0; i < m_groupCount; ++i) {
+ if (insert.inGroup(i))
+ insert.index[i] += range->count;
+ }
+ ++insert.moveId;
+ next = range->next;
+ delete range;
+ }
+
+ m_cacheIt = toIt;
+ QT_DECLARATIVE_VERIFY_LISTCOMPOSITOR
+}
+
+void QDeclarativeListCompositor::clear()
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR( )
+ for (Range *range = m_ranges.next; range != &m_ranges; range = erase(range)) {}
+ m_end = iterator(m_ranges.next, 0, Default, m_groupCount);
+ m_cacheIt = m_end;
+}
+
+void QDeclarativeListCompositor::listItemsInserted(
+ QVector<Insert> *translatedInsertions,
+ void *list,
+ const QVector<QDeclarativeChangeSet::Insert> &insertions,
+ const QVector<MovedFlags> *movedFlags)
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< list << insertions)
+ for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
+ if (it->list != list || it->flags == CacheFlag) {
+ it.incrementIndexes(it->count);
+ continue;
+ } else if (it->flags & MovedFlag) {
+ it->flags &= ~MovedFlag;
+ it.incrementIndexes(it->count);
+ continue;
+ }
+ foreach (const QDeclarativeChangeSet::Insert &insertion, insertions) {
+ int offset = insertion.index - it->index;
+ if ((offset > 0 && offset < it->count)
+ || (offset == 0 && it->prepend())
+ || (offset == it->count && it->append())) {
+ if (it->prepend()) {
+ int flags = m_defaultFlags;
+ if (insertion.isMove()) {
+ for (QVector<MovedFlags>::const_iterator move = movedFlags->begin();
+ move != movedFlags->end();
+ ++move) {
+ if (move->moveId == insertion.moveId) {
+ flags = move->flags;
+ break;
+ }
+ }
+ }
+ if (flags & ~(AppendFlag | PrependFlag)) {
+ Insert translatedInsert(it, insertion.count, flags, insertion.moveId);
+ for (int i = 0; i < m_groupCount; ++i) {
+ if (it->inGroup(i))
+ translatedInsert.index[i] += offset;
+ }
+ translatedInsertions->append(translatedInsert);
+ }
+ if ((it->flags & ~AppendFlag) == flags) {
+ it->count += insertion.count;
+ } else {
+ if (offset > 0) {
+ it.incrementIndexes(offset);
+ *it = insert(*it, it->list, it->index, offset, it->flags & ~AppendFlag)->next;
+ }
+ *it = insert(*it, it->list, insertion.index, insertion.count, flags)->next;
+ it.incrementIndexes(insertion.count, flags);
+ it->index += offset + insertion.count;
+ it->count -= offset;
+ }
+ m_end.incrementIndexes(insertion.count, flags);
+ } else {
+ if (offset > 0) {
+ *it = insert(*it, it->list, it->index, offset, it->flags)->next;
+ it->index += offset;
+ it->count -= offset;
+ }
+ it->index += insertion.count;
+ }
+ } else if (offset <= 0) {
+ it->index += insertion.count;
+ }
+ }
+ it.incrementIndexes(it->count);
+ }
+ m_cacheIt = m_end;
+ QT_DECLARATIVE_VERIFY_LISTCOMPOSITOR
+}
+
+void QDeclarativeListCompositor::listItemsInserted(
+ void *list, int index, int count, QVector<Insert> *translatedInsertions)
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< list << index << count)
+ Q_ASSERT(count > 0);
+
+ QVector<QDeclarativeChangeSet::Insert> insertions;
+ insertions.append(QDeclarativeChangeSet::Insert(index, count));
+
+ listItemsInserted(translatedInsertions, list, insertions);
+}
+
+void QDeclarativeListCompositor::listItemsRemoved(
+ QVector<Remove> *translatedRemovals,
+ void *list,
+ QVector<QDeclarativeChangeSet::Remove> *removals,
+ QVector<QDeclarativeChangeSet::Insert> *insertions,
+ QVector<MovedFlags> *movedFlags, int moveId)
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< list << *removals)
+
+ for (iterator it(m_ranges.next, 0, Default, m_groupCount);
+ *it != &m_ranges && !removals->isEmpty();
+ *it = it->next) {
+ if (it->list != list || it->flags == CacheFlag) {
+ it.incrementIndexes(it->count);
+ continue;
+ }
+ bool removed = false;
+ for (QVector<QDeclarativeChangeSet::Remove>::iterator removal = removals->begin();
+ !removed && removal != removals->end();
+ ++removal) {
+ int relativeIndex = removal->index - it->index;
+ int itemsRemoved = removal->count;
+ if (relativeIndex + removal->count > 0 && relativeIndex < it->count) {
+ const int offset = qMax(0, relativeIndex);
+ int removeCount = qMin(it->count, relativeIndex + removal->count) - offset;
+ it->count -= removeCount;
+ int removeFlags = it->flags & m_removeFlags;
+ Remove translatedRemoval(it, removeCount, it->flags);
+ for (int i = 0; i < m_groupCount; ++i) {
+ if (it->inGroup(i))
+ translatedRemoval.index[i] += offset;
+ }
+ if (removal->isMove()) {
+ QVector<QDeclarativeChangeSet::Insert>::iterator insertion = insertions->begin();
+ for (; insertion != insertions->end() && insertion->moveId != removal->moveId;
+ ++insertion) {}
+ Q_ASSERT(insertion != insertions->end());
+ Q_ASSERT(insertion->count == removal->count);
+
+ if (relativeIndex < 0) {
+ int splitMoveId = ++moveId;
+ removal = removals->insert(removal, QDeclarativeChangeSet::Remove(
+ removal->index, -relativeIndex, splitMoveId));
+ ++removal;
+ removal->count -= -relativeIndex;
+ insertion = insertions->insert(insertion, QDeclarativeChangeSet::Insert(
+ insertion->index, -relativeIndex, splitMoveId));
+ ++insertion;
+ insertion->index += -relativeIndex;
+ insertion->count -= -relativeIndex;
+ }
+
+ if (it->prepend()) {
+ removeFlags |= it->flags & CacheFlag;
+ translatedRemoval.moveId = ++moveId;
+ movedFlags->append(MovedFlags(moveId, it->flags & ~AppendFlag));
+
+ removal = removals->insert(removal, QDeclarativeChangeSet::Remove(
+ removal->index, removeCount, translatedRemoval.moveId));
+ ++removal;
+ insertion = insertions->insert(insertion, QDeclarativeChangeSet::Insert(
+ insertion->index, removeCount, translatedRemoval.moveId));
+ ++insertion;
+
+ removal->count -= removeCount;
+ insertion->index += removeCount;
+ insertion->count -= removeCount;
+ if (removal->count == 0) {
+ removal = removals->erase(removal);
+ insertion = insertions->erase(insertion);
+ --removal;
+ --insertion;
+ }
+ } else {
+ if (offset > 0) {
+ *it = insert(*it, it->list, it->index, offset, it->flags & ~AppendFlag)->next;
+ it->index += offset;
+ it->count -= offset;
+ it.incrementIndexes(offset);
+ }
+ if (it->previous != &m_ranges
+ && it->previous->list == it->list
+ && it->end() == insertion->index
+ && it->previous->flags == (it->flags | MovedFlag)) {
+ it->previous->count += removeCount;
+ } else {
+ *it = insert(*it, it->list, insertion->index, removeCount, it->flags | MovedFlag)->next;
+ }
+ translatedRemoval.flags = 0;
+ removeFlags = 0;
+ }
+ } else if (it->inCache()) {
+ if (offset > 0) {
+ *it = insert(*it, it->list, it->index, offset, it->flags & ~AppendFlag)->next;
+ it->index += offset;
+ it->count -= offset;
+ it.incrementIndexes(offset);
+ }
+ if (it->previous != &m_ranges
+ && it->previous->list == it->list
+ && it->previous->flags == CacheFlag) {
+ it->previous->count += removeCount;
+ } else {
+ *it = insert(*it, it->list, -1, removeCount, CacheFlag)->next;
+ }
+ }
+ if (removeFlags & GroupMask)
+ translatedRemovals->append(translatedRemoval);
+ m_end.decrementIndexes(removeCount, removeFlags);
+ if (it->count == 0 && !it->append()) {
+ *it = erase(*it)->previous;
+ removed = true;
+ } else if (relativeIndex <= 0) {
+ it->index = removal->index;
+ }
+ } else if (relativeIndex < 0) {
+ it->index -= itemsRemoved;
+ }
+ }
+ if (it->next != &m_ranges
+ && it->list == it->next->list
+ && (it->flags == CacheFlag || it->end() == it->next->index)
+ && it->flags == (it->next->flags & ~AppendFlag)) {
+ it->count += it->next->count;
+ it->flags = it->next->flags;
+ erase(it->next);
+ *it = it->previous;
+ } else if (!removed) {
+ it.incrementIndexes(it->count);
+ }
+ }
+ m_cacheIt = m_end;
+ QT_DECLARATIVE_VERIFY_LISTCOMPOSITOR
+}
+
+void QDeclarativeListCompositor::listItemsRemoved(
+ void *list, int index, int count, QVector<Remove> *translatedRemovals)
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< list << index << count)
+ Q_ASSERT(count >= 0);
+
+ QVector<QDeclarativeChangeSet::Remove> removals;
+ removals.append(QDeclarativeChangeSet::Remove(index, count));
+ listItemsRemoved(translatedRemovals, list, &removals, 0, 0, 0);
+}
+
+void QDeclarativeListCompositor::listItemsMoved(
+ void *list,
+ int from,
+ int to,
+ int count,
+ QVector<Remove> *translatedRemovals,
+ QVector<Insert> *translatedInsertions)
+{
+
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< list << from << to << count)
+ Q_ASSERT(count >= 0);
+
+ QVector<QDeclarativeChangeSet::Remove> removals;
+ QVector<QDeclarativeChangeSet::Insert> insertions;
+ QVector<MovedFlags> movedFlags;
+ removals.append(QDeclarativeChangeSet::Remove(from, count, 0));
+ insertions.append(QDeclarativeChangeSet::Insert(to, count, 0));
+
+ listItemsRemoved(translatedRemovals, list, &removals, &insertions, &movedFlags, 0);
+ listItemsInserted(translatedInsertions, list, insertions, &movedFlags);
+}
+
+void QDeclarativeListCompositor::listItemsChanged(
+ QVector<Change> *translatedChanges,
+ void *list,
+ const QVector<QDeclarativeChangeSet::Change> &changes)
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< list << changes)
+ for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
+ if (it->list != list || it->flags == CacheFlag) {
+ it.incrementIndexes(it->count);
+ continue;
+ } else if (!it->inGroup()) {
+ continue;
+ }
+ foreach (const QDeclarativeChangeSet::Change &change, changes) {
+ const int offset = change.index - it->index;
+ if (offset + change.count > 0 && offset < it->count) {
+ const int changeOffset = qMax(0, offset);
+ const int changeCount = qMin(it->count, offset + change.count) - changeOffset;
+
+ Change translatedChange(it, changeCount, it->flags);
+ for (int i = 0; i < m_groupCount; ++i) {
+ if (it->inGroup(i))
+ translatedChange.index[i] += changeOffset;
+ }
+ translatedChanges->append(translatedChange);
+ }
+ }
+ it.incrementIndexes(it->count);
+ }
+}
+
+void QDeclarativeListCompositor::listItemsChanged(
+ void *list, int index, int count, QVector<Change> *translatedChanges)
+{
+ QT_DECLARATIVE_TRACE_LISTCOMPOSITOR(<< list << index << count)
+ Q_ASSERT(count >= 0);
+ QVector<QDeclarativeChangeSet::Change> changes;
+ changes.append(QDeclarativeChangeSet::Change(index, count));
+ listItemsChanged(translatedChanges, list, changes);
+}
+
+void QDeclarativeListCompositor::listChanged(
+ void *list,
+ const QDeclarativeChangeSet &changeSet,
+ QVector<Remove> *translatedRemovals,
+ QVector<Insert> *translatedInsertions,
+ QVector<Change> *translatedChanges)
+{
+ QVector<QDeclarativeChangeSet::Remove> removals = changeSet.removes();
+ QVector<QDeclarativeChangeSet::Insert> insertions = changeSet.inserts();
+ QVector<MovedFlags> movedFlags;
+ listItemsRemoved(translatedRemovals, list, &removals, &insertions, &movedFlags, changeSet.moveCounter());
+ listItemsInserted(translatedInsertions, list, insertions, &movedFlags);
+ listItemsChanged(translatedChanges, list, changeSet.changes());
+}
+
+void QDeclarativeListCompositor::transition(
+ Group from,
+ Group to,
+ QVector<QDeclarativeChangeSet::Remove> *removes,
+ QVector<QDeclarativeChangeSet::Insert> *inserts)
+{
+ int removeCount = 0;
+ for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
+ if (it == from && it != to) {
+ removes->append(QDeclarativeChangeSet::Remove(it.index[from]- removeCount, it->count));
+ removeCount += it->count;
+ } else if (it != from && it == to) {
+ inserts->append(QDeclarativeChangeSet::Insert(it.index[to], it->count));
+ }
+ it.incrementIndexes(it->count);
+ }
+}
+
+QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::Group &group)
+{
+ switch (group) {
+ case QDeclarativeListCompositor::Cache: return debug << "Cache";
+ case QDeclarativeListCompositor::Default: return debug << "Default";
+ default: return (debug.nospace() << "Group" << int(group)).space();
+ }
+
+}
+
+QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::Range &range)
+{
+ (debug.nospace()
+ << "Range("
+ << range.list) << " "
+ << range.index << " "
+ << range.count << " "
+ << (range.append() ? "A" : "0")
+ << (range.prepend() ? "P" : "0");
+ for (int i = QDeclarativeListCompositor::MaximumGroupCount - 1; i >= 2; --i)
+ debug << (range.inGroup(i) ? "1" : "0");
+ return (debug
+ << (range.inGroup(QDeclarativeListCompositor::Default) ? "D" : "0")
+ << (range.inGroup(QDeclarativeListCompositor::Cache) ? "C" : "0"));
+}
+
+static void qt_print_indexes(QDebug &debug, int count, const int *indexes)
+{
+ for (int i = count - 1; i >= 0; --i)
+ debug << indexes[i];
+}
+
+QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::iterator &it)
+{
+ (debug.nospace() << "iterator(" << it.group).space() << "offset:" << it.offset;
+ qt_print_indexes(debug, it.groupCount, it.index);
+ return ((debug << **it).nospace() << ")").space();
+}
+
+static QDebug qt_print_change(QDebug debug, const char *name, const QDeclarativeListCompositor::Change &change)
+{
+ debug.nospace() << name << "(" << change.moveId << " " << change.count << " ";
+ for (int i = QDeclarativeListCompositor::MaximumGroupCount - 1; i >= 2; --i)
+ debug << (change.inGroup(i) ? "1" : "0");
+ debug << (change.inGroup(QDeclarativeListCompositor::Default) ? "D" : "0")
+ << (change.inGroup(QDeclarativeListCompositor::Cache) ? "C" : "0");
+ int i = QDeclarativeListCompositor::MaximumGroupCount - 1;
+ for (; i >= 0 && !change.inGroup(i); --i) {}
+ for (; i >= 0; --i)
+ debug << " " << change.index[i];
+ return (debug << ")").maybeSpace();
+}
+
+QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::Change &change)
+{
+ return qt_print_change(debug, "Change", change);
+}
+
+QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::Remove &remove)
+{
+ return qt_print_change(debug, "Remove", remove);
+}
+
+QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::Insert &insert)
+{
+ return qt_print_change(debug, "Insert", insert);
+}
+
+QDebug operator <<(QDebug debug, const QDeclarativeListCompositor &list)
+{
+ int indexes[QDeclarativeListCompositor::MaximumGroupCount];
+ for (int i = 0; i < QDeclarativeListCompositor::MaximumGroupCount; ++i)
+ indexes[i] = 0;
+ debug.nospace() << "QDeclarativeListCompositor(";
+ qt_print_indexes(debug, list.m_groupCount, list.m_end.index);
+ for (QDeclarativeListCompositor::Range *range = list.m_ranges.next; range != &list.m_ranges; range = range->next) {
+ (debug << "\n").space();
+ qt_print_indexes(debug, list.m_groupCount, indexes);
+ debug << " " << *range;
+
+ for (int i = 0; i < list.m_groupCount; ++i) {
+ if (range->inGroup(i))
+ indexes[i] += range->count;
+ }
+ }
+ return (debug << ")").maybeSpace();
+}
diff --git a/src/declarative/util/qdeclarativelistcompositor_p.h b/src/declarative/util/qdeclarativelistcompositor_p.h
new file mode 100644
index 0000000000..60df819884
--- /dev/null
+++ b/src/declarative/util/qdeclarativelistcompositor_p.h
@@ -0,0 +1,373 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVELISTCOMPOSITOR_P_H
+#define QDECLARATIVELISTCOMPOSITOR_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qvector.h>
+
+#include <private/qdeclarativechangeset_p.h>
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_AUTOTEST_EXPORT QDeclarativeListCompositor
+{
+public:
+ enum { MaximumGroupCount = 11 };
+
+ enum Group
+ {
+ Cache = 0,
+ Default = 1,
+ Persisted = 2
+ };
+
+ enum Flag
+ {
+ CacheFlag = 0x000001,
+ DefaultFlag = 0x000002,
+ PersistedFlag = 0x000004,
+ GroupMask = 0x00FFFE,
+ PrependFlag = 0x100000,
+ AppendFlag = 0x200000,
+ MovedFlag = 0x400000
+ };
+
+ class Range
+ {
+ public:
+ Range() : next(this), previous(this), list(0), index(0), count(0), flags(0) {}
+ Range(Range *next, void *list, int index, int count, uint flags)
+ : next(next), previous(next->previous), list(list), index(index), count(count), flags(flags) {
+ next->previous = this; previous->next = this; }
+
+ Range *next;
+ Range *previous;
+ void *list;
+ int index;
+ int count;
+ int flags;
+
+ inline int start() const { return index; }
+ inline int end() const { return index + count; }
+
+ inline int groups() const { return flags & GroupMask; }
+
+ inline bool inGroup() const { return flags & GroupMask; }
+ inline bool inCache() const { return flags & CacheFlag; }
+ inline bool inGroup(int group) const { return flags & (1 << group); }
+
+ inline bool prepend() const { return flags & PrependFlag; }
+ inline bool append() const { return flags & AppendFlag; }
+ };
+
+ class Q_AUTOTEST_EXPORT iterator
+ {
+ public:
+ inline iterator();
+ inline iterator(const iterator &it);
+ inline iterator(Range *range, int offset, Group group, int groupCount);
+ inline ~iterator() {}
+
+ bool operator ==(const iterator &it) const { return range == it.range && offset == it.offset; }
+ bool operator !=(const iterator &it) const { return range != it.range || offset != it.offset; }
+
+ bool operator ==(Group group) const { return range->flags & (1 << group); }
+ bool operator !=(Group group) const { return !(range->flags & (1 << group)); }
+
+ Range *&operator *() { return range; }
+ Range * const &operator *() const { return range; }
+ Range *operator ->() { return range; }
+ const Range *operator ->() const { return range; }
+
+ iterator &operator ++();
+ iterator &operator +=(int difference);
+ iterator &operator -=(int difference);
+
+ template<typename T> T *list() const { return static_cast<T *>(range->list); }
+ int modelIndex() const { return range->index + offset; }
+
+ void incrementIndexes(int difference) { incrementIndexes(difference, range->flags); }
+ void decrementIndexes(int difference) { decrementIndexes(difference, range->flags); }
+
+ inline void incrementIndexes(int difference, int flags);
+ inline void decrementIndexes(int difference, int flags);
+
+ void setGroup(Group g) { group = g; groupFlag = 1 << g; }
+
+ Range *range;
+ int offset;
+ Group group;
+ int groupFlag;
+ int groupCount;
+ union {
+ struct {
+ int cacheIndex;
+ };
+ int index[MaximumGroupCount];
+ };
+ };
+
+ class Q_AUTOTEST_EXPORT insert_iterator : public iterator
+ {
+ public:
+ inline insert_iterator() {}
+ inline insert_iterator(const iterator &it) : iterator(it) {}
+ inline insert_iterator(Range *, int, Group, int);
+ inline ~insert_iterator() {}
+
+ insert_iterator &operator ++();
+ insert_iterator &operator +=(int difference);
+ insert_iterator &operator -=(int difference);
+ };
+
+ struct Change
+ {
+ inline Change() {}
+ inline Change(iterator it, int count, int flags, int moveId = -1);
+ int count;
+ int flags;
+ int moveId;
+ union {
+ struct {
+ int cacheIndex;
+ };
+ int index[MaximumGroupCount];
+ };
+
+ inline bool isMove() const { return moveId >= 0; }
+ inline bool inCache() const { return flags & CacheFlag; }
+ inline bool inGroup() const { return flags & GroupMask; }
+ inline bool inGroup(int group) const { return flags & (CacheFlag << group); }
+
+ inline int groups() const { return flags & GroupMask; }
+ };
+
+ struct Insert : public Change
+ {
+ Insert() {}
+ Insert(iterator it, int count, int flags, int moveId = -1)
+ : Change(it, count, flags, moveId) {}
+ };
+
+ struct Remove : public Change
+ {
+ Remove() {}
+ Remove(iterator it, int count, int flags, int moveId = -1)
+ : Change(it, count, flags, moveId) {}
+ };
+
+ QDeclarativeListCompositor();
+ ~QDeclarativeListCompositor();
+
+ int defaultGroups() const { return m_defaultFlags & ~PrependFlag; }
+ void setDefaultGroups(int groups) { m_defaultFlags = groups | PrependFlag; }
+ void setDefaultGroup(Group group) { m_defaultFlags |= (1 << group); }
+ void clearDefaultGroup(Group group) { m_defaultFlags &= ~(1 << group); }
+ void setRemoveGroups(int groups) { m_removeFlags = PrependFlag | AppendFlag | groups; }
+ void setGroupCount(int count);
+
+ int count(Group group) const;
+ iterator find(Group group, int index);
+ iterator find(Group group, int index) const;
+ insert_iterator findInsertPosition(Group group, int index);
+
+ iterator begin(Group group);
+ const iterator &end() { return m_end; }
+
+ void append(void *list, int index, int count, int flags, QVector<Insert> *inserts = 0);
+ void insert(Group group, int before, void *list, int index, int count, int flags, QVector<Insert> *inserts = 0);
+ iterator insert(iterator before, void *list, int index, int count, int flags, QVector<Insert> *inserts = 0);
+
+ void setFlags(Group group, int index, int count, int flags, QVector<Insert> *inserts = 0);
+ void setFlags(iterator from, int count, int flags, QVector<Insert> *inserts = 0);
+
+ void clearFlags(Group group, int index, int count, int flags, QVector<Remove> *removals = 0);
+ void clearFlags(iterator from, int count, int flags, QVector<Remove> *removals = 0);
+
+ void removeList(void *list, QVector<Remove> *removals, bool destroyed);
+
+ bool verifyMoveTo(Group fromGroup, int from, Group toGroup, int to, int count) const;
+
+ void move(
+ Group fromGroup,
+ int from,
+ Group toGroup,
+ int to,
+ int count,
+ QVector<Remove> *removals = 0,
+ QVector<Insert> *inserts = 0);
+ void clear();
+
+ void listItemsInserted(void *list, int index, int count, QVector<Insert> *inserts);
+ void listItemsRemoved(void *list, int index, int count, QVector<Remove> *removals);
+ void listItemsMoved(void *list, int from, int to, int count, QVector<Remove> *removals, QVector<Insert> *inserts);
+ void listItemsChanged(void *list, int index, int count, QVector<Change> *changes);
+ void listChanged(
+ void *list,
+ const QDeclarativeChangeSet &changeSet,
+ QVector<Remove> *removals,
+ QVector<Insert> *inserts,
+ QVector<Change> *changes);
+
+ void transition(
+ Group from,
+ Group to,
+ QVector<QDeclarativeChangeSet::Remove> *removes,
+ QVector<QDeclarativeChangeSet::Insert> *inserts);
+
+private:
+ Range m_ranges;
+ iterator m_end;
+ iterator m_cacheIt;
+ int m_groupCount;
+ int m_defaultFlags;
+ int m_removeFlags;
+
+ inline Range *insert(Range *before, void *list, int index, int count, int flags);
+ inline Range *erase(Range *range);
+
+ struct MovedFlags
+ {
+ MovedFlags() {}
+ MovedFlags(int moveId, int flags) : moveId(moveId), flags(flags) {}
+
+ int moveId;
+ int flags;
+ };
+
+ void listItemsRemoved(
+ QVector<Remove> *translatedRemovals,
+ void *list,
+ QVector<QDeclarativeChangeSet::Remove> *removals,
+ QVector<QDeclarativeChangeSet::Insert> *insertions = 0,
+ QVector<MovedFlags> *movedFlags = 0,
+ int moveId = 0);
+ void listItemsInserted(
+ QVector<Insert> *translatedInsertions,
+ void *list,
+ const QVector<QDeclarativeChangeSet::Insert> &insertions,
+ const QVector<MovedFlags> *movedFlags = 0);
+ void listItemsChanged(
+ QVector<Change> *translatedChanges,
+ void *list,
+ const QVector<QDeclarativeChangeSet::Change> &changes);
+
+ friend Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QDeclarativeListCompositor &list);
+};
+
+inline QDeclarativeListCompositor::iterator::iterator()
+ : range(0), offset(0), group(Default), groupCount(0) {}
+inline QDeclarativeListCompositor::iterator::iterator(const iterator &it)
+ : range(it.range)
+ , offset(it.offset)
+ , group(it.group)
+ , groupFlag(it.groupFlag)
+ , groupCount(it.groupCount)
+{
+ for (int i = 0; i < groupCount; ++i)
+ index[i] = it.index[i];
+}
+
+inline QDeclarativeListCompositor::iterator::iterator(
+ Range *range, int offset, Group group, int groupCount)
+ : range(range)
+ , offset(offset)
+ , group(group)
+ , groupFlag(1 << group)
+ , groupCount(groupCount)
+{
+ for (int i = 0; i < groupCount; ++i)
+ index[i] = 0;
+}
+
+inline void QDeclarativeListCompositor::iterator::incrementIndexes(int difference, int flags)
+{
+ for (int i = 0; i < groupCount; ++i) {
+ if (flags & (1 << i))
+ index[i] += difference;
+ }
+}
+
+inline void QDeclarativeListCompositor::iterator::decrementIndexes(int difference, int flags)
+{
+ for (int i = 0; i < groupCount; ++i) {
+ if (flags & (1 << i))
+ index[i] -= difference;
+ }
+}
+
+inline QDeclarativeListCompositor::insert_iterator::insert_iterator(
+ Range *range, int offset, Group group, int groupCount)
+ : iterator(range, offset, group, groupCount) {}
+
+inline QDeclarativeListCompositor::Change::Change(iterator it, int count, int flags, int moveId)
+ : count(count), flags(flags), moveId(moveId)
+{
+ for (int i = 0; i < MaximumGroupCount; ++i)
+ index[i] = it.index[i];
+}
+
+Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::Group &group);
+Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::Range &range);
+Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::iterator &it);
+Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::Change &change);
+Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::Remove &remove);
+Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QDeclarativeListCompositor::Insert &insert);
+Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QDeclarativeListCompositor &list);
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp
index 3add850570..4e67182048 100644
--- a/src/declarative/util/qdeclarativelistmodel.cpp
+++ b/src/declarative/util/qdeclarativelistmodel.cpp
@@ -39,15 +39,15 @@
**
****************************************************************************/
-#include "private/qdeclarativelistmodel_p_p.h"
-#include "private/qdeclarativelistmodelworkeragent_p.h"
-#include "private/qdeclarativeopenmetaobject_p.h"
-#include "parser/qdeclarativejsast_p.h"
-#include "parser/qdeclarativejsengine_p.h"
-
-#include <qdeclarativecustomparser_p.h>
-#include <qdeclarativescript_p.h>
-#include <qdeclarativeengine_p.h>
+#include "qdeclarativelistmodel_p_p.h"
+#include "qdeclarativelistmodelworkeragent_p.h"
+#include "qdeclarativeopenmetaobject_p.h"
+#include <private/qdeclarativejsast_p.h>
+#include <private/qdeclarativejsengine_p.h>
+
+#include <private/qdeclarativecustomparser_p.h>
+#include <private/qdeclarativescript_p.h>
+#include <private/qdeclarativeengine_p.h>
#include <qdeclarativecontext.h>
#include <qdeclarativeinfo.h>
@@ -792,14 +792,14 @@ bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParser
error(nodeProp, QDeclarativeListModel::tr("ListElement: cannot contain nested elements"));
return false;
}
- if (nodeProp.name() == "id") {
+ if (nodeProp.name() == QStringLiteral("id")) {
error(nodeProp, QDeclarativeListModel::tr("ListElement: cannot use reserved \"id\" property"));
return false;
}
ListInstruction li;
int ref = data.count();
- data.append(nodeProp.name());
+ data.append(nodeProp.name().toUtf8());
data.append('\0');
li.type = ListInstruction::Set;
li.dataIdx = ref;
@@ -895,12 +895,12 @@ QByteArray QDeclarativeListModelParser::compile(const QList<QDeclarativeCustomPa
{
QList<ListInstruction> instr;
QByteArray data;
- listElementTypeName = QByteArray(); // unknown
+ listElementTypeName = QString(); // unknown
for(int ii = 0; ii < customProps.count(); ++ii) {
const QDeclarativeCustomParserProperty &prop = customProps.at(ii);
if(!prop.name().isEmpty()) { // isn't default property
- error(prop, QDeclarativeListModel::tr("ListModel: undefined property '%1'").arg(QString::fromUtf8(prop.name())));
+ error(prop, QDeclarativeListModel::tr("ListModel: undefined property '%1'").arg(prop.name()));
return QByteArray();
}
diff --git a/src/declarative/util/qdeclarativelistmodel_p.h b/src/declarative/util/qdeclarativelistmodel_p.h
index e7c5632ce3..ea83ae1e7e 100644
--- a/src/declarative/util/qdeclarativelistmodel_p.h
+++ b/src/declarative/util/qdeclarativelistmodel_p.h
@@ -145,7 +145,7 @@ private:
bool definesEmptyList(const QString &);
- QByteArray listElementTypeName;
+ QString listElementTypeName;
};
diff --git a/src/declarative/util/qdeclarativelistmodel_p_p.h b/src/declarative/util/qdeclarativelistmodel_p_p.h
index 971f0d8d82..99cab4cab9 100644
--- a/src/declarative/util/qdeclarativelistmodel_p_p.h
+++ b/src/declarative/util/qdeclarativelistmodel_p_p.h
@@ -53,10 +53,10 @@
// We mean it.
//
-#include "private/qdeclarativelistmodel_p.h"
-#include "private/qdeclarativeengine_p.h"
-#include "private/qdeclarativeopenmetaobject_p.h"
-#include "qdeclarative.h"
+#include "qdeclarativelistmodel_p.h"
+#include <private/qdeclarativeengine_p.h>
+#include "qdeclarativeopenmetaobject_p.h"
+#include <qdeclarative.h>
QT_BEGIN_HEADER
diff --git a/src/declarative/util/qdeclarativelistmodelworkeragent.cpp b/src/declarative/util/qdeclarativelistmodelworkeragent.cpp
index c6855d354b..b27e3e387f 100644
--- a/src/declarative/util/qdeclarativelistmodelworkeragent.cpp
+++ b/src/declarative/util/qdeclarativelistmodelworkeragent.cpp
@@ -39,11 +39,11 @@
**
****************************************************************************/
-#include "private/qdeclarativelistmodelworkeragent_p.h"
-#include "private/qdeclarativelistmodel_p_p.h"
-#include "private/qdeclarativedata_p.h"
-#include "private/qdeclarativeengine_p.h"
-#include "qdeclarativeinfo.h"
+#include "qdeclarativelistmodelworkeragent_p.h"
+#include "qdeclarativelistmodel_p_p.h"
+#include <private/qdeclarativedata_p.h>
+#include <private/qdeclarativeengine_p.h>
+#include <qdeclarativeinfo.h>
#include <QtCore/qcoreevent.h>
#include <QtCore/qcoreapplication.h>
diff --git a/src/declarative/util/qdeclarativelistmodelworkeragent_p.h b/src/declarative/util/qdeclarativelistmodelworkeragent_p.h
index d814029334..12505e942c 100644
--- a/src/declarative/util/qdeclarativelistmodelworkeragent_p.h
+++ b/src/declarative/util/qdeclarativelistmodelworkeragent_p.h
@@ -53,7 +53,7 @@
// We mean it.
//
-#include "qdeclarative.h"
+#include <qdeclarative.h>
#include <QtGui/qevent.h>
#include <QMutex>
diff --git a/src/declarative/util/qdeclarativeopenmetaobject.cpp b/src/declarative/util/qdeclarativeopenmetaobject.cpp
index a5f47c2ef6..d4dd8242c4 100644
--- a/src/declarative/util/qdeclarativeopenmetaobject.cpp
+++ b/src/declarative/util/qdeclarativeopenmetaobject.cpp
@@ -39,10 +39,10 @@
**
****************************************************************************/
-#include "private/qdeclarativeopenmetaobject_p.h"
-#include "private/qdeclarativepropertycache_p.h"
-#include "private/qdeclarativedata_p.h"
-#include <qmetaobjectbuilder_p.h>
+#include "qdeclarativeopenmetaobject_p.h"
+#include <private/qdeclarativepropertycache_p.h>
+#include <private/qdeclarativedata_p.h>
+#include <private/qmetaobjectbuilder_p.h>
#include <qdebug.h>
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/util/qdeclarativepackage.cpp b/src/declarative/util/qdeclarativepackage.cpp
index 4973ee212a..1d46574f02 100644
--- a/src/declarative/util/qdeclarativepackage.cpp
+++ b/src/declarative/util/qdeclarativepackage.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "private/qdeclarativepackage_p.h"
+#include "qdeclarativepackage_p.h"
#include <private/qobject_p.h>
#include <private/qdeclarativeguard_p.h>
diff --git a/src/declarative/util/qdeclarativepath.cpp b/src/declarative/util/qdeclarativepath.cpp
index f923413e29..146fbf9950 100644
--- a/src/declarative/util/qdeclarativepath.cpp
+++ b/src/declarative/util/qdeclarativepath.cpp
@@ -39,9 +39,9 @@
**
****************************************************************************/
-#include "private/qdeclarativepath_p.h"
-#include "private/qdeclarativepath_p_p.h"
-#include "private/qdeclarativesvgparser_p.h"
+#include "qdeclarativepath_p.h"
+#include "qdeclarativepath_p_p.h"
+#include "qdeclarativesvgparser_p.h"
#include <QSet>
#include <QTime>
@@ -608,7 +608,8 @@ QPointF QDeclarativePath::backwardsPointAt(const QPainterPath &path, const qreal
Q_ASSERT(!(currElement < firstElement));
currBez = nextBezier(path, &currElement, &bezLength, true /*reverse*/);
currLength = prevLength;
- epc = (currLength - bezLength) / pathLength;
+ prevLength = currLength - bezLength;
+ epc = prevLength / pathLength;
}
prevBez.element = currElement;
prevBez.bezLength = bezLength;
diff --git a/src/declarative/util/qdeclarativepath_p.h b/src/declarative/util/qdeclarativepath_p.h
index e9972404da..e449e23085 100644
--- a/src/declarative/util/qdeclarativepath_p.h
+++ b/src/declarative/util/qdeclarativepath_p.h
@@ -44,7 +44,7 @@
#include <qdeclarative.h>
-#include "private/qdeclarativenullablevalue_p_p.h"
+#include <private/qdeclarativenullablevalue_p_p.h>
#include <private/qbezier_p.h>
#include <QtCore/QObject>
diff --git a/src/declarative/util/qdeclarativepath_p_p.h b/src/declarative/util/qdeclarativepath_p_p.h
index c7313ea225..910b7627d3 100644
--- a/src/declarative/util/qdeclarativepath_p_p.h
+++ b/src/declarative/util/qdeclarativepath_p_p.h
@@ -53,7 +53,7 @@
// We mean it.
//
-#include "private/qdeclarativepath_p.h"
+#include "qdeclarativepath_p.h"
#include <qdeclarative.h>
#include <QtCore/QStringList>
diff --git a/src/declarative/util/qdeclarativepathinterpolator.cpp b/src/declarative/util/qdeclarativepathinterpolator.cpp
index db6ef155b7..569884d33a 100644
--- a/src/declarative/util/qdeclarativepathinterpolator.cpp
+++ b/src/declarative/util/qdeclarativepathinterpolator.cpp
@@ -41,7 +41,7 @@
#include "qdeclarativepathinterpolator_p.h"
-#include "private/qdeclarativepath_p.h"
+#include "qdeclarativepath_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp
index 276219eb45..556524cc60 100644
--- a/src/declarative/util/qdeclarativepixmapcache.cpp
+++ b/src/declarative/util/qdeclarativepixmapcache.cpp
@@ -39,9 +39,9 @@
**
****************************************************************************/
-#include "private/qdeclarativepixmapcache_p.h"
-#include "qdeclarativenetworkaccessmanagerfactory.h"
-#include "qdeclarativeimageprovider.h"
+#include "qdeclarativepixmapcache_p.h"
+#include <qdeclarativenetworkaccessmanagerfactory.h>
+#include <qdeclarativeimageprovider.h>
#include <qdeclarativeengine.h>
#include <private/qdeclarativeglobal_p.h>
diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp
index 039803002c..818c1638cd 100644
--- a/src/declarative/util/qdeclarativepropertychanges.cpp
+++ b/src/declarative/util/qdeclarativepropertychanges.cpp
@@ -39,23 +39,22 @@
**
****************************************************************************/
-#include "private/qdeclarativepropertychanges_p.h"
+#include "qdeclarativepropertychanges_p.h"
-#include "private/qdeclarativeopenmetaobject_p.h"
-#include "private/qdeclarativerewrite_p.h"
-#include "private/qdeclarativeengine_p.h"
-#include "private/qdeclarativecompiler_p.h"
+#include "qdeclarativeopenmetaobject_p.h"
+#include <private/qdeclarativerewrite_p.h>
+#include <private/qdeclarativeengine_p.h>
#include <qdeclarativeinfo.h>
-#include <qdeclarativecustomparser_p.h>
-#include <qdeclarativescript_p.h>
+#include <private/qdeclarativecustomparser_p.h>
+#include <private/qdeclarativescript_p.h>
#include <qdeclarativeexpression.h>
-#include <qdeclarativebinding_p.h>
+#include <private/qdeclarativebinding_p.h>
#include <qdeclarativecontext.h>
-#include <qdeclarativeguard_p.h>
-#include <qdeclarativeproperty_p.h>
-#include <qdeclarativecontext_p.h>
-#include <qdeclarativestate_p_p.h>
+#include <private/qdeclarativeguard_p.h>
+#include <private/qdeclarativeproperty_p.h>
+#include <private/qdeclarativecontext_p.h>
+#include <private/qdeclarativestate_p_p.h>
#include <QtCore/qdebug.h>
@@ -240,11 +239,11 @@ public:
};
void
-QDeclarativePropertyChangesParser::compileList(QList<QPair<QByteArray, QVariant> > &list,
- const QByteArray &pre,
+QDeclarativePropertyChangesParser::compileList(QList<QPair<QString, QVariant> > &list,
+ const QString &pre,
const QDeclarativeCustomParserProperty &prop)
{
- QByteArray propName = pre + prop.name();
+ QString propName = pre + prop.name();
QList<QVariant> values = prop.assignedValues();
for (int ii = 0; ii < values.count(); ++ii) {
@@ -258,7 +257,7 @@ QDeclarativePropertyChangesParser::compileList(QList<QPair<QByteArray, QVariant>
QDeclarativeCustomParserProperty prop =
qvariant_cast<QDeclarativeCustomParserProperty>(value);
- QByteArray pre = propName + '.';
+ QString pre = propName + QLatin1Char('.');
compileList(list, pre, prop);
} else {
@@ -270,9 +269,9 @@ QDeclarativePropertyChangesParser::compileList(QList<QPair<QByteArray, QVariant>
QByteArray
QDeclarativePropertyChangesParser::compile(const QList<QDeclarativeCustomParserProperty> &props)
{
- QList<QPair<QByteArray, QVariant> > data;
+ QList<QPair<QString, QVariant> > data;
for(int ii = 0; ii < props.count(); ++ii)
- compileList(data, QByteArray(), props.at(ii));
+ compileList(data, QString(), props.at(ii));
QByteArray rv;
QDataStream ds(&rv, QIODevice::WriteOnly);
@@ -304,7 +303,7 @@ QDeclarativePropertyChangesParser::compile(const QList<QDeclarativeCustomParserP
break;
}
- ds << QString::fromUtf8(data.at(ii).first) << isScript << var;
+ ds << data.at(ii).first << isScript << var;
if (isScript)
ds << id;
}
diff --git a/src/declarative/util/qdeclarativepropertychanges_p.h b/src/declarative/util/qdeclarativepropertychanges_p.h
index cb553e032b..6d3e032b57 100644
--- a/src/declarative/util/qdeclarativepropertychanges_p.h
+++ b/src/declarative/util/qdeclarativepropertychanges_p.h
@@ -42,7 +42,7 @@
#ifndef QDECLARATIVEPROPERTYCHANGES_H
#define QDECLARATIVEPROPERTYCHANGES_H
-#include "private/qdeclarativestateoperations_p.h"
+#include "qdeclarativestateoperations_p.h"
#include <private/qdeclarativecustomparser_p.h>
QT_BEGIN_HEADER
@@ -96,7 +96,7 @@ public:
QDeclarativePropertyChangesParser()
: QDeclarativeCustomParser(AcceptsAttachedProperties) {}
- void compileList(QList<QPair<QByteArray, QVariant> > &list, const QByteArray &pre, const QDeclarativeCustomParserProperty &prop);
+ void compileList(QList<QPair<QString, QVariant> > &list, const QString &pre, const QDeclarativeCustomParserProperty &prop);
virtual QByteArray compile(const QList<QDeclarativeCustomParserProperty> &);
virtual void setCustomData(QObject *, const QByteArray &);
diff --git a/src/declarative/util/qdeclarativepropertymap.cpp b/src/declarative/util/qdeclarativepropertymap.cpp
index fc009a8a36..1149683ea6 100644
--- a/src/declarative/util/qdeclarativepropertymap.cpp
+++ b/src/declarative/util/qdeclarativepropertymap.cpp
@@ -42,7 +42,7 @@
#include "qdeclarativepropertymap.h"
#include <private/qmetaobjectbuilder_p.h>
-#include "private/qdeclarativeopenmetaobject_p.h"
+#include "qdeclarativeopenmetaobject_p.h"
#include <QDebug>
@@ -108,7 +108,7 @@ void QDeclarativePropertyMapMetaObject::propertyCreated(int, QMetaPropertyBuilde
int QDeclarativePropertyMapMetaObject::createProperty(const char *name, const char *value)
{
- if (!priv->validKeyName(name))
+ if (!priv->validKeyName(QString::fromUtf8(name)))
return -1;
return QDeclarativeOpenMetaObject::createProperty(name, value);
}
diff --git a/src/declarative/util/qdeclarativesmoothedanimation.cpp b/src/declarative/util/qdeclarativesmoothedanimation.cpp
index 1c88cd171f..4ef454c0e8 100644
--- a/src/declarative/util/qdeclarativesmoothedanimation.cpp
+++ b/src/declarative/util/qdeclarativesmoothedanimation.cpp
@@ -39,15 +39,15 @@
**
****************************************************************************/
-#include "private/qdeclarativesmoothedanimation_p.h"
-#include "private/qdeclarativesmoothedanimation_p_p.h"
+#include "qdeclarativesmoothedanimation_p.h"
+#include "qdeclarativesmoothedanimation_p_p.h"
-#include "private/qdeclarativeanimation_p_p.h"
+#include "qdeclarativeanimation_p_p.h"
#include <qdeclarativeproperty.h>
-#include "private/qdeclarativeproperty_p.h"
+#include <private/qdeclarativeproperty_p.h>
-#include "private/qdeclarativeglobal_p.h"
+#include <private/qdeclarativeglobal_p.h>
#include <QtCore/qdebug.h>
@@ -535,4 +535,4 @@ void QDeclarativeSmoothedAnimation::setMaximumEasingTime(int v)
d->updateRunningAnimations();
}
-QT_END_NAMESPACE
+QT_END_NAMESPACE \ No newline at end of file
diff --git a/src/declarative/util/qdeclarativesmoothedanimation_p.h b/src/declarative/util/qdeclarativesmoothedanimation_p.h
index ef1c39879c..6215adf366 100644
--- a/src/declarative/util/qdeclarativesmoothedanimation_p.h
+++ b/src/declarative/util/qdeclarativesmoothedanimation_p.h
@@ -43,7 +43,7 @@
#define QDECLARATIVESMOOTHEDANIMATION2_H
#include <qdeclarative.h>
-#include "private/qdeclarativeanimation_p.h"
+#include "qdeclarativeanimation_p.h"
#include <QtCore/qobject.h>
diff --git a/src/declarative/util/qdeclarativesmoothedanimation_p_p.h b/src/declarative/util/qdeclarativesmoothedanimation_p_p.h
index 578d47ef13..84fb1878eb 100644
--- a/src/declarative/util/qdeclarativesmoothedanimation_p_p.h
+++ b/src/declarative/util/qdeclarativesmoothedanimation_p_p.h
@@ -53,15 +53,15 @@
// We mean it.
//
-#include "private/qdeclarativesmoothedanimation_p.h"
-#include "private/qdeclarativeanimation_p.h"
+#include "qdeclarativesmoothedanimation_p.h"
+#include "qdeclarativeanimation_p.h"
-#include "private/qdeclarativeanimation_p_p.h"
+#include "qdeclarativeanimation_p_p.h"
#include "private/qparallelanimationgroup2_p.h"
#include <private/qobject_p.h>
-#include <QTimer>
+#include <QBasicTimer>
QT_BEGIN_NAMESPACE
class QSmoothedAnimation;
@@ -129,8 +129,7 @@ private:
bool recalc();
void delayedStop();
-
- QSmoothedAnimationTimer* delayedStopTimer;
+ QSmoothedAnimationTimer *delayedStopTimer;
};
class QDeclarativeSmoothedAnimationPrivate : public QDeclarativePropertyAnimationPrivate
@@ -148,4 +147,4 @@ public:
QT_END_NAMESPACE
-#endif // QDECLARATIVESMOOTHEDANIMATION2_P_H
+#endif // QDECLARATIVESMOOTHEDANIMATION2_P_H \ No newline at end of file
diff --git a/src/declarative/util/qdeclarativespringanimation.cpp b/src/declarative/util/qdeclarativespringanimation.cpp
index 377356cfce..7676470353 100644
--- a/src/declarative/util/qdeclarativespringanimation.cpp
+++ b/src/declarative/util/qdeclarativespringanimation.cpp
@@ -39,10 +39,10 @@
**
****************************************************************************/
-#include "private/qdeclarativespringanimation_p.h"
+#include "qdeclarativespringanimation_p.h"
-#include "private/qdeclarativeanimation_p_p.h"
-#include <qdeclarativeproperty_p.h>
+#include "qdeclarativeanimation_p_p.h"
+#include <private/qdeclarativeproperty_p.h>
#include <QtCore/qdebug.h>
diff --git a/src/declarative/util/qdeclarativespringanimation_p.h b/src/declarative/util/qdeclarativespringanimation_p.h
index 1d1a0d7392..7e5ee1c56f 100644
--- a/src/declarative/util/qdeclarativespringanimation_p.h
+++ b/src/declarative/util/qdeclarativespringanimation_p.h
@@ -43,7 +43,7 @@
#define QDECLARATIVESPRINGANIMATION2_H
#include <qdeclarative.h>
-#include "private/qdeclarativeanimation_p.h"
+#include "qdeclarativeanimation_p.h"
#include <QtCore/qobject.h>
diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp
index 4779208c5f..2c039f93a4 100644
--- a/src/declarative/util/qdeclarativestate.cpp
+++ b/src/declarative/util/qdeclarativestate.cpp
@@ -39,17 +39,13 @@
**
****************************************************************************/
-#include "private/qdeclarativestate_p_p.h"
-#include "private/qdeclarativestate_p.h"
+#include "qdeclarativestate_p_p.h"
+#include "qdeclarativestate_p.h"
-#include "private/qdeclarativetransition_p.h"
-#include "private/qdeclarativestategroup_p.h"
-#include "private/qdeclarativestateoperations_p.h"
-#include "private/qdeclarativeanimation_p.h"
-#include "private/qdeclarativeanimation_p_p.h"
+#include "qdeclarativestategroup_p.h"
+#include "qdeclarativestateoperations_p.h"
-#include <qdeclarativebinding_p.h>
-#include <qdeclarativeglobal_p.h>
+#include <private/qdeclarativeglobal_p.h>
#include <QtCore/qdebug.h>
diff --git a/src/declarative/util/qdeclarativestate_p_p.h b/src/declarative/util/qdeclarativestate_p_p.h
index 2479413511..a9c50f4aed 100644
--- a/src/declarative/util/qdeclarativestate_p_p.h
+++ b/src/declarative/util/qdeclarativestate_p_p.h
@@ -53,10 +53,9 @@
// We mean it.
//
-#include "private/qdeclarativestate_p.h"
+#include "qdeclarativestate_p.h"
-#include "private/qdeclarativeanimation_p_p.h"
-#include "private/qdeclarativetransitionmanager_p_p.h"
+#include "qdeclarativetransitionmanager_p_p.h"
#include <private/qdeclarativeproperty_p.h>
#include <private/qdeclarativeguard_p.h>
diff --git a/src/declarative/util/qdeclarativestategroup.cpp b/src/declarative/util/qdeclarativestategroup.cpp
index 4f9593011b..51e27e4bf0 100644
--- a/src/declarative/util/qdeclarativestategroup.cpp
+++ b/src/declarative/util/qdeclarativestategroup.cpp
@@ -39,15 +39,15 @@
**
****************************************************************************/
-#include "private/qdeclarativestategroup_p.h"
+#include "qdeclarativestategroup_p.h"
-#include "private/qdeclarativetransition_p.h"
-#include "private/qdeclarativestate_p_p.h"
+#include "qdeclarativetransition_p.h"
-#include <qdeclarativebinding_p.h>
-#include <qdeclarativeglobal_p.h>
+#include <private/qdeclarativebinding_p.h>
+#include <private/qdeclarativeglobal_p.h>
#include <QtCore/qstringbuilder.h>
+#include <QtCore/qstringlist.h>
#include <QtCore/qdebug.h>
#include <private/qobject_p.h>
@@ -444,7 +444,7 @@ void QDeclarativeStateGroupPrivate::setCurrentStateInternal(const QString &state
applyingState = true;
- QDeclarativeTransition *transition = (ignoreTrans || ignoreTrans) ? 0 : findTransition(currentState, state);
+ QDeclarativeTransition *transition = ignoreTrans ? 0 : findTransition(currentState, state);
if (stateChangeDebug()) {
qWarning() << this << "Changing state. From" << currentState << ". To" << state;
if (transition)
diff --git a/src/declarative/util/qdeclarativestategroup_p.h b/src/declarative/util/qdeclarativestategroup_p.h
index e539f3fb16..c59325580b 100644
--- a/src/declarative/util/qdeclarativestategroup_p.h
+++ b/src/declarative/util/qdeclarativestategroup_p.h
@@ -42,7 +42,7 @@
#ifndef QDECLARATIVESTATEGROUP_H
#define QDECLARATIVESTATEGROUP_H
-#include "private/qdeclarativestate_p.h"
+#include "qdeclarativestate_p.h"
QT_BEGIN_HEADER
diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp
index 89cc947d2c..d8a5369568 100644
--- a/src/declarative/util/qdeclarativestateoperations.cpp
+++ b/src/declarative/util/qdeclarativestateoperations.cpp
@@ -39,18 +39,17 @@
**
****************************************************************************/
-#include "private/qdeclarativestateoperations_p.h"
+#include "qdeclarativestateoperations_p.h"
#include <qdeclarative.h>
#include <qdeclarativecontext.h>
#include <qdeclarativeexpression.h>
#include <qdeclarativeinfo.h>
-#include <qdeclarativeguard_p.h>
-#include <qdeclarativenullablevalue_p_p.h>
-#include "private/qdeclarativecontext_p.h"
-#include "private/qdeclarativeproperty_p.h"
-#include "private/qdeclarativebinding_p.h"
-#include "private/qdeclarativestate_p_p.h"
+#include <private/qdeclarativeguard_p.h>
+#include <private/qdeclarativecontext_p.h>
+#include <private/qdeclarativeproperty_p.h>
+#include <private/qdeclarativebinding_p.h>
+#include "qdeclarativestate_p_p.h"
#include <QtCore/qdebug.h>
#include <QtCore/qmath.h>
diff --git a/src/declarative/util/qdeclarativestateoperations_p.h b/src/declarative/util/qdeclarativestateoperations_p.h
index 9d30bf7578..68d3338972 100644
--- a/src/declarative/util/qdeclarativestateoperations_p.h
+++ b/src/declarative/util/qdeclarativestateoperations_p.h
@@ -42,7 +42,7 @@
#ifndef QDECLARATIVESTATEOPERATIONS_H
#define QDECLARATIVESTATEOPERATIONS_H
-#include "private/qdeclarativestate_p.h"
+#include "qdeclarativestate_p.h"
#include <qdeclarativescriptstring.h>
QT_BEGIN_HEADER
diff --git a/src/declarative/util/qdeclarativestyledtext.cpp b/src/declarative/util/qdeclarativestyledtext.cpp
index b3d6c877c4..872bad6589 100644
--- a/src/declarative/util/qdeclarativestyledtext.cpp
+++ b/src/declarative/util/qdeclarativestyledtext.cpp
@@ -45,7 +45,7 @@
#include <QTextLayout>
#include <QDebug>
#include <qmath.h>
-#include "private/qdeclarativestyledtext_p.h"
+#include "qdeclarativestyledtext_p.h"
/*
QDeclarativeStyledText supports few tags:
diff --git a/src/declarative/util/qdeclarativesvgparser.cpp b/src/declarative/util/qdeclarativesvgparser.cpp
index 36714d7a38..e8ceb2116c 100644
--- a/src/declarative/util/qdeclarativesvgparser.cpp
+++ b/src/declarative/util/qdeclarativesvgparser.cpp
@@ -142,25 +142,6 @@ static qreal toDouble(const QChar *&str)
return val;
}
-static qreal toDouble(const QString &str, bool *ok = NULL)
-{
- const QChar *c = str.constData();
- qreal res = toDouble(c);
- if (ok) {
- *ok = ((*c) == QLatin1Char('\0'));
- }
- return res;
-}
-
-static qreal toDouble(const QStringRef &str, bool *ok = NULL)
-{
- const QChar *c = str.constData();
- qreal res = toDouble(c);
- if (ok) {
- *ok = (c == (str.constData() + str.length()));
- }
- return res;
-}
static inline void parseNumbersArray(const QChar *&str, QVarLengthArray<qreal, 8> &points)
{
while (str->isSpace())
diff --git a/src/declarative/util/qdeclarativesystempalette.cpp b/src/declarative/util/qdeclarativesystempalette.cpp
index b4216cb75d..61d8406141 100644
--- a/src/declarative/util/qdeclarativesystempalette.cpp
+++ b/src/declarative/util/qdeclarativesystempalette.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "private/qdeclarativesystempalette_p.h"
+#include "qdeclarativesystempalette_p.h"
#include <QGuiApplication>
diff --git a/src/declarative/util/qdeclarativetimeline.cpp b/src/declarative/util/qdeclarativetimeline.cpp
index e9fbd0b51c..5d97a1b660 100644
--- a/src/declarative/util/qdeclarativetimeline.cpp
+++ b/src/declarative/util/qdeclarativetimeline.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "private/qdeclarativetimeline_p_p.h"
+#include "qdeclarativetimeline_p_p.h"
#include <QDebug>
#include <QMutex>
diff --git a/src/declarative/util/qdeclarativetimer.cpp b/src/declarative/util/qdeclarativetimer.cpp
index 6d5cf7f7ae..e1f88c4125 100644
--- a/src/declarative/util/qdeclarativetimer.cpp
+++ b/src/declarative/util/qdeclarativetimer.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "private/qdeclarativetimer_p.h"
+#include "qdeclarativetimer_p.h"
#include <QtCore/qcoreapplication.h>
#include "private/qpauseanimation2_p.h"
diff --git a/src/declarative/util/qdeclarativetransition.cpp b/src/declarative/util/qdeclarativetransition.cpp
index f59647d920..069e28c7e9 100644
--- a/src/declarative/util/qdeclarativetransition.cpp
+++ b/src/declarative/util/qdeclarativetransition.cpp
@@ -39,13 +39,14 @@
**
****************************************************************************/
-#include "private/qdeclarativestate_p.h"
-#include "private/qdeclarativestategroup_p.h"
-#include "private/qdeclarativestate_p_p.h"
-#include "private/qdeclarativestateoperations_p.h"
-#include "private/qdeclarativeanimation_p.h"
-#include "private/qdeclarativeanimation_p_p.h"
-#include "private/qdeclarativetransitionmanager_p_p.h"
+#include "qdeclarativetransition_p.h"
+
+#include "qdeclarativestate_p.h"
+#include "qdeclarativestate_p_p.h"
+#include "qdeclarativestateoperations_p.h"
+#include "qdeclarativeanimation_p.h"
+#include "qdeclarativeanimation_p_p.h"
+#include "qdeclarativetransitionmanager_p_p.h"
#include "private/qparallelanimationgroup2_p.h"
diff --git a/src/declarative/util/qdeclarativetransition_p.h b/src/declarative/util/qdeclarativetransition_p.h
index db102582d2..a53346e148 100644
--- a/src/declarative/util/qdeclarativetransition_p.h
+++ b/src/declarative/util/qdeclarativetransition_p.h
@@ -42,7 +42,7 @@
#ifndef QDECLARATIVETRANSITION_H
#define QDECLARATIVETRANSITION_H
-#include "private/qdeclarativestate_p.h"
+#include "qdeclarativestate_p.h"
#include <qdeclarative.h>
diff --git a/src/declarative/util/qdeclarativetransitionmanager.cpp b/src/declarative/util/qdeclarativetransitionmanager.cpp
index 30504cb241..2dd1da70ed 100644
--- a/src/declarative/util/qdeclarativetransitionmanager.cpp
+++ b/src/declarative/util/qdeclarativetransitionmanager.cpp
@@ -39,14 +39,17 @@
**
****************************************************************************/
-#include "private/qdeclarativetransitionmanager_p_p.h"
+#include "qdeclarativetransitionmanager_p_p.h"
-#include "private/qdeclarativestate_p_p.h"
-#include "private/qdeclarativestate_p.h"
+#include "qdeclarativetransition_p.h"
+#include "qdeclarativestate_p_p.h"
+#include "qdeclarativestate_p.h"
-#include <qdeclarativebinding_p.h>
-#include <qdeclarativeglobal_p.h>
-#include <qdeclarativeproperty_p.h>
+#include <private/qdeclarativebinding_p.h>
+#include <private/qdeclarativeglobal_p.h>
+#include <private/qdeclarativeproperty_p.h>
+
+#include <QtCore/qdebug.h>
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/util/qdeclarativetransitionmanager_p_p.h b/src/declarative/util/qdeclarativetransitionmanager_p_p.h
index c3645ad293..94a2dd1539 100644
--- a/src/declarative/util/qdeclarativetransitionmanager_p_p.h
+++ b/src/declarative/util/qdeclarativetransitionmanager_p_p.h
@@ -53,7 +53,7 @@
// We mean it.
//
-#include "private/qdeclarativestateoperations_p.h"
+#include "qdeclarativestateoperations_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/util/qdeclarativeutilmodule.cpp b/src/declarative/util/qdeclarativeutilmodule.cpp
index 980a8b1cb9..0a8f04b0de 100644
--- a/src/declarative/util/qdeclarativeutilmodule.cpp
+++ b/src/declarative/util/qdeclarativeutilmodule.cpp
@@ -39,39 +39,34 @@
**
****************************************************************************/
-#include "private/qdeclarativeutilmodule_p.h"
-#include "private/qdeclarativeanimation_p.h"
-#include "private/qdeclarativeanimation_p_p.h"
-#include "private/qdeclarativebehavior_p.h"
-#include "private/qdeclarativebind_p.h"
-#include "private/qdeclarativeconnections_p.h"
-#include "private/qdeclarativesmoothedanimation_p.h"
-#include "private/qdeclarativefontloader_p.h"
-#include "private/qdeclarativelistaccessor_p.h"
-#include "private/qdeclarativelistmodel_p.h"
-#include "private/qdeclarativenullablevalue_p_p.h"
-#include "private/qdeclarativeopenmetaobject_p.h"
-#include "private/qdeclarativepackage_p.h"
-#include "private/qdeclarativepixmapcache_p.h"
-#include "private/qdeclarativepropertychanges_p.h"
-#include "qdeclarativepropertymap.h"
-#include "private/qdeclarativespringanimation_p.h"
-#include "private/qdeclarativestategroup_p.h"
-#include "private/qdeclarativestateoperations_p.h"
-#include "private/qdeclarativestate_p.h"
-#include "private/qdeclarativestate_p_p.h"
-#include "private/qdeclarativestyledtext_p.h"
-#include "private/qdeclarativesystempalette_p.h"
-#include "private/qdeclarativetimeline_p_p.h"
-#include "private/qdeclarativetimer_p.h"
-#include "private/qdeclarativetransitionmanager_p_p.h"
-#include "private/qdeclarativetransition_p.h"
-#include "private/qdeclarativeapplication_p.h"
-#include "qdeclarativeinfo.h"
-#include "private/qdeclarativetypenotavailable_p.h"
+#include "qdeclarativeutilmodule_p.h"
+#include "qdeclarativeanimation_p.h"
+#include "qdeclarativeanimation_p_p.h"
+#include "qdeclarativebehavior_p.h"
+#include "qdeclarativebind_p.h"
+#include "qdeclarativeconnections_p.h"
+#include "qdeclarativesmoothedanimation_p.h"
+#include "qdeclarativefontloader_p.h"
+#include "qdeclarativelistaccessor_p.h"
+#include "qdeclarativelistmodel_p.h"
+#include "qdeclarativepackage_p.h"
+#include "qdeclarativepropertychanges_p.h"
+#include "qdeclarativespringanimation_p.h"
+#include "qdeclarativestategroup_p.h"
+#include "qdeclarativestateoperations_p.h"
+#include "qdeclarativestate_p.h"
+#include "qdeclarativestate_p_p.h"
+#include "qdeclarativesystempalette_p.h"
+#include "qdeclarativetimer_p.h"
+#include "qdeclarativetransition_p.h"
+#include "qdeclarativeapplication_p.h"
+#include <qdeclarativeinfo.h>
+#include <private/qdeclarativetypenotavailable_p.h>
#ifndef QT_NO_XMLPATTERNS
-#include "private/qdeclarativexmllistmodel_p.h"
+#include "qdeclarativexmllistmodel_p.h"
#endif
+#include <QtCore/qcoreapplication.h>
+#include <QtGui/QInputPanel>
void QDeclarativeUtilModule::registerBaseTypes(const char *uri, int versionMajor, int versionMinor)
{
@@ -82,7 +77,7 @@ void QDeclarativeUtilModule::registerBaseTypes(const char *uri, int versionMajor
void QDeclarativeUtilModule::defineModule()
{
qmlRegisterUncreatableType<QDeclarativeApplication>("QtQuick",2,0,"Application", QDeclarativeApplication::tr("Application is an abstract class"));
-
+ qmlRegisterUncreatableType<QInputPanel>("QtQuick",2,0,"InputPanel", QInputPanel::tr("InputPanel is an abstract class"));
qmlRegisterUncreatableType<QDeclarativeAbstractAnimation>("QtQuick",2,0,"Animation",QDeclarativeAbstractAnimation::tr("Animation is an abstract class"));
qmlRegisterType<QDeclarativeBehavior>("QtQuick",2,0,"Behavior");
diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp
index 82b7e7d368..d757516c91 100644
--- a/src/declarative/util/qdeclarativexmllistmodel.cpp
+++ b/src/declarative/util/qdeclarativexmllistmodel.cpp
@@ -39,10 +39,10 @@
**
****************************************************************************/
-#include "private/qdeclarativexmllistmodel_p.h"
+#include "qdeclarativexmllistmodel_p.h"
#include <qdeclarativecontext.h>
-#include <qdeclarativeengine_p.h>
+#include <private/qdeclarativeengine_p.h>
#include <QDebug>
#include <QStringList>
@@ -253,12 +253,12 @@ int QDeclarativeXmlQueryEngine::doQuery(QString query, QString namespaces, QByte
{
QMutexLocker m1(&m_mutex);
m_queryIds.ref();
- if (m_queryIds <= 0)
- m_queryIds = 1;
+ if (m_queryIds.load() <= 0)
+ m_queryIds.store(1);
}
XmlQueryJob job;
- job.queryId = m_queryIds;
+ job.queryId = m_queryIds.load();
job.data = data;
job.query = QLatin1String("doc($src)") + query;
job.namespaces = namespaces;
diff --git a/src/declarative/util/qlistmodelinterface.cpp b/src/declarative/util/qlistmodelinterface.cpp
index 56fc8eeb51..4461456516 100644
--- a/src/declarative/util/qlistmodelinterface.cpp
+++ b/src/declarative/util/qlistmodelinterface.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "private/qlistmodelinterface_p.h"
+#include "qlistmodelinterface_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri
index ddd702609c..1d71225bf5 100644
--- a/src/declarative/util/util.pri
+++ b/src/declarative/util/util.pri
@@ -1,5 +1,3 @@
-INCLUDEPATH += $$PWD
-
SOURCES += \
$$PWD/qdeclarativeapplication.cpp \
$$PWD/qdeclarativeutilmodule.cpp\
@@ -29,6 +27,7 @@ SOURCES += \
$$PWD/qdeclarativelistmodelworkeragent.cpp \
$$PWD/qdeclarativepath.cpp \
$$PWD/qdeclarativechangeset.cpp \
+ $$PWD/qdeclarativelistcompositor.cpp \
$$PWD/qlistmodelinterface.cpp \
$$PWD/qdeclarativepathinterpolator.cpp \
$$PWD/qdeclarativesvgparser.cpp
@@ -67,6 +66,7 @@ HEADERS += \
$$PWD/qdeclarativepath_p.h \
$$PWD/qdeclarativepath_p_p.h \
$$PWD/qdeclarativechangeset_p.h \
+ $$PWD/qdeclarativelistcompositor_p.h \
$$PWD/qlistmodelinterface_p.h \
$$PWD/qdeclarativepathinterpolator_p.h \
$$PWD/qdeclarativesvgparser_p.h
diff --git a/src/imports/gestures/qdeclarativegesturearea.cpp b/src/imports/gestures/qdeclarativegesturearea.cpp
index 1631831c7f..9cd4060ab5 100644
--- a/src/imports/gestures/qdeclarativegesturearea.cpp
+++ b/src/imports/gestures/qdeclarativegesturearea.cpp
@@ -165,7 +165,7 @@ QDeclarativeGestureAreaParser::compile(const QList<QDeclarativeCustomParserPrope
for(int ii = 0; ii < props.count(); ++ii)
{
- QString propName = QString::fromUtf8(props.at(ii).name());
+ QString propName = props.at(ii).name();
Qt::GestureType type;
if (propName == QLatin1String("onTap")) {
diff --git a/src/imports/imports.pro b/src/imports/imports.pro
index c60e72db08..9c66082ba9 100644
--- a/src/imports/imports.pro
+++ b/src/imports/imports.pro
@@ -1,5 +1,5 @@
TEMPLATE = subdirs
-SUBDIRS += qtquick1 qt47 folderlistmodel particles gestures inputcontext etcprovider
+SUBDIRS += qtquick1 qt47 folderlistmodel particles gestures etcprovider
contains(QT_CONFIG, qmltest): SUBDIRS += testlib
diff --git a/src/imports/inputcontext/declarativeinputcontext.cpp b/src/imports/inputcontext/declarativeinputcontext.cpp
deleted file mode 100644
index 9eb01c66cd..0000000000
--- a/src/imports/inputcontext/declarativeinputcontext.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "declarativeinputcontext.h"
-
-#include "inputcontextmodule.h"
-#include "inputcontextfilter.h"
-
-#include <QtCore/qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-DeclarativeInputContext::DeclarativeInputContext(QObject *parent)
- : QInputContext(parent)
- , m_module(0)
-{
-}
-
-DeclarativeInputContext::~DeclarativeInputContext()
-{
-}
-
-bool DeclarativeInputContext::isComposing() const
-{
- return m_module && !m_module->preeditText().isEmpty();
-}
-
-QString DeclarativeInputContext::identifierName()
-{
- return QLatin1String("Qt.labs.inputcontext/1.0");
-}
-
-QString DeclarativeInputContext::language()
-{
- return QString();
-}
-
-void DeclarativeInputContext::setFocusWidget(QWidget *widget)
-{
- QInputContext::setFocusWidget(widget);
-
- if (m_module)
- m_module->setFocusWidget(widget);
-}
-
-void DeclarativeInputContext::mouseHandler(int x, QMouseEvent *event)
-{
- if (!m_mouseHandlers.isEmpty()) {
- InputContextMouseEvent me(*event);
- foreach (InputContextMouseHandler *handler, m_mouseHandlers) {
- handler->processEvent(event->type(), x, &me);
- if (me.isAccepted()) {
- event->setAccepted(true);
- return;
- }
- }
- }
-}
-
-bool DeclarativeInputContext::filterMouseEvent(const QMouseEvent *event)
-{
- if (!m_mouseFilters.isEmpty()) {
- InputContextMouseEvent me(*event);
- foreach (InputContextMouseFilter *filter, m_mouseFilters) {
- filter->processEvent(event->type(), &me);
- if (me.isAccepted())
- return true;
- }
- }
-
- return false;
-}
-
-bool DeclarativeInputContext::filterKeyEvent(const QKeyEvent *event)
-{
- if (!m_keyFilters.isEmpty()) {
- InputContextKeyEvent ke(*event);
- foreach (InputContextKeyFilter *filter, m_keyFilters) {
- filter->processEvent(event->type(), &ke);
- if (ke.isAccepted())
- return true;
- }
- }
- return false;
-}
-
-bool DeclarativeInputContext::filterEvent(const QEvent *event)
-{
- switch (event->type()) {
- case QEvent::RequestSoftwareInputPanel:
- if (m_module)
- m_module->setVisible(true);
- return true;
- case QEvent::CloseSoftwareInputPanel:
- if (m_module)
- m_module->setVisible(false);
- return true;
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseMove:
- return filterMouseEvent(static_cast<const QMouseEvent *>(event));
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- return filterKeyEvent(static_cast<const QKeyEvent *>(event));
- default:
- return false;
- }
-}
-
-void DeclarativeInputContext::reset()
-{
- if (m_module)
- m_module->commit();
-}
-
-void DeclarativeInputContext::update()
-{
- if (m_module)
- m_module->update();
-}
-
-void DeclarativeInputContext::setModule(InputContextModule *module)
-{
- m_module = module;
-}
-
-void DeclarativeInputContext::registerMouseHandler(InputContextMouseHandler *handler)
-{
- connect(handler, SIGNAL(destroyed(QObject*)), this, SLOT(mouseHandlerDestroyed(QObject*)));
- m_mouseHandlers.append(handler);
-}
-
-void DeclarativeInputContext::registerMouseFilter(InputContextMouseFilter *filter)
-{
- connect(filter, SIGNAL(destroyed(QObject*)), this, SLOT(mouseFilterDestroyed(QObject*)));
- m_mouseFilters.append(filter);
-}
-
-void DeclarativeInputContext::registerKeyFilter(InputContextKeyFilter *filter)
-{
- connect(filter, SIGNAL(destroyed(QObject*)), this, SLOT(keyFilterDestroyed(QObject*)));
- m_keyFilters.append(filter);
-}
-
-void DeclarativeInputContext::mouseHandlerDestroyed(QObject *handler)
-{
- m_mouseHandlers.removeAll(static_cast<InputContextMouseHandler *>(handler));
-}
-
-void DeclarativeInputContext::mouseFilterDestroyed(QObject *filter)
-{
- m_mouseFilters.removeAll(static_cast<InputContextMouseFilter *>(filter));
-}
-
-void DeclarativeInputContext::keyFilterDestroyed(QObject *filter)
-{
- m_keyFilters.removeAll(static_cast<InputContextKeyFilter *>(filter));
-}
-
-QT_END_NAMESPACE
diff --git a/src/imports/inputcontext/declarativeinputcontext.h b/src/imports/inputcontext/declarativeinputcontext.h
deleted file mode 100644
index 9e6e65fd6e..0000000000
--- a/src/imports/inputcontext/declarativeinputcontext.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef DECLARATIVEINPUTCONTEXT_H
-#define DECLARATIVEINPUTCONTEXT_H
-
-#include <QtWidgets/qinputcontext.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class InputContextKeyFilter;
-class InputContextModule;
-class InputContextMouseFilter;
-class InputContextMouseHandler;
-
-class DeclarativeInputContext : public QInputContext
-{
- Q_OBJECT
-public:
- explicit DeclarativeInputContext(QObject *parent = 0);
- ~DeclarativeInputContext();
-
- bool isComposing() const;
-
- QString identifierName();
- QString language();
-
- void setFocusWidget(QWidget *widget);
-
- void mouseHandler(int x, QMouseEvent *event);
-
- bool filterMouseEvent(const QMouseEvent *event);
- bool filterKeyEvent(const QKeyEvent *event);
-
- bool filterEvent(const QEvent *event);
-
- void reset();
- void update();
-
- void setModule(InputContextModule *module);
-
- void registerMouseHandler(InputContextMouseHandler *handler);
- void registerMouseFilter(InputContextMouseFilter *filter);
- void registerKeyFilter(InputContextKeyFilter *filter);
-
-private slots:
- void mouseHandlerDestroyed(QObject *handler);
- void mouseFilterDestroyed(QObject *filter);
- void keyFilterDestroyed(QObject *filter);
-
-private:
- InputContextModule *m_module;
- QList<InputContextMouseHandler *> m_mouseHandlers;
- QList<InputContextMouseFilter *> m_mouseFilters;
- QList<InputContextKeyFilter *> m_keyFilters;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
diff --git a/src/imports/inputcontext/inputcontext.pro b/src/imports/inputcontext/inputcontext.pro
deleted file mode 100755
index c8641d20e3..0000000000
--- a/src/imports/inputcontext/inputcontext.pro
+++ /dev/null
@@ -1,38 +0,0 @@
-TARGET = qmlinputcontextplugin
-TARGETPATH = Qt/labs/inputcontext
-include(../qimportbase.pri)
-
-QT += declarative widgets
-
-SOURCES += \
- declarativeinputcontext.cpp \
- inputcontextfilter.cpp \
- inputcontextmodule.cpp \
- plugin.cpp
-
-HEADERS += \
- declarativeinputcontext.h \
- inputcontextfilter.h \
- inputcontextmodule.h
-
-OTHER_FILES = \
- qmldir
-
-QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH
-target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
-
-qmldir.files += $$PWD/qmldir
-qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
-
-symbian:{
- TARGET.UID3 = 0x20031E91
-
- isEmpty(DESTDIR):importFiles.files = qmlinputcontextplugin{QT_LIBINFIX}.dll qmldir
- else:importFiles.files = $$DESTDIR/qmlinputcontextplugin$${QT_LIBINFIX}.dll qmldir
- importFiles.path = $$QT_IMPORTS_BASE_DIR/$$TARGETPATH
-
- DEPLOYMENT = importFiles
-}
-
-INSTALLS += target qmldir
-
diff --git a/src/imports/inputcontext/inputcontextfilter.cpp b/src/imports/inputcontext/inputcontextfilter.cpp
deleted file mode 100644
index be89841b85..0000000000
--- a/src/imports/inputcontext/inputcontextfilter.cpp
+++ /dev/null
@@ -1,352 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "inputcontextfilter.h"
-
-#include "declarativeinputcontext.h"
-
-#include <QtWidgets/qapplication.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \qmlclass KeyEvent InputContextKeyEvent
-
- \inqmlmodule Qt.labs.inputcontext
-
- \brief The KeyEvent object provides information about a key event.
-*/
-
-/*!
- \qmlproperty int KeyEvent::key
-
- This property holds the key code of the key that was pressed or released.
-*/
-
-/*!
- \qmlproperty string KeyEvent::text
-
- This property holds the text that this key generated.
-*/
-
-/*!
- \qmlproperty int KeyEvent::modifiers
-
- This property holds the keyboard modifier flags that existed immediately
- after this event was generated.
-*/
-
-/*!
- \qmlproperty bool KeyEvent::autoRepeat
-
- This property returns true if this event comes from an auto repeating key
- press, on the initial key press this returns false.
-*/
-
-/*!
- \qmlproperty int KeyEvent::count
-
- This property holds the number of keys involved in this event. If the
- \l text is non-empty this is the length of the string.
-*/
-
-/*!
- \qmlproperty bool KeyEvent::accepted
-
- This property holds whether the event was accepted.
-
- This is false by default.
-*/
-
-/*!
- \qmlclass MouseEvent InputContextMouseEvent
-
- \inqmlmodule Qt.labs.inputcontext
-
- \brief The MouseEvent object provides information about a mouse event.
-
-*/
-
-/*!
- \qmlproperty int MouseEvent::x
-
- This property holds the x position in scene coordinates of the mouse cursor
- at the time of the event.
-*/
-
-/*!
- \qmlproperty int MouseEvent::y
-
- This property holds the y position in scene coordinates of the mouse cursor
- at the time of the event.
-*/
-
-/*!
- \qmlproperty enum MouseEvent::button
-
- This property holds the button that caused the event.
-*/
-
-/*!
- \qmlproperty int MouseEvent::buttons
-
- This property holds the button state when the event was generated.
-*/
-
-/*!
- \qmlproperty int MouseEvent::modifiers
-
- This property holds the keyboard modifier flags that existed when the event
- was generated.
-*/
-
-/*!
- \qmlproperty bool MouseEvent::accepted
-
- This property holds whether the event was accepted.
-
- This is false by default.
-*/
-
-/*!
- \qmlclass MouseHandler InputContextMouseHandler
-
- \inqmlmodule Qt.labs.inputcontext
-
- \brief The MouseHandler item provides mouse event handling for input methods.
-
- The MouseHandler item can be used to handle mouse press, release, move and
- double click events within or surrounding the pre-edit text.
-*/
-
-/*!
- \qmlsignal MouseHandler::onPressed(int cursor, MouseEvent mouse)
-
- This handler is called when there is a press. The \a cursor parameter is
- the text cursor position of the press within the pre-edit text, and the
- \a mouse parameter holds information about the press.
-*/
-
-/*!
- \qmlsignal MouseHandler::onReleased(int cursor, MouseEvent mouse)
-
- This handler is called when there is a release. The \a cursor parameter is
- the text cursor position of the press within the pre-edit text, and the
- \a mouse parameter holds information about the release.
-*/
-
-/*!
- \qmlsignal MouseHandler::onPositionChanged(int cursor, MouseEvent mouse)
-
- This handler is called when the mouse position changes.
-
- The \a cursor parameter is the text cursor position of the press within
- the pre-edit text, and the \a mouse parameter holds information about the
- position change.
-*/
-
-/*!
- \qmlsignal MouseHandler::onDoubleClicked(int cursor, MouseEvent mouse)
-
- This handler is called when there is a double-click. The \a cursor
- parameter is the text cursor position of the press within the pre-edit
- text, and the \a mouse parameter holds information about the double-click.
-*/
-
-InputContextMouseHandler::InputContextMouseHandler(QObject *parent)
- : QObject(parent)
-{
- if (DeclarativeInputContext *context = qobject_cast<DeclarativeInputContext *>(
- qApp->inputContext())) {
- context->registerMouseHandler(this);
- }
-}
-
-void InputContextMouseHandler::processEvent(QEvent::Type type, int cursor, InputContextMouseEvent *event)
-{
- switch (type) {
- case QEvent::MouseButtonPress:
- emit pressed(cursor, event);
- break;
- case QEvent::MouseButtonRelease:
- emit released(cursor, event);
- break;
- case QEvent::MouseButtonDblClick:
- emit doubleClicked(cursor, event);
- break;
- case QEvent::MouseMove:
- emit positionChanged(cursor, event);
- break;
- default:
- break;
- }
-}
-
-/*!
- \qmlclass MouseFilter InputContextMouseFilter
-
- \inqmlmodule Qt.labs.inputcontext
-
- \brief The MouseFilter item provides mouse event filtering for input methods.
-
- The MouseFilter item can be used to filter mouse press, release, move and
- double click events received by the item with active focus.
-*/
-
-/*!
- \qmlsignal MouseHandler::onPressed(MouseEvent mouse)
-
- This handler is called when there is a press. The \a mouse parameter holds
- information about the press.
-
- If the event is accepted it will not be delivered to the item.
-*/
-
-/*!
- \qmlsignal MouseHandler::onReleased(MouseEvent mouse)
-
- This handler is called when there is a release. The \a mouse parameter
- holds information about the release.
-
- If the event is accepted it will not be delivered to the item.
-*/
-
-/*!
- \qmlsignal MouseHandler::onPositionChanged(MouseEvent mouse)
-
- This handler is called when the mouse position changes.
-
- The \a mouse parameter holds information about the position change.
-
- If the event is accepted it will not be delivered to the item.
-*/
-
-/*!
- \qmlsignal MouseHandler::onDoubleClicked(MouseEvent mouse)
-
- This handler is called when there is a double-click. The \a mouse
- parameter holds information about the double-click.
-
- If the event is accepted it will not be delivered to the item.
-*/
-
-InputContextMouseFilter::InputContextMouseFilter(QObject *parent)
- : QObject(parent)
-{
- if (DeclarativeInputContext *context = qobject_cast<DeclarativeInputContext *>(
- qApp->inputContext())) {
- context->registerMouseFilter(this);
- }
-}
-
-void InputContextMouseFilter::processEvent(QEvent::Type type, InputContextMouseEvent *event)
-{
- switch (type) {
- case QEvent::MouseButtonPress:
- emit pressed(event);
- break;
- case QEvent::MouseButtonRelease:
- emit released(event);
- break;
- case QEvent::MouseButtonDblClick:
- emit doubleClicked(event);
- break;
- case QEvent::MouseMove:
- emit positionChanged(event);
- break;
- default:
- break;
- }
-}
-
-/*!
- \qmlclass KeyFilter InputContextKeyFilter
-
- \inqmlmodule Qt.labs.inputcontext
-
- \brief The KeyFilter item provides key event filtering for input methods.
-
- The KeyFilter item can be used to filter key press and releae events
- received by the item with active focus.
-*/
-
-/*!
- \qmlsignal KeyFilter::onPressed(KeyEvent event)
-
- This handler is called when there is a key press. The \a event parameter
- holds information about the press.
-
- If the event is accepted it will not be delivered to the item.
-*/
-
-/*!
- \qmlsignal KeyFilter::onReleased(KeyEvent event)
-
- This handler is called when there is a key release. The \a event parameter
- holds information about the release.
-
- If the event is accepted it will not be delivered to the item.
-*/
-
-InputContextKeyFilter::InputContextKeyFilter(QObject *parent)
- : QObject(parent)
-{
- if (DeclarativeInputContext *context = qobject_cast<DeclarativeInputContext *>(
- qApp->inputContext())) {
- context->registerKeyFilter(this);
- }
-}
-
-void InputContextKeyFilter::processEvent(QEvent::Type type, InputContextKeyEvent *event)
-{
- switch (type) {
- case QEvent::KeyPress:
- emit pressed(event);
- break;
- case QEvent::KeyRelease:
- emit released(event);
- break;
- default:
- break;
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/imports/inputcontext/inputcontextfilter.h b/src/imports/inputcontext/inputcontextfilter.h
deleted file mode 100644
index f0eefd90c1..0000000000
--- a/src/imports/inputcontext/inputcontextfilter.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef INPUTCONTEXTFILTER_H
-#define INPUTCONTEXTFILTER_H
-
-#include <QtDeclarative/qdeclarative.h>
-#include <QtGui/qevent.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class InputContextKeyEvent : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(int key READ key)
- Q_PROPERTY(QString text READ text)
- Q_PROPERTY(int modifiers READ modifiers)
- Q_PROPERTY(bool isAutoRepeat READ isAutoRepeat)
- Q_PROPERTY(int count READ count)
- Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
-
-public:
- InputContextKeyEvent(const QKeyEvent &ke)
- : event(ke) { event.setAccepted(false); }
-
- int key() const { return event.key(); }
- QString text() const { return event.text(); }
- int modifiers() const { return event.modifiers(); }
- bool isAutoRepeat() const { return event.isAutoRepeat(); }
- int count() const { return event.count(); }
-
- bool isAccepted() { return event.isAccepted(); }
- void setAccepted(bool accepted) { event.setAccepted(accepted); }
-
-private:
- QKeyEvent event;
-};
-
-class InputContextMouseEvent : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(int x READ x)
- Q_PROPERTY(int y READ y)
- Q_PROPERTY(int button READ button)
- Q_PROPERTY(int buttons READ buttons)
- Q_PROPERTY(int modifiers READ modifiers)
- Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
-
-public:
- InputContextMouseEvent(const QMouseEvent &me)
- : event(me) { event.setAccepted(false);}
-
- int x() const { return event.x(); }
- int y() const { return event.y(); }
- int button() const { return event.button(); }
- int buttons() const { return event.buttons(); }
- int modifiers() const { return event.modifiers(); }
-
- bool isAccepted() { return event.isAccepted(); }
- void setAccepted(bool accepted) { event.setAccepted(accepted); }
-
-private:
- QMouseEvent event;
-};
-
-class InputContextMouseHandler : public QObject
-{
- Q_OBJECT
-public:
- InputContextMouseHandler(QObject *parent = 0);
-
- void processEvent(QEvent::Type type, int cursor, InputContextMouseEvent *event);
-
-signals:
- void pressed(int cursor, InputContextMouseEvent *mouse);
- void released(int cursor, InputContextMouseEvent *mouse);
- void doubleClicked(int cursor, InputContextMouseEvent *mouse);
- void positionChanged(int cursor, InputContextMouseEvent *mouse);
-};
-
-class InputContextMouseFilter : public QObject
-{
- Q_OBJECT
-public:
- InputContextMouseFilter(QObject *parent = 0);
-
- void processEvent(QEvent::Type type, InputContextMouseEvent *event);
-
-signals:
- void pressed(InputContextMouseEvent *mouse);
- void released(InputContextMouseEvent *mouse);
- void doubleClicked(InputContextMouseEvent *mouse);
- void positionChanged(InputContextMouseEvent *mouse);
-};
-
-class InputContextKeyFilter : public QObject
-{
- Q_OBJECT
-public:
- InputContextKeyFilter(QObject *parent = 0);
-
- void processEvent(QEvent::Type type, InputContextKeyEvent *event);
-
-signals:
- void pressed(InputContextKeyEvent *event);
- void released(InputContextKeyEvent *event);
-};
-
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(InputContextKeyEvent)
-QML_DECLARE_TYPE(InputContextMouseEvent)
-QML_DECLARE_TYPE(InputContextMouseHandler)
-QML_DECLARE_TYPE(InputContextMouseFilter)
-QML_DECLARE_TYPE(InputContextKeyFilter)
-
-QT_END_HEADER
-
-#endif
diff --git a/src/imports/inputcontext/inputcontextmodule.cpp b/src/imports/inputcontext/inputcontextmodule.cpp
deleted file mode 100644
index 578fb98733..0000000000
--- a/src/imports/inputcontext/inputcontextmodule.cpp
+++ /dev/null
@@ -1,413 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "inputcontextmodule.h"
-
-#include "declarativeinputcontext.h"
-
-#include <QtCore/qdebug.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qtextformat.h>
-#include <QtWidgets/qapplication.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \qmlmodule Qt.labs.inputcontext InputContextModule
-
- \brief The Qt.labs.inputcontext module provides an API for implementing input methods is QML.
-*/
-
-InputContextModule::InputContextModule(QObject *parent)
- : QObject(parent)
- , m_inputContext(qobject_cast<DeclarativeInputContext *>(qApp->inputContext()))
- , m_focusWidget(m_inputContext ? m_inputContext->focusWidget() : 0)
- , m_visible(false)
-{
- if (m_inputContext)
- m_inputContext->setModule(this);
-}
-
-InputContextModule::~InputContextModule()
-{
- if (m_inputContext)
- m_inputContext->setModule(0);
-}
-
-/*!
- \qmlproperty bool focus
-
- \inqmlmodule Qt.labs.inputcontext
-
- This property identifies whether an item that takes text input has active focus.
-*/
-
-bool InputContextModule::hasFocus() const
-{
- return m_focusWidget != 0;
-}
-
-void InputContextModule::setFocusWidget(QWidget *widget)
-{
- m_focusWidget = widget;
-
- if (!m_focusWidget)
- setVisible(false);
-
- emit focusChanged();
-}
-
-/*!
- \qmlproperty bool softwareInputPanelVisible
-
- \inqmlmodule Qt.labs.inputcontext
-
- This property identifies whether the item with focus has requested a
- software input panel.
-*/
-
-bool InputContextModule::isVisible() const
-{
- return m_visible;
-}
-
-void InputContextModule::setVisible(bool visible)
-{
- if (m_visible != visible) {
- m_visible = visible;
-
- emit visibleChanged();
- }
-}
-
-/*!
- \qmlproperty string preeditText
-
- \inqmlmodule Qt.labs.inputcontext
-
- This property holds the uncommited text that is displayed in the item that
- has focus.
-*/
-
-QString InputContextModule::preeditText() const
-{
- return m_preeditText;
-}
-
-void InputContextModule::setPreeditText(const QString &text)
-{
- if (text != m_preeditText)
- sendPreedit(text);
-}
-
-/*!
- \qmlproperty rectangle microFocus
-
- \inqmlmodule Qt.labs.inputcontext
-
- This property holds a rectangle in scene coordinates around the position
- of the cursor.
-*/
-
-QRect InputContextModule::microFocus() const
-{
- return m_focusWidget
- ? m_focusWidget->inputMethodQuery(Qt::ImMicroFocus).toRect()
- : QRect();
-}
-
-/*!
- \qmlproperty font font
-
- \inqmlmodule Qt.labs.inputcontext
-
- This property holds the font of the text that currently has focus.
-*/
-
-QFont InputContextModule::font() const
-{
- return m_focusWidget
- ? m_focusWidget->inputMethodQuery(Qt::ImFont).value<QFont>()
- : QFont();
-}
-
-/*!
- \qmlproperty int cursorPosition
-
- \inqmlmodule Qt.labs.inputcontext
-
- This property holds the position of the text cursor in the
- \l surroundingText.
-*/
-
-int InputContextModule::cursorPosition() const
-{
- return m_focusWidget
- ? m_focusWidget->inputMethodQuery(Qt::ImCursorPosition).toInt()
- : 0;
-}
-
-/*!
- \qmlproperty int anchorPosition
-
- \inqmlmodule Qt.labs.inputcontext
-
- This property holds the position of the selection anchor in the
- \l surroundingText. If no text is selected this is the same as the
- \l cursorPosition.
-*/
-
-int InputContextModule::anchorPosition() const
-{
- return m_focusWidget
- ? m_focusWidget->inputMethodQuery(Qt::ImAnchorPosition).toInt()
- : 0;
-}
-
-/*!
- \qmlproperty int maximumTextLength
-
- \inqmlmodule Qt.labs.inputcontext
-
- This property holds the maximum number of characters that the item with
- focus can hold. If there is no limit -1 is returned.
-*/
-
-int InputContextModule::maximumTextLength() const
-{
- QVariant length;
- if (m_focusWidget)
- length = m_focusWidget->inputMethodQuery(Qt::ImMaximumTextLength);
- return length.isValid() ? length.toInt() : -1;
-}
-
-/*!
- \qmlproperty string surroundingText
-
- \inqmlmodule Qt.labs.inputcontext
-
- This property holds the plain text around the input area. For example the
- current paragraph.
-*/
-
-QString InputContextModule::surroundingText() const
-{
- return m_focusWidget
- ? m_focusWidget->inputMethodQuery(Qt::ImSurroundingText).toString()
- : QString();
-}
-
-/*!
- \qmlproperty string selectedText
-
- \inqmlmodule Qt.labs.inputcontext
-
- This property holds the currently selected text.
-*/
-
-QString InputContextModule::selectedText() const
-{
- return m_focusWidget
- ? m_focusWidget->inputMethodQuery(Qt::ImCurrentSelection).toString()
- : QString();
-}
-
-/*!
- \qmlmethod sendKeyPress(int key, string text, int modifiers, bool autoRepeat)
-
- \inqmlmodule Qt.labs.inputcontext
-
- This method sends a key press event to the item that currently has focus.
-
- Int key is the code for the Qt::Key that the event loop should listen for.
- If key is 0, the event is not a result of a known key; for example, it may
- be the result of a compose sequence or keyboard macro. The modifiers holds
- the keyboard modifiers, and the given text is the Unicode text that the key
- generated. If autorep is true, isAutoRepeat() will be true. count is the
- number of keys involved in the event.
-*/
-void InputContextModule::sendKeyPress(
- int key, const QString &text, int modifiers, bool autoRepeat, int count)
-{
- if (m_focusWidget) {
- QKeyEvent event(
- QEvent::KeyPress, key, Qt::KeyboardModifiers(modifiers), text, autoRepeat, count);
- if (!m_inputContext || !m_inputContext->filterKeyEvent(&event))
- QApplication::sendEvent(m_focusWidget, &event);
- }
-}
-
-/*!
- \qmlmethod sendKeyRelease(int key, string text, int modifiers)
-
- \inqmlmodule Qt.labs.inputcontext
-
- This method sends a key release event to the item that currently has focus.
-
- Int key is the code for the Qt::Key that the event loop should listen for.
- If key is 0, the event is not a result of a known key; for example, it may
- be the result of a compose sequence or keyboard macro. The modifiers holds
- the keyboard modifiers, and the given text is the Unicode text that the key
- generated. count is the number of keys involved in the event.
-*/
-void InputContextModule::sendKeyRelease(int key, const QString &text, int modifiers, int count)
-{
- if (m_focusWidget) {
- QKeyEvent event(
- QEvent::KeyRelease, key, Qt::KeyboardModifiers(modifiers), text, false, count);
- if (!m_inputContext || !m_inputContext->filterKeyEvent(&event))
- QApplication::sendEvent(m_focusWidget, &event);
- }
-}
-
-/*!
- \qmlmethod sendPreedit(string text, int cursor = -1)
-
- \inqmlmodule Qt.labs.inputcontext
-
- Sends a pre-edit event to the item with active focus.
-
- This will set \l preeditText to \a text, and position the text \a cursor
- within the pre-edit text. If the value of cursor is -1 the cursor will be
- positioned at the end of the pre-edit text.
-*/
-void InputContextModule::sendPreedit(const QString &text, int cursor)
-{
- const QString preedit = m_preeditText;
- m_preeditText = text;
-
- if (m_inputContext) {
- QList<QInputMethodEvent::Attribute> attributes;
-
- if (cursor >= 0 && cursor <= text.length()) {
- attributes.append(QInputMethodEvent::Attribute(
- QInputMethodEvent::Cursor, cursor, text.length(), QVariant()));
- } else {
- cursor = text.length();
- }
-
- if (cursor > 0) {
- attributes.append(QInputMethodEvent::Attribute(
- QInputMethodEvent::TextFormat,
- 0,
- cursor,
- m_inputContext->standardFormat(QInputContext::PreeditFormat)));
- }
- if (cursor < text.length()) {
- attributes.append(QInputMethodEvent::Attribute(
- QInputMethodEvent::TextFormat,
- cursor,
- text.length(),
- m_inputContext->standardFormat(QInputContext::SelectionFormat)));
- }
-
- m_inputContext->sendEvent(QInputMethodEvent(text, attributes));
- }
-
- if (m_preeditText != preedit)
- emit preeditTextChanged();
-}
-
-
-/*!
- \qmlmethod commit()
-
- \inqmlmodule Qt.labs.inputcontext
-
- Commits \l preeditText to the item with active focus.
-*/
-void InputContextModule::commit()
-{
- // Create an explicit copy of m_preeditText as the reference value is cleared before sending
- // the event.
- commit(QString(m_preeditText));
-}
-
-/*!
- \qmlmethod commit(string)
-
- \inqmlmodule Qt.labs.inputcontext
-
- Commits \a text to the item with active focus and clears the current
- \l preeditText. The text will be inserted into the \l surroundingText at a
- position \a replacementStart relative to the \l cursorPosition and will
- replace \a replacementLength characters.
-*/
-void InputContextModule::commit(const QString &text, int replacementStart, int replacementLength)
-{
- const QString preedit = m_preeditText;
- m_preeditText.clear();
-
- if (m_inputContext) {
- QInputMethodEvent inputEvent;
- inputEvent.setCommitString(text, replacementStart, replacementLength);
- m_inputContext->sendEvent(inputEvent);
- }
-
- if (m_preeditText != preedit)
- emit preeditTextChanged();
-}
-
-/*!
- \qmlmethod clear()
-
- \inqmlmodule Qt.labs.inputcontext
-
- Clears the current \l preeditText.
-*/
-void InputContextModule::clear()
-{
- const QString preedit = m_preeditText;
- m_preeditText.clear();
-
- if (m_inputContext)
- m_inputContext->sendEvent(QInputMethodEvent());
-
- if (m_preeditText != preedit)
- emit preeditTextChanged();
-}
-
-void InputContextModule::update()
-{
- emit contextUpdated();
-}
-
-QT_END_NAMESPACE
diff --git a/src/imports/inputcontext/inputcontextmodule.h b/src/imports/inputcontext/inputcontextmodule.h
deleted file mode 100644
index 079890ba9a..0000000000
--- a/src/imports/inputcontext/inputcontextmodule.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef INPUTCONTEXTMODULE_H
-#define INPUTCONTEXTMODULE_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qrect.h>
-#include <QtGui/qfont.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class DeclarativeInputContext;
-
-class InputContextModule : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(bool softwareInputPanelVisible READ isVisible WRITE setVisible NOTIFY visibleChanged)
- Q_PROPERTY(bool focus READ hasFocus NOTIFY focusChanged)
- Q_PROPERTY(QString preeditText READ preeditText WRITE setPreeditText NOTIFY preeditTextChanged)
- Q_PROPERTY(QRect microFocus READ microFocus NOTIFY contextUpdated)
- Q_PROPERTY(QFont font READ font NOTIFY contextUpdated)
- Q_PROPERTY(int cursorPosition READ cursorPosition NOTIFY contextUpdated)
- Q_PROPERTY(int anchorPosition READ anchorPosition NOTIFY contextUpdated)
- Q_PROPERTY(int maximumTextLength READ maximumTextLength NOTIFY contextUpdated)
- Q_PROPERTY(QString surroundingText READ surroundingText NOTIFY contextUpdated)
- Q_PROPERTY(QString selectedText READ selectedText NOTIFY contextUpdated)
-public:
- explicit InputContextModule(QObject *parent = 0);
- ~InputContextModule();
-
- bool hasFocus() const;
- void setFocusWidget(QWidget *widget);
-
- bool isVisible() const;
- void setVisible(bool visible);
-
- QString preeditText() const;
- void setPreeditText(const QString &text);
-
- QRect microFocus() const;
- QFont font() const;
- int cursorPosition() const;
- int anchorPosition() const;
- int maximumTextLength() const;
- QString surroundingText() const;
- QString selectedText() const;
-
- Q_INVOKABLE void sendKeyPress(
- int key, const QString &text, int modifiers = 0, bool autoRepeat = false, int count = 1);
- Q_INVOKABLE void sendKeyRelease(int key, const QString &text, int modifiers = 0, int count = 1);
-
- Q_INVOKABLE void sendPreedit(const QString &text, int cursor = -1);
-
- Q_INVOKABLE void commit();
- Q_INVOKABLE void commit(const QString &text, int replacementStart = 0, int replacementEnd = 0);
-
- Q_INVOKABLE void clear();
-
- void update();
-
-signals:
- void preeditTextChanged();
- void visibleChanged();
- void contextUpdated();
- void focusChanged();
-
-private:
- QString m_preeditText;
- DeclarativeInputContext *m_inputContext;
- QWidget *m_focusWidget;
- bool m_visible;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
diff --git a/src/imports/inputcontext/qmldir b/src/imports/inputcontext/qmldir
deleted file mode 100644
index 3fb65a6e0e..0000000000
--- a/src/imports/inputcontext/qmldir
+++ /dev/null
@@ -1 +0,0 @@
-plugin qmlinputcontextplugin
diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml
index 020f934aac..fd04c786a2 100644
--- a/src/imports/testlib/TestCase.qml
+++ b/src/imports/testlib/TestCase.qml
@@ -307,14 +307,15 @@ Item {
function skip(msg) {
if (msg === undefined)
msg = ""
- qtest_results.skipSingle(msg, util.callerFile(), util.callerLine())
+ qtest_results.skip(msg, util.callerFile(), util.callerLine())
throw new Error("QtQuickTest::skip")
}
function skipAll(msg) {
if (msg === undefined)
msg = ""
- qtest_results.skipAll(msg, util.callerFile(), util.callerLine())
+ warn("The skipAll function is deprecated and will be removed soon. Please update this test by changing skipAll to skip.")
+ qtest_results.skip(msg, util.callerFile(), util.callerLine())
throw new Error("QtQuickTest::skip")
}
diff --git a/src/imports/testlib/main.cpp b/src/imports/testlib/main.cpp
index c12b9423a9..a6fb992fed 100644
--- a/src/imports/testlib/main.cpp
+++ b/src/imports/testlib/main.cpp
@@ -48,13 +48,14 @@
#include "private/qtestoptions_p.h"
#include "QtDeclarative/qsgitem.h"
#include <QtDeclarative/private/qdeclarativeengine_p.h>
-QT_BEGIN_NAMESPACE
QML_DECLARE_TYPE(QuickTestResult)
QML_DECLARE_TYPE(QuickTestEvent)
#include <QtDebug>
+QT_BEGIN_NAMESPACE
+
class QuickTestUtil : public QObject
{
Q_OBJECT
@@ -145,8 +146,13 @@ public Q_SLOTS:
return -1;
}
};
+
+QT_END_NAMESPACE
+
QML_DECLARE_TYPE(QuickTestUtil)
+QT_BEGIN_NAMESPACE
+
class QTestQmlModule : public QDeclarativeExtensionPlugin
{
Q_OBJECT
diff --git a/src/imports/testlib/testcase.qdoc b/src/imports/testlib/testcase.qdoc
index c08af334e5..719d9baea7 100644
--- a/src/imports/testlib/testcase.qdoc
+++ b/src/imports/testlib/testcase.qdoc
@@ -362,19 +362,7 @@
Skips the current test case and prints the optional \a message.
If this is a data-driven test, then only the current row is skipped.
- Similar to \c{QSKIP(message, SkipSingle)} in C++.
-
- \sa skipAll()
-*/
-
-/*!
- \qmlmethod TestCase::skipAll(message = "")
-
- Skips the current test case and prints the optional \a message.
- If this is a data-driven test, then all remaining rows are skipped.
- Similar to \c{QSKIP(message, SkipAll)} in C++.
-
- \sa skip()
+ Similar to \c{QSKIP(message)} in C++.
*/
/*!
diff --git a/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp b/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp
index 8dcc076630..86a42c217c 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp
+++ b/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.cpp
@@ -42,7 +42,6 @@
#include "abstractviewinspector.h"
#include "abstracttool.h"
-#include "editor/qmltoolbar.h"
#include "qdeclarativeinspectorprotocol.h"
#include <QtDeclarative/QDeclarativeEngine>
@@ -54,53 +53,12 @@
#include <QtGui/QMouseEvent>
#include <QtCore/QSettings>
-static inline void initEditorResource() { Q_INIT_RESOURCE(editor); }
-
namespace QmlJSDebugger {
-const char * const KEY_TOOLBOX_GEOMETRY = "toolBox/geometry";
-
-
-class ToolBox : public QWidget
-{
- Q_OBJECT
-
-public:
- ToolBox(QWidget *parent = 0);
- ~ToolBox();
-
- QmlToolBar *toolBar() const { return m_toolBar; }
-
-private:
- QSettings m_settings;
- QmlToolBar *m_toolBar;
-};
-
-ToolBox::ToolBox(QWidget *parent)
- : QWidget(parent, Qt::Tool)
- , m_settings(QLatin1String("Nokia"), QLatin1String("QmlInspector"), this)
- , m_toolBar(new QmlToolBar)
-{
- setWindowFlags((windowFlags() & ~Qt::WindowCloseButtonHint) | Qt::CustomizeWindowHint);
- setWindowTitle(tr("Qt Quick Toolbox"));
-
- QVBoxLayout *verticalLayout = new QVBoxLayout;
- verticalLayout->setMargin(0);
- verticalLayout->addWidget(m_toolBar);
- setLayout(verticalLayout);
-
- restoreGeometry(m_settings.value(QLatin1String(KEY_TOOLBOX_GEOMETRY)).toByteArray());
-}
-
-ToolBox::~ToolBox()
-{
- m_settings.setValue(QLatin1String(KEY_TOOLBOX_GEOMETRY), saveGeometry());
-}
AbstractViewInspector::AbstractViewInspector(QObject *parent) :
QObject(parent),
- m_toolBox(0),
m_currentTool(0),
m_showAppOnTop(false),
m_designModeBehavior(false),
@@ -108,8 +66,6 @@ AbstractViewInspector::AbstractViewInspector(QObject *parent) :
m_slowDownFactor(1.0),
m_debugService(0)
{
- initEditorResource();
-
m_debugService = QDeclarativeInspectorService::instance();
connect(m_debugService, SIGNAL(gotMessage(QByteArray)),
this, SLOT(handleMessage(QByteArray)));
@@ -198,17 +154,13 @@ void AbstractViewInspector::animationPausedChangeRequested(bool paused)
void AbstractViewInspector::setShowAppOnTop(bool appOnTop)
{
- if (viewWidget()) {
- QWidget *window = viewWidget()->window();
- Qt::WindowFlags flags = window->windowFlags();
- if (appOnTop)
- flags |= Qt::WindowStaysOnTopHint;
- else
- flags &= ~Qt::WindowStaysOnTopHint;
+ Qt::WindowFlags flags = windowFlags();
+ if (appOnTop)
+ flags |= Qt::WindowStaysOnTopHint;
+ else
+ flags &= ~Qt::WindowStaysOnTopHint;
- window->setWindowFlags(flags);
- window->show();
- }
+ setWindowFlags(flags);
m_showAppOnTop = appOnTop;
sendShowAppOnTop(appOnTop);
@@ -216,59 +168,6 @@ void AbstractViewInspector::setShowAppOnTop(bool appOnTop)
emit showAppOnTopChanged(appOnTop);
}
-void AbstractViewInspector::setToolBoxVisible(bool visible)
-{
-#if !defined(Q_OS_SYMBIAN) && !defined(Q_WS_MAEMO_5) && !defined(Q_WS_SIMULATOR)
- if (!m_toolBox && visible)
- createToolBox();
- if (m_toolBox)
- m_toolBox->setVisible(visible);
-#else
- Q_UNUSED(visible)
-#endif
-}
-
-void AbstractViewInspector::createToolBox()
-{
- m_toolBox = new ToolBox(viewWidget());
-
- QmlToolBar *toolBar = m_toolBox->toolBar();
-
- QObject::connect(this, SIGNAL(selectedColorChanged(QColor)),
- toolBar, SLOT(setColorBoxColor(QColor)));
-
- QObject::connect(this, SIGNAL(designModeBehaviorChanged(bool)),
- toolBar, SLOT(setDesignModeBehavior(bool)));
-
- QObject::connect(toolBar, SIGNAL(designModeBehaviorChanged(bool)),
- this, SLOT(setDesignModeBehavior(bool)));
- QObject::connect(toolBar, SIGNAL(animationSpeedChanged(qreal)), this, SLOT(setAnimationSpeed(qreal)));
- QObject::connect(toolBar, SIGNAL(animationPausedChanged(bool)), this, SLOT(setAnimationPaused(bool)));
- QObject::connect(toolBar, SIGNAL(colorPickerSelected()), this, SLOT(changeToColorPickerTool()));
- QObject::connect(toolBar, SIGNAL(zoomToolSelected()), this, SLOT(changeToZoomTool()));
- QObject::connect(toolBar, SIGNAL(selectToolSelected()), this, SLOT(changeToSingleSelectTool()));
- QObject::connect(toolBar, SIGNAL(marqueeSelectToolSelected()),
- this, SLOT(changeToMarqueeSelectTool()));
-
- QObject::connect(toolBar, SIGNAL(applyChangesFromQmlFileSelected()),
- this, SLOT(applyChangesFromClient()));
-
- QObject::connect(this, SIGNAL(animationSpeedChanged(qreal)), toolBar, SLOT(setAnimationSpeed(qreal)));
- QObject::connect(this, SIGNAL(animationPausedChanged(bool)), toolBar, SLOT(setAnimationPaused(bool)));
-
- QObject::connect(this, SIGNAL(selectToolActivated()), toolBar, SLOT(activateSelectTool()));
-
- // disabled features
- //connect(d->m_toolBar, SIGNAL(applyChangesToQmlFileSelected()), SLOT(applyChangesToClient()));
- //connect(q, SIGNAL(resizeToolActivated()), d->m_toolBar, SLOT(activateSelectTool()));
- //connect(q, SIGNAL(moveToolActivated()), d->m_toolBar, SLOT(activateSelectTool()));
-
- QObject::connect(this, SIGNAL(colorPickerActivated()), toolBar, SLOT(activateColorPicker()));
- QObject::connect(this, SIGNAL(zoomToolActivated()), toolBar, SLOT(activateZoom()));
- QObject::connect(this, SIGNAL(marqueeSelectToolActivated()),
- toolBar, SLOT(activateMarqueeSelectTool()));
-}
-
void AbstractViewInspector::changeToColorPickerTool()
{
changeTool(InspectorProtocol::ColorPickerTool);
@@ -609,5 +508,3 @@ QString AbstractViewInspector::idStringForObject(QObject *obj) const
}
} // namespace QmlJSDebugger
-
-#include "abstractviewinspector.moc"
diff --git a/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.h b/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.h
index 7202bcca40..7d9ad955dc 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.h
+++ b/src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.h
@@ -87,7 +87,9 @@ public:
void clearComponentCache();
- virtual QWidget *viewWidget() const = 0;
+ virtual Qt::WindowFlags windowFlags() const = 0;
+ virtual void setWindowFlags(Qt::WindowFlags flags) = 0;
+
virtual QDeclarativeEngine *declarativeEngine() const = 0;
@@ -157,10 +159,6 @@ private:
void animationSpeedChangeRequested(qreal factor);
void animationPausedChangeRequested(bool paused);
- void setToolBoxVisible(bool visible);
- void createToolBox();
-
- ToolBox *m_toolBox;
AbstractTool *m_currentTool;
bool m_showAppOnTop;
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/editor.qrc b/src/plugins/qmltooling/qmldbg_inspector/editor/editor.qrc
deleted file mode 100644
index fb2393caa1..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/editor.qrc
+++ /dev/null
@@ -1,24 +0,0 @@
-<RCC>
- <qresource prefix="/qml">
- <file>images/resize_handle.png</file>
- <file>images/select.png</file>
- <file>images/select-marquee.png</file>
- <file>images/color-picker.png</file>
- <file>images/play.png</file>
- <file>images/pause.png</file>
- <file>images/from-qml.png</file>
- <file>images/to-qml.png</file>
- <file>images/color-picker-hicontrast.png</file>
- <file>images/zoom.png</file>
- <file>images/color-picker-24.png</file>
- <file>images/from-qml-24.png</file>
- <file>images/pause-24.png</file>
- <file>images/play-24.png</file>
- <file>images/to-qml-24.png</file>
- <file>images/zoom-24.png</file>
- <file>images/select-24.png</file>
- <file>images/select-marquee-24.png</file>
- <file>images/inspectormode.png</file>
- <file>images/inspectormode-24.png</file>
- </qresource>
-</RCC>
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/color-picker-24.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/color-picker-24.png
deleted file mode 100644
index cff47212a4..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/color-picker-24.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/color-picker-hicontrast.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/color-picker-hicontrast.png
deleted file mode 100644
index b953d08a68..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/color-picker-hicontrast.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/color-picker.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/color-picker.png
deleted file mode 100644
index 026c31b3e1..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/color-picker.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/from-qml-24.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/from-qml-24.png
deleted file mode 100644
index 0ad21f3dbb..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/from-qml-24.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/from-qml.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/from-qml.png
deleted file mode 100644
index 666382c06d..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/from-qml.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/inspectormode-24.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/inspectormode-24.png
deleted file mode 100644
index 5e74d867c0..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/inspectormode-24.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/inspectormode.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/inspectormode.png
deleted file mode 100644
index daed21c944..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/inspectormode.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/pause-24.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/pause-24.png
deleted file mode 100644
index d9a2f6f814..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/pause-24.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/pause.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/pause.png
deleted file mode 100644
index 114d89b12b..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/pause.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/play-24.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/play-24.png
deleted file mode 100644
index e2b9fbcf51..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/play-24.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/play.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/play.png
deleted file mode 100644
index 011598a746..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/play.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/reload.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/reload.png
deleted file mode 100644
index 7042bec9ae..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/reload.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/resize_handle.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/resize_handle.png
deleted file mode 100644
index 2934f25b74..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/resize_handle.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/select-24.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/select-24.png
deleted file mode 100644
index 5388a9d16a..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/select-24.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/select-marquee-24.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/select-marquee-24.png
deleted file mode 100644
index 0111ddae45..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/select-marquee-24.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/select-marquee.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/select-marquee.png
deleted file mode 100644
index 92fe40d1ad..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/select-marquee.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/select.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/select.png
deleted file mode 100644
index 672285582b..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/select.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/to-qml-24.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/to-qml-24.png
deleted file mode 100644
index b72450ddd4..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/to-qml-24.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/to-qml.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/to-qml.png
deleted file mode 100644
index 2ab951fd08..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/to-qml.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/zoom-24.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/zoom-24.png
deleted file mode 100644
index 03462001ec..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/zoom-24.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/images/zoom.png b/src/plugins/qmltooling/qmldbg_inspector/editor/images/zoom.png
deleted file mode 100644
index 17f0da6d64..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/images/zoom.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/qmltoolbar.cpp b/src/plugins/qmltooling/qmldbg_inspector/editor/qmltoolbar.cpp
deleted file mode 100644
index 1f3a1e12c2..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/qmltoolbar.cpp
+++ /dev/null
@@ -1,328 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmltoolbar.h"
-#include "toolbarcolorbox.h"
-
-#include <QtWidgets/QLabel>
-#include <QtWidgets/QIcon>
-#include <QtWidgets/QAction>
-#include <QtWidgets/QMenu>
-
-#include <QtCore/QDebug>
-
-namespace QmlJSDebugger {
-
-QmlToolBar::QmlToolBar(QWidget *parent)
- : QToolBar(parent)
- , m_emitSignals(true)
- , m_paused(false)
- , m_animationSpeed(1.0f)
- , ui(new Ui)
-{
- ui->playIcon = QIcon(QLatin1String(":/qml/images/play-24.png"));
- ui->pauseIcon = QIcon(QLatin1String(":/qml/images/pause-24.png"));
-
- ui->designmode = new QAction(QIcon(QLatin1String(":/qml/images/inspectormode-24.png")),
- tr("Inspector Mode"), this);
- ui->play = new QAction(ui->pauseIcon, tr("Play/Pause Animations"), this);
- ui->select = new QAction(QIcon(QLatin1String(":/qml/images/select-24.png")), tr("Select"), this);
- ui->selectMarquee = new QAction(QIcon(QLatin1String(":/qml/images/select-marquee-24.png")),
- tr("Select (Marquee)"), this);
- ui->zoom = new QAction(QIcon(QLatin1String(":/qml/images/zoom-24.png")), tr("Zoom"), this);
- ui->colorPicker = new QAction(QIcon(QLatin1String(":/qml/images/color-picker-24.png")),
- tr("Color Picker"), this);
- ui->toQml = new QAction(QIcon(QLatin1String(":/qml/images/to-qml-24.png")),
- tr("Apply Changes to QML Viewer"), this);
- ui->fromQml = new QAction(QIcon(QLatin1String(":/qml/images/from-qml-24.png")),
- tr("Apply Changes to Document"), this);
- ui->designmode->setCheckable(true);
- ui->designmode->setChecked(false);
-
- ui->play->setCheckable(false);
- ui->select->setCheckable(true);
- ui->selectMarquee->setCheckable(true);
- ui->zoom->setCheckable(true);
- ui->colorPicker->setCheckable(true);
-
- setWindowTitle(tr("Tools"));
-
- addAction(ui->designmode);
- addAction(ui->play);
- addSeparator();
-
- addAction(ui->select);
- // disabled because multi selection does not do anything useful without design mode
- //addAction(ui->selectMarquee);
- addSeparator();
- addAction(ui->zoom);
- addAction(ui->colorPicker);
- //addAction(ui->fromQml);
-
- ui->colorBox = new ToolBarColorBox(this);
- ui->colorBox->setMinimumSize(24, 24);
- ui->colorBox->setMaximumSize(28, 28);
- ui->colorBox->setColor(Qt::black);
- addWidget(ui->colorBox);
-
- setWindowFlags(Qt::Tool);
-
- QMenu *playSpeedMenu = new QMenu(this);
- ui->playSpeedMenuActions = new QActionGroup(this);
- ui->playSpeedMenuActions->setExclusive(true);
-
- QAction *speedAction = playSpeedMenu->addAction(tr("1x"), this, SLOT(changeAnimationSpeed()));
- speedAction->setCheckable(true);
- speedAction->setChecked(true);
- speedAction->setData(1.0f);
- ui->playSpeedMenuActions->addAction(speedAction);
-
- speedAction = playSpeedMenu->addAction(tr("0.5x"), this, SLOT(changeAnimationSpeed()));
- speedAction->setCheckable(true);
- speedAction->setData(2.0f);
- ui->playSpeedMenuActions->addAction(speedAction);
-
- speedAction = playSpeedMenu->addAction(tr("0.25x"), this, SLOT(changeAnimationSpeed()));
- speedAction->setCheckable(true);
- speedAction->setData(4.0f);
- ui->playSpeedMenuActions->addAction(speedAction);
-
- speedAction = playSpeedMenu->addAction(tr("0.125x"), this, SLOT(changeAnimationSpeed()));
- speedAction->setCheckable(true);
- speedAction->setData(8.0f);
- ui->playSpeedMenuActions->addAction(speedAction);
-
- speedAction = playSpeedMenu->addAction(tr("0.1x"), this, SLOT(changeAnimationSpeed()));
- speedAction->setCheckable(true);
- speedAction->setData(10.0f);
- ui->playSpeedMenuActions->addAction(speedAction);
-
- ui->play->setMenu(playSpeedMenu);
-
- connect(ui->designmode, SIGNAL(toggled(bool)), SLOT(setDesignModeBehaviorOnClick(bool)));
-
- connect(ui->colorPicker, SIGNAL(triggered()), SLOT(activateColorPickerOnClick()));
-
- connect(ui->play, SIGNAL(triggered()), SLOT(activatePlayOnClick()));
-
- connect(ui->zoom, SIGNAL(triggered()), SLOT(activateZoomOnClick()));
- connect(ui->colorPicker, SIGNAL(triggered()), SLOT(activateColorPickerOnClick()));
- connect(ui->select, SIGNAL(triggered()), SLOT(activateSelectToolOnClick()));
- connect(ui->selectMarquee, SIGNAL(triggered()), SLOT(activateMarqueeSelectToolOnClick()));
-
- connect(ui->toQml, SIGNAL(triggered()), SLOT(activateToQml()));
- connect(ui->fromQml, SIGNAL(triggered()), SLOT(activateFromQml()));
-}
-
-QmlToolBar::~QmlToolBar()
-{
- delete ui;
-}
-
-void QmlToolBar::activateColorPicker()
-{
- m_emitSignals = false;
- activateColorPickerOnClick();
- m_emitSignals = true;
-}
-
-void QmlToolBar::activateSelectTool()
-{
- m_emitSignals = false;
- activateSelectToolOnClick();
- m_emitSignals = true;
-}
-
-void QmlToolBar::activateMarqueeSelectTool()
-{
- m_emitSignals = false;
- activateMarqueeSelectToolOnClick();
- m_emitSignals = true;
-}
-
-void QmlToolBar::activateZoom()
-{
- m_emitSignals = false;
- activateZoomOnClick();
- m_emitSignals = true;
-}
-
-void QmlToolBar::setAnimationSpeed(qreal slowDownFactor)
-{
- if (m_animationSpeed == slowDownFactor)
- return;
-
- m_emitSignals = false;
- m_animationSpeed = slowDownFactor;
-
- foreach (QAction *action, ui->playSpeedMenuActions->actions()) {
- if (action->data().toReal() == slowDownFactor) {
- action->setChecked(true);
- break;
- }
- }
-
- m_emitSignals = true;
-}
-
-void QmlToolBar::setAnimationPaused(bool paused)
-{
- if (m_paused == paused)
- return;
-
- m_paused = paused;
- updatePlayAction();
-}
-
-void QmlToolBar::changeAnimationSpeed()
-{
- QAction *action = qobject_cast<QAction*>(sender());
- m_animationSpeed = action->data().toReal();
- emit animationSpeedChanged(m_animationSpeed);
-}
-
-void QmlToolBar::setDesignModeBehavior(bool inDesignMode)
-{
- m_emitSignals = false;
- ui->designmode->setChecked(inDesignMode);
- setDesignModeBehaviorOnClick(inDesignMode);
- m_emitSignals = true;
-}
-
-void QmlToolBar::setDesignModeBehaviorOnClick(bool checked)
-{
- ui->select->setEnabled(checked);
- ui->selectMarquee->setEnabled(checked);
- ui->zoom->setEnabled(checked);
- ui->colorPicker->setEnabled(checked);
- ui->toQml->setEnabled(checked);
- ui->fromQml->setEnabled(checked);
-
- if (m_emitSignals)
- emit designModeBehaviorChanged(checked);
-}
-
-void QmlToolBar::setColorBoxColor(const QColor &color)
-{
- ui->colorBox->setColor(color);
-}
-
-void QmlToolBar::activatePlayOnClick()
-{
- m_paused = !m_paused;
- emit animationPausedChanged(m_paused);
- updatePlayAction();
-}
-
-void QmlToolBar::updatePlayAction()
-{
- ui->play->setIcon(m_paused ? ui->playIcon : ui->pauseIcon);
-}
-
-void QmlToolBar::activateColorPickerOnClick()
-{
- ui->zoom->setChecked(false);
- ui->select->setChecked(false);
- ui->selectMarquee->setChecked(false);
-
- ui->colorPicker->setChecked(true);
- if (m_activeTool != Constants::ColorPickerMode) {
- m_activeTool = Constants::ColorPickerMode;
- if (m_emitSignals)
- emit colorPickerSelected();
- }
-}
-
-void QmlToolBar::activateSelectToolOnClick()
-{
- ui->zoom->setChecked(false);
- ui->selectMarquee->setChecked(false);
- ui->colorPicker->setChecked(false);
-
- ui->select->setChecked(true);
- if (m_activeTool != Constants::SelectionToolMode) {
- m_activeTool = Constants::SelectionToolMode;
- if (m_emitSignals)
- emit selectToolSelected();
- }
-}
-
-void QmlToolBar::activateMarqueeSelectToolOnClick()
-{
- ui->zoom->setChecked(false);
- ui->select->setChecked(false);
- ui->colorPicker->setChecked(false);
-
- ui->selectMarquee->setChecked(true);
- if (m_activeTool != Constants::MarqueeSelectionToolMode) {
- m_activeTool = Constants::MarqueeSelectionToolMode;
- if (m_emitSignals)
- emit marqueeSelectToolSelected();
- }
-}
-
-void QmlToolBar::activateZoomOnClick()
-{
- ui->select->setChecked(false);
- ui->selectMarquee->setChecked(false);
- ui->colorPicker->setChecked(false);
-
- ui->zoom->setChecked(true);
- if (m_activeTool != Constants::ZoomMode) {
- m_activeTool = Constants::ZoomMode;
- if (m_emitSignals)
- emit zoomToolSelected();
- }
-}
-
-void QmlToolBar::activateFromQml()
-{
- if (m_emitSignals)
- emit applyChangesFromQmlFileSelected();
-}
-
-void QmlToolBar::activateToQml()
-{
- if (m_emitSignals)
- emit applyChangesToQmlFileSelected();
-}
-
-} // namespace QmlJSDebugger
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/qmltoolbar.h b/src/plugins/qmltooling/qmldbg_inspector/editor/qmltoolbar.h
deleted file mode 100644
index 177885f700..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/qmltoolbar.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QMLTOOLBAR_H
-#define QMLTOOLBAR_H
-
-#include <QtWidgets/QToolBar>
-#include <QtWidgets/QIcon>
-
-#include "../qmlinspectorconstants.h"
-
-QT_FORWARD_DECLARE_CLASS(QActionGroup)
-
-namespace QmlJSDebugger {
-
-class ToolBarColorBox;
-
-class QmlToolBar : public QToolBar
-{
- Q_OBJECT
-
-public:
- explicit QmlToolBar(QWidget *parent = 0);
- ~QmlToolBar();
-
-public slots:
- void setDesignModeBehavior(bool inDesignMode);
- void setColorBoxColor(const QColor &color);
- void activateColorPicker();
- void activateSelectTool();
- void activateMarqueeSelectTool();
- void activateZoom();
-
- void setAnimationSpeed(qreal slowDownFactor);
- void setAnimationPaused(bool paused);
-
-signals:
- void animationSpeedChanged(qreal factor);
- void animationPausedChanged(bool paused);
-
- void designModeBehaviorChanged(bool inDesignMode);
- void colorPickerSelected();
- void selectToolSelected();
- void marqueeSelectToolSelected();
- void zoomToolSelected();
-
- void applyChangesToQmlFileSelected();
- void applyChangesFromQmlFileSelected();
-
-private slots:
- void setDesignModeBehaviorOnClick(bool inDesignMode);
- void activatePlayOnClick();
- void activateColorPickerOnClick();
- void activateSelectToolOnClick();
- void activateMarqueeSelectToolOnClick();
- void activateZoomOnClick();
-
- void activateFromQml();
- void activateToQml();
-
- void changeAnimationSpeed();
-
- void updatePlayAction();
-
-private:
- class Ui {
- public:
- QAction *designmode;
- QAction *play;
- QAction *select;
- QAction *selectMarquee;
- QAction *zoom;
- QAction *colorPicker;
- QAction *toQml;
- QAction *fromQml;
- QIcon playIcon;
- QIcon pauseIcon;
- ToolBarColorBox *colorBox;
-
- QActionGroup *playSpeedMenuActions;
- };
-
- bool m_emitSignals;
- bool m_paused;
- qreal m_animationSpeed;
-
- Constants::DesignTool m_activeTool;
-
- Ui *ui;
-};
-
-}
-
-#endif // QMLTOOLBAR_H
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/toolbarcolorbox.cpp b/src/plugins/qmltooling/qmldbg_inspector/editor/toolbarcolorbox.cpp
deleted file mode 100644
index 64d4035d09..0000000000
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/toolbarcolorbox.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "toolbarcolorbox.h"
-
-#include "../qmlinspectorconstants.h"
-
-#include <QtGui/QPixmap>
-#include <QtGui/QPainter>
-#include <QtWidgets/QMenu>
-#include <QtWidgets/QAction>
-#include <QtGui/QContextMenuEvent>
-#include <QtGui/QClipboard>
-#include <QtWidgets/QApplication>
-#include <QtWidgets/QColorDialog>
-#include <QtGui/QDrag>
-
-#include <QtCore/QMimeData>
-#include <QtCore/QDebug>
-
-namespace QmlJSDebugger {
-
-ToolBarColorBox::ToolBarColorBox(QWidget *parent) :
- QLabel(parent)
-{
- m_copyHexColor = new QAction(QIcon(QLatin1String(":/qml/images/color-picker-hicontrast.png")),
- tr("Copy Color"), this);
- connect(m_copyHexColor, SIGNAL(triggered()), SLOT(copyColorToClipboard()));
- setScaledContents(false);
-}
-
-void ToolBarColorBox::setColor(const QColor &color)
-{
- m_color = color;
-
- QPixmap pix = createDragPixmap(width());
- setPixmap(pix);
- update();
-}
-
-void ToolBarColorBox::mousePressEvent(QMouseEvent *event)
-{
- m_dragBeginPoint = event->pos();
- m_dragStarted = false;
-}
-
-void ToolBarColorBox::mouseMoveEvent(QMouseEvent *event)
-{
-
- if (event->buttons() & Qt::LeftButton
- && (QPoint(event->pos() - m_dragBeginPoint).manhattanLength()
- > Constants::DragStartDistance)
- && !m_dragStarted)
- {
- m_dragStarted = true;
- QDrag *drag = new QDrag(this);
- QMimeData *mimeData = new QMimeData;
-
- mimeData->setText(m_color.name());
- drag->setMimeData(mimeData);
- drag->setPixmap(createDragPixmap());
-
- drag->exec();
- }
-}
-
-QPixmap ToolBarColorBox::createDragPixmap(int size) const
-{
- QPixmap pix(size, size);
- QPainter p(&pix);
-
- QColor borderColor1 = QColor(143, 143 ,143);
- QColor borderColor2 = QColor(43, 43, 43);
-
- p.setBrush(QBrush(m_color));
- p.setPen(QPen(QBrush(borderColor2),1));
-
- p.fillRect(0, 0, size, size, borderColor1);
- p.drawRect(1,1, size - 3, size - 3);
- return pix;
-}
-
-void ToolBarColorBox::contextMenuEvent(QContextMenuEvent *ev)
-{
- QMenu contextMenu;
- contextMenu.addAction(m_copyHexColor);
- contextMenu.exec(ev->globalPos());
-}
-
-void ToolBarColorBox::copyColorToClipboard()
-{
- QClipboard *clipboard = QApplication::clipboard();
- clipboard->setText(m_color.name());
-}
-
-} // namespace QmlJSDebugger
diff --git a/src/plugins/qmltooling/qmldbg_inspector/qdeclarativeviewinspector.cpp b/src/plugins/qmltooling/qmldbg_inspector/qdeclarativeviewinspector.cpp
index f97ce010ba..4b284b7209 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/qdeclarativeviewinspector.cpp
+++ b/src/plugins/qmltooling/qmldbg_inspector/qdeclarativeviewinspector.cpp
@@ -49,12 +49,7 @@
#include "editor/boundingrecthighlighter.h"
#include <QtQuick1/QDeclarativeItem>
-#include <QtDeclarative/QDeclarativeEngine>
-#include <QtDeclarative/QDeclarativeContext>
-#include <QtDeclarative/QDeclarativeExpression>
-#include <QtWidgets/QWidget>
#include <QtGui/QMouseEvent>
-#include <QtWidgets/QGraphicsObject>
namespace QmlJSDebugger {
@@ -141,6 +136,17 @@ void QDeclarativeViewInspector::changeTool(InspectorProtocol::Tool tool)
}
}
+Qt::WindowFlags QDeclarativeViewInspector::windowFlags() const
+{
+ return declarativeView()->window()->windowFlags();
+}
+
+void QDeclarativeViewInspector::setWindowFlags(Qt::WindowFlags flags)
+{
+ declarativeView()->window()->setWindowFlags(flags);
+ declarativeView()->window()->show();
+}
+
AbstractLiveEditTool *QDeclarativeViewInspector::currentTool() const
{
return static_cast<AbstractLiveEditTool*>(AbstractViewInspector::currentTool());
diff --git a/src/plugins/qmltooling/qmldbg_inspector/qdeclarativeviewinspector.h b/src/plugins/qmltooling/qmldbg_inspector/qdeclarativeviewinspector.h
index 1a1b167622..c769a956e8 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/qdeclarativeviewinspector.h
+++ b/src/plugins/qmltooling/qmldbg_inspector/qdeclarativeviewinspector.h
@@ -68,7 +68,8 @@ public:
void reloadView();
void reparentQmlObject(QObject *object, QObject *newParent);
void changeTool(InspectorProtocol::Tool tool);
- QWidget *viewWidget() const { return declarativeView(); }
+ Qt::WindowFlags windowFlags() const;
+ void setWindowFlags(Qt::WindowFlags flags);
QDeclarativeEngine *declarativeEngine() const;
void setSelectedItems(QList<QGraphicsItem *> items);
diff --git a/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro b/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro
index c165832013..38358da79b 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro
+++ b/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro
@@ -23,8 +23,6 @@ SOURCES += \
editor/subcomponentmasklayeritem.cpp \
editor/zoomtool.cpp \
editor/colorpickertool.cpp \
- editor/qmltoolbar.cpp \
- editor/toolbarcolorbox.cpp \
abstracttool.cpp \
sgviewinspector.cpp \
sgselectiontool.cpp \
@@ -48,15 +46,11 @@ HEADERS += \
editor/subcomponentmasklayeritem.h \
editor/zoomtool.h \
editor/colorpickertool.h \
- editor/qmltoolbar.h \
- editor/toolbarcolorbox.h \
abstracttool.h \
sgviewinspector.h \
sgselectiontool.h \
sghighlight.h
-RESOURCES += editor/editor.qrc
-
target.path += $$[QT_INSTALL_PLUGINS]/qmltooling
INSTALLS += target
diff --git a/src/plugins/qmltooling/qmldbg_inspector/sgviewinspector.cpp b/src/plugins/qmltooling/qmldbg_inspector/sgviewinspector.cpp
index 497e51db4d..a6f405261d 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/sgviewinspector.cpp
+++ b/src/plugins/qmltooling/qmldbg_inspector/sgviewinspector.cpp
@@ -45,12 +45,10 @@
#include "sghighlight.h"
#include "sgselectiontool.h"
-#include <QtDeclarative/private/qdeclarativeinspectorservice_p.h>
#include <QtDeclarative/private/qsgitem_p.h>
#include <QtDeclarative/QSGView>
#include <QtDeclarative/QSGItem>
-#include <QtGui/QMouseEvent>
#include <cfloat>
@@ -126,8 +124,9 @@ SGViewInspector::SGViewInspector(QSGView *view, QObject *parent) :
// Try to make sure the overlay is always on top
m_overlay->setZ(FLT_MAX);
+ // TODO
// Make sure mouse hover events are received
- m_view->setMouseTracking(true);
+// m_view->setMouseTracking(true);
if (QSGItem *root = view->rootItem())
m_overlay->setParentItem(root);
@@ -186,14 +185,31 @@ void SGViewInspector::changeTool(InspectorProtocol::Tool tool)
}
}
-QDeclarativeEngine *SGViewInspector::declarativeEngine() const
+QWindow *getMasterWindow(QWindow *w)
{
- return m_view->engine();
+ QWindow *p = w->parent();
+ while (p) {
+ w = p;
+ p = p->parent();
+ }
+ return w;
+}
+
+Qt::WindowFlags SGViewInspector::windowFlags() const
+{
+ return getMasterWindow(m_view)->windowFlags();
}
-QWidget *SGViewInspector::viewWidget() const
+void SGViewInspector::setWindowFlags(Qt::WindowFlags flags)
{
- return m_view;
+ QWindow *w = getMasterWindow(m_view);
+ w->setWindowFlags(flags);
+ w->show();
+}
+
+QDeclarativeEngine *SGViewInspector::declarativeEngine() const
+{
+ return m_view->engine();
}
QSGItem *SGViewInspector::topVisibleItemAt(const QPointF &pos) const
@@ -281,10 +297,11 @@ bool SGViewInspector::eventFilter(QObject *obj, QEvent *event)
bool SGViewInspector::mouseMoveEvent(QMouseEvent *event)
{
- if (QSGItem *item = topVisibleItemAt(event->pos()))
- m_view->setToolTip(titleForItem(item));
- else
- m_view->setToolTip(QString());
+ // TODO
+// if (QSGItem *item = topVisibleItemAt(event->pos()))
+// m_view->setToolTip(titleForItem(item));
+// else
+// m_view->setToolTip(QString());
return AbstractViewInspector::mouseMoveEvent(event);
}
diff --git a/src/plugins/qmltooling/qmldbg_inspector/sgviewinspector.h b/src/plugins/qmltooling/qmldbg_inspector/sgviewinspector.h
index 14a5bb1872..38271aa2d7 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/sgviewinspector.h
+++ b/src/plugins/qmltooling/qmldbg_inspector/sgviewinspector.h
@@ -68,7 +68,8 @@ public:
void reloadView();
void reparentQmlObject(QObject *object, QObject *newParent);
void changeTool(InspectorProtocol::Tool tool);
- QWidget *viewWidget() const;
+ Qt::WindowFlags windowFlags() const;
+ void setWindowFlags(Qt::WindowFlags flags);
QDeclarativeEngine *declarativeEngine() const;
QSGView *view() const { return m_view; }
diff --git a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp
index 512ea6571d..f9bf9ddbaa 100644
--- a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp
+++ b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp
@@ -180,12 +180,18 @@ void QTcpServerConnection::newConnection()
d->socket->setParent(this);
d->protocol = new QPacketProtocol(d->socket, this);
QObject::connect(d->protocol, SIGNAL(readyRead()), this, SLOT(readyRead()));
+ QObject::connect(d->protocol, SIGNAL(invalidPacket()), this, SLOT(invalidPacket()));
if (d->block) {
d->protocol->waitForReadyRead(-1);
}
}
+void QTcpServerConnection::invalidPacket()
+{
+ qWarning("QDeclarativeDebugServer: Received a corrupted packet! Giving up ...");
+}
+
Q_EXPORT_PLUGIN2(tcpserver, QTcpServerConnection)
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h
index f6886714c8..315f55a8e3 100644
--- a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h
+++ b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h
@@ -75,6 +75,7 @@ public:
private Q_SLOTS:
void readyRead();
void newConnection();
+ void invalidPacket();
private:
QTcpServerConnectionPrivate *d_ptr;
diff --git a/src/plugins/qmltooling/qmltooling.pro b/src/plugins/qmltooling/qmltooling.pro
index d400f741cc..b5c8eaf487 100644
--- a/src/plugins/qmltooling/qmltooling.pro
+++ b/src/plugins/qmltooling/qmltooling.pro
@@ -2,7 +2,6 @@ TEMPLATE = subdirs
SUBDIRS = qmldbg_tcp
-# ### refactor:
-# SUBDIRS = qmldbg_inspector
+SUBDIRS += qmldbg_inspector
symbian:SUBDIRS += qmldbg_ost
diff --git a/src/qmldevtools/qmldevtools.pro b/src/qmldevtools/qmldevtools.pro
new file mode 100644
index 0000000000..3aac5e5a9c
--- /dev/null
+++ b/src/qmldevtools/qmldevtools.pro
@@ -0,0 +1,20 @@
+load(qt_module)
+TARGET = QtQmlDevTools
+QT = core
+TEMPLATE = lib
+DESTDIR = $$QMAKE_LIBDIR_QT
+
+CONFIG += module
+CONFIG += staticlib
+
+MODULE_PRI = ../../modules/qt_qmldevtools.pri
+
+DEFINES += QT_BUILD_QMLDEVTOOLS_LIB
+
+load(qt_module_config)
+
+HEADERS += qtqmldevtoolsversion.h
+
+unix|win32-g++*:QMAKE_PKGCONFIG_REQUIRES = QtCore
+
+include($$QT.declarative.sources/qml/parser/parser.pri)
diff --git a/src/qmltest/quicktest.cpp b/src/qmltest/quicktest.cpp
index 641d7e045a..150304028d 100644
--- a/src/qmltest/quicktest.cpp
+++ b/src/qmltest/quicktest.cpp
@@ -147,16 +147,21 @@ int quick_test_main(int argc, char **argv, const char *name, quick_test_viewport
if (testPath.isEmpty())
testPath = QLatin1String(".");
- // Scan the test data directory recursively, looking for "tst_*.qml" files.
- QStringList filters;
- filters += QLatin1String("tst_*.qml");
QStringList files;
- QDirIterator iter(testPath, filters, QDir::Files,
- QDirIterator::Subdirectories |
- QDirIterator::FollowSymlinks);
- while (iter.hasNext())
- files += iter.next();
- files.sort();
+
+ if (testPath.endsWith(QLatin1String(".qml")) && QFileInfo(testPath).isFile()) {
+ files << testPath;
+ } else {
+ // Scan the test data directory recursively, looking for "tst_*.qml" files.
+ QStringList filters;
+ filters += QLatin1String("tst_*.qml");
+ QDirIterator iter(testPath, filters, QDir::Files,
+ QDirIterator::Subdirectories |
+ QDirIterator::FollowSymlinks);
+ while (iter.hasNext())
+ files += iter.next();
+ files.sort();
+ }
// Bail out if we didn't find any test cases.
if (files.isEmpty()) {
@@ -170,21 +175,23 @@ int quick_test_main(int argc, char **argv, const char *name, quick_test_viewport
// in turn with a QDeclarativeView.
#ifdef QUICK_TEST_SCENEGRAPH
if (qtQuick2) {
+ QSGView view;
+ QTestRootObject rootobj;
+ QEventLoop eventLoop;
+ QObject::connect(view.engine(), SIGNAL(quit()),
+ &rootobj, SLOT(quit()));
+ QObject::connect(view.engine(), SIGNAL(quit()),
+ &eventLoop, SLOT(quit()));
+ view.rootContext()->setContextProperty
+ (QLatin1String("qtest"), &rootobj);
+ foreach (QString path, imports)
+ view.engine()->addImportPath(path);
+
foreach (QString file, files) {
QFileInfo fi(file);
if (!fi.exists())
continue;
- QSGView view;
- QTestRootObject rootobj;
- QEventLoop eventLoop;
- QObject::connect(view.engine(), SIGNAL(quit()),
- &rootobj, SLOT(quit()));
- QObject::connect(view.engine(), SIGNAL(quit()),
- &eventLoop, SLOT(quit()));
- view.rootContext()->setContextProperty
- (QLatin1String("qtest"), &rootobj);
- foreach (QString path, imports)
- view.engine()->addImportPath(path);
+
QString path = fi.absoluteFilePath();
if (path.startsWith(QLatin1String(":/")))
view.setSource(QUrl(QLatin1String("qrc:") + path.mid(2)));
@@ -215,8 +222,7 @@ int quick_test_main(int argc, char **argv, const char *name, quick_test_viewport
// an asynchronous test and we need to show the window
// and wait for the quit indication.
view.show();
- //QTest::qWaitForWindowShown(&view);
- QTest::qWait(50);
+ QTest::qWaitForWindowShown(&view);
rootobj.setWindowShown(true);
if (!rootobj.hasQuit)
eventLoop.exec();
diff --git a/src/qmltest/quicktestevent.cpp b/src/qmltest/quicktestevent.cpp
index f573899d98..4e62d4a827 100644
--- a/src/qmltest/quicktestevent.cpp
+++ b/src/qmltest/quicktestevent.cpp
@@ -162,7 +162,7 @@ namespace QtQuickTest
static const char *mouseActionNames[] =
{ "MousePress", "MouseRelease", "MouseClick", "MouseDoubleClick", "MouseMove" };
QString warning = QString::fromLatin1("Mouse event \"%1\" not accepted by receiving window");
- QTest::qWarn(warning.arg(QString::fromLatin1(mouseActionNames[static_cast<int>(action)])).toAscii().data());
+ QWARN(warning.arg(QString::fromLatin1(mouseActionNames[static_cast<int>(action)])).toAscii().data());
}
}
diff --git a/src/qmltest/quicktestresult.cpp b/src/qmltest/quicktestresult.cpp
index 40b7d9bea8..1924be0d26 100644
--- a/src/qmltest/quicktestresult.cpp
+++ b/src/qmltest/quicktestresult.cpp
@@ -404,14 +404,7 @@ bool QuickTestResult::compare
}
}
-void QuickTestResult::skipSingle
- (const QString &message, const QString &file, int line)
-{
- QTestResult::addSkip(message.toLatin1().constData(),
- qtest_fixFile(file).toLatin1().constData(), line);
-}
-
-void QuickTestResult::skipAll
+void QuickTestResult::skip
(const QString &message, const QString &file, int line)
{
QTestResult::addSkip(message.toLatin1().constData(),
@@ -439,7 +432,7 @@ bool QuickTestResult::expectFailContinue
void QuickTestResult::warn(const QString &message)
{
- QTestLog::warn(message.toLatin1().constData());
+ QTestLog::warn(message.toLatin1().constData(), 0, 0);
}
void QuickTestResult::ignoreWarning(const QString &message)
diff --git a/src/qmltest/quicktestresult_p.h b/src/qmltest/quicktestresult_p.h
index 3e0ea18d25..8707b563e4 100644
--- a/src/qmltest/quicktestresult_p.h
+++ b/src/qmltest/quicktestresult_p.h
@@ -129,8 +129,7 @@ public Q_SLOTS:
bool compare(bool success, const QString &message,
const QString &val1, const QString &val2,
const QString &file, int line);
- void skipSingle(const QString &message, const QString &file, int line);
- void skipAll(const QString &message, const QString &file, int line);
+ void skip(const QString &message, const QString &file, int line);
bool expectFail(const QString &tag, const QString &comment,
const QString &file, int line);
bool expectFailContinue(const QString &tag, const QString &comment,
diff --git a/src/qtquick1/graphicsitems/qdeclarativeflickable.cpp b/src/qtquick1/graphicsitems/qdeclarativeflickable.cpp
index 6fa92b3bfa..6a7f6ae246 100644
--- a/src/qtquick1/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/qtquick1/graphicsitems/qdeclarativeflickable.cpp
@@ -170,9 +170,7 @@ QDeclarative1FlickablePrivate::QDeclarative1FlickablePrivate()
: contentItem(new QDeclarativeItem)
, hData(this, &QDeclarative1FlickablePrivate::setRoundedViewportX)
, vData(this, &QDeclarative1FlickablePrivate::setRoundedViewportY)
- , flickingHorizontally(false), flickingVertically(false)
, hMoved(false), vMoved(false)
- , movingHorizontally(false), movingVertically(false)
, stealMouse(false), pressed(false), interactive(true), calcVelocity(false)
, deceleration(QML_FLICK_DEFAULTDECELERATION)
, maxVelocity(QML_FLICK_DEFAULTMAXVELOCITY), reportedVelocitySmoothing(100)
@@ -296,18 +294,18 @@ void QDeclarative1FlickablePrivate::flick(AxisData &data, qreal minExtent, qreal
else
timeline.accel(data.move, v, deceleration, maxDistance);
timeline.callback(QDeclarative1TimeLineCallback(&data.move, fixupCallback, this));
- if (!flickingHorizontally && q->xflick()) {
- flickingHorizontally = true;
+ if (!hData.flicking && q->xflick()) {
+ hData.flicking = true;
emit q->flickingChanged();
emit q->flickingHorizontallyChanged();
- if (!flickingVertically)
+ if (!vData.flicking)
emit q->flickStarted();
}
- if (!flickingVertically && q->yflick()) {
- flickingVertically = true;
+ if (!vData.flicking && q->yflick()) {
+ vData.flicking = true;
emit q->flickingChanged();
emit q->flickingVerticallyChanged();
- if (!flickingHorizontally)
+ if (!hData.flicking)
emit q->flickStarted();
}
} else {
@@ -617,11 +615,11 @@ void QDeclarative1Flickable::setInteractive(bool interactive)
Q_D(QDeclarative1Flickable);
if (interactive != d->interactive) {
d->interactive = interactive;
- if (!interactive && (d->flickingHorizontally || d->flickingVertically)) {
+ if (!interactive && (d->hData.flicking || d->vData.flicking)) {
d->timeline.clear();
d->vTime = d->timeline.time();
- d->flickingHorizontally = false;
- d->flickingVertically = false;
+ d->hData.flicking = false;
+ d->vData.flicking = false;
emit flickingChanged();
emit flickingHorizontallyChanged();
emit flickingVerticallyChanged();
@@ -774,8 +772,8 @@ void QDeclarative1FlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEve
pressPos = event->pos();
hData.pressPos = hData.move.value();
vData.pressPos = vData.move.value();
- flickingHorizontally = false;
- flickingVertically = false;
+ hData.flicking = false;
+ vData.flicking = false;
QDeclarativeItemPrivate::start(pressTime);
QDeclarativeItemPrivate::start(velocityTime);
}
@@ -900,17 +898,14 @@ void QDeclarative1FlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseE
return;
// if we drag then pause before release we should not cause a flick.
- if (QDeclarativeItemPrivate::elapsed(lastPosTime) < 100) {
- vData.updateVelocity();
- hData.updateVelocity();
- } else {
- hData.velocity = 0.0;
- vData.velocity = 0.0;
- }
+ qint64 elapsed = QDeclarativeItemPrivate::elapsed(lastPosTime);
+
+ vData.updateVelocity();
+ hData.updateVelocity();
vTime = timeline.time();
- qreal velocity = vData.velocity;
+ qreal velocity = elapsed < 100 ? vData.velocity : 0;
if (vData.atBeginning || vData.atEnd)
velocity /= 2;
if (q->yflick() && qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) {
@@ -921,7 +916,7 @@ void QDeclarative1FlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseE
fixupY();
}
- velocity = hData.velocity;
+ velocity = elapsed < 100 ? hData.velocity : 0;
if (hData.atBeginning || hData.atEnd)
velocity /= 2;
if (q->xflick() && qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) {
@@ -987,9 +982,9 @@ void QDeclarative1Flickable::wheelEvent(QGraphicsSceneWheelEvent *event)
valid = true;
}
if (valid) {
- d->flickingVertically = false;
+ d->vData.flicking = false;
d->flickY(d->vData.velocity);
- if (d->flickingVertically) {
+ if (d->vData.flicking) {
d->vMoved = true;
movementStarting();
}
@@ -1005,9 +1000,9 @@ void QDeclarative1Flickable::wheelEvent(QGraphicsSceneWheelEvent *event)
valid = true;
}
if (valid) {
- d->flickingHorizontally = false;
+ d->hData.flicking = false;
d->flickX(d->hData.velocity);
- if (d->flickingHorizontally) {
+ if (d->hData.flicking) {
d->hMoved = true;
movementStarting();
}
@@ -1156,7 +1151,7 @@ void QDeclarative1Flickable::viewportMoved()
}
}
- if (!d->vData.inOvershoot && !d->vData.fixingUp && d->flickingVertically
+ if (!d->vData.inOvershoot && !d->vData.fixingUp && d->vData.flicking
&& (d->vData.move.value() > minYExtent() || d->vData.move.value() < maxYExtent())
&& qAbs(d->vData.smoothVelocity.value()) > 100) {
// Increase deceleration if we've passed a bound
@@ -1166,7 +1161,7 @@ void QDeclarative1Flickable::viewportMoved()
d->timeline.accel(d->vData.move, -d->vData.smoothVelocity.value(), d->deceleration*QML_FLICK_OVERSHOOTFRICTION, maxDistance);
d->timeline.callback(QDeclarative1TimeLineCallback(&d->vData.move, d->fixupY_callback, d));
}
- if (!d->hData.inOvershoot && !d->hData.fixingUp && d->flickingHorizontally
+ if (!d->hData.inOvershoot && !d->hData.fixingUp && d->hData.flicking
&& (d->hData.move.value() > minXExtent() || d->hData.move.value() < maxXExtent())
&& qAbs(d->hData.smoothVelocity.value()) > 100) {
// Increase deceleration if we've passed a bound
@@ -1198,7 +1193,7 @@ void QDeclarative1Flickable::geometryChanged(const QRectF &newGeometry,
emit contentWidthChanged();
}
// Make sure that we're entirely in view.
- if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
+ if (!d->pressed && !d->hData.moving && !d->vData.moving) {
d->fixupMode = QDeclarative1FlickablePrivate::Immediate;
d->fixupX();
}
@@ -1211,7 +1206,7 @@ void QDeclarative1Flickable::geometryChanged(const QRectF &newGeometry,
emit contentHeightChanged();
}
// Make sure that we're entirely in view.
- if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
+ if (!d->pressed && !d->hData.moving && !d->vData.moving) {
d->fixupMode = QDeclarative1FlickablePrivate::Immediate;
d->fixupY();
}
@@ -1366,7 +1361,7 @@ void QDeclarative1Flickable::setContentWidth(qreal w)
else
d->contentItem->setWidth(w);
// Make sure that we're entirely in view.
- if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
+ if (!d->pressed && !d->hData.moving && !d->vData.moving) {
d->fixupMode = QDeclarative1FlickablePrivate::Immediate;
d->fixupX();
} else if (!d->pressed && d->hData.fixingUp) {
@@ -1394,7 +1389,7 @@ void QDeclarative1Flickable::setContentHeight(qreal h)
else
d->contentItem->setHeight(h);
// Make sure that we're entirely in view.
- if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
+ if (!d->pressed && !d->hData.moving && !d->vData.moving) {
d->fixupMode = QDeclarative1FlickablePrivate::Immediate;
d->fixupY();
} else if (!d->pressed && d->vData.fixingUp) {
@@ -1651,7 +1646,7 @@ void QDeclarative1Flickable::setFlickDeceleration(qreal deceleration)
bool QDeclarative1Flickable::isFlicking() const
{
Q_D(const QDeclarative1Flickable);
- return d->flickingHorizontally || d->flickingVertically;
+ return d->hData.flicking || d->vData.flicking;
}
/*!
@@ -1665,13 +1660,13 @@ bool QDeclarative1Flickable::isFlicking() const
bool QDeclarative1Flickable::isFlickingHorizontally() const
{
Q_D(const QDeclarative1Flickable);
- return d->flickingHorizontally;
+ return d->hData.flicking;
}
bool QDeclarative1Flickable::isFlickingVertically() const
{
Q_D(const QDeclarative1Flickable);
- return d->flickingVertically;
+ return d->vData.flicking;
}
/*!
@@ -1707,7 +1702,7 @@ void QDeclarative1Flickable::setPressDelay(int delay)
bool QDeclarative1Flickable::isMoving() const
{
Q_D(const QDeclarative1Flickable);
- return d->movingHorizontally || d->movingVertically;
+ return d->hData.moving || d->vData.moving;
}
/*!
@@ -1722,30 +1717,30 @@ bool QDeclarative1Flickable::isMoving() const
bool QDeclarative1Flickable::isMovingHorizontally() const
{
Q_D(const QDeclarative1Flickable);
- return d->movingHorizontally;
+ return d->hData.moving;
}
bool QDeclarative1Flickable::isMovingVertically() const
{
Q_D(const QDeclarative1Flickable);
- return d->movingVertically;
+ return d->vData.moving;
}
void QDeclarative1Flickable::movementStarting()
{
Q_D(QDeclarative1Flickable);
- if (d->hMoved && !d->movingHorizontally) {
- d->movingHorizontally = true;
+ if (d->hMoved && !d->hData.moving) {
+ d->hData.moving = true;
emit movingChanged();
emit movingHorizontallyChanged();
- if (!d->movingVertically)
+ if (!d->vData.moving)
emit movementStarted();
}
- else if (d->vMoved && !d->movingVertically) {
- d->movingVertically = true;
+ else if (d->vMoved && !d->vData.moving) {
+ d->vData.moving = true;
emit movingChanged();
emit movingVerticallyChanged();
- if (!d->movingHorizontally)
+ if (!d->hData.moving)
emit movementStarted();
}
}
@@ -1762,20 +1757,20 @@ void QDeclarative1Flickable::movementEnding()
void QDeclarative1Flickable::movementXEnding()
{
Q_D(QDeclarative1Flickable);
- if (d->flickingHorizontally) {
- d->flickingHorizontally = false;
+ if (d->hData.flicking) {
+ d->hData.flicking = false;
emit flickingChanged();
emit flickingHorizontallyChanged();
- if (!d->flickingVertically)
+ if (!d->vData.flicking)
emit flickEnded();
}
if (!d->pressed && !d->stealMouse) {
- if (d->movingHorizontally) {
- d->movingHorizontally = false;
+ if (d->hData.moving) {
+ d->hData.moving = false;
d->hMoved = false;
emit movingChanged();
emit movingHorizontallyChanged();
- if (!d->movingVertically)
+ if (!d->vData.moving)
emit movementEnded();
}
}
@@ -1785,20 +1780,20 @@ void QDeclarative1Flickable::movementXEnding()
void QDeclarative1Flickable::movementYEnding()
{
Q_D(QDeclarative1Flickable);
- if (d->flickingVertically) {
- d->flickingVertically = false;
+ if (d->vData.flicking) {
+ d->vData.flicking = false;
emit flickingChanged();
emit flickingVerticallyChanged();
- if (!d->flickingHorizontally)
+ if (!d->hData.flicking)
emit flickEnded();
}
if (!d->pressed && !d->stealMouse) {
- if (d->movingVertically) {
- d->movingVertically = false;
+ if (d->vData.moving) {
+ d->vData.moving = false;
d->vMoved = false;
emit movingChanged();
emit movingVerticallyChanged();
- if (!d->movingHorizontally)
+ if (!d->hData.moving)
emit movementEnded();
}
}
diff --git a/src/qtquick1/graphicsitems/qdeclarativeflickable_p_p.h b/src/qtquick1/graphicsitems/qdeclarativeflickable_p_p.h
index 5bbeb27c9e..c76da83da0 100644
--- a/src/qtquick1/graphicsitems/qdeclarativeflickable_p_p.h
+++ b/src/qtquick1/graphicsitems/qdeclarativeflickable_p_p.h
@@ -94,7 +94,7 @@ public:
struct AxisData {
AxisData(QDeclarative1FlickablePrivate *fp, void (QDeclarative1FlickablePrivate::*func)(qreal))
: move(fp, func), viewSize(-1), smoothVelocity(fp), atEnd(false), atBeginning(true)
- , fixingUp(false), inOvershoot(false)
+ , fixingUp(false), inOvershoot(false), moving(false), flicking(false)
{}
void reset() {
@@ -121,6 +121,8 @@ public:
bool atBeginning : 1;
bool fixingUp : 1;
bool inOvershoot : 1;
+ bool moving : 1;
+ bool flicking : 1;
};
void flickX(qreal velocity);
@@ -152,12 +154,8 @@ public:
AxisData vData;
QDeclarative1TimeLine timeline;
- bool flickingHorizontally : 1;
- bool flickingVertically : 1;
bool hMoved : 1;
bool vMoved : 1;
- bool movingHorizontally : 1;
- bool movingVertically : 1;
bool stealMouse : 1;
bool pressed : 1;
bool interactive : 1;
diff --git a/src/qtquick1/graphicsitems/qdeclarativegridview.cpp b/src/qtquick1/graphicsitems/qdeclarativegridview.cpp
index f2511a15c9..2ed1ca1782 100644
--- a/src/qtquick1/graphicsitems/qdeclarativegridview.cpp
+++ b/src/qtquick1/graphicsitems/qdeclarativegridview.cpp
@@ -51,11 +51,13 @@
#include <qmath.h>
#include <math.h>
+#include "qplatformdefs.h"
QT_BEGIN_NAMESPACE
-
-
+#ifndef QML_FLICK_SNAPONETHRESHOLD
+#define QML_FLICK_SNAPONETHRESHOLD 30
+#endif
//----------------------------------------------------------------------------
@@ -346,9 +348,12 @@ public:
Q_Q(const QDeclarative1GridView);
qreal snapPos = 0;
if (!visibleItems.isEmpty()) {
+ qreal highlightStart = isRightToLeftTopToBottom() && highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart;
+ pos += highlightStart;
pos += rowSize()/2;
snapPos = visibleItems.first()->rowPos() - visibleIndex / columns * rowSize();
snapPos = pos - fmodf(pos - snapPos, qreal(rowSize()));
+ snapPos -= highlightStart;
qreal maxExtent;
qreal minExtent;
if (isRightToLeftTopToBottom()) {
@@ -876,7 +881,7 @@ void QDeclarative1GridViewPrivate::updateHighlight()
{
if ((!currentItem && highlight) || (currentItem && !highlight))
createHighlight();
- if (currentItem && autoHighlight && highlight && !movingHorizontally && !movingVertically) {
+ if (currentItem && autoHighlight && highlight && !hData.moving && !vData.moving) {
// auto-update highlight
highlightXAnimator->to = currentItem->item->x();
highlightYAnimator->to = currentItem->item->y();
@@ -1061,48 +1066,54 @@ void QDeclarative1GridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal
highlightEnd = highlightRangeEnd;
}
+ bool strictHighlightRange = haveHighlightRange && highlightRange == QDeclarative1GridView::StrictlyEnforceRange;
+
if (snapMode != QDeclarative1GridView::NoSnap) {
qreal tempPosition = isRightToLeftTopToBottom() ? -position()-size() : position();
+ if (snapMode == QDeclarative1GridView::SnapOneRow && moveReason == Mouse) {
+ // if we've been dragged < rowSize()/2 then bias towards the next row
+ qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
+ qreal bias = 0;
+ if (data.velocity > 0 && dist > QML_FLICK_SNAPONETHRESHOLD && dist < rowSize()/2)
+ bias = rowSize()/2;
+ else if (data.velocity < 0 && dist < -QML_FLICK_SNAPONETHRESHOLD && dist > -rowSize()/2)
+ bias = -rowSize()/2;
+ if (isRightToLeftTopToBottom())
+ bias = -bias;
+ tempPosition -= bias;
+ }
FxGridItem1 *topItem = snapItemAt(tempPosition+highlightStart);
+ if (!topItem && strictHighlightRange && currentItem) {
+ // StrictlyEnforceRange always keeps an item in range
+ updateHighlight();
+ topItem = currentItem;
+ }
FxGridItem1 *bottomItem = snapItemAt(tempPosition+highlightEnd);
+ if (!bottomItem && strictHighlightRange && currentItem) {
+ // StrictlyEnforceRange always keeps an item in range
+ updateHighlight();
+ bottomItem = currentItem;
+ }
qreal pos;
- if (topItem && bottomItem && haveHighlightRange && highlightRange == QDeclarative1GridView::StrictlyEnforceRange) {
- qreal topPos = qMin(topItem->rowPos() - highlightStart, -maxExtent);
- qreal bottomPos = qMax(bottomItem->rowPos() - highlightEnd, -minExtent);
- pos = qAbs(data.move + topPos) < qAbs(data.move + bottomPos) ? topPos : bottomPos;
- } else if (topItem) {
- qreal headerPos = 0;
- if (header)
- headerPos = isRightToLeftTopToBottom() ? header->rowPos() + cellWidth - headerSize() : header->rowPos();
- if (topItem->index == 0 && header && tempPosition+highlightStart < headerPos+headerSize()/2) {
- pos = isRightToLeftTopToBottom() ? - headerPos + highlightStart - size() : headerPos - highlightStart;
+ bool isInBounds = -position() > maxExtent && -position() <= minExtent;
+ if (topItem && (isInBounds || strictHighlightRange)) {
+ if (topItem->index == 0 && header && tempPosition+highlightStart < header->rowPos()+headerSize()/2 && !strictHighlightRange) {
+ pos = isRightToLeftTopToBottom() ? - header->rowPos() + highlightStart - size() : header->rowPos() - highlightStart;
} else {
if (isRightToLeftTopToBottom())
pos = qMax(qMin(-topItem->rowPos() + highlightStart - size(), -maxExtent), -minExtent);
else
pos = qMax(qMin(topItem->rowPos() - highlightStart, -maxExtent), -minExtent);
}
- } else if (bottomItem) {
+ } else if (bottomItem && isInBounds) {
if (isRightToLeftTopToBottom())
- pos = qMax(qMin(-bottomItem->rowPos() + highlightStart - size(), -maxExtent), -minExtent);
+ pos = qMax(qMin(-bottomItem->rowPos() + highlightEnd - size(), -maxExtent), -minExtent);
else
- pos = qMax(qMin(bottomItem->rowPos() - highlightStart, -maxExtent), -minExtent);
+ pos = qMax(qMin(bottomItem->rowPos() - highlightEnd, -maxExtent), -minExtent);
} else {
QDeclarative1FlickablePrivate::fixup(data, minExtent, maxExtent);
return;
}
- if (currentItem && haveHighlightRange && highlightRange == QDeclarative1GridView::StrictlyEnforceRange) {
- updateHighlight();
- qreal currPos = currentItem->rowPos();
- if (isRightToLeftTopToBottom())
- pos = -pos-size(); // Transform Pos if required
- if (pos < currPos + rowSize() - highlightEnd)
- pos = currPos + rowSize() - highlightEnd;
- if (pos > currPos - highlightStart)
- pos = currPos - highlightStart;
- if (isRightToLeftTopToBottom())
- pos = -pos-size(); // Untransform
- }
qreal dist = qAbs(data.move + pos);
if (dist > 0) {
timeline.reset(data.move);
@@ -1159,9 +1170,14 @@ void QDeclarative1GridViewPrivate::flick(AxisData &data, qreal minExtent, qreal
if (velocity > 0) {
if (data.move.value() < minExtent) {
if (snapMode == QDeclarative1GridView::SnapOneRow) {
- if (FxGridItem1 *item = firstVisibleItem()) {
- maxDistance = qAbs(item->rowPos() + dataValue);
- }
+ // if we've been dragged < averageSize/2 then bias towards the next item
+ qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
+ qreal bias = dist < rowSize()/2 ? rowSize()/2 : 0;
+ if (isRightToLeftTopToBottom())
+ bias = -bias;
+ data.flickTarget = -snapPosAt(-dataValue - bias);
+ maxDistance = qAbs(data.flickTarget - data.move.value());
+ velocity = maxVelocity;
} else {
maxDistance = qAbs(minExtent - data.move.value());
}
@@ -1171,8 +1187,14 @@ void QDeclarative1GridViewPrivate::flick(AxisData &data, qreal minExtent, qreal
} else {
if (data.move.value() > maxExtent) {
if (snapMode == QDeclarative1GridView::SnapOneRow) {
- qreal pos = snapPosAt(-dataValue) + (isRightToLeftTopToBottom() ? 0 : rowSize());
- maxDistance = qAbs(pos + dataValue);
+ // if we've been dragged < averageSize/2 then bias towards the next item
+ qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
+ qreal bias = -dist < rowSize()/2 ? rowSize()/2 : 0;
+ if (isRightToLeftTopToBottom())
+ bias = -bias;
+ data.flickTarget = -snapPosAt(-dataValue + bias);
+ maxDistance = qAbs(data.flickTarget - data.move.value());
+ velocity = -maxVelocity;
} else {
maxDistance = qAbs(maxExtent - data.move.value());
}
@@ -1182,7 +1204,6 @@ void QDeclarative1GridViewPrivate::flick(AxisData &data, qreal minExtent, qreal
}
bool overShoot = boundsBehavior == QDeclarative1Flickable::DragAndOvershootBounds;
- qreal highlightStart = isRightToLeftTopToBottom() && highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart;
if (maxDistance > 0 || overShoot) {
// This mode requires the grid to stop exactly on a row boundary.
@@ -1202,9 +1223,20 @@ void QDeclarative1GridViewPrivate::flick(AxisData &data, qreal minExtent, qreal
dist = qMin(dist, maxDistance);
if (v > 0)
dist = -dist;
- qreal distTemp = isRightToLeftTopToBottom() ? -dist : dist;
- data.flickTarget = -snapPosAt(-(dataValue - highlightStart) + distTemp) + highlightStart;
+ if (snapMode != QDeclarative1GridView::SnapOneRow) {
+ qreal distTemp = isRightToLeftTopToBottom() ? -dist : dist;
+ data.flickTarget = -snapPosAt(-dataValue + distTemp);
+ }
data.flickTarget = isRightToLeftTopToBottom() ? -data.flickTarget+size() : data.flickTarget;
+ if (overShoot) {
+ if (data.flickTarget >= minExtent) {
+ overshootDist = overShootDistance(vSize);
+ data.flickTarget += overshootDist;
+ } else if (data.flickTarget <= maxExtent) {
+ overshootDist = overShootDistance(vSize);
+ data.flickTarget -= overshootDist;
+ }
+ }
qreal adjDist = -data.flickTarget + data.move.value();
if (qAbs(adjDist) > qAbs(dist)) {
// Prevent painfully slow flicking - adjust velocity to suit flickDeceleration
@@ -1225,14 +1257,14 @@ void QDeclarative1GridViewPrivate::flick(AxisData &data, qreal minExtent, qreal
timeline.reset(data.move);
timeline.accel(data.move, v, accel, maxDistance + overshootDist);
timeline.callback(QDeclarative1TimeLineCallback(&data.move, fixupCallback, this));
- if (!flickingHorizontally && q->xflick()) {
- flickingHorizontally = true;
+ if (!hData.flicking && q->xflick()) {
+ hData.flicking = true;
emit q->flickingChanged();
emit q->flickingHorizontallyChanged();
emit q->flickStarted();
}
- if (!flickingVertically && q->yflick()) {
- flickingVertically = true;
+ if (!vData.flicking && q->yflick()) {
+ vData.flicking = true;
emit q->flickingChanged();
emit q->flickingVerticallyChanged();
emit q->flickStarted();
@@ -1557,6 +1589,8 @@ void QDeclarative1GridView::setCurrentIndex(int index)
if (index == d->currentIndex)
return;
if (isComponentComplete() && d->isValid()) {
+ if (d->layoutScheduled)
+ d->layout();
d->moveReason = QDeclarative1GridViewPrivate::SetIndex;
d->updateCurrent(index);
} else {
@@ -2110,7 +2144,8 @@ bool QDeclarative1GridView::event(QEvent *event)
{
Q_D(QDeclarative1GridView);
if (event->type() == QEvent::User) {
- d->layout();
+ if (d->layoutScheduled)
+ d->layout();
return true;
}
@@ -2124,7 +2159,7 @@ void QDeclarative1GridView::viewportMoved()
if (!d->itemCount)
return;
d->lazyRelease = true;
- if (d->flickingHorizontally || d->flickingVertically) {
+ if (d->hData.flicking || d->vData.flicking) {
if (yflick()) {
if (d->vData.velocity > 0)
d->bufferMode = QDeclarative1GridViewPrivate::BufferBefore;
@@ -2140,7 +2175,7 @@ void QDeclarative1GridView::viewportMoved()
}
}
refill();
- if (d->flickingHorizontally || d->flickingVertically || d->movingHorizontally || d->movingVertically)
+ if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving)
d->moveReason = QDeclarative1GridViewPrivate::Mouse;
if (d->moveReason != QDeclarative1GridViewPrivate::SetIndex) {
if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) {
@@ -2226,9 +2261,10 @@ qreal QDeclarative1GridView::minXExtent() const
qreal extent = -d->startPosition();
qreal highlightStart;
qreal highlightEnd;
- qreal endPositionFirstItem;
+ qreal endPositionFirstItem = 0;
if (d->isRightToLeftTopToBottom()) {
- endPositionFirstItem = d->rowPosAt(d->model->count()-1);
+ if (d->model && d->model->count())
+ endPositionFirstItem = d->rowPosAt(d->model->count()-1);
highlightStart = d->highlightRangeStartValid
? d->highlightRangeStart - (d->lastPosition()-endPositionFirstItem)
: d->size() - (d->lastPosition()-endPositionFirstItem);
@@ -2243,7 +2279,7 @@ qreal QDeclarative1GridView::minXExtent() const
extent += d->header->item->width();
}
if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
- extent += highlightStart;
+ extent += d->isRightToLeftTopToBottom() ? -highlightStart : highlightStart;
extent = qMax(extent, -(endPositionFirstItem - highlightEnd));
}
return extent;
@@ -2928,6 +2964,11 @@ void QDeclarative1GridView::itemsRemoved(int modelIndex, int count)
}
}
+ // If we removed items before visible items a layout may be
+ // required to ensure item 0 is in the first column.
+ if (!removedVisible && modelIndex < d->visibleIndex)
+ d->scheduleLayout();
+
// fix current
if (d->currentIndex >= modelIndex + count) {
d->currentIndex -= count;
diff --git a/src/qtquick1/graphicsitems/qdeclarativelistview.cpp b/src/qtquick1/graphicsitems/qdeclarativelistview.cpp
index 5119c0e1fb..6430f6a071 100644
--- a/src/qtquick1/graphicsitems/qdeclarativelistview.cpp
+++ b/src/qtquick1/graphicsitems/qdeclarativelistview.cpp
@@ -52,10 +52,13 @@
#include <qmath.h>
#include <QKeyEvent>
+#include "qplatformdefs.h"
QT_BEGIN_NAMESPACE
-
+#ifndef QML_FLICK_SNAPONETHRESHOLD
+#define QML_FLICK_SNAPONETHRESHOLD 30
+#endif
void QDeclarative1ViewSection::setProperty(const QString &property)
{
@@ -235,21 +238,6 @@ public:
return visibleItems.count() ? visibleItems.first() : 0;
}
- FxListItem1 *nextVisibleItem() const {
- const qreal pos = isRightToLeft() ? -position()-size() : position();
- bool foundFirst = false;
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxListItem1 *item = visibleItems.at(i);
- if (item->index != -1) {
- if (foundFirst)
- return item;
- else if (item->position() < pos && item->endPosition() > pos)
- foundFirst = true;
- }
- }
- return 0;
- }
-
// Returns the item before modelIndex, if created.
// May return an item marked for removal.
FxListItem1 *itemBefore(int modelIndex) const {
@@ -1013,7 +1001,7 @@ void QDeclarative1ListViewPrivate::updateHighlight()
{
if ((!currentItem && highlight) || (currentItem && !highlight))
createHighlight();
- if (currentItem && autoHighlight && highlight && !movingHorizontally && !movingVertically) {
+ if (currentItem && autoHighlight && highlight && !hData.moving && !vData.moving) {
// auto-update highlight
highlightPosAnimator->to = isRightToLeft()
? -currentItem->itemPosition()-currentItem->itemSize()
@@ -1308,6 +1296,7 @@ void QDeclarative1ListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal
correctFlick = false;
fixupMode = moveReason == Mouse ? fixupMode : Immediate;
+ bool strictHighlightRange = haveHighlightRange && highlightRange == QDeclarative1ListView::StrictlyEnforceRange;
qreal highlightStart;
qreal highlightEnd;
@@ -1323,35 +1312,36 @@ void QDeclarative1ListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal
highlightEnd = highlightRangeEnd;
}
- if (currentItem && haveHighlightRange && highlightRange == QDeclarative1ListView::StrictlyEnforceRange
- && moveReason != QDeclarative1ListViewPrivate::SetIndex) {
- updateHighlight();
- qreal pos = currentItem->itemPosition();
- if (viewPos < pos + currentItem->itemSize() - highlightEnd)
- viewPos = pos + currentItem->itemSize() - highlightEnd;
- if (viewPos > pos - highlightStart)
- viewPos = pos - highlightStart;
- if (isRightToLeft())
- viewPos = -viewPos-size();
-
- timeline.reset(data.move);
- if (viewPos != position()) {
- if (fixupMode != Immediate) {
- timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- data.fixingUp = true;
- } else {
- timeline.set(data.move, -viewPos);
- }
- }
- vTime = timeline.time();
- } else if (snapMode != QDeclarative1ListView::NoSnap && moveReason != QDeclarative1ListViewPrivate::SetIndex) {
+ if (snapMode != QDeclarative1ListView::NoSnap && moveReason != QDeclarative1ListViewPrivate::SetIndex) {
qreal tempPosition = isRightToLeft() ? -position()-size() : position();
+ if (snapMode == QDeclarative1ListView::SnapOneItem && moveReason == Mouse) {
+ // if we've been dragged < averageSize/2 then bias towards the next item
+ qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
+ qreal bias = 0;
+ if (data.velocity > 0 && dist > QML_FLICK_SNAPONETHRESHOLD && dist < averageSize/2)
+ bias = averageSize/2;
+ else if (data.velocity < 0 && dist < -QML_FLICK_SNAPONETHRESHOLD && dist > -averageSize/2)
+ bias = -averageSize/2;
+ if (isRightToLeft())
+ bias = -bias;
+ tempPosition -= bias;
+ }
FxListItem1 *topItem = snapItemAt(tempPosition+highlightStart);
+ if (!topItem && strictHighlightRange && currentItem) {
+ // StrictlyEnforceRange always keeps an item in range
+ updateHighlight();
+ topItem = currentItem;
+ }
FxListItem1 *bottomItem = snapItemAt(tempPosition+highlightEnd);
+ if (!bottomItem && strictHighlightRange && currentItem) {
+ // StrictlyEnforceRange always keeps an item in range
+ updateHighlight();
+ bottomItem = currentItem;
+ }
qreal pos;
- bool isInBounds = -position() > maxExtent && -position() < minExtent;
- if (topItem && isInBounds) {
- if (topItem->index == 0 && header && tempPosition+highlightStart < header->position()+header->size()/2) {
+ bool isInBounds = -position() > maxExtent && -position() <= minExtent;
+ if (topItem && (isInBounds || strictHighlightRange)) {
+ if (topItem->index == 0 && header && tempPosition+highlightStart < header->position()+header->size()/2 && !strictHighlightRange) {
pos = isRightToLeft() ? - header->position() + highlightStart - size() : header->position() - highlightStart;
} else {
if (isRightToLeft())
@@ -1361,9 +1351,9 @@ void QDeclarative1ListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal
}
} else if (bottomItem && isInBounds) {
if (isRightToLeft())
- pos = qMax(qMin(-bottomItem->position() + highlightStart - size(), -maxExtent), -minExtent);
+ pos = qMax(qMin(-bottomItem->position() + highlightEnd - size(), -maxExtent), -minExtent);
else
- pos = qMax(qMin(bottomItem->position() - highlightStart, -maxExtent), -minExtent);
+ pos = qMax(qMin(bottomItem->position() - highlightEnd, -maxExtent), -minExtent);
} else {
QDeclarative1FlickablePrivate::fixup(data, minExtent, maxExtent);
return;
@@ -1380,6 +1370,27 @@ void QDeclarative1ListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal
}
vTime = timeline.time();
}
+ } else if (currentItem && strictHighlightRange
+ && moveReason != QDeclarative1ListViewPrivate::SetIndex) {
+ updateHighlight();
+ qreal pos = currentItem->itemPosition();
+ if (viewPos < pos + currentItem->itemSize() - highlightEnd)
+ viewPos = pos + currentItem->itemSize() - highlightEnd;
+ if (viewPos > pos - highlightStart)
+ viewPos = pos - highlightStart;
+ if (isRightToLeft())
+ viewPos = -viewPos-size();
+
+ timeline.reset(data.move);
+ if (viewPos != position()) {
+ if (fixupMode != Immediate) {
+ timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
+ data.fixingUp = true;
+ } else {
+ timeline.set(data.move, -viewPos);
+ }
+ }
+ vTime = timeline.time();
} else {
QDeclarative1FlickablePrivate::fixup(data, minExtent, maxExtent);
}
@@ -1401,12 +1412,19 @@ void QDeclarative1ListViewPrivate::flick(AxisData &data, qreal minExtent, qreal
}
qreal maxDistance = 0;
qreal dataValue = isRightToLeft() ? -data.move.value()+size() : data.move.value();
+ qreal highlightStart = isRightToLeft() && highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart;
// -ve velocity means list is moving up/left
if (velocity > 0) {
if (data.move.value() < minExtent) {
- if (snapMode == QDeclarative1ListView::SnapOneItem) {
- if (FxListItem1 *item = isRightToLeft() ? nextVisibleItem() : firstVisibleItem())
- maxDistance = qAbs(item->position() + dataValue);
+ if (snapMode == QDeclarative1ListView::SnapOneItem && !hData.flicking && !vData.flicking) {
+ // if we've been dragged < averageSize/2 then bias towards the next item
+ qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
+ qreal bias = dist < averageSize/2 ? averageSize/2 : 0;
+ if (isRightToLeft())
+ bias = -bias;
+ data.flickTarget = -snapPosAt(-(dataValue - highlightStart) - bias) + highlightStart;
+ maxDistance = qAbs(data.flickTarget - data.move.value());
+ velocity = maxVelocity;
} else {
maxDistance = qAbs(minExtent - data.move.value());
}
@@ -1415,9 +1433,15 @@ void QDeclarative1ListViewPrivate::flick(AxisData &data, qreal minExtent, qreal
data.flickTarget = minExtent;
} else {
if (data.move.value() > maxExtent) {
- if (snapMode == QDeclarative1ListView::SnapOneItem) {
- if (FxListItem1 *item = isRightToLeft() ? firstVisibleItem() : nextVisibleItem())
- maxDistance = qAbs(item->position() + dataValue);
+ if (snapMode == QDeclarative1ListView::SnapOneItem && !hData.flicking && !vData.flicking) {
+ // if we've been dragged < averageSize/2 then bias towards the next item
+ qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
+ qreal bias = -dist < averageSize/2 ? averageSize/2 : 0;
+ if (isRightToLeft())
+ bias = -bias;
+ data.flickTarget = -snapPosAt(-(dataValue - highlightStart) + bias) + highlightStart;
+ maxDistance = qAbs(data.flickTarget - data.move.value());
+ velocity = -maxVelocity;
} else {
maxDistance = qAbs(maxExtent - data.move.value());
}
@@ -1427,7 +1451,6 @@ void QDeclarative1ListViewPrivate::flick(AxisData &data, qreal minExtent, qreal
}
bool overShoot = boundsBehavior == QDeclarative1Flickable::DragAndOvershootBounds;
- qreal highlightStart = isRightToLeft() && highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart;
if (maxDistance > 0 || overShoot) {
// These modes require the list to stop exactly on an item boundary.
@@ -1441,7 +1464,7 @@ void QDeclarative1ListViewPrivate::flick(AxisData &data, qreal minExtent, qreal
else
v = maxVelocity;
}
- if (!flickingHorizontally && !flickingVertically) {
+ if (!hData.flicking && !vData.flicking) {
// the initial flick - estimate boundary
qreal accel = deceleration;
qreal v2 = v * v;
@@ -1453,8 +1476,10 @@ void QDeclarative1ListViewPrivate::flick(AxisData &data, qreal minExtent, qreal
if (v > 0)
dist = -dist;
if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QDeclarative1ListView::SnapOneItem) {
- qreal distTemp = isRightToLeft() ? -dist : dist;
- data.flickTarget = -snapPosAt(-(dataValue - highlightStart) + distTemp) + highlightStart;
+ if (snapMode != QDeclarative1ListView::SnapOneItem) {
+ qreal distTemp = isRightToLeft() ? -dist : dist;
+ data.flickTarget = -snapPosAt(-(dataValue - highlightStart) + distTemp) + highlightStart;
+ }
data.flickTarget = isRightToLeft() ? -data.flickTarget+size() : data.flickTarget;
if (overShoot) {
if (data.flickTarget >= minExtent) {
@@ -1492,14 +1517,14 @@ void QDeclarative1ListViewPrivate::flick(AxisData &data, qreal minExtent, qreal
timeline.reset(data.move);
timeline.accel(data.move, v, accel, maxDistance + overshootDist);
timeline.callback(QDeclarative1TimeLineCallback(&data.move, fixupCallback, this));
- if (!flickingHorizontally && q->xflick()) {
- flickingHorizontally = true;
+ if (!hData.flicking && q->xflick()) {
+ hData.flicking = true;
emit q->flickingChanged();
emit q->flickingHorizontallyChanged();
emit q->flickStarted();
}
- if (!flickingVertically && q->yflick()) {
- flickingVertically = true;
+ if (!vData.flicking && q->yflick()) {
+ vData.flicking = true;
emit q->flickingChanged();
emit q->flickingVerticallyChanged();
emit q->flickStarted();
@@ -1876,6 +1901,8 @@ void QDeclarative1ListView::setCurrentIndex(int index)
if (index == d->currentIndex)
return;
if (isComponentComplete() && d->isValid()) {
+ if (d->layoutScheduled)
+ d->layout();
d->moveReason = QDeclarative1ListViewPrivate::SetIndex;
d->updateCurrent(index);
} else if (d->currentIndex != index) {
@@ -2568,7 +2595,8 @@ bool QDeclarative1ListView::event(QEvent *event)
{
Q_D(QDeclarative1ListView);
if (event->type() == QEvent::User) {
- d->layout();
+ if (d->layoutScheduled)
+ d->layout();
return true;
}
@@ -2587,7 +2615,7 @@ void QDeclarative1ListView::viewportMoved()
d->inViewportMoved = true;
d->lazyRelease = true;
refill();
- if (d->flickingHorizontally || d->flickingVertically || d->movingHorizontally || d->movingVertically)
+ if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving)
d->moveReason = QDeclarative1ListViewPrivate::Mouse;
if (d->moveReason != QDeclarative1ListViewPrivate::SetIndex) {
if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) {
@@ -2621,7 +2649,7 @@ void QDeclarative1ListView::viewportMoved()
}
}
- if ((d->flickingHorizontally || d->flickingVertically) && d->correctFlick && !d->inFlickCorrection) {
+ if ((d->hData.flicking || d->vData.flicking) && d->correctFlick && !d->inFlickCorrection) {
d->inFlickCorrection = true;
// Near an end and it seems that the extent has changed?
// Recalculate the flick so that we don't end up in an odd position.
@@ -2745,7 +2773,7 @@ qreal QDeclarative1ListView::minXExtent() const
d->minExtent += d->header->size();
}
if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
- d->minExtent += highlightStart;
+ d->minExtent += d->isRightToLeft() ? -highlightStart : highlightStart;
d->minExtent = qMax(d->minExtent, -(endPositionFirstItem - highlightEnd + 1));
}
d->minExtentDirty = false;
diff --git a/src/qtquick1/graphicsitems/qdeclarativetextinput.cpp b/src/qtquick1/graphicsitems/qdeclarativetextinput.cpp
index 3a36e6b070..009c72a4cd 100644
--- a/src/qtquick1/graphicsitems/qdeclarativetextinput.cpp
+++ b/src/qtquick1/graphicsitems/qdeclarativetextinput.cpp
@@ -1392,7 +1392,8 @@ QVariant QDeclarative1TextInput::inputMethodQuery(Qt::InputMethodQuery property)
case Qt::ImCursorPosition:
return QVariant(d->control->cursor());
case Qt::ImSurroundingText:
- if (d->control->echoMode() == PasswordEchoOnEdit && !d->control->passwordEchoEditing())
+ if (d->control->echoMode() == QLineControl::PasswordEchoOnEdit
+ && !d->control->passwordEchoEditing())
return QVariant(displayText());
else
return QVariant(text());
diff --git a/src/qtquick1/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/qtquick1/graphicsitems/qdeclarativevisualitemmodel.cpp
index f76a4d9f08..58bd09b280 100644
--- a/src/qtquick1/graphicsitems/qdeclarativevisualitemmodel.cpp
+++ b/src/qtquick1/graphicsitems/qdeclarativevisualitemmodel.cpp
@@ -60,7 +60,7 @@
#include <QtDeclarative/private/qlistmodelinterface_p.h>
#include <qhash.h>
#include <qlist.h>
-#include <QtDeclarative/private/qmetaobjectbuilder_p.h>
+#include <private/qmetaobjectbuilder_p.h>
#include <QtCore/qdebug.h>
#include <private/qobject_p.h>
diff --git a/src/qtquick1/util/qdeclarativeanimation.cpp b/src/qtquick1/util/qdeclarativeanimation.cpp
index 8204e33022..cc1ada151a 100644
--- a/src/qtquick1/util/qdeclarativeanimation.cpp
+++ b/src/qtquick1/util/qdeclarativeanimation.cpp
@@ -191,7 +191,7 @@ void QDeclarative1AbstractAnimation::setRunning(bool r)
else if (!d->registered) {
d->registered = true;
QDeclarativeEnginePrivate *engPriv = QDeclarativeEnginePrivate::get(qmlEngine(this));
- engPriv->registerFinalizedParserStatusObject(this, this->metaObject()->indexOfSlot("componentFinalized()"));
+ engPriv->registerFinalizeCallback(this, this->metaObject()->indexOfSlot("componentFinalized()"));
}
return;
}
diff --git a/src/qtquick1/util/qdeclarativebehavior.cpp b/src/qtquick1/util/qdeclarativebehavior.cpp
index 0475eea01f..eb0f5880f1 100644
--- a/src/qtquick1/util/qdeclarativebehavior.cpp
+++ b/src/qtquick1/util/qdeclarativebehavior.cpp
@@ -221,7 +221,7 @@ void QDeclarative1Behavior::setTarget(const QDeclarativeProperty &property)
d->animation->setDefaultTarget(property);
QDeclarativeEnginePrivate *engPriv = QDeclarativeEnginePrivate::get(qmlEngine(this));
- engPriv->registerFinalizedParserStatusObject(this, this->metaObject()->indexOfSlot("componentFinalized()"));
+ engPriv->registerFinalizeCallback(this, this->metaObject()->indexOfSlot("componentFinalized()"));
}
void QDeclarative1Behavior::componentFinalized()
diff --git a/src/qtquick1/util/qdeclarativeconnections.cpp b/src/qtquick1/util/qdeclarativeconnections.cpp
index 54f51acd12..03c7a9265d 100644
--- a/src/qtquick1/util/qdeclarativeconnections.cpp
+++ b/src/qtquick1/util/qdeclarativeconnections.cpp
@@ -205,7 +205,7 @@ QDeclarative1ConnectionsParser::compile(const QList<QDeclarativeCustomParserProp
for(int ii = 0; ii < props.count(); ++ii)
{
- QString propName = QString::fromUtf8(props.at(ii).name());
+ QString propName = props.at(ii).name();
if (!propName.startsWith(QLatin1String("on")) || !propName.at(2).isUpper()) {
error(props.at(ii), QDeclarative1Connections::tr("Cannot assign to non-existent property \"%1\"").arg(propName));
return QByteArray();
diff --git a/src/qtquick1/util/qdeclarativeopenmetaobject.cpp b/src/qtquick1/util/qdeclarativeopenmetaobject.cpp
index b4864a9a7c..e6218a6bca 100644
--- a/src/qtquick1/util/qdeclarativeopenmetaobject.cpp
+++ b/src/qtquick1/util/qdeclarativeopenmetaobject.cpp
@@ -42,7 +42,7 @@
#include "QtQuick1/private/qdeclarativeopenmetaobject_p.h"
#include "QtDeclarative/private/qdeclarativepropertycache_p.h"
#include "QtDeclarative/private/qdeclarativedata_p.h"
-#include <QtDeclarative/private/qmetaobjectbuilder_p.h>
+#include <private/qmetaobjectbuilder_p.h>
#include <qdebug.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qtquick1/util/qdeclarativepropertychanges.cpp b/src/qtquick1/util/qdeclarativepropertychanges.cpp
index fc063cafb0..692d7bbb60 100644
--- a/src/qtquick1/util/qdeclarativepropertychanges.cpp
+++ b/src/qtquick1/util/qdeclarativepropertychanges.cpp
@@ -243,11 +243,11 @@ public:
};
void
-QDeclarative1PropertyChangesParser::compileList(QList<QPair<QByteArray, QVariant> > &list,
- const QByteArray &pre,
+QDeclarative1PropertyChangesParser::compileList(QList<QPair<QString, QVariant> > &list,
+ const QString &pre,
const QDeclarativeCustomParserProperty &prop)
{
- QByteArray propName = pre + prop.name();
+ QString propName = pre + prop.name();
QList<QVariant> values = prop.assignedValues();
for (int ii = 0; ii < values.count(); ++ii) {
@@ -261,7 +261,7 @@ QDeclarative1PropertyChangesParser::compileList(QList<QPair<QByteArray, QVariant
QDeclarativeCustomParserProperty prop =
qvariant_cast<QDeclarativeCustomParserProperty>(value);
- QByteArray pre = propName + '.';
+ QString pre = propName + QLatin1Char('.');
compileList(list, pre, prop);
} else {
@@ -273,9 +273,9 @@ QDeclarative1PropertyChangesParser::compileList(QList<QPair<QByteArray, QVariant
QByteArray
QDeclarative1PropertyChangesParser::compile(const QList<QDeclarativeCustomParserProperty> &props)
{
- QList<QPair<QByteArray, QVariant> > data;
+ QList<QPair<QString, QVariant> > data;
for(int ii = 0; ii < props.count(); ++ii)
- compileList(data, QByteArray(), props.at(ii));
+ compileList(data, QString(), props.at(ii));
QByteArray rv;
QDataStream ds(&rv, QIODevice::WriteOnly);
@@ -307,7 +307,7 @@ QDeclarative1PropertyChangesParser::compile(const QList<QDeclarativeCustomParser
break;
}
- ds << QString::fromUtf8(data.at(ii).first) << isScript << var;
+ ds << data.at(ii).first << isScript << var;
if (isScript)
ds << id;
}
diff --git a/src/qtquick1/util/qdeclarativepropertychanges_p.h b/src/qtquick1/util/qdeclarativepropertychanges_p.h
index b3aed087e3..ef3bc003fa 100644
--- a/src/qtquick1/util/qdeclarativepropertychanges_p.h
+++ b/src/qtquick1/util/qdeclarativepropertychanges_p.h
@@ -96,7 +96,7 @@ public:
QDeclarative1PropertyChangesParser()
: QDeclarativeCustomParser(AcceptsAttachedProperties) {}
- void compileList(QList<QPair<QByteArray, QVariant> > &list, const QByteArray &pre, const QDeclarativeCustomParserProperty &prop);
+ void compileList(QList<QPair<QString, QVariant> > &list, const QString &pre, const QDeclarativeCustomParserProperty &prop);
virtual QByteArray compile(const QList<QDeclarativeCustomParserProperty> &);
virtual void setCustomData(QObject *, const QByteArray &);
diff --git a/src/qtquick1/util/qdeclarativestategroup.cpp b/src/qtquick1/util/qdeclarativestategroup.cpp
index 539fbbadab..70b7b37dd8 100644
--- a/src/qtquick1/util/qdeclarativestategroup.cpp
+++ b/src/qtquick1/util/qdeclarativestategroup.cpp
@@ -445,7 +445,7 @@ void QDeclarative1StateGroupPrivate::setCurrentStateInternal(const QString &stat
applyingState = true;
- QDeclarative1Transition *transition = (ignoreTrans || ignoreTrans) ? 0 : findTransition(currentState, state);
+ QDeclarative1Transition *transition = ignoreTrans ? 0 : findTransition(currentState, state);
if (stateChangeDebug()) {
qWarning() << this << "Changing state. From" << currentState << ". To" << state;
if (transition)
diff --git a/src/qtquick1/util/qdeclarativeview.cpp b/src/qtquick1/util/qdeclarativeview.cpp
index fd5f9debf7..8581947c06 100644
--- a/src/qtquick1/util/qdeclarativeview.cpp
+++ b/src/qtquick1/util/qdeclarativeview.cpp
@@ -304,7 +304,8 @@ void QDeclarativeViewPrivate::init()
q->viewport()->setAttribute(Qt::WA_NoSystemBackground);
#endif
- QDeclarativeInspectorService::instance()->addView(q);
+ if (QDeclarativeDebugService::isDebuggingEnabled())
+ QDeclarativeInspectorService::instance()->addView(q);
}
/*!
@@ -312,7 +313,8 @@ void QDeclarativeViewPrivate::init()
*/
QDeclarativeView::~QDeclarativeView()
{
- QDeclarativeInspectorService::instance()->removeView(this);
+ if (QDeclarativeDebugService::isDebuggingEnabled())
+ QDeclarativeInspectorService::instance()->removeView(this);
}
/*! \property QDeclarativeView::source
diff --git a/src/qtquick1/util/qdeclarativexmllistmodel.cpp b/src/qtquick1/util/qdeclarativexmllistmodel.cpp
index 2450534174..d831590883 100644
--- a/src/qtquick1/util/qdeclarativexmllistmodel.cpp
+++ b/src/qtquick1/util/qdeclarativexmllistmodel.cpp
@@ -179,12 +179,12 @@ public:
{
QMutexLocker m1(&m_mutex);
m_queryIds.ref();
- if (m_queryIds <= 0)
- m_queryIds = 1;
+ if (m_queryIds.load() <= 0)
+ m_queryIds.store(1);
}
XmlQueryJob job;
- job.queryId = m_queryIds;
+ job.queryId = m_queryIds.load();
job.data = data;
job.query = QLatin1String("doc($src)") + query;
job.namespaces = namespaces;
@@ -203,7 +203,7 @@ public:
{
QMutexLocker ml(&m_mutex);
- m_jobs.insert(m_queryIds, job);
+ m_jobs.insert(m_queryIds.load(), job);
}
QMetaObject::invokeMethod(this, "processQuery", Qt::QueuedConnection, Q_ARG(int, job.queryId));
diff --git a/src/src.pro b/src/src.pro
index 6fbfc243de..3f71db2472 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -5,4 +5,5 @@ SUBDIRS += declarative qtquick1 plugins
contains(QT_CONFIG, qmltest): SUBDIRS += qmltest
SUBDIRS += imports
+SUBDIRS += qmldevtools
diff --git a/sync.profile b/sync.profile
index 2ea92fb94e..b09462d6aa 100644
--- a/sync.profile
+++ b/sync.profile
@@ -2,8 +2,10 @@
"QtDeclarative" => "$basedir/src/declarative",
"QtQuick1" => "$basedir/src/qtquick1",
"QtQuickTest" => "$basedir/src/qmltest",
+ "QtQmlDevTools" => "$basedir/src/qmldevtools",
);
%moduleheaders = ( # restrict the module headers to those found in relative path
+ "QtQmlDevTools" => "../declarative/qml/parser",
);
%classnames = (
"qtdeclarativeversion.h" => "QtDeclarativeVersion",
@@ -18,6 +20,7 @@
"QtDeclarative" => "$basedir/modules/qt_declarative.pri",
"QtQuick1" => "$basedir/modules/qt_qtquick1.pri",
"QtQuickTest" => "$basedir/modules/qt_qmltest.pri",
+ "QtQmlDevTools" => "$basedir/modules/qt_qmldevtools.pri",
);
# Module dependencies.
# Every module that is required to build this module should have one entry.
@@ -27,6 +30,5 @@
#
%dependencies = (
"qtbase" => "refs/heads/master",
- "qtsvg" => "refs/heads/master",
"qtxmlpatterns" => "refs/heads/master",
);
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index b831ecefe5..c3ec7231cc 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -1,8 +1,11 @@
TEMPLATE=subdirs
SUBDIRS=\
- declarative
+ declarative \
+ particles
# ### refactor: port properly
# contains(QT_CONFIG, qmltest): SUBDIRS += qmltest
+SUBDIRS += qmldevtools
+
!cross_compile: SUBDIRS += host.pro
diff --git a/tests/auto/declarative/debugger/debugger.pro b/tests/auto/declarative/debugger/debugger.pro
new file mode 100644
index 0000000000..a9c5bdee99
--- /dev/null
+++ b/tests/auto/declarative/debugger/debugger.pro
@@ -0,0 +1,12 @@
+TEMPLATE = subdirs
+
+PRIVATETESTS += \
+ qdeclarativeenginedebug \
+ qdeclarativedebugclient \
+ qdeclarativedebugservice \
+ qdeclarativedebugjs \
+ qpacketprotocol
+
+contains(QT_CONFIG, private_tests) {
+ SUBDIRS += $$PRIVATETESTS
+}
diff --git a/tests/auto/declarative/qdeclarativedebugclient/qdeclarativedebugclient.pro b/tests/auto/declarative/debugger/qdeclarativedebugclient/qdeclarativedebugclient.pro
index 28e25e9450..850a0d4ecc 100644
--- a/tests/auto/declarative/qdeclarativedebugclient/qdeclarativedebugclient.pro
+++ b/tests/auto/declarative/debugger/qdeclarativedebugclient/qdeclarativedebugclient.pro
@@ -1,5 +1,5 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += network declarative
+CONFIG += testcase
+TARGET = tst_qdeclarativedebugclient
macx:CONFIG -= app_bundle
HEADERS += ../shared/debugutil_p.h
@@ -8,5 +8,5 @@ SOURCES += tst_qdeclarativedebugclient.cpp \
CONFIG += declarative_debug
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp b/tests/auto/declarative/debugger/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp
index 220669ad8d..1587eee060 100644
--- a/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp
+++ b/tests/auto/declarative/debugger/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp
@@ -47,7 +47,6 @@
#include <QtDeclarative/qdeclarativeengine.h>
-#include "../../../shared/util.h"
#include "../shared/debugutil_p.h"
#define PORT 13770
diff --git a/tests/auto/declarative/qdeclarativedebugjs/data/test.js b/tests/auto/declarative/debugger/qdeclarativedebugjs/data/test.js
index 230a4ea7de..230a4ea7de 100644
--- a/tests/auto/declarative/qdeclarativedebugjs/data/test.js
+++ b/tests/auto/declarative/debugger/qdeclarativedebugjs/data/test.js
diff --git a/tests/auto/declarative/qdeclarativedebugjs/data/test.qml b/tests/auto/declarative/debugger/qdeclarativedebugjs/data/test.qml
index 386b366cab..3bfeb1011a 100644
--- a/tests/auto/declarative/qdeclarativedebugjs/data/test.qml
+++ b/tests/auto/declarative/debugger/qdeclarativedebugjs/data/test.qml
@@ -47,11 +47,11 @@ import "test.js" as Script
Rectangle {
id: root
width: 10; height: 10;
- Component.onCompleted: print("onCompleted")
-
- property int result:0
+ Component.onCompleted: { Script.printMessage("onCompleted"); doSomething(); }
+ property int result: 0
property int someValue: 10
+ property bool raiseException: false
function doSomething() {
var a = root.result;
@@ -63,7 +63,7 @@ Rectangle {
}
Timer {
- interval: 4000; running: true; repeat: true
+ id: timer; interval: 1
onTriggered: {
doSomething();
Script.printMessage("onTriggered");
@@ -77,10 +77,8 @@ Rectangle {
function doSomethingElse() {
result = Script.add(result,8);
- eval("print(root.result)");
- if (root.result > 15)
+ if (raiseException)
dummy();
}
-
}
diff --git a/tests/auto/declarative/debugger/qdeclarativedebugjs/qdeclarativedebugjs.pro b/tests/auto/declarative/debugger/qdeclarativedebugjs/qdeclarativedebugjs.pro
new file mode 100644
index 0000000000..236692a799
--- /dev/null
+++ b/tests/auto/declarative/debugger/qdeclarativedebugjs/qdeclarativedebugjs.pro
@@ -0,0 +1,22 @@
+CONFIG += testcase
+TARGET = tst_qdeclarativedebugjs
+QT += network script declarative-private testlib
+macx:CONFIG -= app_bundle
+
+HEADERS += ../shared/debugutil_p.h
+
+SOURCES += tst_qdeclarativedebugjs.cpp \
+ ../shared/debugutil.cpp
+
+INCLUDEPATH += ../shared
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+
+CONFIG += parallel_test
+#temporary
+CONFIG += insignificant_test
+
+OTHER_FILES += data/test.qml data/test.js
diff --git a/tests/auto/declarative/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp b/tests/auto/declarative/debugger/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp
index d76fa749a2..2386d0be18 100644
--- a/tests/auto/declarative/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp
+++ b/tests/auto/declarative/debugger/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp
@@ -50,8 +50,8 @@
#include <QtDeclarative/QJSEngine>
//QDeclarativeDebugTest
-#include "../../../shared/util.h"
#include "../shared/debugutil_p.h"
+#include "../../shared/util.h"
const char *SEQ = "seq";
const char *TYPE = "type";
@@ -131,12 +131,6 @@ const char *JSFILE = "test.js";
jsonVal.setProperty(SEQ,QJSValue(seq++)); \
jsonVal.setProperty(TYPE,REQUEST);
-inline QString TEST_FILE(const QString &filename)
-{
- QFileInfo fileInfo(__FILE__);
- return fileInfo.absoluteDir().filePath("data/" + filename);
-}
-
class QJSDebugProcess;
class QJSDebugClient;
@@ -297,6 +291,11 @@ void QJSDebugProcess::processAppOutput()
continue;
}
}
+ if (line.startsWith("QDeclarativeDebugServer: Unable to listen on port")) {
+ QFAIL("Application cannot open port 3771: Port is blocked?");
+ break;
+ }
+// qWarning() << line;
}
m_mutex.unlock();
}
@@ -965,7 +964,7 @@ void QJSDebugClient::messageReceived(const QByteArray &data)
if (type == "response") {
if (!value.value("success").toBool()) {
- qDebug() << "Error: The test case will fail since no signal is emitted";
+// qDebug() << "Error: The test case will fail since no signal is emitted";
return;
}
@@ -1055,7 +1054,7 @@ void tst_QDeclarativeDebugJS::init()
process = new QJSDebugProcess();
client = new QJSDebugClient(connection);
- process->start(QStringList() << QLatin1String(BLOCKMODE) << TEST_FILE(QLatin1String(QMLFILE)));
+ process->start(QStringList() << QLatin1String(BLOCKMODE) << TESTDATA(QLatin1String(QMLFILE)));
QVERIFY(process->waitForSessionStart());
connection->connectToHost("127.0.0.1", 3771);
@@ -1174,12 +1173,19 @@ void tst_QDeclarativeDebugJS::setBreakpointInScriptOnCompleted()
void tst_QDeclarativeDebugJS::setBreakpointInScriptOnTimerCallback()
{
+ int sourceLine = 49;
+ client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
+ client->startDebugging();
+ QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
+
+ client->evaluate("timer.running = true");
+ client->continueDebugging(QJSDebugClient::Continue);
+
//void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1)
- int sourceLine = 67;
+ sourceLine = 67;
client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
- client->startDebugging();
QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
QString jsonString(client->response);
@@ -1330,6 +1336,10 @@ void tst_QDeclarativeDebugJS::changeBreakpoint()
client->continueDebugging(QJSDebugClient::Continue);
//Hit 2nd breakpoint
QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
+
+ // start timer
+ client->evaluate("timer.running = true");
+
//Continue with debugging
client->continueDebugging(QJSDebugClient::Continue);
//Should stop at 2nd breakpoint
@@ -1372,6 +1382,8 @@ void tst_QDeclarativeDebugJS::changeBreakpointOnCondition()
client->continueDebugging(QJSDebugClient::Continue);
//Hit 2nd breakpoint
QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ // start timer
+ client->evaluate("timer.running = true");
//Continue with debugging
client->continueDebugging(QJSDebugClient::Continue);
//Should stop at 2nd breakpoint
@@ -1436,6 +1448,8 @@ void tst_QDeclarativeDebugJS::clearBreakpoint()
client->continueDebugging(QJSDebugClient::Continue);
//Hit 2nd breakpoint
QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ // start timer
+ client->evaluate("timer.running = true");
//Continue with debugging
client->continueDebugging(QJSDebugClient::Continue);
//Should stop at 2nd breakpoint
@@ -1453,13 +1467,12 @@ void tst_QDeclarativeDebugJS::setExceptionBreak()
{
//void setExceptionBreak(QString type, bool enabled = false);
- client->interrupt();
+ int sourceLine = 49;
+ client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
+ client->setExceptionBreak(QJSDebugClient::All,true);
client->startDebugging();
QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- client->setExceptionBreak(QJSDebugClient::All,true);
- QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(result())));
-
+ client->evaluate("root.raiseException = true");
client->continueDebugging(QJSDebugClient::Continue);
QVERIFY(QDeclarativeDebugTest::waitForSignal(client, SIGNAL(stopped()), 10000));
}
@@ -1512,8 +1525,8 @@ void tst_QDeclarativeDebugJS::stepIn()
{
//void continueDebugging(StepAction stepAction, int stepCount = 1);
- int sourceLine = 67;
- int actualLine = 56;
+ int sourceLine = 61;
+ int actualLine = 78;
client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
client->startDebugging();
@@ -1536,7 +1549,7 @@ void tst_QDeclarativeDebugJS::stepOut()
//void continueDebugging(StepAction stepAction, int stepCount = 1);
int sourceLine = 56;
- int actualLine = 68;
+ int actualLine = 49;
client->setBreakpoint(QLatin1String(SCRIPT), QLatin1String(QMLFILE), sourceLine, -1, true);
client->startDebugging();
diff --git a/tests/auto/declarative/qdeclarativedebugservice/qdeclarativedebugservice.pro b/tests/auto/declarative/debugger/qdeclarativedebugservice/qdeclarativedebugservice.pro
index 999e19279b..c23e9204f7 100644
--- a/tests/auto/declarative/qdeclarativedebugservice/qdeclarativedebugservice.pro
+++ b/tests/auto/declarative/debugger/qdeclarativedebugservice/qdeclarativedebugservice.pro
@@ -1,5 +1,5 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += network declarative
+CONFIG += testcase
+TARGET = tst_qdeclarativedebugservice
macx:CONFIG -= app_bundle
HEADERS += ../shared/debugutil_p.h
@@ -8,4 +8,4 @@ SOURCES += tst_qdeclarativedebugservice.cpp \
CONFIG += parallel_test declarative_debug
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp b/tests/auto/declarative/debugger/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp
index 011bd40cbc..8f829a6468 100644
--- a/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp
+++ b/tests/auto/declarative/debugger/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp
@@ -50,7 +50,7 @@
#include <private/qdeclarativedebugclient_p.h>
#include <private/qdeclarativedebugservice_p.h>
-#include "../../../shared/util.h"
+#include "../../shared/util.h"
#include "../shared/debugutil_p.h"
diff --git a/tests/auto/declarative/qdeclarativeenginedebug/qdeclarativeenginedebug.pro b/tests/auto/declarative/debugger/qdeclarativeenginedebug/qdeclarativeenginedebug.pro
index acf62acaf9..98736c6628 100644
--- a/tests/auto/declarative/qdeclarativeenginedebug/qdeclarativeenginedebug.pro
+++ b/tests/auto/declarative/debugger/qdeclarativeenginedebug/qdeclarativeenginedebug.pro
@@ -1,5 +1,5 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += network declarative
+CONFIG += testcase
+TARGET = tst_qdeclarativeenginedebug
macx:CONFIG -= app_bundle
HEADERS += ../shared/debugutil_p.h
@@ -8,4 +8,4 @@ SOURCES += tst_qdeclarativeenginedebug.cpp \
CONFIG += parallel_test declarative_debug
-QT += core-private gui-private v8-private declarative-private
+QT += core-private gui-private v8-private declarative-private network testlib
diff --git a/tests/auto/declarative/qdeclarativeenginedebug/tst_qdeclarativeenginedebug.cpp b/tests/auto/declarative/debugger/qdeclarativeenginedebug/tst_qdeclarativeenginedebug.cpp
index 0e4eebb349..8e31303aa4 100644
--- a/tests/auto/declarative/qdeclarativeenginedebug/tst_qdeclarativeenginedebug.cpp
+++ b/tests/auto/declarative/debugger/qdeclarativeenginedebug/tst_qdeclarativeenginedebug.cpp
@@ -58,7 +58,6 @@
#include <private/qdeclarativemetatype_p.h>
#include <private/qdeclarativeproperty_p.h>
-#include "../../../shared/util.h"
#include "../shared/debugutil_p.h"
Q_DECLARE_METATYPE(QDeclarativeDebugWatch::State)
diff --git a/tests/auto/declarative/qpacketprotocol/qpacketprotocol.pro b/tests/auto/declarative/debugger/qpacketprotocol/qpacketprotocol.pro
index 1c2130d5cf..076ab98505 100644
--- a/tests/auto/declarative/qpacketprotocol/qpacketprotocol.pro
+++ b/tests/auto/declarative/debugger/qpacketprotocol/qpacketprotocol.pro
@@ -1,5 +1,5 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += network declarative
+CONFIG += testcase
+TARGET = tst_qpacketprotocol
macx:CONFIG -= app_bundle
HEADERS += ../shared/debugutil_p.h
@@ -7,4 +7,4 @@ SOURCES += tst_qpacketprotocol.cpp \
../shared/debugutil.cpp
CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private
+QT += core-private gui-private v8-private declarative-private network testlib
diff --git a/tests/auto/declarative/qpacketprotocol/tst_qpacketprotocol.cpp b/tests/auto/declarative/debugger/qpacketprotocol/tst_qpacketprotocol.cpp
index 87fa12fdb7..87fa12fdb7 100644
--- a/tests/auto/declarative/qpacketprotocol/tst_qpacketprotocol.cpp
+++ b/tests/auto/declarative/debugger/qpacketprotocol/tst_qpacketprotocol.cpp
diff --git a/tests/auto/declarative/shared/debugutil.cpp b/tests/auto/declarative/debugger/shared/debugutil.cpp
index b502310828..b502310828 100644
--- a/tests/auto/declarative/shared/debugutil.cpp
+++ b/tests/auto/declarative/debugger/shared/debugutil.cpp
diff --git a/tests/auto/declarative/shared/debugutil_p.h b/tests/auto/declarative/debugger/shared/debugutil_p.h
index be8df86b90..be8df86b90 100644
--- a/tests/auto/declarative/shared/debugutil_p.h
+++ b/tests/auto/declarative/debugger/shared/debugutil_p.h
diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro
index 35e3cac4c6..0d9459f81b 100644
--- a/tests/auto/declarative/declarative.pro
+++ b/tests/auto/declarative/declarative.pro
@@ -1,11 +1,11 @@
TEMPLATE = subdirs
METATYPETESTS += \
-# qdeclarativemetatype \
+ qdeclarativemetatype \
qmetaobjectbuilder
PUBLICTESTS += \
-# examples \
+ examples \
geometry \
nodes \
parserstress \
@@ -14,6 +14,7 @@ PUBLICTESTS += \
qdeclarativeengine \
qdeclarativeerror \
qdeclarativefolderlistmodel \
+ qdeclarativeincubator \
qdeclarativeinfo \
qdeclarativelistreference \
qdeclarativemoduleplugin \
@@ -24,26 +25,27 @@ PUBLICTESTS += \
qjsvalue \
qjsvalueiterator \
qjsengine \
- qmlmin
+ qmlmin \
+ qmlplugindump
PRIVATETESTS += \
qdeclarativeanimations \
qdeclarativeapplication \
qdeclarativebehaviors \
qdeclarativebinding \
+ qdeclarativechangeset \
qdeclarativeconnection \
- qdeclarativeenginedebug \
- qdeclarativedebugclient \
- qdeclarativedebugservice \
-# qdeclarativedebugjs \
qdeclarativeecmascript \
+ qdeclarativeexpression \
+ qdeclarativefontloader \
qdeclarativeimageprovider \
qdeclarativeinstruction \
qdeclarativelanguage \
+ qdeclarativelistcompositor \
qdeclarativelistmodel \
+ qdeclarativepath \
qdeclarativeproperty \
qdeclarativepropertymap \
-# qdeclarativescriptdebugging \
qdeclarativesmoothedanimation \
qdeclarativespringanimation \
qdeclarativestyledtext \
@@ -54,19 +56,24 @@ PRIVATETESTS += \
qdeclarativevaluetypes \
qdeclarativeworkerscript \
qdeclarativexmllistmodel \
- qpacketprotocol \
- qdeclarativev4
+ v4
+
+# This test requires the xmlpatterns module
+!contains(QT_CONFIG,xmlpatterns):PRIVATETESTS -= qdeclarativexmllistmodel
SGTESTS = \
qsganimatedimage \
qsgborderimage \
qsgcanvas \
+ qsgdrag \
+ qsgdroparea \
qsgflickable \
qsgflipable \
qsgfocusscope \
qsggridview \
qsgimage \
qsgitem \
+ qsgitem2 \
qsglistview \
qsgloader \
qsgmousearea \
@@ -75,22 +82,18 @@ SGTESTS = \
qsgpositioners \
qsgrepeater \
qsgtext \
-# qsgtextedit \
-# qsgtextinput \
+ qsgtextedit \
+ qsgtextinput \
qsgvisualdatamodel \
+ qsgview \
+ qsgcanvasitem \
SUBDIRS += $$PUBLICTESTS
-
-!symbian: {
- SUBDIRS += $$METATYPETESTS
-}
+SUBDIRS += $$METATYPETESTS
+SUBDIRS += debugger
contains(QT_CONFIG, private_tests) {
SUBDIRS += $$PRIVATETESTS
SUBDIRS += $$SGTESTS
}
-
-# Tests which should run in Pulse
-PULSE_TESTS = $$SUBDIRS
-
diff --git a/tests/auto/declarative/examples/examples.pro b/tests/auto/declarative/examples/examples.pro
index edd4d80e6b..e68a93c6d5 100644
--- a/tests/auto/declarative/examples/examples.pro
+++ b/tests/auto/declarative/examples/examples.pro
@@ -1,5 +1,5 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_examples
macx:CONFIG -= app_bundle
SOURCES += tst_examples.cpp
@@ -8,6 +8,6 @@ DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
#temporary
CONFIG += insignificant_test
-QT += core-private gui-private declarative-private qtquick1-private widgets-private v8-private
+QT += core-private gui-private declarative-private qtquick1-private widgets-private v8-private testlib
qpa:CONFIG+=insignificant_test # QTBUG-20990, aborts
diff --git a/tests/auto/declarative/examples/tst_examples.cpp b/tests/auto/declarative/examples/tst_examples.cpp
index 563aa3ce84..58f16a49d6 100644
--- a/tests/auto/declarative/examples/tst_examples.cpp
+++ b/tests/auto/declarative/examples/tst_examples.cpp
@@ -68,6 +68,9 @@ private:
tst_examples::tst_examples()
{
// Add directories you want excluded here
+#ifdef Q_WS_QPA
+ excludedDirs << "examples/declarative/text/fonts"; // QTBUG-21415
+#endif
// Not run in QSGView
excludedDirs << "examples/declarative/qtquick1";
diff --git a/tests/auto/declarative/geometry/geometry.pro b/tests/auto/declarative/geometry/geometry.pro
index 71d226d503..a66399a6e0 100644
--- a/tests/auto/declarative/geometry/geometry.pro
+++ b/tests/auto/declarative/geometry/geometry.pro
@@ -1,6 +1,4 @@
-load(qttest_p4)
-QT += opengl declarative
-
+CONFIG += testcase
TARGET = tst_geometry
macx:CONFIG -= app_bundle
@@ -8,4 +6,4 @@ SOURCES += tst_geometry.cpp
CONFIG+=parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private opengl testlib
diff --git a/tests/auto/declarative/nodes/nodes.pro b/tests/auto/declarative/nodes/nodes.pro
index 8fda2f649d..b622c6a4b3 100644
--- a/tests/auto/declarative/nodes/nodes.pro
+++ b/tests/auto/declarative/nodes/nodes.pro
@@ -1,6 +1,4 @@
-load(qttest_p4)
-QT += opengl declarative widgets
-
+CONFIG += testcase
TARGET = tst_nodestest
macx:CONFIG -= app_bundle
@@ -8,4 +6,4 @@ SOURCES += tst_nodestest.cpp
CONFIG+=parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private opengl widgets testlib
diff --git a/tests/auto/declarative/parserstress/parserstress.pro b/tests/auto/declarative/parserstress/parserstress.pro
index 4497767a8c..44dc52cc41 100644
--- a/tests/auto/declarative/parserstress/parserstress.pro
+++ b/tests/auto/declarative/parserstress/parserstress.pro
@@ -1,22 +1,14 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_parserstress
macx:CONFIG -= app_bundle
SOURCES += tst_parserstress.cpp
!isEmpty(QT.script.sources) {
- symbian: {
- importFiles.files = $$QT.script.sources\\..\\..\\tests\\auto\\qscriptjstestsuite\\tests
- importFiles.path = .
- DEPLOYMENT += importFiles
- DEFINES += TESTDATADIR=tests
- DEFINES += SRCDIR=.
- } else {
- DEFINES += TESTDATADIR=\\\"$$QT.script.sources/../../tests/auto/qscriptjstestsuite/tests\\\"
- DEFINES += SRCDIR=\\\"$$PWD\\\"
- }
+ DEFINES += TESTDATADIR=\\\"$$QT.script.sources/../../tests/auto/qscriptjstestsuite/tests\\\"
+ DEFINES += SRCDIR=\\\"$$PWD\\\"
}
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/parserstress/tst_parserstress.cpp b/tests/auto/declarative/parserstress/tst_parserstress.cpp
index 574bbfab18..ba958859a0 100644
--- a/tests/auto/declarative/parserstress/tst_parserstress.cpp
+++ b/tests/auto/declarative/parserstress/tst_parserstress.cpp
@@ -100,7 +100,7 @@ void tst_parserstress::ecmascript_data()
void tst_parserstress::ecmascript()
{
#ifndef TESTDATADIR
- QSKIP("Needs QtScript sources", SkipAll);
+ QSKIP("Needs QtScript sources");
#else
QFETCH(QString, file);
diff --git a/tests/auto/declarative/qdeclarativeanimations/data/pathInterpolatorBack.qml b/tests/auto/declarative/qdeclarativeanimations/data/pathInterpolatorBack.qml
new file mode 100644
index 0000000000..41366ef798
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeanimations/data/pathInterpolatorBack.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.0
+
+PathInterpolator {
+ path: Path {
+ startX: 50; startY: 50
+ PathLine { x: 50; y: 100 }
+ PathLine { x: 100; y: 100 }
+ PathLine { x: 100; y: 50 }
+ PathLine { x: 200; y: 50 }
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro b/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro
index 049e1b3acb..5870d74ab2 100644
--- a/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro
+++ b/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro
@@ -1,16 +1,12 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative opengl
+CONFIG += testcase
+TARGET = tst_qdeclarativeanimations
SOURCES += tst_qdeclarativeanimations.cpp
macx:CONFIG -= app_bundle
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private opengl-private
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
diff --git a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
index af2972219a..6265094697 100644
--- a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
+++ b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
@@ -38,12 +38,13 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include <qtest.h>
+#include <QtTest/QtTest>
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtDeclarative/qsgview.h>
#include <QtDeclarative/private/qsgrectangle_p.h>
#include <QtDeclarative/private/qdeclarativeanimation_p.h>
+#include <QtDeclarative/private/qdeclarativetransition_p.h>
#include <QtDeclarative/private/qsganimation_p.h>
#include <QtDeclarative/private/qdeclarativepathinterpolator_p.h>
#include <QtDeclarative/private/qsgitem_p.h>
@@ -53,12 +54,7 @@
#include <limits.h>
#include <math.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class tst_qdeclarativeanimations : public QObject
{
@@ -75,6 +71,7 @@ private slots:
void simpleRotation();
void simplePath();
void pathInterpolator();
+ void pathInterpolatorBackwardJump();
void pathWithNoStart();
void alwaysRunToEnd();
void complete();
@@ -226,7 +223,7 @@ void tst_qdeclarativeanimations::simplePath()
{
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathAnimation.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathAnimation.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -262,7 +259,7 @@ void tst_qdeclarativeanimations::simplePath()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathAnimation2.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathAnimation2.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -294,7 +291,7 @@ void tst_qdeclarativeanimations::simplePath()
void tst_qdeclarativeanimations::pathInterpolator()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathInterpolator.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathInterpolator.qml")));
QDeclarativePathInterpolator *interpolator = qobject_cast<QDeclarativePathInterpolator*>(c.create());
QVERIFY(interpolator);
@@ -316,10 +313,42 @@ void tst_qdeclarativeanimations::pathInterpolator()
QCOMPARE(interpolator->angle(), qreal(0));
}
+void tst_qdeclarativeanimations::pathInterpolatorBackwardJump()
+{
+ QDeclarativeEngine engine;
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathInterpolatorBack.qml")));
+ QDeclarativePathInterpolator *interpolator = qobject_cast<QDeclarativePathInterpolator*>(c.create());
+ QVERIFY(interpolator);
+
+ QCOMPARE(interpolator->progress(), qreal(0));
+ QCOMPARE(interpolator->x(), qreal(50));
+ QCOMPARE(interpolator->y(), qreal(50));
+ QCOMPARE(interpolator->angle(), qreal(270));
+
+ interpolator->setProgress(.5);
+ QCOMPARE(interpolator->progress(), qreal(.5));
+ QCOMPARE(interpolator->x(), qreal(100));
+ QCOMPARE(interpolator->y(), qreal(75));
+ QCOMPARE(interpolator->angle(), qreal(90));
+
+ interpolator->setProgress(1);
+ QCOMPARE(interpolator->progress(), qreal(1));
+ QCOMPARE(interpolator->x(), qreal(200));
+ QCOMPARE(interpolator->y(), qreal(50));
+ QCOMPARE(interpolator->angle(), qreal(0));
+
+ //make sure we don't get caught in infinite loop here
+ interpolator->setProgress(0);
+ QCOMPARE(interpolator->progress(), qreal(0));
+ QCOMPARE(interpolator->x(), qreal(50));
+ QCOMPARE(interpolator->y(), qreal(50));
+ QCOMPARE(interpolator->angle(), qreal(270));
+}
+
void tst_qdeclarativeanimations::pathWithNoStart()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathAnimationNoStart.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathAnimationNoStart.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -442,7 +471,7 @@ void tst_qdeclarativeanimations::badTypes()
//don't crash
{
QSGView *view = new QSGView;
- view->setSource(QUrl::fromLocalFile(SRCDIR "/data/badtype1.qml"));
+ view->setSource(QUrl::fromLocalFile(TESTDATA("badtype1.qml")));
qApp->processEvents();
@@ -452,7 +481,7 @@ void tst_qdeclarativeanimations::badTypes()
//make sure we get a compiler error
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/badtype2.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("badtype2.qml")));
QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready");
c.create();
@@ -463,7 +492,7 @@ void tst_qdeclarativeanimations::badTypes()
//make sure we get a compiler error
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/badtype3.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("badtype3.qml")));
QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready");
c.create();
@@ -474,7 +503,7 @@ void tst_qdeclarativeanimations::badTypes()
//don't crash
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/badtype4.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("badtype4.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -492,14 +521,14 @@ void tst_qdeclarativeanimations::badProperties()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c1(&engine, QUrl::fromLocalFile(SRCDIR "/data/badproperty1.qml"));
- QByteArray message = QUrl::fromLocalFile(SRCDIR "/data/badproperty1.qml").toString().toUtf8() + ":18:9: QML ColorAnimation: Cannot animate non-existent property \"border.colr\"";
+ QDeclarativeComponent c1(&engine, QUrl::fromLocalFile(TESTDATA("badproperty1.qml")));
+ QByteArray message = QUrl::fromLocalFile(TESTDATA("badproperty1.qml")).toString().toUtf8() + ":18:9: QML ColorAnimation: Cannot animate non-existent property \"border.colr\"";
QTest::ignoreMessage(QtWarningMsg, message);
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c1.create());
QVERIFY(rect);
- QDeclarativeComponent c2(&engine, QUrl::fromLocalFile(SRCDIR "/data/badproperty2.qml"));
- message = QUrl::fromLocalFile(SRCDIR "/data/badproperty2.qml").toString().toUtf8() + ":18:9: QML ColorAnimation: Cannot animate read-only property \"border\"";
+ QDeclarativeComponent c2(&engine, QUrl::fromLocalFile(TESTDATA("badproperty2.qml")));
+ message = QUrl::fromLocalFile(TESTDATA("badproperty2.qml")).toString().toUtf8() + ":18:9: QML ColorAnimation: Cannot animate read-only property \"border\"";
QTest::ignoreMessage(QtWarningMsg, message);
rect = qobject_cast<QSGRectangle*>(c2.create());
QVERIFY(rect);
@@ -516,7 +545,7 @@ void tst_qdeclarativeanimations::mixedTypes()
//assumes border.width stays a real -- not real robust
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/mixedtype1.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("mixedtype1.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -532,7 +561,7 @@ void tst_qdeclarativeanimations::mixedTypes()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/mixedtype2.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("mixedtype2.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -552,7 +581,7 @@ void tst_qdeclarativeanimations::properties()
const int waitDuration = 300;
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/properties.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -564,7 +593,7 @@ void tst_qdeclarativeanimations::properties()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/properties2.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties2.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -576,7 +605,7 @@ void tst_qdeclarativeanimations::properties()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/properties3.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties3.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -588,7 +617,7 @@ void tst_qdeclarativeanimations::properties()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/properties4.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties4.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -601,7 +630,7 @@ void tst_qdeclarativeanimations::properties()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/properties5.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties5.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -618,7 +647,7 @@ void tst_qdeclarativeanimations::propertiesTransition()
const int waitDuration = 300;
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/propertiesTransition.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -631,7 +660,7 @@ void tst_qdeclarativeanimations::propertiesTransition()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/propertiesTransition2.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition2.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -646,7 +675,7 @@ void tst_qdeclarativeanimations::propertiesTransition()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/propertiesTransition3.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition3.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -659,7 +688,7 @@ void tst_qdeclarativeanimations::propertiesTransition()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/propertiesTransition4.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition4.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -673,7 +702,7 @@ void tst_qdeclarativeanimations::propertiesTransition()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/propertiesTransition5.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition5.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -687,7 +716,7 @@ void tst_qdeclarativeanimations::propertiesTransition()
/*{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/propertiesTransition6.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition6.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -701,7 +730,7 @@ void tst_qdeclarativeanimations::propertiesTransition()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/propertiesTransition7.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition7.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -717,7 +746,7 @@ void tst_qdeclarativeanimations::propertiesTransition()
void tst_qdeclarativeanimations::pathTransition()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathTransition.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathTransition.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -737,7 +766,7 @@ void tst_qdeclarativeanimations::pathTransition()
void tst_qdeclarativeanimations::disabledTransition()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/disabledTransition.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("disabledTransition.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -777,7 +806,7 @@ void tst_qdeclarativeanimations::attached()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/attached.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("attached.qml")));
QTest::ignoreMessage(QtDebugMsg, "off");
QTest::ignoreMessage(QtDebugMsg, "on");
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
@@ -789,7 +818,7 @@ void tst_qdeclarativeanimations::propertyValueSourceDefaultStart()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/valuesource.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("valuesource.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -802,7 +831,7 @@ void tst_qdeclarativeanimations::propertyValueSourceDefaultStart()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/valuesource2.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("valuesource2.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -815,7 +844,7 @@ void tst_qdeclarativeanimations::propertyValueSourceDefaultStart()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/dontAutoStart.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("dontAutoStart.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -833,7 +862,7 @@ void tst_qdeclarativeanimations::dontStart()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/dontStart.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("dontStart.qml")));
QString warning = c.url().toString() + ":14:13: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes.";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
@@ -849,7 +878,7 @@ void tst_qdeclarativeanimations::dontStart()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/dontStart2.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("dontStart2.qml")));
QString warning = c.url().toString() + ":15:17: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes.";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
@@ -917,7 +946,7 @@ void tst_qdeclarativeanimations::easingProperties()
void tst_qdeclarativeanimations::rotation()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/rotation.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("rotation.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -948,7 +977,7 @@ void tst_qdeclarativeanimations::runningTrueBug()
{
//ensure we start correctly when "running: true" is explicitly set
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/runningTrueBug.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("runningTrueBug.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -965,7 +994,7 @@ void tst_qdeclarativeanimations::nonTransitionBug()
//in the case where an animation in the transition doesn't match anything (but previously did)
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, SRCDIR "/data/nonTransitionBug.qml");
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("nonTransitionBug.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -991,7 +1020,7 @@ void tst_qdeclarativeanimations::registrationBug()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, SRCDIR "/data/registrationBug.qml");
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("registrationBug.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
QTRY_COMPARE(rect->property("value"), QVariant(int(100)));
@@ -1001,7 +1030,7 @@ void tst_qdeclarativeanimations::doubleRegistrationBug()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, SRCDIR "/data/doubleRegistrationBug.qml");
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("doubleRegistrationBug.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
@@ -1039,7 +1068,7 @@ void tst_qdeclarativeanimations::transitionAssignmentBug()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, SRCDIR "/data/transitionAssignmentBug.qml");
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("transitionAssignmentBug.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
@@ -1051,7 +1080,7 @@ void tst_qdeclarativeanimations::pauseBindingBug()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, SRCDIR "/data/pauseBindingBug.qml");
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pauseBindingBug.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
QDeclarativeAbstractAnimation *anim = rect->findChild<QDeclarativeAbstractAnimation*>("animation");
@@ -1065,7 +1094,7 @@ void tst_qdeclarativeanimations::pauseBug()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, SRCDIR "/data/pauseBug.qml");
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pauseBug.qml")));
QDeclarativeAbstractAnimation *anim = qobject_cast<QDeclarativeAbstractAnimation*>(c.create());
QVERIFY(anim != 0);
QCOMPARE(anim->qtAnimation()->state(), QAbstractAnimation2::Paused);
diff --git a/tests/auto/declarative/qdeclarativeapplication/qdeclarativeapplication.pro b/tests/auto/declarative/qdeclarativeapplication/qdeclarativeapplication.pro
index 4dbffa9dfb..3b01fcf9e3 100644
--- a/tests/auto/declarative/qdeclarativeapplication/qdeclarativeapplication.pro
+++ b/tests/auto/declarative/qdeclarativeapplication/qdeclarativeapplication.pro
@@ -1,8 +1,7 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui
+CONFIG += testcase
+TARGET = tst_qdeclarativeapplication
macx:CONFIG -= app_bundle
-#temporary
-CONFIG += insignificant_test
+
SOURCES += tst_qdeclarativeapplication.cpp
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp b/tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp
index 9bdf9c14ed..b3fa38de38 100644
--- a/tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp
+++ b/tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp
@@ -40,11 +40,11 @@
****************************************************************************/
#include <qtest.h>
-#include "../../../shared/util.h"
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtDeclarative/qsgitem.h>
#include <QtDeclarative/qsgview.h>
+#include <QtGui/qinputpanel.h>
class tst_qdeclarativeapplication : public QObject
{
@@ -55,6 +55,7 @@ public:
private slots:
void active();
void layoutDirection();
+ void inputPanel();
private:
QDeclarativeEngine engine;
@@ -66,7 +67,7 @@ tst_qdeclarativeapplication::tst_qdeclarativeapplication()
void tst_qdeclarativeapplication::active()
{
- QSKIP("QTBUG-21573", SkipAll);
+ QSKIP("QTBUG-21573");
QDeclarativeComponent component(&engine);
component.setData("import QtQuick 2.0; Item { property bool active: Qt.application.active }", QUrl::fromLocalFile(""));
@@ -99,7 +100,7 @@ void tst_qdeclarativeapplication::active()
void tst_qdeclarativeapplication::layoutDirection()
{
- QSKIP("QTBUG-21573", SkipAll);
+ QSKIP("QTBUG-21573");
QDeclarativeComponent component(&engine);
component.setData("import QtQuick 2.0; Item { property bool layoutDirection: Qt.application.layoutDirection }", QUrl::fromLocalFile(""));
@@ -120,6 +121,19 @@ void tst_qdeclarativeapplication::layoutDirection()
QCOMPARE(Qt::LayoutDirection(item->property("layoutDirection").toInt()), Qt::LeftToRight);
}
+void tst_qdeclarativeapplication::inputPanel()
+{
+ QDeclarativeComponent component(&engine);
+ component.setData("import QtQuick 2.0; Item { property variant inputPanel: Qt.application.inputPanel }", QUrl::fromLocalFile(""));
+ QSGItem *item = qobject_cast<QSGItem *>(component.create());
+ QVERIFY(item);
+ QSGView view;
+ item->setParentItem(view.rootObject());
+
+ // check that the inputPanel property maches with application's input panel
+ QCOMPARE(qvariant_cast<QObject*>(item->property("inputPanel")), qApp->inputPanel());
+}
+
QTEST_MAIN(tst_qdeclarativeapplication)
#include "tst_qdeclarativeapplication.moc"
diff --git a/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro b/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro
index 8ed7ee5a16..0e7c73ab90 100644
--- a/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro
+++ b/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro
@@ -1,16 +1,12 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative opengl
+CONFIG += testcase
+TARGET = tst_qdeclarativebehaviors
SOURCES += tst_qdeclarativebehaviors.cpp
macx:CONFIG -= app_bundle
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
-CONFIG += parallel_test insignificant_test
+CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private opengl-private
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
diff --git a/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp b/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp
index 855e392592..3904fa335d 100644
--- a/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp
+++ b/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp
@@ -38,7 +38,7 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include <qtest.h>
+#include <QtTest/QtTest>
#include <qsignalspy.h>
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtDeclarative/qdeclarativecomponent.h>
@@ -48,12 +48,7 @@
#include <private/qdeclarativebehavior_p.h>
#include <private/qdeclarativeanimation_p.h>
#include <private/qsgitem_p.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class tst_qdeclarativebehaviors : public QObject
{
@@ -87,7 +82,7 @@ private slots:
void tst_qdeclarativebehaviors::simpleBehavior()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/simple.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("simple.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QTRY_VERIFY(rect);
QTRY_VERIFY(qobject_cast<QDeclarativeBehavior*>(rect->findChild<QDeclarativeBehavior*>("MyBehavior"))->animation());
@@ -103,7 +98,7 @@ void tst_qdeclarativebehaviors::simpleBehavior()
void tst_qdeclarativebehaviors::scriptTriggered()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/scripttrigger.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("scripttrigger.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QTRY_VERIFY(rect);
@@ -118,7 +113,7 @@ void tst_qdeclarativebehaviors::scriptTriggered()
void tst_qdeclarativebehaviors::cppTriggered()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/cpptrigger.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("cpptrigger.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QTRY_VERIFY(rect);
@@ -127,6 +122,7 @@ void tst_qdeclarativebehaviors::cppTriggered()
innerRect->setProperty("x", 200);
QTRY_VERIFY(innerRect->x() > 0);
+ QEXPECT_FAIL("", "QTBUG-21001", Continue);
QTRY_VERIFY(innerRect->x() < 200); //i.e. the behavior has been triggered
delete rect;
@@ -135,7 +131,7 @@ void tst_qdeclarativebehaviors::cppTriggered()
void tst_qdeclarativebehaviors::loop()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/loop.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("loop.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QTRY_VERIFY(rect);
@@ -148,7 +144,7 @@ void tst_qdeclarativebehaviors::loop()
void tst_qdeclarativebehaviors::colorBehavior()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/color.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("color.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QTRY_VERIFY(rect);
@@ -163,7 +159,7 @@ void tst_qdeclarativebehaviors::colorBehavior()
void tst_qdeclarativebehaviors::parentBehavior()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/parent.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("parent.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QTRY_VERIFY(rect);
@@ -177,7 +173,7 @@ void tst_qdeclarativebehaviors::parentBehavior()
void tst_qdeclarativebehaviors::replaceBinding()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/binding.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("binding.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QTRY_VERIFY(rect);
@@ -210,7 +206,7 @@ void tst_qdeclarativebehaviors::group()
/* XXX TODO Create a test element for this case.
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/groupProperty.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("groupProperty.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
qDebug() << c.errorString();
QTRY_VERIFY(rect);
@@ -227,7 +223,7 @@ void tst_qdeclarativebehaviors::group()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/groupProperty2.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("groupProperty2.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QTRY_VERIFY(rect);
@@ -243,7 +239,7 @@ void tst_qdeclarativebehaviors::group()
void tst_qdeclarativebehaviors::emptyBehavior()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/empty.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("empty.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -257,7 +253,7 @@ void tst_qdeclarativebehaviors::emptyBehavior()
void tst_qdeclarativebehaviors::explicitSelection()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/explicit.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("explicit.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -272,7 +268,7 @@ void tst_qdeclarativebehaviors::explicitSelection()
void tst_qdeclarativebehaviors::nonSelectingBehavior()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/nonSelecting2.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("nonSelecting2.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -286,8 +282,8 @@ void tst_qdeclarativebehaviors::nonSelectingBehavior()
void tst_qdeclarativebehaviors::reassignedAnimation()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/reassignedAnimation.qml"));
- QString warning = QUrl::fromLocalFile(SRCDIR "/data/reassignedAnimation.qml").toString() + ":9:9: QML Behavior: Cannot change the animation assigned to a Behavior.";
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("reassignedAnimation.qml")));
+ QString warning = QUrl::fromLocalFile(TESTDATA("reassignedAnimation.qml")).toString() + ":9:9: QML Behavior: Cannot change the animation assigned to a Behavior.";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -300,7 +296,7 @@ void tst_qdeclarativebehaviors::reassignedAnimation()
void tst_qdeclarativebehaviors::disabled()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/disabled.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("disabled.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
QCOMPARE(rect->findChild<QDeclarativeBehavior*>("MyBehavior")->enabled(), false);
@@ -316,7 +312,7 @@ void tst_qdeclarativebehaviors::dontStart()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/dontStart.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("dontStart.qml")));
QString warning = c.url().toString() + ":13:13: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes.";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
@@ -335,7 +331,7 @@ void tst_qdeclarativebehaviors::startup()
{
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/startup.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("startup.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -349,7 +345,7 @@ void tst_qdeclarativebehaviors::startup()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/startup2.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("startup2.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -369,7 +365,7 @@ void tst_qdeclarativebehaviors::startup()
void tst_qdeclarativebehaviors::groupedPropertyCrash()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/groupedPropertyCrash.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("groupedPropertyCrash.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect); //don't crash
}
@@ -378,7 +374,7 @@ void tst_qdeclarativebehaviors::groupedPropertyCrash()
void tst_qdeclarativebehaviors::runningTrue()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/runningTrue.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("runningTrue.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -394,7 +390,7 @@ void tst_qdeclarativebehaviors::runningTrue()
void tst_qdeclarativebehaviors::sameValue()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/qtbug12295.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("qtbug12295.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -405,6 +401,9 @@ void tst_qdeclarativebehaviors::sameValue()
QCOMPARE(target->x(), qreal(100));
target->setProperty("x", 0);
+#ifdef QT_BUILD_INTERNAL
+ QEXPECT_FAIL("", "QTBUG-12295 - Behaviour on x {} does not work consistently.", Continue);
+#endif
QTRY_VERIFY(target->x() != qreal(0) && target->x() != qreal(100));
QTRY_VERIFY(target->x() == qreal(0)); //make sure Behavior has finished.
@@ -422,7 +421,7 @@ void tst_qdeclarativebehaviors::delayedRegistration()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, SRCDIR "/data/delayedRegistration.qml");
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("delayedRegistration.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
diff --git a/tests/auto/declarative/qdeclarativebinding/qdeclarativebinding.pro b/tests/auto/declarative/qdeclarativebinding/qdeclarativebinding.pro
index b2e5d2dc3e..d0bbfe6faa 100644
--- a/tests/auto/declarative/qdeclarativebinding/qdeclarativebinding.pro
+++ b/tests/auto/declarative/qdeclarativebinding/qdeclarativebinding.pro
@@ -1,17 +1,13 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui
+CONFIG += testcase
+TARGET = tst_qdeclarativebinding
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativebinding.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp b/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp
index d2581bcb96..de34d9e009 100644
--- a/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp
+++ b/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp
@@ -43,15 +43,9 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <private/qdeclarativebind_p.h>
#include <private/qsgrectangle_p.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class tst_qdeclarativebinding : public QObject
-
{
Q_OBJECT
public:
@@ -75,7 +69,7 @@ tst_qdeclarativebinding::tst_qdeclarativebinding()
void tst_qdeclarativebinding::binding()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/test-binding.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-binding.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
@@ -103,7 +97,7 @@ void tst_qdeclarativebinding::binding()
void tst_qdeclarativebinding::whenAfterValue()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/test-binding2.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-binding2.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
@@ -119,7 +113,7 @@ void tst_qdeclarativebinding::whenAfterValue()
void tst_qdeclarativebinding::restoreBinding()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/restoreBinding.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("restoreBinding.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
@@ -149,7 +143,7 @@ void tst_qdeclarativebinding::restoreBinding()
void tst_qdeclarativebinding::restoreBindingWithLoop()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/restoreBindingWithLoop.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("restoreBindingWithLoop.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
@@ -184,7 +178,7 @@ void tst_qdeclarativebinding::restoreBindingWithLoop()
void tst_qdeclarativebinding::deletedObject()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/deletedObject.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("deletedObject.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
diff --git a/tests/auto/declarative/qdeclarativechangeset/qdeclarativechangeset.pro b/tests/auto/declarative/qdeclarativechangeset/qdeclarativechangeset.pro
index 1c9a3c00f9..b2f88b630b 100644
--- a/tests/auto/declarative/qdeclarativechangeset/qdeclarativechangeset.pro
+++ b/tests/auto/declarative/qdeclarativechangeset/qdeclarativechangeset.pro
@@ -1,17 +1,9 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui
+CONFIG += testcase
+TARGET = tst_qdeclarativechangeset
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativechangeset.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativechangeset/tst_qdeclarativechangeset.cpp b/tests/auto/declarative/qdeclarativechangeset/tst_qdeclarativechangeset.cpp
index 4aaefba7c4..8da3d9b814 100644
--- a/tests/auto/declarative/qdeclarativechangeset/tst_qdeclarativechangeset.cpp
+++ b/tests/auto/declarative/qdeclarativechangeset/tst_qdeclarativechangeset.cpp
@@ -132,8 +132,13 @@ private slots:
void sequence();
};
-bool operator ==(const tst_qdeclarativemodelchange::Signal &left, const tst_qdeclarativemodelchange::Signal &right) {
- return left.index == right.index && left.count == right.count && left.to == right.to; }
+bool operator ==(const tst_qdeclarativemodelchange::Signal &left, const tst_qdeclarativemodelchange::Signal &right)
+{
+ return left.index == right.index
+ && left.count == right.count
+ && left.to == right.to
+ && ((left.moveId == -1 && right.moveId == -1) || left.moveId != -1 && right.moveId != -1);
+}
QDebug operator <<(QDebug debug, const tst_qdeclarativemodelchange::Signal &signal)
@@ -722,6 +727,28 @@ void tst_qdeclarativemodelchange::sequence_data()
QTest::newRow("m(12-23,6),r(20,4)")
<< (SignalList() << Move(12,23,6) << Remove(20,4))
<< (SignalList() << Remove(12,1) << Remove(12,5,0) << Remove(20,3) << Insert(20,5,0));
+
+
+ // Complex
+ QTest::newRow("r(15,1),r(22,1)")
+ << (SignalList() << Remove(15,1) << Remove(22,1))
+ << (SignalList() << Remove(15,1) << Remove(22,1));
+ QTest::newRow("r(15,1),r(22,1),r(25,1)")
+ << (SignalList() << Remove(15,1) << Remove(22,1) << Remove(25,1))
+ << (SignalList() << Remove(15,1) << Remove(22,1) << Remove(25,1));
+ QTest::newRow("r(15,1),r(22,1),r(25,1),r(15,1)")
+ << (SignalList() << Remove(15,1) << Remove(22,1) << Remove(25,1) << Remove(15,1))
+ << (SignalList() << Remove(15,2) << Remove(21,1) << Remove(24,1));
+ QTest::newRow("r(15,1),r(22,1),r(25,1),r(15,1),r(13,1)")
+ << (SignalList() << Remove(15,1) << Remove(22,1) << Remove(25,1) << Remove(15,1) << Remove(13,1))
+ << (SignalList() << Remove(13,1) << Remove(14,2) << Remove(20,1) << Remove(23,1));
+ QTest::newRow("r(15,1),r(22,1),r(25,1),r(15,1),r(13,1),r(13,1)")
+ << (SignalList() << Remove(15,1) << Remove(22,1) << Remove(25,1) << Remove(15,1) << Remove(13,1) << Remove(13,1))
+ << (SignalList() << Remove(13,4) << Remove(19,1) << Remove(22,1));
+ QTest::newRow("r(15,1),r(22,1),r(25,1),r(15,1),r(13,1),r(13,1),m(12,13,1)")
+ << (SignalList() << Remove(15,1) << Remove(22,1) << Remove(25,1) << Remove(15,1) << Remove(13,1) << Remove(13,1) << Move(12,13,1))
+ << (SignalList() << Remove(12,1,0) << Remove(12,4) << Remove(18,1) << Remove(21,1) << Insert(13,1,0));
+
}
void tst_qdeclarativemodelchange::sequence()
diff --git a/tests/auto/declarative/qdeclarativecomponent/data/incubateObject.qml b/tests/auto/declarative/qdeclarativecomponent/data/incubateObject.qml
new file mode 100644
index 0000000000..c11319db30
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativecomponent/data/incubateObject.qml
@@ -0,0 +1,36 @@
+import QtQuick 2.0
+
+Item{
+ id: root
+
+ property bool test1: false
+ property bool test2: false
+
+ property var i
+
+ Component{
+ id: component
+ Item {
+ property int dummy: 13
+ property int dummy2: 26
+ }
+ }
+
+ Component.onCompleted: {
+ i = component.incubateObject(null, { dummy2: 19 });
+
+ if (i.status != Component.Loading) return;
+ if (i.object != null) return;
+
+ i.onStatusChanged = function(status) {
+ if (status != Component.Ready) return;
+ if (i.object == null) return;
+ if (i.object.dummy != 13) return;
+ if (i.object.dummy2 != 19) return;
+ test2 = true;
+ }
+
+ test1 = true;
+ }
+}
+
diff --git a/tests/auto/declarative/qdeclarativecomponent/qdeclarativecomponent.pro b/tests/auto/declarative/qdeclarativecomponent/qdeclarativecomponent.pro
index 50d63fea42..155d615721 100644
--- a/tests/auto/declarative/qdeclarativecomponent/qdeclarativecomponent.pro
+++ b/tests/auto/declarative/qdeclarativecomponent/qdeclarativecomponent.pro
@@ -1,14 +1,13 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
-QT += network
+CONFIG += testcase
+TARGET = tst_qdeclarativecomponent
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativecomponent.cpp
-!symbian: {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp b/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp
index d983f9b1a7..f3354ac5db 100644
--- a/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp
+++ b/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp
@@ -45,27 +45,37 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtDeclarative/qsgitem.h>
#include <QtDeclarative/qdeclarativeproperty.h>
+#include <QtDeclarative/qdeclarativeincubator.h>
#include <qcolor.h>
+#include "../shared/util.h"
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+class MyIC : public QObject, public QDeclarativeIncubationController
+{
+ Q_OBJECT
+public:
+ MyIC() { startTimer(5); }
+protected:
+ virtual void timerEvent(QTimerEvent*) {
+ incubateFor(5);
+ }
+};
class tst_qdeclarativecomponent : public QObject
{
Q_OBJECT
public:
- tst_qdeclarativecomponent() { }
+ tst_qdeclarativecomponent() { engine.setIncubationController(&ic); }
private slots:
void null();
void loadEmptyUrl();
void qmlCreateObject();
void qmlCreateObjectWithProperties();
+ void qmlIncubateObject();
private:
QDeclarativeEngine engine;
+ MyIC ic;
};
void tst_qdeclarativecomponent::null()
@@ -96,10 +106,23 @@ void tst_qdeclarativecomponent::loadEmptyUrl()
QCOMPARE(error.description(), QLatin1String("Invalid empty URL"));
}
+void tst_qdeclarativecomponent::qmlIncubateObject()
+{
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("incubateObject.qml")));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QCOMPARE(object->property("test1").toBool(), true);
+ QCOMPARE(object->property("test2").toBool(), false);
+
+ QTRY_VERIFY(object->property("test2").toBool() == true);
+
+ delete object;
+}
+
void tst_qdeclarativecomponent::qmlCreateObject()
{
QDeclarativeEngine engine;
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/createObject.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("createObject.qml")));
QObject *object = component.create();
QVERIFY(object != 0);
@@ -116,7 +139,7 @@ void tst_qdeclarativecomponent::qmlCreateObject()
void tst_qdeclarativecomponent::qmlCreateObjectWithProperties()
{
QDeclarativeEngine engine;
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/createObjectWithScript.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("createObjectWithScript.qml")));
QVERIFY2(component.errorString().isEmpty(), component.errorString().toUtf8());
QObject *object = component.create();
QVERIFY(object != 0);
diff --git a/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro b/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro
index 7cd78ab1fc..ef3ef536f0 100644
--- a/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro
+++ b/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro
@@ -1,17 +1,13 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui
+CONFIG += testcase
+TARGET = tst_qdeclarativeconnection
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativeconnection.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private opengl-private
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
diff --git a/tests/auto/declarative/qdeclarativeconnection/tst_qdeclarativeconnection.cpp b/tests/auto/declarative/qdeclarativeconnection/tst_qdeclarativeconnection.cpp
index c726fde0e8..ec04833548 100644
--- a/tests/auto/declarative/qdeclarativeconnection/tst_qdeclarativeconnection.cpp
+++ b/tests/auto/declarative/qdeclarativeconnection/tst_qdeclarativeconnection.cpp
@@ -43,16 +43,10 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <private/qdeclarativeconnections_p.h>
#include <private/qsgitem_p.h>
-#include "../../../shared/util.h"
+#include "../shared/util.h"
#include <QtDeclarative/qdeclarativescriptstring.h>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qdeclarativeconnection : public QObject
-
{
Q_OBJECT
public:
@@ -81,7 +75,7 @@ tst_qdeclarativeconnection::tst_qdeclarativeconnection()
void tst_qdeclarativeconnection::defaultValues()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/test-connection3.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-connection3.qml")));
QDeclarativeConnections *item = qobject_cast<QDeclarativeConnections*>(c.create());
QVERIFY(item != 0);
@@ -93,7 +87,7 @@ void tst_qdeclarativeconnection::defaultValues()
void tst_qdeclarativeconnection::properties()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/test-connection2.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-connection2.qml")));
QDeclarativeConnections *item = qobject_cast<QDeclarativeConnections*>(c.create());
QVERIFY(item != 0);
@@ -107,7 +101,7 @@ void tst_qdeclarativeconnection::properties()
void tst_qdeclarativeconnection::connection()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/test-connection.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-connection.qml")));
QSGItem *item = qobject_cast<QSGItem*>(c.create());
QVERIFY(item != 0);
@@ -124,7 +118,7 @@ void tst_qdeclarativeconnection::connection()
void tst_qdeclarativeconnection::trimming()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/trimming.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("trimming.qml")));
QSGItem *item = qobject_cast<QSGItem*>(c.create());
QVERIFY(item != 0);
@@ -145,7 +139,7 @@ void tst_qdeclarativeconnection::trimming()
void tst_qdeclarativeconnection::targetChanged()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/connection-targetchange.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("connection-targetchange.qml")));
QSGItem *item = qobject_cast<QSGItem*>(c.create());
QVERIFY(item != 0);
@@ -182,7 +176,7 @@ void tst_qdeclarativeconnection::unknownSignals()
QFETCH(QString, file);
QFETCH(QString, error);
- QUrl url = QUrl::fromLocalFile(SRCDIR "/data/" + file);
+ QUrl url = QUrl::fromLocalFile(TESTDATA(file));
if (!error.isEmpty()) {
QTest::ignoreMessage(QtWarningMsg, (url.toString() + error).toLatin1());
} else {
@@ -220,7 +214,7 @@ void tst_qdeclarativeconnection::errors()
QFETCH(QString, file);
QFETCH(QString, error);
- QUrl url = QUrl::fromLocalFile(SRCDIR "/data/" + file);
+ QUrl url = QUrl::fromLocalFile(TESTDATA(file));
QDeclarativeEngine engine;
QDeclarativeComponent c(&engine, url);
@@ -270,7 +264,7 @@ static QObject *module_api_factory(QDeclarativeEngine *engine, QJSEngine *script
void tst_qdeclarativeconnection::moduleApiTarget()
{
qmlRegisterModuleApi("MyTestModuleApi", 1, 0, module_api_factory);
- QDeclarativeComponent component(&engine, QUrl(SRCDIR "/data/moduleapi-target.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("moduleapi-target.qml")));
QObject *object = component.create();
QVERIFY(object != 0);
diff --git a/tests/auto/declarative/qdeclarativecontext/qdeclarativecontext.pro b/tests/auto/declarative/qdeclarativecontext/qdeclarativecontext.pro
index 54a8269e17..65af53a45d 100644
--- a/tests/auto/declarative/qdeclarativecontext/qdeclarativecontext.pro
+++ b/tests/auto/declarative/qdeclarativecontext/qdeclarativecontext.pro
@@ -1,12 +1,8 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qdeclarativecontext
SOURCES += tst_qdeclarativecontext.cpp
macx:CONFIG -= app_bundle
-!symbian: {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp b/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp
index 89d08e01df..c241acac05 100644
--- a/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp
+++ b/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp
@@ -46,11 +46,6 @@
#include <QDeclarativeComponent>
#include <QDeclarativeExpression>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qdeclarativecontext : public QObject
{
Q_OBJECT
diff --git a/tests/auto/declarative/qdeclarativecpputils/qdeclarativecpputils.pro b/tests/auto/declarative/qdeclarativecpputils/qdeclarativecpputils.pro
new file mode 100644
index 0000000000..3cae5c25f3
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativecpputils/qdeclarativecpputils.pro
@@ -0,0 +1,9 @@
+CONFIG += testcase
+TARGET = tst_qdeclarativecpputils
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qdeclarativecpputils.cpp
+
+CONFIG += parallel_test
+
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativecpputils/tst_qdeclarativecpputils.cpp b/tests/auto/declarative/qdeclarativecpputils/tst_qdeclarativecpputils.cpp
new file mode 100644
index 0000000000..d72e6d3290
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativecpputils/tst_qdeclarativecpputils.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qtest.h>
+#include <qsignalspy.h>
+#include <private/qdeclarativeglobal_p.h>
+
+class tst_qdeclarativecpputils : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qdeclarativecpputils() {}
+
+private slots:
+ void fastConnect();
+};
+
+class MyObject : public QObject {
+ Q_OBJECT
+public:
+ MyObject() : slotCount(0) {}
+ friend class tst_qdeclarativecpputils;
+
+ int slotCount;
+
+signals:
+ void signal1();
+ void signal2();
+
+public slots:
+ void slot1() { slotCount++; }
+};
+
+void tst_qdeclarativecpputils::fastConnect()
+{
+ {
+ MyObject *obj = new MyObject;
+ FAST_CONNECT(obj, SIGNAL(signal1()), obj, SLOT(slot1()));
+
+ obj->signal1();
+ QCOMPARE(obj->slotCount, 1);
+
+ delete obj;
+ }
+
+ {
+ MyObject obj;
+ FAST_CONNECT(&obj, SIGNAL(signal1()), &obj, SLOT(slot1()))
+
+ obj.signal1();
+ QCOMPARE(obj.slotCount, 1);
+ }
+
+ {
+ MyObject *obj = new MyObject;
+ QSignalSpy spy(obj, SIGNAL(signal2()));
+ FAST_CONNECT(obj, SIGNAL(signal1()), obj, SIGNAL(signal2()));
+
+ obj->signal1();
+ QCOMPARE(spy.count(), 1);
+
+ delete obj;
+ }
+}
+
+QTEST_MAIN(tst_qdeclarativecpputils)
+
+#include "tst_qdeclarativecpputils.moc"
diff --git a/tests/auto/declarative/qdeclarativedebugjs/qdeclarativedebugjs.pro b/tests/auto/declarative/qdeclarativedebugjs/qdeclarativedebugjs.pro
deleted file mode 100644
index 52bfc49252..0000000000
--- a/tests/auto/declarative/qdeclarativedebugjs/qdeclarativedebugjs.pro
+++ /dev/null
@@ -1,27 +0,0 @@
-load(qttest_p4)
-QT += declarative network script declarative-private
-macx:CONFIG -= app_bundle
-
-HEADERS += ../shared/debugutil_p.h
-
-SOURCES += tst_qdeclarativedebugjs.cpp \
- ../shared/debugutil.cpp
-
-INCLUDEPATH += ../shared
-
-# QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage
-# LIBS += -lgcov
-
-symbian {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-}
-
-OTHER_FILES = data/test.qml \
- data/test.js
-
-
-CONFIG += parallel_test
-#temporary
-CONFIG += insignificant_test
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent.qml b/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent.qml
new file mode 100644
index 0000000000..36c025401f
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent.qml
@@ -0,0 +1,23 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ id: first
+ property var vp: Item {
+ id: second
+ property var vp: Item {
+ id: third
+ property var vp: Item {
+ id: fourth
+ property var vp: Item {
+ id: fifth
+ property int fifthCanary: 5
+ property var circ: third.vp
+ property MyScarceResourceObject srp;
+ srp: MyScarceResourceObject { id: scarceResourceProvider }
+ property variant memoryHog: scarceResourceProvider.newScarceResource()
+ }
+ }
+ }
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent2.qml
new file mode 100644
index 0000000000..6a49cb9317
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent2.qml
@@ -0,0 +1,26 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+// Similar to PVCC.qml except that it has another var property
+// It will have a different metaobject.
+Item {
+ id: first
+ property var anotherVp: 6
+ property var vp: Item {
+ id: second
+ property var vp: Item {
+ id: third
+ property var vp: Item {
+ id: fourth
+ property var vp: Item {
+ id: fifth
+ property int fifthCanary: 5
+ property var circ: third.vp
+ property MyScarceResourceObject srp;
+ srp: MyScarceResourceObject { id: scarceResourceProvider }
+ property variant memoryHog2: scarceResourceProvider.newScarceResource()
+ }
+ }
+ }
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent3.qml
new file mode 100644
index 0000000000..a90725016e
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent3.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: rectangle // will have JS ownership
+ objectName: "rectangle"
+ width: 10
+ height: 10
+ property var rectCanary: 5
+
+ Text {
+ id: text // will have Eventual-JS ownership
+ objectName: "text"
+ property var vp: rectangle
+ property var textCanary: 10
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent4.qml b/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent4.qml
new file mode 100644
index 0000000000..9273a52f54
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent4.qml
@@ -0,0 +1,28 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: rectangle // will have JS ownership
+ objectName: "rectangle"
+ width: 10
+ height: 10
+ property var rectCanary: 5
+
+ Text {
+ id: text // will have Eventual-JS ownership
+ objectName: "text"
+ property var vp
+ property var textCanary: 10
+
+ // The varProperties array of "text" is weak
+ // (due to eventual JS ownership since parent is JS owned)
+ // but nonetheless, the reference to the created QObject
+ // should cause that QObject to NOT be collected.
+ function constructQObject() {
+ var component = Qt.createComponent("PropertyVarCircularComponent5.qml");
+ if (component.status == Component.Ready) {
+ text.vp = component.createObject(null); // has JavaScript ownership
+ }
+ gc();
+ }
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent5.qml b/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent5.qml
new file mode 100644
index 0000000000..94ef338792
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarCircularComponent5.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.0
+
+Image {
+ id: image
+ objectName: "image"
+ property var imageCanary: 13
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarInheritanceComponent.qml b/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarInheritanceComponent.qml
new file mode 100644
index 0000000000..b01cf6ed84
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarInheritanceComponent.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+PropertyVarCircularComponent {
+ id: inheritanceComponent
+ property int inheritanceIntProperty: 6
+ property var inheritanceVarProperty
+
+ function constructGarbage() {
+ var retn = 1;
+ var component = Qt.createComponent("PropertyVarCircularComponent2.qml");
+ if (component.status == Component.Ready) {
+ retn = component.createObject(null); // has JavaScript ownership
+ }
+ return retn;
+ }
+
+ Component.onCompleted: {
+ inheritanceVarProperty = constructGarbage();
+ gc();
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarOwnershipComponent.qml b/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarOwnershipComponent.qml
new file mode 100644
index 0000000000..c1f73d3bac
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/PropertyVarOwnershipComponent.qml
@@ -0,0 +1,37 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: rectangle // will have JS ownership
+ objectName: "rectangle"
+ width: 10
+ height: 10
+ property var rectCanary: 5
+
+ Text {
+ id: textOne // will have Eventual-JS ownership
+ objectName: "textOne"
+ property var textCanary: 11
+ property var vp
+ }
+
+ Text {
+ id: textTwo
+ objectName: "textTwo"
+ property var textCanary: 12
+ property var vp
+
+ function constructQObject() {
+ var component = Qt.createComponent("PropertyVarCircularComponent5.qml");
+ if (component.status == Component.Ready) {
+ textTwo.vp = component.createObject(null); // has JavaScript ownership
+ }
+ gc();
+ }
+
+ function deassignVp() {
+ textTwo.textCanary = 22;
+ textTwo.vp = textTwo.textCanary;
+ gc();
+ }
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/doubleEvaluate.qml b/tests/auto/declarative/qdeclarativeecmascript/data/doubleEvaluate.qml
new file mode 100644
index 0000000000..0532715432
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/doubleEvaluate.qml
@@ -0,0 +1,6 @@
+import Qt.test 1.0
+
+WriteCounter {
+ property int x: 0
+ value: if (1) x + x
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreationOwnership.qml b/tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreationOwnership.qml
new file mode 100644
index 0000000000..ed396d49b0
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/dynamicCreationOwnership.qml
@@ -0,0 +1,20 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ id: obj
+ objectName: "obj"
+
+ MyDynamicCreationDestructionObject {
+ id: mdcdo
+ objectName: "mdcdo"
+ }
+
+ function dynamicallyCreateJsOwnedObject() {
+ mdcdo.createNew();
+ }
+
+ function performGc() {
+ gc();
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.handle.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.handle.1.qml
index 9c27653b34..8a06c30d8c 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.handle.1.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.handle.1.qml
@@ -18,8 +18,4 @@ Item {
// NOTE: manually add reference from first to second
// in unit test prior reparenting and gc.
}
-
- function performGc() {
- gc();
- }
}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.handle.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.handle.2.qml
index dc196263b4..91edc447e2 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.handle.2.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.handle.2.qml
@@ -19,8 +19,4 @@ Item {
// note: must manually reparent in unit test
// after setting the handle references.
}
-
- function performGc() {
- gc();
- }
}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.object.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.object.1.qml
index 4fd1311c29..70e8390677 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.object.1.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.object.1.qml
@@ -24,8 +24,4 @@ Item {
first = cro;
second = cro;
}
-
- function performGc() {
- gc();
- }
}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.object.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.object.2.qml
index 3f8415ce0f..2ddb9253eb 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.object.2.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/handleReferenceManagement.object.2.qml
@@ -25,8 +25,4 @@ Item {
first = cro;
second = cro;
}
-
- function performGc() {
- gc();
- }
}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/jsimport/importPragmaLibraryWithImports.js b/tests/auto/declarative/qdeclarativeecmascript/data/jsimport/importPragmaLibraryWithImports.js
new file mode 100644
index 0000000000..3f2e6589dd
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/jsimport/importPragmaLibraryWithImports.js
@@ -0,0 +1,9 @@
+.pragma library
+.import "importFive.js" as ImportFive
+
+var i = 4;
+
+function importIncrementedValue() {
+ i = i + 1;
+ return (i + ImportFive.importFiveFunction()); // i + '5' (not i+5)
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/jsimport/importPragmaLibraryWithPragmaLibraryImports.js b/tests/auto/declarative/qdeclarativeecmascript/data/jsimport/importPragmaLibraryWithPragmaLibraryImports.js
new file mode 100644
index 0000000000..fa6497d99b
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/jsimport/importPragmaLibraryWithPragmaLibraryImports.js
@@ -0,0 +1,11 @@
+.pragma library
+.import "importPragmaLibrary.js" as LibraryImport
+
+var i = 10;
+
+function importIncrementedValue() {
+ i = i + 1;
+ // because LibraryImport is shared, and used in previous tests,
+ // the value will be large (already incremented a bunch of times).
+ return (i + LibraryImport.importIncrementedValue());
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/jsimport/testImportPragmaLibraryWithImports.qml b/tests/auto/declarative/qdeclarativeecmascript/data/jsimport/testImportPragmaLibraryWithImports.qml
new file mode 100644
index 0000000000..6a7459d3bb
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/jsimport/testImportPragmaLibraryWithImports.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.0
+import "importPragmaLibraryWithImports.js" as LibraryImport
+
+QtObject {
+ id: root
+ property int testValue: LibraryImport.importIncrementedValue(); // valueOf(4 + 1 + '5') = valueOf('55') = 55
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/jsimport/testImportPragmaLibraryWithPragmaLibraryImports.qml b/tests/auto/declarative/qdeclarativeecmascript/data/jsimport/testImportPragmaLibraryWithPragmaLibraryImports.qml
new file mode 100644
index 0000000000..01f08dbdc3
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/jsimport/testImportPragmaLibraryWithPragmaLibraryImports.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.0
+import "importPragmaLibraryWithPragmaLibraryImports.js" as LibraryImport
+
+QtObject {
+ id: root
+ property int testValue: LibraryImport.importIncrementedValue(); // 10 + 1 + (7 due to previous tests) = 18
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/objectConversion.qml b/tests/auto/declarative/qdeclarativeecmascript/data/objectConversion.qml
new file mode 100644
index 0000000000..67fc342db3
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/objectConversion.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 360
+ height: 360
+
+ function circularObject() {
+ var a = {}
+ var b = {}
+
+ a.test = 100;
+ a.c = b;
+ b.c = a;
+ return a;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.1.qml
new file mode 100644
index 0000000000..219e61bf91
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.1.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+ property bool test: false
+
+ property var car: new vehicle(4);
+ property int wheelCount: car.wheels
+
+ function vehicle(wheels) {
+ this.wheels = wheels;
+ }
+
+ Component.onCompleted: {
+ car.wheels = 6; // not bindable, wheelCount shouldn't update
+
+ if (car.wheels != 6) return;
+ if (wheelCount != 4) return;
+
+ test = true;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.2.qml
new file mode 100644
index 0000000000..2ac4807ec5
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.2.qml
@@ -0,0 +1,24 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+ property bool test: false
+
+ property var truck: new vehicle(8);
+ property int wheelCount: truck.wheels
+
+ function vehicle(wheels) {
+ this.wheels = wheels;
+ }
+
+ Component.onCompleted: {
+ if (wheelCount != 8) return;
+
+ // not bindable, but wheelCount will update because truck itself changed.
+ truck = new vehicle(12);
+
+ if (wheelCount != 12) return;
+
+ test = true;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.3.qml
new file mode 100644
index 0000000000..cf6a651639
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.3.qml
@@ -0,0 +1,19 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+ property bool test: false
+
+ property var jsint: 4
+ property int bound: jsint + 5
+
+ Component.onCompleted: {
+ if (bound != 9) return;
+
+ jsint = jsint + 1;
+
+ if (bound != 10) return;
+
+ test = true;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.4.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.4.qml
new file mode 100644
index 0000000000..82fc225e71
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.4.qml
@@ -0,0 +1,18 @@
+import QtQuick 2.0
+
+Item {
+ property bool test: false
+
+ property var items: [1, 2, 3, "four", "five"]
+ property int bound: items[0]
+
+ Component.onCompleted: {
+ if (bound != 1) return;
+
+ items[0] = 10 // bound should remain 1
+
+ if (bound != 1) return;
+
+ test = true;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.5.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.5.qml
new file mode 100644
index 0000000000..a5c7812289
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.5.qml
@@ -0,0 +1,18 @@
+import QtQuick 2.0
+
+Item {
+ property bool test: false
+
+ property var attributes: { 'color': 'red', 'width': 100 }
+ property int bound: attributes.width
+
+ Component.onCompleted: {
+ if (bound != 100) return;
+
+ attributes.width = 200 // bound should remain 100
+
+ if (bound != 100) return;
+
+ test = true;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.6.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.6.qml
new file mode 100644
index 0000000000..5197aeada7
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.6.qml
@@ -0,0 +1,18 @@
+import QtQuick 2.0
+
+Item {
+ property bool test: false
+
+ property var items: [1, 2, 3, "four", "five"]
+ property int bound: items[0]
+
+ Component.onCompleted: {
+ if (bound != 1) return false;
+
+ items = [10, 2, 3, "four", "five"] // bound should now be 10
+
+ if (bound != 10) return false;
+
+ test = true;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.7.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.7.qml
new file mode 100644
index 0000000000..1d6c8c0a37
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.7.qml
@@ -0,0 +1,18 @@
+import QtQuick 2.0
+
+Item {
+ property bool test: false
+
+ property var attributes: { 'color': 'red', 'width': 100 }
+ property int bound: attributes.width
+
+ Component.onCompleted: {
+ if (bound != 100) return;
+
+ attributes = { 'color': 'blue', 'width': 200 } // bound should now be 200
+
+ if (bound != 200) return;
+
+ test = true;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.8.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.8.qml
new file mode 100644
index 0000000000..a9f73db402
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.8.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.0
+
+Item {
+ property bool test: false
+
+ property var literalValue: 6
+
+ Component.onCompleted: {
+ if (literalValue != 6) return;
+ test = true;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.9.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.9.qml
new file mode 100644
index 0000000000..f5aca28417
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.9.qml
@@ -0,0 +1,19 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ property bool test: false
+
+ MyQmlObject {
+ id: qmlobject
+ intProperty: 5
+ }
+ property var qobjectVar: qmlobject
+ property int bound: qobjectVar.intProperty
+
+ Component.onCompleted: {
+ if (bound != 5) return;
+
+ test = true;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.circular.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.circular.2.qml
new file mode 100644
index 0000000000..93c44afcc9
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.circular.2.qml
@@ -0,0 +1,26 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+ objectName: "separateRootObject"
+ property var vp
+
+ function constructGarbage() {
+ var retn = 1;
+ var component = Qt.createComponent("PropertyVarCircularComponent3.qml");
+ if (component.status == Component.Ready) {
+ retn = component.createObject(null); // has JavaScript ownership
+ }
+ return retn;
+ }
+
+ function assignCircular() {
+ vp = constructGarbage();
+ gc();
+ }
+
+ function deassignCircular() {
+ vp = 2;
+ gc();
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.circular.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.circular.qml
new file mode 100644
index 0000000000..171d7747cd
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.circular.qml
@@ -0,0 +1,44 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ id: testCircular
+
+ property var varProperty
+ property variant canaryResource
+ property int canaryInt
+
+ function constructGarbage() {
+ var retn = 1;
+ var component = Qt.createComponent("PropertyVarCircularComponent.qml");
+ if (component.status == Component.Ready) {
+ retn = component.createObject(null); // has JavaScript ownership
+ }
+ return retn;
+ }
+
+ function deassignCanaryResource() {
+ canaryResource = 1;
+ gc();
+ }
+
+ function assignCircular() {
+ varProperty = constructGarbage();
+ canaryResource = varProperty.vp.vp.vp.vp.memoryHog;
+ canaryInt = varProperty.vp.vp.vp.vp.fifthCanary; // == 5
+ gc();
+ }
+
+ function deassignCircular() {
+ canaryInt = 2;
+ varProperty = 2;
+ gc();
+ }
+
+ function assignThenDeassign() {
+ varProperty = constructGarbage();
+ varProperty = 2;
+ gc();
+ }
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.inherit.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.inherit.qml
new file mode 100644
index 0000000000..abd0dd7c04
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.inherit.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ id: testInheritance
+
+ property var varProperty
+
+ function constructGarbage() {
+ var retn = 1;
+ var component = Qt.createComponent("PropertyVarInheritanceComponent.qml");
+ if (component.status == Component.Ready) {
+ retn = component.createObject(null); // has JavaScript ownership
+ }
+ return retn;
+ }
+
+ function assignCircular() {
+ varProperty = constructGarbage();
+ gc();
+ }
+
+ function deassignCircular() {
+ varProperty = 2;
+ gc();
+ }
+
+ function assignThenDeassign() {
+ varProperty = constructGarbage();
+ varProperty = 2;
+ gc();
+ }
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.reparent.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.reparent.qml
new file mode 100644
index 0000000000..7b3df674f1
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVar.reparent.qml
@@ -0,0 +1,27 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+ objectName: "separateRootObject"
+ property var vp
+
+ function constructGarbage() {
+ var retn = 1;
+ var component = Qt.createComponent("PropertyVarOwnershipComponent.qml");
+ if (component.status == Component.Ready) {
+ retn = component.createObject(null); // has JavaScript ownership
+ }
+ return retn;
+ }
+
+ function assignVarProp() {
+ vp = constructGarbage();
+ gc();
+ }
+
+ function deassignVarProp() {
+ vp = 2;
+ gc();
+ }
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarCpp.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarCpp.qml
new file mode 100644
index 0000000000..cd3147f565
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarCpp.qml
@@ -0,0 +1,17 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ id: testOwnership
+ property int intProperty: 10
+ property var varProperty: intProperty
+ property var varProperty2: false
+ property var varBound: varProperty + 5
+ property int intBound: varProperty + 5
+ property var jsobject: new vehicle(4)
+
+ function vehicle(wheels) {
+ this.wheels = wheels;
+ }
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarImplicitOwnership.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarImplicitOwnership.qml
new file mode 100644
index 0000000000..9cebded932
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarImplicitOwnership.qml
@@ -0,0 +1,26 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+ objectName: "separateRootObject"
+ property var vp
+
+ function constructGarbage() {
+ var retn = 1;
+ var component = Qt.createComponent("PropertyVarCircularComponent4.qml");
+ if (component.status == Component.Ready) {
+ retn = component.createObject(null); // has JavaScript ownership
+ }
+ return retn;
+ }
+
+ function assignCircular() {
+ vp = constructGarbage();
+ gc();
+ }
+
+ function deassignCircular() {
+ vp = 2;
+ gc();
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.2.qml
new file mode 100644
index 0000000000..14d4f9fd27
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.2.qml
@@ -0,0 +1,24 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ id: testOwnership
+ property bool test: false
+
+ property int dummyProperty // Tests for non-interference of other properties
+ property var varProperty
+
+ function runTest() {
+ if (varProperty != undefined) return;
+ varProperty = { a: 10, b: 11 }
+ if (varProperty.a != 10) return;
+
+ gc(); // Shouldn't collect
+
+ if (varProperty.a != 10) return;
+
+ test = true;
+ }
+}
+
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.3.qml
new file mode 100644
index 0000000000..d5b449c938
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.3.qml
@@ -0,0 +1,31 @@
+import QtQuick 2.0
+
+Item {
+ property var object
+
+ property bool test1: false
+ property bool test2: false
+
+ // Test methods are executed in sequential order
+
+ function runTest() {
+ var c = Qt.createComponent("propertyVarOwnership.3.type.qml");
+ object = c.createObject();
+
+ if (object.dummy != 10) return;
+ test1 = true;
+ }
+
+ // Run gc() from C++
+
+ function runTest2() {
+ if (object.dummy != 10) return;
+
+ object = undefined;
+ if (object != undefined) return;
+
+ test2 = true;
+ }
+
+ // Run gc() from C++ - QObject should be collected
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.3.type.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.3.type.qml
new file mode 100644
index 0000000000..3406553b91
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.3.type.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+QtObject {
+ property int dummy: 10
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.4.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.4.qml
new file mode 100644
index 0000000000..1eba36ce81
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.4.qml
@@ -0,0 +1,25 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+
+ property var object
+
+ property bool test: false
+
+ Component.onCompleted: {
+ var c = Qt.createComponent("propertyVarOwnership.4.type1.qml");
+ object = c.createObject();
+
+ if (object.dummy != 10) return;
+ if (object.test != true) return;
+
+ object.creatorRef = root;
+
+ test = true;
+ }
+
+ function runTest() {
+ object = null;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.4.type1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.4.type1.qml
new file mode 100644
index 0000000000..9a29b6e17f
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.4.type1.qml
@@ -0,0 +1,23 @@
+import QtQuick 2.0
+
+// Has a self reference in selfRef, and a reference to propertyVarOwnership.4.qml in creatorRef
+Item {
+ id: root
+
+ property var creatorRef
+ property var selfRef
+ property var object
+
+ property int dummy: 10
+ property bool test: false
+
+ Component.onCompleted: {
+ selfRef = root;
+
+ var c = Qt.createComponent("propertyVarOwnership.4.type2.qml");
+ object = c.createObject();
+ object.creatorRef = root;
+
+ test = true;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.4.type2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.4.type2.qml
new file mode 100644
index 0000000000..f82b8a1c1e
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.4.type2.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+
+// Has a reference to propertyVarOwnership.4.type1.qml in creatorRef
+Item {
+ property var creatorRef
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.qml b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.qml
new file mode 100644
index 0000000000..7b99c4b6ad
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/propertyVarOwnership.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ id: testOwnership
+ property bool test: false
+
+ property var varProperty
+
+ function runTest() {
+ if (varProperty != undefined) return;
+ varProperty = { a: 10, b: 11 }
+ if (varProperty.a != 10) return;
+
+ gc(); // Shouldn't collect
+
+ if (varProperty.a != 10) return;
+
+ test = true;
+ }
+}
+
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/stringArg.qml b/tests/auto/declarative/qdeclarativeecmascript/data/stringArg.qml
new file mode 100644
index 0000000000..7019af9da5
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/stringArg.qml
@@ -0,0 +1,49 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+ property bool returnValue: false
+
+ property string first
+ property string second
+ property string third
+ property string fourth
+ property string fifth
+ property string sixth
+ property string seventh
+ property string eighth
+ property string ninth
+
+ function success() {
+ var a = "Value is %1";
+ for (var ii = 0; ii < 10; ++ii) {
+ first = a.arg("string");
+ second = a.arg(1);
+ third = a.arg(true);
+ fourth = a.arg(3.345);
+ fifth = a.arg(undefined);
+ sixth = a.arg(null);
+ seventh = a.arg({"test":5});
+ eighth = a.arg({"test":5, "again":6});
+ }
+
+ if (first != "Value is string") returnValue = false;
+ if (second != "Value is 1") returnValue = false;
+ if (third != "Value is true") returnValue = false;
+ if (fourth != "Value is 3.345") returnValue = false;
+ if (fifth != "Value is undefined") returnValue = false;
+ if (sixth != "Value is null") returnValue = false;
+ if (seventh != "Value is [Object object]") returnValue = false;
+ if (eighth != "Value is [Object object]") returnValue = false;
+ returnValue = true;
+ }
+
+ function failure() {
+ returnValue = true;
+ var a = "Value is %1";
+ for (var ii = 0; ii < 10; ++ii) {
+ ninth = a.arg(1,2,3,4);
+ }
+ returnValue = false;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro b/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro
index 981cad5036..7fde5390bf 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro
+++ b/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro
@@ -1,5 +1,5 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative network widgets
+CONFIG += testcase
+TARGET = tst_qdeclarativeecmascript
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativeecmascript.cpp \
@@ -12,15 +12,11 @@ INCLUDEPATH += ../shared
# QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage
# LIBS += -lgcov
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
#temporary
CONFIG += insignificant_test
-QT += core-private gui-private v8-private declarative-private
+QT += core-private gui-private v8-private declarative-private network widgets testlib
diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp
index 0057c117fa..513705d697 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp
+++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp
@@ -164,6 +164,7 @@ void registerTypes()
qmlRegisterType<MyRevisionedClass,1>("Qt.test",1,1,"MyRevisionedClass");
// test scarce resource property binding post-evaluation optimisation
+ // and for testing memory usage in property var circular reference test
qmlRegisterType<ScarceResourceObject>("Qt.test", 1,0, "MyScarceResourceObject");
// Register the uncreatable base class
@@ -192,6 +193,9 @@ void registerTypes()
qmlRegisterType<CircularReferenceObject>("Qt.test", 1, 0, "CircularReferenceObject");
qmlRegisterType<CircularReferenceHandle>("Qt.test", 1, 0, "CircularReferenceHandle");
+
+ qmlRegisterType<MyDynamicCreationDestructionObject>("Qt.test", 1, 0, "MyDynamicCreationDestructionObject");
+ qmlRegisterType<WriteCounter>("Qt.test", 1, 0, "WriteCounter");
}
#include "testtypes.moc"
diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
index ebe8cc59b7..7684ddd438 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
+++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h
@@ -98,9 +98,10 @@ class MyQmlObject : public QObject
Q_PROPERTY(int resettableProperty READ resettableProperty WRITE setResettableProperty RESET resetProperty)
Q_PROPERTY(QRegExp regExp READ regExp WRITE setRegExp)
Q_PROPERTY(int nonscriptable READ nonscriptable WRITE setNonscriptable SCRIPTABLE false)
+ Q_PROPERTY(int intProperty READ intProperty WRITE setIntProperty NOTIFY intChanged)
public:
- MyQmlObject(): myinvokableObject(0), m_methodCalled(false), m_methodIntCalled(false), m_object(0), m_value(0), m_resetProperty(13) {}
+ MyQmlObject(): myinvokableObject(0), m_methodCalled(false), m_methodIntCalled(false), m_object(0), m_value(0), m_resetProperty(13), m_intProperty(0) {}
enum MyEnum { EnumValue1 = 0, EnumValue2 = 1 };
enum MyEnum2 { EnumValue3 = 2, EnumValue4 = 3 };
@@ -161,6 +162,9 @@ public:
int value;
};
QVariant variant() const { return m_variant; }
+
+ int intProperty() const { return m_intProperty; }
+ void setIntProperty(int i) { m_intProperty = i; emit intChanged(); }
signals:
void basicSignal();
@@ -171,6 +175,7 @@ signals:
void thirdBasicSignal();
void signalWithUnknownType(const MyQmlObject::MyType &arg);
void signalWithVariant(const QVariant &arg);
+ void intChanged();
public slots:
void deleteMe() { delete this; }
@@ -192,6 +197,7 @@ private:
int m_resetProperty;
QRegExp m_regExp;
QVariant m_variant;
+ int m_intProperty;
};
QML_DECLARE_TYPEINFO(MyQmlObject, QML_HAS_ATTACHED_PROPERTIES)
@@ -928,12 +934,24 @@ public:
bool scarceResourceIsDetached() const { return m_value.isDetached(); }
+ // this particular one returns a new one each time
+ // this means that every Scarce Resource Copy will
+ // consume resources (so that we can track disposal
+ // of v8 handles with circular references).
+ Q_INVOKABLE QPixmap newScarceResource() const
+ {
+ QPixmap retn(800, 600);
+ retn.fill(QColor(100, 110, 120, 45));
+ return retn;
+ }
+
signals:
void scarceResourceChanged();
private:
QPixmap m_value;
};
+QML_DECLARE_TYPE(ScarceResourceObject)
class testQObjectApi : public QObject
{
@@ -1072,6 +1090,64 @@ private:
};
Q_DECLARE_METATYPE(CircularReferenceHandle*)
+class MyDynamicCreationDestructionObject : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY (int intProperty READ intProperty WRITE setIntProperty NOTIFY intPropertyChanged)
+
+public:
+ MyDynamicCreationDestructionObject(QObject *parent = 0) : QObject(parent), m_intProperty(0), m_dtorCount(0)
+ {
+ }
+
+ ~MyDynamicCreationDestructionObject()
+ {
+ if (m_dtorCount) {
+ (*m_dtorCount)++;
+ }
+ }
+
+ int intProperty() const { return m_intProperty; }
+ void setIntProperty(int val) { m_intProperty = val; emit intPropertyChanged(); }
+
+ Q_INVOKABLE MyDynamicCreationDestructionObject *createNew()
+ {
+ // no parent == ownership transfers to JS; same dtor counter.
+ MyDynamicCreationDestructionObject *retn = new MyDynamicCreationDestructionObject;
+ retn->setDtorCount(m_dtorCount);
+ return retn;
+ }
+
+ void setDtorCount(int *dtorCount)
+ {
+ m_dtorCount = dtorCount;
+ }
+
+signals:
+ void intPropertyChanged();
+
+private:
+ int m_intProperty;
+ int *m_dtorCount;
+};
+
+class WriteCounter : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int value READ value WRITE setValue);
+public:
+ WriteCounter() : m_value(0), m_count(0) {}
+
+ int value() const { return m_value; }
+ void setValue(int v) { m_value = v; ++m_count; }
+
+ int count() const { return m_count; }
+
+private:
+ int m_value;
+ int m_count;
+};
+
void registerTypes();
#endif // TESTTYPES_H
diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
index 941765d50c..40072c9e60 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
+++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
@@ -38,7 +38,7 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include <qtest.h>
+#include <QtTest/QtTest>
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtDeclarative/qdeclarativeexpression.h>
@@ -49,14 +49,11 @@
#include <QtCore/qdir.h>
#include <QtCore/qnumeric.h>
#include <private/qdeclarativeengine_p.h>
+#include <private/qv8gccallback_p.h>
+#include <private/qdeclarativevmemetaobject_p.h>
#include "testtypes.h"
#include "testhttpserver.h"
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
/*
This test covers evaluation of ECMAScript expressions and bindings from within
@@ -66,8 +63,7 @@ Static QML language issues are covered in qmllanguage
*/
inline QUrl TEST_FILE(const QString &filename)
{
- QFileInfo fileInfo(__FILE__);
- return QUrl::fromLocalFile(fileInfo.absoluteDir().filePath("data/" + filename));
+ return QUrl::fromLocalFile(TESTDATA(filename));
}
inline QUrl TEST_FILE(const char *filename)
@@ -152,17 +148,32 @@ private slots:
void signalWithJSValueInVariant_twoEngines();
void moduleApi_data();
void moduleApi();
+ void importScripts_data();
void importScripts();
void scarceResources();
void propertyChangeSlots();
+ void propertyVar_data();
+ void propertyVar();
+ void propertyVarCpp();
+ void propertyVarOwnership();
+ void propertyVarImplicitOwnership();
+ void propertyVarReparent();
+ void propertyVarReparentNullContext();
+ void propertyVarCircular();
+ void propertyVarCircular2();
+ void propertyVarInheritance();
+ void propertyVarInheritance2();
void elementAssign();
void objectPassThroughSignals();
+ void objectConversion();
void booleanConversion();
void handleReferenceManagement();
+ void stringArg();
void bug1();
void bug2();
void dynamicCreationCrash();
+ void dynamicCreationOwnership();
void regExpBug();
void nullObjectBinding();
void deletedEngine();
@@ -195,6 +206,7 @@ private slots:
void dynamicString();
void include();
void signalHandlers();
+ void doubleEvaluate();
void callQtInvokables();
void invokableObjectArg();
@@ -206,6 +218,7 @@ private slots:
void automaticSemicolon();
private:
+ static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
QDeclarativeEngine engine;
};
@@ -391,7 +404,7 @@ void tst_qdeclarativeecmascript::methods()
void tst_qdeclarativeecmascript::bindingLoop()
{
QDeclarativeComponent component(&engine, TEST_FILE("bindingLoop.qml"));
- QString warning = component.url().toString() + ":9:9: QML MyQmlObject: Binding loop detected for property \"stringProperty\"";
+ QString warning = component.url().toString() + ":5:9: QML MyQmlObject: Binding loop detected for property \"stringProperty\"";
QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData());
QObject *object = component.create();
QVERIFY(object != 0);
@@ -630,7 +643,7 @@ void tst_qdeclarativeecmascript::deferredPropertiesErrors()
QVERIFY(object->objectProperty() == 0);
QVERIFY(object->objectProperty2() == 0);
- QString warning = component.url().toString() + ":6: Unable to assign [undefined] to QObject* objectProperty";
+ QString warning = component.url().toString() + ":6: Unable to assign [undefined] to QObject*";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
qmlExecuteDeferred(object);
@@ -741,8 +754,8 @@ void tst_qdeclarativeecmascript::enums()
{
QDeclarativeComponent component(&engine, TEST_FILE("enums.2.qml"));
- QString warning1 = component.url().toString() + ":5: Unable to assign [undefined] to int a";
- QString warning2 = component.url().toString() + ":6: Unable to assign [undefined] to int b";
+ QString warning1 = component.url().toString() + ":5: Unable to assign [undefined] to int";
+ QString warning2 = component.url().toString() + ":6: Unable to assign [undefined] to int";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -880,7 +893,7 @@ void tst_qdeclarativeecmascript::nonExistentAttachedObject()
{
QDeclarativeComponent component(&engine, TEST_FILE("nonExistentAttachedObject.qml"));
- QString warning = component.url().toString() + ":4: Unable to assign [undefined] to QString stringProperty";
+ QString warning = component.url().toString() + ":4: Unable to assign [undefined] to QString";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
QObject *object = component.create();
@@ -1336,7 +1349,7 @@ void tst_qdeclarativeecmascript::scriptErrors()
QString warning3 = url.left(url.length() - 3) + "js:4: Error: Invalid write to global property \"a\"";
QString warning4 = url + ":10: ReferenceError: Can't find variable: a";
QString warning5 = url + ":8: ReferenceError: Can't find variable: a";
- QString warning6 = url + ":7: Unable to assign [undefined] to int x";
+ QString warning6 = url + ":7: Unable to assign [undefined] to int";
QString warning7 = url + ":12: Error: Cannot assign to read-only property \"trueProperty\"";
QString warning8 = url + ":13: Error: Cannot assign to non-existent property \"fakeProperty\"";
@@ -1663,6 +1676,40 @@ void tst_qdeclarativeecmascript::dynamicCreationCrash()
delete object;
}
+// ownership transferred to JS, ensure that GC runs the dtor
+void tst_qdeclarativeecmascript::dynamicCreationOwnership()
+{
+ int dtorCount = 0;
+ int expectedDtorCount = 1; // start at 1 since we expect mdcdo to dtor too.
+
+ // allow the engine to go out of scope too.
+ {
+ QDeclarativeEngine dcoEngine;
+ QDeclarativeComponent component(&dcoEngine, TEST_FILE("dynamicCreationOwnership.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ MyDynamicCreationDestructionObject *mdcdo = object->findChild<MyDynamicCreationDestructionObject*>("mdcdo");
+ QVERIFY(mdcdo != 0);
+ mdcdo->setDtorCount(&dtorCount);
+
+ for (int i = 1; i < 105; ++i, ++expectedDtorCount) {
+ QMetaObject::invokeMethod(object, "dynamicallyCreateJsOwnedObject");
+ if (i % 90 == 0) {
+ // we do this once manually, but it should be done automatically
+ // when the engine goes out of scope (since it should gc in dtor)
+ QMetaObject::invokeMethod(object, "performGc");
+ }
+ if (i % 10 == 0) {
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+ }
+ }
+
+ delete object;
+ }
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+ QCOMPARE(dtorCount, expectedDtorCount);
+}
+
//QTBUG-9367
void tst_qdeclarativeecmascript::regExpBug()
{
@@ -2982,78 +3029,125 @@ void tst_qdeclarativeecmascript::moduleApi()
}
}
-void tst_qdeclarativeecmascript::importScripts()
+void tst_qdeclarativeecmascript::importScripts_data()
{
- QObject *object = 0;
+ QTest::addColumn<QUrl>("testfile");
+ QTest::addColumn<QString>("errorMessage");
+ QTest::addColumn<QStringList>("warningMessages");
+ QTest::addColumn<QStringList>("propertyNames");
+ QTest::addColumn<QVariantList>("propertyValues");
- // first, ensure that the required behaviour works.
- QDeclarativeComponent component(&engine, TEST_FILE("jsimport/testImport.qml"));
- object = component.create();
- QVERIFY(object != 0);
- QCOMPARE(object->property("importedScriptStringValue"), QVariant(QString(QLatin1String("Hello, World!"))));
- QCOMPARE(object->property("importedScriptFunctionValue"), QVariant(20));
- QCOMPARE(object->property("importedModuleAttachedPropertyValue"), QVariant(19));
- QCOMPARE(object->property("importedModuleEnumValue"), QVariant(2));
- delete object;
+ QTest::newRow("basic functionality")
+ << TEST_FILE("jsimport/testImport.qml")
+ << QString()
+ << QStringList()
+ << (QStringList() << QLatin1String("importedScriptStringValue")
+ << QLatin1String("importedScriptFunctionValue")
+ << QLatin1String("importedModuleAttachedPropertyValue")
+ << QLatin1String("importedModuleEnumValue"))
+ << (QVariantList() << QVariant(QLatin1String("Hello, World!"))
+ << QVariant(20)
+ << QVariant(19)
+ << QVariant(2));
+
+ QTest::newRow("import scoping")
+ << TEST_FILE("jsimport/testImportScoping.qml")
+ << QString()
+ << QStringList()
+ << (QStringList() << QLatin1String("componentError"))
+ << (QVariantList() << QVariant(5));
- QDeclarativeComponent componentTwo(&engine, TEST_FILE("jsimport/testImportScoping.qml"));
- object = componentTwo.create();
- QVERIFY(object != 0);
- QCOMPARE(object->property("componentError"), QVariant(5));
- delete object;
+ QTest::newRow("parent scope shouldn't be inherited by import with imports")
+ << TEST_FILE("jsimportfail/failOne.qml")
+ << QString()
+ << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("jsimportfail/failOne.qml").toLocalFile() + QLatin1String(":6: TypeError: Cannot call method 'greetingString' of undefined")))
+ << (QStringList() << QLatin1String("importScriptFunctionValue"))
+ << (QVariantList() << QVariant(QString()));
- // then, ensure that unintended behaviour does not work.
- QDeclarativeComponent failOneComponent(&engine, TEST_FILE("jsimportfail/failOne.qml"));
- QString expectedWarning = QLatin1String("file://") + TEST_FILE("jsimportfail/failOne.qml").toLocalFile() + QLatin1String(":6: TypeError: Cannot call method 'greetingString' of undefined");
- QTest::ignoreMessage(QtWarningMsg, expectedWarning.toAscii().constData());
- object = failOneComponent.create();
- QVERIFY(object != 0);
- QVERIFY(object->property("importScriptFunctionValue").toString().isEmpty());
- delete object;
- QDeclarativeComponent failTwoComponent(&engine, TEST_FILE("jsimportfail/failTwo.qml"));
- expectedWarning = QLatin1String("file://") + TEST_FILE("jsimportfail/failTwo.qml").toLocalFile() + QLatin1String(":6: ReferenceError: Can't find variable: ImportOneJs");
- QTest::ignoreMessage(QtWarningMsg, expectedWarning.toAscii().constData());
- object = failTwoComponent.create();
- QVERIFY(object != 0);
- QVERIFY(object->property("importScriptFunctionValue").toString().isEmpty());
- delete object;
- QDeclarativeComponent failThreeComponent(&engine, TEST_FILE("jsimportfail/failThree.qml"));
- expectedWarning = QLatin1String("file://") + TEST_FILE("jsimportfail/failThree.qml").toLocalFile() + QLatin1String(":7: TypeError: Cannot read property 'JsQtTest' of undefined");
- QTest::ignoreMessage(QtWarningMsg, expectedWarning.toAscii().constData());
- object = failThreeComponent.create();
- QVERIFY(object != 0);
- QCOMPARE(object->property("importedModuleAttachedPropertyValue"), QVariant(false));
- delete object;
- QDeclarativeComponent failFourComponent(&engine, TEST_FILE("jsimportfail/failFour.qml"));
- expectedWarning = QLatin1String("file://") + TEST_FILE("jsimportfail/failFour.qml").toLocalFile() + QLatin1String(":6: ReferenceError: Can't find variable: JsQtTest");
- QTest::ignoreMessage(QtWarningMsg, expectedWarning.toAscii().constData());
- object = failFourComponent.create();
- QVERIFY(object != 0);
- QCOMPARE(object->property("importedModuleEnumValue"), QVariant(0));
- delete object;
- QDeclarativeComponent failFiveComponent(&engine, TEST_FILE("jsimportfail/failFive.qml"));
- expectedWarning = QLatin1String("file://") + TEST_FILE("jsimportfail/importWithImports.js").toLocalFile() + QLatin1String(":8: ReferenceError: Can't find variable: Component");
- QTest::ignoreMessage(QtWarningMsg, expectedWarning.toAscii().constData());
- expectedWarning = QLatin1String("file://") + TEST_FILE("jsimportfail/importPragmaLibrary.js").toLocalFile() + QLatin1String(":6: ReferenceError: Can't find variable: Component");
- QTest::ignoreMessage(QtWarningMsg, expectedWarning.toAscii().constData());
- object = failFiveComponent.create();
- QVERIFY(object != 0);
- QCOMPARE(object->property("componentError"), QVariant(0));
- delete object;
+ QTest::newRow("javascript imports in an import should be private to the import scope")
+ << TEST_FILE("jsimportfail/failTwo.qml")
+ << QString()
+ << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("jsimportfail/failTwo.qml").toLocalFile() + QLatin1String(":6: ReferenceError: Can't find variable: ImportOneJs")))
+ << (QStringList() << QLatin1String("importScriptFunctionValue"))
+ << (QVariantList() << QVariant(QString()));
- // also, test that importing scripts with .pragma library works as required
- QDeclarativeComponent pragmaLibraryComponent(&engine, TEST_FILE("jsimport/testImportPragmaLibrary.qml"));
- object = pragmaLibraryComponent.create();
- QVERIFY(object != 0);
- QCOMPARE(object->property("testValue"), QVariant(31));
- delete object;
+ QTest::newRow("module imports in an import should be private to the import scope")
+ << TEST_FILE("jsimportfail/failThree.qml")
+ << QString()
+ << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("jsimportfail/failThree.qml").toLocalFile() + QLatin1String(":7: TypeError: Cannot read property 'JsQtTest' of undefined")))
+ << (QStringList() << QLatin1String("importedModuleAttachedPropertyValue"))
+ << (QVariantList() << QVariant(false));
- // and that .pragma library scripts don't inherit imports from any .qml file
- QDeclarativeComponent pragmaLibraryComponentTwo(&engine, TEST_FILE("jsimportfail/testImportPragmaLibrary.qml"));
- object = pragmaLibraryComponentTwo.create();
- QVERIFY(object != 0);
- QCOMPARE(object->property("testValue"), QVariant(0));
- delete object;
+ QTest::newRow("typenames in an import should be private to the import scope")
+ << TEST_FILE("jsimportfail/failFour.qml")
+ << QString()
+ << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("jsimportfail/failFour.qml").toLocalFile() + QLatin1String(":6: ReferenceError: Can't find variable: JsQtTest")))
+ << (QStringList() << QLatin1String("importedModuleEnumValue"))
+ << (QVariantList() << QVariant(0));
+
+ QTest::newRow("import with imports has it's own activation scope")
+ << TEST_FILE("jsimportfail/failFive.qml")
+ << QString()
+ << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("jsimportfail/importWithImports.js").toLocalFile() + QLatin1String(":8: ReferenceError: Can't find variable: Component"))
+ << QString(QLatin1String("file://") + TEST_FILE("jsimportfail/importPragmaLibrary.js").toLocalFile() + QLatin1String(":6: ReferenceError: Can't find variable: Component")))
+ << (QStringList() << QLatin1String("componentError"))
+ << (QVariantList() << QVariant(0));
+
+ QTest::newRow("import pragma library script")
+ << TEST_FILE("jsimport/testImportPragmaLibrary.qml")
+ << QString()
+ << QStringList()
+ << (QStringList() << QLatin1String("testValue"))
+ << (QVariantList() << QVariant(31));
+
+ QTest::newRow("pragma library imports shouldn't inherit parent imports or scope")
+ << TEST_FILE("jsimportfail/testImportPragmaLibrary.qml")
+ << QString()
+ << QStringList()
+ << (QStringList() << QLatin1String("testValue"))
+ << (QVariantList() << QVariant(0));
+
+ QTest::newRow("import pragma library script which has an import")
+ << TEST_FILE("jsimport/testImportPragmaLibraryWithImports.qml")
+ << QString()
+ << QStringList()
+ << (QStringList() << QLatin1String("testValue"))
+ << (QVariantList() << QVariant(55));
+
+ QTest::newRow("import pragma library script which has a pragma library import")
+ << TEST_FILE("jsimport/testImportPragmaLibraryWithPragmaLibraryImports.qml")
+ << QString()
+ << QStringList()
+ << (QStringList() << QLatin1String("testValue"))
+ << (QVariantList() << QVariant(18));
+}
+
+void tst_qdeclarativeecmascript::importScripts()
+{
+ QFETCH(QUrl, testfile);
+ QFETCH(QString, errorMessage);
+ QFETCH(QStringList, warningMessages);
+ QFETCH(QStringList, propertyNames);
+ QFETCH(QVariantList, propertyValues);
+
+ QDeclarativeComponent component(&engine, testfile);
+
+ if (!errorMessage.isEmpty())
+ QTest::ignoreMessage(QtWarningMsg, errorMessage.toAscii().constData());
+
+ if (warningMessages.size())
+ foreach (const QString &warning, warningMessages)
+ QTest::ignoreMessage(QtWarningMsg, warning.toAscii().constData());
+
+ QObject *object = component.create();
+ if (!errorMessage.isEmpty()) {
+ QVERIFY(object == 0);
+ } else {
+ QVERIFY(object != 0);
+ for (int i = 0; i < propertyNames.size(); ++i)
+ QCOMPARE(object->property(propertyNames.at(i).toAscii().constData()), propertyValues.at(i));
+ delete object;
+ }
}
void tst_qdeclarativeecmascript::scarceResources()
@@ -3257,6 +3351,370 @@ void tst_qdeclarativeecmascript::propertyChangeSlots()
delete object;
}
+void tst_qdeclarativeecmascript::propertyVar_data()
+{
+ QTest::addColumn<QUrl>("qmlFile");
+
+ // valid
+ QTest::newRow("non-bindable object subproperty changed") << TEST_FILE("propertyVar.1.qml");
+ QTest::newRow("non-bindable object changed") << TEST_FILE("propertyVar.2.qml");
+ QTest::newRow("primitive changed") << TEST_FILE("propertyVar.3.qml");
+ QTest::newRow("javascript array modification") << TEST_FILE("propertyVar.4.qml");
+ QTest::newRow("javascript map modification") << TEST_FILE("propertyVar.5.qml");
+ QTest::newRow("javascript array assignment") << TEST_FILE("propertyVar.6.qml");
+ QTest::newRow("javascript map assignment") << TEST_FILE("propertyVar.7.qml");
+ QTest::newRow("literal property assignment") << TEST_FILE("propertyVar.8.qml");
+ QTest::newRow("qobject property assignment") << TEST_FILE("propertyVar.9.qml");
+}
+
+void tst_qdeclarativeecmascript::propertyVar()
+{
+ QFETCH(QUrl, qmlFile);
+
+ QDeclarativeComponent component(&engine, qmlFile);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("test").toBool(), true);
+
+ delete object;
+}
+
+// Tests that we can write QVariant values to var properties from C++
+void tst_qdeclarativeecmascript::propertyVarCpp()
+{
+ QObject *object = 0;
+
+ // ensure that writing to and reading from a var property from cpp works as required.
+ // Literal values stored in var properties can be read and written as QVariants
+ // of a specific type, whereas object values are read as QVariantMaps.
+ QDeclarativeComponent component(&engine, TEST_FILE("propertyVarCpp.qml"));
+ object = component.create();
+ QVERIFY(object != 0);
+ // assign int to property var that currently has int assigned
+ QVERIFY(object->setProperty("varProperty", QVariant::fromValue(10)));
+ QCOMPARE(object->property("varBound"), QVariant(15));
+ QCOMPARE(object->property("intBound"), QVariant(15));
+ QCOMPARE(object->property("varProperty").userType(), (int)QVariant::Int);
+ QCOMPARE(object->property("varBound").userType(), (int)QVariant::Int);
+ // assign string to property var that current has bool assigned
+ QCOMPARE(object->property("varProperty2").userType(), (int)QVariant::Bool);
+ QVERIFY(object->setProperty("varProperty2", QVariant(QLatin1String("randomString"))));
+ QCOMPARE(object->property("varProperty2"), QVariant(QLatin1String("randomString")));
+ QCOMPARE(object->property("varProperty2").userType(), (int)QVariant::String);
+ // now enforce behaviour when accessing JavaScript objects from cpp.
+ QCOMPARE(object->property("jsobject").userType(), (int)QVariant::Map);
+ delete object;
+}
+
+static void gc(QDeclarativeEngine &engine)
+{
+ engine.collectGarbage();
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+}
+
+void tst_qdeclarativeecmascript::propertyVarOwnership()
+{
+ // Referenced JS objects are not collected
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("propertyVarOwnership.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QCOMPARE(object->property("test").toBool(), false);
+ QMetaObject::invokeMethod(object, "runTest");
+ QCOMPARE(object->property("test").toBool(), true);
+ delete object;
+ }
+ // Referenced JS objects are not collected
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("propertyVarOwnership.2.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QCOMPARE(object->property("test").toBool(), false);
+ QMetaObject::invokeMethod(object, "runTest");
+ QCOMPARE(object->property("test").toBool(), true);
+ delete object;
+ }
+ // Qt objects are not collected until they've been dereferenced
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("propertyVarOwnership.3.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("test2").toBool(), false);
+ QCOMPARE(object->property("test2").toBool(), false);
+
+ QMetaObject::invokeMethod(object, "runTest");
+ QCOMPARE(object->property("test1").toBool(), true);
+
+ QPointer<QObject> referencedObject = object->property("object").value<QObject*>();
+ QVERIFY(!referencedObject.isNull());
+ gc(engine);
+ QVERIFY(!referencedObject.isNull());
+
+ QMetaObject::invokeMethod(object, "runTest2");
+ QCOMPARE(object->property("test2").toBool(), true);
+ gc(engine);
+ QVERIFY(referencedObject.isNull());
+
+ delete object;
+ }
+ // Self reference does not prevent Qt object collection
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("propertyVarOwnership.4.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("test").toBool(), true);
+
+ QPointer<QObject> referencedObject = object->property("object").value<QObject*>();
+ QVERIFY(!referencedObject.isNull());
+ gc(engine);
+ QVERIFY(!referencedObject.isNull());
+
+ QMetaObject::invokeMethod(object, "runTest");
+ gc(engine);
+ QVERIFY(referencedObject.isNull());
+
+ delete object;
+ }
+}
+
+void tst_qdeclarativeecmascript::propertyVarImplicitOwnership()
+{
+ // The childObject has a reference to a different QObject. We want to ensure
+ // that the different item will not be cleaned up until required. IE, the childObject
+ // has implicit ownership of the constructed QObject.
+ QDeclarativeComponent component(&engine, TEST_FILE("propertyVarImplicitOwnership.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QMetaObject::invokeMethod(object, "assignCircular");
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+ QObject *rootObject = object->property("vp").value<QObject*>();
+ QVERIFY(rootObject != 0);
+ QObject *childObject = rootObject->findChild<QObject*>("text");
+ QVERIFY(childObject != 0);
+ QCOMPARE(rootObject->property("rectCanary").toInt(), 5);
+ QCOMPARE(childObject->property("textCanary").toInt(), 10);
+ QMetaObject::invokeMethod(childObject, "constructQObject"); // creates a reference to a constructed QObject.
+ QWeakPointer<QObject> qobjectGuard(childObject->property("vp").value<QObject*>()); // get the pointer prior to processing deleteLater events.
+ QVERIFY(!qobjectGuard.isNull());
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+ QVERIFY(!qobjectGuard.isNull());
+ QMetaObject::invokeMethod(object, "deassignCircular");
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+ QVERIFY(qobjectGuard.isNull()); // should have been collected now.
+ delete object;
+}
+
+void tst_qdeclarativeecmascript::propertyVarReparent()
+{
+ // ensure that nothing breaks if we re-parent objects
+ QDeclarativeComponent component(&engine, TEST_FILE("propertyVar.reparent.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QMetaObject::invokeMethod(object, "assignVarProp");
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+ QObject *rect = object->property("vp").value<QObject*>();
+ QObject *text = rect->findChild<QObject*>("textOne");
+ QObject *text2 = rect->findChild<QObject*>("textTwo");
+ QWeakPointer<QObject> rectGuard(rect);
+ QWeakPointer<QObject> textGuard(text);
+ QWeakPointer<QObject> text2Guard(text2);
+ QVERIFY(!rectGuard.isNull());
+ QVERIFY(!textGuard.isNull());
+ QVERIFY(!text2Guard.isNull());
+ QCOMPARE(text->property("textCanary").toInt(), 11);
+ QCOMPARE(text2->property("textCanary").toInt(), 12);
+ // now construct an image which we will reparent.
+ QMetaObject::invokeMethod(text2, "constructQObject");
+ QObject *image = text2->property("vp").value<QObject*>();
+ QWeakPointer<QObject> imageGuard(image);
+ QVERIFY(!imageGuard.isNull());
+ QCOMPARE(image->property("imageCanary").toInt(), 13);
+ // now reparent the "Image" object (currently, it has JS ownership)
+ image->setParent(text); // shouldn't be collected after deassignVp now, since has a parent.
+ QMetaObject::invokeMethod(text2, "deassignVp");
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+ QCOMPARE(text->property("textCanary").toInt(), 11);
+ QCOMPARE(text2->property("textCanary").toInt(), 22);
+ QVERIFY(!imageGuard.isNull()); // should still be alive.
+ QCOMPARE(image->property("imageCanary").toInt(), 13); // still able to access var properties
+ QMetaObject::invokeMethod(object, "deassignVarProp"); // now deassign the root-object's vp, causing gc of rect+text+text2
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+ QVERIFY(imageGuard.isNull()); // should now have been deleted, due to parent being deleted.
+ delete object;
+}
+
+void tst_qdeclarativeecmascript::propertyVarReparentNullContext()
+{
+ // sometimes reparenting can cause problems
+ // (eg, if the ctxt is collected, varproperties are no longer available)
+ // this test ensures that no crash occurs in that situation.
+ QDeclarativeComponent component(&engine, TEST_FILE("propertyVar.reparent.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QMetaObject::invokeMethod(object, "assignVarProp");
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+ QObject *rect = object->property("vp").value<QObject*>();
+ QObject *text = rect->findChild<QObject*>("textOne");
+ QObject *text2 = rect->findChild<QObject*>("textTwo");
+ QWeakPointer<QObject> rectGuard(rect);
+ QWeakPointer<QObject> textGuard(text);
+ QWeakPointer<QObject> text2Guard(text2);
+ QVERIFY(!rectGuard.isNull());
+ QVERIFY(!textGuard.isNull());
+ QVERIFY(!text2Guard.isNull());
+ QCOMPARE(text->property("textCanary").toInt(), 11);
+ QCOMPARE(text2->property("textCanary").toInt(), 12);
+ // now construct an image which we will reparent.
+ QMetaObject::invokeMethod(text2, "constructQObject");
+ QObject *image = text2->property("vp").value<QObject*>();
+ QWeakPointer<QObject> imageGuard(image);
+ QVERIFY(!imageGuard.isNull());
+ QCOMPARE(image->property("imageCanary").toInt(), 13);
+ // now reparent the "Image" object (currently, it has JS ownership)
+ image->setParent(object); // reparented to base object. after deassignVarProp, the ctxt will be invalid.
+ QMetaObject::invokeMethod(object, "deassignVarProp"); // now deassign the root-object's vp, causing gc of rect+text+text2
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+ QVERIFY(!imageGuard.isNull()); // should still be alive.
+ QVERIFY(!image->property("imageCanary").isValid()); // but varProperties won't be available (null context).
+ delete object;
+ QVERIFY(imageGuard.isNull()); // should now be dead.
+}
+
+void tst_qdeclarativeecmascript::propertyVarCircular()
+{
+ // enforce behaviour regarding circular references - ensure qdvmemo deletion.
+ QDeclarativeComponent component(&engine, TEST_FILE("propertyVar.circular.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QMetaObject::invokeMethod(object, "assignCircular"); // cause assignment and gc
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+ QCOMPARE(object->property("canaryInt"), QVariant(5));
+ QVariant canaryResourceVariant = object->property("canaryResource");
+ QVERIFY(canaryResourceVariant.isValid());
+ QPixmap canaryResourcePixmap = canaryResourceVariant.value<QPixmap>();
+ canaryResourceVariant = QVariant(); // invalidate it to remove one copy of the pixmap from memory.
+ QMetaObject::invokeMethod(object, "deassignCanaryResource"); // remove one copy of the pixmap from memory
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+ QVERIFY(!canaryResourcePixmap.isDetached()); // two copies extant - this and the propertyVar.vp.vp.vp.vp.memoryHog.
+ QMetaObject::invokeMethod(object, "deassignCircular"); // cause deassignment and gc
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+ QCOMPARE(object->property("canaryInt"), QVariant(2));
+ QCOMPARE(object->property("canaryResource"), QVariant(1));
+ QVERIFY(canaryResourcePixmap.isDetached()); // now detached, since orig copy was member of qdvmemo which was deleted.
+ delete object;
+}
+
+void tst_qdeclarativeecmascript::propertyVarCircular2()
+{
+ // track deletion of JS-owned parent item with Cpp-owned child
+ // where the child has a var property referencing its parent.
+ QDeclarativeComponent component(&engine, TEST_FILE("propertyVar.circular.2.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QMetaObject::invokeMethod(object, "assignCircular");
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+ QObject *rootObject = object->property("vp").value<QObject*>();
+ QVERIFY(rootObject != 0);
+ QObject *childObject = rootObject->findChild<QObject*>("text");
+ QVERIFY(childObject != 0);
+ QWeakPointer<QObject> rootObjectTracker(rootObject);
+ QVERIFY(!rootObjectTracker.isNull());
+ QWeakPointer<QObject> childObjectTracker(childObject);
+ QVERIFY(!childObjectTracker.isNull());
+ gc(engine);
+ QCOMPARE(rootObject->property("rectCanary").toInt(), 5);
+ QCOMPARE(childObject->property("textCanary").toInt(), 10);
+ QMetaObject::invokeMethod(object, "deassignCircular");
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+ QVERIFY(rootObjectTracker.isNull()); // should have been collected
+ QVERIFY(childObjectTracker.isNull()); // should have been collected
+ delete object;
+}
+
+void tst_qdeclarativeecmascript::propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter)
+{
+ *(int*)(parameter) += 1;
+ qPersistentDispose(object);
+}
+
+void tst_qdeclarativeecmascript::propertyVarInheritance()
+{
+ int propertyVarWeakRefCallbackCount = 0;
+
+ // enforce behaviour regarding element inheritance - ensure handle disposal.
+ // The particular component under test here has a chain of references.
+ QDeclarativeComponent component(&engine, TEST_FILE("propertyVar.inherit.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QMetaObject::invokeMethod(object, "assignCircular"); // cause assignment and gc
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+ // we want to be able to track when the varProperties array of the last metaobject is disposed
+ QObject *cco5 = object->property("varProperty").value<QObject*>()->property("vp").value<QObject*>()->property("vp").value<QObject*>()->property("vp").value<QObject*>()->property("vp").value<QObject*>();
+ QObject *ico5 = object->property("varProperty").value<QObject*>()->property("inheritanceVarProperty").value<QObject*>()->property("vp").value<QObject*>()->property("vp").value<QObject*>()->property("vp").value<QObject*>()->property("vp").value<QObject*>();
+ QDeclarativeVMEMetaObject *icovmemo = ((QDeclarativeVMEMetaObject *)(ico5->metaObject()));
+ QDeclarativeVMEMetaObject *ccovmemo = ((QDeclarativeVMEMetaObject *)(cco5->metaObject()));
+ v8::Persistent<v8::Value> icoCanaryHandle;
+ v8::Persistent<v8::Value> ccoCanaryHandle;
+ {
+ v8::HandleScope hs;
+ // XXX NOTE: this is very implementation dependent. QDVMEMO->vmeProperty() is the only
+ // public function which can return us a handle to something in the varProperties array.
+ icoCanaryHandle = qPersistentNew(icovmemo->vmeProperty(41));
+ ccoCanaryHandle = qPersistentNew(ccovmemo->vmeProperty(41));
+ // we make them weak and invoke the gc, but we should not hit the weak-callback yet
+ // as the varproperties array of each vmemo still references the resource.
+ icoCanaryHandle.MakeWeak(&propertyVarWeakRefCallbackCount, propertyVarWeakRefCallback);
+ ccoCanaryHandle.MakeWeak(&propertyVarWeakRefCallbackCount, propertyVarWeakRefCallback);
+ gc(engine);
+ QVERIFY(propertyVarWeakRefCallbackCount == 0);
+ }
+ // now we deassign the var prop, which should trigger collection of item subtrees.
+ QMetaObject::invokeMethod(object, "deassignCircular"); // cause deassignment and gc
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+ // ensure that there are only weak handles to the underlying varProperties array remaining.
+ gc(engine);
+ QCOMPARE(propertyVarWeakRefCallbackCount, 2); // should have been called for both, since all refs should be weak.
+ delete object;
+ // since there are no parent vmemo's to keep implicit references alive, and the only handles
+ // to what remains are weak, all varProperties arrays must have been collected.
+}
+
+void tst_qdeclarativeecmascript::propertyVarInheritance2()
+{
+ int propertyVarWeakRefCallbackCount = 0;
+
+ // The particular component under test here does NOT have a chain of references; the
+ // only link between rootObject and childObject is that rootObject is the parent of childObject.
+ QDeclarativeComponent component(&engine, TEST_FILE("propertyVar.circular.2.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QMetaObject::invokeMethod(object, "assignCircular");
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+ QObject *rootObject = object->property("vp").value<QObject*>();
+ QVERIFY(rootObject != 0);
+ QObject *childObject = rootObject->findChild<QObject*>("text");
+ QVERIFY(childObject != 0);
+ QCOMPARE(rootObject->property("rectCanary").toInt(), 5);
+ QCOMPARE(childObject->property("textCanary").toInt(), 10);
+ v8::Persistent<v8::Value> childObjectVarArrayValueHandle;
+ {
+ v8::HandleScope hs;
+ propertyVarWeakRefCallbackCount = 0; // reset callback count.
+ childObjectVarArrayValueHandle = qPersistentNew(((QDeclarativeVMEMetaObject *)(childObject->metaObject()))->vmeProperty(58));
+ childObjectVarArrayValueHandle.MakeWeak(&propertyVarWeakRefCallbackCount, propertyVarWeakRefCallback);
+ gc(engine);
+ QVERIFY(propertyVarWeakRefCallbackCount == 0); // should not have been collected yet.
+ QCOMPARE(childObject->property("textCanary").toInt(), 10);
+ }
+ QMetaObject::invokeMethod(object, "deassignCircular");
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion); // process deleteLater() events from QV8QObjectWrapper.
+ QVERIFY(propertyVarWeakRefCallbackCount == 1); // should have been collected now.
+ delete object;
+}
+
// Ensure that QObject type conversion works on binding assignment
void tst_qdeclarativeecmascript::elementAssign()
{
@@ -3283,6 +3741,21 @@ void tst_qdeclarativeecmascript::objectPassThroughSignals()
delete object;
}
+// QTBUG-21626
+void tst_qdeclarativeecmascript::objectConversion()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("objectConversion.qml"));
+
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QVariant retn;
+ QMetaObject::invokeMethod(object, "circularObject", Q_RETURN_ARG(QVariant, retn));
+ QCOMPARE(retn.value<QVariantMap>().value("test"), QVariant(100));
+
+ delete object;
+}
+
+
// QTBUG-20242
void tst_qdeclarativeecmascript::booleanConversion()
{
@@ -3317,8 +3790,7 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
CircularReferenceObject *cro = object->findChild<CircularReferenceObject*>("cro");
cro->setDtorCount(&dtorCount);
QMetaObject::invokeMethod(object, "createReference");
- QMetaObject::invokeMethod(object, "performGc");
- QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+ gc(engine);
QCOMPARE(dtorCount, 0); // second has JS ownership, kept alive by first's reference
delete object;
hrmEngine.collectGarbage();
@@ -3336,8 +3808,7 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
CircularReferenceObject *cro = object->findChild<CircularReferenceObject*>("cro");
cro->setDtorCount(&dtorCount);
QMetaObject::invokeMethod(object, "circularReference");
- QMetaObject::invokeMethod(object, "performGc");
- QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+ gc(engine);
QCOMPARE(dtorCount, 2); // both should be cleaned up, since circular references shouldn't keep alive.
delete object;
hrmEngine.collectGarbage();
@@ -3364,8 +3835,7 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
// now we have to reparent second and make second owned by JS.
second->setParent(0);
QDeclarativeEngine::setObjectOwnership(second, QDeclarativeEngine::JavaScriptOwnership);
- QMetaObject::invokeMethod(object, "performGc");
- QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+ gc(engine);
QCOMPARE(dtorCount, 0); // due to reference from first to second, second shouldn't be collected.
delete object;
hrmEngine.collectGarbage();
@@ -3395,8 +3865,7 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
second->setParent(0);
QDeclarativeEngine::setObjectOwnership(first, QDeclarativeEngine::JavaScriptOwnership);
QDeclarativeEngine::setObjectOwnership(second, QDeclarativeEngine::JavaScriptOwnership);
- QMetaObject::invokeMethod(object, "performGc");
- QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+ gc(engine);
QCOMPARE(dtorCount, 2); // despite circular references, both will be collected.
delete object;
hrmEngine.collectGarbage();
@@ -3435,8 +3904,7 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
// now we have to reparent second2 and make second2 owned by JS.
second2->setParent(0);
QDeclarativeEngine::setObjectOwnership(second2, QDeclarativeEngine::JavaScriptOwnership);
- QMetaObject::invokeMethod(object1, "performGc");
- QMetaObject::invokeMethod(object2, "performGc");
+ gc(engine);
QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
QCOMPARE(dtorCount, 0); // due to reference from first1 to second2, second2 shouldn't be collected.
delete object1;
@@ -3487,8 +3955,7 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
QDeclarativeEngine::setObjectOwnership(second1, QDeclarativeEngine::JavaScriptOwnership);
QDeclarativeEngine::setObjectOwnership(first2, QDeclarativeEngine::JavaScriptOwnership);
QDeclarativeEngine::setObjectOwnership(second2, QDeclarativeEngine::JavaScriptOwnership);
- QMetaObject::invokeMethod(object1, "performGc");
- QMetaObject::invokeMethod(object2, "performGc");
+ gc(engine);
QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
QCOMPARE(dtorCount, 4); // circular references shouldn't keep them alive.
delete object1;
@@ -3537,13 +4004,10 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
QDeclarativeEngine::setObjectOwnership(second1, QDeclarativeEngine::JavaScriptOwnership);
QDeclarativeEngine::setObjectOwnership(first2, QDeclarativeEngine::JavaScriptOwnership);
QDeclarativeEngine::setObjectOwnership(second2, QDeclarativeEngine::JavaScriptOwnership);
- QMetaObject::invokeMethod(object1, "performGc");
- QMetaObject::invokeMethod(object2, "performGc");
- QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+ gc(engine);
QCOMPARE(dtorCount, 0);
delete hrmEngine2;
- QMetaObject::invokeMethod(object1, "performGc");
- QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+ gc(engine);
QCOMPARE(dtorCount, 0);
delete object1;
delete object2;
@@ -3554,6 +4018,22 @@ void tst_qdeclarativeecmascript::handleReferenceManagement()
}
}
+void tst_qdeclarativeecmascript::stringArg()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("stringArg.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QMetaObject::invokeMethod(object, "success");
+ QVERIFY(object->property("returnValue").toBool());
+
+ QString w1 = TEST_FILE("stringArg.qml").toString() + QLatin1String(":45: Error: String.arg(): Invalid arguments");
+ QTest::ignoreMessage(QtWarningMsg, w1.toAscii().constData());
+ QMetaObject::invokeMethod(object, "failure");
+ QVERIFY(object->property("returnValue").toBool());
+
+ delete object;
+}
+
// Test that assigning a null object works
// Regressed with: df1788b4dbbb2826ae63f26bdf166342595343f4
void tst_qdeclarativeecmascript::nullObjectBinding()
@@ -3900,7 +4380,7 @@ void tst_qdeclarativeecmascript::include()
{
TestHTTPServer server(8111);
QVERIFY(server.isValid());
- server.serveDirectory(SRCDIR "/data");
+ server.serveDirectory(TESTDATA(""));
QDeclarativeComponent component(&engine, TEST_FILE("include_remote.qml"));
QObject *o = component.create();
@@ -3928,7 +4408,7 @@ void tst_qdeclarativeecmascript::include()
{
TestHTTPServer server(8111);
QVERIFY(server.isValid());
- server.serveDirectory(SRCDIR "/data");
+ server.serveDirectory(TESTDATA(""));
QDeclarativeComponent component(&engine, TEST_FILE("include_remote_missing.qml"));
QObject *o = component.create();
@@ -4283,6 +4763,23 @@ void tst_qdeclarativeecmascript::automaticSemicolon()
QVERIFY(object != 0);
}
+// Makes sure that a binding isn't double re-evaluated when it depends on the same variable twice
+void tst_qdeclarativeecmascript::doubleEvaluate()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("doubleEvaluate.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ WriteCounter *wc = qobject_cast<WriteCounter *>(object);
+ QVERIFY(wc != 0);
+ QCOMPARE(wc->count(), 1);
+
+ wc->setProperty("x", 9);
+
+ QCOMPARE(wc->count(), 2);
+
+ delete object;
+}
+
QTEST_MAIN(tst_qdeclarativeecmascript)
#include "tst_qdeclarativeecmascript.moc"
diff --git a/tests/auto/declarative/qdeclarativeengine/qdeclarativeengine.pro b/tests/auto/declarative/qdeclarativeengine/qdeclarativeengine.pro
index 61ad24d194..547d56b3ad 100644
--- a/tests/auto/declarative/qdeclarativeengine/qdeclarativeengine.pro
+++ b/tests/auto/declarative/qdeclarativeengine/qdeclarativeengine.pro
@@ -1,13 +1,9 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative network
+CONFIG += testcase
+TARGET = tst_qdeclarativeengine
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativeengine.cpp
-!symbian: {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp b/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp
index e9bd735dbd..06ee4e98cd 100644
--- a/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp
+++ b/tests/auto/declarative/qdeclarativeengine/tst_qdeclarativeengine.cpp
@@ -51,11 +51,6 @@
#include <QDeclarativeNetworkAccessManagerFactory>
#include <QDeclarativeExpression>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qdeclarativeengine : public QObject
{
Q_OBJECT
@@ -273,7 +268,7 @@ void tst_qdeclarativeengine::outputWarningsToStandardError()
delete o;
QCOMPARE(warnings.count(), 1);
- QCOMPARE(warnings.at(0), QLatin1String("<Unknown File>:1: Unable to assign [undefined] to int a"));
+ QCOMPARE(warnings.at(0), QLatin1String("<Unknown File>:1: Unable to assign [undefined] to int"));
warnings.clear();
diff --git a/tests/auto/declarative/qdeclarativeerror/test.txt b/tests/auto/declarative/qdeclarativeerror/data/test.txt
index cdafd9ed82..cdafd9ed82 100644
--- a/tests/auto/declarative/qdeclarativeerror/test.txt
+++ b/tests/auto/declarative/qdeclarativeerror/data/test.txt
diff --git a/tests/auto/declarative/qdeclarativeerror/qdeclarativeerror.pro b/tests/auto/declarative/qdeclarativeerror/qdeclarativeerror.pro
index 4132abe30a..11f6beadf0 100644
--- a/tests/auto/declarative/qdeclarativeerror/qdeclarativeerror.pro
+++ b/tests/auto/declarative/qdeclarativeerror/qdeclarativeerror.pro
@@ -1,12 +1,12 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qdeclarativeerror
SOURCES += tst_qdeclarativeerror.cpp
macx:CONFIG -= app_bundle
-!symbian: {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativeerror/tst_qdeclarativeerror.cpp b/tests/auto/declarative/qdeclarativeerror/tst_qdeclarativeerror.cpp
index 5d9f6d7318..ab97d04d4c 100644
--- a/tests/auto/declarative/qdeclarativeerror/tst_qdeclarativeerror.cpp
+++ b/tests/auto/declarative/qdeclarativeerror/tst_qdeclarativeerror.cpp
@@ -42,11 +42,7 @@
#include <qtest.h>
#include <QDeclarativeError>
#include <QDebug>
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class tst_qdeclarativeerror : public QObject
{
@@ -212,7 +208,7 @@ void tst_qdeclarativeerror::debug()
}
{
- QUrl url(QUrl::fromLocalFile(QString(SRCDIR) + "/").resolved(QUrl("test.txt")));
+ QUrl url(QUrl::fromLocalFile(TESTDATA("")).resolved(QUrl("test.txt")));
QDeclarativeError error;
error.setUrl(url);
error.setDescription("An Error");
@@ -226,7 +222,7 @@ void tst_qdeclarativeerror::debug()
}
{
- QUrl url(QUrl::fromLocalFile(QString(SRCDIR) + "/").resolved(QUrl("foo.txt")));
+ QUrl url(QUrl::fromLocalFile(TESTDATA("")).resolved(QUrl("foo.txt")));
QDeclarativeError error;
error.setUrl(url);
error.setDescription("An Error");
diff --git a/tests/auto/declarative/qdeclarativeexpression/qdeclarativeexpression.pro b/tests/auto/declarative/qdeclarativeexpression/qdeclarativeexpression.pro
index 8c73a7cb87..8807e7a2e2 100644
--- a/tests/auto/declarative/qdeclarativeexpression/qdeclarativeexpression.pro
+++ b/tests/auto/declarative/qdeclarativeexpression/qdeclarativeexpression.pro
@@ -1,17 +1,13 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui
+CONFIG += testcase
+TARGET = tst_qdeclarativeexpression
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativeexpression.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativeexpression/tst_qdeclarativeexpression.cpp b/tests/auto/declarative/qdeclarativeexpression/tst_qdeclarativeexpression.cpp
index aa8c12e332..a05c06f23f 100644
--- a/tests/auto/declarative/qdeclarativeexpression/tst_qdeclarativeexpression.cpp
+++ b/tests/auto/declarative/qdeclarativeexpression/tst_qdeclarativeexpression.cpp
@@ -44,11 +44,7 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtDeclarative/qdeclarativeexpression.h>
#include <QtDeclarative/qdeclarativescriptstring.h>
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class tst_qdeclarativeexpression : public QObject
{
@@ -86,7 +82,7 @@ void tst_qdeclarativeexpression::scriptString()
qmlRegisterType<TestObject>("Test", 1, 0, "TestObject");
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/scriptString.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("scriptString.qml")));
TestObject *testObj = qobject_cast<TestObject*>(c.create());
QVERIFY(testObj != 0);
diff --git a/tests/auto/declarative/qdeclarativefolderlistmodel/qdeclarativefolderlistmodel.pro b/tests/auto/declarative/qdeclarativefolderlistmodel/qdeclarativefolderlistmodel.pro
index ad02dd4ac1..b59d39f629 100644
--- a/tests/auto/declarative/qdeclarativefolderlistmodel/qdeclarativefolderlistmodel.pro
+++ b/tests/auto/declarative/qdeclarativefolderlistmodel/qdeclarativefolderlistmodel.pro
@@ -1,16 +1,12 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qdeclarativefolderlistmodel
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativefolderlistmodel.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp b/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp
index ef7738dc2e..f8c91e6000 100644
--- a/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp
+++ b/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp
@@ -40,18 +40,13 @@
****************************************************************************/
#include <qtest.h>
#include <QtTest/QSignalSpy>
-#include "../../../shared/util.h"
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtCore/qdir.h>
#include <QtCore/qfile.h>
#include <QtCore/qabstractitemmodel.h>
#include <QDebug>
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
// From qdeclarastivefolderlistmodel.h
const int FileNameRole = Qt::UserRole+1;
@@ -103,16 +98,16 @@ void tst_qdeclarativefolderlistmodel::checkNoErrors(const QDeclarativeComponent&
void tst_qdeclarativefolderlistmodel::basicProperties()
{
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/basic.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("basic.qml")));
checkNoErrors(component);
QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(component.create());
QVERIFY(flm != 0);
- flm->setProperty("folder",QUrl::fromLocalFile(SRCDIR "/data"));
+ flm->setProperty("folder",QUrl::fromLocalFile(TESTDATA("")));
QTRY_COMPARE(flm->property("count").toInt(),4); // wait for refresh
- QCOMPARE(flm->property("folder").toUrl(), QUrl::fromLocalFile(SRCDIR "/data"));
- QCOMPARE(flm->property("parentFolder").toUrl(), QUrl::fromLocalFile(SRCDIR));
+ QCOMPARE(flm->property("folder").toUrl(), QUrl::fromLocalFile(TESTDATA("")));
+ QCOMPARE(flm->property("parentFolder").toUrl(), QUrl::fromLocalFile(QDir(TESTDATA("..")).canonicalPath()));
QCOMPARE(flm->property("sortField").toInt(), int(Name));
QCOMPARE(flm->property("nameFilters").toStringList(), QStringList() << "*.qml");
QCOMPARE(flm->property("sortReversed").toBool(), false);
@@ -129,7 +124,7 @@ void tst_qdeclarativefolderlistmodel::basicProperties()
void tst_qdeclarativefolderlistmodel::resetFiltering()
{
// see QTBUG-17837
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/resetFiltering.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("resetFiltering.qml")));
checkNoErrors(component);
QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(component.create());
@@ -138,19 +133,19 @@ void tst_qdeclarativefolderlistmodel::resetFiltering()
connect(flm, SIGNAL(rowsRemoved(const QModelIndex&,int,int)),
this, SLOT(removed(const QModelIndex&,int,int)));
- flm->setProperty("folder",QUrl::fromLocalFile(SRCDIR "/data/resetfiltering"));
+ flm->setProperty("folder",QUrl::fromLocalFile(TESTDATA("resetfiltering")));
QTRY_COMPARE(flm->property("count").toInt(),1); // should just be "test.txt" visible
int count = flm->rowCount();
QCOMPARE(removeStart, 0);
QCOMPARE(removeEnd, count-1);
- flm->setProperty("folder",QUrl::fromLocalFile(SRCDIR "/data/resetfiltering/innerdir"));
+ flm->setProperty("folder",QUrl::fromLocalFile(TESTDATA("resetfiltering/innerdir")));
QTRY_COMPARE(flm->property("count").toInt(),1); // should just be "test2.txt" visible
count = flm->rowCount();
QCOMPARE(removeStart, 0);
QCOMPARE(removeEnd, count-1);
- flm->setProperty("folder",QUrl::fromLocalFile(SRCDIR "/data/resetfiltering"));
+ flm->setProperty("folder",QUrl::fromLocalFile(TESTDATA("resetfiltering")));
QTRY_COMPARE(flm->property("count").toInt(),1); // should just be "test.txt" visible
count = flm->rowCount();
QCOMPARE(removeStart, 0);
@@ -159,13 +154,13 @@ void tst_qdeclarativefolderlistmodel::resetFiltering()
void tst_qdeclarativefolderlistmodel::refresh()
{
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/basic.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("basic.qml")));
checkNoErrors(component);
QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(component.create());
QVERIFY(flm != 0);
- flm->setProperty("folder",QUrl::fromLocalFile(SRCDIR "/data"));
+ flm->setProperty("folder",QUrl::fromLocalFile(TESTDATA("")));
QTRY_COMPARE(flm->property("count").toInt(),4); // wait for refresh
int count = flm->rowCount();
diff --git a/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro b/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro
index 946e5a8a16..3efde621b2 100644
--- a/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro
+++ b/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro
@@ -1,18 +1,14 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui network
+CONFIG += testcase
+TARGET = tst_qdeclarativefontloader
macx:CONFIG -= app_bundle
HEADERS += ../../declarative/shared/testhttpserver.h
SOURCES += tst_qdeclarativefontloader.cpp ../../declarative/shared/testhttpserver.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp
index 29fe0329bb..67a040dcf2 100644
--- a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp
+++ b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp
@@ -44,16 +44,11 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtDeclarative/qdeclarativecontext.h>
#include <QtDeclarative/private/qdeclarativefontloader_p.h>
-#include "../../../shared/util.h"
+#include "../shared/util.h"
#include "../../declarative/shared/testhttpserver.h"
#define SERVER_PORT 14448
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qdeclarativefontloader : public QObject
{
Q_OBJECT
@@ -79,7 +74,7 @@ private:
tst_qdeclarativefontloader::tst_qdeclarativefontloader() :
server(SERVER_PORT)
{
- server.serveDirectory(SRCDIR "/data");
+ server.serveDirectory(TESTDATA(""));
}
void tst_qdeclarativefontloader::init()
@@ -117,7 +112,7 @@ void tst_qdeclarativefontloader::namedFont()
void tst_qdeclarativefontloader::localFont()
{
- QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"" SRCDIR "/data/tarzeau_ocr_a.ttf\" }";
+ QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"" + TESTDATA("tarzeau_ocr_a.ttf") + "\" }";
QDeclarativeComponent component(&engine);
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QDeclarativeFontLoader *fontObject = qobject_cast<QDeclarativeFontLoader*>(component.create());
@@ -130,8 +125,8 @@ void tst_qdeclarativefontloader::localFont()
void tst_qdeclarativefontloader::failLocalFont()
{
- QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"" + QUrl::fromLocalFile(SRCDIR "/data/dummy.ttf").toString() + "\" }";
- QTest::ignoreMessage(QtWarningMsg, QString("file::2:1: QML FontLoader: Cannot load font: \"" + QUrl::fromLocalFile(SRCDIR "/data/dummy.ttf").toString() + "\"").toUtf8().constData());
+ QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"" + QUrl::fromLocalFile(TESTDATA("dummy.ttf")).toString() + "\" }";
+ QTest::ignoreMessage(QtWarningMsg, QString("file::2:1: QML FontLoader: Cannot load font: \"" + QUrl::fromLocalFile(TESTDATA("dummy.ttf")).toString() + "\"").toUtf8().constData());
QDeclarativeComponent component(&engine);
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QDeclarativeFontLoader *fontObject = qobject_cast<QDeclarativeFontLoader*>(component.create());
@@ -190,7 +185,7 @@ void tst_qdeclarativefontloader::changeFont()
{
QString componentStr = "import QtQuick 2.0\nFontLoader { source: font }";
QDeclarativeContext *ctxt = engine.rootContext();
- ctxt->setContextProperty("font", QUrl::fromLocalFile(SRCDIR "/data/tarzeau_ocr_a.ttf"));
+ ctxt->setContextProperty("font", QUrl::fromLocalFile(TESTDATA("tarzeau_ocr_a.ttf")));
QDeclarativeComponent component(&engine);
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QDeclarativeFontLoader *fontObject = qobject_cast<QDeclarativeFontLoader*>(component.create());
@@ -212,7 +207,7 @@ void tst_qdeclarativefontloader::changeFont()
QCOMPARE(statusSpy.count(), 2);
QTRY_COMPARE(fontObject->name(), QString("Daniel"));
- ctxt->setContextProperty("font", QUrl::fromLocalFile(SRCDIR "/data/tarzeau_ocr_a.ttf"));
+ ctxt->setContextProperty("font", QUrl::fromLocalFile(TESTDATA("tarzeau_ocr_a.ttf")));
QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready);
QCOMPARE(nameSpy.count(), 2);
QCOMPARE(statusSpy.count(), 2);
diff --git a/tests/auto/declarative/qdeclarativeimageprovider/qdeclarativeimageprovider.pro b/tests/auto/declarative/qdeclarativeimageprovider/qdeclarativeimageprovider.pro
index 6cb38e7cb4..dda2595956 100644
--- a/tests/auto/declarative/qdeclarativeimageprovider/qdeclarativeimageprovider.pro
+++ b/tests/auto/declarative/qdeclarativeimageprovider/qdeclarativeimageprovider.pro
@@ -1,17 +1,9 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
-QT += network
+CONFIG += testcase
+TARGET = tst_qdeclarativeimageprovider
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativeimageprovider.cpp
-# QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage
-# LIBS += -lgcov
-
-!symbian: {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp b/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp
index 6ddc3bcb58..9f4e131cbd 100644
--- a/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp
+++ b/tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp
@@ -45,12 +45,6 @@
#include <private/qsgimage_p.h>
#include <QImageReader>
#include <QWaitCondition>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
Q_DECLARE_METATYPE(QDeclarativeImageProvider*);
@@ -413,13 +407,13 @@ void tst_qdeclarativeimageprovider::threadTest()
QList<QSGImage *> images = obj->findChildren<QSGImage *>();
QCOMPARE(images.count(), 4);
QTest::qWait(100);
- foreach(QSGImage *img, images) {
+ foreach (QSGImage *img, images) {
QCOMPARE(img->status(), QSGImage::Loading);
}
provider->ok = true;
provider->cond.wakeAll();
QTest::qWait(250);
- foreach(QSGImage *img, images) {
+ foreach (QSGImage *img, images) {
QTRY_VERIFY(img->status() == QSGImage::Ready);
}
}
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/AsynchronousIfNestedType.qml b/tests/auto/declarative/qdeclarativeincubator/data/AsynchronousIfNestedType.qml
new file mode 100644
index 0000000000..8a3f46ee72
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/AsynchronousIfNestedType.qml
@@ -0,0 +1,7 @@
+import Qt.test 1.0
+
+SelfRegistering {
+ property int dummy1: 11
+ property int dummy2: 19
+}
+
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/asynchronousIfNested.1.qml b/tests/auto/declarative/qdeclarativeincubator/data/asynchronousIfNested.1.qml
new file mode 100644
index 0000000000..18ff4aabb7
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/asynchronousIfNested.1.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+QtObject {
+ property int a: 10
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/asynchronousIfNested.2.qml b/tests/auto/declarative/qdeclarativeincubator/data/asynchronousIfNested.2.qml
new file mode 100644
index 0000000000..3f6cd932de
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/asynchronousIfNested.2.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+
+QtObject {
+ property QtObject o: AsynchronousIfNestedType { }
+ property int dummy: 11
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/asynchronousIfNested.3.qml b/tests/auto/declarative/qdeclarativeincubator/data/asynchronousIfNested.3.qml
new file mode 100644
index 0000000000..7e5ee7cf5c
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/asynchronousIfNested.3.qml
@@ -0,0 +1,5 @@
+import Qt.test 1.0
+
+CallbackRegistering {
+ value: 19
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/chainedAsynchronousIfNested.qml b/tests/auto/declarative/qdeclarativeincubator/data/chainedAsynchronousIfNested.qml
new file mode 100644
index 0000000000..1300426cfa
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/chainedAsynchronousIfNested.qml
@@ -0,0 +1,5 @@
+import Qt.test 1.0
+
+SelfRegistering {
+ property int dummy: 10
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/clear.qml b/tests/auto/declarative/qdeclarativeincubator/data/clear.qml
new file mode 100644
index 0000000000..f00f975923
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/clear.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ SelfRegistering {
+ value: 11
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/clearDuringCompletion.qml b/tests/auto/declarative/qdeclarativeincubator/data/clearDuringCompletion.qml
new file mode 100644
index 0000000000..556f460d58
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/clearDuringCompletion.qml
@@ -0,0 +1,6 @@
+import Qt.test 1.0
+
+SelfRegistering {
+ property variant a: CompletionRegistering {}
+ property variant b: CompletionRegistering {}
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/forceCompletion.qml b/tests/auto/declarative/qdeclarativeincubator/data/forceCompletion.qml
new file mode 100644
index 0000000000..9b76701c1b
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/forceCompletion.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ property int testValue: 3499
+ SelfRegistering {
+ property int testValue2: 19
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/nestedComponent.js b/tests/auto/declarative/qdeclarativeincubator/data/nestedComponent.js
new file mode 100644
index 0000000000..4b6b0bde43
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/nestedComponent.js
@@ -0,0 +1 @@
+var value = 19988
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/nestedComponent.qml b/tests/auto/declarative/qdeclarativeincubator/data/nestedComponent.qml
new file mode 100644
index 0000000000..dd20707456
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/nestedComponent.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.0
+import "nestedComponent.js" as NestedJS
+
+QtObject {
+ property Component c: Component {
+ QtObject {
+ property int value: NestedJS.value
+ }
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/noIncubationController.qml b/tests/auto/declarative/qdeclarativeincubator/data/noIncubationController.qml
new file mode 100644
index 0000000000..7d93e856f0
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/noIncubationController.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+QtObject {
+ property int testValue: 1913
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/objectDeleted.errors.txt b/tests/auto/declarative/qdeclarativeincubator/data/objectDeleted.errors.txt
new file mode 100644
index 0000000000..eeda289d35
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/objectDeleted.errors.txt
@@ -0,0 +1 @@
+-1:-1:Object destroyed during incubation
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/objectDeleted.qml b/tests/auto/declarative/qdeclarativeincubator/data/objectDeleted.qml
new file mode 100644
index 0000000000..f00f975923
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/objectDeleted.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+ SelfRegistering {
+ value: 11
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/recursiveClear.1.qml b/tests/auto/declarative/qdeclarativeincubator/data/recursiveClear.1.qml
new file mode 100644
index 0000000000..748a3f0cbf
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/recursiveClear.1.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+
+Rectangle {
+ objectName: "switchMe"
+ signal switchMe
+ width: 100; height: 100
+ color: "green"
+ Component.onCompleted: switchMe()
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/recursiveClear.2.qml b/tests/auto/declarative/qdeclarativeincubator/data/recursiveClear.2.qml
new file mode 100644
index 0000000000..e96ac00f21
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/recursiveClear.2.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+
+Rectangle {
+ objectName: "blue"
+ width: 100
+ height: 100
+ color: "blue"
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/selfDelete.qml b/tests/auto/declarative/qdeclarativeincubator/data/selfDelete.qml
new file mode 100644
index 0000000000..c3952074f1
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/selfDelete.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+QtObject {
+ property int dummy: 12
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/setInitialState.qml b/tests/auto/declarative/qdeclarativeincubator/data/setInitialState.qml
new file mode 100644
index 0000000000..0fd61abfd2
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/setInitialState.qml
@@ -0,0 +1,17 @@
+import QtQuick 2.0
+
+QtObject {
+ property int test1: (testData1 * 32 + 99) / testData2
+ property int test2: myValueFunction()
+
+ property bool myValueFunctionCalled: false
+
+ property int testData1: 19
+ property int testData2: 13
+
+ function myValueFunction() {
+ myValueFunctionCalled = true;
+ return 13;
+ }
+}
+
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/statusChanged.nested.qml b/tests/auto/declarative/qdeclarativeincubator/data/statusChanged.nested.qml
new file mode 100644
index 0000000000..3a496ea6fe
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/statusChanged.nested.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.0
+
+QtObject {
+ id: root
+
+ property bool test: false
+
+ Component.onCompleted: {
+ var c = Qt.createComponent("statusChanged.qml");
+ c.incubateObject(root, null, Qt.Synchronous);
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/data/statusChanged.qml b/tests/auto/declarative/qdeclarativeincubator/data/statusChanged.qml
new file mode 100644
index 0000000000..18ff4aabb7
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/data/statusChanged.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+QtObject {
+ property int a: 10
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/qdeclarativeincubator.pro b/tests/auto/declarative/qdeclarativeincubator/qdeclarativeincubator.pro
new file mode 100644
index 0000000000..11725b40bc
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/qdeclarativeincubator.pro
@@ -0,0 +1,15 @@
+CONFIG += testcase
+TARGET = tst_qdeclarativeincubator
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qdeclarativeincubator.cpp \
+ testtypes.cpp
+HEADERS += testtypes.h
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+
+QT += core-private gui-private v8-private declarative-private network widgets testlib
diff --git a/tests/auto/declarative/qdeclarativeincubator/testtypes.cpp b/tests/auto/declarative/qdeclarativeincubator/testtypes.cpp
new file mode 100644
index 0000000000..99d2cb1005
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/testtypes.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "testtypes.h"
+#include <QtDeclarative/qdeclarative.h>
+
+SelfRegisteringType *SelfRegisteringType::m_me = 0;
+SelfRegisteringType::SelfRegisteringType()
+: m_v(0)
+{
+ m_me = this;
+}
+
+SelfRegisteringType *SelfRegisteringType::me()
+{
+ return m_me;
+}
+
+void SelfRegisteringType::clearMe()
+{
+ m_me = 0;
+}
+
+CompletionRegisteringType *CompletionRegisteringType::m_me = 0;
+CompletionRegisteringType::CompletionRegisteringType()
+{
+}
+
+void CompletionRegisteringType::classBegin()
+{
+}
+
+void CompletionRegisteringType::componentComplete()
+{
+ m_me = this;
+}
+
+CompletionRegisteringType *CompletionRegisteringType::me()
+{
+ return m_me;
+}
+
+void CompletionRegisteringType::clearMe()
+{
+ m_me = 0;
+}
+
+CallbackRegisteringType::callback CallbackRegisteringType::m_callback = 0;
+void *CallbackRegisteringType::m_data = 0;
+CallbackRegisteringType::CallbackRegisteringType()
+: m_v(0)
+{
+}
+
+void CallbackRegisteringType::clearCallback()
+{
+ m_callback = 0;
+ m_data = 0;
+}
+
+void CallbackRegisteringType::registerCallback(callback c, void *d)
+{
+ m_callback = c;
+ m_data = d;
+}
+
+void registerTypes()
+{
+ qmlRegisterType<SelfRegisteringType>("Qt.test", 1,0, "SelfRegistering");
+ qmlRegisterType<CompletionRegisteringType>("Qt.test", 1,0, "CompletionRegistering");
+ qmlRegisterType<CallbackRegisteringType>("Qt.test", 1,0, "CallbackRegistering");
+}
diff --git a/tests/auto/declarative/qdeclarativeincubator/testtypes.h b/tests/auto/declarative/qdeclarativeincubator/testtypes.h
new file mode 100644
index 0000000000..6e732548b2
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/testtypes.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef TESTTYPES_H
+#define TESTTYPES_H
+
+#include <QtCore/qobject.h>
+#include <QDeclarativeParserStatus>
+
+class SelfRegisteringType : public QObject
+{
+Q_OBJECT
+Q_PROPERTY(int value READ value WRITE setValue);
+public:
+ SelfRegisteringType();
+
+ int value() const { return m_v; }
+ void setValue(int v) { m_v = v; }
+
+ static SelfRegisteringType *me();
+ static void clearMe();
+
+private:
+ static SelfRegisteringType *m_me;
+
+ int m_v;
+};
+
+class CallbackRegisteringType : public QObject
+{
+Q_OBJECT
+Q_PROPERTY(int value READ value WRITE setValue)
+public:
+ CallbackRegisteringType();
+
+ int value() const { return m_v; }
+ void setValue(int v) { if (m_callback) m_callback(this, m_data); m_v = v; }
+
+ typedef void (*callback)(CallbackRegisteringType *, void *);
+ static void clearCallback();
+ static void registerCallback(callback, void *);
+
+private:
+ static callback m_callback;
+ static void *m_data;
+
+ int m_v;
+};
+
+class CompletionRegisteringType : public QObject, public QDeclarativeParserStatus
+{
+Q_OBJECT
+public:
+ CompletionRegisteringType();
+
+ virtual void classBegin();
+ virtual void componentComplete();
+
+ static CompletionRegisteringType *me();
+ static void clearMe();
+
+private:
+ static CompletionRegisteringType *m_me;
+};
+
+void registerTypes();
+
+#endif // TESTTYPES_H
diff --git a/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp b/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp
new file mode 100644
index 0000000000..00c226e6a5
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp
@@ -0,0 +1,852 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "testtypes.h"
+
+#include <QUrl>
+#include <QDir>
+#include <QDebug>
+#include <qtest.h>
+#include <QPointer>
+#include <QFileInfo>
+#include <QDeclarativeEngine>
+#include <QDeclarativeProperty>
+#include <QDeclarativeComponent>
+#include <QDeclarativeIncubator>
+#include "../shared/util.h"
+#include "../../../shared/util.h"
+
+inline QUrl TEST_FILE(const QString &filename)
+{
+ return QUrl::fromLocalFile(TESTDATA(filename));
+}
+
+inline QUrl TEST_FILE(const char *filename)
+{
+ return TEST_FILE(QLatin1String(filename));
+}
+
+class tst_qdeclarativeincubator : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qdeclarativeincubator() {}
+
+private slots:
+ void initTestCase();
+
+ void incubationMode();
+ void objectDeleted();
+ void clear();
+ void noIncubationController();
+ void forceCompletion();
+ void setInitialState();
+ void clearDuringCompletion();
+ void recursiveClear();
+ void statusChanged();
+ void asynchronousIfNested();
+ void nestedComponent();
+ void chainedAsynchronousIfNested();
+ void selfDelete();
+
+private:
+ QDeclarativeIncubationController controller;
+ QDeclarativeEngine engine;
+};
+
+#define VERIFY_ERRORS(component, errorfile) \
+ if (!errorfile) { \
+ if (qgetenv("DEBUG") != "" && !component.errors().isEmpty()) \
+ qWarning() << "Unexpected Errors:" << component.errors(); \
+ QVERIFY(!component.isError()); \
+ QVERIFY(component.errors().isEmpty()); \
+ } else { \
+ QFile file(TESTDATA(errorfile)); \
+ QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); \
+ QByteArray data = file.readAll(); \
+ file.close(); \
+ QList<QByteArray> expected = data.split('\n'); \
+ expected.removeAll(QByteArray("")); \
+ QList<QDeclarativeError> errors = component.errors(); \
+ QList<QByteArray> actual; \
+ for (int ii = 0; ii < errors.count(); ++ii) { \
+ const QDeclarativeError &error = errors.at(ii); \
+ QByteArray errorStr = QByteArray::number(error.line()) + ":" + \
+ QByteArray::number(error.column()) + ":" + \
+ error.description().toUtf8(); \
+ actual << errorStr; \
+ } \
+ if (qgetenv("DEBUG") != "" && expected != actual) \
+ qWarning() << "Expected:" << expected << "Actual:" << actual; \
+ QCOMPARE(expected, actual); \
+ }
+
+void tst_qdeclarativeincubator::initTestCase()
+{
+ registerTypes();
+ engine.setIncubationController(&controller);
+}
+
+void tst_qdeclarativeincubator::incubationMode()
+{
+ {
+ QDeclarativeIncubator incubator;
+ QCOMPARE(incubator.incubationMode(), QDeclarativeIncubator::Asynchronous);
+ }
+ {
+ QDeclarativeIncubator incubator(QDeclarativeIncubator::Asynchronous);
+ QCOMPARE(incubator.incubationMode(), QDeclarativeIncubator::Asynchronous);
+ }
+ {
+ QDeclarativeIncubator incubator(QDeclarativeIncubator::Synchronous);
+ QCOMPARE(incubator.incubationMode(), QDeclarativeIncubator::Synchronous);
+ }
+ {
+ QDeclarativeIncubator incubator(QDeclarativeIncubator::AsynchronousIfNested);
+ QCOMPARE(incubator.incubationMode(), QDeclarativeIncubator::AsynchronousIfNested);
+ }
+}
+
+void tst_qdeclarativeincubator::objectDeleted()
+{
+ SelfRegisteringType::clearMe();
+
+ QDeclarativeComponent component(&engine, TEST_FILE("objectDeleted.qml"));
+ QVERIFY(component.isReady());
+
+ QDeclarativeIncubator incubator;
+ component.create(incubator);
+
+ QCOMPARE(incubator.status(), QDeclarativeIncubator::Loading);
+ QVERIFY(SelfRegisteringType::me() == 0);
+
+ while (SelfRegisteringType::me() == 0 && incubator.isLoading()) {
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(SelfRegisteringType::me() != 0);
+ QVERIFY(incubator.isLoading());
+
+ delete SelfRegisteringType::me();
+
+ {
+ bool b = true;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(incubator.isError());
+ VERIFY_ERRORS(incubator, "objectDeleted.errors.txt");
+ QVERIFY(incubator.object() == 0);
+}
+
+void tst_qdeclarativeincubator::clear()
+{
+ SelfRegisteringType::clearMe();
+
+ QDeclarativeComponent component(&engine, TEST_FILE("clear.qml"));
+ QVERIFY(component.isReady());
+
+ // Clear in null state
+ {
+ QDeclarativeIncubator incubator;
+ QVERIFY(incubator.isNull());
+ incubator.clear(); // no effect
+ QVERIFY(incubator.isNull());
+ }
+
+ // Clear in loading state
+ {
+ QDeclarativeIncubator incubator;
+ component.create(incubator);
+ QVERIFY(incubator.isLoading());
+ incubator.clear();
+ QVERIFY(incubator.isNull());
+ }
+
+ // Clear mid load
+ {
+ QDeclarativeIncubator incubator;
+ component.create(incubator);
+
+ while (SelfRegisteringType::me() == 0 && incubator.isLoading()) {
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(incubator.isLoading());
+ QVERIFY(SelfRegisteringType::me() != 0);
+ QPointer<SelfRegisteringType> srt = SelfRegisteringType::me();
+
+ incubator.clear();
+ QVERIFY(incubator.isNull());
+ QVERIFY(srt.isNull());
+ }
+
+ // Clear in ready state
+ {
+ QDeclarativeIncubator incubator;
+ component.create(incubator);
+
+ {
+ bool b = true;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(incubator.isReady());
+ QVERIFY(incubator.object() != 0);
+ QPointer<QObject> obj = incubator.object();
+
+ incubator.clear();
+ QVERIFY(incubator.isNull());
+ QVERIFY(incubator.object() == 0);
+ QVERIFY(!obj.isNull());
+
+ delete obj;
+ QVERIFY(obj.isNull());
+ }
+}
+
+void tst_qdeclarativeincubator::noIncubationController()
+{
+ // All incubators should behave synchronously when there is no controller
+
+ QDeclarativeEngine engine;
+ QDeclarativeComponent component(&engine, TEST_FILE("noIncubationController.qml"));
+
+ QVERIFY(component.isReady());
+
+ {
+ QDeclarativeIncubator incubator(QDeclarativeIncubator::Asynchronous);
+ component.create(incubator);
+ QVERIFY(incubator.isReady());
+ QVERIFY(incubator.object());
+ QCOMPARE(incubator.object()->property("testValue").toInt(), 1913);
+ delete incubator.object();
+ }
+
+ {
+ QDeclarativeIncubator incubator(QDeclarativeIncubator::AsynchronousIfNested);
+ component.create(incubator);
+ QVERIFY(incubator.isReady());
+ QVERIFY(incubator.object());
+ QCOMPARE(incubator.object()->property("testValue").toInt(), 1913);
+ delete incubator.object();
+ }
+
+ {
+ QDeclarativeIncubator incubator(QDeclarativeIncubator::Synchronous);
+ component.create(incubator);
+ QVERIFY(incubator.isReady());
+ QVERIFY(incubator.object());
+ QCOMPARE(incubator.object()->property("testValue").toInt(), 1913);
+ delete incubator.object();
+ }
+}
+
+void tst_qdeclarativeincubator::forceCompletion()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("forceCompletion.qml"));
+ QVERIFY(component.isReady());
+
+ {
+ // forceCompletion on a null incubator does nothing
+ QDeclarativeIncubator incubator;
+ QVERIFY(incubator.isNull());
+ incubator.forceCompletion();
+ QVERIFY(incubator.isNull());
+ }
+
+ {
+ // forceCompletion immediately after creating an asynchronous object completes it
+ QDeclarativeIncubator incubator;
+ QVERIFY(incubator.isNull());
+ component.create(incubator);
+ QVERIFY(incubator.isLoading());
+
+ incubator.forceCompletion();
+
+ QVERIFY(incubator.isReady());
+ QVERIFY(incubator.object() != 0);
+ QCOMPARE(incubator.object()->property("testValue").toInt(), 3499);
+
+ delete incubator.object();
+ }
+
+ {
+ // forceCompletion during creation completes it
+ SelfRegisteringType::clearMe();
+
+ QDeclarativeIncubator incubator;
+ QVERIFY(incubator.isNull());
+ component.create(incubator);
+ QVERIFY(incubator.isLoading());
+
+ while (SelfRegisteringType::me() == 0 && incubator.isLoading()) {
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(SelfRegisteringType::me() != 0);
+ QVERIFY(incubator.isLoading());
+
+ incubator.forceCompletion();
+
+ QVERIFY(incubator.isReady());
+ QVERIFY(incubator.object() != 0);
+ QCOMPARE(incubator.object()->property("testValue").toInt(), 3499);
+
+ delete incubator.object();
+ }
+
+ {
+ // forceCompletion on a ready incubator has no effect
+ QDeclarativeIncubator incubator;
+ QVERIFY(incubator.isNull());
+ component.create(incubator);
+ QVERIFY(incubator.isLoading());
+
+ incubator.forceCompletion();
+
+ QVERIFY(incubator.isReady());
+ QVERIFY(incubator.object() != 0);
+ QCOMPARE(incubator.object()->property("testValue").toInt(), 3499);
+
+ incubator.forceCompletion();
+
+ QVERIFY(incubator.isReady());
+ QVERIFY(incubator.object() != 0);
+ QCOMPARE(incubator.object()->property("testValue").toInt(), 3499);
+
+ delete incubator.object();
+ }
+}
+
+void tst_qdeclarativeincubator::setInitialState()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("setInitialState.qml"));
+ QVERIFY(component.isReady());
+
+ struct MyIncubator : public QDeclarativeIncubator
+ {
+ MyIncubator(QDeclarativeIncubator::IncubationMode mode)
+ : QDeclarativeIncubator(mode) {}
+
+ virtual void setInitialState(QObject *o) {
+ QDeclarativeProperty::write(o, "test2", 19);
+ QDeclarativeProperty::write(o, "testData1", 201);
+ }
+ };
+
+ {
+ MyIncubator incubator(QDeclarativeIncubator::Asynchronous);
+ component.create(incubator);
+ QVERIFY(incubator.isLoading());
+ bool b = true;
+ controller.incubateWhile(&b);
+ QVERIFY(incubator.isReady());
+ QVERIFY(incubator.object());
+ QCOMPARE(incubator.object()->property("myValueFunctionCalled").toBool(), false);
+ QCOMPARE(incubator.object()->property("test1").toInt(), 502);
+ QCOMPARE(incubator.object()->property("test2").toInt(), 19);
+ delete incubator.object();
+ }
+
+ {
+ MyIncubator incubator(QDeclarativeIncubator::Synchronous);
+ component.create(incubator);
+ QVERIFY(incubator.isReady());
+ QVERIFY(incubator.object());
+ QCOMPARE(incubator.object()->property("myValueFunctionCalled").toBool(), false);
+ QCOMPARE(incubator.object()->property("test1").toInt(), 502);
+ QCOMPARE(incubator.object()->property("test2").toInt(), 19);
+ delete incubator.object();
+ }
+}
+
+void tst_qdeclarativeincubator::clearDuringCompletion()
+{
+ CompletionRegisteringType::clearMe();
+ SelfRegisteringType::clearMe();
+
+ QDeclarativeComponent component(&engine, TEST_FILE("clearDuringCompletion.qml"));
+ QVERIFY(component.isReady());
+
+ QDeclarativeIncubator incubator;
+ component.create(incubator);
+
+ QCOMPARE(incubator.status(), QDeclarativeIncubator::Loading);
+ QVERIFY(CompletionRegisteringType::me() == 0);
+
+ while (CompletionRegisteringType::me() == 0 && incubator.isLoading()) {
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(CompletionRegisteringType::me() != 0);
+ QVERIFY(SelfRegisteringType::me() != 0);
+ QVERIFY(incubator.isLoading());
+
+ QPointer<QObject> srt = SelfRegisteringType::me();
+
+ incubator.clear();
+ QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
+ QVERIFY(incubator.isNull());
+ QVERIFY(srt.isNull());
+}
+
+class Switcher : public QObject
+{
+ Q_OBJECT
+public:
+ Switcher(QDeclarativeEngine *e) : QObject(), engine(e) { }
+
+ struct MyIncubator : public QDeclarativeIncubator
+ {
+ MyIncubator(QDeclarativeIncubator::IncubationMode mode, QObject *s)
+ : QDeclarativeIncubator(mode), switcher(s) {}
+
+ virtual void setInitialState(QObject *o) {
+ if (o->objectName() == "switchMe")
+ connect(o, SIGNAL(switchMe()), switcher, SLOT(switchIt()));
+ }
+
+ QObject *switcher;
+ };
+
+ void start()
+ {
+ incubator = new MyIncubator(QDeclarativeIncubator::Synchronous, this);
+ component = new QDeclarativeComponent(engine, TEST_FILE("recursiveClear.1.qml"));
+ component->create(*incubator);
+ }
+
+ QDeclarativeEngine *engine;
+ MyIncubator *incubator;
+ QDeclarativeComponent *component;
+
+public slots:
+ void switchIt() {
+ component->deleteLater();
+ incubator->clear();
+ component = new QDeclarativeComponent(engine, TEST_FILE("recursiveClear.2.qml"));
+ component->create(*incubator);
+ }
+};
+
+void tst_qdeclarativeincubator::recursiveClear()
+{
+ Switcher switcher(&engine);
+ switcher.start();
+}
+
+void tst_qdeclarativeincubator::statusChanged()
+{
+ class MyIncubator : public QDeclarativeIncubator
+ {
+ public:
+ MyIncubator(QDeclarativeIncubator::IncubationMode mode = QDeclarativeIncubator::Asynchronous)
+ : QDeclarativeIncubator(mode) {}
+
+ QList<int> statuses;
+ protected:
+ virtual void statusChanged(Status s) { statuses << s; }
+ virtual void setInitialState(QObject *) { statuses << -1; }
+ };
+
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("statusChanged.qml"));
+ QVERIFY(component.isReady());
+
+ MyIncubator incubator(QDeclarativeIncubator::Synchronous);
+ component.create(incubator);
+ QVERIFY(incubator.isReady());
+ QCOMPARE(incubator.statuses.count(), 3);
+ QCOMPARE(incubator.statuses.at(0), int(QDeclarativeIncubator::Loading));
+ QCOMPARE(incubator.statuses.at(1), -1);
+ QCOMPARE(incubator.statuses.at(2), int(QDeclarativeIncubator::Ready));
+ delete incubator.object();
+ }
+
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("statusChanged.qml"));
+ QVERIFY(component.isReady());
+
+ MyIncubator incubator(QDeclarativeIncubator::Asynchronous);
+ component.create(incubator);
+ QVERIFY(incubator.isLoading());
+ QCOMPARE(incubator.statuses.count(), 1);
+ QCOMPARE(incubator.statuses.at(0), int(QDeclarativeIncubator::Loading));
+
+ {
+ bool b = true;
+ controller.incubateWhile(&b);
+ }
+
+ QCOMPARE(incubator.statuses.count(), 3);
+ QCOMPARE(incubator.statuses.at(0), int(QDeclarativeIncubator::Loading));
+ QCOMPARE(incubator.statuses.at(1), -1);
+ QCOMPARE(incubator.statuses.at(2), int(QDeclarativeIncubator::Ready));
+ delete incubator.object();
+ }
+
+ {
+ QDeclarativeComponent component2(&engine, TEST_FILE("statusChanged.nested.qml"));
+ QVERIFY(component2.isReady());
+
+ MyIncubator incubator(QDeclarativeIncubator::Asynchronous);
+ component2.create(incubator);
+ QVERIFY(incubator.isLoading());
+ QCOMPARE(incubator.statuses.count(), 1);
+ QCOMPARE(incubator.statuses.at(0), int(QDeclarativeIncubator::Loading));
+
+ {
+ bool b = true;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(incubator.isReady());
+ QCOMPARE(incubator.statuses.count(), 3);
+ QCOMPARE(incubator.statuses.at(0), int(QDeclarativeIncubator::Loading));
+ QCOMPARE(incubator.statuses.at(1), -1);
+ QCOMPARE(incubator.statuses.at(2), int(QDeclarativeIncubator::Ready));
+ delete incubator.object();
+ }
+}
+
+void tst_qdeclarativeincubator::asynchronousIfNested()
+{
+ // Asynchronous if nested within a finalized context behaves synchronously
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("asynchronousIfNested.1.qml"));
+ QVERIFY(component.isReady());
+
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QCOMPARE(object->property("a").toInt(), 10);
+
+ QDeclarativeIncubator incubator(QDeclarativeIncubator::AsynchronousIfNested);
+ component.create(incubator, 0, qmlContext(object));
+
+ QVERIFY(incubator.isReady());
+ QVERIFY(incubator.object());
+ QCOMPARE(incubator.object()->property("a").toInt(), 10);
+ delete incubator.object();
+ delete object;
+ }
+
+ // Asynchronous if nested within an executing context behaves asynchronously, but prevents
+ // the parent from finishing
+ {
+ SelfRegisteringType::clearMe();
+
+ QDeclarativeComponent component(&engine, TEST_FILE("asynchronousIfNested.2.qml"));
+ QVERIFY(component.isReady());
+
+ QDeclarativeIncubator incubator;
+ component.create(incubator);
+
+ QVERIFY(incubator.isLoading());
+ QVERIFY(SelfRegisteringType::me() == 0);
+ while (SelfRegisteringType::me() == 0 && incubator.isLoading()) {
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(SelfRegisteringType::me() != 0);
+ QVERIFY(incubator.isLoading());
+
+ QDeclarativeIncubator nested(QDeclarativeIncubator::AsynchronousIfNested);
+ component.create(nested, 0, qmlContext(SelfRegisteringType::me()));
+ QVERIFY(nested.isLoading());
+
+ while (nested.isLoading()) {
+ QVERIFY(incubator.isLoading());
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(nested.isReady());
+ QVERIFY(incubator.isLoading());
+
+ {
+ bool b = true;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(nested.isReady());
+ QVERIFY(incubator.isReady());
+
+ delete nested.object();
+ delete incubator.object();
+ }
+
+ // AsynchronousIfNested within a synchronous AsynchronousIfNested behaves synchronously
+ {
+ SelfRegisteringType::clearMe();
+
+ QDeclarativeComponent component(&engine, TEST_FILE("asynchronousIfNested.3.qml"));
+ QVERIFY(component.isReady());
+
+ struct CallbackData {
+ CallbackData(QDeclarativeEngine *e) : engine(e), pass(false) {}
+ QDeclarativeEngine *engine;
+ bool pass;
+ static void callback(CallbackRegisteringType *o, void *data) {
+ CallbackData *d = (CallbackData *)data;
+
+ QDeclarativeComponent c(d->engine, TEST_FILE("asynchronousIfNested.1.qml"));
+ if (!c.isReady()) return;
+
+ QDeclarativeIncubator incubator(QDeclarativeIncubator::AsynchronousIfNested);
+ c.create(incubator, 0, qmlContext(o));
+
+ if (!incubator.isReady()) return;
+
+ if (incubator.object()->property("a").toInt() != 10) return;
+
+ d->pass = true;
+ }
+ };
+
+ CallbackData cd(&engine);
+ CallbackRegisteringType::registerCallback(&CallbackData::callback, &cd);
+
+ QDeclarativeIncubator incubator(QDeclarativeIncubator::AsynchronousIfNested);
+ component.create(incubator);
+
+ QVERIFY(incubator.isReady());
+ QCOMPARE(cd.pass, true);
+
+ delete incubator.object();
+ }
+}
+
+void tst_qdeclarativeincubator::nestedComponent()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("nestedComponent.qml"));
+ QVERIFY(component.isReady());
+
+ QObject *object = component.create();
+
+ QDeclarativeComponent *nested = object->property("c").value<QDeclarativeComponent*>();
+ QVERIFY(nested);
+ QVERIFY(nested->isReady());
+
+ // Test without incubator
+ {
+ QObject *nestedObject = nested->create();
+ QCOMPARE(nestedObject->property("value").toInt(), 19988);
+ delete nestedObject;
+ }
+
+ // Test with incubator
+ {
+ QDeclarativeIncubator incubator(QDeclarativeIncubator::Synchronous);
+ nested->create(incubator);
+ QVERIFY(incubator.isReady());
+ QVERIFY(incubator.object());
+ QCOMPARE(incubator.object()->property("value").toInt(), 19988);
+ delete incubator.object();
+ }
+
+ delete object;
+}
+
+// Checks that a new AsynchronousIfNested incubator can be correctly started in the
+// statusChanged() callback of another.
+void tst_qdeclarativeincubator::chainedAsynchronousIfNested()
+{
+ SelfRegisteringType::clearMe();
+
+ QDeclarativeComponent component(&engine, TEST_FILE("chainedAsynchronousIfNested.qml"));
+ QVERIFY(component.isReady());
+
+ QDeclarativeIncubator incubator(QDeclarativeIncubator::Asynchronous);
+ component.create(incubator);
+
+ QVERIFY(incubator.isLoading());
+ QVERIFY(SelfRegisteringType::me() == 0);
+
+ while (SelfRegisteringType::me() == 0 && incubator.isLoading()) {
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(SelfRegisteringType::me() != 0);
+ QVERIFY(incubator.isLoading());
+
+ struct MyIncubator : public QDeclarativeIncubator {
+ MyIncubator(MyIncubator *next, QDeclarativeComponent *component, QDeclarativeContext *ctxt)
+ : QDeclarativeIncubator(AsynchronousIfNested), next(next), component(component), ctxt(ctxt) {}
+
+ protected:
+ virtual void statusChanged(Status s) {
+ if (s == Ready && next)
+ component->create(*next, 0, ctxt);
+ }
+
+ private:
+ MyIncubator *next;
+ QDeclarativeComponent *component;
+ QDeclarativeContext *ctxt;
+ };
+
+ MyIncubator incubator2(0, &component, 0);
+ MyIncubator incubator1(&incubator2, &component, qmlContext(SelfRegisteringType::me()));
+
+ component.create(incubator1, 0, qmlContext(SelfRegisteringType::me()));
+
+ QVERIFY(incubator.isLoading());
+ QVERIFY(incubator1.isLoading());
+ QVERIFY(incubator2.isNull());
+
+ while (incubator1.isLoading()) {
+ QVERIFY(incubator.isLoading());
+ QVERIFY(incubator1.isLoading());
+ QVERIFY(incubator2.isNull());
+
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(incubator.isLoading());
+ QVERIFY(incubator1.isReady());
+ QVERIFY(incubator2.isLoading());
+
+ while (incubator2.isLoading()) {
+ QVERIFY(incubator.isLoading());
+ QVERIFY(incubator1.isReady());
+ QVERIFY(incubator2.isLoading());
+
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(incubator.isLoading());
+ QVERIFY(incubator1.isReady());
+ QVERIFY(incubator2.isReady());
+
+ {
+ bool b = true;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(incubator.isReady());
+ QVERIFY(incubator1.isReady());
+ QVERIFY(incubator2.isReady());
+}
+
+void tst_qdeclarativeincubator::selfDelete()
+{
+ struct MyIncubator : public QDeclarativeIncubator {
+ MyIncubator(bool *done, Status status, IncubationMode mode)
+ : QDeclarativeIncubator(mode), done(done), status(status) {}
+
+ protected:
+ virtual void statusChanged(Status s) {
+ if (s == status) {
+ *done = true;
+ if (s == Ready) delete object();
+ delete this;
+ }
+ }
+
+ private:
+ bool *done;
+ Status status;
+ };
+
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("selfDelete.qml"));
+
+#define DELETE_TEST(status, mode) { \
+ bool done = false; \
+ component.create(*(new MyIncubator(&done, status, mode))); \
+ bool True = true; \
+ controller.incubateWhile(&True); \
+ QVERIFY(done == true); \
+ }
+
+ DELETE_TEST(QDeclarativeIncubator::Loading, QDeclarativeIncubator::Synchronous);
+ DELETE_TEST(QDeclarativeIncubator::Ready, QDeclarativeIncubator::Synchronous);
+ DELETE_TEST(QDeclarativeIncubator::Loading, QDeclarativeIncubator::Asynchronous);
+ DELETE_TEST(QDeclarativeIncubator::Ready, QDeclarativeIncubator::Asynchronous);
+
+#undef DELETE_TEST
+ }
+
+ // Delete within error status
+ {
+ SelfRegisteringType::clearMe();
+
+ QDeclarativeComponent component(&engine, TEST_FILE("objectDeleted.qml"));
+ QVERIFY(component.isReady());
+
+ bool done = false;
+ MyIncubator *incubator = new MyIncubator(&done, QDeclarativeIncubator::Error,
+ QDeclarativeIncubator::Asynchronous);
+ component.create(*incubator);
+
+ QCOMPARE(incubator->QDeclarativeIncubator::status(), QDeclarativeIncubator::Loading);
+ QVERIFY(SelfRegisteringType::me() == 0);
+
+ while (SelfRegisteringType::me() == 0 && incubator->isLoading()) {
+ bool b = false;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(SelfRegisteringType::me() != 0);
+ QVERIFY(incubator->isLoading());
+
+ delete SelfRegisteringType::me();
+
+ {
+ bool b = true;
+ controller.incubateWhile(&b);
+ }
+
+ QVERIFY(done);
+ }
+}
+
+QTEST_MAIN(tst_qdeclarativeincubator)
+
+#include "tst_qdeclarativeincubator.moc"
diff --git a/tests/auto/declarative/qdeclarativeinfo/qdeclarativeinfo.pro b/tests/auto/declarative/qdeclarativeinfo/qdeclarativeinfo.pro
index ddca3d3530..bd8d963f3f 100644
--- a/tests/auto/declarative/qdeclarativeinfo/qdeclarativeinfo.pro
+++ b/tests/auto/declarative/qdeclarativeinfo/qdeclarativeinfo.pro
@@ -1,18 +1,12 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative widgets
+CONFIG += testcase
+TARGET = tst_qdeclarativeinfo
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativeinfo.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-#temporary
-CONFIG += insignificant_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private widgets testlib
diff --git a/tests/auto/declarative/qdeclarativeinfo/tst_qdeclarativeinfo.cpp b/tests/auto/declarative/qdeclarativeinfo/tst_qdeclarativeinfo.cpp
index 71ff738619..ec04a83102 100644
--- a/tests/auto/declarative/qdeclarativeinfo/tst_qdeclarativeinfo.cpp
+++ b/tests/auto/declarative/qdeclarativeinfo/tst_qdeclarativeinfo.cpp
@@ -45,11 +45,7 @@
#include <QTimer>
#include <QDeclarativeContext>
#include <qdeclarativeinfo.h>
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class tst_qdeclarativeinfo : public QObject
{
@@ -73,7 +69,7 @@ private:
inline QUrl TEST_FILE(const QString &filename)
{
- return QUrl::fromLocalFile(QLatin1String(SRCDIR) + QLatin1String("/data/") + filename);
+ return QUrl::fromLocalFile(TESTDATA(filename));
}
void tst_qdeclarativeinfo::qmlObject()
diff --git a/tests/auto/declarative/qdeclarativeinstruction/qdeclarativeinstruction.pro b/tests/auto/declarative/qdeclarativeinstruction/qdeclarativeinstruction.pro
index 7cff542838..437b0869d1 100644
--- a/tests/auto/declarative/qdeclarativeinstruction/qdeclarativeinstruction.pro
+++ b/tests/auto/declarative/qdeclarativeinstruction/qdeclarativeinstruction.pro
@@ -1,12 +1,8 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qdeclarativeinstruction
SOURCES += tst_qdeclarativeinstruction.cpp
macx:CONFIG -= app_bundle
-!symbian: {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-
CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private
+QT += core-private gui-private v8-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp
index 98c5f7d9b0..ebe9253bae 100644
--- a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp
+++ b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp
@@ -42,11 +42,6 @@
#include <qtest.h>
#include <private/qdeclarativecompiler_p.h>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qdeclarativeinstruction : public QObject
{
Q_OBJECT
@@ -75,7 +70,9 @@ static void msgHandler(QtMsgType, const char *msg)
void tst_qdeclarativeinstruction::dump()
{
- QDeclarativeCompiledData *data = new QDeclarativeCompiledData(0);
+ QDeclarativeEngine engine;
+ QDeclarativeCompiledData *data = new QDeclarativeCompiledData(&engine);
+
{
QDeclarativeCompiledData::Instruction::Init i;
i.bindingsSize = 0;
@@ -90,10 +87,9 @@ void tst_qdeclarativeinstruction::dump()
ref.className = "Test";
data->types << ref;
- QDeclarativeCompiledData::Instruction::CreateObject i;
+ QDeclarativeCompiledData::Instruction::CreateCppObject i;
i.type = 0;
i.data = -1;
- i.bindingBits = -1;
i.column = 10;
data->addInstruction(i);
}
@@ -309,10 +305,10 @@ void tst_qdeclarativeinstruction::dump()
}
{
- data->datas << "mySignal";
+ data->primitives << "mySignal";
QDeclarativeCompiledData::Instruction::AssignSignalObject i;
- i.signal = 0;
+ i.signal = data->primitives.count() - 1;
data->addInstruction(i);
}
@@ -326,7 +322,7 @@ void tst_qdeclarativeinstruction::dump()
{
QDeclarativeCompiledData::Instruction::StoreBinding i;
- i.property = 26;
+ i.property.coreIndex = 26;
i.value = 3;
i.context = 2;
i.owner = 0;
@@ -344,7 +340,7 @@ void tst_qdeclarativeinstruction::dump()
{
QDeclarativeCompiledData::Instruction::StoreValueSource i;
- i.property = 29;
+ i.property.coreIndex = 29;
i.owner = 1;
i.castValue = 4;
data->addInstruction(i);
@@ -352,7 +348,7 @@ void tst_qdeclarativeinstruction::dump()
{
QDeclarativeCompiledData::Instruction::StoreValueInterceptor i;
- i.property = 30;
+ i.property.coreIndex = 30;
i.owner = 2;
i.castValue = -4;
data->addInstruction(i);
@@ -459,7 +455,7 @@ void tst_qdeclarativeinstruction::dump()
<< "Index\tOperation\t\tData1\tData2\tData3\tComments"
<< "-------------------------------------------------------------------------------"
<< "0\t\tINIT\t\t\t0\t3\t-1\t-1"
- << "1\t\tCREATE\t\t\t0\t-1\t\t\"Test\""
+ << "1\t\tCREATECPP\t\t\t0\t\t\t\"Test\""
<< "2\t\tSETID\t\t\t0\t\t\t\"testId\""
<< "3\t\tSET_DEFAULT"
<< "4\t\tCREATE_COMPONENT\t3"
@@ -487,7 +483,7 @@ void tst_qdeclarativeinstruction::dump()
<< "26\t\tSTORE_INTERFACE\t\t23"
<< "27\t\tSTORE_SIGNAL\t\t2\t3\t\t\"console.log(1921)\""
<< "28\t\tSTORE_SCRIPT_STRING\t24\t3\t1\t4"
- << "29\t\tASSIGN_SIGNAL_OBJECT\t0\t\t\t\"mySignal\""
+ << "29\t\tASSIGN_SIGNAL_OBJECT\t4\t\t\t\"mySignal\""
<< "30\t\tASSIGN_CUSTOMTYPE\t25\t6\t9"
<< "31\t\tSTORE_BINDING\t26\t3\t2"
<< "32\t\tSTORE_COMPILED_BINDING\t27\t2\t4"
@@ -513,6 +509,7 @@ void tst_qdeclarativeinstruction::dump()
messages = QStringList();
QtMsgHandler old = qInstallMsgHandler(msgHandler);
+
data->dumpInstructions();
qInstallMsgHandler(old);
diff --git a/tests/auto/declarative/qdeclarativelanguage/data/assignLiteralToVar.qml b/tests/auto/declarative/qdeclarativelanguage/data/assignLiteralToVar.qml
new file mode 100644
index 0000000000..65826dcc87
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelanguage/data/assignLiteralToVar.qml
@@ -0,0 +1,32 @@
+// This tests assigning literals to "var" properties.
+// These properties store JavaScript object references.
+
+import QtQuick 1.0
+
+QtObject {
+ property var test1: 1
+ property var test2: 1.7
+ property var test3: "Hello world!"
+ property var test4: "#FF008800"
+ property var test5: "10,10,10x10"
+ property var test6: "10,10"
+ property var test7: "10x10"
+ property var test8: "100,100,100"
+ property var test9: String("#FF008800")
+ property var test10: true
+ property var test11: false
+
+ property variant variantTest1Bound: test1 + 4 // 1 + 4 + 4 = 9
+
+ property var test12: Qt.rgba(0.2, 0.3, 0.4, 0.5)
+ property var test13: Qt.rect(10, 10, 10, 10)
+ property var test14: Qt.point(10, 10)
+ property var test15: Qt.size(10, 10)
+ property var test16: Qt.vector3d(100, 100, 100)
+
+ property var test1Bound: test1 + 6 // 1 + 4 + 6 = 11
+
+ Component.onCompleted: {
+ test1 = test1 + 4;
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/LocalInternal.qml b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/LocalInternal.qml
index 4ce04c46d2..4ce04c46d2 100644
--- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/LocalInternal.qml
+++ b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/LocalInternal.qml
diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/Test.qml b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/Test.qml
index f789a905f2..f789a905f2 100644
--- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/Test.qml
+++ b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/Test.qml
diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/TestLocal.qml b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/TestLocal.qml
index 11443ca6d5..11443ca6d5 100644
--- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/TestLocal.qml
+++ b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/TestLocal.qml
diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/TestNamed.qml b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/TestNamed.qml
index 672cb8f201..672cb8f201 100644
--- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/TestNamed.qml
+++ b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/TestNamed.qml
diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/TestSubDir.qml b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/TestSubDir.qml
index 0dfede4093..0dfede4093 100644
--- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/TestSubDir.qml
+++ b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/TestSubDir.qml
diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/UndeclaredLocal.qml b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/UndeclaredLocal.qml
index 4ce04c46d2..4ce04c46d2 100644
--- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/UndeclaredLocal.qml
+++ b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/UndeclaredLocal.qml
diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/WrongTestLocal.qml b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/WrongTestLocal.qml
index 8dcb7be231..8dcb7be231 100644
--- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/WrongTestLocal.qml
+++ b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/WrongTestLocal.qml
diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/noqmldir/Test.qml b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/noqmldir/Test.qml
index f789a905f2..f789a905f2 100644
--- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/noqmldir/Test.qml
+++ b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/noqmldir/Test.qml
diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/pics/blue.png b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/pics/blue.png
index 46f815f1ed..46f815f1ed 100644
--- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/pics/blue.png
+++ b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/pics/blue.png
Binary files differ
diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/qmldir
index 60150f837c..60150f837c 100644
--- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir
+++ b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/qmldir
diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/subdir/SubTest.qml b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/subdir/SubTest.qml
index 1480ae8683..1480ae8683 100644
--- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/subdir/SubTest.qml
+++ b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/subdir/SubTest.qml
diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/subdir/qmldir b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/subdir/qmldir
index a54f7dfa61..a54f7dfa61 100644
--- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/subdir/qmldir
+++ b/tests/auto/declarative/qdeclarativelanguage/data/qtest/declarative/qmllanguage/subdir/qmldir
diff --git a/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro b/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro
index e6006aed00..105e2b44d6 100644
--- a/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro
+++ b/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro
@@ -1,6 +1,5 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
-QT += network
+CONFIG += testcase
+TARGET = tst_qdeclarativelanguage
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativelanguage.cpp \
@@ -11,13 +10,9 @@ INCLUDEPATH += ../shared/
HEADERS += ../shared/testhttpserver.h
SOURCES += ../shared/testhttpserver.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+importFiles.files = data
+importFiles.path = .
+DEPLOYMENT += importFiles
CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private
+QT += core-private gui-private v8-private declarative-private network testlib
diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
index 5e9bc418cc..bde2c14fd9 100644
--- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
+++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
@@ -41,6 +41,7 @@
#include <qtest.h>
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtCore/qcoreapplication.h>
#include <QtCore/qfile.h>
#include <QtCore/qdebug.h>
#include <QtCore/qfileinfo.h>
@@ -51,17 +52,35 @@
#include <private/qdeclarativeglobal_p.h>
#include "testtypes.h"
-
-#include "../../../shared/util.h"
#include "testhttpserver.h"
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
DEFINE_BOOL_CONFIG_OPTION(qmlCheckTypes, QML_CHECK_TYPES)
+/*
+ Returns the path to some testdata file or directory.
+*/
+QString testdata(QString const& name = QString())
+{
+ /*
+ Try to find it relative to the binary.
+ Note we are looking for a _directory_ which exists, but the _file_ itself need not exist,
+ to support the case of finding a path to a testdata file which doesn't exist yet (i.e.
+ a file we are about to create).
+ */
+ QFileInfo relative = QDir(QCoreApplication::applicationDirPath()).filePath(QLatin1String("data/") + name);
+ if (relative.dir().exists()) {
+ return relative.absoluteFilePath();
+ }
+
+ qWarning("requested testdata %s could not be found (looked at %s)",
+ qPrintable(name),
+ qPrintable(relative.filePath())
+ );
+
+ // Chances are the calling test will now fail.
+ return QString();
+}
+
/*
This test case covers QML language issues. This covers everything that does not
@@ -75,8 +94,7 @@ class tst_qdeclarativelanguage : public QObject
public:
tst_qdeclarativelanguage() {
QDeclarativeMetaType::registerCustomStringConverter(qMetaTypeId<MyCustomVariantType>(), myCustomVariantTypeConverter);
- QFileInfo fileInfo(__FILE__);
- engine.addImportPath(fileInfo.absoluteDir().filePath(QLatin1String("data/lib")));
+ engine.addImportPath(testdata("lib"));
}
private slots:
@@ -101,6 +119,7 @@ private slots:
void assignTypeExtremes();
void assignCompositeToType();
void assignLiteralToVariant();
+ void assignLiteralToVar();
void customParserTypes();
void rootAsQmlComponent();
void inlineQmlComponents();
@@ -178,7 +197,7 @@ private:
QVERIFY(!component.isError()); \
QVERIFY(component.errors().isEmpty()); \
} else { \
- QFile file(QLatin1String(SRCDIR) + QLatin1String("/data/") + QLatin1String(errorfile)); \
+ QFile file(testdata(QLatin1String(errorfile))); \
QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); \
QByteArray data = file.readAll(); \
file.close(); \
@@ -209,8 +228,7 @@ private:
inline QUrl TEST_FILE(const QString &filename)
{
- QFileInfo fileInfo(__FILE__);
- return QUrl::fromLocalFile(fileInfo.absoluteDir().filePath(QLatin1String("data/") + filename));
+ return QUrl::fromLocalFile(testdata(filename));
}
inline QUrl TEST_FILE(const char *filename)
@@ -629,6 +647,57 @@ void tst_qdeclarativelanguage::assignLiteralToVariant()
delete object;
}
+// Test that literals are stored correctly in "var" properties
+// Note that behaviour differs from "variant" properties in that
+// no conversion from "special strings" to QVariants is performed.
+void tst_qdeclarativelanguage::assignLiteralToVar()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("assignLiteralToVar.qml"));
+ VERIFY_ERRORS(0);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("test1").userType(), (int)QMetaType::Int);
+ QCOMPARE(object->property("test2").userType(), (int)QMetaType::Double);
+ QCOMPARE(object->property("test3").userType(), (int)QVariant::String);
+ QCOMPARE(object->property("test4").userType(), (int)QVariant::String);
+ QCOMPARE(object->property("test5").userType(), (int)QVariant::String);
+ QCOMPARE(object->property("test6").userType(), (int)QVariant::String);
+ QCOMPARE(object->property("test7").userType(), (int)QVariant::String);
+ QCOMPARE(object->property("test8").userType(), (int)QVariant::String);
+ QCOMPARE(object->property("test9").userType(), (int)QVariant::String);
+ QCOMPARE(object->property("test10").userType(), (int)QVariant::Bool);
+ QCOMPARE(object->property("test11").userType(), (int)QVariant::Bool);
+ QCOMPARE(object->property("test12").userType(), (int)QVariant::Color);
+ QCOMPARE(object->property("test13").userType(), (int)QVariant::RectF);
+ QCOMPARE(object->property("test14").userType(), (int)QVariant::PointF);
+ QCOMPARE(object->property("test15").userType(), (int)QVariant::SizeF);
+ QCOMPARE(object->property("test16").userType(), (int)QVariant::Vector3D);
+ QCOMPARE(object->property("variantTest1Bound").userType(), (int)QMetaType::Int);
+ QCOMPARE(object->property("test1Bound").userType(), (int)QMetaType::Int);
+
+ QCOMPARE(object->property("test1"), QVariant(5));
+ QCOMPARE(object->property("test2"), QVariant((double)1.7));
+ QCOMPARE(object->property("test3"), QVariant(QString(QLatin1String("Hello world!"))));
+ QCOMPARE(object->property("test4"), QVariant(QString(QLatin1String("#FF008800"))));
+ QCOMPARE(object->property("test5"), QVariant(QString(QLatin1String("10,10,10x10"))));
+ QCOMPARE(object->property("test6"), QVariant(QString(QLatin1String("10,10"))));
+ QCOMPARE(object->property("test7"), QVariant(QString(QLatin1String("10x10"))));
+ QCOMPARE(object->property("test8"), QVariant(QString(QLatin1String("100,100,100"))));
+ QCOMPARE(object->property("test9"), QVariant(QString(QLatin1String("#FF008800"))));
+ QCOMPARE(object->property("test10"), QVariant(bool(true)));
+ QCOMPARE(object->property("test11"), QVariant(bool(false)));
+ QCOMPARE(object->property("test12"), QVariant(QColor::fromRgbF(0.2, 0.3, 0.4, 0.5)));
+ QCOMPARE(object->property("test13"), QVariant(QRectF(10, 10, 10, 10)));
+ QCOMPARE(object->property("test14"), QVariant(QPointF(10, 10)));
+ QCOMPARE(object->property("test15"), QVariant(QSizeF(10, 10)));
+ QCOMPARE(object->property("test16"), QVariant(QVector3D(100, 100, 100)));
+ QCOMPARE(object->property("variantTest1Bound"), QVariant(9));
+ QCOMPARE(object->property("test1Bound"), QVariant(11));
+
+ delete object;
+}
+
// Tests that custom parser types can be instantiated
void tst_qdeclarativelanguage::customParserTypes()
{
@@ -1642,7 +1711,7 @@ void tst_qdeclarativelanguage::basicRemote()
QFETCH(QString, error);
TestHTTPServer server(14447);
- server.serveDirectory(SRCDIR);
+ server.serveDirectory(testdata());
QDeclarativeComponent component(&engine, url);
@@ -1686,7 +1755,7 @@ void tst_qdeclarativelanguage::importsRemote()
QFETCH(QString, error);
TestHTTPServer server(14447);
- server.serveDirectory(SRCDIR);
+ server.serveDirectory(testdata());
testType(qml,type,error);
}
@@ -1847,7 +1916,7 @@ void tst_qdeclarativelanguage::importIncorrectCase()
QCOMPARE(errors.count(), 1);
#if defined(Q_OS_MAC) || defined(Q_OS_WIN32)
- QString expectedError = QLatin1String("cannot load module \"com.Nokia.installedtest\": File name case mismatch for \"") + QFileInfo(__FILE__).absoluteDir().filePath("data/lib/com/Nokia/installedtest/qmldir") + QLatin1String("\"");
+ QString expectedError = QLatin1String("cannot load module \"com.Nokia.installedtest\": File name case mismatch for \"") + testdata("lib/com/Nokia/installedtest/qmldir") + QLatin1String("\"");
#else
QString expectedError = QLatin1String("module \"com.Nokia.installedtest\" is not installed");
#endif
@@ -2077,10 +2146,10 @@ void tst_qdeclarativelanguage::registrationOrder()
void tst_qdeclarativelanguage::remoteLoadCrash()
{
TestHTTPServer server(14448);
- server.serveDirectory(SRCDIR);
+ server.serveDirectory(testdata());
QDeclarativeComponent component(&engine);
- component.setData("import QtQuick 1.0; Text {}", QUrl("http://127.0.0.1:14448/data/remoteLoadCrash.qml"));
+ component.setData("import QtQuick 1.0; Text {}", QUrl("http://127.0.0.1:14448/remoteLoadCrash.qml"));
while (component.isLoading())
QCoreApplication::processEvents( QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents, 50);
diff --git a/tests/auto/declarative/qdeclarativelistcompositor/qdeclarativelistcompositor.pro b/tests/auto/declarative/qdeclarativelistcompositor/qdeclarativelistcompositor.pro
new file mode 100644
index 0000000000..e8dd7dd83a
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelistcompositor/qdeclarativelistcompositor.pro
@@ -0,0 +1,9 @@
+CONFIG += testcase
+TARGET = tst_qdeclarativelistcompositor
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qdeclarativelistcompositor.cpp
+
+CONFIG += parallel_test
+
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativelistcompositor/tst_qdeclarativelistcompositor.cpp b/tests/auto/declarative/qdeclarativelistcompositor/tst_qdeclarativelistcompositor.cpp
new file mode 100644
index 0000000000..67bced6da8
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelistcompositor/tst_qdeclarativelistcompositor.cpp
@@ -0,0 +1,1322 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qtest.h>
+#include <private/qdeclarativelistcompositor_p.h>
+
+template<typename T, int N> int lengthOf(const T (&)[N]) { return N; }
+
+typedef QDeclarativeListCompositor C;
+
+struct Range
+{
+ Range() {}
+ Range(void *list, int index, int count, int flags)
+ : list(list), index(index), count(count), flags(flags) {}
+ void *list;
+ int index;
+ int count;
+ int flags;
+};
+
+template <typename T> struct Array
+{
+ Array() : array(0), count(0) {}
+ template<int N> Array(const T (&array)[N]) : array(array), count(N) {}
+
+ T operator [](int index) const { return array[index]; }
+
+ const T *array;
+ int count;
+};
+
+typedef Array<int> IndexArray;
+typedef Array<const void *> ListArray;
+
+typedef QVector<QDeclarativeListCompositor::Remove> RemoveList;
+typedef QVector<QDeclarativeListCompositor::Insert> InsertList;
+typedef QVector<QDeclarativeListCompositor::Change> ChangeList;
+
+typedef QVector<Range> RangeList;
+
+Q_DECLARE_METATYPE(RangeList)
+Q_DECLARE_METATYPE(RemoveList)
+Q_DECLARE_METATYPE(InsertList)
+Q_DECLARE_METATYPE(ChangeList)
+Q_DECLARE_METATYPE(void *)
+Q_DECLARE_METATYPE(IndexArray)
+Q_DECLARE_METATYPE(ListArray)
+Q_DECLARE_METATYPE(C::Group)
+
+bool operator ==(const C::Change &left, const C::Change &right)
+{
+ return left.index[3] == right.index[3]
+ && left.index[2] == right.index[2]
+ && left.index[1] == right.index[1]
+ && left.index[0] == right.index[0]
+ && left.count == right.count
+ && left.groups() == right.groups()
+ && left.inCache() == right.inCache()
+ && (left.moveId == -1) == (right.moveId == -1);
+}
+
+static const C::Group Visible = C::Group(2);
+static const C::Group Selection = C::Group(3);
+
+class tst_qdeclarativelistcompositor : public QObject
+{
+ Q_OBJECT
+
+ enum {
+ VisibleFlag = 0x04,
+ SelectionFlag = 0x08
+ };
+
+ void populateChange(
+ C::Change &change, int sIndex, int vIndex, int dIndex, int cIndex, int count, int flags, int moveId)
+ {
+ change.index[Selection] = sIndex;
+ change.index[Visible] = vIndex;
+ change.index[C::Default] = dIndex;
+ change.index[C::Cache] = cIndex;
+ change.count = count;
+ change.flags = flags;
+ change.moveId = moveId;
+ }
+
+ C::Remove Remove(
+ int sIndex, int vIndex, int dIndex, int cIndex, int count, int flags, int moveId = -1)
+ {
+ C::Remove remove;
+ populateChange(remove, sIndex, vIndex, dIndex, cIndex, count, flags, moveId);
+ return remove;
+ }
+
+ C::Insert Insert(
+ int sIndex, int vIndex, int dIndex, int cIndex, int count, int flags, int moveId = -1)
+ {
+ C::Insert insert;
+ populateChange(insert, sIndex, vIndex, dIndex, cIndex, count, flags, moveId);
+ return insert;
+ }
+
+ C::Change Change(
+ int sIndex, int vIndex, int dIndex, int cIndex, int count, int flags, int moveId = -1)
+ {
+ C::Change change;
+ populateChange(change, sIndex, vIndex, dIndex, cIndex, count, flags, moveId);
+ return change;
+ }
+
+private slots:
+ void insert();
+ void clearFlags_data();
+ void clearFlags();
+ void setFlags_data();
+ void setFlags();
+ void move_data();
+ void move();
+ void clear();
+ void listItemsInserted_data();
+ void listItemsInserted();
+ void listItemsRemoved_data();
+ void listItemsRemoved();
+ void listItemsMoved_data();
+ void listItemsMoved();
+ void listItemsChanged_data();
+ void listItemsChanged();
+};
+
+void tst_qdeclarativelistcompositor::insert()
+{
+ QDeclarativeListCompositor compositor;
+ compositor.setGroupCount(4);
+ compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
+
+ C::iterator it;
+
+ int listA; int *a = &listA;
+ int listB; int *b = &listB;
+ int listC; int *c = &listC;
+
+ {
+ compositor.append(a, 0, 12, C::AppendFlag | C::PrependFlag | C::DefaultFlag);
+ const int indexes[] = {0,1,2,3,4,5,6,7,8,9,10,11};
+ const int *lists[] = {a,a,a,a,a,a,a,a,a,a, a, a};
+ QCOMPARE(compositor.count(C::Default), lengthOf(indexes));
+ for (int i = 0; i < lengthOf(indexes); ++i) {
+ it = compositor.find(C::Default, i);
+ QCOMPARE(it.list<int>(), lists[i]);
+ if (lists[i]) QCOMPARE(it.modelIndex(), indexes[i]);
+ }
+ } {
+ compositor.append(b, 4, 4, C::DefaultFlag);
+ const int indexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,4,5,6,7};
+ const int *lists[] = {a,a,a,a,a,a,a,a,a,a, a, a,b,b,b,b};
+ QCOMPARE(compositor.count(C::Default), lengthOf(indexes));
+ for (int i = 0; i < lengthOf(indexes); ++i) {
+ it = compositor.find(C::Default, i);
+ QCOMPARE(it.list<int>(), lists[i]);
+ if (lists[i]) QCOMPARE(it.modelIndex(), indexes[i]);
+ }
+ } { // Insert at end.
+ compositor.insert(
+ C::Default, 16, c, 2, 2, C::DefaultFlag);
+ const int indexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,4,5,6,7,2,3};
+ const int *lists[] = {a,a,a,a,a,a,a,a,a,a, a, a,b,b,b,b,c,c};
+ QCOMPARE(compositor.count(C::Default), lengthOf(indexes));
+ for (int i = 0; i < lengthOf(indexes); ++i) {
+ it = compositor.find(C::Default, i);
+ QCOMPARE(it.list<int>(), lists[i]);
+ if (lists[i]) QCOMPARE(it.modelIndex(), indexes[i]);
+ }
+ } { // Insert at start
+ compositor.insert(
+ C::Default, 0, c, 6, 4, C::DefaultFlag);
+ const int indexes[] = {6,7,8,9,0,1,2,3,4,5,6,7,8,9,10,11,4,5,6,7,2,3};
+ const int *lists[] = {c,c,c,c,a,a,a,a,a,a,a,a,a,a, a, a,b,b,b,b,c,c};
+ QCOMPARE(compositor.count(C::Default), lengthOf(indexes));
+ for (int i = 0; i < lengthOf(indexes); ++i) {
+ it = compositor.find(C::Default, i);
+ QCOMPARE(it.list<int>(), lists[i]);
+ if (lists[i]) QCOMPARE(it.modelIndex(), indexes[i]);
+ }
+ } { // Insert after static range.
+ compositor.insert(
+ C::Default, 4, b, 0, 8, C::AppendFlag | C::PrependFlag | C::DefaultFlag);
+ const int indexes[] = {6,7,8,9,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,8,9,10,11,4,5,6,7,2,3};
+ const int *lists[] = {c,c,c,c,b,b,b,b,b,b,b,b,a,a,a,a,a,a,a,a,a,a, a, a,b,b,b,b,c,c};
+ QCOMPARE(compositor.count(C::Default), lengthOf(indexes));
+ for (int i = 0; i < lengthOf(indexes); ++i) {
+ it = compositor.find(C::Default, i);
+ QCOMPARE(it.list<int>(), lists[i]);
+ if (lists[i]) QCOMPARE(it.modelIndex(), indexes[i]);
+ }
+ } { // Insert at end of dynamic range.
+ compositor.insert(
+ C::Default, 12, c, 0, 4, C::AppendFlag | C::PrependFlag | C::DefaultFlag);
+ const int indexes[] = {6,7,8,9,0,1,2,3,4,5,6,7,0,1,2,3,0,1,2,3,4,5,6,7,8,9,10,11,4,5,6,7,2,3};
+ const int *lists[] = {c,c,c,c,b,b,b,b,b,b,b,b,c,c,c,c,a,a,a,a,a,a,a,a,a,a, a, a,b,b,b,b,c,c};
+ QCOMPARE(compositor.count(C::Default), lengthOf(indexes));
+ for (int i = 0; i < lengthOf(indexes); ++i) {
+ it = compositor.find(C::Default, i);
+ QCOMPARE(it.list<int>(), lists[i]);
+ if (lists[i]) QCOMPARE(it.modelIndex(), indexes[i]);
+ }
+ } { // Insert into range.
+ compositor.insert(
+ C::Default, 8, c, 0, 4, C::AppendFlag | C::PrependFlag | C::DefaultFlag);
+ const int indexes[] = {6,7,8,9,0,1,2,3,0,1,2,3,4,5,6,7,0,1,2,3,0,1,2,3,4,5,6,7,8,9,10,11,4,5,6,7,2,3};
+ const int *lists[] = {c,c,c,c,b,b,b,b,c,c,c,c,b,b,b,b,c,c,c,c,a,a,a,a,a,a,a,a,a,a, a, a,b,b,b,b,c,c};
+ QCOMPARE(compositor.count(C::Default), lengthOf(indexes));
+ for (int i = 0; i < lengthOf(indexes); ++i) {
+ it = compositor.find(C::Default, i);
+ QCOMPARE(it.list<int>(), lists[i]);
+ if (lists[i]) QCOMPARE(it.modelIndex(), indexes[i]);
+ }
+ }
+}
+
+void tst_qdeclarativelistcompositor::clearFlags_data()
+{
+ QTest::addColumn<RangeList>("ranges");
+ QTest::addColumn<C::Group>("group");
+ QTest::addColumn<int>("index");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<int>("flags");
+ QTest::addColumn<RemoveList>("expectedRemoves");
+ QTest::addColumn<IndexArray>("cacheIndexes");
+ QTest::addColumn<ListArray>("cacheLists");
+ QTest::addColumn<IndexArray>("defaultIndexes");
+ QTest::addColumn<ListArray>("defaultLists");
+ QTest::addColumn<IndexArray>("visibleIndexes");
+ QTest::addColumn<ListArray>("visibleLists");
+ QTest::addColumn<IndexArray>("selectionIndexes");
+ QTest::addColumn<ListArray>("selectionLists");
+
+ int listA; void *a = &listA;
+
+ { static const int cacheIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,0,0,0,0};
+ static const void *cacheLists[] = {a,a,a,a,a,a,a,a,a,a, a, a,0,0,0,0};
+ static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,0,0,0,0};
+ static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a, a,0,0,0,0};
+ static const int visibleIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,0,0,0,0};
+ static const void *visibleLists[] = {a,a,a,a,a,a,a,a,a,a, a, a,0,0,0,0};
+ static const int selectionIndexes[] = {0,1,4,5,6,7,8,9,10,11,0,0,0,0};
+ static const void *selectionLists[] = {a,a,a,a,a,a,a,a, a, a,0,0,0,0};
+ QTest::newRow("Default, 2, 2, Selection")
+ << (RangeList()
+ << Range(a, 0, 12, int(C::AppendFlag | C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(0, 0, 4, int(SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)))
+ << C::Default << 2 << 2 << int(SelectionFlag)
+ << (RemoveList()
+ << Remove(2, 2, 2, 2, 2, SelectionFlag | C::CacheFlag))
+ << IndexArray(cacheIndexes) << ListArray(cacheLists)
+ << IndexArray(defaultIndexes) << ListArray(defaultLists)
+ << IndexArray(visibleIndexes) << ListArray(visibleLists)
+ << IndexArray(selectionIndexes) << ListArray(selectionLists);
+ } { static const int cacheIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,0,0,0,0};
+ static const void *cacheLists[] = {a,a,a,a,a,a,a,a,a,a, a, a,0,0,0,0};
+ static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,0,0,0,0};
+ static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a, a,0,0,0,0};
+ static const int visibleIndexes[] = {0,2,3,5,6,7,8,9,10,11,0,0,0,0};
+ static const void *visibleLists[] = {a,a,a,a,a,a,a,a, a, a,0,0,0,0};
+ static const int selectionIndexes[] = {0,1,4,5,6,7,8,9,10,11,0,0,0,0};
+ static const void *selectionLists[] = {a,a,a,a,a,a,a,a, a, a,0,0,0,0};
+ QTest::newRow("Selection, 1, 2, Visible")
+ << (RangeList()
+ << Range(a, 0, 2, int(C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(a, 2, 2, int(C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(a, 4, 8, int(C::AppendFlag | C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(0, 0, 4, int(SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)))
+ << Selection << 1 << 2 << int(VisibleFlag)
+ << (RemoveList()
+ << Remove(1, 1, 1, 1, 1, VisibleFlag | C::CacheFlag)
+ << Remove(2, 3, 4, 4, 1, VisibleFlag | C::CacheFlag))
+ << IndexArray(cacheIndexes) << ListArray(cacheLists)
+ << IndexArray(defaultIndexes) << ListArray(defaultLists)
+ << IndexArray(visibleIndexes) << ListArray(visibleLists)
+ << IndexArray(selectionIndexes) << ListArray(selectionLists);
+ } { static const int cacheIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,0,0,0,0};
+ static const void *cacheLists[] = {a,a,a,a,a,a,a,a,a,a, a, a,0,0,0,0};
+ static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,0,0,0};
+ static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a, a,0,0,0};
+ static const int visibleIndexes[] = {0,2,3,5,6,7,8,9,10,11,0,0,0};
+ static const void *visibleLists[] = {a,a,a,a,a,a,a,a, a, a,0,0,0};
+ static const int selectionIndexes[] = {0,1,4,5,6,7,8,9,10,11,0,0,0};
+ static const void *selectionLists[] = {a,a,a,a,a,a,a,a, a, a,0,0,0};
+ QTest::newRow("Default, 13, 1, Prepend | Selection | Visible | Default")
+ << (RangeList()
+ << Range(a, 0, 1, int(C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(a, 1, 1, int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(a, 2, 2, int(C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(a, 4, 1, int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(a, 5, 7, int(C::AppendFlag | C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(0, 0, 4, int(SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)))
+ << C::Default << 13 << 1 << int(C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag)
+ << (RemoveList()
+ << Remove(11, 11, 13, 13, 1, SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
+ << IndexArray(cacheIndexes) << ListArray(cacheLists)
+ << IndexArray(defaultIndexes) << ListArray(defaultLists)
+ << IndexArray(visibleIndexes) << ListArray(visibleLists)
+ << IndexArray(selectionIndexes) << ListArray(selectionLists);
+ } { static const int cacheIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,0};
+ static const void *cacheLists[] = {a,a,a,a,a,a,a,a,a,a, a,0};
+ static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11,0,0,0};
+ static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a, a,0,0,0};
+ static const int visibleIndexes[] = {0,2,3,5,6,7,8,9,10,11,0,0,0};
+ static const void *visibleLists[] = {a,a,a,a,a,a,a,a, a, a,0,0,0};
+ static const int selectionIndexes[] = {0,1,4,5,6,7,8,9,10,11,0,0,0};
+ static const void *selectionLists[] = {a,a,a,a,a,a,a,a, a, a,0,0,0};
+ QTest::newRow("Cache, 11, 4, Cache")
+ << (RangeList()
+ << Range(a, 0, 1, int(C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(a, 1, 1, int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(a, 2, 2, int(C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(a, 4, 1, int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(a, 5, 7, int(C::AppendFlag | C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(0, 0, 1, int(C::CacheFlag))
+ << Range(0, 0, 3, int(SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)))
+ << C::Cache << 11 << 4 << int(C::CacheFlag)
+ << (RemoveList())
+ << IndexArray(cacheIndexes) << ListArray(cacheLists)
+ << IndexArray(defaultIndexes) << ListArray(defaultLists)
+ << IndexArray(visibleIndexes) << ListArray(visibleLists)
+ << IndexArray(selectionIndexes) << ListArray(selectionLists);
+ } { static const int cacheIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,0};
+ static const void *cacheLists[] = {a,a,a,a,a,a,a,a,a,a, a,0};
+ static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,0};
+ static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a,0};
+ static const int visibleIndexes[] = {0,2,3,5,6,7,8,9,10,0};
+ static const void *visibleLists[] = {a,a,a,a,a,a,a,a, a,0};
+ static const int selectionIndexes[] = {0,1,4,5,6,7,8,9,10,0};
+ static const void *selectionLists[] = {a,a,a,a,a,a,a,a, a,0};
+ QTest::newRow("Default, 11, 3, Default | Visible | Selection")
+ << (RangeList()
+ << Range(a, 0, 1, int(C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(a, 1, 1, int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(a, 2, 2, int(C::PrependFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(a, 4, 1, int(C::PrependFlag | SelectionFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(a, 5, 6, int(C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag))
+ << Range(a, 11, 1, int(C::AppendFlag | C::PrependFlag | SelectionFlag | VisibleFlag | C::DefaultFlag))
+ << Range(0, 0, 2, int(SelectionFlag | VisibleFlag | C::DefaultFlag))
+ << Range(0, 0, 1, int(SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)))
+ << C::Default << 11 << 3 << int(C::DefaultFlag | VisibleFlag| SelectionFlag)
+ << (RemoveList()
+ << Remove(9, 9, 11, 11, 1, SelectionFlag | VisibleFlag | C::DefaultFlag)
+ << Remove(9, 9, 11, 11, 2, SelectionFlag | VisibleFlag | C::DefaultFlag))
+ << IndexArray(cacheIndexes) << ListArray(cacheLists)
+ << IndexArray(defaultIndexes) << ListArray(defaultLists)
+ << IndexArray(visibleIndexes) << ListArray(visibleLists)
+ << IndexArray(selectionIndexes) << ListArray(selectionLists);
+ }
+}
+
+void tst_qdeclarativelistcompositor::clearFlags()
+{
+ QFETCH(RangeList, ranges);
+ QFETCH(C::Group, group);
+ QFETCH(int, index);
+ QFETCH(int, count);
+ QFETCH(int, flags);
+ QFETCH(RemoveList, expectedRemoves);
+ QFETCH(IndexArray, cacheIndexes);
+ QFETCH(ListArray, cacheLists);
+ QFETCH(IndexArray, defaultIndexes);
+ QFETCH(ListArray, defaultLists);
+ QFETCH(IndexArray, visibleIndexes);
+ QFETCH(ListArray, visibleLists);
+ QFETCH(IndexArray, selectionIndexes);
+ QFETCH(ListArray, selectionLists);
+
+ QDeclarativeListCompositor compositor;
+ compositor.setGroupCount(4);
+ compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
+
+ foreach (const Range &range, ranges)
+ compositor.append(range.list, range.index, range.count, range.flags);
+
+ QVector<C::Remove> removes;
+ compositor.clearFlags(group, index, count, flags, &removes);
+
+ QCOMPARE(removes, expectedRemoves);
+
+ QCOMPARE(compositor.count(C::Cache), cacheIndexes.count);
+ for (int i = 0; i < cacheIndexes.count; ++i) {
+ C::iterator it = compositor.find(C::Cache, i);
+ QCOMPARE(it->list, cacheLists[i]);
+ if (cacheLists[i])
+ QCOMPARE(it.modelIndex(), cacheIndexes[i]);
+ }
+ QCOMPARE(compositor.count(C::Default), defaultIndexes.count);
+ for (int i = 0; i < defaultIndexes.count; ++i) {
+ C::iterator it = compositor.find(C::Default, i);
+ QCOMPARE(it->list, defaultLists[i]);
+ if (defaultLists[i])
+ QCOMPARE(it.modelIndex(), defaultIndexes[i]);
+ }
+ QCOMPARE(compositor.count(Visible), visibleIndexes.count);
+ for (int i = 0; i < visibleIndexes.count; ++i) {
+ C::iterator it = compositor.find(Visible, i);
+ QCOMPARE(it->list, visibleLists[i]);
+ if (visibleLists[i])
+ QCOMPARE(it.modelIndex(), visibleIndexes[i]);
+ }
+ QCOMPARE(compositor.count(Selection), selectionIndexes.count);
+ for (int i = 0; i < selectionIndexes.count; ++i) {
+ C::iterator it = compositor.find(Selection, i);
+ QCOMPARE(it->list, selectionLists[i]);
+ if (selectionLists[i])
+ QCOMPARE(it.modelIndex(), selectionIndexes[i]);
+ }
+}
+
+void tst_qdeclarativelistcompositor::setFlags_data()
+{
+ QTest::addColumn<RangeList>("ranges");
+ QTest::addColumn<C::Group>("group");
+ QTest::addColumn<int>("index");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<int>("flags");
+ QTest::addColumn<InsertList>("expectedInserts");
+ QTest::addColumn<IndexArray>("cacheIndexes");
+ QTest::addColumn<ListArray>("cacheLists");
+ QTest::addColumn<IndexArray>("defaultIndexes");
+ QTest::addColumn<ListArray>("defaultLists");
+ QTest::addColumn<IndexArray>("visibleIndexes");
+ QTest::addColumn<ListArray>("visibleLists");
+ QTest::addColumn<IndexArray>("selectionIndexes");
+ QTest::addColumn<ListArray>("selectionLists");
+
+ int listA; void *a = &listA;
+
+ { static const int cacheIndexes[] = {0,0,0,0};
+ static const void *cacheLists[] = {0,0,0,0};
+ static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11};
+ static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a, a};
+ QTest::newRow("Default, 2, 2, Default")
+ << (RangeList()
+ << Range(a, 0, 12, C::DefaultFlag)
+ << Range(0, 0, 4, C::CacheFlag))
+ << C::Default << 2 << 2 << int(C::DefaultFlag)
+ << (InsertList())
+ << IndexArray(cacheIndexes) << ListArray(cacheLists)
+ << IndexArray(defaultIndexes) << ListArray(defaultLists)
+ << IndexArray() << ListArray()
+ << IndexArray() << ListArray();
+ } { static const int cacheIndexes[] = {0,0,0,0};
+ static const void *cacheLists[] = {0,0,0,0};
+ static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11};
+ static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a, a};
+ static const int visibleIndexes[] = {2,3};
+ static const void *visibleLists[] = {a,a};
+ QTest::newRow("Default, 2, 2, Visible")
+ << (RangeList()
+ << Range(a, 0, 12, C::DefaultFlag)
+ << Range(0, 0, 4, C::CacheFlag))
+ << C::Default << 2 << 2 << int(VisibleFlag)
+ << (InsertList()
+ << Insert(0, 0, 2, 0, 2, VisibleFlag))
+ << IndexArray(cacheIndexes) << ListArray(cacheLists)
+ << IndexArray(defaultIndexes) << ListArray(defaultLists)
+ << IndexArray(visibleIndexes) << ListArray(visibleLists)
+ << IndexArray() << ListArray();
+ } { static const int cacheIndexes[] = {3,6,0,0,0,0};
+ static const void *cacheLists[] = {a,a,0,0,0,0};
+ static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11};
+ static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a, a};
+ static const int visibleIndexes[] = {2,3,6,7};
+ static const void *visibleLists[] = {a,a,a,a};
+ static const int selectionIndexes[] = {3,6};
+ static const void *selectionLists[] = {a,a};
+ QTest::newRow("Visible, 1, 2, Selection | Cache")
+ << (RangeList()
+ << Range(a, 0, 2, C::DefaultFlag)
+ << Range(a, 2, 2, VisibleFlag | C::DefaultFlag)
+ << Range(a, 4, 2, C::DefaultFlag)
+ << Range(a, 6, 2, VisibleFlag | C::DefaultFlag)
+ << Range(a, 8, 4, C::DefaultFlag)
+ << Range(0, 0, 4, C::CacheFlag))
+ << Visible << 1 << 2 << int(SelectionFlag | C::CacheFlag)
+ << (InsertList()
+ << Insert(0, 1, 3, 0, 1, SelectionFlag | C::CacheFlag)
+ << Insert(1, 2, 6, 1, 1, SelectionFlag | C::CacheFlag))
+ << IndexArray(cacheIndexes) << ListArray(cacheLists)
+ << IndexArray(defaultIndexes) << ListArray(defaultLists)
+ << IndexArray(visibleIndexes) << ListArray(visibleLists)
+ << IndexArray(selectionIndexes) << ListArray(selectionLists);
+ } { static const int cacheIndexes[] = {3,6,0,0,0,0};
+ static const void *cacheLists[] = {a,a,0,0,0,0};
+ static const int defaultIndexes[] = {0,1,2,3,4,5,6,7,8,9,10,11};
+ static const void *defaultLists[] = {a,a,a,a,a,a,a,a,a,a, a, a};
+ static const int visibleIndexes[] = {2,3,6,7,0};
+ static const void *visibleLists[] = {a,a,a,a,0};
+ static const int selectionIndexes[] = {3,6};
+ static const void *selectionLists[] = {a,a};
+ QTest::newRow("Cache, 3, 1, Visible")
+ << (RangeList()
+ << Range(a, 0, 2, C::DefaultFlag)
+ << Range(a, 2, 1, VisibleFlag | C::DefaultFlag)
+ << Range(a, 3, 1, SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(a, 4, 2, C::DefaultFlag)
+ << Range(a, 6, 1, SelectionFlag | VisibleFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(a, 7, 1, VisibleFlag | C::DefaultFlag)
+ << Range(a, 8, 4, C::DefaultFlag)
+ << Range(0, 0, 4, C::CacheFlag))
+ << C::Cache << 3 << 1 << int(VisibleFlag)
+ << (InsertList()
+ << Insert(2, 4, 12, 3, 1, VisibleFlag | C::CacheFlag))
+ << IndexArray(cacheIndexes) << ListArray(cacheLists)
+ << IndexArray(defaultIndexes) << ListArray(defaultLists)
+ << IndexArray(visibleIndexes) << ListArray(visibleLists)
+ << IndexArray(selectionIndexes) << ListArray(selectionLists);
+ }
+}
+
+void tst_qdeclarativelistcompositor::setFlags()
+{
+ QFETCH(RangeList, ranges);
+ QFETCH(C::Group, group);
+ QFETCH(int, index);
+ QFETCH(int, count);
+ QFETCH(int, flags);
+ QFETCH(InsertList, expectedInserts);
+ QFETCH(IndexArray, cacheIndexes);
+ QFETCH(ListArray, cacheLists);
+ QFETCH(IndexArray, defaultIndexes);
+ QFETCH(ListArray, defaultLists);
+ QFETCH(IndexArray, visibleIndexes);
+ QFETCH(ListArray, visibleLists);
+ QFETCH(IndexArray, selectionIndexes);
+ QFETCH(ListArray, selectionLists);
+
+ QDeclarativeListCompositor compositor;
+ compositor.setGroupCount(4);
+ compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
+
+ foreach (const Range &range, ranges)
+ compositor.append(range.list, range.index, range.count, range.flags);
+
+ QVector<C::Insert> inserts;
+ compositor.setFlags(group, index, count, flags, &inserts);
+
+ QCOMPARE(inserts, expectedInserts);
+
+ QCOMPARE(compositor.count(C::Cache), cacheIndexes.count);
+ for (int i = 0; i < cacheIndexes.count; ++i) {
+ C::iterator it = compositor.find(C::Cache, i);
+ QCOMPARE(it->list, cacheLists[i]);
+ if (cacheLists[i])
+ QCOMPARE(it.modelIndex(), cacheIndexes[i]);
+ }
+ QCOMPARE(compositor.count(C::Default), defaultIndexes.count);
+ for (int i = 0; i < defaultIndexes.count; ++i) {
+ C::iterator it = compositor.find(C::Default, i);
+ QCOMPARE(it->list, defaultLists[i]);
+ if (defaultLists[i])
+ QCOMPARE(it.modelIndex(), defaultIndexes[i]);
+ }
+ QCOMPARE(compositor.count(Visible), visibleIndexes.count);
+ for (int i = 0; i < visibleIndexes.count; ++i) {
+ C::iterator it = compositor.find(Visible, i);
+ QCOMPARE(it->list, visibleLists[i]);
+ if (visibleLists[i])
+ QCOMPARE(it.modelIndex(), visibleIndexes[i]);
+ }
+ QCOMPARE(compositor.count(Selection), selectionIndexes.count);
+ for (int i = 0; i < selectionIndexes.count; ++i) {
+ C::iterator it = compositor.find(Selection, i);
+ QCOMPARE(it->list, selectionLists[i]);
+ if (selectionLists[i])
+ QCOMPARE(it.modelIndex(), selectionIndexes[i]);
+ }
+}
+
+void tst_qdeclarativelistcompositor::move_data()
+{
+ QTest::addColumn<RangeList>("ranges");
+ QTest::addColumn<C::Group>("fromGroup");
+ QTest::addColumn<int>("from");
+ QTest::addColumn<C::Group>("toGroup");
+ QTest::addColumn<int>("to");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<RemoveList>("expectedRemoves");
+ QTest::addColumn<InsertList>("expectedInserts");
+ QTest::addColumn<IndexArray>("cacheIndexes");
+ QTest::addColumn<ListArray>("cacheLists");
+ QTest::addColumn<IndexArray>("defaultIndexes");
+ QTest::addColumn<ListArray>("defaultLists");
+ QTest::addColumn<IndexArray>("visibleIndexes");
+ QTest::addColumn<ListArray>("visibleLists");
+ QTest::addColumn<IndexArray>("selectionIndexes");
+ QTest::addColumn<ListArray>("selectionLists");
+
+ int listA; void *a = &listA;
+ int listB; void *b = &listB;
+ int listC; void *c = &listC;
+
+ { static const int cacheIndexes[] = {0,0,0,0,2,3};
+ static const void *cacheLists[] = {0,0,0,0,c,c};
+ static const int defaultIndexes[] = {0,0,1,2,3,4,5,0,1,2,3,4,5,1,2,3,0,1,2,3,4,5};
+ static const void *defaultLists[] = {0,a,a,a,a,a,a,b,b,b,b,b,b,0,0,0,c,c,c,c,c,c};
+ QTest::newRow("15, 0, 1")
+ << (RangeList()
+ << Range(a, 0, 6, C::DefaultFlag)
+ << Range(b, 0, 6, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
+ << Range(0, 0, 4, C::DefaultFlag | C::CacheFlag)
+ << Range(c, 0, 2, C::PrependFlag | C::DefaultFlag)
+ << Range(c, 2, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(c, 4, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag))
+ << C::Default << 15 << C::Default << 0 << 1
+ << (RemoveList()
+ << Remove(0, 0, 15, 3, 1, C::DefaultFlag | C::CacheFlag, 0))
+ << (InsertList()
+ << Insert(0, 0, 0, 0, 1, C::DefaultFlag | C::CacheFlag, 0))
+ << IndexArray(cacheIndexes) << ListArray(cacheLists)
+ << IndexArray(defaultIndexes) << ListArray(defaultLists)
+ << IndexArray() << ListArray()
+ << IndexArray() << ListArray();
+ } { static const int cacheIndexes[] = {0,0,0,0,2,3};
+ static const void *cacheLists[] = {0,0,0,0,c,c};
+ static const int defaultIndexes[] = {0,1,0,1,2,3,4,5,0,1,2,3,4,5,2,3,0,1,2,3,4,5};
+ static const void *defaultLists[] = {0,0,a,a,a,a,a,a,b,b,b,b,b,b,0,0,c,c,c,c,c,c};
+ QTest::newRow("15, 1, 1")
+ << (RangeList()
+ << Range(0, 0, 1, C::DefaultFlag | C::CacheFlag)
+ << Range(a, 0, 6, C::DefaultFlag)
+ << Range(b, 0, 6, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
+ << Range(0, 0, 3, C::DefaultFlag | C::CacheFlag)
+ << Range(c, 0, 2, C::PrependFlag | C::DefaultFlag)
+ << Range(c, 2, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(c, 4, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag))
+ << C::Default << 15 << C::Default << 1 << 1
+ << (RemoveList()
+ << Remove(0, 0, 15, 3, 1, C::DefaultFlag | C::CacheFlag, 0))
+ << (InsertList()
+ << Insert(0, 0, 1, 1, 1, C::DefaultFlag | C::CacheFlag, 0))
+ << IndexArray(cacheIndexes) << ListArray(cacheLists)
+ << IndexArray(defaultIndexes) << ListArray(defaultLists)
+ << IndexArray() << ListArray()
+ << IndexArray() << ListArray();
+ } { static const int cacheIndexes[] = {0,0,0,0,2,3};
+ static const void *cacheLists[] = {0,0,0,0,c,c};
+ static const int defaultIndexes[] = {0,1,2,0,1,3,4,5,0,1,2,3,4,5,2,3,0,1,2,3,4,5};
+ static const void *defaultLists[] = {a,a,a,0,0,a,a,a,b,b,b,b,b,b,0,0,c,c,c,c,c,c};
+ QTest::newRow("0, 3, 2")
+ << (RangeList()
+ << Range(0, 0, 2, C::DefaultFlag | C::CacheFlag)
+ << Range(a, 0, 6, C::DefaultFlag)
+ << Range(b, 0, 6, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
+ << Range(0, 0, 2, C::DefaultFlag | C::CacheFlag)
+ << Range(c, 0, 2, C::PrependFlag | C::DefaultFlag)
+ << Range(c, 2, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(c, 4, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag))
+ << C::Default << 0 << C::Default << 3 << 2
+ << (RemoveList()
+ << Remove(0, 0, 0, 0, 2, C::DefaultFlag | C::CacheFlag, 0))
+ << (InsertList()
+ << Insert(0, 0, 3, 0, 2, C::DefaultFlag | C::CacheFlag, 0))
+ << IndexArray(cacheIndexes) << ListArray(cacheLists)
+ << IndexArray(defaultIndexes) << ListArray(defaultLists)
+ << IndexArray() << ListArray()
+ << IndexArray() << ListArray();
+ } { static const int cacheIndexes[] = {0,0,0,0,2,3};
+ static const void *cacheLists[] = {0,0,0,0,c,c};
+ static const int defaultIndexes[] = {0,5,0,1,2,3,4,5,0,1,0,1,2,2,3,3,4,1,2,3,4,5};
+ static const void *defaultLists[] = {a,a,b,b,b,b,b,b,0,0,c,a,a,0,0,a,a,c,c,c,c,c};
+ QTest::newRow("7, 1, 10")
+ << (RangeList()
+ << Range(a, 0, 3, C::DefaultFlag)
+ << Range(0, 0, 2, C::DefaultFlag | C::CacheFlag)
+ << Range(a, 3, 3, C::DefaultFlag)
+ << Range(b, 0, 6, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
+ << Range(0, 0, 2, C::DefaultFlag | C::CacheFlag)
+ << Range(c, 0, 2, C::PrependFlag | C::DefaultFlag)
+ << Range(c, 2, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(c, 4, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag))
+ << C::Default << 7 << C::Default << 1 << 10
+ << (RemoveList()
+ << Remove(0, 0, 7, 2, 1, C::DefaultFlag, 0)
+ << Remove(0, 0, 7, 2, 6, C::DefaultFlag, 1)
+ << Remove(0, 0, 7, 2, 2, C::DefaultFlag | C::CacheFlag, 2)
+ << Remove(0, 0, 7, 2, 1, C::DefaultFlag, 3))
+ << (InsertList()
+ << Insert(0, 0, 1, 0, 1, C::DefaultFlag, 0)
+ << Insert(0, 0, 2, 0, 6, C::DefaultFlag, 1)
+ << Insert(0, 0, 8, 0, 2, C::DefaultFlag | C::CacheFlag, 2)
+ << Insert(0, 0, 10, 2, 1, C::DefaultFlag, 3))
+ << IndexArray(cacheIndexes) << ListArray(cacheLists)
+ << IndexArray(defaultIndexes) << ListArray(defaultLists)
+ << IndexArray() << ListArray()
+ << IndexArray() << ListArray();
+ } { static const int cacheIndexes[] = {0,0,0,0,3,2};
+ static const void *cacheLists[] = {0,0,0,0,c,c};
+ static const int defaultIndexes[] = {0,5,0,1,2,3,4,5,0,1,0,1,2,2,3,3,4,3,4,5,1,2};
+ static const void *defaultLists[] = {a,a,b,b,b,b,b,b,0,0,c,a,a,0,0,a,a,c,c,c,c,c};
+ QTest::newRow("17, 20, 2")
+ << (RangeList()
+ << Range(a, 0, 1, C::DefaultFlag)
+ << Range(a, 5, 1, C::DefaultFlag)
+ << Range(b, 0, 6, C::DefaultFlag)
+ << Range(0, 0, 2, C::DefaultFlag | C::CacheFlag)
+ << Range(c, 0, 1, C::DefaultFlag)
+ << Range(a, 1, 2, C::DefaultFlag)
+ << Range(0, 0, 2, C::DefaultFlag | C::CacheFlag)
+ << Range(a, 3, 2, C::DefaultFlag)
+ << Range(b, 0, 6, C::AppendFlag | C::PrependFlag)
+ << Range(c, 0, 1, C::PrependFlag)
+ << Range(c, 1, 1, C::PrependFlag | C::DefaultFlag)
+ << Range(c, 2, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(c, 4, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag))
+ << C::Default << 17 << C::Default << 20 << 2
+ << (RemoveList()
+ << Remove(0, 0, 17, 4, 1, C::DefaultFlag, 0)
+ << Remove(0, 0, 17, 4, 1, C::DefaultFlag | C::CacheFlag, 1))
+ << (InsertList()
+ << Insert(0, 0, 20, 5, 1, C::DefaultFlag, 0)
+ << Insert(0, 0, 21, 5, 1, C::DefaultFlag | C::CacheFlag, 1))
+ << IndexArray(cacheIndexes) << ListArray(cacheLists)
+ << IndexArray(defaultIndexes) << ListArray(defaultLists)
+ << IndexArray() << ListArray()
+ << IndexArray() << ListArray();
+ }
+}
+
+void tst_qdeclarativelistcompositor::move()
+{
+ QFETCH(RangeList, ranges);
+ QFETCH(C::Group, fromGroup);
+ QFETCH(int, from);
+ QFETCH(C::Group, toGroup);
+ QFETCH(int, to);
+ QFETCH(int, count);
+ QFETCH(RemoveList, expectedRemoves);
+ QFETCH(InsertList, expectedInserts);
+ QFETCH(IndexArray, cacheIndexes);
+ QFETCH(ListArray, cacheLists);
+ QFETCH(IndexArray, defaultIndexes);
+ QFETCH(ListArray, defaultLists);
+ QFETCH(IndexArray, visibleIndexes);
+ QFETCH(ListArray, visibleLists);
+ QFETCH(IndexArray, selectionIndexes);
+ QFETCH(ListArray, selectionLists);
+
+ QDeclarativeListCompositor compositor;
+ compositor.setGroupCount(4);
+ compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
+
+ foreach (const Range &range, ranges)
+ compositor.append(range.list, range.index, range.count, range.flags);
+
+ QVector<C::Remove> removes;
+ QVector<C::Insert> inserts;
+ compositor.move(fromGroup, from, toGroup, to, count, &removes, &inserts);
+
+ QCOMPARE(removes, expectedRemoves);
+ QCOMPARE(inserts, expectedInserts);
+
+ QCOMPARE(compositor.count(C::Cache), cacheIndexes.count);
+ for (int i = 0; i < cacheIndexes.count; ++i) {
+ C::iterator it = compositor.find(C::Cache, i);
+ QCOMPARE(it->list, cacheLists[i]);
+ if (cacheLists[i])
+ QCOMPARE(it.modelIndex(), cacheIndexes[i]);
+ }
+ QCOMPARE(compositor.count(C::Default), defaultIndexes.count);
+ for (int i = 0; i < defaultIndexes.count; ++i) {
+ C::iterator it = compositor.find(C::Default, i);
+ QCOMPARE(it->list, defaultLists[i]);
+ if (defaultLists[i])
+ QCOMPARE(it.modelIndex(), defaultIndexes[i]);
+ }
+ QCOMPARE(compositor.count(Visible), visibleIndexes.count);
+ for (int i = 0; i < visibleIndexes.count; ++i) {
+ C::iterator it = compositor.find(Visible, i);
+ QCOMPARE(it->list, visibleLists[i]);
+ if (visibleLists[i])
+ QCOMPARE(it.modelIndex(), visibleIndexes[i]);
+ }
+ QCOMPARE(compositor.count(Selection), selectionIndexes.count);
+ for (int i = 0; i < selectionIndexes.count; ++i) {
+ C::iterator it = compositor.find(Selection, i);
+ QCOMPARE(it->list, selectionLists[i]);
+ if (selectionLists[i])
+ QCOMPARE(it.modelIndex(), selectionIndexes[i]);
+ }
+}
+void tst_qdeclarativelistcompositor::clear()
+{
+ QDeclarativeListCompositor compositor;
+ compositor.setGroupCount(4);
+ compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
+
+ int listA; void *a = &listA;
+ int listB; void *b = &listB;
+
+ compositor.append(a, 0, 8, C::AppendFlag | C::PrependFlag | VisibleFlag | C::DefaultFlag);
+ compositor.append(b, 4, 5, VisibleFlag | C::DefaultFlag);
+ compositor.append(0, 0, 3, VisibleFlag | C::DefaultFlag | C::CacheFlag);
+
+ QCOMPARE(compositor.count(C::Default), 16);
+ QCOMPARE(compositor.count(Visible), 16);
+ QCOMPARE(compositor.count(C::Cache), 3);
+
+ compositor.clear();
+ QCOMPARE(compositor.count(C::Default), 0);
+ QCOMPARE(compositor.count(Visible), 0);
+ QCOMPARE(compositor.count(C::Cache), 0);
+}
+
+void tst_qdeclarativelistcompositor::listItemsInserted_data()
+{
+ QTest::addColumn<RangeList>("ranges");
+ QTest::addColumn<void *>("list");
+ QTest::addColumn<int>("index");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<InsertList>("expectedInserts");
+ QTest::addColumn<IndexArray>("cacheIndexes");
+ QTest::addColumn<IndexArray>("defaultIndexes");
+ QTest::addColumn<IndexArray>("visibleIndexes");
+ QTest::addColumn<IndexArray>("selectionIndexes");
+
+ int listA; void *a = &listA;
+ int listB; void *b = &listB;
+
+ { static const int defaultIndexes[] = {/*A*/0,1,5,6,/*B*/0,1,2,3,/*A*/2,3,4};
+ QTest::newRow("A 10, 2")
+ << (RangeList()
+ << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag)
+ << Range(a, 2, 3, C::PrependFlag)
+ << Range(a, 5, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
+ << Range(b, 0, 4, C::DefaultFlag)
+ << Range(a, 2, 3, C::DefaultFlag))
+ << a << 10 << 2
+ << InsertList()
+ << IndexArray()
+ << IndexArray(defaultIndexes)
+ << IndexArray()
+ << IndexArray();
+ } { static const int defaultIndexes[] = {/*A*/0,1,5,6,/*B*/0,1,2,3,/*A*/2,3,4};
+ QTest::newRow("B 10, 2")
+ << (RangeList()
+ << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag)
+ << Range(a, 2, 3, C::PrependFlag)
+ << Range(a, 5, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
+ << Range(b, 0, 4, C::DefaultFlag)
+ << Range(a, 2, 3, C::DefaultFlag))
+ << b << 10 << 2
+ << InsertList()
+ << IndexArray()
+ << IndexArray(defaultIndexes)
+ << IndexArray()
+ << IndexArray();
+ } { static const int defaultIndexes[] = {/*A*/0,1,2,3,7,8,/*B*/0,1,2,3,/*A*/4,5,6};
+ static const int visibleIndexes[] = {/*A*/0,1};
+ QTest::newRow("A 0, 2")
+ << (RangeList()
+ << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag)
+ << Range(a, 2, 3, C::PrependFlag)
+ << Range(a, 5, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
+ << Range(b, 0, 4, C::DefaultFlag)
+ << Range(a, 2, 3, C::DefaultFlag))
+ << a << 0 << 2
+ << (InsertList()
+ << Insert(0, 0, 0, 0, 2, VisibleFlag | C::DefaultFlag))
+ << IndexArray()
+ << IndexArray(defaultIndexes)
+ << IndexArray(visibleIndexes)
+ << IndexArray();
+ } { static const int defaultIndexes[] = {/*A*/0,1,2,3,5,8,9,/*B*/0,1,2,3,/*A*/4,6,7};
+ static const int visibleIndexes[] = {/*A*/0,1,5};
+ QTest::newRow("A 5, 1")
+ << (RangeList()
+ << Range(a, 0, 2, C::PrependFlag | VisibleFlag | C::DefaultFlag)
+ << Range(a, 2, 2, C::PrependFlag | C::DefaultFlag)
+ << Range(a, 4, 3, C::PrependFlag)
+ << Range(a, 7, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
+ << Range(b, 0, 4, C::DefaultFlag)
+ << Range(a, 4, 3, C::DefaultFlag))
+ << a << 5 << 1
+ << (InsertList()
+ << Insert(0, 2, 4, 0, 1, VisibleFlag | C::DefaultFlag))
+ << IndexArray()
+ << IndexArray(defaultIndexes)
+ << IndexArray(visibleIndexes)
+ << IndexArray();
+ } { static const int defaultIndexes[] = {/*A*/0,1,2,3,5,8,9,10,11,/*B*/0,1,2,3,/*A*/4,6,7};
+ static const int visibleIndexes[] = {/*A*/0,1,5,10,11};
+ QTest::newRow("A 10, 2")
+ << (RangeList()
+ << Range(a, 0, 2, C::PrependFlag | VisibleFlag | C::DefaultFlag)
+ << Range(a, 2, 2, C::PrependFlag | C::DefaultFlag)
+ << Range(a, 4, 1, C::PrependFlag)
+ << Range(a, 5, 1, C::PrependFlag | VisibleFlag | C::DefaultFlag)
+ << Range(a, 6, 2, C::PrependFlag)
+ << Range(a, 8, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
+ << Range(b, 0, 4, C::DefaultFlag)
+ << Range(a, 4, 1, C::DefaultFlag)
+ << Range(a, 6, 2, C::DefaultFlag))
+ << a << 10 << 2
+ << (InsertList()
+ << Insert(0, 3, 7, 0, 2, VisibleFlag | C::DefaultFlag))
+ << IndexArray()
+ << IndexArray(defaultIndexes)
+ << IndexArray(visibleIndexes)
+ << IndexArray();
+ } { static const int cacheIndexes[] = {/*A*/0,1,-1,-1,-1,2,5,6,7,8,9};
+ static const int defaultIndexes[] = {/*A*/0,1,2,3,4,5,6,7,8,9};
+ static const int visibleIndexes[] = {/*A*/3,4};
+ QTest::newRow("Insert after remove")
+ << (RangeList()
+ << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(a, 2, 3, C::CacheFlag)
+ << Range(a, 2, 6, C::AppendFlag | C::PrependFlag | C::DefaultFlag | C::CacheFlag))
+ << a << 3 << 2
+ << (InsertList()
+ << Insert(0, 0, 3, 6, 2, VisibleFlag | C::DefaultFlag))
+ << IndexArray(cacheIndexes)
+ << IndexArray(defaultIndexes)
+ << IndexArray(visibleIndexes)
+ << IndexArray();
+ }
+}
+
+void tst_qdeclarativelistcompositor::listItemsInserted()
+{
+ QFETCH(RangeList, ranges);
+ QFETCH(void *, list);
+ QFETCH(int, index);
+ QFETCH(int, count);
+ QFETCH(InsertList, expectedInserts);
+ QFETCH(IndexArray, cacheIndexes);
+ QFETCH(IndexArray, defaultIndexes);
+ QFETCH(IndexArray, visibleIndexes);
+ QFETCH(IndexArray, selectionIndexes);
+
+ QDeclarativeListCompositor compositor;
+ compositor.setGroupCount(4);
+ compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
+
+ foreach (const Range &range, ranges)
+ compositor.append(range.list, range.index, range.count, range.flags);
+
+ QVector<C::Insert> inserts;
+ compositor.listItemsInserted(list, index, count, &inserts);
+
+ QCOMPARE(inserts, expectedInserts);
+
+ QCOMPARE(compositor.count(C::Cache), cacheIndexes.count);
+ for (int i = 0; i < cacheIndexes.count; ++i) {
+ if (cacheIndexes[i] != -1) {
+ QCOMPARE(compositor.find(C::Cache, i).modelIndex(), cacheIndexes[i]);
+ }
+ }
+ QCOMPARE(compositor.count(C::Default), defaultIndexes.count);
+ for (int i = 0; i < defaultIndexes.count; ++i) {
+ if (defaultIndexes[i] != -1) {
+ QCOMPARE(compositor.find(C::Default, i).modelIndex(), defaultIndexes[i]);
+ }
+ }
+ QCOMPARE(compositor.count(Visible), visibleIndexes.count);
+ for (int i = 0; i < visibleIndexes.count; ++i) {
+ if (visibleIndexes[i] != -1) {
+ QCOMPARE(compositor.find(Visible, i).modelIndex(), visibleIndexes[i]);
+ }
+ }
+ QCOMPARE(compositor.count(Selection), selectionIndexes.count);
+ for (int i = 0; i < selectionIndexes.count; ++i) {
+ if (selectionIndexes[i] != -1) {
+ QCOMPARE(compositor.find(Selection, i).modelIndex(), selectionIndexes[i]);
+ }
+ }
+}
+
+void tst_qdeclarativelistcompositor::listItemsRemoved_data()
+{
+ QTest::addColumn<RangeList>("ranges");
+ QTest::addColumn<void *>("list");
+ QTest::addColumn<int>("index");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<RemoveList>("expectedRemoves");
+ QTest::addColumn<IndexArray>("cacheIndexes");
+ QTest::addColumn<IndexArray>("defaultIndexes");
+ QTest::addColumn<IndexArray>("visibleIndexes");
+ QTest::addColumn<IndexArray>("selectionIndexes");
+
+ int listA; void *a = &listA;
+ int listB; void *b = &listB;
+
+ { static const int defaultIndexes[] = {/*A*/0,1,5,6,/*B*/0,1,2,3,/*A*/2,3,4};
+ QTest::newRow("12, 2")
+ << (RangeList()
+ << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag)
+ << Range(a, 2, 3, C::PrependFlag)
+ << Range(a, 5, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
+ << Range(b, 0, 4, C::DefaultFlag)
+ << Range(a, 2, 3, C::DefaultFlag))
+ << a << 12 << 2
+ << RemoveList()
+ << IndexArray()
+ << IndexArray(defaultIndexes)
+ << IndexArray()
+ << IndexArray();
+ } { static const int defaultIndexes[] = {/*A*/0,1,/*B*/0,1,2,3,/*A*/2,3};
+ QTest::newRow("4, 3")
+ << (RangeList()
+ << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag)
+ << Range(a, 2, 3, C::PrependFlag)
+ << Range(a, 5, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
+ << Range(b, 0, 4, C::DefaultFlag)
+ << Range(a, 2, 3, C::DefaultFlag))
+ << a << 4 << 3
+ << (RemoveList()
+ << Remove(0, 0, 2, 0, 2, C::DefaultFlag)
+ << Remove(0, 0, 8, 0, 1, C::DefaultFlag))
+ << IndexArray()
+ << IndexArray(defaultIndexes)
+ << IndexArray()
+ << IndexArray();
+ } { static const int cacheIndexes[] = {/*A*/0,1,-1,-1,-1,2,-1,-1,3,4,5};
+ static const int defaultIndexes[] = {/*A*/0,1,2,3,4,5};
+ QTest::newRow("Remove after remove")
+ << (RangeList()
+ << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(a, 2, 3, C::CacheFlag)
+ << Range(a, 2, 6, C::AppendFlag | C::PrependFlag | C::DefaultFlag | C::CacheFlag))
+ << a << 3 << 2
+ << (RemoveList()
+ << Remove(0, 0, 3, 6, 2, C::DefaultFlag | C::CacheFlag))
+ << IndexArray(cacheIndexes)
+ << IndexArray(defaultIndexes)
+ << IndexArray()
+ << IndexArray();
+ }
+}
+
+void tst_qdeclarativelistcompositor::listItemsRemoved()
+{
+ QFETCH(RangeList, ranges);
+ QFETCH(void *, list);
+ QFETCH(int, index);
+ QFETCH(int, count);
+ QFETCH(RemoveList, expectedRemoves);
+ QFETCH(IndexArray, cacheIndexes);
+ QFETCH(IndexArray, defaultIndexes);
+ QFETCH(IndexArray, visibleIndexes);
+ QFETCH(IndexArray, selectionIndexes);
+
+ QDeclarativeListCompositor compositor;
+ compositor.setGroupCount(4);
+ compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
+
+ foreach (const Range &range, ranges)
+ compositor.append(range.list, range.index, range.count, range.flags);
+
+ QVector<C::Remove> removes;
+ compositor.listItemsRemoved(list, index, count, &removes);
+
+ QCOMPARE(removes, expectedRemoves);
+
+ QCOMPARE(compositor.count(C::Cache), cacheIndexes.count);
+ for (int i = 0; i < cacheIndexes.count; ++i) {
+ if (cacheIndexes[i] != -1) {
+ QCOMPARE(compositor.find(C::Cache, i).modelIndex(), cacheIndexes[i]);
+ }
+ }
+ QCOMPARE(compositor.count(C::Default), defaultIndexes.count);
+ for (int i = 0; i < defaultIndexes.count; ++i) {
+ if (defaultIndexes[i] != -1) {
+ QCOMPARE(compositor.find(C::Default, i).modelIndex(), defaultIndexes[i]);
+ }
+ }
+ QCOMPARE(compositor.count(Visible), visibleIndexes.count);
+ for (int i = 0; i < visibleIndexes.count; ++i) {
+ if (visibleIndexes[i] != -1) {
+ QCOMPARE(compositor.find(Visible, i).modelIndex(), visibleIndexes[i]);
+ }
+ }
+ QCOMPARE(compositor.count(Selection), selectionIndexes.count);
+ for (int i = 0; i < selectionIndexes.count; ++i) {
+ if (selectionIndexes[i] != -1) {
+ QCOMPARE(compositor.find(Selection, i).modelIndex(), selectionIndexes[i]);
+ }
+ }
+}
+
+void tst_qdeclarativelistcompositor::listItemsMoved_data()
+{
+ QTest::addColumn<RangeList>("ranges");
+ QTest::addColumn<void *>("list");
+ QTest::addColumn<int>("from");
+ QTest::addColumn<int>("to");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<RemoveList>("expectedRemoves");
+ QTest::addColumn<InsertList>("expectedInserts");
+ QTest::addColumn<IndexArray>("cacheIndexes");
+ QTest::addColumn<IndexArray>("defaultIndexes");
+ QTest::addColumn<IndexArray>("visibleIndexes");
+ QTest::addColumn<IndexArray>("selectionIndexes");
+
+ int listA; void *a = &listA;
+ int listB; void *b = &listB;
+
+ { static const int defaultIndexes[] = {/*A*/0,2,3,4,/*B*/0,1,2,3,/*A*/5,6,1};
+ QTest::newRow("4, 1, 3")
+ << (RangeList()
+ << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag)
+ << Range(a, 2, 3, C::PrependFlag)
+ << Range(a, 5, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
+ << Range(b, 0, 4, C::DefaultFlag)
+ << Range(a, 2, 3, C::DefaultFlag))
+ << a << 4 << 1 << 3
+ << (RemoveList()
+ << Remove(0, 0, 2, 0, 2, C::DefaultFlag, 0))
+ << (InsertList()
+ << Insert(0, 0, 1, 0, 2, C::DefaultFlag, 0))
+ << IndexArray()
+ << IndexArray(defaultIndexes)
+ << IndexArray()
+ << IndexArray();
+ } { static const int defaultIndexes[] = {/*A*/1,2,3,6,/*B*/0,1,2,3,/*A*/4,5,0};
+ QTest::newRow("0, 6, 1")
+ << (RangeList()
+ << Range(a, 0, 1, C::PrependFlag | C::DefaultFlag)
+ << Range(a, 1, 1, C::PrependFlag)
+ << Range(a, 2, 3, C::PrependFlag | C::DefaultFlag)
+ << Range(a, 5, 2, C::PrependFlag)
+ << Range(a, 7, 0, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
+ << Range(b, 0, 4, C::DefaultFlag)
+ << Range(a, 5, 2, C::DefaultFlag)
+ << Range(a, 1, 1, C::DefaultFlag))
+ << a << 0 << 6 << 1
+ << (RemoveList()
+ << Remove(0, 0, 0, 0, 1, C::DefaultFlag, 0))
+ << (InsertList()
+ << Insert(0, 0, 3, 0, 1, C::DefaultFlag, 0))
+ << IndexArray()
+ << IndexArray(defaultIndexes)
+ << IndexArray()
+ << IndexArray();
+ } { static const int cacheIndexes[] = {/*A*/0,1,3,4};
+ static const int defaultIndexes[] = {/*A*/0,1,2,3,4,5,6,7};
+ QTest::newRow("6, 2, 1")
+ << (RangeList()
+ << Range(a, 0, 4, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(a, 4, 4, C::AppendFlag | C::PrependFlag | C::DefaultFlag))
+ << a << 6 << 2 << 1
+ << (RemoveList()
+ << Remove(0, 0, 6, 4, 1, C::DefaultFlag, 0))
+ << (InsertList()
+ << Insert(0, 0, 2, 2, 1, C::DefaultFlag, 0))
+ << IndexArray(cacheIndexes)
+ << IndexArray(defaultIndexes)
+ << IndexArray()
+ << IndexArray();
+ } { static const int cacheIndexes[] = {/*A*/0,1,-1,-1,-1,2,3,4,5,6,7};
+ static const int defaultIndexes[] = {/*A*/0,1,2,3,4,5,6,7};
+ QTest::newRow("Move after remove")
+ << (RangeList()
+ << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(a, 2, 3, C::CacheFlag)
+ << Range(a, 2, 6, C::AppendFlag | C::PrependFlag | C::DefaultFlag | C::CacheFlag))
+ << a << 4 << 2 << 2
+ << (RemoveList()
+ << Remove(0, 0, 4, 7, 2, C::DefaultFlag | C::CacheFlag, 0))
+ << (InsertList()
+ << Insert(0, 0, 2, 5, 2, C::DefaultFlag | C::CacheFlag, 0))
+ << IndexArray(cacheIndexes)
+ << IndexArray(defaultIndexes)
+ << IndexArray()
+ << IndexArray();
+ }
+}
+
+void tst_qdeclarativelistcompositor::listItemsMoved()
+{
+ QFETCH(RangeList, ranges);
+ QFETCH(void *, list);
+ QFETCH(int, from);
+ QFETCH(int, to);
+ QFETCH(int, count);
+ QFETCH(RemoveList, expectedRemoves);
+ QFETCH(InsertList, expectedInserts);
+ QFETCH(IndexArray, cacheIndexes);
+ QFETCH(IndexArray, defaultIndexes);
+ QFETCH(IndexArray, visibleIndexes);
+ QFETCH(IndexArray, selectionIndexes);
+
+ QDeclarativeListCompositor compositor;
+ compositor.setGroupCount(4);
+ compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
+
+ foreach (const Range &range, ranges)
+ compositor.append(range.list, range.index, range.count, range.flags);
+
+ QVector<C::Remove> removes;
+ QVector<C::Insert> inserts;
+ compositor.listItemsMoved(list, from, to, count, &removes, &inserts);
+
+ QCOMPARE(removes, expectedRemoves);
+ QCOMPARE(inserts, expectedInserts);
+
+ QCOMPARE(compositor.count(C::Cache), cacheIndexes.count);
+ for (int i = 0; i < cacheIndexes.count; ++i) {
+ if (cacheIndexes[i] != -1) {
+ QCOMPARE(compositor.find(C::Cache, i).modelIndex(), cacheIndexes[i]);
+ }
+ }
+ QCOMPARE(compositor.count(C::Default), defaultIndexes.count);
+ for (int i = 0; i < defaultIndexes.count; ++i) {
+ if (defaultIndexes[i] != -1) {
+ QCOMPARE(compositor.find(C::Default, i).modelIndex(), defaultIndexes[i]);
+ }
+ }
+ QCOMPARE(compositor.count(Visible), visibleIndexes.count);
+ for (int i = 0; i < visibleIndexes.count; ++i) {
+ if (visibleIndexes[i] != -1) {
+ QCOMPARE(compositor.find(Visible, i).modelIndex(), visibleIndexes[i]);
+ }
+ }
+ QCOMPARE(compositor.count(Selection), selectionIndexes.count);
+ for (int i = 0; i < selectionIndexes.count; ++i) {
+ if (selectionIndexes[i] != -1) {
+ QCOMPARE(compositor.find(Selection, i).modelIndex(), selectionIndexes[i]);
+ }
+ }
+}
+
+void tst_qdeclarativelistcompositor::listItemsChanged_data()
+{
+ QTest::addColumn<RangeList>("ranges");
+ QTest::addColumn<void *>("list");
+ QTest::addColumn<int>("index");
+ QTest::addColumn<int>("count");
+ QTest::addColumn<ChangeList>("expectedChanges");
+
+ int listA; void *a = &listA;
+ int listB; void *b = &listB;
+
+ QTest::newRow("overlapping")
+ << (RangeList()
+ << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag)
+ << Range(a, 2, 3, C::PrependFlag)
+ << Range(a, 5, 2, C::AppendFlag | C::PrependFlag | C::DefaultFlag)
+ << Range(b, 0, 4, C::DefaultFlag)
+ << Range(a, 2, 3, C::DefaultFlag))
+ << a << 3 << 4
+ << (ChangeList()
+ << Change(0, 0, 2, 0, 2, C::DefaultFlag)
+ << Change(0, 0, 9, 0, 2, C::DefaultFlag));
+ QTest::newRow("Change after remove")
+ << (RangeList()
+ << Range(a, 0, 2, C::PrependFlag | C::DefaultFlag | C::CacheFlag)
+ << Range(a, 2, 3, C::CacheFlag)
+ << Range(a, 2, 6, C::AppendFlag | C::PrependFlag | C::DefaultFlag | C::CacheFlag))
+ << a << 3 << 2
+ << (ChangeList()
+ << Change(0, 0, 3, 6, 2, C::DefaultFlag | C::CacheFlag));
+}
+
+void tst_qdeclarativelistcompositor::listItemsChanged()
+{
+ QFETCH(RangeList, ranges);
+ QFETCH(void *, list);
+ QFETCH(int, index);
+ QFETCH(int, count);
+ QFETCH(ChangeList, expectedChanges);
+
+ QDeclarativeListCompositor compositor;
+ compositor.setGroupCount(4);
+ compositor.setDefaultGroups(VisibleFlag | C::DefaultFlag);
+
+ foreach (const Range &range, ranges)
+ compositor.append(range.list, range.index, range.count, range.flags);
+
+ QVector<C::Change> changes;
+ compositor.listItemsChanged(list, index, count, &changes);
+
+ QCOMPARE(changes, expectedChanges);
+}
+
+QTEST_MAIN(tst_qdeclarativelistcompositor)
+
+#include "tst_qdeclarativelistcompositor.moc"
+
+
diff --git a/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro b/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro
index 4575c581ae..1586e68281 100644
--- a/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro
+++ b/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qdeclarativelistmodel
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativelistmodel.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private opengl-private
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
index 0c3b75ac98..92e3a8f58d 100644
--- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
+++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
@@ -51,13 +51,6 @@
#include <QtCore/qtranslator.h>
#include <QSignalSpy>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
Q_DECLARE_METATYPE(QList<int>)
Q_DECLARE_METATYPE(QList<QVariantHash>)
diff --git a/tests/auto/declarative/qdeclarativelistreference/qdeclarativelistreference.pro b/tests/auto/declarative/qdeclarativelistreference/qdeclarativelistreference.pro
index 03affbf482..5020c02f43 100644
--- a/tests/auto/declarative/qdeclarativelistreference/qdeclarativelistreference.pro
+++ b/tests/auto/declarative/qdeclarativelistreference/qdeclarativelistreference.pro
@@ -1,9 +1,13 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qdeclarativelistreference
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativelistreference.cpp
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativelistreference/tst_qdeclarativelistreference.cpp b/tests/auto/declarative/qdeclarativelistreference/tst_qdeclarativelistreference.cpp
index f60c5c4be0..a86e66de45 100644
--- a/tests/auto/declarative/qdeclarativelistreference/tst_qdeclarativelistreference.cpp
+++ b/tests/auto/declarative/qdeclarativelistreference/tst_qdeclarativelistreference.cpp
@@ -49,11 +49,11 @@
#include <QtDeclarative/qdeclarativeprivate.h>
#include <QtDeclarative/qdeclarativeproperty.h>
#include <QDebug>
+#include "../shared/util.h"
inline QUrl TEST_FILE(const QString &filename)
{
- QFileInfo fileInfo(__FILE__);
- return QUrl::fromLocalFile(fileInfo.absoluteDir().filePath("data/" + filename));
+ return QUrl::fromLocalFile(TESTDATA(filename));
}
inline QUrl TEST_FILE(const char *filename)
diff --git a/tests/auto/declarative/qdeclarativemetatype/qdeclarativemetatype.pro b/tests/auto/declarative/qdeclarativemetatype/qdeclarativemetatype.pro
index a7a2953df4..8261f6d930 100644
--- a/tests/auto/declarative/qdeclarativemetatype/qdeclarativemetatype.pro
+++ b/tests/auto/declarative/qdeclarativemetatype/qdeclarativemetatype.pro
@@ -1,13 +1,7 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qdeclarativemetatype
SOURCES += tst_qdeclarativemetatype.cpp
macx:CONFIG -= app_bundle
-!symbian: {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-
CONFIG += parallel_test
-#temporary
-CONFIG += insignificant_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private widgets testlib
diff --git a/tests/auto/declarative/qdeclarativemetatype/tst_qdeclarativemetatype.cpp b/tests/auto/declarative/qdeclarativemetatype/tst_qdeclarativemetatype.cpp
index e248c7cf99..a85e73ed57 100644
--- a/tests/auto/declarative/qdeclarativemetatype/tst_qdeclarativemetatype.cpp
+++ b/tests/auto/declarative/qdeclarativemetatype/tst_qdeclarativemetatype.cpp
@@ -51,14 +51,10 @@
#include <QVector4D>
#include <QQuaternion>
#include <qdeclarative.h>
+#include <QWidget>
#include <private/qdeclarativemetatype_p.h>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qdeclarativemetatype : public QObject
{
Q_OBJECT
@@ -209,6 +205,7 @@ void tst_qdeclarativemetatype::copy()
QPixmap icon(100, 100);
QIcon v = QIcon(icon); QIcon v2 = QIcon(icon);
+ QEXPECT_FAIL("", "QTBUG-21629 - copy() test function failure.", Abort);
QVERIFY(QDeclarativeMetaType::copy(QMetaType::QIcon, &v, 0));
QVERIFY(v.isNull() == QIcon().isNull());
QVERIFY(QDeclarativeMetaType::copy(QMetaType::QIcon , &v, &v2));
diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/plugin.2.1/plugin.2.1.pro b/tests/auto/declarative/qdeclarativemoduleplugin/plugin.2.1/plugin.2.1.pro
index 1c94420cb5..21835613af 100644
--- a/tests/auto/declarative/qdeclarativemoduleplugin/plugin.2.1/plugin.2.1.pro
+++ b/tests/auto/declarative/qdeclarativemoduleplugin/plugin.2.1/plugin.2.1.pro
@@ -4,7 +4,4 @@ SOURCES = plugin.cpp
QT = core declarative
DESTDIR = ../imports/com/nokia/AutoTestQmlPluginType.2.1
-symbian: {
- TARGET.EPOCALLOWDLLDATA=1
-}
QT += core-private gui-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/plugin.2/plugin.2.pro b/tests/auto/declarative/qdeclarativemoduleplugin/plugin.2/plugin.2.pro
index d4797a7ed8..6d4f5fb301 100644
--- a/tests/auto/declarative/qdeclarativemoduleplugin/plugin.2/plugin.2.pro
+++ b/tests/auto/declarative/qdeclarativemoduleplugin/plugin.2/plugin.2.pro
@@ -4,7 +4,4 @@ SOURCES = plugin.cpp
QT = core declarative
DESTDIR = ../imports/com/nokia/AutoTestQmlPluginType.2
-symbian: {
- TARGET.EPOCALLOWDLLDATA=1
-}
QT += core-private gui-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/plugin/plugin.pro b/tests/auto/declarative/qdeclarativemoduleplugin/plugin/plugin.pro
index 2bf974a6cc..61fab02109 100644
--- a/tests/auto/declarative/qdeclarativemoduleplugin/plugin/plugin.pro
+++ b/tests/auto/declarative/qdeclarativemoduleplugin/plugin/plugin.pro
@@ -4,7 +4,4 @@ SOURCES = plugin.cpp
QT = core declarative
DESTDIR = ../imports/com/nokia/AutoTestQmlPluginType
-symbian: {
- TARGET.EPOCALLOWDLLDATA=1
-}
QT += core-private gui-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/pluginMixed/pluginMixed.pro b/tests/auto/declarative/qdeclarativemoduleplugin/pluginMixed/pluginMixed.pro
index 52cf49d28e..f8b279cbf6 100644
--- a/tests/auto/declarative/qdeclarativemoduleplugin/pluginMixed/pluginMixed.pro
+++ b/tests/auto/declarative/qdeclarativemoduleplugin/pluginMixed/pluginMixed.pro
@@ -4,7 +4,4 @@ SOURCES = plugin.cpp
QT = core declarative
DESTDIR = ../imports/com/nokia/AutoTestQmlMixedPluginType
-symbian: {
- TARGET.EPOCALLOWDLLDATA=1
-}
QT += core-private gui-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/pluginVersion/pluginVersion.pro b/tests/auto/declarative/qdeclarativemoduleplugin/pluginVersion/pluginVersion.pro
index 2c69f225be..32e017e79d 100644
--- a/tests/auto/declarative/qdeclarativemoduleplugin/pluginVersion/pluginVersion.pro
+++ b/tests/auto/declarative/qdeclarativemoduleplugin/pluginVersion/pluginVersion.pro
@@ -4,7 +4,4 @@ SOURCES = plugin.cpp
QT = core declarative
DESTDIR = ../imports/com/nokia/AutoTestQmlVersionPluginType
-symbian: {
- TARGET.EPOCALLOWDLLDATA=1
-}
QT += core-private gui-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/pluginWithQmlFile/pluginWithQmlFile.pro b/tests/auto/declarative/qdeclarativemoduleplugin/pluginWithQmlFile/pluginWithQmlFile.pro
index b39f63ecbc..1b496d689a 100644
--- a/tests/auto/declarative/qdeclarativemoduleplugin/pluginWithQmlFile/pluginWithQmlFile.pro
+++ b/tests/auto/declarative/qdeclarativemoduleplugin/pluginWithQmlFile/pluginWithQmlFile.pro
@@ -4,7 +4,4 @@ SOURCES = plugin.cpp
QT = core declarative
DESTDIR = ../imports/com/nokia/AutoTestPluginWithQmlFile
-symbian: {
- TARGET.EPOCALLOWDLLDATA=1
-}
QT += core-private gui-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/pluginWrongCase/pluginWrongCase.pro b/tests/auto/declarative/qdeclarativemoduleplugin/pluginWrongCase/pluginWrongCase.pro
index 87cf7d61b5..5d21114a2f 100644
--- a/tests/auto/declarative/qdeclarativemoduleplugin/pluginWrongCase/pluginWrongCase.pro
+++ b/tests/auto/declarative/qdeclarativemoduleplugin/pluginWrongCase/pluginWrongCase.pro
@@ -5,7 +5,4 @@ QT = core declarative
TARGET = Plugin
DESTDIR = ../imports/com/nokia/WrongCase
-symbian: {
- TARGET.EPOCALLOWDLLDATA=1
-}
QT += core-private gui-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp
index 3b08229554..d8b7cf4e5b 100644
--- a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp
+++ b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp
@@ -45,7 +45,7 @@
#include <QDebug>
#include "../shared/testhttpserver.h"
-#include "../../../shared/util.h"
+#include "../shared/util.h"
#define SERVER_ADDR "http://127.0.0.1:14450"
#define SERVER_PORT 14450
@@ -74,11 +74,6 @@ private slots:
void implicitQmldir_data();
};
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
#define VERIFY_ERRORS(errorfile) \
if (!errorfile) { \
if (qgetenv("DEBUG") != "" && !component.errors().isEmpty()) \
@@ -86,7 +81,7 @@ private slots:
QVERIFY(!component.isError()); \
QVERIFY(component.errors().isEmpty()); \
} else { \
- QString verify_errors_file_name = QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("data") + QDir::separator() + QLatin1String(errorfile); \
+ QString verify_errors_file_name = TESTDATA(errorfile); \
QFile file(verify_errors_file_name); \
QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); \
QByteArray data = file.readAll(); \
@@ -106,7 +101,7 @@ private slots:
qWarning() << "Expected:" << expected << "Actual:" << actual; \
} \
if (qgetenv("QDECLARATIVELANGUAGE_UPDATEERRORS") != "" && expected != actual) {\
- QFile file(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("data") + QDir::separator() + QLatin1String(errorfile)); \
+ QFile file(TESTDATA(errorfile)); \
QVERIFY(file.open(QIODevice::WriteOnly)); \
for (int ii = 0; ii < actual.count(); ++ii) { \
file.write(actual.at(ii)); file.write("\n"); \
@@ -119,17 +114,38 @@ private slots:
inline QUrl TEST_FILE(const QString &filename)
{
- QFileInfo fileInfo(__FILE__);
- return QUrl::fromLocalFile(fileInfo.absoluteDir().filePath(filename));
+ return QUrl::fromLocalFile(TESTDATA(filename));
+}
+
+QString IMPORTSDIR()
+{
+ // Try to find it relative to the binary.
+ QDir appDir(QCoreApplication::applicationDirPath() + QDir::separator() + QLatin1String("imports"));
+ if (appDir.exists()) {
+ return appDir.absolutePath();
+ }
+
+ // Else try to find it in the source tree
+ QDir sourceDir(QFileInfo(__FILE__).absoluteDir().filePath(QLatin1String("imports")));
+ if (sourceDir.exists()) {
+ return sourceDir.absolutePath();
+ }
+
+ qWarning("requested importsPath could not be found (looked at: %s, %s)",
+ qPrintable(appDir.path()),
+ qPrintable(sourceDir.path())
+ );
+
+ return QString();
}
void tst_qdeclarativemoduleplugin::importsPlugin()
{
QDeclarativeEngine engine;
- engine.addImportPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports"));
+ engine.addImportPath(IMPORTSDIR());
QTest::ignoreMessage(QtWarningMsg, "plugin created");
QTest::ignoreMessage(QtWarningMsg, "import worked");
- QDeclarativeComponent component(&engine, TEST_FILE("data/works.qml"));
+ QDeclarativeComponent component(&engine, TEST_FILE("works.qml"));
foreach (QDeclarativeError err, component.errors())
qWarning() << err;
VERIFY_ERRORS(0);
@@ -142,10 +158,10 @@ void tst_qdeclarativemoduleplugin::importsPlugin()
void tst_qdeclarativemoduleplugin::importsPlugin2()
{
QDeclarativeEngine engine;
- engine.addImportPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports"));
+ engine.addImportPath(IMPORTSDIR());
QTest::ignoreMessage(QtWarningMsg, "plugin2 created");
QTest::ignoreMessage(QtWarningMsg, "import2 worked");
- QDeclarativeComponent component(&engine, TEST_FILE("data/works2.qml"));
+ QDeclarativeComponent component(&engine, TEST_FILE("works2.qml"));
foreach (QDeclarativeError err, component.errors())
qWarning() << err;
VERIFY_ERRORS(0);
@@ -158,10 +174,10 @@ void tst_qdeclarativemoduleplugin::importsPlugin2()
void tst_qdeclarativemoduleplugin::importsPlugin21()
{
QDeclarativeEngine engine;
- engine.addImportPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports"));
+ engine.addImportPath(IMPORTSDIR());
QTest::ignoreMessage(QtWarningMsg, "plugin2.1 created");
QTest::ignoreMessage(QtWarningMsg, "import2.1 worked");
- QDeclarativeComponent component(&engine, TEST_FILE("data/works21.qml"));
+ QDeclarativeComponent component(&engine, TEST_FILE("works21.qml"));
foreach (QDeclarativeError err, component.errors())
qWarning() << err;
VERIFY_ERRORS(0);
@@ -174,9 +190,9 @@ void tst_qdeclarativemoduleplugin::importsPlugin21()
void tst_qdeclarativemoduleplugin::incorrectPluginCase()
{
QDeclarativeEngine engine;
- engine.addImportPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports"));
+ engine.addImportPath(IMPORTSDIR());
- QDeclarativeComponent component(&engine, TEST_FILE("data/incorrectCase.qml"));
+ QDeclarativeComponent component(&engine, TEST_FILE("incorrectCase.qml"));
QList<QDeclarativeError> errors = component.errors();
QCOMPARE(errors.count(), 1);
@@ -187,7 +203,7 @@ void tst_qdeclarativemoduleplugin::incorrectPluginCase()
#elif defined(Q_OS_WIN32)
QString libname = "PluGin.dll";
#endif
- QString expectedError = QLatin1String("plugin cannot be loaded for module \"com.nokia.WrongCase\": File name case mismatch for \"") + QFileInfo(__FILE__).absoluteDir().filePath("imports/com/nokia/WrongCase/" + libname) + QLatin1String("\"");
+ QString expectedError = QLatin1String("plugin cannot be loaded for module \"com.nokia.WrongCase\": File name case mismatch for \"") + QDir(IMPORTSDIR()).filePath("com/nokia/WrongCase/" + libname) + QLatin1String("\"");
#else
QString expectedError = QLatin1String("module \"com.nokia.WrongCase\" plugin \"PluGin\" not found");
#endif
@@ -197,7 +213,7 @@ void tst_qdeclarativemoduleplugin::incorrectPluginCase()
void tst_qdeclarativemoduleplugin::importPluginWithQmlFile()
{
- QString path = QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports");
+ QString path = IMPORTSDIR();
// QTBUG-16885: adding an import path with a lower-case "c:" causes assert failure
// (this only happens if the plugin includes pure QML files)
@@ -209,7 +225,7 @@ void tst_qdeclarativemoduleplugin::importPluginWithQmlFile()
QDeclarativeEngine engine;
engine.addImportPath(path);
- QDeclarativeComponent component(&engine, TEST_FILE("data/pluginWithQmlFile.qml"));
+ QDeclarativeComponent component(&engine, TEST_FILE("pluginWithQmlFile.qml"));
foreach (QDeclarativeError err, component.errors())
qWarning() << err;
VERIFY_ERRORS(0);
@@ -222,7 +238,7 @@ void tst_qdeclarativemoduleplugin::remoteImportWithQuotedUrl()
{
TestHTTPServer server(SERVER_PORT);
QVERIFY(server.isValid());
- server.serveDirectory(SRCDIR "/imports");
+ server.serveDirectory(IMPORTSDIR());
QDeclarativeEngine engine;
QDeclarativeComponent component(&engine);
@@ -243,10 +259,10 @@ void tst_qdeclarativemoduleplugin::remoteImportWithUnquotedUri()
{
TestHTTPServer server(SERVER_PORT);
QVERIFY(server.isValid());
- server.serveDirectory(SRCDIR "/imports");
+ server.serveDirectory(IMPORTSDIR());
QDeclarativeEngine engine;
- engine.addImportPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports"));
+ engine.addImportPath(IMPORTSDIR());
QDeclarativeComponent component(&engine);
component.setData("import com.nokia.PureQmlModule 1.0 \nComponentA { width: 300; ComponentB{} }", QUrl());
@@ -266,10 +282,10 @@ void tst_qdeclarativemoduleplugin::remoteImportWithUnquotedUri()
void tst_qdeclarativemoduleplugin::importsMixedQmlCppPlugin()
{
QDeclarativeEngine engine;
- engine.addImportPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports"));
+ engine.addImportPath(IMPORTSDIR());
{
- QDeclarativeComponent component(&engine, TEST_FILE("data/importsMixedQmlCppPlugin.qml"));
+ QDeclarativeComponent component(&engine, TEST_FILE("importsMixedQmlCppPlugin.qml"));
QObject *o = component.create();
QVERIFY(o != 0);
@@ -278,7 +294,7 @@ void tst_qdeclarativemoduleplugin::importsMixedQmlCppPlugin()
}
{
- QDeclarativeComponent component(&engine, TEST_FILE("data/importsMixedQmlCppPlugin.2.qml"));
+ QDeclarativeComponent component(&engine, TEST_FILE("importsMixedQmlCppPlugin.2.qml"));
QObject *o = component.create();
QVERIFY(o != 0);
@@ -295,8 +311,8 @@ void tst_qdeclarativemoduleplugin::versionNotInstalled_data()
QTest::addColumn<QString>("file");
QTest::addColumn<QString>("errorFile");
- QTest::newRow("versionNotInstalled") << "data/versionNotInstalled.qml" << "versionNotInstalled.errors.txt";
- QTest::newRow("versionNotInstalled") << "data/versionNotInstalled.2.qml" << "versionNotInstalled.2.errors.txt";
+ QTest::newRow("versionNotInstalled") << "versionNotInstalled.qml" << "versionNotInstalled.errors.txt";
+ QTest::newRow("versionNotInstalled") << "versionNotInstalled.2.qml" << "versionNotInstalled.2.errors.txt";
}
void tst_qdeclarativemoduleplugin::versionNotInstalled()
@@ -305,7 +321,7 @@ void tst_qdeclarativemoduleplugin::versionNotInstalled()
QFETCH(QString, errorFile);
QDeclarativeEngine engine;
- engine.addImportPath(QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("imports"));
+ engine.addImportPath(IMPORTSDIR());
QDeclarativeComponent component(&engine, TEST_FILE(file));
VERIFY_ERRORS(errorFile.toLatin1().constData());
@@ -331,8 +347,8 @@ void tst_qdeclarativemoduleplugin::implicitQmldir()
QFETCH(QString, file);
QFETCH(QString, errorFile);
- QString importPath = QLatin1String(SRCDIR) + QDir::separator() + QLatin1String("data") + QDir::separator() + directory;
- QString fileName = QLatin1String("data") + QDir::separator() + directory + QDir::separator() + file;
+ QString importPath = TESTDATA(directory);
+ QString fileName = directory + QDir::separator() + file;
QString errorFileName = directory + QDir::separator() + errorFile;
QUrl testFileUrl = TEST_FILE(fileName);
diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.pro b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.pro
index b22162676c..94c0f9dde1 100644
--- a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.pro
+++ b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.pro
@@ -1,16 +1,17 @@
-load(qttest_p4)
+CONFIG += testcase
+TARGET = tst_qdeclarativemoduleplugin
HEADERS = ../shared/testhttpserver.h
SOURCES = tst_qdeclarativemoduleplugin.cpp \
../shared/testhttpserver.cpp
-QT += declarative network
CONFIG -= app_bundle
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-QT += core-private gui-private declarative-private
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+testImportFiles.files = imports
+testImportFiles.path = .
+DEPLOYMENT += testImportFiles
+
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qdeclarativepath/qdeclarativepath.pro b/tests/auto/declarative/qdeclarativepath/qdeclarativepath.pro
index d6fe1cf789..212117165d 100644
--- a/tests/auto/declarative/qdeclarativepath/qdeclarativepath.pro
+++ b/tests/auto/declarative/qdeclarativepath/qdeclarativepath.pro
@@ -1,17 +1,13 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qdeclarativepath
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativepath.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private
+QT += core-private gui-private v8-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativepath/tst_qdeclarativepath.cpp b/tests/auto/declarative/qdeclarativepath/tst_qdeclarativepath.cpp
index d8a539ea2a..91513fc8a5 100644
--- a/tests/auto/declarative/qdeclarativepath/tst_qdeclarativepath.cpp
+++ b/tests/auto/declarative/qdeclarativepath/tst_qdeclarativepath.cpp
@@ -44,12 +44,7 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtDeclarative/private/qdeclarativepath_p.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class tst_QDeclarativePath : public QObject
{
@@ -66,7 +61,7 @@ private slots:
void tst_QDeclarativePath::arc()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/arc.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("arc.qml")));
QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create());
QVERIFY(obj != 0);
@@ -101,7 +96,7 @@ void tst_QDeclarativePath::arc()
void tst_QDeclarativePath::catmullromCurve()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/curve.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("curve.qml")));
QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create());
QVERIFY(obj != 0);
@@ -136,7 +131,7 @@ void tst_QDeclarativePath::catmullromCurve()
void tst_QDeclarativePath::svg()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/svg.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("svg.qml")));
QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create());
QVERIFY(obj != 0);
diff --git a/tests/auto/declarative/qdeclarativepixmapcache/qdeclarativepixmapcache.pro b/tests/auto/declarative/qdeclarativepixmapcache/qdeclarativepixmapcache.pro
index aaf94ea291..79d411c62c 100644
--- a/tests/auto/declarative/qdeclarativepixmapcache/qdeclarativepixmapcache.pro
+++ b/tests/auto/declarative/qdeclarativepixmapcache/qdeclarativepixmapcache.pro
@@ -1,6 +1,5 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
-QT += network
+CONFIG += testcase
+TARGET = tst_qdeclarativepixmapcache
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativepixmapcache.cpp
@@ -9,17 +8,13 @@ INCLUDEPATH += ../shared/
HEADERS += ../shared/testhttpserver.h
SOURCES += ../shared/testhttpserver.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+importFiles.files = data
+importFiles.path = .
+DEPLOYMENT += importFiles
# QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage
# LIBS += -lgcov
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp b/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp
index e810e1e8a8..386d465982 100644
--- a/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp
+++ b/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp
@@ -45,7 +45,6 @@
#include <QtDeclarative/qdeclarativeimageprovider.h>
#include <QNetworkReply>
#include "testhttpserver.h"
-#include "../../../shared/util.h"
#ifndef QT_NO_CONCURRENT
#include <qtconcurrentrun.h>
@@ -55,20 +54,15 @@
// These don't let normal people run tests!
//#include "../network-settings.h"
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qdeclarativepixmapcache : public QObject
{
Q_OBJECT
public:
tst_qdeclarativepixmapcache() :
- thisfile(QUrl::fromLocalFile(__FILE__)),
+ thisfile(QUrl::fromLocalFile(QCoreApplication::applicationFilePath())),
server(14452)
{
- server.serveDirectory(SRCDIR "/data/http");
+ server.serveDirectory(QCoreApplication::applicationDirPath() + "/data/http");
}
private slots:
@@ -368,7 +362,7 @@ void createNetworkServer()
{
QEventLoop eventLoop;
TestHTTPServer server(14453);
- server.serveDirectory(SRCDIR "/data/http");
+ server.serveDirectory(QCoreApplication::applicationDirPath() + "/data/http");
QTimer::singleShot(100, &eventLoop, SLOT(quit()));
eventLoop.exec();
}
diff --git a/tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro b/tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro
index 223133400d..310fa94214 100644
--- a/tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro
+++ b/tests/auto/declarative/qdeclarativeproperty/qdeclarativeproperty.pro
@@ -1,17 +1,13 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative widgets
+CONFIG += testcase
+TARGET = tst_qdeclarativeproperty
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativeproperty.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private
+QT += core-private gui-private v8-private declarative-private widgets testlib
diff --git a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp
index 75c2f7f7b0..411eeeacc7 100644
--- a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp
+++ b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp
@@ -47,16 +47,11 @@
#include <QtWidgets/QLineEdit>
#include <QtCore/qfileinfo.h>
#include <QtCore/qdir.h>
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
inline QUrl TEST_FILE(const QString &filename)
{
- QFileInfo fileInfo(__FILE__);
- return QUrl::fromLocalFile(fileInfo.absoluteDir().filePath(QLatin1String("data/") + filename));
+ return QUrl::fromLocalFile(TESTDATA(filename));
}
class MyQmlObject : public QObject
diff --git a/tests/auto/declarative/qdeclarativepropertymap/qdeclarativepropertymap.pro b/tests/auto/declarative/qdeclarativepropertymap/qdeclarativepropertymap.pro
index 505058b1af..a6332161a0 100644
--- a/tests/auto/declarative/qdeclarativepropertymap/qdeclarativepropertymap.pro
+++ b/tests/auto/declarative/qdeclarativepropertymap/qdeclarativepropertymap.pro
@@ -1,9 +1,9 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qdeclarativepropertymap
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativepropertymap.cpp
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro b/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro
index 69ebb8e668..18fb8b2027 100644
--- a/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro
+++ b/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro
@@ -1,19 +1,12 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qdeclarativeqt
SOURCES += tst_qdeclarativeqt.cpp
macx:CONFIG -= app_bundle
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-
-# QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage
-# LIBS += -lgcov
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private
+QT += core-private gui-private v8-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp
index d9cd2b8fdf..dbf5373599 100644
--- a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp
+++ b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp
@@ -52,11 +52,7 @@
#include <QCryptographicHash>
#include <QSGItem>
#include <QSignalSpy>
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class tst_qdeclarativeqt : public QObject
{
@@ -100,7 +96,7 @@ private:
inline QUrl TEST_FILE(const QString &filename)
{
- return QUrl::fromLocalFile(QLatin1String(SRCDIR) + QLatin1String("/data/") + filename);
+ return QUrl::fromLocalFile(TESTDATA(filename));
}
void tst_qdeclarativeqt::enums()
diff --git a/tests/auto/declarative/qdeclarativescriptdebugging/data/backtrace1.js b/tests/auto/declarative/qdeclarativescriptdebugging/data/backtrace1.js
deleted file mode 100644
index 8decbf03a4..0000000000
--- a/tests/auto/declarative/qdeclarativescriptdebugging/data/backtrace1.js
+++ /dev/null
@@ -1,11 +0,0 @@
-
-function function2InScript(a)
-{
- mainRectangle.foo = a;
-}
-
-
-function functionInScript(a , b)
-{
- function2InScript(a + b);
-}
diff --git a/tests/auto/declarative/qdeclarativescriptdebugging/data/backtrace1.qml b/tests/auto/declarative/qdeclarativescriptdebugging/data/backtrace1.qml
deleted file mode 100644
index 8bba61ec15..0000000000
--- a/tests/auto/declarative/qdeclarativescriptdebugging/data/backtrace1.qml
+++ /dev/null
@@ -1,27 +0,0 @@
-import QtQuick 2.0
-import Qt.test 1.0
-import "backtrace1.js" as Script
-
-Rectangle {
- id: mainRectangle
-
- property string foo: "Default";
- width: 200
- height: 200
-
-
- MyTestObject {
-
- function append(a, b) {
- return a + " " + b;
- }
-
-
- id: testObject;
- someProperty: append("Hello", mainRectangle.foo)
-
- onSignaled: {
- Script.functionInScript(value , "b");
- }
- }
-}
diff --git a/tests/auto/declarative/qdeclarativescriptdebugging/qdeclarativescriptdebugging.pro b/tests/auto/declarative/qdeclarativescriptdebugging/qdeclarativescriptdebugging.pro
deleted file mode 100644
index cedb92743e..0000000000
--- a/tests/auto/declarative/qdeclarativescriptdebugging/qdeclarativescriptdebugging.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_qdeclarativescriptdebugging.cpp
-INCLUDEPATH += ../shared
-
-# QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage
-# LIBS += -lgcov
-
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-
-CONFIG += parallel_test
-
-QT += core-private gui-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativescriptdebugging/tst_qdeclarativescriptdebugging.cpp b/tests/auto/declarative/qdeclarativescriptdebugging/tst_qdeclarativescriptdebugging.cpp
deleted file mode 100644
index 4301174184..0000000000
--- a/tests/auto/declarative/qdeclarativescriptdebugging/tst_qdeclarativescriptdebugging.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <qtest.h>
-#include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativeitem.h>
-#include <QtDeclarative/qdeclarativecontext.h>
-#include <QtCore/QDir>
-#include <QtScript/QScriptEngineAgent>
-#include <private/qdeclarativeengine_p.h>
-
-class MyTestObject : public QObject {
- Q_OBJECT
- Q_PROPERTY(QString someProperty READ someProperty WRITE setSomeProperty NOTIFY somePropertyChanged)
-
-public:
- QString someProperty() { return _someProperty; }
- void setSomeProperty(const QString &p) { _someProperty = p; }
- QString _someProperty;
-
- void emitSignal(const QString &value) { emit signaled(value); }
-
-signals:
- void signaled(const QString &value);
- void somePropertyChanged();
-};
-
-
-class BtAgent : public QScriptEngineAgent {
-public:
- BtAgent(QScriptEngine *engine) : QScriptEngineAgent(engine)
- { count = 0; engine->setAgent(this); }
-
- QStringList bt;
- int count;
- int breakpoint;
- void positionChange(qint64 , int lineNumber, int )
- {
- if(lineNumber == breakpoint) {
- count++;
- bt = engine()->currentContext()->backtrace();
- }
- }
-};
-
-
-
-/*
-This test covers evaluation of ECMAScript expressions and bindings from within
-QML. This does not include static QML language issues.
-
-Static QML language issues are covered in qmllanguage
-*/
-inline QUrl TEST_FILE(const QString &filename)
-{
- QFileInfo fileInfo(__FILE__);
- return QUrl::fromLocalFile(fileInfo.absoluteDir().filePath("data/" + filename));
-}
-
-inline QUrl TEST_FILE(const char *filename)
-{
- return TEST_FILE(QLatin1String(filename));
-}
-
-class tst_qdeclarativescriptdebugging : public QObject
-{
- Q_OBJECT
-public:
- tst_qdeclarativescriptdebugging() {}
-
-private slots:
- void initTestCase();
- void backtrace1();
-};
-
-void tst_qdeclarativescriptdebugging::initTestCase()
-{
- qmlRegisterType<MyTestObject>("Qt.test", 1,0, "MyTestObject");
-}
-
-void tst_qdeclarativescriptdebugging::backtrace1()
-{
- {
- QDeclarativeEngine engine;
- QUrl file = TEST_FILE("backtrace1.qml");
- QDeclarativeComponent component(&engine, file);
- QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(component.create());
- QVERIFY(item);
- MyTestObject *obj = item->findChild<MyTestObject *>();
- QVERIFY(obj);
- QCOMPARE(obj->someProperty(), QString("Hello Default"));
-
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(&engine);
- BtAgent agent(&ep->scriptEngine);
- agent.breakpoint = 16;
-
- obj->emitSignal("blah");
- QCOMPARE(obj->someProperty(), QString("Hello blahb"));
- QCOMPARE(agent.count, 1);
-
- QStringList expected;
- expected << "append(a = 'Hello', b = 'blahb') at @PREFIX@/backtrace1.qml:16"
- << "$someProperty() at @PREFIX@/backtrace1.qml:21"
- << "function2InScript(a = 'blahb') at @PREFIX@/backtrace1.js:4"
- << "functionInScript(a = 'blah', b = 'b') at @PREFIX@/backtrace1.js:10"
- << "onSignaled() at @PREFIX@/backtrace1.qml:24"
- << "<global>() at -1";
- expected.replaceInStrings("@PREFIX@", file.toString().section('/', 0, -2));
- QCOMPARE(agent.bt, expected);
- }
-}
-
-
-QTEST_MAIN(tst_qdeclarativescriptdebugging)
-
-#include "tst_qdeclarativescriptdebugging.moc"
diff --git a/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro b/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro
index 27d2c0c1b2..05d31be39d 100644
--- a/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro
+++ b/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro
@@ -1,17 +1,13 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui
+CONFIG += testcase
+TARGET = tst_qdeclarativesmoothedanimation
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativesmoothedanimation.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private
+QT += core-private gui-private v8-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp b/tests/auto/declarative/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp
index 243f4e716b..989edfab8b 100644
--- a/tests/auto/declarative/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp
+++ b/tests/auto/declarative/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp
@@ -44,12 +44,7 @@
#include <private/qdeclarativesmoothedanimation_p.h>
#include <private/qsgrectangle_p.h>
#include <private/qdeclarativevaluetype_p.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class tst_qdeclarativesmoothedanimation : public QObject
{
@@ -76,7 +71,7 @@ tst_qdeclarativesmoothedanimation::tst_qdeclarativesmoothedanimation()
void tst_qdeclarativesmoothedanimation::defaultValues()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/smoothedanimation1.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("smoothedanimation1.qml")));
QDeclarativeSmoothedAnimation *obj = qobject_cast<QDeclarativeSmoothedAnimation*>(c.create());
QVERIFY(obj != 0);
@@ -93,7 +88,7 @@ void tst_qdeclarativesmoothedanimation::defaultValues()
void tst_qdeclarativesmoothedanimation::values()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/smoothedanimation2.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("smoothedanimation2.qml")));
QDeclarativeSmoothedAnimation *obj = qobject_cast<QDeclarativeSmoothedAnimation*>(c.create());
QVERIFY(obj != 0);
@@ -110,7 +105,7 @@ void tst_qdeclarativesmoothedanimation::values()
void tst_qdeclarativesmoothedanimation::disabled()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/smoothedanimation3.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("smoothedanimation3.qml")));
QDeclarativeSmoothedAnimation *obj = qobject_cast<QDeclarativeSmoothedAnimation*>(c.create());
QVERIFY(obj != 0);
@@ -153,7 +148,7 @@ void tst_qdeclarativesmoothedanimation::valueSource()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/smoothedanimationValueSource.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("smoothedanimationValueSource.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
@@ -185,7 +180,7 @@ void tst_qdeclarativesmoothedanimation::behavior()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/smoothedanimationBehavior.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("smoothedanimationBehavior.qml")));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect);
diff --git a/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro b/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro
index 63944117d6..7153327829 100644
--- a/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro
+++ b/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro
@@ -1,17 +1,13 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui
+CONFIG += testcase
+TARGET = tst_qdeclarativespringanimation
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativespringanimation.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private
+QT += core-private gui-private v8-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativespringanimation/tst_qdeclarativespringanimation.cpp b/tests/auto/declarative/qdeclarativespringanimation/tst_qdeclarativespringanimation.cpp
index 0c8ee5f416..d7edcee386 100644
--- a/tests/auto/declarative/qdeclarativespringanimation/tst_qdeclarativespringanimation.cpp
+++ b/tests/auto/declarative/qdeclarativespringanimation/tst_qdeclarativespringanimation.cpp
@@ -43,12 +43,7 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <private/qdeclarativespringanimation_p.h>
#include <private/qdeclarativevaluetype_p.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class tst_qdeclarativespringanimation : public QObject
{
@@ -72,7 +67,7 @@ tst_qdeclarativespringanimation::tst_qdeclarativespringanimation()
void tst_qdeclarativespringanimation::defaultValues()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/springanimation1.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("springanimation1.qml")));
QDeclarativeSpringAnimation *obj = qobject_cast<QDeclarativeSpringAnimation*>(c.create());
QVERIFY(obj != 0);
@@ -92,7 +87,7 @@ void tst_qdeclarativespringanimation::defaultValues()
void tst_qdeclarativespringanimation::values()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/springanimation2.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("springanimation2.qml")));
QDeclarativeSpringAnimation *obj = qobject_cast<QDeclarativeSpringAnimation*>(c.create());
QVERIFY(obj != 0);
@@ -114,7 +109,7 @@ void tst_qdeclarativespringanimation::values()
void tst_qdeclarativespringanimation::disabled()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/springanimation3.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("springanimation3.qml")));
QDeclarativeSpringAnimation *obj = qobject_cast<QDeclarativeSpringAnimation*>(c.create());
QVERIFY(obj != 0);
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro b/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro
index c22e8cc9e7..2d0efec9a5 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro
+++ b/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro
@@ -1,18 +1,13 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
-QT += sql
+CONFIG += testcase
+TARGET = tst_qdeclarativesqldatabase
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativesqldatabase.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-
CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private sql testlib
diff --git a/tests/auto/declarative/qdeclarativesqldatabase/tst_qdeclarativesqldatabase.cpp b/tests/auto/declarative/qdeclarativesqldatabase/tst_qdeclarativesqldatabase.cpp
index 7517bd3498..b7e04b7e70 100644
--- a/tests/auto/declarative/qdeclarativesqldatabase/tst_qdeclarativesqldatabase.cpp
+++ b/tests/auto/declarative/qdeclarativesqldatabase/tst_qdeclarativesqldatabase.cpp
@@ -39,7 +39,6 @@
**
****************************************************************************/
#include <qtest.h>
-#include "../../../shared/util.h"
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtDeclarative/qdeclarativecomponent.h>
#include <private/qsgtext_p.h>
@@ -54,11 +53,7 @@
#include <QtSql/qsqldatabase.h>
#include <QtCore/qdir.h>
#include <QtCore/qfile.h>
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class tst_qdeclarativesqldatabase : public QObject
{
@@ -138,22 +133,22 @@ void tst_qdeclarativesqldatabase::testQml_data()
QTest::addColumn<QString>("jsfile"); // The input file
// Each test should use a newly named DB to avoid inter-test dependencies
- QTest::newRow("creation") << "data/creation.js";
- QTest::newRow("creation-a") << "data/creation-a.js";
- QTest::newRow("creation") << "data/creation.js";
- QTest::newRow("error-creation") << "data/error-creation.js"; // re-uses above DB
- QTest::newRow("changeversion") << "data/changeversion.js";
- QTest::newRow("readonly") << "data/readonly.js";
- QTest::newRow("readonly-error") << "data/readonly-error.js";
- QTest::newRow("selection") << "data/selection.js";
- QTest::newRow("selection-bindnames") << "data/selection-bindnames.js";
- QTest::newRow("iteration") << "data/iteration.js";
- QTest::newRow("iteration-forwardonly") << "data/iteration-forwardonly.js";
- QTest::newRow("error-a") << "data/error-a.js";
- QTest::newRow("error-notransaction") << "data/error-notransaction.js";
- QTest::newRow("error-outsidetransaction") << "data/error-outsidetransaction.js"; // reuse above
- QTest::newRow("reopen1") << "data/reopen1.js";
- QTest::newRow("reopen2") << "data/reopen2.js"; // re-uses above DB
+ QTest::newRow("creation") << "creation.js";
+ QTest::newRow("creation-a") << "creation-a.js";
+ QTest::newRow("creation") << "creation.js";
+ QTest::newRow("error-creation") << "error-creation.js"; // re-uses above DB
+ QTest::newRow("changeversion") << "changeversion.js";
+ QTest::newRow("readonly") << "readonly.js";
+ QTest::newRow("readonly-error") << "readonly-error.js";
+ QTest::newRow("selection") << "selection.js";
+ QTest::newRow("selection-bindnames") << "selection-bindnames.js";
+ QTest::newRow("iteration") << "iteration.js";
+ QTest::newRow("iteration-forwardonly") << "iteration-forwardonly.js";
+ QTest::newRow("error-a") << "error-a.js";
+ QTest::newRow("error-notransaction") << "error-notransaction.js";
+ QTest::newRow("error-outsidetransaction") << "error-outsidetransaction.js"; // reuse above
+ QTest::newRow("reopen1") << "reopen1.js";
+ QTest::newRow("reopen2") << "reopen2.js"; // re-uses above DB
// If you add a test, you should usually use a new database in the
// test - in which case increment total_databases_created_by_tests above.
@@ -209,7 +204,7 @@ void tst_qdeclarativesqldatabase::testQml()
engine->setOfflineStoragePath(dbDir());
QDeclarativeComponent component(engine);
- component.setData(qml.toUtf8(), QUrl::fromLocalFile(SRCDIR "/empty.qml")); // just a file for relative local imports
+ component.setData(qml.toUtf8(), QUrl::fromLocalFile(TESTDATA("empty.qml"))); // just a file for relative local imports
QVERIFY(!component.isError());
QSGText *text = qobject_cast<QSGText*>(component.create());
QVERIFY(text != 0);
@@ -219,9 +214,9 @@ void tst_qdeclarativesqldatabase::testQml()
void tst_qdeclarativesqldatabase::testQml_cleanopen_data()
{
QTest::addColumn<QString>("jsfile"); // The input file
- QTest::newRow("reopen1") << "data/reopen1.js";
- QTest::newRow("reopen2") << "data/reopen2.js";
- QTest::newRow("error-creation") << "data/error-creation.js"; // re-uses creation DB
+ QTest::newRow("reopen1") << "reopen1.js";
+ QTest::newRow("reopen2") << "reopen2.js";
+ QTest::newRow("error-creation") << "error-creation.js"; // re-uses creation DB
}
void tst_qdeclarativesqldatabase::testQml_cleanopen()
diff --git a/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro b/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro
index 9935178beb..c0ffda7828 100644
--- a/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro
+++ b/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro
@@ -1,18 +1,12 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qdeclarativestates
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativestates.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-#temporary
-CONFIG += insignificant_test
-QT += core-private gui-private v8-private declarative-private opengl-private
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
diff --git a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp
index f3b93ef67f..ac24a0b6c5 100644
--- a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp
+++ b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp
@@ -50,12 +50,7 @@
#include <private/qdeclarativestategroup_p.h>
#include <private/qsgitem_p.h>
#include <private/qdeclarativeproperty_p.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class MyAttached : public QObject
{
@@ -159,7 +154,7 @@ void tst_qdeclarativestates::initTestCase()
QByteArray tst_qdeclarativestates::fullDataPath(const QString &path)
{
- return QUrl::fromLocalFile(SRCDIR + path).toString().toUtf8();
+ return QUrl::fromLocalFile(TESTDATA(path)).toString().toUtf8();
}
void tst_qdeclarativestates::basicChanges()
@@ -167,7 +162,7 @@ void tst_qdeclarativestates::basicChanges()
QDeclarativeEngine engine;
{
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicChanges.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("basicChanges.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
QVERIFY(rect != 0);
@@ -182,7 +177,7 @@ void tst_qdeclarativestates::basicChanges()
}
{
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicChanges2.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("basicChanges2.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
QVERIFY(rect != 0);
@@ -203,7 +198,7 @@ void tst_qdeclarativestates::basicChanges()
}
{
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicChanges3.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("basicChanges3.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
QVERIFY(rect != 0);
@@ -239,7 +234,7 @@ void tst_qdeclarativestates::basicChanges()
// signal using 'onPropertyWithNotifyChanged' even though the signal name is
// actually 'oddlyNamedNotifySignal'
- QDeclarativeComponent component(&engine, SRCDIR "/data/basicChanges4.qml");
+ QDeclarativeComponent component(&engine, TESTDATA("basicChanges4.qml"));
QVERIFY(component.isReady());
MyRect *rect = qobject_cast<MyRect*>(component.create());
@@ -261,7 +256,7 @@ void tst_qdeclarativestates::attachedPropertyChanges()
{
QDeclarativeEngine engine;
- QDeclarativeComponent component(&engine, SRCDIR "/data/attachedPropertyChanges.qml");
+ QDeclarativeComponent component(&engine, TESTDATA("attachedPropertyChanges.qml"));
QVERIFY(component.isReady());
QSGItem *item = qobject_cast<QSGItem*>(component.create());
@@ -283,7 +278,7 @@ void tst_qdeclarativestates::basicExtension()
QDeclarativeEngine engine;
{
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicExtension.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("basicExtension.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
QVERIFY(rect != 0);
@@ -317,7 +312,7 @@ void tst_qdeclarativestates::basicExtension()
}
{
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/fakeExtension.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("fakeExtension.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
QVERIFY(rect != 0);
@@ -349,7 +344,7 @@ void tst_qdeclarativestates::basicBinding()
QDeclarativeEngine engine;
{
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicBinding.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("basicBinding.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
QVERIFY(rect != 0);
@@ -377,7 +372,7 @@ void tst_qdeclarativestates::basicBinding()
}
{
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicBinding2.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("basicBinding2.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
QVERIFY(rect != 0);
@@ -408,7 +403,7 @@ void tst_qdeclarativestates::basicBinding()
}
{
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicBinding3.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("basicBinding3.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
QVERIFY(rect != 0);
@@ -433,7 +428,7 @@ void tst_qdeclarativestates::basicBinding()
}
{
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicBinding4.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("basicBinding4.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
QVERIFY(rect != 0);
@@ -466,7 +461,7 @@ void tst_qdeclarativestates::signalOverride()
QDeclarativeEngine engine;
{
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverride.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("signalOverride.qml"));
MyRect *rect = qobject_cast<MyRect*>(rectComponent.create());
QVERIFY(rect != 0);
@@ -480,7 +475,7 @@ void tst_qdeclarativestates::signalOverride()
}
{
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverride2.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("signalOverride2.qml"));
MyRect *rect = qobject_cast<MyRect*>(rectComponent.create());
QVERIFY(rect != 0);
@@ -501,7 +496,7 @@ void tst_qdeclarativestates::signalOverrideCrash()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverrideCrash.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("signalOverrideCrash.qml"));
MyRect *rect = qobject_cast<MyRect*>(rectComponent.create());
QVERIFY(rect != 0);
@@ -513,7 +508,7 @@ void tst_qdeclarativestates::signalOverrideCrash2()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/signalOverrideCrash2.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("signalOverrideCrash2.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
@@ -529,7 +524,7 @@ void tst_qdeclarativestates::parentChange()
QDeclarativeEngine engine;
{
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange1.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange1.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
@@ -556,7 +551,7 @@ void tst_qdeclarativestates::parentChange()
}
{
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange2.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange2.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -571,7 +566,7 @@ void tst_qdeclarativestates::parentChange()
}
{
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange3.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange3.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -593,7 +588,7 @@ void tst_qdeclarativestates::parentChange()
}
{
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange6.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange6.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
@@ -613,14 +608,14 @@ void tst_qdeclarativestates::parentChangeErrors()
QDeclarativeEngine engine;
{
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange4.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange4.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"));
QVERIFY(innerRect != 0);
- QTest::ignoreMessage(QtWarningMsg, fullDataPath("/data/parentChange4.qml") + ":25:9: QML ParentChange: Unable to preserve appearance under non-uniform scale");
+ QTest::ignoreMessage(QtWarningMsg, fullDataPath("parentChange4.qml") + ":25:9: QML ParentChange: Unable to preserve appearance under non-uniform scale");
QSGItemPrivate::get(rect)->setState("reparented");
QCOMPARE(innerRect->rotation(), qreal(0));
QCOMPARE(innerRect->scale(), qreal(1));
@@ -629,14 +624,14 @@ void tst_qdeclarativestates::parentChangeErrors()
}
{
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/parentChange5.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange5.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"));
QVERIFY(innerRect != 0);
- QTest::ignoreMessage(QtWarningMsg, fullDataPath("/data/parentChange5.qml") + ":25:9: QML ParentChange: Unable to preserve appearance under complex transform");
+ QTest::ignoreMessage(QtWarningMsg, fullDataPath("parentChange5.qml") + ":25:9: QML ParentChange: Unable to preserve appearance under complex transform");
QSGItemPrivate::get(rect)->setState("reparented");
QCOMPARE(innerRect->rotation(), qreal(0));
QCOMPARE(innerRect->scale(), qreal(1));
@@ -649,7 +644,7 @@ void tst_qdeclarativestates::anchorChanges()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges1.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges1.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -682,7 +677,7 @@ void tst_qdeclarativestates::anchorChanges2()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges2.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges2.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -703,7 +698,7 @@ void tst_qdeclarativestates::anchorChanges3()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges3.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges3.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -754,7 +749,7 @@ void tst_qdeclarativestates::anchorChanges4()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges4.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges4.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
@@ -789,7 +784,7 @@ void tst_qdeclarativestates::anchorChanges5()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges5.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges5.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
@@ -833,7 +828,7 @@ void tst_qdeclarativestates::anchorChangesRTL()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges1.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges1.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -867,7 +862,7 @@ void tst_qdeclarativestates::anchorChangesRTL2()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges2.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges2.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -889,7 +884,7 @@ void tst_qdeclarativestates::anchorChangesRTL3()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChanges3.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges3.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -944,7 +939,7 @@ void tst_qdeclarativestates::anchorChangesCrash()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorChangesCrash.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChangesCrash.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
@@ -957,7 +952,7 @@ void tst_qdeclarativestates::anchorChangesCrash()
void tst_qdeclarativestates::anchorRewindBug()
{
QSGView *view = new QSGView;
- view->setSource(QUrl::fromLocalFile(SRCDIR "/data/anchorRewindBug.qml"));
+ view->setSource(QUrl::fromLocalFile(TESTDATA("anchorRewindBug.qml")));
view->show();
view->requestActivateWindow();
@@ -997,7 +992,7 @@ void tst_qdeclarativestates::anchorRewindBug2()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/anchorRewindBug2.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorRewindBug2.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
@@ -1023,7 +1018,7 @@ void tst_qdeclarativestates::script()
QDeclarativeEngine engine;
{
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/script.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("script.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -1041,7 +1036,7 @@ void tst_qdeclarativestates::restoreEntryValues()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/restoreEntryValues.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("restoreEntryValues.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -1058,7 +1053,7 @@ void tst_qdeclarativestates::explicitChanges()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/explicit.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("explicit.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -1091,14 +1086,14 @@ void tst_qdeclarativestates::explicitChanges()
void tst_qdeclarativestates::propertyErrors()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/propertyErrors.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("propertyErrors.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QCOMPARE(rect->color(),QColor("red"));
- QTest::ignoreMessage(QtWarningMsg, fullDataPath("/data/propertyErrors.qml") + ":8:9: QML PropertyChanges: Cannot assign to non-existent property \"colr\"");
- QTest::ignoreMessage(QtWarningMsg, fullDataPath("/data/propertyErrors.qml") + ":8:9: QML PropertyChanges: Cannot assign to read-only property \"activeFocus\"");
+ QTest::ignoreMessage(QtWarningMsg, fullDataPath("propertyErrors.qml") + ":8:9: QML PropertyChanges: Cannot assign to non-existent property \"colr\"");
+ QTest::ignoreMessage(QtWarningMsg, fullDataPath("propertyErrors.qml") + ":8:9: QML PropertyChanges: Cannot assign to read-only property \"activeFocus\"");
QSGItemPrivate::get(rect)->setState("blue");
}
@@ -1106,7 +1101,7 @@ void tst_qdeclarativestates::incorrectRestoreBug()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/basicChanges.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("basicChanges.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -1132,7 +1127,7 @@ void tst_qdeclarativestates::autoStateAtStartupRestoreBug()
{
QDeclarativeEngine engine;
- QDeclarativeComponent component(&engine, SRCDIR "/data/autoStateAtStartupRestoreBug.qml");
+ QDeclarativeComponent component(&engine, TESTDATA("autoStateAtStartupRestoreBug.qml"));
QObject *obj = component.create();
QVERIFY(obj != 0);
@@ -1149,7 +1144,7 @@ void tst_qdeclarativestates::deletingChange()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/deleting.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("deleting.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -1181,7 +1176,7 @@ void tst_qdeclarativestates::deletingState()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/deletingState.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("deletingState.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
@@ -1212,7 +1207,7 @@ void tst_qdeclarativestates::tempState()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/legalTempState.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("legalTempState.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -1226,7 +1221,7 @@ void tst_qdeclarativestates::illegalTempState()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/illegalTempState.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("illegalTempState.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -1239,11 +1234,11 @@ void tst_qdeclarativestates::nonExistantProperty()
{
QDeclarativeEngine engine;
- QDeclarativeComponent rectComponent(&engine, SRCDIR "/data/nonExistantProp.qml");
+ QDeclarativeComponent rectComponent(&engine, TESTDATA("nonExistantProp.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
- QTest::ignoreMessage(QtWarningMsg, fullDataPath("/data/nonExistantProp.qml") + ":9:9: QML PropertyChanges: Cannot assign to non-existent property \"colr\"");
+ QTest::ignoreMessage(QtWarningMsg, fullDataPath("nonExistantProp.qml") + ":9:9: QML PropertyChanges: Cannot assign to non-existent property \"colr\"");
rectPrivate->setState("blue");
QCOMPARE(rectPrivate->state(), QLatin1String("blue"));
}
@@ -1252,7 +1247,7 @@ void tst_qdeclarativestates::reset()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, SRCDIR "/data/reset.qml");
+ QDeclarativeComponent c(&engine, TESTDATA("reset.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
@@ -1271,7 +1266,7 @@ void tst_qdeclarativestates::illegalObjectCreation()
{
QDeclarativeEngine engine;
- QDeclarativeComponent component(&engine, SRCDIR "/data/illegalObj.qml");
+ QDeclarativeComponent component(&engine, TESTDATA("illegalObj.qml"));
QList<QDeclarativeError> errors = component.errors();
QVERIFY(errors.count() == 1);
const QDeclarativeError &error = errors.at(0);
@@ -1284,7 +1279,7 @@ void tst_qdeclarativestates::whenOrdering()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, SRCDIR "/data/whenOrdering.qml");
+ QDeclarativeComponent c(&engine, TESTDATA("whenOrdering.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -1307,7 +1302,7 @@ void tst_qdeclarativestates::urlResolution()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, SRCDIR "/data/urlResolution.qml");
+ QDeclarativeComponent c(&engine, TESTDATA("urlResolution.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
@@ -1318,7 +1313,7 @@ void tst_qdeclarativestates::urlResolution()
QVERIFY(myType != 0 && image1 != 0 && image2 != 0 && image3 != 0);
QSGItemPrivate::get(myType)->setState("SetImageState");
- QUrl resolved = QUrl::fromLocalFile(SRCDIR "/data/Implementation/images/qt-logo.png");
+ QUrl resolved = QUrl::fromLocalFile(TESTDATA("Implementation/images/qt-logo.png"));
QCOMPARE(image1->source(), resolved);
QCOMPARE(image2->source(), resolved);
QCOMPARE(image3->source(), resolved);
@@ -1328,7 +1323,7 @@ void tst_qdeclarativestates::unnamedWhen()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, SRCDIR "/data/unnamedWhen.qml");
+ QDeclarativeComponent c(&engine, TESTDATA("unnamedWhen.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -1347,7 +1342,7 @@ void tst_qdeclarativestates::returnToBase()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, SRCDIR "/data/returnToBase.qml");
+ QDeclarativeComponent c(&engine, TESTDATA("returnToBase.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -1367,7 +1362,7 @@ void tst_qdeclarativestates::extendsBug()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, SRCDIR "/data/extendsBug.qml");
+ QDeclarativeComponent c(&engine, TESTDATA("extendsBug.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
@@ -1382,7 +1377,7 @@ void tst_qdeclarativestates::editProperties()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, SRCDIR "/data/editProperties.qml");
+ QDeclarativeComponent c(&engine, TESTDATA("editProperties.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
@@ -1510,7 +1505,7 @@ void tst_qdeclarativestates::QTBUG_14830()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, SRCDIR "/data/QTBUG-14830.qml");
+ QDeclarativeComponent c(&engine, TESTDATA("QTBUG-14830.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
QSGItem *item = rect->findChild<QSGItem*>("area");
@@ -1523,7 +1518,7 @@ void tst_qdeclarativestates::avoidFastForward()
QDeclarativeEngine engine;
//shouldn't fast forward if there isn't a transition
- QDeclarativeComponent c(&engine, SRCDIR "/data/avoidFastForward.qml");
+ QDeclarativeComponent c(&engine, TESTDATA("avoidFastForward.qml"));
QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
QVERIFY(rect != 0);
diff --git a/tests/auto/declarative/qdeclarativestyledtext/qdeclarativestyledtext.pro b/tests/auto/declarative/qdeclarativestyledtext/qdeclarativestyledtext.pro
index e8e75fb3ff..70e6fafe59 100644
--- a/tests/auto/declarative/qdeclarativestyledtext/qdeclarativestyledtext.pro
+++ b/tests/auto/declarative/qdeclarativestyledtext/qdeclarativestyledtext.pro
@@ -1,12 +1,8 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
-QT += network
+CONFIG += testcase
+TARGET = tst_qdeclarativestyledtext
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativestyledtext.cpp
-# QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage
-# LIBS += -lgcov
-
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qdeclarativesystempalette/qdeclarativesystempalette.pro b/tests/auto/declarative/qdeclarativesystempalette/qdeclarativesystempalette.pro
index bc801d6f57..4eee37678f 100644
--- a/tests/auto/declarative/qdeclarativesystempalette/qdeclarativesystempalette.pro
+++ b/tests/auto/declarative/qdeclarativesystempalette/qdeclarativesystempalette.pro
@@ -1,14 +1,8 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui widgets
+CONFIG += testcase
+TARGET = tst_qdeclarativesystempalette
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativesystempalette.cpp
-!symbian: {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-
CONFIG += parallel_test
-#temporary
-CONFIG += insignificant_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private widgets testlib
diff --git a/tests/auto/declarative/qdeclarativesystempalette/tst_qdeclarativesystempalette.cpp b/tests/auto/declarative/qdeclarativesystempalette/tst_qdeclarativesystempalette.cpp
index 993536f8b6..8c9543273c 100644
--- a/tests/auto/declarative/qdeclarativesystempalette/tst_qdeclarativesystempalette.cpp
+++ b/tests/auto/declarative/qdeclarativesystempalette/tst_qdeclarativesystempalette.cpp
@@ -45,15 +45,8 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtDeclarative/private/qdeclarativesystempalette_p.h>
#include <qpalette.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
class tst_qdeclarativesystempalette : public QObject
-
{
Q_OBJECT
public:
diff --git a/tests/auto/declarative/qdeclarativetimer/qdeclarativetimer.pro b/tests/auto/declarative/qdeclarativetimer/qdeclarativetimer.pro
index 28b76c9dfb..b5b04b2aa1 100644
--- a/tests/auto/declarative/qdeclarativetimer/qdeclarativetimer.pro
+++ b/tests/auto/declarative/qdeclarativetimer/qdeclarativetimer.pro
@@ -1,12 +1,8 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui
+CONFIG += testcase
+TARGET = tst_qdeclarativetimer
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativetimer.cpp
-!symbian: {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-
CONFIG += parallel_test
-QT += core-private gui-private declarative-private v8-private
+QT += core-private gui-private declarative-private gui testlib \ No newline at end of file
diff --git a/tests/auto/declarative/qdeclarativetimer/tst_qdeclarativetimer.cpp b/tests/auto/declarative/qdeclarativetimer/tst_qdeclarativetimer.cpp
index 537c055f00..d6cf8c058f 100644
--- a/tests/auto/declarative/qdeclarativetimer/tst_qdeclarativetimer.cpp
+++ b/tests/auto/declarative/qdeclarativetimer/tst_qdeclarativetimer.cpp
@@ -46,11 +46,6 @@
#include <QtDeclarative/qsgitem.h>
#include <QDebug>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qdeclarativetimer : public QObject
{
Q_OBJECT
@@ -85,12 +80,7 @@ public slots:
}
};
-#if defined(Q_OS_SYMBIAN) && defined(Q_CC_NOKIAX86)
-// Increase wait as emulator startup can cause unexpected delays
-#define TIMEOUT_TIMEOUT 2000
-#else
#define TIMEOUT_TIMEOUT 200
-#endif
tst_qdeclarativetimer::tst_qdeclarativetimer()
{
diff --git a/tests/auto/declarative/qdeclarativetranslation/qdeclarativetranslation.pro b/tests/auto/declarative/qdeclarativetranslation/qdeclarativetranslation.pro
index b6f0df2fbc..488395ea52 100644
--- a/tests/auto/declarative/qdeclarativetranslation/qdeclarativetranslation.pro
+++ b/tests/auto/declarative/qdeclarativetranslation/qdeclarativetranslation.pro
@@ -1,18 +1,14 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qdeclarativetranslation
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativetranslation.cpp
RESOURCES += data/translation.qrc
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativetranslation/tst_qdeclarativetranslation.cpp b/tests/auto/declarative/qdeclarativetranslation/tst_qdeclarativetranslation.cpp
index 4f47b80fdd..be257fdc41 100644
--- a/tests/auto/declarative/qdeclarativetranslation/tst_qdeclarativetranslation.cpp
+++ b/tests/auto/declarative/qdeclarativetranslation/tst_qdeclarativetranslation.cpp
@@ -43,11 +43,7 @@
#include <QDeclarativeEngine>
#include <QDeclarativeComponent>
#include <QTranslator>
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class tst_qdeclarativetranslation : public QObject
{
@@ -63,13 +59,13 @@ private slots:
inline QUrl TEST_FILE(const QString &filename)
{
- return QUrl::fromLocalFile(QLatin1String(SRCDIR) + QLatin1String("/data/") + filename);
+ return QUrl::fromLocalFile(TESTDATA(filename));
}
void tst_qdeclarativetranslation::translation()
{
QTranslator translator;
- translator.load(QLatin1String("qml_fr"), QLatin1String(SRCDIR) + QLatin1String("/data"));
+ translator.load(QLatin1String("qml_fr"), TESTDATA(""));
QCoreApplication::installTranslator(&translator);
QDeclarativeEngine engine;
@@ -93,7 +89,7 @@ void tst_qdeclarativetranslation::translation()
void tst_qdeclarativetranslation::idTranslation()
{
QTranslator translator;
- translator.load(QLatin1String("qmlid_fr"), QLatin1String(SRCDIR) + QLatin1String("/data"));
+ translator.load(QLatin1String("qmlid_fr"),TESTDATA(""));
QCoreApplication::installTranslator(&translator);
QDeclarativeEngine engine;
diff --git a/tests/auto/declarative/qdeclarativev4/qdeclarativev4.pro b/tests/auto/declarative/qdeclarativev4/qdeclarativev4.pro
deleted file mode 100644
index 0701d95902..0000000000
--- a/tests/auto/declarative/qdeclarativev4/qdeclarativev4.pro
+++ /dev/null
@@ -1,19 +0,0 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative network
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_qdeclarativev4.cpp \
- testtypes.cpp
-HEADERS += testtypes.h
-
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-
-CONFIG += parallel_test
-
-QT += core-private gui-private v8-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro b/tests/auto/declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro
index 79bac3998e..d7097de835 100644
--- a/tests/auto/declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro
+++ b/tests/auto/declarative/qdeclarativevaluetypes/qdeclarativevaluetypes.pro
@@ -1,5 +1,5 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qdeclarativevaluetypes
macx:CONFIG -= app_bundle
HEADERS += testtypes.h
@@ -7,14 +7,10 @@ HEADERS += testtypes.h
SOURCES += tst_qdeclarativevaluetypes.cpp \
testtypes.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private
+QT += core-private gui-private v8-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp
index 3ccd5cb341..db0e05bcf2 100644
--- a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp
+++ b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp
@@ -44,13 +44,9 @@
#include <QDeclarativeComponent>
#include <QDebug>
#include <private/qdeclarativevaluetype_p.h>
+#include "../shared/util.h"
#include "testtypes.h"
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
QT_BEGIN_NAMESPACE
extern int qt_defaultDpi();
QT_END_NAMESPACE
@@ -109,7 +105,7 @@ void tst_qdeclarativevaluetypes::initTestCase()
inline QUrl TEST_FILE(const QString &filename)
{
- return QUrl::fromLocalFile(QLatin1String(SRCDIR) + QLatin1String("/data/") + filename);
+ return QUrl::fromLocalFile(TESTDATA(filename));
}
void tst_qdeclarativevaluetypes::point()
diff --git a/tests/auto/declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro b/tests/auto/declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro
index aae48ca14e..6eaaf577b4 100644
--- a/tests/auto/declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro
+++ b/tests/auto/declarative/qdeclarativeworkerscript/qdeclarativeworkerscript.pro
@@ -1,17 +1,13 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qdeclarativeworkerscript
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativeworkerscript.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private
+QT += core-private gui-private v8-private declarative-private testlib
diff --git a/tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp b/tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp
index 5e67360e15..bb7921c8e3 100644
--- a/tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp
+++ b/tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp
@@ -50,17 +50,11 @@
#include <private/qdeclarativeworkerscript_p.h>
#include <private/qdeclarativeengine_p.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
inline QUrl TEST_FILE(const QString &filename)
{
- QFileInfo fileInfo(__FILE__);
- return QUrl::fromLocalFile(fileInfo.absoluteDir().filePath(filename));
+ return QUrl::fromLocalFile(TESTDATA(filename));
}
@@ -98,7 +92,7 @@ private:
void tst_QDeclarativeWorkerScript::source()
{
- QDeclarativeComponent component(&m_engine, SRCDIR "/data/worker.qml");
+ QDeclarativeComponent component(&m_engine, TESTDATA("worker.qml"));
QDeclarativeWorkerScript *worker = qobject_cast<QDeclarativeWorkerScript*>(component.create());
QVERIFY(worker != 0);
const QMetaObject *mo = worker->metaObject();
@@ -108,7 +102,7 @@ void tst_QDeclarativeWorkerScript::source()
waitForEchoMessage(worker);
QCOMPARE(mo->property(mo->indexOfProperty("response")).read(worker).value<QVariant>(), value);
- QUrl source = QUrl::fromLocalFile(SRCDIR "/data/script_fixed_return.js");
+ QUrl source = QUrl::fromLocalFile(TESTDATA("script_fixed_return.js"));
worker->setSource(source);
QCOMPARE(worker->source(), source);
QVERIFY(QMetaObject::invokeMethod(worker, "testSend", Q_ARG(QVariant, value)));
@@ -123,7 +117,7 @@ void tst_QDeclarativeWorkerScript::messaging()
{
QFETCH(QVariant, value);
- QDeclarativeComponent component(&m_engine, SRCDIR "/data/worker.qml");
+ QDeclarativeComponent component(&m_engine, TESTDATA("worker.qml"));
QDeclarativeWorkerScript *worker = qobject_cast<QDeclarativeWorkerScript*>(component.create());
QVERIFY(worker != 0);
@@ -160,7 +154,7 @@ void tst_QDeclarativeWorkerScript::messaging_sendQObjectList()
// instances. If objects are sent in a list, they will be sent as 'undefined'
// js values.
- QDeclarativeComponent component(&m_engine, SRCDIR "/data/worker.qml");
+ QDeclarativeComponent component(&m_engine, TESTDATA("worker.qml"));
QDeclarativeWorkerScript *worker = qobject_cast<QDeclarativeWorkerScript*>(component.create());
QVERIFY(worker != 0);
@@ -181,7 +175,7 @@ void tst_QDeclarativeWorkerScript::messaging_sendQObjectList()
void tst_QDeclarativeWorkerScript::messaging_sendJsObject()
{
- QDeclarativeComponent component(&m_engine, SRCDIR "/data/worker.qml");
+ QDeclarativeComponent component(&m_engine, TESTDATA("worker.qml"));
QDeclarativeWorkerScript *worker = qobject_cast<QDeclarativeWorkerScript*>(component.create());
QVERIFY(worker != 0);
@@ -210,7 +204,7 @@ void tst_QDeclarativeWorkerScript::script_with_pragma()
{
QVariant value(100);
- QDeclarativeComponent component(&m_engine, SRCDIR "/data/worker_pragma.qml");
+ QDeclarativeComponent component(&m_engine, TESTDATA("worker_pragma.qml"));
QDeclarativeWorkerScript *worker = qobject_cast<QDeclarativeWorkerScript*>(component.create());
QVERIFY(worker != 0);
@@ -226,7 +220,7 @@ void tst_QDeclarativeWorkerScript::script_with_pragma()
void tst_QDeclarativeWorkerScript::script_included()
{
- QDeclarativeComponent component(&m_engine, SRCDIR "/data/worker_include.qml");
+ QDeclarativeComponent component(&m_engine, TESTDATA("worker_include.qml"));
QDeclarativeWorkerScript *worker = qobject_cast<QDeclarativeWorkerScript*>(component.create());
QVERIFY(worker != 0);
@@ -251,14 +245,14 @@ static void qdeclarativeworkerscript_warningsHandler(QtMsgType type, const char
void tst_QDeclarativeWorkerScript::scriptError_onLoad()
{
- QDeclarativeComponent component(&m_engine, SRCDIR "/data/worker_error_onLoad.qml");
+ QDeclarativeComponent component(&m_engine, TESTDATA("worker_error_onLoad.qml"));
QtMsgHandler previousMsgHandler = qInstallMsgHandler(qdeclarativeworkerscript_warningsHandler);
QDeclarativeWorkerScript *worker = qobject_cast<QDeclarativeWorkerScript*>(component.create());
QVERIFY(worker != 0);
QTRY_COMPARE(qdeclarativeworkerscript_lastWarning,
- TEST_FILE("data/script_error_onLoad.js").toString() + QLatin1String(":3: SyntaxError: Unexpected identifier"));
+ TEST_FILE("script_error_onLoad.js").toString() + QLatin1String(":3: SyntaxError: Unexpected identifier"));
qInstallMsgHandler(previousMsgHandler);
qApp->processEvents();
@@ -267,7 +261,7 @@ void tst_QDeclarativeWorkerScript::scriptError_onLoad()
void tst_QDeclarativeWorkerScript::scriptError_onCall()
{
- QDeclarativeComponent component(&m_engine, SRCDIR "/data/worker_error_onCall.qml");
+ QDeclarativeComponent component(&m_engine, TESTDATA("worker_error_onCall.qml"));
QDeclarativeWorkerScript *worker = qobject_cast<QDeclarativeWorkerScript*>(component.create());
QVERIFY(worker != 0);
@@ -276,7 +270,7 @@ void tst_QDeclarativeWorkerScript::scriptError_onCall()
QVERIFY(QMetaObject::invokeMethod(worker, "testSend", Q_ARG(QVariant, value)));
QTRY_COMPARE(qdeclarativeworkerscript_lastWarning,
- TEST_FILE("data/script_error_onCall.js").toString() + QLatin1String(":4: ReferenceError: Can't find variable: getData"));
+ TEST_FILE("script_error_onCall.js").toString() + QLatin1String(":4: ReferenceError: Can't find variable: getData"));
qInstallMsgHandler(previousMsgHandler);
qApp->processEvents();
@@ -289,7 +283,7 @@ void tst_QDeclarativeWorkerScript::stressDispose()
{
for (int ii = 0; ii < 100; ++ii) {
QDeclarativeEngine engine;
- QDeclarativeComponent component(&engine, SRCDIR "/data/stressDispose.qml");
+ QDeclarativeComponent component(&engine, TESTDATA("stressDispose.qml"));
QObject *o = component.create();
QVERIFY(o);
delete o;
diff --git a/tests/auto/declarative/qdeclarativexmlhttprequest/qdeclarativexmlhttprequest.pro b/tests/auto/declarative/qdeclarativexmlhttprequest/qdeclarativexmlhttprequest.pro
index 441a9cfc64..0e6073b503 100644
--- a/tests/auto/declarative/qdeclarativexmlhttprequest/qdeclarativexmlhttprequest.pro
+++ b/tests/auto/declarative/qdeclarativexmlhttprequest/qdeclarativexmlhttprequest.pro
@@ -1,5 +1,5 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative network
+CONFIG += testcase
+TARGET = tst_qdeclarativexmlhttprequest
macx:CONFIG -= app_bundle
INCLUDEPATH += ../shared/
@@ -8,14 +8,10 @@ HEADERS += ../shared/testhttpserver.h
SOURCES += tst_qdeclarativexmlhttprequest.cpp \
../shared/testhttpserver.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qdeclarativexmlhttprequest/tst_qdeclarativexmlhttprequest.cpp b/tests/auto/declarative/qdeclarativexmlhttprequest/tst_qdeclarativexmlhttprequest.cpp
index 51b23c732a..1caec581cc 100644
--- a/tests/auto/declarative/qdeclarativexmlhttprequest/tst_qdeclarativexmlhttprequest.cpp
+++ b/tests/auto/declarative/qdeclarativexmlhttprequest/tst_qdeclarativexmlhttprequest.cpp
@@ -45,15 +45,10 @@
#include <QDebug>
#include <QNetworkCookieJar>
#include "testhttpserver.h"
-#include "../../../shared/util.h"
+#include "../shared/util.h"
#define SERVER_PORT 14445
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qdeclarativexmlhttprequest : public QObject
{
Q_OBJECT
@@ -127,7 +122,7 @@ private:
inline QUrl TEST_FILE(const QString &filename)
{
- return QUrl::fromLocalFile(QLatin1String(SRCDIR) + QLatin1String("/data/") + filename);
+ return QUrl::fromLocalFile(TESTDATA(filename));
}
// Test that the dom exception codes are correct
@@ -1023,7 +1018,7 @@ void tst_qdeclarativexmlhttprequest::redirects()
TestHTTPServer server(SERVER_PORT);
QVERIFY(server.isValid());
server.addRedirect("redirect.html", "http://127.0.0.1:14445/redirecttarget.html");
- server.serveDirectory(SRCDIR "/data");
+ server.serveDirectory(TESTDATA(""));
QDeclarativeComponent component(&engine, TEST_FILE("redirects.qml"));
QObject *object = component.beginCreate(engine.rootContext());
@@ -1042,7 +1037,7 @@ void tst_qdeclarativexmlhttprequest::redirects()
TestHTTPServer server(SERVER_PORT);
QVERIFY(server.isValid());
server.addRedirect("redirect.html", "http://127.0.0.1:14445/redirectmissing.html");
- server.serveDirectory(SRCDIR "/data");
+ server.serveDirectory(TESTDATA(""));
QDeclarativeComponent component(&engine, TEST_FILE("redirectError.qml"));
QObject *object = component.beginCreate(engine.rootContext());
@@ -1061,7 +1056,7 @@ void tst_qdeclarativexmlhttprequest::redirects()
TestHTTPServer server(SERVER_PORT);
QVERIFY(server.isValid());
server.addRedirect("redirect.html", "http://127.0.0.1:14445/redirect.html");
- server.serveDirectory(SRCDIR "/data");
+ server.serveDirectory(TESTDATA(""));
QDeclarativeComponent component(&engine, TEST_FILE("redirectRecur.qml"));
QObject *object = component.beginCreate(engine.rootContext());
diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro b/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro
index 6733d3595e..ae5523711c 100644
--- a/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro
+++ b/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro
@@ -1,21 +1,13 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui network
-contains(QT_CONFIG,xmlpatterns) {
- QT += xmlpatterns
- DEFINES += QTEST_XMLPATTERNS
-}
+CONFIG += testcase
+TARGET = tst_qdeclarativexmllistmodel
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativexmllistmodel.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private
+QT += core-private gui-private v8-private declarative-private network testlib xmlpatterns
diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp
index 2a1d71623e..2b66e67024 100644
--- a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp
+++ b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp
@@ -52,17 +52,11 @@
#include <QtCore/qtimer.h>
#include <QtCore/qfile.h>
#include <QtCore/qtemporaryfile.h>
+#include "../shared/util.h"
-#ifdef QTEST_XMLPATTERNS
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtDeclarative/qdeclarativecomponent.h>
#include <private/qdeclarativexmllistmodel_p.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
typedef QPair<int, int> QDeclarativeXmlListRange;
typedef QList<QVariantList> QDeclarativeXmlModelData;
@@ -193,7 +187,7 @@ QNetworkAccessManager *CustomNetworkAccessManagerFactory::create(QObject *parent
void tst_qdeclarativexmllistmodel::buildModel()
{
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml")));
QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create());
QVERIFY(model != 0);
QTRY_COMPARE(model->count(), 9);
@@ -216,7 +210,7 @@ void tst_qdeclarativexmllistmodel::testTypes()
QFETCH(QString, roleName);
QFETCH(QVariant, expectedValue);
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/testtypes.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("testtypes.qml")));
QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create());
QVERIFY(model != 0);
model->setXml(xml.toUtf8());
@@ -276,7 +270,7 @@ void tst_qdeclarativexmllistmodel::testTypes_data()
void tst_qdeclarativexmllistmodel::cdata()
{
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/recipes.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("recipes.qml")));
QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create());
QVERIFY(model != 0);
QTRY_COMPARE(model->count(), 5);
@@ -292,7 +286,7 @@ void tst_qdeclarativexmllistmodel::cdata()
void tst_qdeclarativexmllistmodel::attributes()
{
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/recipes.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("recipes.qml")));
QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create());
QVERIFY(model != 0);
QTRY_COMPARE(model->count(), 5);
@@ -307,7 +301,7 @@ void tst_qdeclarativexmllistmodel::attributes()
void tst_qdeclarativexmllistmodel::roles()
{
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml")));
QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create());
QVERIFY(model != 0);
QTRY_COMPARE(model->count(), 9);
@@ -324,9 +318,9 @@ void tst_qdeclarativexmllistmodel::roles()
void tst_qdeclarativexmllistmodel::roleErrors()
{
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/roleErrors.qml"));
- QTest::ignoreMessage(QtWarningMsg, (QUrl::fromLocalFile(SRCDIR "/data/roleErrors.qml").toString() + ":6:5: QML XmlRole: An XmlRole query must not start with '/'").toUtf8().constData());
- QTest::ignoreMessage(QtWarningMsg, (QUrl::fromLocalFile(SRCDIR "/data/roleErrors.qml").toString() + ":9:5: QML XmlRole: invalid query: \"age/\"").toUtf8().constData());
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("roleErrors.qml")));
+ QTest::ignoreMessage(QtWarningMsg, (QUrl::fromLocalFile(TESTDATA("roleErrors.qml")).toString() + ":6:5: QML XmlRole: An XmlRole query must not start with '/'").toUtf8().constData());
+ QTest::ignoreMessage(QtWarningMsg, (QUrl::fromLocalFile(TESTDATA("roleErrors.qml")).toString() + ":9:5: QML XmlRole: invalid query: \"age/\"").toUtf8().constData());
//### make sure we receive all expected warning messages.
QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create());
@@ -351,8 +345,8 @@ void tst_qdeclarativexmllistmodel::roleErrors()
void tst_qdeclarativexmllistmodel::uniqueRoleNames()
{
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/unique.qml"));
- QTest::ignoreMessage(QtWarningMsg, (QUrl::fromLocalFile(SRCDIR "/data/unique.qml").toString() + ":7:5: QML XmlRole: \"name\" duplicates a previous role name and will be disabled.").toUtf8().constData());
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("unique.qml")));
+ QTest::ignoreMessage(QtWarningMsg, (QUrl::fromLocalFile(TESTDATA("unique.qml")).toString() + ":7:5: QML XmlRole: \"name\" duplicates a previous role name and will be disabled.").toUtf8().constData());
QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create());
QVERIFY(model != 0);
QTRY_COMPARE(model->count(), 9);
@@ -369,7 +363,7 @@ void tst_qdeclarativexmllistmodel::xml()
QFETCH(QString, xml);
QFETCH(int, count);
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml")));
QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create());
QSignalSpy spy(model, SIGNAL(statusChanged(QDeclarativeXmlListModel::Status)));
@@ -418,7 +412,7 @@ void tst_qdeclarativexmllistmodel::headers()
CustomNetworkAccessManagerFactory factory;
qmlEng.setNetworkAccessManagerFactory(&factory);
- QDeclarativeComponent component(&qmlEng, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
+ QDeclarativeComponent component(&qmlEng, QUrl::fromLocalFile(TESTDATA("model.qml")));
QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create());
QVERIFY(model != 0);
QTRY_COMPARE(model->status(), QDeclarativeXmlListModel::Ready);
@@ -441,7 +435,7 @@ void tst_qdeclarativexmllistmodel::source()
QFETCH(int, count);
QFETCH(QDeclarativeXmlListModel::Status, status);
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml")));
QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create());
QSignalSpy spy(model, SIGNAL(statusChanged(QDeclarativeXmlListModel::Status)));
@@ -493,7 +487,7 @@ void tst_qdeclarativexmllistmodel::source_data()
QTest::addColumn<int>("count");
QTest::addColumn<QDeclarativeXmlListModel::Status>("status");
- QTest::newRow("valid") << QUrl::fromLocalFile(SRCDIR "/data/model2.xml") << 2 << QDeclarativeXmlListModel::Ready;
+ QTest::newRow("valid") << QUrl::fromLocalFile(TESTDATA("model2.xml")) << 2 << QDeclarativeXmlListModel::Ready;
QTest::newRow("invalid") << QUrl("http://blah.blah/blah.xml") << 0 << QDeclarativeXmlListModel::Error;
// empty file
@@ -505,7 +499,7 @@ void tst_qdeclarativexmllistmodel::source_data()
void tst_qdeclarativexmllistmodel::data()
{
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml")));
QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create());
QVERIFY(model != 0);
@@ -525,7 +519,7 @@ void tst_qdeclarativexmllistmodel::data()
void tst_qdeclarativexmllistmodel::get()
{
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/get.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("get.qml")));
QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create());
QVERIFY(model != 0);
@@ -546,7 +540,7 @@ void tst_qdeclarativexmllistmodel::reload()
// If no keys are used, the model should be rebuilt from scratch when
// reload() is called.
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml")));
QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create());
QVERIFY(model != 0);
QTRY_COMPARE(model->count(), 9);
@@ -587,7 +581,7 @@ void tst_qdeclarativexmllistmodel::useKeys()
QFETCH(QList<QDeclarativeXmlListRange>, insertRanges);
QFETCH(QList<QDeclarativeXmlListRange>, removeRanges);
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/roleKeys.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("roleKeys.qml")));
QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create());
QVERIFY(model != 0);
@@ -738,7 +732,7 @@ void tst_qdeclarativexmllistmodel::noKeysValueChanges()
// If a 'sport' value is changed, the model should not be reloaded,
// since 'sport' is not marked as a key.
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/roleKeys.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("roleKeys.qml")));
QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create());
QVERIFY(model != 0);
@@ -776,7 +770,7 @@ void tst_qdeclarativexmllistmodel::keysChanged()
// delete all its data and build a clean model (i.e. same behaviour as
// if no keys are set).
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/roleKeys.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("roleKeys.qml")));
QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create());
QVERIFY(model != 0);
@@ -812,7 +806,7 @@ void tst_qdeclarativexmllistmodel::threading()
{
QFETCH(int, xmlDataCount);
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/roleKeys.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("roleKeys.qml")));
QDeclarativeXmlListModel *m1 = qobject_cast<QDeclarativeXmlListModel*>(component.create());
QVERIFY(m1 != 0);
@@ -885,7 +879,7 @@ void tst_qdeclarativexmllistmodel::threading_data()
void tst_qdeclarativexmllistmodel::propertyChanges()
{
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("propertychanges.qml")));
QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create());
QVERIFY(model != 0);
QTRY_COMPARE(model->count(), 9);
@@ -956,7 +950,7 @@ void tst_qdeclarativexmllistmodel::propertyChanges()
void tst_qdeclarativexmllistmodel::roleCrash()
{
// don't crash
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/roleCrash.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("roleCrash.qml")));
QDeclarativeXmlListModel *model = qobject_cast<QDeclarativeXmlListModel*>(component.create());
QVERIFY(model != 0);
delete model;
@@ -965,7 +959,3 @@ void tst_qdeclarativexmllistmodel::roleCrash()
QTEST_MAIN(tst_qdeclarativexmllistmodel)
#include "tst_qdeclarativexmllistmodel.moc"
-
-#else
-QTEST_NOOP_MAIN
-#endif
diff --git a/tests/auto/declarative/qjsengine/qjsengine.pro b/tests/auto/declarative/qjsengine/qjsengine.pro
index 10d75b4ede..5696ef845a 100644
--- a/tests/auto/declarative/qjsengine/qjsengine.pro
+++ b/tests/auto/declarative/qjsengine/qjsengine.pro
@@ -1,22 +1,15 @@
-load(qttest_p4)
-QT += declarative widgets
+CONFIG += testcase
+TARGET = tst_qjsengine
+QT += declarative widgets testlib
macx:CONFIG -= app_bundle
SOURCES += tst_qjsengine.cpp
#temporary
CONFIG += insignificant_test
wince* {
+ addFiles.files = script
+ addFiles.path = .
+ DEPLOYMENT += addFiles
DEFINES += SRCDIR=\\\"./\\\"
-} else:!symbian {
+} else {
DEFINES += SRCDIR=\\\"$$PWD\\\"
}
-
-wince*|symbian: {
- addFiles.files = script
- addFiles.path = .
- DEPLOYMENT += addFiles
-}
-
-symbian: {
- TARGET.UID3 = 0xE0340006
- DEFINES += SYMBIAN_SRCDIR_UID=$$lower($$replace(TARGET.UID3,"0x",""))
-}
diff --git a/tests/auto/declarative/qjsengine/tst_qjsengine.cpp b/tests/auto/declarative/qjsengine/tst_qjsengine.cpp
index c6f026da15..f83a1b3efd 100644
--- a/tests/auto/declarative/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/declarative/qjsengine/tst_qjsengine.cpp
@@ -55,12 +55,6 @@ Q_DECLARE_METATYPE(QObjectList)
//TESTED_CLASS=
//TESTED_FILES=
-#if defined(Q_OS_SYMBIAN)
-# define STRINGIFY(x) #x
-# define TOSTRING(x) STRINGIFY(x)
-# define SRCDIR "C:/Private/" TOSTRING(SYMBIAN_SRCDIR_UID)
-#endif
-
// The JavaScriptCore GC marks the C stack. To try to ensure that there is
// no JSObject* left in stack memory by the compiler, we call this function
// to zap some bytes of memory before calling collectGarbage().
@@ -188,9 +182,7 @@ private slots:
void castWithPrototypeChain();
#endif
void castWithMultipleInheritance();
-#if 0 // ###FIXME: ScriptOwnership
void collectGarbage();
-#endif
#if 0 // ###FIXME: no reportAdditionalMemoryCost API
void reportAdditionalMemoryCost();
#endif
@@ -709,7 +701,7 @@ void tst_QJSEngine::newVariant_promoteObject()
QVERIFY(object.property("foo").isObject());
QVERIFY(!object.property("foo").isVariant());
QScriptValue originalProto = object.property("foo").prototype();
- QSKIP("It is not possible to promote plain object to a wrapper", SkipAll);
+ QSKIP("It is not possible to promote plain object to a wrapper");
QScriptValue ret = eng.newVariant(object.property("foo"), QVariant(123));
QVERIFY(ret.isValid());
QVERIFY(ret.strictlyEquals(object.property("foo")));
@@ -789,7 +781,7 @@ void tst_QJSEngine::newVariant_promoteNonObject()
void tst_QJSEngine::newVariant_promoteNonQScriptObject()
{
- QSKIP("This test relay on limitation of QtScript JSC implementation", SkipAll);
+ QSKIP("This test relay on limitation of QtScript JSC implementation");
QScriptEngine eng;
{
QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::newVariant(): changing class of non-QScriptObject not supported");
@@ -801,6 +793,7 @@ void tst_QJSEngine::newVariant_promoteNonQScriptObject()
void tst_QJSEngine::newRegExp()
{
+ QSKIP("Test failing - QTBUG-22238", SkipAll);
QJSEngine eng;
for (int x = 0; x < 2; ++x) {
QJSValue rexp;
@@ -824,6 +817,8 @@ void tst_QJSEngine::newRegExp()
void tst_QJSEngine::jsRegExp()
{
+ QSKIP("Test failing - QTBUG-22238", SkipAll);
+
// See ECMA-262 Section 15.10, "RegExp Objects".
// These should really be JS-only tests, as they test the implementation's
// ECMA-compliance, not the C++ API. Compliance should already be covered
@@ -971,34 +966,33 @@ void tst_QJSEngine::newQObject()
void tst_QJSEngine::newQObject_ownership()
{
-#if 0 // FIXME: ownership tests need to be revivewed
- QScriptEngine eng;
+ QJSEngine eng;
{
QPointer<QObject> ptr = new QObject();
QVERIFY(ptr != 0);
{
- QScriptValue v = eng.newQObject(ptr, QScriptEngine::ScriptOwnership);
+ QJSValue v = eng.newQObject(ptr);
}
- eng.evaluate("gc()");
+ collectGarbage_helper(eng);
if (ptr)
- QEXPECT_FAIL("", "In the JSC-based back-end, script-owned QObjects are not always deleted immediately during GC", Continue);
+ QApplication::sendPostedEvents(ptr, QEvent::DeferredDelete);
QVERIFY(ptr == 0);
}
{
- QPointer<QObject> ptr = new QObject();
+ QPointer<QObject> ptr = new QObject(this);
QVERIFY(ptr != 0);
{
- QScriptValue v = eng.newQObject(ptr, QScriptEngine::QtOwnership);
+ QJSValue v = eng.newQObject(ptr);
}
QObject *before = ptr;
- eng.evaluate("gc()");
+ collectGarbage_helper(eng);
QVERIFY(ptr == before);
delete ptr;
}
{
QObject *parent = new QObject();
QObject *child = new QObject(parent);
- QScriptValue v = eng.newQObject(child, QScriptEngine::QtOwnership);
+ QJSValue v = eng.newQObject(child);
QCOMPARE(v.toQObject(), child);
delete parent;
QCOMPARE(v.toQObject(), (QObject *)0);
@@ -1007,12 +1001,12 @@ void tst_QJSEngine::newQObject_ownership()
QPointer<QObject> ptr = new QObject();
QVERIFY(ptr != 0);
{
- QScriptValue v = eng.newQObject(ptr, QScriptEngine::AutoOwnership);
+ QJSValue v = eng.newQObject(ptr);
}
- eng.evaluate("gc()");
+ collectGarbage_helper(eng);
// no parent, so it should be like ScriptOwnership
if (ptr)
- QEXPECT_FAIL("", "In the JSC-based back-end, script-owned QObjects are not always deleted immediately during GC", Continue);
+ QApplication::sendPostedEvents(ptr, QEvent::DeferredDelete);
QVERIFY(ptr == 0);
}
{
@@ -1020,14 +1014,13 @@ void tst_QJSEngine::newQObject_ownership()
QPointer<QObject> child = new QObject(parent);
QVERIFY(child != 0);
{
- QScriptValue v = eng.newQObject(child, QScriptEngine::AutoOwnership);
+ QJSValue v = eng.newQObject(child);
}
- eng.evaluate("gc()");
+ collectGarbage_helper(eng);
// has parent, so it should be like QtOwnership
QVERIFY(child != 0);
delete parent;
}
-#endif
}
void tst_QJSEngine::newQObject_promoteObject()
@@ -1080,7 +1073,7 @@ void tst_QJSEngine::newQObject_promoteObject()
void tst_QJSEngine::newQObject_sameQObject()
{
#if 0 // ###FIXME: No QObjectWrapOptions API
- QSKIP("This test stongly relay on strictlyEquals feature that would change in near future", SkipAll);
+ QSKIP("This test stongly relay on strictlyEquals feature that would change in near future");
QScriptEngine eng;
// calling newQObject() several times with same object
for (int x = 0; x < 2; ++x) {
@@ -1158,7 +1151,7 @@ void tst_QJSEngine::newQObject_promoteNonObject()
void tst_QJSEngine::newQObject_promoteNonQScriptObject()
{
#if 0 // ### FIXME: object promotion is not supported
- QSKIP("Promotion of non QScriptObjects kind of works (there is not difference between Object and Array, look at comments in newQObject implementation).", SkipAll);
+ QSKIP("Promotion of non QScriptObjects kind of works (there is not difference between Object and Array, look at comments in newQObject implementation).");
QScriptEngine eng;
{
QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::newQObject(): changing class of non-QScriptObject not supported");
@@ -1326,7 +1319,7 @@ void tst_QJSEngine::newQMetaObject()
#if 0 // ###FIXME: No activation object support
void tst_QJSEngine::newActivationObject()
{
- QSKIP("internal function not implemented in JSC-based back-end", SkipAll);
+ QSKIP("internal function not implemented in JSC-based back-end");
QScriptEngine eng;
QScriptValue act = eng.newActivationObject();
QEXPECT_FAIL("", "", Continue);
@@ -1472,6 +1465,7 @@ static QScriptValue getSetFoo(QScriptContext *ctx, QScriptEngine *)
void tst_QJSEngine::globalObjectProperties()
{
+ QSKIP("Test failing - QTBUG-22238", SkipAll);
// See ECMA-262 Section 15.1, "The Global Object".
QJSEngine eng;
@@ -1560,6 +1554,7 @@ void tst_QJSEngine::globalObjectEquals()
void tst_QJSEngine::globalObjectProperties_enumerate()
{
+ QSKIP("Test failing - QTBUG-22238", SkipAll);
QJSEngine eng;
QJSValue global = eng.globalObject();
@@ -3103,21 +3098,21 @@ void tst_QJSEngine::castWithMultipleInheritance()
QCOMPARE(qjsvalue_cast<QGraphicsItem*>(v), (QGraphicsItem *)&klz);
}
-#if 0 // ###FIXME: ScriptOwnership
void tst_QJSEngine::collectGarbage()
{
- QScriptEngine eng;
+ QJSEngine eng;
eng.evaluate("a = new Object(); a = new Object(); a = new Object()");
- QScriptValue a = eng.newObject();
+ QJSValue a = eng.newObject();
a = eng.newObject();
a = eng.newObject();
QPointer<QObject> ptr = new QObject();
QVERIFY(ptr != 0);
- (void)eng.newQObject(ptr, QScriptEngine::ScriptOwnership);
+ (void)eng.newQObject(ptr);
collectGarbage_helper(eng);
+ if (ptr)
+ QApplication::sendPostedEvents(ptr, QEvent::DeferredDelete);
QVERIFY(ptr == 0);
}
-#endif
#if 0 // ###FIXME: no reportAdditionalMemoryCost API
void tst_QJSEngine::reportAdditionalMemoryCost()
@@ -3781,7 +3776,7 @@ void tst_QJSEngine::abortEvaluation()
void tst_QJSEngine::abortEvaluation_tryCatch()
{
- QSKIP("It crashes", SkipAll);
+ QSKIP("It crashes");
QScriptEngine eng;
EventReceiver3 receiver(&eng);
eng.setProcessEventsInterval(100);
@@ -4881,7 +4876,7 @@ void tst_QJSEngine::jsFutureReservedWords_data()
void tst_QJSEngine::jsFutureReservedWords()
{
- QSKIP("Fails", SkipAll);
+ QSKIP("Fails");
// See ECMA-262 Section 7.6.1.2, "Future Reserved Words".
// In real-world implementations, most of these words are
// actually allowed as normal identifiers.
@@ -6088,6 +6083,7 @@ void tst_QJSEngine::qRegExpInport_data()
void tst_QJSEngine::qRegExpInport()
{
+ QSKIP("Test failing - QTBUG-22238", SkipAll);
QFETCH(QRegExp, rx);
QFETCH(QString, string);
diff --git a/tests/auto/declarative/qjsvalue/qjsvalue.pro b/tests/auto/declarative/qjsvalue/qjsvalue.pro
index caa148f86d..36ce0024c2 100644
--- a/tests/auto/declarative/qjsvalue/qjsvalue.pro
+++ b/tests/auto/declarative/qjsvalue/qjsvalue.pro
@@ -1,5 +1,6 @@
-load(qttest_p4)
-QT += declarative widgets
+CONFIG += testcase
+TARGET = tst_qjsvalue
+QT += declarative widgets testlib
SOURCES += tst_qjsvalue.cpp
HEADERS += tst_qjsvalue.h
diff --git a/tests/auto/declarative/qjsvalueiterator/qjsvalueiterator.pro b/tests/auto/declarative/qjsvalueiterator/qjsvalueiterator.pro
index e5137fcdf1..a705858ade 100644
--- a/tests/auto/declarative/qjsvalueiterator/qjsvalueiterator.pro
+++ b/tests/auto/declarative/qjsvalueiterator/qjsvalueiterator.pro
@@ -1,5 +1,6 @@
-load(qttest_p4)
-QT = core declarative
+CONFIG += testcase
+TARGET = tst_qjsvalueiterator
+QT = core declarative testlib
SOURCES += tst_qjsvalueiterator.cpp
diff --git a/tests/auto/declarative/qmetaobjectbuilder/qmetaobjectbuilder.pro b/tests/auto/declarative/qmetaobjectbuilder/qmetaobjectbuilder.pro
index 15a4e76aa6..047a871496 100644
--- a/tests/auto/declarative/qmetaobjectbuilder/qmetaobjectbuilder.pro
+++ b/tests/auto/declarative/qmetaobjectbuilder/qmetaobjectbuilder.pro
@@ -1,9 +1,9 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qmetaobjectbuilder
macx:CONFIG -= app_bundle
SOURCES += \
tst_qmetaobjectbuilder.cpp
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qmlmin/qmlmin.pro b/tests/auto/declarative/qmlmin/qmlmin.pro
index 83c11b4934..61d2330b06 100644
--- a/tests/auto/declarative/qmlmin/qmlmin.pro
+++ b/tests/auto/declarative/qmlmin/qmlmin.pro
@@ -1,5 +1,6 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qmlmin
+QT += declarative testlib
macx:CONFIG -= app_bundle
SOURCES += tst_qmlmin.cpp
diff --git a/tests/auto/declarative/qmlplugindump/qmlplugindump.pro b/tests/auto/declarative/qmlplugindump/qmlplugindump.pro
new file mode 100644
index 0000000000..498a520873
--- /dev/null
+++ b/tests/auto/declarative/qmlplugindump/qmlplugindump.pro
@@ -0,0 +1,7 @@
+CONFIG += testcase
+TARGET = tst_qmlplugindump
+QT += testlib
+macx:CONFIG -= app_bundle
+CONFIG += parallel_test
+
+SOURCES += tst_qmlplugindump.cpp
diff --git a/tests/auto/declarative/qmlplugindump/tst_qmlplugindump.cpp b/tests/auto/declarative/qmlplugindump/tst_qmlplugindump.cpp
new file mode 100644
index 0000000000..234d4bc04c
--- /dev/null
+++ b/tests/auto/declarative/qmlplugindump/tst_qmlplugindump.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qtest.h>
+#include <QLibraryInfo>
+#include <QDir>
+#include <QProcess>
+#include <QDebug>
+#include <cstdlib>
+
+class tst_qmlplugindump : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qmlplugindump();
+
+private slots:
+ void initTestCase();
+ void builtins();
+
+private:
+ QString qmlplugindumpPath;
+};
+
+tst_qmlplugindump::tst_qmlplugindump()
+{
+}
+
+void tst_qmlplugindump::initTestCase()
+{
+ qmlplugindumpPath = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QLatin1String("/qmlplugindump");
+#ifdef Q_OS_WIN
+ qmlplugindumpPath += QLatin1String(".exe");
+#endif
+ if (!QFileInfo(qmlplugindumpPath).exists()) {
+ QString message = QString::fromLatin1("qmlplugindump executable not found (looked for %0)")
+ .arg(qmlplugindumpPath);
+ QFAIL(qPrintable(message));
+ }
+}
+
+void tst_qmlplugindump::builtins()
+{
+ QProcess dumper;
+ QStringList args;
+ args += QLatin1String("-builtins");
+ dumper.start(qmlplugindumpPath, args);
+ dumper.waitForFinished();
+
+ if (dumper.error() != QProcess::UnknownError
+ || dumper.exitStatus() != QProcess::NormalExit) {
+ qWarning() << QString("Error while running '%1 %2'").arg(
+ qmlplugindumpPath, args.join(QLatin1String(" ")));
+ }
+
+ if (dumper.error() == QProcess::FailedToStart) {
+ QFAIL("failed to start");
+ }
+ if (dumper.error() == QProcess::Crashed) {
+ qWarning() << "stderr:\n" << dumper.readAllStandardError();
+ QFAIL("crashed");
+ }
+
+ QCOMPARE(dumper.error(), QProcess::UnknownError);
+ QCOMPARE(dumper.exitStatus(), QProcess::NormalExit);
+
+ const QString &result = dumper.readAllStandardOutput();
+ QVERIFY(result.contains(QLatin1String("Module {")));
+}
+
+QTEST_MAIN(tst_qmlplugindump)
+
+#include "tst_qmlplugindump.moc"
diff --git a/tests/auto/declarative/qsganimatedimage/qsganimatedimage.pro b/tests/auto/declarative/qsganimatedimage/qsganimatedimage.pro
index 5da2ba95b9..eaf83ccfef 100644
--- a/tests/auto/declarative/qsganimatedimage/qsganimatedimage.pro
+++ b/tests/auto/declarative/qsganimatedimage/qsganimatedimage.pro
@@ -1,17 +1,13 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative network
+CONFIG += testcase
+TARGET = tst_qsganimatedimage
HEADERS += ../shared/testhttpserver.h
SOURCES += tst_qsganimatedimage.cpp ../shared/testhttpserver.cpp
macx:CONFIG -= app_bundle
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qsganimatedimage/tst_qsganimatedimage.cpp b/tests/auto/declarative/qsganimatedimage/tst_qsganimatedimage.cpp
index 0c927c2c5c..aa39c52a31 100644
--- a/tests/auto/declarative/qsganimatedimage/tst_qsganimatedimage.cpp
+++ b/tests/auto/declarative/qsganimatedimage/tst_qsganimatedimage.cpp
@@ -49,12 +49,7 @@
#include <QtDeclarative/qdeclarativecontext.h>
#include "../shared/testhttpserver.h"
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class tst_qsganimatedimage : public QObject
{
@@ -84,7 +79,7 @@ private slots:
void tst_qsganimatedimage::play()
{
QDeclarativeEngine engine;
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/stickman.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickman.qml")));
QSGAnimatedImage *anim = qobject_cast<QSGAnimatedImage *>(component.create());
QVERIFY(anim);
QVERIFY(anim->isPlaying());
@@ -95,7 +90,7 @@ void tst_qsganimatedimage::play()
void tst_qsganimatedimage::pause()
{
QDeclarativeEngine engine;
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/stickmanpause.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanpause.qml")));
QSGAnimatedImage *anim = qobject_cast<QSGAnimatedImage *>(component.create());
QVERIFY(anim);
QVERIFY(anim->isPlaying());
@@ -107,7 +102,7 @@ void tst_qsganimatedimage::pause()
void tst_qsganimatedimage::stopped()
{
QDeclarativeEngine engine;
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/stickmanstopped.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanstopped.qml")));
QSGAnimatedImage *anim = qobject_cast<QSGAnimatedImage *>(component.create());
QVERIFY(anim);
QVERIFY(!anim->isPlaying());
@@ -119,7 +114,7 @@ void tst_qsganimatedimage::stopped()
void tst_qsganimatedimage::setFrame()
{
QDeclarativeEngine engine;
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/stickmanpause.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanpause.qml")));
QSGAnimatedImage *anim = qobject_cast<QSGAnimatedImage *>(component.create());
QVERIFY(anim);
QVERIFY(anim->isPlaying());
@@ -131,7 +126,7 @@ void tst_qsganimatedimage::setFrame()
void tst_qsganimatedimage::frameCount()
{
QDeclarativeEngine engine;
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/colors.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("colors.qml")));
QSGAnimatedImage *anim = qobject_cast<QSGAnimatedImage *>(component.create());
QVERIFY(anim);
QVERIFY(anim->isPlaying());
@@ -147,7 +142,7 @@ void tst_qsganimatedimage::mirror_running()
QSGView *canvas = new QSGView;
canvas->show();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/hearts.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("hearts.qml")));
QSGAnimatedImage *anim = qobject_cast<QSGAnimatedImage *>(canvas->rootObject());
QVERIFY(anim);
@@ -174,7 +169,7 @@ void tst_qsganimatedimage::mirror_running()
QCOMPARE(anim->currentFrame(), 0); // animation only has 2 frames, should cycle back to first
QPixmap frame0_flipped = QPixmap::fromImage(canvas->grabFrameBuffer());
- QSKIP("Skip while QTBUG-19351 and QTBUG-19252 are not resolved", SkipSingle);
+ QSKIP("Skip while QTBUG-19351 and QTBUG-19252 are not resolved");
QTransform transform;
transform.translate(width, 0).scale(-1, 1.0);
@@ -212,7 +207,7 @@ void tst_qsganimatedimage::mirror_notRunning()
anim->setProperty("mirror", true);
screenshot = QPixmap::fromImage(canvas->grabFrameBuffer());
- QSKIP("Skip while QTBUG-19351 and QTBUG-19252 are not resolved", SkipSingle);
+ QSKIP("Skip while QTBUG-19351 and QTBUG-19252 are not resolved");
QCOMPARE(screenshot, expected);
// mirroring should not change the current frame or playing status
@@ -227,8 +222,8 @@ void tst_qsganimatedimage::mirror_notRunning_data()
{
QTest::addColumn<QUrl>("fileUrl");
- QTest::newRow("paused") << QUrl::fromLocalFile(SRCDIR "/data/stickmanpause.qml");
- QTest::newRow("stopped") << QUrl::fromLocalFile(SRCDIR "/data/stickmanstopped.qml");
+ QTest::newRow("paused") << QUrl::fromLocalFile(TESTDATA("stickmanpause.qml"));
+ QTest::newRow("stopped") << QUrl::fromLocalFile(TESTDATA("stickmanstopped.qml"));
}
void tst_qsganimatedimage::remote()
@@ -238,7 +233,7 @@ void tst_qsganimatedimage::remote()
TestHTTPServer server(14449);
QVERIFY(server.isValid());
- server.serveDirectory(SRCDIR "/data");
+ server.serveDirectory(TESTDATA(""));
QDeclarativeEngine engine;
QDeclarativeComponent component(&engine, QUrl("http://127.0.0.1:14449/" + fileName));
@@ -260,7 +255,7 @@ void tst_qsganimatedimage::remote()
void tst_qsganimatedimage::sourceSize()
{
QDeclarativeEngine engine;
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/stickmanscaled.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanscaled.qml")));
QSGAnimatedImage *anim = qobject_cast<QSGAnimatedImage *>(component.create());
QVERIFY(anim);
QCOMPARE(anim->width(),240.0);
@@ -273,7 +268,7 @@ void tst_qsganimatedimage::sourceSize()
void tst_qsganimatedimage::sourceSizeReadOnly()
{
QDeclarativeEngine engine;
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/stickmanerror1.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanerror1.qml")));
QVERIFY(component.isError());
QCOMPARE(component.errors().at(0).description(), QString("Invalid property assignment: \"sourceSize\" is a read-only property"));
}
@@ -310,10 +305,10 @@ void tst_qsganimatedimage::qtbug_16520()
{
TestHTTPServer server(14449);
QVERIFY(server.isValid());
- server.serveDirectory(SRCDIR "/data");
+ server.serveDirectory(TESTDATA(""));
QDeclarativeEngine engine;
- QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/qtbug-16520.qml"));
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("qtbug-16520.qml")));
QTRY_VERIFY(component.isReady());
QSGRectangle *root = qobject_cast<QSGRectangle *>(component.create());
@@ -332,12 +327,12 @@ void tst_qsganimatedimage::progressAndStatusChanges()
{
TestHTTPServer server(14449);
QVERIFY(server.isValid());
- server.serveDirectory(SRCDIR "/data");
+ server.serveDirectory(TESTDATA(""));
QDeclarativeEngine engine;
QString componentStr = "import QtQuick 2.0\nAnimatedImage { source: srcImage }";
QDeclarativeContext *ctxt = engine.rootContext();
- ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/stickman.gif"));
+ ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("stickman.gif")));
QDeclarativeComponent component(&engine);
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QSGImage *obj = qobject_cast<QSGImage*>(component.create());
@@ -350,7 +345,7 @@ void tst_qsganimatedimage::progressAndStatusChanges()
QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QSGImageBase::Status)));
// Loading local file
- ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/colors.gif"));
+ ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("colors.gif")));
QTRY_VERIFY(obj->status() == QSGImage::Ready);
QTRY_VERIFY(obj->progress() == 1.0);
QTRY_COMPARE(sourceSpy.count(), 1);
diff --git a/tests/auto/declarative/qsgborderimage/qsgborderimage.pro b/tests/auto/declarative/qsgborderimage/qsgborderimage.pro
index 5a68e67e44..65200a9a93 100644
--- a/tests/auto/declarative/qsgborderimage/qsgborderimage.pro
+++ b/tests/auto/declarative/qsgborderimage/qsgborderimage.pro
@@ -1,19 +1,14 @@
-load(qttest_p4)
+CONFIG += testcase
+TARGET = tst_qsgborderimage
macx:CONFIG -= app_bundle
HEADERS += ../shared/testhttpserver.h
SOURCES += tst_qsgborderimage.cpp ../shared/testhttpserver.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private declarative-private network widgets
-
-qpa:CONFIG+=insignificant_test # QTBUG-21004 fails, unstably
+QT += core-private gui-private declarative-private network widgets testlib
diff --git a/tests/auto/declarative/qsgborderimage/tst_qsgborderimage.cpp b/tests/auto/declarative/qsgborderimage/tst_qsgborderimage.cpp
index d1fe084df2..0835a66dd7 100644
--- a/tests/auto/declarative/qsgborderimage/tst_qsgborderimage.cpp
+++ b/tests/auto/declarative/qsgborderimage/tst_qsgborderimage.cpp
@@ -56,12 +56,7 @@
#include <QtDeclarative/qdeclarativecontext.h>
#include "../shared/testhttpserver.h"
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
#define SERVER_PORT 14446
#define SERVER_ADDR "http://127.0.0.1:14446"
@@ -118,9 +113,9 @@ void tst_qsgborderimage::imageSource_data()
QTest::addColumn<bool>("remote");
QTest::addColumn<QString>("error");
- QTest::newRow("local") << QUrl::fromLocalFile(SRCDIR "/data/colors.png").toString() << false << "";
- QTest::newRow("local not found") << QUrl::fromLocalFile(SRCDIR "/data/no-such-file.png").toString() << false
- << "file::2:1: QML BorderImage: Cannot open: " + QUrl::fromLocalFile(SRCDIR "/data/no-such-file.png").toString();
+ QTest::newRow("local") << QUrl::fromLocalFile(TESTDATA("colors.png")).toString() << false << "";
+ QTest::newRow("local not found") << QUrl::fromLocalFile(TESTDATA("no-such-file.png")).toString() << false
+ << "file::2:1: QML BorderImage: Cannot open: " + QUrl::fromLocalFile(TESTDATA("no-such-file.png")).toString();
QTest::newRow("remote") << SERVER_ADDR "/colors.png" << true << "";
QTest::newRow("remote not found") << SERVER_ADDR "/no-such-file.png" << true
<< "file::2:1: QML BorderImage: Error downloading " SERVER_ADDR "/no-such-file.png - server replied: Not found";
@@ -136,7 +131,7 @@ void tst_qsgborderimage::imageSource()
if (remote) {
server = new TestHTTPServer(SERVER_PORT);
QVERIFY(server->isValid());
- server->serveDirectory(SRCDIR "/data");
+ server->serveDirectory(TESTDATA(""));
}
if (!error.isEmpty())
@@ -173,7 +168,7 @@ void tst_qsgborderimage::clearSource()
{
QString componentStr = "import QtQuick 2.0\nBorderImage { source: srcImage }";
QDeclarativeContext *ctxt = engine.rootContext();
- ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/colors.png"));
+ ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("colors.png")));
QDeclarativeComponent component(&engine);
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QSGBorderImage *obj = qobject_cast<QSGBorderImage*>(component.create());
@@ -191,7 +186,7 @@ void tst_qsgborderimage::clearSource()
void tst_qsgborderimage::resized()
{
- QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + QUrl::fromLocalFile(SRCDIR "/data/colors.png").toString() + "\"; width: 300; height: 300 }";
+ QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + QUrl::fromLocalFile(TESTDATA("colors.png")).toString() + "\"; width: 300; height: 300 }";
QDeclarativeComponent component(&engine);
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QSGBorderImage *obj = qobject_cast<QSGBorderImage*>(component.create());
@@ -208,7 +203,7 @@ void tst_qsgborderimage::resized()
void tst_qsgborderimage::smooth()
{
- QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" SRCDIR "/data/colors.png\"; smooth: true; width: 300; height: 300 }";
+ QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + TESTDATA("colors.png") + "\"; smooth: true; width: 300; height: 300 }";
QDeclarativeComponent component(&engine);
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QSGBorderImage *obj = qobject_cast<QSGBorderImage*>(component.create());
@@ -227,7 +222,7 @@ void tst_qsgborderimage::mirror()
QSGView *canvas = new QSGView;
canvas->show();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/mirror.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("mirror.qml")));
QSGBorderImage *image = qobject_cast<QSGBorderImage*>(canvas->rootObject());
QVERIFY(image != 0);
canvas->show();
@@ -249,7 +244,7 @@ void tst_qsgborderimage::mirror()
void tst_qsgborderimage::tileModes()
{
{
- QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" SRCDIR "/data/colors.png\"; width: 100; height: 300; horizontalTileMode: BorderImage.Repeat; verticalTileMode: BorderImage.Repeat }";
+ QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + TESTDATA("colors.png") + "\"; width: 100; height: 300; horizontalTileMode: BorderImage.Repeat; verticalTileMode: BorderImage.Repeat }";
QDeclarativeComponent component(&engine);
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QSGBorderImage *obj = qobject_cast<QSGBorderImage*>(component.create());
@@ -262,7 +257,7 @@ void tst_qsgborderimage::tileModes()
delete obj;
}
{
- QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" SRCDIR "/data/colors.png\"; width: 300; height: 150; horizontalTileMode: BorderImage.Round; verticalTileMode: BorderImage.Round }";
+ QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + TESTDATA("colors.png") + "\"; width: 300; height: 150; horizontalTileMode: BorderImage.Round; verticalTileMode: BorderImage.Round }";
QDeclarativeComponent component(&engine);
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QSGBorderImage *obj = qobject_cast<QSGBorderImage*>(component.create());
@@ -286,7 +281,7 @@ void tst_qsgborderimage::sciSource()
if (remote) {
server = new TestHTTPServer(SERVER_PORT);
QVERIFY(server->isValid());
- server->serveDirectory(SRCDIR "/data");
+ server->serveDirectory(TESTDATA(""));
}
QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + source + "\"; width: 300; height: 300 }";
@@ -323,9 +318,9 @@ void tst_qsgborderimage::sciSource_data()
QTest::addColumn<QString>("source");
QTest::addColumn<bool>("valid");
- QTest::newRow("local") << QUrl::fromLocalFile(SRCDIR "/data/colors-round.sci").toString() << true;
- QTest::newRow("local quoted filename") << QUrl::fromLocalFile(SRCDIR "/data/colors-round-quotes.sci").toString() << true;
- QTest::newRow("local not found") << QUrl::fromLocalFile(SRCDIR "/data/no-such-file.sci").toString() << false;
+ QTest::newRow("local") << QUrl::fromLocalFile(TESTDATA("colors-round.sci")).toString() << true;
+ QTest::newRow("local quoted filename") << QUrl::fromLocalFile(TESTDATA("colors-round-quotes.sci")).toString() << true;
+ QTest::newRow("local not found") << QUrl::fromLocalFile(TESTDATA("no-such-file.sci")).toString() << false;
QTest::newRow("remote") << SERVER_ADDR "/colors-round.sci" << true;
QTest::newRow("remote filename quoted") << SERVER_ADDR "/colors-round-quotes.sci" << true;
QTest::newRow("remote image") << SERVER_ADDR "/colors-round-remote.sci" << true;
@@ -337,7 +332,7 @@ void tst_qsgborderimage::invalidSciFile()
QTest::ignoreMessage(QtWarningMsg, "QSGGridScaledImage: Invalid tile rule specified. Using Stretch."); // for "Roun"
QTest::ignoreMessage(QtWarningMsg, "QSGGridScaledImage: Invalid tile rule specified. Using Stretch."); // for "Repea"
- QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + QUrl::fromLocalFile(SRCDIR "/data/invalid.sci").toString() +"\"; width: 300; height: 300 }";
+ QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + QUrl::fromLocalFile(TESTDATA("invalid.sci")).toString() +"\"; width: 300; height: 300 }";
QDeclarativeComponent component(&engine);
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QSGBorderImage *obj = qobject_cast<QSGBorderImage*>(component.create());
diff --git a/tests/auto/declarative/qsgcanvas/qsgcanvas.pro b/tests/auto/declarative/qsgcanvas/qsgcanvas.pro
index 9fe5dd9194..d8749112d5 100644
--- a/tests/auto/declarative/qsgcanvas/qsgcanvas.pro
+++ b/tests/auto/declarative/qsgcanvas/qsgcanvas.pro
@@ -1,8 +1,8 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qsgcanvas
SOURCES += tst_qsgcanvas.cpp
macx:CONFIG -= app_bundle
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qsgcanvas/tst_qsgcanvas.cpp b/tests/auto/declarative/qsgcanvas/tst_qsgcanvas.cpp
index 32271b091f..d8135ed233 100644
--- a/tests/auto/declarative/qsgcanvas/tst_qsgcanvas.cpp
+++ b/tests/auto/declarative/qsgcanvas/tst_qsgcanvas.cpp
@@ -45,7 +45,6 @@
#include <QtDeclarative/QSGItem>
#include <QtDeclarative/QSGCanvas>
#include <QtDeclarative/private/qsgrectangle_p.h>
-#include "../../../shared/util.h"
#include <QtGui/QWindowSystemInterface>
struct TouchEventData {
@@ -121,9 +120,11 @@ class TestTouchItem : public QSGRectangle
Q_OBJECT
public:
TestTouchItem(QSGItem *parent = 0)
- : QSGRectangle(parent), acceptEvents(true)
+ : QSGRectangle(parent), acceptEvents(true), mousePressId(0)
{
border()->setWidth(1);
+ setAcceptedMouseButtons(Qt::LeftButton);
+ setFiltersChildMouseEvents(true);
}
void reset() {
@@ -136,6 +137,7 @@ public:
bool acceptEvents;
TouchEventData lastEvent;
+ int mousePressId;
protected:
virtual void touchEvent(QTouchEvent *event) {
@@ -146,8 +148,20 @@ protected:
lastEvent = makeTouchData(event->type(), event->widget(), event->touchPointStates(), event->touchPoints());
event->accept();
}
+
+ virtual void mousePressEvent(QMouseEvent *event) {
+ mousePressId = ++mousePressNum;
+ }
+
+ bool childMouseEventFilter(QSGItem *, QEvent *) {
+ mousePressId = ++mousePressNum;
+ return false;
+ }
+
+ static int mousePressNum;
};
+int TestTouchItem::mousePressNum = 0;
class ConstantUpdateItem : public QSGItem
{
@@ -181,6 +195,7 @@ private slots:
void touchEvent_propagation_data();
void clearCanvas();
+ void mouseFiltering();
};
tst_qsgcanvas::tst_qsgcanvas()
@@ -464,6 +479,41 @@ void tst_qsgcanvas::clearCanvas()
delete item;
}
+void tst_qsgcanvas::mouseFiltering()
+{
+ QSGCanvas *canvas = new QSGCanvas;
+ canvas->resize(250, 250);
+ canvas->move(100, 100);
+ canvas->show();
+
+ TestTouchItem *bottomItem = new TestTouchItem(canvas->rootItem());
+ bottomItem->setObjectName("Bottom Item");
+ bottomItem->setSize(QSizeF(150, 150));
+
+ TestTouchItem *middleItem = new TestTouchItem(bottomItem);
+ middleItem->setObjectName("Middle Item");
+ middleItem->setPos(QPointF(50, 50));
+ middleItem->setSize(QSizeF(150, 150));
+
+ TestTouchItem *topItem = new TestTouchItem(middleItem);
+ topItem->setObjectName("Top Item");
+ topItem->setPos(QPointF(50, 50));
+ topItem->setSize(QSizeF(150, 150));
+
+ QPoint pos(100, 100);
+
+ QTest::mousePress(canvas, Qt::LeftButton, 0, pos);
+ QTest::qWait(50);
+
+ // Mouse filtering propagates down the stack, so the
+ // correct order is
+ // 1. middleItem filters event
+ // 2. bottomItem filters event
+ // 3. topItem receives event
+ QCOMPARE(middleItem->mousePressId, 1);
+ QCOMPARE(bottomItem->mousePressId, 2);
+ QCOMPARE(topItem->mousePressId, 3);
+}
QTEST_MAIN(tst_qsgcanvas)
diff --git a/tests/auto/declarative/qsgcanvasitem/data/anim-gr.gif b/tests/auto/declarative/qsgcanvasitem/data/anim-gr.gif
new file mode 100644
index 0000000000..45263e0afb
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/anim-gr.gif
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/anim-gr.png b/tests/auto/declarative/qsgcanvasitem/data/anim-gr.png
new file mode 100644
index 0000000000..925e2efc9a
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/anim-gr.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/anim-poster-gr.png b/tests/auto/declarative/qsgcanvasitem/data/anim-poster-gr.png
new file mode 100644
index 0000000000..6941207373
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/anim-poster-gr.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/background.png b/tests/auto/declarative/qsgcanvasitem/data/background.png
new file mode 100644
index 0000000000..6db6c6b1b9
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/background.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/broken.png b/tests/auto/declarative/qsgcanvasitem/data/broken.png
new file mode 100644
index 0000000000..f2581017b4
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/broken.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/ggrr-256x256.png b/tests/auto/declarative/qsgcanvasitem/data/ggrr-256x256.png
new file mode 100644
index 0000000000..0342e4a384
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/ggrr-256x256.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/green-16x16.png b/tests/auto/declarative/qsgcanvasitem/data/green-16x16.png
new file mode 100644
index 0000000000..e19a3ffddd
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/green-16x16.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/green-1x1.png b/tests/auto/declarative/qsgcanvasitem/data/green-1x1.png
new file mode 100644
index 0000000000..862d1dd10c
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/green-1x1.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/green-256x256.png b/tests/auto/declarative/qsgcanvasitem/data/green-256x256.png
new file mode 100644
index 0000000000..b06945c310
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/green-256x256.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/green-2x2.png b/tests/auto/declarative/qsgcanvasitem/data/green-2x2.png
new file mode 100644
index 0000000000..adc059449c
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/green-2x2.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/green.png b/tests/auto/declarative/qsgcanvasitem/data/green.png
new file mode 100644
index 0000000000..28a1faab37
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/green.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/grgr-256x256.png b/tests/auto/declarative/qsgcanvasitem/data/grgr-256x256.png
new file mode 100644
index 0000000000..b8c7189d62
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/grgr-256x256.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/red-16x16.png b/tests/auto/declarative/qsgcanvasitem/data/red-16x16.png
new file mode 100644
index 0000000000..9038fef784
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/red-16x16.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/red.png b/tests/auto/declarative/qsgcanvasitem/data/red.png
new file mode 100644
index 0000000000..a6e195d59c
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/red.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/redtransparent.png b/tests/auto/declarative/qsgcanvasitem/data/redtransparent.png
new file mode 100644
index 0000000000..75da08c3d6
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/redtransparent.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/rgrg-256x256.png b/tests/auto/declarative/qsgcanvasitem/data/rgrg-256x256.png
new file mode 100644
index 0000000000..e6fba3daa5
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/rgrg-256x256.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/rrgg-256x256.png b/tests/auto/declarative/qsgcanvasitem/data/rrgg-256x256.png
new file mode 100644
index 0000000000..7f63515654
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/rrgg-256x256.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/testhelper.js b/tests/auto/declarative/qsgcanvasitem/data/testhelper.js
new file mode 100644
index 0000000000..bac0210e16
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/testhelper.js
@@ -0,0 +1,18 @@
+function comparePixel(ctx,x,y,r,g,b,a, d)
+{
+ var c = ctx.getImageData(x,y,1,1).data;
+ if (d === undefined)
+ d = 0;
+ r = Math.round(r);
+ g = Math.round(g);
+ b = Math.round(b);
+ a = Math.round(a);
+
+ if (Math.abs(c[0]-r)>d || Math.abs(c[1]-g)>d || Math.abs(c[2]-b)>d || Math.abs(c[3]-a)>d) {
+ console.log('Pixel compare fail:\nactual :[' + c[0]+','+c[1]+','+c[2]+','+c[3] + ']\nexpected:['+r+','+g+','+b+','+a+'] +/- '+d);
+ return false;
+ }
+ return true;
+}
+
+
diff --git a/tests/auto/declarative/qsgcanvasitem/data/transparent.png b/tests/auto/declarative/qsgcanvasitem/data/transparent.png
new file mode 100644
index 0000000000..2b498699a8
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/transparent.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/transparent50.png b/tests/auto/declarative/qsgcanvasitem/data/transparent50.png
new file mode 100644
index 0000000000..55f8e69325
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/transparent50.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/tst_arc.qml b/tests/auto/declarative/qsgcanvasitem/data/tst_arc.qml
new file mode 100644
index 0000000000..6006a5a4c0
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/tst_arc.qml
@@ -0,0 +1,487 @@
+import QtQuick 2.0
+import QtTest 1.0
+import "testhelper.js" as Helper
+
+Canvas {
+ id:canvas; width:100;height:50; renderTarget: Canvas.Image
+ TestCase {
+ name: "arc"; when: windowShown
+ function test_angle_1() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, Math.PI/2, -Math.PI, true);
+ ctx.fill();
+ verify(Helper.comparePixel(ctx,50,25, 0,255,0,255));
+ }
+ function test_angle_2() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, -3*Math.PI/2, -Math.PI, true);
+ ctx.fill();
+ verify(Helper.comparePixel(ctx,50,25, 0,255,0,255));
+ }
+ function test_angle_3() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, (512+1/2)*Math.PI, (1024-1)*Math.PI, true);
+ ctx.fill();
+ //verify(Helper.comparePixel(ctx,50,25, 0,255,0,255));
+ }
+ function test_angle_4() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 60, (512+1/2)*Math.PI, (1024-1)*Math.PI, false);
+ ctx.fill();
+ verify(Helper.comparePixel(ctx,1,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx,98,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx,1,48, 0,255,0,255));
+ verify(Helper.comparePixel(ctx,98,48, 0,255,0,255));
+ }
+ function test_angle_5() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 0);
+ ctx.arc(100, 0, 150, (1024-1)*Math.PI, (512+1/2)*Math.PI, false);
+ ctx.fill();
+ /*FIXME:
+ actual :[255,0,0,255]
+ expected:[0,255,0,255] +/- 0
+ */
+ //verify(Helper.comparePixel(ctx,50,25, 0,255,0,255));
+ }
+
+ function test_angle_6() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 60, (1024-1)*Math.PI, (512+1/2)*Math.PI, true);
+ ctx.fill();
+
+ verify(Helper.comparePixel(ctx,1,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx,98,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx,1,48, 0,255,0,255));
+ verify(Helper.comparePixel(ctx,98,48, 0,255,0,255));
+ }
+
+ function test_empty() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(200, 25, 5, 0, 2*Math.PI, true);
+ ctx.stroke();
+ /*FIXME:
+ actual :[255,0,0,255]
+ expected:[0,255,0,255] +/- 0
+ */
+ //verify(Helper.comparePixel(ctx,50,25, 0,255,0,255));
+ }
+ function test_nonempty() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arc(200, 25, 5, 0, 2*Math.PI, true);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx,50,25, 0,255,0,255));
+ }
+ function test_nonfinite() {
+ skip("FIXME");
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.arc(Infinity, 0, 50, 0, 2*Math.PI, true);
+ ctx.arc(-Infinity, 0, 50, 0, 2*Math.PI, true);
+ ctx.arc(NaN, 0, 50, 0, 2*Math.PI, true);
+ ctx.arc(0, Infinity, 50, 0, 2*Math.PI, true);
+ ctx.arc(0, -Infinity, 50, 0, 2*Math.PI, true);
+ ctx.arc(0, NaN, 50, 0, 2*Math.PI, true);
+ ctx.arc(0, 0, Infinity, 0, 2*Math.PI, true);
+ ctx.arc(0, 0, -Infinity, 0, 2*Math.PI, true);
+ ctx.arc(0, 0, NaN, 0, 2*Math.PI, true);
+ ctx.arc(0, 0, 50, Infinity, 2*Math.PI, true);
+ ctx.arc(0, 0, 50, -Infinity, 2*Math.PI, true);
+ ctx.arc(0, 0, 50, NaN, 2*Math.PI, true);
+ ctx.arc(0, 0, 50, 0, Infinity, true);
+ ctx.arc(0, 0, 50, 0, -Infinity, true);
+ ctx.arc(0, 0, 50, 0, NaN, true);
+ ctx.arc(Infinity, Infinity, 50, 0, 2*Math.PI, true);
+ ctx.arc(Infinity, Infinity, Infinity, 0, 2*Math.PI, true);
+ ctx.arc(Infinity, Infinity, Infinity, Infinity, 2*Math.PI, true);
+ ctx.arc(Infinity, Infinity, Infinity, Infinity, Infinity, true);
+ ctx.arc(Infinity, Infinity, Infinity, 0, Infinity, true);
+ ctx.arc(Infinity, Infinity, 50, Infinity, 2*Math.PI, true);
+ ctx.arc(Infinity, Infinity, 50, Infinity, Infinity, true);
+ ctx.arc(Infinity, Infinity, 50, 0, Infinity, true);
+ ctx.arc(Infinity, 0, Infinity, 0, 2*Math.PI, true);
+ ctx.arc(Infinity, 0, Infinity, Infinity, 2*Math.PI, true);
+ ctx.arc(Infinity, 0, Infinity, Infinity, Infinity, true);
+ ctx.arc(Infinity, 0, Infinity, 0, Infinity, true);
+ ctx.arc(Infinity, 0, 50, Infinity, 2*Math.PI, true);
+ ctx.arc(Infinity, 0, 50, Infinity, Infinity, true);
+ ctx.arc(Infinity, 0, 50, 0, Infinity, true);
+ ctx.arc(0, Infinity, Infinity, 0, 2*Math.PI, true);
+ ctx.arc(0, Infinity, Infinity, Infinity, 2*Math.PI, true);
+ ctx.arc(0, Infinity, Infinity, Infinity, Infinity, true);
+ ctx.arc(0, Infinity, Infinity, 0, Infinity, true);
+ ctx.arc(0, Infinity, 50, Infinity, 2*Math.PI, true);
+ ctx.arc(0, Infinity, 50, Infinity, Infinity, true);
+ ctx.arc(0, Infinity, 50, 0, Infinity, true);
+ ctx.arc(0, 0, Infinity, Infinity, 2*Math.PI, true);
+ ctx.arc(0, 0, Infinity, Infinity, Infinity, true);
+ ctx.arc(0, 0, Infinity, 0, Infinity, true);
+ ctx.arc(0, 0, 50, Infinity, Infinity, true);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ verify(Helper.comparePixel(ctx,50,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx,90,45, 0,255,0,255));
+ }
+ function test_end() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(-100, 0);
+ ctx.arc(-100, 0, 25, -Math.PI/2, Math.PI/2, true);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx,50,25, 0,255,0,255));
+ }
+ function test_negative() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ try { var err = false;
+ ctx.arc(0, 0, -1, 0, 0, true);
+ } catch (e) {
+ if (e.code != DOMException.INDEX_SIZE_ERR)
+ fail("expected exception of type INDEX_SIZE_ERR, got: "+e.message);
+ err = true;
+ } finally {
+ verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.arc(0, 0, -1, 0, 0, true)");
+ }
+
+ }
+
+ function test_scale_1() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(2, 0.5);
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(25, 50, 56, 0, 2*Math.PI, false);
+ ctx.fill();
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(-25, 50);
+ ctx.arc(-25, 50, 24, 0, 2*Math.PI, false);
+ ctx.moveTo(75, 50);
+ ctx.arc(75, 50, 24, 0, 2*Math.PI, false);
+ ctx.moveTo(25, -25);
+ ctx.arc(25, -25, 24, 0, 2*Math.PI, false);
+ ctx.moveTo(25, 125);
+ ctx.arc(25, 125, 24, 0, 2*Math.PI, false);
+ ctx.fill();
+
+ verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255));
+ }
+
+ function test_scale_2() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(100, 100);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 1.2;
+ ctx.beginPath();
+ ctx.arc(0, 0, 0.6, 0, Math.PI/2, false);
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+ }
+
+ function test_selfintersect_1() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 200;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(100, 50, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(0, 0, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ }
+
+ function test_selfintersect_2() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 180;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(-50, 50, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ ctx.beginPath();
+ ctx.arc(100, 0, 25, 0, -Math.PI/2, true);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 90,10, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 97,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 97,2, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 97,3, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 2,48, 0,255,0,255));
+ }
+
+ function test_shape_1() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(50, 50, 50, 0, Math.PI, false);
+ ctx.stroke();
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 20,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+ }
+
+ function test_shape_2() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 100;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(50, 50, 50, 0, Math.PI, true);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 20,48, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+ }
+ function test_shape_3() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 100;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(0, 50, 50, 0, -Math.PI/2, false);
+ ctx.stroke();
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+ }
+
+ function test_shape_4() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 150;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arc(-50, 50, 100, 0, -Math.PI/2, true);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+ }
+
+ function test_shape_5() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 200;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arc(300, 0, 100, 0, 5*Math.PI, false);
+ ctx.stroke();
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+ }
+
+ function test_twopie() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, true);
+ ctx.stroke();
+ //verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, false);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, true);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, false);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255));
+ }
+
+ function test_zero() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 0, true);
+ ctx.stroke();
+ //verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.arc(50, 25, 50, 0, 0, false);
+ ctx.stroke();
+ //verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00'
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arc(200, 25, 0, 0, Math.PI, true);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ }
+ }
+}
diff --git a/tests/auto/declarative/qsgcanvasitem/data/tst_arcto.qml b/tests/auto/declarative/qsgcanvasitem/data/tst_arcto.qml
new file mode 100644
index 0000000000..cc1d88672b
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/tst_arcto.qml
@@ -0,0 +1,410 @@
+import QtQuick 2.0
+import QtTest 1.0
+import "testhelper.js" as Helper
+
+Canvas {
+ id:canvas; width:100;height:50; renderTarget: Canvas.Image
+ TestCase {
+ name: "arcTo"; when: windowShown
+ function test_coincide() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(0, 25, 50, 1000, 1);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arcTo(50, 25, 100, 25, 1);
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 100, 25, 1);
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ }
+ function test_collinear() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 200, 25, 1);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(-100, 25);
+ ctx.arcTo(0, 25, 100, 25, 1);
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 10, 25, 1);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 25);
+ ctx.arcTo(200, 25, 110, 25, 1);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, -100, 25, 1);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 25);
+ ctx.arcTo(200, 25, 0, 25, 1);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(-100, 25);
+ ctx.arcTo(0, 25, -200, 25, 1);
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ }
+ function test_subpath() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.arcTo(100, 50, 200, 50, 0.1);
+ ctx.stroke();
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.arcTo(0, 25, 50, 250, 0.1);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ }
+
+ function test_negative() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ try { var err = false;
+ ctx.arcTo(0, 0, 0, 0, -1);
+ } catch (e) {
+ if (e.code != DOMException.INDEX_SIZE_ERR)
+ fail("expectes INDEX_SIZE_ERR, got: "+e.message);
+ err = true;
+ }
+ finally {
+ verify(err, "should throw INDEX_SIZE_ERR: ctx.arcTo(0, 0, 0, 0, -1)");
+ }
+ }
+
+ function test_nonfinite() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ skip("FIXME");
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.arcTo(Infinity, 50, 0, 50, 0);
+ ctx.arcTo(-Infinity, 50, 0, 50, 0);
+ ctx.arcTo(NaN, 50, 0, 50, 0);
+ ctx.arcTo(0, Infinity, 0, 50, 0);
+ ctx.arcTo(0, -Infinity, 0, 50, 0);
+ ctx.arcTo(0, NaN, 0, 50, 0);
+ ctx.arcTo(0, 50, Infinity, 50, 0);
+ ctx.arcTo(0, 50, -Infinity, 50, 0);
+ ctx.arcTo(0, 50, NaN, 50, 0);
+ ctx.arcTo(0, 50, 0, Infinity, 0);
+ ctx.arcTo(0, 50, 0, -Infinity, 0);
+ ctx.arcTo(0, 50, 0, NaN, 0);
+ ctx.arcTo(0, 50, 0, 50, Infinity);
+ ctx.arcTo(0, 50, 0, 50, -Infinity);
+ ctx.arcTo(0, 50, 0, 50, NaN);
+ ctx.arcTo(Infinity, Infinity, 0, 50, 0);
+ ctx.arcTo(Infinity, Infinity, Infinity, 50, 0);
+ ctx.arcTo(Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.arcTo(Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.arcTo(Infinity, Infinity, Infinity, 50, Infinity);
+ ctx.arcTo(Infinity, Infinity, 0, Infinity, 0);
+ ctx.arcTo(Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.arcTo(Infinity, Infinity, 0, 50, Infinity);
+ ctx.arcTo(Infinity, 50, Infinity, 50, 0);
+ ctx.arcTo(Infinity, 50, Infinity, Infinity, 0);
+ ctx.arcTo(Infinity, 50, Infinity, Infinity, Infinity);
+ ctx.arcTo(Infinity, 50, Infinity, 50, Infinity);
+ ctx.arcTo(Infinity, 50, 0, Infinity, 0);
+ ctx.arcTo(Infinity, 50, 0, Infinity, Infinity);
+ ctx.arcTo(Infinity, 50, 0, 50, Infinity);
+ ctx.arcTo(0, Infinity, Infinity, 50, 0);
+ ctx.arcTo(0, Infinity, Infinity, Infinity, 0);
+ ctx.arcTo(0, Infinity, Infinity, Infinity, Infinity);
+ ctx.arcTo(0, Infinity, Infinity, 50, Infinity);
+ ctx.arcTo(0, Infinity, 0, Infinity, 0);
+ ctx.arcTo(0, Infinity, 0, Infinity, Infinity);
+ ctx.arcTo(0, Infinity, 0, 50, Infinity);
+ ctx.arcTo(0, 50, Infinity, Infinity, 0);
+ ctx.arcTo(0, 50, Infinity, Infinity, Infinity);
+ ctx.arcTo(0, 50, Infinity, 50, Infinity);
+ ctx.arcTo(0, 50, 0, Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255));
+
+ }
+ function test_scale() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 50);
+ ctx.translate(100, 0);
+ ctx.scale(0.1, 1);
+ ctx.arcTo(50, 50, 50, 0, 50);
+ ctx.lineTo(-1000, 0);
+ ctx.fill();
+
+ skip("FIXME");
+ //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255));
+ }
+
+ function test_shape() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ var tol = 1.5; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 10;
+ ctx.beginPath();
+ ctx.moveTo(10, 25);
+ ctx.arcTo(75, 25, 75, 60, 20);
+ ctx.stroke();
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.rect(10, 20, 45, 10);
+ ctx.moveTo(80, 45);
+ ctx.arc(55, 45, 25+tol, 0, -Math.PI/2, true);
+ ctx.arc(55, 45, 15-tol, -Math.PI/2, 0, false);
+ ctx.fill();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 55,19, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 55,20, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 55,21, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 64,22, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 65,21, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 72,28, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 73,27, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 78,36, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 79,35, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 80,44, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 80,45, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 80,46, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 65,45, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.rect(10, 20, 45, 10);
+ ctx.moveTo(80, 45);
+ ctx.arc(55, 45, 25-tol, 0, -Math.PI/2, true);
+ ctx.arc(55, 45, 15+tol, -Math.PI/2, 0, false);
+ ctx.fill();
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 10;
+ ctx.beginPath();
+ ctx.moveTo(10, 25);
+ ctx.arcTo(75, 25, 75, 60, 20);
+ ctx.stroke();
+
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 55,19, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 55,20, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 55,21, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 64,22, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 65,21, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 72,28, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 73,27, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 78,36, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 79,35, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 80,44, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 80,45, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 80,46, 0,255,0,255));
+ ctx.reset();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(-100, -100);
+ ctx.arcTo(-100, 25, 200, 25, 10);
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(200, 25, 200, 50, 10);
+ ctx.stroke();
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+ }
+
+ function test_transform() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 50);
+ ctx.translate(100, 0);
+ ctx.arcTo(50, 50, 50, 0, 50);
+ ctx.lineTo(-100, 0);
+ ctx.fill();
+
+ skip("FIXME");
+ //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255));
+ }
+ function test_zero() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, 100, 100, 0);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(0, -25);
+ ctx.arcTo(50, -25, 50, 50, 0);
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.lineWidth = 50;
+
+ ctx.strokeStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.arcTo(100, 25, -100, 25, 0);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(100, 25);
+ ctx.arcTo(200, 25, 50, 25, 0);
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ }
+ }
+}
diff --git a/tests/auto/declarative/qsgcanvasitem/data/tst_canvas.qml b/tests/auto/declarative/qsgcanvasitem/data/tst_canvas.qml
new file mode 100644
index 0000000000..70bedb2131
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/tst_canvas.qml
@@ -0,0 +1,274 @@
+import QtQuick 2.0
+import QtTest 1.0
+
+Rectangle {
+ id:container
+ width:100
+ height:100
+ Component {
+ id:canvas
+ Canvas {
+ id:c
+ width:100;height:100
+ onPaint: {
+ context.fillStyle = "red";
+ context.fillRect(0, 0, 100, 100);
+ }
+ property int paintCount:spyPaint.count
+ property int paintedCount:spyPainted.count
+ property int canvasSizeChangedCount:spyCanvasSizeChanged.count
+ property int tileSizeChangedCount:spyTileSizeChanged.count
+ property int renderInThreadChangedCount:spyRenderInThreadChanged.count
+ property int canvasWindowChangedCount:spyCanvasWindowChanged.count
+ property int renderTargetChangedCount:spyRenderTargetChanged.count
+ property int imageLoadedCount:spyImageLoaded.count
+
+ SignalSpy {id: spyPaint;target:c;signalName: "paint"}
+ SignalSpy {id: spyPainted;target:c;signalName: "painted"}
+ SignalSpy {id: spyCanvasSizeChanged;target:c;signalName: "canvasSizeChanged"}
+ SignalSpy {id: spyTileSizeChanged;target:c;signalName: "tileSizeChanged"}
+ SignalSpy {id: spyRenderInThreadChanged;target:c;signalName: "renderInThreadChanged"}
+ SignalSpy {id: spyCanvasWindowChanged;target:c;signalName: "canvasWindowChanged"}
+ SignalSpy {id: spyRenderTargetChanged;target:c;signalName: "renderTargetChanged"}
+ SignalSpy {id: spyImageLoaded;target:c;signalName: "imageLoaded"}
+ }
+ }
+
+ TestCase {
+ name: "Canvas"; when: windowShown
+ function test_canvasSize() {
+ var c = canvas.createObject();
+ verify(c);
+
+ //by default canvasSize is same with canvas' actual size
+ // when canvas size changes, canvasSize should be changed as well.
+ compare(c.canvasSize.width, c.width);
+ compare(c.canvasSize.height, c.height);
+ c.width = 20;
+ compare(c.canvasSize.width, 20);
+ compare(c.canvasSizeChangedCount, 1);
+ c.height = 5;
+ compare(c.canvasSizeChangedCount, 2);
+ compare(c.canvasSize.height, 5);
+
+ //change canvasSize manually, then canvasSize detaches from canvas
+ //actual size.
+ c.canvasSize.width = 100;
+ compare(c.canvasSizeChangedCount, 3);
+ compare(c.canvasSize.width, 100);
+ compare(c.width, 20);
+ c.canvasSize.height = 50;
+ compare(c.canvasSizeChangedCount, 4);
+ compare(c.canvasSize.height, 50);
+ compare(c.height, 5);
+
+ c.width = 10;
+ compare(c.canvasSizeChangedCount, 4);
+ compare(c.canvasSize.width, 100);
+ compare(c.canvasSize.height, 50);
+
+ c.height = 10;
+ compare(c.canvasSizeChangedCount, 4);
+ compare(c.canvasSize.width, 100);
+ compare(c.canvasSize.height, 50);
+ c.destroy();
+ }
+ function test_tileSize() {
+ var c = canvas.createObject();
+ verify(c);
+
+ compare(c.tileSize.width, c.width);
+ compare(c.tileSize.height, c.height);
+ c.width = 20;
+ compare(c.tileSize.width, 20);
+ compare(c.tileSizeChangedCount, 1);
+ c.height = 5;
+ compare(c.tileSizeChangedCount, 2);
+ compare(c.tileSize.height, 5);
+
+ c.tileSize.width = 100;
+ compare(c.tileSizeChangedCount, 3);
+ compare(c.tileSize.width, 100);
+ compare(c.width, 20);
+ c.tileSize.height = 50;
+ compare(c.tileSizeChangedCount, 4);
+ compare(c.tileSize.height, 50);
+ compare(c.height, 5);
+
+ c.width = 10;
+ compare(c.tileSizeChangedCount, 4);
+ compare(c.tileSize.width, 100);
+ compare(c.tileSize.height, 50);
+
+ c.height = 10;
+ compare(c.tileSizeChangedCount, 4);
+ compare(c.tileSize.width, 100);
+ compare(c.tileSize.height, 50);
+ c.destroy();
+
+ }
+
+ function test_canvasWindow() {
+ var c = canvas.createObject();
+ verify(c);
+ compare(c.canvasWindow.x, 0);
+ compare(c.canvasWindow.y, 0);
+ compare(c.canvasWindow.width, c.width);
+ compare(c.canvasWindow.height, c.height);
+
+ c.width = 20;
+ compare(c.canvasWindow.width, 20);
+ compare(c.canvasWindowChangedCount, 1);
+ c.height = 5;
+ compare(c.canvasWindowChangedCount, 2);
+ compare(c.canvasWindow.height, 5);
+
+ c.canvasWindow.x = 5;
+ c.canvasWindow.y = 6;
+ c.canvasWindow.width = 10;
+ c.canvasWindow.height =20;
+ compare(c.canvasWindowChangedCount, 6);
+ compare(c.canvasWindow.width, 10);
+ compare(c.canvasWindow.height, 20);
+ compare(c.canvasWindow.x, 5);
+ compare(c.canvasWindow.y, 6);
+ c.destroy();
+
+ }
+ function test_renderTargetAndThread() {
+ var c = canvas.createObject();
+ verify(c);
+
+ compare(c.renderTarget, Canvas.FramebufferObject);
+ verify(!c.renderInThread);
+ c.renderTarget = Canvas.Image;
+ compare(c.renderTargetChangedCount, 1);
+ compare(c.renderInThreadChangedCount, 0);
+
+ compare(c.renderTarget, Canvas.Image);
+ verify(!c.renderInThread);
+ c.renderInThread = true;
+ verify(c.renderInThread);
+ compare(c.renderTargetChangedCount, 1);
+ compare(c.renderInThreadChangedCount, 1);
+
+ ignoreWarning("Canvas: render target does not support thread rendering, force to non-thread rendering mode.");
+ c.renderTarget = Canvas.FramebufferObject;
+ verify(!c.renderInThread);
+ compare(c.renderTargetChangedCount, 2);
+ compare(c.renderInThreadChangedCount, 2);
+ c.destroy();
+
+ }
+ function test_save() {
+ var c = canvas.createObject();
+ verify(c);
+
+ c.renderTarget = Canvas.Image;
+ c.requestPaint();
+ wait(100);
+ verify(c.save("c.png"));
+ c.loadImage("c.png");
+ wait(200);
+ compare(c.imageLoadedCount, 1);
+ verify(c.isImageLoaded("c.png"));
+ verify(!c.isImageLoading("c.png"));
+ verify(!c.isImageError("c.png"));
+ c.destroy();
+
+ }
+ function test_toDataURL_data() {
+ return [{mimeType:"image/png"},
+ {mimeType:"image/bmp"},
+ {mimeType:"image/jpeg"},
+ {mimeType:"image/x-portable-pixmap"},
+ {mimeType:"image/tiff"},
+ {mimeType:"image/xpm"},
+ ];
+ }
+
+ function test_toDataURL(data) {
+ var c = canvas.createObject();
+ verify(c);
+
+ c.renderTarget = Canvas.Image;
+ var ctx = c.getContext();
+ ctx.fillStyle = "red";
+ ctx.fillRect(0, 0, c.width, c.height);
+
+ c.requestPaint();
+ wait(100);
+ var dataUrl = c.toDataURL();
+ verify(dataUrl != "data:,");
+ dataUrl = c.toDataURL("image/invalid");
+ verify(dataUrl == "data:,");
+
+ dataUrl = c.toDataURL(data.mimeType);
+ verify(dataUrl != "data:,");
+ ctx.save();
+ ctx.fillStyle = "blue";
+ ctx.fillRect(0, 0, c.width, c.height);
+ ctx.restore();
+ c.requestPaint();
+ wait(100);
+ var dataUrl2 = c.toDataURL(data.mimeType);
+ verify (dataUrl2 != "data:,");
+ verify (dataUrl2 != dataUrl);
+ c.destroy();
+
+ }
+ function test_paint() {
+ var c = canvas.createObject();
+ verify(c);
+
+ c.renderTarget = Canvas.Image;
+ c.renderInThread = true;
+ var ctx = c.getContext();
+ ctx.fillRect(0, 0, c.width, c.height);
+ c.toDataURL();
+ wait(100);
+
+ compare(c.paintedCount, 1);
+ compare(c.paintCount, 1);
+ c.destroy();
+
+ }
+ function test_loadImage() {
+ var c = canvas.createObject();
+ verify(c);
+
+ c.loadImage("red.png");
+ wait(200);
+ compare(c.imageLoadedCount, 1);
+ verify(c.isImageLoaded("red.png"));
+ verify(!c.isImageLoading("red.png"));
+ verify(!c.isImageError("red.png"));
+
+ c.unloadImage("red.png");
+ verify(!c.isImageLoaded("red.png"));
+ verify(!c.isImageLoading("red.png"));
+ verify(!c.isImageError("red.png"));
+ c.destroy();
+
+ }
+
+ function test_getContext() {
+ var c = canvas.createObject();
+ verify(c);
+
+ var ctx = c.getContext();
+ verify(ctx);
+ compare(ctx.canvas, c);
+ ctx = c.getContext('2d');
+ verify(ctx);
+ compare(ctx.canvas, c);
+ ctx = c.getContext('2D');
+ verify(ctx);
+ compare(ctx.canvas, c);
+ ctx = c.getContext('invalid');
+ verify(!ctx);
+ c.destroy();
+
+ }
+ }
+}
diff --git a/tests/auto/declarative/qsgcanvasitem/data/tst_composite.qml b/tests/auto/declarative/qsgcanvasitem/data/tst_composite.qml
new file mode 100644
index 0000000000..11e1dce902
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/tst_composite.qml
@@ -0,0 +1,380 @@
+import QtQuick 2.0
+import QtTest 1.0
+import "testhelper.js" as Helper
+Canvas {
+ id:canvas; width:100;height:50; renderTarget:Canvas.Image
+ TestCase {
+ name: "composite"; when: windowShown
+ function test_clearRect() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.clearRect(0, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0));
+ }
+
+ function test_clip_data() {
+ return [ {compsite:"copy"},
+ {compsite:"destination-atop"},
+ {compsite:"destination-in"},
+ {compsite:"destination-out"},
+ {compsite:"destination-over"},
+ {compsite:"lighter"},
+ {compsite:"source-atop"},
+ {compsite:"source-in"},
+ {compsite:"source-out"},
+ {compsite:"source-over"},
+ {compsite:"xor"}
+ ];
+ }
+
+ function test_clip(data) {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = data.compsite;
+ ctx.rect(-20, -20, 10, 10);
+ ctx.clip();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 50, 50);
+ verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
+ }
+
+ function test_globalAlpha() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ compare(ctx.globalAlpha, 1.0);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 50,25, 2,253,0,255, 2));
+
+ ctx.reset();
+ ctx.globalAlpha = 0.5;
+ var a = ctx.globalAlpha; // might not be exactly 0.5, if it is rounded/quantised, so remember for future comparisons
+ ctx.globalAlpha = Infinity;
+ compare(ctx.globalAlpha, a);
+ ctx.globalAlpha = -Infinity;
+ compare(ctx.globalAlpha, a);
+ ctx.globalAlpha = NaN;
+ compare(ctx.globalAlpha, a);
+
+ ctx.globalAlpha = 0.5;
+ a = ctx.globalAlpha; // might not be exactly 0.5, if it is rounded/quantised, so remember for future comparisons
+ ctx.globalAlpha = 1.1;
+ compare(ctx.globalAlpha, a);
+ ctx.globalAlpha = -0.1;
+ compare(ctx.globalAlpha, a);
+ ctx.globalAlpha = 0;
+ compare(ctx.globalAlpha, 0);
+ ctx.globalAlpha = 1;
+ compare(ctx.globalAlpha, 1);
+
+ }
+
+ function test_operation() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'Source-over';
+ compare(ctx.globalCompositeOperation, 'xor');
+
+ ctx.reset();
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'clear';
+ compare(ctx.globalCompositeOperation, 'xor');
+
+ ctx.reset();
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'darker';
+ compare(ctx.globalCompositeOperation, 'xor');
+
+ ctx.reset();
+ compare(ctx.globalCompositeOperation, 'source-over');
+
+
+ ctx.reset();
+ var modes = ['source-atop', 'source-in', 'source-out', 'source-over',
+ 'destination-atop', 'destination-in', 'destination-out', 'destination-over',
+ 'lighter', 'copy', 'xor'];
+ for (var i = 0; i < modes.length; ++i)
+ {
+ ctx.globalCompositeOperation = modes[i];
+ compare(ctx.globalCompositeOperation, modes[i]);
+ }
+
+ ctx.reset();
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'highlight';
+ compare(ctx.globalCompositeOperation, 'xor');
+
+ ctx.reset();
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'source-over\\0';
+ compare(ctx.globalCompositeOperation, 'xor');
+
+ ctx.reset();
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'over';
+ compare(ctx.globalCompositeOperation, 'xor');
+
+
+ ctx.reset();
+ ctx.globalCompositeOperation = 'xor';
+ ctx.globalCompositeOperation = 'nonexistent';
+ compare(ctx.globalCompositeOperation, 'xor');
+ }
+
+ function test_solid() {
+ skip("FIXME");
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = Qt.rgba(0, 1, 1, 1.0);
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.fillStyle = Qt.rgba(1, 1, 0, 1.0);
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 50,25, 255,255,0, 5));
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,255,255, 5));
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,255,255, 5));
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5));
+
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,255,255, 5));
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'lighter';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 50,25, 255,255,255,255, 5));
+
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-atop';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 50,25, 255,255,0, 5));
+
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 50,25, 255,255,0, 5));
+
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ // verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5));
+
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 50,25, 255,255,0, 5));
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 255, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5));
+ }
+ function test_transparent() {
+
+ skip("FIXME");
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,0,255,191, 5));
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,0,255,191, 5));
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,95, 5));
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-out';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,31, 5));
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,145,109,223, 5));
+
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'lighter';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,127,191,255, 5));
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-atop';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,63,191,127, 5));
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,0,255,95, 5));
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,0,255,95, 5));
+
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-over';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,36,218,223, 5));
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'xor';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.fillRect(0, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,63,191,127, 5));
+
+ }
+
+ function test_uncovered() {
+ skip("FIXME");
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'copy';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5));
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-atop';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5));
+
+
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-in';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5));
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-in';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5));
+
+ ctx.reset();
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'source-out';
+ ctx.fillStyle = 'rgba(0, 0, 255, 0.75)';
+ ctx.translate(0, 25);
+ ctx.fillRect(0, 50, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5));
+
+ }
+
+ }
+} \ No newline at end of file
diff --git a/tests/auto/declarative/qsgcanvasitem/data/tst_drawimage.qml b/tests/auto/declarative/qsgcanvasitem/data/tst_drawimage.qml
new file mode 100644
index 0000000000..3752f528be
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/tst_drawimage.qml
@@ -0,0 +1,662 @@
+import QtQuick 2.0
+import QtTest 1.0
+import "testhelper.js" as Helper
+Canvas {
+ id:canvas; width:100;height:50; renderTarget: Canvas.Image
+ Component.onCompleted: {
+ canvas.loadImage('green.png');
+ canvas.loadImage('red.png');
+ canvas.loadImage('rgrg-256x256.png');
+ canvas.loadImage('ggrr-256x256.png');
+ canvas.loadImage('broken.png');
+ }
+
+ TestCase {
+ //TODO
+ name: "image"; when: windowShown
+ function test_3args() {
+ //make sure all images are loaded
+ wait(200);
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.drawImage('green.png', 0, 0);
+ ctx.drawImage('red.png', -100, 0);
+ ctx.drawImage('red.png', 100, 0);
+ ctx.drawImage('red.png', 0, -50);
+ ctx.drawImage('red.png', 0, 50);
+
+ verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
+
+ }
+ function test_5args() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage('green.png', 50, 0, 50, 50);
+ ctx.drawImage('red.png', 0, 0, 50, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+
+ verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
+
+ }
+ function test_9args() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage('green.png', 0, 0, 100, 50, 0, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
+
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage('green.png', 0, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage('red.png', 0, 0, 100, 50, -100, 0, 100, 50);
+ ctx.drawImage('red.png', 0, 0, 100, 50, 100, 0, 100, 50);
+ ctx.drawImage('red.png', 0, 0, 100, 50, 0, -50, 100, 50);
+ ctx.drawImage('red.png', 0, 0, 100, 50, 0, 50, 100, 50);
+ verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
+
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage('green.png', 1, 1, 1, 1, 0, 0, 100, 50);
+ ctx.drawImage('red.png', 0, 0, 100, 50, -50, 0, 50, 50);
+ ctx.drawImage('red.png', 0, 0, 100, 50, 100, 0, 50, 50);
+ ctx.drawImage('red.png', 0, 0, 100, 50, 0, -25, 100, 25);
+ ctx.drawImage('red.png', 0, 0, 100, 50, 0, 50, 100, 25);
+ verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage('rgrg-256x256.png', 140, 20, 100, 50, 0, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage('rgrg-256x256.png', 0, 0, 256, 256, 0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 51, 26);
+ ctx.fillRect(49, 24, 51, 26);
+ verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 20,20, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 80,20, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 20,30, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 80,30, 0,255,0,255,2));
+
+ }
+ function test_animated() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ //should animated image be supported at all?
+ }
+ function test_clip() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(-10, -10, 1, 1);
+ ctx.clip();
+ ctx.drawImage('red.png', 0, 0);
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2));
+
+
+ }
+ function test_self() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(50, 0, 50, 50);
+ ctx.drawImage(canvas, 50, 0);
+
+ verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 1, 100, 49);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 1);
+ ctx.drawImage(canvas, 0, 1);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 2);
+
+ verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
+ verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
+
+
+ }
+
+ function test_outsidesource() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.drawImage('green.png', 10.5, 10.5, 89.5, 39.5, 0, 0, 100, 50);
+ ctx.drawImage('green.png', 5.5, 5.5, -5.5, -5.5, 0, 0, 100, 50);
+ ctx.drawImage('green.png', 100, 50, -5, -5, 0, 0, 100, 50);
+ try { var err = false;
+ ctx.drawImage('red.png', -0.001, 0, 100, 50, 0, 0, 100, 50);
+ } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', -0.001, 0, 100, 50, 0, 0, 100, 50)"); }
+ try { var err = false;
+ ctx.drawImage('red.png', 0, -0.001, 100, 50, 0, 0, 100, 50);
+ } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, -0.001, 100, 50, 0, 0, 100, 50)"); }
+ try { var err = false;
+ ctx.drawImage('red.png', 0, 0, 100.001, 50, 0, 0, 100, 50);
+ } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, 100.001, 50, 0, 0, 100, 50)"); }
+ try { var err = false;
+ ctx.drawImage('red.png', 0, 0, 100, 50.001, 0, 0, 100, 50);
+ } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, 100, 50.001, 0, 0, 100, 50)"); }
+ try { var err = false;
+ ctx.drawImage('red.png', 50, 0, 50.001, 50, 0, 0, 100, 50);
+ } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 50, 0, 50.001, 50, 0, 0, 100, 50)"); }
+ try { var err = false;
+ ctx.drawImage('red.png', 0, 0, -5, 5, 0, 0, 100, 50);
+ } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, -5, 5, 0, 0, 100, 50)"); }
+ try { var err = false;
+ ctx.drawImage('red.png', 0, 0, 5, -5, 0, 0, 100, 50);
+ } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, 5, -5, 0, 0, 100, 50)"); }
+// try { var err = false;
+// ctx.drawImage('red.png', 110, 60, -20, -20, 0, 0, 100, 50);
+// } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 110, 60, -20, -20, 0, 0, 100, 50)"); }
+// verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2));
+
+ }
+
+ function test_null() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ try { var err = false;
+ ctx.drawImage(null, 0, 0);
+ } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(null, 0, 0)"); }
+
+ }
+
+ function test_composite() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalCompositeOperation = 'destination-over';
+ ctx.drawImage('red.png', 0, 0);
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2));
+
+ }
+ function test_path() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_transform() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.translate(100, 0);
+ ctx.drawImage('red.png', 0, 0);
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2));
+
+ }
+
+ function test_imageitem() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ //TODO
+ }
+
+ function test_imageData() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ //TODO
+ }
+
+ function test_wrongtype() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ try { var err = false;
+ ctx.drawImage(undefined, 0, 0);
+ } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(undefined, 0, 0)"); }
+ try { var err = false;
+ ctx.drawImage(0, 0, 0);
+ } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(0, 0, 0)"); }
+ try { var err = false;
+ ctx.drawImage("", 0, 0);
+ } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(\"\", 0, 0)"); }
+ }
+
+ function test_nonfinite() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var red = 'red.png';
+ ctx.drawImage(red, Infinity, 0);
+ ctx.drawImage(red, -Infinity, 0);
+ ctx.drawImage(red, NaN, 0);
+ ctx.drawImage(red, 0, Infinity);
+ ctx.drawImage(red, 0, -Infinity);
+ ctx.drawImage(red, 0, NaN);
+ ctx.drawImage(red, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, 50);
+ ctx.drawImage(red, -Infinity, 0, 100, 50);
+ ctx.drawImage(red, NaN, 0, 100, 50);
+ ctx.drawImage(red, 0, Infinity, 100, 50);
+ ctx.drawImage(red, 0, -Infinity, 100, 50);
+ ctx.drawImage(red, 0, NaN, 100, 50);
+ ctx.drawImage(red, 0, 0, Infinity, 50);
+ ctx.drawImage(red, 0, 0, -Infinity, 50);
+ ctx.drawImage(red, 0, 0, NaN, 50);
+ ctx.drawImage(red, 0, 0, 100, Infinity);
+ ctx.drawImage(red, 0, 0, 100, -Infinity);
+ ctx.drawImage(red, 0, 0, 100, NaN);
+ ctx.drawImage(red, Infinity, Infinity, 100, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(red, Infinity, 0, Infinity, 50);
+ ctx.drawImage(red, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, Infinity);
+ ctx.drawImage(red, 0, Infinity, Infinity, 50);
+ ctx.drawImage(red, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, 0, Infinity, 100, Infinity);
+ ctx.drawImage(red, 0, 0, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(red, -Infinity, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(red, NaN, 0, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(red, 0, -Infinity, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(red, 0, NaN, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(red, 0, 0, -Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(red, 0, 0, NaN, 50, 0, 0, 100, 50);
+ ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(red, 0, 0, 100, -Infinity, 0, 0, 100, 50);
+ ctx.drawImage(red, 0, 0, 100, NaN, 0, 0, 100, 50);
+ ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(red, 0, 0, 100, 50, -Infinity, 0, 100, 50);
+ ctx.drawImage(red, 0, 0, 100, 50, NaN, 0, 100, 50);
+ ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(red, 0, 0, 100, 50, 0, -Infinity, 100, 50);
+ ctx.drawImage(red, 0, 0, 100, 50, 0, NaN, 100, 50);
+ ctx.drawImage(red, 0, 0, 100, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(red, 0, 0, 100, 50, 0, 0, -Infinity, 50);
+ ctx.drawImage(red, 0, 0, 100, 50, 0, 0, NaN, 50);
+ ctx.drawImage(red, 0, 0, 100, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(red, 0, 0, 100, 50, 0, 0, 100, -Infinity);
+ ctx.drawImage(red, 0, 0, 100, 50, 0, 0, 100, NaN);
+ ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, 100, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, 100, 50);
+ ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, 100, 50);
+ ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, 100, 50);
+ ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, 100, 50);
+ ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, Infinity, 50);
+ ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, Infinity, Infinity);
+ ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, 100, Infinity);
+ ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, 100, 50);
+ ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, 100, 50);
+ ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, Infinity, 50);
+ ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, 100, Infinity);
+ ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, 100, 50);
+ ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, Infinity, 50);
+ ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, 100, Infinity);
+ ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, Infinity, 50);
+ ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, Infinity, Infinity);
+ ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, 100, Infinity);
+ ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, 100, 50);
+ ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, Infinity, 50);
+ ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, 100, Infinity);
+ ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, Infinity, 50);
+ ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, Infinity, Infinity);
+ ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, 100, Infinity);
+ ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, Infinity, 50);
+ ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, Infinity, Infinity);
+ ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, 100, Infinity);
+ ctx.drawImage(red, 0, 0, 100, 50, 0, 0, Infinity, Infinity);
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ }
+
+ function test_negative() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage('ggrr-256x256.png', 100, 78, 50, 50, 0, 50, 50, -50);
+ ctx.drawImage('ggrr-256x256.png', 100, 128, 50, -50, 100, 50, -50, -50);
+// verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 51,1, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 51,48, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255,2));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage('ggrr-256x256.png', 0, 178, 50, -100, 0, 0, 50, 100);
+ ctx.drawImage('ggrr-256x256.png', 0, 78, 50, 100, 50, 100, 50, -100);
+// verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 51,1, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 51,48, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255,2));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.drawImage('ggrr-256x256.png', 100, 78, -100, 50, 0, 0, 50, 50);
+ ctx.drawImage('ggrr-256x256.png', 100, 128, -100, -50, 50, 0, 50, 50);
+// verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 51,1, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 51,48, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255,2));
+// verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255,2));
+
+ }
+
+ function test_canvas() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ var canvas2 = Qt.createQmlObject("import QtQuick 2.0; Canvas{renderTarget:Canvas.Image}", canvas);
+ canvas2.width = 100;
+ canvas2.height = 50;
+ var ctx2 = canvas2.getContext('2d');
+ ctx2.fillStyle = '#0f0';
+ ctx2.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.drawImage(canvas2, 0, 0);
+
+ //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2));
+ //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2));
+ //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2));
+ //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2));
+
+ }
+
+ function test_broken() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ var img = 'broken.png';
+ verify(!img.complete);
+ ctx.drawImage(img, 0, 0);
+ }
+
+ function test_alpha() {
+ var ctx=canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.globalAlpha = 0;
+ ctx.drawImage('red.png', 0, 0);
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255, 2));
+
+ }
+ }
+}
diff --git a/tests/auto/declarative/qsgcanvasitem/data/tst_fillStyle.qml b/tests/auto/declarative/qsgcanvasitem/data/tst_fillStyle.qml
new file mode 100644
index 0000000000..8f5a78cec0
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/tst_fillStyle.qml
@@ -0,0 +1,113 @@
+import QtQuick 2.0
+import QtTest 1.0
+import "testhelper.js" as Helper
+
+Canvas {
+ id:canvas; width:1;height:1;renderTarget:Canvas.Image
+ TestCase {
+ name: "fillStyle"; when: windowShown
+ function test_default() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ verify(ctx.fillStyle, "#000000");
+ ctx.clearRect(0, 0, 1, 1);
+ compare(ctx.fillStyle, "#000000");
+ }
+ function test_get() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#fa0';
+ compare(ctx.fillStyle, '#ffaa00');
+ ctx.fillStyle = Qt.rgba(0,0,0,0);
+ compare(ctx.fillStyle, 'rgba(0, 0, 0, 0.0)');
+ }
+ function test_hex() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ compare(ctx.fillStyle, '#ff0000');
+ ctx.fillStyle = "#0f0";
+ compare(ctx.fillStyle, '#00ff00');
+ ctx.fillStyle = "#0fF";
+ compare(ctx.fillStyle, '#00ffff');
+ ctx.fillStyle = "#0aCCfb";
+ compare(ctx.fillStyle, '#0accfb');
+
+ }
+ function test_invalid() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#fa0';
+ compare(ctx.fillStyle, '#ffaa00');
+ ctx.fillStyle = "invalid";
+ compare(ctx.fillStyle, '#ffaa00');
+ ctx.fillStyle = "rgb (1, 2, 3)";
+ compare(ctx.fillStyle, '#ffaa00');
+ ctx.fillStyle = '#fa0';
+
+ ctx.fillStyle = "rgba(3, 1, 2)";
+ compare(ctx.fillStyle, '#ffaa00');
+ ctx.fillStyle = "rgb((3,4,1)";
+ compare(ctx.fillStyle, '#ffaa00');
+ ctx.fillStyle = "rgb(1, 3, 4, 0.5)";
+ compare(ctx.fillStyle, '#ffaa00');
+ ctx.fillStyle = "hsl(2, 3, 4, 0.8)";
+ compare(ctx.fillStyle, '#ffaa00');
+ ctx.fillStyle = "hsl(2, 3, 4";
+ compare(ctx.fillStyle, '#ffaa00');
+ }
+ function test_saverestore() {
+ var ctx = canvas.getContext('2d');
+ var old = ctx.fillStyle;
+ ctx.save();
+ ctx.fillStyle = "#ffaaff";
+ ctx.restore();
+ compare(ctx.fillStyle, old);
+
+ ctx.fillStyle = "#ffcc88";
+ old = ctx.fillStyle;
+ ctx.save();
+ compare(ctx.fillStyle, old);
+ ctx.restore();
+ }
+ function test_namedColor() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = "red";
+ ctx.fillRect(0,0,1,1);
+ verify(Helper.comparePixel(ctx,0,0,255,0,0,255));
+
+ ctx.fillStyle = "black";
+ ctx.fillRect(0,0,1,1);
+ verify(Helper.comparePixel(ctx,0,0,0,0,0,255));
+
+ ctx.fillStyle = "white";
+ ctx.fillRect(0,0,1,1);
+ verify(Helper.comparePixel(ctx,0,0,255,255,255,255));
+ }
+ function test_rgba() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = "rgb(-100, 300, 255)";
+ compare(ctx.fillStyle, "#00ffff");
+ ctx.fillStyle = "rgba(-100, 300, 255, 0.0)";
+ compare(ctx.fillStyle, "rgba(0, 255, 255, 0.0)");
+ ctx.fillStyle = "rgb(-10%, 110%, 50%)";
+ compare(ctx.fillStyle, "#00ff80");
+
+ ctx.clearRect(0, 0, 1, 1);
+ ctx.fillStyle = 'rgba(0%, 100%, 0%, 0.499)';
+ ctx.fillRect(0, 0, 1, 1);
+ verify(Helper.comparePixel(ctx, 0,0, 0,255,0,127));
+ }
+
+ function test_hsla() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = "hsla(120, 100%, 50%, 0.499)";
+ ctx.fillRect(0, 0, 1, 1);
+ verify(Helper.comparePixel(ctx,0,0,0,255,0,127));
+ }
+
+ }
+}
diff --git a/tests/auto/declarative/qsgcanvasitem/data/tst_fillrect.qml b/tests/auto/declarative/qsgcanvasitem/data/tst_fillrect.qml
new file mode 100644
index 0000000000..2061647268
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/tst_fillrect.qml
@@ -0,0 +1,23 @@
+import QtQuick 2.0
+import QtTest 1.0
+
+Canvas {
+ id:canvas; width:1;height:1; renderTarget:Canvas.Image
+ onPaint: {
+ context.fillStyle = "red";
+ context.fillRect(0, 0, canvas.width, canvas.height);
+ }
+ TestCase {
+ name: "FillRect"; when: windowShown
+ function test_fillRect() {
+ var ctx = canvas.getContext('2d');
+ var imageData = ctx.getImageData(0, 0, 1, 1);
+ var d = imageData.data;
+ verify(d.length == 4);
+ verify(d[0] == 255);
+ verify(d[1] == 0);
+ verify(d[2] == 0);
+ verify(d[3] == 255);
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/auto/declarative/qsgcanvasitem/data/tst_gradient.qml b/tests/auto/declarative/qsgcanvasitem/data/tst_gradient.qml
new file mode 100644
index 0000000000..d454c2efe1
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/tst_gradient.qml
@@ -0,0 +1,981 @@
+import QtQuick 2.0
+import QtTest 1.0
+import "testhelper.js" as Helper
+Canvas {
+ id:canvas; width:100;height:50; renderTarget: Canvas.Image
+ TestCase {
+ name: "gradient"; when: windowShown
+ function test_basic() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ var g = ctx.createLinearGradient(0, 0, 0, 50);
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2));
+
+ }
+
+ function test_interpolate() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#ff0';
+ ctx.fillRect(0, 0, 100, 50);
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, 'rgba(0,0,255, 0)');
+ g.addColorStop(1, 'rgba(0,0,255, 1)');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 25,25, 191,191,63,255,3));
+ //verify(Helper.comparePixel(ctx, 50,25, 127,127,127,255,3));
+ //verify(Helper.comparePixel(ctx, 75,25, 63,63,191,255,3));
+
+ ctx.reset();
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(1, '#00f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 25,25, 191,191,63,255,3));
+ //verify(Helper.comparePixel(ctx, 50,25, 127,127,127,255,3));
+ //verify(Helper.comparePixel(ctx, 75,25, 63,63,191,255,3));
+
+
+ ctx.reset();
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, 'rgba(255,255,0, 0)');
+ g.addColorStop(1, 'rgba(0,0,255, 1)');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 25,25, 191,191,63,63,3));
+ //verify(Helper.comparePixel(ctx, 50,25, 127,127,127,127,3));
+ //verify(Helper.comparePixel(ctx, 75,25, 63,63,191,191,3));
+
+ ctx.reset();
+ canvas.width = 200;
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(0.5, '#0ff');
+ g.addColorStop(1, '#f0f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 200, 50);
+ //verify(Helper.comparePixel(ctx, 50,25, 127,255,127,255,3));
+ //verify(Helper.comparePixel(ctx, 100,25, 0,255,255,255,3));
+ //verify(Helper.comparePixel(ctx, 150,25, 127,127,255,255,3));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(25, 0, 75, 0);
+ g.addColorStop(0.4, '#0f0');
+ g.addColorStop(0.6, '#0f0');
+
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 20,25, 0,255,0,255,2));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2));
+ //verify(Helper.comparePixel(ctx, 80,25, 0,255,0,255,2));
+
+
+ ctx.reset();
+ ctx.canvas.width = 200;
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(0.25, '#00f');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.25, '#ff0');
+ g.addColorStop(0.5, '#00f');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.75, '#00f');
+ g.addColorStop(0.75, '#f00');
+ g.addColorStop(0.75, '#ff0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.5, '#ff0');
+ g.addColorStop(1, '#00f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 200, 50);
+ //verify(Helper.comparePixel(ctx, 49,25, 0,0,255,255,16));
+ //verify(Helper.comparePixel(ctx, 51,25, 255,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 99,25, 0,0,255,255,16));
+ //verify(Helper.comparePixel(ctx, 101,25, 255,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 149,25, 0,0,255,255,16));
+ //verify(Helper.comparePixel(ctx, 151,25, 255,255,0,255,16));
+ ctx.canvas.width = 100;
+
+ ctx.reset();
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ var ps = [ 0, 1/10, 1/4, 1/3, 1/2, 3/4, 1 ];
+ for (var p = 0; p < ps.length; ++p)
+ {
+ g.addColorStop(ps[p], '#0f0');
+ for (var i = 0; i < 15; ++i)
+ g.addColorStop(ps[p], '#f00');
+ g.addColorStop(ps[p], '#0f0');
+ }
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 30,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 40,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 60,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 80,25, 0,255,0,255));
+
+
+ ctx.reset();
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+
+
+ ctx.reset();
+ var g = ctx.createLinearGradient(0, 0, 0, 50);
+ g.addColorStop(0, '#ff0');
+ g.addColorStop(1, '#00f');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 50,12, 191,191,63,255,10));
+ //verify(Helper.comparePixel(ctx, 50,25, 127,127,127,255,5));
+ //verify(Helper.comparePixel(ctx, 50,37, 63,63,191,255,10));
+
+
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 40,20, 0,255,0,255,2));
+
+
+
+ }
+ function test_radial() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var g = ctx.createRadialGradient(0, 100, 40, 100, 100, 50);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ g = ctx.createRadialGradient(210, 25, 100, 230, 25, 101);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ g = ctx.createRadialGradient(210, 25, 100, 230, 25, 100);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ g = ctx.createRadialGradient(311, 25, 10, 210, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(30+tol, 40);
+ ctx.lineTo(110, -20+tol);
+ ctx.lineTo(110, 100-tol);
+ ctx.fill();
+
+ g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.moveTo(30-tol, 40);
+ ctx.lineTo(110, -20-tol);
+ ctx.lineTo(110, 100+tol);
+ ctx.fill();
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ g = ctx.createRadialGradient(230, 25, 100, 100, 25, 101);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ g = ctx.createRadialGradient(50, 25, 20, 50, 25, 20);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ g = ctx.createRadialGradient(50, 25, 100, 50, 25, 200);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.993, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, -0.1, 0, 0, 1);
+ } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.createRadialGradient(0, 0, -0.1, 0, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, 1, 0, 0, -0.1);
+ } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, -0.1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, -0.1, 0, 0, -0.1);
+ } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.createRadialGradient(0, 0, -0.1, 0, 0, -0.1)"); }
+
+
+ ctx.reset();
+
+
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, 0, 1, 0, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(-Infinity, 0, 1, 0, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(-Infinity, 0, 1, 0, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(NaN, 0, 1, 0, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(NaN, 0, 1, 0, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, Infinity, 1, 0, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, -Infinity, 1, 0, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, -Infinity, 1, 0, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, NaN, 1, 0, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, NaN, 1, 0, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, Infinity, 0, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, -Infinity, 0, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, -Infinity, 0, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, NaN, 0, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, NaN, 0, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, 1, Infinity, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, 1, -Infinity, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, -Infinity, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, 1, NaN, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, NaN, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, 1, 0, Infinity, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, Infinity, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, 1, 0, -Infinity, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, -Infinity, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, 1, 0, NaN, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, NaN, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, 1, 0, 0, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, 1, 0, 0, -Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, -Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, 1, 0, 0, NaN);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, NaN)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(Infinity, 0, 1, 0, 0, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, 0, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, Infinity, 1, 0, 0, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, 0, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, Infinity, 0, 0, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, 0, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, 1);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, 1)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, 1, Infinity, 0, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, 0, Infinity)"); }
+ try { var err = false;
+ ctx.createRadialGradient(0, 0, 1, 0, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, Infinity, Infinity)"); }
+
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ g = ctx.createRadialGradient(200, 25, 10, 200, 25, 20);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#0f0');
+ ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50);
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50);
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.001, '#f00');
+ g.addColorStop(1, '#f00');ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ g = ctx.createRadialGradient(150, 25, 50, 200, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50);
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ g = ctx.createRadialGradient(-80, 25, 70, 0, 25, 150);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.01, '#0f0');
+ g.addColorStop(0.99, '#0f0');g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));//verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ g = ctx.createRadialGradient(120, -15, 25, 140, -30, 50);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50);
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+ g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.5, '#0f0');g.addColorStop(0.51, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(50, 25);ctx.scale(10, 10);
+ ctx.fillRect(-5, -2.5, 10, 5);
+ //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.translate(100, 0);
+ g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
+ g.addColorStop(0, '#0f0');g.addColorStop(0.5, '#0f0');
+ g.addColorStop(0.51, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;ctx.translate(-50, 25);
+ ctx.scale(10, 10);
+ ctx.fillRect(-5, -2.5, 10, 5);
+ //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
+
+
+ ctx.reset();
+ g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2);
+ g.addColorStop(0, '#0f0');
+ g.addColorStop(0.5, '#0f0');g.addColorStop(0.51, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);ctx.translate(50, 25);
+ ctx.scale(10, 10);
+ ctx.fillRect(-5, -2.5, 10, 5);
+ //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
+
+
+ }
+ function test_linear() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ try { var err = false;
+ ctx.createLinearGradient(Infinity, 0, 1, 0);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, 1, 0)"); }
+ try { var err = false;
+ ctx.createLinearGradient(-Infinity, 0, 1, 0);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(-Infinity, 0, 1, 0)"); }
+ try { var err = false;
+ ctx.createLinearGradient(NaN, 0, 1, 0);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(NaN, 0, 1, 0)"); }
+ try { var err = false;
+ ctx.createLinearGradient(0, Infinity, 1, 0);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, 1, 0)"); }
+ try { var err = false;
+ ctx.createLinearGradient(0, -Infinity, 1, 0);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, -Infinity, 1, 0)"); }
+ try { var err = false;
+ ctx.createLinearGradient(0, NaN, 1, 0);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, NaN, 1, 0)"); }
+ try { var err = false;
+ ctx.createLinearGradient(0, 0, Infinity, 0);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, Infinity, 0)"); }
+ try { var err = false;
+ ctx.createLinearGradient(0, 0, -Infinity, 0);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, -Infinity, 0)"); }
+ try { var err = false;
+ ctx.createLinearGradient(0, 0, NaN, 0);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, NaN, 0)"); }
+ try { var err = false;
+ ctx.createLinearGradient(0, 0, 1, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, 1, Infinity)"); }
+ try { var err = false;
+ ctx.createLinearGradient(0, 0, 1, -Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, 1, -Infinity)"); }
+ try { var err = false;
+ ctx.createLinearGradient(0, 0, 1, NaN);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, 1, NaN)"); }
+ try { var err = false;
+ ctx.createLinearGradient(Infinity, Infinity, 1, 0);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, 1, 0)"); }
+ try { var err = false;
+ ctx.createLinearGradient(Infinity, Infinity, Infinity, 0);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, Infinity, 0)"); }
+ try { var err = false;
+ ctx.createLinearGradient(Infinity, Infinity, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, Infinity, Infinity)"); }
+ try { var err = false;
+ ctx.createLinearGradient(Infinity, Infinity, 1, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, 1, Infinity)"); }
+ try { var err = false;
+ ctx.createLinearGradient(Infinity, 0, Infinity, 0);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, Infinity, 0)"); }
+ try { var err = false;
+ ctx.createLinearGradient(Infinity, 0, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, Infinity, Infinity)"); }
+ try { var err = false;
+ ctx.createLinearGradient(Infinity, 0, 1, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, 1, Infinity)"); }
+ try { var err = false;
+ ctx.createLinearGradient(0, Infinity, Infinity, 0);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, Infinity, 0)"); }
+ try { var err = false;
+ ctx.createLinearGradient(0, Infinity, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, Infinity, Infinity)"); }
+ try { var err = false;
+ ctx.createLinearGradient(0, Infinity, 1, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, 1, Infinity)"); }
+ try { var err = false;
+ ctx.createLinearGradient(0, 0, Infinity, Infinity);
+ } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, Infinity, Infinity)"); }
+
+ ctx.reset();
+ var g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.75, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(-50, 0);
+ ctx.fillRect(50, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.translate(100, 0);
+ g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.75, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.translate(-150, 0);
+ ctx.fillRect(50, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
+
+
+ ctx.reset();
+ g = ctx.createLinearGradient(0, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(0.25, '#0f0');
+ g.addColorStop(0.75, '#0f0');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.translate(-50, 0);
+ ctx.fillRect(50, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
+
+ }
+ function test_object() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ var g1 = ctx.createLinearGradient(0, 0, 100, 0);
+ var g2 = ctx.createLinearGradient(0, 0, 100, 0);
+ ctx.fillStyle = g1;
+
+
+ ctx.reset();
+ var g = ctx.createLinearGradient(0, 0, 100, 0);
+ try { var err = false;
+ g.addColorStop(0, "");
+ } catch (e) { if (e.code != DOMException.SYNTAX_ERR) fail("Failed assertion: expected exception of type SYNTAX_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type SYNTAX_ERR: g.addColorStop(0, \"\")"); }
+ try { var err = false;
+ g.addColorStop(0, 'undefined');
+ } catch (e) { if (e.code != DOMException.SYNTAX_ERR) fail("Failed assertion: expected exception of type SYNTAX_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type SYNTAX_ERR: g.addColorStop(0, 'undefined')"); }
+
+
+ ctx.reset();
+ g = ctx.createLinearGradient(0, 0, 100, 0);
+ try { var err = false;
+ g.addColorStop(-1, '#000');
+ } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(-1, '#000')"); }
+ try { var err = false;
+ g.addColorStop(2, '#000');
+ } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(2, '#000')"); }
+ try { var err = false;
+ g.addColorStop(Infinity, '#000');
+ } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(Infinity, '#000')"); }
+ try { var err = false;
+ g.addColorStop(-Infinity, '#000');
+ } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(-Infinity, '#000')"); }
+ try { var err = false;
+ g.addColorStop(NaN, '#000');
+ } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(NaN, '#000')"); }
+
+
+ ctx.reset();
+ g = ctx.createLinearGradient(-100, 0, 200, 0);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ g.addColorStop(0.1, '#0f0');
+ g.addColorStop(0.9, '#0f0');
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ g = ctx.createRadialGradient(120, 25, 10, 211, 25, 100);
+ g.addColorStop(0, '#f00');
+ g.addColorStop(1, '#f00');
+ ctx.fillStyle = g;
+ ctx.fillRect(0, 0, 100, 50);
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+
+ }
+
+ function test_conical() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ var g = ctx.createConicalGradient(10, 10, 50);
+ //TODO
+ }
+ }
+}
diff --git a/tests/auto/declarative/qsgcanvasitem/data/tst_line.qml b/tests/auto/declarative/qsgcanvasitem/data/tst_line.qml
new file mode 100644
index 0000000000..baf9987ce3
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/tst_line.qml
@@ -0,0 +1,831 @@
+import QtQuick 2.0
+import QtTest 1.0
+import"testhelper.js" as Helper
+Canvas {
+ id:canvas; width:100;height:50;renderTarget: Canvas.Image
+ TestCase {
+ name: "line"; when: windowShown
+ function test_default() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ compare(ctx.lineWidth, 1);
+ compare(ctx.lineCap, 'butt');
+ compare(ctx.lineJoin, 'miter');
+ compare(ctx.miterLimit, 10);
+ }
+
+ function test_cross() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'bevel';
+
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(110, 50);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(100, 60);
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+
+ }
+
+ function test_join() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillRect(10, 10, 20, 20);
+ ctx.fillRect(20, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(30, 20);
+ ctx.lineTo(40-tol, 20);
+ ctx.lineTo(30, 10+tol);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(30, 20);
+ ctx.lineTo(30, 40);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(60, 20);
+ ctx.lineTo(80, 20);
+ ctx.lineTo(80, 40);
+ ctx.stroke();
+
+ ctx.fillRect(60, 10, 20, 20);
+ ctx.fillRect(70, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(80, 20);
+ ctx.lineTo(90+tol, 20);
+ ctx.lineTo(80, 10-tol);
+ ctx.fill();
+
+ verify(Helper.comparePixel(ctx, 34,16, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 34,15, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 35,15, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 36,15, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 36,14, 0,255,0,255));
+
+ verify(Helper.comparePixel(ctx, 84,16, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 84,15, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 85,15, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 86,15, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 86,14, 0,255,0,255));
+
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'miter';
+ ctx.lineWidth = 200;
+
+ ctx.beginPath();
+ ctx.moveTo(100, 50);
+ ctx.lineTo(100, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 50);
+ ctx.closePath();
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+
+
+ ctx.reset();
+ ctx.lineJoin = 'bevel'
+ compare(ctx.lineJoin, 'bevel');
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'invalid';
+ compare(ctx.lineJoin, 'bevel');
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'ROUND';
+ compare(ctx.lineJoin, 'bevel');
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'round\\0';
+ compare(ctx.lineJoin, 'bevel');
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'round ';
+ compare(ctx.lineJoin, 'bevel');
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = "";
+ compare(ctx.lineJoin, 'bevel');
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineJoin = 'butt';
+ compare(ctx.lineJoin, 'bevel');
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'miter';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillRect(10, 10, 30, 20);
+ ctx.fillRect(20, 10, 20, 30);
+
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(30, 20);
+ ctx.lineTo(30, 40);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(60, 20);
+ ctx.lineTo(80, 20);
+ ctx.lineTo(80, 40);
+ ctx.stroke();
+
+ ctx.fillRect(60, 10, 30, 20);
+ ctx.fillRect(70, 10, 20, 30);
+
+ verify(Helper.comparePixel(ctx, 38,12, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 39,11, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 40,10, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 41,9, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 42,8, 0,255,0,255));
+
+ verify(Helper.comparePixel(ctx, 88,12, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 89,11, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 90,10, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 91,9, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 92,8, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'miter';
+ ctx.lineWidth = 200;
+
+ ctx.beginPath();
+ ctx.moveTo(100, 50);
+ ctx.lineTo(100, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 50);
+ ctx.lineTo(100, 50);
+ ctx.stroke();
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 300;
+ ctx.lineJoin = 'round';
+ ctx.beginPath();
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(0, 25);
+ ctx.lineTo(-100, 25);
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.lineJoin = 'round';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.fillRect(10, 10, 20, 20);
+ ctx.fillRect(20, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(30, 20);
+ ctx.arc(30, 20, 10-tol, 0, 2*Math.PI, true);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(10, 20);
+ ctx.lineTo(30, 20);
+ ctx.lineTo(30, 40);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(60, 20);
+ ctx.lineTo(80, 20);
+ ctx.lineTo(80, 40);
+ ctx.stroke();
+
+ ctx.fillRect(60, 10, 20, 20);
+ ctx.fillRect(70, 20, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(80, 20);
+ ctx.arc(80, 20, 10+tol, 0, 2*Math.PI, true);
+ ctx.fill();
+
+ verify(Helper.comparePixel(ctx, 36,14, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 36,13, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 37,13, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 38,13, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 38,12, 0,255,0,255));
+
+ verify(Helper.comparePixel(ctx, 86,14, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 86,13, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 87,13, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 88,13, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 88,12, 0,255,0,255));
+
+ ctx.reset();
+ ctx.lineJoin = 'bevel'
+ compare(ctx.lineJoin, 'bevel');
+
+ ctx.lineJoin = 'round';
+ compare(ctx.lineJoin, 'round');
+
+ ctx.lineJoin = 'miter';
+ compare(ctx.lineJoin, 'miter');
+
+ }
+ function test_miter() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.miterLimit = 2.614;
+ ctx.beginPath();
+ ctx.moveTo(100, 1000);
+ ctx.lineTo(100, 100);
+ ctx.lineTo(1000, 1000);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 2.613;
+ ctx.beginPath();
+ ctx.moveTo(100, 1000);
+ ctx.lineTo(100, 100);
+ ctx.lineTo(1000, 1000);
+ ctx.stroke();
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.414;
+ ctx.beginPath();
+ ctx.moveTo(200, 1000);
+ ctx.lineTo(200, 200);
+ ctx.lineTo(1000, 201); // slightly non-right-angle to avoid being a special case
+ ctx.stroke();
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.miterLimit = 1.5;
+ compare(ctx.miterLimit, 1.5);
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = 0;
+ compare(ctx.miterLimit, 1.5);
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = -1;
+ compare(ctx.miterLimit, 1.5);
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = Infinity;
+ compare(ctx.miterLimit, 1.5);
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = -Infinity;
+ compare(ctx.miterLimit, 1.5);
+
+ ctx.miterLimit = 1.5;
+ ctx.miterLimit = NaN;
+ compare(ctx.miterLimit, 1.5);
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.414;
+ ctx.beginPath();
+ ctx.strokeRect(100, 25, 200, 0);
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 1600;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.miterLimit = 1.083;
+ ctx.beginPath();
+ ctx.moveTo(800, 10000);
+ ctx.lineTo(800, 300);
+ ctx.lineTo(10000, -8900);
+ ctx.stroke();
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.082;
+ ctx.beginPath();
+ ctx.moveTo(800, 10000);
+ ctx.lineTo(800, 300);
+ ctx.lineTo(10000, -8900);
+ ctx.stroke();
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#f00';
+ ctx.miterLimit = 1.414;
+ ctx.beginPath();
+ ctx.moveTo(200, 1000);
+ ctx.lineTo(200, 200);
+ ctx.lineTo(1000, 200);
+ ctx.stroke();
+
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.miterLimit = 1.5;
+ compare(ctx.miterLimit, 1.5);
+
+ ctx.miterLimit = "1e1";
+ compare(ctx.miterLimit, 10);
+
+ ctx.miterLimit = 1/1024;
+ compare(ctx.miterLimit, 1/1024);
+
+ ctx.miterLimit = 1000;
+ compare(ctx.miterLimit, 1000);
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+
+ ctx.strokeStyle = '#0f0';
+ ctx.miterLimit = 1.416;
+ ctx.beginPath();
+ ctx.moveTo(200, 1000);
+ ctx.lineTo(200, 200);
+ ctx.lineTo(1000, 201);
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+
+
+ }
+ function test_width() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 20;
+ // Draw a green line over a red box, to check the line is not too small
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 15, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+ // Draw a green box over a red line, to check the line is not too large
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+ ctx.fillRect(65, 15, 20, 20);
+
+ verify(Helper.comparePixel(ctx, 14,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 15,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 16,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 34,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 35,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 36,25, 0,255,0,255));
+
+ verify(Helper.comparePixel(ctx, 64,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 65,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 66,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 84,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 85,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 86,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.lineWidth = 1.5;
+ compare(ctx.lineWidth, 1.5);
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = 0;
+ compare(ctx.lineWidth, 1.5);
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = -1;
+ compare(ctx.lineWidth, 1.5);
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = Infinity;
+ compare(ctx.lineWidth, 1.5);
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = -Infinity;
+ compare(ctx.lineWidth, 1.5);
+
+ ctx.lineWidth = 1.5;
+ ctx.lineWidth = NaN;
+ compare(ctx.lineWidth, 1.5);
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(50, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.moveTo(0, 0.5);
+ ctx.lineTo(2, 0.5);
+ ctx.stroke();
+
+ //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,5, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,45, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 4;
+ // Draw a green line over a red box, to check the line is not too small
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 15, 20, 20);
+ ctx.save();
+ ctx.scale(5, 1);
+ ctx.beginPath();
+ ctx.moveTo(5, 15);
+ ctx.lineTo(5, 35);
+ ctx.stroke();
+ ctx.restore();
+
+ // Draw a green box over a red line, to check the line is not too large
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.save();
+ ctx.scale(-5, 1);
+ ctx.beginPath();
+ ctx.moveTo(-15, 15);
+ ctx.lineTo(-15, 35);
+ ctx.stroke();
+ ctx.restore();
+ ctx.fillRect(65, 15, 20, 20);
+
+ verify(Helper.comparePixel(ctx, 14,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 15,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 16,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 34,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 35,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 36,25, 0,255,0,255));
+
+ //verify(Helper.comparePixel(ctx, 64,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 65,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 66,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 84,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 85,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 86,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.lineWidth = 1.5;
+ compare(ctx.lineWidth, 1.5);
+
+ ctx.lineWidth = "1e1";
+ compare(ctx.lineWidth, 10);
+
+ ctx.lineWidth = 1/1024;
+ compare(ctx.lineWidth, 1/1024);
+
+ ctx.lineWidth = 1000;
+ compare(ctx.lineWidth, 1000);
+
+ }
+ function test_cap() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineCap = 'butt';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 15, 20, 20);
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+ ctx.fillRect(65, 15, 20, 20);
+
+ verify(Helper.comparePixel(ctx, 25,14, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 25,15, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 25,16, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 25,34, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 25,35, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 25,36, 0,255,0,255));
+
+ verify(Helper.comparePixel(ctx, 75,14, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,15, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,16, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,34, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,35, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,36, 0,255,0,255));
+
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineCap = 'square';
+ ctx.lineWidth = 400;
+
+ ctx.beginPath();
+ ctx.moveTo(200, 200);
+ ctx.lineTo(200, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 200);
+ ctx.closePath();
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ ctx.reset();
+
+ ctx.lineCap = 'butt'
+ compare(ctx.lineCap, 'butt');
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'invalid';
+ compare(ctx.lineCap, 'butt');
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'ROUND';
+ compare(ctx.lineCap, 'butt');
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'round\\0';
+ compare(ctx.lineCap, 'butt');
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'round ';
+ compare(ctx.lineCap, 'butt');
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = "";
+ compare(ctx.lineCap, 'butt');
+
+ ctx.lineCap = 'butt';
+ ctx.lineCap = 'bevel';
+ compare(ctx.lineCap, 'butt');
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineJoin = 'bevel';
+ ctx.lineCap = 'square';
+ ctx.lineWidth = 400;
+
+ ctx.beginPath();
+ ctx.moveTo(200, 200);
+ ctx.lineTo(200, 1000);
+ ctx.lineTo(1000, 1000);
+ ctx.lineTo(1000, 200);
+ ctx.lineTo(200, 200);
+ ctx.stroke();
+
+ //FIXME:!!!
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ var tol = 1; // tolerance to avoid antialiasing artifacts
+
+ ctx.lineCap = 'round';
+ ctx.lineWidth = 20;
+
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+
+ ctx.beginPath();
+ ctx.moveTo(35-tol, 15);
+ ctx.arc(25, 15, 10-tol, 0, Math.PI, true);
+ ctx.arc(25, 35, 10-tol, Math.PI, 0, true);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(85+tol, 15);
+ ctx.arc(75, 15, 10+tol, 0, Math.PI, true);
+ ctx.arc(75, 35, 10+tol, Math.PI, 0, true);
+ ctx.fill();
+
+ verify(Helper.comparePixel(ctx, 17,6, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 25,6, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 32,6, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 17,43, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 25,43, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 32,43, 0,255,0,255));
+
+ verify(Helper.comparePixel(ctx, 67,6, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,6, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 82,6, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 67,43, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,43, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 82,43, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineCap = 'square';
+ ctx.lineWidth = 20;
+
+ ctx.fillStyle = '#f00';
+ ctx.strokeStyle = '#0f0';
+ ctx.fillRect(15, 5, 20, 40);
+ ctx.beginPath();
+ ctx.moveTo(25, 15);
+ ctx.lineTo(25, 35);
+ ctx.stroke();
+
+ ctx.fillStyle = '#0f0';
+ ctx.strokeStyle = '#f00';
+ ctx.beginPath();
+ ctx.moveTo(75, 15);
+ ctx.lineTo(75, 35);
+ ctx.stroke();
+ ctx.fillRect(65, 5, 20, 40);
+
+ verify(Helper.comparePixel(ctx, 25,4, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 25,5, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 25,6, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 25,44, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 25,45, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 25,46, 0,255,0,255));
+
+ verify(Helper.comparePixel(ctx, 75,4, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,5, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,6, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,44, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,45, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,46, 0,255,0,255));
+
+ ctx.reset();
+ ctx.lineCap = 'butt'
+ compare(ctx.lineCap, 'butt');
+
+ ctx.lineCap = 'round';
+ compare(ctx.lineCap, 'round');
+
+ ctx.lineCap = 'square';
+ compare(ctx.lineCap, 'square');
+
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/auto/declarative/qsgcanvasitem/data/tst_path.qml b/tests/auto/declarative/qsgcanvasitem/data/tst_path.qml
new file mode 100644
index 0000000000..b04ccf5458
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/tst_path.qml
@@ -0,0 +1,1443 @@
+import QtQuick 2.0
+import QtTest 1.0
+import "testhelper.js" as Helper
+
+Canvas {
+ id:canvas; width:100;height:50; renderTarget: Canvas.Image
+ TestCase {
+ name: "path"; when: windowShown
+
+ function test_basic() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.closePath();
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.rect(0, 0, 100, 50);
+ ctx.restore();
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+
+ canvas.width = 100;
+ ctx.rect(0, 0, 100, 50);
+ canvas.width = 100;
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ //verify(Helper.comparePixel(ctx, 20,20, 0,0,0,0));
+ }
+ function test_beginPath() {
+ var ctx = canvas.getContext('2d');
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ }
+ function test_closePath() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.closePath();
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-100, -100);
+ ctx.lineTo(200, -100);
+ ctx.lineTo(200, 25);
+ ctx.closePath();
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-100, -1000);
+ ctx.closePath();
+ ctx.lineTo(1000, 25);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ }
+
+ function test_isPointInPath() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.arc(50, 25, 10, 0, Math.PI, false);
+ verify(!ctx.isPointInPath(50, 10));
+ verify(!ctx.isPointInPath(50, 20));
+ //verify(!ctx.isPointInPath(50, 30));
+ verify(!ctx.isPointInPath(50, 40));
+ verify(!ctx.isPointInPath(30, 20));
+ verify(!ctx.isPointInPath(70, 20));
+ verify(!ctx.isPointInPath(30, 30));
+ verify(!ctx.isPointInPath(70, 30));
+
+ ctx.reset();
+ ctx.rect(0, 0, 20, 20);
+ verify(ctx.isPointInPath(10, 10));
+ verify(!ctx.isPointInPath(30, 10));
+
+ ctx.reset();
+ ctx.rect(20, 0, 20, 20);
+ //verify(ctx.isPointInPath(10, 10));
+ verify(ctx.isPointInPath(30, 10));
+
+ ctx.reset();
+ ctx.bezierCurveTo(50, -50, 50, 100, 75, 25);
+ verify(!ctx.isPointInPath(25, 20));
+ verify(!ctx.isPointInPath(25, 30));
+ //verify(ctx.isPointInPath(30, 20));
+ verify(!ctx.isPointInPath(30, 30));
+ //verify(!ctx.isPointInPath(40, 2));
+ //verify(ctx.isPointInPath(40, 20));
+ verify(!ctx.isPointInPath(40, 30));
+ verify(!ctx.isPointInPath(40, 47));
+ //verify(ctx.isPointInPath(45, 20));
+ //verify(!ctx.isPointInPath(45, 30));
+ //verify(!ctx.isPointInPath(55, 20));
+ //verify(ctx.isPointInPath(55, 30));
+ verify(!ctx.isPointInPath(60, 2));
+ //verify(!ctx.isPointInPath(60, 20));
+ verify(ctx.isPointInPath(60, 30));
+ verify(!ctx.isPointInPath(60, 47));
+ verify(!ctx.isPointInPath(70, 20));
+ verify(ctx.isPointInPath(70, 30));
+ verify(!ctx.isPointInPath(75, 20));
+ verify(!ctx.isPointInPath(75, 30));
+
+ ctx.reset();
+ ctx.arc(50, 25, 10, 0, 7, false);
+ verify(!ctx.isPointInPath(50, 10));
+ //verify(ctx.isPointInPath(50, 20));
+ //verify(ctx.isPointInPath(50, 30));
+ verify(!ctx.isPointInPath(50, 40));
+ verify(!ctx.isPointInPath(30, 20));
+ verify(!ctx.isPointInPath(70, 20));
+ verify(!ctx.isPointInPath(30, 30));
+ //verify(!ctx.isPointInPath(70, 30));
+
+ ctx.reset();
+ ctx.rect(0, 0, 20, 20);
+ verify(ctx.isPointInPath(0, 0));
+ verify(ctx.isPointInPath(10, 0));
+ //verify(ctx.isPointInPath(20, 0));
+ //verify(ctx.isPointInPath(20, 10));
+ //verify(ctx.isPointInPath(20, 20));
+ //verify(ctx.isPointInPath(10, 20));
+ //verify(ctx.isPointInPath(0, 20));
+ verify(ctx.isPointInPath(0, 10));
+ verify(!ctx.isPointInPath(10, -0.01));
+ verify(!ctx.isPointInPath(10, 20.01));
+ verify(!ctx.isPointInPath(-0.01, 10));
+ //verify(!ctx.isPointInPath(20.01, 10));
+
+ ctx.reset();
+ verify(!ctx.isPointInPath(0, 0));
+
+
+ ctx.reset();
+ ctx.rect(-100, -50, 200, 100);
+ //verify(ctx.isPointInPath(Infinity, 0));
+ //verify(ctx.isPointInPath(-Infinity, 0));
+ //verify(ctx.isPointInPath(NaN, 0));
+ //verify(ctx.isPointInPath(0, Infinity));
+ //verify(ctx.isPointInPath(0, -Infinity));
+ //verify(ctx.isPointInPath(0, NaN));
+ //verify(ctx.isPointInPath(NaN, NaN));
+
+ ctx.reset();
+ ctx.rect(0, -100, 20, 20);
+ ctx.rect(20, -10, 20, 20);
+ verify(!ctx.isPointInPath(10, -110));
+ verify(ctx.isPointInPath(10, -90));
+ verify(!ctx.isPointInPath(10, -70));
+ //verify(!ctx.isPointInPath(30, -20));
+ //verify(ctx.isPointInPath(30, 0));
+ //verify(!ctx.isPointInPath(30, 20));
+
+ ctx.reset();
+ ctx.rect(0, 0, 20, 20);
+ ctx.beginPath();
+ ctx.rect(20, 0, 20, 20);
+ ctx.closePath();
+ ctx.rect(40, 0, 20, 20);
+ verify(!ctx.isPointInPath(10, 10));
+ verify(ctx.isPointInPath(30, 10));
+ verify(ctx.isPointInPath(50, 10));
+
+ ctx.reset();
+ ctx.translate(50, 0);
+ ctx.rect(0, 0, 20, 20);
+ verify(!ctx.isPointInPath(-40, 10));
+ verify(!ctx.isPointInPath(10, 10));
+ //verify(!ctx.isPointInPath(49, 10));
+ verify(ctx.isPointInPath(51, 10));
+ verify(ctx.isPointInPath(69, 10));
+ verify(!ctx.isPointInPath(71, 10));
+
+ ctx.reset();
+ ctx.rect(50, 0, 20, 20);
+ ctx.translate(50, 0);
+ verify(!ctx.isPointInPath(-40, 10));
+ verify(!ctx.isPointInPath(10, 10));
+ //verify(!ctx.isPointInPath(49, 10));
+ verify(ctx.isPointInPath(51, 10));
+ verify(ctx.isPointInPath(69, 10));
+ verify(!ctx.isPointInPath(71, 10));
+
+ ctx.reset();
+ ctx.scale(-1, 1);
+ ctx.rect(-70, 0, 20, 20);
+ verify(!ctx.isPointInPath(-40, 10));
+ verify(!ctx.isPointInPath(10, 10));
+ //verify(!ctx.isPointInPath(49, 10));
+ verify(ctx.isPointInPath(51, 10));
+ verify(ctx.isPointInPath(69, 10));
+ verify(!ctx.isPointInPath(71, 10));
+
+ ctx.reset();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(20, 0);
+ ctx.lineTo(20, 20);
+ ctx.lineTo(0, 20);
+ verify(ctx.isPointInPath(10, 10));
+ //verify(!ctx.isPointInPath(30, 10));
+
+ ctx.reset();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(50, 0);
+ ctx.lineTo(50, 50);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(10, 10);
+ ctx.lineTo(10, 40);
+ ctx.lineTo(40, 40);
+ ctx.lineTo(40, 10);
+ ctx.lineTo(10, 10);
+
+ verify(ctx.isPointInPath(5, 5));
+ verify(ctx.isPointInPath(25, 5));
+ verify(ctx.isPointInPath(45, 5));
+ verify(ctx.isPointInPath(5, 25));
+ verify(!ctx.isPointInPath(25, 25));
+ verify(ctx.isPointInPath(45, 25));
+ verify(ctx.isPointInPath(5, 45));
+ verify(ctx.isPointInPath(25, 45));
+ verify(ctx.isPointInPath(45, 45));
+ }
+
+
+ function test_fill() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fill();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+
+ ctx.reset();
+ ctx.fillStyle = '#00f';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ //verify(Helper.comparePixel(ctx, 90,10, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 10,40, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.rect(0, 0, 100, 50);
+ ctx.closePath();
+ ctx.rect(10, 10, 80, 30);
+ ctx.fill();
+
+ //verify(Helper.comparePixel(ctx, 50,25, 0,127,0,255, 1));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fill();
+
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.fill();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.fill();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(-20, -20);
+ ctx.lineTo(120, -20);
+ ctx.lineTo(120, 70);
+ ctx.lineTo(-20, 70);
+ ctx.lineTo(-20, -20);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.fill();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ }
+ function test_stroke() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(40, 25);
+ ctx.moveTo(60, 25);
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#000';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)';
+ ctx.lineWidth = 50;
+ ctx.moveTo(0, 20);
+ ctx.lineTo(100, 20);
+ ctx.moveTo(0, 30);
+ ctx.lineTo(100, 30);
+ ctx.stroke();
+
+ //verify(Helper.comparePixel(ctx, 50,25, 0,127,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arcTo(50, 25, 150, 25, 10);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.arc(50, 25, 10, 0, 0, false);
+ ctx.stroke();
+
+ // verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.lineTo(50, 25);
+ ctx.closePath();
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 400;
+ ctx.lineJoin = 'miter';
+ ctx.miterLimit = 1.4;
+
+ ctx.beginPath();
+ ctx.moveTo(-1000, 200, 0, 0);
+ ctx.lineTo(-100, 200);
+ ctx.lineTo(-100, 200);
+ ctx.lineTo(-100, 200);
+ ctx.lineTo(-100, 1000);
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.quadraticCurveTo(50, 25, 50, 25);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.bezierCurveTo(50, 25, 50, 25, 50, 25);
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.moveTo(50, 25);
+ ctx.lineTo(50, 25);
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'round';
+
+ ctx.beginPath();
+ ctx.rect(50, 25, 0, 0);
+ ctx.stroke();
+
+ ctx.strokeRect(50, 25, 0, 0);
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(25, 12.5, 50, 25);
+ ctx.save();
+ ctx.scale(50, 25);
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.beginPath();
+ ctx.rect(-25, -12.5, 150, 75);
+ ctx.save();
+ ctx.scale(50, 25);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(25, 12.5, 50, 25);
+ ctx.save();
+ ctx.rotate(Math.PI/2);
+ ctx.scale(25, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.beginPath();
+ ctx.rect(-25, -12.5, 150, 75);
+ ctx.save();
+ ctx.rotate(Math.PI/2);
+ ctx.scale(25, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.moveTo(49, -50);
+ ctx.lineTo(201, -50);
+ ctx.rotate(Math.PI/4);
+ ctx.scale(1, 283);
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.translate(-150, 0);
+ ctx.moveTo(49, -50);
+ ctx.lineTo(199, -50);
+ ctx.rotate(Math.PI/4);
+ ctx.scale(1, 142);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.translate(-150, 0);
+ ctx.moveTo(49, -50);
+ ctx.lineTo(199, -50);
+ ctx.rotate(Math.PI/4);
+ ctx.scale(1, 142);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+ ctx.restore();
+
+ //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-100, -100);
+ ctx.lineTo(200, -100);
+ ctx.lineTo(200, 25);
+ ctx.strokeStyle = '#f00';
+ ctx.stroke();
+
+ ctx.closePath();
+ ctx.strokeStyle = '#0f0';
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 40;
+ ctx.moveTo(0, 10);
+ ctx.lineTo(100, 10);
+ ctx.moveTo(100, 40);
+ ctx.lineTo(0, 40);
+ ctx.stroke();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ }
+ function test_clip() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.clip();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(-100, 0, 100, 50);
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.rect(0, 0, 50, 50);
+ ctx.clip();
+ ctx.beginPath();
+ ctx.rect(50, 0, 50, 50)
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#0f0';
+
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.clip();
+
+ ctx.lineTo(0, 0);
+ ctx.fill();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.lineTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.clip();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.beginPath();
+ ctx.moveTo(-10, -10);
+ ctx.lineTo(110, -10);
+ ctx.lineTo(110, 60);
+ ctx.lineTo(-10, 60);
+ ctx.lineTo(-10, -10);
+ ctx.clip();
+
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, 50);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(0, 0);
+ ctx.clip();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ }
+
+ function test_moveTo() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.rect(0, 0, 10, 50);
+ ctx.moveTo(100, 0);
+ ctx.lineTo(10, 0);
+ ctx.lineTo(10, 50);
+ ctx.lineTo(100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ verify(Helper.comparePixel(ctx, 90,25, 0,255,0,255));
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.moveTo(0, 25);
+ ctx.moveTo(100, 25);
+ ctx.moveTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.moveTo(100, 0);
+ ctx.moveTo(100, 50);
+ ctx.moveTo(0, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fill();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.moveTo(Infinity, 50);
+ ctx.moveTo(-Infinity, 50);
+ ctx.moveTo(NaN, 50);
+ ctx.moveTo(0, Infinity);
+ ctx.moveTo(0, -Infinity);
+ ctx.moveTo(0, NaN);
+ ctx.moveTo(Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ }
+ function test_lineTo() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.lineTo(100, 50);
+ ctx.stroke();
+ // verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.lineTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(-100, -100);
+ ctx.lineTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.lineTo(Infinity, 50);
+ ctx.lineTo(-Infinity, 50);
+ ctx.lineTo(NaN, 50);
+ ctx.lineTo(0, Infinity);
+ ctx.lineTo(0, -Infinity);
+ ctx.lineTo(0, NaN);
+ ctx.lineTo(Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255));
+
+ }
+ function test_bezierCurveTo() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.bezierCurveTo(100, 25, 100, 25, 100, 25);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.bezierCurveTo(100, 50, 200, 50, 200, 50);
+ ctx.stroke();
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 95,45, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.bezierCurveTo(0, 25, 100, 25, 100, 25);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 5,45, 0,255,0,255));
+
+ ctx.reset();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, 0, 50);
+ ctx.bezierCurveTo(-Infinity, 50, 0, 50, 0, 50);
+ ctx.bezierCurveTo(NaN, 50, 0, 50, 0, 50);
+ ctx.bezierCurveTo(0, Infinity, 0, 50, 0, 50);
+ ctx.bezierCurveTo(0, -Infinity, 0, 50, 0, 50);
+ ctx.bezierCurveTo(0, NaN, 0, 50, 0, 50);
+ ctx.bezierCurveTo(0, 50, Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(0, 50, -Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(0, 50, NaN, 50, 0, 50);
+ ctx.bezierCurveTo(0, 50, 0, Infinity, 0, 50);
+ ctx.bezierCurveTo(0, 50, 0, -Infinity, 0, 50);
+ ctx.bezierCurveTo(0, 50, 0, NaN, 0, 50);
+ ctx.bezierCurveTo(0, 50, 0, 50, Infinity, 50);
+ ctx.bezierCurveTo(0, 50, 0, 50, -Infinity, 50);
+ ctx.bezierCurveTo(0, 50, 0, 50, NaN, 50);
+ ctx.bezierCurveTo(0, 50, 0, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, 0, 50, 0, -Infinity);
+ ctx.bezierCurveTo(0, 50, 0, 50, 0, NaN);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, 50, 0, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, 0, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, 0, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, 50, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, Infinity, 0, 50, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, 50);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, 50);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, 50);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(Infinity, 50, 0, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, Infinity, Infinity, 50, 0, 50);
+ ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, 0, 50);
+ ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(0, Infinity, Infinity, 50, Infinity, 50);
+ ctx.bezierCurveTo(0, Infinity, Infinity, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(0, Infinity, Infinity, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, Infinity, 0, Infinity, 0, 50);
+ ctx.bezierCurveTo(0, Infinity, 0, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(0, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(0, Infinity, 0, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(0, Infinity, 0, 50, Infinity, 50);
+ ctx.bezierCurveTo(0, Infinity, 0, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(0, Infinity, 0, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, Infinity, Infinity, 0, 50);
+ ctx.bezierCurveTo(0, 50, Infinity, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(0, 50, Infinity, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(0, 50, Infinity, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, Infinity, 50, Infinity, 50);
+ ctx.bezierCurveTo(0, 50, Infinity, 50, Infinity, Infinity);
+ ctx.bezierCurveTo(0, 50, Infinity, 50, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, 0, Infinity, Infinity, 50);
+ ctx.bezierCurveTo(0, 50, 0, Infinity, Infinity, Infinity);
+ ctx.bezierCurveTo(0, 50, 0, Infinity, 0, Infinity);
+ ctx.bezierCurveTo(0, 50, 0, 50, Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(1000, 1000);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 0.055;
+ ctx.beginPath();
+ ctx.moveTo(-2, 3.1);
+ ctx.bezierCurveTo(-2, -1, 2.1, -1, 2.1, 3.1);
+ ctx.stroke();
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 55;
+ ctx.beginPath();
+ ctx.moveTo(-2000, 3100);
+ ctx.bezierCurveTo(-2000, -1000, 2100, -1000, 2100, 3100);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ }
+ function test_quadraticCurveTo() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.moveTo(0, 25);
+ ctx.quadraticCurveTo(100, 25, 100, 25);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.quadraticCurveTo(100, 50, 200, 50);
+ ctx.stroke();
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 95,45, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.beginPath();
+ ctx.quadraticCurveTo(0, 25, 100, 25);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 5,45, 0,255,0,255));
+
+ ctx.reset();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.quadraticCurveTo(Infinity, 50, 0, 50);
+ ctx.quadraticCurveTo(-Infinity, 50, 0, 50);
+ ctx.quadraticCurveTo(NaN, 50, 0, 50);
+ ctx.quadraticCurveTo(0, Infinity, 0, 50);
+ ctx.quadraticCurveTo(0, -Infinity, 0, 50);
+ ctx.quadraticCurveTo(0, NaN, 0, 50);
+ ctx.quadraticCurveTo(0, 50, Infinity, 50);
+ ctx.quadraticCurveTo(0, 50, -Infinity, 50);
+ ctx.quadraticCurveTo(0, 50, NaN, 50);
+ ctx.quadraticCurveTo(0, 50, 0, Infinity);
+ ctx.quadraticCurveTo(0, 50, 0, -Infinity);
+ ctx.quadraticCurveTo(0, 50, 0, NaN);
+ ctx.quadraticCurveTo(Infinity, Infinity, 0, 50);
+ ctx.quadraticCurveTo(Infinity, Infinity, Infinity, 50);
+ ctx.quadraticCurveTo(Infinity, Infinity, Infinity, Infinity);
+ ctx.quadraticCurveTo(Infinity, Infinity, 0, Infinity);
+ ctx.quadraticCurveTo(Infinity, 50, Infinity, 50);
+ ctx.quadraticCurveTo(Infinity, 50, Infinity, Infinity);
+ ctx.quadraticCurveTo(Infinity, 50, 0, Infinity);
+ ctx.quadraticCurveTo(0, Infinity, Infinity, 50);
+ ctx.quadraticCurveTo(0, Infinity, Infinity, Infinity);
+ ctx.quadraticCurveTo(0, Infinity, 0, Infinity);
+ ctx.quadraticCurveTo(0, 50, Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.scale(1000, 1000);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 0.055;
+ ctx.beginPath();
+ ctx.moveTo(-1, 1.05);
+ ctx.quadraticCurveTo(0, -1, 1.2, 1.05);
+ ctx.stroke();
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 55;
+ ctx.beginPath();
+ ctx.moveTo(-1000, 1050);
+ ctx.quadraticCurveTo(0, -1000, 1200, 1050);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+ }
+ function test_rect() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.rect(0, 0, 100, 50);
+ ctx.fill();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 200;
+ ctx.lineJoin = 'miter';
+ ctx.rect(100, 50, 100, 100);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.rect(200, 100, 400, 1000);
+ ctx.lineTo(-2000, -1000);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 450;
+ ctx.lineCap = 'round';
+ ctx.lineJoin = 'bevel';
+ ctx.rect(150, 150, 2000, 2000);
+ ctx.lineTo(160, 160);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#0f0';
+ ctx.rect(0, 0, 50, 25);
+ ctx.rect(100, 0, -50, 25);
+ ctx.rect(0, 50, 50, -25);
+ ctx.rect(100, 50, -50, -25);
+ ctx.fill();
+ verify(Helper.comparePixel(ctx, 25,12, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,12, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 25,37, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,37, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.moveTo(-100, 25);
+ ctx.lineTo(-50, 25);
+ ctx.rect(200, 25, 1, 1);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+
+ ctx.reset();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(100, 0);
+ ctx.rect(Infinity, 50, 1, 1);
+ ctx.rect(-Infinity, 50, 1, 1);
+ ctx.rect(NaN, 50, 1, 1);
+ ctx.rect(0, Infinity, 1, 1);
+ ctx.rect(0, -Infinity, 1, 1);
+ ctx.rect(0, NaN, 1, 1);
+ ctx.rect(0, 50, Infinity, 1);
+ ctx.rect(0, 50, -Infinity, 1);
+ ctx.rect(0, 50, NaN, 1);
+ ctx.rect(0, 50, 1, Infinity);
+ ctx.rect(0, 50, 1, -Infinity);
+ ctx.rect(0, 50, 1, NaN);
+ ctx.rect(Infinity, Infinity, 1, 1);
+ ctx.rect(Infinity, Infinity, Infinity, 1);
+ ctx.rect(Infinity, Infinity, Infinity, Infinity);
+ ctx.rect(Infinity, Infinity, 1, Infinity);
+ ctx.rect(Infinity, 50, Infinity, 1);
+ ctx.rect(Infinity, 50, Infinity, Infinity);
+ ctx.rect(Infinity, 50, 1, Infinity);
+ ctx.rect(0, Infinity, Infinity, 1);
+ ctx.rect(0, Infinity, Infinity, Infinity);
+ ctx.rect(0, Infinity, 1, Infinity);
+ ctx.rect(0, 50, Infinity, Infinity);
+ ctx.lineTo(100, 50);
+ ctx.lineTo(0, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ //verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255));
+
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 90;
+ ctx.beginPath();
+ ctx.rect(45, 20, 10, 10);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.beginPath();
+ ctx.fillStyle = '#f00';
+ ctx.rect(0, 0, 50, 50);
+ ctx.rect(100, 50, -50, -50);
+ ctx.rect(0, 25, 100, -25);
+ ctx.rect(100, 25, -100, 25);
+ ctx.fill();
+ verify(Helper.comparePixel(ctx, 25,12, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,12, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 25,37, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,37, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.rect(0, 50, 100, 0);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.rect(50, -100, 0, 250);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 100;
+ ctx.beginPath();
+ ctx.rect(50, 25, 0, 0);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#0f0';
+ ctx.lineWidth = 50;
+ ctx.rect(100, 25, 0, 0);
+ ctx.lineTo(0, 25);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.moveTo(0, 0);
+ ctx.rect(100, 25, 0, 0);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineJoin = 'miter';
+ ctx.miterLimit = 1.5;
+ ctx.lineWidth = 200;
+ ctx.beginPath();
+ ctx.rect(100, 25, 1000, 0);
+ ctx.stroke();
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ }
+
+ function test_clearRect() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.clearRect(0, 0, 16, 16);
+ ctx.fill();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ }
+ function test_fillRect() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 16, 16);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ }
+
+ function test_strokeRect() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.beginPath();
+ ctx.rect(0, 0, 100, 50);
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 5;
+ ctx.strokeRect(0, 0, 16, 16);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ }
+ function test_transform() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(-100, 0);
+ ctx.rect(100, 0, 100, 50);
+ ctx.translate(0, -100);
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.moveTo(0, 0);
+ ctx.translate(100, 0);
+ ctx.lineTo(0, 0);
+ ctx.translate(0, 50);
+ ctx.lineTo(0, 0);
+ ctx.translate(-100, 0);
+ ctx.lineTo(0, 0);
+ ctx.translate(1000, 1000);
+ ctx.rotate(Math.PI/2);
+ ctx.scale(0.1, 0.1);
+ ctx.fill();
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ ctx.reset();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.fillStyle = '#f00';
+ ctx.translate(-100, 0);
+ ctx.rect(0, 0, 100, 50);
+ ctx.fill();
+ ctx.translate(100, 0);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.strokeStyle = '#f00';
+ ctx.lineWidth = 50;
+ ctx.translate(0, -50);
+ ctx.moveTo(0, 25);
+ ctx.lineTo(100, 25);
+ ctx.stroke();
+ ctx.translate(0, 50);
+ ctx.stroke();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ }
+ }
+}
diff --git a/tests/auto/declarative/qsgcanvasitem/data/tst_pattern.qml b/tests/auto/declarative/qsgcanvasitem/data/tst_pattern.qml
new file mode 100644
index 0000000000..dd5b6628e8
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/tst_pattern.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.0
+import QtTest 1.0
+import "testhelper.js" as Helper
+Canvas {
+ id:canvas; width:100;height:50; renderTarget: Canvas.Image
+ TestCase {
+ //TODO
+ name: "pattern"; when: windowShown
+ function test_basic() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_animated() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_image() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_modified() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_paint() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_repeat() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ }
+}
diff --git a/tests/auto/declarative/qsgcanvasitem/data/tst_pixel.qml b/tests/auto/declarative/qsgcanvasitem/data/tst_pixel.qml
new file mode 100644
index 0000000000..1a3793d7a3
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/tst_pixel.qml
@@ -0,0 +1,30 @@
+import QtQuick 2.0
+import QtTest 1.0
+import "testhelper.js" as Helper
+Canvas {
+ id:canvas; width:100;height:50; renderTarget: Canvas.Image
+ TestCase {
+ //TODO
+ name: "pixel"; when: windowShown
+ function test_createImageData() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_getImageData() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_object() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_putImageData() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_filters() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ }
+}
diff --git a/tests/auto/declarative/qsgcanvasitem/data/tst_shadow.qml b/tests/auto/declarative/qsgcanvasitem/data/tst_shadow.qml
new file mode 100644
index 0000000000..4405ca6c0e
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/tst_shadow.qml
@@ -0,0 +1,59 @@
+import QtQuick 2.0
+import QtTest 1.0
+import "testhelper.js" as Helper
+Canvas {
+ id:canvas; width:100;height:50; renderTarget: Canvas.Image
+ TestCase {
+ //TODO
+
+ name: "shadow"; when: windowShown
+ function test_basic() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_blur() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+
+ function test_clip() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+
+ function test_composite() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+
+ function test_enable() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+
+ function test_gradient() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_image() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_offset() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_pattern() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_stroke() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_tranform() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ }
+}
diff --git a/tests/auto/declarative/qsgcanvasitem/data/tst_state.qml b/tests/auto/declarative/qsgcanvasitem/data/tst_state.qml
new file mode 100644
index 0000000000..f0040ce0a4
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/tst_state.qml
@@ -0,0 +1,389 @@
+import QtQuick 2.0
+import QtTest 1.0
+import "testhelper.js" as Helper
+Canvas {
+ id:canvas; width:100;height:50; renderTarget: Canvas.Image
+ TestCase {
+ name: "state"; when: windowShown
+ function test_bitmap() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.restore();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ }
+ function test_clip() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.rect(0, 0, 1, 1);
+ ctx.clip();
+ ctx.restore();
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ }
+ function test_fillStyle() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ // Test that restore() undoes any modifications
+ var old = ctx.fillStyle;
+ ctx.save();
+ ctx.fillStyle = "#ff0000";
+ ctx.restore();
+ compare(ctx.fillStyle, old);
+
+ // Also test that save() doesn't modify the values
+ ctx.fillStyle = "#ff0000";
+ old = ctx.fillStyle;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "#ff0000"
+ ctx.save();
+ compare(ctx.fillStyle, old);
+ ctx.restore();
+ }
+ function test_font() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ // Test that restore() undoes any modifications
+ var old = ctx.font;
+ ctx.save();
+ ctx.font = "25px serif";
+ ctx.restore();
+ compare(ctx.font, old);
+
+ // Also test that save() doesn't modify the values
+ ctx.font = "25px serif";
+ old = ctx.font;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "25px serif"
+ ctx.save();
+ compare(ctx.font, old);
+ ctx.restore();
+ }
+ function test_globalAlpha() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ // Test that restore() undoes any modifications
+ var old = ctx.globalAlpha;
+ ctx.save();
+ ctx.globalAlpha = 0.5;
+ ctx.restore();
+ compare(ctx.globalAlpha, old);
+
+ // Also test that save() doesn't modify the values
+ ctx.globalAlpha = 0.5;
+ old = ctx.globalAlpha;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 0.5
+ ctx.save();
+ compare(ctx.globalAlpha, old);
+ ctx.restore();
+ }
+ function test_globalCompositeOperation() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ // Test that restore() undoes any modifications
+ var old = ctx.globalCompositeOperation;
+ ctx.save();
+ ctx.globalCompositeOperation = "copy";
+ ctx.restore();
+ compare(ctx.globalCompositeOperation, old);
+
+ // Also test that save() doesn't modify the values
+ ctx.globalCompositeOperation = "copy";
+ old = ctx.globalCompositeOperation;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "copy"
+ ctx.save();
+ compare(ctx.globalCompositeOperation, old);
+ ctx.restore();
+ }
+ function test_lineCap() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ // Test that restore() undoes any modifications
+ var old = ctx.lineCap;
+ ctx.save();
+ ctx.lineCap = "round";
+ ctx.restore();
+ compare(ctx.lineCap, old);
+
+ // Also test that save() doesn't modify the values
+ ctx.lineCap = "round";
+ old = ctx.lineCap;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "round"
+ ctx.save();
+ compare(ctx.lineCap, old);
+ ctx.restore();
+ }
+ function test_lineJoin() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ // Test that restore() undoes any modifications
+ var old = ctx.lineJoin;
+ ctx.save();
+ ctx.lineJoin = "round";
+ ctx.restore();
+ compare(ctx.lineJoin, old);
+
+ // Also test that save() doesn't modify the values
+ ctx.lineJoin = "round";
+ old = ctx.lineJoin;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "round"
+ ctx.save();
+ compare(ctx.lineJoin, old);
+ ctx.restore();
+ }
+ function test_lineWidth() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ // Test that restore() undoes any modifications
+ var old = ctx.lineJoin;
+ ctx.save();
+ ctx.lineJoin = "round";
+ ctx.restore();
+ compare(ctx.lineJoin, old, "ctx.lineJoin", "old");
+
+ // Also test that save() doesn't modify the values
+ ctx.lineJoin = "round";
+ old = ctx.lineJoin;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "round"
+ ctx.save();
+ compare(ctx.lineJoin, old);
+ ctx.restore();
+ }
+ function test_miterLimit() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ // Test that restore() undoes any modifications
+ var old = ctx.miterLimit;
+ ctx.save();
+ ctx.miterLimit = 0.5;
+ ctx.restore();
+ compare(ctx.miterLimit, old);
+
+ // Also test that save() doesn't modify the values
+ ctx.miterLimit = 0.5;
+ old = ctx.miterLimit;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 0.5
+ ctx.save();
+ compare(ctx.miterLimit, old);
+ ctx.restore();
+ }
+ function test_path() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.rect(0, 0, 100, 50);
+ ctx.restore();
+ ctx.fillStyle = '#0f0';
+ ctx.fill();
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ }
+ function test_shadow() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ // Test that restore() undoes any modifications
+ var old = ctx.shadowBlur;
+ ctx.save();
+ ctx.shadowBlur = 5;
+ ctx.restore();
+ compare(ctx.shadowBlur, old);
+
+ // Also test that save() doesn't modify the values
+ ctx.shadowBlur = 5;
+ old = ctx.shadowBlur;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 5
+ ctx.save();
+ compare(ctx.shadowBlur, old);
+ ctx.restore();
+
+ // Test that restore() undoes any modifications
+ var old = ctx.shadowColor;
+ ctx.save();
+ ctx.shadowColor = "#ff0000";
+ ctx.restore();
+ compare(ctx.shadowColor, old);
+
+ // Also test that save() doesn't modify the values
+ ctx.shadowColor = "#ff0000";
+ old = ctx.shadowColor;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "#ff0000"
+ ctx.save();
+ compare(ctx.shadowColor, old);
+ ctx.restore();
+
+ // Test that restore() undoes any modifications
+ var old = ctx.shadowOffsetX;
+ ctx.save();
+ ctx.shadowOffsetX = 5;
+ ctx.restore();
+ compare(ctx.shadowOffsetX, old);
+
+ // Also test that save() doesn't modify the values
+ ctx.shadowOffsetX = 5;
+ old = ctx.shadowOffsetX;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 5
+ ctx.save();
+ compare(ctx.shadowOffsetX, old);
+ ctx.restore();
+
+ // Test that restore() undoes any modifications
+ var old = ctx.shadowOffsetY;
+ ctx.save();
+ ctx.shadowOffsetY = 5;
+ ctx.restore();
+ compare(ctx.shadowOffsetY, old);
+
+ // Also test that save() doesn't modify the values
+ ctx.shadowOffsetY = 5;
+ old = ctx.shadowOffsetY;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against 5
+ ctx.save();
+ compare(ctx.shadowOffsetY, old);
+ ctx.restore();
+
+ }
+ function test_stack() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.lineWidth = 1;
+ ctx.save();
+ ctx.lineWidth = 2;
+ ctx.save();
+ ctx.lineWidth = 3;
+ compare(ctx.lineWidth, 3);
+ ctx.restore();
+ compare(ctx.lineWidth, 2);
+ ctx.restore();
+ compare(ctx.lineWidth, 1);
+
+ var limit = 512;
+ for (var i = 1; i < limit; ++i)
+ {
+ ctx.save();
+ ctx.lineWidth = i;
+ }
+ for (var i = limit-1; i > 0; --i)
+ {
+ compare(ctx.lineWidth, i);
+ ctx.restore();
+ }
+
+ for (var i = 0; i < 16; ++i)
+ ctx.restore();
+ ctx.lineWidth = 0.5;
+ ctx.restore();
+ compare(ctx.lineWidth, 0.5);
+
+ }
+ function test_strokeStyle() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ // Test that restore() undoes any modifications
+ var old = ctx.strokeStyle;
+ ctx.save();
+ ctx.strokeStyle = "#ff0000";
+ ctx.restore();
+ compare(ctx.strokeStyle, old);
+
+ // Also test that save() doesn't modify the values
+ ctx.strokeStyle = "#ff0000";
+ old = ctx.strokeStyle;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "#ff0000"
+ ctx.save();
+ compare(ctx.strokeStyle, old);
+ ctx.restore();
+
+
+ }
+
+ function test_text() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ // Test that restore() undoes any modifications
+ var old = ctx.textAlign;
+ ctx.save();
+ ctx.textAlign = "center";
+ ctx.restore();
+ compare(ctx.textAlign, old);
+
+ // Also test that save() doesn't modify the values
+ ctx.textAlign = "center";
+ old = ctx.textAlign;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "center"
+ ctx.save();
+ compare(ctx.textAlign, old);
+ ctx.restore();
+
+ // Test that restore() undoes any modifications
+ var old = ctx.textBaseline;
+ ctx.save();
+ ctx.textBaseline = "bottom";
+ ctx.restore();
+ compare(ctx.textBaseline, old);
+
+ // Also test that save() doesn't modify the values
+ ctx.textBaseline = "bottom";
+ old = ctx.textBaseline;
+ // we're not interested in failures caused by get(set(x)) != x (e.g.
+ // from rounding), so compare against 'old' instead of against "bottom"
+ ctx.save();
+ compare(ctx.textBaseline, old);
+ ctx.restore();
+
+
+ }
+
+ function test_transform() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.save();
+ ctx.translate(200, 0);
+ ctx.restore();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(-200, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+
+ }
+
+
+ }
+}
diff --git a/tests/auto/declarative/qsgcanvasitem/data/tst_strokeStyle.qml b/tests/auto/declarative/qsgcanvasitem/data/tst_strokeStyle.qml
new file mode 100644
index 0000000000..6b42f8a770
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/tst_strokeStyle.qml
@@ -0,0 +1,48 @@
+import QtQuick 2.0
+import QtTest 1.0
+import "testhelper.js" as Helper
+
+Canvas {
+ id:canvas; width:100;height:50; renderTarget:Canvas.Image
+ TestCase {
+ name: "strokeStyle"; when: windowShown
+ function test_default() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ compare(ctx.strokeStyle, "#000000")
+ ctx.clearRect(0, 0, 1, 1);
+ compare(ctx.strokeStyle, "#000000")
+ }
+ function test_saverestore() {
+ var ctx = canvas.getContext('2d');
+ var old = ctx.strokeStyle;
+ ctx.save();
+ ctx.strokeStyle = "#ffaaff";
+ ctx.restore();
+ compare(ctx.strokeStyle, old);
+
+ ctx.strokeStyle = "#ffcc88";
+ old = ctx.strokeStyle;
+ ctx.save();
+ compare(ctx.strokeStyle, old);
+ ctx.restore();
+ }
+ function test_namedColor() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.strokeStyle = "red";
+ ctx.strokeRect(0,0,1,1);
+ verify(Helper.comparePixel(ctx,0,0,255,0,0,255));
+
+ ctx.strokeStyle = "black";
+ ctx.strokeRect(0,0,1,1);
+ verify(Helper.comparePixel(ctx,0,0,0,0,0,255));
+
+ ctx.strokeStyle = "white";
+ ctx.strokeRect(0,0,1,1);
+ verify(Helper.comparePixel(ctx,0,0,255,255,255,255));
+ }
+
+
+ }
+}
diff --git a/tests/auto/declarative/qsgcanvasitem/data/tst_text.qml b/tests/auto/declarative/qsgcanvasitem/data/tst_text.qml
new file mode 100644
index 0000000000..baeb17c9fb
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/tst_text.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.0
+import QtTest 1.0
+import "testhelper.js" as Helper
+Canvas {
+ id:canvas; width:100;height:50; renderTarget: Canvas.Image
+ TestCase {
+ //TODO
+ name: "text"; when: windowShown
+ function test_baseLine() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_align() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_stroke() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_fill() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_font() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ function test_measure() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ }
+ }
+}
diff --git a/tests/auto/declarative/qsgcanvasitem/data/tst_transform.qml b/tests/auto/declarative/qsgcanvasitem/data/tst_transform.qml
new file mode 100644
index 0000000000..834a22f549
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/tst_transform.qml
@@ -0,0 +1,487 @@
+import QtQuick 2.0
+import QtTest 1.0
+import "testhelper.js" as Helper
+Canvas {
+ id:canvas; width:100;height:50; renderTarget: Canvas.Image
+ TestCase {
+ name: "transform"; when: windowShown
+ function test_order() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(2, 1);
+ ctx.rotate(Math.PI / 2);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, -50, 50, 50);
+ verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
+ }
+ function test_rotate() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(Math.PI / 2);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, -100, 50, 100);
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.rotate(Infinity);
+ ctx.rotate(-Infinity);
+ ctx.rotate(NaN);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(Math.PI); // should fail obviously if this is 3.1 degrees
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(Math.PI * (1 + 4096)); // == pi (mod 2*pi)
+ // We need about pi +/- 0.001 in order to get correct-looking results
+ // 32-bit floats can store pi*4097 with precision 2^-10, so that should
+ // be safe enough on reasonable implementations
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,2, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,47, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(-Math.PI * (1 + 4096));
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,2, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 98,47, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.rotate(0);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+
+ }
+ function test_scale() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(2, 4);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 12.5);
+ verify(Helper.comparePixel(ctx, 90,40, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(1e5, 1e5);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 1, 1);
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.scale(Math.sqrt(2), Math.sqrt(2));
+ ctx.scale(Math.sqrt(2), Math.sqrt(2));
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+ verify(Helper.comparePixel(ctx, 90,40, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.save();
+ ctx.scale(-1, 1);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-50, 0, 50, 50);
+ ctx.restore();
+
+ ctx.save();
+ ctx.scale(1, -1);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(50, -50, 50, 50);
+ ctx.restore();
+ verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.scale(Infinity, 0.1);
+ ctx.scale(-Infinity, 0.1);
+ ctx.scale(NaN, 0.1);
+ ctx.scale(0.1, Infinity);
+ ctx.scale(0.1, -Infinity);
+ ctx.scale(0.1, NaN);
+ ctx.scale(Infinity, Infinity);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.save();
+ ctx.translate(50, 0);
+ ctx.scale(0, 1);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.restore();
+
+ ctx.save();
+ ctx.translate(0, 25);
+ ctx.scale(1, 0);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.restore();
+
+ // Firefox has a bug where it renders the canvas as empty and toDataURL throws an exception
+ canvas.toDataURL();
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ }
+ function test_setTransform() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.setTransform(1/2,0, 0,1/2, 0,0);
+ ctx.setTransform(2,0, 0,2, 0,0);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 50, 25);
+ verify(Helper.comparePixel(ctx, 75,35, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.setTransform(Infinity, 0, 0, 0, 0, 0);
+ ctx.setTransform(-Infinity, 0, 0, 0, 0, 0);
+ ctx.setTransform(NaN, 0, 0, 0, 0, 0);
+ ctx.setTransform(0, Infinity, 0, 0, 0, 0);
+ ctx.setTransform(0, -Infinity, 0, 0, 0, 0);
+ ctx.setTransform(0, NaN, 0, 0, 0, 0);
+ ctx.setTransform(0, 0, Infinity, 0, 0, 0);
+ ctx.setTransform(0, 0, -Infinity, 0, 0, 0);
+ ctx.setTransform(0, 0, NaN, 0, 0, 0);
+ ctx.setTransform(0, 0, 0, Infinity, 0, 0);
+ ctx.setTransform(0, 0, 0, -Infinity, 0, 0);
+ ctx.setTransform(0, 0, 0, NaN, 0, 0);
+ ctx.setTransform(0, 0, 0, 0, Infinity, 0);
+ ctx.setTransform(0, 0, 0, 0, -Infinity, 0);
+ ctx.setTransform(0, 0, 0, 0, NaN, 0);
+ ctx.setTransform(0, 0, 0, 0, 0, Infinity);
+ ctx.setTransform(0, 0, 0, 0, 0, -Infinity);
+ ctx.setTransform(0, 0, 0, 0, 0, NaN);
+ ctx.setTransform(Infinity, Infinity, 0, 0, 0, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, 0, 0, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, Infinity, 0, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.setTransform(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.setTransform(Infinity, Infinity, Infinity, 0, Infinity, 0);
+ ctx.setTransform(Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.setTransform(Infinity, Infinity, Infinity, 0, 0, Infinity);
+ ctx.setTransform(Infinity, Infinity, 0, Infinity, 0, 0);
+ ctx.setTransform(Infinity, Infinity, 0, Infinity, Infinity, 0);
+ ctx.setTransform(Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.setTransform(Infinity, Infinity, 0, Infinity, 0, Infinity);
+ ctx.setTransform(Infinity, Infinity, 0, 0, Infinity, 0);
+ ctx.setTransform(Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.setTransform(Infinity, Infinity, 0, 0, 0, Infinity);
+ ctx.setTransform(Infinity, 0, Infinity, 0, 0, 0);
+ ctx.setTransform(Infinity, 0, Infinity, Infinity, 0, 0);
+ ctx.setTransform(Infinity, 0, Infinity, Infinity, Infinity, 0);
+ ctx.setTransform(Infinity, 0, Infinity, Infinity, Infinity, Infinity);
+ ctx.setTransform(Infinity, 0, Infinity, Infinity, 0, Infinity);
+ ctx.setTransform(Infinity, 0, Infinity, 0, Infinity, 0);
+ ctx.setTransform(Infinity, 0, Infinity, 0, Infinity, Infinity);
+ ctx.setTransform(Infinity, 0, Infinity, 0, 0, Infinity);
+ ctx.setTransform(Infinity, 0, 0, Infinity, 0, 0);
+ ctx.setTransform(Infinity, 0, 0, Infinity, Infinity, 0);
+ ctx.setTransform(Infinity, 0, 0, Infinity, Infinity, Infinity);
+ ctx.setTransform(Infinity, 0, 0, Infinity, 0, Infinity);
+ ctx.setTransform(Infinity, 0, 0, 0, Infinity, 0);
+ ctx.setTransform(Infinity, 0, 0, 0, Infinity, Infinity);
+ ctx.setTransform(Infinity, 0, 0, 0, 0, Infinity);
+ ctx.setTransform(0, Infinity, Infinity, 0, 0, 0);
+ ctx.setTransform(0, Infinity, Infinity, Infinity, 0, 0);
+ ctx.setTransform(0, Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.setTransform(0, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.setTransform(0, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.setTransform(0, Infinity, Infinity, 0, Infinity, 0);
+ ctx.setTransform(0, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.setTransform(0, Infinity, Infinity, 0, 0, Infinity);
+ ctx.setTransform(0, Infinity, 0, Infinity, 0, 0);
+ ctx.setTransform(0, Infinity, 0, Infinity, Infinity, 0);
+ ctx.setTransform(0, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.setTransform(0, Infinity, 0, Infinity, 0, Infinity);
+ ctx.setTransform(0, Infinity, 0, 0, Infinity, 0);
+ ctx.setTransform(0, Infinity, 0, 0, Infinity, Infinity);
+ ctx.setTransform(0, Infinity, 0, 0, 0, Infinity);
+ ctx.setTransform(0, 0, Infinity, Infinity, 0, 0);
+ ctx.setTransform(0, 0, Infinity, Infinity, Infinity, 0);
+ ctx.setTransform(0, 0, Infinity, Infinity, Infinity, Infinity);
+ ctx.setTransform(0, 0, Infinity, Infinity, 0, Infinity);
+ ctx.setTransform(0, 0, Infinity, 0, Infinity, 0);
+ ctx.setTransform(0, 0, Infinity, 0, Infinity, Infinity);
+ ctx.setTransform(0, 0, Infinity, 0, 0, Infinity);
+ ctx.setTransform(0, 0, 0, Infinity, Infinity, 0);
+ ctx.setTransform(0, 0, 0, Infinity, Infinity, Infinity);
+ ctx.setTransform(0, 0, 0, Infinity, 0, Infinity);
+ ctx.setTransform(0, 0, 0, 0, Infinity, Infinity);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ ctx.reset();
+
+ // Create green with a red square ring inside it
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(20, 10, 60, 30);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(40, 20, 20, 10);
+
+ // Draw a skewed shape to fill that gap, to make sure it is aligned correctly
+ ctx.setTransform(1,4, 2,3, 5,6);
+ // Post-transform coordinates:
+ // [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]];
+ // Hence pre-transform coordinates:
+ var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2],
+ [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2],
+ [-7.4,11.2]];
+ ctx.beginPath();
+ ctx.moveTo(pts[0][0], pts[0][1]);
+ for (var i = 0; i < pts.length; ++i)
+ ctx.lineTo(pts[i][0], pts[i][1]);
+ ctx.fill();
+ /*
+ //FIXME:
+ verify(Helper.comparePixel(ctx, 21,11, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 79,11, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 21,39, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 79,39, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 39,19, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 61,19, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 39,31, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 61,31, 0,255,0,255));
+ */
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.transform(1,0, 0,1, 0,0);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+ }
+ function test_transform() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.transform(1,2, 3,4, 5,6);
+ ctx.transform(-2,1, 3/2,-1/2, 1,-2);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.transform(Infinity, 0, 0, 0, 0, 0);
+ ctx.transform(-Infinity, 0, 0, 0, 0, 0);
+ ctx.transform(NaN, 0, 0, 0, 0, 0);
+ ctx.transform(0, Infinity, 0, 0, 0, 0);
+ ctx.transform(0, -Infinity, 0, 0, 0, 0);
+ ctx.transform(0, NaN, 0, 0, 0, 0);
+ ctx.transform(0, 0, Infinity, 0, 0, 0);
+ ctx.transform(0, 0, -Infinity, 0, 0, 0);
+ ctx.transform(0, 0, NaN, 0, 0, 0);
+ ctx.transform(0, 0, 0, Infinity, 0, 0);
+ ctx.transform(0, 0, 0, -Infinity, 0, 0);
+ ctx.transform(0, 0, 0, NaN, 0, 0);
+ ctx.transform(0, 0, 0, 0, Infinity, 0);
+ ctx.transform(0, 0, 0, 0, -Infinity, 0);
+ ctx.transform(0, 0, 0, 0, NaN, 0);
+ ctx.transform(0, 0, 0, 0, 0, Infinity);
+ ctx.transform(0, 0, 0, 0, 0, -Infinity);
+ ctx.transform(0, 0, 0, 0, 0, NaN);
+ ctx.transform(Infinity, Infinity, 0, 0, 0, 0);
+ ctx.transform(Infinity, Infinity, Infinity, 0, 0, 0);
+ ctx.transform(Infinity, Infinity, Infinity, Infinity, 0, 0);
+ ctx.transform(Infinity, Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.transform(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.transform(Infinity, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.transform(Infinity, Infinity, Infinity, 0, Infinity, 0);
+ ctx.transform(Infinity, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.transform(Infinity, Infinity, Infinity, 0, 0, Infinity);
+ ctx.transform(Infinity, Infinity, 0, Infinity, 0, 0);
+ ctx.transform(Infinity, Infinity, 0, Infinity, Infinity, 0);
+ ctx.transform(Infinity, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.transform(Infinity, Infinity, 0, Infinity, 0, Infinity);
+ ctx.transform(Infinity, Infinity, 0, 0, Infinity, 0);
+ ctx.transform(Infinity, Infinity, 0, 0, Infinity, Infinity);
+ ctx.transform(Infinity, Infinity, 0, 0, 0, Infinity);
+ ctx.transform(Infinity, 0, Infinity, 0, 0, 0);
+ ctx.transform(Infinity, 0, Infinity, Infinity, 0, 0);
+ ctx.transform(Infinity, 0, Infinity, Infinity, Infinity, 0);
+ ctx.transform(Infinity, 0, Infinity, Infinity, Infinity, Infinity);
+ ctx.transform(Infinity, 0, Infinity, Infinity, 0, Infinity);
+ ctx.transform(Infinity, 0, Infinity, 0, Infinity, 0);
+ ctx.transform(Infinity, 0, Infinity, 0, Infinity, 0);
+ ctx.transform(Infinity, 0, Infinity, 0, Infinity, Infinity);
+ ctx.transform(Infinity, 0, Infinity, 0, 0, Infinity);
+ ctx.transform(Infinity, 0, 0, Infinity, 0, 0);
+ ctx.transform(Infinity, 0, 0, Infinity, Infinity, 0);
+ ctx.transform(Infinity, 0, 0, Infinity, Infinity, Infinity);
+ ctx.transform(Infinity, 0, 0, Infinity, 0, Infinity);
+ ctx.transform(Infinity, 0, 0, 0, Infinity, 0);
+ ctx.transform(Infinity, 0, 0, 0, Infinity, Infinity);
+ ctx.transform(Infinity, 0, 0, 0, 0, Infinity);
+ ctx.transform(0, Infinity, Infinity, 0, 0, 0);
+ ctx.transform(0, Infinity, Infinity, Infinity, 0, 0);
+ ctx.transform(0, Infinity, Infinity, Infinity, Infinity, 0);
+ ctx.transform(0, Infinity, Infinity, Infinity, Infinity, Infinity);
+ ctx.transform(0, Infinity, Infinity, Infinity, 0, Infinity);
+ ctx.transform(0, Infinity, Infinity, 0, Infinity, 0);
+ ctx.transform(0, Infinity, Infinity, 0, Infinity, Infinity);
+ ctx.transform(0, Infinity, Infinity, 0, 0, Infinity);
+ ctx.transform(0, Infinity, 0, Infinity, 0, 0);
+ ctx.transform(0, Infinity, 0, Infinity, Infinity, 0);
+ ctx.transform(0, Infinity, 0, Infinity, Infinity, Infinity);
+ ctx.transform(0, Infinity, 0, Infinity, 0, Infinity);
+ ctx.transform(0, Infinity, 0, 0, Infinity, 0);
+ ctx.transform(0, Infinity, 0, 0, Infinity, Infinity);
+ ctx.transform(0, Infinity, 0, 0, 0, Infinity);
+ ctx.transform(0, 0, Infinity, Infinity, 0, 0);
+ ctx.transform(0, 0, Infinity, Infinity, Infinity, 0);
+ ctx.transform(0, 0, Infinity, Infinity, Infinity, Infinity);
+ ctx.transform(0, 0, Infinity, Infinity, 0, Infinity);
+ ctx.transform(0, 0, Infinity, 0, Infinity, 0);
+ ctx.transform(0, 0, Infinity, 0, Infinity, Infinity);
+ ctx.transform(0, 0, Infinity, 0, 0, Infinity);
+ ctx.transform(0, 0, 0, Infinity, Infinity, 0);
+ ctx.transform(0, 0, 0, Infinity, Infinity, Infinity);
+ ctx.transform(0, 0, 0, Infinity, 0, Infinity);
+ ctx.transform(0, 0, 0, 0, Infinity, Infinity);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+ ctx.reset();
+
+ // Create green with a red square ring inside it
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(0, 0, 100, 50);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(20, 10, 60, 30);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(40, 20, 20, 10);
+
+ // Draw a skewed shape to fill that gap, to make sure it is aligned correctly
+ ctx.transform(1,4, 2,3, 5,6);
+ // Post-transform coordinates:
+ // [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]];
+ // Hence pre-transform coordinates:
+ var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2],
+ [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2],
+ [-7.4,11.2]];
+ ctx.beginPath();
+ ctx.moveTo(pts[0][0], pts[0][1]);
+ for (var i = 0; i < pts.length; ++i)
+ ctx.lineTo(pts[i][0], pts[i][1]);
+ ctx.fill();
+ /*
+ //FIXME:
+ verify(Helper.comparePixel(ctx, 21,11, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 79,11, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 21,39, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 79,39, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 39,19, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 61,19, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 39,31, 0,255,0,255));
+ verify(Helper.comparePixel(ctx, 61,31, 0,255,0,255));
+ */
+ }
+ function test_translate() {
+ var ctx = canvas.getContext('2d');
+ ctx.reset();
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 50);
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -50, 100, 50);
+ verify(Helper.comparePixel(ctx, 90,40, 0,255,0,255));
+ ctx.reset();
+
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+
+ ctx.translate(100, 10);
+ ctx.translate(Infinity, 0.1);
+ ctx.translate(-Infinity, 0.1);
+ ctx.translate(NaN, 0.1);
+ ctx.translate(0.1, Infinity);
+ ctx.translate(0.1, -Infinity);
+ ctx.translate(0.1, NaN);
+ ctx.translate(Infinity, Infinity);
+
+ ctx.fillStyle = '#0f0';
+ ctx.fillRect(-100, -10, 100, 50);
+
+ verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));
+
+
+ }
+ }
+}
diff --git a/tests/auto/declarative/qsgcanvasitem/data/yellow.png b/tests/auto/declarative/qsgcanvasitem/data/yellow.png
new file mode 100644
index 0000000000..51e8aaf38c
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/yellow.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/data/yellow75.png b/tests/auto/declarative/qsgcanvasitem/data/yellow75.png
new file mode 100644
index 0000000000..2bb82c9834
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/data/yellow75.png
Binary files differ
diff --git a/tests/auto/declarative/qsgcanvasitem/qsgcanvasitem.pro b/tests/auto/declarative/qsgcanvasitem/qsgcanvasitem.pro
new file mode 100644
index 0000000000..18c1ea6d4a
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/qsgcanvasitem.pro
@@ -0,0 +1,34 @@
+QT += core-private gui-private declarative-private widgets
+TEMPLATE=app
+TARGET=tst_qsgcanvasitem
+
+CONFIG+=insignificant_test
+CONFIG += warn_on qmltestcase
+SOURCES += tst_qsgcanvasitem.cpp
+
+importFiles.files = data
+importFiles.path = .
+DEPLOYMENT += importFiles
+
+OTHER_FILES += \
+ data/testhelper.js \
+ data/tst_transform.qml \
+ data/tst_text.qml \
+ data/tst_strokeStyle.qml \
+ data/tst_state.qml \
+ data/tst_shadow.qml \
+ data/tst_pattern.qml \
+ data/tst_path.qml \
+ data/tst_line.qml \
+ data/tst_fillStyle.qml \
+ data/tst_fillrect.qml \
+ data/tst_drawimage.qml \
+ data/tst_composite.qml \
+ data/tst_canvas.qml \
+ data/tst_pixel.qml \
+ data/tst_gradient.qml \
+ data/tst_arcto.qml \
+ data/tst_arc.qml
+
+
+
diff --git a/tests/auto/declarative/qsgcanvasitem/tst_qsgcanvasitem.cpp b/tests/auto/declarative/qsgcanvasitem/tst_qsgcanvasitem.cpp
new file mode 100644
index 0000000000..680e45238e
--- /dev/null
+++ b/tests/auto/declarative/qsgcanvasitem/tst_qsgcanvasitem.cpp
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtQuickTest/quicktest.h>
+QUICK_TEST_MAIN(qsgcanvasitem)
diff --git a/tests/auto/declarative/qsgdrag/qsgdrag.pro b/tests/auto/declarative/qsgdrag/qsgdrag.pro
new file mode 100644
index 0000000000..a799860be9
--- /dev/null
+++ b/tests/auto/declarative/qsgdrag/qsgdrag.pro
@@ -0,0 +1,9 @@
+TARGET = tst_qsgdrag
+CONFIG += testcase
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qsgdrag.cpp
+
+CONFIG += parallel_test
+
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qsgdrag/tst_qsgdrag.cpp b/tests/auto/declarative/qsgdrag/tst_qsgdrag.cpp
new file mode 100644
index 0000000000..9719114662
--- /dev/null
+++ b/tests/auto/declarative/qsgdrag/tst_qsgdrag.cpp
@@ -0,0 +1,827 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtTest/QSignalSpy>
+#include <QtDeclarative/qsgitem.h>
+#include <QtDeclarative/qsgview.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativeexpression.h>
+
+template <typename T> static T evaluate(QObject *scope, const QString &expression)
+{
+ QDeclarativeExpression expr(qmlContext(scope), scope, expression);
+ QVariant result = expr.evaluate();
+ if (expr.hasError())
+ qWarning() << expr.error().toString();
+ return result.value<T>();
+}
+
+template <> void evaluate<void>(QObject *scope, const QString &expression)
+{
+ QDeclarativeExpression expr(qmlContext(scope), scope, expression);
+ expr.evaluate();
+ if (expr.hasError())
+ qWarning() << expr.error().toString();
+}
+
+Q_DECLARE_METATYPE(Qt::DropActions)
+
+class TestDropTarget : public QSGItem
+{
+ Q_OBJECT
+public:
+ TestDropTarget(QSGItem *parent = 0)
+ : QSGItem(parent)
+ , enterEvents(0)
+ , moveEvents(0)
+ , leaveEvents(0)
+ , dropEvents(0)
+ , acceptAction(Qt::MoveAction)
+ , defaultAction(Qt::IgnoreAction)
+ , proposedAction(Qt::IgnoreAction)
+ , accept(true)
+ {
+ setFlags(ItemAcceptsDrops);
+ }
+
+ void reset()
+ {
+ enterEvents = 0;
+ moveEvents = 0;
+ leaveEvents = 0;
+ dropEvents = 0;
+ defaultAction = Qt::IgnoreAction;
+ proposedAction = Qt::IgnoreAction;
+ supportedActions = Qt::IgnoreAction;
+ }
+
+ void dragEnterEvent(QDragEnterEvent *event)
+ {
+ ++enterEvents;
+ position = event->pos();
+ defaultAction = event->dropAction();
+ proposedAction = event->proposedAction();
+ supportedActions = event->possibleActions();
+ event->setAccepted(accept);
+ }
+
+ void dragMoveEvent(QDragMoveEvent *event)
+ {
+ ++moveEvents;
+ position = event->pos();
+ defaultAction = event->dropAction();
+ proposedAction = event->proposedAction();
+ supportedActions = event->possibleActions();
+ event->setAccepted(accept);
+ }
+
+ void dragLeaveEvent(QDragLeaveEvent *event)
+ {
+ ++leaveEvents;
+ event->setAccepted(accept);
+ }
+
+ void dropEvent(QDropEvent *event)
+ {
+ ++dropEvents;
+ position = event->pos();
+ defaultAction = event->dropAction();
+ proposedAction = event->proposedAction();
+ supportedActions = event->possibleActions();
+ event->setDropAction(acceptAction);
+ event->setAccepted(accept);
+ }
+
+ int enterEvents;
+ int moveEvents;
+ int leaveEvents;
+ int dropEvents;
+ Qt::DropAction acceptAction;
+ Qt::DropAction defaultAction;
+ Qt::DropAction proposedAction;
+ Qt::DropActions supportedActions;
+ QPointF position;
+ bool accept;
+};
+
+class tst_QSGDrag: public QObject
+{
+ Q_OBJECT
+private slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+ void active();
+ void drop();
+ void move();
+ void hotSpot();
+ void supportedActions();
+ void proposedAction();
+ void keys();
+ void source();
+
+private:
+ QDeclarativeEngine engine;
+};
+
+void tst_QSGDrag::initTestCase()
+{
+
+}
+
+void tst_QSGDrag::cleanupTestCase()
+{
+
+}
+
+void tst_QSGDrag::active()
+{
+ QSGCanvas canvas;
+ TestDropTarget dropTarget(canvas.rootItem());
+ dropTarget.setSize(QSizeF(100, 100));
+ QDeclarativeComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "Item {\n"
+ "property bool dragActive: Drag.active\n"
+ "property Item dragTarget: Drag.target\n"
+ "x: 50; y: 50\n"
+ "width: 10; height: 10\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QSGItem *item = qobject_cast<QSGItem *>(object.data());
+ QVERIFY(item);
+ item->setParentItem(&dropTarget);
+
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), false);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), false);
+
+ evaluate<void>(item, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), true);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), true);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&dropTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&dropTarget));
+ QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0);
+
+ dropTarget.reset();
+ evaluate<void>(item, "Drag.active = false");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), false);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), false);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0));
+ QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 1);
+
+ dropTarget.reset();
+ evaluate<void>(item, "Drag.cancel()");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), false);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), false);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0));
+ QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0);
+
+ dropTarget.reset();
+ evaluate<void>(item, "Drag.start()");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), true);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), true);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&dropTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&dropTarget));
+ QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0);
+
+ // Start while a drag is active, cancels the previous drag and starts a new one.
+ dropTarget.reset();
+ evaluate<void>(item, "Drag.start()");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), true);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), true);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&dropTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&dropTarget));
+ QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 1);
+
+ dropTarget.reset();
+ evaluate<void>(item, "Drag.cancel()");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), false);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), false);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0));
+ QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 1);
+
+ // Enter events aren't sent to items without the QSGItem::ItemAcceptsDrops flag.
+ dropTarget.setFlags(QSGItem::Flags());
+
+ dropTarget.reset();
+ evaluate<void>(item, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), true);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), true);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0));
+ QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0);
+
+ dropTarget.reset();
+ evaluate<void>(item, "Drag.active = false");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), false);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), false);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0));
+ QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0);
+
+ dropTarget.setFlags(QSGItem::ItemAcceptsDrops);
+
+ dropTarget.reset();
+ evaluate<void>(item, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), true);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), true);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&dropTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&dropTarget));
+ QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0);
+
+ dropTarget.setFlags(QSGItem::Flags());
+
+ dropTarget.reset();
+ evaluate<void>(item, "Drag.active = false");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), false);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), false);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0));
+ QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 1);
+
+ // Follow up events aren't sent to items if the enter event isn't accepted.
+ dropTarget.setFlags(QSGItem::ItemAcceptsDrops);
+ dropTarget.accept = false;
+
+ dropTarget.reset();
+ evaluate<void>(item, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), true);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), true);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0));
+ QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0);
+
+ dropTarget.reset();
+ evaluate<void>(item, "Drag.active = false");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), false);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), false);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0));
+ QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0);
+
+ dropTarget.accept = true;
+
+ dropTarget.reset();
+ evaluate<void>(item, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), true);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), true);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&dropTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&dropTarget));
+ QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0);
+
+ dropTarget.accept = false;
+
+ dropTarget.reset();
+ evaluate<void>(item, "Drag.active = false");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), false);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), false);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0));
+ QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 1);
+
+ // Events are sent to hidden or disabled items.
+ dropTarget.accept = true;
+ dropTarget.setVisible(false);
+ dropTarget.reset();
+ evaluate<void>(item, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), true);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), true);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0));
+ QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0);
+
+ evaluate<void>(item, "Drag.active = false");
+ dropTarget.setVisible(true);
+
+ dropTarget.setOpacity(0.0);
+ dropTarget.reset();
+ evaluate<void>(item, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), true);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), true);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0));
+ QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0);
+
+ evaluate<void>(item, "Drag.active = false");
+ dropTarget.setOpacity(1.0);
+
+ dropTarget.setEnabled(false);
+ dropTarget.reset();
+ evaluate<void>(item, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), true);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), true);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0));
+ QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0);
+}
+
+void tst_QSGDrag::drop()
+{
+ QSGCanvas canvas;
+ TestDropTarget outerTarget(canvas.rootItem());
+ outerTarget.setSize(QSizeF(100, 100));
+ outerTarget.acceptAction = Qt::CopyAction;
+ TestDropTarget innerTarget(&outerTarget);
+ innerTarget.setSize(QSizeF(100, 100));
+ innerTarget.acceptAction = Qt::MoveAction;
+ QDeclarativeComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "Item {\n"
+ "property bool dragActive: Drag.active\n"
+ "property Item dragTarget: Drag.target\n"
+ "x: 50; y: 50\n"
+ "width: 10; height: 10\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QSGItem *item = qobject_cast<QSGItem *>(object.data());
+ QVERIFY(item);
+ item->setParentItem(&outerTarget);
+
+ innerTarget.reset(); outerTarget.reset();
+ evaluate<void>(item, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), true);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), true);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&innerTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&innerTarget));
+ QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0);
+ QCOMPARE(innerTarget.enterEvents, 1); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0);
+
+ innerTarget.reset(); outerTarget.reset();
+ QCOMPARE(evaluate<bool>(item, "Drag.drop() == Qt.MoveAction"), true);
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), false);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), false);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&innerTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&innerTarget));
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 1); QCOMPARE(outerTarget.dropEvents, 0);
+ QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 1);
+
+ innerTarget.reset(); outerTarget.reset();
+ evaluate<void>(item, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), true);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), true);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&innerTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&innerTarget));
+ QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0);
+ QCOMPARE(innerTarget.enterEvents, 1); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0);
+
+ // Inner target declines the drop so it is propagated to the outer target.
+ innerTarget.accept = false;
+
+ innerTarget.reset(); outerTarget.reset();
+ QCOMPARE(evaluate<bool>(item, "Drag.drop() == Qt.CopyAction"), true);
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), false);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), false);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 1);
+ QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 1);
+
+
+ // Inner target doesn't accept enter so drop goes directly to outer.
+ innerTarget.accept = true;
+ innerTarget.setFlags(QSGItem::Flags());
+
+ innerTarget.reset(); outerTarget.reset();
+ evaluate<void>(item, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), true);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), true);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0);
+ QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0);
+
+ innerTarget.reset(); outerTarget.reset();
+ QCOMPARE(evaluate<bool>(item, "Drag.drop() == Qt.CopyAction"), true);
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), false);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), false);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 1);
+ QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0);
+
+ // Neither target accepts drop so Qt::IgnoreAction is returned.
+ innerTarget.reset(); outerTarget.reset();
+ evaluate<void>(item, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), true);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), true);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0);
+ QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0);
+
+ outerTarget.accept = false;
+
+ innerTarget.reset(); outerTarget.reset();
+ QCOMPARE(evaluate<bool>(item, "Drag.drop() == Qt.IgnoreAction"), true);
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), false);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), false);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0));
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 1);
+ QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0);
+
+ // drop doesn't send an event and returns Qt.IgnoreAction if not active.
+ innerTarget.accept = true;
+ outerTarget.accept = true;
+ innerTarget.reset(); outerTarget.reset();
+ QCOMPARE(evaluate<bool>(item, "Drag.drop() == Qt.IgnoreAction"), true);
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), false);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), false);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0));
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0);
+ QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0);
+}
+
+void tst_QSGDrag::move()
+{
+ QSGCanvas canvas;
+ TestDropTarget outerTarget(canvas.rootItem());
+ outerTarget.setSize(QSizeF(100, 100));
+ TestDropTarget leftTarget(&outerTarget);
+ leftTarget.setPos(QPointF(0, 35));
+ leftTarget.setSize(QSizeF(30, 30));
+ TestDropTarget rightTarget(&outerTarget);
+ rightTarget.setPos(QPointF(70, 35));
+ rightTarget.setSize(QSizeF(30, 30));
+ QDeclarativeComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "Item {\n"
+ "property bool dragActive: Drag.active\n"
+ "property Item dragTarget: Drag.target\n"
+ "x: 50; y: 50\n"
+ "width: 10; height: 10\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QSGItem *item = qobject_cast<QSGItem *>(object.data());
+ QVERIFY(item);
+ item->setParentItem(&outerTarget);
+
+ evaluate<void>(item, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(item, "Drag.active"), true);
+ QCOMPARE(evaluate<bool>(item, "dragActive"), true);
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 0);
+ QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0);
+ QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0);
+ QCOMPARE(outerTarget.position.x(), qreal(50)); QCOMPARE(outerTarget.position.y(), qreal(50));
+
+ // Move within the outer target.
+ outerTarget.reset(); leftTarget.reset(); rightTarget.reset();
+ item->setPos(QPointF(60, 50));
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1);
+ QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0);
+ QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0);
+ QCOMPARE(outerTarget.position.x(), qreal(60)); QCOMPARE(outerTarget.position.y(), qreal(50));
+
+ // Move into the right target.
+ outerTarget.reset(); leftTarget.reset(); rightTarget.reset();
+ item->setPos(QPointF(75, 50));
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&rightTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&rightTarget));
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1);
+ QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0);
+ QCOMPARE(rightTarget.enterEvents, 1); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0);
+ QCOMPARE(outerTarget.position.x(), qreal(75)); QCOMPARE(outerTarget.position.y(), qreal(50));
+ QCOMPARE(rightTarget.position.x(), qreal(5)); QCOMPARE(rightTarget.position.y(), qreal(15));
+
+ // Move into the left target.
+ outerTarget.reset(); leftTarget.reset(); rightTarget.reset();
+ item->setPos(QPointF(25, 50));
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&leftTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&leftTarget));
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1);
+ QCOMPARE(leftTarget .enterEvents, 1); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0);
+ QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 1); QCOMPARE(rightTarget.moveEvents, 0);
+ QCOMPARE(outerTarget.position.x(), qreal(25)); QCOMPARE(outerTarget.position.y(), qreal(50));
+ QCOMPARE(leftTarget.position.x(), qreal(25)); QCOMPARE(leftTarget.position.y(), qreal(15));
+
+ // Move within the left target.
+ outerTarget.reset(); leftTarget.reset(); rightTarget.reset();
+ item->setPos(QPointF(25, 40));
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&leftTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&leftTarget));
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1);
+ QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 1);
+ QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0);
+ QCOMPARE(outerTarget.position.x(), qreal(25)); QCOMPARE(outerTarget.position.y(), qreal(40));
+ QCOMPARE(leftTarget.position.x(), qreal(25)); QCOMPARE(leftTarget.position.y(), qreal(5));
+
+ // Move out of all targets.
+ outerTarget.reset(); leftTarget.reset(); rightTarget.reset();
+ item->setPos(QPointF(110, 50));
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0));
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 1); QCOMPARE(outerTarget.moveEvents, 0);
+ QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 1); QCOMPARE(leftTarget .moveEvents, 0);
+ QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0);
+
+ // Stop the right target accepting drag events and move into it.
+ rightTarget.accept = false;
+
+ outerTarget.reset(); leftTarget.reset(); rightTarget.reset();
+ item->setPos(QPointF(80, 50));
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 0);
+ QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0);
+ QCOMPARE(rightTarget.enterEvents, 1); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0);
+ QCOMPARE(outerTarget.position.x(), qreal(80)); QCOMPARE(outerTarget.position.y(), qreal(50));
+
+ // Stop the outer target accepting drag events after it has accepted an enter event.
+ outerTarget.accept = false;
+
+ outerTarget.reset(); leftTarget.reset(); rightTarget.reset();
+ item->setPos(QPointF(60, 50));
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1);
+ QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0);
+ QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0);
+ QCOMPARE(outerTarget.position.x(), qreal(60)); QCOMPARE(outerTarget.position.y(), qreal(50));
+
+ // Clear the QSGItem::ItemAcceptsDrops flag from the outer target after it accepted an enter event.
+ outerTarget.setFlags(QSGItem::Flags());
+
+ outerTarget.reset(); leftTarget.reset(); rightTarget.reset();
+ item->setPos(QPointF(40, 50));
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1);
+ QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0);
+ QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0);
+ QCOMPARE(outerTarget.position.x(), qreal(40)); QCOMPARE(outerTarget.position.y(), qreal(50));
+
+ // Clear the QSGItem::ItemAcceptsDrops flag from the left target before it accepts an enter event.
+ leftTarget.setFlags(QSGItem::Flags());
+
+ outerTarget.reset(); leftTarget.reset(); rightTarget.reset();
+ item->setPos(QPointF(25, 50));
+ QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget));
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1);
+ QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0);
+ QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0);
+ QCOMPARE(outerTarget.position.x(), qreal(25)); QCOMPARE(outerTarget.position.y(), qreal(50));
+}
+
+
+void tst_QSGDrag::hotSpot()
+{
+ QSGCanvas canvas;
+ TestDropTarget dropTarget(canvas.rootItem());
+ dropTarget.setSize(QSizeF(100, 100));
+ QDeclarativeComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "Item {\n"
+ "property real hotSpotX: Drag.hotSpot.x\n"
+ "property real hotSpotY: Drag.hotSpot.y\n"
+ "x: 50; y: 50\n"
+ "width: 10; height: 10\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QSGItem *item = qobject_cast<QSGItem *>(object.data());
+ QVERIFY(item);
+ item->setParentItem(&dropTarget);
+
+ QCOMPARE(evaluate<qreal>(item, "Drag.hotSpot.x"), qreal(0));
+ QCOMPARE(evaluate<qreal>(item, "Drag.hotSpot.y"), qreal(0));
+ QCOMPARE(evaluate<qreal>(item, "hotSpotX"), qreal(0));
+ QCOMPARE(evaluate<qreal>(item, "hotSpotY"), qreal(0));
+
+ evaluate<void>(item, "{ Drag.start(); Drag.cancel() }");
+ QCOMPARE(dropTarget.position.x(), qreal(50));
+ QCOMPARE(dropTarget.position.y(), qreal(50));
+
+ evaluate<void>(item, "{ Drag.hotSpot.x = 5, Drag.hotSpot.y = 5 }");
+ QCOMPARE(evaluate<qreal>(item, "Drag.hotSpot.x"), qreal(5));
+ QCOMPARE(evaluate<qreal>(item, "Drag.hotSpot.y"), qreal(5));
+ QCOMPARE(evaluate<qreal>(item, "hotSpotX"), qreal(5));
+ QCOMPARE(evaluate<qreal>(item, "hotSpotY"), qreal(5));
+
+ evaluate<void>(item, "Drag.start()");
+ QCOMPARE(dropTarget.position.x(), qreal(55));
+ QCOMPARE(dropTarget.position.y(), qreal(55));
+
+ item->setPos(QPointF(30, 20));
+ QCOMPARE(dropTarget.position.x(), qreal(35));
+ QCOMPARE(dropTarget.position.y(), qreal(25));
+
+ evaluate<void>(item, "{ Drag.hotSpot.x = 10; Drag.hotSpot.y = 10 }");
+ QCOMPARE(evaluate<qreal>(item, "Drag.hotSpot.x"), qreal(10));
+ QCOMPARE(evaluate<qreal>(item, "Drag.hotSpot.y"), qreal(10));
+ QCOMPARE(evaluate<qreal>(item, "hotSpotX"), qreal(10));
+ QCOMPARE(evaluate<qreal>(item, "hotSpotY"), qreal(10));
+ // Changing the hotSpot won't generate a move event so the position is unchanged. Should it?
+ QCOMPARE(dropTarget.position.x(), qreal(35));
+ QCOMPARE(dropTarget.position.y(), qreal(25));
+
+ item->setPos(QPointF(10, 20));
+ QCOMPARE(dropTarget.position.x(), qreal(20));
+ QCOMPARE(dropTarget.position.y(), qreal(30));
+}
+
+void tst_QSGDrag::supportedActions()
+{
+ QSGCanvas canvas;
+ TestDropTarget dropTarget(canvas.rootItem());
+ dropTarget.setSize(QSizeF(100, 100));
+ QDeclarativeComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "Item {\n"
+ "property int supportedActions: Drag.supportedActions\n"
+ "x: 50; y: 50\n"
+ "width: 10; height: 10\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QSGItem *item = qobject_cast<QSGItem *>(object.data());
+ QVERIFY(item);
+ item->setParentItem(&dropTarget);
+
+ QCOMPARE(evaluate<bool>(item, "Drag.supportedActions == Qt.CopyAction | Qt.MoveAction | Qt.LinkAction"), true);
+ QCOMPARE(evaluate<bool>(item, "supportedActions == Qt.CopyAction | Qt.MoveAction | Qt.LinkAction"), true);
+ evaluate<void>(item, "{ Drag.start(); Drag.cancel() }");
+ QCOMPARE(dropTarget.supportedActions, Qt::CopyAction | Qt::MoveAction | Qt::LinkAction);
+
+ evaluate<void>(item, "Drag.supportedActions = Qt.CopyAction | Qt.MoveAction");
+ QCOMPARE(evaluate<bool>(item, "Drag.supportedActions == Qt.CopyAction | Qt.MoveAction"), true);
+ QCOMPARE(evaluate<bool>(item, "supportedActions == Qt.CopyAction | Qt.MoveAction"), true);
+ evaluate<void>(item, "Drag.start()");
+ QCOMPARE(dropTarget.supportedActions, Qt::CopyAction | Qt::MoveAction);
+
+ // Once a drag is started the proposed actions are locked in for future events.
+ evaluate<void>(item, "Drag.supportedActions = Qt.MoveAction");
+ QCOMPARE(evaluate<bool>(item, "Drag.supportedActions == Qt.MoveAction"), true);
+ QCOMPARE(evaluate<bool>(item, "supportedActions == Qt.MoveAction"), true);
+ item->setPos(QPointF(60, 60));
+ QCOMPARE(dropTarget.supportedActions, Qt::CopyAction | Qt::MoveAction);
+
+ // Calling start with proposed actions will override the current actions for the next sequence.
+ evaluate<void>(item, "Drag.start(Qt.CopyAction)");
+ QCOMPARE(evaluate<bool>(item, "Drag.supportedActions == Qt.MoveAction"), true);
+ QCOMPARE(evaluate<bool>(item, "supportedActions == Qt.MoveAction"), true);
+ QCOMPARE(dropTarget.supportedActions, Qt::CopyAction);
+
+ evaluate<void>(item, "Drag.start()");
+ QCOMPARE(evaluate<bool>(item, "Drag.supportedActions == Qt.MoveAction"), true);
+ QCOMPARE(evaluate<bool>(item, "supportedActions == Qt.MoveAction"), true);
+ QCOMPARE(dropTarget.supportedActions, Qt::MoveAction);
+}
+
+void tst_QSGDrag::proposedAction()
+{
+ QSGCanvas canvas;
+ TestDropTarget dropTarget(canvas.rootItem());
+ dropTarget.setSize(QSizeF(100, 100));
+ QDeclarativeComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "Item {\n"
+ "property int proposedAction: Drag.proposedAction\n"
+ "x: 50; y: 50\n"
+ "width: 10; height: 10\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QSGItem *item = qobject_cast<QSGItem *>(object.data());
+ QVERIFY(item);
+ item->setParentItem(&dropTarget);
+
+
+ QCOMPARE(evaluate<bool>(item, "Drag.proposedAction == Qt.MoveAction"), true);
+ QCOMPARE(evaluate<bool>(item, "proposedAction == Qt.MoveAction"), true);
+ evaluate<void>(item, "{ Drag.start(); Drag.cancel() }");
+ QCOMPARE(dropTarget.defaultAction, Qt::MoveAction);
+ QCOMPARE(dropTarget.proposedAction, Qt::MoveAction);
+
+ evaluate<void>(item, "Drag.proposedAction = Qt.CopyAction");
+ QCOMPARE(evaluate<bool>(item, "Drag.proposedAction == Qt.CopyAction"), true);
+ QCOMPARE(evaluate<bool>(item, "proposedAction == Qt.CopyAction"), true);
+ evaluate<void>(item, "Drag.start()");
+ QCOMPARE(dropTarget.defaultAction, Qt::CopyAction);
+ QCOMPARE(dropTarget.proposedAction, Qt::CopyAction);
+
+ // The proposed action can change during a drag.
+ evaluate<void>(item, "Drag.proposedAction = Qt.MoveAction");
+ QCOMPARE(evaluate<bool>(item, "Drag.proposedAction == Qt.MoveAction"), true);
+ QCOMPARE(evaluate<bool>(item, "proposedAction == Qt.MoveAction"), true);
+ item->setPos(QPointF(60, 60));
+ QCOMPARE(dropTarget.defaultAction, Qt::MoveAction);
+ QCOMPARE(dropTarget.proposedAction, Qt::MoveAction);
+
+ evaluate<void>(item, "Drag.proposedAction = Qt.LinkAction");
+ QCOMPARE(evaluate<bool>(item, "Drag.proposedAction == Qt.LinkAction"), true);
+ QCOMPARE(evaluate<bool>(item, "proposedAction == Qt.LinkAction"), true);
+ evaluate<void>(item, "Drag.drop()");
+ QCOMPARE(dropTarget.defaultAction, Qt::LinkAction);
+ QCOMPARE(dropTarget.proposedAction, Qt::LinkAction);
+}
+
+void tst_QSGDrag::keys()
+{
+ QDeclarativeComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "Item {\n"
+ "property variant keys: Drag.keys\n"
+ "x: 50; y: 50\n"
+ "width: 10; height: 10\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QSGItem *item = qobject_cast<QSGItem *>(object.data());
+ QVERIFY(item);
+
+// QCOMPARE(evaluate<QStringList>(item, "Drag.keys"), QStringList());
+// QCOMPARE(evaluate<QStringList>(item, "keys"), QStringList());
+ QCOMPARE(item->property("keys").toStringList(), QStringList());
+
+ evaluate<void>(item, "Drag.keys = [\"red\", \"blue\"]");
+// QCOMPARE(evaluate<QStringList>(item, "Drag.keys"), QStringList() << "red" << "blue");
+// QCOMPARE(evaluate<QStringList>(item, "keys"), QStringList() << "red" << "blue");
+ QCOMPARE(item->property("keys").toStringList(), QStringList() << "red" << "blue");
+}
+
+void tst_QSGDrag::source()
+{
+
+ QDeclarativeComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "Item {\n"
+ "property Item source: Drag.source\n"
+ "x: 50; y: 50\n"
+ "width: 10; height: 10\n"
+ "Item { id: proxySource; objectName: \"proxySource\" }\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QSGItem *item = qobject_cast<QSGItem *>(object.data());
+ QVERIFY(item);
+
+ QCOMPARE(evaluate<QObject *>(item, "Drag.source"), static_cast<QObject *>(item));
+ QCOMPARE(evaluate<QObject *>(item, "source"), static_cast<QObject *>(item));
+
+ QSGItem *proxySource = item->findChild<QSGItem *>("proxySource");
+ QVERIFY(proxySource);
+
+ evaluate<void>(item, "Drag.source = proxySource");
+ QCOMPARE(evaluate<QObject *>(item, "Drag.source"), static_cast<QObject *>(proxySource));
+ QCOMPARE(evaluate<QObject *>(item, "source"), static_cast<QObject *>(proxySource));
+
+ evaluate<void>(item, "Drag.source = undefined");
+ QCOMPARE(evaluate<QObject *>(item, "Drag.source"), static_cast<QObject *>(item));
+ QCOMPARE(evaluate<QObject *>(item, "source"), static_cast<QObject *>(item));
+}
+
+QTEST_MAIN(tst_QSGDrag)
+
+#include "tst_qsgdrag.moc"
diff --git a/tests/auto/declarative/qsgdroparea/qsgdroparea.pro b/tests/auto/declarative/qsgdroparea/qsgdroparea.pro
new file mode 100644
index 0000000000..f07071f9dc
--- /dev/null
+++ b/tests/auto/declarative/qsgdroparea/qsgdroparea.pro
@@ -0,0 +1,9 @@
+TARGET = tst_qsgdroparea
+CONFIG += testcase
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qsgdroparea.cpp
+
+CONFIG += parallel_test
+
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qsgdroparea/tst_qsgdroparea.cpp b/tests/auto/declarative/qsgdroparea/tst_qsgdroparea.cpp
new file mode 100644
index 0000000000..1c303b4b3e
--- /dev/null
+++ b/tests/auto/declarative/qsgdroparea/tst_qsgdroparea.cpp
@@ -0,0 +1,1110 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtTest/QSignalSpy>
+#include <QtDeclarative/qsgitem.h>
+#include <QtDeclarative/qsgview.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativeexpression.h>
+
+#include <QtGui/qwindowsysteminterface_qpa.h>
+
+template <typename T> static T evaluate(QObject *scope, const QString &expression)
+{
+ QDeclarativeExpression expr(qmlContext(scope), scope, expression);
+ QVariant result = expr.evaluate();
+ if (expr.hasError())
+ qWarning() << expr.error().toString();
+ return result.value<T>();
+}
+
+template <> void evaluate<void>(QObject *scope, const QString &expression)
+{
+ QDeclarativeExpression expr(qmlContext(scope), scope, expression);
+ expr.evaluate();
+ if (expr.hasError())
+ qWarning() << expr.error().toString();
+}
+
+class tst_QSGDropArea: public QObject
+{
+ Q_OBJECT
+private slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+ void containsDrag_internal();
+ void containsDrag_external();
+ void keys_internal();
+ void keys_external();
+ void source_internal();
+// void source_external();
+ void position_internal();
+ void position_external();
+ void drop_internal();
+// void drop_external();
+ void simultaneousDrags();
+
+private:
+ QDeclarativeEngine engine;
+};
+
+void tst_QSGDropArea::initTestCase()
+{
+
+}
+
+void tst_QSGDropArea::cleanupTestCase()
+{
+
+}
+
+void tst_QSGDropArea::containsDrag_internal()
+{
+ QSGCanvas canvas;
+ QDeclarativeComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "DropArea {\n"
+ "property bool hasDrag: containsDrag\n"
+ "property int enterEvents: 0\n"
+ "property int exitEvents: 0\n"
+ "width: 100; height: 100\n"
+ "onEntered: {++enterEvents}\n"
+ "onExited: {++exitEvents}\n"
+ "Item {\n"
+ "objectName: \"dragItem\"\n"
+ "x: 50; y: 50\n"
+ "width: 10; height: 10\n"
+ "}\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QSGItem *dropArea = qobject_cast<QSGItem *>(object.data());
+ QVERIFY(dropArea);
+ dropArea->setParentItem(canvas.rootItem());
+
+ QSGItem *dragItem = dropArea->findChild<QSGItem *>("dragItem");
+ QVERIFY(dragItem);
+
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
+ QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
+
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
+ QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0);
+
+ evaluate<void>(dropArea, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dragItem, "Drag.active = false");
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
+ QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 1);
+
+ evaluate<void>(dropArea, "{ enterEvents = 0; exitEvents = 0 }");
+
+ dragItem->setPos(QPointF(150, 50));
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
+ QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0);
+
+ dragItem->setPos(QPointF(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
+ QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0);
+
+ evaluate<void>(dropArea, "{ enterEvents = 0; exitEvents = 0 }");
+ dragItem->setPos(QPointF(150, 50));
+
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
+ QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 1);
+
+ evaluate<void>(dragItem, "Drag.active = false");
+}
+
+void tst_QSGDropArea::containsDrag_external()
+{
+ QSGCanvas canvas;
+ QDeclarativeComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "DropArea {\n"
+ "property bool hasDrag: containsDrag\n"
+ "property int enterEvents: 0\n"
+ "property int exitEvents: 0\n"
+ "width: 100; height: 100\n"
+ "onEntered: {++enterEvents}\n"
+ "onExited: {++exitEvents}\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QSGItem *dropArea = qobject_cast<QSGItem *>(object.data());
+ dropArea->setParentItem(canvas.rootItem());
+
+ QMimeData data;
+ QSGCanvas alternateCanvas;
+
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
+ QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
+
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
+ QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0);
+
+ evaluate<void>(dropArea, "{ enterEvents = 0; exitEvents = 0 }");
+ QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
+ QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 1);
+
+ evaluate<void>(dropArea, "{ enterEvents = 0; exitEvents = 0 }");
+
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(150, 50));
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
+ QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0);
+
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
+ QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0);
+
+ evaluate<void>(dropArea, "{ enterEvents = 0; exitEvents = 0 }");
+
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(150, 50));
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
+ QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 1);
+
+ QWindowSystemInterface::handleDrop(&canvas, &data, QPoint(150, 50));
+}
+
+void tst_QSGDropArea::keys_internal()
+{
+ QSGCanvas canvas;
+ QDeclarativeComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "DropArea {\n"
+ "property variant dragKeys\n"
+ "property variant dropKeys: keys\n"
+ "property int enterEvents: 0\n"
+ "width: 100; height: 100\n"
+ "onEntered: {++enterEvents; dragKeys = drag.keys }\n"
+ "Item {\n"
+ "objectName: \"dragItem\"\n"
+ "x: 50; y: 50\n"
+ "width: 10; height: 10\n"
+ "Drag.keys: [\"red\", \"blue\"]\n"
+ "}\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QSGItem *dropArea = qobject_cast<QSGItem *>(object.data());
+ dropArea->setParentItem(canvas.rootItem());
+
+ QSGItem *dragItem = dropArea->findChild<QSGItem *>("dragItem");
+ QVERIFY(dragItem);
+
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
+
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue");
+
+ evaluate<void>(dragItem, "Drag.active = false");
+ evaluate<void>(dropArea, "keys = \"blue\"");
+ QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "blue");
+ QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "blue");
+ evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue");
+
+ evaluate<void>(dragItem, "Drag.active = false");
+ evaluate<void>(dropArea, "keys = \"red\"");
+ QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "red");
+ QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "red");
+ evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue");
+
+ evaluate<void>(dragItem, "Drag.active = false");
+ evaluate<void>(dropArea, "keys = \"green\"");
+ QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "green");
+ QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "green");
+ evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
+
+ evaluate<void>(dragItem, "Drag.active = false");
+ evaluate<void>(dropArea, "keys = [\"red\", \"green\"]");
+ QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "red" << "green");
+ QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "red" << "green");
+ evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue");
+
+ evaluate<void>(dragItem, "Drag.active = false");
+ evaluate<void>(dragItem, "Drag.keys = []");
+ evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
+
+ evaluate<void>(dragItem, "Drag.active = false");
+ evaluate<void>(dropArea, "keys = []");
+ QCOMPARE(dropArea->property("keys").toStringList(), QStringList());
+ QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList());
+ evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList());
+
+ evaluate<void>(dragItem, "Drag.active = false");
+ evaluate<void>(dropArea, "keys = []");
+ evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList());
+
+ evaluate<void>(dragItem, "Drag.active = false");
+ evaluate<void>(dragItem, "Drag.keys = [\"red\", \"blue\"]");
+ evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue");
+}
+
+void tst_QSGDropArea::keys_external()
+{
+ QSGCanvas canvas;
+ QDeclarativeComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "DropArea {\n"
+ "property variant dragKeys\n"
+ "property variant dropKeys: keys\n"
+ "property int enterEvents: 0\n"
+ "width: 100; height: 100\n"
+ "onEntered: {++enterEvents; dragKeys = drag.keys }\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QSGItem *dropArea = qobject_cast<QSGItem *>(object.data());
+ dropArea->setParentItem(canvas.rootItem());
+
+ QMimeData data;
+ QSGCanvas alternateCanvas;
+
+ data.setData("text/x-red", "red");
+ data.setData("text/x-blue", "blue");
+
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
+
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue");
+
+ QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50));
+ evaluate<void>(dropArea, "keys = \"text/x-blue\"");
+ QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-blue");
+ QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-blue");
+ evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }");
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue");
+
+ QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50));
+ evaluate<void>(dropArea, "keys = \"text/x-red\"");
+ QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-red");
+ QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-red");
+ evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }");
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue");
+
+ QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50));
+ evaluate<void>(dropArea, "keys = \"text/x-green\"");
+ QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-green");
+ QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-green");
+ evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }");
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
+
+ QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50));
+ evaluate<void>(dropArea, "keys = [\"text/x-red\", \"text/x-green\"]");
+ QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-red" << "text/x-green");
+ QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-red" << "text/x-green");
+ evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }");
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue");
+
+ QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50));
+ data.removeFormat("text/x-red");
+ data.removeFormat("text/x-blue");
+ evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }");
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
+
+ QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50));
+ evaluate<void>(dropArea, "keys = []");
+ QCOMPARE(dropArea->property("keys").toStringList(), QStringList());
+ QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList());
+ evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }");
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList());
+
+ QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50));
+ data.setData("text/x-red", "red");
+ data.setData("text/x-blue", "blue");
+ QCOMPARE(dropArea->property("keys").toStringList(), QStringList());
+ QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList());
+ evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }");
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue");
+
+ QWindowSystemInterface::handleDrop(&canvas, &data, QPoint(50, 50));
+}
+
+void tst_QSGDropArea::source_internal()
+{
+ QSGCanvas canvas;
+ QDeclarativeComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "DropArea {\n"
+ "property Item source: drag.source\n"
+ "property Item eventSource\n"
+ "width: 100; height: 100\n"
+ "onEntered: {eventSource = drag.source}\n"
+ "Item {\n"
+ "objectName: \"dragItem\"\n"
+ "x: 50; y: 50\n"
+ "width: 10; height: 10\n"
+ "}\n"
+ "Item { id: dragSource; objectName: \"dragSource\" }\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QSGItem *dropArea = qobject_cast<QSGItem *>(object.data());
+ dropArea->setParentItem(canvas.rootItem());
+
+ QSGItem *dragItem = dropArea->findChild<QSGItem *>("dragItem");
+ QVERIFY(dragItem);
+
+ QSGItem *dragSource = dropArea->findChild<QSGItem *>("dragSource");
+ QVERIFY(dragSource);
+
+ QCOMPARE(evaluate<QObject *>(dropArea, "source"), static_cast<QObject *>(0));
+ QCOMPARE(evaluate<QObject *>(dropArea, "drag.source"), static_cast<QObject *>(0));
+
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<QObject *>(dropArea, "source"), static_cast<QObject *>(dragItem));
+ QCOMPARE(evaluate<QObject *>(dropArea, "drag.source"), static_cast<QObject *>(dragItem));
+ QCOMPARE(evaluate<QObject *>(dropArea, "eventSource"), static_cast<QObject *>(dragItem));
+
+ evaluate<void>(dragItem, "Drag.active = false");
+ QCOMPARE(evaluate<QObject *>(dropArea, "source"), static_cast<QObject *>(0));
+ QCOMPARE(evaluate<QObject *>(dropArea, "drag.source"), static_cast<QObject *>(0));
+
+
+ evaluate<void>(dropArea, "{ eventSource = null }");
+ evaluate<void>(dragItem, "Drag.source = dragSource");
+
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<QObject *>(dropArea, "source"), static_cast<QObject *>(dragSource));
+ QCOMPARE(evaluate<QObject *>(dropArea, "drag.source"), static_cast<QObject *>(dragSource));
+ QCOMPARE(evaluate<QObject *>(dropArea, "eventSource"), static_cast<QObject *>(dragSource));
+
+ evaluate<void>(dragItem, "Drag.active = false");
+ QCOMPARE(evaluate<QObject *>(dropArea, "source"), static_cast<QObject *>(0));
+ QCOMPARE(evaluate<QObject *>(dropArea, "drag.source"), static_cast<QObject *>(0));
+}
+
+// Setting a source can't be emulated using the QWindowSystemInterface API.
+
+//void tst_QSGDropArea::source_external()
+//{
+//}
+
+void tst_QSGDropArea::position_internal()
+{
+ QSGCanvas canvas;
+ QDeclarativeComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "DropArea {\n"
+ "property real dragX: drag.x\n"
+ "property real dragY: drag.y\n"
+ "property real eventX\n"
+ "property real eventY\n"
+ "property int enterEvents: 0\n"
+ "property int moveEvents: 0\n"
+ "width: 100; height: 100\n"
+ "onEntered: {++enterEvents; eventX = drag.x; eventY = drag.y}\n"
+ "onPositionChanged: {++moveEvents; eventX = drag.x; eventY = drag.y}\n"
+ "Item {\n"
+ "objectName: \"dragItem\"\n"
+ "x: 50; y: 50\n"
+ "width: 10; height: 10\n"
+ "}\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QSGItem *dropArea = qobject_cast<QSGItem *>(object.data());
+ dropArea->setParentItem(canvas.rootItem());
+
+ QSGItem *dragItem = dropArea->findChild<QSGItem *>("dragItem");
+ QVERIFY(dragItem);
+
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 0);
+ QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(50));
+ QCOMPARE(evaluate<qreal>(dropArea, "drag.y"), qreal(50));
+ QCOMPARE(evaluate<qreal>(dropArea, "dragX"), qreal(50));
+ QCOMPARE(evaluate<qreal>(dropArea, "dragY"), qreal(50));
+ QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(50));
+ QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(50));
+
+ evaluate<void>(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }");
+ dragItem->setPos(QPointF(40, 50));
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1);
+ QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(40));
+ QCOMPARE(evaluate<qreal>(dropArea, "drag.y"), qreal(50));
+ QCOMPARE(evaluate<qreal>(dropArea, "dragX"), qreal(40));
+ QCOMPARE(evaluate<qreal>(dropArea, "dragY"), qreal(50));
+ QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(40));
+ QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(50));
+
+ evaluate<void>(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }");
+ dragItem->setPos(QPointF(75, 25));
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1);
+ QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(75));
+ QCOMPARE(evaluate<qreal>(dropArea, "drag.y"), qreal(25));
+ QCOMPARE(evaluate<qreal>(dropArea, "dragX"), qreal(75));
+ QCOMPARE(evaluate<qreal>(dropArea, "dragY"), qreal(25));
+ QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(75));
+ QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(25));
+
+ evaluate<void>(dragItem, "Drag.active = false");
+}
+
+void tst_QSGDropArea::position_external()
+{
+ QSGCanvas canvas;
+ QDeclarativeComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "DropArea {\n"
+ "property real dragX: drag.x\n"
+ "property real dragY: drag.y\n"
+ "property real eventX\n"
+ "property real eventY\n"
+ "property int enterEvents: 0\n"
+ "property int moveEvents: 0\n"
+ "width: 100; height: 100\n"
+ "onEntered: {++enterEvents; eventX = drag.x; eventY = drag.y}\n"
+ "onPositionChanged: {++moveEvents; eventX = drag.x; eventY = drag.y}\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QSGItem *dropArea = qobject_cast<QSGItem *>(object.data());
+ dropArea->setParentItem(canvas.rootItem());
+
+ QMimeData data;
+
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1);
+ QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(50));
+ QCOMPARE(evaluate<qreal>(dropArea, "drag.y"), qreal(50));
+ QCOMPARE(evaluate<qreal>(dropArea, "dragX"), qreal(50));
+ QCOMPARE(evaluate<qreal>(dropArea, "dragY"), qreal(50));
+ QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(50));
+ QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(50));
+
+ evaluate<void>(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }");
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(40, 50));
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1);
+ QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(40));
+ QCOMPARE(evaluate<qreal>(dropArea, "drag.y"), qreal(50));
+ QCOMPARE(evaluate<qreal>(dropArea, "dragX"), qreal(40));
+ QCOMPARE(evaluate<qreal>(dropArea, "dragY"), qreal(50));
+ QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(40));
+ QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(50));
+
+ evaluate<void>(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }");
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(75, 25));
+ QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1);
+ QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(75));
+ QCOMPARE(evaluate<qreal>(dropArea, "drag.y"), qreal(25));
+ QCOMPARE(evaluate<qreal>(dropArea, "dragX"), qreal(75));
+ QCOMPARE(evaluate<qreal>(dropArea, "dragY"), qreal(25));
+ QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(75));
+ QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(25));
+
+ QWindowSystemInterface::handleDrop(&canvas, &data, QPoint(75, 25));
+}
+
+void tst_QSGDropArea::drop_internal()
+{
+ QSGCanvas canvas;
+ QDeclarativeComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "DropArea {\n"
+ "property bool accept: false\n"
+ "property bool setAccepted: false\n"
+ "property bool acceptDropAction: false\n"
+ "property bool setDropAction: false\n"
+ "property int dropAction: Qt.IgnoreAction\n"
+ "property int proposedAction: Qt.IgnoreAction\n"
+ "property int supportedActions: Qt.IgnoreAction\n"
+ "property int dropEvents: 0\n"
+ "width: 100; height: 100\n"
+ "onDropped: {\n"
+ "++dropEvents\n"
+ "supportedActions = drop.supportedActions\n"
+ "proposedAction = drop.action\n"
+ "if (setDropAction)\n"
+ "drop.action = dropAction\n"
+ "if (acceptDropAction)\n"
+ "drop.accept(dropAction)\n"
+ "else if (setAccepted)\n"
+ "drop.accepted = accept\n"
+ "else if (accept)\n"
+ "drop.accept()\n"
+ "}\n"
+ "Item {\n"
+ "objectName: \"dragItem\"\n"
+ "x: 50; y: 50\n"
+ "width: 10; height: 10\n"
+ "}\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QSGItem *dropArea = qobject_cast<QSGItem *>(object.data());
+ dropArea->setParentItem(canvas.rootItem());
+
+ QSGItem *dragItem = dropArea->findChild<QSGItem *>("dragItem");
+ QVERIFY(dragItem);
+
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::IgnoreAction));
+ QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction));
+ QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction));
+
+ evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
+ evaluate<void>(dropArea, "{ accept = true; setDropAction = true; dropAction = Qt.LinkAction }");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::LinkAction));
+ QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction));
+ QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction));
+
+ evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
+ evaluate<void>(dropArea, "{ setAccepted = true; }");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::LinkAction));
+ QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction));
+ QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction));
+
+ evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
+ evaluate<void>(dropArea, "{ accept = false; setAccepted = true; }");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::IgnoreAction));
+ QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction));
+ QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction));
+
+ evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
+ evaluate<void>(dropArea, "{ setAccepted = false; setDropAction = false; acceptDropAction = true; }");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::LinkAction));
+ QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction));
+ QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction));
+
+ evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
+ evaluate<void>(dropArea, "{ acceptDropAction = false; dropAction = Qt.IgnoreAction; accept = true }");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::MoveAction));
+ QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction));
+ QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction));
+
+ evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
+ evaluate<void>(dropArea, "{ setAccepted = true }");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::MoveAction));
+ QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction));
+ QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction));
+
+ evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
+ evaluate<void>(dropArea, "{ setAccepted = false }");
+ evaluate<void>(dragItem, "Drag.supportedActions = Qt.LinkAction");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::MoveAction));
+ QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::LinkAction));
+ QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction));
+
+ evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
+ evaluate<void>(dropArea, "{ setAccepted = true }");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::MoveAction));
+ QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::LinkAction));
+ QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction));
+
+ evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
+ evaluate<void>(dropArea, "{ setAccepted = false }");
+ evaluate<void>(dragItem, "Drag.proposedAction = Qt.LinkAction");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::LinkAction));
+ QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::LinkAction));
+ QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::LinkAction));
+
+ evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
+ evaluate<void>(dropArea, "{ setAccepted = true }");
+ evaluate<void>(dragItem, "Drag.active = true");
+ QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::LinkAction));
+ QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::LinkAction));
+ QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::LinkAction));
+}
+
+// Setting the supportedActions can't be emulated using the QWindowSystemInterface API.
+
+//void tst_QSGDropArea::drop_external()
+//{
+//}
+
+void tst_QSGDropArea::simultaneousDrags()
+{
+ QSGCanvas canvas;
+ QDeclarativeComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "DropArea {\n"
+ "property int enterEvents: 0\n"
+ "property int exitEvents: 0\n"
+ "width: 100; height: 100\n"
+ "keys: [\"red\", \"text/x-red\"]\n"
+ "onEntered: {++enterEvents}\n"
+ "onExited: {++exitEvents}\n"
+ "DropArea {\n"
+ "objectName: \"dropArea2\"\n"
+ "property int enterEvents: 0\n"
+ "property int exitEvents: 0\n"
+ "width: 100; height: 100\n"
+ "keys: [\"blue\", \"text/x-blue\"]\n"
+ "onEntered: {++enterEvents}\n"
+ "onExited: {++exitEvents}\n"
+ "}\n"
+ "Item {\n"
+ "objectName: \"dragItem1\"\n"
+ "x: 50; y: 50\n"
+ "width: 10; height: 10\n"
+ "Drag.keys: [\"red\", \"blue\"]"
+ "}\n"
+ "Item {\n"
+ "objectName: \"dragItem2\"\n"
+ "x: 50; y: 50\n"
+ "width: 10; height: 10\n"
+ "Drag.keys: [\"red\", \"blue\"]"
+ "}\n"
+ "}", QUrl());
+
+ QScopedPointer<QObject> object(component.create());
+ QSGItem *dropArea1 = qobject_cast<QSGItem *>(object.data());
+ dropArea1->setParentItem(canvas.rootItem());
+
+ QSGItem *dropArea2 = dropArea1->findChild<QSGItem *>("dropArea2");
+ QVERIFY(dropArea2);
+
+ QSGItem *dragItem1 = dropArea1->findChild<QSGItem *>("dragItem1");
+ QVERIFY(dragItem1);
+
+ QSGItem *dragItem2 = dropArea1->findChild<QSGItem *>("dragItem2");
+ QVERIFY(dragItem2);
+
+ QMimeData data;
+ data.setData("text/x-red", "red");
+ data.setData("text/x-blue", "blue");
+
+ QSGCanvas alternateCanvas;
+
+ // Mixed internal drags.
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dragItem1, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dragItem2, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ evaluate<void>(dragItem2, "Drag.active = false");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ evaluate<void>(dragItem2, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ evaluate<void>(dragItem1, "Drag.active = false");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1);
+
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dragItem2, "Drag.active = false");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ // internal then external.
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dragItem1, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ evaluate<void>(dragItem1, "Drag.active = false");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1);
+
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ // external then internal.
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dragItem2, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ evaluate<void>(dragItem2, "Drag.active = false");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ evaluate<void>(dragItem2, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1);
+
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dragItem2, "Drag.active = false");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ // Different acceptance
+ evaluate<void>(dragItem1, "Drag.keys = \"red\"");
+ evaluate<void>(dragItem2, "Drag.keys = \"blue\"");
+ data.removeFormat("text/x-red");
+
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dragItem1, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dragItem2, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dragItem2, "Drag.active = false");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1);
+
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dragItem2, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dragItem1, "Drag.active = false");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dragItem2, "Drag.active = false");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1);
+
+ // internal then external
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dragItem1, "Drag.active = true");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1);
+
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dragItem1, "Drag.active = false");
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
+
+ evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }");
+ evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }");
+ QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50));
+ QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
+ QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
+ QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
+ QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1);
+
+ QWindowSystemInterface::handleDrop(&alternateCanvas, &data, QPoint(50, 50));
+}
+
+QTEST_MAIN(tst_QSGDropArea)
+
+#include "tst_qsgdroparea.moc"
diff --git a/tests/auto/declarative/qsgflickable/data/margins.qml b/tests/auto/declarative/qsgflickable/data/margins.qml
new file mode 100644
index 0000000000..4866bd8301
--- /dev/null
+++ b/tests/auto/declarative/qsgflickable/data/margins.qml
@@ -0,0 +1,19 @@
+import QtQuick 2.0
+
+Flickable {
+ width: 200; height: 200
+ contentWidth: row.width; contentHeight: row.height
+
+ topMargin: 20
+ bottomMargin: 30
+ leftMargin: 40
+ rightMargin: 50
+
+ Row {
+ id: row
+ Repeater {
+ model: 4
+ Rectangle { width: 400; height: 600; color: "blue" }
+ }
+ }
+}
diff --git a/tests/auto/declarative/qsgflickable/qsgflickable.pro b/tests/auto/declarative/qsgflickable/qsgflickable.pro
index 61197dfe1b..48cf8b6335 100644
--- a/tests/auto/declarative/qsgflickable/qsgflickable.pro
+++ b/tests/auto/declarative/qsgflickable/qsgflickable.pro
@@ -1,18 +1,12 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui
+CONFIG += testcase
+TARGET = tst_qsgflickable
macx:CONFIG -= app_bundle
SOURCES += tst_qsgflickable.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-#temporary
-CONFIG += insignificant_test
-QT += core-private gui-private v8-private declarative-private
+QT += core-private gui-private v8-private declarative-private testlib
diff --git a/tests/auto/declarative/qsgflickable/tst_qsgflickable.cpp b/tests/auto/declarative/qsgflickable/tst_qsgflickable.cpp
index e75914a746..f8d7bfd28d 100644
--- a/tests/auto/declarative/qsgflickable/tst_qsgflickable.cpp
+++ b/tests/auto/declarative/qsgflickable/tst_qsgflickable.cpp
@@ -46,14 +46,9 @@
#include <private/qsgflickable_p.h>
#include <private/qdeclarativevaluetype_p.h>
#include <math.h>
-#include "../../../shared/util.h"
+#include "../shared/util.h"
#include <QtOpenGL/QGLShaderProgram>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qsgflickable : public QObject
{
Q_OBJECT
@@ -80,6 +75,7 @@ private slots:
void movingAndDragging();
void disabled();
void flickVelocity();
+ void margins();
private:
QDeclarativeEngine engine;
@@ -106,7 +102,7 @@ void tst_qsgflickable::cleanupTestCase()
void tst_qsgflickable::create()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/flickable01.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable01.qml")));
QSGFlickable *obj = qobject_cast<QSGFlickable*>(c.create());
QVERIFY(obj != 0);
@@ -131,7 +127,7 @@ void tst_qsgflickable::create()
void tst_qsgflickable::horizontalViewportSize()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/flickable02.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable02.qml")));
QSGFlickable *obj = qobject_cast<QSGFlickable*>(c.create());
QVERIFY(obj != 0);
@@ -148,7 +144,7 @@ void tst_qsgflickable::horizontalViewportSize()
void tst_qsgflickable::verticalViewportSize()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/flickable03.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable03.qml")));
QSGFlickable *obj = qobject_cast<QSGFlickable*>(c.create());
QVERIFY(obj != 0);
@@ -165,7 +161,7 @@ void tst_qsgflickable::verticalViewportSize()
void tst_qsgflickable::properties()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/flickable04.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable04.qml")));
QSGFlickable *obj = qobject_cast<QSGFlickable*>(c.create());
QVERIFY(obj != 0);
@@ -265,7 +261,7 @@ void tst_qsgflickable::pressDelay()
void tst_qsgflickable::nestedPressDelay()
{
QSGView *canvas = new QSGView;
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/nestedPressDelay.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("nestedPressDelay.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
@@ -320,7 +316,7 @@ void tst_qsgflickable::flickableDirection()
void tst_qsgflickable::resizeContent()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/resize.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("resize.qml")));
QSGItem *root = qobject_cast<QSGItem*>(c.create());
QSGFlickable *obj = findItem<QSGFlickable>(root, "flick");
@@ -344,7 +340,7 @@ void tst_qsgflickable::resizeContent()
void tst_qsgflickable::returnToBounds()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/resize.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("resize.qml")));
QSGItem *root = qobject_cast<QSGItem*>(c.create());
QSGFlickable *obj = findItem<QSGFlickable>(root, "flick");
@@ -370,7 +366,7 @@ void tst_qsgflickable::returnToBounds()
void tst_qsgflickable::wheel()
{
QSGView *canvas = new QSGView;
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/wheel.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("wheel.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
@@ -405,7 +401,7 @@ void tst_qsgflickable::wheel()
void tst_qsgflickable::movingAndDragging()
{
QSGView *canvas = new QSGView;
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/flickable03.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("flickable03.qml")));
canvas->show();
canvas->requestActivateWindow();
QTest::qWaitForWindowShown(canvas);
@@ -510,7 +506,7 @@ void tst_qsgflickable::movingAndDragging()
void tst_qsgflickable::disabled()
{
QSGView *canvas = new QSGView;
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/disabled.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("disabled.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
@@ -538,11 +534,11 @@ void tst_qsgflickable::disabled()
void tst_qsgflickable::flickVelocity()
{
#ifdef Q_WS_MAC
- QSKIP("Producing flicks on Mac CI impossible due to timing problems", SkipAll);
+ QSKIP("Producing flicks on Mac CI impossible due to timing problems");
#endif
QSGView *canvas = new QSGView;
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/flickable03.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("flickable03.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
@@ -563,6 +559,65 @@ void tst_qsgflickable::flickVelocity()
delete canvas;
}
+void tst_qsgflickable::margins()
+{
+ QDeclarativeEngine engine;
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("margins.qml")));
+ QSGItem *root = qobject_cast<QSGItem*>(c.create());
+ QSGFlickable *obj = qobject_cast<QSGFlickable*>(root);
+ QVERIFY(obj != 0);
+
+ // starting state
+ QCOMPARE(obj->contentX(), -40.);
+ QCOMPARE(obj->contentY(), -20.);
+ QCOMPARE(obj->contentWidth(), 1600.);
+ QCOMPARE(obj->contentHeight(), 600.);
+ QCOMPARE(obj->xOrigin(), 0.);
+ QCOMPARE(obj->yOrigin(), 0.);
+
+ // Reduce left margin
+ obj->setLeftMargin(30);
+ QTRY_COMPARE(obj->contentX(), -30.);
+
+ // Reduce top margin
+ obj->setTopMargin(20);
+ QTRY_COMPARE(obj->contentY(), -20.);
+
+ // position to the far right, including margin
+ obj->setContentX(1600 + 50 - obj->width());
+ obj->returnToBounds();
+ QTest::qWait(200);
+ QCOMPARE(obj->contentX(), 1600. + 50. - obj->width());
+
+ // position beyond the far right, including margin
+ obj->setContentX(1600 + 50 - obj->width() + 1.);
+ obj->returnToBounds();
+ QTRY_COMPARE(obj->contentX(), 1600. + 50. - obj->width());
+
+ // Reduce right margin
+ obj->setRightMargin(40);
+ QTRY_COMPARE(obj->contentX(), 1600. + 40. - obj->width());
+ QCOMPARE(obj->contentWidth(), 1600.);
+
+ // position to the far bottom, including margin
+ obj->setContentY(600 + 30 - obj->height());
+ obj->returnToBounds();
+ QTest::qWait(200);
+ QCOMPARE(obj->contentY(), 600. + 30. - obj->height());
+
+ // position beyond the far bottom, including margin
+ obj->setContentY(600 + 30 - obj->height() + 1.);
+ obj->returnToBounds();
+ QTRY_COMPARE(obj->contentY(), 600. + 30. - obj->height());
+
+ // Reduce bottom margin
+ obj->setBottomMargin(20);
+ QTRY_COMPARE(obj->contentY(), 600. + 20. - obj->height());
+ QCOMPARE(obj->contentHeight(), 600.);
+
+ delete root;
+}
+
void tst_qsgflickable::flick(QSGView *canvas, const QPoint &from, const QPoint &to, int duration)
{
const int pointCount = 5;
@@ -588,7 +643,7 @@ T *tst_qsgflickable::findItem(QSGItem *parent, const QString &objectName)
//qDebug() << parent->childItems().count() << "children";
for (int i = 0; i < parent->childItems().count(); ++i) {
QSGItem *item = qobject_cast<QSGItem*>(parent->childItems().at(i));
- if(!item)
+ if (!item)
continue;
//qDebug() << "try" << item;
if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
diff --git a/tests/auto/declarative/qsgflipable/qsgflipable.pro b/tests/auto/declarative/qsgflipable/qsgflipable.pro
index e28de1b610..806aeb28e7 100644
--- a/tests/auto/declarative/qsgflipable/qsgflipable.pro
+++ b/tests/auto/declarative/qsgflipable/qsgflipable.pro
@@ -1,17 +1,13 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui
+CONFIG += testcase
+TARGET = tst_qsgflipable
macx:CONFIG -= app_bundle
SOURCES += tst_qsgflipable.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private
+QT += core-private gui-private v8-private declarative-private testlib
diff --git a/tests/auto/declarative/qsgflipable/tst_qsgflipable.cpp b/tests/auto/declarative/qsgflipable/tst_qsgflipable.cpp
index bd2090df2f..2fc1924c9a 100644
--- a/tests/auto/declarative/qsgflipable/tst_qsgflipable.cpp
+++ b/tests/auto/declarative/qsgflipable/tst_qsgflipable.cpp
@@ -48,12 +48,7 @@
#include <private/qsgrectangle_p.h>
#include <math.h>
#include <QtOpenGL/QGLShaderProgram>
-
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class tst_qsgflipable : public QObject
{
@@ -91,7 +86,7 @@ void tst_qsgflipable::cleanupTestCase()
void tst_qsgflipable::create()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/test-flipable.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-flipable.qml")));
QSGFlipable *obj = qobject_cast<QSGFlipable*>(c.create());
QVERIFY(obj != 0);
@@ -101,7 +96,7 @@ void tst_qsgflipable::create()
void tst_qsgflipable::checkFrontAndBack()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/test-flipable.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-flipable.qml")));
QSGFlipable *obj = qobject_cast<QSGFlipable*>(c.create());
QVERIFY(obj != 0);
@@ -113,7 +108,7 @@ void tst_qsgflipable::checkFrontAndBack()
void tst_qsgflipable::setFrontAndBack()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/test-flipable.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-flipable.qml")));
QSGFlipable *obj = qobject_cast<QSGFlipable*>(c.create());
QVERIFY(obj != 0);
@@ -133,7 +128,7 @@ void tst_qsgflipable::setFrontAndBack()
void tst_qsgflipable::QTBUG_9161_crash()
{
QSGView *canvas = new QSGView;
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/crash.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("crash.qml")));
QSGItem *root = canvas->rootObject();
QVERIFY(root != 0);
canvas->show();
@@ -143,7 +138,7 @@ void tst_qsgflipable::QTBUG_9161_crash()
void tst_qsgflipable::QTBUG_8474_qgv_abort()
{
QSGView *canvas = new QSGView;
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/flipable-abort.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("flipable-abort.qml")));
QSGItem *root = canvas->rootObject();
QVERIFY(root != 0);
canvas->show();
diff --git a/tests/auto/declarative/qsgfocusscope/qsgfocusscope.pro b/tests/auto/declarative/qsgfocusscope/qsgfocusscope.pro
index 375b497e3f..4b7b436ac6 100644
--- a/tests/auto/declarative/qsgfocusscope/qsgfocusscope.pro
+++ b/tests/auto/declarative/qsgfocusscope/qsgfocusscope.pro
@@ -1,16 +1,10 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qsgfocusscope
SOURCES += tst_qsgfocusscope.cpp
macx:CONFIG -= app_bundle
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
-QT += core-private gui-private declarative-private
-
-qpa:contains(QT_CONFIG,xcb):CONFIG+=insignificant_test # QTBUG-21054, unstable
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qsgfocusscope/tst_qsgfocusscope.cpp b/tests/auto/declarative/qsgfocusscope/tst_qsgfocusscope.cpp
index e2ac4c9e54..c70ba69f36 100644
--- a/tests/auto/declarative/qsgfocusscope/tst_qsgfocusscope.cpp
+++ b/tests/auto/declarative/qsgfocusscope/tst_qsgfocusscope.cpp
@@ -47,13 +47,7 @@
#include <private/qsgtextedit_p.h>
#include <private/qsgtext_p.h>
#include <QtDeclarative/private/qsgfocusscope_p.h>
-#include "../../../shared/util.h"
-#include <QtOpenGL/QGLShaderProgram>
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class tst_qsgfocusscope : public QObject
{
@@ -112,7 +106,7 @@ T *tst_qsgfocusscope::findItem(QSGItem *parent, const QString &objectName)
void tst_qsgfocusscope::basic()
{
QSGView *view = new QSGView;
- view->setSource(QUrl::fromLocalFile(SRCDIR "/data/test.qml"));
+ view->setSource(QUrl::fromLocalFile(TESTDATA("test.qml")));
QSGFocusScope *item0 = findItem<QSGFocusScope>(view->rootObject(), QLatin1String("item0"));
QSGRectangle *item1 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item1"));
@@ -154,7 +148,7 @@ void tst_qsgfocusscope::basic()
void tst_qsgfocusscope::nested()
{
QSGView *view = new QSGView;
- view->setSource(QUrl::fromLocalFile(SRCDIR "/data/test2.qml"));
+ view->setSource(QUrl::fromLocalFile(TESTDATA("test2.qml")));
QSGFocusScope *item1 = findItem<QSGFocusScope>(view->rootObject(), QLatin1String("item1"));
QSGFocusScope *item2 = findItem<QSGFocusScope>(view->rootObject(), QLatin1String("item2"));
@@ -183,7 +177,7 @@ void tst_qsgfocusscope::nested()
void tst_qsgfocusscope::noFocus()
{
QSGView *view = new QSGView;
- view->setSource(QUrl::fromLocalFile(SRCDIR "/data/test4.qml"));
+ view->setSource(QUrl::fromLocalFile(TESTDATA("test4.qml")));
QSGRectangle *item0 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item0"));
QSGRectangle *item1 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item1"));
@@ -221,7 +215,7 @@ void tst_qsgfocusscope::noFocus()
void tst_qsgfocusscope::textEdit()
{
QSGView *view = new QSGView;
- view->setSource(QUrl::fromLocalFile(SRCDIR "/data/test5.qml"));
+ view->setSource(QUrl::fromLocalFile(TESTDATA("test5.qml")));
QSGFocusScope *item0 = findItem<QSGFocusScope>(view->rootObject(), QLatin1String("item0"));
QSGTextEdit *item1 = findItem<QSGTextEdit>(view->rootObject(), QLatin1String("item1"));
@@ -237,7 +231,7 @@ void tst_qsgfocusscope::textEdit()
QTest::qWaitForWindowShown(view);
- QVERIFY(view->windowState() == Qt::WindowActive);
+ QTRY_VERIFY(view == qGuiApp->focusWindow());
QVERIFY(item0->hasActiveFocus() == true);
QVERIFY(item1->hasActiveFocus() == true);
QVERIFY(item2->hasActiveFocus() == false);
@@ -271,7 +265,7 @@ void tst_qsgfocusscope::textEdit()
void tst_qsgfocusscope::forceFocus()
{
QSGView *view = new QSGView;
- view->setSource(QUrl::fromLocalFile(SRCDIR "/data/forcefocus.qml"));
+ view->setSource(QUrl::fromLocalFile(TESTDATA("forcefocus.qml")));
QSGFocusScope *item0 = findItem<QSGFocusScope>(view->rootObject(), QLatin1String("item0"));
QSGRectangle *item1 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item1"));
@@ -319,7 +313,7 @@ void tst_qsgfocusscope::forceFocus()
void tst_qsgfocusscope::noParentFocus()
{
QSGView *view = new QSGView;
- view->setSource(QUrl::fromLocalFile(SRCDIR "/data/chain.qml"));
+ view->setSource(QUrl::fromLocalFile(TESTDATA("chain.qml")));
QVERIFY(view->rootObject());
view->show();
@@ -343,7 +337,7 @@ void tst_qsgfocusscope::noParentFocus()
void tst_qsgfocusscope::signalEmission()
{
QSGView *view = new QSGView;
- view->setSource(QUrl::fromLocalFile(SRCDIR "/data/signalEmission.qml"));
+ view->setSource(QUrl::fromLocalFile(TESTDATA("signalEmission.qml")));
QSGRectangle *item1 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item1"));
QSGRectangle *item2 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item2"));
@@ -398,7 +392,7 @@ void tst_qsgfocusscope::signalEmission()
void tst_qsgfocusscope::qtBug13380()
{
QSGView *view = new QSGView;
- view->setSource(QUrl::fromLocalFile(SRCDIR "/data/qtBug13380.qml"));
+ view->setSource(QUrl::fromLocalFile(TESTDATA("qtBug13380.qml")));
view->show();
QVERIFY(view->rootObject());
@@ -407,7 +401,7 @@ void tst_qsgfocusscope::qtBug13380()
QTest::qWaitForWindowShown(view);
- QVERIFY(view->windowState() == Qt::WindowActive);
+ QTRY_VERIFY(view == qGuiApp->focusWindow());
QVERIFY(view->rootObject()->property("noFocus").toBool());
view->rootObject()->setProperty("showRect", true);
@@ -419,7 +413,7 @@ void tst_qsgfocusscope::qtBug13380()
void tst_qsgfocusscope::forceActiveFocus()
{
QSGView *view = new QSGView;
- view->setSource(QUrl::fromLocalFile(SRCDIR "/data/forceActiveFocus.qml"));
+ view->setSource(QUrl::fromLocalFile(TESTDATA("forceActiveFocus.qml")));
view->show();
view->requestActivateWindow();
@@ -537,7 +531,7 @@ void tst_qsgfocusscope::forceActiveFocus()
void tst_qsgfocusscope::canvasFocus()
{
QSGView *view = new QSGView;
- view->setSource(QUrl::fromLocalFile(SRCDIR "/data/canvasFocus.qml"));
+ view->setSource(QUrl::fromLocalFile(TESTDATA("canvasFocus.qml")));
QSGItem *rootObject = view->rootObject();
QVERIFY(rootObject);
@@ -564,8 +558,8 @@ void tst_qsgfocusscope::canvasFocus()
QSignalSpy scope2ActiveFocusSpy(scope2, SIGNAL(activeFocusChanged(bool)));
QSignalSpy item2ActiveFocusSpy(item2, SIGNAL(activeFocusChanged(bool)));
- // until the canvas widget has gained focus, no one should have active focus
- QCOMPARE((view->windowState() == Qt::WindowActive), false);
+ QEXPECT_FAIL("", "QTBUG-21054 - Root item hasFocus returns true already", Abort);
+
QCOMPARE(rootItem->hasFocus(), false);
QCOMPARE(rootItem->hasActiveFocus(), false);
QCOMPARE(scope1->hasFocus(), true);
@@ -601,7 +595,7 @@ void tst_qsgfocusscope::canvasFocus()
QCOMPARE(item1ActiveFocusSpy.count(), 1);
- view->setWindowState(Qt::WindowNoState);
+ view->hide();
QCOMPARE(rootItem->hasFocus(), false);
QCOMPARE(rootItem->hasActiveFocus(), false);
QCOMPARE(scope1->hasFocus(), true);
@@ -641,7 +635,7 @@ void tst_qsgfocusscope::canvasFocus()
QCOMPARE(item2ActiveFocusSpy.count(), 0);
// give the canvas focus, and item2 will get active focus
- view->setWindowState(Qt::WindowActive);
+ view->show();
QCOMPARE(rootItem->hasFocus(), true);
QCOMPARE(rootItem->hasActiveFocus(), true);
diff --git a/tests/auto/declarative/qsggridview/data/ComponentView.qml b/tests/auto/declarative/qsggridview/data/ComponentView.qml
new file mode 100644
index 0000000000..12ab6c92d1
--- /dev/null
+++ b/tests/auto/declarative/qsggridview/data/ComponentView.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+
+GridView {
+ id: view
+
+ property string title
+
+ width: 100; height: 100;
+
+ model: 1
+ delegate: Text { objectName: "listItem"; text: view.title }
+ header: Text { objectName: "header"; text: view.title }
+ footer: Text { objectName: "footer"; text: view.title }
+}
diff --git a/tests/auto/declarative/qsggridview/data/creationContext.qml b/tests/auto/declarative/qsggridview/data/creationContext.qml
new file mode 100644
index 0000000000..79a682788b
--- /dev/null
+++ b/tests/auto/declarative/qsggridview/data/creationContext.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+ComponentView {
+ title: "Hello!"
+}
diff --git a/tests/auto/declarative/qsggridview/data/gridview4.qml b/tests/auto/declarative/qsggridview/data/gridview4.qml
index 01b31da082..eed3a2bdb1 100644
--- a/tests/auto/declarative/qsggridview/data/gridview4.qml
+++ b/tests/auto/declarative/qsggridview/data/gridview4.qml
@@ -1,7 +1,7 @@
import QtQuick 2.0
GridView {
- width: 400
+ width: 405
height: 200
cellWidth: width/9
cellHeight: height/2
diff --git a/tests/auto/declarative/qsggridview/data/margins.qml b/tests/auto/declarative/qsggridview/data/margins.qml
new file mode 100644
index 0000000000..d369658a91
--- /dev/null
+++ b/tests/auto/declarative/qsggridview/data/margins.qml
@@ -0,0 +1,55 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+
+ width: 240
+ height: 320
+ color: "#ffffff"
+ Component {
+ id: myDelegate
+ Rectangle {
+ id: wrapper
+ objectName: "wrapper"
+ width: 100
+ height: 80
+ border.color: "blue"
+ property string name: model.name
+ Text {
+ text: index
+ }
+ Text {
+ x: 40
+ text: wrapper.x + ", " + wrapper.y
+ }
+ Text {
+ y: 20
+ id: textName
+ objectName: "textName"
+ text: name
+ }
+ Text {
+ y: 40
+ id: textNumber
+ objectName: "textNumber"
+ text: number
+ }
+ color: GridView.isCurrentItem ? "lightsteelblue" : "white"
+ }
+ }
+ GridView {
+ id: grid
+ objectName: "grid"
+ width: 240
+ height: 320
+ cellWidth: 100
+ cellHeight: 80
+ leftMargin: 30
+ rightMargin: 50
+ flow: GridView.TopToBottom
+ layoutDirection: (testRightToLeft == true) ? Qt.RightToLeft : Qt.LeftToRight
+ model: testModel
+ delegate: myDelegate
+ }
+ Text { anchors.bottom: parent.bottom; text: grid.contentX }
+}
diff --git a/tests/auto/declarative/qsggridview/data/resizeview.qml b/tests/auto/declarative/qsggridview/data/resizeview.qml
new file mode 100644
index 0000000000..1f730a4a8a
--- /dev/null
+++ b/tests/auto/declarative/qsggridview/data/resizeview.qml
@@ -0,0 +1,24 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+
+ property real initialHeight
+
+ GridView {
+ id: grid
+ objectName: "grid"
+ width: 240
+ height: initialHeight
+ cellWidth: 80
+ cellHeight: 60
+ model: testModel
+ delegate: Rectangle {
+ objectName: "wrapper"
+ width: 80
+ height: 60
+ border.width: 1
+ }
+ }
+}
+
diff --git a/tests/auto/declarative/qsggridview/data/snapToRow.qml b/tests/auto/declarative/qsggridview/data/snapToRow.qml
new file mode 100644
index 0000000000..f079a048f0
--- /dev/null
+++ b/tests/auto/declarative/qsggridview/data/snapToRow.qml
@@ -0,0 +1,49 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ width: 240
+ height: 240
+ color: "#ffffff"
+
+ Component {
+ id: myDelegate
+ Rectangle {
+ id: wrapper
+ objectName: "wrapper"
+ height: 80
+ width: 80
+ Column {
+ Text {
+ text: index
+ }
+ Text {
+ text: wrapper.x + ", " + wrapper.y
+ }
+ }
+ color: GridView.isCurrentItem ? "lightsteelblue" : "transparent"
+ }
+ }
+ GridView {
+ id: grid
+ objectName: "grid"
+ anchors.fill: parent
+ cellWidth: 80
+ cellHeight: 80
+ preferredHighlightBegin: 20
+ preferredHighlightEnd: 100
+ snapMode: GridView.SnapToRow
+ layoutDirection: Qt.RightToLeft
+ flow: GridView.TopToBottom
+ highlightRangeMode: GridView.StrictlyEnforceRange
+ highlight: Rectangle { width: 80; height: 80; color: "yellow" }
+ model: 54
+ delegate: myDelegate
+ }
+
+ Text {
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ text: grid.contentX + ", " + grid.contentY
+ }
+}
diff --git a/tests/auto/declarative/qsggridview/qsggridview.pro b/tests/auto/declarative/qsggridview/qsggridview.pro
index e093813484..6588472779 100644
--- a/tests/auto/declarative/qsggridview/qsggridview.pro
+++ b/tests/auto/declarative/qsggridview/qsggridview.pro
@@ -1,19 +1,14 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qsggridview
macx:CONFIG -= app_bundle
SOURCES += tst_qsggridview.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
#temporary
CONFIG += insignificant_test
-QT += core-private gui-private v8-private declarative-private
-QT += opengl-private
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
diff --git a/tests/auto/declarative/qsggridview/tst_qsggridview.cpp b/tests/auto/declarative/qsggridview/tst_qsggridview.cpp
index 5d35ffc542..9e5c425632 100644
--- a/tests/auto/declarative/qsggridview/tst_qsggridview.cpp
+++ b/tests/auto/declarative/qsggridview/tst_qsggridview.cpp
@@ -51,13 +51,8 @@
#include <QtDeclarative/private/qsggridview_p.h>
#include <QtDeclarative/private/qsgtext_p.h>
#include <QtDeclarative/private/qdeclarativelistmodel_p.h>
-#include "../../../shared/util.h"
-#include <QtOpenGL/QGLShaderProgram>
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
+#include <QtGui/qguiapplication.h>
Q_DECLARE_METATYPE(Qt::LayoutDirection)
Q_DECLARE_METATYPE(QSGGridView::Flow)
@@ -74,6 +69,8 @@ private slots:
void items();
void changed();
void inserted();
+ void inserted_more();
+ void inserted_more_data();
void removed();
void clear();
void moved();
@@ -102,6 +99,7 @@ private slots:
void footer_data();
void header();
void header_data();
+ void resizeViewAndRepaint();
void indexAt();
void onAdd();
void onAdd_data();
@@ -110,9 +108,14 @@ private slots:
void testQtQuick11Attributes();
void testQtQuick11Attributes_data();
void columnCount();
+ void margins();
+ void creationContext();
+ void snapToRow_data();
+ void snapToRow();
private:
QSGView *createView();
+ void flick(QSGView *canvas, const QPoint &from, const QPoint &to, int duration);
template<typename T>
T *findItem(QSGItem *parent, const QString &id, int index=-1);
template<typename T>
@@ -269,7 +272,7 @@ void tst_QSGGridView::items()
ctxt->setContextProperty("testRightToLeft", QVariant(false));
ctxt->setContextProperty("testTopToBottom", QVariant(false));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
qApp->processEvents();
QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
@@ -319,7 +322,7 @@ void tst_QSGGridView::changed()
ctxt->setContextProperty("testRightToLeft", QVariant(false));
ctxt->setContextProperty("testTopToBottom", QVariant(false));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
qApp->processEvents();
QSGFlickable *gridview = findItem<QSGFlickable>(canvas->rootObject(), "grid");
@@ -354,7 +357,7 @@ void tst_QSGGridView::inserted()
ctxt->setContextProperty("testRightToLeft", QVariant(false));
ctxt->setContextProperty("testTopToBottom", QVariant(false));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
qApp->processEvents();
QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
@@ -419,6 +422,178 @@ void tst_QSGGridView::inserted()
delete canvas;
}
+void tst_QSGGridView::inserted_more()
+{
+ QFETCH(qreal, contentY);
+ QFETCH(int, insertIndex);
+ QFETCH(int, insertCount);
+ QFETCH(qreal, itemsOffsetAfterMove);
+
+ QSGText *name;
+ QSGText *number;
+ QSGView *canvas = createView();
+ canvas->show();
+
+ TestModel model;
+ for (int i = 0; i < 30; i++)
+ model.addItem("Item" + QString::number(i), "");
+
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+ ctxt->setContextProperty("testRightToLeft", QVariant(false));
+ ctxt->setContextProperty("testTopToBottom", QVariant(false));
+
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
+ qApp->processEvents();
+
+ QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
+ QTRY_VERIFY(gridview != 0);
+ QSGItem *contentItem = gridview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ gridview->setContentY(contentY);
+
+ QList<QPair<QString, QString> > newData;
+ for (int i=0; i<insertCount; i++)
+ newData << qMakePair(QString("value %1").arg(i), QString::number(i));
+ model.insertItems(insertIndex, newData);
+ QTRY_COMPARE(gridview->property("count").toInt(), model.count());
+
+ // check visibleItems.first() is in correct position
+ QSGItem *item0 = findItem<QSGItem>(contentItem, "wrapper", 0);
+ QVERIFY(item0);
+ QCOMPARE(item0->y(), itemsOffsetAfterMove);
+
+ QList<QSGItem*> items = findItems<QSGItem>(contentItem, "wrapper");
+ int firstVisibleIndex = -1;
+ for (int i=0; i<items.count(); i++) {
+ if (items[i]->y() >= contentY) {
+ QDeclarativeExpression e(qmlContext(items[i]), items[i], "index");
+ firstVisibleIndex = e.evaluate().toInt();
+ break;
+ }
+ }
+ QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex));
+
+ // Confirm items positioned correctly and indexes correct
+ int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
+ for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) {
+ QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
+ QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+
+ QCOMPARE(item->x(), (i%3)*80.0);
+ QCOMPARE(item->y(), (i/3)*60.0 + itemsOffsetAfterMove);
+
+ name = findItem<QSGText>(contentItem, "textName", i);
+ QVERIFY(name != 0);
+ QCOMPARE(name->text(), model.name(i));
+ number = findItem<QSGText>(contentItem, "textNumber", i);
+ QVERIFY(number != 0);
+ QCOMPARE(number->text(), model.number(i));
+ }
+
+ delete canvas;
+}
+
+void tst_QSGGridView::inserted_more_data()
+{
+ QTest::addColumn<qreal>("contentY");
+ QTest::addColumn<int>("insertIndex");
+ QTest::addColumn<int>("insertCount");
+ QTest::addColumn<qreal>("itemsOffsetAfterMove");
+
+ QTest::newRow("add 1, before visible items")
+ << 120.0 // show 6-23
+ << 5 << 1
+ << 0.0; // insert 1 above first visible, grid is rearranged; first visible moves forward within its row
+ // new 1st visible item is at 0
+
+ QTest::newRow("add 2, before visible items")
+ << 120.0 // show 6-23
+ << 5 << 2
+ << 0.0; // insert 2 above first visible, grid is rearranged; first visible moves forward within its row
+
+ QTest::newRow("add 3, before visible items")
+ << 120.0 // show 6-23
+ << 5 << 3
+ << -60.0; // insert 3 (1 row) above first visible in negative pos, first visible does not move
+
+ QTest::newRow("add 5, before visible items")
+ << 120.0 // show 6-23
+ << 5 << 5
+ << -60.0; // insert 1 row + 2 items above first visible, 1 row added at negative pos,
+ // grid is rearranged and first visible moves forward within its row
+
+ QTest::newRow("add 6, before visible items")
+ << 120.0 // show 6-23
+ << 5 << 6
+ << -60.0 * 2; // insert 2 rows above first visible in negative pos, first visible does not move
+
+
+
+ QTest::newRow("add 1, at start of visible, content at start")
+ << 0.0
+ << 0 << 1
+ << 0.0;
+
+ QTest::newRow("add multiple, at start of visible, content at start")
+ << 0.0
+ << 0 << 3
+ << 0.0;
+
+ QTest::newRow("add 1, at start of visible, content not at start")
+ << 120.0 // show 6-23
+ << 6 << 1
+ << 0.0;
+
+ QTest::newRow("add multiple, at start of visible, content not at start")
+ << 120.0 // show 6-23
+ << 6 << 3
+ << 0.0;
+
+
+ QTest::newRow("add 1, at end of visible, content at start")
+ << 0.0
+ << 17 << 1
+ << 0.0;
+
+ QTest::newRow("add 1, at end of visible, content at start")
+ << 0.0
+ << 17 << 3
+ << 0.0;
+
+ QTest::newRow("add 1, at end of visible, content not at start")
+ << 120.0 // show 6-23
+ << 23 << 1
+ << 0.0;
+
+ QTest::newRow("add multiple, at end of visible, content not at start")
+ << 120.0 // show 6-23
+ << 23 << 3
+ << 0.0;
+
+
+ QTest::newRow("add 1, after visible, content at start")
+ << 0.0
+ << 20 << 1
+ << 0.0;
+
+ QTest::newRow("add 1, after visible, content at start")
+ << 0.0
+ << 20 << 3
+ << 0.0;
+
+ QTest::newRow("add 1, after visible, content not at start")
+ << 120.0 // show 6-23
+ << 24 << 1
+ << 0.0;
+
+ QTest::newRow("add multiple, after visible, content not at start")
+ << 120.0 // show 6-23
+ << 24 << 3
+ << 0.0;
+}
+
void tst_QSGGridView::removed()
{
QSGView *canvas = createView();
@@ -433,7 +608,7 @@ void tst_QSGGridView::removed()
ctxt->setContextProperty("testRightToLeft", QVariant(false));
ctxt->setContextProperty("testTopToBottom", QVariant(false));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
qApp->processEvents();
QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
@@ -578,7 +753,7 @@ void tst_QSGGridView::clear()
ctxt->setContextProperty("testRightToLeft", QVariant(false));
ctxt->setContextProperty("testTopToBottom", QVariant(false));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
qApp->processEvents();
QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
@@ -625,7 +800,7 @@ void tst_QSGGridView::moved()
ctxt->setContextProperty("testRightToLeft", QVariant(false));
ctxt->setContextProperty("testTopToBottom", QVariant(false));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
qApp->processEvents();
QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
@@ -741,7 +916,12 @@ void tst_QSGGridView::moved_data()
QTest::newRow("move multiple forwards, within visible items")
<< 0.0
<< 0 << 5 << 3
- << 60.0; // moved 3 items (i.e. 1 row) down
+ << 0.0;
+
+ QTest::newRow("move multiple forwards, before visible items")
+ << 120.0 // show 6-23
+ << 3 << 4 << 3 // 3, 4, 5 move to after 6
+ << 60.0; // row of 3,4,5 has moved down
QTest::newRow("move multiple forwards, from non-visible -> visible")
<< 120.0 // show 6-23
@@ -761,7 +941,7 @@ void tst_QSGGridView::moved_data()
QTest::newRow("move multiple forwards, from visible -> non-visible (move first item)")
<< 0.0
<< 0 << 16 << 3
- << 60.0;
+ << 0.0;
QTest::newRow("move multiple backwards, within visible items")
@@ -822,7 +1002,7 @@ void tst_QSGGridView::multipleChanges()
ctxt->setContextProperty("testRightToLeft", QVariant(false));
ctxt->setContextProperty("testTopToBottom", QVariant(false));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
qApp->processEvents();
QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
@@ -1039,7 +1219,7 @@ void tst_QSGGridView::swapWithFirstItem()
ctxt->setContextProperty("testRightToLeft", QVariant(false));
ctxt->setContextProperty("testTopToBottom", QVariant(false));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
qApp->processEvents();
QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
@@ -1066,7 +1246,7 @@ void tst_QSGGridView::currentIndex()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- QString filename(SRCDIR "/data/gridview-initCurrent.qml");
+ QString filename(TESTDATA("gridview-initCurrent.qml"));
canvas->setSource(QUrl::fromLocalFile(filename));
qApp->processEvents();
@@ -1152,12 +1332,8 @@ void tst_QSGGridView::currentIndex()
// Test keys
canvas->requestActivateWindow();
-#ifdef Q_WS_X11
- // to be safe and avoid failing setFocus with window managers
- qt_x11_wait_for_window_manager(canvas);
-#endif
- QTRY_VERIFY(canvas->windowState() == Qt::WindowActive);
- qApp->processEvents();
+ QTest::qWaitForWindowShown(canvas);
+ QTRY_VERIFY(qGuiApp->focusWindow() == canvas);
gridview->setCurrentIndex(0);
@@ -1189,11 +1365,8 @@ void tst_QSGGridView::currentIndex()
gridview->setFlow(QSGGridView::TopToBottom);
canvas->requestActivateWindow();
-#ifdef Q_WS_X11
- // to be safe and avoid failing setFocus with window managers
- qt_x11_wait_for_window_manager(canvas);
-#endif
- QTRY_VERIFY((canvas->windowState() == Qt::WindowActive));
+ QTest::qWaitForWindowShown(canvas);
+ QVERIFY(qGuiApp->focusWindow() == canvas);
qApp->processEvents();
QTest::keyClick(canvas, Qt::Key_Right);
@@ -1213,6 +1386,7 @@ void tst_QSGGridView::currentIndex()
QTest::simulateEvent(canvas, true, Qt::Key_Right, Qt::NoModifier, "", true);
QTRY_COMPARE(gridview->currentIndex(), i*5 + 5);
}
+
QTest::keyRelease(canvas, Qt::Key_Right);
QTRY_COMPARE(gridview->currentIndex(), 55);
QTRY_COMPARE(gridview->contentX(), 720.0);
@@ -1256,11 +1430,8 @@ void tst_QSGGridView::currentIndex()
gridview->setLayoutDirection(Qt::RightToLeft);
canvas->requestActivateWindow();
-#ifdef Q_WS_X11
- // to be safe and avoid failing setFocus with window managers
- qt_x11_wait_for_window_manager(canvas);
-#endif
- QTRY_VERIFY(canvas->windowState() == Qt::WindowActive);
+ QTest::qWaitForWindowShown(canvas);
+ QTRY_VERIFY(qGuiApp->focusWindow() == canvas);
qApp->processEvents();
gridview->setCurrentIndex(35);
@@ -1316,7 +1487,7 @@ void tst_QSGGridView::noCurrentIndex()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- QString filename(SRCDIR "/data/gridview-noCurrent.qml");
+ QString filename(TESTDATA("gridview-noCurrent.qml"));
canvas->setSource(QUrl::fromLocalFile(filename));
qApp->processEvents();
@@ -1354,7 +1525,7 @@ void tst_QSGGridView::changeFlow()
ctxt->setContextProperty("testRightToLeft", QVariant(false));
ctxt->setContextProperty("testTopToBottom", QVariant(false));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
qApp->processEvents();
QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
@@ -1441,7 +1612,7 @@ void tst_QSGGridView::changeFlow()
void tst_QSGGridView::defaultValues()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/gridview3.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("gridview3.qml")));
QSGGridView *obj = qobject_cast<QSGGridView*>(c.create());
QTRY_VERIFY(obj != 0);
@@ -1464,7 +1635,7 @@ void tst_QSGGridView::defaultValues()
void tst_QSGGridView::properties()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/gridview2.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("gridview2.qml")));
QSGGridView *obj = qobject_cast<QSGGridView*>(c.create());
QTRY_VERIFY(obj != 0);
@@ -1488,7 +1659,7 @@ void tst_QSGGridView::propertyChanges()
{
QSGView *canvas = createView();
QTRY_VERIFY(canvas);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml")));
QSGGridView *gridView = canvas->rootObject()->findChild<QSGGridView*>("gridView");
QTRY_VERIFY(gridView);
@@ -1561,7 +1732,7 @@ void tst_QSGGridView::componentChanges()
{
QSGView *canvas = createView();
QTRY_VERIFY(canvas);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml")));
QSGGridView *gridView = canvas->rootObject()->findChild<QSGGridView*>("gridView");
QTRY_VERIFY(gridView);
@@ -1609,7 +1780,7 @@ void tst_QSGGridView::modelChanges()
{
QSGView *canvas = createView();
QTRY_VERIFY(canvas);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml")));
QSGGridView *gridView = canvas->rootObject()->findChild<QSGGridView*>("gridView");
QTRY_VERIFY(gridView);
@@ -1644,7 +1815,7 @@ void tst_QSGGridView::positionViewAtIndex()
ctxt->setContextProperty("testRightToLeft", QVariant(false));
ctxt->setContextProperty("testTopToBottom", QVariant(false));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
qApp->processEvents();
QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
@@ -1845,7 +2016,7 @@ void tst_QSGGridView::snapping()
ctxt->setContextProperty("testTopToBottom", QVariant(false));
ctxt->setContextProperty("testRightToLeft", QVariant(false));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
qApp->processEvents();
QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
@@ -1876,12 +2047,12 @@ void tst_QSGGridView::snapping()
void tst_QSGGridView::mirroring()
{
QSGView *canvasA = createView();
- canvasA->setSource(QUrl::fromLocalFile(SRCDIR "/data/mirroring.qml"));
+ canvasA->setSource(QUrl::fromLocalFile(TESTDATA("mirroring.qml")));
QSGGridView *gridviewA = findItem<QSGGridView>(canvasA->rootObject(), "view");
QTRY_VERIFY(gridviewA != 0);
QSGView *canvasB = createView();
- canvasB->setSource(QUrl::fromLocalFile(SRCDIR "/data/mirroring.qml"));
+ canvasB->setSource(QUrl::fromLocalFile(TESTDATA("mirroring.qml")));
QSGGridView *gridviewB = findItem<QSGGridView>(canvasB->rootObject(), "view");
QTRY_VERIFY(gridviewA != 0);
qApp->processEvents();
@@ -1894,14 +2065,14 @@ void tst_QSGGridView::mirroring()
QCOMPARE(gridviewA->layoutDirection(), gridviewA->effectiveLayoutDirection());
// LTR != RTL
- foreach(const QString objectName, objectNames)
+ foreach (const QString objectName, objectNames)
QVERIFY(findItem<QSGItem>(gridviewA, objectName)->x() != findItem<QSGItem>(gridviewB, objectName)->x());
gridviewA->setProperty("layoutDirection", Qt::LeftToRight);
gridviewB->setProperty("layoutDirection", Qt::LeftToRight);
// LTR == LTR
- foreach(const QString objectName, objectNames)
+ foreach (const QString objectName, objectNames)
QCOMPARE(findItem<QSGItem>(gridviewA, objectName)->x(), findItem<QSGItem>(gridviewB, objectName)->x());
QVERIFY(gridviewB->layoutDirection() == gridviewB->effectiveLayoutDirection());
@@ -1909,25 +2080,25 @@ void tst_QSGGridView::mirroring()
QVERIFY(gridviewB->layoutDirection() != gridviewB->effectiveLayoutDirection());
// LTR != LTR+mirror
- foreach(const QString objectName, objectNames)
+ foreach (const QString objectName, objectNames)
QVERIFY(findItem<QSGItem>(gridviewA, objectName)->x() != findItem<QSGItem>(gridviewB, objectName)->x());
gridviewA->setProperty("layoutDirection", Qt::RightToLeft);
// RTL == LTR+mirror
- foreach(const QString objectName, objectNames)
+ foreach (const QString objectName, objectNames)
QCOMPARE(findItem<QSGItem>(gridviewA, objectName)->x(), findItem<QSGItem>(gridviewB, objectName)->x());
gridviewB->setProperty("layoutDirection", Qt::RightToLeft);
// RTL != RTL+mirror
- foreach(const QString objectName, objectNames)
+ foreach (const QString objectName, objectNames)
QVERIFY(findItem<QSGItem>(gridviewA, objectName)->x() != findItem<QSGItem>(gridviewB, objectName)->x());
gridviewA->setProperty("layoutDirection", Qt::LeftToRight);
// LTR == RTL+mirror
- foreach(const QString objectName, objectNames)
+ foreach (const QString objectName, objectNames)
QCOMPARE(findItem<QSGItem>(gridviewA, objectName)->x(), findItem<QSGItem>(gridviewB, objectName)->x());
delete canvasA;
@@ -1947,7 +2118,7 @@ void tst_QSGGridView::positionViewAtIndex_rightToLeft()
ctxt->setContextProperty("testTopToBottom", QVariant(true));
ctxt->setContextProperty("testRightToLeft", QVariant(true));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
qApp->processEvents();
QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
@@ -2077,7 +2248,7 @@ void tst_QSGGridView::resetModel()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/displaygrid.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaygrid.qml")));
qApp->processEvents();
QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
@@ -2122,7 +2293,7 @@ void tst_QSGGridView::enforceRange()
ctxt->setContextProperty("testRightToLeft", QVariant(false));
ctxt->setContextProperty("testTopToBottom", QVariant(false));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview-enforcerange.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview-enforcerange.qml")));
qApp->processEvents();
QVERIFY(canvas->rootObject() != 0);
@@ -2178,7 +2349,7 @@ void tst_QSGGridView::enforceRange_rightToLeft()
ctxt->setContextProperty("testRightToLeft", QVariant(true));
ctxt->setContextProperty("testTopToBottom", QVariant(true));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview-enforcerange.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview-enforcerange.qml")));
qApp->processEvents();
QVERIFY(canvas->rootObject() != 0);
@@ -2227,7 +2398,7 @@ void tst_QSGGridView::QTBUG_8456()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/setindex.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("setindex.qml")));
qApp->processEvents();
QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
@@ -2242,7 +2413,7 @@ void tst_QSGGridView::manualHighlight()
{
QSGView *canvas = createView();
- QString filename(SRCDIR "/data/manual-highlight.qml");
+ QString filename(TESTDATA("manual-highlight.qml"));
canvas->setSource(QUrl::fromLocalFile(filename));
qApp->processEvents();
@@ -2306,7 +2477,7 @@ void tst_QSGGridView::footer()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/footer.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("footer.qml")));
qApp->processEvents();
QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
@@ -2465,7 +2636,7 @@ void tst_QSGGridView::header()
canvas->rootContext()->setContextProperty("testModel", &model);
canvas->rootContext()->setContextProperty("initialViewWidth", 240);
canvas->rootContext()->setContextProperty("initialViewHeight", 320);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml")));
QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
QTRY_VERIFY(gridview != 0);
@@ -2529,7 +2700,7 @@ void tst_QSGGridView::header()
canvas->rootContext()->setContextProperty("testModel", &model);
canvas->rootContext()->setContextProperty("initialViewWidth", 240);
canvas->rootContext()->setContextProperty("initialViewHeight", 320);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml")));
gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
QTRY_VERIFY(gridview != 0);
@@ -2597,6 +2768,39 @@ void tst_QSGGridView::header_data()
<< QPointF(-(240 - 40), 0);
}
+void tst_QSGGridView::resizeViewAndRepaint()
+{
+ QSGView *canvas = createView();
+ canvas->show();
+
+ TestModel model;
+ for (int i = 0; i < 40; i++)
+ model.addItem("Item" + QString::number(i), "");
+
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+ ctxt->setContextProperty("initialHeight", 100);
+
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizeview.qml")));
+ qApp->processEvents();
+
+ QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
+ QTRY_VERIFY(gridview != 0);
+ QSGItem *contentItem = gridview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ // item at index 10 should not be currently visible
+ QVERIFY(!findItem<QSGItem>(contentItem, "wrapper", 10));
+
+ gridview->setHeight(320);
+ QTRY_VERIFY(findItem<QSGItem>(contentItem, "wrapper", 10));
+
+ gridview->setHeight(100);
+ QTRY_VERIFY(!findItem<QSGItem>(contentItem, "wrapper", 10));
+
+ delete canvas;
+}
+
void tst_QSGGridView::indexAt()
{
QSGView *canvas = createView();
@@ -2615,7 +2819,7 @@ void tst_QSGGridView::indexAt()
ctxt->setContextProperty("testRightToLeft", QVariant(false));
ctxt->setContextProperty("testTopToBottom", QVariant(false));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview1.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
qApp->processEvents();
QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
@@ -2654,7 +2858,7 @@ void tst_QSGGridView::onAdd()
ctxt->setContextProperty("testModel", &model);
ctxt->setContextProperty("delegateWidth", delegateWidth);
ctxt->setContextProperty("delegateHeight", delegateHeight);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/attachedSignals.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml")));
QObject *object = canvas->rootObject();
object->setProperty("width", canvas->width());
@@ -2712,7 +2916,7 @@ void tst_QSGGridView::onRemove()
ctxt->setContextProperty("testModel", &model);
ctxt->setContextProperty("delegateWidth", delegateWidth);
ctxt->setContextProperty("delegateHeight", delegateHeight);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/attachedSignals.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml")));
QObject *object = canvas->rootObject();
model.removeItems(indexToRemove, removeCount);
@@ -2787,14 +2991,14 @@ void tst_QSGGridView::testQtQuick11Attributes_data()
void tst_QSGGridView::columnCount()
{
QSGView canvas;
- canvas.setSource(QUrl::fromLocalFile(SRCDIR "/data/gridview4.qml"));
+ canvas.setSource(QUrl::fromLocalFile(TESTDATA("gridview4.qml")));
canvas.show();
canvas.requestActivateWindow();
QTest::qWaitForWindowShown(&canvas);
QSGGridView *view = qobject_cast<QSGGridView*>(canvas.rootObject());
- QCOMPARE(view->cellWidth(), qreal(400)/qreal(9));
+ QCOMPARE(view->cellWidth(), qreal(405)/qreal(9));
QCOMPARE(view->cellHeight(), qreal(100));
QList<QSGItem*> items = findItems<QSGItem>(view, "delegate");
@@ -2803,6 +3007,251 @@ void tst_QSGGridView::columnCount()
QCOMPARE(items.at(9)->y(), qreal(100));
}
+void tst_QSGGridView::margins()
+{
+ {
+ QSGView *canvas = createView();
+ canvas->show();
+
+ TestModel model;
+ for (int i = 0; i < 40; i++)
+ model.addItem("Item" + QString::number(i), "");
+
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+ ctxt->setContextProperty("testRightToLeft", QVariant(false));
+
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("margins.qml")));
+ qApp->processEvents();
+
+ QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
+ QTRY_VERIFY(gridview != 0);
+
+ QSGItem *contentItem = gridview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ QCOMPARE(gridview->contentX(), -30.);
+ QCOMPARE(gridview->xOrigin(), 0.);
+
+ // check end bound
+ gridview->positionViewAtEnd();
+ qreal pos = gridview->contentX();
+ gridview->setContentX(pos + 80);
+ gridview->returnToBounds();
+ QTRY_COMPARE(gridview->contentX(), pos + 50);
+
+ // remove item before visible and check that left margin is maintained
+ // and xOrigin is updated
+ gridview->setContentX(200);
+ model.removeItems(0, 4);
+ QTest::qWait(100);
+ gridview->setContentX(-50);
+ gridview->returnToBounds();
+ QCOMPARE(gridview->xOrigin(), 100.);
+ QTRY_COMPARE(gridview->contentX(), 70.);
+
+ // reduce left margin
+ gridview->setLeftMargin(20);
+ QCOMPARE(gridview->xOrigin(), 100.);
+ QTRY_COMPARE(gridview->contentX(), 80.);
+
+ // check end bound
+ gridview->positionViewAtEnd();
+ QCOMPARE(gridview->xOrigin(), 0.); // positionViewAtEnd() resets origin
+ pos = gridview->contentX();
+ gridview->setContentX(pos + 80);
+ gridview->returnToBounds();
+ QTRY_COMPARE(gridview->contentX(), pos + 50);
+
+ // reduce right margin
+ pos = gridview->contentX();
+ gridview->setRightMargin(40);
+ QCOMPARE(gridview->xOrigin(), 0.);
+ QTRY_COMPARE(gridview->contentX(), pos-10);
+
+ delete canvas;
+ }
+ {
+ //RTL
+ QSGView *canvas = createView();
+ canvas->show();
+
+ TestModel model;
+ for (int i = 0; i < 40; i++)
+ model.addItem("Item" + QString::number(i), "");
+
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+ ctxt->setContextProperty("testRightToLeft", QVariant(true));
+
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("margins.qml")));
+ qApp->processEvents();
+
+ QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
+ QTRY_VERIFY(gridview != 0);
+
+ QSGItem *contentItem = gridview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ QCOMPARE(gridview->contentX(), -240+30.);
+ QCOMPARE(gridview->xOrigin(), 0.);
+
+ // check end bound
+ gridview->positionViewAtEnd();
+ qreal pos = gridview->contentX();
+ gridview->setContentX(pos - 80);
+ gridview->returnToBounds();
+ QTRY_COMPARE(gridview->contentX(), pos - 50);
+
+ // remove item before visible and check that left margin is maintained
+ // and xOrigin is updated
+ gridview->setContentX(-400);
+ model.removeItems(0, 4);
+ QTest::qWait(100);
+ gridview->setContentX(-240+50);
+ gridview->returnToBounds();
+ QCOMPARE(gridview->xOrigin(), -100.);
+ QTRY_COMPARE(gridview->contentX(), -240-70.);
+
+ // reduce left margin (i.e. right side due to RTL)
+ pos = gridview->contentX();
+ gridview->setLeftMargin(20);
+ QCOMPARE(gridview->xOrigin(), -100.);
+ QTRY_COMPARE(gridview->contentX(), -240-80.);
+
+ // check end bound
+ gridview->positionViewAtEnd();
+ QCOMPARE(gridview->xOrigin(), 0.); // positionViewAtEnd() resets origin
+ pos = gridview->contentX();
+ gridview->setContentX(pos - 80);
+ gridview->returnToBounds();
+ QTRY_COMPARE(gridview->contentX(), pos - 50);
+
+ // reduce right margin (i.e. left side due to RTL)
+ pos = gridview->contentX();
+ gridview->setRightMargin(40);
+ QCOMPARE(gridview->xOrigin(), 0.);
+ QTRY_COMPARE(gridview->contentX(), pos+10);
+
+ delete canvas;
+ }
+}
+
+void tst_QSGGridView::creationContext()
+{
+ QSGView canvas;
+ canvas.setGeometry(0,0,240,320);
+ canvas.setSource(QUrl::fromLocalFile(TESTDATA("creationContext.qml")));
+ qApp->processEvents();
+
+ QSGItem *rootItem = qobject_cast<QSGItem *>(canvas.rootObject());
+ QVERIFY(rootItem);
+ QVERIFY(rootItem->property("count").toInt() > 0);
+
+ QSGItem *item;
+ QVERIFY(item = rootItem->findChild<QSGItem *>("listItem"));
+ QCOMPARE(item->property("text").toString(), QString("Hello!"));
+ QVERIFY(item = rootItem->findChild<QSGItem *>("header"));
+ QCOMPARE(item->property("text").toString(), QString("Hello!"));
+ QVERIFY(item = rootItem->findChild<QSGItem *>("footer"));
+ QCOMPARE(item->property("text").toString(), QString("Hello!"));
+}
+
+void tst_QSGGridView::snapToRow_data()
+{
+ QTest::addColumn<QSGGridView::Flow>("flow");
+ QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<int>("highlightRangeMode");
+ QTest::addColumn<QPoint>("flickStart");
+ QTest::addColumn<QPoint>("flickEnd");
+ QTest::addColumn<qreal>("snapAlignment");
+ QTest::addColumn<qreal>("endExtent");
+ QTest::addColumn<qreal>("startExtent");
+
+ QTest::newRow("vertical, left to right") << QSGGridView::LeftToRight << Qt::LeftToRight << int(QSGItemView::NoHighlightRange)
+ << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 1200.0 << 0.0;
+
+ QTest::newRow("horizontal, left to right") << QSGGridView::TopToBottom << Qt::LeftToRight << int(QSGItemView::NoHighlightRange)
+ << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 1200.0 << 0.0;
+
+ QTest::newRow("horizontal, right to left") << QSGGridView::TopToBottom << Qt::RightToLeft << int(QSGItemView::NoHighlightRange)
+ << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -1200.0 - 240.0 << -240.0;
+
+ QTest::newRow("vertical, left to right, enforce range") << QSGGridView::LeftToRight << Qt::LeftToRight << int(QSGItemView::StrictlyEnforceRange)
+ << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 1340.0 << -20.0;
+
+ QTest::newRow("horizontal, left to right, enforce range") << QSGGridView::TopToBottom << Qt::LeftToRight << int(QSGItemView::StrictlyEnforceRange)
+ << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 1340.0 << -20.0;
+
+ QTest::newRow("horizontal, right to left, enforce range") << QSGGridView::TopToBottom << Qt::RightToLeft << int(QSGItemView::StrictlyEnforceRange)
+ << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -1200.0 - 240.0 - 140.0 << -220.0;
+}
+
+void tst_QSGGridView::snapToRow()
+{
+ QFETCH(QSGGridView::Flow, flow);
+ QFETCH(Qt::LayoutDirection, layoutDirection);
+ QFETCH(int, highlightRangeMode);
+ QFETCH(QPoint, flickStart);
+ QFETCH(QPoint, flickEnd);
+ QFETCH(qreal, snapAlignment);
+ QFETCH(qreal, endExtent);
+ QFETCH(qreal, startExtent);
+
+ QSGView *canvas = createView();
+
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("snapToRow.qml")));
+ canvas->show();
+ qApp->processEvents();
+
+ QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
+ QTRY_VERIFY(gridview != 0);
+
+ gridview->setFlow(flow);
+ gridview->setLayoutDirection(layoutDirection);
+ gridview->setHighlightRangeMode(QSGItemView::HighlightRangeMode(highlightRangeMode));
+
+ QSGItem *contentItem = gridview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ // confirm that a flick hits an item boundary
+ flick(canvas, flickStart, flickEnd, 180);
+ QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops
+ if (flow == QSGGridView::LeftToRight)
+ QCOMPARE(qreal(fmod(gridview->contentY(),80.0)), snapAlignment);
+ else
+ QCOMPARE(qreal(fmod(gridview->contentX(),80.0)), snapAlignment);
+
+ // flick to end
+ do {
+ flick(canvas, flickStart, flickEnd, 180);
+ QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops
+ } while (flow == QSGGridView::LeftToRight
+ ? !gridview->isAtYEnd()
+ : layoutDirection == Qt::LeftToRight ? !gridview->isAtXEnd() : !gridview->isAtXBeginning());
+
+ if (flow == QSGGridView::LeftToRight)
+ QCOMPARE(gridview->contentY(), endExtent);
+ else
+ QCOMPARE(gridview->contentX(), endExtent);
+
+ // flick to start
+ do {
+ flick(canvas, flickEnd, flickStart, 180);
+ QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops
+ } while (flow == QSGGridView::LeftToRight
+ ? !gridview->isAtYBeginning()
+ : layoutDirection == Qt::LeftToRight ? !gridview->isAtXBeginning() : !gridview->isAtXEnd());
+
+ if (flow == QSGGridView::LeftToRight)
+ QCOMPARE(gridview->contentY(), startExtent);
+ else
+ QCOMPARE(gridview->contentX(), startExtent);
+
+ delete canvas;
+}
+
+
QSGView *tst_QSGGridView::createView()
{
QSGView *canvas = new QSGView(0);
@@ -2811,6 +3260,24 @@ QSGView *tst_QSGGridView::createView()
return canvas;
}
+void tst_QSGGridView::flick(QSGView *canvas, const QPoint &from, const QPoint &to, int duration)
+{
+ const int pointCount = 5;
+ QPoint diff = to - from;
+
+ // send press, five equally spaced moves, and release.
+ QTest::mousePress(canvas, Qt::LeftButton, 0, from);
+
+ for (int i = 0; i < pointCount; ++i) {
+ QMouseEvent mv(QEvent::MouseMove, from + (i+1)*diff/pointCount, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+ QApplication::sendEvent(canvas, &mv);
+ QTest::qWait(duration/pointCount);
+ QCoreApplication::processEvents();
+ }
+
+ QTest::mouseRelease(canvas, Qt::LeftButton, 0, to);
+}
+
/*
Find an item with the specified objectName. If index is supplied then the
item must also evaluate the {index} expression equal to index
@@ -2822,7 +3289,7 @@ T *tst_QSGGridView::findItem(QSGItem *parent, const QString &objectName, int ind
//qDebug() << parent->childItems().count() << "children";
for (int i = 0; i < parent->childItems().count(); ++i) {
QSGItem *item = qobject_cast<QSGItem*>(parent->childItems().at(i));
- if(!item)
+ if (!item)
continue;
//qDebug() << "try" << item;
if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
@@ -2853,7 +3320,7 @@ QList<T*> tst_QSGGridView::findItems(QSGItem *parent, const QString &objectName)
//qDebug() << parent->childItems().count() << "children";
for (int i = 0; i < parent->childItems().count(); ++i) {
QSGItem *item = qobject_cast<QSGItem*>(parent->childItems().at(i));
- if(!item)
+ if (!item)
continue;
//qDebug() << "try" << item;
if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
@@ -2871,7 +3338,7 @@ void tst_QSGGridView::dumpTree(QSGItem *parent, int depth)
static QString padding(" ");
for (int i = 0; i < parent->childItems().count(); ++i) {
QSGItem *item = qobject_cast<QSGItem*>(parent->childItems().at(i));
- if(!item)
+ if (!item)
continue;
QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item);
qDebug() << padding.left(depth*2) << item << (context ? context->contextProperty("index").toInt() : -1);
diff --git a/tests/auto/declarative/qsgimage/qsgimage.pro b/tests/auto/declarative/qsgimage/qsgimage.pro
index e7f3dfa20d..11abb9fa18 100644
--- a/tests/auto/declarative/qsgimage/qsgimage.pro
+++ b/tests/auto/declarative/qsgimage/qsgimage.pro
@@ -1,19 +1,13 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui network
+CONFIG += testcase
+TARGET = tst_qsgimage
macx:CONFIG -= app_bundle
HEADERS += ../shared/testhttpserver.h
SOURCES += tst_qsgimage.cpp ../shared/testhttpserver.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-#temporary
-CONFIG += insignificant_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qsgimage/tst_qsgimage.cpp b/tests/auto/declarative/qsgimage/tst_qsgimage.cpp
index 18770d0eb8..d0125e6582 100644
--- a/tests/auto/declarative/qsgimage/tst_qsgimage.cpp
+++ b/tests/auto/declarative/qsgimage/tst_qsgimage.cpp
@@ -54,15 +54,11 @@
#include <QtDeclarative/qdeclarativeexpression.h>
#include <QtTest/QSignalSpy>
#include <QtGui/QPainter>
+#include <QtGui/QImageReader>
-#include "../../../shared/util.h"
+#include "../shared/util.h"
#include "../shared/testhttpserver.h"
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
#define SERVER_PORT 14451
#define SERVER_ADDR "http://127.0.0.1:14451"
@@ -131,16 +127,18 @@ void tst_qsgimage::imageSource_data()
QTest::addColumn<bool>("cache");
QTest::addColumn<QString>("error");
- QTest::newRow("local") << QUrl::fromLocalFile(SRCDIR "/data/colors.png").toString() << 120.0 << 120.0 << false << false << true << "";
- QTest::newRow("local no cache") << QUrl::fromLocalFile(SRCDIR "/data/colors.png").toString() << 120.0 << 120.0 << false << false << false << "";
- QTest::newRow("local async") << QUrl::fromLocalFile(SRCDIR "/data/colors1.png").toString() << 120.0 << 120.0 << false << true << true << "";
- QTest::newRow("local not found") << QUrl::fromLocalFile(SRCDIR "/data/no-such-file.png").toString() << 0.0 << 0.0 << false
- << false << true << "file::2:1: QML Image: Cannot open: " + QUrl::fromLocalFile(SRCDIR "/data/no-such-file.png").toString();
- QTest::newRow("local async not found") << QUrl::fromLocalFile(SRCDIR "/data/no-such-file-1.png").toString() << 0.0 << 0.0 << false
- << true << true << "file::2:1: QML Image: Cannot open: " + QUrl::fromLocalFile(SRCDIR "/data/no-such-file-1.png").toString();
+ QTest::newRow("local") << QUrl::fromLocalFile(TESTDATA("colors.png")).toString() << 120.0 << 120.0 << false << false << true << "";
+ QTest::newRow("local no cache") << QUrl::fromLocalFile(TESTDATA("colors.png")).toString() << 120.0 << 120.0 << false << false << false << "";
+ QTest::newRow("local async") << QUrl::fromLocalFile(TESTDATA("colors1.png")).toString() << 120.0 << 120.0 << false << true << true << "";
+ QTest::newRow("local not found") << QUrl::fromLocalFile(TESTDATA("no-such-file.png")).toString() << 0.0 << 0.0 << false
+ << false << true << "file::2:1: QML Image: Cannot open: " + QUrl::fromLocalFile(TESTDATA("no-such-file.png")).toString();
+ QTest::newRow("local async not found") << QUrl::fromLocalFile(TESTDATA("no-such-file-1.png")).toString() << 0.0 << 0.0 << false
+ << true << true << "file::2:1: QML Image: Cannot open: " + QUrl::fromLocalFile(TESTDATA("no-such-file-1.png")).toString();
QTest::newRow("remote") << SERVER_ADDR "/colors.png" << 120.0 << 120.0 << true << false << true << "";
QTest::newRow("remote redirected") << SERVER_ADDR "/oldcolors.png" << 120.0 << 120.0 << true << false << false << "";
- QTest::newRow("remote svg") << SERVER_ADDR "/heart.svg" << 550.0 << 500.0 << true << false << false << "";
+ if (QImageReader::supportedImageFormats().contains("svg"))
+ QTest::newRow("remote svg") << SERVER_ADDR "/heart.svg" << 550.0 << 500.0 << true << false << false << "";
+
QTest::newRow("remote not found") << SERVER_ADDR "/no-such-file.png" << 0.0 << 0.0 << true
<< false << true << "file::2:1: QML Image: Error downloading " SERVER_ADDR "/no-such-file.png - server replied: Not found";
@@ -159,7 +157,7 @@ void tst_qsgimage::imageSource()
TestHTTPServer server(SERVER_PORT);
if (remote) {
QVERIFY(server.isValid());
- server.serveDirectory(SRCDIR "/data");
+ server.serveDirectory(TESTDATA(""));
server.addRedirect("oldcolors.png", SERVER_ADDR "/colors.png");
}
@@ -206,7 +204,7 @@ void tst_qsgimage::clearSource()
{
QString componentStr = "import QtQuick 2.0\nImage { source: srcImage }";
QDeclarativeContext *ctxt = engine.rootContext();
- ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/colors.png"));
+ ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("colors.png")));
QDeclarativeComponent component(&engine);
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QSGImage *obj = qobject_cast<QSGImage*>(component.create());
@@ -228,7 +226,7 @@ void tst_qsgimage::clearSource()
void tst_qsgimage::resized()
{
- QString componentStr = "import QtQuick 2.0\nImage { source: \"" SRCDIR "/data/colors.png\"; width: 300; height: 300 }";
+ QString componentStr = "import QtQuick 2.0\nImage { source: \"" + TESTDATA("colors.png") + "\"; width: 300; height: 300 }";
QDeclarativeComponent component(&engine);
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QSGImage *obj = qobject_cast<QSGImage*>(component.create());
@@ -245,14 +243,14 @@ void tst_qsgimage::preserveAspectRatio()
QSGView *canvas = new QSGView(0);
canvas->show();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/aspectratio.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("aspectratio.qml")));
QSGImage *image = qobject_cast<QSGImage*>(canvas->rootObject());
QVERIFY(image != 0);
image->setWidth(80.0);
QCOMPARE(image->width(), 80.);
QCOMPARE(image->height(), 80.);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/aspectratio.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("aspectratio.qml")));
image = qobject_cast<QSGImage*>(canvas->rootObject());
image->setHeight(60.0);
QVERIFY(image != 0);
@@ -263,7 +261,7 @@ void tst_qsgimage::preserveAspectRatio()
void tst_qsgimage::smooth()
{
- QString componentStr = "import QtQuick 2.0\nImage { source: \"" SRCDIR "/data/colors.png\"; smooth: true; width: 300; height: 300 }";
+ QString componentStr = "import QtQuick 2.0\nImage { source: \"" + TESTDATA("colors.png") + "\"; smooth: true; width: 300; height: 300 }";
QDeclarativeComponent component(&engine);
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QSGImage *obj = qobject_cast<QSGImage*>(component.create());
@@ -288,7 +286,7 @@ void tst_qsgimage::mirror()
foreach (QSGImage::FillMode fillMode, fillModes) {
QSGView *canvas = new QSGView;
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/mirror.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("mirror.qml")));
QSGImage *obj = canvas->rootObject()->findChild<QSGImage*>("image");
QVERIFY(obj != 0);
@@ -304,7 +302,7 @@ void tst_qsgimage::mirror()
foreach (QSGImage::FillMode fillMode, fillModes) {
QPixmap srcPixmap;
- QVERIFY(srcPixmap.load(SRCDIR "/data/pattern.png"));
+ QVERIFY(srcPixmap.load(TESTDATA("pattern.png")));
QPixmap expected(width, height);
expected.fill();
@@ -353,7 +351,10 @@ void tst_qsgimage::mirror()
void tst_qsgimage::svg()
{
- QString src = QUrl::fromLocalFile(SRCDIR "/data/heart.svg").toString();
+ if (!QImageReader::supportedImageFormats().contains("svg"))
+ QSKIP("svg support not available");
+
+ QString src = QUrl::fromLocalFile(TESTDATA("heart.svg")).toString();
QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; sourceSize.width: 300; sourceSize.height: 300 }";
QDeclarativeComponent component(&engine);
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
@@ -417,7 +418,7 @@ void tst_qsgimage::geometry()
QFETCH(double, boundingWidth);
QFETCH(double, boundingHeight);
- QString src = QUrl::fromLocalFile(SRCDIR "/data/rect.png").toString();
+ QString src = QUrl::fromLocalFile(TESTDATA("rect.png")).toString();
QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; fillMode: Image." + fillMode + "; ";
if (explicitWidth)
@@ -445,7 +446,7 @@ void tst_qsgimage::big()
// If the JPEG loader does not implement scaling efficiently, it would
// have to build a 400 MB image. That would be a bug in the JPEG loader.
- QString src = QUrl::fromLocalFile(SRCDIR "/data/big.jpeg").toString();
+ QString src = QUrl::fromLocalFile(TESTDATA("big.jpeg")).toString();
QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; width: 100; sourceSize.height: 256 }";
QDeclarativeComponent component(&engine);
@@ -463,7 +464,7 @@ void tst_qsgimage::tiling_QTBUG_6716()
QFETCH(QString, source);
QSGView *canvas = new QSGView(0);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR + source));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA(source)));
canvas->show();
qApp->processEvents();
@@ -473,9 +474,7 @@ void tst_qsgimage::tiling_QTBUG_6716()
QImage img = canvas->grabFrameBuffer();
for (int x = 0; x < tiling->width(); ++x) {
for (int y = 0; y < tiling->height(); ++y) {
-#ifdef Q_WS_QPA
- QEXPECT_FAIL("", "QTBUG-21005 fails", Abort);
-#endif
+ QEXPECT_FAIL("horizontal_tiling", "QTBUG-21005 - stable failing test", Abort);
QVERIFY(img.pixel(x, y) == qRgb(0, 255, 0));
}
}
@@ -485,20 +484,20 @@ void tst_qsgimage::tiling_QTBUG_6716()
void tst_qsgimage::tiling_QTBUG_6716_data()
{
QTest::addColumn<QString>("source");
- QTest::newRow("vertical_tiling") << "/data/vtiling.qml";
- QTest::newRow("horizontal_tiling") << "/data/htiling.qml";
+ QTest::newRow("vertical_tiling") << "vtiling.qml";
+ QTest::newRow("horizontal_tiling") << "htiling.qml";
}
void tst_qsgimage::noLoading()
{
TestHTTPServer server(SERVER_PORT);
QVERIFY(server.isValid());
- server.serveDirectory(SRCDIR "/data");
+ server.serveDirectory(TESTDATA(""));
server.addRedirect("oldcolors.png", SERVER_ADDR "/colors.png");
QString componentStr = "import QtQuick 2.0\nImage { source: srcImage; cache: true }";
QDeclarativeContext *ctxt = engine.rootContext();
- ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/heart.png"));
+ ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("heart.png")));
QDeclarativeComponent component(&engine);
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QSGImage *obj = qobject_cast<QSGImage*>(component.create());
@@ -510,7 +509,7 @@ void tst_qsgimage::noLoading()
QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QSGImageBase::Status)));
// Loading local file
- ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/green.png"));
+ ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("green.png")));
QTRY_VERIFY(obj->status() == QSGImage::Ready);
QTRY_VERIFY(obj->progress() == 1.0);
QTRY_COMPARE(sourceSpy.count(), 1);
@@ -528,7 +527,7 @@ void tst_qsgimage::noLoading()
QTRY_COMPARE(statusSpy.count(), 2);
// Loading remote file again - should not go through 'Loading' state.
- ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/green.png"));
+ ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("green.png")));
ctxt->setContextProperty("srcImage", QString(SERVER_ADDR) + "/rect.png");
QTRY_VERIFY(obj->status() == QSGImage::Ready);
QTRY_VERIFY(obj->progress() == 1.0);
@@ -542,7 +541,7 @@ void tst_qsgimage::noLoading()
void tst_qsgimage::paintedWidthHeight()
{
{
- QString src = QUrl::fromLocalFile(SRCDIR "/data/heart.png").toString();
+ QString src = QUrl::fromLocalFile(TESTDATA("heart.png")).toString();
QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; width: 200; height: 25; fillMode: Image.PreserveAspectFit }";
QDeclarativeComponent component(&engine);
@@ -558,7 +557,7 @@ void tst_qsgimage::paintedWidthHeight()
}
{
- QString src = QUrl::fromLocalFile(SRCDIR "/data/heart.png").toString();
+ QString src = QUrl::fromLocalFile(TESTDATA("heart.png")).toString();
QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; width: 26; height: 175; fillMode: Image.PreserveAspectFit }";
QDeclarativeComponent component(&engine);
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
@@ -577,7 +576,7 @@ void tst_qsgimage::sourceSize_QTBUG_14303()
{
QString componentStr = "import QtQuick 2.0\nImage { source: srcImage }";
QDeclarativeContext *ctxt = engine.rootContext();
- ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/heart200.png"));
+ ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("heart200.png")));
QDeclarativeComponent component(&engine);
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QSGImage *obj = qobject_cast<QSGImage*>(component.create());
@@ -591,12 +590,12 @@ void tst_qsgimage::sourceSize_QTBUG_14303()
QTRY_COMPARE(obj->sourceSize().height(), 200);
QTRY_COMPARE(sourceSizeSpy.count(), 0);
- ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/colors.png"));
+ ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("colors.png")));
QTRY_COMPARE(obj->sourceSize().width(), 120);
QTRY_COMPARE(obj->sourceSize().height(), 120);
QTRY_COMPARE(sourceSizeSpy.count(), 1);
- ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(SRCDIR "/data/heart200.png"));
+ ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("heart200.png")));
QTRY_COMPARE(obj->sourceSize().width(), 200);
QTRY_COMPARE(obj->sourceSize().height(), 200);
QTRY_COMPARE(sourceSizeSpy.count(), 2);
@@ -607,7 +606,7 @@ void tst_qsgimage::sourceSize_QTBUG_14303()
void tst_qsgimage::sourceSize_QTBUG_16389()
{
QSGView *canvas = new QSGView(0);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/qtbug_16389.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("qtbug_16389.qml")));
canvas->show();
qApp->processEvents();
@@ -638,7 +637,7 @@ static void checkWarnings(QtMsgType, const char *msg)
void tst_qsgimage::nullPixmapPaint()
{
QSGView *canvas = new QSGView(0);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/nullpixmap.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("nullpixmap.qml")));
canvas->show();
QSGImage *image = qobject_cast<QSGImage*>(canvas->rootObject());
@@ -665,7 +664,7 @@ T *tst_qsgimage::findItem(QSGItem *parent, const QString &objectName, int index)
//qDebug() << parent->childItems().count() << "children";
for (int i = 0; i < parent->childItems().count(); ++i) {
QSGItem *item = qobject_cast<QSGItem*>(parent->childItems().at(i));
- if(!item)
+ if (!item)
continue;
//qDebug() << "try" << item;
if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
diff --git a/tests/auto/declarative/qsgitem/qsgitem.pro b/tests/auto/declarative/qsgitem/qsgitem.pro
index 314491c798..76d6547da7 100644
--- a/tests/auto/declarative/qsgitem/qsgitem.pro
+++ b/tests/auto/declarative/qsgitem/qsgitem.pro
@@ -1,8 +1,8 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qsgitem
SOURCES += tst_qsgitem.cpp
macx:CONFIG -= app_bundle
CONFIG += parallel_test
-QT += core-private gui-private declarative-private widgets
+QT += core-private gui-private declarative-private widgets testlib
diff --git a/tests/auto/declarative/qsgitem/tst_qsgitem.cpp b/tests/auto/declarative/qsgitem/tst_qsgitem.cpp
index 5949b7b76d..84c52bdde8 100644
--- a/tests/auto/declarative/qsgitem/tst_qsgitem.cpp
+++ b/tests/auto/declarative/qsgitem/tst_qsgitem.cpp
@@ -45,7 +45,6 @@
#include "qsgcanvas.h"
#include <QtWidgets/QGraphicsSceneMouseEvent>
#include "private/qsgfocusscope_p.h"
-#include "../../../shared/util.h"
#include <QDebug>
#include <QTimer>
@@ -84,7 +83,7 @@ protected:
}
public slots:
- void doPolish() {
+ void doPolish() {
polish();
}
};
@@ -227,13 +226,13 @@ struct FocusState : public QHash<QSGItem *, FocusData>
} else { \
QCOMPARE(canvas.activeFocusItem(), canvas.rootItem()); \
} \
- for(QHash<QSGItem *, FocusData>::Iterator iter = focusState.begin(); \
+ for (QHash<QSGItem *, FocusData>::Iterator iter = focusState.begin(); \
iter != focusState.end(); \
iter++) { \
QCOMPARE(iter.key()->hasFocus(), iter.value().focus); \
QCOMPARE(iter.key()->hasActiveFocus(), iter.value().activeFocus); \
} \
- } while(false)
+ } while (false)
// Tests a simple set of top-level scoped items
void tst_qsgitem::simpleFocus()
@@ -632,7 +631,7 @@ void tst_qsgitem::changeParent()
focusState[item].set(false, false);
FVERIFY();
}
-
+
}
void tst_qsgitem::constructor()
diff --git a/tests/auto/declarative/qsgitem2/data/mapCoordinates.qml b/tests/auto/declarative/qsgitem2/data/mapCoordinates.qml
index a5a073c1a0..566cb220ff 100644
--- a/tests/auto/declarative/qsgitem2/data/mapCoordinates.qml
+++ b/tests/auto/declarative/qsgitem2/data/mapCoordinates.qml
@@ -1,3 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
import QtQuick 2.0
Item {
@@ -33,11 +74,11 @@ Item {
function checkMapAToInvalid(x, y) {
var pos = itemA.mapToItem(1122, x, y)
- return pos.x == undefined && pos.y == undefined
+ return pos == undefined;
}
function checkMapAFromInvalid(x, y) {
var pos = itemA.mapFromItem(1122, x, y)
- return pos.x == undefined && pos.y == undefined
+ return pos == undefined;
}
}
diff --git a/tests/auto/declarative/qsgitem2/qsgitem.pro b/tests/auto/declarative/qsgitem2/qsgitem.pro
deleted file mode 100644
index aa2528f4c6..0000000000
--- a/tests/auto/declarative/qsgitem2/qsgitem.pro
+++ /dev/null
@@ -1,18 +0,0 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_qsgitem.cpp
-
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-
-CONFIG += parallel_test
-
-QT += core-private gui-private v8-private declarative-private
-QT += opengl-private
diff --git a/tests/auto/declarative/qsgitem2/qsgitem2.pro b/tests/auto/declarative/qsgitem2/qsgitem2.pro
new file mode 100644
index 0000000000..517e67619b
--- /dev/null
+++ b/tests/auto/declarative/qsgitem2/qsgitem2.pro
@@ -0,0 +1,13 @@
+CONFIG += testcase
+TARGET = tst_qsgitem
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qsgitem.cpp
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
diff --git a/tests/auto/declarative/qsgitem2/tst_qsgitem.cpp b/tests/auto/declarative/qsgitem2/tst_qsgitem.cpp
index 4250708397..fe29de1aad 100644
--- a/tests/auto/declarative/qsgitem2/tst_qsgitem.cpp
+++ b/tests/auto/declarative/qsgitem2/tst_qsgitem.cpp
@@ -46,15 +46,9 @@
#include <QtDeclarative/qsgview.h>
#include <private/qsgrectangle_p.h>
#include <private/qsgitem_p.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class tst_QSGItem : public QObject
-
{
Q_OBJECT
public:
@@ -102,7 +96,7 @@ T *findItem(QSGItem *parent, const QString &objectName)
//qDebug() << parent->QSGItem::children().count() << "children";
for (int i = 0; i < parent->childItems().count(); ++i) {
QSGItem *item = qobject_cast<QSGItem*>(parent->childItems().at(i));
- if(!item)
+ if (!item)
continue;
//qDebug() << "try" << item;
if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName))
@@ -209,7 +203,7 @@ void tst_QSGItem::initTestCase()
void tst_QSGItem::keys()
{
QSGView *canvas = new QSGView(0);
- canvas->setFixedSize(240,320);
+ canvas->setBaseSize(QSize(240,320));
KeysTestObject *testObject = new KeysTestObject;
canvas->rootContext()->setContextProperty("keysTestObject", testObject);
@@ -217,7 +211,7 @@ void tst_QSGItem::keys()
canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(true));
canvas->rootContext()->setContextProperty("forwardeeVisible", QVariant(true));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keystest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("keystest.qml")));
canvas->show();
qApp->processEvents();
@@ -333,12 +327,12 @@ void tst_QSGItem::keys()
void tst_QSGItem::keysProcessingOrder()
{
QSGView *canvas = new QSGView(0);
- canvas->setFixedSize(240,320);
+ canvas->setBaseSize(QSize(240,320));
KeysTestObject *testObject = new KeysTestObject;
canvas->rootContext()->setContextProperty("keysTestObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keyspriority.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("keyspriority.qml")));
canvas->show();
qApp->processEvents();
@@ -409,7 +403,7 @@ bool anchorsMirrored(QSGItem *rootItem, const char * itemString)
void tst_QSGItem::layoutMirroring()
{
QSGView *canvas = new QSGView(0);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/layoutmirroring.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("layoutmirroring.qml")));
canvas->show();
QSGItem *rootItem = qobject_cast<QSGItem*>(canvas->rootObject());
@@ -501,7 +495,7 @@ void tst_QSGItem::layoutMirroring()
QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, true);
QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, true);
QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, true);
-
+
//
// dynamic parenting
//
@@ -531,7 +525,7 @@ void tst_QSGItem::layoutMirroring()
childItem2->setParentItem(parentItem2);
QCOMPARE(QSGItemPrivate::get(childItem2)->effectiveLayoutMirror, false);
QCOMPARE(QSGItemPrivate::get(childItem2)->inheritMirrorFromParent, false);
-
+
delete parentItem1;
delete parentItem2;
}
@@ -548,9 +542,9 @@ void tst_QSGItem::layoutMirroringIllegalParent()
void tst_QSGItem::keyNavigation()
{
QSGView *canvas = new QSGView(0);
- canvas->setFixedSize(240,320);
+ canvas->setBaseSize(QSize(240,320));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keynavigationtest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest.qml")));
canvas->show();
qApp->processEvents();
@@ -628,9 +622,9 @@ void tst_QSGItem::keyNavigation()
void tst_QSGItem::keyNavigation_RightToLeft()
{
QSGView *canvas = new QSGView(0);
- canvas->setFixedSize(240,320);
+ canvas->setBaseSize(QSize(240,320));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keynavigationtest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest.qml")));
canvas->show();
qApp->processEvents();
@@ -681,9 +675,9 @@ void tst_QSGItem::keyNavigation_RightToLeft()
void tst_QSGItem::keyNavigation_skipNotVisible()
{
QSGView *canvas = new QSGView(0);
- canvas->setFixedSize(240,320);
+ canvas->setBaseSize(QSize(240,320));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keynavigationtest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest.qml")));
canvas->show();
qApp->processEvents();
@@ -759,9 +753,9 @@ void tst_QSGItem::keyNavigation_skipNotVisible()
void tst_QSGItem::keyNavigation_implicitSetting()
{
QSGView *canvas = new QSGView(0);
- canvas->setFixedSize(240,320);
+ canvas->setBaseSize(QSize(240,320));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keynavigationtest_implicit.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest_implicit.qml")));
canvas->show();
qApp->processEvents();
@@ -946,8 +940,8 @@ void tst_QSGItem::mapCoordinates()
QFETCH(int, y);
QSGView *canvas = new QSGView(0);
- canvas->setFixedSize(300, 300);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/mapCoordinates.qml"));
+ canvas->setBaseSize(QSize(300, 300));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("mapCoordinates.qml")));
canvas->show();
qApp->processEvents();
@@ -976,8 +970,8 @@ void tst_QSGItem::mapCoordinates()
Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
QCOMPARE(result.value<QPointF>(), qobject_cast<QSGItem*>(a)->mapFromScene(QPointF(x, y)));
- QString warning1 = QUrl::fromLocalFile(SRCDIR "/data/mapCoordinates.qml").toString() + ":7:5: QML Item: mapToItem() given argument \"1122\" which is neither null nor an Item";
- QString warning2 = QUrl::fromLocalFile(SRCDIR "/data/mapCoordinates.qml").toString() + ":7:5: QML Item: mapFromItem() given argument \"1122\" which is neither null nor an Item";
+ QString warning1 = QUrl::fromLocalFile(TESTDATA("mapCoordinates.qml")).toString() + ":48:5: QML Item: mapToItem() given argument \"1122\" which is neither null nor an Item";
+ QString warning2 = QUrl::fromLocalFile(TESTDATA("mapCoordinates.qml")).toString() + ":48:5: QML Item: mapFromItem() given argument \"1122\" which is neither null nor an Item";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QVERIFY(QMetaObject::invokeMethod(root, "checkMapAToInvalid",
@@ -1028,8 +1022,8 @@ void tst_QSGItem::transforms()
void tst_QSGItem::childrenProperty()
{
- QDeclarativeComponent component(&engine, SRCDIR "/data/childrenProperty.qml");
-
+ QDeclarativeComponent component(&engine, TESTDATA("childrenProperty.qml"));
+
QObject *o = component.create();
QVERIFY(o != 0);
@@ -1043,8 +1037,8 @@ void tst_QSGItem::childrenProperty()
void tst_QSGItem::resourcesProperty()
{
- QDeclarativeComponent component(&engine, SRCDIR "/data/resourcesProperty.qml");
-
+ QDeclarativeComponent component(&engine, TESTDATA("resourcesProperty.qml"));
+
QObject *o = component.create();
QVERIFY(o != 0);
@@ -1059,13 +1053,11 @@ void tst_QSGItem::resourcesProperty()
void tst_QSGItem::propertyChanges()
{
QSGView *canvas = new QSGView(0);
- canvas->setFixedSize(240,320);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
+ canvas->setBaseSize(QSize(300, 300));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml")));
canvas->show();
- QApplication::setActiveWindow(canvas);
QTest::qWaitForWindowShown(canvas);
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
QSGItem *item = findItem<QSGItem>(canvas->rootObject(), "item");
QSGItem *parentItem = findItem<QSGItem>(canvas->rootObject(), "parentItem");
@@ -1142,8 +1134,8 @@ void tst_QSGItem::propertyChanges()
void tst_QSGItem::childrenRect()
{
QSGView *canvas = new QSGView(0);
- canvas->setFixedSize(240,320);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/childrenRect.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRect.qml")));
+ canvas->setBaseSize(QSize(240,320));
canvas->show();
QSGItem *o = canvas->rootObject();
@@ -1171,7 +1163,7 @@ void tst_QSGItem::childrenRect()
void tst_QSGItem::childrenRectBug()
{
QSGView *canvas = new QSGView(0);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/childrenRectBug.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRectBug.qml")));
canvas->show();
QSGItem *o = canvas->rootObject();
@@ -1187,7 +1179,7 @@ void tst_QSGItem::childrenRectBug()
void tst_QSGItem::childrenRectBug2()
{
QSGView *canvas = new QSGView(0);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/childrenRectBug2.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRectBug2.qml")));
canvas->show();
QSGRectangle *rect = qobject_cast<QSGRectangle*>(canvas->rootObject());
@@ -1210,7 +1202,7 @@ void tst_QSGItem::childrenRectBug2()
void tst_QSGItem::childrenRectBug3()
{
QSGView *canvas = new QSGView(0);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/childrenRectBug3.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRectBug3.qml")));
canvas->show();
//don't crash on delete
@@ -1221,7 +1213,7 @@ void tst_QSGItem::childrenRectBug3()
void tst_QSGItem::transformCrash()
{
QSGView *canvas = new QSGView(0);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/transformCrash.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("transformCrash.qml")));
canvas->show();
delete canvas;
@@ -1230,7 +1222,7 @@ void tst_QSGItem::transformCrash()
void tst_QSGItem::implicitSize()
{
QSGView *canvas = new QSGView(0);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/implicitsize.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("implicitsize.qml")));
canvas->show();
QSGItem *item = qobject_cast<QSGItem*>(canvas->rootObject());
@@ -1258,7 +1250,7 @@ void tst_QSGItem::implicitSize()
void tst_QSGItem::qtbug_16871()
{
- QDeclarativeComponent component(&engine, SRCDIR "/data/qtbug_16871.qml");
+ QDeclarativeComponent component(&engine, TESTDATA("qtbug_16871.qml"));
QObject *o = component.create();
QVERIFY(o != 0);
delete o;
diff --git a/tests/auto/declarative/qsglistview/data/ComponentView.qml b/tests/auto/declarative/qsglistview/data/ComponentView.qml
new file mode 100644
index 0000000000..3e87be8799
--- /dev/null
+++ b/tests/auto/declarative/qsglistview/data/ComponentView.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.0
+
+ListView {
+ id: view
+
+ property string title
+
+ width: 100; height: 100;
+
+ model: 1
+ delegate: Text { objectName: "listItem"; text: view.title }
+ header: Text { objectName: "header"; text: view.title }
+ footer: Text { objectName: "footer"; text: view.title }
+ section.delegate: Text { objectName: "section"; text: view.title }
+ section.property: "modelData"
+}
diff --git a/tests/auto/declarative/qsglistview/data/creationContext.qml b/tests/auto/declarative/qsglistview/data/creationContext.qml
new file mode 100644
index 0000000000..79a682788b
--- /dev/null
+++ b/tests/auto/declarative/qsglistview/data/creationContext.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+ComponentView {
+ title: "Hello!"
+}
diff --git a/tests/auto/declarative/qsglistview/data/header1.qml b/tests/auto/declarative/qsglistview/data/fillModelOnComponentCompleted.qml
index 8ba6e57594..906e6adb6b 100644
--- a/tests/auto/declarative/qsglistview/data/header1.qml
+++ b/tests/auto/declarative/qsglistview/data/fillModelOnComponentCompleted.qml
@@ -14,6 +14,7 @@ Rectangle {
anchors.top: parent.top
anchors.bottom: parent.bottom
model: testModel
+
delegate: Text {
objectName: "wrapper"
font.pointSize: 20
@@ -28,6 +29,8 @@ Rectangle {
}
Component.onCompleted: {
+ if (setCurrentToZero == 0)
+ list.currentIndex = 0
for (var i=0; i<30; i++) testModel.append({"name" : i, "val": i})
}
}
diff --git a/tests/auto/declarative/qsglistview/data/margins.qml b/tests/auto/declarative/qsglistview/data/margins.qml
new file mode 100644
index 0000000000..19bbef500f
--- /dev/null
+++ b/tests/auto/declarative/qsglistview/data/margins.qml
@@ -0,0 +1,47 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ width: 240
+ height: 320
+ color: "#ffffff"
+
+ Component {
+ id: myDelegate
+ Rectangle {
+ id: wrapper
+ objectName: "wrapper"
+ height: 20
+ width: 240
+ Text {
+ text: index
+ }
+ Text {
+ x: 30
+ id: textName
+ objectName: "textName"
+ text: name
+ }
+ Text {
+ x: 120
+ id: textNumber
+ objectName: "textNumber"
+ text: number
+ }
+ Text {
+ x: 200
+ text: wrapper.y
+ }
+ color: ListView.isCurrentItem ? "lightsteelblue" : "white"
+ }
+ }
+ ListView {
+ id: list
+ objectName: "list"
+ anchors.fill: parent
+ topMargin: 30
+ bottomMargin: 50
+ model: testModel
+ delegate: myDelegate
+ }
+}
diff --git a/tests/auto/declarative/qsglistview/data/qtbug-21742.qml b/tests/auto/declarative/qsglistview/data/qtbug-21742.qml
new file mode 100644
index 0000000000..774f9041fb
--- /dev/null
+++ b/tests/auto/declarative/qsglistview/data/qtbug-21742.qml
@@ -0,0 +1,36 @@
+import QtQuick 2.0
+
+Rectangle {
+ height: 200
+ width: 200
+ property int count: menuView.count
+
+ Component.onCompleted: { setModel(); }
+
+ function setModel()
+ {
+ menuModel.append({"enabledItem" : true});
+ menuView.currentIndex = 0;
+ }
+
+ ListModel {
+ id: menuModel
+ }
+
+ ListView {
+ id: menuView
+ anchors.fill: parent
+ model: menuModel
+ delegate: mything
+ }
+
+ Component {
+ id: mything
+ Rectangle {
+ height: 50
+ width: 200
+ color: index == menuView.currentIndex ? "green" : "blue"
+ }
+ }
+
+} \ No newline at end of file
diff --git a/tests/auto/declarative/qsglistview/data/resizeview.qml b/tests/auto/declarative/qsglistview/data/resizeview.qml
new file mode 100644
index 0000000000..071cdedf2e
--- /dev/null
+++ b/tests/auto/declarative/qsglistview/data/resizeview.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+
+ property real initialHeight
+
+ ListView {
+ id: list
+ objectName: "list"
+ width: 240
+ height: initialHeight
+ model: testModel
+ delegate: Rectangle {
+ objectName: "wrapper"
+ width: 240
+ height: 20
+ border.width: 1
+ }
+ }
+}
+
diff --git a/tests/auto/declarative/qsglistview/data/snapToItem.qml b/tests/auto/declarative/qsglistview/data/snapToItem.qml
new file mode 100644
index 0000000000..6f201072f0
--- /dev/null
+++ b/tests/auto/declarative/qsglistview/data/snapToItem.qml
@@ -0,0 +1,49 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ width: 240
+ height: 240
+ color: "#ffffff"
+
+ Component {
+ id: myDelegate
+ Rectangle {
+ id: wrapper
+ objectName: "wrapper"
+ height: 80
+ width: 80
+ Column {
+ Text {
+ text: index
+ }
+ Text {
+ text: wrapper.x + ", " + wrapper.y
+ }
+ }
+ color: ListView.isCurrentItem ? "lightsteelblue" : "transparent"
+ }
+ }
+ ListView {
+ id: list
+ objectName: "list"
+ anchors.fill: parent
+// preferredHighlightBegin: 20
+// preferredHighlightEnd: 100
+ preferredHighlightBegin: 20
+ preferredHighlightEnd: 100
+ snapMode: ListView.SnapToItem
+ orientation: ListView.Horizontal
+ layoutDirection: Qt.RightToLeft
+ highlightRangeMode: ListView.StrictlyEnforceRange
+ highlight: Rectangle { width: 80; height: 80; color: "yellow" }
+ model: 18
+ delegate: myDelegate
+ }
+
+ Text {
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ text: list.contentX + ", " + list.contentY
+ }
+}
diff --git a/tests/auto/declarative/qsglistview/incrementalmodel.cpp b/tests/auto/declarative/qsglistview/incrementalmodel.cpp
index 4b8e3cf6fa..53d30915f5 100644
--- a/tests/auto/declarative/qsglistview/incrementalmodel.cpp
+++ b/tests/auto/declarative/qsglistview/incrementalmodel.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
#include "incrementalmodel.h"
-#include <QApplication>
+#include <QGuiApplication>
#include <QDebug>
IncrementalModel::IncrementalModel(QObject *parent)
diff --git a/tests/auto/declarative/qsglistview/qsglistview.pro b/tests/auto/declarative/qsglistview/qsglistview.pro
index 4c781887ce..3322f30dd9 100644
--- a/tests/auto/declarative/qsglistview/qsglistview.pro
+++ b/tests/auto/declarative/qsglistview/qsglistview.pro
@@ -1,18 +1,13 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qsglistview
macx:CONFIG -= app_bundle
HEADERS += incrementalmodel.h
SOURCES += tst_qsglistview.cpp incrementalmodel.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
-CONFIG += parallel_test
-QT += core-private gui-private declarative-private widgets widgets-private v8-private
-QT += opengl-private
+CONFIG += insignificant_test parallel_test
+QT += core-private gui-private declarative-private widgets widgets-private v8-private opengl-private testlib
diff --git a/tests/auto/declarative/qsglistview/tst_qsglistview.cpp b/tests/auto/declarative/qsglistview/tst_qsglistview.cpp
index ce1587db88..8e2375d6b5 100644
--- a/tests/auto/declarative/qsglistview/tst_qsglistview.cpp
+++ b/tests/auto/declarative/qsglistview/tst_qsglistview.cpp
@@ -52,14 +52,9 @@
#include <QtDeclarative/private/qdeclarativelistmodel_p.h>
#include <QtDeclarative/private/qlistmodelinterface_p.h>
#include <QtDeclarative/private/qdeclarativechangeset_p.h>
-#include "../../../shared/util.h"
+#include "../shared/util.h"
#include "incrementalmodel.h"
-#include <QtOpenGL/QGLShaderProgram>
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include <math.h>
Q_DECLARE_METATYPE(Qt::LayoutDirection)
Q_DECLARE_METATYPE(QSGListView::Orientation)
@@ -81,7 +76,11 @@ private slots:
void qAbstractItemModel_changed();
void qListModelInterface_inserted();
+ void qListModelInterface_inserted_more();
+ void qListModelInterface_inserted_more_data();
void qAbstractItemModel_inserted();
+ void qAbstractItemModel_inserted_more();
+ void qAbstractItemModel_inserted_more_data();
void qListModelInterface_removed();
void qAbstractItemModel_removed();
@@ -99,6 +98,8 @@ private slots:
void swapWithFirstItem();
void itemList();
+ void currentIndex_delayedItemCreation();
+ void currentIndex_delayedItemCreation_data();
void currentIndex();
void noCurrentIndex();
void enforceRange();
@@ -113,9 +114,7 @@ private slots:
void propertyChanges();
void componentChanges();
void modelChanges();
- void QTBUG_9791();
void manualHighlight();
- void QTBUG_11105();
void header();
void header_data();
void header_delayItemCreation();
@@ -123,6 +122,7 @@ private slots:
void footer_data();
void headerFooter();
void resizeView();
+ void resizeViewAndRepaint();
void sizeLessThan1();
void QTBUG_14821();
void resizeDelegate();
@@ -136,15 +136,25 @@ private slots:
void onRemove_data();
void rightToLeft();
void test_mirroring();
+ void margins();
+ void creationContext();
+ void snapToItem_data();
+ void snapToItem();
+
+ void QTBUG_9791();
+ void QTBUG_11105();
+ void QTBUG_21742();
private:
template <class T> void items();
template <class T> void changed();
template <class T> void inserted();
+ template <class T> void inserted_more();
template <class T> void removed(bool animated);
template <class T> void moved();
template <class T> void clear();
QSGView *createView();
+ void flick(QSGView *canvas, const QPoint &from, const QPoint &to, int duration);
QSGItem *findVisibleChild(QSGItem *parent, const QString &objectName);
template<typename T>
T *findItem(QSGItem *parent, const QString &id, int index=-1);
@@ -152,6 +162,7 @@ private:
QList<T*> findItems(QSGItem *parent, const QString &objectName);
void dumpTree(QSGItem *parent, int depth = 0);
+ void inserted_more_data();
void moved_data();
};
@@ -248,7 +259,7 @@ public:
QList<int> roles() const { return QList<int>() << Name << Number; }
QString toString(int role) const {
- switch(role) {
+ switch (role) {
case Name:
return "name";
case Number:
@@ -272,7 +283,7 @@ public:
for (int i = 0; i < roles.size(); ++i) {
int role = roles.at(i);
QVariant info;
- switch(role) {
+ switch (role) {
case Name:
info = list.at(index).first;
break;
@@ -455,7 +466,7 @@ void tst_QSGListView::items()
TestObject *testObject = new TestObject;
ctxt->setContextProperty("testObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -535,7 +546,7 @@ void tst_QSGListView::changed()
TestObject *testObject = new TestObject;
ctxt->setContextProperty("testObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")));
qApp->processEvents();
QSGFlickable *listview = findItem<QSGFlickable>(canvas->rootObject(), "list");
@@ -573,7 +584,7 @@ void tst_QSGListView::inserted()
TestObject *testObject = new TestObject;
ctxt->setContextProperty("testObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -655,6 +666,159 @@ void tst_QSGListView::inserted()
}
template <class T>
+void tst_QSGListView::inserted_more()
+{
+ QFETCH(qreal, contentY);
+ QFETCH(int, insertIndex);
+ QFETCH(int, insertCount);
+ QFETCH(qreal, itemsOffsetAfterMove);
+
+ QSGText *name;
+ QSGText *number;
+ QSGView *canvas = createView();
+ canvas->show();
+
+ T model;
+ for (int i = 0; i < 30; i++)
+ model.addItem("Item" + QString::number(i), "");
+
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ TestObject *testObject = new TestObject;
+ ctxt->setContextProperty("testObject", testObject);
+
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")));
+ qApp->processEvents();
+
+ QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
+ QTRY_VERIFY(listview != 0);
+ QSGItem *contentItem = listview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ listview->setContentY(contentY);
+
+ QList<QPair<QString, QString> > newData;
+ for (int i=0; i<insertCount; i++)
+ newData << qMakePair(QString("value %1").arg(i), QString::number(i));
+ model.insertItems(insertIndex, newData);
+ QTRY_COMPARE(listview->property("count").toInt(), model.count());
+
+ // check visibleItems.first() is in correct position
+ QSGItem *item0 = findItem<QSGItem>(contentItem, "wrapper", 0);
+ QVERIFY(item0);
+ QCOMPARE(item0->y(), itemsOffsetAfterMove);
+
+ QList<QSGItem*> items = findItems<QSGItem>(contentItem, "wrapper");
+ int firstVisibleIndex = -1;
+ for (int i=0; i<items.count(); i++) {
+ if (items[i]->y() >= contentY) {
+ QDeclarativeExpression e(qmlContext(items[i]), items[i], "index");
+ firstVisibleIndex = e.evaluate().toInt();
+ break;
+ }
+ }
+ QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex));
+
+ // Confirm items positioned correctly and indexes correct
+ int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
+ for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) {
+ QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
+ QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+ QTRY_COMPARE(item->y(), i*20.0 + itemsOffsetAfterMove);
+ name = findItem<QSGText>(contentItem, "textName", i);
+ QVERIFY(name != 0);
+ QTRY_COMPARE(name->text(), model.name(i));
+ number = findItem<QSGText>(contentItem, "textNumber", i);
+ QVERIFY(number != 0);
+ QTRY_COMPARE(number->text(), model.number(i));
+ }
+
+ delete canvas;
+ delete testObject;
+}
+
+void tst_QSGListView::inserted_more_data()
+{
+ QTest::addColumn<qreal>("contentY");
+ QTest::addColumn<int>("insertIndex");
+ QTest::addColumn<int>("insertCount");
+ QTest::addColumn<qreal>("itemsOffsetAfterMove");
+
+ QTest::newRow("add 1, before visible items")
+ << 80.0 // show 4-19
+ << 3 << 1
+ << -20.0; // insert above first visible i.e. 0 is at -20, first visible should not move
+
+ QTest::newRow("add multiple, before visible")
+ << 80.0 // show 4-19
+ << 3 << 3
+ << -20.0 * 3; // again first visible should not move
+
+ QTest::newRow("add 1, at start of visible, content at start")
+ << 0.0
+ << 0 << 1
+ << 0.0;
+
+ QTest::newRow("add multiple, start of visible, content at start")
+ << 0.0
+ << 0 << 3
+ << 0.0;
+
+ QTest::newRow("add 1, at start of visible, content not at start")
+ << 80.0 // show 4-19
+ << 4 << 1
+ << 0.0;
+
+ QTest::newRow("add multiple, at start of visible, content not at start")
+ << 80.0 // show 4-19
+ << 4 << 3
+ << 0.0;
+
+
+ QTest::newRow("add 1, at end of visible, content at start")
+ << 0.0
+ << 15 << 1
+ << 0.0;
+
+ QTest::newRow("add 1, at end of visible, content at start")
+ << 0.0
+ << 15 << 3
+ << 0.0;
+
+ QTest::newRow("add 1, at end of visible, content not at start")
+ << 80.0 // show 4-19
+ << 19 << 1
+ << 0.0;
+
+ QTest::newRow("add multiple, at end of visible, content not at start")
+ << 80.0 // show 4-19
+ << 19 << 3
+ << 0.0;
+
+
+ QTest::newRow("add 1, after visible, content at start")
+ << 0.0
+ << 16 << 1
+ << 0.0;
+
+ QTest::newRow("add 1, after visible, content at start")
+ << 0.0
+ << 16 << 3
+ << 0.0;
+
+ QTest::newRow("add 1, after visible, content not at start")
+ << 80.0 // show 4-19
+ << 20 << 1
+ << 0.0;
+
+ QTest::newRow("add multiple, after visible, content not at start")
+ << 80.0 // show 4-19
+ << 20 << 3
+ << 0.0;
+}
+
+template <class T>
void tst_QSGListView::removed(bool animated)
{
QSGView *canvas = createView();
@@ -669,7 +833,7 @@ void tst_QSGListView::removed(bool animated)
TestObject *testObject = new TestObject;
ctxt->setContextProperty("testObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")));
canvas->show();
qApp->processEvents();
@@ -847,7 +1011,7 @@ void tst_QSGListView::clear()
TestObject *testObject = new TestObject;
ctxt->setContextProperty("testObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -897,7 +1061,7 @@ void tst_QSGListView::moved()
TestObject *testObject = new TestObject;
ctxt->setContextProperty("testObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -913,7 +1077,7 @@ void tst_QSGListView::moved()
model.moveItems(from, to, count);
// wait for items to move
- QTest::qWait(300);
+ QTest::qWait(100);
QList<QSGItem*> items = findItems<QSGItem>(contentItem, "wrapper");
int firstVisibleIndex = -1;
@@ -985,7 +1149,7 @@ void tst_QSGListView::moved_data()
QTest::newRow("move 1 forwards, from visible -> non-visible (move first item)")
<< 0.0
<< 0 << 16 << 1
- << 20.0;
+ << 0.0;
QTest::newRow("move 1 backwards, within visible items")
@@ -1022,7 +1186,12 @@ void tst_QSGListView::moved_data()
QTest::newRow("move multiple forwards, within visible items")
<< 0.0
<< 0 << 5 << 3
- << 20.0 * 3;
+ << 0.0;
+
+ QTest::newRow("move multiple forwards, before visible items")
+ << 140.0 // show 7-22
+ << 4 << 5 << 3 // 4,5,6 move to below 7
+ << 20.0 * 3; // 4,5,6 moved down
QTest::newRow("move multiple forwards, from non-visible -> visible")
<< 80.0 // show 4-19
@@ -1042,7 +1211,7 @@ void tst_QSGListView::moved_data()
QTest::newRow("move multiple forwards, from visible -> non-visible (move first item)")
<< 0.0
<< 0 << 16 << 3
- << 20.0 * 3;
+ << 0.0;
QTest::newRow("move multiple backwards, within visible items")
@@ -1105,7 +1274,7 @@ void tst_QSGListView::multipleChanges()
TestObject *testObject = new TestObject;
ctxt->setContextProperty("testObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -1322,7 +1491,7 @@ void tst_QSGListView::swapWithFirstItem()
TestObject *testObject = new TestObject;
ctxt->setContextProperty("testObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -1348,7 +1517,7 @@ void tst_QSGListView::enforceRange()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview-enforcerange.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-enforcerange.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -1409,7 +1578,7 @@ void tst_QSGListView::enforceRange_withoutHighlight()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview-enforcerange-nohighlight.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-enforcerange-nohighlight.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -1451,7 +1620,7 @@ void tst_QSGListView::spacing()
TestObject *testObject = new TestObject;
ctxt->setContextProperty("testObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -1508,7 +1677,7 @@ void tst_QSGListView::sections()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview-sections.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-sections.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -1602,7 +1771,7 @@ void tst_QSGListView::sectionsDelegate()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview-sections_delegate.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-sections_delegate.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -1715,7 +1884,7 @@ void tst_QSGListView::sectionsPositioning()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview-sections_delegate.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-sections_delegate.qml")));
qApp->processEvents();
canvas->rootObject()->setProperty("sectionPositioning", QVariant(int(QSGViewSection::InlineLabels | QSGViewSection::CurrentLabelAtStart | QSGViewSection::NextLabelAtEnd)));
@@ -1804,18 +1973,18 @@ void tst_QSGListView::sectionsPositioning()
QTRY_VERIFY(topItem = findVisibleChild(contentItem, "sect_aaa")); // section header
QCOMPARE(topItem->y(), 120.);
QVERIFY(topItem = findVisibleChild(contentItem, "sect_1"));
- QCOMPARE(topItem->y(), 140.);
+ QTRY_COMPARE(topItem->y(), 140.);
// Change the next section
listview->setContentY(0);
bottomItem = findVisibleChild(contentItem, "sect_3"); // section footer
QVERIFY(bottomItem);
- QCOMPARE(bottomItem->y(), 320.);
+ QTRY_COMPARE(bottomItem->y(), 320.);
model.modifyItem(14, "New", "new");
QTRY_VERIFY(bottomItem = findVisibleChild(contentItem, "sect_new")); // section footer
- QCOMPARE(bottomItem->y(), 320.);
+ QTRY_COMPARE(bottomItem->y(), 320.);
// Turn sticky footer off
listview->setContentY(50);
@@ -1832,6 +2001,42 @@ void tst_QSGListView::sectionsPositioning()
delete canvas;
}
+void tst_QSGListView::currentIndex_delayedItemCreation()
+{
+ QFETCH(bool, setCurrentToZero);
+
+ QSGView *canvas = createView();
+
+ TestModel model;
+
+ // test currentIndexChanged() is emitted even if currentIndex = 0 on start up
+ // (since the currentItem will have changed and that shares the same index)
+ canvas->rootContext()->setContextProperty("setCurrentToZero", setCurrentToZero);
+
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("fillModelOnComponentCompleted.qml")));
+ qApp->processEvents();
+
+ QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
+ QTRY_VERIFY(listview != 0);
+
+ QSGItem *contentItem = listview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ QSignalSpy spy(listview, SIGNAL(currentIndexChanged()));
+ QCOMPARE(listview->currentIndex(), 0);
+ QTRY_COMPARE(spy.count(), 1);
+
+ delete canvas;
+}
+
+void tst_QSGListView::currentIndex_delayedItemCreation_data()
+{
+ QTest::addColumn<bool>("setCurrentToZero");
+
+ QTest::newRow("set to 0") << true;
+ QTest::newRow("don't set to 0") << false;
+}
+
void tst_QSGListView::currentIndex()
{
TestModel model;
@@ -1845,7 +2050,7 @@ void tst_QSGListView::currentIndex()
ctxt->setContextProperty("testModel", &model);
ctxt->setContextProperty("testWrap", QVariant(false));
- QString filename(SRCDIR "/data/listview-initCurrent.qml");
+ QString filename(TESTDATA("listview-initCurrent.qml"));
canvas->setSource(QUrl::fromLocalFile(filename));
qApp->processEvents();
@@ -1914,12 +2119,8 @@ void tst_QSGListView::currentIndex()
// Test keys
canvas->show();
canvas->requestActivateWindow();
-#ifdef Q_WS_X11
- // to be safe and avoid failing setFocus with window managers
- qt_x11_wait_for_window_manager(canvas);
-#endif
-
- qApp->processEvents();
+ QTest::qWaitForWindowShown(canvas);
+ QTRY_VERIFY(qGuiApp->focusWindow() == canvas);
listview->setCurrentIndex(0);
@@ -1985,7 +2186,7 @@ void tst_QSGListView::noCurrentIndex()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- QString filename(SRCDIR "/data/listview-noCurrent.qml");
+ QString filename(TESTDATA("listview-noCurrent.qml"));
canvas->setSource(QUrl::fromLocalFile(filename));
qApp->processEvents();
@@ -2015,7 +2216,7 @@ void tst_QSGListView::itemList()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/itemlist.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("itemlist.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "view");
@@ -2066,7 +2267,7 @@ void tst_QSGListView::cacheBuffer()
TestObject *testObject = new TestObject;
ctxt->setContextProperty("testObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -2119,7 +2320,7 @@ void tst_QSGListView::positionViewAtIndex()
TestObject *testObject = new TestObject;
ctxt->setContextProperty("testObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -2284,7 +2485,7 @@ void tst_QSGListView::resetModel()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/displaylist.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaylist.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -2320,7 +2521,7 @@ void tst_QSGListView::propertyChanges()
{
QSGView *canvas = createView();
QTRY_VERIFY(canvas);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml")));
QSGListView *listView = canvas->rootObject()->findChild<QSGListView*>("listView");
QTRY_VERIFY(listView);
@@ -2388,7 +2589,7 @@ void tst_QSGListView::componentChanges()
{
QSGView *canvas = createView();
QTRY_VERIFY(canvas);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml")));
QSGListView *listView = canvas->rootObject()->findChild<QSGListView*>("listView");
QTRY_VERIFY(listView);
@@ -2436,7 +2637,7 @@ void tst_QSGListView::modelChanges()
{
QSGView *canvas = createView();
QTRY_VERIFY(canvas);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychangestest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml")));
QSGListView *listView = canvas->rootObject()->findChild<QSGListView*>("listView");
QTRY_VERIFY(listView);
@@ -2463,7 +2664,7 @@ void tst_QSGListView::QTBUG_9791()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/strictlyenforcerange.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("strictlyenforcerange.qml")));
qApp->processEvents();
QSGListView *listview = qobject_cast<QSGListView*>(canvas->rootObject());
@@ -2499,7 +2700,7 @@ void tst_QSGListView::manualHighlight()
QSGView *canvas = new QSGView(0);
canvas->setGeometry(0,0,240,320);
- QString filename(SRCDIR "/data/manual-highlight.qml");
+ QString filename(TESTDATA("manual-highlight.qml"));
canvas->setSource(QUrl::fromLocalFile(filename));
qApp->processEvents();
@@ -2544,7 +2745,7 @@ void tst_QSGListView::QTBUG_11105()
TestObject *testObject = new TestObject;
ctxt->setContextProperty("testObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -2597,7 +2798,7 @@ void tst_QSGListView::header()
canvas->rootContext()->setContextProperty("testModel", &model);
canvas->rootContext()->setContextProperty("initialViewWidth", 240);
canvas->rootContext()->setContextProperty("initialViewHeight", 320);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml")));
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
QTRY_VERIFY(listview != 0);
@@ -2654,7 +2855,7 @@ void tst_QSGListView::header()
canvas->rootContext()->setContextProperty("testModel", &model);
canvas->rootContext()->setContextProperty("initialViewWidth", 0.0);
canvas->rootContext()->setContextProperty("initialViewHeight", 0.0);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml")));
listview = findItem<QSGListView>(canvas->rootObject(), "list");
QTRY_VERIFY(listview != 0);
@@ -2729,7 +2930,8 @@ void tst_QSGListView::header_delayItemCreation()
TestModel model;
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/header1.qml"));
+ canvas->rootContext()->setContextProperty("setCurrentToZero", false);
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("fillModelOnComponentCompleted.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -2770,7 +2972,7 @@ void tst_QSGListView::footer()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/footer.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("footer.qml")));
canvas->show();
qApp->processEvents();
@@ -2925,7 +3127,7 @@ void tst_QSGListView::headerFooter()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/headerfooter.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("headerfooter.qml")));
qApp->processEvents();
QSGListView *listview = qobject_cast<QSGListView*>(canvas->rootObject());
@@ -2955,7 +3157,7 @@ void tst_QSGListView::headerFooter()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/headerfooter.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("headerfooter.qml")));
canvas->rootObject()->setProperty("horizontal", true);
qApp->processEvents();
@@ -2986,7 +3188,7 @@ void tst_QSGListView::headerFooter()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/headerfooter.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("headerfooter.qml")));
canvas->rootObject()->setProperty("horizontal", true);
canvas->rootObject()->setProperty("rtl", true);
qApp->processEvents();
@@ -3026,7 +3228,7 @@ void tst_QSGListView::resizeView()
TestObject *testObject = new TestObject;
ctxt->setContextProperty("testObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -3057,6 +3259,39 @@ void tst_QSGListView::resizeView()
delete testObject;
}
+void tst_QSGListView::resizeViewAndRepaint()
+{
+ QSGView *canvas = createView();
+ canvas->show();
+
+ TestModel model;
+ for (int i = 0; i < 40; i++)
+ model.addItem("Item" + QString::number(i), "");
+
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+ ctxt->setContextProperty("initialHeight", 100);
+
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizeview.qml")));
+ qApp->processEvents();
+
+ QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
+ QTRY_VERIFY(listview != 0);
+ QSGItem *contentItem = listview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ // item at index 10 should not be currently visible
+ QVERIFY(!findItem<QSGItem>(contentItem, "wrapper", 10));
+
+ listview->setHeight(320);
+ QTRY_VERIFY(findItem<QSGItem>(contentItem, "wrapper", 10));
+
+ listview->setHeight(100);
+ QTRY_VERIFY(!findItem<QSGItem>(contentItem, "wrapper", 10));
+
+ delete canvas;
+}
+
void tst_QSGListView::sizeLessThan1()
{
QSGView *canvas = createView();
@@ -3071,7 +3306,7 @@ void tst_QSGListView::sizeLessThan1()
TestObject *testObject = new TestObject;
ctxt->setContextProperty("testObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/sizelessthan1.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("sizelessthan1.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -3097,7 +3332,7 @@ void tst_QSGListView::QTBUG_14821()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/qtbug14821.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("qtbug14821.qml")));
qApp->processEvents();
QSGListView *listview = qobject_cast<QSGListView*>(canvas->rootObject());
@@ -3128,7 +3363,7 @@ void tst_QSGListView::resizeDelegate()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/displaylist.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaylist.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -3211,7 +3446,7 @@ void tst_QSGListView::resizeFirstDelegate()
TestObject *testObject = new TestObject;
ctxt->setContextProperty("testObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -3251,7 +3486,7 @@ void tst_QSGListView::QTBUG_16037()
QSGView *canvas = createView();
canvas->show();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/qtbug16037.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("qtbug16037.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "listview");
@@ -3280,7 +3515,7 @@ void tst_QSGListView::indexAt()
TestObject *testObject = new TestObject;
ctxt->setContextProperty("testObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listviewtest.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -3307,7 +3542,7 @@ void tst_QSGListView::incrementalModel()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/displaylist.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaylist.qml")));
qApp->processEvents();
QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
@@ -3342,7 +3577,7 @@ void tst_QSGListView::onAdd()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
ctxt->setContextProperty("delegateHeight", delegateHeight);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/attachedSignals.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml")));
QObject *object = canvas->rootObject();
object->setProperty("width", canvas->width());
@@ -3396,7 +3631,7 @@ void tst_QSGListView::onRemove()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
ctxt->setContextProperty("delegateHeight", delegateHeight);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/attachedSignals.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml")));
QObject *object = canvas->rootObject();
model.removeItems(indexToRemove, removeCount);
@@ -3434,7 +3669,7 @@ void tst_QSGListView::rightToLeft()
{
QSGView *canvas = createView();
canvas->setGeometry(0,0,640,320);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/rightToLeft.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("rightToLeft.qml")));
qApp->processEvents();
QVERIFY(canvas->rootObject() != 0);
@@ -3484,12 +3719,12 @@ void tst_QSGListView::rightToLeft()
void tst_QSGListView::test_mirroring()
{
QSGView *canvasA = createView();
- canvasA->setSource(QUrl::fromLocalFile(SRCDIR "/data/rightToLeft.qml"));
+ canvasA->setSource(QUrl::fromLocalFile(TESTDATA("rightToLeft.qml")));
QSGListView *listviewA = findItem<QSGListView>(canvasA->rootObject(), "view");
QTRY_VERIFY(listviewA != 0);
QSGView *canvasB = createView();
- canvasB->setSource(QUrl::fromLocalFile(SRCDIR "/data/rightToLeft.qml"));
+ canvasB->setSource(QUrl::fromLocalFile(TESTDATA("rightToLeft.qml")));
QSGListView *listviewB = findItem<QSGListView>(canvasB->rootObject(), "view");
QTRY_VERIFY(listviewA != 0);
qApp->processEvents();
@@ -3502,14 +3737,14 @@ void tst_QSGListView::test_mirroring()
QCOMPARE(listviewA->layoutDirection(), listviewA->effectiveLayoutDirection());
// LTR != RTL
- foreach(const QString objectName, objectNames)
+ foreach (const QString objectName, objectNames)
QVERIFY(findItem<QSGItem>(listviewA, objectName)->x() != findItem<QSGItem>(listviewB, objectName)->x());
listviewA->setProperty("layoutDirection", Qt::LeftToRight);
listviewB->setProperty("layoutDirection", Qt::LeftToRight);
// LTR == LTR
- foreach(const QString objectName, objectNames)
+ foreach (const QString objectName, objectNames)
QCOMPARE(findItem<QSGItem>(listviewA, objectName)->x(), findItem<QSGItem>(listviewB, objectName)->x());
QVERIFY(listviewB->layoutDirection() == listviewB->effectiveLayoutDirection());
@@ -3517,31 +3752,187 @@ void tst_QSGListView::test_mirroring()
QVERIFY(listviewB->layoutDirection() != listviewB->effectiveLayoutDirection());
// LTR != LTR+mirror
- foreach(const QString objectName, objectNames)
+ foreach (const QString objectName, objectNames)
QVERIFY(findItem<QSGItem>(listviewA, objectName)->x() != findItem<QSGItem>(listviewB, objectName)->x());
listviewA->setProperty("layoutDirection", Qt::RightToLeft);
// RTL == LTR+mirror
- foreach(const QString objectName, objectNames)
+ foreach (const QString objectName, objectNames)
QCOMPARE(findItem<QSGItem>(listviewA, objectName)->x(), findItem<QSGItem>(listviewB, objectName)->x());
listviewB->setProperty("layoutDirection", Qt::RightToLeft);
// RTL != RTL+mirror
- foreach(const QString objectName, objectNames)
+ foreach (const QString objectName, objectNames)
QVERIFY(findItem<QSGItem>(listviewA, objectName)->x() != findItem<QSGItem>(listviewB, objectName)->x());
listviewA->setProperty("layoutDirection", Qt::LeftToRight);
// LTR == RTL+mirror
- foreach(const QString objectName, objectNames)
+ foreach (const QString objectName, objectNames)
QCOMPARE(findItem<QSGItem>(listviewA, objectName)->x(), findItem<QSGItem>(listviewB, objectName)->x());
delete canvasA;
delete canvasB;
}
+void tst_QSGListView::margins()
+{
+ QSGView *canvas = createView();
+
+ TestModel2 model;
+ for (int i = 0; i < 50; i++)
+ model.addItem("Item" + QString::number(i), "");
+
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("margins.qml")));
+ canvas->show();
+ qApp->processEvents();
+
+ QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
+ QTRY_VERIFY(listview != 0);
+
+ QSGItem *contentItem = listview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ QCOMPARE(listview->contentY(), -30.);
+ QCOMPARE(listview->yOrigin(), 0.);
+
+ // check end bound
+ listview->positionViewAtEnd();
+ qreal pos = listview->contentY();
+ listview->setContentY(pos + 80);
+ listview->returnToBounds();
+ QTRY_COMPARE(listview->contentY(), pos + 50);
+
+ // remove item before visible and check that top margin is maintained
+ // and yOrigin is updated
+ listview->setContentY(100);
+ model.removeItem(1);
+ QTest::qWait(100);
+ listview->setContentY(-50);
+ listview->returnToBounds();
+ QCOMPARE(listview->yOrigin(), 20.);
+ QTRY_COMPARE(listview->contentY(), -10.);
+
+ // reduce top margin
+ listview->setTopMargin(20);
+ QCOMPARE(listview->yOrigin(), 20.);
+ QTRY_COMPARE(listview->contentY(), 0.);
+
+ // check end bound
+ listview->positionViewAtEnd();
+ pos = listview->contentY();
+ listview->setContentY(pos + 80);
+ listview->returnToBounds();
+ QTRY_COMPARE(listview->contentY(), pos + 50);
+
+ // reduce bottom margin
+ pos = listview->contentY();
+ listview->setBottomMargin(40);
+ QCOMPARE(listview->yOrigin(), 20.);
+ QTRY_COMPARE(listview->contentY(), pos-10);
+
+ delete canvas;
+}
+
+void tst_QSGListView::snapToItem_data()
+{
+ QTest::addColumn<QSGListView::Orientation>("orientation");
+ QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<int>("highlightRangeMode");
+ QTest::addColumn<QPoint>("flickStart");
+ QTest::addColumn<QPoint>("flickEnd");
+ QTest::addColumn<qreal>("snapAlignment");
+ QTest::addColumn<qreal>("endExtent");
+ QTest::addColumn<qreal>("startExtent");
+
+ QTest::newRow("vertical, left to right") << QSGListView::Vertical << Qt::LeftToRight << int(QSGItemView::NoHighlightRange)
+ << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 1200.0 << 0.0;
+
+ QTest::newRow("horizontal, left to right") << QSGListView::Horizontal << Qt::LeftToRight << int(QSGItemView::NoHighlightRange)
+ << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 1200.0 << 0.0;
+
+ QTest::newRow("horizontal, right to left") << QSGListView::Horizontal << Qt::RightToLeft << int(QSGItemView::NoHighlightRange)
+ << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -1200.0 - 240.0 << -240.0;
+
+ QTest::newRow("vertical, left to right, enforce range") << QSGListView::Vertical << Qt::LeftToRight << int(QSGItemView::StrictlyEnforceRange)
+ << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 1340.0 << -20.0;
+
+ QTest::newRow("horizontal, left to right, enforce range") << QSGListView::Horizontal << Qt::LeftToRight << int(QSGItemView::StrictlyEnforceRange)
+ << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 1340.0 << -20.0;
+
+ QTest::newRow("horizontal, right to left, enforce range") << QSGListView::Horizontal << Qt::RightToLeft << int(QSGItemView::StrictlyEnforceRange)
+ << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -1200.0 - 240.0 - 140.0 << -220.0;
+}
+
+void tst_QSGListView::snapToItem()
+{
+ QFETCH(QSGListView::Orientation, orientation);
+ QFETCH(Qt::LayoutDirection, layoutDirection);
+ QFETCH(int, highlightRangeMode);
+ QFETCH(QPoint, flickStart);
+ QFETCH(QPoint, flickEnd);
+ QFETCH(qreal, snapAlignment);
+ QFETCH(qreal, endExtent);
+ QFETCH(qreal, startExtent);
+
+ QSGView *canvas = createView();
+
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("snapToItem.qml")));
+ canvas->show();
+ qApp->processEvents();
+
+ QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
+ QTRY_VERIFY(listview != 0);
+
+ listview->setOrientation(orientation);
+ listview->setLayoutDirection(layoutDirection);
+ listview->setHighlightRangeMode(QSGItemView::HighlightRangeMode(highlightRangeMode));
+
+ QSGItem *contentItem = listview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ // confirm that a flick hits an item boundary
+ flick(canvas, flickStart, flickEnd, 180);
+ QTRY_VERIFY(listview->isMoving() == false); // wait until it stops
+ if (orientation == QSGListView::Vertical)
+ QCOMPARE(qreal(fmod(listview->contentY(),80.0)), snapAlignment);
+ else
+ QCOMPARE(qreal(fmod(listview->contentX(),80.0)), snapAlignment);
+
+ // flick to end
+ do {
+ flick(canvas, flickStart, flickEnd, 180);
+ QTRY_VERIFY(listview->isMoving() == false); // wait until it stops
+ } while (orientation == QSGListView::Vertical
+ ? !listview->isAtYEnd()
+ : layoutDirection == Qt::LeftToRight ? !listview->isAtXEnd() : !listview->isAtXBeginning());
+
+ if (orientation == QSGListView::Vertical)
+ QCOMPARE(listview->contentY(), endExtent);
+ else
+ QCOMPARE(listview->contentX(), endExtent);
+
+ // flick to start
+ do {
+ flick(canvas, flickEnd, flickStart, 180);
+ QTRY_VERIFY(listview->isMoving() == false); // wait until it stops
+ } while (orientation == QSGListView::Vertical
+ ? !listview->isAtYBeginning()
+ : layoutDirection == Qt::LeftToRight ? !listview->isAtXBeginning() : !listview->isAtXEnd());
+
+ if (orientation == QSGListView::Vertical)
+ QCOMPARE(listview->contentY(), startExtent);
+ else
+ QCOMPARE(listview->contentX(), startExtent);
+
+ delete canvas;
+}
+
void tst_QSGListView::qListModelInterface_items()
{
items<TestModel>();
@@ -3567,11 +3958,31 @@ void tst_QSGListView::qListModelInterface_inserted()
inserted<TestModel>();
}
+void tst_QSGListView::qListModelInterface_inserted_more()
+{
+ inserted_more<TestModel>();
+}
+
+void tst_QSGListView::qListModelInterface_inserted_more_data()
+{
+ inserted_more_data();
+}
+
void tst_QSGListView::qAbstractItemModel_inserted()
{
inserted<TestModel2>();
}
+void tst_QSGListView::qAbstractItemModel_inserted_more()
+{
+ inserted_more<TestModel2>();
+}
+
+void tst_QSGListView::qAbstractItemModel_inserted_more_data()
+{
+ inserted_more_data();
+}
+
void tst_QSGListView::qListModelInterface_removed()
{
removed<TestModel>(false);
@@ -3614,6 +4025,40 @@ void tst_QSGListView::qAbstractItemModel_clear()
clear<TestModel2>();
}
+void tst_QSGListView::creationContext()
+{
+ QSGView canvas;
+ canvas.setGeometry(0,0,240,320);
+ canvas.setSource(QUrl::fromLocalFile(TESTDATA("creationContext.qml")));
+ qApp->processEvents();
+
+ QSGItem *rootItem = qobject_cast<QSGItem *>(canvas.rootObject());
+ QVERIFY(rootItem);
+ QVERIFY(rootItem->property("count").toInt() > 0);
+
+ QSGItem *item;
+ QVERIFY(item = rootItem->findChild<QSGItem *>("listItem"));
+ QCOMPARE(item->property("text").toString(), QString("Hello!"));
+ QVERIFY(item = rootItem->findChild<QSGItem *>("header"));
+ QCOMPARE(item->property("text").toString(), QString("Hello!"));
+ QVERIFY(item = rootItem->findChild<QSGItem *>("footer"));
+ QCOMPARE(item->property("text").toString(), QString("Hello!"));
+ QVERIFY(item = rootItem->findChild<QSGItem *>("section"));
+ QCOMPARE(item->property("text").toString(), QString("Hello!"));
+}
+
+void tst_QSGListView::QTBUG_21742()
+{
+ QSGView canvas;
+ canvas.setGeometry(0,0,200,200);
+ canvas.setSource(QUrl::fromLocalFile(TESTDATA("qtbug-21742.qml")));
+ qApp->processEvents();
+
+ QSGItem *rootItem = qobject_cast<QSGItem *>(canvas.rootObject());
+ QVERIFY(rootItem);
+ QCOMPARE(rootItem->property("count").toInt(), 1);
+}
+
QSGView *tst_QSGListView::createView()
{
QSGView *canvas = new QSGView(0);
@@ -3622,6 +4067,25 @@ QSGView *tst_QSGListView::createView()
return canvas;
}
+void tst_QSGListView::flick(QSGView *canvas, const QPoint &from, const QPoint &to, int duration)
+{
+ const int pointCount = 5;
+ QPoint diff = to - from;
+
+ // send press, five equally spaced moves, and release.
+ QTest::mousePress(canvas, Qt::LeftButton, 0, from);
+
+ for (int i = 0; i < pointCount; ++i) {
+ QMouseEvent mv(QEvent::MouseMove, from + (i+1)*diff/pointCount, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+ QApplication::sendEvent(canvas, &mv);
+ QTest::qWait(duration/pointCount);
+ QCoreApplication::processEvents();
+ }
+
+ QTest::mouseRelease(canvas, Qt::LeftButton, 0, to);
+}
+
+
QSGItem *tst_QSGListView::findVisibleChild(QSGItem *parent, const QString &objectName)
{
QSGItem *item = 0;
@@ -3645,7 +4109,7 @@ T *tst_QSGListView::findItem(QSGItem *parent, const QString &objectName, int ind
//qDebug() << parent->childItems().count() << "children";
for (int i = 0; i < parent->childItems().count(); ++i) {
QSGItem *item = qobject_cast<QSGItem*>(parent->childItems().at(i));
- if(!item)
+ if (!item)
continue;
//qDebug() << "try" << item;
if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
@@ -3673,7 +4137,7 @@ QList<T*> tst_QSGListView::findItems(QSGItem *parent, const QString &objectName)
//qDebug() << parent->childItems().count() << "children";
for (int i = 0; i < parent->childItems().count(); ++i) {
QSGItem *item = qobject_cast<QSGItem*>(parent->childItems().at(i));
- if(!item || !item->isVisible())
+ if (!item || !item->isVisible())
continue;
//qDebug() << "try" << item;
if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName))
@@ -3689,14 +4153,13 @@ void tst_QSGListView::dumpTree(QSGItem *parent, int depth)
static QString padding(" ");
for (int i = 0; i < parent->childItems().count(); ++i) {
QSGItem *item = qobject_cast<QSGItem*>(parent->childItems().at(i));
- if(!item)
+ if (!item)
continue;
qDebug() << padding.left(depth*2) << item;
dumpTree(item, depth+1);
}
}
-
QTEST_MAIN(tst_QSGListView)
#include "tst_qsglistview.moc"
diff --git a/tests/auto/declarative/qsgloader/data/BigComponent.qml b/tests/auto/declarative/qsgloader/data/BigComponent.qml
new file mode 100644
index 0000000000..df92532c43
--- /dev/null
+++ b/tests/auto/declarative/qsgloader/data/BigComponent.qml
@@ -0,0 +1,5015 @@
+import QtQuick 2.0
+
+Item {
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+ Item {}
+}
diff --git a/tests/auto/declarative/qsgloader/data/active.7.qml b/tests/auto/declarative/qsgloader/data/active.7.qml
new file mode 100644
index 0000000000..a29e932f5e
--- /dev/null
+++ b/tests/auto/declarative/qsgloader/data/active.7.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+Rectangle {
+ id: root
+ color: "blue"
+ width: 100; height: 100
+ property bool success: true
+
+ Loader {
+ active: false
+ anchors.fill: parent
+ sourceComponent: Rectangle { color: "red" }
+ onLoaded: { root.success = false; } // shouldn't be triggered if active is false
+ }
+}
diff --git a/tests/auto/declarative/qsgloader/data/active.8.qml b/tests/auto/declarative/qsgloader/data/active.8.qml
new file mode 100644
index 0000000000..3a66d3e99a
--- /dev/null
+++ b/tests/auto/declarative/qsgloader/data/active.8.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.0
+Rectangle {
+ id: root
+ color: "blue"
+ width: 100; height: 100
+ property bool success: false
+
+ Loader {
+ anchors.fill: parent
+ sourceComponent: Rectangle { color: "red" }
+ onLoaded: { root.success = true; } // should be triggered since active is true by default
+ }
+}
diff --git a/tests/auto/declarative/qsgloader/data/asynchronous.qml b/tests/auto/declarative/qsgloader/data/asynchronous.qml
new file mode 100644
index 0000000000..29570525ad
--- /dev/null
+++ b/tests/auto/declarative/qsgloader/data/asynchronous.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 400; height: 400
+
+ property string comp
+ function loadComponent() {
+ loader.source = comp
+ }
+
+ Loader {
+ id: loader
+ objectName: "loader"
+ asynchronous: true
+ }
+}
diff --git a/tests/auto/declarative/qsgloader/data/initialPropertyValues.8.qml b/tests/auto/declarative/qsgloader/data/initialPropertyValues.8.qml
new file mode 100644
index 0000000000..79e9264d4a
--- /dev/null
+++ b/tests/auto/declarative/qsgloader/data/initialPropertyValues.8.qml
@@ -0,0 +1,20 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+ property int initialValue: 0
+
+ Loader {
+ id: loader
+ objectName: "loader"
+ active: false
+ onLoaded: {
+ root.initialValue = loader.item.canary; // should be six
+ }
+ }
+
+ Component.onCompleted: {
+ loader.setSource("http://127.0.0.1:14450/InitialPropertyValuesComponent.qml", {"canary": 6});
+ loader.active = true;
+ }
+}
diff --git a/tests/auto/declarative/qsgloader/qsgloader.pro b/tests/auto/declarative/qsgloader/qsgloader.pro
index 22752dff9a..01e942e926 100644
--- a/tests/auto/declarative/qsgloader/qsgloader.pro
+++ b/tests/auto/declarative/qsgloader/qsgloader.pro
@@ -1,5 +1,5 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui network
+CONFIG += testcase
+TARGET = tst_qsgloader
macx:CONFIG -= app_bundle
INCLUDEPATH += ../shared/
@@ -7,14 +7,10 @@ HEADERS += ../shared/testhttpserver.h
SOURCES += tst_qsgloader.cpp \
../shared/testhttpserver.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qsgloader/tst_qsgloader.cpp b/tests/auto/declarative/qsgloader/tst_qsgloader.cpp
index daf9e2a58a..3968a92ac0 100644
--- a/tests/auto/declarative/qsgloader/tst_qsgloader.cpp
+++ b/tests/auto/declarative/qsgloader/tst_qsgloader.cpp
@@ -44,22 +44,32 @@
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qdeclarativeincubator.h>
#include <private/qsgloader_p.h>
#include "testhttpserver.h"
-#include "../../../shared/util.h"
+#include "../shared/util.h"
#define SERVER_PORT 14450
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
inline QUrl TEST_FILE(const QString &filename)
{
- return QUrl::fromLocalFile(QLatin1String(SRCDIR) + QLatin1String("/data/") + filename);
+ return QUrl::fromLocalFile(TESTDATA(filename));
}
+class PeriodicIncubationController : public QObject,
+ public QDeclarativeIncubationController
+{
+public:
+ PeriodicIncubationController() {
+ startTimer(16);
+ }
+
+protected:
+ virtual void timerEvent(QTimerEvent *) {
+ incubateFor(15);
+ }
+};
+
class tst_QSGLoader : public QObject
{
@@ -94,6 +104,9 @@ private slots:
void QTBUG_16928();
void implicitSize();
void QTBUG_17114();
+ void asynchronous_data();
+ void asynchronous();
+ void asynchronous_clear();
private:
QDeclarativeEngine engine;
@@ -146,9 +159,14 @@ void tst_QSGLoader::sourceOrComponent()
QCOMPARE(static_cast<QSGItem*>(loader)->childItems().count(), error ? 0: 1);
if (!error) {
- QDeclarativeComponent *c = qobject_cast<QDeclarativeComponent*>(loader->children().at(0));
- QVERIFY(c);
- QCOMPARE(loader->sourceComponent(), c);
+ bool sourceComponentIsChildOfLoader = false;
+ for (int ii = 0; ii < loader->children().size(); ++ii) {
+ QDeclarativeComponent *c = qobject_cast<QDeclarativeComponent*>(loader->children().at(ii));
+ if (c && c == loader->sourceComponent()) {
+ sourceComponentIsChildOfLoader = true;
+ }
+ }
+ QVERIFY(sourceComponentIsChildOfLoader);
}
if (sourceOrComponent == "component") {
@@ -174,10 +192,10 @@ void tst_QSGLoader::sourceOrComponent_data()
QTest::addColumn<QUrl>("sourceUrl");
QTest::addColumn<QString>("errorString");
- QTest::newRow("source") << "source" << "source: 'Rect120x60.qml'\n" << QUrl::fromLocalFile(SRCDIR "/data/Rect120x60.qml") << "";
+ QTest::newRow("source") << "source" << "source: 'Rect120x60.qml'\n" << QUrl::fromLocalFile(TESTDATA("Rect120x60.qml")) << "";
QTest::newRow("sourceComponent") << "component" << "Component { id: comp; Rectangle { width: 100; height: 50 } }\n sourceComponent: comp\n" << QUrl() << "";
- QTest::newRow("invalid source") << "source" << "source: 'IDontExist.qml'\n" << QUrl::fromLocalFile(SRCDIR "/data/IDontExist.qml")
- << QString(QUrl::fromLocalFile(SRCDIR "/data/IDontExist.qml").toString() + ": File not found");
+ QTest::newRow("invalid source") << "source" << "source: 'IDontExist.qml'\n" << QUrl::fromLocalFile(TESTDATA("IDontExist.qml"))
+ << QString(QUrl::fromLocalFile(TESTDATA("IDontExist.qml")).toString() + ": File not found");
}
void tst_QSGLoader::clear()
@@ -229,7 +247,7 @@ void tst_QSGLoader::clear()
QSGItem *item = qobject_cast<QSGItem*>(component.create());
QVERIFY(item);
- QSGLoader *loader = qobject_cast<QSGLoader*>(item->QSGItem::childItems().at(0));
+ QSGLoader *loader = qobject_cast<QSGLoader*>(item->QSGItem::childItems().at(0));
QVERIFY(loader);
QVERIFY(loader->item());
QCOMPARE(loader->progress(), 1.0);
@@ -275,7 +293,7 @@ void tst_QSGLoader::componentToUrl()
QSGItem *item = qobject_cast<QSGItem*>(component.create());
QVERIFY(item);
- QSGLoader *loader = qobject_cast<QSGLoader*>(item->QSGItem::childItems().at(0));
+ QSGLoader *loader = qobject_cast<QSGLoader*>(item->QSGItem::childItems().at(0));
QVERIFY(loader);
QVERIFY(loader->item());
QCOMPARE(loader->progress(), 1.0);
@@ -398,10 +416,10 @@ void tst_QSGLoader::networkRequestUrl()
{
TestHTTPServer server(SERVER_PORT);
QVERIFY(server.isValid());
- server.serveDirectory(SRCDIR "/data");
+ server.serveDirectory(TESTDATA(""));
QDeclarativeComponent component(&engine);
- component.setData(QByteArray("import QtQuick 2.0\nLoader { property int signalCount : 0; source: \"http://127.0.0.1:14450/Rect120x60.qml\"; onLoaded: signalCount += 1 }"), QUrl::fromLocalFile(SRCDIR "/dummy.qml"));
+ component.setData(QByteArray("import QtQuick 2.0\nLoader { property int signalCount : 0; source: \"http://127.0.0.1:14450/Rect120x60.qml\"; onLoaded: signalCount += 1 }"), QUrl::fromLocalFile(TESTDATA("../dummy.qml")));
if (component.isError())
qDebug() << component.errors();
QSGLoader *loader = qobject_cast<QSGLoader*>(component.create());
@@ -436,7 +454,7 @@ void tst_QSGLoader::networkComponent()
QSGItem *item = qobject_cast<QSGItem*>(component.create());
QVERIFY(item);
- QSGLoader *loader = qobject_cast<QSGLoader*>(item->QSGItem::children().at(1));
+ QSGLoader *loader = qobject_cast<QSGLoader*>(item->QSGItem::children().at(1));
QVERIFY(loader);
QTRY_VERIFY(loader->status() == QSGLoader::Ready);
@@ -453,7 +471,7 @@ void tst_QSGLoader::failNetworkRequest()
{
TestHTTPServer server(SERVER_PORT);
QVERIFY(server.isValid());
- server.serveDirectory(SRCDIR "/data");
+ server.serveDirectory(TESTDATA(""));
QTest::ignoreMessage(QtWarningMsg, "http://127.0.0.1:14450/IDontExist.qml: File not found");
@@ -590,6 +608,24 @@ void tst_QSGLoader::active()
delete object;
}
+
+ // check that the component isn't loaded until active is set to true
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("active.7.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QCOMPARE(object->property("success").toBool(), true);
+ delete object;
+ }
+
+ // check that the component is loaded if active is not set (true by default)
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("active.8.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QCOMPARE(object->property("success").toBool(), true);
+ delete object;
+ }
}
void tst_QSGLoader::initialPropertyValues_data()
@@ -633,6 +669,11 @@ void tst_QSGLoader::initialPropertyValues_data()
<< QStringList()
<< (QStringList() << "loaderValue" << "createObjectValue")
<< (QVariantList() << 1 << 1);
+
+ QTest::newRow("ensure initial property values aren't disposed prior to component completion") << TEST_FILE("initialPropertyValues.8.qml")
+ << QStringList()
+ << (QStringList() << "initialValue")
+ << (QVariantList() << 6);
}
void tst_QSGLoader::initialPropertyValues()
@@ -642,12 +683,18 @@ void tst_QSGLoader::initialPropertyValues()
QFETCH(QStringList, propertyNames);
QFETCH(QVariantList, propertyValues);
+ TestHTTPServer server(SERVER_PORT);
+ QVERIFY(server.isValid());
+ server.serveDirectory(TESTDATA(""));
+
foreach (const QString &warning, expectedWarnings)
QTest::ignoreMessage(QtWarningMsg, warning.toAscii().constData());
QDeclarativeComponent component(&engine, qmlFile);
QObject *object = component.create();
QVERIFY(object != 0);
+ qApp->processEvents();
+ QTest::qWait(50);
for (int i = 0; i < propertyNames.size(); ++i)
QCOMPARE(object->property(propertyNames.at(i).toAscii().constData()), propertyValues.at(i));
@@ -718,8 +765,9 @@ void tst_QSGLoader::deleteComponentCrash()
QCOMPARE(loader->item()->objectName(), QLatin1String("blue"));
QCOMPARE(loader->progress(), 1.0);
QCOMPARE(loader->status(), QSGLoader::Ready);
- QCOMPARE(static_cast<QSGItem*>(loader)->childItems().count(), 1);
- QVERIFY(loader->source() == QUrl::fromLocalFile(SRCDIR "/data/BlueRect.qml"));
+ qApp->processEvents(QEventLoop::DeferredDeletion);
+ QTRY_COMPARE(static_cast<QSGItem*>(loader)->childItems().count(), 1);
+ QVERIFY(loader->source() == QUrl::fromLocalFile(TESTDATA("BlueRect.qml")));
delete item;
}
@@ -727,7 +775,7 @@ void tst_QSGLoader::deleteComponentCrash()
void tst_QSGLoader::nonItem()
{
QDeclarativeComponent component(&engine, TEST_FILE("nonItem.qml"));
- QString err = QUrl::fromLocalFile(SRCDIR).toString() + "/data/nonItem.qml:3:1: QML Loader: Loader does not support loading non-visual elements.";
+ QString err = QUrl::fromLocalFile(TESTDATA("nonItem.qml")).toString() + ":3:1: QML Loader: Loader does not support loading non-visual elements.";
QTest::ignoreMessage(QtWarningMsg, err.toLatin1().constData());
QSGLoader *loader = qobject_cast<QSGLoader*>(component.create());
@@ -740,7 +788,7 @@ void tst_QSGLoader::nonItem()
void tst_QSGLoader::vmeErrors()
{
QDeclarativeComponent component(&engine, TEST_FILE("vmeErrors.qml"));
- QString err = QUrl::fromLocalFile(SRCDIR).toString() + "/data/VmeError.qml:6: Cannot assign object type QObject with no default method";
+ QString err = QUrl::fromLocalFile(TESTDATA("VmeError.qml")).toString() + ":6: Cannot assign object type QObject with no default method";
QTest::ignoreMessage(QtWarningMsg, err.toLatin1().constData());
QSGLoader *loader = qobject_cast<QSGLoader*>(component.create());
QVERIFY(loader);
@@ -801,6 +849,102 @@ void tst_QSGLoader::QTBUG_17114()
delete item;
}
+void tst_QSGLoader::asynchronous_data()
+{
+ QTest::addColumn<QUrl>("qmlFile");
+ QTest::addColumn<QStringList>("expectedWarnings");
+
+ QTest::newRow("Valid component") << TEST_FILE("BigComponent.qml")
+ << QStringList();
+
+ QTest::newRow("Non-existant component") << TEST_FILE("IDoNotExist.qml")
+ << (QStringList() << QString(TEST_FILE("IDoNotExist.qml").toString() + ": File not found"));
+
+ QTest::newRow("Invalid component") << TEST_FILE("InvalidSourceComponent.qml")
+ << (QStringList() << QString(TEST_FILE("InvalidSourceComponent.qml").toString() + ":5:1: Syntax error"));
+}
+
+void tst_QSGLoader::asynchronous()
+{
+ QFETCH(QUrl, qmlFile);
+ QFETCH(QStringList, expectedWarnings);
+
+ if (!engine.incubationController())
+ engine.setIncubationController(new PeriodicIncubationController);
+ QDeclarativeComponent component(&engine, TEST_FILE("asynchronous.qml"));
+ QSGItem *root = qobject_cast<QSGItem*>(component.create());
+ QVERIFY(root);
+
+ QSGLoader *loader = root->findChild<QSGLoader*>("loader");
+ QVERIFY(loader);
+
+ foreach (const QString &warning, expectedWarnings)
+ QTest::ignoreMessage(QtWarningMsg, warning.toUtf8().constData());
+
+ QVERIFY(!loader->item());
+ root->setProperty("comp", qmlFile.toString());
+ QMetaObject::invokeMethod(root, "loadComponent");
+ QVERIFY(!loader->item());
+
+ if (expectedWarnings.isEmpty()) {
+ QCOMPARE(loader->status(), QSGLoader::Loading);
+ QCOMPARE(engine.incubationController()->incubatingObjectCount(), 1);
+
+ QTRY_VERIFY(loader->item());
+ QCOMPARE(loader->progress(), 1.0);
+ QCOMPARE(loader->status(), QSGLoader::Ready);
+ } else {
+ QCOMPARE(loader->progress(), 1.0);
+ QTRY_COMPARE(loader->status(), QSGLoader::Error);
+ }
+
+ delete root;
+}
+
+void tst_QSGLoader::asynchronous_clear()
+{
+ if (!engine.incubationController())
+ engine.setIncubationController(new PeriodicIncubationController);
+ QDeclarativeComponent component(&engine, TEST_FILE("asynchronous.qml"));
+ QSGItem *root = qobject_cast<QSGItem*>(component.create());
+ QVERIFY(root);
+
+ QSGLoader *loader = root->findChild<QSGLoader*>("loader");
+ QVERIFY(loader);
+
+ QVERIFY(!loader->item());
+ root->setProperty("comp", "BigComponent.qml");
+ QMetaObject::invokeMethod(root, "loadComponent");
+ QVERIFY(!loader->item());
+
+ QCOMPARE(loader->status(), QSGLoader::Loading);
+ QCOMPARE(engine.incubationController()->incubatingObjectCount(), 1);
+
+ // clear before component created
+ root->setProperty("comp", "");
+ QMetaObject::invokeMethod(root, "loadComponent");
+ QVERIFY(!loader->item());
+ QCOMPARE(engine.incubationController()->incubatingObjectCount(), 0);
+
+ QCOMPARE(loader->progress(), 0.0);
+ QCOMPARE(loader->status(), QSGLoader::Null);
+ QCOMPARE(static_cast<QSGItem*>(loader)->childItems().count(), 0);
+
+ // check loading component
+ root->setProperty("comp", "Rect120x60.qml");
+ QMetaObject::invokeMethod(root, "loadComponent");
+ QVERIFY(!loader->item());
+
+ QCOMPARE(loader->status(), QSGLoader::Loading);
+ QCOMPARE(engine.incubationController()->incubatingObjectCount(), 1);
+
+ QTRY_VERIFY(loader->item());
+ QCOMPARE(loader->progress(), 1.0);
+ QCOMPARE(loader->status(), QSGLoader::Ready);
+ QCOMPARE(static_cast<QSGItem*>(loader)->childItems().count(), 1);
+}
+
+
QTEST_MAIN(tst_QSGLoader)
#include "tst_qsgloader.moc"
diff --git a/tests/auto/declarative/qsgmousearea/qsgmousearea.pro b/tests/auto/declarative/qsgmousearea/qsgmousearea.pro
index f0179e8eb2..39abd5a75d 100644
--- a/tests/auto/declarative/qsgmousearea/qsgmousearea.pro
+++ b/tests/auto/declarative/qsgmousearea/qsgmousearea.pro
@@ -1,18 +1,14 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui network
+CONFIG += testcase
+TARGET = tst_qsgmousearea
macx:CONFIG -= app_bundle
HEADERS += ../shared/testhttpserver.h
SOURCES += tst_qsgmousearea.cpp ../shared/testhttpserver.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qsgmousearea/tst_qsgmousearea.cpp b/tests/auto/declarative/qsgmousearea/tst_qsgmousearea.cpp
index 2f91f15211..be6a6017f0 100644
--- a/tests/auto/declarative/qsgmousearea/tst_qsgmousearea.cpp
+++ b/tests/auto/declarative/qsgmousearea/tst_qsgmousearea.cpp
@@ -48,11 +48,7 @@
#include <QtDeclarative/qdeclarativecontext.h>
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtOpenGL/QGLShaderProgram>
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
//#define OLDWAY
@@ -98,7 +94,7 @@ void tst_QSGMouseArea::dragProperties()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/dragproperties.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragproperties.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
@@ -184,7 +180,7 @@ void tst_QSGMouseArea::resetDrag()
QSGView *canvas = createView();
canvas->rootContext()->setContextProperty("haveTarget", QVariant(true));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/dragreset.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragreset.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
@@ -214,7 +210,7 @@ void tst_QSGMouseArea::dragging()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/dragging.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragging.qml")));
canvas->show();
canvas->requestActivateWindow();
QTest::qWait(20);
@@ -281,7 +277,7 @@ QSGView *tst_QSGMouseArea::createView()
void tst_QSGMouseArea::updateMouseAreaPosOnClick()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/updateMousePosOnClick.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("updateMousePosOnClick.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
@@ -310,7 +306,7 @@ void tst_QSGMouseArea::updateMouseAreaPosOnClick()
void tst_QSGMouseArea::updateMouseAreaPosOnResize()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/updateMousePosOnResize.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("updateMousePosOnResize.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
@@ -348,7 +344,7 @@ void tst_QSGMouseArea::noOnClickedWithPressAndHold()
{
// We handle onPressAndHold, therefore no onClicked
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/clickandhold.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("clickandhold.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
@@ -373,7 +369,7 @@ void tst_QSGMouseArea::noOnClickedWithPressAndHold()
{
// We do not handle onPressAndHold, therefore we get onClicked
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/noclickandhold.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("noclickandhold.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
@@ -397,7 +393,7 @@ void tst_QSGMouseArea::noOnClickedWithPressAndHold()
void tst_QSGMouseArea::onMousePressRejected()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/rejectEvent.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("rejectEvent.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
@@ -434,7 +430,7 @@ void tst_QSGMouseArea::onMousePressRejected()
void tst_QSGMouseArea::pressedCanceledOnWindowDeactivate()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pressedCanceled.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("pressedCanceled.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
@@ -479,7 +475,7 @@ void tst_QSGMouseArea::pressedCanceledOnWindowDeactivate()
void tst_QSGMouseArea::doubleClick()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/doubleclick.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("doubleclick.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
@@ -508,7 +504,7 @@ void tst_QSGMouseArea::doubleClick()
void tst_QSGMouseArea::clickTwice()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/clicktwice.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("clicktwice.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
@@ -539,7 +535,7 @@ void tst_QSGMouseArea::clickTwice()
void tst_QSGMouseArea::pressedOrdering()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pressedOrdering.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("pressedOrdering.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
@@ -567,7 +563,7 @@ void tst_QSGMouseArea::preventStealing()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/preventstealing.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("preventstealing.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
@@ -630,72 +626,63 @@ void tst_QSGMouseArea::clickThrough()
{
//With no handlers defined click, doubleClick and PressAndHold should propagate to those with handlers
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/clickThrough.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("clickThrough.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
- QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
- QApplication::sendEvent(canvas, &pressEvent);
+ QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
+ QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
- QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
- QApplication::sendEvent(canvas, &releaseEvent);
+ QTRY_COMPARE(canvas->rootObject()->property("presses").toInt(), 0);
+ QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
- QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
- QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
+ QTest::qWait(800); // to avoid generating a double click.
- QApplication::sendEvent(canvas, &pressEvent);
+ QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
QTest::qWait(1000);
- QApplication::sendEvent(canvas, &releaseEvent);
+ QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
- QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
- QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
- QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
-
- QApplication::sendEvent(canvas, &pressEvent);
- QApplication::sendEvent(canvas, &releaseEvent);
- pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+ QTRY_COMPARE(canvas->rootObject()->property("presses").toInt(), 0);
+ QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
+ QTRY_COMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
- QApplication::sendEvent(canvas, &pressEvent);
- QApplication::sendEvent(canvas, &releaseEvent);
+ QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
+ QTest::qWait(100);
QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
- QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 2);
- QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1);
+ QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2);
+ QTRY_COMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1);
QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
delete canvas;
//With handlers defined click, doubleClick and PressAndHold should propagate only when explicitly ignored
canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/clickThrough2.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("clickThrough2.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
- pressEvent = QMouseEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
- QApplication::sendEvent(canvas, &pressEvent);
-
- releaseEvent = QMouseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
- QApplication::sendEvent(canvas, &releaseEvent);
+ QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
+ QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 0);
- QApplication::sendEvent(canvas, &pressEvent);
+ QTest::qWait(800); // to avoid generating a double click.
+
+ QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
QTest::qWait(1000);
- QApplication::sendEvent(canvas, &releaseEvent);
+ QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
+ QTest::qWait(100);
QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 0);
QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 0);
- QApplication::sendEvent(canvas, &pressEvent);
- QApplication::sendEvent(canvas, &releaseEvent);
-
- pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
- QApplication::sendEvent(canvas, &pressEvent);
- QApplication::sendEvent(canvas, &releaseEvent);
+ QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
+ QTest::qWait(100);
QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 0);
@@ -704,32 +691,28 @@ void tst_QSGMouseArea::clickThrough()
canvas->rootObject()->setProperty("letThrough", QVariant(true));
- pressEvent = QMouseEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
- QApplication::sendEvent(canvas, &pressEvent);
-
- releaseEvent = QMouseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
- QApplication::sendEvent(canvas, &releaseEvent);
+ QTest::qWait(800); // to avoid generating a double click.
+ QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
+ QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
- QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
+ QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
- QApplication::sendEvent(canvas, &pressEvent);
+ QTest::qWait(800); // to avoid generating a double click.
+ QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
QTest::qWait(1000);
- QApplication::sendEvent(canvas, &releaseEvent);
+ QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
+ QTest::qWait(100);
QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
- QApplication::sendEvent(canvas, &pressEvent);
- QApplication::sendEvent(canvas, &releaseEvent);
- pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
-
- QApplication::sendEvent(canvas, &pressEvent);
- QApplication::sendEvent(canvas, &releaseEvent);
+ QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
+ QTest::qWait(100);
QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
- QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 2);
+ QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2);
QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1);
QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
@@ -774,7 +757,7 @@ void tst_QSGMouseArea::testQtQuick11Attributes_data()
void tst_QSGMouseArea::hoverPosition()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/hoverPosition.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("hoverPosition.qml")));
QSGItem *root = canvas->rootObject();
QVERIFY(root != 0);
@@ -795,7 +778,7 @@ void tst_QSGMouseArea::hoverPropagation()
{
//QTBUG-18175, to behave like GV did.
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/hoverPropagation.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("hoverPropagation.qml")));
QSGItem *root = canvas->rootObject();
QVERIFY(root != 0);
diff --git a/tests/auto/declarative/qsgpathview/data/ComponentView.qml b/tests/auto/declarative/qsgpathview/data/ComponentView.qml
new file mode 100644
index 0000000000..b61033d375
--- /dev/null
+++ b/tests/auto/declarative/qsgpathview/data/ComponentView.qml
@@ -0,0 +1,17 @@
+import QtQuick 2.0
+
+PathView {
+ id: view
+
+ property string title
+
+ width: 100; height: 100;
+
+ model: 1
+ delegate: Text { objectName: "listItem"; text: view.title }
+
+ path: Path {
+ startX: 25; startY: 25;
+ PathLine { x: 75; y: 75 }
+ }
+}
diff --git a/tests/auto/declarative/qsgpathview/data/creationContext.qml b/tests/auto/declarative/qsgpathview/data/creationContext.qml
new file mode 100644
index 0000000000..79a682788b
--- /dev/null
+++ b/tests/auto/declarative/qsgpathview/data/creationContext.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+
+ComponentView {
+ title: "Hello!"
+}
diff --git a/tests/auto/declarative/qsgpathview/qsgpathview.pro b/tests/auto/declarative/qsgpathview/qsgpathview.pro
index a9b3838a0c..d4c237d168 100644
--- a/tests/auto/declarative/qsgpathview/qsgpathview.pro
+++ b/tests/auto/declarative/qsgpathview/qsgpathview.pro
@@ -1,17 +1,12 @@
-load(qttest_p4)
+CONFIG += testcase
+TARGET = tst_qsgpathview
macx:CONFIG -= app_bundle
SOURCES += tst_qsgpathview.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
-CONFIG += parallel_test
-#temporary
-CONFIG += insignificant_test
-QT += core-private gui-private v8-private declarative-private widgets
+CONFIG += parallel_test
+QT += core-private gui-private v8-private declarative-private widgets testlib
diff --git a/tests/auto/declarative/qsgpathview/tst_qsgpathview.cpp b/tests/auto/declarative/qsgpathview/tst_qsgpathview.cpp
index a5f12787c3..c6440cf5ef 100644
--- a/tests/auto/declarative/qsgpathview/tst_qsgpathview.cpp
+++ b/tests/auto/declarative/qsgpathview/tst_qsgpathview.cpp
@@ -55,14 +55,8 @@
#include <QStringListModel>
#include <QStandardItemModel>
#include <QFile>
-#include <QtOpenGL/QGLShaderProgram>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
static void initStandardTreeModel(QStandardItemModel *model)
{
@@ -116,6 +110,7 @@ private slots:
void treeModel();
void changePreferredHighlight();
void missingPercent();
+ void creationContext();
private:
QSGView *createView();
@@ -232,7 +227,7 @@ tst_QSGPathView::tst_QSGPathView()
void tst_QSGPathView::initValues()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathview1.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathview1.qml")));
QSGPathView *obj = qobject_cast<QSGPathView*>(c.create());
QVERIFY(obj != 0);
@@ -260,7 +255,7 @@ void tst_QSGPathView::items()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml")));
qApp->processEvents();
QSGPathView *pathview = findItem<QSGPathView>(canvas->rootObject(), "view");
@@ -295,7 +290,7 @@ void tst_QSGPathView::items()
void tst_QSGPathView::pathview2()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathview2.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathview2.qml")));
QSGPathView *obj = qobject_cast<QSGPathView*>(c.create());
QVERIFY(obj != 0);
@@ -313,7 +308,7 @@ void tst_QSGPathView::pathview2()
void tst_QSGPathView::pathview3()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathview3.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathview3.qml")));
QSGPathView *obj = qobject_cast<QSGPathView*>(c.create());
QVERIFY(obj != 0);
@@ -331,7 +326,7 @@ void tst_QSGPathView::pathview3()
void tst_QSGPathView::path()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/pathtest.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathtest.qml")));
QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create());
QVERIFY(obj != 0);
@@ -399,7 +394,7 @@ void tst_QSGPathView::dataModel()
ctxt->setContextProperty("testData", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/datamodel.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("datamodel.qml")));
qApp->processEvents();
QSGPathView *pathview = qobject_cast<QSGPathView*>(canvas->rootObject());
@@ -501,7 +496,7 @@ void tst_QSGPathView::pathMoved()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml")));
qApp->processEvents();
QSGPathView *pathview = findItem<QSGPathView>(canvas->rootObject(), "view");
@@ -518,7 +513,7 @@ void tst_QSGPathView::pathMoved()
QCOMPARE(firstItem->pos() + offset, start);
pathview->setOffset(1.0);
- for(int i=0; i<model.count(); i++){
+ for (int i=0; i<model.count(); i++) {
QSGRectangle *curItem = findItem<QSGRectangle>(pathview, "wrapper", i);
QPointF itemPos(path->pointAt(0.25 + i*0.25));
QCOMPARE(curItem->pos() + offset, QPointF(qRound(itemPos.x()), qRound(itemPos.y())));
@@ -558,7 +553,7 @@ void tst_QSGPathView::setCurrentIndex()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview0.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml")));
qApp->processEvents();
QSGPathView *pathview = findItem<QSGPathView>(canvas->rootObject(), "view");
@@ -672,7 +667,7 @@ void tst_QSGPathView::resetModel()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/displaypath.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaypath.qml")));
qApp->processEvents();
QSGPathView *pathview = findItem<QSGPathView>(canvas->rootObject(), "view");
@@ -705,7 +700,7 @@ void tst_QSGPathView::propertyChanges()
{
QSGView *canvas = createView();
QVERIFY(canvas);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml")));
QSGPathView *pathView = canvas->rootObject()->findChild<QSGPathView*>("pathView");
QVERIFY(pathView);
@@ -740,7 +735,7 @@ void tst_QSGPathView::pathChanges()
{
QSGView *canvas = createView();
QVERIFY(canvas);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml")));
QSGPathView *pathView = canvas->rootObject()->findChild<QSGPathView*>("pathView");
QVERIFY(pathView);
@@ -802,7 +797,7 @@ void tst_QSGPathView::componentChanges()
{
QSGView *canvas = createView();
QVERIFY(canvas);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml")));
QSGPathView *pathView = canvas->rootObject()->findChild<QSGPathView*>("pathView");
QVERIFY(pathView);
@@ -825,7 +820,7 @@ void tst_QSGPathView::modelChanges()
{
QSGView *canvas = createView();
QVERIFY(canvas);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml")));
QSGPathView *pathView = canvas->rootObject()->findChild<QSGPathView*>("pathView");
QVERIFY(pathView);
@@ -852,7 +847,7 @@ void tst_QSGPathView::pathUpdateOnStartChanged()
{
QSGView *canvas = createView();
QVERIFY(canvas);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathUpdateOnStartChanged.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathUpdateOnStartChanged.qml")));
QSGPathView *pathView = canvas->rootObject()->findChild<QSGPathView*>("pathView");
QVERIFY(pathView);
@@ -874,7 +869,7 @@ void tst_QSGPathView::package()
{
QSGView *canvas = createView();
QVERIFY(canvas);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview_package.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview_package.qml")));
QSGPathView *pathView = canvas->rootObject()->findChild<QSGPathView*>("photoPathView");
QVERIFY(pathView);
@@ -896,7 +891,7 @@ void tst_QSGPathView::emptyModel()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("emptyModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/emptymodel.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("emptymodel.qml")));
qApp->processEvents();
QSGPathView *pathview = qobject_cast<QSGPathView*>(canvas->rootObject());
@@ -912,7 +907,7 @@ void tst_QSGPathView::closed()
QDeclarativeEngine engine;
{
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/openPath.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("openPath.qml")));
QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create());
QVERIFY(obj);
QCOMPARE(obj->isClosed(), false);
@@ -920,7 +915,7 @@ void tst_QSGPathView::closed()
}
{
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/closedPath.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("closedPath.qml")));
QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create());
QVERIFY(obj);
QCOMPARE(obj->isClosed(), true);
@@ -933,7 +928,7 @@ void tst_QSGPathView::pathUpdate()
{
QSGView *canvas = createView();
QVERIFY(canvas);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathUpdate.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathUpdate.qml")));
QSGPathView *pathView = canvas->rootObject()->findChild<QSGPathView*>("pathView");
QVERIFY(pathView);
@@ -948,7 +943,7 @@ void tst_QSGPathView::pathUpdate()
void tst_QSGPathView::visualDataModel()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/vdm.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("vdm.qml")));
QSGPathView *obj = qobject_cast<QSGPathView*>(c.create());
QVERIFY(obj != 0);
@@ -961,7 +956,7 @@ void tst_QSGPathView::visualDataModel()
void tst_QSGPathView::undefinedPath()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/undefinedpath.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("undefinedpath.qml")));
QSGPathView *obj = qobject_cast<QSGPathView*>(c.create());
QVERIFY(obj != 0);
@@ -974,11 +969,11 @@ void tst_QSGPathView::undefinedPath()
void tst_QSGPathView::mouseDrag()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/dragpath.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragpath.qml")));
canvas->show();
canvas->requestActivateWindow();
QTest::qWaitForWindowShown(canvas);
- QTRY_COMPARE(canvas->windowState(), Qt::WindowActive);
+ QTRY_COMPARE(canvas, qGuiApp->focusWindow());
QSGPathView *pathview = qobject_cast<QSGPathView*>(canvas->rootObject());
QVERIFY(pathview != 0);
@@ -986,6 +981,7 @@ void tst_QSGPathView::mouseDrag()
int current = pathview->currentIndex();
QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(10,100));
+ QTest::qWait(100);
{
QMouseEvent mv(QEvent::MouseMove, QPoint(30,100), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
@@ -1012,7 +1008,7 @@ void tst_QSGPathView::treeModel()
initStandardTreeModel(&model);
canvas->engine()->rootContext()->setContextProperty("myModel", &model);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/treemodel.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("treemodel.qml")));
QSGPathView *pathview = qobject_cast<QSGPathView*>(canvas->rootObject());
QVERIFY(pathview != 0);
@@ -1035,11 +1031,11 @@ void tst_QSGPathView::changePreferredHighlight()
{
QSGView *canvas = createView();
canvas->setGeometry(0,0,400,200);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/dragpath.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragpath.qml")));
canvas->show();
canvas->requestActivateWindow();
QTest::qWaitForWindowShown(canvas);
- QTRY_COMPARE(canvas->windowState(), Qt::WindowActive);
+ QTRY_COMPARE(canvas, qGuiApp->focusWindow());
QSGPathView *pathview = qobject_cast<QSGPathView*>(canvas->rootObject());
QVERIFY(pathview != 0);
@@ -1070,6 +1066,21 @@ void tst_QSGPathView::changePreferredHighlight()
delete canvas;
}
+void tst_QSGPathView::creationContext()
+{
+ QSGView canvas;
+ canvas.setGeometry(0,0,240,320);
+ canvas.setSource(QUrl::fromLocalFile(TESTDATA("creationContext.qml")));
+
+ QSGItem *rootItem = qobject_cast<QSGItem *>(canvas.rootObject());
+ QVERIFY(rootItem);
+ QVERIFY(rootItem->property("count").toInt() > 0);
+
+ QSGItem *item;
+ QVERIFY(item = findItem<QSGItem>(rootItem, "listItem", 0));
+ QCOMPARE(item->property("text").toString(), QString("Hello!"));
+}
+
QSGView *tst_QSGPathView::createView()
{
QSGView *canvas = new QSGView(0);
@@ -1089,7 +1100,7 @@ T *tst_QSGPathView::findItem(QSGItem *parent, const QString &objectName, int ind
//qDebug() << parent->childItems().count() << "children";
for (int i = 0; i < parent->childItems().count(); ++i) {
QSGItem *item = qobject_cast<QSGItem*>(parent->childItems().at(i));
- if(!item)
+ if (!item)
continue;
//qDebug() << "try" << item;
if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
@@ -1117,7 +1128,7 @@ QList<T*> tst_QSGPathView::findItems(QSGItem *parent, const QString &objectName)
//qDebug() << parent->QSGItem::children().count() << "children";
for (int i = 0; i < parent->childItems().count(); ++i) {
QSGItem *item = qobject_cast<QSGItem*>(parent->childItems().at(i));
- if(!item)
+ if (!item)
continue;
//qDebug() << "try" << item;
if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName))
@@ -1131,7 +1142,7 @@ QList<T*> tst_QSGPathView::findItems(QSGItem *parent, const QString &objectName)
void tst_QSGPathView::missingPercent()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/missingPercent.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("missingPercent.qml")));
QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create());
QVERIFY(obj);
QCOMPARE(obj->attributeAt("_qfx_percent", 1.0), qreal(1.0));
diff --git a/tests/auto/declarative/qsgpincharea/qsgpincharea.pro b/tests/auto/declarative/qsgpincharea/qsgpincharea.pro
index cf1ff0cac2..628bbc7a88 100644
--- a/tests/auto/declarative/qsgpincharea/qsgpincharea.pro
+++ b/tests/auto/declarative/qsgpincharea/qsgpincharea.pro
@@ -1,17 +1,13 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui
+CONFIG += testcase
+TARGET = tst_qsgpincharea
macx:CONFIG -= app_bundle
SOURCES += tst_qsgpincharea.cpp
-symbian: {
- importFiles.sources = data
- importFiles.path = .
- DEPLOYMENT = importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qsgpincharea/tst_qsgpincharea.cpp b/tests/auto/declarative/qsgpincharea/tst_qsgpincharea.cpp
index d71c999ba9..24cdf90657 100644
--- a/tests/auto/declarative/qsgpincharea/tst_qsgpincharea.cpp
+++ b/tests/auto/declarative/qsgpincharea/tst_qsgpincharea.cpp
@@ -45,12 +45,7 @@
#include <private/qsgrectangle_p.h>
#include <QtDeclarative/qsgview.h>
#include <QtDeclarative/qdeclarativecontext.h>
-#include <QtOpenGL/QGLShaderProgram>
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class tst_QSGPinchArea: public QObject
{
@@ -77,7 +72,7 @@ void tst_QSGPinchArea::cleanupTestCase()
void tst_QSGPinchArea::pinchProperties()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pinchproperties.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml")));
canvas->show();
canvas->requestActivateWindow();
QVERIFY(canvas->rootObject() != 0);
@@ -203,7 +198,7 @@ QTouchEvent::TouchPoint makeTouchPoint(int id, QPoint p, QSGView *v, QSGItem *i)
void tst_QSGPinchArea::scale()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pinchproperties.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml")));
canvas->show();
canvas->requestActivateWindow();
QTest::qWaitForWindowShown(canvas);
@@ -256,7 +251,7 @@ void tst_QSGPinchArea::scale()
void tst_QSGPinchArea::pan()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pinchproperties.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml")));
canvas->show();
canvas->requestActivateWindow();
QTest::qWaitForWindowShown(canvas);
@@ -312,7 +307,7 @@ void tst_QSGPinchArea::pan()
void tst_QSGPinchArea::retouch()
{
QSGView *canvas = createView();
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pinchproperties.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml")));
canvas->show();
canvas->requestActivateWindow();
QTest::qWaitForWindowShown(canvas);
diff --git a/tests/auto/declarative/qsgpositioners/qsgpositioners.pro b/tests/auto/declarative/qsgpositioners/qsgpositioners.pro
index 637ba9b10b..d0ecbd677c 100644
--- a/tests/auto/declarative/qsgpositioners/qsgpositioners.pro
+++ b/tests/auto/declarative/qsgpositioners/qsgpositioners.pro
@@ -1,18 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qsgpositioners
SOURCES += tst_qsgpositioners.cpp
macx:CONFIG -= app_bundle
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-#temporary
-CONFIG += insignificant_test
-QT += core-private gui-private v8-private declarative-private
-QT += opengl-private
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
diff --git a/tests/auto/declarative/qsgpositioners/tst_qsgpositioners.cpp b/tests/auto/declarative/qsgpositioners/tst_qsgpositioners.cpp
index 2ea8205b08..22a33869fc 100644
--- a/tests/auto/declarative/qsgpositioners/tst_qsgpositioners.cpp
+++ b/tests/auto/declarative/qsgpositioners/tst_qsgpositioners.cpp
@@ -47,13 +47,7 @@
#include <private/qdeclarativetransition_p.h>
#include <private/qsgitem_p.h>
#include <qdeclarativeexpression.h>
-#include <QtWidgets/qgraphicswidget.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
class tst_qsgpositioners : public QObject
{
@@ -105,7 +99,7 @@ tst_qsgpositioners::tst_qsgpositioners()
void tst_qsgpositioners::test_horizontal()
{
- QSGView *canvas = createView(SRCDIR "/data/horizontal.qml");
+ QSGView *canvas = createView(TESTDATA("horizontal.qml"));
canvas->rootObject()->setProperty("testRightToLeft", false);
@@ -134,7 +128,7 @@ void tst_qsgpositioners::test_horizontal()
void tst_qsgpositioners::test_horizontal_rtl()
{
- QSGView *canvas = createView(SRCDIR "/data/horizontal.qml");
+ QSGView *canvas = createView(TESTDATA("horizontal.qml"));
canvas->rootObject()->setProperty("testRightToLeft", true);
@@ -172,7 +166,7 @@ void tst_qsgpositioners::test_horizontal_rtl()
void tst_qsgpositioners::test_horizontal_spacing()
{
- QSGView *canvas = createView(SRCDIR "/data/horizontal-spacing.qml");
+ QSGView *canvas = createView(TESTDATA("horizontal-spacing.qml"));
canvas->rootObject()->setProperty("testRightToLeft", false);
@@ -201,7 +195,7 @@ void tst_qsgpositioners::test_horizontal_spacing()
void tst_qsgpositioners::test_horizontal_spacing_rightToLeft()
{
- QSGView *canvas = createView(SRCDIR "/data/horizontal-spacing.qml");
+ QSGView *canvas = createView(TESTDATA("horizontal-spacing.qml"));
canvas->rootObject()->setProperty("testRightToLeft", true);
@@ -230,7 +224,7 @@ void tst_qsgpositioners::test_horizontal_spacing_rightToLeft()
void tst_qsgpositioners::test_horizontal_animated()
{
- QSGView *canvas = createView(SRCDIR "/data/horizontal-animated.qml", false);
+ QSGView *canvas = createView(TESTDATA("horizontal-animated.qml"), false);
canvas->rootObject()->setProperty("testRightToLeft", false);
@@ -284,7 +278,7 @@ void tst_qsgpositioners::test_horizontal_animated()
void tst_qsgpositioners::test_horizontal_animated_rightToLeft()
{
- QSGView *canvas = createView(SRCDIR "/data/horizontal-animated.qml", false);
+ QSGView *canvas = createView(TESTDATA("horizontal-animated.qml"), false);
canvas->rootObject()->setProperty("testRightToLeft", true);
@@ -340,7 +334,7 @@ void tst_qsgpositioners::test_horizontal_animated_rightToLeft()
void tst_qsgpositioners::test_horizontal_animated_disabled()
{
- QSGView *canvas = createView(SRCDIR "/data/horizontal-animated-disabled.qml");
+ QSGView *canvas = createView(TESTDATA("horizontal-animated-disabled.qml"));
QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
QVERIFY(one != 0);
@@ -380,7 +374,7 @@ void tst_qsgpositioners::test_horizontal_animated_disabled()
void tst_qsgpositioners::test_vertical()
{
- QSGView *canvas = createView(SRCDIR "/data/vertical.qml");
+ QSGView *canvas = createView(TESTDATA("vertical.qml"));
QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
QVERIFY(one != 0);
@@ -408,7 +402,7 @@ void tst_qsgpositioners::test_vertical()
void tst_qsgpositioners::test_vertical_spacing()
{
- QSGView *canvas = createView(SRCDIR "/data/vertical-spacing.qml");
+ QSGView *canvas = createView(TESTDATA("vertical-spacing.qml"));
QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
QVERIFY(one != 0);
@@ -435,7 +429,7 @@ void tst_qsgpositioners::test_vertical_spacing()
void tst_qsgpositioners::test_vertical_animated()
{
- QSGView *canvas = createView(SRCDIR "/data/vertical-animated.qml", false);
+ QSGView *canvas = createView(TESTDATA("vertical-animated.qml"), false);
//Note that they animate in
QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
@@ -485,7 +479,7 @@ void tst_qsgpositioners::test_vertical_animated()
void tst_qsgpositioners::test_grid()
{
- QSGView *canvas = createView(SRCDIR "/data/gridtest.qml");
+ QSGView *canvas = createView(TESTDATA("gridtest.qml"));
QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
QVERIFY(one != 0);
@@ -519,7 +513,7 @@ void tst_qsgpositioners::test_grid()
void tst_qsgpositioners::test_grid_topToBottom()
{
- QSGView *canvas = createView(SRCDIR "/data/grid-toptobottom.qml");
+ QSGView *canvas = createView(TESTDATA("grid-toptobottom.qml"));
QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
QVERIFY(one != 0);
@@ -553,7 +547,7 @@ void tst_qsgpositioners::test_grid_topToBottom()
void tst_qsgpositioners::test_grid_rightToLeft()
{
- QSGView *canvas = createView(SRCDIR "/data/gridtest.qml");
+ QSGView *canvas = createView(TESTDATA("gridtest.qml"));
canvas->rootObject()->setProperty("testRightToLeft", true);
@@ -602,7 +596,7 @@ void tst_qsgpositioners::test_grid_rightToLeft()
void tst_qsgpositioners::test_grid_spacing()
{
- QSGView *canvas = createView(SRCDIR "/data/grid-spacing.qml");
+ QSGView *canvas = createView(TESTDATA("grid-spacing.qml"));
QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
QVERIFY(one != 0);
@@ -635,7 +629,7 @@ void tst_qsgpositioners::test_grid_spacing()
void tst_qsgpositioners::test_grid_row_column_spacing()
{
- QSGView *canvas = createView(SRCDIR "/data/grid-row-column-spacing.qml");
+ QSGView *canvas = createView(TESTDATA("grid-row-column-spacing.qml"));
QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
QVERIFY(one != 0);
@@ -668,7 +662,7 @@ void tst_qsgpositioners::test_grid_row_column_spacing()
void tst_qsgpositioners::test_grid_animated()
{
- QSGView *canvas = createView(SRCDIR "/data/grid-animated.qml", false);
+ QSGView *canvas = createView(TESTDATA("grid-animated.qml"), false);
canvas->rootObject()->setProperty("testRightToLeft", false);
@@ -753,7 +747,7 @@ void tst_qsgpositioners::test_grid_animated()
void tst_qsgpositioners::test_grid_animated_rightToLeft()
{
- QSGView *canvas = createView(SRCDIR "/data/grid-animated.qml", false);
+ QSGView *canvas = createView(TESTDATA("grid-animated.qml"), false);
canvas->rootObject()->setProperty("testRightToLeft", true);
@@ -838,7 +832,7 @@ void tst_qsgpositioners::test_grid_animated_rightToLeft()
void tst_qsgpositioners::test_grid_zero_columns()
{
- QSGView *canvas = createView(SRCDIR "/data/gridzerocolumns.qml");
+ QSGView *canvas = createView(TESTDATA("gridzerocolumns.qml"));
QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
QVERIFY(one != 0);
@@ -871,7 +865,7 @@ void tst_qsgpositioners::test_grid_zero_columns()
void tst_qsgpositioners::test_propertychanges()
{
- QSGView *canvas = createView(SRCDIR "/data/propertychangestest.qml");
+ QSGView *canvas = createView(TESTDATA("propertychangestest.qml"));
QSGGrid *grid = qobject_cast<QSGGrid*>(canvas->rootObject());
QVERIFY(grid != 0);
@@ -930,7 +924,7 @@ void tst_qsgpositioners::test_propertychanges()
void tst_qsgpositioners::test_repeater()
{
- QSGView *canvas = createView(SRCDIR "/data/repeatertest.qml");
+ QSGView *canvas = createView(TESTDATA("repeatertest.qml"));
QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
QVERIFY(one != 0);
@@ -953,7 +947,7 @@ void tst_qsgpositioners::test_repeater()
void tst_qsgpositioners::test_flow()
{
- QSGView *canvas = createView(SRCDIR "/data/flowtest.qml");
+ QSGView *canvas = createView(TESTDATA("flowtest.qml"));
canvas->rootObject()->setProperty("testRightToLeft", false);
@@ -989,7 +983,7 @@ void tst_qsgpositioners::test_flow()
void tst_qsgpositioners::test_flow_rightToLeft()
{
- QSGView *canvas = createView(SRCDIR "/data/flowtest.qml");
+ QSGView *canvas = createView(TESTDATA("flowtest.qml"));
canvas->rootObject()->setProperty("testRightToLeft", true);
@@ -1025,7 +1019,7 @@ void tst_qsgpositioners::test_flow_rightToLeft()
void tst_qsgpositioners::test_flow_topToBottom()
{
- QSGView *canvas = createView(SRCDIR "/data/flowtest-toptobottom.qml");
+ QSGView *canvas = createView(TESTDATA("flowtest-toptobottom.qml"));
canvas->rootObject()->setProperty("testRightToLeft", false);
@@ -1078,7 +1072,7 @@ void tst_qsgpositioners::test_flow_topToBottom()
void tst_qsgpositioners::test_flow_resize()
{
- QSGView *canvas = createView(SRCDIR "/data/flowtest.qml");
+ QSGView *canvas = createView(TESTDATA("flowtest.qml"));
QSGItem *root = qobject_cast<QSGItem*>(canvas->rootObject());
QVERIFY(root);
@@ -1112,7 +1106,7 @@ void tst_qsgpositioners::test_flow_resize()
void tst_qsgpositioners::test_flow_resize_rightToLeft()
{
- QSGView *canvas = createView(SRCDIR "/data/flowtest.qml");
+ QSGView *canvas = createView(TESTDATA("flowtest.qml"));
QSGItem *root = qobject_cast<QSGItem*>(canvas->rootObject());
QVERIFY(root);
@@ -1146,7 +1140,7 @@ void tst_qsgpositioners::test_flow_resize_rightToLeft()
void tst_qsgpositioners::test_flow_implicit_resize()
{
- QSGView *canvas = createView(SRCDIR "/data/flow-testimplicitsize.qml");
+ QSGView *canvas = createView(TESTDATA("flow-testimplicitsize.qml"));
QVERIFY(canvas->rootObject() != 0);
QSGFlow *flow = canvas->rootObject()->findChild<QSGFlow*>("flow");
@@ -1288,17 +1282,17 @@ void tst_qsgpositioners::test_mirroring()
QList<QString> objectNames;
objectNames << "one" << "two" << "three" << "four" << "five";
- foreach(const QString qmlFile, qmlFiles) {
- QSGView *canvasA = createView(QString(SRCDIR) + "/data/" + qmlFile);
+ foreach (const QString qmlFile, qmlFiles) {
+ QSGView *canvasA = createView(TESTDATA(qmlFile));
QSGItem *rootA = qobject_cast<QSGItem*>(canvasA->rootObject());
- QSGView *canvasB = createView(QString(SRCDIR) + "/data/" + qmlFile);
+ QSGView *canvasB = createView(TESTDATA(qmlFile));
QSGItem *rootB = qobject_cast<QSGItem*>(canvasB->rootObject());
rootA->setProperty("testRightToLeft", true); // layoutDirection: Qt.RightToLeft
// LTR != RTL
- foreach(const QString objectName, objectNames) {
+ foreach (const QString objectName, objectNames) {
// horizontal.qml only has three items
if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
break;
@@ -1315,7 +1309,7 @@ void tst_qsgpositioners::test_mirroring()
rootPrivateB->resolveLayoutMirror();
// RTL == mirror
- foreach(const QString objectName, objectNames) {
+ foreach (const QString objectName, objectNames) {
// horizontal.qml only has three items
if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
break;
@@ -1328,7 +1322,7 @@ void tst_qsgpositioners::test_mirroring()
rootB->setProperty("testRightToLeft", true); // layoutDirection: Qt.RightToLeft
// LTR == RTL + mirror
- foreach(const QString objectName, objectNames) {
+ foreach (const QString objectName, objectNames) {
// horizontal.qml only has three items
if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
break;
@@ -1344,7 +1338,7 @@ void tst_qsgpositioners::test_mirroring()
void tst_qsgpositioners::test_allInvisible()
{
//QTBUG-19361
- QSGView *canvas = createView(SRCDIR "/data/allInvisible.qml");
+ QSGView *canvas = createView(TESTDATA("allInvisible.qml"));
QSGItem *root = qobject_cast<QSGItem*>(canvas->rootObject());
QVERIFY(root);
@@ -1402,15 +1396,16 @@ void tst_qsgpositioners::test_attachedproperties_data()
{
QTest::addColumn<QString>("filename");
- QTest::newRow("column") << SRCDIR "/data/attachedproperties-column.qml";
- QTest::newRow("row") << SRCDIR "/data/attachedproperties-row.qml";
- QTest::newRow("grid") << SRCDIR "/data/attachedproperties-grid.qml";
- QTest::newRow("flow") << SRCDIR "/data/attachedproperties-flow.qml";
+ QTest::newRow("column") << TESTDATA("attachedproperties-column.qml");
+ QTest::newRow("row") << TESTDATA("attachedproperties-row.qml");
+ QTest::newRow("grid") << TESTDATA("attachedproperties-grid.qml");
+ QTest::newRow("flow") << TESTDATA("attachedproperties-flow.qml");
}
void tst_qsgpositioners::test_attachedproperties_dynamic()
{
- QSGView *canvas = createView(SRCDIR "/data/attachedproperties-dynamic.qml");
+ QSKIP("QTBUG-21995 - Test crashes on exit");
+ QSGView *canvas = createView(TESTDATA("attachedproperties-dynamic.qml"));
QVERIFY(canvas->rootObject() != 0);
QSGRow *row = canvas->rootObject()->findChild<QSGRow *>("pos");
diff --git a/tests/auto/declarative/qsgrepeater/qsgrepeater.pro b/tests/auto/declarative/qsgrepeater/qsgrepeater.pro
index 9c2891778d..aa15c71f8c 100644
--- a/tests/auto/declarative/qsgrepeater/qsgrepeater.pro
+++ b/tests/auto/declarative/qsgrepeater/qsgrepeater.pro
@@ -1,16 +1,12 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative
+CONFIG += testcase
+TARGET = tst_qsgrepeater
macx:CONFIG -= app_bundle
SOURCES += tst_qsgrepeater.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testFiles.files = data
+testFiles.path = .
+DEPLOYMENT += testFiles
CONFIG += parallel_test
-QT += core-private gui-private declarative-private
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qsgrepeater/tst_qsgrepeater.cpp b/tests/auto/declarative/qsgrepeater/tst_qsgrepeater.cpp
index 9eb88137f5..40d7b77827 100644
--- a/tests/auto/declarative/qsgrepeater/tst_qsgrepeater.cpp
+++ b/tests/auto/declarative/qsgrepeater/tst_qsgrepeater.cpp
@@ -49,14 +49,11 @@
#include <private/qsgrepeater_p.h>
#include <private/qsgtext_p.h>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#include "../shared/util.h"
inline QUrl TEST_FILE(const QString &filename)
{
- return QUrl::fromLocalFile(QLatin1String(SRCDIR) + QLatin1String("/data/") + filename);
+ return QUrl::fromLocalFile(TESTDATA(filename));
}
class tst_QSGRepeater : public QObject
@@ -183,7 +180,7 @@ void tst_QSGRepeater::numberModel()
TestObject *testObject = new TestObject;
ctxt->setContextProperty("testObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/intmodel.qml"));
+ canvas->setSource(TEST_FILE("intmodel.qml"));
qApp->processEvents();
QSGRepeater *repeater = findItem<QSGRepeater>(canvas->rootObject(), "repeater");
@@ -218,13 +215,13 @@ void tst_QSGRepeater::objectList()
{
QSGView *canvas = createView();
QObjectList data;
- for(int i=0; i<100; i++)
+ for (int i=0; i<100; i++)
data << new MyObject(i);
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testData", QVariant::fromValue(data));
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/objlist.qml"));
+ canvas->setSource(TEST_FILE("objlist.qml"));
qApp->processEvents();
QSGRepeater *repeater = findItem<QSGRepeater>(canvas->rootObject(), "repeater");
@@ -265,7 +262,7 @@ void tst_QSGRepeater::stringList()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testData", data);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/repeater1.qml"));
+ canvas->setSource(TEST_FILE("repeater1.qml"));
qApp->processEvents();
QSGRepeater *repeater = findItem<QSGRepeater>(canvas->rootObject(), "repeater");
@@ -313,7 +310,7 @@ void tst_QSGRepeater::dataModel_adding()
TestModel testModel;
ctxt->setContextProperty("testData", &testModel);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/repeater2.qml"));
+ canvas->setSource(TEST_FILE("repeater2.qml"));
qApp->processEvents();
QSGRepeater *repeater = findItem<QSGRepeater>(canvas->rootObject(), "repeater");
@@ -383,7 +380,7 @@ void tst_QSGRepeater::dataModel_removing()
testModel.addItem("five", "5");
ctxt->setContextProperty("testData", &testModel);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/repeater2.qml"));
+ canvas->setSource(TEST_FILE("repeater2.qml"));
qApp->processEvents();
QSGRepeater *repeater = findItem<QSGRepeater>(canvas->rootObject(), "repeater");
@@ -449,7 +446,7 @@ void tst_QSGRepeater::dataModel_changes()
testModel.addItem("three", "3");
ctxt->setContextProperty("testData", &testModel);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/repeater2.qml"));
+ canvas->setSource(TEST_FILE("repeater2.qml"));
qApp->processEvents();
QSGRepeater *repeater = findItem<QSGRepeater>(canvas->rootObject(), "repeater");
@@ -483,7 +480,7 @@ void tst_QSGRepeater::itemModel()
TestObject *testObject = new TestObject;
ctxt->setContextProperty("testObject", testObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/itemlist.qml"));
+ canvas->setSource(TEST_FILE("itemlist.qml"));
qApp->processEvents();
QSGRepeater *repeater = findItem<QSGRepeater>(canvas->rootObject(), "repeater");
@@ -527,7 +524,7 @@ void tst_QSGRepeater::resetModel()
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testData", dataA);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/repeater1.qml"));
+ canvas->setSource(TEST_FILE("repeater1.qml"));
qApp->processEvents();
QSGRepeater *repeater = findItem<QSGRepeater>(canvas->rootObject(), "repeater");
QVERIFY(repeater != 0);
@@ -589,7 +586,7 @@ void tst_QSGRepeater::resetModel()
void tst_QSGRepeater::modelChanged()
{
QDeclarativeEngine engine;
- QDeclarativeComponent component(&engine, TEST_FILE("/modelChanged.qml"));
+ QDeclarativeComponent component(&engine, TEST_FILE("modelChanged.qml"));
QSGItem *rootObject = qobject_cast<QSGItem*>(component.create());
QVERIFY(rootObject);
@@ -612,7 +609,7 @@ void tst_QSGRepeater::modelChanged()
void tst_QSGRepeater::properties()
{
QDeclarativeEngine engine;
- QDeclarativeComponent component(&engine, TEST_FILE("/properties.qml"));
+ QDeclarativeComponent component(&engine, TEST_FILE("properties.qml"));
QSGItem *rootObject = qobject_cast<QSGItem*>(component.create());
QVERIFY(rootObject);
@@ -654,7 +651,7 @@ T *tst_QSGRepeater::findItem(QObject *parent, const QString &objectName, int ind
//qDebug() << parent->children().count() << "children";
for (int i = 0; i < parent->children().count(); ++i) {
QSGItem *item = qobject_cast<QSGItem*>(parent->children().at(i));
- if(!item)
+ if (!item)
continue;
//qDebug() << "try" << item;
if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
diff --git a/tests/auto/declarative/qsgtext/data/embeddedImagesLocal.qml b/tests/auto/declarative/qsgtext/data/embeddedImagesLocal.qml
index d71e9bb5bf..74b2ab817a 100644
--- a/tests/auto/declarative/qsgtext/data/embeddedImagesLocal.qml
+++ b/tests/auto/declarative/qsgtext/data/embeddedImagesLocal.qml
@@ -1,5 +1,6 @@
import QtQuick 2.0
Text {
+ textFormat: Text.RichText
text: "<img src='http/exists.png'>"
}
diff --git a/tests/auto/declarative/qsgtext/data/embeddedImagesLocalError.qml b/tests/auto/declarative/qsgtext/data/embeddedImagesLocalError.qml
index e6719481db..a2f7e0c89f 100644
--- a/tests/auto/declarative/qsgtext/data/embeddedImagesLocalError.qml
+++ b/tests/auto/declarative/qsgtext/data/embeddedImagesLocalError.qml
@@ -1,5 +1,6 @@
import QtQuick 2.0
Text {
+ textFormat: Text.RichText
text: "<img src='http/notexists.png'>"
}
diff --git a/tests/auto/declarative/qsgtext/data/embeddedImagesRemote.qml b/tests/auto/declarative/qsgtext/data/embeddedImagesRemote.qml
index e524d028b5..702633c538 100644
--- a/tests/auto/declarative/qsgtext/data/embeddedImagesRemote.qml
+++ b/tests/auto/declarative/qsgtext/data/embeddedImagesRemote.qml
@@ -1,5 +1,6 @@
import QtQuick 2.0
Text {
+ textFormat: Text.RichText
text: "<img src='http://127.0.0.1:14453/exists.png'>"
}
diff --git a/tests/auto/declarative/qsgtext/data/embeddedImagesRemoteError.qml b/tests/auto/declarative/qsgtext/data/embeddedImagesRemoteError.qml
index f541e0e497..5762f3e47d 100644
--- a/tests/auto/declarative/qsgtext/data/embeddedImagesRemoteError.qml
+++ b/tests/auto/declarative/qsgtext/data/embeddedImagesRemoteError.qml
@@ -1,5 +1,6 @@
import QtQuick 2.0
Text {
+ textFormat: Text.RichText
text: "<img src='http://127.0.0.1:14453/notexists.png'>"
}
diff --git a/tests/auto/declarative/qsgtext/data/lineLayout.qml b/tests/auto/declarative/qsgtext/data/lineLayout.qml
new file mode 100644
index 0000000000..cb2474791e
--- /dev/null
+++ b/tests/auto/declarative/qsgtext/data/lineLayout.qml
@@ -0,0 +1,35 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: main
+ width: 800; height: 600
+
+ property real off: 0
+
+ Text {
+ id: myText
+ objectName: "myText"
+ wrapMode: Text.WordWrap
+ font.pixelSize: 14
+ textFormat: Text.StyledText
+ focus: true
+
+ text: "<b>Lorem ipsum</b> dolor sit amet, consectetur adipiscing elit. Integer at ante dui. Sed eu egestas est.
+ <br/><p><i>Maecenas nec libero leo. Sed ac leo eget ipsum ultricies viverra sit amet eu orci. Praesent et tortor risus, viverra accumsan sapien. Sed faucibus eleifend lectus, sed euismod urna porta eu. Aenean ultricies lectus ut orci dictum quis convallis nisi ultrices. Nunc elit mi, iaculis a porttitor rutrum, venenatis malesuada nisi. Suspendisse turpis quam, euismod non imperdiet et, rutrum nec ligula. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper tristique metus eu sodales. Integer eget risus ipsum. Quisque ut risus ut nulla tristique volutpat at sit amet nisl. Aliquam pulvinar auctor diam nec bibendum.</i><br/><p>Quisque luctus sapien id arcu volutpat pharetra. Praesent pretium imperdiet euismod. Integer fringilla rhoncus condimentum. Quisque sit amet ornare nulla. Cras sapien augue, sagittis a dictum id, suscipit et nunc. Cras vitae augue in enim elementum venenatis sed nec risus. Sed nisi quam, mollis quis auctor ac, vestibulum in neque. Vivamus eu justo risus. Suspendisse vel mollis est. Vestibulum gravida interdum mi, in molestie neque gravida in. Donec nibh odio, mattis facilisis vulputate et, scelerisque ut felis. Sed ornare eros nec odio aliquam eu varius augue adipiscing. Vivamus sit amet massa dapibus sapien pulvinar consectetur a sit amet felis. Cras non mi id libero dictum iaculis id dignissim eros. Praesent eget enim dui, sed bibendum neque. Ut interdum nisl id leo malesuada ornare. Pellentesque id nisl eu odio volutpat posuere et at massa. Pellentesque nec lorem justo. Integer sem urna, pharetra sed sagittis vitae, condimentum ac felis. Ut vitae sapien ac tortor adipiscing pharetra. Cras tristique urna tempus ante volutpat eleifend non eu ligula. Mauris sodales nisl et lorem tristique sodales. Mauris arcu orci, vehicula semper cursus ac, dapibus ut mi."
+
+ onLineLaidOut: {
+ line.width = line.number * 15
+ if (line.number === 30 || line.number === 60) {
+ main.off = line.y
+ }
+ if (line.number >= 30) {
+ line.x = line.width + 30
+ line.y -= main.off
+ }
+ if (line.number >= 60) {
+ line.x = line.width * 2 + 60
+ line.height = 20
+ }
+ }
+ }
+}
diff --git a/tests/auto/declarative/qsgtext/qsgtext.pro b/tests/auto/declarative/qsgtext/qsgtext.pro
index a13f8f93c8..a04c079ef2 100644
--- a/tests/auto/declarative/qsgtext/qsgtext.pro
+++ b/tests/auto/declarative/qsgtext/qsgtext.pro
@@ -1,6 +1,5 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui
-QT += network
+CONFIG += testcase
+TARGET = tst_qsgtext
macx:CONFIG -= app_bundle
SOURCES += tst_qsgtext.cpp
@@ -9,15 +8,10 @@ INCLUDEPATH += ../shared/
HEADERS += ../shared/testhttpserver.h
SOURCES += ../shared/testhttpserver.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private widgets-private
-QT += opengl-private
+QT += core-private gui-private v8-private declarative-private widgets-private opengl-private network testlib
diff --git a/tests/auto/declarative/qsgtext/tst_qsgtext.cpp b/tests/auto/declarative/qsgtext/tst_qsgtext.cpp
index 7b04e76f01..a46969e217 100644
--- a/tests/auto/declarative/qsgtext/tst_qsgtext.cpp
+++ b/tests/auto/declarative/qsgtext/tst_qsgtext.cpp
@@ -53,19 +53,12 @@
#include <private/qapplication_p.h>
#include <limits.h>
#include <QtGui/QMouseEvent>
-#include "../../../shared/util.h"
+#include "../shared/util.h"
#include "testhttpserver.h"
-#include <QtOpenGL/QGLShaderProgram>
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
class tst_qsgtext : public QObject
-
{
Q_OBJECT
public:
@@ -89,7 +82,7 @@ private slots:
void lineCount();
void lineHeight();
- // ### these tests may be trivial
+ // ### these tests may be trivial
void horizontalAlignment();
void horizontalAlignment_RightToLeft();
void verticalAlignment();
@@ -109,10 +102,11 @@ private slots:
void clickLink();
-
void implicitSize_data();
void implicitSize();
+ void lineLaidOut();
+
private:
QStringList standard;
@@ -315,20 +309,20 @@ void tst_qsgtext::width()
{
QVERIFY(Qt::mightBeRichText(richText.at(i))); // self-test
- QTextDocument document;
- document.setHtml(richText.at(i));
- document.setDocumentMargin(0);
-
- int documentWidth = document.idealWidth();
-
- QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\" }";
+ QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\"; textFormat: Text.RichText }";
QDeclarativeComponent textComponent(&engine);
textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
QVERIFY(textObject != 0);
- QCOMPARE(textObject->width(), qreal(documentWidth));
- QVERIFY(textObject->textFormat() == QSGText::AutoText); // setting text doesn't change format
+
+ QSGTextPrivate *textPrivate = QSGTextPrivate::get(textObject);
+ QVERIFY(textPrivate != 0);
+
+ QTextDocument *doc = textPrivate->textDocument();
+ QVERIFY(doc != 0);
+
+ QCOMPARE(int(textObject->width()), int(doc->idealWidth()));
+ QVERIFY(textObject->textFormat() == QSGText::RichText);
delete textObject;
}
@@ -465,6 +459,24 @@ void tst_qsgtext::textFormat()
QVERIFY(textObject != 0);
QVERIFY(textObject->textFormat() == QSGText::RichText);
+ QSGTextPrivate *textPrivate = QSGTextPrivate::get(textObject);
+ QVERIFY(textPrivate != 0);
+ QVERIFY(textPrivate->richText == true);
+
+ delete textObject;
+ }
+ {
+ QDeclarativeComponent textComponent(&engine);
+ textComponent.setData("import QtQuick 2.0\nText { text: \"<b>Hello</b>\" }", QUrl::fromLocalFile(""));
+ QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QVERIFY(textObject->textFormat() == QSGText::AutoText);
+
+ QSGTextPrivate *textPrivate = QSGTextPrivate::get(textObject);
+ QVERIFY(textPrivate != 0);
+ QVERIFY(textPrivate->styledText == true);
+
delete textObject;
}
{
@@ -486,24 +498,23 @@ void tst_qsgtext::alignments_data()
QTest::addColumn<int>("vAlign");
QTest::addColumn<QString>("expectfile");
- QTest::newRow("LT") << int(Qt::AlignLeft) << int(Qt::AlignTop) << SRCDIR "/data/alignments_lt.png";
- QTest::newRow("RT") << int(Qt::AlignRight) << int(Qt::AlignTop) << SRCDIR "/data/alignments_rt.png";
- QTest::newRow("CT") << int(Qt::AlignHCenter) << int(Qt::AlignTop) << SRCDIR "/data/alignments_ct.png";
+ QTest::newRow("LT") << int(Qt::AlignLeft) << int(Qt::AlignTop) << TESTDATA("alignments_lt.png");
+ QTest::newRow("RT") << int(Qt::AlignRight) << int(Qt::AlignTop) << TESTDATA("alignments_rt.png");
+ QTest::newRow("CT") << int(Qt::AlignHCenter) << int(Qt::AlignTop) << TESTDATA("alignments_ct.png");
- QTest::newRow("LB") << int(Qt::AlignLeft) << int(Qt::AlignBottom) << SRCDIR "/data/alignments_lb.png";
- QTest::newRow("RB") << int(Qt::AlignRight) << int(Qt::AlignBottom) << SRCDIR "/data/alignments_rb.png";
- QTest::newRow("CB") << int(Qt::AlignHCenter) << int(Qt::AlignBottom) << SRCDIR "/data/alignments_cb.png";
+ QTest::newRow("LB") << int(Qt::AlignLeft) << int(Qt::AlignBottom) << TESTDATA("alignments_lb.png");
+ QTest::newRow("RB") << int(Qt::AlignRight) << int(Qt::AlignBottom) << TESTDATA("alignments_rb.png");
+ QTest::newRow("CB") << int(Qt::AlignHCenter) << int(Qt::AlignBottom) << TESTDATA("alignments_cb.png");
- QTest::newRow("LC") << int(Qt::AlignLeft) << int(Qt::AlignVCenter) << SRCDIR "/data/alignments_lc.png";
- QTest::newRow("RC") << int(Qt::AlignRight) << int(Qt::AlignVCenter) << SRCDIR "/data/alignments_rc.png";
- QTest::newRow("CC") << int(Qt::AlignHCenter) << int(Qt::AlignVCenter) << SRCDIR "/data/alignments_cc.png";
+ QTest::newRow("LC") << int(Qt::AlignLeft) << int(Qt::AlignVCenter) << TESTDATA("alignments_lc.png");
+ QTest::newRow("RC") << int(Qt::AlignRight) << int(Qt::AlignVCenter) << TESTDATA("alignments_rc.png");
+ QTest::newRow("CC") << int(Qt::AlignHCenter) << int(Qt::AlignVCenter) << TESTDATA("alignments_cc.png");
}
void tst_qsgtext::alignments()
{
-
- QSKIP("Text alignment pixmap comparison tests will not work with scenegraph", SkipAll);
+ QSKIP("Text alignment pixmap comparison tests will not work with scenegraph");
#if (0)// No widgets in scenegraph
QFETCH(int, hAlign);
QFETCH(int, vAlign);
@@ -516,7 +527,7 @@ void tst_qsgtext::alignments()
QApplication::setFont(fn);
#endif
- QSGView *canvas = createView(SRCDIR "/data/alignments.qml");
+ QSGView *canvas = createView(TESTDATA("alignments.qml"));
canvas->show();
canvas->requestActivateWindow();
@@ -585,7 +596,7 @@ void tst_qsgtext::horizontalAlignment()
void tst_qsgtext::horizontalAlignment_RightToLeft()
{
- QSGView *canvas = createView(SRCDIR "/data/horizontalAlignment_RightToLeft.qml");
+ QSGView *canvas = createView(TESTDATA("horizontalAlignment_RightToLeft.qml"));
QSGText *text = canvas->rootObject()->findChild<QSGText*>("text");
QVERIFY(text != 0);
canvas->show();
@@ -768,7 +779,7 @@ void tst_qsgtext::font()
delete textObject;
}
- {
+ {
QString componentStr = "import QtQuick 2.0\nText { font.bold: true; text: \"Hello World\" }";
QDeclarativeComponent textComponent(&engine);
textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
@@ -780,7 +791,7 @@ void tst_qsgtext::font()
delete textObject;
}
- {
+ {
QString componentStr = "import QtQuick 2.0\nText { font.italic: true; text: \"Hello World\" }";
QDeclarativeComponent textComponent(&engine);
textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
@@ -792,7 +803,7 @@ void tst_qsgtext::font()
delete textObject;
}
- {
+ {
QString componentStr = "import QtQuick 2.0\nText { font.family: \"Helvetica\"; text: \"Hello World\" }";
QDeclarativeComponent textComponent(&engine);
textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
@@ -805,7 +816,7 @@ void tst_qsgtext::font()
delete textObject;
}
- {
+ {
QString componentStr = "import QtQuick 2.0\nText { font.family: \"\"; text: \"Hello World\" }";
QDeclarativeComponent textComponent(&engine);
textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
@@ -821,7 +832,7 @@ void tst_qsgtext::style()
{
//test style
for (int i = 0; i < styles.size(); i++)
- {
+ {
QString componentStr = "import QtQuick 2.0\nText { style: \"" + styleStrings.at(i) + "\"; styleColor: \"white\"; text: \"Hello World\" }";
QDeclarativeComponent textComponent(&engine);
textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
@@ -851,7 +862,7 @@ void tst_qsgtext::color()
{
//test style
for (int i = 0; i < colorStrings.size(); i++)
- {
+ {
QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
QDeclarativeComponent textComponent(&engine);
textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
@@ -864,7 +875,7 @@ void tst_qsgtext::color()
}
for (int i = 0; i < colorStrings.size(); i++)
- {
+ {
QString componentStr = "import QtQuick 2.0\nText { styleColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
QDeclarativeComponent textComponent(&engine);
textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
@@ -876,9 +887,9 @@ void tst_qsgtext::color()
delete textObject;
}
-
+
for (int i = 0; i < colorStrings.size(); i++)
- {
+ {
for (int j = 0; j < colorStrings.size(); j++)
{
QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStrings.at(i) + "\"; styleColor: \"" + colorStrings.at(j) + "\"; text: \"Hello World\" }";
@@ -1255,12 +1266,12 @@ void tst_qsgtext::embeddedImages_data()
{
QTest::addColumn<QUrl>("qmlfile");
QTest::addColumn<QString>("error");
- QTest::newRow("local") << QUrl::fromLocalFile(SRCDIR "/data/embeddedImagesLocal.qml") << "";
- QTest::newRow("local-error") << QUrl::fromLocalFile(SRCDIR "/data/embeddedImagesLocalError.qml")
- << QUrl::fromLocalFile(SRCDIR "/data/embeddedImagesLocalError.qml").toString()+":3:1: QML Text: Cannot open: " + QUrl::fromLocalFile(SRCDIR "/data/http/notexists.png").toString();
- QTest::newRow("remote") << QUrl::fromLocalFile(SRCDIR "/data/embeddedImagesRemote.qml") << "";
- QTest::newRow("remote-error") << QUrl::fromLocalFile(SRCDIR "/data/embeddedImagesRemoteError.qml")
- << QUrl::fromLocalFile(SRCDIR "/data/embeddedImagesRemoteError.qml").toString()+":3:1: QML Text: Error downloading http://127.0.0.1:14453/notexists.png - server replied: Not found";
+ QTest::newRow("local") << QUrl::fromLocalFile(TESTDATA("embeddedImagesLocal.qml")) << "";
+ QTest::newRow("local-error") << QUrl::fromLocalFile(TESTDATA("embeddedImagesLocalError.qml"))
+ << QUrl::fromLocalFile(TESTDATA("embeddedImagesLocalError.qml")).toString()+":3:1: QML Text: Cannot open: " + QUrl::fromLocalFile(TESTDATA("http/notexists.png")).toString();
+ QTest::newRow("remote") << QUrl::fromLocalFile(TESTDATA("embeddedImagesRemote.qml")) << "";
+ QTest::newRow("remote-error") << QUrl::fromLocalFile(TESTDATA("embeddedImagesRemoteError.qml"))
+ << QUrl::fromLocalFile(TESTDATA("embeddedImagesRemoteError.qml")).toString()+":3:1: QML Text: Error downloading http://127.0.0.1:14453/notexists.png - server replied: Not found";
}
void tst_qsgtext::embeddedImages()
@@ -1271,11 +1282,11 @@ void tst_qsgtext::embeddedImages()
QFETCH(QString, error);
TestHTTPServer server(14453);
- server.serveDirectory(SRCDIR "/data/http");
+ server.serveDirectory(TESTDATA("http"));
if (!error.isEmpty())
QTest::ignoreMessage(QtWarningMsg, error.toLatin1());
-
+
QDeclarativeComponent textComponent(&engine, qmlfile);
QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
@@ -1283,7 +1294,7 @@ void tst_qsgtext::embeddedImages()
QTRY_COMPARE(textObject->resourcesLoading(), 0);
- QPixmap pm(SRCDIR "/data/http/exists.png");
+ QPixmap pm(TESTDATA("http/exists.png"));
if (error.isEmpty()) {
QCOMPARE(textObject->width(), double(pm.width()));
QCOMPARE(textObject->height(), double(pm.height()));
@@ -1298,7 +1309,7 @@ void tst_qsgtext::embeddedImages()
void tst_qsgtext::lineCount()
{
- QSGView *canvas = createView(SRCDIR "/data/lineCount.qml");
+ QSGView *canvas = createView(TESTDATA("lineCount.qml"));
QSGText *myText = canvas->rootObject()->findChild<QSGText*>("myText");
QVERIFY(myText != 0);
@@ -1327,7 +1338,7 @@ void tst_qsgtext::lineCount()
void tst_qsgtext::lineHeight()
{
- QSGView *canvas = createView(SRCDIR "/data/lineHeight.qml");
+ QSGView *canvas = createView(TESTDATA("lineHeight.qml"));
QSGText *myText = canvas->rootObject()->findChild<QSGText*>("myText");
QVERIFY(myText != 0);
@@ -1390,6 +1401,32 @@ void tst_qsgtext::implicitSize()
delete textObject;
}
+void tst_qsgtext::lineLaidOut()
+{
+ QSGView *canvas = createView(TESTDATA("lineLayout.qml"));
+
+ QSGText *myText = canvas->rootObject()->findChild<QSGText*>("myText");
+ QVERIFY(myText != 0);
+
+ QSGTextPrivate *textPrivate = QSGTextPrivate::get(myText);
+ QVERIFY(textPrivate != 0);
+
+ QTextDocument *doc = textPrivate->textDocument();
+ QVERIFY(doc == 0);
+
+ QVERIFY(myText->lineCount() == textPrivate->linesRects.count());
+
+ for (int i = 0; i < textPrivate->linesRects.count(); ++i) {
+ QRectF r = textPrivate->linesRects.at(i);
+ QVERIFY(r.width() == i * 15);
+ if (i >= 30)
+ QVERIFY(r.x() == r.width() + 30);
+ if (i >= 60) {
+ QVERIFY(r.x() == r.width() * 2 + 60);
+ QVERIFY(r.height() == 20);
+ }
+ }
+}
QTEST_MAIN(tst_qsgtext)
diff --git a/tests/auto/declarative/qsgtextedit/data/cursorTest.qml b/tests/auto/declarative/qsgtextedit/data/cursorTest.qml
index e734fc141c..7bfc869403 100644
--- a/tests/auto/declarative/qsgtextedit/data/cursorTest.qml
+++ b/tests/auto/declarative/qsgtextedit/data/cursorTest.qml
@@ -1,8 +1,9 @@
import QtQuick 2.0
Rectangle { width: 300; height: 300; color: "white"
+ property string contextualProperty: "Hello"
TextEdit { text: "Hello world!"; id: textEditObject; objectName: "textEditObject"
- resources: [ Component { id:cursor; Item { id:cursorInstance; objectName: "cursorInstance" } } ]
+ resources: [ Component { id:cursor; Item { id:cursorInstance; objectName: "cursorInstance"; property string localProperty: contextualProperty } } ]
cursorDelegate: cursor
}
}
diff --git a/tests/auto/declarative/qsgtextedit/data/openInputPanel.qml b/tests/auto/declarative/qsgtextedit/data/openInputPanel.qml
index 8998e55abb..d3aecf21be 100644
--- a/tests/auto/declarative/qsgtextedit/data/openInputPanel.qml
+++ b/tests/auto/declarative/qsgtextedit/data/openInputPanel.qml
@@ -1,6 +1,7 @@
import QtQuick 2.0
TextEdit {
+ width: 100; height: 100
text: "Hello world"
focus: false
}
diff --git a/tests/auto/declarative/qsgtextedit/data/qtbug-22058.qml b/tests/auto/declarative/qsgtextedit/data/qtbug-22058.qml
new file mode 100644
index 0000000000..8ad1514fbf
--- /dev/null
+++ b/tests/auto/declarative/qsgtextedit/data/qtbug-22058.qml
@@ -0,0 +1,39 @@
+import QtQuick 2.0
+
+Rectangle {
+ property variant inputField: textedit
+ height: 200
+ width: 200
+
+ Rectangle {
+ height: parent.height /2
+ width: parent.width
+ color: "transparent"
+ border.color: "black"
+ border.width: 4
+ Text {
+ anchors.centerIn: parent
+ height: parent.height * .95
+ width: parent.width * .95
+ text: textedit.text
+ }
+ }
+
+ Rectangle {
+ height: parent.height /2
+ width: parent.width
+ color: "transparent"
+ border.color: "black"
+ border.width: 4
+ anchors.bottom: parent.bottom
+ TextEdit {
+ id: textedit
+ anchors.centerIn: parent
+ height: parent.height * .95
+ width: parent.width * .95
+ focus: true
+ wrapMode: TextEdit.WordWrap
+ text: ""
+ }
+ }
+}
diff --git a/tests/auto/declarative/qsgtextedit/qsgtextedit.pro b/tests/auto/declarative/qsgtextedit/qsgtextedit.pro
index 1048e499d9..41c7b65b56 100644
--- a/tests/auto/declarative/qsgtextedit/qsgtextedit.pro
+++ b/tests/auto/declarative/qsgtextedit/qsgtextedit.pro
@@ -1,18 +1,12 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui network widgets widgets-private
+CONFIG += testcase
+TARGET = tst_qsgtextedit
macx:CONFIG -= app_bundle
SOURCES += tst_qsgtextedit.cpp ../shared/testhttpserver.cpp
HEADERS += ../shared/testhttpserver.h
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-QT += core-private gui-private v8-private declarative-private
-QT += opengl-private
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
-qpa:CONFIG+=insignificant_test # QTBUG-21010, fails unstably
+QT += core-private gui-private v8-private declarative-private opengl-private network widgets-private testlib
diff --git a/tests/auto/declarative/qsgtextedit/tst_qsgtextedit.cpp b/tests/auto/declarative/qsgtextedit/tst_qsgtextedit.cpp
index 0fc2a1a509..9b48b5fbd4 100644
--- a/tests/auto/declarative/qsgtextedit/tst_qsgtextedit.cpp
+++ b/tests/auto/declarative/qsgtextedit/tst_qsgtextedit.cpp
@@ -40,7 +40,6 @@
****************************************************************************/
#include <qtest.h>
#include <QtTest/QSignalSpy>
-#include "../../../shared/util.h"
#include "../shared/testhttpserver.h"
#include <math.h>
#include <QFile>
@@ -49,6 +48,7 @@
#include <QtDeclarative/qdeclarativecontext.h>
#include <QtDeclarative/qdeclarativeexpression.h>
#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtGui/qguiapplication.h>
#include <private/qsgtextedit_p.h>
#include <private/qsgtextedit_p_p.h>
#include <private/qsgdistancefieldglyphcache_p.h>
@@ -57,20 +57,18 @@
#include <QDir>
#include <QStyle>
#include <QInputContext>
+#include <QInputPanel>
#include <QClipboard>
#include <QMimeData>
-#include <QtWidgets/5.0.0/QtWidgets/private/qapplication_p.h>
#include <private/qtextcontrol_p.h>
-#include <QtOpenGL/QGLShaderProgram>
+#include "../shared/util.h"
#ifdef Q_WS_MAC
#include <Carbon/Carbon.h>
#endif
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+#define QTBUG_21691
+#define QTBUG_21691_MESSAGE "QTBUG-21691: The test needs to be rewritten to not use QInputContext"
Q_DECLARE_METATYPE(QSGTextEdit::SelectionMode)
DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
@@ -78,7 +76,7 @@ DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
QString createExpectedFileIfNotFound(const QString& filebasename, const QImage& actual)
{
// XXX This will be replaced by some clever persistent platform image store.
- QString persistent_dir = SRCDIR "/data";
+ QString persistent_dir = TESTDATA("");
QString arch = "unknown-architecture"; // QTest needs to help with this.
QString expectfile = persistent_dir + QDir::separator() + filebasename + "-" + arch + ".png";
@@ -109,7 +107,7 @@ private slots:
void alignments();
void alignments_data();
- // ### these tests may be trivial
+ // ### these tests may be trivial
void hAlign();
void hAlign_RightToLeft();
void vAlign();
@@ -145,8 +143,7 @@ private slots:
void canPaste();
void canPasteEmpty();
void textInput();
- void openInputPanelOnClick();
- void openInputPanelOnFocus();
+ void openInputPanel();
void geometrySignals();
void pastingRichText_QTBUG_14003();
void implicitSize_data();
@@ -159,6 +156,8 @@ private slots:
void inputMethodComposing();
void cursorRectangleSize();
+ void emptytags_QTBUG_22058();
+
private:
void simulateKey(QSGView *, int key, Qt::KeyboardModifiers modifiers = 0);
@@ -225,7 +224,7 @@ tst_qsgtextedit::tst_qsgtextedit()
// need a different test to do alpha channel test
// << "#AA0011DD"
// << "#00F16B11";
- //
+ //
}
void tst_qsgtextedit::text()
@@ -421,16 +420,18 @@ void tst_qsgtextedit::alignments_data()
void tst_qsgtextedit::alignments()
{
+ QSKIP("Image comparison of text is almost guaranteed to fail during development");
+
QFETCH(int, hAlign);
QFETCH(int, vAlign);
QFETCH(QString, expectfile);
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/alignments.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("alignments.qml")));
canvas.show();
canvas.requestActivateWindow();
QTest::qWaitForWindowShown(&canvas);
- QTRY_COMPARE(canvas.windowState(), Qt::WindowActive);
+ QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
QObject *ob = canvas.rootObject();
QVERIFY(ob != 0);
@@ -484,7 +485,7 @@ void tst_qsgtextedit::hAlign()
void tst_qsgtextedit::hAlign_RightToLeft()
{
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/horizontalAlignment_RightToLeft.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("horizontalAlignment_RightToLeft.qml")));
QSGTextEdit *textEdit = canvas.rootObject()->findChild<QSGTextEdit*>("text");
QVERIFY(textEdit != 0);
canvas.show();
@@ -569,21 +570,22 @@ void tst_qsgtextedit::hAlign_RightToLeft()
canvas.requestActivateWindow();
QTest::qWaitForWindowShown(&canvas);
- QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas);
+ QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
textEdit->setText(QString());
- { QInputMethodEvent ev(rtlText, QList<QInputMethodEvent::Attribute>()); QApplication::sendEvent(&canvas, &ev); }
+ { QInputMethodEvent ev(rtlText, QList<QInputMethodEvent::Attribute>()); QGuiApplication::sendEvent(&canvas, &ev); }
+ QEXPECT_FAIL("", "QTBUG-21691", Abort);
QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignRight);
- { QInputMethodEvent ev("Hello world!", QList<QInputMethodEvent::Attribute>()); QApplication::sendEvent(&canvas, &ev); }
+ { QInputMethodEvent ev("Hello world!", QList<QInputMethodEvent::Attribute>()); QGuiApplication::sendEvent(&canvas, &ev); }
QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignLeft);
#ifndef Q_OS_MAC // QTBUG-18040
// empty text with implicit alignment follows the system locale-based
- // keyboard input direction from QApplication::keyboardInputDirection
+ // keyboard input direction from QGuiApplication::keyboardInputDirection
textEdit->setText("");
- QCOMPARE(textEdit->hAlign(), QApplication::keyboardInputDirection() == Qt::LeftToRight ?
+ QCOMPARE(textEdit->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ?
QSGTextEdit::AlignLeft : QSGTextEdit::AlignRight);
- if (QApplication::keyboardInputDirection() == Qt::LeftToRight)
+ if (QGuiApplication::keyboardInputDirection() == Qt::LeftToRight)
QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2);
else
QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
@@ -598,7 +600,7 @@ void tst_qsgtextedit::hAlign_RightToLeft()
QDeclarativeComponent textComponent(&engine);
textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QSGTextEdit *textObject = qobject_cast<QSGTextEdit*>(textComponent.create());
- QCOMPARE(textObject->hAlign(), QApplication::keyboardInputDirection() == Qt::LeftToRight ?
+ QCOMPARE(textObject->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ?
QSGTextEdit::AlignLeft : QSGTextEdit::AlignRight);
delete textObject;
#endif
@@ -641,7 +643,7 @@ void tst_qsgtextedit::vAlign()
void tst_qsgtextedit::font()
{
//test size, then bold, then italic, then family
- {
+ {
QString componentStr = "import QtQuick 2.0\nTextEdit { font.pointSize: 40; text: \"Hello World\" }";
QDeclarativeComponent texteditComponent(&engine);
texteditComponent.setData(componentStr.toLatin1(), QUrl());
@@ -653,7 +655,7 @@ void tst_qsgtextedit::font()
QCOMPARE(textEditObject->font().italic(), false);
}
- {
+ {
QString componentStr = "import QtQuick 2.0\nTextEdit { font.bold: true; text: \"Hello World\" }";
QDeclarativeComponent texteditComponent(&engine);
texteditComponent.setData(componentStr.toLatin1(), QUrl());
@@ -664,7 +666,7 @@ void tst_qsgtextedit::font()
QCOMPARE(textEditObject->font().italic(), false);
}
- {
+ {
QString componentStr = "import QtQuick 2.0\nTextEdit { font.italic: true; text: \"Hello World\" }";
QDeclarativeComponent texteditComponent(&engine);
texteditComponent.setData(componentStr.toLatin1(), QUrl());
@@ -675,7 +677,7 @@ void tst_qsgtextedit::font()
QCOMPARE(textEditObject->font().bold(), false);
}
- {
+ {
QString componentStr = "import QtQuick 2.0\nTextEdit { font.family: \"Helvetica\"; text: \"Hello World\" }";
QDeclarativeComponent texteditComponent(&engine);
texteditComponent.setData(componentStr.toLatin1(), QUrl());
@@ -687,7 +689,7 @@ void tst_qsgtextedit::font()
QCOMPARE(textEditObject->font().italic(), false);
}
- {
+ {
QString componentStr = "import QtQuick 2.0\nTextEdit { font.family: \"\"; text: \"Hello World\" }";
QDeclarativeComponent texteditComponent(&engine);
texteditComponent.setData(componentStr.toLatin1(), QUrl());
@@ -719,7 +721,7 @@ void tst_qsgtextedit::color()
}
//test normal
for (int i = 0; i < colorStrings.size(); i++)
- {
+ {
QString componentStr = "import QtQuick 2.0\nTextEdit { color: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
QDeclarativeComponent texteditComponent(&engine);
texteditComponent.setData(componentStr.toLatin1(), QUrl());
@@ -768,7 +770,7 @@ void tst_qsgtextedit::color()
void tst_qsgtextedit::textMargin()
{
- for(qreal i=0; i<=10; i+=0.3){
+ for (qreal i=0; i<=10; i+=0.3) {
QString componentStr = "import QtQuick 2.0\nTextEdit { textMargin: " + QString::number(i) + "; text: \"Hello World\" }";
QDeclarativeComponent texteditComponent(&engine);
texteditComponent.setData(componentStr.toLatin1(), QUrl());
@@ -831,7 +833,7 @@ void tst_qsgtextedit::selection()
//Test selection follows cursor
- for(int i=0; i<= testStr.size(); i++) {
+ for (int i=0; i<= testStr.size(); i++) {
textEditObject->setCursorPosition(i);
QCOMPARE(textEditObject->cursorPosition(), i);
QCOMPARE(textEditObject->selectionStart(), i);
@@ -859,11 +861,11 @@ void tst_qsgtextedit::selection()
QVERIFY(textEditObject->selectedText().isNull());
//Test selection
- for(int i=0; i<= testStr.size(); i++) {
+ for (int i=0; i<= testStr.size(); i++) {
textEditObject->select(0,i);
QCOMPARE(testStr.mid(0,i), textEditObject->selectedText());
}
- for(int i=0; i<= testStr.size(); i++) {
+ for (int i=0; i<= testStr.size(); i++) {
textEditObject->select(i,testStr.size());
QCOMPARE(testStr.mid(i,testStr.size()-i), textEditObject->selectedText());
}
@@ -963,11 +965,11 @@ void tst_qsgtextedit::isRightToLeft()
void tst_qsgtextedit::keySelection()
{
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/navigation.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml")));
canvas.show();
canvas.requestActivateWindow();
QTest::qWaitForWindowShown(&canvas);
- QTRY_COMPARE(canvas.windowState(), Qt::WindowActive);
+ QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
canvas.requestActivateWindow();
QVERIFY(canvas.rootObject() != 0);
@@ -1353,19 +1355,19 @@ void tst_qsgtextedit::mouseSelection_data()
QTest::addColumn<QString>("selectedText");
// import installed
- QTest::newRow("on") << SRCDIR "/data/mouseselection_true.qml" << 4 << 9 << "45678";
- QTest::newRow("off") << SRCDIR "/data/mouseselection_false.qml" << 4 << 9 << QString();
- QTest::newRow("default") << SRCDIR "/data/mouseselection_default.qml" << 4 << 9 << QString();
- QTest::newRow("off word selection") << SRCDIR "/data/mouseselection_false_words.qml" << 4 << 9 << QString();
- QTest::newRow("on word selection (4,9)") << SRCDIR "/data/mouseselection_true_words.qml" << 4 << 9 << "0123456789";
- QTest::newRow("on word selection (2,13)") << SRCDIR "/data/mouseselection_true_words.qml" << 2 << 13 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- QTest::newRow("on word selection (2,30)") << SRCDIR "/data/mouseselection_true_words.qml" << 2 << 30 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- QTest::newRow("on word selection (9,13)") << SRCDIR "/data/mouseselection_true_words.qml" << 9 << 13 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- QTest::newRow("on word selection (9,30)") << SRCDIR "/data/mouseselection_true_words.qml" << 9 << 30 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- QTest::newRow("on word selection (13,2)") << SRCDIR "/data/mouseselection_true_words.qml" << 13 << 2 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- QTest::newRow("on word selection (20,2)") << SRCDIR "/data/mouseselection_true_words.qml" << 20 << 2 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- QTest::newRow("on word selection (12,9)") << SRCDIR "/data/mouseselection_true_words.qml" << 12 << 9 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- QTest::newRow("on word selection (30,9)") << SRCDIR "/data/mouseselection_true_words.qml" << 30 << 9 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ QTest::newRow("on") << TESTDATA("mouseselection_true.qml") << 4 << 9 << "45678";
+ QTest::newRow("off") << TESTDATA("mouseselection_false.qml") << 4 << 9 << QString();
+ QTest::newRow("default") << TESTDATA("mouseselection_default.qml") << 4 << 9 << QString();
+ QTest::newRow("off word selection") << TESTDATA("mouseselection_false_words.qml") << 4 << 9 << QString();
+ QTest::newRow("on word selection (4,9)") << TESTDATA("mouseselection_true_words.qml") << 4 << 9 << "0123456789";
+ QTest::newRow("on word selection (2,13)") << TESTDATA("mouseselection_true_words.qml") << 2 << 13 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ QTest::newRow("on word selection (2,30)") << TESTDATA("mouseselection_true_words.qml") << 2 << 30 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ QTest::newRow("on word selection (9,13)") << TESTDATA("mouseselection_true_words.qml") << 9 << 13 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ QTest::newRow("on word selection (9,30)") << TESTDATA("mouseselection_true_words.qml") << 9 << 30 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ QTest::newRow("on word selection (13,2)") << TESTDATA("mouseselection_true_words.qml") << 13 << 2 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ QTest::newRow("on word selection (20,2)") << TESTDATA("mouseselection_true_words.qml") << 20 << 2 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ QTest::newRow("on word selection (12,9)") << TESTDATA("mouseselection_true_words.qml") << 12 << 9 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ QTest::newRow("on word selection (30,9)") << TESTDATA("mouseselection_true_words.qml") << 30 << 9 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
}
void tst_qsgtextedit::mouseSelection()
@@ -1380,7 +1382,7 @@ void tst_qsgtextedit::mouseSelection()
canvas.show();
canvas.requestActivateWindow();
QTest::qWaitForWindowShown(&canvas);
- QTRY_COMPARE(canvas.windowState(), Qt::WindowActive);
+ QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
QVERIFY(canvas.rootObject() != 0);
QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit *>(canvas.rootObject());
@@ -1390,29 +1392,31 @@ void tst_qsgtextedit::mouseSelection()
QPoint p1 = textEditObject->positionToRectangle(from).center().toPoint();
QPoint p2 = textEditObject->positionToRectangle(to).center().toPoint();
QTest::mousePress(&canvas, Qt::LeftButton, 0, p1);
- //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work
- QMouseEvent mv(QEvent::MouseMove, p2, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
- QApplication::sendEvent(&canvas, &mv);
+ QTest::mouseMove(&canvas, p2);
QTest::mouseRelease(&canvas, Qt::LeftButton, 0, p2);
- QCOMPARE(textEditObject->selectedText(), selectedText);
+ QTest::qWait(50);
+ QTRY_COMPARE(textEditObject->selectedText(), selectedText);
// Clicking and shift to clicking between the same points should select the same text.
textEditObject->setCursorPosition(0);
QTest::mouseClick(&canvas, Qt::LeftButton, Qt::NoModifier, p1);
QTest::mouseClick(&canvas, Qt::LeftButton, Qt::ShiftModifier, p2);
- QCOMPARE(textEditObject->selectedText(), selectedText);
+ QTest::qWait(50);
+ if (!selectedText.isEmpty())
+ QEXPECT_FAIL("", "QTBUG-21743", Continue);
+ QTRY_COMPARE(textEditObject->selectedText(), selectedText);
}
void tst_qsgtextedit::dragMouseSelection()
{
- QString qmlfile = SRCDIR "/data/mouseselection_true.qml";
+ QString qmlfile = TESTDATA("mouseselection_true.qml");
QSGView canvas(QUrl::fromLocalFile(qmlfile));
canvas.show();
canvas.requestActivateWindow();
QTest::qWaitForWindowShown(&canvas);
- QTRY_COMPARE(canvas.windowState(), Qt::WindowActive);
+ QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
QVERIFY(canvas.rootObject() != 0);
QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit *>(canvas.rootObject());
@@ -1423,25 +1427,21 @@ void tst_qsgtextedit::dragMouseSelection()
int x2 = 70;
int y = textEditObject->height()/2;
QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y));
- {
- QMouseEvent mv(QEvent::MouseMove, QPoint(x2,y), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
- QApplication::sendEvent(&canvas, &mv);
- }
+ QTest::mouseMove(&canvas, QPoint(x2, y));
QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y));
- QString str1 = textEditObject->selectedText();
- QVERIFY(str1.length() > 3);
+ QTest::qWait(300);
+ QString str1;
+ QTRY_VERIFY((str1 = textEditObject->selectedText()).length() > 3);
// press and drag the current selection.
x1 = 40;
x2 = 100;
QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y));
- {
- QMouseEvent mv(QEvent::MouseMove, QPoint(x2,y), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
- QApplication::sendEvent(&canvas, &mv);
- }
+ QTest::mouseMove(&canvas, QPoint(x2, y));
QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y));
- QString str2 = textEditObject->selectedText();
- QVERIFY(str2.length() > 3);
+ QTest::qWait(300);
+ QString str2;
+ QTRY_VERIFY((str2 = textEditObject->selectedText()).length() > 3);
QVERIFY(str1 != str2); // Verify the second press and drag is a new selection and not the first moved.
}
@@ -1452,9 +1452,9 @@ void tst_qsgtextedit::mouseSelectionMode_data()
QTest::addColumn<bool>("selectWords");
// import installed
- QTest::newRow("SelectWords") << SRCDIR "/data/mouseselectionmode_words.qml" << true;
- QTest::newRow("SelectCharacters") << SRCDIR "/data/mouseselectionmode_characters.qml" << false;
- QTest::newRow("default") << SRCDIR "/data/mouseselectionmode_default.qml" << false;
+ QTest::newRow("SelectWords") << TESTDATA("mouseselectionmode_words.qml") << true;
+ QTest::newRow("SelectCharacters") << TESTDATA("mouseselectionmode_characters.qml") << false;
+ QTest::newRow("default") << TESTDATA("mouseselectionmode_default.qml") << false;
}
void tst_qsgtextedit::mouseSelectionMode()
@@ -1469,7 +1469,7 @@ void tst_qsgtextedit::mouseSelectionMode()
canvas.show();
canvas.requestActivateWindow();
QTest::qWaitForWindowShown(&canvas);
- QTRY_COMPARE(canvas.windowState(), Qt::WindowActive);
+ QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
QVERIFY(canvas.rootObject() != 0);
QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit *>(canvas.rootObject());
@@ -1480,22 +1480,23 @@ void tst_qsgtextedit::mouseSelectionMode()
int x2 = 70;
int y = textEditObject->height()/2;
QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y));
+ QTest::mouseMove(&canvas, QPoint(x2, y));
//QTest::mouseMove(canvas, QPoint(x2,y)); // doesn't work
- QMouseEvent mv(QEvent::MouseMove, QPoint(x2,y), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
- QApplication::sendEvent(&canvas, &mv);
+// QMouseEvent mv(QEvent::MouseMove, QPoint(x2,y), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+// QGuiApplication::sendEvent(&canvas, &mv);
QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y));
QString str = textEditObject->selectedText();
if (selectWords) {
- QCOMPARE(str, text);
+ QTRY_COMPARE(textEditObject->selectedText(), text);
} else {
- QVERIFY(str.length() > 3);
+ QTRY_VERIFY(textEditObject->selectedText().length() > 3);
QVERIFY(str != text);
}
}
void tst_qsgtextedit::inputMethodHints()
{
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/inputmethodhints.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("inputmethodhints.qml")));
canvas.show();
canvas.requestActivateWindow();
@@ -1509,7 +1510,7 @@ void tst_qsgtextedit::inputMethodHints()
void tst_qsgtextedit::positionAt()
{
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/positionAt.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("positionAt.qml")));
QVERIFY(canvas.rootObject() != 0);
canvas.show();
canvas.requestActivateWindow();
@@ -1547,6 +1548,7 @@ void tst_qsgtextedit::positionAt()
int diff = abs(int(width-texteditObject->width()/2));
+ QEXPECT_FAIL("", "QTBUG-21689", Abort);
// some tollerance for different fonts.
#ifdef Q_OS_LINUX
QVERIFY(diff < 2);
@@ -1562,7 +1564,7 @@ void tst_qsgtextedit::positionAt()
texteditObject->setCursorPosition(0);
QInputMethodEvent inputEvent(preeditText, QList<QInputMethodEvent::Attribute>());
- QApplication::sendEvent(&canvas, &inputEvent);
+ QGuiApplication::sendEvent(&canvas, &inputEvent);
// Check all points within the preedit text return the same position.
QCOMPARE(texteditObject->positionAt(0, y0), 0);
@@ -1578,7 +1580,7 @@ void tst_qsgtextedit::positionAt()
void tst_qsgtextedit::cursorDelegate()
{
- QSGView view(QUrl::fromLocalFile(SRCDIR "/data/cursorTest.qml"));
+ QSGView view(QUrl::fromLocalFile(TESTDATA("cursorTest.qml")));
view.show();
view.requestActivateWindow();
QSGTextEdit *textEditObject = view.rootObject()->findChild<QSGTextEdit*>("textEditObject");
@@ -1588,15 +1590,16 @@ void tst_qsgtextedit::cursorDelegate()
textEditObject->setFocus(true);
QSGItem* delegateObject = textEditObject->findChild<QSGItem*>("cursorInstance");
QVERIFY(delegateObject);
+ QCOMPARE(delegateObject->property("localProperty").toString(), QString("Hello"));
//Test Delegate gets moved
- for(int i=0; i<= textEditObject->text().length(); i++){
+ for (int i=0; i<= textEditObject->text().length(); i++) {
textEditObject->setCursorPosition(i);
QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
}
// Clear preedit text;
QInputMethodEvent event;
- QApplication::sendEvent(&view, &event);
+ QGuiApplication::sendEvent(&view, &event);
// Test delegate gets moved on mouse press.
@@ -1604,7 +1607,8 @@ void tst_qsgtextedit::cursorDelegate()
textEditObject->setCursorPosition(0);
const QPoint point1 = textEditObject->positionToRectangle(5).center().toPoint();
QTest::mouseClick(&view, Qt::LeftButton, 0, point1);
- QVERIFY(textEditObject->cursorPosition() != 0);
+ QTest::qWait(50);
+ QTRY_VERIFY(textEditObject->cursorPosition() != 0);
QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
@@ -1613,21 +1617,24 @@ void tst_qsgtextedit::cursorDelegate()
const QPoint point2 = textEditObject->positionToRectangle(10).center().toPoint();
QTest::mousePress(&view, Qt::LeftButton, 0, point1);
QMouseEvent mv(QEvent::MouseMove, point2, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
- QApplication::sendEvent(&view, &mv);
+ QGuiApplication::sendEvent(&view, &mv);
QTest::mouseRelease(&view, Qt::LeftButton, 0, point2);
- QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
+ QTest::qWait(50);
+ QTRY_COMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
textEditObject->setReadOnly(true);
textEditObject->setCursorPosition(0);
QTest::mouseClick(&view, Qt::LeftButton, 0, textEditObject->positionToRectangle(5).center().toPoint());
- QVERIFY(textEditObject->cursorPosition() != 0);
+ QTest::qWait(50);
+ QTRY_VERIFY(textEditObject->cursorPosition() != 0);
QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
textEditObject->setCursorPosition(0);
QTest::mouseClick(&view, Qt::LeftButton, 0, textEditObject->positionToRectangle(5).center().toPoint());
- QVERIFY(textEditObject->cursorPosition() != 0);
+ QTest::qWait(50);
+ QTRY_VERIFY(textEditObject->cursorPosition() != 0);
QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
@@ -1641,12 +1648,11 @@ void tst_qsgtextedit::cursorDelegate()
void tst_qsgtextedit::cursorVisible()
{
- QSGView view(QUrl::fromLocalFile(SRCDIR "/data/cursorVisible.qml"));
+ QSGView view(QUrl::fromLocalFile(TESTDATA("cursorVisible.qml")));
view.show();
view.requestActivateWindow();
QTest::qWaitForWindowShown(&view);
- QTRY_COMPARE(view.windowState(), Qt::WindowActive);
- view.requestActivateWindow();
+ QTRY_COMPARE(&view, qGuiApp->focusWindow());
QSGTextEdit edit;
QSignalSpy spy(&edit, SIGNAL(cursorVisibleChanged(bool)));
@@ -1677,6 +1683,7 @@ void tst_qsgtextedit::cursorVisible()
QCOMPARE(edit.isCursorVisible(), true);
QCOMPARE(spy.count(), 5);
+ QEXPECT_FAIL("", "Most likely a side-effect of QTBUG-21489", Abort);
view.setWindowState(Qt::WindowNoState);
QCOMPARE(edit.isCursorVisible(), false);
QCOMPARE(spy.count(), 6);
@@ -1688,16 +1695,18 @@ void tst_qsgtextedit::cursorVisible()
// on mac, setActiveWindow(0) on mac does not deactivate the current application
// (you have to switch to a different app or hide the current app to trigger this)
#if !defined(Q_WS_MAC)
- QApplication::setActiveWindow(0);
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(0));
- QCOMPARE(edit.isCursorVisible(), false);
- QCOMPARE(spy.count(), 8);
-
- view.requestActivateWindow();
- QTest::qWaitForWindowShown(&view);
- QTRY_COMPARE(view.windowState(), Qt::WindowActive);
- QCOMPARE(edit.isCursorVisible(), true);
- QCOMPARE(spy.count(), 9);
+ // on mac, setActiveWindow(0) on mac does not deactivate the current application
+ // (you have to switch to a different app or hide the current app to trigger this)
+// QApplication::setActiveWindow(0);
+// QTRY_COMPARE(QApplication::focusWindow(), static_cast<QWidget *>(0));
+// QCOMPARE(edit.isCursorVisible(), false);
+// QCOMPARE(spy.count(), 8);
+
+// view.requestActivateWindow();
+// QTest::qWaitForWindowShown(&view);
+// QTRY_COMPARE(view.windowState(), Qt::WindowActive);
+// QCOMPARE(edit.isCursorVisible(), true);
+// QCOMPARE(spy.count(), 9);
#endif
}
@@ -1718,9 +1727,9 @@ void tst_qsgtextedit::delegateLoading()
QFETCH(QString, error);
TestHTTPServer server(42332);
- server.serveDirectory(SRCDIR "/data/httpfail", TestHTTPServer::Disconnect);
- server.serveDirectory(SRCDIR "/data/httpslow", TestHTTPServer::Delay);
- server.serveDirectory(SRCDIR "/data/http");
+ server.serveDirectory(TESTDATA("httpfail"), TestHTTPServer::Disconnect);
+ server.serveDirectory(TESTDATA("httpslow"), TestHTTPServer::Delay);
+ server.serveDirectory(TESTDATA("http"));
QSGView view(QUrl(QLatin1String("http://localhost:42332/") + qmlfile));
view.show();
@@ -1759,7 +1768,7 @@ the extent of the text, then they should ignore the keys.
*/
void tst_qsgtextedit::navigation()
{
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/navigation.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml")));
canvas.show();
canvas.requestActivateWindow();
@@ -1791,7 +1800,7 @@ void tst_qsgtextedit::copyAndPaste() {
if (status == noErr)
CFRelease(pasteboard);
else
- QSKIP("This machine doesn't support the clipboard", SkipAll);
+ QSKIP("This machine doesn't support the clipboard");
}
#endif
@@ -1844,7 +1853,7 @@ void tst_qsgtextedit::copyAndPaste() {
void tst_qsgtextedit::canPaste() {
#ifndef QT_NO_CLIPBOARD
- QApplication::clipboard()->setText("Some text");
+ QGuiApplication::clipboard()->setText("Some text");
QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"Hello world!\" }";
QDeclarativeComponent textEditComponent(&engine);
@@ -1862,7 +1871,7 @@ void tst_qsgtextedit::canPaste() {
void tst_qsgtextedit::canPasteEmpty() {
#ifndef QT_NO_CLIPBOARD
- QApplication::clipboard()->clear();
+ QGuiApplication::clipboard()->clear();
QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"Hello world!\" }";
QDeclarativeComponent textEditComponent(&engine);
@@ -1879,7 +1888,7 @@ void tst_qsgtextedit::canPasteEmpty() {
void tst_qsgtextedit::readOnly()
{
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/readOnly.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("readOnly.qml")));
canvas.show();
canvas.requestActivateWindow();
@@ -1891,7 +1900,7 @@ void tst_qsgtextedit::readOnly()
QTRY_VERIFY(edit->hasActiveFocus() == true);
QVERIFY(edit->isReadOnly() == true);
QString initial = edit->text();
- for(int k=Qt::Key_0; k<=Qt::Key_Z; k++)
+ for (int k=Qt::Key_0; k<=Qt::Key_Z; k++)
simulateKey(&canvas, k);
simulateKey(&canvas, Qt::Key_Return);
simulateKey(&canvas, Qt::Key_Space);
@@ -1909,14 +1918,16 @@ void tst_qsgtextedit::simulateKey(QSGView *view, int key, Qt::KeyboardModifiers
QKeyEvent press(QKeyEvent::KeyPress, key, modifiers);
QKeyEvent release(QKeyEvent::KeyRelease, key, modifiers);
- QApplication::sendEvent(view, &press);
- QApplication::sendEvent(view, &release);
+ QGuiApplication::sendEvent(view, &press);
+ QGuiApplication::sendEvent(view, &release);
}
+
+#ifndef QTBUG_21691
class MyInputContext : public QInputContext
{
public:
- MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false), updateReceived(false), eventType(QEvent::None) {}
+ MyInputContext() : updateReceived(false), eventType(QEvent::None) {}
~MyInputContext() {}
QString identifierName() { return QString(); }
@@ -1926,16 +1937,6 @@ public:
bool isComposing() const { return false; }
- bool filterEvent( const QEvent *event )
- {
- if (event->type() == QEvent::RequestSoftwareInputPanel)
- openInputPanelReceived = true;
- if (event->type() == QEvent::CloseSoftwareInputPanel)
- closeInputPanelReceived = true;
- return QInputContext::filterEvent(event);
-
- }
-
void update() { updateReceived = true; }
void sendPreeditText(const QString &text, int cursor)
@@ -1959,8 +1960,6 @@ public:
eventModifiers = event->modifiers();
}
- bool openInputPanelReceived;
- bool closeInputPanelReceived;
bool updateReceived;
int cursor;
QEvent::Type eventType;
@@ -1970,14 +1969,15 @@ public:
Qt::MouseButtons eventButtons;
Qt::KeyboardModifiers eventModifiers;
};
+#endif
void tst_qsgtextedit::textInput()
{
- QSGView view(QUrl::fromLocalFile(SRCDIR "/data/inputMethodEvent.qml"));
+ QSGView view(QUrl::fromLocalFile(TESTDATA("inputMethodEvent.qml")));
view.show();
view.requestActivateWindow();
QTest::qWaitForWindowShown(&view);
- QTRY_COMPARE(view.windowState(), Qt::WindowActive);
+ QTRY_COMPARE(&view, qGuiApp->focusWindow());
QSGTextEdit *edit = qobject_cast<QSGTextEdit *>(view.rootObject());
QVERIFY(edit);
QVERIFY(edit->hasActiveFocus() == true);
@@ -1985,7 +1985,8 @@ void tst_qsgtextedit::textInput()
// test that input method event is committed
QInputMethodEvent event;
event.setCommitString( "Hello world!", 0, 0);
- QApplication::sendEvent(&view, &event);
+ QGuiApplication::sendEvent(&view, &event);
+ QEXPECT_FAIL("", "QTBUG-21689", Abort);
QCOMPARE(edit->text(), QString("Hello world!"));
// QTBUG-12339
@@ -1994,194 +1995,97 @@ void tst_qsgtextedit::textInput()
QCOMPARE(editPrivate->text, QString("Hello world!"));
}
-void tst_qsgtextedit::openInputPanelOnClick()
+void tst_qsgtextedit::openInputPanel()
{
- QSGView view(QUrl::fromLocalFile(SRCDIR "/data/openInputPanel.qml"));
- MyInputContext ic;
- // QSGCanvas won't set the Qt::WA_InputMethodEnabled flag unless a suitable item has focus
- // and QWidget won't allow an input context to be set when the flag is not set.
- view.setAttribute(Qt::WA_InputMethodEnabled, true);
- view.setInputContext(&ic);
- view.setAttribute(Qt::WA_InputMethodEnabled, false);
+ QSGView view(QUrl::fromLocalFile(TESTDATA("openInputPanel.qml")));
view.show();
-
- qApp->setAutoSipEnabled(true);
view.requestActivateWindow();
QTest::qWaitForWindowShown(&view);
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
+ QTRY_COMPARE(&view, qGuiApp->focusWindow());
QSGTextEdit *edit = qobject_cast<QSGTextEdit *>(view.rootObject());
QVERIFY(edit);
- QSignalSpy focusOnPressSpy(edit, SIGNAL(activeFocusOnPressChanged(bool)));
-
- QSGItemPrivate* pri = QSGItemPrivate::get(edit);
- QSGTextEditPrivate *editPrivate = static_cast<QSGTextEditPrivate*>(pri);
-
- // input panel on click
- editPrivate->showInputPanelOnFocus = false;
-
- QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel(
- view.style()->styleHint(QStyle::SH_RequestSoftwareInputPanel));
- QTest::mouseClick(&view, Qt::LeftButton, 0, edit->mapToScene(QPointF(0,0)).toPoint());
- QApplication::processEvents();
- if (behavior == QStyle::RSIP_OnMouseClickAndAlreadyFocused) {
- QCOMPARE(ic.openInputPanelReceived, false);
- QTest::mouseClick(&view, Qt::LeftButton, 0, edit->mapToScene(QPointF(0,0)).toPoint());
- QApplication::processEvents();
- QCOMPARE(ic.openInputPanelReceived, true);
- } else if (behavior == QStyle::RSIP_OnMouseClick) {
- QCOMPARE(ic.openInputPanelReceived, true);
- }
- ic.openInputPanelReceived = false;
- // focus should not cause input panels to open or close
- edit->setFocus(false);
- edit->setFocus(true);
- edit->setFocus(false);
- edit->setFocus(true);
- edit->setFocus(false);
- QApplication::processEvents();
- QCOMPARE(ic.openInputPanelReceived, false);
- QCOMPARE(ic.closeInputPanelReceived, false);
-}
-
-void tst_qsgtextedit::openInputPanelOnFocus()
-{
- QSGView view(QUrl::fromLocalFile(SRCDIR "/data/openInputPanel.qml"));
- MyInputContext ic;
- // QSGCanvas won't set the Qt::WA_InputMethodEnabled flag unless a suitable item has focus
- // and QWidget won't allow an input context to be set when the flag is not set.
- view.setAttribute(Qt::WA_InputMethodEnabled, true);
- view.setInputContext(&ic);
- view.setAttribute(Qt::WA_InputMethodEnabled, false);
- view.show();
-
- qApp->setAutoSipEnabled(true);
- view.requestActivateWindow();
- QTest::qWaitForWindowShown(&view);
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
-
- QSGTextEdit *edit = qobject_cast<QSGTextEdit *>(view.rootObject());
- QVERIFY(edit);
- QSignalSpy focusOnPressSpy(edit, SIGNAL(activeFocusOnPressChanged(bool)));
-
- QSGItemPrivate* pri = QSGItemPrivate::get(edit);
- QSGTextEditPrivate *editPrivate = static_cast<QSGTextEditPrivate*>(pri);
- editPrivate->showInputPanelOnFocus = true;
-
- // test default values
+ // check default values
QVERIFY(edit->focusOnPress());
- QCOMPARE(ic.openInputPanelReceived, false);
- QCOMPARE(ic.closeInputPanelReceived, false);
-
- // focus on press, input panel on focus
- QTest::mousePress(&view, Qt::LeftButton, 0, edit->mapToScene(QPointF(0,0)).toPoint());
- QApplication::processEvents();
+ QVERIFY(!edit->hasActiveFocus());
+ qDebug() << &edit << qApp->inputPanel()->inputItem();
+ QCOMPARE(qApp->inputPanel()->inputItem(), static_cast<QObject*>(0));
+ QEXPECT_FAIL("", "QTBUG-21946", Abort);
+ QCOMPARE(qApp->inputPanel()->visible(), false);
+
+ // input panel should open on focus
+ QPoint centerPoint(view.width()/2, view.height()/2);
+ Qt::KeyboardModifiers noModifiers = 0;
+ QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint);
+ QGuiApplication::processEvents();
QVERIFY(edit->hasActiveFocus());
- QCOMPARE(ic.openInputPanelReceived, true);
- ic.openInputPanelReceived = false;
-
- // no events on release
- QTest::mouseRelease(&view, Qt::LeftButton, 0, edit->mapToScene(QPointF(0,0)).toPoint());
- QCOMPARE(ic.openInputPanelReceived, false);
- ic.openInputPanelReceived = false;
+ QCOMPARE(qApp->inputPanel()->inputItem(), edit);
+ QCOMPARE(qApp->inputPanel()->visible(), true);
+ QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint);
- // if already focused, input panel can be opened on press
+ // input panel should be re-opened when pressing already focused TextEdit
+ qApp->inputPanel()->hide();
+ QCOMPARE(qApp->inputPanel()->visible(), false);
QVERIFY(edit->hasActiveFocus());
- QTest::mousePress(&view, Qt::LeftButton, 0, edit->mapToScene(QPointF(0,0)).toPoint());
- QApplication::processEvents();
- QCOMPARE(ic.openInputPanelReceived, true);
- ic.openInputPanelReceived = false;
+ QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint);
+ QGuiApplication::processEvents();
+ QCOMPARE(qApp->inputPanel()->visible(), true);
+ QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint);
- // input method should stay enabled if focus
- // is lost to an item that also accepts inputs
+ // input panel should stay visible if focus is lost to another text editor
+ QSignalSpy inputPanelVisibilitySpy(qApp->inputPanel(), SIGNAL(visibleChanged()));
QSGTextEdit anotherEdit;
anotherEdit.setParentItem(view.rootObject());
anotherEdit.setFocus(true);
- QApplication::processEvents();
- QCOMPARE(ic.openInputPanelReceived, true);
- ic.openInputPanelReceived = false;
- QCOMPARE(view.inputContext(), (QInputContext*)&ic);
- QVERIFY(view.testAttribute(Qt::WA_InputMethodEnabled));
-
- // input method should be disabled if focus
- // is lost to an item that doesn't accept inputs
+ QCOMPARE(qApp->inputPanel()->visible(), true);
+ QCOMPARE(qApp->inputPanel()->inputItem(), qobject_cast<QObject*>(&anotherEdit));
+ QCOMPARE(inputPanelVisibilitySpy.count(), 0);
+
+ anotherEdit.setFocus(false);
+ QCOMPARE(qApp->inputPanel()->inputItem(), static_cast<QObject*>(0));
+ QCOMPARE(view.activeFocusItem(), view.rootItem());
+ anotherEdit.setFocus(true);
+
+ // input item should be null if focus is lost to an item that doesn't accept inputs
QSGItem item;
item.setParentItem(view.rootObject());
item.setFocus(true);
- QApplication::processEvents();
- QCOMPARE(ic.openInputPanelReceived, false);
- QVERIFY(view.inputContext() == 0);
- QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled));
+ QCOMPARE(qApp->inputPanel()->inputItem(), static_cast<QObject*>(0));
+ QCOMPARE(view.activeFocusItem(), &item);
- // no automatic input panel events should
- // be sent if activeFocusOnPress is false
- edit->setFocusOnPress(false);
- QCOMPARE(focusOnPressSpy.count(),1);
- edit->setFocusOnPress(false);
- QCOMPARE(focusOnPressSpy.count(),1);
- edit->setFocus(false);
+ qApp->inputPanel()->hide();
+
+ // input panel should not be opened if TextEdit is read only
+ edit->setReadOnly(true);
edit->setFocus(true);
- QTest::mousePress(&view, Qt::LeftButton, 0, edit->mapToScene(QPointF(0,0)).toPoint());
- QTest::mouseRelease(&view, Qt::LeftButton, 0, edit->mapToScene(QPointF(0,0)).toPoint());
- QApplication::processEvents();
- QCOMPARE(ic.openInputPanelReceived, false);
- QCOMPARE(ic.closeInputPanelReceived, false);
-
- // one show input panel event should
- // be set when openSoftwareInputPanel is called
- edit->openSoftwareInputPanel();
- QCOMPARE(ic.openInputPanelReceived, true);
- QCOMPARE(ic.closeInputPanelReceived, false);
- ic.openInputPanelReceived = false;
+ QCOMPARE(qApp->inputPanel()->visible(), false);
+ QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint);
+ QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint);
+ QGuiApplication::processEvents();
+ QCOMPARE(qApp->inputPanel()->visible(), false);
- // one close input panel event should
- // be sent when closeSoftwareInputPanel is called
- edit->closeSoftwareInputPanel();
- QCOMPARE(ic.openInputPanelReceived, false);
- QCOMPARE(ic.closeInputPanelReceived, true);
- ic.closeInputPanelReceived = false;
-
- // set activeFocusOnPress back to true
- edit->setFocusOnPress(true);
- QCOMPARE(focusOnPressSpy.count(),2);
- edit->setFocusOnPress(true);
- QCOMPARE(focusOnPressSpy.count(),2);
+ // input panel should not be opened if focusOnPress is set to false
+ edit->setFocusOnPress(false);
edit->setFocus(false);
- QApplication::processEvents();
- QCOMPARE(ic.openInputPanelReceived, false);
- QCOMPARE(ic.closeInputPanelReceived, false);
- ic.closeInputPanelReceived = false;
-
- // input panel should not re-open
- // if focus has already been set
- edit->setFocus(true);
- QCOMPARE(ic.openInputPanelReceived, true);
- ic.openInputPanelReceived = false;
edit->setFocus(true);
- QCOMPARE(ic.openInputPanelReceived, false);
+ QCOMPARE(qApp->inputPanel()->visible(), false);
+ QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint);
+ QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint);
+ QCOMPARE(qApp->inputPanel()->visible(), false);
- // input method should be disabled
- // if TextEdit loses focus
- edit->setFocus(false);
- QApplication::processEvents();
- QVERIFY(view.inputContext() == 0);
- QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled));
+ // input panel should open when openSoftwareInputPanel is called
+ edit->openSoftwareInputPanel();
+ QCOMPARE(qApp->inputPanel()->visible(), true);
- // input method should not be enabled
- // if TextEdit is read only.
- edit->setReadOnly(true);
- ic.openInputPanelReceived = false;
- edit->setFocus(true);
- QApplication::processEvents();
- QCOMPARE(ic.openInputPanelReceived, false);
- QVERIFY(view.inputContext() == 0);
- QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled));
+ // input panel should close when closeSoftwareInputPanel is called
+ edit->closeSoftwareInputPanel();
+ QCOMPARE(qApp->inputPanel()->visible(), false);
}
void tst_qsgtextedit::geometrySignals()
{
- QDeclarativeComponent component(&engine, SRCDIR "/data/geometrySignals.qml");
+ QDeclarativeComponent component(&engine, TESTDATA("geometrySignals.qml"));
QObject *o = component.create();
QVERIFY(o);
QCOMPARE(o->property("bindingWidth").toInt(), 400);
@@ -2202,7 +2106,7 @@ void tst_qsgtextedit::pastingRichText_QTBUG_14003()
QMimeData *mData = new QMimeData;
mData->setHtml("<font color=\"red\">Hello</font>");
- QApplication::clipboard()->setMimeData(mData);
+ QGuiApplication::clipboard()->setMimeData(mData);
obj->paste();
QTRY_VERIFY(obj->text() == "");
@@ -2290,35 +2194,33 @@ void tst_qsgtextedit::testQtQuick11Attributes_data()
void tst_qsgtextedit::preeditMicroFocus()
{
+#ifdef QTBUG_21691
+ QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
+ QVERIFY(false);
+#else
QString preeditText = "super";
- QSGView view(QUrl::fromLocalFile(SRCDIR "/data/inputMethodEvent.qml"));
- MyInputContext ic;
- // QSGCanvas won't set the Qt::WA_InputMethodEnabled flag unless a suitable item has focus
- // and QWidget won't allow an input context to be set when the flag is not set.
- view.setAttribute(Qt::WA_InputMethodEnabled, true);
- view.setInputContext(&ic);
- view.setAttribute(Qt::WA_InputMethodEnabled, false);
+ QSGView view(QUrl::fromLocalFile(TESTDATA("inputMethodEvent.qml")));
view.show();
view.requestActivateWindow();
QTest::qWaitForWindowShown(&view);
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
+ QTRY_COMPARE(&view, qGuiApp->focusWindow());
QSGTextEdit *edit = qobject_cast<QSGTextEdit *>(view.rootObject());
QVERIFY(edit);
QSignalSpy cursorRectangleSpy(edit, SIGNAL(cursorRectangleChanged()));
QRect currentRect;
- QRect previousRect = edit->inputMethodQuery(Qt::ImMicroFocus).toRect();
+ QRect previousRect = edit->inputMethodQuery(Qt::ImCursorRectangle).toRect();
// Verify that the micro focus rect is positioned the same for position 0 as
// it would be if there was no preedit text.
ic.updateReceived = false;
ic.sendPreeditText(preeditText, 0);
- currentRect = edit->inputMethodQuery(Qt::ImMicroFocus).toRect();
+ currentRect = edit->inputMethodQuery(Qt::ImCursorRectangle).toRect();
QCOMPARE(currentRect, previousRect);
-#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
QCOMPARE(ic.updateReceived, false); // The cursor position hasn't changed.
#endif
QCOMPARE(cursorRectangleSpy.count(), 0);
@@ -2328,9 +2230,9 @@ void tst_qsgtextedit::preeditMicroFocus()
for (int i = 1; i <= 5; ++i) {
ic.updateReceived = false;
ic.sendPreeditText(preeditText, i);
- currentRect = edit->inputMethodQuery(Qt::ImMicroFocus).toRect();
+ currentRect = edit->inputMethodQuery(Qt::ImCursorRectangle).toRect();
QVERIFY(previousRect.left() < currentRect.left());
-#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
QCOMPARE(ic.updateReceived, true);
#endif
QVERIFY(cursorRectangleSpy.count() > 0);
@@ -2343,19 +2245,25 @@ void tst_qsgtextedit::preeditMicroFocus()
ic.sendPreeditText(preeditText, 0);
ic.updateReceived = false;
ic.sendEvent(QInputMethodEvent(preeditText, QList<QInputMethodEvent::Attribute>()));
- currentRect = edit->inputMethodQuery(Qt::ImMicroFocus).toRect();
+ currentRect = edit->inputMethodQuery(Qt::ImCursorRectangle).toRect();
QCOMPARE(currentRect, previousRect);
-#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
QCOMPARE(ic.updateReceived, true);
#endif
QVERIFY(cursorRectangleSpy.count() > 0);
+#endif
}
void tst_qsgtextedit::inputContextMouseHandler()
{
+
+#ifdef QTBUG_21691
+ QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
+ QVERIFY(false);
+#else
QString text = "supercalifragisiticexpialidocious!";
- QSGView view(QUrl::fromLocalFile(SRCDIR "/data/inputContext.qml"));
+ QSGView view(QUrl::fromLocalFile(TESTDATA("inputContext.qml")));
MyInputContext ic;
// QSGCanvas won't set the Qt::WA_InputMethodEnabled flag unless a suitable item has focus
// and QWidget won't allow an input context to be set when the flag is not set.
@@ -2366,7 +2274,7 @@ void tst_qsgtextedit::inputContextMouseHandler()
view.requestActivateWindow();
QTest::qWaitForWindowShown(&view);
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
+ QTRY_COMPARE(&view, qGuiApp->focusWindow());
QSGTextEdit *edit = qobject_cast<QSGTextEdit *>(view.rootObject());
QVERIFY(edit);
edit->setCursorPosition(12);
@@ -2404,11 +2312,11 @@ void tst_qsgtextedit::inputContextMouseHandler()
ic.eventType = QEvent::None;
{ QMouseEvent mv(QEvent::MouseMove, position8, globalposition8, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
- QApplication::sendEvent(&view, &mv); }
+ QGuiApplication::sendEvent(&view, &mv); }
QCOMPARE(ic.eventType, QEvent::None);
{ QMouseEvent mv(QEvent::MouseMove, position27, globalposition27, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
- QApplication::sendEvent(&view, &mv); }
+ QGuiApplication::sendEvent(&view, &mv); }
QCOMPARE(ic.eventType, QEvent::MouseMove);
QCOMPARE(ic.eventPosition, position27);
QCOMPARE(ic.eventGlobalPosition, globalposition27);
@@ -2446,7 +2354,7 @@ void tst_qsgtextedit::inputContextMouseHandler()
ic.eventType = QEvent::None;
{ QMouseEvent mv(QEvent::MouseMove, position20, globalposition20, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
- QApplication::sendEvent(&view, &mv); }
+ QGuiApplication::sendEvent(&view, &mv); }
QCOMPARE(ic.eventType, QEvent::MouseMove);
QCOMPARE(ic.eventPosition, position20);
QCOMPARE(ic.eventGlobalPosition, globalposition20);
@@ -2456,7 +2364,7 @@ void tst_qsgtextedit::inputContextMouseHandler()
ic.eventType = QEvent::None;
{ QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
- QApplication::sendEvent(&view, &mv); }
+ QGuiApplication::sendEvent(&view, &mv); }
QCOMPARE(ic.eventType, QEvent::None);
QTest::mouseRelease(&view, Qt::RightButton, Qt::ControlModifier, position2);
@@ -2467,17 +2375,18 @@ void tst_qsgtextedit::inputContextMouseHandler()
QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
QVERIFY(ic.cursor < 0);
ic.eventType = QEvent::None;
+#endif
}
void tst_qsgtextedit::inputMethodComposing()
{
QString text = "supercalifragisiticexpialidocious!";
- QSGView view(QUrl::fromLocalFile(SRCDIR "/data/inputContext.qml"));
+ QSGView view(QUrl::fromLocalFile(TESTDATA("inputContext.qml")));
view.show();
view.requestActivateWindow();
QTest::qWaitForWindowShown(&view);
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
+ QTRY_COMPARE(&view, qGuiApp->focusWindow());
QSGTextEdit *edit = qobject_cast<QSGTextEdit *>(view.rootObject());
QVERIFY(edit);
QSignalSpy spy(edit, SIGNAL(inputMethodComposingChanged()));
@@ -2487,20 +2396,21 @@ void tst_qsgtextedit::inputMethodComposing()
{
QInputMethodEvent event(text.mid(3), QList<QInputMethodEvent::Attribute>());
- QApplication::sendEvent(&view, &event);
+ QGuiApplication::sendEvent(edit, &event);
}
+
QCOMPARE(edit->isInputMethodComposing(), true);
QCOMPARE(spy.count(), 1);
{
QInputMethodEvent event(text.mid(12), QList<QInputMethodEvent::Attribute>());
- QApplication::sendEvent(&view, &event);
+ QGuiApplication::sendEvent(edit, &event);
}
QCOMPARE(spy.count(), 1);
{
QInputMethodEvent event;
- QApplication::sendEvent(&view, &event);
+ QGuiApplication::sendEvent(edit, &event);
}
QCOMPARE(edit->isInputMethodComposing(), false);
QCOMPARE(spy.count(), 2);
@@ -2508,10 +2418,9 @@ void tst_qsgtextedit::inputMethodComposing()
void tst_qsgtextedit::cursorRectangleSize()
{
- QSGView *canvas = new QSGView(QUrl::fromLocalFile(SRCDIR "/data/CursorRect.qml"));
+ QSGView *canvas = new QSGView(QUrl::fromLocalFile(TESTDATA("CursorRect.qml")));
QVERIFY(canvas->rootObject() != 0);
canvas->show();
- canvas->setFocus();
canvas->requestActivateWindow();
QTest::qWaitForWindowShown(canvas);
@@ -2519,8 +2428,11 @@ void tst_qsgtextedit::cursorRectangleSize()
QVERIFY(textEdit != 0);
textEdit->setFocus(Qt::OtherFocusReason);
QRectF cursorRect = textEdit->positionToRectangle(textEdit->cursorPosition());
- QRectF microFocusFromScene = canvas->inputMethodQuery(Qt::ImMicroFocus).toRectF();
- QRectF microFocusFromApp= QApplication::focusWidget()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
+ QRectF microFocusFromScene = canvas->inputMethodQuery(Qt::ImCursorRectangle).toRectF();
+ QInputMethodQueryEvent event(Qt::ImCursorRectangle);
+ qApp->sendEvent(qApp->inputPanel()->inputItem(), &event);
+
+ QRectF microFocusFromApp = event.value(Qt::ImCursorRectangle).toRectF();
QCOMPARE(microFocusFromScene.size(), cursorRect.size());
QCOMPARE(microFocusFromApp.size(), cursorRect.size());
@@ -2528,6 +2440,28 @@ void tst_qsgtextedit::cursorRectangleSize()
delete canvas;
}
+void tst_qsgtextedit::emptytags_QTBUG_22058()
+{
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("qtbug-22058.qml")));
+ QVERIFY(canvas.rootObject() != 0);
+
+ canvas.show();
+ canvas.requestActivateWindow();
+ QTest::qWaitForWindowShown(&canvas);
+ QSGTextEdit *input = qobject_cast<QSGTextEdit *>(qvariant_cast<QObject *>(canvas.rootObject()->property("inputField")));
+ QVERIFY(input->hasActiveFocus());
+
+ QInputMethodEvent event("", QList<QInputMethodEvent::Attribute>());
+ event.setCommitString("<b>Bold<");
+ QGuiApplication::sendEvent(input, &event);
+ QCOMPARE(input->text(), QString("<b>Bold<"));
+ event.setCommitString(">");
+ QEXPECT_FAIL("", "Entering empty tags into a TextEdit asserts - QTBUG-22058", Abort);
+ QVERIFY(false);
+ QGuiApplication::sendEvent(input, &event);
+ QCOMPARE(input->text(), QString("<b>Bold<>"));
+}
+
QTEST_MAIN(tst_qsgtextedit)
#include "tst_qsgtextedit.moc"
diff --git a/tests/auto/declarative/qsgtextinput/data/cursorTest.qml b/tests/auto/declarative/qsgtextinput/data/cursorTest.qml
index 01858fba77..71a420ee7c 100644
--- a/tests/auto/declarative/qsgtextinput/data/cursorTest.qml
+++ b/tests/auto/declarative/qsgtextinput/data/cursorTest.qml
@@ -1,8 +1,9 @@
import QtQuick 2.0
-Rectangle { width: 300; height: 300; color: "white"
+Rectangle { id:rect; width: 300; height: 300; color: "white"
+ property string contextualProperty: "Hello"
TextInput { text: "Hello world!"; id: textInputObject; objectName: "textInputObject"
- resources: [ Component { id:cursor; Item { id:cursorInstance; objectName: "cursorInstance";} } ]
+ resources: [ Component { id:cursor; Item { id:cursorInstance; objectName: "cursorInstance"; property string localProperty: contextualProperty } } ]
cursorDelegate: cursor
}
}
diff --git a/tests/auto/declarative/qsgtextinput/data/openInputPanel.qml b/tests/auto/declarative/qsgtextinput/data/openInputPanel.qml
index 3924b2ab99..ca5cb263aa 100644
--- a/tests/auto/declarative/qsgtextinput/data/openInputPanel.qml
+++ b/tests/auto/declarative/qsgtextinput/data/openInputPanel.qml
@@ -1,6 +1,7 @@
import QtQuick 2.0
TextInput {
+ width: 100; height: 100
text: "Hello world"
focus: false
}
diff --git a/tests/auto/declarative/qsgtextinput/qsgtextinput.pro b/tests/auto/declarative/qsgtextinput/qsgtextinput.pro
index fceef18487..1c988be880 100644
--- a/tests/auto/declarative/qsgtextinput/qsgtextinput.pro
+++ b/tests/auto/declarative/qsgtextinput/qsgtextinput.pro
@@ -1,16 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui
+CONFIG += testcase
+TARGET = tst_qsgtextinput
macx:CONFIG -= app_bundle
SOURCES += tst_qsgtextinput.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
-QT += core-private gui-private v8-private declarative-private
-QT += opengl-private
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
diff --git a/tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp b/tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp
index dafed15bf4..0a733b5618 100644
--- a/tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp
+++ b/tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp
@@ -40,35 +40,35 @@
****************************************************************************/
#include <qtest.h>
#include <QtTest/QSignalSpy>
-#include "../../../shared/util.h"
+#include "../shared/util.h"
#include <QtDeclarative/qdeclarativeengine.h>
#include <QFile>
#include <QtDeclarative/qsgview.h>
+#include <QtGui/qguiapplication.h>
+#include <QInputPanel>
#include <private/qsgtextinput_p.h>
#include <private/qsgtextinput_p_p.h>
#include <QDebug>
#include <QDir>
#include <QStyle>
#include <QInputContext>
-#include <QtWidgets/5.0.0/QtWidgets/private/qapplication_p.h>
#include <private/qsgdistancefieldglyphcache_p.h>
#include <QtOpenGL/QGLShaderProgram>
#include <math.h>
#include "qplatformdefs.h"
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
Q_DECLARE_METATYPE(QSGTextInput::SelectionMode)
DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
+#define QTBUG_21691
+#define QTBUG_21691_MESSAGE "QTBUG-21691: The test needs to be rewritten to not use QInputContext"
+
+
QString createExpectedFileIfNotFound(const QString& filebasename, const QImage& actual)
{
// XXX This will be replaced by some clever persistent platform image store.
- QString persistent_dir = SRCDIR "/data";
+ QString persistent_dir = TESTDATA("");
QString arch = "unknown-architecture"; // QTest needs to help with this.
QString expectfile = persistent_dir + QDir::separator() + filebasename + "-" + arch + ".png";
@@ -105,6 +105,7 @@ private slots:
void dragMouseSelection();
void mouseSelectionMode_data();
void mouseSelectionMode();
+ void tripleClickSelectsAll();
void horizontalAlignment_data();
void horizontalAlignment();
@@ -128,8 +129,7 @@ private slots:
void canPaste();
void readOnly();
- void openInputPanelOnClick();
- void openInputPanelOnFocus();
+ void openInputPanel();
void setHAlignClearCache();
void focusOutClearSelection();
@@ -275,7 +275,7 @@ void tst_qsgtextinput::width()
void tst_qsgtextinput::font()
{
//test size, then bold, then italic, then family
- {
+ {
QString componentStr = "import QtQuick 2.0\nTextInput { font.pointSize: 40; text: \"Hello World\" }";
QDeclarativeComponent textinputComponent(&engine);
textinputComponent.setData(componentStr.toLatin1(), QUrl());
@@ -289,7 +289,7 @@ void tst_qsgtextinput::font()
delete textinputObject;
}
- {
+ {
QString componentStr = "import QtQuick 2.0\nTextInput { font.bold: true; text: \"Hello World\" }";
QDeclarativeComponent textinputComponent(&engine);
textinputComponent.setData(componentStr.toLatin1(), QUrl());
@@ -302,7 +302,7 @@ void tst_qsgtextinput::font()
delete textinputObject;
}
- {
+ {
QString componentStr = "import QtQuick 2.0\nTextInput { font.italic: true; text: \"Hello World\" }";
QDeclarativeComponent textinputComponent(&engine);
textinputComponent.setData(componentStr.toLatin1(), QUrl());
@@ -314,8 +314,8 @@ void tst_qsgtextinput::font()
delete textinputObject;
}
-
- {
+
+ {
QString componentStr = "import QtQuick 2.0\nTextInput { font.family: \"Helvetica\"; text: \"Hello World\" }";
QDeclarativeComponent textinputComponent(&engine);
textinputComponent.setData(componentStr.toLatin1(), QUrl());
@@ -329,7 +329,7 @@ void tst_qsgtextinput::font()
delete textinputObject;
}
- {
+ {
QString componentStr = "import QtQuick 2.0\nTextInput { font.family: \"\"; text: \"Hello World\" }";
QDeclarativeComponent textinputComponent(&engine);
textinputComponent.setData(componentStr.toLatin1(), QUrl());
@@ -346,7 +346,7 @@ void tst_qsgtextinput::color()
{
//test color
for (int i = 0; i < colorStrings.size(); i++)
- {
+ {
QString componentStr = "import QtQuick 2.0\nTextInput { color: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
QDeclarativeComponent textinputComponent(&engine);
textinputComponent.setData(componentStr.toLatin1(), QUrl());
@@ -372,7 +372,7 @@ void tst_qsgtextinput::color()
//test selected text color
for (int i = 0; i < colorStrings.size(); i++)
- {
+ {
QString componentStr = "import QtQuick 2.0\nTextInput { selectedTextColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
QDeclarativeComponent textinputComponent(&engine);
textinputComponent.setData(componentStr.toLatin1(), QUrl());
@@ -411,7 +411,7 @@ void tst_qsgtextinput::selection()
//Test selection follows cursor
- for(int i=0; i<= testStr.size(); i++) {
+ for (int i=0; i<= testStr.size(); i++) {
textinputObject->setCursorPosition(i);
QCOMPARE(textinputObject->cursorPosition(), i);
QCOMPARE(textinputObject->selectionStart(), i);
@@ -439,11 +439,11 @@ void tst_qsgtextinput::selection()
QVERIFY(textinputObject->selectedText().isNull());
//Test selection
- for(int i=0; i<= testStr.size(); i++) {
+ for (int i=0; i<= testStr.size(); i++) {
textinputObject->select(0,i);
QCOMPARE(testStr.mid(0,i), textinputObject->selectedText());
}
- for(int i=0; i<= testStr.size(); i++) {
+ for (int i=0; i<= testStr.size(); i++) {
textinputObject->select(i,testStr.size());
QCOMPARE(testStr.mid(i,testStr.size()-i), textinputObject->selectedText());
}
@@ -956,7 +956,7 @@ void tst_qsgtextinput::moveCursorSelectionSequence()
void tst_qsgtextinput::dragMouseSelection()
{
- QString qmlfile = SRCDIR "/data/mouseselection_true.qml";
+ QString qmlfile = TESTDATA("mouseselection_true.qml");
QSGView canvas(QUrl::fromLocalFile(qmlfile));
@@ -964,7 +964,7 @@ void tst_qsgtextinput::dragMouseSelection()
canvas.requestActivateWindow();
QTest::qWaitForWindowShown(&canvas);
- QTRY_COMPARE(canvas.windowState(), Qt::WindowActive);
+ QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
QVERIFY(canvas.rootObject() != 0);
QSGTextInput *textInputObject = qobject_cast<QSGTextInput *>(canvas.rootObject());
@@ -975,28 +975,24 @@ void tst_qsgtextinput::dragMouseSelection()
int x2 = 70;
int y = textInputObject->height()/2;
QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y));
- {
- QMouseEvent mv(QEvent::MouseMove, QPoint(x2,y), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
- QApplication::sendEvent(&canvas, &mv);
- }
+ QTest::mouseMove(&canvas, QPoint(x2, y));
QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y));
-
- QString str1 = textInputObject->selectedText();
+ QTest::qWait(100);
+ QString str1;
+ QVERIFY((str1 = textInputObject->selectedText()).length() > 3);
QVERIFY(str1.length() > 3);
// press and drag the current selection.
x1 = 40;
x2 = 100;
QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y));
- {
- QMouseEvent mv(QEvent::MouseMove, QPoint(x2,y), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
- QApplication::sendEvent(&canvas, &mv);
- }
- QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y));
+ QTest::mouseMove(&canvas, QPoint(x2, y));
+ QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y));
+ QTest::qWait(300);
QString str2 = textInputObject->selectedText();
QVERIFY(str2.length() > 3);
- QVERIFY(str1 != str2); // Verify the second press and drag is a new selection and doesn't not the first moved.
+ QVERIFY(str1 != str2);
}
void tst_qsgtextinput::mouseSelectionMode_data()
@@ -1005,9 +1001,9 @@ void tst_qsgtextinput::mouseSelectionMode_data()
QTest::addColumn<bool>("selectWords");
// import installed
- QTest::newRow("SelectWords") << SRCDIR "/data/mouseselectionmode_words.qml" << true;
- QTest::newRow("SelectCharacters") << SRCDIR "/data/mouseselectionmode_characters.qml" << false;
- QTest::newRow("default") << SRCDIR "/data/mouseselectionmode_default.qml" << false;
+ QTest::newRow("SelectWords") << TESTDATA("mouseselectionmode_words.qml") << true;
+ QTest::newRow("SelectCharacters") << TESTDATA("mouseselectionmode_characters.qml") << false;
+ QTest::newRow("default") << TESTDATA("mouseselectionmode_default.qml") << false;
}
void tst_qsgtextinput::mouseSelectionMode()
@@ -1022,7 +1018,7 @@ void tst_qsgtextinput::mouseSelectionMode()
canvas.show();
canvas.requestActivateWindow();
QTest::qWaitForWindowShown(&canvas);
- QTRY_COMPARE(canvas.windowState(), Qt::WindowActive);
+ QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
QVERIFY(canvas.rootObject() != 0);
QSGTextInput *textInputObject = qobject_cast<QSGTextInput *>(canvas.rootObject());
@@ -1033,16 +1029,14 @@ void tst_qsgtextinput::mouseSelectionMode()
int x2 = 70;
int y = textInputObject->height()/2;
QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y));
- //QTest::mouseMove(&canvas, canvas.mapFromScene(QPoint(x2,y))); // doesn't work
- QMouseEvent mv(QEvent::MouseMove, QPoint(x2,y), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
- QApplication::sendEvent(&canvas, &mv);
+ QTest::mouseMove(&canvas, QPoint(x2,y)); // doesn't work
QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y));
- QString str = textInputObject->selectedText();
+ QTest::qWait(300);
if (selectWords) {
- QCOMPARE(str, text);
+ QTRY_COMPARE(textInputObject->selectedText(), text);
} else {
- QVERIFY(str.length() > 3);
- QVERIFY(str != text);
+ QTRY_VERIFY(textInputObject->selectedText().length() > 3);
+ QVERIFY(textInputObject->selectedText() != text);
}
}
@@ -1058,15 +1052,17 @@ void tst_qsgtextinput::horizontalAlignment_data()
void tst_qsgtextinput::horizontalAlignment()
{
+ QSKIP("Image comparison of text is almost guaranteed to fail during development");
+
QFETCH(int, hAlign);
QFETCH(QString, expectfile);
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/horizontalAlignment.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("horizontalAlignment.qml")));
canvas.show();
canvas.requestActivateWindow();
QTest::qWaitForWindowShown(&canvas);
- QTRY_COMPARE(canvas.windowState(), Qt::WindowActive);
+ QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
QObject *ob = canvas.rootObject();
QVERIFY(ob != 0);
ob->setProperty("horizontalAlignment",hAlign);
@@ -1081,7 +1077,7 @@ void tst_qsgtextinput::horizontalAlignment()
void tst_qsgtextinput::horizontalAlignment_RightToLeft()
{
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/horizontalAlignment_RightToLeft.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("horizontalAlignment_RightToLeft.qml")));
QSGTextInput *textInput = canvas.rootObject()->findChild<QSGTextInput*>("text");
QVERIFY(textInput != 0);
canvas.show();
@@ -1152,24 +1148,25 @@ void tst_qsgtextinput::horizontalAlignment_RightToLeft()
QCOMPARE(textInput->hAlign(), QSGTextInput::AlignLeft);
QVERIFY(-textInputPrivate->hscroll < canvas.width()/2);
- QApplication::setActiveWindow(&canvas);
+ canvas.requestActivateWindow();
QTest::qWaitForWindowShown(&canvas);
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&canvas));
+ QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
// If there is no commited text, the preedit text should determine the alignment.
textInput->setText(QString());
- { QInputMethodEvent ev(rtlText, QList<QInputMethodEvent::Attribute>()); QApplication::sendEvent(&canvas, &ev); }
+ { QInputMethodEvent ev(rtlText, QList<QInputMethodEvent::Attribute>()); QGuiApplication::sendEvent(&canvas, &ev); }
+ QEXPECT_FAIL("", "QTBUG-21691", Continue);
QCOMPARE(textInput->hAlign(), QSGTextInput::AlignRight);
- { QInputMethodEvent ev("Hello world!", QList<QInputMethodEvent::Attribute>()); QApplication::sendEvent(&canvas, &ev); }
+ { QInputMethodEvent ev("Hello world!", QList<QInputMethodEvent::Attribute>()); QGuiApplication::sendEvent(&canvas, &ev); }
QCOMPARE(textInput->hAlign(), QSGTextInput::AlignLeft);
#ifndef Q_OS_MAC // QTBUG-18040
// empty text with implicit alignment follows the system locale-based
- // keyboard input direction from QApplication::keyboardInputDirection
+ // keyboard input direction from QGuiApplication::keyboardInputDirection
textInput->setText("");
- QCOMPARE(textInput->hAlign(), QApplication::keyboardInputDirection() == Qt::LeftToRight ?
+ QCOMPARE(textInput->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ?
QSGTextInput::AlignLeft : QSGTextInput::AlignRight);
- if (QApplication::keyboardInputDirection() == Qt::LeftToRight)
+ if (QGuiApplication::keyboardInputDirection() == Qt::LeftToRight)
QVERIFY(-textInputPrivate->hscroll < canvas.width()/2);
else
QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
@@ -1184,7 +1181,7 @@ void tst_qsgtextinput::horizontalAlignment_RightToLeft()
QDeclarativeComponent textComponent(&engine);
textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QSGTextInput *textObject = qobject_cast<QSGTextInput*>(textComponent.create());
- QCOMPARE(textObject->hAlign(), QApplication::keyboardInputDirection() == Qt::LeftToRight ?
+ QCOMPARE(textObject->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ?
QSGTextInput::AlignLeft : QSGTextInput::AlignRight);
delete textObject;
#endif
@@ -1192,7 +1189,7 @@ void tst_qsgtextinput::horizontalAlignment_RightToLeft()
void tst_qsgtextinput::positionAt()
{
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/positionAt.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("positionAt.qml")));
QVERIFY(canvas.rootObject() != 0);
canvas.show();
canvas.requestActivateWindow();
@@ -1246,6 +1243,7 @@ void tst_qsgtextinput::positionAt()
int diff = abs(textWidth - (textLeftWidth+textinputObject->width()/2));
// some tollerance for different fonts.
+ QEXPECT_FAIL("", "QTBUG-21689", Abort);
#ifdef Q_OS_LINUX
QVERIFY(diff < 2);
#else
@@ -1301,7 +1299,7 @@ void tst_qsgtextinput::positionAt()
textinputObject->setCursorPosition(0);
QInputMethodEvent inputEvent(preeditText, QList<QInputMethodEvent::Attribute>());
- QApplication::sendEvent(&canvas, &inputEvent);
+ QGuiApplication::sendEvent(&canvas, &inputEvent);
// Check all points within the preedit text return the same position.
QCOMPARE(textinputObject->positionAt(0), 0);
@@ -1315,7 +1313,7 @@ void tst_qsgtextinput::positionAt()
void tst_qsgtextinput::maxLength()
{
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/maxLength.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("maxLength.qml")));
QVERIFY(canvas.rootObject() != 0);
canvas.show();
canvas.requestActivateWindow();
@@ -1325,7 +1323,7 @@ void tst_qsgtextinput::maxLength()
QVERIFY(textinputObject != 0);
QVERIFY(textinputObject->text().isEmpty());
QVERIFY(textinputObject->maxLength() == 10);
- foreach(const QString &str, standard){
+ foreach (const QString &str, standard) {
QVERIFY(textinputObject->text().length() <= 10);
textinputObject->setText(str);
QVERIFY(textinputObject->text().length() <= 10);
@@ -1333,11 +1331,12 @@ void tst_qsgtextinput::maxLength()
textinputObject->setText("");
QTRY_VERIFY(textinputObject->hasActiveFocus() == true);
- for(int i=0; i<20; i++){
- QCOMPARE(textinputObject->text().length(), qMin(i,10));
+ for (int i=0; i<20; i++) {
+ QTRY_COMPARE(textinputObject->text().length(), qMin(i,10));
//simulateKey(&canvas, Qt::Key_A);
QTest::keyPress(&canvas, Qt::Key_A);
QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10);
+ QTest::qWait(50);
}
}
@@ -1345,7 +1344,7 @@ void tst_qsgtextinput::masks()
{
//Not a comprehensive test of the possible masks, that's done elsewhere (QLineEdit)
//QString componentStr = "import QtQuick 2.0\nTextInput { inputMask: 'HHHHhhhh'; }";
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/masks.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("masks.qml")));
canvas.show();
canvas.requestActivateWindow();
QVERIFY(canvas.rootObject() != 0);
@@ -1354,12 +1353,13 @@ void tst_qsgtextinput::masks()
QTRY_VERIFY(textinputObject->hasActiveFocus() == true);
QVERIFY(textinputObject->text().length() == 0);
QCOMPARE(textinputObject->inputMask(), QString("HHHHhhhh; "));
- for(int i=0; i<10; i++){
- QCOMPARE(qMin(i,8), textinputObject->text().length());
+ for (int i=0; i<10; i++) {
+ QTRY_COMPARE(qMin(i,8), textinputObject->text().length());
QCOMPARE(i>=4, textinputObject->hasAcceptableInput());
//simulateKey(&canvas, Qt::Key_A);
QTest::keyPress(&canvas, Qt::Key_A);
QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10);
+ QTest::qWait(50);
}
}
@@ -1369,7 +1369,7 @@ void tst_qsgtextinput::validators()
// so you may need to run their tests first. All validators are checked
// here to ensure that their exposure to QML is working.
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/validators.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("validators.qml")));
canvas.show();
canvas.requestActivateWindow();
@@ -1381,18 +1381,22 @@ void tst_qsgtextinput::validators()
QTRY_VERIFY(intInput->hasActiveFocus());
QTest::keyPress(&canvas, Qt::Key_1);
QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10);
- QCOMPARE(intInput->text(), QLatin1String("1"));
+ QTest::qWait(50);
+ QTRY_COMPARE(intInput->text(), QLatin1String("1"));
QCOMPARE(intInput->hasAcceptableInput(), false);
QTest::keyPress(&canvas, Qt::Key_2);
QTest::keyRelease(&canvas, Qt::Key_2, Qt::NoModifier ,10);
- QCOMPARE(intInput->text(), QLatin1String("1"));
+ QTest::qWait(50);
+ QTRY_COMPARE(intInput->text(), QLatin1String("1"));
QCOMPARE(intInput->hasAcceptableInput(), false);
QTest::keyPress(&canvas, Qt::Key_1);
QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10);
+ QTest::qWait(50);
QCOMPARE(intInput->text(), QLatin1String("11"));
QCOMPARE(intInput->hasAcceptableInput(), true);
QTest::keyPress(&canvas, Qt::Key_0);
QTest::keyRelease(&canvas, Qt::Key_0, Qt::NoModifier ,10);
+ QTest::qWait(50);
QCOMPARE(intInput->text(), QLatin1String("11"));
QCOMPARE(intInput->hasAcceptableInput(), true);
@@ -1402,27 +1406,33 @@ void tst_qsgtextinput::validators()
QVERIFY(dblInput->hasActiveFocus() == true);
QTest::keyPress(&canvas, Qt::Key_1);
QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10);
- QCOMPARE(dblInput->text(), QLatin1String("1"));
+ QTest::qWait(50);
+ QTRY_COMPARE(dblInput->text(), QLatin1String("1"));
QCOMPARE(dblInput->hasAcceptableInput(), false);
QTest::keyPress(&canvas, Qt::Key_2);
QTest::keyRelease(&canvas, Qt::Key_2, Qt::NoModifier ,10);
- QCOMPARE(dblInput->text(), QLatin1String("12"));
+ QTest::qWait(50);
+ QTRY_COMPARE(dblInput->text(), QLatin1String("12"));
QCOMPARE(dblInput->hasAcceptableInput(), true);
QTest::keyPress(&canvas, Qt::Key_Period);
QTest::keyRelease(&canvas, Qt::Key_Period, Qt::NoModifier ,10);
- QCOMPARE(dblInput->text(), QLatin1String("12."));
+ QTest::qWait(50);
+ QTRY_COMPARE(dblInput->text(), QLatin1String("12."));
QCOMPARE(dblInput->hasAcceptableInput(), true);
QTest::keyPress(&canvas, Qt::Key_1);
QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10);
- QCOMPARE(dblInput->text(), QLatin1String("12.1"));
+ QTest::qWait(50);
+ QTRY_COMPARE(dblInput->text(), QLatin1String("12.1"));
QCOMPARE(dblInput->hasAcceptableInput(), true);
QTest::keyPress(&canvas, Qt::Key_1);
QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10);
- QCOMPARE(dblInput->text(), QLatin1String("12.11"));
+ QTest::qWait(50);
+ QTRY_COMPARE(dblInput->text(), QLatin1String("12.11"));
QCOMPARE(dblInput->hasAcceptableInput(), true);
QTest::keyPress(&canvas, Qt::Key_1);
QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10);
- QCOMPARE(dblInput->text(), QLatin1String("12.11"));
+ QTest::qWait(50);
+ QTRY_COMPARE(dblInput->text(), QLatin1String("12.11"));
QCOMPARE(dblInput->hasAcceptableInput(), true);
QSGTextInput *strInput = qobject_cast<QSGTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("strInput")));
@@ -1431,33 +1441,39 @@ void tst_qsgtextinput::validators()
QVERIFY(strInput->hasActiveFocus() == true);
QTest::keyPress(&canvas, Qt::Key_1);
QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10);
- QCOMPARE(strInput->text(), QLatin1String(""));
+ QTest::qWait(50);
+ QTRY_COMPARE(strInput->text(), QLatin1String(""));
QCOMPARE(strInput->hasAcceptableInput(), false);
QTest::keyPress(&canvas, Qt::Key_A);
QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10);
- QCOMPARE(strInput->text(), QLatin1String("a"));
+ QTest::qWait(50);
+ QTRY_COMPARE(strInput->text(), QLatin1String("a"));
QCOMPARE(strInput->hasAcceptableInput(), false);
QTest::keyPress(&canvas, Qt::Key_A);
QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10);
- QCOMPARE(strInput->text(), QLatin1String("aa"));
+ QTest::qWait(50);
+ QTRY_COMPARE(strInput->text(), QLatin1String("aa"));
QCOMPARE(strInput->hasAcceptableInput(), true);
QTest::keyPress(&canvas, Qt::Key_A);
QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10);
- QCOMPARE(strInput->text(), QLatin1String("aaa"));
+ QTest::qWait(50);
+ QTRY_COMPARE(strInput->text(), QLatin1String("aaa"));
QCOMPARE(strInput->hasAcceptableInput(), true);
QTest::keyPress(&canvas, Qt::Key_A);
QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10);
- QCOMPARE(strInput->text(), QLatin1String("aaaa"));
+ QTest::qWait(50);
+ QTRY_COMPARE(strInput->text(), QLatin1String("aaaa"));
QCOMPARE(strInput->hasAcceptableInput(), true);
QTest::keyPress(&canvas, Qt::Key_A);
QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10);
- QCOMPARE(strInput->text(), QLatin1String("aaaa"));
+ QTest::qWait(50);
+ QTRY_COMPARE(strInput->text(), QLatin1String("aaaa"));
QCOMPARE(strInput->hasAcceptableInput(), true);
}
void tst_qsgtextinput::inputMethods()
{
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/inputmethods.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("inputmethods.qml")));
canvas.show();
canvas.requestActivateWindow();
QTest::qWaitForWindowShown(&canvas);
@@ -1475,24 +1491,25 @@ void tst_qsgtextinput::inputMethods()
// test that input method event is committed
QInputMethodEvent event;
event.setCommitString( "My ", -12, 0);
- QApplication::sendEvent(&canvas, &event);
+ QGuiApplication::sendEvent(&canvas, &event);
+ QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
QCOMPARE(input->text(), QString("My Hello world!"));
input->setCursorPosition(2);
event.setCommitString("Your", -2, 2);
- QApplication::sendEvent(&canvas, &event);
+ QGuiApplication::sendEvent(&canvas, &event);
QCOMPARE(input->text(), QString("Your Hello world!"));
QCOMPARE(input->cursorPosition(), 4);
input->setCursorPosition(7);
event.setCommitString("Goodbye", -2, 5);
- QApplication::sendEvent(&canvas, &event);
+ QGuiApplication::sendEvent(&canvas, &event);
QCOMPARE(input->text(), QString("Your Goodbye world!"));
QCOMPARE(input->cursorPosition(), 12);
input->setCursorPosition(8);
event.setCommitString("Our", -8, 4);
- QApplication::sendEvent(&canvas, &event);
+ QGuiApplication::sendEvent(&canvas, &event);
QCOMPARE(input->text(), QString("Our Goodbye world!"));
QCOMPARE(input->cursorPosition(), 7);
}
@@ -1504,7 +1521,7 @@ the extent of the text, then they should ignore the keys.
*/
void tst_qsgtextinput::navigation()
{
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/navigation.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml")));
canvas.show();
canvas.requestActivateWindow();
@@ -1543,7 +1560,7 @@ void tst_qsgtextinput::navigation()
void tst_qsgtextinput::navigation_RTL()
{
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/navigation.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml")));
canvas.show();
canvas.requestActivateWindow();
@@ -1588,7 +1605,7 @@ void tst_qsgtextinput::copyAndPaste() {
if (status == noErr)
CFRelease(pasteboard);
else
- QSKIP("This machine doesn't support the clipboard", SkipAll);
+ QSKIP("This machine doesn't support the clipboard");
}
#endif
@@ -1631,7 +1648,7 @@ void tst_qsgtextinput::copyAndPaste() {
QCOMPARE(textInput->text().length(), 24);
// clear copy buffer
- QClipboard *clipboard = QApplication::clipboard();
+ QClipboard *clipboard = QGuiApplication::clipboard();
QVERIFY(clipboard);
clipboard->clear();
QVERIFY(!textInput->canPaste());
@@ -1662,7 +1679,7 @@ void tst_qsgtextinput::copyAndPaste() {
void tst_qsgtextinput::canPasteEmpty() {
#ifndef QT_NO_CLIPBOARD
- QApplication::clipboard()->clear();
+ QGuiApplication::clipboard()->clear();
QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\" }";
QDeclarativeComponent textInputComponent(&engine);
@@ -1671,7 +1688,7 @@ void tst_qsgtextinput::canPasteEmpty() {
QVERIFY(textInput != 0);
QLineControl lc;
- bool cp = !lc.isReadOnly() && QApplication::clipboard()->text().length() != 0;
+ bool cp = !lc.isReadOnly() && QGuiApplication::clipboard()->text().length() != 0;
QCOMPARE(textInput->canPaste(), cp);
#endif
@@ -1680,7 +1697,7 @@ void tst_qsgtextinput::canPasteEmpty() {
void tst_qsgtextinput::canPaste() {
#ifndef QT_NO_CLIPBOARD
- QApplication::clipboard()->setText("Some text");
+ QGuiApplication::clipboard()->setText("Some text");
QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\" }";
QDeclarativeComponent textInputComponent(&engine);
@@ -1689,7 +1706,7 @@ void tst_qsgtextinput::canPaste() {
QVERIFY(textInput != 0);
QLineControl lc;
- bool cp = !lc.isReadOnly() && QApplication::clipboard()->text().length() != 0;
+ bool cp = !lc.isReadOnly() && QGuiApplication::clipboard()->text().length() != 0;
QCOMPARE(textInput->canPaste(), cp);
#endif
@@ -1715,7 +1732,7 @@ void tst_qsgtextinput::passwordCharacter()
void tst_qsgtextinput::cursorDelegate()
{
- QSGView view(QUrl::fromLocalFile(SRCDIR "/data/cursorTest.qml"));
+ QSGView view(QUrl::fromLocalFile(TESTDATA("cursorTest.qml")));
view.show();
view.requestActivateWindow();
QSGTextInput *textInputObject = view.rootObject()->findChild<QSGTextInput*>("textInputObject");
@@ -1725,8 +1742,9 @@ void tst_qsgtextinput::cursorDelegate()
textInputObject->setFocus(true);
QSGItem* delegateObject = textInputObject->findChild<QSGItem*>("cursorInstance");
QVERIFY(delegateObject);
+ QCOMPARE(delegateObject->property("localProperty").toString(), QString("Hello"));
//Test Delegate gets moved
- for(int i=0; i<= textInputObject->text().length(); i++){
+ for (int i=0; i<= textInputObject->text().length(); i++) {
textInputObject->setCursorPosition(i);
QCOMPARE(textInputObject->cursorRectangle().x(), qRound(delegateObject->x()));
QCOMPARE(textInputObject->cursorRectangle().y(), qRound(delegateObject->y()));
@@ -1741,11 +1759,11 @@ void tst_qsgtextinput::cursorDelegate()
void tst_qsgtextinput::cursorVisible()
{
- QSGView view(QUrl::fromLocalFile(SRCDIR "/data/cursorVisible.qml"));
+ QSGView view(QUrl::fromLocalFile(TESTDATA("cursorVisible.qml")));
view.show();
view.requestActivateWindow();
QTest::qWaitForWindowShown(&view);
- QTRY_COMPARE(view.windowState(), Qt::WindowActive);
+ QTRY_COMPARE(&view, qGuiApp->focusWindow());
QSGTextInput input;
QSignalSpy spy(&input, SIGNAL(cursorVisibleChanged(bool)));
@@ -1777,6 +1795,7 @@ void tst_qsgtextinput::cursorVisible()
QCOMPARE(spy.count(), 5);
view.setWindowState(Qt::WindowNoState);
+ QEXPECT_FAIL("", "Most likely a side-effect of QTBUG-21489", Abort);
QCOMPARE(input.isCursorVisible(), false);
QCOMPARE(spy.count(), 6);
@@ -1787,20 +1806,24 @@ void tst_qsgtextinput::cursorVisible()
// on mac, setActiveWindow(0) on mac does not deactivate the current application
// (you have to switch to a different app or hide the current app to trigger this)
#if !defined(Q_WS_MAC)
- QApplication::setActiveWindow(0);
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(0));
- QCOMPARE(input.isCursorVisible(), false);
- QCOMPARE(spy.count(), 8);
-
- view.requestActivateWindow();
- QTRY_COMPARE(view.windowState(), Qt::WindowActive);
- QCOMPARE(input.isCursorVisible(), true);
- QCOMPARE(spy.count(), 9);
+ // QGuiApplication has no equivalent of setActiveWindow(0). Is this different to clearing the
+ // active state of the window or can it be removed?
+// QApplication::setActiveWindow(0);
+// QTRY_COMPARE(QApplication::focusWindow(), static_cast<QWidget *>(0));
+// QCOMPARE(input.isCursorVisible(), false);
+// QCOMPARE(spy.count(), 8);
+
+// view.requestActivateWindow();
+// QTRY_COMPARE(view.windowState(), Qt::WindowActive);
+// QCOMPARE(input.isCursorVisible(), true);
+// QCOMPARE(spy.count(), 9);
#endif
}
void tst_qsgtextinput::cursorRectangle()
{
+ QSKIP("QTBUG-21689");
+
QString text = "Hello World!";
QSGTextInput input;
@@ -1825,7 +1848,7 @@ void tst_qsgtextinput::cursorRectangle()
QVERIFY(r.left() < textWidth + error);
QVERIFY(r.right() > textWidth - error);
- QCOMPARE(input.inputMethodQuery(Qt::ImMicroFocus).toRect(), r);
+ QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
}
// Check the cursor rectangle remains within the input bounding rect when auto scrolling.
@@ -1835,14 +1858,14 @@ void tst_qsgtextinput::cursorRectangle()
for (int i = 6; i < text.length(); ++i) {
input.setCursorPosition(i);
QCOMPARE(r, input.cursorRectangle());
- QCOMPARE(input.inputMethodQuery(Qt::ImMicroFocus).toRect(), r);
+ QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
}
for (int i = text.length() - 2; i >= 0; --i) {
input.setCursorPosition(i);
r = input.cursorRectangle();
QVERIFY(r.right() >= 0);
- QCOMPARE(input.inputMethodQuery(Qt::ImMicroFocus).toRect(), r);
+ QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
}
input.setText("Hi!");
@@ -1854,7 +1877,7 @@ void tst_qsgtextinput::cursorRectangle()
void tst_qsgtextinput::readOnly()
{
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/readOnly.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("readOnly.qml")));
canvas.show();
canvas.requestActivateWindow();
@@ -1866,7 +1889,7 @@ void tst_qsgtextinput::readOnly()
QTRY_VERIFY(input->hasActiveFocus() == true);
QVERIFY(input->isReadOnly() == true);
QString initial = input->text();
- for(int k=Qt::Key_0; k<=Qt::Key_Z; k++)
+ for (int k=Qt::Key_0; k<=Qt::Key_Z; k++)
simulateKey(&canvas, k);
simulateKey(&canvas, Qt::Key_Return);
simulateKey(&canvas, Qt::Key_Space);
@@ -1881,11 +1904,11 @@ void tst_qsgtextinput::readOnly()
void tst_qsgtextinput::echoMode()
{
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/echoMode.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("echoMode.qml")));
canvas.show();
canvas.requestActivateWindow();
QTest::qWaitForWindowShown(&canvas);
- QTRY_COMPARE(canvas.windowState(), Qt::WindowActive);
+ QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
QVERIFY(canvas.rootObject() != 0);
@@ -1939,9 +1962,10 @@ void tst_qsgtextinput::echoMode()
QCOMPARE(input->displayText(), QLatin1String("Q"));
QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QLatin1String("Q"));
input->setFocus(true);
+ QVERIFY(input->hasActiveFocus());
QInputMethodEvent inputEvent;
inputEvent.setCommitString(initial);
- QApplication::sendEvent(&canvas, &inputEvent);
+ QGuiApplication::sendEvent(input, &inputEvent);
QCOMPARE(input->text(), initial);
QCOMPARE(input->displayText(), initial);
QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), initial);
@@ -1950,12 +1974,12 @@ void tst_qsgtextinput::echoMode()
#ifdef QT_GUI_PASSWORD_ECHO_DELAY
void tst_qdeclarativetextinput::passwordEchoDelay()
{
- QSGView canvas(QUrl::fromLocalFile(SRCDIR "/data/echoMode.qml"));
+ QSGView canvas(QUrl::fromLocalFile(TESTDATA("echoMode.qml")));
canvas.show();
canvas.setFocus();
- QApplication::setActiveWindow(&canvas);
+ QGuiApplication::setActiveWindow(&canvas);
QTest::qWaitForWindowShown(&canvas);
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&canvas));
+ QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
QVERIFY(canvas.rootObject() != 0);
@@ -1994,7 +2018,7 @@ void tst_qdeclarativetextinput::passwordEchoDelay()
QInputMethodEvent ev;
ev.setCommitString(QLatin1String("7"));
- QApplication::sendEvent(&canvas, &ev);
+ QGuiApplication::sendEvent(&canvas, &ev);
QCOMPARE(input->displayText(), QString(7, fillChar) + QLatin1Char('7'));
}
#endif
@@ -2005,14 +2029,15 @@ void tst_qsgtextinput::simulateKey(QSGView *view, int key)
QKeyEvent press(QKeyEvent::KeyPress, key, 0);
QKeyEvent release(QKeyEvent::KeyRelease, key, 0);
- QApplication::sendEvent(view, &press);
- QApplication::sendEvent(view, &release);
+ QGuiApplication::sendEvent(view, &press);
+ QGuiApplication::sendEvent(view, &release);
}
+#ifndef QTBUG_21691
class MyInputContext : public QInputContext
{
public:
- MyInputContext() : openInputPanelReceived(false), closeInputPanelReceived(false), updateReceived(false), eventType(QEvent::None) {}
+ MyInputContext() : updateReceived(false), eventType(QEvent::None) {}
~MyInputContext() {}
QString identifierName() { return QString(); }
@@ -2022,15 +2047,6 @@ public:
bool isComposing() const { return false; }
- bool filterEvent( const QEvent *event )
- {
- if (event->type() == QEvent::RequestSoftwareInputPanel)
- openInputPanelReceived = true;
- if (event->type() == QEvent::CloseSoftwareInputPanel)
- closeInputPanelReceived = true;
- return QInputContext::filterEvent(event);
- }
-
void update() { updateReceived = true; }
void mouseHandler(int x, QMouseEvent *event)
@@ -2054,8 +2070,6 @@ public:
sendEvent(event);
}
- bool openInputPanelReceived;
- bool closeInputPanelReceived;
bool updateReceived;
int cursor;
QEvent::Type eventType;
@@ -2065,182 +2079,94 @@ public:
Qt::MouseButtons eventButtons;
Qt::KeyboardModifiers eventModifiers;
};
+#endif
-void tst_qsgtextinput::openInputPanelOnClick()
+void tst_qsgtextinput::openInputPanel()
{
- QSGView view(QUrl::fromLocalFile(SRCDIR "/data/openInputPanel.qml"));
- MyInputContext ic;
- // QSGCanvas won't set the Qt::WA_InputMethodEnabled flag unless a suitable item has focus
- // and QWidget won't allow an input context to be set when the flag is not set.
- view.setAttribute(Qt::WA_InputMethodEnabled, true);
- view.setInputContext(&ic);
- view.setAttribute(Qt::WA_InputMethodEnabled, false);
+ QSGView view(QUrl::fromLocalFile(TESTDATA("openInputPanel.qml")));
view.show();
- QApplication::setActiveWindow(&view);
+ view.requestActivateWindow();
QTest::qWaitForWindowShown(&view);
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
- QSGTextInput *input = qobject_cast<QSGTextInput *>(view.rootObject());
- QVERIFY(input);
+ QTRY_COMPARE(&view, qGuiApp->focusWindow());
- QSGItemPrivate* pri = QSGItemPrivate::get(input);
- QSGTextInputPrivate *inputPrivate = static_cast<QSGTextInputPrivate*>(pri);
-
- // input panel on click
- inputPrivate->showInputPanelOnFocus = false;
-
- QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel(
- view.style()->styleHint(QStyle::SH_RequestSoftwareInputPanel));
- QTest::mouseClick(&view, Qt::LeftButton, 0, input->pos().toPoint());
- QApplication::processEvents();
- if (behavior == QStyle::RSIP_OnMouseClickAndAlreadyFocused) {
- QCOMPARE(ic.openInputPanelReceived, false);
- QTest::mouseClick(&view, Qt::LeftButton, 0, input->pos().toPoint());
- QApplication::processEvents();
- QCOMPARE(ic.openInputPanelReceived, true);
- } else if (behavior == QStyle::RSIP_OnMouseClick) {
- QCOMPARE(ic.openInputPanelReceived, true);
- }
- ic.openInputPanelReceived = false;
-
- // focus should not cause input panels to open or close
- input->setFocus(false);
- input->setFocus(true);
- input->setFocus(false);
- input->setFocus(true);
- input->setFocus(false);
- QCOMPARE(ic.openInputPanelReceived, false);
- QCOMPARE(ic.closeInputPanelReceived, false);
-}
-
-void tst_qsgtextinput::openInputPanelOnFocus()
-{
- QSGView view(QUrl::fromLocalFile(SRCDIR "/data/openInputPanel.qml"));
- MyInputContext ic;
- // QSGCanvas won't set the Qt::WA_InputMethodEnabled flag unless a suitable item has focus
- // and QWidget won't allow an input context to be set when the flag is not set.
- view.setAttribute(Qt::WA_InputMethodEnabled, true);
- view.setInputContext(&ic);
- view.setAttribute(Qt::WA_InputMethodEnabled, false);
- view.show();
- QApplication::setActiveWindow(&view);
- QTest::qWaitForWindowShown(&view);
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
QSGTextInput *input = qobject_cast<QSGTextInput *>(view.rootObject());
QVERIFY(input);
- QSignalSpy focusOnPressSpy(input, SIGNAL(activeFocusOnPressChanged(bool)));
-
- QSGItemPrivate* pri = QSGItemPrivate::get(input);
- QSGTextInputPrivate *inputPrivate = static_cast<QSGTextInputPrivate*>(pri);
- inputPrivate->showInputPanelOnFocus = true;
- // test default values
+ // check default values
QVERIFY(input->focusOnPress());
- QCOMPARE(ic.openInputPanelReceived, false);
- QCOMPARE(ic.closeInputPanelReceived, false);
-
- // focus on press, input panel on focus
- QTest::mousePress(&view, Qt::LeftButton, 0, input->pos().toPoint());
- QApplication::processEvents();
+ QVERIFY(!input->hasActiveFocus());
+ qDebug() << &input << qApp->inputPanel()->inputItem();
+ QCOMPARE(qApp->inputPanel()->inputItem(), static_cast<QObject*>(0));
+ QEXPECT_FAIL("", "QTBUG-21946", Abort);
+ QCOMPARE(qApp->inputPanel()->visible(), false);
+
+ // input panel should open on focus
+ QPoint centerPoint(view.width()/2, view.height()/2);
+ Qt::KeyboardModifiers noModifiers = 0;
+ QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint);
+ QGuiApplication::processEvents();
QVERIFY(input->hasActiveFocus());
- QCOMPARE(ic.openInputPanelReceived, true);
- ic.openInputPanelReceived = false;
+ QCOMPARE(qApp->inputPanel()->inputItem(), input);
+ QCOMPARE(qApp->inputPanel()->visible(), true);
+ QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint);
- // no events on release
- QTest::mouseRelease(&view, Qt::LeftButton, 0, input->pos().toPoint());
- QCOMPARE(ic.openInputPanelReceived, false);
- ic.openInputPanelReceived = false;
-
- // if already focused, input panel can be opened on press
+ // input panel should be re-opened when pressing already focused TextInput
+ qApp->inputPanel()->hide();
+ QCOMPARE(qApp->inputPanel()->visible(), false);
QVERIFY(input->hasActiveFocus());
- QTest::mousePress(&view, Qt::LeftButton, 0, input->pos().toPoint());
- QApplication::processEvents();
- QCOMPARE(ic.openInputPanelReceived, true);
- ic.openInputPanelReceived = false;
+ QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint);
+ QGuiApplication::processEvents();
+ QCOMPARE(qApp->inputPanel()->visible(), true);
+ QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint);
- // input method should stay enabled if focus
- // is lost to an item that also accepts inputs
+ // input panel should stay visible if focus is lost to another text inputor
+ QSignalSpy inputPanelVisibilitySpy(qApp->inputPanel(), SIGNAL(visibleChanged()));
QSGTextInput anotherInput;
- anotherInput.setParentItem(view.rootItem());
+ anotherInput.setParentItem(view.rootObject());
+ anotherInput.setFocus(true);
+ QCOMPARE(qApp->inputPanel()->visible(), true);
+ QCOMPARE(qApp->inputPanel()->inputItem(), qobject_cast<QObject*>(&anotherInput));
+ QCOMPARE(inputPanelVisibilitySpy.count(), 0);
+
+ anotherInput.setFocus(false);
+ QCOMPARE(qApp->inputPanel()->inputItem(), static_cast<QObject*>(0));
+ QCOMPARE(view.activeFocusItem(), view.rootItem());
anotherInput.setFocus(true);
- QApplication::processEvents();
- QCOMPARE(ic.openInputPanelReceived, true);
- ic.openInputPanelReceived = false;
- QCOMPARE(view.inputContext(), (QInputContext*)&ic);
- QVERIFY(view.testAttribute(Qt::WA_InputMethodEnabled));
-
- // input method should be disabled if focus
- // is lost to an item that doesn't accept inputs
+
+ // input item should be null if focus is lost to an item that doesn't accept inputs
QSGItem item;
- item.setParentItem(view.rootItem());
+ item.setParentItem(view.rootObject());
item.setFocus(true);
- QApplication::processEvents();
- QCOMPARE(ic.openInputPanelReceived, false);
- QVERIFY(view.inputContext() == 0);
- QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled));
+ QCOMPARE(qApp->inputPanel()->inputItem(), static_cast<QObject*>(0));
+ QCOMPARE(view.activeFocusItem(), &item);
- // no automatic input panel events should
- // be sent if activeFocusOnPress is false
- input->setFocusOnPress(false);
- QCOMPARE(focusOnPressSpy.count(),1);
- input->setFocusOnPress(false);
- QCOMPARE(focusOnPressSpy.count(),1);
- input->setFocus(false);
+ qApp->inputPanel()->hide();
+
+ // input panel should not be opened if TextInput is read only
+ input->setReadOnly(true);
input->setFocus(true);
- QTest::mousePress(&view, Qt::LeftButton, 0, input->pos().toPoint());
- QTest::mouseRelease(&view, Qt::LeftButton, 0, input->pos().toPoint());
- QApplication::processEvents();
- QCOMPARE(ic.openInputPanelReceived, false);
- QCOMPARE(ic.closeInputPanelReceived, false);
-
- // one show input panel event should
- // be set when openSoftwareInputPanel is called
- input->openSoftwareInputPanel();
- QCOMPARE(ic.openInputPanelReceived, true);
- QCOMPARE(ic.closeInputPanelReceived, false);
- ic.openInputPanelReceived = false;
+ QCOMPARE(qApp->inputPanel()->visible(), false);
+ QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint);
+ QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint);
+ QGuiApplication::processEvents();
+ QCOMPARE(qApp->inputPanel()->visible(), false);
- // one close input panel event should
- // be sent when closeSoftwareInputPanel is called
- input->closeSoftwareInputPanel();
- QCOMPARE(ic.openInputPanelReceived, false);
- QCOMPARE(ic.closeInputPanelReceived, true);
- ic.closeInputPanelReceived = false;
-
- // set activeFocusOnPress back to true
- input->setFocusOnPress(true);
- QCOMPARE(focusOnPressSpy.count(),2);
- input->setFocusOnPress(true);
- QCOMPARE(focusOnPressSpy.count(),2);
+ // input panel should not be opened if focusOnPress is set to false
+ input->setFocusOnPress(false);
input->setFocus(false);
- QApplication::processEvents();
- QCOMPARE(ic.openInputPanelReceived, false);
- QCOMPARE(ic.closeInputPanelReceived, false);
- ic.closeInputPanelReceived = false;
-
- // input panel should not re-open
- // if focus has already been set
- input->setFocus(true);
- QCOMPARE(ic.openInputPanelReceived, true);
- ic.openInputPanelReceived = false;
input->setFocus(true);
- QCOMPARE(ic.openInputPanelReceived, false);
+ QCOMPARE(qApp->inputPanel()->visible(), false);
+ QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint);
+ QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint);
+ QCOMPARE(qApp->inputPanel()->visible(), false);
- // input method should be disabled
- // if TextInput loses focus
- input->setFocus(false);
- QApplication::processEvents();
- QVERIFY(view.inputContext() == 0);
- QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled));
+ // input panel should open when openSoftwareInputPanel is called
+ input->openSoftwareInputPanel();
+ QCOMPARE(qApp->inputPanel()->visible(), true);
- // input method should not be enabled
- // if TextEdit is read only.
- input->setReadOnly(true);
- ic.openInputPanelReceived = false;
- input->setFocus(true);
- QApplication::processEvents();
- QCOMPARE(ic.openInputPanelReceived, false);
- QVERIFY(view.inputContext() == 0);
- QVERIFY(!view.testAttribute(Qt::WA_InputMethodEnabled));
+ // input panel should close when closeSoftwareInputPanel is called
+ input->closeSoftwareInputPanel();
+ QCOMPARE(qApp->inputPanel()->visible(), false);
}
class MyTextInput : public QSGTextInput
@@ -2265,7 +2191,7 @@ void tst_qsgtextinput::setHAlignClearCache()
input.setText("Hello world");
input.setParentItem(view.rootItem());
view.show();
- QApplication::setActiveWindow(&view);
+ view.requestActivateWindow();
QTest::qWaitForWindowShown(&view);
QTRY_COMPARE(input.nbPaint, 1);
input.setHAlign(QSGTextInput::AlignRight);
@@ -2283,20 +2209,20 @@ void tst_qsgtextinput::focusOutClearSelection()
input2.setParentItem(view.rootItem());
input.setParentItem(view.rootItem());
view.show();
- QApplication::setActiveWindow(&view);
+ view.requestActivateWindow();
QTest::qWaitForWindowShown(&view);
input.select(2,5);
//The selection should work
QTRY_COMPARE(input.selectedText(), QLatin1String("llo"));
input2.setFocus(true);
- QApplication::processEvents();
+ QGuiApplication::processEvents();
//The input lost the focus selection should be cleared
QTRY_COMPARE(input.selectedText(), QLatin1String(""));
}
void tst_qsgtextinput::geometrySignals()
{
- QDeclarativeComponent component(&engine, SRCDIR "/data/geometrySignals.qml");
+ QDeclarativeComponent component(&engine, TESTDATA("geometrySignals.qml"));
QObject *o = component.create();
QVERIFY(o);
QCOMPARE(o->property("bindingWidth").toInt(), 400);
@@ -2349,9 +2275,13 @@ void tst_qsgtextinput::testQtQuick11Attributes_data()
void tst_qsgtextinput::preeditAutoScroll()
{
+#ifdef QTBUG_21691
+ QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
+ QVERIFY(false);
+#else
QString preeditText = "califragisiticexpialidocious!";
- QSGView view(QUrl::fromLocalFile(SRCDIR "/data/preeditAutoScroll.qml"));
+ QSGView view(QUrl::fromLocalFile(TESTDATA("preeditAutoScroll.qml")));
MyInputContext ic;
// QSGCanvas won't set the Qt::WA_InputMethodEnabled flag unless a suitable item has active focus
// and QWidget won't allow an input context to be set when the flag is not set.
@@ -2359,9 +2289,9 @@ void tst_qsgtextinput::preeditAutoScroll()
view.setInputContext(&ic);
view.setAttribute(Qt::WA_InputMethodEnabled, false);
view.show();
- QApplication::setActiveWindow(&view);
+ view.requestActivateWindow();
QTest::qWaitForWindowShown(&view);
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
+ QTRY_COMPARE(&view, qGuiApp->focusWindow());
QSGTextInput *input = qobject_cast<QSGTextInput *>(view.rootObject());
QVERIFY(input);
@@ -2431,13 +2361,18 @@ void tst_qsgtextinput::preeditAutoScroll()
ic.sendPreeditText(preeditText.mid(0, 3), 1);
QCOMPARE(input->positionAt(0), 0);
QCOMPARE(input->positionAt(input->width()), 5);
+#endif
}
void tst_qsgtextinput::preeditMicroFocus()
{
+#ifdef QTBUG_21691
+ QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
+ QVERIFY(false);
+#else
QString preeditText = "super";
- QSGView view(QUrl::fromLocalFile(SRCDIR "/data/inputMethodEvent.qml"));
+ QSGView view(QUrl::fromLocalFile(TESTDATA("inputMethodEvent.qml")));
MyInputContext ic;
// QSGCanvas won't set the Qt::WA_InputMethodEnabled flag unless a suitable item has active focus
// and QWidget won't allow an input context to be set when the flag is not set.
@@ -2445,22 +2380,22 @@ void tst_qsgtextinput::preeditMicroFocus()
view.setInputContext(&ic);
view.setAttribute(Qt::WA_InputMethodEnabled, false);
view.show();
- QApplication::setActiveWindow(&view);
+ view.requestActivateWindow();
QTest::qWaitForWindowShown(&view);
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
+ QTRY_COMPARE(&view, qGuiApp->focusWindow());
QSGTextInput *input = qobject_cast<QSGTextInput *>(view.rootObject());
QVERIFY(input);
QRect currentRect;
- QRect previousRect = input->inputMethodQuery(Qt::ImMicroFocus).toRect();
+ QRect previousRect = input->inputMethodQuery(Qt::ImCursorRectangle).toRect();
// Verify that the micro focus rect is positioned the same for position 0 as
// it would be if there was no preedit text.
ic.updateReceived = false;
ic.sendPreeditText(preeditText, 0);
- currentRect = input->inputMethodQuery(Qt::ImMicroFocus).toRect();
+ currentRect = input->inputMethodQuery(Qt::ImCursorRectangle).toRect();
QCOMPARE(currentRect, previousRect);
-#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
QCOMPARE(ic.updateReceived, true);
#endif
@@ -2469,9 +2404,9 @@ void tst_qsgtextinput::preeditMicroFocus()
for (int i = 1; i <= 5; ++i) {
ic.updateReceived = false;
ic.sendPreeditText(preeditText, i);
- currentRect = input->inputMethodQuery(Qt::ImMicroFocus).toRect();
+ currentRect = input->inputMethodQuery(Qt::ImCursorRectangle).toRect();
QVERIFY(previousRect.left() < currentRect.left());
-#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
QCOMPARE(ic.updateReceived, true);
#endif
previousRect = currentRect;
@@ -2482,18 +2417,23 @@ void tst_qsgtextinput::preeditMicroFocus()
ic.sendPreeditText(preeditText, 0);
ic.updateReceived = false;
ic.sendEvent(QInputMethodEvent(preeditText, QList<QInputMethodEvent::Attribute>()));
- currentRect = input->inputMethodQuery(Qt::ImMicroFocus).toRect();
+ currentRect = input->inputMethodQuery(Qt::ImCursorRectangle).toRect();
QCOMPARE(currentRect, previousRect);
-#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
QCOMPARE(ic.updateReceived, true);
#endif
+#endif
}
void tst_qsgtextinput::inputContextMouseHandler()
{
+#ifdef QTBUG_21691
+ QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
+ QVERIFY(false);
+#else
QString text = "supercalifragisiticexpialidocious!";
- QSGView view(QUrl::fromLocalFile(SRCDIR "/data/inputContext.qml"));
+ QSGView view(QUrl::fromLocalFile(TESTDATA("inputContext.qml")));
MyInputContext ic;
// QSGCanvas won't set the Qt::WA_InputMethodEnabled flag unless a suitable item has active focus
// and QWidget won't allow an input context to be set when the flag is not set.
@@ -2501,9 +2441,9 @@ void tst_qsgtextinput::inputContextMouseHandler()
view.setInputContext(&ic);
view.setAttribute(Qt::WA_InputMethodEnabled, false);
view.show();
- QApplication::setActiveWindow(&view);
+ view.requestActivateWindow();
QTest::qWaitForWindowShown(&view);
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
+ QTRY_COMPARE(&view, qGuiApp->focusWindow());
QSGTextInput *input = qobject_cast<QSGTextInput *>(view.rootObject());
QVERIFY(input);
@@ -2540,11 +2480,11 @@ void tst_qsgtextinput::inputContextMouseHandler()
ic.eventType = QEvent::None;
{ QMouseEvent mv(QEvent::MouseMove, position8, globalposition8, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
- QApplication::sendEvent(&view, &mv); }
+ QGuiApplication::sendEvent(&view, &mv); }
QCOMPARE(ic.eventType, QEvent::None);
{ QMouseEvent mv(QEvent::MouseMove, position27, globalposition27, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
- QApplication::sendEvent(&view, &mv); }
+ QGuiApplication::sendEvent(&view, &mv); }
QCOMPARE(ic.eventType, QEvent::MouseMove);
QCOMPARE(ic.eventPosition, position27);
QCOMPARE(ic.eventGlobalPosition, globalposition27);
@@ -2582,7 +2522,7 @@ void tst_qsgtextinput::inputContextMouseHandler()
ic.eventType = QEvent::None;
{ QMouseEvent mv(QEvent::MouseMove, position20, globalposition20, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
- QApplication::sendEvent(&view, &mv); }
+ QGuiApplication::sendEvent(&view, &mv); }
QCOMPARE(ic.eventType, QEvent::MouseMove);
QCOMPARE(ic.eventPosition, position20);
QCOMPARE(ic.eventGlobalPosition, globalposition20);
@@ -2592,7 +2532,7 @@ void tst_qsgtextinput::inputContextMouseHandler()
ic.eventType = QEvent::None;
{ QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
- QApplication::sendEvent(&view, &mv); }
+ QGuiApplication::sendEvent(&view, &mv); }
QCOMPARE(ic.eventType, QEvent::None);
QTest::mouseRelease(&view, Qt::RightButton, Qt::ControlModifier, position2);
@@ -2603,17 +2543,18 @@ void tst_qsgtextinput::inputContextMouseHandler()
QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
QVERIFY(ic.cursor < 0);
ic.eventType = QEvent::None;
+#endif
}
void tst_qsgtextinput::inputMethodComposing()
{
QString text = "supercalifragisiticexpialidocious!";
- QSGView view(QUrl::fromLocalFile(SRCDIR "/data/inputContext.qml"));
+ QSGView view(QUrl::fromLocalFile(TESTDATA("inputContext.qml")));
view.show();
- QApplication::setActiveWindow(&view);
+ view.requestActivateWindow();
QTest::qWaitForWindowShown(&view);
- QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
+ QTRY_COMPARE(&view, qGuiApp->focusWindow());
QSGTextInput *input = qobject_cast<QSGTextInput *>(view.rootObject());
QVERIFY(input);
QSignalSpy spy(input, SIGNAL(inputMethodComposingChanged()));
@@ -2621,20 +2562,20 @@ void tst_qsgtextinput::inputMethodComposing()
QCOMPARE(input->isInputMethodComposing(), false);
{
QInputMethodEvent event(text.mid(3), QList<QInputMethodEvent::Attribute>());
- QApplication::sendEvent(&view, &event);
+ QGuiApplication::sendEvent(input, &event);
}
QCOMPARE(input->isInputMethodComposing(), true);
QCOMPARE(spy.count(), 1);
{
QInputMethodEvent event(text.mid(12), QList<QInputMethodEvent::Attribute>());
- QApplication::sendEvent(&view, &event);
+ QGuiApplication::sendEvent(input, &event);
}
QCOMPARE(spy.count(), 1);
{
QInputMethodEvent event;
- QApplication::sendEvent(&view, &event);
+ QGuiApplication::sendEvent(input, &event);
}
QCOMPARE(input->isInputMethodComposing(), false);
QCOMPARE(spy.count(), 2);
@@ -2642,19 +2583,21 @@ void tst_qsgtextinput::inputMethodComposing()
void tst_qsgtextinput::cursorRectangleSize()
{
- QSGView *canvas = new QSGView(QUrl::fromLocalFile(SRCDIR "/data/positionAt.qml"));
+ QSGView *canvas = new QSGView(QUrl::fromLocalFile(TESTDATA("positionAt.qml")));
QVERIFY(canvas->rootObject() != 0);
canvas->show();
- canvas->setFocus();
- QApplication::setActiveWindow(canvas);
+ canvas->requestActivateWindow();
QTest::qWaitForWindowShown(canvas);
QSGTextInput *textInput = qobject_cast<QSGTextInput *>(canvas->rootObject());
QVERIFY(textInput != 0);
textInput->setFocus(Qt::OtherFocusReason);
QRectF cursorRect = textInput->positionToRectangle(textInput->cursorPosition());
- QRectF microFocusFromScene = canvas->inputMethodQuery(Qt::ImMicroFocus).toRectF();
- QRectF microFocusFromApp= QApplication::focusWidget()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
+ QRectF microFocusFromScene = canvas->inputMethodQuery(Qt::ImCursorRectangle).toRectF();
+ QInputMethodQueryEvent event(Qt::ImCursorRectangle);
+ qApp->sendEvent(qApp->inputPanel()->inputItem(), &event);
+
+ QRectF microFocusFromApp = event.value(Qt::ImCursorRectangle).toRectF();
QCOMPARE(microFocusFromScene.size(), cursorRect.size());
QCOMPARE(microFocusFromApp.size(), cursorRect.size());
@@ -2662,6 +2605,48 @@ void tst_qsgtextinput::cursorRectangleSize()
delete canvas;
}
+void tst_qsgtextinput::tripleClickSelectsAll()
+{
+ QString qmlfile = TESTDATA("positionAt.qml");
+ QSGView view(QUrl::fromLocalFile(qmlfile));
+ view.show();
+ view.requestActivateWindow();
+ QTest::qWaitForWindowShown(&view);
+
+ QTRY_COMPARE(&view, qGuiApp->focusWindow());
+
+ QSGTextInput* input = qobject_cast<QSGTextInput*>(view.rootObject());
+ QVERIFY(input);
+
+ QLatin1String hello("Hello world!");
+ input->setSelectByMouse(true);
+ input->setText(hello);
+
+ // Clicking on the same point inside TextInput three times in a row
+ // should trigger a triple click, thus selecting all the text.
+ QPoint pointInside = input->pos().toPoint() + QPoint(2,2);
+ QTest::mouseDClick(&view, Qt::LeftButton, 0, pointInside);
+ QTest::mouseClick(&view, Qt::LeftButton, 0, pointInside);
+ QGuiApplication::processEvents();
+ QCOMPARE(input->selectedText(), hello);
+
+ // Now it simulates user moving the mouse between the second and the third click.
+ // In this situation, we don't expect a triple click.
+ QPoint pointInsideButFar = QPoint(input->width(),input->height()) - QPoint(2,2);
+ QTest::mouseDClick(&view, Qt::LeftButton, 0, pointInside);
+ QTest::mouseClick(&view, Qt::LeftButton, 0, pointInsideButFar);
+ QGuiApplication::processEvents();
+ QVERIFY(input->selectedText().isEmpty());
+
+ // And now we press the third click too late, so no triple click event is triggered.
+ QTest::mouseDClick(&view, Qt::LeftButton, 0, pointInside);
+ QGuiApplication::processEvents();
+ QTest::qWait(QApplication::doubleClickInterval() + 1);
+ QTest::mouseClick(&view, Qt::LeftButton, 0, pointInside);
+ QGuiApplication::processEvents();
+ QVERIFY(input->selectedText().isEmpty());
+}
+
QTEST_MAIN(tst_qsgtextinput)
#include "tst_qsgtextinput.moc"
diff --git a/tests/auto/declarative/qsgview/qsgview.pro b/tests/auto/declarative/qsgview/qsgview.pro
index e6cb0785bb..dd67cff632 100644
--- a/tests/auto/declarative/qsgview/qsgview.pro
+++ b/tests/auto/declarative/qsgview/qsgview.pro
@@ -1,14 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui
+CONFIG += testcase
+TARGET = tst_qsgview
macx:CONFIG -= app_bundle
SOURCES += tst_qsgview.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-QT += core-private gui-private declarative-private
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qsgview/tst_qsgview.cpp b/tests/auto/declarative/qsgview/tst_qsgview.cpp
index 1e2e06375b..d2c51d60e9 100644
--- a/tests/auto/declarative/qsgview/tst_qsgview.cpp
+++ b/tests/auto/declarative/qsgview/tst_qsgview.cpp
@@ -44,16 +44,11 @@
#include <QtDeclarative/qdeclarativecontext.h>
#include <QtDeclarative/qsgview.h>
#include <QtDeclarative/qsgitem.h>
-#include "../../../shared/util.h"
+#include "../shared/util.h"
#include <QtGui/QWindow>
#include <QtCore/QDebug>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
class tst_QSGView : public QObject
-
{
Q_OBJECT
public:
@@ -78,7 +73,7 @@ void tst_QSGView::resizemodeitem()
QVERIFY(canvas);
canvas->setResizeMode(QSGView::SizeRootObjectToView);
QCOMPARE(QSize(0,0), canvas->initialSize());
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/resizemodeitem.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizemodeitem.qml")));
QSGItem* item = qobject_cast<QSGItem*>(canvas->rootObject());
QVERIFY(item);
window.show();
@@ -92,13 +87,9 @@ void tst_QSGView::resizemodeitem()
QCOMPARE(canvas->size(), canvas->sizeHint());
QCOMPARE(canvas->size(), canvas->initialSize());
- qDebug() << window.size();
- qDebug() << "canvas size:" << canvas->size();
// size update from view
canvas->resize(QSize(80,100));
QTest::qWait(50);
- qDebug() << window.size();
- qDebug() << "canvas size:" << canvas->size();
QCOMPARE(item->width(), 80.0);
QCOMPARE(item->height(), 100.0);
@@ -129,7 +120,7 @@ void tst_QSGView::resizemodeitem()
canvas = new QSGView(&window);
QVERIFY(canvas);
canvas->setResizeMode(QSGView::SizeViewToRootObject);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/resizemodeitem.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizemodeitem.qml")));
item = qobject_cast<QSGItem*>(canvas->rootObject());
QVERIFY(item);
window.show();
@@ -176,7 +167,7 @@ void tst_QSGView::resizemodeitem()
canvas->resize(300, 300);
canvas->setResizeMode(QSGView::SizeRootObjectToView);
QCOMPARE(QSize(0,0), canvas->initialSize());
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/resizemodeitem.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizemodeitem.qml")));
canvas->resize(300, 300);
item = qobject_cast<QSGItem*>(canvas->rootObject());
QVERIFY(item);
@@ -186,6 +177,7 @@ void tst_QSGView::resizemodeitem()
QTest::qWait(50);
// initial size from root object
+ QEXPECT_FAIL("", "QTBUG-22019", Abort);
QCOMPARE(item->width(), 300.0);
QCOMPARE(item->height(), 300.0);
QCOMPARE(canvas->size(), QSize(300, 300));
@@ -204,7 +196,7 @@ void tst_QSGView::errors()
QSGView *canvas = new QSGView;
QVERIFY(canvas);
QtMsgHandler old = qInstallMsgHandler(silentErrorsMsgHandler);
- canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/error1.qml"));
+ canvas->setSource(QUrl::fromLocalFile(TESTDATA("error1.qml")));
qInstallMsgHandler(old);
QVERIFY(canvas->status() == QSGView::Error);
QVERIFY(canvas->errors().count() == 1);
diff --git a/tests/auto/declarative/qsgvisualdatamodel/data/create.qml b/tests/auto/declarative/qsgvisualdatamodel/data/create.qml
new file mode 100644
index 0000000000..36ea3baf76
--- /dev/null
+++ b/tests/auto/declarative/qsgvisualdatamodel/data/create.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.0
+
+ListView {
+ width: 200
+ height: 200
+
+ model: VisualDataModel {
+ id: visualModel
+
+ model: myModel
+ delegate: Item {
+ id: delegate
+ objectName: "delegate"
+ width: 200
+ height: 20
+
+ property bool destroyed: false
+
+ Component.onDestruction: destroyed = true
+ }
+ }
+}
diff --git a/tests/auto/declarative/qsgvisualdatamodel/data/groups.qml b/tests/auto/declarative/qsgvisualdatamodel/data/groups.qml
new file mode 100644
index 0000000000..a24e223bc5
--- /dev/null
+++ b/tests/auto/declarative/qsgvisualdatamodel/data/groups.qml
@@ -0,0 +1,40 @@
+import QtQuick 2.0
+
+ListView {
+ width: 100
+ height: 100
+
+ function contains(array, value) {
+ for (var i = 0; i < array.length; ++i)
+ if (array[i] == value)
+ return true
+ return false
+ }
+
+ model: VisualDataModel {
+ groups: [
+ VisualDataGroup { id: visibleItems; objectName: "visibleItems"; name: "visible"; includeByDefault: true },
+ VisualDataGroup { id: selectedItems; objectName: "selectedItems"; name: "selected" }
+ ]
+
+ model: myModel
+ delegate: Item {
+ id: delegate
+ objectName: "delegate"
+ width: 100
+ height: 2
+ property variant test1: name
+ property variant test2: index
+ property variant test3: VisualDataModel.itemsIndex
+ property variant test4: VisualDataModel.inItems
+ property variant test5: VisualDataModel.visibleIndex
+ property variant test6: VisualDataModel.inVisible
+ property variant test7: VisualDataModel.selectedIndex
+ property variant test8: VisualDataModel.inSelected
+ property variant test9: VisualDataModel.groups
+
+ function hide() { VisualDataModel.inVisible = false }
+ function select() { VisualDataModel.inSelected = true }
+ }
+ }
+}
diff --git a/tests/auto/declarative/qsgvisualdatamodel/qsgvisualdatamodel.pro b/tests/auto/declarative/qsgvisualdatamodel/qsgvisualdatamodel.pro
index 31047068d7..1e8b8a29d3 100644
--- a/tests/auto/declarative/qsgvisualdatamodel/qsgvisualdatamodel.pro
+++ b/tests/auto/declarative/qsgvisualdatamodel/qsgvisualdatamodel.pro
@@ -1,16 +1,13 @@
-load(qttest_p4)
+CONFIG += testcase
+TARGET = tst_qsgvisualdatamodel
macx:CONFIG -= app_bundle
SOURCES += tst_qsgvisualdatamodel.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
CONFIG += parallel_test
-QT += core-private gui-private v8-private declarative-private widgets
+QT += core-private gui-private v8-private declarative-private widgets testlib
diff --git a/tests/auto/declarative/qsgvisualdatamodel/tst_qsgvisualdatamodel.cpp b/tests/auto/declarative/qsgvisualdatamodel/tst_qsgvisualdatamodel.cpp
index bd17deb777..019493109d 100644
--- a/tests/auto/declarative/qsgvisualdatamodel/tst_qsgvisualdatamodel.cpp
+++ b/tests/auto/declarative/qsgvisualdatamodel/tst_qsgvisualdatamodel.cpp
@@ -38,7 +38,7 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include "../../../shared/util.h"
+#include "../shared/util.h"
#include <qtest.h>
#include <QtTest/QSignalSpy>
#include <QStandardItemModel>
@@ -52,13 +52,10 @@
#include <private/qsgvisualdatamodel_p.h>
#include <private/qdeclarativevaluetype_p.h>
#include <private/qdeclarativechangeset_p.h>
+#include <private/qdeclarativeengine_p.h>
#include <math.h>
-#include <QtOpenGL/QGLShaderProgram>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
+template <typename T, int N> int lengthOf(const T (&)[N]) { return N; }
static void initStandardTreeModel(QStandardItemModel *model)
{
@@ -133,8 +130,36 @@ private slots:
void noDelegate();
void qaimRowsMoved();
void qaimRowsMoved_data();
+ void remove();
+ void move();
+ void groups();
+ void get();
+ void create();
private:
+ template <int N> void groups_verify(
+ const SingleRoleModel &model,
+ QSGItem *contentItem,
+ const int (&mIndex)[N],
+ const int (&iIndex)[N],
+ const int (&vIndex)[N],
+ const int (&sIndex)[N],
+ const bool (&vMember)[N],
+ const bool (&sMember)[N]);
+
+ template <int N> void get_verify(
+ const SingleRoleModel &model,
+ QSGVisualDataModel *visualModel,
+ QSGVisualDataGroup *visibleItems,
+ QSGVisualDataGroup *selectedItems,
+ const int (&mIndex)[N],
+ const int (&iIndex)[N],
+ const int (&vIndex)[N],
+ const int (&sIndex)[N],
+ const bool (&vMember)[N],
+ const bool (&sMember)[N]);
+
+ bool failed;
QDeclarativeEngine engine;
template<typename T>
T *findItem(QSGItem *parent, const QString &objectName, int index);
@@ -189,6 +214,23 @@ private:
QString m_color;
};
+template <typename T> static T evaluate(QObject *scope, const QString &expression)
+{
+ QDeclarativeExpression expr(qmlContext(scope), scope, expression);
+ T result = expr.evaluate().value<T>();
+ if (expr.hasError())
+ qWarning() << expr.error().toString();
+ return result;
+}
+
+template <> void evaluate<void>(QObject *scope, const QString &expression)
+{
+ QDeclarativeExpression expr(qmlContext(scope), scope, expression);
+ expr.evaluate();
+ if (expr.hasError())
+ qWarning() << expr.error().toString();
+}
+
tst_qsgvisualdatamodel::tst_qsgvisualdatamodel()
{
}
@@ -196,7 +238,7 @@ tst_qsgvisualdatamodel::tst_qsgvisualdatamodel()
void tst_qsgvisualdatamodel::rootIndex()
{
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/visualdatamodel.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("visualdatamodel.qml")));
QStandardItemModel model;
initStandardTreeModel(&model);
@@ -229,7 +271,7 @@ void tst_qsgvisualdatamodel::updateLayout()
view.rootContext()->setContextProperty("myModel", &model);
- view.setSource(QUrl::fromLocalFile(SRCDIR "/data/datalist.qml"));
+ view.setSource(QUrl::fromLocalFile(TESTDATA("datalist.qml")));
QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
QVERIFY(listview != 0);
@@ -269,7 +311,7 @@ void tst_qsgvisualdatamodel::childChanged()
view.rootContext()->setContextProperty("myModel", &model);
- view.setSource(QUrl::fromLocalFile(SRCDIR "/data/datalist.qml"));
+ view.setSource(QUrl::fromLocalFile(TESTDATA("datalist.qml")));
QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
QVERIFY(listview != 0);
@@ -328,7 +370,7 @@ void tst_qsgvisualdatamodel::objectListModel()
QDeclarativeContext *ctxt = view.rootContext();
ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
- view.setSource(QUrl::fromLocalFile(SRCDIR "/data/objectlist.qml"));
+ view.setSource(QUrl::fromLocalFile(TESTDATA("objectlist.qml")));
QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
QVERIFY(listview != 0);
@@ -356,7 +398,7 @@ void tst_qsgvisualdatamodel::singleRole()
QDeclarativeContext *ctxt = view.rootContext();
ctxt->setContextProperty("myModel", &model);
- view.setSource(QUrl::fromLocalFile(SRCDIR "/data/singlerole1.qml"));
+ view.setSource(QUrl::fromLocalFile(TESTDATA("singlerole1.qml")));
QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
QVERIFY(listview != 0);
@@ -378,7 +420,7 @@ void tst_qsgvisualdatamodel::singleRole()
QDeclarativeContext *ctxt = view.rootContext();
ctxt->setContextProperty("myModel", &model);
- view.setSource(QUrl::fromLocalFile(SRCDIR "/data/singlerole2.qml"));
+ view.setSource(QUrl::fromLocalFile(TESTDATA("singlerole2.qml")));
QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
QVERIFY(listview != 0);
@@ -400,7 +442,7 @@ void tst_qsgvisualdatamodel::singleRole()
QDeclarativeContext *ctxt = view.rootContext();
ctxt->setContextProperty("myModel", &model);
- view.setSource(QUrl::fromLocalFile(SRCDIR "/data/singlerole2.qml"));
+ view.setSource(QUrl::fromLocalFile(TESTDATA("singlerole2.qml")));
QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
QVERIFY(listview != 0);
@@ -426,7 +468,7 @@ void tst_qsgvisualdatamodel::modelProperties()
QDeclarativeContext *ctxt = view.rootContext();
ctxt->setContextProperty("myModel", &model);
- view.setSource(QUrl::fromLocalFile(SRCDIR "/data/modelproperties.qml"));
+ view.setSource(QUrl::fromLocalFile(TESTDATA("modelproperties.qml")));
QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
QVERIFY(listview != 0);
@@ -459,7 +501,7 @@ void tst_qsgvisualdatamodel::modelProperties()
QDeclarativeContext *ctxt = view.rootContext();
ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
- view.setSource(QUrl::fromLocalFile(SRCDIR "/data/modelproperties.qml"));
+ view.setSource(QUrl::fromLocalFile(TESTDATA("modelproperties.qml")));
QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
QVERIFY(listview != 0);
@@ -488,7 +530,7 @@ void tst_qsgvisualdatamodel::modelProperties()
view.rootContext()->setContextProperty("myModel", &model);
- QUrl source(QUrl::fromLocalFile(SRCDIR "/data/modelproperties2.qml"));
+ QUrl source(QUrl::fromLocalFile(TESTDATA("modelproperties2.qml")));
//3 items, 3 warnings each
QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData");
@@ -534,7 +576,7 @@ void tst_qsgvisualdatamodel::noDelegate()
view.rootContext()->setContextProperty("myModel", &model);
- view.setSource(QUrl::fromLocalFile(SRCDIR "/data/datalist.qml"));
+ view.setSource(QUrl::fromLocalFile(TESTDATA("datalist.qml")));
QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
QVERIFY(listview != 0);
@@ -560,7 +602,7 @@ void tst_qsgvisualdatamodel::qaimRowsMoved()
QFETCH(int, expectCount);
QDeclarativeEngine engine;
- QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/visualdatamodel.qml"));
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("visualdatamodel.qml")));
SingleRoleModel model;
model.list.clear();
@@ -627,6 +669,859 @@ void tst_qsgvisualdatamodel::qaimRowsMoved_data()
<< 10 << 1 << 5;
}
+void tst_qsgvisualdatamodel::remove()
+{
+ QSGView view;
+
+ SingleRoleModel model;
+ model.list = QStringList()
+ << "one"
+ << "two"
+ << "three"
+ << "four"
+ << "five"
+ << "six"
+ << "seven"
+ << "eight"
+ << "nine"
+ << "ten"
+ << "eleven"
+ << "twelve";
+
+ QDeclarativeContext *ctxt = view.rootContext();
+ ctxt->setContextProperty("myModel", &model);
+
+ view.setSource(QUrl::fromLocalFile(TESTDATA("groups.qml")));
+
+ QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
+ QVERIFY(listview != 0);
+
+ QSGItem *contentItem = listview->contentItem();
+ QVERIFY(contentItem != 0);
+
+ QSGVisualDataModel *visualModel = qobject_cast<QSGVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
+ QVERIFY(visualModel);
+
+ {
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+
+ for (int i = 0; i < lengthOf(mIndex); ++i) {
+ QSGItem *delegate = findItem<QSGItem>(contentItem, "delegate", mIndex[i]);
+ QVERIFY(delegate);
+ QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
+ QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
+ QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
+ }
+ } {
+ evaluate<void>(visualModel, "items.remove(2)");
+ QCOMPARE(listview->count(), 11);
+ QCOMPARE(visualModel->items()->count(), 11);
+ static const int mIndex[] = { 0, 1, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10 };
+
+ for (int i = 0; i < lengthOf(mIndex); ++i) {
+ QSGItem *delegate = findItem<QSGItem>(contentItem, "delegate", mIndex[i]);
+ QVERIFY(delegate);
+ QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
+ QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
+ QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
+ }
+ } {
+ evaluate<void>(visualModel, "items.remove(1, 4)");
+ QCOMPARE(listview->count(), 7);
+ QCOMPARE(visualModel->items()->count(), 7);
+ static const int mIndex[] = { 0, 6, 7, 8, 9,10,11 };
+ static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6 };
+
+ for (int i = 0; i < lengthOf(mIndex); ++i) {
+ QSGItem *delegate = findItem<QSGItem>(contentItem, "delegate", mIndex[i]);
+ QVERIFY(delegate);
+ QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
+ QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
+ QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
+ }
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: index out of range");
+ evaluate<void>(visualModel, "items.remove(-8, 4)");
+ QCOMPARE(listview->count(), 7);
+ QCOMPARE(visualModel->items()->count(), 7);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: index out of range");
+ evaluate<void>(visualModel, "items.remove(12, 2)");
+ QCOMPARE(listview->count(), 7);
+ QCOMPARE(visualModel->items()->count(), 7);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: index out of range");
+ evaluate<void>(visualModel, "items.remove(5, 3)");
+ QCOMPARE(listview->count(), 7);
+ QCOMPARE(visualModel->items()->count(), 7);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: remove: invalid count");
+ evaluate<void>(visualModel, "items.remove(5, -2)");
+ QCOMPARE(listview->count(), 7);
+ QCOMPARE(visualModel->items()->count(), 7);
+ }
+}
+
+void tst_qsgvisualdatamodel::move()
+{
+ QSGView view;
+
+ SingleRoleModel model;
+ model.list = QStringList()
+ << "one"
+ << "two"
+ << "three"
+ << "four"
+ << "five"
+ << "six"
+ << "seven"
+ << "eight"
+ << "nine"
+ << "ten"
+ << "eleven"
+ << "twelve";
+
+ QDeclarativeContext *ctxt = view.rootContext();
+ ctxt->setContextProperty("myModel", &model);
+
+ view.setSource(QUrl::fromLocalFile(TESTDATA("groups.qml")));
+
+ QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
+ QVERIFY(listview != 0);
+
+ QSGItem *contentItem = listview->contentItem();
+ QVERIFY(contentItem != 0);
+
+ QSGVisualDataModel *visualModel = qobject_cast<QSGVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
+ QVERIFY(visualModel);
+
+ {
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+
+ for (int i = 0; i < lengthOf(mIndex); ++i) {
+ QSGItem *delegate = findItem<QSGItem>(contentItem, "delegate", mIndex[i]);
+ QVERIFY(delegate);
+ QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
+ QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
+ QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
+ }
+ } {
+ evaluate<void>(visualModel, "items.move(2, 4)");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ static const int mIndex[] = { 0, 1, 3, 4, 2, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+
+ for (int i = 0; i < lengthOf(mIndex); ++i) {
+ QSGItem *delegate = findItem<QSGItem>(contentItem, "delegate", mIndex[i]);
+ QVERIFY(delegate);
+ QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
+ QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
+ QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
+ }
+ } {
+ evaluate<void>(visualModel, "items.move(4, 2)");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+
+ for (int i = 0; i < lengthOf(mIndex); ++i) {
+ QSGItem *delegate = findItem<QSGItem>(contentItem, "delegate", mIndex[i]);
+ QVERIFY(delegate);
+ QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
+ QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
+ QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
+ }
+ } {
+ evaluate<void>(visualModel, "items.move(8, 0, 4)");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ static const int mIndex[] = { 8, 9,10,11, 0, 1, 2, 3, 4, 5, 6, 7 };
+ static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+
+ for (int i = 0; i < lengthOf(mIndex); ++i) {
+ QSGItem *delegate = findItem<QSGItem>(contentItem, "delegate", mIndex[i]);
+ QVERIFY(delegate);
+ QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
+ QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
+ QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
+ }
+ } {
+ evaluate<void>(visualModel, "items.move(3, 4, 5)");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ static const int mIndex[] = { 8, 9,10,4, 11, 0, 1, 2, 3, 5, 6, 7 };
+ static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+
+ for (int i = 0; i < lengthOf(mIndex); ++i) {
+ QSGItem *delegate = findItem<QSGItem>(contentItem, "delegate", mIndex[i]);
+ QVERIFY(delegate);
+ QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
+ QCOMPARE(delegate->property("test2").toInt(), mIndex[i]);
+ QCOMPARE(delegate->property("test3").toInt(), iIndex[i]);
+ }
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: invalid count");
+ evaluate<void>(visualModel, "items.move(5, 2, -2)");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: from index out of range");
+ evaluate<void>(visualModel, "items.move(-6, 2, 1)");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: from index out of range");
+ evaluate<void>(visualModel, "items.move(15, 2, 1)");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: from index out of range");
+ evaluate<void>(visualModel, "items.move(11, 1, 3)");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: to index out of range");
+ evaluate<void>(visualModel, "items.move(2, -5, 1)");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: to index out of range");
+ evaluate<void>(visualModel, "items.move(2, 14, 1)");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: move: to index out of range");
+ evaluate<void>(visualModel, "items.move(2, 11, 4)");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ }
+}
+
+
+template <int N> void tst_qsgvisualdatamodel::groups_verify(
+ const SingleRoleModel &model,
+ QSGItem *contentItem,
+ const int (&mIndex)[N],
+ const int (&iIndex)[N],
+ const int (&vIndex)[N],
+ const int (&sIndex)[N],
+ const bool (&vMember)[N],
+ const bool (&sMember)[N])
+{
+ failed = true;
+ for (int i = 0; i < N; ++i) {
+ QSGItem *delegate = findItem<QSGItem>(contentItem, "delegate", mIndex[i]);
+ QVERIFY(delegate);
+ QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i]));
+ QCOMPARE(delegate->property("test2").toInt() , mIndex[i]);
+ QCOMPARE(delegate->property("test3").toInt() , iIndex[i]);
+ QCOMPARE(delegate->property("test4").toBool(), true);
+ QCOMPARE(delegate->property("test5").toInt() , vIndex[i]);
+ QCOMPARE(delegate->property("test6").toBool(), vMember[i]);
+ QCOMPARE(delegate->property("test7").toInt() , sIndex[i]);
+ QCOMPARE(delegate->property("test8").toBool(), sMember[i]);
+ QCOMPARE(delegate->property("test9").toStringList().contains("items") , QBool(true));
+ QCOMPARE(delegate->property("test9").toStringList().contains("visible") , QBool(vMember[i]));
+ QCOMPARE(delegate->property("test9").toStringList().contains("selected"), QBool(sMember[i]));
+ }
+ failed = false;
+}
+
+#define VERIFY_GROUPS \
+ groups_verify(model, contentItem, mIndex, iIndex, vIndex, sIndex, vMember, sMember); \
+ QVERIFY(!failed)
+
+
+void tst_qsgvisualdatamodel::groups()
+{
+ QSGView view;
+
+ SingleRoleModel model;
+ model.list = QStringList()
+ << "one"
+ << "two"
+ << "three"
+ << "four"
+ << "five"
+ << "six"
+ << "seven"
+ << "eight"
+ << "nine"
+ << "ten"
+ << "eleven"
+ << "twelve";
+
+ QDeclarativeContext *ctxt = view.rootContext();
+ ctxt->setContextProperty("myModel", &model);
+
+ view.setSource(QUrl::fromLocalFile(TESTDATA("groups.qml")));
+
+ QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
+ QVERIFY(listview != 0);
+
+ QSGItem *contentItem = listview->contentItem();
+ QVERIFY(contentItem != 0);
+
+ QSGVisualDataModel *visualModel = qobject_cast<QSGVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
+ QVERIFY(visualModel);
+
+ QSGVisualDataGroup *visibleItems = visualModel->findChild<QSGVisualDataGroup *>("visibleItems");
+ QVERIFY(visibleItems);
+
+ QSGVisualDataGroup *selectedItems = visualModel->findChild<QSGVisualDataGroup *>("selectedItems");
+ QVERIFY(selectedItems);
+
+ const bool f = false;
+ const bool t = true;
+
+ {
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 12);
+ QCOMPARE(selectedItems->count(), 0);
+ static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
+ static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ static const bool sMember[] = { f, f, f, f, f, f, f, f, f, f, f, f };
+ VERIFY_GROUPS;
+ } {
+ evaluate<void>(visualModel, "items.addGroups(8, \"selected\")");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 12);
+ QCOMPARE(selectedItems->count(), 1);
+ static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
+ static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 };
+ static const bool sMember[] = { f, f, f, f, f, f, f, f, t, f, f, f };
+ VERIFY_GROUPS;
+ } {
+ evaluate<void>(visualModel, "items.addGroups(6, 4, [\"visible\", \"selected\"])");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 12);
+ QCOMPARE(selectedItems->count(), 4);
+ static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
+ static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4 };
+ static const bool sMember[] = { f, f, f, f, f, f, t, t, t, t, f, f };
+ VERIFY_GROUPS;
+ } {
+ evaluate<void>(visualModel, "items.setGroups(2, [\"items\", \"selected\"])");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 11);
+ QCOMPARE(selectedItems->count(), 5);
+ static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9,10 };
+ static const bool vMember[] = { t, t, f, t, t, t, t, t, t, t, t, t };
+ static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 1, 2, 3, 4, 5, 5 };
+ static const bool sMember[] = { f, f, t, f, f, f, t, t, t, t, f, f };
+ VERIFY_GROUPS;
+ } {
+ evaluate<void>(selectedItems, "setGroups(0, 3, \"items\")");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 9);
+ QCOMPARE(selectedItems->count(), 2);
+ static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 };
+ static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t };
+ static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
+ static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
+ VERIFY_GROUPS;
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: invalid count");
+ evaluate<void>(visualModel, "items.addGroups(11, -4, \"items\")");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 9);
+ QCOMPARE(selectedItems->count(), 2);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: index out of range");
+ evaluate<void>(visualModel, "items.addGroups(-1, 3, \"items\")");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 9);
+ QCOMPARE(selectedItems->count(), 2);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: index out of range");
+ evaluate<void>(visualModel, "items.addGroups(14, 3, \"items\")");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 9);
+ QCOMPARE(selectedItems->count(), 2);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: addGroups: index out of range");
+ evaluate<void>(visualModel, "items.addGroups(11, 5, \"items\")");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 9);
+ QCOMPARE(selectedItems->count(), 2);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: invalid count");
+ evaluate<void>(visualModel, "items.setGroups(11, -4, \"items\")");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 9);
+ QCOMPARE(selectedItems->count(), 2);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: index out of range");
+ evaluate<void>(visualModel, "items.setGroups(-1, 3, \"items\")");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 9);
+ QCOMPARE(selectedItems->count(), 2);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: index out of range");
+ evaluate<void>(visualModel, "items.setGroups(14, 3, \"items\")");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 9);
+ QCOMPARE(selectedItems->count(), 2);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: setGroups: index out of range");
+ evaluate<void>(visualModel, "items.setGroups(11, 5, \"items\")");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 9);
+ QCOMPARE(selectedItems->count(), 2);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: invalid count");
+ evaluate<void>(visualModel, "items.removeGroups(11, -4, \"items\")");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: index out of range");
+ evaluate<void>(visualModel, "items.removeGroups(-1, 3, \"items\")");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 9);
+ QCOMPARE(selectedItems->count(), 2);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: index out of range");
+ evaluate<void>(visualModel, "items.removeGroups(14, 3, \"items\")");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 9);
+ QCOMPARE(selectedItems->count(), 2);
+ } {
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML VisualDataGroup: removeGroups: index out of range");
+ evaluate<void>(visualModel, "items.removeGroups(11, 5, \"items\")");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 9);
+ QCOMPARE(selectedItems->count(), 2);
+ } {
+ evaluate<void>(visualModel, "filterOnGroup = \"visible\"");
+ QCOMPARE(listview->count(), 9);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 9);
+ QCOMPARE(selectedItems->count(), 2);
+ } {
+ evaluate<void>(visualModel, "filterOnGroup = \"selected\"");
+ QCOMPARE(listview->count(), 2);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 9);
+ QCOMPARE(selectedItems->count(), 2);
+ } {
+ evaluate<void>(visualModel, "filterOnGroup = \"items\"");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 9);
+ QCOMPARE(selectedItems->count(), 2);
+ } {
+ QSGItem *delegate = findItem<QSGItem>(contentItem, "delegate", 5);
+ QVERIFY(delegate);
+
+ evaluate<void>(delegate, "hide()");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 8);
+ QCOMPARE(selectedItems->count(), 2);
+ static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
+ static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
+ static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
+ static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
+ VERIFY_GROUPS;
+ } {
+ QSGItem *delegate = findItem<QSGItem>(contentItem, "delegate", 5);
+ QVERIFY(delegate);
+
+ evaluate<void>(delegate, "select()");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 8);
+ QCOMPARE(selectedItems->count(), 3);
+ static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
+ static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
+ static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 };
+ static const bool sMember[] = { f, f, f, f, f, t, f, f, t, t, f, f };
+ VERIFY_GROUPS;
+ } {
+ evaluate<void>(visualModel, "items.move(2, 6, 3)");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 8);
+ QCOMPARE(selectedItems->count(), 3);
+ static const int mIndex [] = { 0, 1, 5, 6, 7, 8, 2, 3, 4, 9,10,11 };
+ static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int vIndex [] = { 0, 1, 2, 2, 2, 2, 3, 3, 4, 5, 6, 7 };
+ static const bool vMember[] = { t, t, f, f, f, t, f, t, t, t, t, t };
+ static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3 };
+ static const bool sMember[] = { f, f, t, f, f, t, f, f, f, t, f, f };
+ VERIFY_GROUPS;
+ }
+}
+
+template <int N> void tst_qsgvisualdatamodel::get_verify(
+ const SingleRoleModel &model,
+ QSGVisualDataModel *visualModel,
+ QSGVisualDataGroup *visibleItems,
+ QSGVisualDataGroup *selectedItems,
+ const int (&mIndex)[N],
+ const int (&iIndex)[N],
+ const int (&vIndex)[N],
+ const int (&sIndex)[N],
+ const bool (&vMember)[N],
+ const bool (&sMember)[N])
+{
+ failed = true;
+ for (int i = 0; i < N; ++i) {
+ QCOMPARE(evaluate<QString>(visualModel, QString("items.get(%1).model.name").arg(i)), model.list.at(mIndex[i]));
+ QCOMPARE(evaluate<QString>(visualModel, QString("items.get(%1).model.modelData").arg(i)), model.list.at(mIndex[i]));
+ QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).model.index").arg(i)), mIndex[i]);
+ QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).itemsIndex").arg(i)), iIndex[i]);
+ QCOMPARE(evaluate<bool>(visualModel, QString("items.get(%1).inItems").arg(i)), true);
+ QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).visibleIndex").arg(i)), vIndex[i]);
+ QCOMPARE(evaluate<bool>(visualModel, QString("items.get(%1).inVisible").arg(i)), vMember[i]);
+ QCOMPARE(evaluate<int>(visualModel, QString("items.get(%1).selectedIndex").arg(i)), sIndex[i]);
+ QCOMPARE(evaluate<bool>(visualModel, QString("items.get(%1).inSelected").arg(i)), sMember[i]);
+ QCOMPARE(evaluate<bool>(visualModel, QString("contains(items.get(%1).groups, \"items\")").arg(i)), true);
+ QCOMPARE(evaluate<bool>(visualModel, QString("contains(items.get(%1).groups, \"visible\")").arg(i)), vMember[i]);
+ QCOMPARE(evaluate<bool>(visualModel, QString("contains(items.get(%1).groups, \"selected\")").arg(i)), sMember[i]);
+
+ if (vMember[i]) {
+ QCOMPARE(evaluate<QString>(visibleItems, QString("get(%1).model.name").arg(vIndex[i])), model.list.at(mIndex[i]));
+ QCOMPARE(evaluate<QString>(visibleItems, QString("get(%1).model.modelData").arg(vIndex[i])), model.list.at(mIndex[i]));
+ QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).model.index").arg(vIndex[i])), mIndex[i]);
+ QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).itemsIndex").arg(vIndex[i])), iIndex[i]);
+ QCOMPARE(evaluate<bool>(visibleItems, QString("get(%1).inItems").arg(vIndex[i])), true);
+ QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).visibleIndex").arg(vIndex[i])), vIndex[i]);
+ QCOMPARE(evaluate<bool>(visibleItems, QString("get(%1).inVisible").arg(vIndex[i])), vMember[i]);
+ QCOMPARE(evaluate<int>(visibleItems, QString("get(%1).selectedIndex").arg(vIndex[i])), sIndex[i]);
+ QCOMPARE(evaluate<bool>(visibleItems, QString("get(%1).inSelected").arg(vIndex[i])), sMember[i]);
+
+ QCOMPARE(evaluate<bool>(visibleItems, QString("contains(get(%1).groups, \"items\")").arg(vIndex[i])), true);
+ QCOMPARE(evaluate<bool>(visibleItems, QString("contains(get(%1).groups, \"visible\")").arg(vIndex[i])), vMember[i]);
+ QCOMPARE(evaluate<bool>(visibleItems, QString("contains(get(%1).groups, \"selected\")").arg(vIndex[i])), sMember[i]);
+ }
+ if (sMember[i]) {
+ QCOMPARE(evaluate<QString>(selectedItems, QString("get(%1).model.name").arg(sIndex[i])), model.list.at(mIndex[i]));
+ QCOMPARE(evaluate<QString>(selectedItems, QString("get(%1).model.modelData").arg(sIndex[i])), model.list.at(mIndex[i]));
+ QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).model.index").arg(sIndex[i])), mIndex[i]);
+ QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).itemsIndex").arg(sIndex[i])), iIndex[i]);
+ QCOMPARE(evaluate<bool>(selectedItems, QString("get(%1).inItems").arg(sIndex[i])), true);
+ QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).visibleIndex").arg(sIndex[i])), vIndex[i]);
+ QCOMPARE(evaluate<bool>(selectedItems, QString("get(%1).inVisible").arg(sIndex[i])), vMember[i]);
+ QCOMPARE(evaluate<int>(selectedItems, QString("get(%1).selectedIndex").arg(sIndex[i])), sIndex[i]);
+ QCOMPARE(evaluate<bool>(selectedItems, QString("get(%1).inSelected").arg(sIndex[i])), sMember[i]);
+ QCOMPARE(evaluate<bool>(selectedItems, QString("contains(get(%1).groups, \"items\")").arg(sIndex[i])), true);
+ QCOMPARE(evaluate<bool>(selectedItems, QString("contains(get(%1).groups, \"visible\")").arg(sIndex[i])), vMember[i]);
+ QCOMPARE(evaluate<bool>(selectedItems, QString("contains(get(%1).groups, \"selected\")").arg(sIndex[i])), sMember[i]);
+ }
+ }
+ failed = false;
+}
+
+#define VERIFY_GET \
+ get_verify(model, visualModel, visibleItems, selectedItems, mIndex, iIndex, vIndex, sIndex, vMember, sMember); \
+ QVERIFY(!failed)
+
+void tst_qsgvisualdatamodel::get()
+{
+ QSGView view;
+
+ SingleRoleModel model;
+ model.list = QStringList()
+ << "one"
+ << "two"
+ << "three"
+ << "four"
+ << "five"
+ << "six"
+ << "seven"
+ << "eight"
+ << "nine"
+ << "ten"
+ << "eleven"
+ << "twelve";
+
+ QDeclarativeContext *ctxt = view.rootContext();
+ ctxt->setContextProperty("myModel", &model);
+
+ view.setSource(QUrl::fromLocalFile(TESTDATA("groups.qml")));
+
+ QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
+ QVERIFY(listview != 0);
+
+ QSGItem *contentItem = listview->contentItem();
+ QVERIFY(contentItem != 0);
+
+ QSGVisualDataModel *visualModel = qobject_cast<QSGVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
+ QVERIFY(visualModel);
+
+ QSGVisualDataGroup *visibleItems = visualModel->findChild<QSGVisualDataGroup *>("visibleItems");
+ QVERIFY(visibleItems);
+
+ QSGVisualDataGroup *selectedItems = visualModel->findChild<QSGVisualDataGroup *>("selectedItems");
+ QVERIFY(selectedItems);
+
+ QV8Engine *v8Engine = QDeclarativeEnginePrivate::getV8Engine(ctxt->engine());
+ QVERIFY(v8Engine);
+
+ const bool f = false;
+ const bool t = true;
+
+ {
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 12);
+ QCOMPARE(selectedItems->count(), 0);
+ static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
+ static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ static const bool sMember[] = { f, f, f, f, f, f, f, f, f, f, f, f };
+ VERIFY_GET;
+ } {
+ evaluate<void>(visualModel, "items.addGroups(8, \"selected\")");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 12);
+ QCOMPARE(selectedItems->count(), 1);
+ static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
+ static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 };
+ static const bool sMember[] = { f, f, f, f, f, f, f, f, t, f, f, f };
+ VERIFY_GET;
+ } {
+ evaluate<void>(visualModel, "items.addGroups(6, 4, [\"visible\", \"selected\"])");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 12);
+ QCOMPARE(selectedItems->count(), 4);
+ static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t };
+ static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4 };
+ static const bool sMember[] = { f, f, f, f, f, f, t, t, t, t, f, f };
+ VERIFY_GET;
+ } {
+ evaluate<void>(visualModel, "items.setGroups(2, [\"items\", \"selected\"])");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 11);
+ QCOMPARE(selectedItems->count(), 5);
+ static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9,10 };
+ static const bool vMember[] = { t, t, f, t, t, t, t, t, t, t, t, t };
+ static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 1, 2, 3, 4, 5, 5 };
+ static const bool sMember[] = { f, f, t, f, f, f, t, t, t, t, f, f };
+ VERIFY_GET;
+ } {
+ evaluate<void>(selectedItems, "setGroups(0, 3, \"items\")");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 9);
+ QCOMPARE(selectedItems->count(), 2);
+ static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 };
+ static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t };
+ static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
+ static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
+ VERIFY_GET;
+ } {
+ evaluate<void>(visualModel, "items.get(5).inVisible = false");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 8);
+ QCOMPARE(selectedItems->count(), 2);
+ static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
+ static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
+ static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
+ static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
+ VERIFY_GET;
+ } {
+ evaluate<void>(visualModel, "items.get(5).inSelected = true");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 8);
+ QCOMPARE(selectedItems->count(), 3);
+ static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 };
+ static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t };
+ static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 };
+ static const bool sMember[] = { f, f, f, f, f, t, f, f, t, t, f, f };
+ VERIFY_GET;
+ } {
+ evaluate<void>(visualModel, "items.get(5).groups = [\"visible\", \"items\"]");
+ QCOMPARE(listview->count(), 12);
+ QCOMPARE(visualModel->items()->count(), 12);
+ QCOMPARE(visibleItems->count(), 9);
+ QCOMPARE(selectedItems->count(), 2);
+ static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
+ static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 };
+ static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t };
+ static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 };
+ static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f };
+ VERIFY_GET;
+ }
+}
+
+void tst_qsgvisualdatamodel::create()
+{
+ QSGView view;
+
+ SingleRoleModel model;
+ model.list = QStringList()
+ << "one"
+ << "two"
+ << "three"
+ << "four"
+ << "five"
+ << "six"
+ << "seven"
+ << "eight"
+ << "nine"
+ << "ten"
+ << "eleven"
+ << "twelve"
+ << "thirteen"
+ << "fourteen"
+ << "fifteen"
+ << "sixteen"
+ << "seventeen"
+ << "eighteen"
+ << "nineteen"
+ << "twenty";
+
+ QDeclarativeContext *ctxt = view.rootContext();
+ ctxt->setContextProperty("myModel", &model);
+
+ view.setSource(QUrl::fromLocalFile(TESTDATA("create.qml")));
+
+ QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
+ QVERIFY(listview != 0);
+
+ QSGItem *contentItem = listview->contentItem();
+ QVERIFY(contentItem != 0);
+
+ QSGVisualDataModel *visualModel = qobject_cast<QSGVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
+ QVERIFY(visualModel);
+
+ QCOMPARE(listview->count(), 20);
+
+ QSGItem *delegate;
+
+ // Request an item instantiated by the view.
+ QVERIFY(findItem<QSGItem>(contentItem, "delegate", 1));
+ QVERIFY(delegate = qobject_cast<QSGItem *>(evaluate<QObject *>(visualModel, "items.create(1)")));
+ QCOMPARE(delegate, findItem<QSGItem>(contentItem, "delegate", 1));
+ QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
+ QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
+
+ evaluate<void>(delegate, "VisualDataModel.inPersistedItems = false");
+ QCOMPARE(listview->count(), 20);
+ QCOMPARE(evaluate<bool>(delegate, "destroyed"), false);
+ QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
+ QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
+
+ // Request an item not instantiated by the view.
+ QVERIFY(!findItem<QSGItem>(contentItem, "delegate", 15));
+ QVERIFY(delegate = qobject_cast<QSGItem *>(evaluate<QObject *>(visualModel, "items.create(15)")));
+ QCOMPARE(delegate, findItem<QSGItem>(contentItem, "delegate", 15));
+ QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
+ QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
+
+ evaluate<void>(visualModel, "persistedItems.remove(0)");
+ QCOMPARE(evaluate<bool>(delegate, "destroyed"), true);
+ QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
+
+ // Request an item not instantiated by the view, then scroll the view so it will request it.
+ QVERIFY(!findItem<QSGItem>(contentItem, "delegate", 16));
+ QVERIFY(delegate = qobject_cast<QSGItem *>(evaluate<QObject *>(visualModel, "items.create(16)")));
+ QCOMPARE(delegate, findItem<QSGItem>(contentItem, "delegate", 16));
+ QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
+ QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
+
+ evaluate<void>(listview, "positionViewAtIndex(19, ListView.End)");
+ QCOMPARE(listview->count(), 20);
+ evaluate<void>(delegate, "VisualDataModel.groups = [\"items\"]");
+ QCOMPARE(evaluate<bool>(delegate, "destroyed"), false);
+ QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
+ QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
+
+ // Request and release an item instantiated by the view, then scroll the view so it releases it.
+ QVERIFY(findItem<QSGItem>(contentItem, "delegate", 17));
+ QVERIFY(delegate = qobject_cast<QSGItem *>(evaluate<QObject *>(visualModel, "items.create(17)")));
+ QCOMPARE(delegate, findItem<QSGItem>(contentItem, "delegate", 17));
+ QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
+ QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
+
+ evaluate<void>(visualModel, "items.removeGroups(17, \"persistedItems\")");
+ QCOMPARE(evaluate<bool>(delegate, "destroyed"), false);
+ QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), false);
+ QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 0);
+ evaluate<void>(listview, "positionViewAtIndex(1, ListView.Beginning)");
+ QCOMPARE(listview->count(), 20);
+ QCOMPARE(evaluate<bool>(delegate, "destroyed"), true);
+
+ // Adding an item to the persistedItems group won't instantiate it, but if later requested by
+ // the view it will be persisted.
+ evaluate<void>(visualModel, "items.addGroups(18, \"persistedItems\")");
+ QCOMPARE(evaluate<int>(visualModel, "persistedItems.count"), 1);
+ QVERIFY(!findItem<QSGItem>(contentItem, "delegate", 18));
+ evaluate<void>(listview, "positionViewAtIndex(19, ListView.End)");
+ QCOMPARE(listview->count(), 20);
+ QVERIFY(delegate = findItem<QSGItem>(contentItem, "delegate", 18));
+ QCOMPARE(evaluate<bool>(delegate, "VisualDataModel.inPersistedItems"), true);
+ QCOMPARE(evaluate<bool>(delegate, "destroyed"), false);
+ evaluate<void>(listview, "positionViewAtIndex(1, ListView.Beginning)");
+ QCOMPARE(listview->count(), 20);
+ QCOMPARE(evaluate<bool>(delegate, "destroyed"), false);
+}
template<typename T>
T *tst_qsgvisualdatamodel::findItem(QSGItem *parent, const QString &objectName, int index)
@@ -635,7 +1530,7 @@ T *tst_qsgvisualdatamodel::findItem(QSGItem *parent, const QString &objectName,
//qDebug() << parent->childItems().count() << "children";
for (int i = 0; i < parent->childItems().count(); ++i) {
QSGItem *item = qobject_cast<QSGItem*>(parent->childItems().at(i));
- if(!item)
+ if (!item)
continue;
//qDebug() << "try" << item;
if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
diff --git a/tests/auto/declarative/shared/util.h b/tests/auto/declarative/shared/util.h
new file mode 100644
index 0000000000..eac2c4ec12
--- /dev/null
+++ b/tests/auto/declarative/shared/util.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVETESTUTILS_H
+#define QDECLARATIVETESTUTILS_H
+
+#include <QtCore/qdir.h>
+#include <QtCore/qcoreapplication.h>
+
+namespace QDeclarativeTestUtils
+{
+ /*
+ Returns the path to some testdata file.
+
+ We first check relative to the binary, and then look in the source tree.
+
+ Note we are looking for a _directory_ which exists, but the _file_ itself need not exist,
+ to support the case of finding a path to a testdata file which doesn't exist yet (i.e.
+ a file we are about to create).
+ */
+ QString testdata(QString const& name, const char *sourceFile)
+ {
+ // Try to find it relative to the binary.
+ QFileInfo relative = QDir(QCoreApplication::applicationDirPath()).filePath(QLatin1String("data/") + name);
+ if (relative.dir().exists()) {
+ return relative.absoluteFilePath();
+ }
+
+ // Else try to find it in the source tree
+ QFileInfo from_source = QFileInfo(sourceFile).absoluteDir().filePath(QLatin1String("data/") + name);
+ if (from_source.dir().exists()) {
+ return from_source.absoluteFilePath();
+ }
+
+ qWarning("requested testdata %s could not be found (looked at: %s, %s)",
+ qPrintable(name),
+ qPrintable(relative.filePath()),
+ qPrintable(from_source.filePath())
+ );
+
+ return QString();
+ }
+}
+
+#define TESTDATA(name) QDeclarativeTestUtils::testdata(name, __FILE__)
+
+#endif // QDECLARATIVETESTUTILS_H
diff --git a/tests/auto/declarative/symbianlibs.pri b/tests/auto/declarative/symbianlibs.pri
deleted file mode 100644
index 4452f67faf..0000000000
--- a/tests/auto/declarative/symbianlibs.pri
+++ /dev/null
@@ -1,9 +0,0 @@
-#additional libs required for orientation sensor
-symbian {
- !contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2) {
- LIBS += -lsensrvclient -lsensrvutil
- }
- contains(QT_CONFIG, s60): {
- LIBS += -lavkon -lcone
- }
-}
diff --git a/tests/auto/declarative/qdeclarativev4/data/conditionalExpr.qml b/tests/auto/declarative/v4/data/conditionalExpr.qml
index b74a95a94b..b74a95a94b 100644
--- a/tests/auto/declarative/qdeclarativev4/data/conditionalExpr.qml
+++ b/tests/auto/declarative/v4/data/conditionalExpr.qml
diff --git a/tests/auto/declarative/qdeclarativev4/data/doubleBoolJump.qml b/tests/auto/declarative/v4/data/doubleBoolJump.qml
index 2eea73b573..2eea73b573 100644
--- a/tests/auto/declarative/qdeclarativev4/data/doubleBoolJump.qml
+++ b/tests/auto/declarative/v4/data/doubleBoolJump.qml
diff --git a/tests/auto/declarative/qdeclarativev4/data/fetchException.qml b/tests/auto/declarative/v4/data/fetchException.qml
index 6431fcfae8..6431fcfae8 100644
--- a/tests/auto/declarative/qdeclarativev4/data/fetchException.qml
+++ b/tests/auto/declarative/v4/data/fetchException.qml
diff --git a/tests/auto/declarative/qdeclarativev4/data/logicalOr.2.qml b/tests/auto/declarative/v4/data/logicalOr.2.qml
index 54fb78b127..54fb78b127 100644
--- a/tests/auto/declarative/qdeclarativev4/data/logicalOr.2.qml
+++ b/tests/auto/declarative/v4/data/logicalOr.2.qml
diff --git a/tests/auto/declarative/qdeclarativev4/data/logicalOr.qml b/tests/auto/declarative/v4/data/logicalOr.qml
index 406a7d83eb..406a7d83eb 100644
--- a/tests/auto/declarative/qdeclarativev4/data/logicalOr.qml
+++ b/tests/auto/declarative/v4/data/logicalOr.qml
diff --git a/tests/auto/declarative/qdeclarativev4/data/nestedObjectAccess.qml b/tests/auto/declarative/v4/data/nestedObjectAccess.qml
index 56cd17e41e..56cd17e41e 100644
--- a/tests/auto/declarative/qdeclarativev4/data/nestedObjectAccess.qml
+++ b/tests/auto/declarative/v4/data/nestedObjectAccess.qml
diff --git a/tests/auto/declarative/qdeclarativev4/data/nullQObject.qml b/tests/auto/declarative/v4/data/nullQObject.qml
index 00185b3988..00185b3988 100644
--- a/tests/auto/declarative/qdeclarativev4/data/nullQObject.qml
+++ b/tests/auto/declarative/v4/data/nullQObject.qml
diff --git a/tests/auto/declarative/qdeclarativev4/data/qrealToIntRounding.qml b/tests/auto/declarative/v4/data/qrealToIntRounding.qml
index ee3d405073..ee3d405073 100644
--- a/tests/auto/declarative/qdeclarativev4/data/qrealToIntRounding.qml
+++ b/tests/auto/declarative/v4/data/qrealToIntRounding.qml
diff --git a/tests/auto/declarative/qdeclarativev4/data/subscriptionsInConditionalExpressions.qml b/tests/auto/declarative/v4/data/subscriptionsInConditionalExpressions.qml
index a8e05eeda1..a8e05eeda1 100644
--- a/tests/auto/declarative/qdeclarativev4/data/subscriptionsInConditionalExpressions.qml
+++ b/tests/auto/declarative/v4/data/subscriptionsInConditionalExpressions.qml
diff --git a/tests/auto/declarative/qdeclarativev4/data/unaryMinus.qml b/tests/auto/declarative/v4/data/unaryMinus.qml
index 01fa515d6f..01fa515d6f 100644
--- a/tests/auto/declarative/qdeclarativev4/data/unaryMinus.qml
+++ b/tests/auto/declarative/v4/data/unaryMinus.qml
diff --git a/tests/auto/declarative/qdeclarativev4/data/unnecessaryReeval.qml b/tests/auto/declarative/v4/data/unnecessaryReeval.qml
index 48662d7a2d..48662d7a2d 100644
--- a/tests/auto/declarative/qdeclarativev4/data/unnecessaryReeval.qml
+++ b/tests/auto/declarative/v4/data/unnecessaryReeval.qml
diff --git a/tests/auto/declarative/qdeclarativev4/testtypes.cpp b/tests/auto/declarative/v4/testtypes.cpp
index d1ae1253a5..d1ae1253a5 100644
--- a/tests/auto/declarative/qdeclarativev4/testtypes.cpp
+++ b/tests/auto/declarative/v4/testtypes.cpp
diff --git a/tests/auto/declarative/qdeclarativev4/testtypes.h b/tests/auto/declarative/v4/testtypes.h
index 22f3a40a4f..22f3a40a4f 100644
--- a/tests/auto/declarative/qdeclarativev4/testtypes.h
+++ b/tests/auto/declarative/v4/testtypes.h
diff --git a/tests/auto/declarative/qdeclarativev4/tst_qdeclarativev4.cpp b/tests/auto/declarative/v4/tst_v4.cpp
index 85f51c53d8..0b6b2c24f7 100644
--- a/tests/auto/declarative/qdeclarativev4/tst_qdeclarativev4.cpp
+++ b/tests/auto/declarative/v4/tst_v4.cpp
@@ -46,14 +46,14 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtCore/qdebug.h>
-#include <private/qdeclarativev4compiler_p.h>
+#include <private/qv4compiler_p.h>
+#include "../shared/util.h"
#include "testtypes.h"
inline QUrl TEST_FILE(const QString &filename)
{
- QFileInfo fileInfo(__FILE__);
- return QUrl::fromLocalFile(fileInfo.absoluteDir().filePath("data/" + filename));
+ return QUrl::fromLocalFile(TESTDATA(filename));
}
inline QUrl TEST_FILE(const char *filename)
@@ -61,11 +61,11 @@ inline QUrl TEST_FILE(const char *filename)
return TEST_FILE(QLatin1String(filename));
}
-class tst_qdeclarativev4 : public QObject
+class tst_v4 : public QObject
{
Q_OBJECT
public:
- tst_qdeclarativev4() {}
+ tst_v4() {}
private slots:
void initTestCase();
@@ -82,7 +82,7 @@ private:
QDeclarativeEngine engine;
};
-void tst_qdeclarativev4::initTestCase()
+void tst_v4::initTestCase()
{
registerTypes();
}
@@ -91,14 +91,14 @@ static int v4ErrorsMsgCount = 0;
static void v4ErrorsMsgHandler(QtMsgType, const char *message)
{
QByteArray m(message);
- if (m.contains("QDeclarativeV4"))
+ if (m.contains("QV4"))
v4ErrorsMsgCount++;
}
-void tst_qdeclarativev4::qtscript()
+void tst_v4::qtscript()
{
QFETCH(QString, file);
- QDeclarativeV4Compiler::enableBindingsTest(true);
+ QV4Compiler::enableBindingsTest(true);
QDeclarativeComponent component(&engine, TEST_FILE(file));
@@ -112,10 +112,10 @@ void tst_qdeclarativev4::qtscript()
QCOMPARE(v4ErrorsMsgCount, 0);
- QDeclarativeV4Compiler::enableBindingsTest(false);
+ QV4Compiler::enableBindingsTest(false);
}
-void tst_qdeclarativev4::qtscript_data()
+void tst_v4::qtscript_data()
{
QTest::addColumn<QString>("file");
@@ -128,7 +128,7 @@ void tst_qdeclarativev4::qtscript_data()
QTest::newRow("null qobject") << "nullQObject.qml";
}
-void tst_qdeclarativev4::unnecessaryReeval()
+void tst_v4::unnecessaryReeval()
{
QDeclarativeComponent component(&engine, TEST_FILE("unnecessaryReeval.qml"));
@@ -161,7 +161,7 @@ void tst_qdeclarativev4::unnecessaryReeval()
delete o;
}
-void tst_qdeclarativev4::logicalOr()
+void tst_v4::logicalOr()
{
{
QDeclarativeComponent component(&engine, TEST_FILE("logicalOr.qml"));
@@ -190,7 +190,7 @@ void tst_qdeclarativev4::logicalOr()
}
}
-void tst_qdeclarativev4::conditionalExpr()
+void tst_v4::conditionalExpr()
{
{
QDeclarativeComponent component(&engine, TEST_FILE("conditionalExpr.qml"));
@@ -209,7 +209,7 @@ void tst_qdeclarativev4::conditionalExpr()
// This would previously use the metaObject of the root element to result the nested access.
// That is, the index for accessing "result" would have been RootObject::result, instead of
// NestedObject::result.
-void tst_qdeclarativev4::nestedObjectAccess()
+void tst_v4::nestedObjectAccess()
{
QDeclarativeComponent component(&engine, TEST_FILE("nestedObjectAccess.qml"));
@@ -224,7 +224,7 @@ void tst_qdeclarativev4::nestedObjectAccess()
delete o;
}
-void tst_qdeclarativev4::subscriptionsInConditionalExpressions()
+void tst_v4::subscriptionsInConditionalExpressions()
{
QDeclarativeComponent component(&engine, TEST_FILE("subscriptionsInConditionalExpressions.qml"));
@@ -239,6 +239,6 @@ void tst_qdeclarativev4::subscriptionsInConditionalExpressions()
delete o;
}
-QTEST_MAIN(tst_qdeclarativev4)
+QTEST_MAIN(tst_v4)
-#include "tst_qdeclarativev4.moc"
+#include "tst_v4.moc"
diff --git a/tests/auto/declarative/v4/v4.pro b/tests/auto/declarative/v4/v4.pro
new file mode 100644
index 0000000000..04d20f0fc3
--- /dev/null
+++ b/tests/auto/declarative/v4/v4.pro
@@ -0,0 +1,15 @@
+CONFIG += testcase
+TARGET = tst_qdeclarativev4
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_v4.cpp \
+ testtypes.cpp
+HEADERS += testtypes.h
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+
+QT += core-private gui-private v8-private declarative-private network testlib
diff --git a/tests/auto/headersclean/headersclean.pro b/tests/auto/headersclean/headersclean.pro
index c9522f9b50..16802b7e06 100644
--- a/tests/auto/headersclean/headersclean.pro
+++ b/tests/auto/headersclean/headersclean.pro
@@ -1,5 +1,6 @@
-load(qttest_p4)
+CONFIG += testcase
+TARGET = tst_headersclean
SOURCES += tst_headersclean.cpp
-QT = core
+QT = core testlib
contains(QT_CONFIG,declarative): QT += declarative declarative-private
diff --git a/tests/auto/particles/particles.pro b/tests/auto/particles/particles.pro
new file mode 100644
index 0000000000..2c793a988e
--- /dev/null
+++ b/tests/auto/particles/particles.pro
@@ -0,0 +1,28 @@
+TEMPLATE = subdirs
+
+PRIVATETESTS += \
+ qsgage \
+ qsgangleddirection \
+ qsgcumulativedirection \
+ qsgcustomaffector \
+ qsgcustomparticle \
+ qsgellipseextruder \
+ qsgfriction \
+ qsggravity \
+ qsgimageparticle \
+ qsgitemparticle \
+ qsglineextruder \
+ qsgmaskextruder \
+ qsgparticlegroup \
+ qsgparticlesystem \
+ qsgpointattractor \
+ qsgpointdirection \
+ qsgrectangleextruder \
+ qsgtargetdirection \
+ qsgtrailemitter \
+ qsgturbulence \
+ qsgwander
+
+contains(QT_CONFIG, private_tests) {
+ SUBDIRS += $$PRIVATETESTS
+}
diff --git a/tests/auto/particles/qsgage/data/jump.qml b/tests/auto/particles/qsgage/data/jump.qml
new file mode 100644
index 0000000000..e66f9f4950
--- /dev/null
+++ b/tests/auto/particles/qsgage/data/jump.qml
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ Age {
+ once: true
+ advancePosition: false
+ lifeLeft: 100
+ }
+
+ ImageParticle { source: "../../shared/star.png" }
+ Emitter {
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ speed: PointDirection{ x: 500; y: 500 }
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgage/data/kill.qml b/tests/auto/particles/qsgage/data/kill.qml
new file mode 100644
index 0000000000..2558435e60
--- /dev/null
+++ b/tests/auto/particles/qsgage/data/kill.qml
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ Age {}
+
+ ImageParticle { source: "../../shared/star.png" }
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ speed: PointDirection{ x: 1000; y: 1000 }
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgage/data/onceoff.qml b/tests/auto/particles/qsgage/data/onceoff.qml
new file mode 100644
index 0000000000..15d0e123b4
--- /dev/null
+++ b/tests/auto/particles/qsgage/data/onceoff.qml
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ Age {
+ once: true
+ lifeLeft: 100
+ }
+
+ ImageParticle { source: "../../shared/star.png" }
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ speed: PointDirection{ x: 500; y: 500 }
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgage/data/sustained.qml b/tests/auto/particles/qsgage/data/sustained.qml
new file mode 100644
index 0000000000..96aefec3dc
--- /dev/null
+++ b/tests/auto/particles/qsgage/data/sustained.qml
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ Age {
+ once: false
+ lifeLeft: 100
+ }
+
+ ImageParticle { source: "../../shared/star.png" }
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ speed: PointDirection{ x: 500; y: 500 }
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgage/qsgage.pro b/tests/auto/particles/qsgage/qsgage.pro
new file mode 100644
index 0000000000..e4904c8691
--- /dev/null
+++ b/tests/auto/particles/qsgage/qsgage.pro
@@ -0,0 +1,13 @@
+CONFIG += testcase
+TARGET = tst_qsgage
+SOURCES += tst_qsgage.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += insignificant_test
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgage/tst_qsgage.cpp b/tests/auto/particles/qsgage/tst_qsgage.cpp
new file mode 100644
index 0000000000..faa267560b
--- /dev/null
+++ b/tests/auto/particles/qsgage/tst_qsgage.cpp
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsgage : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgage();
+
+private slots:
+ void test_kill();
+ void test_jump();
+ void test_onceOff();
+ void test_sustained();
+};
+
+tst_qsgage::tst_qsgage()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsgage::test_kill()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/kill.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vx, 1000.f);
+ QCOMPARE(d->vy, 1000.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(d->t <= ((qreal)system->timeInt/1000.0) - 0.5f + EPSILON);
+ }
+}
+
+void tst_qsgage::test_jump()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/jump.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ //Allow for a small variance because jump is trying to simulate off wall time
+ extremelyFuzzyCompare(d->x, -100.f, 5.0f);
+ extremelyFuzzyCompare(d->y, -100.f, 5.0f);
+ QCOMPARE(d->vx, 500.f);
+ QCOMPARE(d->vy, 500.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(d->t <= ((qreal)system->timeInt/1000.0) - 0.4f + EPSILON);
+ }
+}
+
+void tst_qsgage::test_onceOff()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/onceoff.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vx, 500.f);
+ QCOMPARE(d->vy, 500.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(d->t <= ((qreal)system->timeInt/1000.0) - 0.4f + EPSILON);
+ }
+}
+
+void tst_qsgage::test_sustained()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/sustained.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+ //TODO: Ensure some particles have lived to 0.4s point despite unified timer
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vx, 500.f);
+ QCOMPARE(d->vy, 500.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyCompare(d->t, ((qreal)system->timeInt/1000.0) - 0.4f));
+ }
+}
+
+QTEST_MAIN(tst_qsgage);
+
+#include "tst_qsgage.moc"
diff --git a/tests/auto/particles/qsgangleddirection/data/basic.qml b/tests/auto/particles/qsgangleddirection/data/basic.qml
new file mode 100644
index 0000000000..c2fda56561
--- /dev/null
+++ b/tests/auto/particles/qsgangleddirection/data/basic.qml
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ }
+
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ speed: AngleDirection { angle: 45; magnitude: 500 }
+ acceleration: AngleDirection { angle: 45; angleVariation: 22; magnitude: 250; magnitudeVariation: 249}
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgangleddirection/qsgangleddirection.pro b/tests/auto/particles/qsgangleddirection/qsgangleddirection.pro
new file mode 100644
index 0000000000..e8e1e5b9a5
--- /dev/null
+++ b/tests/auto/particles/qsgangleddirection/qsgangleddirection.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsgangleddirection
+SOURCES += tst_qsgangleddirection.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgangleddirection/tst_qsgangleddirection.cpp b/tests/auto/particles/qsgangleddirection/tst_qsgangleddirection.cpp
new file mode 100644
index 0000000000..dbb23ff29e
--- /dev/null
+++ b/tests/auto/particles/qsgangleddirection/tst_qsgangleddirection.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <qmath.h>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsgangleddirection : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgangleddirection();
+
+private slots:
+ void test_basic();
+};
+
+tst_qsgangleddirection::tst_qsgangleddirection()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsgangleddirection::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QVERIFY(qFuzzyCompare(d->vx, 353.55339f));
+ QVERIFY(qFuzzyCompare(d->vy, 353.55339f));
+ QVERIFY(d->ax > 0.f);
+ QVERIFY(d->ax < 500.f);
+ QVERIFY(d->ay > 0.f);
+ QVERIFY(d->ay < 500.f);
+ QVERIFY(qSqrt(d->ax*d->ax + d->ay*d->ay) < 500.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+}
+
+QTEST_MAIN(tst_qsgangleddirection);
+
+#include "tst_qsgangleddirection.moc"
diff --git a/tests/auto/particles/qsgcumulativedirection/data/basic.qml b/tests/auto/particles/qsgcumulativedirection/data/basic.qml
new file mode 100644
index 0000000000..bd46c4556f
--- /dev/null
+++ b/tests/auto/particles/qsgcumulativedirection/data/basic.qml
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ }
+
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ speed: CumulativeDirection {
+ PointDirection { x: 100; y: -100 }
+ PointDirection { x: -100; y: 100 }
+ }
+ acceleration: CumulativeDirection {
+ AngleDirection { angle: 0; magnitude: 100 }
+ AngleDirection { angle: 180; magnitude: 100 }
+ }
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgcumulativedirection/qsgcumulativedirection.pro b/tests/auto/particles/qsgcumulativedirection/qsgcumulativedirection.pro
new file mode 100644
index 0000000000..75933c679f
--- /dev/null
+++ b/tests/auto/particles/qsgcumulativedirection/qsgcumulativedirection.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsgcumulativedirection
+SOURCES += tst_qsgcumulativedirection.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgcumulativedirection/tst_qsgcumulativedirection.cpp b/tests/auto/particles/qsgcumulativedirection/tst_qsgcumulativedirection.cpp
new file mode 100644
index 0000000000..00efff54bf
--- /dev/null
+++ b/tests/auto/particles/qsgcumulativedirection/tst_qsgcumulativedirection.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsgcumulativedirection : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgcumulativedirection();
+
+private slots:
+ void test_basic();
+};
+
+tst_qsgcumulativedirection::tst_qsgcumulativedirection()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsgcumulativedirection::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QVERIFY(myFuzzyCompare(d->x, 0.0f));
+ QVERIFY(myFuzzyCompare(d->y, 0.0f));
+ QVERIFY(myFuzzyCompare(d->vx, 0.0f));
+ QVERIFY(myFuzzyCompare(d->vy, 0.0f));
+ QVERIFY(myFuzzyCompare(d->ax, 0.0f));
+ QVERIFY(myFuzzyCompare(d->ay, 0.0f));
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+}
+
+QTEST_MAIN(tst_qsgcumulativedirection);
+
+#include "tst_qsgcumulativedirection.moc"
diff --git a/tests/auto/particles/qsgcustomaffector/data/basic.qml b/tests/auto/particles/qsgcustomaffector/data/basic.qml
new file mode 100644
index 0000000000..7371698026
--- /dev/null
+++ b/tests/auto/particles/qsgcustomaffector/data/basic.qml
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ }
+
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+
+ Affector {
+ once: true
+ onAffectParticles: {
+ for (var i=0; i<particles.length; i++) {
+ particles[i].initialX = 100;
+ particles[i].initialY = 100;
+ particles[i].initialVX = 100;
+ particles[i].initialVY = 100;
+ particles[i].initialAX = 100;
+ particles[i].initialAY = 100;
+ particles[i].startSize = 100;
+ particles[i].endSize = 100;
+ }
+ }
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgcustomaffector/qsgcustomaffector.pro b/tests/auto/particles/qsgcustomaffector/qsgcustomaffector.pro
new file mode 100644
index 0000000000..6ce702aa12
--- /dev/null
+++ b/tests/auto/particles/qsgcustomaffector/qsgcustomaffector.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsgcustomaffector
+SOURCES += tst_qsgcustomaffector.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgcustomaffector/tst_qsgcustomaffector.cpp b/tests/auto/particles/qsgcustomaffector/tst_qsgcustomaffector.cpp
new file mode 100644
index 0000000000..2b36d318c5
--- /dev/null
+++ b/tests/auto/particles/qsgcustomaffector/tst_qsgcustomaffector.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsgcustomaffector : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgcustomaffector();
+
+private slots:
+ void test_basic();
+};
+
+tst_qsgcustomaffector::tst_qsgcustomaffector()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsgcustomaffector::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, 100.f);
+ QCOMPARE(d->y, 100.f);
+ QCOMPARE(d->vx, 100.f);
+ QCOMPARE(d->vy, 100.f);
+ QCOMPARE(d->ax, 100.f);
+ QCOMPARE(d->ay, 100.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 100.f);
+ QCOMPARE(d->endSize, 100.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+}
+
+QTEST_MAIN(tst_qsgcustomaffector);
+
+#include "tst_qsgcustomaffector.moc"
diff --git a/tests/auto/particles/qsgcustomparticle/data/basic.qml b/tests/auto/particles/qsgcustomparticle/data/basic.qml
new file mode 100644
index 0000000000..244f706b99
--- /dev/null
+++ b/tests/auto/particles/qsgcustomparticle/data/basic.qml
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ CustomParticle {
+ property variant source: ShaderEffectSource {
+ hideSource: true
+ sourceItem: Image {
+ source: "../../shared/star.png"
+ }
+ }
+ }
+
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgcustomparticle/qsgcustomparticle.pro b/tests/auto/particles/qsgcustomparticle/qsgcustomparticle.pro
new file mode 100644
index 0000000000..2f84d78c08
--- /dev/null
+++ b/tests/auto/particles/qsgcustomparticle/qsgcustomparticle.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsgcustomparticle
+SOURCES += tst_qsgcustomparticle.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgcustomparticle/tst_qsgcustomparticle.cpp b/tests/auto/particles/qsgcustomparticle/tst_qsgcustomparticle.cpp
new file mode 100644
index 0000000000..92762ea8e2
--- /dev/null
+++ b/tests/auto/particles/qsgcustomparticle/tst_qsgcustomparticle.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsgcustomparticle : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgcustomparticle();
+
+private slots:
+ void test_basic();
+};
+
+tst_qsgcustomparticle::tst_qsgcustomparticle()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsgcustomparticle::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QVERIFY(view);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ bool oneNonZero = false;
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ QVERIFY(d->r >= 0.0 && d->r <= 1.0);
+ if (d->r != 0.0 )
+ oneNonZero = true;
+ }
+ QVERIFY(oneNonZero);//Zero is a valid value, but it also needs to be set to a random number
+}
+
+QTEST_MAIN(tst_qsgcustomparticle);
+
+#include "tst_qsgcustomparticle.moc"
diff --git a/tests/auto/particles/qsgellipseextruder/data/basic.qml b/tests/auto/particles/qsgellipseextruder/data/basic.qml
new file mode 100644
index 0000000000..fa5fb3686a
--- /dev/null
+++ b/tests/auto/particles/qsgellipseextruder/data/basic.qml
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ groups: ["", "nondefault"]
+ source: "../../shared/star.png"
+ }
+
+ Emitter{
+ anchors.fill: parent
+ shape: EllipseShape{}
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+
+ Emitter{
+ group: "nondefault"
+ anchors.fill: parent
+ shape: EllipseShape{ fill: false }
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgellipseextruder/qsgellipseextruder.pro b/tests/auto/particles/qsgellipseextruder/qsgellipseextruder.pro
new file mode 100644
index 0000000000..297bba9952
--- /dev/null
+++ b/tests/auto/particles/qsgellipseextruder/qsgellipseextruder.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsgellipseextruder
+SOURCES += tst_qsgellipseextruder.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgellipseextruder/tst_qsgellipseextruder.cpp b/tests/auto/particles/qsgellipseextruder/tst_qsgellipseextruder.cpp
new file mode 100644
index 0000000000..040a5e98b5
--- /dev/null
+++ b/tests/auto/particles/qsgellipseextruder/tst_qsgellipseextruder.cpp
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qmath.h>
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsgellipseextruder : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgellipseextruder();
+
+private slots:
+ void test_basic();
+private:
+ bool inCircle(qreal x, qreal y, qreal r, bool borderOnly=false);
+};
+
+tst_qsgellipseextruder::tst_qsgellipseextruder()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+bool tst_qsgellipseextruder::inCircle(qreal x, qreal y, qreal r, bool borderOnly)
+{
+ x -= r;
+ y -= r;
+ if (myFuzzyCompare(x,0) && myFuzzyCompare(y,0))
+ return !borderOnly;
+ qreal mag = qSqrt(x*x + y*y);
+ if (borderOnly)
+ return myFuzzyCompare(mag, r); //Need myFuzzyCompare for smaller Epsilon than qFuzzyCompare
+ else
+ return mag - EPSILON < r;
+}
+
+void tst_qsgellipseextruder::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ //Filled
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QVERIFY(inCircle(d->x, d->y, 160, false));
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+ //Just border
+ QCOMPARE(system->groupData[1]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[1]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QVERIFY(inCircle(d->x, d->y, 160, true));
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+}
+
+QTEST_MAIN(tst_qsgellipseextruder);
+
+#include "tst_qsgellipseextruder.moc"
diff --git a/tests/auto/particles/qsgfriction/data/basic.qml b/tests/auto/particles/qsgfriction/data/basic.qml
new file mode 100644
index 0000000000..87a8897914
--- /dev/null
+++ b/tests/auto/particles/qsgfriction/data/basic.qml
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ groups: ["","notdefault"]
+ source: "../../shared/star.png"
+ }
+
+ Friction {
+ factor: 0.2
+ }
+
+ Emitter{
+ //0,0 position
+ speed: PointDirection{x:100}
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+
+ Friction {
+ groups: ["notdefault"]
+ factor: 1000.0
+ }
+
+ Emitter{
+ //0,0 position
+ group: "notdefault"
+ y:200
+ speed: PointDirection{x:100}
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgfriction/qsgfriction.pro b/tests/auto/particles/qsgfriction/qsgfriction.pro
new file mode 100644
index 0000000000..ad3f054957
--- /dev/null
+++ b/tests/auto/particles/qsgfriction/qsgfriction.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsgfriction
+SOURCES += tst_qsgfriction.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgfriction/tst_qsgfriction.cpp b/tests/auto/particles/qsgfriction/tst_qsgfriction.cpp
new file mode 100644
index 0000000000..bc622e4648
--- /dev/null
+++ b/tests/auto/particles/qsgfriction/tst_qsgfriction.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsgfriction : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgfriction();
+
+private slots:
+ void test_basic();
+};
+
+tst_qsgfriction::tst_qsgfriction()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsgfriction::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ //Default is just slowed a little
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QVERIFY(d->vx < 100.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+
+ //Nondefault comes to a complete stop within the first half of its life
+ QCOMPARE(system->groupData[1]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[1]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ if (d->t > ((qreal)system->timeInt/1000.0) - 0.25)
+ continue;
+ QVERIFY(myFuzzyCompare(d->vx, 0.f));
+ QCOMPARE(d->y, 200.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+}
+
+QTEST_MAIN(tst_qsgfriction);
+
+#include "tst_qsgfriction.moc"
diff --git a/tests/auto/particles/qsggravity/data/basic.qml b/tests/auto/particles/qsggravity/data/basic.qml
new file mode 100644
index 0000000000..9275654297
--- /dev/null
+++ b/tests/auto/particles/qsggravity/data/basic.qml
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ }
+
+ Gravity {
+ acceleration: 1000
+ angle: 45
+ }
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsggravity/qsggravity.pro b/tests/auto/particles/qsggravity/qsggravity.pro
new file mode 100644
index 0000000000..a6e345146f
--- /dev/null
+++ b/tests/auto/particles/qsggravity/qsggravity.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsggravity
+SOURCES += tst_qsggravity.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsggravity/tst_qsggravity.cpp b/tests/auto/particles/qsggravity/tst_qsggravity.cpp
new file mode 100644
index 0000000000..475809446c
--- /dev/null
+++ b/tests/auto/particles/qsggravity/tst_qsggravity.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsggravity : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsggravity();
+
+private slots:
+ void test_basic();
+};
+
+tst_qsggravity::tst_qsggravity()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsggravity::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->ax, 707.10678f);
+ QCOMPARE(d->ay, 707.10678f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+}
+
+QTEST_MAIN(tst_qsggravity);
+
+#include "tst_qsggravity.moc"
diff --git a/tests/auto/particles/qsgimageparticle/data/basic.qml b/tests/auto/particles/qsgimageparticle/data/basic.qml
new file mode 100644
index 0000000000..f5ef4c16c0
--- /dev/null
+++ b/tests/auto/particles/qsgimageparticle/data/basic.qml
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ }
+
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgimageparticle/data/colored.qml b/tests/auto/particles/qsgimageparticle/data/colored.qml
new file mode 100644
index 0000000000..8f4ddbf8c4
--- /dev/null
+++ b/tests/auto/particles/qsgimageparticle/data/colored.qml
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ alpha: 0.5
+ color: "#030201"
+ }
+
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgimageparticle/data/deformed.qml b/tests/auto/particles/qsgimageparticle/data/deformed.qml
new file mode 100644
index 0000000000..b0a58ee5d1
--- /dev/null
+++ b/tests/auto/particles/qsgimageparticle/data/deformed.qml
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ rotation: 90
+ rotationSpeed: 90
+ autoRotation: true
+ yVector: PointDirection{x: 0.5; y: 0.5}
+ xVector: PointDirection{x: 0.5; y: 0.5}
+ }
+
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgimageparticle/data/sprite.qml b/tests/auto/particles/qsgimageparticle/data/sprite.qml
new file mode 100644
index 0000000000..5c1acf4b04
--- /dev/null
+++ b/tests/auto/particles/qsgimageparticle/data/sprite.qml
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ sprites: Sprite {
+ name: "happy"
+ source: "../../shared/squarefacesprite.png"
+ frames: 6
+ duration: 120
+ }
+ }
+
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgimageparticle/data/tabled.qml b/tests/auto/particles/qsgimageparticle/data/tabled.qml
new file mode 100644
index 0000000000..8a7a9ce229
--- /dev/null
+++ b/tests/auto/particles/qsgimageparticle/data/tabled.qml
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ sizeTable: "../../shared/table.png"
+ colorTable: "../../shared/table.png"
+ opacityTable: "../../shared/table.png"
+ }
+
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgimageparticle/qsgimageparticle.pro b/tests/auto/particles/qsgimageparticle/qsgimageparticle.pro
new file mode 100644
index 0000000000..62dbd0b817
--- /dev/null
+++ b/tests/auto/particles/qsgimageparticle/qsgimageparticle.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsgimageparticle
+SOURCES += tst_qsgimageparticle.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgimageparticle/tst_qsgimageparticle.cpp b/tests/auto/particles/qsgimageparticle/tst_qsgimageparticle.cpp
new file mode 100644
index 0000000000..a416271669
--- /dev/null
+++ b/tests/auto/particles/qsgimageparticle/tst_qsgimageparticle.cpp
@@ -0,0 +1,285 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+const double CONV_FACTOR = 0.017453292519943295;//Degrees to radians
+
+class tst_qsgimageparticle : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgimageparticle();
+
+private slots:
+ void test_basic();
+ void test_colored();
+ void test_deformed();
+ void test_tabled();
+ void test_sprite();
+};
+
+tst_qsgimageparticle::tst_qsgimageparticle()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsgimageparticle::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ QCOMPARE(d->color.r, (uchar)255);
+ QCOMPARE(d->color.g, (uchar)255);
+ QCOMPARE(d->color.b, (uchar)255);
+ QCOMPARE(d->color.a, (uchar)255);
+ QCOMPARE(d->xx, 1.0f);
+ QCOMPARE(d->xy, 0.0f);
+ QCOMPARE(d->yy, 1.0f);
+ QCOMPARE(d->yx, 0.0f);
+ QCOMPARE(d->rotation, 0.0f);
+ QCOMPARE(d->rotationSpeed, 0.0f);
+ QCOMPARE(d->autoRotate, 0.0f);
+ QCOMPARE(d->animX, 0.0f);
+ QCOMPARE(d->animY, 0.0f);
+ QCOMPARE(d->animWidth, 1.0f);
+ QCOMPARE(d->animHeight, 1.0f);
+ QCOMPARE(d->frameDuration, 1.0f);
+ QCOMPARE(d->frameCount, 1.0f);
+ QCOMPARE(d->animT, -1.0f);
+ }
+}
+
+
+void tst_qsgimageparticle::test_colored()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/colored.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ QCOMPARE(d->color.r, (uchar)003);
+ QCOMPARE(d->color.g, (uchar)002);
+ QCOMPARE(d->color.b, (uchar)001);
+ QCOMPARE(d->color.a, (uchar)127);
+ QCOMPARE(d->xx, 1.0f);
+ QCOMPARE(d->xy, 0.0f);
+ QCOMPARE(d->yy, 1.0f);
+ QCOMPARE(d->yx, 0.0f);
+ QCOMPARE(d->rotation, 0.0f);
+ QCOMPARE(d->rotationSpeed, 0.0f);
+ QCOMPARE(d->autoRotate, 0.0f);
+ QCOMPARE(d->animX, 0.0f);
+ QCOMPARE(d->animY, 0.0f);
+ QCOMPARE(d->animWidth, 1.0f);
+ QCOMPARE(d->animHeight, 1.0f);
+ QCOMPARE(d->frameDuration, 1.0f);
+ QCOMPARE(d->frameCount, 1.0f);
+ QCOMPARE(d->animT, -1.0f);
+ }
+}
+
+
+void tst_qsgimageparticle::test_deformed()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/deformed.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ QCOMPARE(d->color.r, (uchar)255);
+ QCOMPARE(d->color.g, (uchar)255);
+ QCOMPARE(d->color.b, (uchar)255);
+ QCOMPARE(d->color.a, (uchar)255);
+ QCOMPARE(d->xx, 0.5f);
+ QCOMPARE(d->xy, 0.5f);
+ QCOMPARE(d->yy, 0.5f);
+ QCOMPARE(d->yx, 0.5f);
+ QCOMPARE(d->rotation, 90.0f * (float)CONV_FACTOR);
+ QCOMPARE(d->rotationSpeed, 90.0f * (float)CONV_FACTOR);
+ QCOMPARE(d->autoRotate, 1.0f);
+ QCOMPARE(d->animX, 0.0f);
+ QCOMPARE(d->animY, 0.0f);
+ QCOMPARE(d->animWidth, 1.0f);
+ QCOMPARE(d->animHeight, 1.0f);
+ QCOMPARE(d->frameDuration, 1.0f);
+ QCOMPARE(d->frameCount, 1.0f);
+ QCOMPARE(d->animT, -1.0f);
+ }
+}
+
+
+void tst_qsgimageparticle::test_tabled()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/tabled.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ QCOMPARE(d->color.r, (uchar)255);
+ QCOMPARE(d->color.g, (uchar)255);
+ QCOMPARE(d->color.b, (uchar)255);
+ QCOMPARE(d->color.a, (uchar)255);
+ QCOMPARE(d->xx, 1.0f);
+ QCOMPARE(d->xy, 0.0f);
+ QCOMPARE(d->yy, 1.0f);
+ QCOMPARE(d->yx, 0.0f);
+ QCOMPARE(d->rotation, 0.0f);
+ QCOMPARE(d->rotationSpeed, 0.0f);
+ QCOMPARE(d->autoRotate, 0.0f);
+ QCOMPARE(d->animX, 0.0f);
+ QCOMPARE(d->animY, 0.0f);
+ QCOMPARE(d->animWidth, 1.0f);
+ QCOMPARE(d->animHeight, 1.0f);
+ QCOMPARE(d->frameDuration, 1.0f);
+ QCOMPARE(d->frameCount, 1.0f);
+ QCOMPARE(d->animT, -1.0f);
+ //TODO: This performance level doesn't alter particleData, but goes straight to shaders. Find something to test
+ }
+}
+
+
+void tst_qsgimageparticle::test_sprite()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/sprite.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ QCOMPARE(d->color.r, (uchar)255);
+ QCOMPARE(d->color.g, (uchar)255);
+ QCOMPARE(d->color.b, (uchar)255);
+ QCOMPARE(d->color.a, (uchar)255);
+ QCOMPARE(d->xx, 1.0f);
+ QCOMPARE(d->xy, 0.0f);
+ QCOMPARE(d->yy, 1.0f);
+ QCOMPARE(d->yx, 0.0f);
+ QCOMPARE(d->rotation, 0.0f);
+ QCOMPARE(d->rotationSpeed, 0.0f);
+ QCOMPARE(d->autoRotate, 0.0f);
+ QVERIFY(myFuzzyCompare(d->frameDuration, 120.f));
+ QCOMPARE(d->frameCount, 6.0f);
+ QVERIFY(d->animT > 0.0f);
+ QCOMPARE(d->animX, 0.0f);
+ QCOMPARE(d->animY, 0.0f);
+ QCOMPARE(d->animWidth, 31.0f);
+ QCOMPARE(d->animHeight, 30.0f);
+ }
+}
+
+QTEST_MAIN(tst_qsgimageparticle);
+
+#include "tst_qsgimageparticle.moc"
diff --git a/tests/auto/particles/qsgitemparticle/data/basic.qml b/tests/auto/particles/qsgitemparticle/data/basic.qml
new file mode 100644
index 0000000000..dbe16a0b4e
--- /dev/null
+++ b/tests/auto/particles/qsgitemparticle/data/basic.qml
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ItemParticle {
+ delegate: Image{ source: "../../shared/star.png" }
+ }
+
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgitemparticle/qsgitemparticle.pro b/tests/auto/particles/qsgitemparticle/qsgitemparticle.pro
new file mode 100644
index 0000000000..afecb905db
--- /dev/null
+++ b/tests/auto/particles/qsgitemparticle/qsgitemparticle.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsgitemparticle
+SOURCES += tst_qsgitemparticle.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgitemparticle/tst_qsgitemparticle.cpp b/tests/auto/particles/qsgitemparticle/tst_qsgitemparticle.cpp
new file mode 100644
index 0000000000..e58ab834f9
--- /dev/null
+++ b/tests/auto/particles/qsgitemparticle/tst_qsgitemparticle.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qsgimage_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsgitemparticle : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgitemparticle();
+
+private slots:
+ void test_basic();
+};
+
+tst_qsgitemparticle::tst_qsgitemparticle()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsgitemparticle::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ if (d->t > ((qreal)system->timeInt/1000.0) - 0.05)//Delegates appear between frames, may miss the first couple
+ continue;
+ if (d->t < ((qreal)system->timeInt/1000.0) - 0.45)//Delegates cleared on death
+ continue;
+ QVERIFY(d->delegate);
+ QVERIFY(qobject_cast<QSGImage*>(d->delegate));
+ }
+}
+
+QTEST_MAIN(tst_qsgitemparticle);
+
+#include "tst_qsgitemparticle.moc"
diff --git a/tests/auto/particles/qsglineextruder/data/basic.qml b/tests/auto/particles/qsglineextruder/data/basic.qml
new file mode 100644
index 0000000000..dbe2ec5c7d
--- /dev/null
+++ b/tests/auto/particles/qsglineextruder/data/basic.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ groups: ["", "notdefault"]
+ source: "../../shared/star.png"
+ }
+
+ Emitter{
+ anchors.fill: parent
+ shape: LineShape{}
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ Emitter{
+ anchors.fill: parent
+ group: "notdefault"
+ shape: LineShape{mirrored: true}
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsglineextruder/qsglineextruder.pro b/tests/auto/particles/qsglineextruder/qsglineextruder.pro
new file mode 100644
index 0000000000..90e28fc2ae
--- /dev/null
+++ b/tests/auto/particles/qsglineextruder/qsglineextruder.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsglineextruder
+SOURCES += tst_qsglineextruder.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsglineextruder/tst_qsglineextruder.cpp b/tests/auto/particles/qsglineextruder/tst_qsglineextruder.cpp
new file mode 100644
index 0000000000..0f25f50089
--- /dev/null
+++ b/tests/auto/particles/qsglineextruder/tst_qsglineextruder.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsglineextruder : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsglineextruder();
+
+private slots:
+ void test_basic();
+};
+
+tst_qsglineextruder::tst_qsglineextruder()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsglineextruder::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, d->y);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+
+ QCOMPARE(system->groupData[1]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[1]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x + d->y, 320.0f);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+}
+
+QTEST_MAIN(tst_qsglineextruder);
+
+#include "tst_qsglineextruder.moc"
diff --git a/tests/auto/particles/qsgmaskextruder/data/basic.qml b/tests/auto/particles/qsgmaskextruder/data/basic.qml
new file mode 100644
index 0000000000..804df83de8
--- /dev/null
+++ b/tests/auto/particles/qsgmaskextruder/data/basic.qml
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ }
+
+ Emitter{
+ //100,100 rect at 100,100
+ anchors.fill: parent
+ shape: MaskShape{source: "smallmask.png"}
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgmaskextruder/data/smallmask.png b/tests/auto/particles/qsgmaskextruder/data/smallmask.png
new file mode 100644
index 0000000000..e36fb9fe55
--- /dev/null
+++ b/tests/auto/particles/qsgmaskextruder/data/smallmask.png
Binary files differ
diff --git a/tests/auto/particles/qsgmaskextruder/qsgmaskextruder.pro b/tests/auto/particles/qsgmaskextruder/qsgmaskextruder.pro
new file mode 100644
index 0000000000..995adabc7b
--- /dev/null
+++ b/tests/auto/particles/qsgmaskextruder/qsgmaskextruder.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsgmaskextruder
+SOURCES += tst_qsgmaskextruder.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgmaskextruder/tst_qsgmaskextruder.cpp b/tests/auto/particles/qsgmaskextruder/tst_qsgmaskextruder.cpp
new file mode 100644
index 0000000000..03070d8be0
--- /dev/null
+++ b/tests/auto/particles/qsgmaskextruder/tst_qsgmaskextruder.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsgmaskextruder : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgmaskextruder();
+
+private slots:
+ void test_basic();
+};
+
+tst_qsgmaskextruder::tst_qsgmaskextruder()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsgmaskextruder::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QVERIFY(d->x >= 100.0f && d->x <= 200.0f);
+ QVERIFY(d->y >= 100.0f && d->y <= 200.0f);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+}
+
+QTEST_MAIN(tst_qsgmaskextruder);
+
+#include "tst_qsgmaskextruder.moc"
diff --git a/tests/auto/particles/qsgparticlegroup/data/basic.qml b/tests/auto/particles/qsgparticlegroup/data/basic.qml
new file mode 100644
index 0000000000..97dadd7461
--- /dev/null
+++ b/tests/auto/particles/qsgparticlegroup/data/basic.qml
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ }
+
+ ParticleGroup {
+ name: "notdefault"
+ duration: 0
+ to: {"":1}
+ }
+
+ Emitter{
+ //0,0 position
+ group: "notdefault"
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgparticlegroup/qsgparticlegroup.pro b/tests/auto/particles/qsgparticlegroup/qsgparticlegroup.pro
new file mode 100644
index 0000000000..3d71ee0289
--- /dev/null
+++ b/tests/auto/particles/qsgparticlegroup/qsgparticlegroup.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsgparticlegroup
+SOURCES += tst_qsgparticlegroup.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgparticlegroup/tst_qsgparticlegroup.cpp b/tests/auto/particles/qsgparticlegroup/tst_qsgparticlegroup.cpp
new file mode 100644
index 0000000000..49dc197ebb
--- /dev/null
+++ b/tests/auto/particles/qsgparticlegroup/tst_qsgparticlegroup.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsgparticlegroup : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgparticlegroup();
+
+private slots:
+ void test_instantTransition();
+};
+
+tst_qsgparticlegroup::tst_qsgparticlegroup()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsgparticlegroup::test_instantTransition()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ //A frame or two worth of particles will be missed, the transition doesn't take effect on the frame it's spawned (QTBUG-21781)
+ QVERIFY(system->groupData[0]->size() <= 500 && system->groupData[0]->size() >= 450);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+}
+
+QTEST_MAIN(tst_qsgparticlegroup);
+
+#include "tst_qsgparticlegroup.moc"
diff --git a/tests/auto/particles/qsgparticlesystem/data/basic.qml b/tests/auto/particles/qsgparticlesystem/data/basic.qml
new file mode 100644
index 0000000000..f5ef4c16c0
--- /dev/null
+++ b/tests/auto/particles/qsgparticlesystem/data/basic.qml
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ }
+
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgparticlesystem/qsgparticlesystem.pro b/tests/auto/particles/qsgparticlesystem/qsgparticlesystem.pro
new file mode 100644
index 0000000000..6236a20bb6
--- /dev/null
+++ b/tests/auto/particles/qsgparticlesystem/qsgparticlesystem.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsgparticlesystem
+SOURCES += tst_qsgparticlesystem.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgparticlesystem/tst_qsgparticlesystem.cpp b/tests/auto/particles/qsgparticlesystem/tst_qsgparticlesystem.cpp
new file mode 100644
index 0000000000..9c6f299884
--- /dev/null
+++ b/tests/auto/particles/qsgparticlesystem/tst_qsgparticlesystem.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsgparticlesystem : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgparticlesystem();
+
+private slots:
+ void test_basic();
+};
+
+tst_qsgparticlesystem::tst_qsgparticlesystem()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsgparticlesystem::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ int stillAlive = 0;
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ if (d->stillAlive())
+ stillAlive++;
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+ QVERIFY(extremelyFuzzyCompare(stillAlive, 500, 5));//Small simulation variance is permissible.
+}
+
+QTEST_MAIN(tst_qsgparticlesystem);
+
+#include "tst_qsgparticlesystem.moc"
diff --git a/tests/auto/particles/qsgpointattractor/data/basic.qml b/tests/auto/particles/qsgpointattractor/data/basic.qml
new file mode 100644
index 0000000000..86861a9cf2
--- /dev/null
+++ b/tests/auto/particles/qsgpointattractor/data/basic.qml
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ }
+
+ Attractor {
+ anchors.centerIn: parent
+ proportionalToDistance: Attractor.Constant
+ affectedParameter: Attractor.Position
+ strength: 100
+ }
+
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgpointattractor/qsgpointattractor.pro b/tests/auto/particles/qsgpointattractor/qsgpointattractor.pro
new file mode 100644
index 0000000000..865d58c89d
--- /dev/null
+++ b/tests/auto/particles/qsgpointattractor/qsgpointattractor.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsgpointattractor
+SOURCES += tst_qsgpointattractor.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgpointattractor/tst_qsgpointattractor.cpp b/tests/auto/particles/qsgpointattractor/tst_qsgpointattractor.cpp
new file mode 100644
index 0000000000..9e4ff328a7
--- /dev/null
+++ b/tests/auto/particles/qsgpointattractor/tst_qsgpointattractor.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsgpointattractor : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgpointattractor();
+
+private slots:
+ void test_basic();
+};
+
+tst_qsgpointattractor::tst_qsgpointattractor()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsgpointattractor::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QVERIFY(d->x != 0.f);
+ QVERIFY(d->y != 0.f);
+ QVERIFY(d->x == d->y);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+}
+
+QTEST_MAIN(tst_qsgpointattractor);
+
+#include "tst_qsgpointattractor.moc"
diff --git a/tests/auto/particles/qsgpointdirection/data/basic.qml b/tests/auto/particles/qsgpointdirection/data/basic.qml
new file mode 100644
index 0000000000..60c2a3e37b
--- /dev/null
+++ b/tests/auto/particles/qsgpointdirection/data/basic.qml
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ }
+
+ Emitter{
+ //0,0 position
+ size: 32
+ speed: PointDirection{ x: 100; y: 100 }
+ acceleration: PointDirection{ x: 100; xVariation: 100; y: 100; yVariation: 100 }
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgpointdirection/qsgpointdirection.pro b/tests/auto/particles/qsgpointdirection/qsgpointdirection.pro
new file mode 100644
index 0000000000..841464d48e
--- /dev/null
+++ b/tests/auto/particles/qsgpointdirection/qsgpointdirection.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsgpointdirection
+SOURCES += tst_qsgpointdirection.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgpointdirection/tst_qsgpointdirection.cpp b/tests/auto/particles/qsgpointdirection/tst_qsgpointdirection.cpp
new file mode 100644
index 0000000000..c6a3a2c9b8
--- /dev/null
+++ b/tests/auto/particles/qsgpointdirection/tst_qsgpointdirection.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsgpointdirection : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgpointdirection();
+
+private slots:
+ void test_basic();
+};
+
+tst_qsgpointdirection::tst_qsgpointdirection()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsgpointdirection::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vx, 100.f);
+ QCOMPARE(d->vy, 100.f);
+ QVERIFY(d->ax >= 0.f);
+ QVERIFY(d->ax <= 200.f);
+ QVERIFY(d->ay >= 0.f);
+ QVERIFY(d->ay <= 200.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+}
+
+QTEST_MAIN(tst_qsgpointdirection);
+
+#include "tst_qsgpointdirection.moc"
diff --git a/tests/auto/particles/qsgrectangleextruder/data/basic.qml b/tests/auto/particles/qsgrectangleextruder/data/basic.qml
new file mode 100644
index 0000000000..a66827ed90
--- /dev/null
+++ b/tests/auto/particles/qsgrectangleextruder/data/basic.qml
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ groups: ["", "notdefault"]
+ source: "../../shared/star.png"
+ }
+
+ Emitter{
+ width: 100
+ height: 100
+ size: 32
+ shape: RectangleShape{}
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ Emitter{
+ width: 100
+ height: 100
+ group: "notdefault"
+ size: 32
+ shape: RectangleShape{fill: false}
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgrectangleextruder/qsgrectangleextruder.pro b/tests/auto/particles/qsgrectangleextruder/qsgrectangleextruder.pro
new file mode 100644
index 0000000000..e0e8f51aaa
--- /dev/null
+++ b/tests/auto/particles/qsgrectangleextruder/qsgrectangleextruder.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsgrectangleextruder
+SOURCES += tst_qsgrectangleextruder.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgrectangleextruder/tst_qsgrectangleextruder.cpp b/tests/auto/particles/qsgrectangleextruder/tst_qsgrectangleextruder.cpp
new file mode 100644
index 0000000000..e8c27aab34
--- /dev/null
+++ b/tests/auto/particles/qsgrectangleextruder/tst_qsgrectangleextruder.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsgrectangleextruder : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgrectangleextruder();
+
+private slots:
+ void test_basic();
+};
+
+tst_qsgrectangleextruder::tst_qsgrectangleextruder()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsgrectangleextruder::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QVERIFY(d->x >= 0.f);
+ QVERIFY(d->x <= 100.f);
+ QVERIFY(d->y >= 0.f);
+ QVERIFY(d->y <= 100.f);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+
+ QCOMPARE(system->groupData[1]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[1]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ if (!myFuzzyCompare(d->x, 0.f) && !myFuzzyCompare(d->x, 100.f)){
+ QVERIFY(d->x >= 0.f);
+ QVERIFY(d->x <= 100.f);
+ QVERIFY(myFuzzyCompare(d->y, 0.f) || myFuzzyCompare(d->y, 100.f));
+ } else {
+ QVERIFY(d->y >= 0.f);
+ QVERIFY(d->y <= 100.f);
+ }
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+}
+
+QTEST_MAIN(tst_qsgrectangleextruder);
+
+#include "tst_qsgrectangleextruder.moc"
diff --git a/tests/auto/particles/qsgtargetdirection/data/basic.qml b/tests/auto/particles/qsgtargetdirection/data/basic.qml
new file mode 100644
index 0000000000..a8caea4641
--- /dev/null
+++ b/tests/auto/particles/qsgtargetdirection/data/basic.qml
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ }
+
+ Emitter{
+ //0,0 position
+ speed: TargetDirection{ targetItem: sys; proportionalMagnitude: true; magnitude: 1 }
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgtargetdirection/qsgtargetdirection.pro b/tests/auto/particles/qsgtargetdirection/qsgtargetdirection.pro
new file mode 100644
index 0000000000..77288f7bc1
--- /dev/null
+++ b/tests/auto/particles/qsgtargetdirection/qsgtargetdirection.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsgtargetdirection
+SOURCES += tst_qsgtargetdirection.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgtargetdirection/tst_qsgtargetdirection.cpp b/tests/auto/particles/qsgtargetdirection/tst_qsgtargetdirection.cpp
new file mode 100644
index 0000000000..decc96117a
--- /dev/null
+++ b/tests/auto/particles/qsgtargetdirection/tst_qsgtargetdirection.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsgtargetdirection : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgtargetdirection();
+
+private slots:
+ void test_basic();
+};
+
+tst_qsgtargetdirection::tst_qsgtargetdirection()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsgtargetdirection::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vx, 160.f);
+ QCOMPARE(d->vy, 160.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+}
+
+QTEST_MAIN(tst_qsgtargetdirection);
+
+#include "tst_qsgtargetdirection.moc"
diff --git a/tests/auto/particles/qsgtrailemitter/data/basic.qml b/tests/auto/particles/qsgtrailemitter/data/basic.qml
new file mode 100644
index 0000000000..538d14f1d5
--- /dev/null
+++ b/tests/auto/particles/qsgtrailemitter/data/basic.qml
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ groups: ["","notdefault"]
+ source: "../../shared/star.png"
+ }
+
+
+ TrailEmitter {
+ group: "notdefault"
+ follow: ""
+ size: 32
+ emitRatePerParticle: 2
+ lifeSpan: 500
+ speed: PointDirection{ x: 500; y: 500 }
+ }
+ Emitter{
+ x: 4
+ y: 4
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgtrailemitter/qsgtrailemitter.pro b/tests/auto/particles/qsgtrailemitter/qsgtrailemitter.pro
new file mode 100644
index 0000000000..b7cb766877
--- /dev/null
+++ b/tests/auto/particles/qsgtrailemitter/qsgtrailemitter.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsgtrailemitter
+SOURCES += tst_qsgtrailemitter.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgtrailemitter/tst_qsgtrailemitter.cpp b/tests/auto/particles/qsgtrailemitter/tst_qsgtrailemitter.cpp
new file mode 100644
index 0000000000..e24c63c9d5
--- /dev/null
+++ b/tests/auto/particles/qsgtrailemitter/tst_qsgtrailemitter.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsgtrailemitter : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgtrailemitter();
+
+private slots:
+ void test_basic();
+};
+
+tst_qsgtrailemitter::tst_qsgtrailemitter()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsgtrailemitter::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, 4.f);
+ QCOMPARE(d->y, 4.f);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+
+ QCOMPARE(system->groupData[1]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[1]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->x, 4.f);
+ QCOMPARE(d->y, 4.f);
+ QCOMPARE(d->vx, 500.f);
+ QCOMPARE(d->vy, 500.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+}
+
+QTEST_MAIN(tst_qsgtrailemitter);
+
+#include "tst_qsgtrailemitter.moc"
diff --git a/tests/auto/particles/qsgturbulence/data/basic.qml b/tests/auto/particles/qsgturbulence/data/basic.qml
new file mode 100644
index 0000000000..42b5cd6a97
--- /dev/null
+++ b/tests/auto/particles/qsgturbulence/data/basic.qml
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ }
+
+ Turbulence {
+ anchors.fill: parent
+ strength: 1000
+ }
+
+ Emitter{
+ //100,100 position
+ x: 100
+ y: 100
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgturbulence/qsgturbulence.pro b/tests/auto/particles/qsgturbulence/qsgturbulence.pro
new file mode 100644
index 0000000000..702c1d11a5
--- /dev/null
+++ b/tests/auto/particles/qsgturbulence/qsgturbulence.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsgturbulence
+SOURCES += tst_qsgturbulence.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgturbulence/tst_qsgturbulence.cpp b/tests/auto/particles/qsgturbulence/tst_qsgturbulence.cpp
new file mode 100644
index 0000000000..4230bc529f
--- /dev/null
+++ b/tests/auto/particles/qsgturbulence/tst_qsgturbulence.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsgturbulence : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgturbulence();
+
+private slots:
+ void test_basic();
+};
+
+tst_qsgturbulence::tst_qsgturbulence()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsgturbulence::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ //Note that the noise image built-in provides the 'randomness', so this test should be stable so long as it and the size
+ //of the Turbulence item remain the same
+ QCOMPARE(system->groupData[0]->size(), 500);
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QVERIFY(d->vx != 0.f);
+ QVERIFY(d->vy != 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+}
+
+QTEST_MAIN(tst_qsgturbulence);
+
+#include "tst_qsgturbulence.moc"
diff --git a/tests/auto/particles/qsgwander/data/basic.qml b/tests/auto/particles/qsgwander/data/basic.qml
new file mode 100644
index 0000000000..ebb4bd963a
--- /dev/null
+++ b/tests/auto/particles/qsgwander/data/basic.qml
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ }
+
+ Wander {
+ pace: 400
+ xVariance: 100
+ yVariance: 100
+ }
+
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/auto/particles/qsgwander/qsgwander.pro b/tests/auto/particles/qsgwander/qsgwander.pro
new file mode 100644
index 0000000000..e11a522885
--- /dev/null
+++ b/tests/auto/particles/qsgwander/qsgwander.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qsgwander
+SOURCES += tst_qsgwander.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
+
diff --git a/tests/auto/particles/qsgwander/tst_qsgwander.cpp b/tests/auto/particles/qsgwander/tst_qsgwander.cpp
new file mode 100644
index 0000000000..b200b6fbf0
--- /dev/null
+++ b/tests/auto/particles/qsgwander/tst_qsgwander.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+#include <private/qabstractanimation_p.h>
+
+class tst_qsgwander : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qsgwander();
+
+private slots:
+ void test_basic();
+};
+
+tst_qsgwander::tst_qsgwander()
+{
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+}
+
+void tst_qsgwander::test_basic()
+{
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->groupData[0]->size(), 500);
+ //Since Wander is random perturbations, the compromise between stability and actual testing is to hope that one of
+ //the 500 was randomly changed from 0.0 in velocity
+ bool vxChanged = false;
+ bool vyChanged = false;
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ if (d->vx != 0.0f)
+ vxChanged = true;
+ if (d->vy != 0.0f)
+ vyChanged = true;
+ }
+ QVERIFY(vxChanged);
+ QVERIFY(vyChanged);
+}
+
+QTEST_MAIN(tst_qsgwander);
+
+#include "tst_qsgwander.moc"
diff --git a/tests/auto/particles/shared/particlestestsshared.h b/tests/auto/particles/shared/particlestestsshared.h
new file mode 100644
index 0000000000..ed483bae01
--- /dev/null
+++ b/tests/auto/particles/shared/particlestestsshared.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PARTICLES_TESTS_SHARED
+#define PARTICLES_TESTS_SHARED
+#include <QSGView>
+#include <QtTest>
+#include <QAbstractAnimation>
+const qreal EPSILON = 0.0001;
+
+bool extremelyFuzzyCompare(qreal a, qreal b, qreal e)//For cases which can have larger variances
+{
+ return (a + e >= b) && (a - e <= b);
+}
+
+bool myFuzzyCompare(qreal a, qreal b)//For cases which might be near 0 so qFuzzyCompare fails
+{
+ return (a + EPSILON > b) && (a - EPSILON < b);
+}
+
+bool myFuzzyLEQ(qreal a, qreal b)
+{
+ return (a - EPSILON < b);
+}
+
+bool myFuzzyGEQ(qreal a, qreal b)
+{
+ return (a + EPSILON > b);
+}
+
+QSGView* createView(const QString &filename, int additionalWait=0)
+{
+ QSGView *canvas = new QSGView(0);
+
+ canvas->setSource(QUrl::fromLocalFile(filename));
+ if (canvas->status() != QSGView::Ready)
+ return 0;
+ canvas->show();
+ QTest::qWaitForWindowShown(canvas);
+ if (additionalWait)
+ QTest::qWait(additionalWait);
+
+ return canvas;
+}
+
+void ensureAnimTime(int requiredTime, QAbstractAnimation* anim)//With consistentTiming, who knows how long an animation really takes...
+{
+ while (anim->currentTime() < requiredTime)
+ QTest::qWait(100);
+}
+
+#endif
diff --git a/examples/declarative/particles/images/squarefacesprite.png b/tests/auto/particles/shared/squarefacesprite.png
index f9a5d5fcce..f9a5d5fcce 100644
--- a/examples/declarative/particles/images/squarefacesprite.png
+++ b/tests/auto/particles/shared/squarefacesprite.png
Binary files differ
diff --git a/tests/auto/particles/shared/star.png b/tests/auto/particles/shared/star.png
new file mode 100644
index 0000000000..0d592cfa87
--- /dev/null
+++ b/tests/auto/particles/shared/star.png
Binary files differ
diff --git a/tests/auto/particles/shared/table.png b/tests/auto/particles/shared/table.png
new file mode 100644
index 0000000000..a62ceeb4a0
--- /dev/null
+++ b/tests/auto/particles/shared/table.png
Binary files differ
diff --git a/tests/auto/qmldevtools/compile/compile.pro b/tests/auto/qmldevtools/compile/compile.pro
new file mode 100644
index 0000000000..7cb01d7d7f
--- /dev/null
+++ b/tests/auto/qmldevtools/compile/compile.pro
@@ -0,0 +1,8 @@
+CONFIG += testcase
+TARGET = tst_compile
+QT = core qmldevtools-private testlib
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_compile.cpp
+
+CONFIG += parallel_test
diff --git a/src/plugins/qmltooling/qmldbg_inspector/editor/toolbarcolorbox.h b/tests/auto/qmldevtools/compile/tst_compile.cpp
index ce5ecf0e7e..afca92994d 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/editor/toolbarcolorbox.h
+++ b/tests/auto/qmldevtools/compile/tst_compile.cpp
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -38,44 +38,25 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#include <qtest.h>
-#ifndef TOOLBARCOLORBOX_H
-#define TOOLBARCOLORBOX_H
+#include <private/qdeclarativejsengine_p.h>
+#include <private/qdeclarativejslexer_p.h>
+#include <private/qdeclarativejsparser_p.h>
+#include <private/qdeclarativejsastvisitor_p.h>
+#include <private/qdeclarativejsast_p.h>
-#include <QtWidgets/QLabel>
-#include <QtGui/QColor>
-#include <QtCore/QPoint>
-
-QT_FORWARD_DECLARE_CLASS(QContextMenuEvent)
-QT_FORWARD_DECLARE_CLASS(QAction)
-
-namespace QmlJSDebugger {
-
-class ToolBarColorBox : public QLabel
+class tst_compile : public QObject
{
Q_OBJECT
-
public:
- explicit ToolBarColorBox(QWidget *parent = 0);
- void setColor(const QColor &color);
+ tst_compile() { }
-protected:
- void contextMenuEvent(QContextMenuEvent *ev);
- void mousePressEvent(QMouseEvent *ev);
- void mouseMoveEvent(QMouseEvent *ev);
private slots:
- void copyColorToClipboard();
-
-private:
- QPixmap createDragPixmap(int size = 24) const;
-
-private:
- bool m_dragStarted;
- QPoint m_dragBeginPoint;
- QAction *m_copyHexColor;
- QColor m_color;
+ // Nothing - this test just makes sure that the QmlDevTools headers
+ // are present, and that we can link against the library.
};
-} // namespace QmlJSDebugger
+QTEST_MAIN(tst_compile)
-#endif // TOOLBARCOLORBOX_H
+#include "tst_compile.moc"
diff --git a/tests/auto/qmldevtools/qmldevtools.pro b/tests/auto/qmldevtools/qmldevtools.pro
new file mode 100644
index 0000000000..a0ca1bff87
--- /dev/null
+++ b/tests/auto/qmldevtools/qmldevtools.pro
@@ -0,0 +1,6 @@
+TEMPLATE = subdirs
+
+contains(QT_CONFIG, private_tests) {
+ SUBDIRS += \
+ compile
+}
diff --git a/tests/auto/qmltest/events/tst_wheel.qml b/tests/auto/qmltest/events/tst_wheel.qml
index 243b932848..95f483aa01 100644
--- a/tests/auto/qmltest/events/tst_wheel.qml
+++ b/tests/auto/qmltest/events/tst_wheel.qml
@@ -1,3 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
import QtQuick 2.0
import QtTest 1.0
@@ -44,4 +85,4 @@ Rectangle {
}
-} \ No newline at end of file
+}
diff --git a/tests/auto/qmltest/qmltest.pro b/tests/auto/qmltest/qmltest.pro
index 1b7dad2ace..d0bc8a89cd 100644
--- a/tests/auto/qmltest/qmltest.pro
+++ b/tests/auto/qmltest/qmltest.pro
@@ -3,11 +3,10 @@ TARGET=tst_qmltest
CONFIG += warn_on qmltestcase
SOURCES += tst_qmltest.cpp
-OTHER_FILES += \
- selftests/tst_selftests.qml \
- qdeclarativebinding/tst_binding2.qml \
- qdeclarativebinding/tst_binding.qml \
- selftests/tst_compare.qml \
- selftests/tst_compare_quickobjects.qml
-
-CONFIG+=insignificant_test
+
+importFiles.files = borderimage buttonclick createbenchmark events qdeclarativebinding selftests
+
+importFiles.path = .
+DEPLOYMENT += importFiles
+
+CONFIG+=insignificant_test \ No newline at end of file
diff --git a/tests/auto/qmltest/selftests/tst_selftests.qml b/tests/auto/qmltest/selftests/tst_selftests.qml
index 88f0468de9..3da615d8c2 100644
--- a/tests/auto/qmltest/selftests/tst_selftests.qml
+++ b/tests/auto/qmltest/selftests/tst_selftests.qml
@@ -82,12 +82,8 @@ TestCase {
}
}
- function skipSingle(msg, file, line) {
- failmsg = "skipSingle:" + msg
- }
-
- function skipAll(msg, file, line) {
- failmsg = "skipAll:" + msg
+ function skip(msg, file, line) {
+ failmsg = "skip:" + msg
}
}
@@ -271,7 +267,7 @@ TestCase {
testCase.skip("foo")
} catch (e) {
compare(e.message, "QtQuickTest::skip")
- compare(functions.failmsg, "skipSingle:foo")
+ compare(functions.failmsg, "skip:foo")
caught = true
}
verify(caught)
@@ -281,27 +277,7 @@ TestCase {
testCase.skip()
} catch (e) {
compare(e.message, "QtQuickTest::skip")
- compare(functions.failmsg, "skipSingle:")
- caught = true
- }
- verify(caught)
-
- caught = false
- try {
- testCase.skipAll("foo")
- } catch (e) {
- compare(e.message, "QtQuickTest::skip")
- compare(functions.failmsg, "skipAll:foo")
- caught = true
- }
- verify(caught)
-
- caught = false
- try {
- testCase.skipAll()
- } catch (e) {
- compare(e.message, "QtQuickTest::skip")
- compare(functions.failmsg, "skipAll:")
+ compare(functions.failmsg, "skip:")
caught = true
}
verify(caught)
diff --git a/tests/auto/qtquick1/examples/examples.pro b/tests/auto/qtquick1/examples/examples.pro
index ab1d897ecb..ca4ad04e47 100644
--- a/tests/auto/qtquick1/examples/examples.pro
+++ b/tests/auto/qtquick1/examples/examples.pro
@@ -1,5 +1,5 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative qtquick1
+CONFIG += testcase
+TARGET = tst_examples
macx:CONFIG -= app_bundle
include(../../../../tools/qmlviewer/qml.pri)
@@ -9,6 +9,6 @@ DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private declarative-private qtquick1-private testlib
qpa:CONFIG+=insignificant_test # QTBUG-20990, aborts
diff --git a/tests/auto/qtquick1/moduleqt47/moduleqt47.pro b/tests/auto/qtquick1/moduleqt47/moduleqt47.pro
index f58c96f3ff..d751ea0b86 100644
--- a/tests/auto/qtquick1/moduleqt47/moduleqt47.pro
+++ b/tests/auto/qtquick1/moduleqt47/moduleqt47.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
+CONFIG += testcase
+TARGET = tst_moduleqt47
macx:CONFIG -= app_bundle
SOURCES += tst_moduleqt47.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/moduleqt47/tst_moduleqt47.cpp b/tests/auto/qtquick1/moduleqt47/tst_moduleqt47.cpp
index 0e2490a3cf..18efc4ac90 100644
--- a/tests/auto/qtquick1/moduleqt47/tst_moduleqt47.cpp
+++ b/tests/auto/qtquick1/moduleqt47/tst_moduleqt47.cpp
@@ -44,11 +44,6 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QDebug>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_moduleqt47 : public QObject
{
Q_OBJECT
diff --git a/tests/auto/qtquick1/qdeclarativeanchors/qdeclarativeanchors.pro b/tests/auto/qtquick1/qdeclarativeanchors/qdeclarativeanchors.pro
index 0c3e1cff0c..57a285b4f9 100644
--- a/tests/auto/qtquick1/qdeclarativeanchors/qdeclarativeanchors.pro
+++ b/tests/auto/qtquick1/qdeclarativeanchors/qdeclarativeanchors.pro
@@ -1,16 +1,10 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativeanchors
SOURCES += tst_qdeclarativeanchors.cpp
macx:CONFIG -= app_bundle
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativeanchors/tst_qdeclarativeanchors.cpp b/tests/auto/qtquick1/qdeclarativeanchors/tst_qdeclarativeanchors.cpp
index 7aef248bb6..e58e917492 100644
--- a/tests/auto/qtquick1/qdeclarativeanchors/tst_qdeclarativeanchors.cpp
+++ b/tests/auto/qtquick1/qdeclarativeanchors/tst_qdeclarativeanchors.cpp
@@ -50,11 +50,6 @@
#include <QtQuick1/private/qdeclarativeanchors_p_p.h>
#include <QtQuick1/private/qdeclarativeitem_p.h>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
Q_DECLARE_METATYPE(QDeclarative1Anchors::Anchor)
Q_DECLARE_METATYPE(QDeclarative1AnchorLine::AnchorLine)
@@ -381,7 +376,7 @@ void tst_QDeclarative1Anchors::loops()
}
{
- QSKIP("This causes a lockup due to Bearer management stuff", SkipSingle);
+ QSKIP("This causes a lockup due to Bearer management stuff");
QUrl source(QUrl::fromLocalFile(SRCDIR "/data/loop2.qml"));
QString expect = source.toString() + ":8:3: QML Image: Possible anchor loop detected on horizontal anchor.";
diff --git a/tests/auto/qtquick1/qdeclarativeanimatedimage/qdeclarativeanimatedimage.pro b/tests/auto/qtquick1/qdeclarativeanimatedimage/qdeclarativeanimatedimage.pro
index 5e34dd6bd7..c5ec23e17e 100644
--- a/tests/auto/qtquick1/qdeclarativeanimatedimage/qdeclarativeanimatedimage.pro
+++ b/tests/auto/qtquick1/qdeclarativeanimatedimage/qdeclarativeanimatedimage.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative network qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativeanimatedimage
HEADERS += ../../declarative/shared/testhttpserver.h
SOURCES += tst_qdeclarativeanimatedimage.cpp ../../declarative/shared/testhttpserver.cpp
macx:CONFIG -= app_bundle
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private declarative-private qtquick1-private network testlib
diff --git a/tests/auto/qtquick1/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp b/tests/auto/qtquick1/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp
index 1d2f5ad4de..275b8d0fb4 100644
--- a/tests/auto/qtquick1/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp
+++ b/tests/auto/qtquick1/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp
@@ -49,12 +49,6 @@
#include <QtDeclarative/qdeclarativecontext.h>
#include "../../declarative/shared/testhttpserver.h"
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
class tst_qdeclarativeanimatedimage : public QObject
{
diff --git a/tests/auto/qtquick1/qdeclarativeanimations/qdeclarativeanimations.pro b/tests/auto/qtquick1/qdeclarativeanimations/qdeclarativeanimations.pro
index ad217c4eef..7998a069b6 100644
--- a/tests/auto/qtquick1/qdeclarativeanimations/qdeclarativeanimations.pro
+++ b/tests/auto/qtquick1/qdeclarativeanimations/qdeclarativeanimations.pro
@@ -1,16 +1,8 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativeanimations
SOURCES += tst_qdeclarativeanimations.cpp
macx:CONFIG -= app_bundle
-
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativeanimations/tst_qdeclarativeanimations.cpp b/tests/auto/qtquick1/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
index 53e5502c5f..7075be8f98 100644
--- a/tests/auto/qtquick1/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
+++ b/tests/auto/qtquick1/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
@@ -48,13 +48,6 @@
#include <QVariantAnimation>
#include <QEasingCurve>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qdeclarativeanimations : public QObject
{
Q_OBJECT
diff --git a/tests/auto/qtquick1/qdeclarativeapplication/qdeclarativeapplication.pro b/tests/auto/qtquick1/qdeclarativeapplication/qdeclarativeapplication.pro
index abbe16393c..d74cbff668 100644
--- a/tests/auto/qtquick1/qdeclarativeapplication/qdeclarativeapplication.pro
+++ b/tests/auto/qtquick1/qdeclarativeapplication/qdeclarativeapplication.pro
@@ -1,6 +1,6 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativeapplication
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativeapplication.cpp
-QT += core-private gui-private widgets-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativeapplication/tst_qdeclarativeapplication.cpp b/tests/auto/qtquick1/qdeclarativeapplication/tst_qdeclarativeapplication.cpp
index 14765e41db..be4dc5f0c0 100644
--- a/tests/auto/qtquick1/qdeclarativeapplication/tst_qdeclarativeapplication.cpp
+++ b/tests/auto/qtquick1/qdeclarativeapplication/tst_qdeclarativeapplication.cpp
@@ -40,7 +40,6 @@
****************************************************************************/
#include <qtest.h>
-#include "../../../shared/util.h"
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtQuick1/qdeclarativeitem.h>
diff --git a/tests/auto/qtquick1/qdeclarativebehaviors/qdeclarativebehaviors.pro b/tests/auto/qtquick1/qdeclarativebehaviors/qdeclarativebehaviors.pro
index 4d7616028f..76a89eb0eb 100644
--- a/tests/auto/qtquick1/qdeclarativebehaviors/qdeclarativebehaviors.pro
+++ b/tests/auto/qtquick1/qdeclarativebehaviors/qdeclarativebehaviors.pro
@@ -1,16 +1,10 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativebehaviors
SOURCES += tst_qdeclarativebehaviors.cpp
macx:CONFIG -= app_bundle
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test insignificant_test
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp b/tests/auto/qtquick1/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp
index 773fc24148..7e2f8343eb 100644
--- a/tests/auto/qtquick1/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp
+++ b/tests/auto/qtquick1/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp
@@ -48,12 +48,6 @@
#include <QtQuick1/private/qdeclarativebehavior_p.h>
#include <QtQuick1/private/qdeclarativeanimation_p.h>
#include <QtQuick1/private/qdeclarativeitem_p.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
class tst_qdeclarativebehaviors : public QObject
{
diff --git a/tests/auto/qtquick1/qdeclarativebinding/qdeclarativebinding.pro b/tests/auto/qtquick1/qdeclarativebinding/qdeclarativebinding.pro
index af82548548..0c38a9c783 100644
--- a/tests/auto/qtquick1/qdeclarativebinding/qdeclarativebinding.pro
+++ b/tests/auto/qtquick1/qdeclarativebinding/qdeclarativebinding.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativebinding
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativebinding.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativebinding/tst_qdeclarativebinding.cpp b/tests/auto/qtquick1/qdeclarativebinding/tst_qdeclarativebinding.cpp
index 54ff801375..d476748da5 100644
--- a/tests/auto/qtquick1/qdeclarativebinding/tst_qdeclarativebinding.cpp
+++ b/tests/auto/qtquick1/qdeclarativebinding/tst_qdeclarativebinding.cpp
@@ -43,15 +43,8 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtQuick1/private/qdeclarativebind_p.h>
#include <QtQuick1/private/qdeclarativerectangle_p.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
class tst_qdeclarativebinding : public QObject
-
{
Q_OBJECT
public:
diff --git a/tests/auto/qtquick1/qdeclarativeborderimage/qdeclarativeborderimage.pro b/tests/auto/qtquick1/qdeclarativeborderimage/qdeclarativeborderimage.pro
index 2a5f79dccd..83319faf8a 100644
--- a/tests/auto/qtquick1/qdeclarativeborderimage/qdeclarativeborderimage.pro
+++ b/tests/auto/qtquick1/qdeclarativeborderimage/qdeclarativeborderimage.pro
@@ -1,18 +1,12 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui network qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativeborderimage
macx:CONFIG -= app_bundle
HEADERS += ../../declarative/shared/testhttpserver.h
SOURCES += tst_qdeclarativeborderimage.cpp ../../declarative/shared/testhttpserver.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private declarative-private qtquick1-private network testlib
diff --git a/tests/auto/qtquick1/qdeclarativeborderimage/tst_qdeclarativeborderimage.cpp b/tests/auto/qtquick1/qdeclarativeborderimage/tst_qdeclarativeborderimage.cpp
index 9ef2aaeb56..4b82fe0a4e 100644
--- a/tests/auto/qtquick1/qdeclarativeborderimage/tst_qdeclarativeborderimage.cpp
+++ b/tests/auto/qtquick1/qdeclarativeborderimage/tst_qdeclarativeborderimage.cpp
@@ -55,12 +55,6 @@
#include <QtDeclarative/qdeclarativecontext.h>
#include "../../declarative/shared/testhttpserver.h"
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
#define SERVER_PORT 14446
#define SERVER_ADDR "http://127.0.0.1:14446"
diff --git a/tests/auto/qtquick1/qdeclarativeconnection/qdeclarativeconnection.pro b/tests/auto/qtquick1/qdeclarativeconnection/qdeclarativeconnection.pro
index 405969b8a3..833c77db54 100644
--- a/tests/auto/qtquick1/qdeclarativeconnection/qdeclarativeconnection.pro
+++ b/tests/auto/qtquick1/qdeclarativeconnection/qdeclarativeconnection.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativeconnection
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativeconnection.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativeconnection/tst_qdeclarativeconnection.cpp b/tests/auto/qtquick1/qdeclarativeconnection/tst_qdeclarativeconnection.cpp
index 96e2957fbe..588090af31 100644
--- a/tests/auto/qtquick1/qdeclarativeconnection/tst_qdeclarativeconnection.cpp
+++ b/tests/auto/qtquick1/qdeclarativeconnection/tst_qdeclarativeconnection.cpp
@@ -43,16 +43,9 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtQuick1/private/qdeclarativeconnections_p.h>
#include <QtQuick1/private/qdeclarativeitem_p.h>
-#include "../../../shared/util.h"
#include <QtDeclarative/qdeclarativescriptstring.h>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qdeclarativeconnection : public QObject
-
{
Q_OBJECT
public:
diff --git a/tests/auto/qtquick1/qdeclarativeflickable/qdeclarativeflickable.pro b/tests/auto/qtquick1/qdeclarativeflickable/qdeclarativeflickable.pro
index ea3144ad3e..1c54ef413f 100644
--- a/tests/auto/qtquick1/qdeclarativeflickable/qdeclarativeflickable.pro
+++ b/tests/auto/qtquick1/qdeclarativeflickable/qdeclarativeflickable.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
+TARGET = tst_qdeclarativeflickable
+CONFIG += testcase
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativeflickable.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativeflickable/tst_qdeclarativeflickable.cpp b/tests/auto/qtquick1/qdeclarativeflickable/tst_qdeclarativeflickable.cpp
index 2d8c75ba22..5915538393 100644
--- a/tests/auto/qtquick1/qdeclarativeflickable/tst_qdeclarativeflickable.cpp
+++ b/tests/auto/qtquick1/qdeclarativeflickable/tst_qdeclarativeflickable.cpp
@@ -47,12 +47,6 @@
#include <private/qdeclarativevaluetype_p.h>
#include <QtWidgets/qgraphicswidget.h>
#include <math.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
class tst_qdeclarativeflickable : public QObject
{
@@ -519,7 +513,7 @@ void tst_qdeclarativeflickable::disabled()
void tst_qdeclarativeflickable::flickVelocity()
{
#ifdef Q_WS_MAC
- QSKIP("Producing flicks on Mac CI impossible due to timing problems", SkipAll);
+ QSKIP("Producing flicks on Mac CI impossible due to timing problems");
#endif
QDeclarativeView *canvas = new QDeclarativeView;
diff --git a/tests/auto/qtquick1/qdeclarativeflipable/qdeclarativeflipable.pro b/tests/auto/qtquick1/qdeclarativeflipable/qdeclarativeflipable.pro
index d982b99a26..3b0fd671e1 100644
--- a/tests/auto/qtquick1/qdeclarativeflipable/qdeclarativeflipable.pro
+++ b/tests/auto/qtquick1/qdeclarativeflipable/qdeclarativeflipable.pro
@@ -1,18 +1,12 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativeflipable
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativeflipable.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private testlib
qpa:contains(QT_CONFIG,xcb):CONFIG+=insignificant_test # QTBUG-21012 fails on exit (X11-specific)
diff --git a/tests/auto/qtquick1/qdeclarativeflipable/tst_qdeclarativeflipable.cpp b/tests/auto/qtquick1/qdeclarativeflipable/tst_qdeclarativeflipable.cpp
index 60d71253a5..e32f6fa09a 100644
--- a/tests/auto/qtquick1/qdeclarativeflipable/tst_qdeclarativeflipable.cpp
+++ b/tests/auto/qtquick1/qdeclarativeflipable/tst_qdeclarativeflipable.cpp
@@ -48,11 +48,6 @@
#include <QtQuick1/private/qdeclarativerectangle_p.h>
#include <math.h>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qdeclarativeflipable : public QObject
{
Q_OBJECT
diff --git a/tests/auto/qtquick1/qdeclarativefocusscope/qdeclarativefocusscope.pro b/tests/auto/qtquick1/qdeclarativefocusscope/qdeclarativefocusscope.pro
index 78123ab3ad..a42997dc08 100644
--- a/tests/auto/qtquick1/qdeclarativefocusscope/qdeclarativefocusscope.pro
+++ b/tests/auto/qtquick1/qdeclarativefocusscope/qdeclarativefocusscope.pro
@@ -1,15 +1,9 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativefocusscope
SOURCES += tst_qdeclarativefocusscope.cpp
macx:CONFIG -= app_bundle
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
-QT += core-private gui-private widgets-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private declarative-private qtquick1-private testlib
qpa:CONFIG+=insignificant_test # QTBUG-21013 unstable
diff --git a/tests/auto/qtquick1/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp b/tests/auto/qtquick1/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp
index 9a80525b5e..0102782b14 100644
--- a/tests/auto/qtquick1/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp
+++ b/tests/auto/qtquick1/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp
@@ -47,12 +47,6 @@
#include <QtQuick1/private/qdeclarativetextedit_p.h>
#include <QtQuick1/private/qdeclarativetext_p.h>
#include <QtQuick1/private/qdeclarativefocusscope_p.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
class tst_qdeclarativefocusscope : public QObject
{
diff --git a/tests/auto/qtquick1/qdeclarativefontloader/qdeclarativefontloader.pro b/tests/auto/qtquick1/qdeclarativefontloader/qdeclarativefontloader.pro
index 0940239024..fc48544fa0 100644
--- a/tests/auto/qtquick1/qdeclarativefontloader/qdeclarativefontloader.pro
+++ b/tests/auto/qtquick1/qdeclarativefontloader/qdeclarativefontloader.pro
@@ -1,18 +1,12 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui network qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativefontloader
macx:CONFIG -= app_bundle
HEADERS += ../../declarative/shared/testhttpserver.h
SOURCES += tst_qdeclarativefontloader.cpp ../../declarative/shared/testhttpserver.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private declarative-private qtquick1-private network testlib
diff --git a/tests/auto/qtquick1/qdeclarativefontloader/tst_qdeclarativefontloader.cpp b/tests/auto/qtquick1/qdeclarativefontloader/tst_qdeclarativefontloader.cpp
index cfd3087f77..3bcbe1b67c 100644
--- a/tests/auto/qtquick1/qdeclarativefontloader/tst_qdeclarativefontloader.cpp
+++ b/tests/auto/qtquick1/qdeclarativefontloader/tst_qdeclarativefontloader.cpp
@@ -44,16 +44,10 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtDeclarative/qdeclarativecontext.h>
#include <QtQuick1/private/qdeclarativefontloader_p.h>
-#include "../../../shared/util.h"
#include "../../declarative/shared/testhttpserver.h"
#define SERVER_PORT 14448
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qdeclarativefontloader : public QObject
{
Q_OBJECT
diff --git a/tests/auto/qtquick1/qdeclarativegridview/qdeclarativegridview.pro b/tests/auto/qtquick1/qdeclarativegridview/qdeclarativegridview.pro
index 2d2075b943..299b6a3273 100644
--- a/tests/auto/qtquick1/qdeclarativegridview/qdeclarativegridview.pro
+++ b/tests/auto/qtquick1/qdeclarativegridview/qdeclarativegridview.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativegridview
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativegridview.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/qtquick1/qdeclarativegridview/tst_qdeclarativegridview.cpp
index e96af5100c..4a332320f1 100644
--- a/tests/auto/qtquick1/qdeclarativegridview/tst_qdeclarativegridview.cpp
+++ b/tests/auto/qtquick1/qdeclarativegridview/tst_qdeclarativegridview.cpp
@@ -49,12 +49,6 @@
#include <QtQuick1/private/qdeclarativeitem_p.h>
#include <QtQuick1/private/qdeclarativegridview_p.h>
#include <QtQuick1/private/qdeclarativetext_p.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
class tst_QDeclarative1GridView : public QObject
{
@@ -448,12 +442,12 @@ void tst_QDeclarative1GridView::removed()
model.removeItem(1);
// Confirm items positioned correctly
- for (int i = 6; i < 18; ++i) {
+ for (int i = 3; i < 15; ++i) {
QDeclarativeItem *item = findItem<QDeclarativeItem>(contentItem, "wrapper", i);
if (!item) qWarning() << "Item" << i << "not found";
QTRY_VERIFY(item);
- QTRY_VERIFY(item->x() == (i%3)*80);
- QTRY_VERIFY(item->y() == (i/3)*60);
+ QTRY_COMPARE(item->x(), (i%3)*80.0);
+ QTRY_COMPARE(item->y(), 60+(i/3)*60.0);
}
// Remove currentIndex
@@ -474,7 +468,7 @@ void tst_QDeclarative1GridView::removed()
if (!item) qWarning() << "Item" << i << "not found";
QTRY_VERIFY(item);
QTRY_VERIFY(item->x() == (i%3)*80);
- QTRY_VERIFY(item->y() == (i/3)*60);
+ QTRY_VERIFY(item->y() == 60+(i/3)*60);
}
// remove item outside current view.
diff --git a/tests/auto/qtquick1/qdeclarativeimage/qdeclarativeimage.pro b/tests/auto/qtquick1/qdeclarativeimage/qdeclarativeimage.pro
index b50241c73f..5c9b9db5c8 100644
--- a/tests/auto/qtquick1/qdeclarativeimage/qdeclarativeimage.pro
+++ b/tests/auto/qtquick1/qdeclarativeimage/qdeclarativeimage.pro
@@ -1,18 +1,12 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui network qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativeimage
macx:CONFIG -= app_bundle
HEADERS += ../../declarative/shared/testhttpserver.h
SOURCES += tst_qdeclarativeimage.cpp ../../declarative/shared/testhttpserver.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private declarative-private qtquick1-private network testlib
diff --git a/tests/auto/qtquick1/qdeclarativeimage/tst_qdeclarativeimage.cpp b/tests/auto/qtquick1/qdeclarativeimage/tst_qdeclarativeimage.cpp
index cd07b00d5d..e93c373bf1 100644
--- a/tests/auto/qtquick1/qdeclarativeimage/tst_qdeclarativeimage.cpp
+++ b/tests/auto/qtquick1/qdeclarativeimage/tst_qdeclarativeimage.cpp
@@ -54,14 +54,8 @@
#include <QtDeclarative/qdeclarativeexpression.h>
#include <QtTest/QSignalSpy>
-#include "../../../shared/util.h"
#include "../../declarative/shared/testhttpserver.h"
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
#define SERVER_PORT 14451
#define SERVER_ADDR "http://127.0.0.1:14451"
diff --git a/tests/auto/qtquick1/qdeclarativeimageprovider/qdeclarativeimageprovider.pro b/tests/auto/qtquick1/qdeclarativeimageprovider/qdeclarativeimageprovider.pro
index 74d9e8a066..ec1d87e589 100644
--- a/tests/auto/qtquick1/qdeclarativeimageprovider/qdeclarativeimageprovider.pro
+++ b/tests/auto/qtquick1/qdeclarativeimageprovider/qdeclarativeimageprovider.pro
@@ -1,6 +1,5 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative qtquick1
-QT += network
+CONFIG += testcase
+TARGET = tst_qdeclarativeimageprovider
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativeimageprovider.cpp
@@ -8,10 +7,8 @@ SOURCES += tst_qdeclarativeimageprovider.cpp
# QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage
# LIBS += -lgcov
-!symbian: {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private declarative-private qtquick1-private network testlib
diff --git a/tests/auto/qtquick1/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp b/tests/auto/qtquick1/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp
index 3190579949..21e41333af 100644
--- a/tests/auto/qtquick1/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp
+++ b/tests/auto/qtquick1/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp
@@ -45,12 +45,6 @@
#include <QtQuick1/private/qdeclarativeimage_p.h>
#include <QImageReader>
#include <QWaitCondition>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
Q_DECLARE_METATYPE(QDeclarativeImageProvider*);
diff --git a/tests/auto/qtquick1/qdeclarativeitem/qdeclarativeitem.pro b/tests/auto/qtquick1/qdeclarativeitem/qdeclarativeitem.pro
index 0515e56707..31a71a5ab8 100644
--- a/tests/auto/qtquick1/qdeclarativeitem/qdeclarativeitem.pro
+++ b/tests/auto/qtquick1/qdeclarativeitem/qdeclarativeitem.pro
@@ -1,18 +1,12 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativeitem
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativeitem.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private testlib
qpa:contains(QT_CONFIG,xcb):CONFIG+=insignificant_test # QTBUG-21012 fails on exit (X11-specific)
diff --git a/tests/auto/qtquick1/qdeclarativeitem/tst_qdeclarativeitem.cpp b/tests/auto/qtquick1/qdeclarativeitem/tst_qdeclarativeitem.cpp
index 5b71f23f36..0998573b5b 100644
--- a/tests/auto/qtquick1/qdeclarativeitem/tst_qdeclarativeitem.cpp
+++ b/tests/auto/qtquick1/qdeclarativeitem/tst_qdeclarativeitem.cpp
@@ -46,15 +46,8 @@
#include <QtQuick1/qdeclarativeview.h>
#include <QtQuick1/private/qdeclarativerectangle_p.h>
#include <QtQuick1/private/qdeclarativeitem_p.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
class tst_QDeclarativeItem : public QObject
-
{
Q_OBJECT
public:
diff --git a/tests/auto/qtquick1/qdeclarativelayoutitem/qdeclarativelayoutitem.pro b/tests/auto/qtquick1/qdeclarativelayoutitem/qdeclarativelayoutitem.pro
index 29b038006e..1471884752 100644
--- a/tests/auto/qtquick1/qdeclarativelayoutitem/qdeclarativelayoutitem.pro
+++ b/tests/auto/qtquick1/qdeclarativelayoutitem/qdeclarativelayoutitem.pro
@@ -1,14 +1,9 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativelayoutitem
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativelayoutitem.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-QT += core-private gui-private widgets-private declarative-private qtquick1-private
+DEFINES += SRCDIR=\\\"$$PWD\\\"
+
+QT += core-private gui-private widgets-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativelayoutitem/tst_qdeclarativelayoutitem.cpp b/tests/auto/qtquick1/qdeclarativelayoutitem/tst_qdeclarativelayoutitem.cpp
index 095ad2ba38..c3a0b2267a 100644
--- a/tests/auto/qtquick1/qdeclarativelayoutitem/tst_qdeclarativelayoutitem.cpp
+++ b/tests/auto/qtquick1/qdeclarativelayoutitem/tst_qdeclarativelayoutitem.cpp
@@ -47,12 +47,6 @@
#include <qgraphicsscene.h>
#include <qgraphicswidget.h>
#include <qgraphicslinearlayout.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
class tst_qdeclarativelayoutitem : public QObject
{
diff --git a/tests/auto/qtquick1/qdeclarativelistmodel/qdeclarativelistmodel.pro b/tests/auto/qtquick1/qdeclarativelistmodel/qdeclarativelistmodel.pro
index 799b48a987..c928f1f33a 100644
--- a/tests/auto/qtquick1/qdeclarativelistmodel/qdeclarativelistmodel.pro
+++ b/tests/auto/qtquick1/qdeclarativelistmodel/qdeclarativelistmodel.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativelistmodel
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativelistmodel.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private v8-private widgets-private declarative-private qtquick1-private
+QT += core-private gui-private v8-private widgets-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/qtquick1/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
index a67c7c3916..945a2134d1 100644
--- a/tests/auto/qtquick1/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
+++ b/tests/auto/qtquick1/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
@@ -51,13 +51,6 @@
#include <QtCore/qtranslator.h>
#include <QSignalSpy>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
Q_DECLARE_METATYPE(QList<int>)
Q_DECLARE_METATYPE(QList<QVariantHash>)
diff --git a/tests/auto/qtquick1/qdeclarativelistview/qdeclarativelistview.pro b/tests/auto/qtquick1/qdeclarativelistview/qdeclarativelistview.pro
index 6adac2120d..1f66d7f45f 100644
--- a/tests/auto/qtquick1/qdeclarativelistview/qdeclarativelistview.pro
+++ b/tests/auto/qtquick1/qdeclarativelistview/qdeclarativelistview.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativelistview
macx:CONFIG -= app_bundle
HEADERS += incrementalmodel.h
SOURCES += tst_qdeclarativelistview.cpp incrementalmodel.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/qtquick1/qdeclarativelistview/tst_qdeclarativelistview.cpp
index c9cce3d6b3..835623f53c 100644
--- a/tests/auto/qtquick1/qdeclarativelistview/tst_qdeclarativelistview.cpp
+++ b/tests/auto/qtquick1/qdeclarativelistview/tst_qdeclarativelistview.cpp
@@ -50,14 +50,8 @@
#include <QtQuick1/private/qdeclarativetext_p.h>
#include <QtQuick1/private/qdeclarativevisualitemmodel_p.h>
#include <QtDeclarative/private/qlistmodelinterface_p.h>
-#include "../../../shared/util.h"
#include "incrementalmodel.h"
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_QDeclarative1ListView : public QObject
{
Q_OBJECT
diff --git a/tests/auto/qtquick1/qdeclarativeloader/qdeclarativeloader.pro b/tests/auto/qtquick1/qdeclarativeloader/qdeclarativeloader.pro
index c2d0fe693d..7f3cfb20b1 100644
--- a/tests/auto/qtquick1/qdeclarativeloader/qdeclarativeloader.pro
+++ b/tests/auto/qtquick1/qdeclarativeloader/qdeclarativeloader.pro
@@ -1,5 +1,5 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui network qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativeloader
macx:CONFIG -= app_bundle
INCLUDEPATH += ../../declarative/shared/
@@ -7,14 +7,8 @@ HEADERS += ../../declarative/shared/testhttpserver.h
SOURCES += tst_qdeclarativeloader.cpp \
../../declarative/shared/testhttpserver.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private declarative-private qtquick1-private network testlib
diff --git a/tests/auto/qtquick1/qdeclarativeloader/tst_qdeclarativeloader.cpp b/tests/auto/qtquick1/qdeclarativeloader/tst_qdeclarativeloader.cpp
index e73f9e0cf3..665f2b5521 100644
--- a/tests/auto/qtquick1/qdeclarativeloader/tst_qdeclarativeloader.cpp
+++ b/tests/auto/qtquick1/qdeclarativeloader/tst_qdeclarativeloader.cpp
@@ -47,15 +47,9 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtQuick1/private/qdeclarativeloader_p.h>
#include "testhttpserver.h"
-#include "../../../shared/util.h"
#define SERVER_PORT 14450
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
inline QUrl TEST_FILE(const QString &filename)
{
return QUrl::fromLocalFile(QLatin1String(SRCDIR) + QLatin1String("/data/") + filename);
diff --git a/tests/auto/qtquick1/qdeclarativemousearea/qdeclarativemousearea.pro b/tests/auto/qtquick1/qdeclarativemousearea/qdeclarativemousearea.pro
index 173990876c..f7e6a5b292 100644
--- a/tests/auto/qtquick1/qdeclarativemousearea/qdeclarativemousearea.pro
+++ b/tests/auto/qtquick1/qdeclarativemousearea/qdeclarativemousearea.pro
@@ -1,18 +1,12 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui network qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativemousearea
macx:CONFIG -= app_bundle
HEADERS += ../../declarative/shared/testhttpserver.h
SOURCES += tst_qdeclarativemousearea.cpp ../../declarative/shared/testhttpserver.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private declarative-private qtquick1-private network testlib
diff --git a/tests/auto/qtquick1/qdeclarativemousearea/tst_qdeclarativemousearea.cpp b/tests/auto/qtquick1/qdeclarativemousearea/tst_qdeclarativemousearea.cpp
index a84071045a..fc6a26d4d6 100644
--- a/tests/auto/qtquick1/qdeclarativemousearea/tst_qdeclarativemousearea.cpp
+++ b/tests/auto/qtquick1/qdeclarativemousearea/tst_qdeclarativemousearea.cpp
@@ -49,11 +49,6 @@
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtDeclarative/qdeclarativeproperty.h>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_QDeclarative1MouseArea: public QObject
{
Q_OBJECT
diff --git a/tests/auto/qtquick1/qdeclarativeparticles/qdeclarativeparticles.pro b/tests/auto/qtquick1/qdeclarativeparticles/qdeclarativeparticles.pro
index e968467c52..666fce999f 100644
--- a/tests/auto/qtquick1/qdeclarativeparticles/qdeclarativeparticles.pro
+++ b/tests/auto/qtquick1/qdeclarativeparticles/qdeclarativeparticles.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativeparticles
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativeparticles.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private declarative-private qtquick1
+QT += core-private gui-private widgets-private declarative-private qtquick1 testlib
diff --git a/tests/auto/qtquick1/qdeclarativeparticles/tst_qdeclarativeparticles.cpp b/tests/auto/qtquick1/qdeclarativeparticles/tst_qdeclarativeparticles.cpp
index a321c284c4..c4186f4d3a 100644
--- a/tests/auto/qtquick1/qdeclarativeparticles/tst_qdeclarativeparticles.cpp
+++ b/tests/auto/qtquick1/qdeclarativeparticles/tst_qdeclarativeparticles.cpp
@@ -43,11 +43,6 @@
#include <QtQuick1/qdeclarativeview.h>
#include <QGraphicsObject>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_QDeclarativeParticles : public QObject
{
Q_OBJECT
diff --git a/tests/auto/qtquick1/qdeclarativepathview/qdeclarativepathview.pro b/tests/auto/qtquick1/qdeclarativepathview/qdeclarativepathview.pro
index d72d3f326a..cf5cf64d01 100644
--- a/tests/auto/qtquick1/qdeclarativepathview/qdeclarativepathview.pro
+++ b/tests/auto/qtquick1/qdeclarativepathview/qdeclarativepathview.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativepathview
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativepathview.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativepathview/tst_qdeclarativepathview.cpp b/tests/auto/qtquick1/qdeclarativepathview/tst_qdeclarativepathview.cpp
index 194d42130d..d4e5378289 100644
--- a/tests/auto/qtquick1/qdeclarativepathview/tst_qdeclarativepathview.cpp
+++ b/tests/auto/qtquick1/qdeclarativepathview/tst_qdeclarativepathview.cpp
@@ -55,13 +55,6 @@
#include <QStandardItemModel>
#include <QFile>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
static void initStandardTreeModel(QStandardItemModel *model)
{
QStandardItem *item;
diff --git a/tests/auto/qtquick1/qdeclarativepincharea/qdeclarativepincharea.pro b/tests/auto/qtquick1/qdeclarativepincharea/qdeclarativepincharea.pro
index 7079de3f6e..4a8ef9bc5d 100644
--- a/tests/auto/qtquick1/qdeclarativepincharea/qdeclarativepincharea.pro
+++ b/tests/auto/qtquick1/qdeclarativepincharea/qdeclarativepincharea.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativepincharea
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativepincharea.cpp
-symbian: {
- importFiles.sources = data
- importFiles.path = .
- DEPLOYMENT = importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativepincharea/tst_qdeclarativepincharea.cpp b/tests/auto/qtquick1/qdeclarativepincharea/tst_qdeclarativepincharea.cpp
index e48bad3712..a1e27ea709 100644
--- a/tests/auto/qtquick1/qdeclarativepincharea/tst_qdeclarativepincharea.cpp
+++ b/tests/auto/qtquick1/qdeclarativepincharea/tst_qdeclarativepincharea.cpp
@@ -47,11 +47,6 @@
#include <QtQuick1/qdeclarativeview.h>
#include <QtDeclarative/qdeclarativecontext.h>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_QDeclarative1PinchArea: public QObject
{
Q_OBJECT
diff --git a/tests/auto/qtquick1/qdeclarativepositioners/qdeclarativepositioners.pro b/tests/auto/qtquick1/qdeclarativepositioners/qdeclarativepositioners.pro
index b5772ee044..2844c51232 100644
--- a/tests/auto/qtquick1/qdeclarativepositioners/qdeclarativepositioners.pro
+++ b/tests/auto/qtquick1/qdeclarativepositioners/qdeclarativepositioners.pro
@@ -1,16 +1,10 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativepositioners
SOURCES += tst_qdeclarativepositioners.cpp
macx:CONFIG -= app_bundle
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativepositioners/tst_qdeclarativepositioners.cpp b/tests/auto/qtquick1/qdeclarativepositioners/tst_qdeclarativepositioners.cpp
index 32eba6132b..35bd4fba5a 100644
--- a/tests/auto/qtquick1/qdeclarativepositioners/tst_qdeclarativepositioners.cpp
+++ b/tests/auto/qtquick1/qdeclarativepositioners/tst_qdeclarativepositioners.cpp
@@ -47,12 +47,6 @@
#include <QtQuick1/private/qdeclarativeitem_p.h>
#include <qdeclarativeexpression.h>
#include <QtWidgets/qgraphicswidget.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
class tst_QDeclarativePositioners : public QObject
{
diff --git a/tests/auto/qtquick1/qdeclarativerepeater/qdeclarativerepeater.pro b/tests/auto/qtquick1/qdeclarativerepeater/qdeclarativerepeater.pro
index 03bfdd8237..0fc556c10a 100644
--- a/tests/auto/qtquick1/qdeclarativerepeater/qdeclarativerepeater.pro
+++ b/tests/auto/qtquick1/qdeclarativerepeater/qdeclarativerepeater.pro
@@ -1,16 +1,10 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativerepeater
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativerepeater.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativerepeater/tst_qdeclarativerepeater.cpp b/tests/auto/qtquick1/qdeclarativerepeater/tst_qdeclarativerepeater.cpp
index de9ed67275..95f5dd2ed5 100644
--- a/tests/auto/qtquick1/qdeclarativerepeater/tst_qdeclarativerepeater.cpp
+++ b/tests/auto/qtquick1/qdeclarativerepeater/tst_qdeclarativerepeater.cpp
@@ -48,11 +48,6 @@
#include <QtQuick1/private/qdeclarativerepeater_p.h>
#include <QtQuick1/private/qdeclarativetext_p.h>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
inline QUrl TEST_FILE(const QString &filename)
{
return QUrl::fromLocalFile(QLatin1String(SRCDIR) + QLatin1String("/data/") + filename);
diff --git a/tests/auto/qtquick1/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro b/tests/auto/qtquick1/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro
index 873e15fbdd..3044072c7c 100644
--- a/tests/auto/qtquick1/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro
+++ b/tests/auto/qtquick1/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativesmoothedanimation
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativesmoothedanimation.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp b/tests/auto/qtquick1/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp
index 0b1c46d20c..7ddcc43dc9 100644
--- a/tests/auto/qtquick1/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp
+++ b/tests/auto/qtquick1/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp
@@ -44,12 +44,6 @@
#include <QtQuick1/private/qdeclarativesmoothedanimation_p.h>
#include <QtQuick1/private/qdeclarativerectangle_p.h>
#include <private/qdeclarativevaluetype_p.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
class tst_qdeclarativesmoothedanimation : public QObject
{
diff --git a/tests/auto/qtquick1/qdeclarativespringanimation/qdeclarativespringanimation.pro b/tests/auto/qtquick1/qdeclarativespringanimation/qdeclarativespringanimation.pro
index 327765dc8e..14b5fb3ec0 100644
--- a/tests/auto/qtquick1/qdeclarativespringanimation/qdeclarativespringanimation.pro
+++ b/tests/auto/qtquick1/qdeclarativespringanimation/qdeclarativespringanimation.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativespringanimation
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativespringanimation.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativespringanimation/tst_qdeclarativespringanimation.cpp b/tests/auto/qtquick1/qdeclarativespringanimation/tst_qdeclarativespringanimation.cpp
index 8c22f97acb..5a7bea6664 100644
--- a/tests/auto/qtquick1/qdeclarativespringanimation/tst_qdeclarativespringanimation.cpp
+++ b/tests/auto/qtquick1/qdeclarativespringanimation/tst_qdeclarativespringanimation.cpp
@@ -43,12 +43,6 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtQuick1/private/qdeclarativespringanimation_p.h>
#include <private/qdeclarativevaluetype_p.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
class tst_qdeclarativespringanimation : public QObject
{
diff --git a/tests/auto/qtquick1/qdeclarativestates/qdeclarativestates.pro b/tests/auto/qtquick1/qdeclarativestates/qdeclarativestates.pro
index ede4e8c4f1..1c9a58647f 100644
--- a/tests/auto/qtquick1/qdeclarativestates/qdeclarativestates.pro
+++ b/tests/auto/qtquick1/qdeclarativestates/qdeclarativestates.pro
@@ -1,16 +1,10 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativestates
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativestates.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/qtquick1/qdeclarativestates/tst_qdeclarativestates.cpp
index 8da3abf614..809d9ca65c 100644
--- a/tests/auto/qtquick1/qdeclarativestates/tst_qdeclarativestates.cpp
+++ b/tests/auto/qtquick1/qdeclarativestates/tst_qdeclarativestates.cpp
@@ -49,11 +49,6 @@
#include <QtQuick1/private/qdeclarativeitem_p.h>
#include <private/qdeclarativeproperty_p.h>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class MyAttached : public QObject
{
Q_OBJECT
diff --git a/tests/auto/qtquick1/qdeclarativesystempalette/qdeclarativesystempalette.pro b/tests/auto/qtquick1/qdeclarativesystempalette/qdeclarativesystempalette.pro
index 33effc776a..3efa477a33 100644
--- a/tests/auto/qtquick1/qdeclarativesystempalette/qdeclarativesystempalette.pro
+++ b/tests/auto/qtquick1/qdeclarativesystempalette/qdeclarativesystempalette.pro
@@ -1,13 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativesystempalette
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativesystempalette.cpp
-!symbian: {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativesystempalette/tst_qdeclarativesystempalette.cpp b/tests/auto/qtquick1/qdeclarativesystempalette/tst_qdeclarativesystempalette.cpp
index 0c44e9f833..22805be64f 100644
--- a/tests/auto/qtquick1/qdeclarativesystempalette/tst_qdeclarativesystempalette.cpp
+++ b/tests/auto/qtquick1/qdeclarativesystempalette/tst_qdeclarativesystempalette.cpp
@@ -45,15 +45,8 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtQuick1/private/qdeclarativesystempalette_p.h>
#include <qpalette.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
class tst_qdeclarativesystempalette : public QObject
-
{
Q_OBJECT
public:
diff --git a/tests/auto/qtquick1/qdeclarativetext/qdeclarativetext.pro b/tests/auto/qtquick1/qdeclarativetext/qdeclarativetext.pro
index 63dfc491ad..0989aab14f 100644
--- a/tests/auto/qtquick1/qdeclarativetext/qdeclarativetext.pro
+++ b/tests/auto/qtquick1/qdeclarativetext/qdeclarativetext.pro
@@ -1,6 +1,5 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
-QT += network
+CONFIG += testcase
+TARGET = tst_qdeclarativetext
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativetext.cpp
@@ -9,14 +8,8 @@ INCLUDEPATH += ../../declarative/shared/
HEADERS += ../../declarative/shared/testhttpserver.h
SOURCES += ../../declarative/shared/testhttpserver.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private network testlib
diff --git a/tests/auto/qtquick1/qdeclarativetext/tst_qdeclarativetext.cpp b/tests/auto/qtquick1/qdeclarativetext/tst_qdeclarativetext.cpp
index 801d631629..42a7fe1404 100644
--- a/tests/auto/qtquick1/qdeclarativetext/tst_qdeclarativetext.cpp
+++ b/tests/auto/qtquick1/qdeclarativetext/tst_qdeclarativetext.cpp
@@ -52,16 +52,9 @@
#include <QtWidgets/5.0.0/QtWidgets/private/qapplication_p.h>
#include <limits.h>
-#include "../../../shared/util.h"
#include "testhttpserver.h"
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qdeclarativetext : public QObject
-
{
Q_OBJECT
public:
diff --git a/tests/auto/qtquick1/qdeclarativetextedit/qdeclarativetextedit.pro b/tests/auto/qtquick1/qdeclarativetextedit/qdeclarativetextedit.pro
index 7eb558a92f..74c4215579 100644
--- a/tests/auto/qtquick1/qdeclarativetextedit/qdeclarativetextedit.pro
+++ b/tests/auto/qtquick1/qdeclarativetextedit/qdeclarativetextedit.pro
@@ -1,15 +1,10 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui network qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativetextedit
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativetextedit.cpp ../../declarative/shared/testhttpserver.cpp
HEADERS += ../../declarative/shared/testhttpserver.h
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+DEFINES += SRCDIR=\\\"$$PWD\\\"
+
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private network testlib
diff --git a/tests/auto/qtquick1/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/qtquick1/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
index ec48769ca3..2f5accae93 100644
--- a/tests/auto/qtquick1/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
+++ b/tests/auto/qtquick1/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
@@ -40,7 +40,6 @@
****************************************************************************/
#include <qtest.h>
#include <QtTest/QSignalSpy>
-#include "../../../shared/util.h"
#include "../../declarative/shared/testhttpserver.h"
#include <math.h>
#include <QFile>
@@ -61,11 +60,6 @@
#include <QtWidgets/5.0.0/QtWidgets/private/qapplication_p.h>
#include <private/qtextcontrol_p.h>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
Q_DECLARE_METATYPE(QDeclarative1TextEdit::SelectionMode)
QString createExpectedFileIfNotFound(const QString& filebasename, const QImage& actual)
@@ -1923,7 +1917,7 @@ void tst_qdeclarativetextedit::copyAndPaste() {
if (status == noErr)
CFRelease(pasteboard);
else
- QSKIP("This machine doesn't support the clipboard", SkipAll);
+ QSKIP("This machine doesn't support the clipboard");
}
#endif
@@ -2449,7 +2443,7 @@ void tst_qdeclarativetextedit::preeditMicroFocus()
ic.sendPreeditText(preeditText, 0);
currentRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect();
QCOMPARE(currentRect, previousRect);
-#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
QCOMPARE(ic.updateReceived, false); // The cursor position hasn't changed.
#endif
QCOMPARE(cursorRectangleSpy.count(), 0);
@@ -2461,7 +2455,7 @@ void tst_qdeclarativetextedit::preeditMicroFocus()
ic.sendPreeditText(preeditText, i);
currentRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect();
QVERIFY(previousRect.left() < currentRect.left());
-#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
QCOMPARE(ic.updateReceived, true);
#endif
QVERIFY(cursorRectangleSpy.count() > 0);
@@ -2476,7 +2470,7 @@ void tst_qdeclarativetextedit::preeditMicroFocus()
ic.sendEvent(QInputMethodEvent(preeditText, QList<QInputMethodEvent::Attribute>()));
currentRect = edit.inputMethodQuery(Qt::ImMicroFocus).toRect();
QCOMPARE(currentRect, previousRect);
-#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
QCOMPARE(ic.updateReceived, true);
#endif
QVERIFY(cursorRectangleSpy.count() > 0);
diff --git a/tests/auto/qtquick1/qdeclarativetextinput/qdeclarativetextinput.pro b/tests/auto/qtquick1/qdeclarativetextinput/qdeclarativetextinput.pro
index 213c4d6c65..655c4a27a1 100644
--- a/tests/auto/qtquick1/qdeclarativetextinput/qdeclarativetextinput.pro
+++ b/tests/auto/qtquick1/qdeclarativetextinput/qdeclarativetextinput.pro
@@ -1,15 +1,9 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativetextinput
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativetextinput.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/qtquick1/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
index 55c431f721..ff080cc1f2 100644
--- a/tests/auto/qtquick1/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
+++ b/tests/auto/qtquick1/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
@@ -40,7 +40,6 @@
****************************************************************************/
#include <qtest.h>
#include <QtTest/QSignalSpy>
-#include "../../../shared/util.h"
#include <QtDeclarative/qdeclarativeengine.h>
#include <QFile>
#include <QtQuick1/qdeclarativeview.h>
@@ -54,11 +53,6 @@
#include "qplatformdefs.h"
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
Q_DECLARE_METATYPE(QDeclarative1TextInput::SelectionMode)
QString createExpectedFileIfNotFound(const QString& filebasename, const QImage& actual)
@@ -1671,7 +1665,7 @@ void tst_qdeclarativetextinput::copyAndPaste() {
if (status == noErr)
CFRelease(pasteboard);
else
- QSKIP("This machine doesn't support the clipboard", SkipAll);
+ QSKIP("This machine doesn't support the clipboard");
}
#endif
@@ -2628,7 +2622,7 @@ void tst_qdeclarativetextinput::preeditMicroFocus()
ic.sendPreeditText(preeditText, 0);
currentRect = input.inputMethodQuery(Qt::ImMicroFocus).toRect();
QCOMPARE(currentRect, previousRect);
-#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
QCOMPARE(ic.updateReceived, true);
#endif
@@ -2639,7 +2633,7 @@ void tst_qdeclarativetextinput::preeditMicroFocus()
ic.sendPreeditText(preeditText, i);
currentRect = input.inputMethodQuery(Qt::ImMicroFocus).toRect();
QVERIFY(previousRect.left() < currentRect.left());
-#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
QCOMPARE(ic.updateReceived, true);
#endif
previousRect = currentRect;
@@ -2652,7 +2646,7 @@ void tst_qdeclarativetextinput::preeditMicroFocus()
ic.sendEvent(QInputMethodEvent(preeditText, QList<QInputMethodEvent::Attribute>()));
currentRect = input.inputMethodQuery(Qt::ImMicroFocus).toRect();
QCOMPARE(currentRect, previousRect);
-#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
QCOMPARE(ic.updateReceived, true);
#endif
}
diff --git a/tests/auto/qtquick1/qdeclarativetimer/qdeclarativetimer.pro b/tests/auto/qtquick1/qdeclarativetimer/qdeclarativetimer.pro
index d0639dcdd5..4709d21ac0 100644
--- a/tests/auto/qtquick1/qdeclarativetimer/qdeclarativetimer.pro
+++ b/tests/auto/qtquick1/qdeclarativetimer/qdeclarativetimer.pro
@@ -1,12 +1,10 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativetimer
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativetimer.cpp
-!symbian: {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativetimer/tst_qdeclarativetimer.cpp b/tests/auto/qtquick1/qdeclarativetimer/tst_qdeclarativetimer.cpp
index 8b1b79a034..4af458561b 100644
--- a/tests/auto/qtquick1/qdeclarativetimer/tst_qdeclarativetimer.cpp
+++ b/tests/auto/qtquick1/qdeclarativetimer/tst_qdeclarativetimer.cpp
@@ -46,11 +46,6 @@
#include <QtQuick1/qdeclarativeitem.h>
#include <QDebug>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qdeclarativetimer : public QObject
{
Q_OBJECT
@@ -85,12 +80,7 @@ public slots:
}
};
-#if defined(Q_OS_SYMBIAN) && defined(Q_CC_NOKIAX86)
-// Increase wait as emulator startup can cause unexpected delays
-#define TIMEOUT_TIMEOUT 2000
-#else
#define TIMEOUT_TIMEOUT 200
-#endif
tst_qdeclarativetimer::tst_qdeclarativetimer()
{
diff --git a/tests/auto/qtquick1/qdeclarativeview/qdeclarativeview.pro b/tests/auto/qtquick1/qdeclarativeview/qdeclarativeview.pro
index c81a4a7695..08f10dfc9e 100644
--- a/tests/auto/qtquick1/qdeclarativeview/qdeclarativeview.pro
+++ b/tests/auto/qtquick1/qdeclarativeview/qdeclarativeview.pro
@@ -1,14 +1,9 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativeview
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativeview.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-QT += core-private gui-private widgets-private declarative-private qtquick1-private widgets
+DEFINES += SRCDIR=\\\"$$PWD\\\"
+
+QT += core-private gui-private widgets-private declarative-private qtquick1-private widgets testlib
diff --git a/tests/auto/qtquick1/qdeclarativeview/tst_qdeclarativeview.cpp b/tests/auto/qtquick1/qdeclarativeview/tst_qdeclarativeview.cpp
index 9b844de946..b2dfc8e8f6 100644
--- a/tests/auto/qtquick1/qdeclarativeview/tst_qdeclarativeview.cpp
+++ b/tests/auto/qtquick1/qdeclarativeview/tst_qdeclarativeview.cpp
@@ -45,15 +45,8 @@
#include <QtQuick1/qdeclarativeview.h>
#include <QtQuick1/qdeclarativeitem.h>
#include <QtWidgets/qgraphicswidget.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
class tst_QDeclarativeView : public QObject
-
{
Q_OBJECT
public:
diff --git a/tests/auto/qtquick1/qdeclarativeviewer/qdeclarativeviewer.pro b/tests/auto/qtquick1/qdeclarativeviewer/qdeclarativeviewer.pro
index 433eaf8029..b49264bcca 100644
--- a/tests/auto/qtquick1/qdeclarativeviewer/qdeclarativeviewer.pro
+++ b/tests/auto/qtquick1/qdeclarativeviewer/qdeclarativeviewer.pro
@@ -1,19 +1,12 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativeviewer
macx:CONFIG -= app_bundle
include(../../../../tools/qmlviewer/qml.pri)
SOURCES += tst_qdeclarativeviewer.cpp
-symbian: {
- include(../symbianlibs.pri)
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test insignificant_test
-QT += core-private gui-private widgets-private declarative-private qtquick1-private widgets-private v8-private
+QT += core-private gui-private widgets-private declarative-private qtquick1-private v8-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativeviewer/tst_qdeclarativeviewer.cpp b/tests/auto/qtquick1/qdeclarativeviewer/tst_qdeclarativeviewer.cpp
index e6bd2d0a31..3ab836be40 100644
--- a/tests/auto/qtquick1/qdeclarativeviewer/tst_qdeclarativeviewer.cpp
+++ b/tests/auto/qtquick1/qdeclarativeviewer/tst_qdeclarativeviewer.cpp
@@ -46,17 +46,10 @@
#include <QtDeclarative/qdeclarativecontext.h>
#include <QtWidgets/qmenubar.h>
#include <QSignalSpy>
-#include "../../../shared/util.h"
#include "qmlruntime.h"
#include "deviceorientation.h"
-#include "../../../shared/util.h"
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
-#if defined(Q_OS_MAC) || defined(Q_WS_MAEMO_5) || defined(Q_WS_S60)
+#if defined(Q_OS_MAC) || defined(Q_WS_MAEMO_5)
# define MENUBAR_HEIGHT(mw) 0
#else
# define MENUBAR_HEIGHT(mw) (mw->menuBar()->height())
diff --git a/tests/auto/qtquick1/qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro b/tests/auto/qtquick1/qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro
index 0f7eec330b..128e4ff244 100644
--- a/tests/auto/qtquick1/qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro
+++ b/tests/auto/qtquick1/qdeclarativevisualdatamodel/qdeclarativevisualdatamodel.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui qtquick1
+CONFIG += testcase
+TARGET = tst_qdeclarativevisualdatamodel
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativevisualdatamodel.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private testlib
diff --git a/tests/auto/qtquick1/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp b/tests/auto/qtquick1/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp
index d08251e67b..2d849a8029 100644
--- a/tests/auto/qtquick1/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp
+++ b/tests/auto/qtquick1/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp
@@ -52,11 +52,6 @@
#include <private/qdeclarativevaluetype_p.h>
#include <math.h>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
static void initStandardTreeModel(QStandardItemModel *model)
{
QStandardItem *item;
diff --git a/tests/auto/qtquick1/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro b/tests/auto/qtquick1/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro
index cb7b5434f9..fc74409802 100644
--- a/tests/auto/qtquick1/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro
+++ b/tests/auto/qtquick1/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro
@@ -1,21 +1,11 @@
-load(qttest_p4)
-contains(QT_CONFIG,declarative): QT += declarative gui network qtquick1
-contains(QT_CONFIG,xmlpatterns) {
- QT += xmlpatterns
- DEFINES += QTEST_XMLPATTERNS
-}
+CONFIG += testcase
+TARGET = tst_qdeclarativexmllistmodel
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativexmllistmodel.cpp
-symbian: {
- importFiles.files = data
- importFiles.path = .
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
CONFIG += parallel_test
-QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private
+QT += core-private gui-private widgets-private v8-private declarative-private qtquick1-private network testlib xmlpatterns
diff --git a/tests/auto/qtquick1/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp b/tests/auto/qtquick1/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp
index 35a78e0a46..4a219dbe6d 100644
--- a/tests/auto/qtquick1/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp
+++ b/tests/auto/qtquick1/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp
@@ -53,16 +53,9 @@
#include <QtCore/qfile.h>
#include <QtCore/qtemporaryfile.h>
-#ifdef QTEST_XMLPATTERNS
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtQuick1/private/qdeclarativexmllistmodel_p.h>
-#include "../../../shared/util.h"
-
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
typedef QPair<int, int> QDeclarativeXmlListRange;
typedef QList<QVariantList> QDeclarativeXmlModelData;
@@ -959,7 +952,3 @@ void tst_qdeclarativexmllistmodel::roleCrash()
QTEST_MAIN(tst_qdeclarativexmllistmodel)
#include "tst_qdeclarativexmllistmodel.moc"
-
-#else
-QTEST_NOOP_MAIN
-#endif
diff --git a/tests/auto/qtquick1/qtquick1.pro b/tests/auto/qtquick1/qtquick1.pro
index 489accb839..f1177cd0f2 100644
--- a/tests/auto/qtquick1/qtquick1.pro
+++ b/tests/auto/qtquick1/qtquick1.pro
@@ -45,7 +45,6 @@ contains(QT_CONFIG, private_tests) {
qdeclarativexmllistmodel \
examples
+ # This test needs the xmlpatterns module
+ !contains(QT_CONFIG,xmlpatterns): SUBDIRS -= qdeclarativexmllistmodel
}
-
-# Tests which should run in Pulse
-PULSE_TESTS = $$SUBDIRS
diff --git a/tests/benchmarks/declarative/binding/binding.pro b/tests/benchmarks/declarative/binding/binding.pro
index bbe8701d32..ba59080232 100644
--- a/tests/benchmarks/declarative/binding/binding.pro
+++ b/tests/benchmarks/declarative/binding/binding.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
+CONFIG += testcase
TEMPLATE = app
TARGET = tst_binding
-QT += declarative
+QT += declarative testlib
macx:CONFIG -= app_bundle
SOURCES += tst_binding.cpp testtypes.cpp
HEADERS += testtypes.h
-symbian {
- data.files = data
- data.path = .
- DEPLOYMENT += data
-} else {
- # Define SRCDIR equal to test's source directory
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+# Define SRCDIR equal to test's source directory
+DEFINES += SRCDIR=\\\"$$PWD\\\"
diff --git a/tests/benchmarks/declarative/binding/tst_binding.cpp b/tests/benchmarks/declarative/binding/tst_binding.cpp
index 70796f682a..c1b5035789 100644
--- a/tests/benchmarks/declarative/binding/tst_binding.cpp
+++ b/tests/benchmarks/declarative/binding/tst_binding.cpp
@@ -49,11 +49,6 @@
//TESTED_FILES=
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_binding : public QObject
{
Q_OBJECT
diff --git a/tests/benchmarks/declarative/compilation/compilation.pro b/tests/benchmarks/declarative/compilation/compilation.pro
index 9ab2a25731..44ea3d0c68 100644
--- a/tests/benchmarks/declarative/compilation/compilation.pro
+++ b/tests/benchmarks/declarative/compilation/compilation.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
+CONFIG += testcase
TEMPLATE = app
TARGET = tst_compilation
-QT += declarative
+QT += declarative testlib
macx:CONFIG -= app_bundle
CONFIG += release
SOURCES += tst_compilation.cpp
-symbian {
- data.files += data
- data.path = .
- DEPLOYMENT += data
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
diff --git a/tests/benchmarks/declarative/compilation/tst_compilation.cpp b/tests/benchmarks/declarative/compilation/tst_compilation.cpp
index 9b4f9a70e8..17200439f4 100644
--- a/tests/benchmarks/declarative/compilation/tst_compilation.cpp
+++ b/tests/benchmarks/declarative/compilation/tst_compilation.cpp
@@ -53,11 +53,6 @@
#include <QDebug>
#include <QTextStream>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_compilation : public QObject
{
Q_OBJECT
diff --git a/tests/benchmarks/declarative/creation/creation.pro b/tests/benchmarks/declarative/creation/creation.pro
index 4d6cafba49..6d0d9d7e8f 100644
--- a/tests/benchmarks/declarative/creation/creation.pro
+++ b/tests/benchmarks/declarative/creation/creation.pro
@@ -1,17 +1,10 @@
-load(qttest_p4)
+CONFIG += testcase
TEMPLATE = app
TARGET = tst_creation
-QT += declarative qtquick1 widgets
macx:CONFIG -= app_bundle
SOURCES += tst_creation.cpp
-symbian {
- data.files = data
- data.path = .
- DEPLOYMENT += data
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
-QT += core-private gui-private declarative-private qtquick1-private
+QT += core-private gui-private declarative-private qtquick1-private widgets testlib
diff --git a/tests/benchmarks/declarative/creation/tst_creation.cpp b/tests/benchmarks/declarative/creation/tst_creation.cpp
index 2ccdcb43bd..ebc51dde8a 100644
--- a/tests/benchmarks/declarative/creation/tst_creation.cpp
+++ b/tests/benchmarks/declarative/creation/tst_creation.cpp
@@ -51,11 +51,6 @@
#include <QtQuick1/private/qdeclarativetextinput_p.h>
#include <private/qobject_p.h>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_creation : public QObject
{
Q_OBJECT
@@ -353,7 +348,7 @@ void tst_creation::elements()
QFETCH(QString, type);
QDeclarativeType *t = QDeclarativeMetaType::qmlType(type, 2, 0);
if (!t || !t->isCreatable())
- QSKIP("Non-creatable type", SkipSingle);
+ QSKIP("Non-creatable type");
QBENCHMARK {
QObject *obj = t->create();
diff --git a/tests/benchmarks/declarative/holistic/holistic.pro b/tests/benchmarks/declarative/holistic/holistic.pro
index fadb04db88..586af79275 100644
--- a/tests/benchmarks/declarative/holistic/holistic.pro
+++ b/tests/benchmarks/declarative/holistic/holistic.pro
@@ -1,7 +1,7 @@
-load(qttest_p4)
+CONFIG += testcase
TEMPLATE = app
TARGET = tst_holistic
-QT += declarative network
+QT += declarative network testlib
macx:CONFIG -= app_bundle
CONFIG += release
@@ -10,10 +10,4 @@ SOURCES += tst_holistic.cpp \
testtypes.cpp
HEADERS += testtypes.h
-symbian {
- data.files += data
- data.path = .
- DEPLOYMENT += data
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
diff --git a/tests/benchmarks/declarative/holistic/tst_holistic.cpp b/tests/benchmarks/declarative/holistic/tst_holistic.cpp
index 102a91cb25..88c7d52f56 100644
--- a/tests/benchmarks/declarative/holistic/tst_holistic.cpp
+++ b/tests/benchmarks/declarative/holistic/tst_holistic.cpp
@@ -49,11 +49,6 @@
#include <QFile>
#include <QDebug>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
// Conceptually, there are several different "holistic" areas to benchmark:
// 1) Loading
// - read file from disk
diff --git a/tests/benchmarks/declarative/javascript/javascript.pro b/tests/benchmarks/declarative/javascript/javascript.pro
index 7395cef07e..8026540309 100644
--- a/tests/benchmarks/declarative/javascript/javascript.pro
+++ b/tests/benchmarks/declarative/javascript/javascript.pro
@@ -1,7 +1,7 @@
-load(qttest_p4)
+CONFIG += testcase
TEMPLATE = app
TARGET = tst_javascript
-QT += declarative
+QT += declarative testlib
macx:CONFIG -= app_bundle
SOURCES += tst_javascript.cpp testtypes.cpp
diff --git a/tests/benchmarks/declarative/js/qjsengine/qjsengine.pro b/tests/benchmarks/declarative/js/qjsengine/qjsengine.pro
index cbd128bf97..f04da8ec95 100644
--- a/tests/benchmarks/declarative/js/qjsengine/qjsengine.pro
+++ b/tests/benchmarks/declarative/js/qjsengine/qjsengine.pro
@@ -1,12 +1,7 @@
-load(qttest_p4)
+CONFIG += testcase
TEMPLATE = app
TARGET = tst_bench_qjsengine
SOURCES += tst_qjsengine.cpp
-QT += declarative
-
-symbian* {
- TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 // Min 128kB, Max 32MB
- TARGET.EPOCSTACKSIZE = 0x14000
-}
+QT += declarative testlib
diff --git a/tests/benchmarks/declarative/js/qjsengine/tst_qjsengine.cpp b/tests/benchmarks/declarative/js/qjsengine/tst_qjsengine.cpp
index f8bade3f9d..da5788e6fe 100644
--- a/tests/benchmarks/declarative/js/qjsengine/tst_qjsengine.cpp
+++ b/tests/benchmarks/declarative/js/qjsengine/tst_qjsengine.cpp
@@ -540,13 +540,8 @@ void tst_QJSEngine::nativeCall()
newEngine();
m_engine->globalObject().setProperty("fun", m_engine->newFunction(native_function));
QBENCHMARK{
-#if !defined(Q_OS_SYMBIAN)
m_engine->evaluate("var w = 0; for (i = 0; i < 100000; ++i) {\n"
" w += fun() + fun(); w -= fun(); fun(); w -= fun(); }");
-#else
- m_engine->evaluate("var w = 0; for (i = 0; i < 25000; ++i) {\n"
- " w += fun() + fun(); w -= fun(); fun(); w -= fun(); }");
-#endif
}
}
diff --git a/tests/benchmarks/declarative/js/qjsvalue/qjsvalue.pro b/tests/benchmarks/declarative/js/qjsvalue/qjsvalue.pro
index 48c40a2a52..2dc917d3aa 100644
--- a/tests/benchmarks/declarative/js/qjsvalue/qjsvalue.pro
+++ b/tests/benchmarks/declarative/js/qjsvalue/qjsvalue.pro
@@ -1,7 +1,7 @@
-load(qttest_p4)
+CONFIG += testcase
TEMPLATE = app
TARGET = tst_bench_qjsvalue
SOURCES += tst_qjsvalue.cpp
-QT += declarative
+QT += declarative testlib
diff --git a/tests/benchmarks/declarative/js/qjsvalueiterator/qjsvalueiterator.pro b/tests/benchmarks/declarative/js/qjsvalueiterator/qjsvalueiterator.pro
index a114b863f6..a15ceba9a4 100644
--- a/tests/benchmarks/declarative/js/qjsvalueiterator/qjsvalueiterator.pro
+++ b/tests/benchmarks/declarative/js/qjsvalueiterator/qjsvalueiterator.pro
@@ -1,7 +1,7 @@
-load(qttest_p4)
+CONFIG += testcase
TEMPLATE = app
TARGET = tst_bench_qjsvalueiterator
SOURCES += tst_qjsvalueiterator.cpp
-QT = core declarative
+QT = core declarative testlib
diff --git a/tests/benchmarks/declarative/pointers/pointers.pro b/tests/benchmarks/declarative/pointers/pointers.pro
index 5180a2a9d1..d4112f94ec 100644
--- a/tests/benchmarks/declarative/pointers/pointers.pro
+++ b/tests/benchmarks/declarative/pointers/pointers.pro
@@ -1,5 +1,5 @@
-load(qttest_p4)
-QT += declarative
+CONFIG += testcase
+QT += declarative testlib
TEMPLATE = app
TARGET = tst_pointers
macx:CONFIG -= app_bundle
diff --git a/tests/benchmarks/declarative/qdeclarativecomponent/qdeclarativecomponent.pro b/tests/benchmarks/declarative/qdeclarativecomponent/qdeclarativecomponent.pro
index 4693a82231..0d415db8ba 100644
--- a/tests/benchmarks/declarative/qdeclarativecomponent/qdeclarativecomponent.pro
+++ b/tests/benchmarks/declarative/qdeclarativecomponent/qdeclarativecomponent.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
+CONFIG += testcase
TEMPLATE = app
TARGET = tst_qdeclarativecomponent
-QT += declarative
+QT += declarative testlib
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativecomponent.cpp testtypes.cpp
HEADERS += testtypes.h
-symbian {
- data.files = data
- data.path = .
- DEPLOYMENT += data
-} else {
- # Define SRCDIR equal to test's source directory
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+# Define SRCDIR equal to test's source directory
+DEFINES += SRCDIR=\\\"$$PWD\\\"
diff --git a/tests/benchmarks/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp b/tests/benchmarks/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp
index 94b096792f..1ff3e2db84 100644
--- a/tests/benchmarks/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp
+++ b/tests/benchmarks/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp
@@ -48,11 +48,6 @@
//TESTED_FILES=
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qmlcomponent : public QObject
{
Q_OBJECT
diff --git a/tests/benchmarks/declarative/qdeclarativedebugtrace/qdeclarativedebugtrace.pro b/tests/benchmarks/declarative/qdeclarativedebugtrace/qdeclarativedebugtrace.pro
index e9aea4f71c..6f2712adec 100644
--- a/tests/benchmarks/declarative/qdeclarativedebugtrace/qdeclarativedebugtrace.pro
+++ b/tests/benchmarks/declarative/qdeclarativedebugtrace/qdeclarativedebugtrace.pro
@@ -1,5 +1,5 @@
-load(qttest_p4)
-QT += declarative
+CONFIG += testcase
+QT += declarative testlib
TEMPLATE = app
TARGET = tst_qdeclarativedebugtrace
macx:CONFIG -= app_bundle
diff --git a/tests/benchmarks/declarative/qdeclarativeimage/qdeclarativeimage.pro b/tests/benchmarks/declarative/qdeclarativeimage/qdeclarativeimage.pro
index 0d7c184f37..6a46e8f40c 100644
--- a/tests/benchmarks/declarative/qdeclarativeimage/qdeclarativeimage.pro
+++ b/tests/benchmarks/declarative/qdeclarativeimage/qdeclarativeimage.pro
@@ -1,17 +1,11 @@
-load(qttest_p4)
+CONFIG += testcase
TEMPLATE = app
TARGET = tst_qdeclarativeimage
-QT += declarative
+QT += declarative testlib
macx:CONFIG -= app_bundle
CONFIG += release
SOURCES += tst_qdeclarativeimage.cpp
-symbian {
- importFiles.files = image.png
- importFiles.path =
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+DEFINES += SRCDIR=\\\"$$PWD\\\"
diff --git a/tests/benchmarks/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp b/tests/benchmarks/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp
index 74bb35b055..2aade96143 100644
--- a/tests/benchmarks/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp
+++ b/tests/benchmarks/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp
@@ -44,11 +44,6 @@
#include <QDeclarativeComponent>
#include <private/qdeclarativeimage_p.h>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qmlgraphicsimage : public QObject
{
Q_OBJECT
diff --git a/tests/benchmarks/declarative/qdeclarativemetaproperty/qdeclarativemetaproperty.pro b/tests/benchmarks/declarative/qdeclarativemetaproperty/qdeclarativemetaproperty.pro
index 765e37a15d..1ac0bb240a 100644
--- a/tests/benchmarks/declarative/qdeclarativemetaproperty/qdeclarativemetaproperty.pro
+++ b/tests/benchmarks/declarative/qdeclarativemetaproperty/qdeclarativemetaproperty.pro
@@ -1,16 +1,10 @@
-load(qttest_p4)
+CONFIG += testcase
TEMPLATE = app
TARGET = tst_qdeclarativemetaproperty
-QT += declarative
+QT += declarative testlib
macx:CONFIG -= app_bundle
SOURCES += tst_qdeclarativemetaproperty.cpp
-symbian {
- data.files += data
- data.path = .
- DEPLOYMENT += data
-} else {
- # Define SRCDIR equal to test's source directory
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
+# Define SRCDIR equal to test's source directory
+DEFINES += SRCDIR=\\\"$$PWD\\\"
diff --git a/tests/benchmarks/declarative/qdeclarativemetaproperty/tst_qdeclarativemetaproperty.cpp b/tests/benchmarks/declarative/qdeclarativemetaproperty/tst_qdeclarativemetaproperty.cpp
index ff18aa435e..05dd46a17f 100644
--- a/tests/benchmarks/declarative/qdeclarativemetaproperty/tst_qdeclarativemetaproperty.cpp
+++ b/tests/benchmarks/declarative/qdeclarativemetaproperty/tst_qdeclarativemetaproperty.cpp
@@ -48,11 +48,6 @@
//TESTED_FILES=
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_qmlmetaproperty : public QObject
{
Q_OBJECT
diff --git a/tests/benchmarks/declarative/qmltime/qmltime.cpp b/tests/benchmarks/declarative/qmltime/qmltime.cpp
index d5a3c5a7c0..4e7ef3a995 100644
--- a/tests/benchmarks/declarative/qmltime/qmltime.cpp
+++ b/tests/benchmarks/declarative/qmltime/qmltime.cpp
@@ -247,11 +247,7 @@ int main(int argc, char ** argv)
}
if (filename.isEmpty())
-#ifdef Q_OS_SYMBIAN
- filename = QLatin1String("./tests/item_creation/data.qml");
-#else
usage(argv[0]);
-#endif
QDeclarativeEngine engine;
QDeclarativeComponent component(&engine, filename);
@@ -272,9 +268,6 @@ int main(int argc, char ** argv)
return -1;
}
-#ifdef Q_OS_SYMBIAN
- willParent = true;
-#endif
timer->setWillParent(willParent);
if (!timer->component()) {
@@ -282,10 +275,6 @@ int main(int argc, char ** argv)
return -1;
}
-#ifdef Q_OS_SYMBIAN
- iterations = 1024;
-#endif
-
timer->run(iterations);
return 0;
diff --git a/tests/benchmarks/declarative/qmltime/qmltime.pro b/tests/benchmarks/declarative/qmltime/qmltime.pro
index 273a60ac75..e1948981bf 100644
--- a/tests/benchmarks/declarative/qmltime/qmltime.pro
+++ b/tests/benchmarks/declarative/qmltime/qmltime.pro
@@ -1,15 +1,8 @@
-load(qttest_p4)
+CONFIG += testcase
TEMPLATE = app
TARGET = qmltime
-QT += declarative
+QT += declarative widgets testlib
macx:CONFIG -= app_bundle
SOURCES += qmltime.cpp
-symbian {
- TARGET.CAPABILITY = "All -TCB"
- example.files = example.qml tests
- example.path = .
- DEPLOYMENT += example
-}
-
diff --git a/tests/benchmarks/declarative/script/script.pro b/tests/benchmarks/declarative/script/script.pro
index 01df571fda..310d17d3c9 100644
--- a/tests/benchmarks/declarative/script/script.pro
+++ b/tests/benchmarks/declarative/script/script.pro
@@ -1,20 +1,10 @@
-load(qttest_p4)
+CONFIG += testcase
TEMPLATE = app
TARGET = tst_script
-QT += declarative
+QT += declarative testlib
macx:CONFIG -= app_bundle
CONFIG += release
SOURCES += tst_script.cpp
-symbian {
- importFiles.files = data
- importFiles.path =
- DEPLOYMENT += importFiles
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-}
-
-
-
-
+DEFINES += SRCDIR=\\\"$$PWD\\\"
diff --git a/tests/benchmarks/declarative/script/tst_script.cpp b/tests/benchmarks/declarative/script/tst_script.cpp
index 4321b09b75..1ac51319e5 100644
--- a/tests/benchmarks/declarative/script/tst_script.cpp
+++ b/tests/benchmarks/declarative/script/tst_script.cpp
@@ -48,11 +48,6 @@
#include <QScriptEngine>
#include <QScriptValue>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_script : public QObject
{
Q_OBJECT
diff --git a/tests/benchmarks/declarative/typeimports/tst_typeimports.cpp b/tests/benchmarks/declarative/typeimports/tst_typeimports.cpp
index 16b54b5350..caa1777d0b 100644
--- a/tests/benchmarks/declarative/typeimports/tst_typeimports.cpp
+++ b/tests/benchmarks/declarative/typeimports/tst_typeimports.cpp
@@ -44,11 +44,6 @@
#include <QDeclarativeComponent>
#include <QDebug>
-#ifdef Q_OS_SYMBIAN
-// In Symbian OS test data is located in applications private dir
-#define SRCDIR "."
-#endif
-
class tst_typeimports : public QObject
{
Q_OBJECT
diff --git a/tests/benchmarks/declarative/typeimports/typeimports.pro b/tests/benchmarks/declarative/typeimports/typeimports.pro
index 56834e6175..403387f0ce 100644
--- a/tests/benchmarks/declarative/typeimports/typeimports.pro
+++ b/tests/benchmarks/declarative/typeimports/typeimports.pro
@@ -1,15 +1,9 @@
-load(qttest_p4)
+CONFIG += testcase
TEMPLATE = app
TARGET = tst_typeimports
-QT += declarative
+QT += declarative testlib
macx:CONFIG -= app_bundle
SOURCES += tst_typeimports.cpp
-symbian {
- data.files = data
- data.path = .
- DEPLOYMENT += data
-} else {
- DEFINES += SRCDIR=\\\"$$PWD\\\"
-} \ No newline at end of file
+DEFINES += SRCDIR=\\\"$$PWD\\\"
diff --git a/tests/benchmarks/particles/affectors/affectors.pro b/tests/benchmarks/particles/affectors/affectors.pro
new file mode 100644
index 0000000000..4d1926da22
--- /dev/null
+++ b/tests/benchmarks/particles/affectors/affectors.pro
@@ -0,0 +1,10 @@
+CONFIG += testcase
+TARGET = tst_affectors
+SOURCES += tst_affectors.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
diff --git a/tests/benchmarks/particles/affectors/data/basic.qml b/tests/benchmarks/particles/affectors/data/basic.qml
new file mode 100644
index 0000000000..a10e2002d5
--- /dev/null
+++ b/tests/benchmarks/particles/affectors/data/basic.qml
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+ running: false //Benchmark will manage it
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ }
+
+ Emitter{
+ //0,0 position
+ id: emitter
+ enabled: false
+ size: 32
+ emitRate: 1000
+ lifeSpan: Emitter.InfiniteLife
+ maximumEmitted: 1000
+ Component.onCompleted: emitter.burst(1000);
+ }
+
+ Affector{
+ }
+ }
+}
diff --git a/tests/benchmarks/particles/affectors/data/filtered.qml b/tests/benchmarks/particles/affectors/data/filtered.qml
new file mode 100644
index 0000000000..1b88140044
--- /dev/null
+++ b/tests/benchmarks/particles/affectors/data/filtered.qml
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+ running: false //Benchmark will manage it
+
+ ImageParticle {
+ groups: ["A"]
+ source: "../../shared/star.png"
+ }
+
+ Emitter{
+ //central position
+ id: emitter
+ x: 160
+ y: 160
+ group: "A"
+ size: 32
+ emitRate: 1000
+ lifeSpan: Emitter.InfiniteLife
+ maximumEmitted: 1000
+ enabled: false
+ Component.onCompleted: emitter.burst(1000);
+ }
+
+ Affector{
+ groups: ["A"]
+ anchors.fill: parent
+ //whenCollidingWith: ["A"] //Test separately?
+ }
+ }
+}
diff --git a/tests/benchmarks/particles/affectors/tst_affectors.cpp b/tests/benchmarks/particles/affectors/tst_affectors.cpp
new file mode 100644
index 0000000000..f85f877c51
--- /dev/null
+++ b/tests/benchmarks/particles/affectors/tst_affectors.cpp
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qtest.h>
+#include <QtTest/QtTest>
+#include "../../../auto/particles/shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+
+class tst_affectors : public QObject
+{
+ Q_OBJECT
+public:
+ tst_affectors();
+
+private slots:
+ void test_basic();
+ void test_basic_data();
+ void test_filtered();
+ void test_filtered_data();
+};
+
+tst_affectors::tst_affectors()
+{
+}
+
+void tst_affectors::test_basic_data()
+{
+ QTest::addColumn<int> ("dt");
+ QTest::newRow("16ms") << 16;
+ QTest::newRow("32ms") << 32;
+ QTest::newRow("100ms") << 100;
+ QTest::newRow("500ms") << 500;
+}
+
+void tst_affectors::test_filtered_data()
+{
+ QTest::addColumn<int> ("dt");
+ QTest::newRow("16ms") << 16;
+ QTest::newRow("32ms") << 32;
+ QTest::newRow("100ms") << 100;
+ QTest::newRow("500ms") << 500;
+}
+
+void tst_affectors::test_basic()
+{
+ QFETCH(int, dt);
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml");
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ //Pretend we're running, but we manually advance the simulation
+ system->m_running = true;
+ system->m_animation = 0;
+ system->reset();
+
+ int curTime = 1;
+ system->updateCurrentTime(curTime);//Fixed point and get init out of the way - including emission
+
+ QBENCHMARK {
+ curTime += dt;
+ system->updateCurrentTime(curTime);
+ }
+
+ int stillAlive = 0;
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 1000, 10));//Small simulation variance is permissible.
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ if (d->stillAlive())
+ stillAlive++;
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+ QVERIFY(extremelyFuzzyCompare(stillAlive, 1000, 10));//Small simulation variance is permissible.
+ delete view;
+}
+
+void tst_affectors::test_filtered()
+{
+ QFETCH(int, dt);
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/filtered.qml");
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ //Pretend we're running, but we manually advance the simulation
+ system->m_running = true;
+ system->m_animation = 0;
+ system->reset();
+
+ int curTime = 1;
+ system->updateCurrentTime(curTime);//Fixed point and get init out of the way - including emission
+
+ QBENCHMARK {
+ curTime += dt;
+ system->updateCurrentTime(curTime);
+ }
+
+ int stillAlive = 0;
+ QVERIFY(extremelyFuzzyCompare(system->groupData[1]->size(), 1000, 10));//Small simulation variance is permissible.
+ foreach (QSGParticleData *d, system->groupData[1]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ if (d->stillAlive())
+ stillAlive++;
+ QCOMPARE(d->x, 160.f);
+ QCOMPARE(d->y, 160.f);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+ QVERIFY(extremelyFuzzyCompare(stillAlive, 1000, 10));//Small simulation variance is permissible.
+ delete view;
+}
+
+QTEST_MAIN(tst_affectors);
+
+#include "tst_affectors.moc"
diff --git a/tests/benchmarks/particles/emission/data/basic.qml b/tests/benchmarks/particles/emission/data/basic.qml
new file mode 100644
index 0000000000..9ded4b69c1
--- /dev/null
+++ b/tests/benchmarks/particles/emission/data/basic.qml
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+ running: false //Benchmark will manage it
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ }
+
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 2000
+ lifeSpan: 500
+ }
+ }
+}
diff --git a/tests/benchmarks/particles/emission/emission.pro b/tests/benchmarks/particles/emission/emission.pro
new file mode 100644
index 0000000000..6e5e8ec019
--- /dev/null
+++ b/tests/benchmarks/particles/emission/emission.pro
@@ -0,0 +1,10 @@
+CONFIG += testcase
+TARGET = tst_emission
+SOURCES += tst_emission.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
diff --git a/tests/benchmarks/particles/emission/tst_emission.cpp b/tests/benchmarks/particles/emission/tst_emission.cpp
new file mode 100644
index 0000000000..66ce547dd2
--- /dev/null
+++ b/tests/benchmarks/particles/emission/tst_emission.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qtest.h>
+#include <QtTest/QtTest>
+#include "../../../auto/particles/shared/particlestestsshared.h"
+#include <private/qsgparticlesystem_p.h>
+
+class tst_emission : public QObject
+{
+ Q_OBJECT
+public:
+ tst_emission();
+
+private slots:
+ void test_basic();
+ void test_basic_data();
+};
+
+tst_emission::tst_emission()
+{
+}
+
+void tst_emission::test_basic_data()
+{
+ QTest::addColumn<int> ("dt");
+ QTest::newRow("16ms") << 16;
+ QTest::newRow("32ms") << 32;
+ QTest::newRow("100ms") << 100;
+ QTest::newRow("500ms") << 500;
+ QTest::newRow("1000ms") << 1000;
+ QTest::newRow("10000ms") << 10000;
+}
+
+void tst_emission::test_basic()
+{
+ QFETCH(int, dt);
+ QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml");
+ QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
+ //Pretend we're running, but we manually advance the simulation
+ system->m_running = true;
+ system->m_animation = 0;
+ system->reset();
+
+ int curTime = 1;
+ system->updateCurrentTime(curTime);//Fixed point and get init out of the way.
+
+ while (curTime < 500){//Minimum time needed to get enough alive
+ QBENCHMARK {
+ curTime += dt;
+ system->updateCurrentTime(curTime);
+ }
+ }
+
+ int stillAlive = 0;
+ QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 1000, 10));//Small simulation variance is permissible.
+ foreach (QSGParticleData *d, system->groupData[0]->data) {
+ if (d->t == -1)
+ continue; //Particle data unused
+
+ if (d->stillAlive())
+ stillAlive++;
+ QCOMPARE(d->x, 0.f);
+ QCOMPARE(d->y, 0.f);
+ QCOMPARE(d->vx, 0.f);
+ QCOMPARE(d->vy, 0.f);
+ QCOMPARE(d->ax, 0.f);
+ QCOMPARE(d->ay, 0.f);
+ QCOMPARE(d->lifeSpan, 0.5f);
+ QCOMPARE(d->size, 32.f);
+ QCOMPARE(d->endSize, 32.f);
+ QVERIFY(myFuzzyLEQ(d->t, ((qreal)system->timeInt/1000.0)));
+ }
+ QVERIFY(extremelyFuzzyCompare(stillAlive, 1000, 10));//Small simulation variance is permissible.
+ delete view;
+}
+
+QTEST_MAIN(tst_emission);
+
+#include "tst_emission.moc"
diff --git a/tests/benchmarks/particles/particles.pro b/tests/benchmarks/particles/particles.pro
new file mode 100644
index 0000000000..535bedd1f9
--- /dev/null
+++ b/tests/benchmarks/particles/particles.pro
@@ -0,0 +1,5 @@
+TEMPLATE = subdirs
+
+SUBDIRS += \
+ emission \
+ affectors
diff --git a/tests/shared/util.h b/tests/shared/util.h
deleted file mode 100644
index ac78f2dfec..0000000000
--- a/tests/shared/util.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-// Functions and macros that really need to be in QTestLib
-
-// Will try to wait for the condition while allowing event processing
-#define QTRY_VERIFY(__expr) \
- do { \
- const int __step = 50; \
- const int __timeout = 5000; \
- if (!(__expr)) { \
- QTest::qWait(0); \
- } \
- for (int __i = 0; __i < __timeout && !(__expr); __i+=__step) { \
- QTest::qWait(__step); \
- } \
- QVERIFY(__expr); \
- } while(0)
-
-// Will try to wait for the condition while allowing event processing
-#define QTRY_COMPARE(__expr, __expected) \
- do { \
- const int __step = 50; \
- const int __timeout = 5000; \
- if ((__expr) != (__expected)) { \
- QTest::qWait(0); \
- } \
- for (int __i = 0; __i < __timeout && ((__expr) != (__expected)); __i+=__step) { \
- QTest::qWait(__step); \
- } \
- QCOMPARE(__expr, __expected); \
- } while(0)
-
diff --git a/tests/system/sys_elements.qtt b/tests/system/sys_elements.qtt
index 1f1fbb7ab2..296dd83cb8 100644
--- a/tests/system/sys_elements.qtt
+++ b/tests/system/sys_elements.qtt
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -40,373 +40,82 @@
****************************************************************************/
//TESTED_COMPONENT=qtdeclarative
-var adv = "Press the Advance button";
-testcase = {
-
- rectangle: function()
- {
- // Test Meta-data
- testApplication = "Elements: Rectangle";
- testBinary = "tests/testapplications/elements/elements";
- testGoal = "Verify the rectangle element is shown correctly";
- testPreconditions = "";
- testGroups = "BAT";
-
- // Test Steps
- prompt(twiki('---+++ ' + testApplication + '<br><br>
- *Goal:* ' + testGoal + '<br>
- *Pre-Requisites:* ' + testPreconditions + '<br>
- *Tested Binary:* ' + testBinary + '<br>
- | Select the Rectangle list item | Verify that the Rectangle displayed in the center is small, blue, with a thin red angular border |
- | '+adv+' | The rectangle should now be twice the size as the previous step |
- | '+adv+' | The rectangle should now have rounded corners |
- | '+adv+' | The rectangle color should have shifted to green |
- | '+adv+' | The rectangle border should have increased significantly |
- | '+adv+' | The rectangle border should have now be small, blue, with a thin red angular border |'));
- },
-
- image: function()
- {
- // Test Meta-data
- testApplication = "Elements: Image";
- testBinary = "tests/testapplications/elements/elements";
- testGoal = "Verify the Image element is shown correctly";
- testPreconditions = "";
- testGroups = "BAT";
-
- // Test Steps
- prompt(twiki('---+++ ' + testApplication + '<br><br>
- *Goal:* ' + testGoal + '<br>
- *Pre-Requisites:* ' + testPreconditions + '<br>
- *Tested Binary:* ' + testBinary + '<br>
- | Select the Image list item | Verify it shows the Nokia logo, large and still slightly stretched |
- | '+adv+' | Verify it shows the Nokia logo normally, longer horizontally |
- | '+adv+' | Verify it shows the Nokia logo with the sides cut |
- | '+adv+' | Verify it shows the Nokia logo repeated both horizontally and vertically |
- | '+adv+' | Verify it shows the Nokia logo repeated vertically only |
- | '+adv+' | Verify it shows the Nokia logo repeated horizontally only |'));
- },
-
- animatedimage: function()
- {
- // Test Meta-data
- testApplication = "Elements: AnimatedImage";
- testBinary = "tests/testapplications/elements/elements";
- testGoal = "Verify the AnimatedImage element is shown correctly";
- testPreconditions = "";
- testGroups = "BAT";
-
- // Test Steps
- prompt(twiki('---+++ ' + testApplication + '<br><br>
- *Goal:* ' + testGoal + '<br>
- *Pre-Requisites:* ' + testPreconditions + '<br>
- *Tested Binary:* ' + testBinary + '<br>
- | Select the AnimatedImage list item | Verify it shows a small animated icon, but slightly stretched. |
- | '+adv+' | Verify it shows the animated icon, large and still slightly stretched |
- | '+adv+' | Verify it shows the animated icon normally, square |
- | '+adv+' | Verify it shows the animated icon with the sides cut |
- | '+adv+' | Verify it shows the animated icon repeated both horizontally and vertically |
- | '+adv+' | Verify it shows the animated icon repeated vertically only |
- | '+adv+' | Verify it shows the animated icon repeated horizontally only |'));
- },
-
- borderimage: function()
- {
- // Test Meta-data
- testApplication = "Elements: BorderImage";
- testBinary = "tests/testapplications/elements/elements";
- testGoal = "Verify the BorderImage element is shown correctly";
- testPreconditions = "";
- testGroups = "BAT";
- // Test Steps
- prompt(twiki('---+++ ' + testApplication + '<br><br>
- *Goal:* ' + testGoal + '<br>
- *Pre-Requisites:* ' + testPreconditions + '<br>
- *Tested Binary:* ' + testBinary + '<br>
- | Select the BorderImage list item | Verify it shows a small framed image |
- | '+adv+' | Verify it shows the frame, large and each side stretched |
- | '+adv+' | Verify it shows the frame with slightly off centere sides |
- | '+adv+' | Verify it shows the frame with uniformly repeated sides |'));
- },
-
- systempalette: function()
- {
- // Test Meta-data
- testApplication = "Elements: SystemPalette";
- testBinary = "tests/testapplications/elements/elements";
- testGoal = "Verify the SystemPalette element is shown correctly";
- testPreconditions = "";
- testGroups = "BAT";
-
- // Test Steps
- prompt(twiki('---+++ ' + testApplication + '<br><br>
- *Goal:* ' + testGoal + '<br>
- *Pre-Requisites:* ' + testPreconditions + '<br>
- *Tested Binary:* ' + testBinary + '<br>
- | Select the SystemPalette list item | Verify it shows a mockup of an application |
- | '+adv+' | Verify it shows the colors similar to the system it is running on |
- | '+adv+' | Verify it shows the new coloring |'));
- },
-
- text: function()
- {
- // Test Meta-data
- testApplication = "Elements: Text";
- testBinary = "tests/testapplications/elements/elements";
- testGoal = "Verify the Text element is shown correctly";
- testPreconditions = "";
- testGroups = "BAT";
-
- // Test Steps
- prompt(twiki('---+++ ' + testApplication + '<br><br>
- *Goal:* ' + testGoal + '<br>
- *Pre-Requisites:* ' + testPreconditions + '<br>
- *Tested Binary:* ' + testBinary + '<br>
- | Select the Text list item | Verify it shows a Hello message |
- | '+adv+' | Verify it shows the text increased to twice the previous size, and wrapped to two lines |
- | '+adv+' | Verify it shows the text smoothly changed color to blue over a second |
- | '+adv+' | Verify it shows the text as blue, bolded and in italic |
- | '+adv+' | Verify it shows the text as alternating between green and black |'));
- },
-
- textinput: function()
- {
- // Test Meta-data
- testApplication = "Elements: TextInput";
- testBinary = "tests/testapplications/elements/elements";
- testGoal = "Verify the TextInput element is shown correctly";
- testPreconditions = "";
- testGroups = "BAT";
-
- // Test Steps
- prompt(twiki('---+++ ' + testApplication + '<br><br>
- *Goal:* ' + testGoal + '<br>
- *Pre-Requisites:* ' + testPreconditions + '<br>
- *Tested Binary:* ' + testBinary + '<br>
- | Select the TextInput list item | Verify it shows two fields, the green one displaying a Hello message |
- | '+adv+' | Verify it selects the last word - TextInput - of the green field |
- | '+adv+' | Verify it animates a copy of the selected text to the gray field |
- | '+adv+' | Verify it shows the text as asterisks |'));
- },
-
- textedit: function()
- {
- // Test Meta-data
- testApplication = "Elements: TextEdit";
- testBinary = "tests/testapplications/elements/elements";
- testGoal = "Verify the TextEdit element is shown correctly";
- testPreconditions = "";
- testGroups = "BAT";
-
- // Test Steps
- prompt(twiki('---+++ ' + testApplication + '<br><br>
- *Goal:* ' + testGoal + '<br>
- *Pre-Requisites:* ' + testPreconditions + '<br>
- *Tested Binary:* ' + testBinary + '<br>
- | Select the TextEdit list item | Verify it shows two large fields |
- | '+adv+' | Verify it selects the last word - TextEdit - of the green field |
- | '+adv+' | Verify it animates a copy of the selected text to the gray field |
- | '+adv+' | Verify it shows more text, with the end disappearing past the right side of the green field |
- | '+adv+' | Verify it shows the full text, properly wrapped within the green field |'));
- },
-
- fontloader: function()
- {
- // Test Meta-data
- testApplication = "Elements: FontLoader";
- testBinary = "tests/testapplications/elements/elements";
- testGoal = "Verify the FontLoader element is shown correctly";
- testPreconditions = "";
- testGroups = "BAT";
-
- // Test Steps
- prompt(twiki('---+++ ' + testApplication + '<br><br>
- *Goal:* ' + testGoal + '<br>
- *Pre-Requisites:* ' + testPreconditions + '<br>
- *Tested Binary:* ' + testBinary + '<br>
- | Select the FontLoader list item | Verify it shows a box with a named font in the center |
- | '+adv+' | Verify the font has changed along with the named font text |
- | '+adv+' | Verify the font is changing every half second, for at least a few different fonts, without error |
- | '+adv+' | Verify the font has changed to a Neon Lights font |
- | '+adv+' | Verify the font has reverted to a named system font |'));
- },
-
- flipable: function() {
- // Test Meta-data
- testApplication = "Elements: Flipable";
- testBinary = "tests/testapplications/elements/elements";
- testGoal = "Verify the Flipable element is shown correctly";
- testPreconditions = "";
- testGroups = "BAT";
-
- // Test Steps
- prompt(twiki('---+++ ' + testApplication + '<br><br>
- *Goal:* ' + testGoal + '<br>
- *Pre-Requisites:* ' + testPreconditions + '<br>
- *Tested Binary:* ' + testBinary + '<br>
- | Select the Flipable list item | Verify it shows a large green rectangle |
- | '+adv+' | Verify it slowly spins horizontally to show a red rectangle on the back |
- | '+adv+' | Verify it again slowly spins horizontally to show a green rectangle on the front |
- | '+adv+' | Verify it again slowly spins vertically to show a red rectangle on the back |
- | '+adv+' | Verify it again slowly spins horizontally to show a green rectangle on the front |'));
- },
-
- intvalidator: function()
- {
- // Test Meta-data
- testApplication = "Elements: IntValidator";
- testBinary = "tests/testapplications/elements/elements";
- testGoal = "Verify the IntValidator element is shown correctly";
- testPreconditions = "";
- testGroups = "BAT";
-
- // Test Steps
- prompt(twiki('---+++ ' + testApplication + '<br><br>
- *Goal:* ' + testGoal + '<br>
- *Pre-Requisites:* ' + testPreconditions + '<br>
- *Tested Binary:* ' + testBinary + '<br>
- | Select the IntValidator list item | Verify it shows a green field with the number 0. The upper and lower bounds are 30 and -50 |
- | '+adv+' | Verify the number is now -80, and the field is now red |
- | '+adv+' | Verify the number is now -50, and the field is now green |
- | '+adv+' | Verify the number is now 35, and the field is now red |
- | '+adv+' | Verify the top value has changed to 35, and the field is now green |
- | '+adv+' | Verify the bottom has changed to 36, and the field is now red |'));
- },
-
- doublevalidator: function()
- {
- // Test Meta-data
- testApplication = "Elements: DoubleValidator";
- testBinary = "tests/testapplications/elements/elements";
- testGoal = "Verify the DoubleValidator element is shown correctly";
- testPreconditions = "";
- testGroups = "BAT";
-
- // Test Steps
- prompt(twiki('---+++ ' + testApplication + '<br><br>
- *Goal:* ' + testGoal + '<br>
- *Pre-Requisites:* ' + testPreconditions + '<br>
- *Tested Binary:* ' + testBinary + '<br>
- | Select the DoubleValidator list item | Verify it shows a green field with the number 0. The upper and lower bounds are 30.06 and 30.02 |
- | '+adv+' | Verify the number is now 30.01, and the field is now red |
- | '+adv+' | Verify the number is now 30.02, and the field is now green |
- | '+adv+' | Verify the number is now 30.08, and the field is now red |
- | '+adv+' | Verify the top value has changed to 30.09, and the field is now green |
- | '+adv+' | Verify the bottom has changed to 40.05, and the field is now red |'));
- },
-
- regexpvalidator: function()
- {
- // Test Meta-data
- testApplication = "Elements: RegExpValidator";
- testBinary = "tests/testapplications/elements/elements";
- testGoal = "Verify the RegExpValidator element is shown correctly";
- testPreconditions = "";
- testGroups = "BAT";
-
- // Test Steps
- prompt(twiki('---+++ ' + testApplication + '<br><br>
- *Goal:* ' + testGoal + '<br>
- *Pre-Requisites:* ' + testPreconditions + '<br>
- *Tested Binary:* ' + testBinary + '<br>
- | Select the RegExpValidator list item | Verify it shows a green field with the text abc |
- | '+adv+' | Verify the text is now 123, and the field is now red |
- | '+adv+' | Verify the number is now aa, and the field is still red |
- | '+adv+' | Verify the number is now abcd, and the field is still red |
- | '+adv+' | Verify the regex value has changed to allow four characters, and the field is now green |'));
- },
-
- column: function()
- {
- // Test Meta-data
- testApplication = "Elements: Column";
- testBinary = "tests/testapplications/elements/elements";
- testGoal = "Verify the Column element is shown correctly";
- testPreconditions = "";
- testGroups = "BAT";
-
- // Test Steps
- prompt(twiki('---+++ ' + testApplication + '<br><br>
- *Goal:* ' + testGoal + '<br>
- *Pre-Requisites:* ' + testPreconditions + '<br>
- *Tested Binary:* ' + testBinary + '<br>
- | Select the Column list item | Verify it shows three rectangles - green, red and black |
- | '+adv+' | Verify the blue rectangle slid in to place between the red and black rectangles |'));
- },
-
- row: function()
- {
- // Test Meta-data
- testApplication = "Elements: Row";
- testBinary = "tests/testapplications/elements/elements";
- testGoal = "Verify the Row element is shown correctly";
- testPreconditions = "";
- testGroups = "BAT";
+testcase = {
- // Test Steps
- prompt(twiki('---+++ ' + testApplication + '<br><br>
- *Goal:* ' + testGoal + '<br>
- *Pre-Requisites:* ' + testPreconditions + '<br>
- *Tested Binary:* ' + testBinary + '<br>
- | Select the Row list item | Verify it shows three rectangles - green, red and black |
- | '+adv+' | Verify the blue rectangle slid in to place between the red and black rectangles |'));
+ pre_existing_elements_data: {
+ // ElementName: [preconditions,[groups]]
+ Rectangle: ["",["QtQuick1.0","BAT"]],
+ Image: ["",["QtQuick1.0","BAT"]],
+ AnimatedImage: ["",["QtQuick1.0","BAT"]],
+ BorderImage: ["",["QtQuick1.0","BAT"]],
+ SystemPalette: ["",["QtQuick1.0","BAT"]],
+ Text: ["",["QtQuick1.0","BAT"]],
+ TextInput: ["",["QtQuick1.0","BAT"]],
+ TextEdit: ["",["QtQuick1.0","BAT"]],
+ FontLoader: ["",["QtQuick1.0","BAT"]],
+ Flipable: ["",["QtQuick1.0","BAT"]],
+ Flickable: ["",["QtQuick1.0","BAT"]],
+ IntValidator: ["",["QtQuick1.0","BAT"]],
+ DoubleValidator: ["",["QtQuick1.0","BAT"]],
+ RegExpValidator: ["",["QtQuick1.0","BAT"]],
+ Column: ["",["QtQuick1.0","BAT"]],
+ Row: ["",["QtQuick1.0","BAT"]],
+ Flow: ["",["QtQuick1.0","BAT"]],
+ Grid: ["",["QtQuick1.0","BAT"]],
+ Repeater: ["",["QtQuick1.0","BAT"]],
+ ListView: ["",["QtQuick1.0","BAT"]],
+ Keys: ["",["QtQuick1.0","BAT"]],
+ MouseArea: ["",["QtQuick1.0","BAT"]],
+ SequentialAnimation: ["",["QtQuick1.0","BAT"]],
+ ParallelAnimation: ["",["QtQuick1.0","BAT"]],
+ XmlListModel: ["",["QtQuick1.0","BAT"]],
+ Scale: ["",["QtQuick1.0","BAT"]]
},
- flow: function()
- {
+ pre_existing_elements: function(prec,groups) {
// Test Meta-data
- testApplication = "Elements: Flow";
- testBinary = "tests/testapplications/elements/elements";
- testGoal = "Verify the Flow element is shown correctly";
- testPreconditions = "";
- testGroups = "BAT";
+ testTitle = currentDataTag()+ " Element";
+ testBinary = "qmlscene tests/testapplications/elements/elements.qml";
+ testGoal = "Verify the "+currentDataTag()+" element is shown correctly";
+ testPreconditions = prec;
+ testGroups = groups;
// Test Steps
- prompt(twiki('---+++ ' + testApplication + '<br><br>
+ prompt(twiki('---+++ ' + testTitle + '<br><br>
*Goal:* ' + testGoal + '<br>
*Pre-Requisites:* ' + testPreconditions + '<br>
*Tested Binary:* ' + testBinary + '<br>
- | Select the Flow list item | Verify it shows three rectangles - green (1), red (2, to the right of 1) and black (4, below 1) |
- | '+adv+' | Verify the blue rectangle appears where the black was, the black sliding to the right |
- | '+adv+' | Verify the direction of the numbers is now in two columns |
- | '+adv+' | Verify the direction of the numbers has now reversed, still in columns, but progressing from the right to left |'));
+ | Select the '+currentDataTag()+' list item | Verify that the '+currentDataTag()+' application is displayed |
+ | Follow the instructions in the in-app test | Verify all steps are completed successfully |'));
},
- grid: function()
- {
- // Test Meta-data
- testApplication = "Elements: Grid";
- testBinary = "tests/testapplications/elements/elements";
- testGoal = "Verify the Grid element is shown correctly";
- testPreconditions = "";
- testGroups = "BAT";
-
- // Test Steps
- prompt(twiki('---+++ ' + testApplication + '<br><br>
- *Goal:* ' + testGoal + '<br>
- *Pre-Requisites:* ' + testPreconditions + '<br>
- *Tested Binary:* ' + testBinary + '<br>
- | Select the Grid list item | Verify it shows four rectangles - green, a red to the right and a black below |
- | '+adv+' | Verify the blue rectangle slid in to place previously held by the black rectangle |'));
+ new_elements_data: {
+ // ElementName: [preconditions,[groups]]
+ ParticleSystem: ["",["QtQuick2.0","BAT"]],
+ ImageParticle: ["",["QtQuick2.0","BAT"]],
+ Emitter: ["",["QtQuick2.0","BAT"]],
+ Affector: ["",["QtQuick2.0","BAT"]],
+ Shape: ["",["QtQuick2.0","BAT"]],
+ TrailEmitter: ["",["QtQuick2.0","BAT"]],
+ Direction: ["",["QtQuick2.0","BAT"]]
},
- repeater: function()
- {
+ new_elements: function(prec,groups) {
// Test Meta-data
- testApplication = "Elements: Repeater";
- testBinary = "tests/testapplications/elements/elements";
- testGoal = "Verify the Repeater element is shown correctly";
- testPreconditions = "";
- testGroups = "BAT";
+ testTitle = currentDataTag()+ " Element";
+ testBinary = "qmlscene tests/testapplications/elements/elements.qml";
+ testGoal = "Verify the "+currentDataTag()+" element is shown correctly";
+ testPreconditions = prec;
+ testGroups = groups;
// Test Steps
- prompt(twiki('---+++ ' + testApplication + '<br><br>
+ prompt(twiki('---+++ ' + testTitle + '<br><br>
*Goal:* ' + testGoal + '<br>
*Pre-Requisites:* ' + testPreconditions + '<br>
*Tested Binary:* ' + testBinary + '<br>
- | Select the Repeater list item | Verify it shows five blue rectangles with text and a green rectangle at the bottom |
- | '+adv+' | Verify the third blue rectangle is now gone and the others bounced up to fill the gap |'));
+ | Select the '+currentDataTag()+' list item | Verify that the '+currentDataTag()+' application is displayed |
+ | Follow the instructions in the in-app test | Verify all steps are completed successfully |'));
}
}
diff --git a/tests/testapplications/elements/content/AffectorElement.qml b/tests/testapplications/elements/content/AffectorElement.qml
new file mode 100644
index 0000000000..9edd399a84
--- /dev/null
+++ b/tests/testapplications/elements/content/AffectorElement.qml
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Item {
+ id: affectorelementtest
+ anchors.fill: parent
+ property string testtext: ""
+
+ ParticleSystem {
+ id: particlesystem
+ anchors.fill: parent
+
+ ImageParticle {
+ id: imageparticle
+ source: "pics/star.png"
+ color: "blue"
+ entryEffect: ImageParticle.None
+ anchors.fill: parent
+ }
+
+ // Pipe
+ Rectangle {
+ id: pipe
+ x: 0; y: 300
+ border.color: "black"
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: "lightgray" }
+ GradientStop { position: 1.0; color: "gray" }
+ }
+ height: 40; width: 40
+ }
+ Rectangle {
+ id: pipehead
+ anchors.left: pipe.right
+ anchors.verticalCenter: pipe.verticalCenter
+ border.color: "black"
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: "lightgray" }
+ GradientStop { position: 1.0; color: "gray" }
+ }
+ height: 50; width: 10
+ }
+
+ Emitter {
+ id: emitterelement
+ anchors.left: pipe.left
+ anchors.leftMargin: 10
+ anchors.bottom: pipe.bottom
+ anchors.bottomMargin: 8
+ height: 5
+ emitRate: 100
+ lifeSpan: 10000
+ speed: AngleDirection { angle: 0; magnitude: 30 }
+ }
+
+ // Affectors
+ Gravity {
+ id: gravity
+ x: pipe.width; y: pipe.y-100
+ enabled: false
+ height: 200
+ width: parent.width - pipe.width
+ angle: 90
+ acceleration: 30
+ }
+ Wander {
+ id: wander
+ enabled: false
+ anchors.verticalCenter: pipe.verticalCenter
+ anchors.left: pipe.right
+ height: pipe.height
+ width: 5
+ xVariance: 50
+ yVariance: 100
+ pace: 200
+ }
+ Turbulence {
+ id: turbulence
+ enabled: false
+ strength: 40
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 100
+ width: parent.width; height: 100
+ }
+ Friction {
+ id: friction
+ anchors.bottom: parent.bottom; width: parent.width; height: 100
+ enabled: false
+ factor: 2
+ }
+ Age {
+ id: age
+ anchors.bottom: parent.bottom; width: 360; height: 5
+ }
+
+ }
+
+ SystemTestHelp { id: helpbubble; visible: statenum != 0
+ anchors { top: parent.top; horizontalCenter: parent.horizontalCenter; topMargin: 50 }
+ }
+ BugPanel { id: bugpanel }
+
+ states: [
+ State { name: "start"; when: statenum == 1
+ PropertyChanges { target: affectorelementtest
+ testtext: "This is a group of currently disabled Affector elements. "+
+ "A blue stream of particles should be flowing from a block to the left.\n"+
+ "Next, let's add some variance in direction when the particles leave the block." }
+ },
+ State { name: "spread"; when: statenum == 2
+ PropertyChanges { target: wander; enabled: true }
+ PropertyChanges { target: affectorelementtest
+ testtext: "The particles should be spreading out as they progress.\n"+
+ "Next, let's introduce gravity." }
+ },
+ State { name: "gravity"; when: statenum == 3
+ PropertyChanges { target: wander; enabled: true }
+ PropertyChanges { target: gravity; enabled: true }
+ PropertyChanges { target: affectorelementtest
+ testtext: "The particles should now be dropping.\n"+
+ "Also, no particles should be visible below the bounds of the application, "+
+ "i.e. the white panel.\n"+
+ "Next, let's introduce some friction at the bottom of the display." }
+ },
+ State { name: "friction"; when: statenum == 4
+ PropertyChanges { target: wander; enabled: true }
+ PropertyChanges { target: gravity; enabled: true }
+ PropertyChanges { target: friction; enabled: true }
+ PropertyChanges { target: affectorelementtest
+ testtext: "The particles should now be decelerating suddenly at the bottom.\n"+
+ "Next, let's add some turbulence to the flow." }
+ },
+ State { name: "turbulence"; when: statenum == 5
+ PropertyChanges { target: wander; enabled: true }
+ PropertyChanges { target: gravity; enabled: true }
+ PropertyChanges { target: friction; enabled: true }
+ PropertyChanges { target: turbulence; enabled: true }
+ PropertyChanges { target: affectorelementtest
+ testtext: "The particles should now be turbulent.\n"+
+ "Advance to restart the test." }
+ }
+ ]
+} \ No newline at end of file
diff --git a/tests/testapplications/elements/content/AnimatedImageElement.qml b/tests/testapplications/elements/content/AnimatedImageElement.qml
index be772640b2..f1a78da3be 100644
--- a/tests/testapplications/elements/content/AnimatedImageElement.qml
+++ b/tests/testapplications/elements/content/AnimatedImageElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -108,4 +108,4 @@ Item {
"The next step will return the image to a small, stretched state" }
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/AppContainer.qml b/tests/testapplications/elements/content/AppContainer.qml
index e1d52609e7..f3cb0d069e 100644
--- a/tests/testapplications/elements/content/AppContainer.qml
+++ b/tests/testapplications/elements/content/AppContainer.qml
@@ -4,32 +4,32 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
+** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
@@ -68,4 +68,4 @@ Rectangle {
Text { anchors.centerIn: parent; visible: qmlapp.status == Loader.Error; text: qmlfile+" failed to load.\n"; }
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/BorderImageElement.qml b/tests/testapplications/elements/content/BorderImageElement.qml
index 89794c27e7..53f941f47a 100644
--- a/tests/testapplications/elements/content/BorderImageElement.qml
+++ b/tests/testapplications/elements/content/BorderImageElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -94,4 +94,4 @@ Item {
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/BugPanel.qml b/tests/testapplications/elements/content/BugPanel.qml
index 7e60a3f684..7b6d811999 100644
--- a/tests/testapplications/elements/content/BugPanel.qml
+++ b/tests/testapplications/elements/content/BugPanel.qml
@@ -4,32 +4,32 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
+** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
@@ -54,4 +54,4 @@ Rectangle {
Text { id: buglist; text: urltext; textFormat: Text.RichText; visible: bugnumber != ""
anchors.centerIn: parent; onLinkActivated: { Qt.openUrlExternally(link); }
}
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/ColumnElement.qml b/tests/testapplications/elements/content/ColumnElement.qml
index daaf391172..0ad860ee29 100644
--- a/tests/testapplications/elements/content/ColumnElement.qml
+++ b/tests/testapplications/elements/content/ColumnElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -82,4 +82,4 @@ Item {
"Advance to restart the test." }
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/DirectionElement.qml b/tests/testapplications/elements/content/DirectionElement.qml
new file mode 100644
index 0000000000..2e2003c113
--- /dev/null
+++ b/tests/testapplications/elements/content/DirectionElement.qml
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Item {
+ id: directionelementtest
+ anchors.fill: parent
+ property string testtext: ""
+
+ ParticleSystem {
+ id: particlesystem
+ anchors.fill: parent
+ Item {
+ id: targetbox
+ x: 50
+ y: 300
+ Rectangle {
+ id: targeticon
+ color: "brown"
+ height: 0; width: 0; radius: 20
+ anchors.centerIn: parent
+ Behavior on height { NumberAnimation { duration: 500; easing.type: Easing.OutBounce } }
+ Behavior on width { NumberAnimation { duration: 500; easing.type: Easing.OutBounce } }
+ }
+ }
+ ImageParticle {
+ id: imgparticle
+ source: "pics/star.png"
+ color: "red"
+ entryEffect: ImageParticle.None
+ }
+ Emitter {
+ id: emitter
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 5
+ anchors.horizontalCenter: parent.horizontalCenter
+ emitRate: 50
+ lifeSpan: 4000
+ size: 20
+ speed: angledirectionelement
+ AngleDirection { id: angledirectionelement; angle: -75; angleVariation: 5; magnitude: 150 }
+ TargetDirection { id: targetdirectionelement; targetItem: targetbox; targetVariation: 10; magnitude: 150 }
+ PointDirection { id: pointdirectionelement; y: -100; xVariation: 10; yVariation: 10; }
+ PointDirection { id: pointdirectionelementdownward; y: 200 }
+ CumulativeDirection {
+ id: cumulativedirectionelement
+ PointDirection { y: -200 }
+ AngleDirection { angle: 270; angleVariation: 45; magnitude: 100; magnitudeVariation: 10; }
+ }
+ }
+ }
+
+ SystemTestHelp { id: helpbubble; visible: statenum != 0
+ anchors { top: parent.top; horizontalCenter: parent.horizontalCenter; topMargin: 50 }
+ }
+ BugPanel { id: bugpanel }
+
+ states: [
+ State { name: "start"; when: statenum == 1
+ PropertyChanges { target: directionelementtest
+ testtext: "This is an Emitter with the direction set by an AngleDirection.\n"+
+ "The particles should be firing at a -75 degree (to the top right) .\n"+
+ "Next, let's change the Emitter to target an item." }
+ },
+ State { name: "ontarget"; when: statenum == 2
+ PropertyChanges { target: emitter; speed: targetdirectionelement }
+ PropertyChanges { target: targeticon; height: 50; width: 50 }
+ PropertyChanges { target: directionelementtest
+ testtext: "The particles should be directed at the rectangle.\n"+
+ "Next, let's set an arbritary point to direct the particles to." }
+ },
+ State { name: "onpoint"; when: statenum == 3
+ PropertyChanges { target: emitter; speed: pointdirectionelement }
+ PropertyChanges { target: directionelementtest
+ testtext: "The particles should be directed upwards with a small amount of spread.\n"+
+ "Next, let's create a fountain with CumulativeDirection and a downward PointDirection" }
+ },
+ State { name: "cumulative"; when: statenum == 4
+ PropertyChanges { target: emitter; emitRate: 200; speed: cumulativedirectionelement
+ acceleration: pointdirectionelementdownward }
+ PropertyChanges { target: imgparticle; color: "aqua"; colorVariation: .2 }
+ PropertyChanges { target: directionelementtest
+ testtext: "The particles should be flowing upwards and falling in a fountain effect.\n"+
+ "Advance to restart the test." }
+ }
+ ]
+} \ No newline at end of file
diff --git a/tests/testapplications/elements/content/DoubleValidatorElement.qml b/tests/testapplications/elements/content/DoubleValidatorElement.qml
index df725b357a..e9cf50e88f 100644
--- a/tests/testapplications/elements/content/DoubleValidatorElement.qml
+++ b/tests/testapplications/elements/content/DoubleValidatorElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -121,4 +121,4 @@ Item {
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/EmitterElement.qml b/tests/testapplications/elements/content/EmitterElement.qml
new file mode 100644
index 0000000000..5842ffbdad
--- /dev/null
+++ b/tests/testapplications/elements/content/EmitterElement.qml
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Item {
+ id: emitterelementtest
+ anchors.fill: parent
+ property string testtext: ""
+
+ ParticleSystem {
+ id: particlesystem
+ anchors.fill: parent
+ ImageParticle {
+ id: imageparticle
+ source: "pics/smile.png"
+ color: "red"
+ Behavior on color { ColorAnimation { duration: 3000 } }
+ }
+ Emitter {
+ id: emitterelement
+ anchors.centerIn: parent
+ property int emitspeed: 10
+ emitRate: 5
+ lifeSpan: 1000
+ speed: AngleDirection { angle: 0; angleVariation: 360; magnitude: emitterelement.emitspeed }
+ }
+ }
+
+
+ SystemTestHelp { id: helpbubble; visible: statenum != 0
+ anchors { top: parent.top; horizontalCenter: parent.horizontalCenter; topMargin: 50 }
+ }
+ BugPanel { id: bugpanel }
+
+ states: [
+ State { name: "start"; when: statenum == 1
+ PropertyChanges { target: emitterelementtest
+ testtext: "This is an Emitter element, visualized by an ImageParticle. It should be emitting particles "+
+ "slowly from the center of the display.\n"+
+ "Next, let's change the emission speed of the particles." }
+ },
+ State { name: "fast"; when: statenum == 2
+ PropertyChanges { target: emitterelement; emitspeed: 50 }
+ PropertyChanges { target: emitterelementtest
+ testtext: "The particles emitted should be moving more quickly.\n"+
+ "Next, let's increase the number of particles emitted." }
+ },
+ State { name: "many"; when: statenum == 3
+ PropertyChanges { target: emitterelement; emitspeed: 50; emitRate: 100 }
+ PropertyChanges { target: emitterelementtest
+ testtext: "The particles should now be quick and numerous.\n"+
+ "Next, let's allow them to survive longer." }
+ },
+ State { name: "enduring"; when: statenum == 4
+ PropertyChanges { target: emitterelement; emitspeed: 50; emitRate: 100; lifeSpan: 3000 }
+ PropertyChanges { target: emitterelementtest
+ testtext: "The particles should now be enduring to the edges of the display.\n"+
+ "Next, let's have them changing their size." }
+ },
+ State { name: "sized"; when: statenum == 5
+ PropertyChanges { target: emitterelement; emitspeed: 50; emitRate: 100; lifeSpan: 3000; size: 20; endSize: 5 }
+ PropertyChanges { target: emitterelementtest
+ testtext: "The particles should now be starting large and ending small.\n"+
+ "Advance to restart the test." }
+ }
+ ]
+} \ No newline at end of file
diff --git a/tests/testapplications/elements/content/FlickableElement.qml b/tests/testapplications/elements/content/FlickableElement.qml
index 67a4d8102e..345d5eb16d 100644
--- a/tests/testapplications/elements/content/FlickableElement.qml
+++ b/tests/testapplications/elements/content/FlickableElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/tests/testapplications/elements/content/FlipableElement.qml b/tests/testapplications/elements/content/FlipableElement.qml
index 8c0e80828d..23ab330042 100644
--- a/tests/testapplications/elements/content/FlipableElement.qml
+++ b/tests/testapplications/elements/content/FlipableElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -102,4 +102,4 @@ Item {
"Next, let's restart the test." }
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/FlowElement.qml b/tests/testapplications/elements/content/FlowElement.qml
index eccca1c2ee..b68fe2288a 100644
--- a/tests/testapplications/elements/content/FlowElement.qml
+++ b/tests/testapplications/elements/content/FlowElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -102,4 +102,4 @@ Item {
"Advance to restart the test." }
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/FocusScopeElement.qml b/tests/testapplications/elements/content/FocusScopeElement.qml
index 3f299e8dd2..7c38ec3364 100644
--- a/tests/testapplications/elements/content/FocusScopeElement.qml
+++ b/tests/testapplications/elements/content/FocusScopeElement.qml
@@ -4,32 +4,32 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
+** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
@@ -68,4 +68,4 @@ Item {
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/FontLoaderElement.qml b/tests/testapplications/elements/content/FontLoaderElement.qml
index 7488ecad90..808e3798c4 100644
--- a/tests/testapplications/elements/content/FontLoaderElement.qml
+++ b/tests/testapplications/elements/content/FontLoaderElement.qml
@@ -4,32 +4,32 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
+** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
diff --git a/tests/testapplications/elements/content/GradientElement.qml b/tests/testapplications/elements/content/GradientElement.qml
index b437ea2f8e..5459769f6c 100644
--- a/tests/testapplications/elements/content/GradientElement.qml
+++ b/tests/testapplications/elements/content/GradientElement.qml
@@ -4,32 +4,32 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
+** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
@@ -59,4 +59,4 @@ Rectangle {
NumberAnimation { target: gradientelement; property: "gradstop"; to: 0.88; duration: 10000; easing.type: Easing.InOutQuad }
NumberAnimation { target: gradientelement; property: "gradstop"; to: 0.22; duration: 10000; easing.type: Easing.InOutQuad }
}
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/GridElement.qml b/tests/testapplications/elements/content/GridElement.qml
index 544afc3f63..b917227345 100644
--- a/tests/testapplications/elements/content/GridElement.qml
+++ b/tests/testapplications/elements/content/GridElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -92,4 +92,4 @@ Item {
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/GridViewElement.qml b/tests/testapplications/elements/content/GridViewElement.qml
index 86aeaddd03..2b9884d4a9 100644
--- a/tests/testapplications/elements/content/GridViewElement.qml
+++ b/tests/testapplications/elements/content/GridViewElement.qml
@@ -4,32 +4,32 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
+** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
@@ -116,5 +116,12 @@ Rectangle {
ListElement { label: "ParallelAnimation"; help: "The ParallelAnimation element allows animations to be run in parallel." }
ListElement { label: "XmlListModel"; help: "The XmlListModel element is used to specify a read-only model using XPath expressions." }
ListElement { label: "Scale"; help: "The Scale element provides a way to scale an Item." }
+ ListElement { label: "ParticleSystem"; help: "The ParticleSystem brings together ParticlePainter, Emitter and Affector elements." }
+ ListElement { label: "ImageParticle"; help: "The ImageParticle element visualizes logical particles using an image." }
+ ListElement { label: "Emitter"; help: "The Emitter element allows you to emit logical particles." }
+ ListElement { label: "Affector"; help: "Affector elements can alter the attributes of logical particles at any point in their lifetime." }
+ ListElement { label: "Shape"; help: "The Shape element allows you to specify an area for affectors and emitter." }
+ ListElement { label: "TrailEmitter"; help: "The TrailEmitter element allows you to emit logical particles from other logical particles." }
+ ListElement { label: "Direction"; help: "The Direction elements allow you to specify a vector space." }
}
}
diff --git a/tests/testapplications/elements/content/Help.qml b/tests/testapplications/elements/content/Help.qml
index e0b7c026a0..628a9fa1f8 100644
--- a/tests/testapplications/elements/content/Help.qml
+++ b/tests/testapplications/elements/content/Help.qml
@@ -4,32 +4,32 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
+** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
@@ -49,4 +49,4 @@ Item {
"Each system test qml \"application\" provides a basic visual element affected by one or more non-visual (functional) elements.<br>"+
"Simply select the element you wish to test, and follow the instructions. Use the arrow to advance the test.<br>"
}
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/HelpDesk.qml b/tests/testapplications/elements/content/HelpDesk.qml
index c60b8dee74..9bf82d1a2a 100644
--- a/tests/testapplications/elements/content/HelpDesk.qml
+++ b/tests/testapplications/elements/content/HelpDesk.qml
@@ -4,32 +4,32 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
+** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
@@ -55,4 +55,4 @@ Item {
anchors { right: helpbutton.left; bottom: parent.bottom; rightMargin: 5; bottomMargin: 20 }
Text { id: infotext; text: elementsapp.helptext; width: parent.width - 10; anchors.centerIn: parent; wrapMode: Text.WordWrap }
}
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/ImageElement.qml b/tests/testapplications/elements/content/ImageElement.qml
index a8811675df..1efd981078 100644
--- a/tests/testapplications/elements/content/ImageElement.qml
+++ b/tests/testapplications/elements/content/ImageElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -113,4 +113,4 @@ Item {
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/ImageParticleElement.qml b/tests/testapplications/elements/content/ImageParticleElement.qml
new file mode 100644
index 0000000000..fd6ef05158
--- /dev/null
+++ b/tests/testapplications/elements/content/ImageParticleElement.qml
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Item {
+ id: imageparticleelementtest
+ anchors.fill: parent
+ property string testtext: ""
+
+ ParticleSystem {
+ id: particlesystemelement
+ anchors.fill: parent
+ ImageParticle {
+ id: imageparticle
+ source: "pics/smile.png"
+ color: "red"
+ Behavior on color { ColorAnimation { duration: 3000 } }
+ }
+ Emitter {
+ id: particleemitter
+ anchors.centerIn: parent
+ emitRate: 50
+ lifeSpan: 3000
+ speed: AngleDirection { angle: 0; angleVariation: 360; magnitude: 60 }
+ }
+ }
+
+
+ SystemTestHelp { id: helpbubble; visible: statenum != 0
+ anchors { top: parent.top; horizontalCenter: parent.horizontalCenter; topMargin: 50 }
+ }
+ BugPanel { id: bugpanel }
+
+ states: [
+ State { name: "start"; when: statenum == 1
+ PropertyChanges { target: imageparticleelementtest
+ testtext: "This is an ImageParticle element. It should be emitting particles "+
+ "from the center of the display.\n"+
+ "Next, let's change the color of the particles." }
+ },
+ State { name: "green"; when: statenum == 2
+ PropertyChanges { target: imageparticle; color: "lightgreen" }
+ PropertyChanges { target: imageparticleelementtest
+ testtext: "The particles should now be green.\n"+
+ "Next, let's get them spinning." }
+ },
+ State { name: "spinning"; when: statenum == 3
+ PropertyChanges { target: imageparticle; color: "lightgreen"; rotation: 360; rotationSpeed: 100 }
+ PropertyChanges { target: imageparticleelementtest
+ testtext: "The particles should now be green and spinning.\n"+
+ "Next, let's get them popping in and out." }
+ },
+ State { name: "scaling"; when: statenum == 4
+ PropertyChanges { target: imageparticle; color: "lightgreen"; rotation: 360; rotationSpeed: 100; entryEffect: ImageParticle.Scale }
+ PropertyChanges { target: imageparticleelementtest
+ testtext: "The particles should now be scaling in and out.\n"+
+ "Advance to restart the test." }
+ }
+ ]
+} \ No newline at end of file
diff --git a/tests/testapplications/elements/content/IntValidatorElement.qml b/tests/testapplications/elements/content/IntValidatorElement.qml
index 2b1f80274f..72b693b487 100644
--- a/tests/testapplications/elements/content/IntValidatorElement.qml
+++ b/tests/testapplications/elements/content/IntValidatorElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -117,4 +117,4 @@ Item {
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/KeysElement.qml b/tests/testapplications/elements/content/KeysElement.qml
index c754376dd5..4af8999b6a 100644
--- a/tests/testapplications/elements/content/KeysElement.qml
+++ b/tests/testapplications/elements/content/KeysElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/tests/testapplications/elements/content/ListViewElement.qml b/tests/testapplications/elements/content/ListViewElement.qml
index 221c967f14..c59b3ecfb8 100644
--- a/tests/testapplications/elements/content/ListViewElement.qml
+++ b/tests/testapplications/elements/content/ListViewElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/tests/testapplications/elements/content/MouseAreaElement.qml b/tests/testapplications/elements/content/MouseAreaElement.qml
index 67399688cf..b8f97d0ae0 100644
--- a/tests/testapplications/elements/content/MouseAreaElement.qml
+++ b/tests/testapplications/elements/content/MouseAreaElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/tests/testapplications/elements/content/ParallelAnimationElement.qml b/tests/testapplications/elements/content/ParallelAnimationElement.qml
index eb217da286..3fd4353c3f 100644
--- a/tests/testapplications/elements/content/ParallelAnimationElement.qml
+++ b/tests/testapplications/elements/content/ParallelAnimationElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -91,4 +91,4 @@ Item {
}
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/ParticleSystemElement.qml b/tests/testapplications/elements/content/ParticleSystemElement.qml
new file mode 100644
index 0000000000..d7eeb20038
--- /dev/null
+++ b/tests/testapplications/elements/content/ParticleSystemElement.qml
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Item {
+ id: particlesystemelementtest
+ anchors.fill: parent
+ property string testtext: ""
+ Rectangle { x: 50; y: 200; height: 300; width: 260; color: "transparent"; border.color: "lightgray" }
+ ParticleSystem {
+ id: particlesystemelement
+ anchors.fill: parent
+ ImageParticle { source: "pics/star.png"; color: "red" }
+ Emitter {
+ id: particleemitter
+ x: 50; y: 200
+ emitRate: 100
+ speed: AngleDirection { angle: 0; angleVariation: 360; magnitude: 100 }
+ Rectangle { anchors.centerIn: parent; height: 1; width: 1; color: "black" }
+ SequentialAnimation {
+ running: true; paused: particlesystemelement.paused; loops: Animation.Infinite
+ NumberAnimation { target: particleemitter; properties: "x"; to: 310; duration: 3000 }
+ NumberAnimation { target: particleemitter; properties: "y"; to: 500; duration: 3000 }
+ NumberAnimation { target: particleemitter; properties: "x"; to: 50; duration: 3000 }
+ NumberAnimation { target: particleemitter; properties: "y"; to: 200; duration: 3000 }
+ }
+ }
+ }
+
+
+ SystemTestHelp { id: helpbubble; visible: statenum != 0
+ anchors { top: parent.top; horizontalCenter: parent.horizontalCenter; topMargin: 50 }
+ }
+ BugPanel { id: bugpanel }
+
+ states: [
+ State { name: "start"; when: statenum == 1
+ PropertyChanges { target: particlesystemelementtest
+ testtext: "This is an ParticleSystem element. It is represented by an ImageParticle, "+
+ "tracing around the display.\n"+
+ "Next, it should pause simulation." }
+ },
+ State { name: "paused"; when: statenum == 2
+ PropertyChanges { target: particlesystemelement; paused: true }
+ PropertyChanges { target: particlesystemelementtest
+ testtext: "The simulation should now be paused.\n"+
+ "Advance to resume simulation." }
+ },
+ State { name: "resumed"; when: statenum == 3
+ PropertyChanges { target: bugpanel; bugnumber: "21539" }
+ PropertyChanges { target: particlesystemelement; paused: false }
+ PropertyChanges { target: particlesystemelementtest
+ testtext: "The simulation should now be active.\n"+
+ "Advance to restart the test" }
+ }
+ ]
+} \ No newline at end of file
diff --git a/tests/testapplications/elements/content/RectangleElement.qml b/tests/testapplications/elements/content/RectangleElement.qml
index a34e43b7e9..ec734547c6 100644
--- a/tests/testapplications/elements/content/RectangleElement.qml
+++ b/tests/testapplications/elements/content/RectangleElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/tests/testapplications/elements/content/RegExpValidatorElement.qml b/tests/testapplications/elements/content/RegExpValidatorElement.qml
index 4892ca55e7..fe3903b68c 100644
--- a/tests/testapplications/elements/content/RegExpValidatorElement.qml
+++ b/tests/testapplications/elements/content/RegExpValidatorElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -110,4 +110,4 @@ Item {
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/RepeaterElement.qml b/tests/testapplications/elements/content/RepeaterElement.qml
index 327eb626e3..97a44f00c0 100644
--- a/tests/testapplications/elements/content/RepeaterElement.qml
+++ b/tests/testapplications/elements/content/RepeaterElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -93,4 +93,4 @@ Item {
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/RowElement.qml b/tests/testapplications/elements/content/RowElement.qml
index dda913a2d6..001ce6d2b4 100644
--- a/tests/testapplications/elements/content/RowElement.qml
+++ b/tests/testapplications/elements/content/RowElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -83,4 +83,4 @@ Item {
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/ScaleElement.qml b/tests/testapplications/elements/content/ScaleElement.qml
index 2563f77023..5897d684e7 100644
--- a/tests/testapplications/elements/content/ScaleElement.qml
+++ b/tests/testapplications/elements/content/ScaleElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -91,4 +91,4 @@ Item {
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/SequentialAnimationElement.qml b/tests/testapplications/elements/content/SequentialAnimationElement.qml
index 94531a2184..792b962882 100644
--- a/tests/testapplications/elements/content/SequentialAnimationElement.qml
+++ b/tests/testapplications/elements/content/SequentialAnimationElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -91,4 +91,4 @@ Item {
}
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/ShapeElement.qml b/tests/testapplications/elements/content/ShapeElement.qml
new file mode 100644
index 0000000000..e72fcaf072
--- /dev/null
+++ b/tests/testapplications/elements/content/ShapeElement.qml
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Item {
+ id: shapeelementtest
+ anchors.fill: parent
+ property string testtext: ""
+
+ ParticleSystem {
+ id: particlesystem
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 20
+ height: 300
+ width: 300
+
+ ImageParticle {
+ id: imageparticle
+ source: "pics/star.png"
+ color: "red"
+ }
+
+ Emitter {
+ id: emitter
+ property real magn: 0.1
+ anchors.fill: parent
+ emitRate: 500
+ lifeSpan: 2000
+ speed: TargetDirection {
+ targetX: particlesystem.width/2
+ targetY: particlesystem.height/2
+ proportionalMagnitude: true
+ magnitude: emitter.magn
+ magnitudeVariation: emitter.magn
+ }
+ shape: rectangleshapeelement
+ }
+ Emitter {
+ id: emitter2
+ enabled: false
+ anchors.fill: parent
+ emitRate: 200
+ lifeSpan: 1000
+ speed: TargetDirection {
+ targetX: particlesystem.width/2
+ targetY: particlesystem.height/2
+ proportionalMagnitude: true
+ magnitude: 0
+ magnitudeVariation: 0
+ }
+ shape: lineshapeelement2
+ }
+ // Shapes
+ EllipseShape {
+ id: ellipseshapeelement
+ fill: false
+ }
+ RectangleShape {
+ id: rectangleshapeelement
+ fill: false
+ }
+ LineShape {
+ id: lineshapeelement
+ }
+ LineShape {
+ id: lineshapeelement2
+ mirrored: true
+ }
+ MaskShape {
+ id: maskshapeelement
+ source: "pics/logo-hollowed.png"
+ }
+ }
+
+
+ SystemTestHelp { id: helpbubble; visible: statenum != 0
+ anchors { top: parent.top; horizontalCenter: parent.horizontalCenter; topMargin: 50 }
+ }
+ BugPanel { id: bugpanel }
+
+ states: [
+ State { name: "start"; when: statenum == 1
+ PropertyChanges { target: shapeelementtest
+ testtext: "This is an Shape element, used by Emitter. There should be a rectangle "+
+ "shape emitting into its center.\n"+
+ "Next, let's change the shape to an ellipse." }
+ },
+ State { name: "ellipse"; when: statenum == 2
+ PropertyChanges { target: emitter; shape: ellipseshapeelement }
+ PropertyChanges { target: shapeelementtest
+ testtext: "The particles should now be emitted in a circular shape.\n"+
+ "Next, let's change the shape to a line." }
+ },
+ State { name: "line"; when: statenum == 3
+ PropertyChanges { target: emitter; shape: lineshapeelement; lifeSpan: 1000; emitRate: 200; }
+ PropertyChanges { target: emitter2; enabled: true }
+ PropertyChanges { target: shapeelementtest
+ testtext: "The particles should now be emitted from two lines, creating an X shape.\n"+
+ "Next, let's change the shape to an image." }
+ },
+ State { name: "enduring"; when: statenum == 4
+ PropertyChanges { target: emitter; shape: maskshapeelement; lifeSpan: 1000; emitRate: 1000; magn: 0 }
+ PropertyChanges { target: shapeelementtest
+ testtext: "The particles should now be sparkling, stationary within a 'Qt' text image.\n"+
+ "Advance to restart the test." }
+ }
+ ]
+} \ No newline at end of file
diff --git a/tests/testapplications/elements/content/SystemPaletteElement.qml b/tests/testapplications/elements/content/SystemPaletteElement.qml
index 8a0347e104..9758884cb0 100644
--- a/tests/testapplications/elements/content/SystemPaletteElement.qml
+++ b/tests/testapplications/elements/content/SystemPaletteElement.qml
@@ -4,32 +4,32 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
+** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
@@ -89,4 +89,4 @@ Item {
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/SystemTestHelp.qml b/tests/testapplications/elements/content/SystemTestHelp.qml
index 7f3d8c3451..8d97b51388 100644
--- a/tests/testapplications/elements/content/SystemTestHelp.qml
+++ b/tests/testapplications/elements/content/SystemTestHelp.qml
@@ -4,32 +4,32 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
+** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
@@ -71,4 +71,4 @@ Rectangle {
anchors { right: parent.right; bottom: parent.bottom; rightMargin: 5; bottomMargin: 5 }
MouseArea { enabled: showadvance; anchors.fill: parent; onClicked: { advance(); } }
}
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/TextEditElement.qml b/tests/testapplications/elements/content/TextEditElement.qml
index 4be0188c7b..4966cdb54d 100644
--- a/tests/testapplications/elements/content/TextEditElement.qml
+++ b/tests/testapplications/elements/content/TextEditElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -141,4 +141,4 @@ Item {
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/TextElement.qml b/tests/testapplications/elements/content/TextElement.qml
index 2af1214186..383881c158 100644
--- a/tests/testapplications/elements/content/TextElement.qml
+++ b/tests/testapplications/elements/content/TextElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -98,4 +98,4 @@ Item {
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/TextInputElement.qml b/tests/testapplications/elements/content/TextInputElement.qml
index 14e3203238..4706549696 100644
--- a/tests/testapplications/elements/content/TextInputElement.qml
+++ b/tests/testapplications/elements/content/TextInputElement.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -136,4 +136,4 @@ Item {
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/TrailEmitterElement.qml b/tests/testapplications/elements/content/TrailEmitterElement.qml
new file mode 100644
index 0000000000..d90b760c99
--- /dev/null
+++ b/tests/testapplications/elements/content/TrailEmitterElement.qml
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Item {
+ id: trailemitterelementtest
+ anchors.fill: parent
+ property string testtext: ""
+
+ ParticleSystem {
+ id: particlesystem
+ anchors.fill: parent
+ Image {
+ id: backgroundpic
+ anchors.fill: parent
+ source: "pics/logo.png"
+ opacity: 0
+ Behavior on opacity { NumberAnimation { duration: 1000 } }
+ }
+ ImageParticle {
+ id: omissile
+ source: "pics/star.png"
+ color: "orange"
+ entryEffect: ImageParticle.None
+ groups: ["orangemissile"]
+ }
+ ImageParticle {
+ id: gmissile
+ source: "pics/star.png"
+ color: "green"
+ entryEffect: ImageParticle.None
+ groups: ["greenmissile"]
+ }
+ ImageParticle {
+ id: sparks
+ source: "pics/star.png"
+ color: "red"
+ colorVariation: .5
+ entryEffect: ImageParticle.None
+ groups: ["sparks"]
+ }
+ Emitter {
+ id: emitter
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 5
+ anchors.horizontalCenter: parent.horizontalCenter
+ emitRate: 1
+ lifeSpan: 3000
+ size: 20
+ speed: AngleDirection { angle: 270; angleVariation: 25; magnitude: 150 }
+ group: "orangemissile"
+ }
+ Emitter {
+ id: emitter2
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 5
+ anchors.horizontalCenter: parent.horizontalCenter
+ emitRate: 1
+ lifeSpan: 3000
+ size: 20
+ speed: AngleDirection { angle: 270; angleVariation: 25; magnitude: 150 }
+ group: "greenmissile"
+ }
+ Gravity {
+ anchors.fill: parent
+ angle: 90
+ acceleration: 30
+ }
+ TrailEmitter {
+ id: trailemitterelement
+ follow: "orangemissile"
+ group:"sparks"
+ anchors.fill: parent
+ emitRatePerParticle: 50
+ lifeSpan: 1000
+ speedFromMovement: .2
+ speed: AngleDirection { angle: 0; angleVariation: 360; magnitude: 5 }
+ maximumEmitted: 500
+ shape: basicshape
+ }
+
+ RectangleShape { id: basicshape }
+
+ MaskShape {
+ id: maskshape
+ source: "pics/logo-hollowed.png"
+ }
+
+ }
+
+ SystemTestHelp { id: helpbubble; visible: statenum != 0
+ anchors { top: parent.top; horizontalCenter: parent.horizontalCenter; topMargin: 50 }
+ }
+ BugPanel { id: bugpanel }
+
+ states: [
+ State { name: "start"; when: statenum == 1
+ PropertyChanges { target: trailemitterelementtest
+ testtext: "This is a TrailEmitter, with particles following the orange particles.\n"+
+ "The green particles should not be followed by other particles.\n"+
+ "Next, let's change the sparks to follow the green particles." }
+ },
+ State { name: "followgreen"; when: statenum == 2
+ PropertyChanges { target: trailemitterelement; follow: "greenmissile" }
+ PropertyChanges { target: trailemitterelementtest
+ testtext: "The particles should be following the green particles.\n"+
+ "Next, let's add a shape to emit within." }
+ },
+ State { name: "onlyinshape"; when: statenum == 3
+ PropertyChanges { target: trailemitterelement; follow: "greenmissile"; shape: maskshape }
+ PropertyChanges { target: backgroundpic; opacity: .5 }
+ PropertyChanges { target: trailemitterelementtest
+ testtext: "The particles should now be only emitted when they pass through the 'Qt' text.\n"+
+ "Next, let's create small Qt missiles." }
+ },
+ State { name: "emittingashape"; when: statenum == 4
+ PropertyChanges { target: trailemitterelement; follow: "greenmissile"; shape: basicshape
+ emitHeight: 60; emitWidth: 60; emitRatePerParticle: 1500; emitShape: maskshape; maximumEmitted: 1500; lifeSpan: 50
+ }
+ PropertyChanges { target: trailemitterelementtest
+ testtext: "The particles should now be Qt text shaped particles.\n"+
+ "Advance to restart the test." }
+ }
+ ]
+} \ No newline at end of file
diff --git a/tests/testapplications/elements/content/XmlListModelElement.qml b/tests/testapplications/elements/content/XmlListModelElement.qml
index 3ea0f9cc8a..306205fe65 100644
--- a/tests/testapplications/elements/content/XmlListModelElement.qml
+++ b/tests/testapplications/elements/content/XmlListModelElement.qml
@@ -4,32 +4,32 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
+** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
@@ -151,4 +151,4 @@ Item {
}
]
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/elements/content/elements.js b/tests/testapplications/elements/content/elements.js
index fb8cfdec45..e6e272e2c0 100644
--- a/tests/testapplications/elements/content/elements.js
+++ b/tests/testapplications/elements/content/elements.js
@@ -4,32 +4,32 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
+** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
diff --git a/tests/testapplications/elements/content/pics/logo-hollowed.png b/tests/testapplications/elements/content/pics/logo-hollowed.png
new file mode 100644
index 0000000000..ca2acb3651
--- /dev/null
+++ b/tests/testapplications/elements/content/pics/logo-hollowed.png
Binary files differ
diff --git a/examples/declarative/particles/images/smile.png b/tests/testapplications/elements/content/pics/smile.png
index 3d66d72578..3d66d72578 100644
--- a/examples/declarative/particles/images/smile.png
+++ b/tests/testapplications/elements/content/pics/smile.png
Binary files differ
diff --git a/tests/testapplications/elements/content/pics/star.png b/tests/testapplications/elements/content/pics/star.png
new file mode 100644
index 0000000000..0d592cfa87
--- /dev/null
+++ b/tests/testapplications/elements/content/pics/star.png
Binary files differ
diff --git a/tests/testapplications/elements/elements.qml b/tests/testapplications/elements/elements.qml
index 414d5aaacb..358e58230b 100644
--- a/tests/testapplications/elements/elements.qml
+++ b/tests/testapplications/elements/elements.qml
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of QtUiTest.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -69,4 +69,4 @@ Item {
console.log("Starting ",qmlfile);
qmlfiletoload = qmlfile;
}
-} \ No newline at end of file
+}
diff --git a/tests/testapplications/textlayout/styledtext-layout.qml b/tests/testapplications/textlayout/styledtext-layout.qml
new file mode 100644
index 0000000000..9ef30ef1ca
--- /dev/null
+++ b/tests/testapplications/textlayout/styledtext-layout.qml
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: main
+ width: 1024; height: 1024
+ focus: true
+
+ property real offset: 0
+ property real margin: 15
+
+ Keys.onLeftPressed: myText.horizontalAlignment = Text.AlignLeft
+ Keys.onUpPressed: myText.horizontalAlignment = Text.AlignHCenter
+ Keys.onRightPressed: myText.horizontalAlignment = Text.AlignRight
+ Keys.onDownPressed: myText.horizontalAlignment = Text.AlignJustify
+
+ Text {
+ id: myText
+ anchors.fill: parent
+ anchors.margins: 20
+ wrapMode: Text.WordWrap
+ font.family: "Times New Roman"
+ font.pixelSize: 18
+ textFormat: Text.StyledText
+ horizontalAlignment: Text.AlignJustify
+
+ text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer at ante dui sed eu egestas est facilis <a href=\"www.nokia.com\">www.nokia.com</a>.<br/>Curabitur ante est, pulvinar quis adipiscing a, iaculis id ipsum. Phasellus id neque id velit facilisis cursus ac sit amet nibh. Donec enim arcu, pharetra non semper nec, iaculis eget elit. Nunc blandit condimentum odio vel egestas.<br><ul type=\"bullet\"><li>Coffee<ol type=\"a\"><li>Espresso<li><b>Cappuccino</b><li><i>Flat White</i><li>Latte</ol><li>Juice<ol type=\"1\"><li>Orange</li><li>Apple</li><li>Pineapple</li><li>Tomato</li></ol></li></ul><p><font color=\"#434343\"><i>Proin consectetur <b>sapien</b> in ipsum lacinia sit amet mattis orci interdum. Quisque vitae accumsan lectus. Ut nisi turpis, sollicitudin ut dignissim id, fermentum ac est. Maecenas nec libero leo. Sed ac leo eget ipsum ultricies viverra sit amet eu orci. Praesent et tortor risus, viverra accumsan sapien. Sed faucibus eleifend lectus, sed euismod urna porta eu. Aenean ultricies lectus ut orci dictum quis convallis nisi ultrices. Nunc elit mi, iaculis a porttitor rutrum, venenatis malesuada nisi. Suspendisse turpis quam, euismod non imperdiet et, rutrum nec ligula. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper tristique metus eu sodales. Integer eget risus ipsum. Quisque ut risus ut nulla tristique volutpat at sit amet nisl. Aliquam pulvinar auctor diam nec bibendum. Quisque luctus sapien id arcu volutpat pharetra. Praesent pretium imperdiet euismod. Integer fringilla rhoncus condimentum. Quisque sit amet ornare nulla. Cras sapien augue, sagittis a dictum id, suscipit et nunc. Cras vitae augue in enim elementum venenatis sed nec risus. Sed nisi quam, mollis quis auctor ac, vestibulum in neque. Vivamus eu justo risus. Suspendisse vel mollis est. Vestibulum gravida interdum mi, in molestie neque gravida in.</i></font><br><br> Donec nibh odio, mattis facilisis vulputate et, scelerisque ut felis. Sed ornare eros nec odio aliquam eu varius augue adipiscing. Vivamus sit amet massa dapibus sapien pulvinar consectetur a sit amet felis. Cras non mi id libero dictum iaculis id dignissim eros. Praesent eget enim dui, sed bibendum neque. Ut interdum nisl id leo malesuada ornare.<br><br>Pellentesque id nisl eu odio volutpat posuere et at massa. Pellentesque nec lorem justo. Integer sem urna, pharetra sed sagittis vitae, condimentum ac felis. Ut vitae sapien ac tortor adipiscing pharetra. Cras tristique urna tempus ante volutpat eleifend non eu ligula. Mauris sodales nisl et lorem tristique sodales. Mauris arcu orci, vehicula semper cursus ac, dapibus ut mi. Cras orci ligula, lacinia non laoreet non, feugiat eget lorem. Duis commodo urna nunc. Ut eu diam quis magna volutpat auctor. Duis non nibh non leo aliquet gravida. <font color=\"green\">Aenean diam velit, eleifend sed porta eu, malesuada sed erat.</font> In hac habitasse platea dictumst. Ut nulla ligula, tincidunt ac volutpat nec, accumsan at risus. Donec eget ipsum sit amet nulla tempus auctor ut non massa. Donec enim purus, consectetur viverra congue vitae, vehicula eu sapien. Ut aliquam iaculis metus, a bibendum nisi fringilla ut. Maecenas ut libero augue, vitae tristique diam. Vivamus nec rhoncus ipsum. Maecenas rutrum, libero sit amet ultrices cursus, elit massa laoreet odio, in luctus elit quam eu quam. Sed non diam urna. Maecenas fringilla feugiat malesuada. In tellus nibh, gravida vitae cursus mollis, tincidunt eu urna. Cras turpis lorem, dictum in feugiat id, gravida eu nulla. In ultricies nisl in sapien consectetur eu ultricies nisl facilisis. Nam id mauris a leo pretium facilisis eget quis est. Fusce fermentum quam in metus facilisis semper."
+
+
+ onLineLaidOut: {
+ line.width = width / 2 - (2 * margin)
+ if (line.number === 40) {
+ main.offset = line.y
+ }
+ if (line.number >= 40) {
+ line.x = width / 2 + margin
+ line.y -= main.offset
+ }
+ if ((line.y + line.height) > rect.y && line.y < (rect.y + rect.height)) {
+ if (line.number < 40)
+ line.width = Math.min((rect.x - line.x), line.width)
+ else {
+ line.x = Math.max((rect.x + rect.width), width / 2 + margin)
+ line.width = Math.min((width - margin - line.x), line.width)
+ }
+ }
+ }
+
+ Item {
+ id: rect
+ x: 280; y: 200
+ width: 300; height: 300
+
+ Rectangle {
+ anchors { fill: parent; leftMargin: 15; rightMargin: 15 }
+ color: "lightsteelblue"; opacity: 0.3
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ drag.target: rect
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
+ onClicked: mouse.button == Qt.RightButton ? myText.font.pixelSize -= 1 : myText.font.pixelSize += 1
+ onPositionChanged: myText.doLayout()
+ }
+ }
+ }
+
+}
diff --git a/tools/qmlmin/main.cpp b/tools/qmlmin/main.cpp
index 7a5b8f9457..ebfc5851dd 100644
--- a/tools/qmlmin/main.cpp
+++ b/tools/qmlmin/main.cpp
@@ -39,9 +39,9 @@
**
****************************************************************************/
-#include "qdeclarativejsengine_p.h"
-#include "qdeclarativejslexer_p.h"
-#include "qdeclarativejsparser_p.h"
+#include <private/qdeclarativejsengine_p.h>
+#include <private/qdeclarativejslexer_p.h>
+#include <private/qdeclarativejsparser_p.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QStringList>
#include <QtCore/QFile>
@@ -50,6 +50,8 @@
#include <iostream>
#include <cstdlib>
+QT_BEGIN_NAMESPACE
+
//
// QML/JS minifier
//
@@ -139,6 +141,7 @@ protected:
else if (ch == QLatin1Char('\r')) quotedString += QLatin1String("\\r");
else if (ch == QLatin1Char('\t')) quotedString += QLatin1String("\\t");
else if (ch == QLatin1Char('\v')) quotedString += QLatin1String("\\v");
+ else if (ch == QLatin1Char('\0')) quotedString += QLatin1String("\\0");
else quotedString += ch;
}
}
@@ -483,7 +486,7 @@ static void usage(bool showHelp = false)
}
}
-int main(int argc, char *argv[])
+int runQmlmin(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
@@ -589,3 +592,10 @@ int main(int argc, char *argv[])
return 0;
}
+
+QT_END_NAMESPACE
+
+int main(int argc, char **argv)
+{
+ return QT_PREPEND_NAMESPACE(runQmlmin(argc, argv));
+}
diff --git a/tools/qmlmin/qmlmin.pro b/tools/qmlmin/qmlmin.pro
index 5b783a3439..67c7004c18 100644
--- a/tools/qmlmin/qmlmin.pro
+++ b/tools/qmlmin/qmlmin.pro
@@ -1,11 +1,9 @@
-QT = core
+QT = core qmldevtools-private
CONFIG += console
CONFIG -= app_bundle
DESTDIR = $$QT.declarative.bins
SOURCES += main.cpp
-include(../../src/declarative/qml/parser/parser.pri)
-
target.path = $$[QT_INSTALL_BINS]
INSTALLS += target
diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp
index 6132d15d0d..d0ab0d8784 100644
--- a/tools/qmlplugindump/main.cpp
+++ b/tools/qmlplugindump/main.cpp
@@ -42,6 +42,8 @@
#include <QtDeclarative/QtDeclarative>
#include <QtDeclarative/private/qdeclarativemetatype_p.h>
#include <QtDeclarative/private/qdeclarativeopenmetaobject_p.h>
+#include <QtDeclarative/private/qsgevents_p_p.h>
+#include <QtDeclarative/private/qsgpincharea_p.h>
#include <QtWidgets/QApplication>
@@ -204,8 +206,8 @@ QSet<const QMetaObject *> collectReachableMetaObjects(const QList<QDeclarativeTy
if (ty->typeName() == "QDeclarativeComponent")
continue;
- QByteArray tyName = ty->qmlTypeName();
- tyName = tyName.mid(tyName.lastIndexOf('/') + 1);
+ QString tyName = ty->qmlTypeName();
+ tyName = tyName.mid(tyName.lastIndexOf(QLatin1Char('/')) + 1);
if (tyName.isEmpty())
continue;
@@ -303,11 +305,15 @@ public:
for (int index = meta->enumeratorOffset(); index < meta->enumeratorCount(); ++index)
dump(meta->enumerator(index));
- for (int index = meta->propertyOffset(); index < meta->propertyCount(); ++index)
- dump(meta->property(index));
+ QSet<QString> implicitSignals;
+ for (int index = meta->propertyOffset(); index < meta->propertyCount(); ++index) {
+ const QMetaProperty &property = meta->property(index);
+ dump(property);
+ implicitSignals.insert(QString("%1Changed").arg(QString::fromUtf8(property.name())));
+ }
for (int index = meta->methodOffset(); index < meta->methodCount(); ++index)
- dump(meta->method(index));
+ dump(meta->method(index), implicitSignals);
qml->writeEndObject();
}
@@ -375,7 +381,7 @@ private:
qml->writeEndObject();
}
- void dump(const QMetaMethod &meth)
+ void dump(const QMetaMethod &meth, const QSet<QString> &implicitSignals)
{
if (meth.methodType() == QMetaMethod::Signal) {
if (meth.access() != QMetaMethod::Protected)
@@ -390,6 +396,16 @@ private:
return; // invalid signature
}
name = name.left(lparenIndex);
+ const QString typeName = convertToId(meth.typeName());
+
+ if (implicitSignals.contains(name)
+ && !meth.revision()
+ && meth.methodType() == QMetaMethod::Signal
+ && meth.parameterNames().isEmpty()
+ && typeName.isEmpty()) {
+ // don't mention implicit signals
+ return;
+ }
if (meth.methodType() == QMetaMethod::Signal)
qml->writeStartObject(QLatin1String("Signal"));
@@ -403,7 +419,6 @@ private:
qml->writeScriptBinding(QLatin1String("revision"), QString::number(revision));
#endif
- const QString typeName = convertToId(meth.typeName());
if (! typeName.isEmpty())
qml->writeScriptBinding(QLatin1String("type"), enquote(typeName));
@@ -570,6 +585,10 @@ int main(int argc, char *argv[])
QSet<const QMetaObject *> defaultReachable = collectReachableMetaObjects();
QList<QDeclarativeType *> defaultTypes = QDeclarativeMetaType::qmlTypes();
+ // add some otherwise unreachable QMetaObjects
+ defaultReachable.insert(&QSGMouseEvent::staticMetaObject);
+ // QSGKeyEvent, QSGPinchEvent, QSGDropEvent are not exported
+
// this will hold the meta objects we want to dump information of
QSet<const QMetaObject *> metas;
@@ -583,8 +602,8 @@ int main(int argc, char *argv[])
qWarning() << "Could not find QtObject type";
importCode = QByteArray("import QtQuick 2.0\n");
} else {
- QByteArray module = qtObjectType->qmlTypeName();
- module = module.mid(0, module.lastIndexOf('/'));
+ QString module = qtObjectType->qmlTypeName();
+ module = module.mid(0, module.lastIndexOf(QLatin1Char('/')));
importCode = QString("import %1 %2.%3\n").arg(module,
QString::number(qtObjectType->majorVersion()),
QString::number(qtObjectType->minorVersion())).toUtf8();
diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp
index cd40ea5f8c..c5f9274571 100644
--- a/tools/qmlscene/main.cpp
+++ b/tools/qmlscene/main.cpp
@@ -424,31 +424,34 @@ int main(int argc, char ** argv)
QStringList imports;
for (int i = 1; i < argc; ++i) {
- if (*argv[i] != '-' && QFileInfo(argv[i]).exists())
+ if (*argv[i] != '-' && QFileInfo(QFile::decodeName(argv[i])).exists()) {
options.file = QUrl::fromLocalFile(argv[i]);
- else if (QString::fromLatin1(argv[i]).toLower() == QLatin1String("--original-qml"))
- options.originalQml = true;
- else if (QString::fromLatin1(argv[i]).toLower() == QLatin1String("--original-qml-raster"))
- options.originalQmlRaster = true;
- else if (QString::fromLatin1(argv[i]).toLower() == QLatin1String("--maximized"))
- options.maximized = true;
- else if (QString::fromLatin1(argv[i]).toLower() == QLatin1String("--fullscreen"))
- options.fullscreen = true;
- else if (QString::fromLatin1(argv[i]).toLower() == QLatin1String("--sg-on-gv"))
- options.scenegraphOnGraphicsview = true;
- else if (QString::fromLatin1(argv[i]).toLower() == QLatin1String("--clip"))
- options.clip = true;
- else if (QString::fromLatin1(argv[i]).toLower() == QLatin1String("--no-version-detection"))
- options.versionDetection = false;
- else if (QString::fromLatin1(argv[i]).toLower() == QLatin1String("-i") && i + 1 < argc)
- imports.append(QString::fromLatin1(argv[++i]));
- else if (QString::fromLatin1(argv[i]).toLower() == QLatin1String("--no-vsync-animations"))
- options.vsync = false;
- else if (QString::fromLatin1(argv[i]).toLower() == QLatin1String("--help")
- || QString::fromLatin1(argv[i]).toLower() == QLatin1String("-help")
- || QString::fromLatin1(argv[i]).toLower() == QLatin1String("--h")
- || QString::fromLatin1(argv[i]).toLower() == QLatin1String("-h"))
- usage();
+ } else {
+ const QString lowerArgument = QString::fromLatin1(argv[i]).toLower();
+ if (lowerArgument == QLatin1String("--original-qml"))
+ options.originalQml = true;
+ else if (lowerArgument == QLatin1String("--original-qml-raster"))
+ options.originalQmlRaster = true;
+ else if (lowerArgument == QLatin1String("--maximized"))
+ options.maximized = true;
+ else if (lowerArgument == QLatin1String("--fullscreen"))
+ options.fullscreen = true;
+ else if (lowerArgument == QLatin1String("--sg-on-gv"))
+ options.scenegraphOnGraphicsview = true;
+ else if (lowerArgument == QLatin1String("--clip"))
+ options.clip = true;
+ else if (lowerArgument == QLatin1String("--no-version-detection"))
+ options.versionDetection = false;
+ else if (lowerArgument == QLatin1String("-i") && i + 1 < argc)
+ imports.append(QString::fromLatin1(argv[++i]));
+ else if (lowerArgument == QLatin1String("--no-vsync-animations"))
+ options.vsync = false;
+ else if (lowerArgument == QLatin1String("--help")
+ || lowerArgument == QLatin1String("-help")
+ || lowerArgument == QLatin1String("--h")
+ || lowerArgument == QLatin1String("-h"))
+ usage();
+ }
}
QApplication::setGraphicsSystem("raster");
@@ -502,6 +505,7 @@ int main(int argc, char ** argv)
QObject::connect(engine, SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit()));
+ window->setWindowFlags(Qt::Window | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
if (options.fullscreen)
window->showFullScreen();
else if (options.maximized)
diff --git a/tools/qmlviewer/deviceorientation_harmattan.cpp b/tools/qmlviewer/deviceorientation_harmattan.cpp
index b3b3fe54d7..c5e329b152 100644
--- a/tools/qmlviewer/deviceorientation_harmattan.cpp
+++ b/tools/qmlviewer/deviceorientation_harmattan.cpp
@@ -43,13 +43,13 @@
#include <QtDBus>
#include <QDebug>
-#define ORIENTATION_SERVICE "com.nokia.SensorService"
-#define ORIENTATION_PATH "/org/maemo/contextkit/Screen/TopEdge"
-#define CONTEXT_INTERFACE "org.maemo.contextkit.Property"
-#define CONTEXT_CHANGED "ValueChanged"
-#define CONTEXT_SUBSCRIBE "Subscribe"
-#define CONTEXT_UNSUBSCRIBE "Unsubscribe"
-#define CONTEXT_GET "Get"
+#define ORIENTATION_SERVICE QStringLiteral("com.nokia.SensorService")
+#define ORIENTATION_PATH QStringLiteral("/org/maemo/contextkit/Screen/TopEdge")
+#define CONTEXT_INTERFACE QStringLiteral("org.maemo.contextkit.Property")
+#define CONTEXT_CHANGED QStringLiteral("ValueChanged")
+#define CONTEXT_SUBSCRIBE QStringLiteral("Subscribe")
+#define CONTEXT_UNSUBSCRIBE QStringLiteral("Unsubscribe")
+#define CONTEXT_GET QStringLiteral("Get")
class HarmattanOrientation : public DeviceOrientation
@@ -136,13 +136,13 @@ private Q_SLOTS:
private:
static Orientation toOrientation(const QString &nativeOrientation)
{
- if (nativeOrientation == "top")
+ if (nativeOrientation == QLatin1String("top"))
return Landscape;
- else if (nativeOrientation == "left")
+ else if (nativeOrientation == QLatin1String("left"))
return Portrait;
- else if (nativeOrientation == "bottom")
+ else if (nativeOrientation == QLatin1String("bottom"))
return LandscapeInverted;
- else if (nativeOrientation == "right")
+ else if (nativeOrientation == QLatin1String("right"))
return PortraitInverted;
return UnknownOrientation;
}
diff --git a/tools/qmlviewer/qmlruntime.cpp b/tools/qmlviewer/qmlruntime.cpp
index b4c74e128c..a1ebd54a52 100644
--- a/tools/qmlviewer/qmlruntime.cpp
+++ b/tools/qmlviewer/qmlruntime.cpp
@@ -60,6 +60,7 @@
#include <qdeclarativenetworkaccessmanagerfactory.h>
#include <QSettings>
+#include <QMimeData>
#include <QXmlStreamReader>
#include <QBuffer>
#include <QNetworkReply>
@@ -87,6 +88,7 @@
#include <QGraphicsObject>
#include <QNetworkProxyFactory>
#include <QKeyEvent>
+#include <QMimeData>
#include <QMutex>
#include <QMutexLocker>
#include "proxysettings.h"