Rename Qt Quick-specific classes to QQuick*
authorKent Hansen <kent.hansen@nokia.com>
Fri, 14 Oct 2011 08:51:42 +0000 (10:51 +0200)
committerQt by Nokia <qt-info@nokia.com>
Fri, 21 Oct 2011 09:53:26 +0000 (11:53 +0200)
The QSG (SceneGraph) prefix is too generic for
Qt Quick(2)-specific classes.

All the classes and files in the declarative/items
directory have been renamed.

In particular, for classes that are currently public,
the renaming is as follows:

QSGView --> QQuickView
QSGCanvas --> QQuickCanvas
QSGItem --> QQuickItem
QSGPaintedItem --> QQuickPaintedItem

The header files have been renamed accordingly
(e.g. qsgview.h --> qquickview.h).

Change-Id: Iac937fff81db20bb639486a793c3aeb5230b038c
Reviewed-by: Kent Hansen <kent.hansen@nokia.com>

900 files changed:
doc/src/declarative/example-textballoons.qdoc
doc/src/declarative/qmltest.qdoc
doc/src/declarative/whatsnew.qdoc
doc/src/qtquick1/example-textballoons.qdoc
doc/src/qtquick1/qmltest.qdoc
examples/declarative/cppextensions/networkaccessmanagerfactory/main.cpp
examples/declarative/minehunt/main.cpp
examples/declarative/modelviews/abstractitemmodel/main.cpp
examples/declarative/modelviews/objectlistmodel/main.cpp
examples/declarative/modelviews/stringlistmodel/main.cpp
examples/declarative/painteditem/smile/main.cpp
examples/declarative/painteditem/textballoons/textballoon.cpp
examples/declarative/painteditem/textballoons/textballoon.h
examples/declarative/tutorials/extending/chapter1-basics/main.cpp
examples/declarative/tutorials/extending/chapter1-basics/piechart.cpp
examples/declarative/tutorials/extending/chapter1-basics/piechart.h
examples/declarative/tutorials/extending/chapter2-methods/main.cpp
examples/declarative/tutorials/extending/chapter2-methods/piechart.cpp
examples/declarative/tutorials/extending/chapter2-methods/piechart.h
examples/declarative/tutorials/extending/chapter3-bindings/main.cpp
examples/declarative/tutorials/extending/chapter3-bindings/piechart.cpp
examples/declarative/tutorials/extending/chapter3-bindings/piechart.h
examples/declarative/tutorials/extending/chapter4-customPropertyTypes/main.cpp
examples/declarative/tutorials/extending/chapter4-customPropertyTypes/piechart.cpp
examples/declarative/tutorials/extending/chapter4-customPropertyTypes/piechart.h
examples/declarative/tutorials/extending/chapter4-customPropertyTypes/pieslice.cpp
examples/declarative/tutorials/extending/chapter4-customPropertyTypes/pieslice.h
examples/declarative/tutorials/extending/chapter5-listproperties/main.cpp
examples/declarative/tutorials/extending/chapter5-listproperties/piechart.cpp
examples/declarative/tutorials/extending/chapter5-listproperties/piechart.h
examples/declarative/tutorials/extending/chapter5-listproperties/pieslice.cpp
examples/declarative/tutorials/extending/chapter5-listproperties/pieslice.h
examples/declarative/tutorials/extending/chapter6-plugins/piechart.cpp
examples/declarative/tutorials/extending/chapter6-plugins/piechart.h
examples/declarative/tutorials/extending/chapter6-plugins/pieslice.cpp
examples/declarative/tutorials/extending/chapter6-plugins/pieslice.h
src/declarative/designer/designersupport.cpp
src/declarative/designer/designersupport.h
src/declarative/items/context2d/context2d.pri
src/declarative/items/context2d/qquickcanvasitem.cpp [new file with mode: 0644]
src/declarative/items/context2d/qquickcanvasitem_p.h [new file with mode: 0644]
src/declarative/items/context2d/qquickcontext2d.cpp [new file with mode: 0644]
src/declarative/items/context2d/qquickcontext2d_p.h [new file with mode: 0644]
src/declarative/items/context2d/qquickcontext2dcommandbuffer.cpp [new file with mode: 0644]
src/declarative/items/context2d/qquickcontext2dcommandbuffer_p.h [new file with mode: 0644]
src/declarative/items/context2d/qquickcontext2dnode.cpp [new file with mode: 0644]
src/declarative/items/context2d/qquickcontext2dnode_p.h [new file with mode: 0644]
src/declarative/items/context2d/qquickcontext2dtexture.cpp [new file with mode: 0644]
src/declarative/items/context2d/qquickcontext2dtexture_p.h [new file with mode: 0644]
src/declarative/items/context2d/qquickcontext2dtile.cpp [new file with mode: 0644]
src/declarative/items/context2d/qquickcontext2dtile_p.h [new file with mode: 0644]
src/declarative/items/context2d/qsgcanvasitem.cpp [deleted file]
src/declarative/items/context2d/qsgcanvasitem_p.h [deleted file]
src/declarative/items/context2d/qsgcontext2d.cpp [deleted file]
src/declarative/items/context2d/qsgcontext2d_p.h [deleted file]
src/declarative/items/context2d/qsgcontext2dcommandbuffer.cpp [deleted file]
src/declarative/items/context2d/qsgcontext2dcommandbuffer_p.h [deleted file]
src/declarative/items/context2d/qsgcontext2dnode.cpp [deleted file]
src/declarative/items/context2d/qsgcontext2dnode_p.h [deleted file]
src/declarative/items/context2d/qsgcontext2dtexture.cpp [deleted file]
src/declarative/items/context2d/qsgcontext2dtexture_p.h [deleted file]
src/declarative/items/context2d/qsgcontext2dtile.cpp [deleted file]
src/declarative/items/context2d/qsgcontext2dtile_p.h [deleted file]
src/declarative/items/items.pri
src/declarative/items/qquickanchors.cpp [new file with mode: 0644]
src/declarative/items/qquickanchors_p.h [new file with mode: 0644]
src/declarative/items/qquickanchors_p_p.h [new file with mode: 0644]
src/declarative/items/qquickanimatedimage.cpp [new file with mode: 0644]
src/declarative/items/qquickanimatedimage_p.h [new file with mode: 0644]
src/declarative/items/qquickanimatedimage_p_p.h [new file with mode: 0644]
src/declarative/items/qquickanimation.cpp [new file with mode: 0644]
src/declarative/items/qquickanimation_p.h [new file with mode: 0644]
src/declarative/items/qquickanimation_p_p.h [new file with mode: 0644]
src/declarative/items/qquickborderimage.cpp [new file with mode: 0644]
src/declarative/items/qquickborderimage_p.h [new file with mode: 0644]
src/declarative/items/qquickborderimage_p_p.h [new file with mode: 0644]
src/declarative/items/qquickcanvas.cpp [new file with mode: 0644]
src/declarative/items/qquickcanvas.h [new file with mode: 0644]
src/declarative/items/qquickcanvas_p.h [new file with mode: 0644]
src/declarative/items/qquickclipnode.cpp [new file with mode: 0644]
src/declarative/items/qquickclipnode_p.h [new file with mode: 0644]
src/declarative/items/qquickdrag.cpp [new file with mode: 0644]
src/declarative/items/qquickdrag_p.h [new file with mode: 0644]
src/declarative/items/qquickdroparea.cpp [new file with mode: 0644]
src/declarative/items/qquickdroparea_p.h [new file with mode: 0644]
src/declarative/items/qquickevents.cpp [new file with mode: 0644]
src/declarative/items/qquickevents_p_p.h [new file with mode: 0644]
src/declarative/items/qquickflickable.cpp [new file with mode: 0644]
src/declarative/items/qquickflickable_p.h [new file with mode: 0644]
src/declarative/items/qquickflickable_p_p.h [new file with mode: 0644]
src/declarative/items/qquickflipable.cpp [new file with mode: 0644]
src/declarative/items/qquickflipable_p.h [new file with mode: 0644]
src/declarative/items/qquickfocusscope.cpp [new file with mode: 0644]
src/declarative/items/qquickfocusscope_p.h [new file with mode: 0644]
src/declarative/items/qquickgridview.cpp [new file with mode: 0644]
src/declarative/items/qquickgridview_p.h [new file with mode: 0644]
src/declarative/items/qquickimage.cpp [new file with mode: 0644]
src/declarative/items/qquickimage_p.h [new file with mode: 0644]
src/declarative/items/qquickimage_p_p.h [new file with mode: 0644]
src/declarative/items/qquickimagebase.cpp [new file with mode: 0644]
src/declarative/items/qquickimagebase_p.h [new file with mode: 0644]
src/declarative/items/qquickimagebase_p_p.h [new file with mode: 0644]
src/declarative/items/qquickimplicitsizeitem.cpp [new file with mode: 0644]
src/declarative/items/qquickimplicitsizeitem_p.h [new file with mode: 0644]
src/declarative/items/qquickimplicitsizeitem_p_p.h [new file with mode: 0644]
src/declarative/items/qquickitem.cpp [new file with mode: 0644]
src/declarative/items/qquickitem.h [new file with mode: 0644]
src/declarative/items/qquickitem_p.h [new file with mode: 0644]
src/declarative/items/qquickitemchangelistener_p.h [new file with mode: 0644]
src/declarative/items/qquickitemsmodule.cpp [new file with mode: 0644]
src/declarative/items/qquickitemsmodule_p.h [new file with mode: 0644]
src/declarative/items/qquickitemview.cpp [new file with mode: 0644]
src/declarative/items/qquickitemview_p.h [new file with mode: 0644]
src/declarative/items/qquickitemview_p_p.h [new file with mode: 0644]
src/declarative/items/qquicklistview.cpp [new file with mode: 0644]
src/declarative/items/qquicklistview_p.h [new file with mode: 0644]
src/declarative/items/qquickloader.cpp [new file with mode: 0644]
src/declarative/items/qquickloader_p.h [new file with mode: 0644]
src/declarative/items/qquickloader_p_p.h [new file with mode: 0644]
src/declarative/items/qquickmousearea.cpp [new file with mode: 0644]
src/declarative/items/qquickmousearea_p.h [new file with mode: 0644]
src/declarative/items/qquickmousearea_p_p.h [new file with mode: 0644]
src/declarative/items/qquickninepatchnode.cpp [new file with mode: 0644]
src/declarative/items/qquickninepatchnode_p.h [new file with mode: 0644]
src/declarative/items/qquickpainteditem.cpp [new file with mode: 0644]
src/declarative/items/qquickpainteditem.h [new file with mode: 0644]
src/declarative/items/qquickpainteditem_p.h [new file with mode: 0644]
src/declarative/items/qquickpathview.cpp [new file with mode: 0644]
src/declarative/items/qquickpathview_p.h [new file with mode: 0644]
src/declarative/items/qquickpathview_p_p.h [new file with mode: 0644]
src/declarative/items/qquickpincharea.cpp [new file with mode: 0644]
src/declarative/items/qquickpincharea_p.h [new file with mode: 0644]
src/declarative/items/qquickpincharea_p_p.h [new file with mode: 0644]
src/declarative/items/qquickpositioners.cpp [new file with mode: 0644]
src/declarative/items/qquickpositioners_p.h [new file with mode: 0644]
src/declarative/items/qquickpositioners_p_p.h [new file with mode: 0644]
src/declarative/items/qquickrectangle.cpp [new file with mode: 0644]
src/declarative/items/qquickrectangle_p.h [new file with mode: 0644]
src/declarative/items/qquickrectangle_p_p.h [new file with mode: 0644]
src/declarative/items/qquickrepeater.cpp [new file with mode: 0644]
src/declarative/items/qquickrepeater_p.h [new file with mode: 0644]
src/declarative/items/qquickrepeater_p_p.h [new file with mode: 0644]
src/declarative/items/qquickscalegrid.cpp [new file with mode: 0644]
src/declarative/items/qquickscalegrid_p_p.h [new file with mode: 0644]
src/declarative/items/qquickshadereffect.cpp [new file with mode: 0644]
src/declarative/items/qquickshadereffect_p.h [new file with mode: 0644]
src/declarative/items/qquickshadereffectmesh.cpp [new file with mode: 0644]
src/declarative/items/qquickshadereffectmesh_p.h [new file with mode: 0644]
src/declarative/items/qquickshadereffectnode.cpp [new file with mode: 0644]
src/declarative/items/qquickshadereffectnode_p.h [new file with mode: 0644]
src/declarative/items/qquickshadereffectsource.cpp [new file with mode: 0644]
src/declarative/items/qquickshadereffectsource_p.h [new file with mode: 0644]
src/declarative/items/qquicksprite.cpp [new file with mode: 0644]
src/declarative/items/qquicksprite_p.h [new file with mode: 0644]
src/declarative/items/qquickspriteengine.cpp [new file with mode: 0644]
src/declarative/items/qquickspriteengine_p.h [new file with mode: 0644]
src/declarative/items/qquickspriteimage.cpp [new file with mode: 0644]
src/declarative/items/qquickspriteimage_p.h [new file with mode: 0644]
src/declarative/items/qquickstateoperations.cpp [new file with mode: 0644]
src/declarative/items/qquickstateoperations_p.h [new file with mode: 0644]
src/declarative/items/qquicktext.cpp [new file with mode: 0644]
src/declarative/items/qquicktext_p.h [new file with mode: 0644]
src/declarative/items/qquicktext_p_p.h [new file with mode: 0644]
src/declarative/items/qquicktextedit.cpp [new file with mode: 0644]
src/declarative/items/qquicktextedit_p.h [new file with mode: 0644]
src/declarative/items/qquicktextedit_p_p.h [new file with mode: 0644]
src/declarative/items/qquicktextinput.cpp [new file with mode: 0644]
src/declarative/items/qquicktextinput_p.h [new file with mode: 0644]
src/declarative/items/qquicktextinput_p_p.h [new file with mode: 0644]
src/declarative/items/qquicktextnode.cpp [new file with mode: 0644]
src/declarative/items/qquicktextnode_p.h [new file with mode: 0644]
src/declarative/items/qquicktranslate.cpp [new file with mode: 0644]
src/declarative/items/qquicktranslate_p.h [new file with mode: 0644]
src/declarative/items/qquickview.cpp [new file with mode: 0644]
src/declarative/items/qquickview.h [new file with mode: 0644]
src/declarative/items/qquickview_p.h [new file with mode: 0644]
src/declarative/items/qquickvisualadaptormodel.cpp [new file with mode: 0644]
src/declarative/items/qquickvisualadaptormodel_p.h [new file with mode: 0644]
src/declarative/items/qquickvisualdatamodel.cpp [new file with mode: 0644]
src/declarative/items/qquickvisualdatamodel_p.h [new file with mode: 0644]
src/declarative/items/qquickvisualitemmodel.cpp [new file with mode: 0644]
src/declarative/items/qquickvisualitemmodel_p.h [new file with mode: 0644]
src/declarative/items/qsganchors.cpp [deleted file]
src/declarative/items/qsganchors_p.h [deleted file]
src/declarative/items/qsganchors_p_p.h [deleted file]
src/declarative/items/qsganimatedimage.cpp [deleted file]
src/declarative/items/qsganimatedimage_p.h [deleted file]
src/declarative/items/qsganimatedimage_p_p.h [deleted file]
src/declarative/items/qsganimation.cpp [deleted file]
src/declarative/items/qsganimation_p.h [deleted file]
src/declarative/items/qsganimation_p_p.h [deleted file]
src/declarative/items/qsgborderimage.cpp [deleted file]
src/declarative/items/qsgborderimage_p.h [deleted file]
src/declarative/items/qsgborderimage_p_p.h [deleted file]
src/declarative/items/qsgcanvas.cpp [deleted file]
src/declarative/items/qsgcanvas.h [deleted file]
src/declarative/items/qsgcanvas_p.h [deleted file]
src/declarative/items/qsgclipnode.cpp [deleted file]
src/declarative/items/qsgclipnode_p.h [deleted file]
src/declarative/items/qsgdrag.cpp [deleted file]
src/declarative/items/qsgdrag_p.h [deleted file]
src/declarative/items/qsgdroparea.cpp [deleted file]
src/declarative/items/qsgdroparea_p.h [deleted file]
src/declarative/items/qsgevents.cpp [deleted file]
src/declarative/items/qsgevents_p_p.h [deleted file]
src/declarative/items/qsgflickable.cpp [deleted file]
src/declarative/items/qsgflickable_p.h [deleted file]
src/declarative/items/qsgflickable_p_p.h [deleted file]
src/declarative/items/qsgflipable.cpp [deleted file]
src/declarative/items/qsgflipable_p.h [deleted file]
src/declarative/items/qsgfocusscope.cpp [deleted file]
src/declarative/items/qsgfocusscope_p.h [deleted file]
src/declarative/items/qsggridview.cpp [deleted file]
src/declarative/items/qsggridview_p.h [deleted file]
src/declarative/items/qsgimage.cpp [deleted file]
src/declarative/items/qsgimage_p.h [deleted file]
src/declarative/items/qsgimage_p_p.h [deleted file]
src/declarative/items/qsgimagebase.cpp [deleted file]
src/declarative/items/qsgimagebase_p.h [deleted file]
src/declarative/items/qsgimagebase_p_p.h [deleted file]
src/declarative/items/qsgimplicitsizeitem.cpp [deleted file]
src/declarative/items/qsgimplicitsizeitem_p.h [deleted file]
src/declarative/items/qsgimplicitsizeitem_p_p.h [deleted file]
src/declarative/items/qsgitem.cpp [deleted file]
src/declarative/items/qsgitem.h [deleted file]
src/declarative/items/qsgitem_p.h [deleted file]
src/declarative/items/qsgitemchangelistener_p.h [deleted file]
src/declarative/items/qsgitemsmodule.cpp [deleted file]
src/declarative/items/qsgitemsmodule_p.h [deleted file]
src/declarative/items/qsgitemview.cpp [deleted file]
src/declarative/items/qsgitemview_p.h [deleted file]
src/declarative/items/qsgitemview_p_p.h [deleted file]
src/declarative/items/qsglistview.cpp [deleted file]
src/declarative/items/qsglistview_p.h [deleted file]
src/declarative/items/qsgloader.cpp [deleted file]
src/declarative/items/qsgloader_p.h [deleted file]
src/declarative/items/qsgloader_p_p.h [deleted file]
src/declarative/items/qsgmousearea.cpp [deleted file]
src/declarative/items/qsgmousearea_p.h [deleted file]
src/declarative/items/qsgmousearea_p_p.h [deleted file]
src/declarative/items/qsgninepatchnode.cpp [deleted file]
src/declarative/items/qsgninepatchnode_p.h [deleted file]
src/declarative/items/qsgpainteditem.cpp [deleted file]
src/declarative/items/qsgpainteditem.h [deleted file]
src/declarative/items/qsgpainteditem_p.h [deleted file]
src/declarative/items/qsgpathview.cpp [deleted file]
src/declarative/items/qsgpathview_p.h [deleted file]
src/declarative/items/qsgpathview_p_p.h [deleted file]
src/declarative/items/qsgpincharea.cpp [deleted file]
src/declarative/items/qsgpincharea_p.h [deleted file]
src/declarative/items/qsgpincharea_p_p.h [deleted file]
src/declarative/items/qsgpositioners.cpp [deleted file]
src/declarative/items/qsgpositioners_p.h [deleted file]
src/declarative/items/qsgpositioners_p_p.h [deleted file]
src/declarative/items/qsgrectangle.cpp [deleted file]
src/declarative/items/qsgrectangle_p.h [deleted file]
src/declarative/items/qsgrectangle_p_p.h [deleted file]
src/declarative/items/qsgrepeater.cpp [deleted file]
src/declarative/items/qsgrepeater_p.h [deleted file]
src/declarative/items/qsgrepeater_p_p.h [deleted file]
src/declarative/items/qsgscalegrid.cpp [deleted file]
src/declarative/items/qsgscalegrid_p_p.h [deleted file]
src/declarative/items/qsgshadereffect.cpp [deleted file]
src/declarative/items/qsgshadereffect_p.h [deleted file]
src/declarative/items/qsgshadereffectmesh.cpp [deleted file]
src/declarative/items/qsgshadereffectmesh_p.h [deleted file]
src/declarative/items/qsgshadereffectnode.cpp [deleted file]
src/declarative/items/qsgshadereffectnode_p.h [deleted file]
src/declarative/items/qsgshadereffectsource.cpp [deleted file]
src/declarative/items/qsgshadereffectsource_p.h [deleted file]
src/declarative/items/qsgsprite.cpp [deleted file]
src/declarative/items/qsgsprite_p.h [deleted file]
src/declarative/items/qsgspriteengine.cpp [deleted file]
src/declarative/items/qsgspriteengine_p.h [deleted file]
src/declarative/items/qsgspriteimage.cpp [deleted file]
src/declarative/items/qsgspriteimage_p.h [deleted file]
src/declarative/items/qsgstateoperations.cpp [deleted file]
src/declarative/items/qsgstateoperations_p.h [deleted file]
src/declarative/items/qsgtext.cpp [deleted file]
src/declarative/items/qsgtext_p.h [deleted file]
src/declarative/items/qsgtext_p_p.h [deleted file]
src/declarative/items/qsgtextedit.cpp [deleted file]
src/declarative/items/qsgtextedit_p.h [deleted file]
src/declarative/items/qsgtextedit_p_p.h [deleted file]
src/declarative/items/qsgtextinput.cpp [deleted file]
src/declarative/items/qsgtextinput_p.h [deleted file]
src/declarative/items/qsgtextinput_p_p.h [deleted file]
src/declarative/items/qsgtextnode.cpp [deleted file]
src/declarative/items/qsgtextnode_p.h [deleted file]
src/declarative/items/qsgtranslate.cpp [deleted file]
src/declarative/items/qsgtranslate_p.h [deleted file]
src/declarative/items/qsgview.cpp [deleted file]
src/declarative/items/qsgview.h [deleted file]
src/declarative/items/qsgview_p.h [deleted file]
src/declarative/items/qsgvisualadaptormodel.cpp [deleted file]
src/declarative/items/qsgvisualadaptormodel_p.h [deleted file]
src/declarative/items/qsgvisualdatamodel.cpp [deleted file]
src/declarative/items/qsgvisualdatamodel_p.h [deleted file]
src/declarative/items/qsgvisualitemmodel.cpp [deleted file]
src/declarative/items/qsgvisualitemmodel_p.h [deleted file]
src/declarative/particles/qsgage.cpp
src/declarative/particles/qsgage_p.h
src/declarative/particles/qsgcustomaffector.cpp
src/declarative/particles/qsgcustomaffector_p.h
src/declarative/particles/qsgcustomparticle.cpp
src/declarative/particles/qsgcustomparticle_p.h
src/declarative/particles/qsgfriction.cpp
src/declarative/particles/qsgfriction_p.h
src/declarative/particles/qsggravity.cpp
src/declarative/particles/qsggravity_p.h
src/declarative/particles/qsggroupgoal.cpp
src/declarative/particles/qsggroupgoal_p.h
src/declarative/particles/qsgimageparticle.cpp
src/declarative/particles/qsgimageparticle_p.h
src/declarative/particles/qsgitemparticle.cpp
src/declarative/particles/qsgitemparticle_p.h
src/declarative/particles/qsgmove.cpp
src/declarative/particles/qsgmove_p.h
src/declarative/particles/qsgparticleaffector.cpp
src/declarative/particles/qsgparticleaffector_p.h
src/declarative/particles/qsgparticleemitter.cpp
src/declarative/particles/qsgparticleemitter_p.h
src/declarative/particles/qsgparticlegroup.cpp
src/declarative/particles/qsgparticlegroup_p.h
src/declarative/particles/qsgparticlepainter.cpp
src/declarative/particles/qsgparticlepainter_p.h
src/declarative/particles/qsgparticlesmodule.cpp
src/declarative/particles/qsgparticlesystem.cpp
src/declarative/particles/qsgparticlesystem_p.h
src/declarative/particles/qsgpointattractor.cpp
src/declarative/particles/qsgpointattractor_p.h
src/declarative/particles/qsgspritegoal.cpp
src/declarative/particles/qsgspritegoal_p.h
src/declarative/particles/qsgtargetaffector.cpp
src/declarative/particles/qsgtargetaffector_p.h
src/declarative/particles/qsgtargetdirection_p.h
src/declarative/particles/qsgtrailemitter.cpp
src/declarative/particles/qsgtrailemitter_p.h
src/declarative/particles/qsgturbulence.cpp
src/declarative/particles/qsgturbulence_p.h
src/declarative/particles/qsgv8particledata.cpp
src/declarative/particles/qsgwander.cpp
src/declarative/particles/qsgwander_p.h
src/declarative/qml/qdeclarativeengine.cpp
src/declarative/qml/v4/qv4bindings.cpp
src/declarative/qml/v4/qv4compiler.cpp
src/declarative/qml/v4/qv4irbuilder.cpp
src/declarative/scenegraph/qsgadaptationlayer_p.h
src/declarative/scenegraph/qsgcontext.cpp
src/declarative/scenegraph/qsgdefaultglyphnode_p.h
src/declarative/scenegraph/qsgdistancefieldglyphnode.cpp
src/declarative/scenegraph/qsgdistancefieldglyphnode_p.h
src/declarative/scenegraph/util/qsgpainternode.cpp
src/declarative/scenegraph/util/qsgpainternode_p.h
src/declarative/scenegraph/util/qsgtextureprovider.cpp
src/declarative/util/qdeclarativepath_p.h
src/imports/testlib/main.cpp
src/plugins/qmltooling/qmldbg_inspector/abstractviewinspector.h
src/plugins/qmltooling/qmldbg_inspector/qdeclarativeinspectorplugin.cpp
src/plugins/qmltooling/qmldbg_inspector/sghighlight.cpp
src/plugins/qmltooling/qmldbg_inspector/sghighlight.h
src/plugins/qmltooling/qmldbg_inspector/sgselectiontool.cpp
src/plugins/qmltooling/qmldbg_inspector/sgselectiontool.h
src/plugins/qmltooling/qmldbg_inspector/sgviewinspector.cpp
src/plugins/qmltooling/qmldbg_inspector/sgviewinspector.h
src/qmltest/quicktest.cpp
src/qmltest/quicktestevent.cpp
tests/auto/declarative/debugger/qdeclarativeenginedebug/tst_qdeclarativeenginedebug.cpp
tests/auto/declarative/declarative.pro
tests/auto/declarative/examples/tst_examples.cpp
tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp
tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp
tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp
tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp
tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp
tests/auto/declarative/qdeclarativeconnection/tst_qdeclarativeconnection.cpp
tests/auto/declarative/qdeclarativeimageprovider/tst_qdeclarativeimageprovider.cpp
tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
tests/auto/declarative/qdeclarativepropertymap/tst_qdeclarativepropertymap.cpp
tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp
tests/auto/declarative/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp
tests/auto/declarative/qdeclarativesqldatabase/tst_qdeclarativesqldatabase.cpp
tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp
tests/auto/declarative/qdeclarativetimer/tst_qdeclarativetimer.cpp
tests/auto/declarative/qmlmin/tst_qmlmin.cpp
tests/auto/declarative/qquickanimatedimage/data/colors.gif [moved from tests/auto/declarative/qsganimatedimage/data/colors.gif with 100% similarity]
tests/auto/declarative/qquickanimatedimage/data/colors.qml [moved from tests/auto/declarative/qsganimatedimage/data/colors.qml with 100% similarity]
tests/auto/declarative/qquickanimatedimage/data/hearts.gif [moved from tests/auto/declarative/qsganimatedimage/data/hearts.gif with 100% similarity]
tests/auto/declarative/qquickanimatedimage/data/hearts.qml [moved from tests/auto/declarative/qsganimatedimage/data/hearts.qml with 100% similarity]
tests/auto/declarative/qquickanimatedimage/data/qmldir [moved from tests/auto/declarative/qsganimatedimage/data/qmldir with 100% similarity]
tests/auto/declarative/qquickanimatedimage/data/qtbug-16520.qml [moved from tests/auto/declarative/qsganimatedimage/data/qtbug-16520.qml with 100% similarity]
tests/auto/declarative/qquickanimatedimage/data/stickman.gif [moved from tests/auto/declarative/qsganimatedimage/data/stickman.gif with 100% similarity]
tests/auto/declarative/qquickanimatedimage/data/stickman.qml [moved from tests/auto/declarative/qsganimatedimage/data/stickman.qml with 100% similarity]
tests/auto/declarative/qquickanimatedimage/data/stickmanerror1.qml [moved from tests/auto/declarative/qsganimatedimage/data/stickmanerror1.qml with 100% similarity]
tests/auto/declarative/qquickanimatedimage/data/stickmanpause.qml [moved from tests/auto/declarative/qsganimatedimage/data/stickmanpause.qml with 100% similarity]
tests/auto/declarative/qquickanimatedimage/data/stickmanscaled.qml [moved from tests/auto/declarative/qsganimatedimage/data/stickmanscaled.qml with 100% similarity]
tests/auto/declarative/qquickanimatedimage/data/stickmanstopped.qml [moved from tests/auto/declarative/qsganimatedimage/data/stickmanstopped.qml with 100% similarity]
tests/auto/declarative/qquickanimatedimage/qquickanimatedimage.pro [new file with mode: 0644]
tests/auto/declarative/qquickanimatedimage/tst_qquickanimatedimage.cpp [new file with mode: 0644]
tests/auto/declarative/qquickborderimage/data/colors-mirror.png [moved from tests/auto/declarative/qsgborderimage/data/colors-mirror.png with 100% similarity]
tests/auto/declarative/qquickborderimage/data/colors-round-quotes.sci [moved from tests/auto/declarative/qsgborderimage/data/colors-round-quotes.sci with 100% similarity]
tests/auto/declarative/qquickborderimage/data/colors-round-remote.sci [moved from tests/auto/declarative/qsgborderimage/data/colors-round-remote.sci with 100% similarity]
tests/auto/declarative/qquickborderimage/data/colors-round.sci [moved from tests/auto/declarative/qsgborderimage/data/colors-round.sci with 100% similarity]
tests/auto/declarative/qquickborderimage/data/colors.png [moved from tests/auto/declarative/qsgborderimage/data/colors.png with 100% similarity]
tests/auto/declarative/qquickborderimage/data/heart200.png [moved from tests/auto/declarative/qsgborderimage/data/heart200.png with 100% similarity]
tests/auto/declarative/qquickborderimage/data/invalid.sci [moved from tests/auto/declarative/qsgborderimage/data/invalid.sci with 100% similarity]
tests/auto/declarative/qquickborderimage/data/mirror.qml [moved from tests/auto/declarative/qsgborderimage/data/mirror.qml with 100% similarity]
tests/auto/declarative/qquickborderimage/qquickborderimage.pro [new file with mode: 0644]
tests/auto/declarative/qquickborderimage/tst_qquickborderimage.cpp [new file with mode: 0644]
tests/auto/declarative/qquickcanvas/qquickcanvas.pro [new file with mode: 0644]
tests/auto/declarative/qquickcanvas/tst_qquickcanvas.cpp [new file with mode: 0644]
tests/auto/declarative/qquickcanvasitem/data/anim-gr.gif [moved from tests/auto/declarative/qsgcanvasitem/data/anim-gr.gif with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/anim-gr.png [moved from tests/auto/declarative/qsgcanvasitem/data/anim-gr.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/anim-poster-gr.png [moved from tests/auto/declarative/qsgcanvasitem/data/anim-poster-gr.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/background.png [moved from tests/auto/declarative/qsgcanvasitem/data/background.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/broken.png [moved from tests/auto/declarative/qsgcanvasitem/data/broken.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/ggrr-256x256.png [moved from tests/auto/declarative/qsgcanvasitem/data/ggrr-256x256.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/green-16x16.png [moved from tests/auto/declarative/qsgcanvasitem/data/green-16x16.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/green-1x1.png [moved from tests/auto/declarative/qsgcanvasitem/data/green-1x1.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/green-256x256.png [moved from tests/auto/declarative/qsgcanvasitem/data/green-256x256.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/green-2x2.png [moved from tests/auto/declarative/qsgcanvasitem/data/green-2x2.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/green.png [moved from tests/auto/declarative/qsgcanvasitem/data/green.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/grgr-256x256.png [moved from tests/auto/declarative/qsgcanvasitem/data/grgr-256x256.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/red-16x16.png [moved from tests/auto/declarative/qsgcanvasitem/data/red-16x16.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/red.png [moved from tests/auto/declarative/qsgcanvasitem/data/red.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/redtransparent.png [moved from tests/auto/declarative/qsgcanvasitem/data/redtransparent.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/rgrg-256x256.png [moved from tests/auto/declarative/qsgcanvasitem/data/rgrg-256x256.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/rrgg-256x256.png [moved from tests/auto/declarative/qsgcanvasitem/data/rrgg-256x256.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/testhelper.js [moved from tests/auto/declarative/qsgcanvasitem/data/testhelper.js with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/transparent.png [moved from tests/auto/declarative/qsgcanvasitem/data/transparent.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/transparent50.png [moved from tests/auto/declarative/qsgcanvasitem/data/transparent50.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/tst_arc.qml [moved from tests/auto/declarative/qsgcanvasitem/data/tst_arc.qml with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/tst_arcto.qml [moved from tests/auto/declarative/qsgcanvasitem/data/tst_arcto.qml with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/tst_canvas.qml [moved from tests/auto/declarative/qsgcanvasitem/data/tst_canvas.qml with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/tst_composite.qml [moved from tests/auto/declarative/qsgcanvasitem/data/tst_composite.qml with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/tst_drawimage.qml [moved from tests/auto/declarative/qsgcanvasitem/data/tst_drawimage.qml with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/tst_fillStyle.qml [moved from tests/auto/declarative/qsgcanvasitem/data/tst_fillStyle.qml with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/tst_fillrect.qml [moved from tests/auto/declarative/qsgcanvasitem/data/tst_fillrect.qml with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/tst_gradient.qml [moved from tests/auto/declarative/qsgcanvasitem/data/tst_gradient.qml with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/tst_line.qml [moved from tests/auto/declarative/qsgcanvasitem/data/tst_line.qml with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/tst_path.qml [moved from tests/auto/declarative/qsgcanvasitem/data/tst_path.qml with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/tst_pattern.qml [moved from tests/auto/declarative/qsgcanvasitem/data/tst_pattern.qml with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/tst_pixel.qml [moved from tests/auto/declarative/qsgcanvasitem/data/tst_pixel.qml with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/tst_shadow.qml [moved from tests/auto/declarative/qsgcanvasitem/data/tst_shadow.qml with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/tst_state.qml [moved from tests/auto/declarative/qsgcanvasitem/data/tst_state.qml with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/tst_strokeStyle.qml [moved from tests/auto/declarative/qsgcanvasitem/data/tst_strokeStyle.qml with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/tst_text.qml [moved from tests/auto/declarative/qsgcanvasitem/data/tst_text.qml with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/tst_transform.qml [moved from tests/auto/declarative/qsgcanvasitem/data/tst_transform.qml with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/yellow.png [moved from tests/auto/declarative/qsgcanvasitem/data/yellow.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/data/yellow75.png [moved from tests/auto/declarative/qsgcanvasitem/data/yellow75.png with 100% similarity]
tests/auto/declarative/qquickcanvasitem/qquickcanvasitem.pro [new file with mode: 0644]
tests/auto/declarative/qquickcanvasitem/tst_qquickcanvasitem.cpp [new file with mode: 0644]
tests/auto/declarative/qquickdrag/qquickdrag.pro [new file with mode: 0644]
tests/auto/declarative/qquickdrag/tst_qquickdrag.cpp [new file with mode: 0644]
tests/auto/declarative/qquickdroparea/qquickdroparea.pro [new file with mode: 0644]
tests/auto/declarative/qquickdroparea/tst_qquickdroparea.cpp [new file with mode: 0644]
tests/auto/declarative/qquickflickable/data/disabled.qml [moved from tests/auto/declarative/qsgflickable/data/disabled.qml with 100% similarity]
tests/auto/declarative/qquickflickable/data/flickable01.qml [moved from tests/auto/declarative/qsgflickable/data/flickable01.qml with 100% similarity]
tests/auto/declarative/qquickflickable/data/flickable02.qml [moved from tests/auto/declarative/qsgflickable/data/flickable02.qml with 100% similarity]
tests/auto/declarative/qquickflickable/data/flickable03.qml [moved from tests/auto/declarative/qsgflickable/data/flickable03.qml with 100% similarity]
tests/auto/declarative/qquickflickable/data/flickable04.qml [moved from tests/auto/declarative/qsgflickable/data/flickable04.qml with 100% similarity]
tests/auto/declarative/qquickflickable/data/flickableqgraphicswidget.qml [moved from tests/auto/declarative/qsgflickable/data/flickableqgraphicswidget.qml with 100% similarity]
tests/auto/declarative/qquickflickable/data/margins.qml [moved from tests/auto/declarative/qsgflickable/data/margins.qml with 100% similarity]
tests/auto/declarative/qquickflickable/data/nestedPressDelay.qml [moved from tests/auto/declarative/qsgflickable/data/nestedPressDelay.qml with 100% similarity]
tests/auto/declarative/qquickflickable/data/resize.qml [moved from tests/auto/declarative/qsgflickable/data/resize.qml with 100% similarity]
tests/auto/declarative/qquickflickable/data/wheel.qml [moved from tests/auto/declarative/qsgflickable/data/wheel.qml with 100% similarity]
tests/auto/declarative/qquickflickable/qquickflickable.pro [new file with mode: 0644]
tests/auto/declarative/qquickflickable/tst_qquickflickable.cpp [new file with mode: 0644]
tests/auto/declarative/qquickflipable/data/crash.qml [moved from tests/auto/declarative/qsgflipable/data/crash.qml with 100% similarity]
tests/auto/declarative/qquickflipable/data/flipable-abort.qml [moved from tests/auto/declarative/qsgflipable/data/flipable-abort.qml with 100% similarity]
tests/auto/declarative/qquickflipable/data/test-flipable.qml [moved from tests/auto/declarative/qsgflipable/data/test-flipable.qml with 100% similarity]
tests/auto/declarative/qquickflipable/qquickflipable.pro [new file with mode: 0644]
tests/auto/declarative/qquickflipable/tst_qquickflipable.cpp [new file with mode: 0644]
tests/auto/declarative/qquickfocusscope/data/canvasFocus.qml [moved from tests/auto/declarative/qsgfocusscope/data/canvasFocus.qml with 100% similarity]
tests/auto/declarative/qquickfocusscope/data/chain.qml [moved from tests/auto/declarative/qsgfocusscope/data/chain.qml with 100% similarity]
tests/auto/declarative/qquickfocusscope/data/forceActiveFocus.qml [moved from tests/auto/declarative/qsgfocusscope/data/forceActiveFocus.qml with 100% similarity]
tests/auto/declarative/qquickfocusscope/data/forcefocus.qml [moved from tests/auto/declarative/qsgfocusscope/data/forcefocus.qml with 100% similarity]
tests/auto/declarative/qquickfocusscope/data/qtBug13380.qml [moved from tests/auto/declarative/qsgfocusscope/data/qtBug13380.qml with 100% similarity]
tests/auto/declarative/qquickfocusscope/data/signalEmission.qml [moved from tests/auto/declarative/qsgfocusscope/data/signalEmission.qml with 100% similarity]
tests/auto/declarative/qquickfocusscope/data/test.qml [moved from tests/auto/declarative/qsgfocusscope/data/test.qml with 100% similarity]
tests/auto/declarative/qquickfocusscope/data/test2.qml [moved from tests/auto/declarative/qsgfocusscope/data/test2.qml with 100% similarity]
tests/auto/declarative/qquickfocusscope/data/test3.qml [moved from tests/auto/declarative/qsgfocusscope/data/test3.qml with 100% similarity]
tests/auto/declarative/qquickfocusscope/data/test4.qml [moved from tests/auto/declarative/qsgfocusscope/data/test4.qml with 100% similarity]
tests/auto/declarative/qquickfocusscope/data/test5.qml [moved from tests/auto/declarative/qsgfocusscope/data/test5.qml with 100% similarity]
tests/auto/declarative/qquickfocusscope/qquickfocusscope.pro [new file with mode: 0644]
tests/auto/declarative/qquickfocusscope/tst_qquickfocusscope.cpp [new file with mode: 0644]
tests/auto/declarative/qquickgridview/data/ComponentView.qml [moved from tests/auto/declarative/qsggridview/data/ComponentView.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/attachedSignals.qml [moved from tests/auto/declarative/qsggridview/data/attachedSignals.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/creationContext.qml [moved from tests/auto/declarative/qsggridview/data/creationContext.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/displaygrid.qml [moved from tests/auto/declarative/qsggridview/data/displaygrid.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/footer.qml [moved from tests/auto/declarative/qsggridview/data/footer.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/gridview-enforcerange.qml [moved from tests/auto/declarative/qsggridview/data/gridview-enforcerange.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/gridview-initCurrent.qml [moved from tests/auto/declarative/qsggridview/data/gridview-initCurrent.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/gridview-noCurrent.qml [moved from tests/auto/declarative/qsggridview/data/gridview-noCurrent.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/gridview1.qml [moved from tests/auto/declarative/qsggridview/data/gridview1.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/gridview2.qml [moved from tests/auto/declarative/qsggridview/data/gridview2.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/gridview3.qml [moved from tests/auto/declarative/qsggridview/data/gridview3.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/gridview4.qml [moved from tests/auto/declarative/qsggridview/data/gridview4.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/header.qml [moved from tests/auto/declarative/qsggridview/data/header.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/manual-highlight.qml [moved from tests/auto/declarative/qsggridview/data/manual-highlight.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/margins.qml [moved from tests/auto/declarative/qsggridview/data/margins.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/mirroring.qml [moved from tests/auto/declarative/qsggridview/data/mirroring.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/propertychangestest.qml [moved from tests/auto/declarative/qsggridview/data/propertychangestest.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/resizeview.qml [moved from tests/auto/declarative/qsggridview/data/resizeview.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/setindex.qml [moved from tests/auto/declarative/qsggridview/data/setindex.qml with 100% similarity]
tests/auto/declarative/qquickgridview/data/snapToRow.qml [moved from tests/auto/declarative/qsggridview/data/snapToRow.qml with 100% similarity]
tests/auto/declarative/qquickgridview/qquickgridview.pro [new file with mode: 0644]
tests/auto/declarative/qquickgridview/tst_qquickgridview.cpp [new file with mode: 0644]
tests/auto/declarative/qquickimage/data/aspectratio.qml [moved from tests/auto/declarative/qsgimage/data/aspectratio.qml with 100% similarity]
tests/auto/declarative/qquickimage/data/big.jpeg [moved from tests/auto/declarative/qsgimage/data/big.jpeg with 100% similarity]
tests/auto/declarative/qquickimage/data/big256.png [moved from tests/auto/declarative/qsgimage/data/big256.png with 100% similarity]
tests/auto/declarative/qquickimage/data/colors.png [moved from tests/auto/declarative/qsgimage/data/colors.png with 100% similarity]
tests/auto/declarative/qquickimage/data/colors1.png [moved from tests/auto/declarative/qsgimage/data/colors1.png with 100% similarity]
tests/auto/declarative/qquickimage/data/green.png [moved from tests/auto/declarative/qsgimage/data/green.png with 100% similarity]
tests/auto/declarative/qquickimage/data/heart-win32.png [moved from tests/auto/declarative/qsgimage/data/heart-win32.png with 100% similarity]
tests/auto/declarative/qquickimage/data/heart.png [moved from tests/auto/declarative/qsgimage/data/heart.png with 100% similarity]
tests/auto/declarative/qquickimage/data/heart.svg [moved from tests/auto/declarative/qsgimage/data/heart.svg with 100% similarity]
tests/auto/declarative/qquickimage/data/heart200-win32.png [moved from tests/auto/declarative/qsgimage/data/heart200-win32.png with 100% similarity]
tests/auto/declarative/qquickimage/data/heart200.png [moved from tests/auto/declarative/qsgimage/data/heart200.png with 100% similarity]
tests/auto/declarative/qquickimage/data/htiling.qml [moved from tests/auto/declarative/qsgimage/data/htiling.qml with 100% similarity]
tests/auto/declarative/qquickimage/data/mirror.qml [moved from tests/auto/declarative/qsgimage/data/mirror.qml with 100% similarity]
tests/auto/declarative/qquickimage/data/nullpixmap.qml [moved from tests/auto/declarative/qsgimage/data/nullpixmap.qml with 100% similarity]
tests/auto/declarative/qquickimage/data/pattern.png [moved from tests/auto/declarative/qsgimage/data/pattern.png with 100% similarity]
tests/auto/declarative/qquickimage/data/qtbug_16389.qml [moved from tests/auto/declarative/qsgimage/data/qtbug_16389.qml with 100% similarity]
tests/auto/declarative/qquickimage/data/rect.png [moved from tests/auto/declarative/qsgimage/data/rect.png with 100% similarity]
tests/auto/declarative/qquickimage/data/vtiling.qml [moved from tests/auto/declarative/qsgimage/data/vtiling.qml with 100% similarity]
tests/auto/declarative/qquickimage/qquickimage.pro [new file with mode: 0644]
tests/auto/declarative/qquickimage/tst_qquickimage.cpp [new file with mode: 0644]
tests/auto/declarative/qquickitem/qquickitem.pro [new file with mode: 0644]
tests/auto/declarative/qquickitem/tst_qquickitem.cpp [new file with mode: 0644]
tests/auto/declarative/qquickitem2/data/childrenProperty.qml [moved from tests/auto/declarative/qsgitem2/data/childrenProperty.qml with 100% similarity]
tests/auto/declarative/qquickitem2/data/childrenRect.qml [moved from tests/auto/declarative/qsgitem2/data/childrenRect.qml with 100% similarity]
tests/auto/declarative/qquickitem2/data/childrenRectBug.qml [moved from tests/auto/declarative/qsgitem2/data/childrenRectBug.qml with 100% similarity]
tests/auto/declarative/qquickitem2/data/childrenRectBug2.qml [moved from tests/auto/declarative/qsgitem2/data/childrenRectBug2.qml with 100% similarity]
tests/auto/declarative/qquickitem2/data/childrenRectBug3.qml [moved from tests/auto/declarative/qsgitem2/data/childrenRectBug3.qml with 100% similarity]
tests/auto/declarative/qquickitem2/data/implicitsize.qml [moved from tests/auto/declarative/qsgitem2/data/implicitsize.qml with 100% similarity]
tests/auto/declarative/qquickitem2/data/keynavigationtest.qml [moved from tests/auto/declarative/qsgitem2/data/keynavigationtest.qml with 100% similarity]
tests/auto/declarative/qquickitem2/data/keynavigationtest_implicit.qml [moved from tests/auto/declarative/qsgitem2/data/keynavigationtest_implicit.qml with 100% similarity]
tests/auto/declarative/qquickitem2/data/keyspriority.qml [moved from tests/auto/declarative/qsgitem2/data/keyspriority.qml with 100% similarity]
tests/auto/declarative/qquickitem2/data/keystest.qml [moved from tests/auto/declarative/qsgitem2/data/keystest.qml with 100% similarity]
tests/auto/declarative/qquickitem2/data/layoutmirroring.qml [moved from tests/auto/declarative/qsgitem2/data/layoutmirroring.qml with 100% similarity]
tests/auto/declarative/qquickitem2/data/mapCoordinates.qml [moved from tests/auto/declarative/qsgitem2/data/mapCoordinates.qml with 100% similarity]
tests/auto/declarative/qquickitem2/data/propertychanges.qml [moved from tests/auto/declarative/qsgitem2/data/propertychanges.qml with 100% similarity]
tests/auto/declarative/qquickitem2/data/qtbug_16871.qml [moved from tests/auto/declarative/qsgitem2/data/qtbug_16871.qml with 100% similarity]
tests/auto/declarative/qquickitem2/data/resourcesProperty.qml [moved from tests/auto/declarative/qsgitem2/data/resourcesProperty.qml with 100% similarity]
tests/auto/declarative/qquickitem2/data/transformCrash.qml [moved from tests/auto/declarative/qsgitem2/data/transformCrash.qml with 100% similarity]
tests/auto/declarative/qquickitem2/qquickitem2.pro [new file with mode: 0644]
tests/auto/declarative/qquickitem2/tst_qquickitem.cpp [new file with mode: 0644]
tests/auto/declarative/qquicklistview/data/ComponentView.qml [moved from tests/auto/declarative/qsglistview/data/ComponentView.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/attachedSignals.qml [moved from tests/auto/declarative/qsglistview/data/attachedSignals.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/creationContext.qml [moved from tests/auto/declarative/qsglistview/data/creationContext.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/displaylist.qml [moved from tests/auto/declarative/qsglistview/data/displaylist.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/fillModelOnComponentCompleted.qml [moved from tests/auto/declarative/qsglistview/data/fillModelOnComponentCompleted.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/footer.qml [moved from tests/auto/declarative/qsglistview/data/footer.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/header.qml [moved from tests/auto/declarative/qsglistview/data/header.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/headerfooter.qml [moved from tests/auto/declarative/qsglistview/data/headerfooter.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/itemlist.qml [moved from tests/auto/declarative/qsglistview/data/itemlist.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/listview-enforcerange-nohighlight.qml [moved from tests/auto/declarative/qsglistview/data/listview-enforcerange-nohighlight.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/listview-enforcerange.qml [moved from tests/auto/declarative/qsglistview/data/listview-enforcerange.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/listview-initCurrent.qml [moved from tests/auto/declarative/qsglistview/data/listview-initCurrent.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/listview-noCurrent.qml [moved from tests/auto/declarative/qsglistview/data/listview-noCurrent.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/listview-sections.qml [moved from tests/auto/declarative/qsglistview/data/listview-sections.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/listview-sections_delegate.qml [moved from tests/auto/declarative/qsglistview/data/listview-sections_delegate.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/listviewtest.qml [moved from tests/auto/declarative/qsglistview/data/listviewtest.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/manual-highlight.qml [moved from tests/auto/declarative/qsglistview/data/manual-highlight.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/margins.qml [moved from tests/auto/declarative/qsglistview/data/margins.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/propertychangestest.qml [moved from tests/auto/declarative/qsglistview/data/propertychangestest.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/qtbug-21742.qml [moved from tests/auto/declarative/qsglistview/data/qtbug-21742.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/qtbug14821.qml [moved from tests/auto/declarative/qsglistview/data/qtbug14821.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/qtbug16037.qml [moved from tests/auto/declarative/qsglistview/data/qtbug16037.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/resizeview.qml [moved from tests/auto/declarative/qsglistview/data/resizeview.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/rightToLeft.qml [moved from tests/auto/declarative/qsglistview/data/rightToLeft.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/sizelessthan1.qml [moved from tests/auto/declarative/qsglistview/data/sizelessthan1.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/snapToItem.qml [moved from tests/auto/declarative/qsglistview/data/snapToItem.qml with 100% similarity]
tests/auto/declarative/qquicklistview/data/strictlyenforcerange.qml [moved from tests/auto/declarative/qsglistview/data/strictlyenforcerange.qml with 100% similarity]
tests/auto/declarative/qquicklistview/incrementalmodel.cpp [moved from tests/auto/declarative/qsglistview/incrementalmodel.cpp with 100% similarity]
tests/auto/declarative/qquicklistview/incrementalmodel.h [moved from tests/auto/declarative/qsglistview/incrementalmodel.h with 100% similarity]
tests/auto/declarative/qquicklistview/qquicklistview.pro [new file with mode: 0644]
tests/auto/declarative/qquicklistview/tst_qquicklistview.cpp [new file with mode: 0644]
tests/auto/declarative/qquickloader/data/ActiveComponent.qml [moved from tests/auto/declarative/qsgloader/data/ActiveComponent.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/AnchoredLoader.qml [moved from tests/auto/declarative/qsgloader/data/AnchoredLoader.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/BigComponent.qml [moved from tests/auto/declarative/qsgloader/data/BigComponent.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/BlueRect.qml [moved from tests/auto/declarative/qsgloader/data/BlueRect.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/CreationContextLoader.qml [moved from tests/auto/declarative/qsgloader/data/CreationContextLoader.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/GraphicsWidget250x250.qml [moved from tests/auto/declarative/qsgloader/data/GraphicsWidget250x250.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/GreenRect.qml [moved from tests/auto/declarative/qsgloader/data/GreenRect.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/InitialPropertyValuesComponent.qml [moved from tests/auto/declarative/qsgloader/data/InitialPropertyValuesComponent.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/InvalidSourceComponent.qml [moved from tests/auto/declarative/qsgloader/data/InvalidSourceComponent.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/NoResize.qml [moved from tests/auto/declarative/qsgloader/data/NoResize.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/NoResizeGraphicsWidget.qml [moved from tests/auto/declarative/qsgloader/data/NoResizeGraphicsWidget.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/QTBUG_16928.qml [moved from tests/auto/declarative/qsgloader/data/QTBUG_16928.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/QTBUG_17114.qml [moved from tests/auto/declarative/qsgloader/data/QTBUG_17114.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/Rect120x60.qml [moved from tests/auto/declarative/qsgloader/data/Rect120x60.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/SetSourceComponent.qml [moved from tests/auto/declarative/qsgloader/data/SetSourceComponent.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/SizeGraphicsWidgetToLoader.qml [moved from tests/auto/declarative/qsgloader/data/SizeGraphicsWidgetToLoader.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/SizeLoaderToGraphicsWidget.qml [moved from tests/auto/declarative/qsgloader/data/SizeLoaderToGraphicsWidget.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/SizeToItem.qml [moved from tests/auto/declarative/qsgloader/data/SizeToItem.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/SizeToLoader.qml [moved from tests/auto/declarative/qsgloader/data/SizeToLoader.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/VmeError.qml [moved from tests/auto/declarative/qsgloader/data/VmeError.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/active.1.qml [moved from tests/auto/declarative/qsgloader/data/active.1.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/active.2.qml [moved from tests/auto/declarative/qsgloader/data/active.2.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/active.3.qml [moved from tests/auto/declarative/qsgloader/data/active.3.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/active.4.qml [moved from tests/auto/declarative/qsgloader/data/active.4.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/active.5.qml [moved from tests/auto/declarative/qsgloader/data/active.5.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/active.6.qml [moved from tests/auto/declarative/qsgloader/data/active.6.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/active.7.qml [moved from tests/auto/declarative/qsgloader/data/active.7.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/active.8.qml [moved from tests/auto/declarative/qsgloader/data/active.8.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/asynchronous.qml [moved from tests/auto/declarative/qsgloader/data/asynchronous.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/crash.qml [moved from tests/auto/declarative/qsgloader/data/crash.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/creationContext.qml [moved from tests/auto/declarative/qsgloader/data/creationContext.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/differentorigin.qml [moved from tests/auto/declarative/qsgloader/data/differentorigin.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/implicitSize.qml [moved from tests/auto/declarative/qsgloader/data/implicitSize.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/initialPropertyValues.1.qml [moved from tests/auto/declarative/qsgloader/data/initialPropertyValues.1.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/initialPropertyValues.2.qml [moved from tests/auto/declarative/qsgloader/data/initialPropertyValues.2.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/initialPropertyValues.3.qml [moved from tests/auto/declarative/qsgloader/data/initialPropertyValues.3.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/initialPropertyValues.4.qml [moved from tests/auto/declarative/qsgloader/data/initialPropertyValues.4.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/initialPropertyValues.5.qml [moved from tests/auto/declarative/qsgloader/data/initialPropertyValues.5.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/initialPropertyValues.6.qml [moved from tests/auto/declarative/qsgloader/data/initialPropertyValues.6.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/initialPropertyValues.7.qml [moved from tests/auto/declarative/qsgloader/data/initialPropertyValues.7.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/initialPropertyValues.8.qml [moved from tests/auto/declarative/qsgloader/data/initialPropertyValues.8.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/initialPropertyValues.binding.qml [moved from tests/auto/declarative/qsgloader/data/initialPropertyValues.binding.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/initialPropertyValues.error.1.qml [moved from tests/auto/declarative/qsgloader/data/initialPropertyValues.error.1.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/initialPropertyValues.error.2.qml [moved from tests/auto/declarative/qsgloader/data/initialPropertyValues.error.2.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/initialPropertyValues.error.3.qml [moved from tests/auto/declarative/qsgloader/data/initialPropertyValues.error.3.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/initialPropertyValues.error.4.qml [moved from tests/auto/declarative/qsgloader/data/initialPropertyValues.error.4.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/nonItem.qml [moved from tests/auto/declarative/qsgloader/data/nonItem.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/qmldir [moved from tests/auto/declarative/qsgloader/data/qmldir with 100% similarity]
tests/auto/declarative/qquickloader/data/sameorigin-load.qml [moved from tests/auto/declarative/qsgloader/data/sameorigin-load.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/sameorigin.qml [moved from tests/auto/declarative/qsgloader/data/sameorigin.qml with 100% similarity]
tests/auto/declarative/qquickloader/data/vmeErrors.qml [moved from tests/auto/declarative/qsgloader/data/vmeErrors.qml with 100% similarity]
tests/auto/declarative/qquickloader/qquickloader.pro [new file with mode: 0644]
tests/auto/declarative/qquickloader/tst_qquickloader.cpp [new file with mode: 0644]
tests/auto/declarative/qquickmousearea/data/clickThrough.qml [moved from tests/auto/declarative/qsgmousearea/data/clickThrough.qml with 100% similarity]
tests/auto/declarative/qquickmousearea/data/clickThrough2.qml [moved from tests/auto/declarative/qsgmousearea/data/clickThrough2.qml with 100% similarity]
tests/auto/declarative/qquickmousearea/data/clickandhold.qml [moved from tests/auto/declarative/qsgmousearea/data/clickandhold.qml with 100% similarity]
tests/auto/declarative/qquickmousearea/data/clicktwice.qml [moved from tests/auto/declarative/qsgmousearea/data/clicktwice.qml with 100% similarity]
tests/auto/declarative/qquickmousearea/data/doubleclick.qml [moved from tests/auto/declarative/qsgmousearea/data/doubleclick.qml with 100% similarity]
tests/auto/declarative/qquickmousearea/data/dragging.qml [moved from tests/auto/declarative/qsgmousearea/data/dragging.qml with 100% similarity]
tests/auto/declarative/qquickmousearea/data/dragproperties.qml [moved from tests/auto/declarative/qsgmousearea/data/dragproperties.qml with 100% similarity]
tests/auto/declarative/qquickmousearea/data/dragreset.qml [moved from tests/auto/declarative/qsgmousearea/data/dragreset.qml with 100% similarity]
tests/auto/declarative/qquickmousearea/data/hoverPosition.qml [moved from tests/auto/declarative/qsgmousearea/data/hoverPosition.qml with 100% similarity]
tests/auto/declarative/qquickmousearea/data/hoverPropagation.qml [moved from tests/auto/declarative/qsgmousearea/data/hoverPropagation.qml with 100% similarity]
tests/auto/declarative/qquickmousearea/data/noclickandhold.qml [moved from tests/auto/declarative/qsgmousearea/data/noclickandhold.qml with 100% similarity]
tests/auto/declarative/qquickmousearea/data/pressedCanceled.qml [moved from tests/auto/declarative/qsgmousearea/data/pressedCanceled.qml with 100% similarity]
tests/auto/declarative/qquickmousearea/data/pressedOrdering.qml [moved from tests/auto/declarative/qsgmousearea/data/pressedOrdering.qml with 100% similarity]
tests/auto/declarative/qquickmousearea/data/preventstealing.qml [moved from tests/auto/declarative/qsgmousearea/data/preventstealing.qml with 100% similarity]
tests/auto/declarative/qquickmousearea/data/rejectEvent.qml [moved from tests/auto/declarative/qsgmousearea/data/rejectEvent.qml with 100% similarity]
tests/auto/declarative/qquickmousearea/data/updateMousePosOnClick.qml [moved from tests/auto/declarative/qsgmousearea/data/updateMousePosOnClick.qml with 100% similarity]
tests/auto/declarative/qquickmousearea/data/updateMousePosOnResize.qml [moved from tests/auto/declarative/qsgmousearea/data/updateMousePosOnResize.qml with 100% similarity]
tests/auto/declarative/qquickmousearea/qquickmousearea.pro [new file with mode: 0644]
tests/auto/declarative/qquickmousearea/tst_qquickmousearea.cpp [new file with mode: 0644]
tests/auto/declarative/qquickpathview/data/ComponentView.qml [moved from tests/auto/declarative/qsgpathview/data/ComponentView.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/closedPath.qml [moved from tests/auto/declarative/qsgpathview/data/closedPath.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/creationContext.qml [moved from tests/auto/declarative/qsgpathview/data/creationContext.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/datamodel.qml [moved from tests/auto/declarative/qsgpathview/data/datamodel.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/displaypath.qml [moved from tests/auto/declarative/qsgpathview/data/displaypath.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/dragpath.qml [moved from tests/auto/declarative/qsgpathview/data/dragpath.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/emptymodel.qml [moved from tests/auto/declarative/qsgpathview/data/emptymodel.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/missingPercent.qml [moved from tests/auto/declarative/qsgpathview/data/missingPercent.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/openPath.qml [moved from tests/auto/declarative/qsgpathview/data/openPath.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/pathUpdate.qml [moved from tests/auto/declarative/qsgpathview/data/pathUpdate.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/pathUpdateOnStartChanged.qml [moved from tests/auto/declarative/qsgpathview/data/pathUpdateOnStartChanged.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/pathtest.qml [moved from tests/auto/declarative/qsgpathview/data/pathtest.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/pathview0.qml [moved from tests/auto/declarative/qsgpathview/data/pathview0.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/pathview1.qml [moved from tests/auto/declarative/qsgpathview/data/pathview1.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/pathview2.qml [moved from tests/auto/declarative/qsgpathview/data/pathview2.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/pathview3.qml [moved from tests/auto/declarative/qsgpathview/data/pathview3.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/pathview_package.qml [moved from tests/auto/declarative/qsgpathview/data/pathview_package.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/propertychanges.qml [moved from tests/auto/declarative/qsgpathview/data/propertychanges.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/treemodel.qml [moved from tests/auto/declarative/qsgpathview/data/treemodel.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/undefinedpath.qml [moved from tests/auto/declarative/qsgpathview/data/undefinedpath.qml with 100% similarity]
tests/auto/declarative/qquickpathview/data/vdm.qml [moved from tests/auto/declarative/qsgpathview/data/vdm.qml with 100% similarity]
tests/auto/declarative/qquickpathview/qquickpathview.pro [new file with mode: 0644]
tests/auto/declarative/qquickpathview/tst_qquickpathview.cpp [new file with mode: 0644]
tests/auto/declarative/qquickpincharea/data/pinchproperties.qml [moved from tests/auto/declarative/qsgpincharea/data/pinchproperties.qml with 100% similarity]
tests/auto/declarative/qquickpincharea/qquickpincharea.pro [new file with mode: 0644]
tests/auto/declarative/qquickpincharea/tst_qquickpincharea.cpp [new file with mode: 0644]
tests/auto/declarative/qquickpositioners/data/allInvisible.qml [moved from tests/auto/declarative/qsgpositioners/data/allInvisible.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/attachedproperties-column.qml [moved from tests/auto/declarative/qsgpositioners/data/attachedproperties-column.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/attachedproperties-dynamic.qml [moved from tests/auto/declarative/qsgpositioners/data/attachedproperties-dynamic.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/attachedproperties-flow.qml [moved from tests/auto/declarative/qsgpositioners/data/attachedproperties-flow.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/attachedproperties-grid.qml [moved from tests/auto/declarative/qsgpositioners/data/attachedproperties-grid.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/attachedproperties-row.qml [moved from tests/auto/declarative/qsgpositioners/data/attachedproperties-row.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/flow-testimplicitsize.qml [moved from tests/auto/declarative/qsgpositioners/data/flow-testimplicitsize.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/flowtest-toptobottom.qml [moved from tests/auto/declarative/qsgpositioners/data/flowtest-toptobottom.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/flowtest.qml [moved from tests/auto/declarative/qsgpositioners/data/flowtest.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/grid-animated.qml [moved from tests/auto/declarative/qsgpositioners/data/grid-animated.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/grid-row-column-spacing.qml [moved from tests/auto/declarative/qsgpositioners/data/grid-row-column-spacing.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/grid-spacing.qml [moved from tests/auto/declarative/qsgpositioners/data/grid-spacing.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/grid-toptobottom.qml [moved from tests/auto/declarative/qsgpositioners/data/grid-toptobottom.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/gridtest.qml [moved from tests/auto/declarative/qsgpositioners/data/gridtest.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/gridzerocolumns.qml [moved from tests/auto/declarative/qsgpositioners/data/gridzerocolumns.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/horizontal-animated-disabled.qml [moved from tests/auto/declarative/qsgpositioners/data/horizontal-animated-disabled.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/horizontal-animated.qml [moved from tests/auto/declarative/qsgpositioners/data/horizontal-animated.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/horizontal-spacing.qml [moved from tests/auto/declarative/qsgpositioners/data/horizontal-spacing.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/horizontal.qml [moved from tests/auto/declarative/qsgpositioners/data/horizontal.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/propertychangestest.qml [moved from tests/auto/declarative/qsgpositioners/data/propertychangestest.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/rectangleComponent.qml [moved from tests/auto/declarative/qsgpositioners/data/rectangleComponent.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/repeatertest.qml [moved from tests/auto/declarative/qsgpositioners/data/repeatertest.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/vertical-animated.qml [moved from tests/auto/declarative/qsgpositioners/data/vertical-animated.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/vertical-spacing.qml [moved from tests/auto/declarative/qsgpositioners/data/vertical-spacing.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/data/vertical.qml [moved from tests/auto/declarative/qsgpositioners/data/vertical.qml with 100% similarity]
tests/auto/declarative/qquickpositioners/qquickpositioners.pro [new file with mode: 0644]
tests/auto/declarative/qquickpositioners/tst_qquickpositioners.cpp [new file with mode: 0644]
tests/auto/declarative/qquickrepeater/data/intmodel.qml [moved from tests/auto/declarative/qsgrepeater/data/intmodel.qml with 100% similarity]
tests/auto/declarative/qquickrepeater/data/itemlist.qml [moved from tests/auto/declarative/qsgrepeater/data/itemlist.qml with 100% similarity]
tests/auto/declarative/qquickrepeater/data/modelChanged.qml [moved from tests/auto/declarative/qsgrepeater/data/modelChanged.qml with 100% similarity]
tests/auto/declarative/qquickrepeater/data/objlist.qml [moved from tests/auto/declarative/qsgrepeater/data/objlist.qml with 100% similarity]
tests/auto/declarative/qquickrepeater/data/properties.qml [moved from tests/auto/declarative/qsgrepeater/data/properties.qml with 100% similarity]
tests/auto/declarative/qquickrepeater/data/repeater1.qml [moved from tests/auto/declarative/qsgrepeater/data/repeater1.qml with 100% similarity]
tests/auto/declarative/qquickrepeater/data/repeater2.qml [moved from tests/auto/declarative/qsgrepeater/data/repeater2.qml with 100% similarity]
tests/auto/declarative/qquickrepeater/qquickrepeater.pro [new file with mode: 0644]
tests/auto/declarative/qquickrepeater/tst_qquickrepeater.cpp [new file with mode: 0644]
tests/auto/declarative/qquicktext/data/alignments.qml [moved from tests/auto/declarative/qsgtext/data/alignments.qml with 100% similarity]
tests/auto/declarative/qquicktext/data/alignments_cb.png [moved from tests/auto/declarative/qsgtext/data/alignments_cb.png with 100% similarity]
tests/auto/declarative/qquicktext/data/alignments_cc.png [moved from tests/auto/declarative/qsgtext/data/alignments_cc.png with 100% similarity]
tests/auto/declarative/qquicktext/data/alignments_ct.png [moved from tests/auto/declarative/qsgtext/data/alignments_ct.png with 100% similarity]
tests/auto/declarative/qquicktext/data/alignments_lb.png [moved from tests/auto/declarative/qsgtext/data/alignments_lb.png with 100% similarity]
tests/auto/declarative/qquicktext/data/alignments_lc.png [moved from tests/auto/declarative/qsgtext/data/alignments_lc.png with 100% similarity]
tests/auto/declarative/qquicktext/data/alignments_lt.png [moved from tests/auto/declarative/qsgtext/data/alignments_lt.png with 100% similarity]
tests/auto/declarative/qquicktext/data/alignments_rb.png [moved from tests/auto/declarative/qsgtext/data/alignments_rb.png with 100% similarity]
tests/auto/declarative/qquicktext/data/alignments_rc.png [moved from tests/auto/declarative/qsgtext/data/alignments_rc.png with 100% similarity]
tests/auto/declarative/qquicktext/data/alignments_rt.png [moved from tests/auto/declarative/qsgtext/data/alignments_rt.png with 100% similarity]
tests/auto/declarative/qquicktext/data/embeddedImagesLocal.qml [moved from tests/auto/declarative/qsgtext/data/embeddedImagesLocal.qml with 100% similarity]
tests/auto/declarative/qquicktext/data/embeddedImagesLocalError.qml [moved from tests/auto/declarative/qsgtext/data/embeddedImagesLocalError.qml with 100% similarity]
tests/auto/declarative/qquicktext/data/embeddedImagesRemote.qml [moved from tests/auto/declarative/qsgtext/data/embeddedImagesRemote.qml with 100% similarity]
tests/auto/declarative/qquicktext/data/embeddedImagesRemoteError.qml [moved from tests/auto/declarative/qsgtext/data/embeddedImagesRemoteError.qml with 100% similarity]
tests/auto/declarative/qquicktext/data/horizontalAlignment_RightToLeft.qml [moved from tests/auto/declarative/qsgtext/data/horizontalAlignment_RightToLeft.qml with 100% similarity]
tests/auto/declarative/qquicktext/data/http/exists.png [moved from tests/auto/declarative/qsgtext/data/http/exists.png with 100% similarity]
tests/auto/declarative/qquicktext/data/lineCount.qml [moved from tests/auto/declarative/qsgtext/data/lineCount.qml with 100% similarity]
tests/auto/declarative/qquicktext/data/lineHeight.qml [moved from tests/auto/declarative/qsgtext/data/lineHeight.qml with 100% similarity]
tests/auto/declarative/qquicktext/data/lineLayout.qml [moved from tests/auto/declarative/qsgtext/data/lineLayout.qml with 100% similarity]
tests/auto/declarative/qquicktext/data/qtbug_14734.qml [moved from tests/auto/declarative/qsgtext/data/qtbug_14734.qml with 100% similarity]
tests/auto/declarative/qquicktext/data/rotated.qml [moved from tests/auto/declarative/qsgtext/data/rotated.qml with 100% similarity]
tests/auto/declarative/qquicktext/qquicktext.pro [new file with mode: 0644]
tests/auto/declarative/qquicktext/tst_qquicktext.cpp [new file with mode: 0644]
tests/auto/declarative/qquicktextedit/data/CursorRect.qml [moved from tests/auto/declarative/qsgtextedit/data/CursorRect.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/alignments.qml [moved from tests/auto/declarative/qsgtextedit/data/alignments.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/alignments_cb.png [moved from tests/auto/declarative/qsgtextedit/data/alignments_cb.png with 100% similarity]
tests/auto/declarative/qquicktextedit/data/alignments_cc.png [moved from tests/auto/declarative/qsgtextedit/data/alignments_cc.png with 100% similarity]
tests/auto/declarative/qquicktextedit/data/alignments_ct.png [moved from tests/auto/declarative/qsgtextedit/data/alignments_ct.png with 100% similarity]
tests/auto/declarative/qquicktextedit/data/alignments_lb.png [moved from tests/auto/declarative/qsgtextedit/data/alignments_lb.png with 100% similarity]
tests/auto/declarative/qquicktextedit/data/alignments_lc.png [moved from tests/auto/declarative/qsgtextedit/data/alignments_lc.png with 100% similarity]
tests/auto/declarative/qquicktextedit/data/alignments_lt.png [moved from tests/auto/declarative/qsgtextedit/data/alignments_lt.png with 100% similarity]
tests/auto/declarative/qquicktextedit/data/alignments_rb.png [moved from tests/auto/declarative/qsgtextedit/data/alignments_rb.png with 100% similarity]
tests/auto/declarative/qquicktextedit/data/alignments_rc.png [moved from tests/auto/declarative/qsgtextedit/data/alignments_rc.png with 100% similarity]
tests/auto/declarative/qquicktextedit/data/alignments_rt.png [moved from tests/auto/declarative/qsgtextedit/data/alignments_rt.png with 100% similarity]
tests/auto/declarative/qquicktextedit/data/cursorTest.qml [moved from tests/auto/declarative/qsgtextedit/data/cursorTest.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/cursorVisible.qml [moved from tests/auto/declarative/qsgtextedit/data/cursorVisible.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/geometrySignals.qml [moved from tests/auto/declarative/qsgtextedit/data/geometrySignals.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/horizontalAlignment_RightToLeft.qml [moved from tests/auto/declarative/qsgtextedit/data/horizontalAlignment_RightToLeft.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/http/ErrItem.qml [moved from tests/auto/declarative/qsgtextedit/data/http/ErrItem.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/http/NormItem.qml [moved from tests/auto/declarative/qsgtextedit/data/http/NormItem.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/http/cursorHttpTest.qml [moved from tests/auto/declarative/qsgtextedit/data/http/cursorHttpTest.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/http/cursorHttpTestFail1.qml [moved from tests/auto/declarative/qsgtextedit/data/http/cursorHttpTestFail1.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/http/cursorHttpTestFail2.qml [moved from tests/auto/declarative/qsgtextedit/data/http/cursorHttpTestFail2.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/http/cursorHttpTestPass.qml [moved from tests/auto/declarative/qsgtextedit/data/http/cursorHttpTestPass.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/http/qmldir [moved from tests/auto/declarative/qsgtextedit/data/http/qmldir with 100% similarity]
tests/auto/declarative/qquicktextedit/data/httpfail/FailItem.qml [moved from tests/auto/declarative/qsgtextedit/data/httpfail/FailItem.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/httpslow/WaitItem.qml [moved from tests/auto/declarative/qsgtextedit/data/httpslow/WaitItem.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/inputContext.qml [moved from tests/auto/declarative/qsgtextedit/data/inputContext.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/inputMethodEvent.qml [moved from tests/auto/declarative/qsgtextedit/data/inputMethodEvent.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/inputmethodhints.qml [moved from tests/auto/declarative/qsgtextedit/data/inputmethodhints.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/mouseselection_default.qml [moved from tests/auto/declarative/qsgtextedit/data/mouseselection_default.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/mouseselection_false.qml [moved from tests/auto/declarative/qsgtextedit/data/mouseselection_false.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/mouseselection_false_words.qml [moved from tests/auto/declarative/qsgtextedit/data/mouseselection_false_words.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/mouseselection_true.qml [moved from tests/auto/declarative/qsgtextedit/data/mouseselection_true.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/mouseselection_true_words.qml [moved from tests/auto/declarative/qsgtextedit/data/mouseselection_true_words.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/mouseselectionmode_characters.qml [moved from tests/auto/declarative/qsgtextedit/data/mouseselectionmode_characters.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/mouseselectionmode_default.qml [moved from tests/auto/declarative/qsgtextedit/data/mouseselectionmode_default.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/mouseselectionmode_words.qml [moved from tests/auto/declarative/qsgtextedit/data/mouseselectionmode_words.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/navigation.qml [moved from tests/auto/declarative/qsgtextedit/data/navigation.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/openInputPanel.qml [moved from tests/auto/declarative/qsgtextedit/data/openInputPanel.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/positionAt.qml [moved from tests/auto/declarative/qsgtextedit/data/positionAt.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/qtbug-22058.qml [moved from tests/auto/declarative/qsgtextedit/data/qtbug-22058.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/data/readOnly.qml [moved from tests/auto/declarative/qsgtextedit/data/readOnly.qml with 100% similarity]
tests/auto/declarative/qquicktextedit/qquicktextedit.pro [new file with mode: 0644]
tests/auto/declarative/qquicktextedit/tst_qquicktextedit.cpp [new file with mode: 0644]
tests/auto/declarative/qquicktextinput/data/cursorTest.qml [moved from tests/auto/declarative/qsgtextinput/data/cursorTest.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/cursorVisible.qml [moved from tests/auto/declarative/qsgtextinput/data/cursorVisible.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/echoMode.qml [moved from tests/auto/declarative/qsgtextinput/data/echoMode.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/geometrySignals.qml [moved from tests/auto/declarative/qsgtextinput/data/geometrySignals.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/halign_center.png [moved from tests/auto/declarative/qsgtextinput/data/halign_center.png with 100% similarity]
tests/auto/declarative/qquicktextinput/data/halign_left.png [moved from tests/auto/declarative/qsgtextinput/data/halign_left.png with 100% similarity]
tests/auto/declarative/qquicktextinput/data/halign_right.png [moved from tests/auto/declarative/qsgtextinput/data/halign_right.png with 100% similarity]
tests/auto/declarative/qquicktextinput/data/horizontalAlignment.qml [moved from tests/auto/declarative/qsgtextinput/data/horizontalAlignment.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/horizontalAlignment_RightToLeft.qml [moved from tests/auto/declarative/qsgtextinput/data/horizontalAlignment_RightToLeft.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/inputContext.qml [moved from tests/auto/declarative/qsgtextinput/data/inputContext.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/inputMethodEvent.qml [moved from tests/auto/declarative/qsgtextinput/data/inputMethodEvent.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/inputmethods.qml [moved from tests/auto/declarative/qsgtextinput/data/inputmethods.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/masks.qml [moved from tests/auto/declarative/qsgtextinput/data/masks.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/maxLength.qml [moved from tests/auto/declarative/qsgtextinput/data/maxLength.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/mouseselection_true.qml [moved from tests/auto/declarative/qsgtextinput/data/mouseselection_true.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/mouseselectionmode_characters.qml [moved from tests/auto/declarative/qsgtextinput/data/mouseselectionmode_characters.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/mouseselectionmode_default.qml [moved from tests/auto/declarative/qsgtextinput/data/mouseselectionmode_default.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/mouseselectionmode_words.qml [moved from tests/auto/declarative/qsgtextinput/data/mouseselectionmode_words.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/navigation.qml [moved from tests/auto/declarative/qsgtextinput/data/navigation.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/openInputPanel.qml [moved from tests/auto/declarative/qsgtextinput/data/openInputPanel.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/positionAt.qml [moved from tests/auto/declarative/qsgtextinput/data/positionAt.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/preeditAutoScroll.qml [moved from tests/auto/declarative/qsgtextinput/data/preeditAutoScroll.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/qtbug-19956double.qml [moved from tests/auto/declarative/qsgtextinput/data/qtbug-19956double.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/qtbug-19956int.qml [moved from tests/auto/declarative/qsgtextinput/data/qtbug-19956int.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/qtbug-19956regexp.qml [moved from tests/auto/declarative/qsgtextinput/data/qtbug-19956regexp.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/readOnly.qml [moved from tests/auto/declarative/qsgtextinput/data/readOnly.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/data/validators.qml [moved from tests/auto/declarative/qsgtextinput/data/validators.qml with 100% similarity]
tests/auto/declarative/qquicktextinput/qquicktextinput.pro [new file with mode: 0644]
tests/auto/declarative/qquicktextinput/tst_qquicktextinput.cpp [new file with mode: 0644]
tests/auto/declarative/qquickview/data/error1.qml [moved from tests/auto/declarative/qsgview/data/error1.qml with 100% similarity]
tests/auto/declarative/qquickview/data/resizemodeitem.qml [moved from tests/auto/declarative/qsgview/data/resizemodeitem.qml with 100% similarity]
tests/auto/declarative/qquickview/qquickview.pro [new file with mode: 0644]
tests/auto/declarative/qquickview/tst_qquickview.cpp [new file with mode: 0644]
tests/auto/declarative/qquickvisualdatamodel/data/create.qml [moved from tests/auto/declarative/qsgvisualdatamodel/data/create.qml with 100% similarity]
tests/auto/declarative/qquickvisualdatamodel/data/datalist.qml [moved from tests/auto/declarative/qsgvisualdatamodel/data/datalist.qml with 100% similarity]
tests/auto/declarative/qquickvisualdatamodel/data/groups.qml [moved from tests/auto/declarative/qsgvisualdatamodel/data/groups.qml with 100% similarity]
tests/auto/declarative/qquickvisualdatamodel/data/modelproperties.qml [moved from tests/auto/declarative/qsgvisualdatamodel/data/modelproperties.qml with 100% similarity]
tests/auto/declarative/qquickvisualdatamodel/data/modelproperties2.qml [moved from tests/auto/declarative/qsgvisualdatamodel/data/modelproperties2.qml with 100% similarity]
tests/auto/declarative/qquickvisualdatamodel/data/objectlist.qml [moved from tests/auto/declarative/qsgvisualdatamodel/data/objectlist.qml with 100% similarity]
tests/auto/declarative/qquickvisualdatamodel/data/singlerole1.qml [moved from tests/auto/declarative/qsgvisualdatamodel/data/singlerole1.qml with 100% similarity]
tests/auto/declarative/qquickvisualdatamodel/data/singlerole2.qml [moved from tests/auto/declarative/qsgvisualdatamodel/data/singlerole2.qml with 100% similarity]
tests/auto/declarative/qquickvisualdatamodel/data/visualdatamodel.qml [moved from tests/auto/declarative/qsgvisualdatamodel/data/visualdatamodel.qml with 100% similarity]
tests/auto/declarative/qquickvisualdatamodel/qquickvisualdatamodel.pro [new file with mode: 0644]
tests/auto/declarative/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp [new file with mode: 0644]
tests/auto/declarative/qsganimatedimage/qsganimatedimage.pro [deleted file]
tests/auto/declarative/qsganimatedimage/tst_qsganimatedimage.cpp [deleted file]
tests/auto/declarative/qsgborderimage/qsgborderimage.pro [deleted file]
tests/auto/declarative/qsgborderimage/tst_qsgborderimage.cpp [deleted file]
tests/auto/declarative/qsgcanvas/qsgcanvas.pro [deleted file]
tests/auto/declarative/qsgcanvas/tst_qsgcanvas.cpp [deleted file]
tests/auto/declarative/qsgcanvasitem/qsgcanvasitem.pro [deleted file]
tests/auto/declarative/qsgcanvasitem/tst_qsgcanvasitem.cpp [deleted file]
tests/auto/declarative/qsgdrag/qsgdrag.pro [deleted file]
tests/auto/declarative/qsgdrag/tst_qsgdrag.cpp [deleted file]
tests/auto/declarative/qsgdroparea/qsgdroparea.pro [deleted file]
tests/auto/declarative/qsgdroparea/tst_qsgdroparea.cpp [deleted file]
tests/auto/declarative/qsgflickable/qsgflickable.pro [deleted file]
tests/auto/declarative/qsgflickable/tst_qsgflickable.cpp [deleted file]
tests/auto/declarative/qsgflipable/qsgflipable.pro [deleted file]
tests/auto/declarative/qsgflipable/tst_qsgflipable.cpp [deleted file]
tests/auto/declarative/qsgfocusscope/qsgfocusscope.pro [deleted file]
tests/auto/declarative/qsgfocusscope/tst_qsgfocusscope.cpp [deleted file]
tests/auto/declarative/qsggridview/qsggridview.pro [deleted file]
tests/auto/declarative/qsggridview/tst_qsggridview.cpp [deleted file]
tests/auto/declarative/qsgimage/qsgimage.pro [deleted file]
tests/auto/declarative/qsgimage/tst_qsgimage.cpp [deleted file]
tests/auto/declarative/qsgitem/qsgitem.pro [deleted file]
tests/auto/declarative/qsgitem/tst_qsgitem.cpp [deleted file]
tests/auto/declarative/qsgitem2/qsgitem2.pro [deleted file]
tests/auto/declarative/qsgitem2/tst_qsgitem.cpp [deleted file]
tests/auto/declarative/qsglistview/qsglistview.pro [deleted file]
tests/auto/declarative/qsglistview/tst_qsglistview.cpp [deleted file]
tests/auto/declarative/qsgloader/qsgloader.pro [deleted file]
tests/auto/declarative/qsgloader/tst_qsgloader.cpp [deleted file]
tests/auto/declarative/qsgmousearea/qsgmousearea.pro [deleted file]
tests/auto/declarative/qsgmousearea/tst_qsgmousearea.cpp [deleted file]
tests/auto/declarative/qsgpathview/qsgpathview.pro [deleted file]
tests/auto/declarative/qsgpathview/tst_qsgpathview.cpp [deleted file]
tests/auto/declarative/qsgpincharea/qsgpincharea.pro [deleted file]
tests/auto/declarative/qsgpincharea/tst_qsgpincharea.cpp [deleted file]
tests/auto/declarative/qsgpositioners/qsgpositioners.pro [deleted file]
tests/auto/declarative/qsgpositioners/tst_qsgpositioners.cpp [deleted file]
tests/auto/declarative/qsgrepeater/qsgrepeater.pro [deleted file]
tests/auto/declarative/qsgrepeater/tst_qsgrepeater.cpp [deleted file]
tests/auto/declarative/qsgtext/qsgtext.pro [deleted file]
tests/auto/declarative/qsgtext/tst_qsgtext.cpp [deleted file]
tests/auto/declarative/qsgtextedit/qsgtextedit.pro [deleted file]
tests/auto/declarative/qsgtextedit/tst_qsgtextedit.cpp [deleted file]
tests/auto/declarative/qsgtextinput/qsgtextinput.pro [deleted file]
tests/auto/declarative/qsgtextinput/tst_qsgtextinput.cpp [deleted file]
tests/auto/declarative/qsgview/qsgview.pro [deleted file]
tests/auto/declarative/qsgview/tst_qsgview.cpp [deleted file]
tests/auto/declarative/qsgvisualdatamodel/qsgvisualdatamodel.pro [deleted file]
tests/auto/declarative/qsgvisualdatamodel/tst_qsgvisualdatamodel.cpp [deleted file]
tests/auto/particles/qsgage/tst_qsgage.cpp
tests/auto/particles/qsgangleddirection/tst_qsgangleddirection.cpp
tests/auto/particles/qsgcumulativedirection/tst_qsgcumulativedirection.cpp
tests/auto/particles/qsgcustomaffector/tst_qsgcustomaffector.cpp
tests/auto/particles/qsgcustomparticle/tst_qsgcustomparticle.cpp
tests/auto/particles/qsgellipseextruder/tst_qsgellipseextruder.cpp
tests/auto/particles/qsgfriction/tst_qsgfriction.cpp
tests/auto/particles/qsggravity/tst_qsggravity.cpp
tests/auto/particles/qsgimageparticle/tst_qsgimageparticle.cpp
tests/auto/particles/qsgitemparticle/tst_qsgitemparticle.cpp
tests/auto/particles/qsglineextruder/tst_qsglineextruder.cpp
tests/auto/particles/qsgmaskextruder/tst_qsgmaskextruder.cpp
tests/auto/particles/qsgparticlegroup/tst_qsgparticlegroup.cpp
tests/auto/particles/qsgparticlesystem/tst_qsgparticlesystem.cpp
tests/auto/particles/qsgpointattractor/tst_qsgpointattractor.cpp
tests/auto/particles/qsgpointdirection/tst_qsgpointdirection.cpp
tests/auto/particles/qsgrectangleextruder/tst_qsgrectangleextruder.cpp
tests/auto/particles/qsgtargetdirection/tst_qsgtargetdirection.cpp
tests/auto/particles/qsgtrailemitter/tst_qsgtrailemitter.cpp
tests/auto/particles/qsgturbulence/tst_qsgturbulence.cpp
tests/auto/particles/qsgwander/tst_qsgwander.cpp
tests/auto/particles/shared/particlestestsshared.h
tests/auto/qmltest/borderimage/tst_borderimage.qml
tests/benchmarks/particles/affectors/tst_affectors.cpp
tests/benchmarks/particles/emission/tst_emission.cpp
tools/qmlplugindump/main.cpp
tools/qmlscene/main.cpp

index a8bed3a..489d8ac 100644 (file)
 
     \image declarative-textballoons_example.png
 
-    The QSGPaintedItem class is a class derived from QSGItem for implementing
+    The QQuickPaintedItem class is a class derived from QQuickItem for implementing
     custom QML Scene Graph items using the QPainter interfaces.
 
     The example consists of an item class, a plugin class and a QML file
     to use this plugin. The \c TextBalloon class represents the individual
-    text balloons extending QSGPaintedItem, the \c TextBalloonPlugin class
+    text balloons extending QQuickPaintedItem, the \c TextBalloonPlugin class
     represents the skeleton code for a QtQuick plugin and the
     \c textballoons.qml file is used to load the plugin and display the text
     balloons.
 
     \section1 TextBalloon Class Declaration
 
-    The \c TextBalloon class inherits from QSGPaintedItem. QSGPaintedItem
+    The \c TextBalloon class inherits from QQuickPaintedItem. QQuickPaintedItem
     is the base class for all QPainter based items in the QML Scene Graph
     framework.
 
     \snippet examples/declarative/painteditem/textballoons/textballoon.h 0
 
-    To implement a QSGPaintedItem you must implement QSGPaintedIem's pure
-    virtual function \l {QSGPaintedItem::}{paint()} which implements the
+    To implement a QQuickPaintedItem you must implement QQuickPaintedIem's pure
+    virtual function \l {QQuickPaintedItem::}{paint()} which implements the
     painting of the element.
 
     \section1 TextBalloon Class Definition
@@ -75,9 +75,9 @@
     \snippet examples/declarative/painteditem/textballoons/textballoon.cpp 1
 
     We start with setting the pen and brush on the item to define the look of
-    the item. After that we start drawing. Note that the \l {QSGPaintedItem::}{boundingRect()}
+    the item. After that we start drawing. Note that the \l {QQuickPaintedItem::}{boundingRect()}
     item is called to draw depending on the size of the item. The rectangle
-    returned by the \l {QSGPaintedItem::}{boundingRect()} function is the size
+    returned by the \l {QQuickPaintedItem::}{boundingRect()} function is the size
     of the item as defined in the QML file.
 
     \section1 textballoons.qml file
index 3421c16..102118d 100644 (file)
     \section1 Running tests with QtQuick 1
 
     The \c{-qtquick1} option can be passed to a test binary to run
-    the tests using QDeclarativeView (QtQuick 1) rather than QSGView (QtQuick 2):
+    the tests using QDeclarativeView (QtQuick 1) rather than QQuickView (QtQuick 2):
 
     \code
     tst_example -qtquick1
index 4c44166..749392a 100644 (file)
@@ -39,10 +39,10 @@ QtQuick 2 is based on an OpenGL scenegraph.  The following
 classes replace their equivalents in QtQuick 1:
 
 \list
-\o QSGView
-\o QSGCanvas
-\o QSGItem
-\o QSGPaintedItem
+\o QQuickView
+\o QQuickCanvas
+\o QQuickItem
+\o QQuickPaintedItem
 \endlist
 
 \section2 QML Engine/Language Improvements
index a8bed3a..489d8ac 100644 (file)
 
     \image declarative-textballoons_example.png
 
-    The QSGPaintedItem class is a class derived from QSGItem for implementing
+    The QQuickPaintedItem class is a class derived from QQuickItem for implementing
     custom QML Scene Graph items using the QPainter interfaces.
 
     The example consists of an item class, a plugin class and a QML file
     to use this plugin. The \c TextBalloon class represents the individual
-    text balloons extending QSGPaintedItem, the \c TextBalloonPlugin class
+    text balloons extending QQuickPaintedItem, the \c TextBalloonPlugin class
     represents the skeleton code for a QtQuick plugin and the
     \c textballoons.qml file is used to load the plugin and display the text
     balloons.
 
     \section1 TextBalloon Class Declaration
 
-    The \c TextBalloon class inherits from QSGPaintedItem. QSGPaintedItem
+    The \c TextBalloon class inherits from QQuickPaintedItem. QQuickPaintedItem
     is the base class for all QPainter based items in the QML Scene Graph
     framework.
 
     \snippet examples/declarative/painteditem/textballoons/textballoon.h 0
 
-    To implement a QSGPaintedItem you must implement QSGPaintedIem's pure
-    virtual function \l {QSGPaintedItem::}{paint()} which implements the
+    To implement a QQuickPaintedItem you must implement QQuickPaintedIem's pure
+    virtual function \l {QQuickPaintedItem::}{paint()} which implements the
     painting of the element.
 
     \section1 TextBalloon Class Definition
@@ -75,9 +75,9 @@
     \snippet examples/declarative/painteditem/textballoons/textballoon.cpp 1
 
     We start with setting the pen and brush on the item to define the look of
-    the item. After that we start drawing. Note that the \l {QSGPaintedItem::}{boundingRect()}
+    the item. After that we start drawing. Note that the \l {QQuickPaintedItem::}{boundingRect()}
     item is called to draw depending on the size of the item. The rectangle
-    returned by the \l {QSGPaintedItem::}{boundingRect()} function is the size
+    returned by the \l {QQuickPaintedItem::}{boundingRect()} function is the size
     of the item as defined in the QML file.
 
     \section1 textballoons.qml file
index 3421c16..102118d 100644 (file)
     \section1 Running tests with QtQuick 1
 
     The \c{-qtquick1} option can be passed to a test binary to run
-    the tests using QDeclarativeView (QtQuick 1) rather than QSGView (QtQuick 2):
+    the tests using QDeclarativeView (QtQuick 1) rather than QQuickView (QtQuick 2):
 
     \code
     tst_example -qtquick1
index 7caeaf9..e8ccdb7 100644 (file)
@@ -44,7 +44,7 @@
 
 #include <QDeclarativeEngine>
 #include <QDeclarativeNetworkAccessManagerFactory>
-#include <QSGView>
+#include <QQuickView>
 
 
 /*
@@ -97,7 +97,7 @@ int main(int argc, char ** argv)
         }
     }
 
-    QSGView view;
+    QQuickView view;
     view.engine()->setNetworkAccessManagerFactory(new MyNetworkAccessManagerFactory);
 
     view.setSource(source);
index 2ae2cc0..205835a 100644 (file)
@@ -40,7 +40,7 @@
 ****************************************************************************/
 
 #include <QtGui/QGuiApplication>
-#include <qsgview.h>
+#include <qquickview.h>
 #include <QtDeclarative/QDeclarativeContext>
 #include <QtDeclarative/QDeclarativeEngine>
 
 int main(int argc, char *argv[])
 {
     QGuiApplication app(argc, argv);
-    QSGView canvas;
+    QQuickView canvas;
 
     qmlRegisterType<TileData>();
     MinehuntGame* game = new MinehuntGame();
 
-    canvas.setResizeMode(QSGView::SizeRootObjectToView);
+    canvas.setResizeMode(QQuickView::SizeRootObjectToView);
     canvas.engine()->rootContext()->setContextObject(game);
     canvas.setSource(QString("qrc:minehunt.qml"));
     QObject::connect(canvas.engine(), SIGNAL(quit()), &app, SLOT(quit()));
index 3c78608..dd72661 100644 (file)
@@ -43,8 +43,8 @@
 #include <qdeclarativeengine.h>
 #include <qdeclarativecontext.h>
 #include <qdeclarative.h>
-#include <qsgitem.h>
-#include <qsgview.h>
+#include <qquickitem.h>
+#include <qquickview.h>
 
 //![0]
 int main(int argc, char ** argv)
@@ -56,8 +56,8 @@ int main(int argc, char ** argv)
     model.addAnimal(Animal("Polar bear", "Large"));
     model.addAnimal(Animal("Quoll", "Small"));
 
-    QSGView view;
-    view.setResizeMode(QSGView::SizeRootObjectToView);
+    QQuickView view;
+    view.setResizeMode(QQuickView::SizeRootObjectToView);
     QDeclarativeContext *ctxt = view.rootContext();
     ctxt->setContextProperty("myModel", &model);
 //![0]
index ba37e17..67ffb94 100644 (file)
@@ -43,8 +43,8 @@
 #include <qdeclarativeengine.h>
 #include <qdeclarativecontext.h>
 #include <qdeclarative.h>
-#include <qsgitem.h>
-#include <qsgview.h>
+#include <qquickitem.h>
+#include <qquickview.h>
 
 #include "dataobject.h"
 
@@ -64,8 +64,8 @@ int main(int argc, char ** argv)
     dataList.append(new DataObject("Item 3", "blue"));
     dataList.append(new DataObject("Item 4", "yellow"));
 
-    QSGView view;
-    view.setResizeMode(QSGView::SizeRootObjectToView);
+    QQuickView view;
+    view.setResizeMode(QQuickView::SizeRootObjectToView);
     QDeclarativeContext *ctxt = view.rootContext();
     ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
 //![0]
index 5d01c6f..ebd3c59 100644 (file)
@@ -44,8 +44,8 @@
 #include <qdeclarativeengine.h>
 #include <qdeclarativecontext.h>
 #include <qdeclarative.h>
-#include <qsgitem.h>
-#include <qsgview.h>
+#include <qquickitem.h>
+#include <qquickview.h>
 
 
 /*
@@ -64,7 +64,7 @@ int main(int argc, char ** argv)
     dataList.append("Item 3");
     dataList.append("Item 4");
 
-    QSGView view;
+    QQuickView view;
     QDeclarativeContext *ctxt = view.rootContext();
     ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
 //![0]
index 423ff29..1f0b3a3 100644 (file)
 #include <QGuiApplication>
 #include <QPainter>
 #include <QtDeclarative/qdeclarative.h>
-#include <QtDeclarative/qsgview.h>
-#include <QtDeclarative/qsgpainteditem.h>
+#include <QtDeclarative/qquickview.h>
+#include <QtDeclarative/qquickpainteditem.h>
 
-class MyPaintItem : public QSGPaintedItem
+class MyPaintItem : public QQuickPaintedItem
 {
     Q_OBJECT
 public:
-    MyPaintItem() : QSGPaintedItem()
+    MyPaintItem() : QQuickPaintedItem()
     {
         setAntialiasing(true);
     }
@@ -72,8 +72,8 @@ int main(int argc, char ** argv)
 
     qmlRegisterType<MyPaintItem>("MyModule", 1, 0, "MyPaintItem");
 
-    QSGView view;
-    view.setResizeMode(QSGView::SizeRootObjectToView);
+    QQuickView view;
+    view.setResizeMode(QQuickView::SizeRootObjectToView);
     view.setSource(QUrl::fromLocalFile("smile.qml"));
     view.show();
     view.raise();
index 185cea7..c90118c 100644 (file)
@@ -42,8 +42,8 @@
 #include "textballoon.h"
 
 //! [0]
-TextBalloon::TextBalloon(QSGItem *parent)
-    : QSGPaintedItem(parent)
+TextBalloon::TextBalloon(QQuickItem *parent)
+    : QQuickPaintedItem(parent)
     , rightAligned(false)
 {
 }
index 272e5f5..064d20b 100644 (file)
 #include <QtDeclarative>
 
 //! [0]
-class TextBalloon : public QSGPaintedItem
+class TextBalloon : public QQuickPaintedItem
 {
     Q_OBJECT
     Q_PROPERTY(bool rightAligned READ isRightAligned WRITE setRightAligned NOTIFY rightAlignedChanged)
 
     public:
-        TextBalloon(QSGItem *parent = 0);
+        TextBalloon(QQuickItem *parent = 0);
         void paint(QPainter *painter);
 
         bool isRightAligned();
index ca6a97e..2670871 100644 (file)
@@ -39,7 +39,7 @@
 ****************************************************************************/
 //![0]
 #include "piechart.h"
-#include <QSGView>
+#include <QQuickView>
 #include <QGuiApplication>
 
 int main(int argc, char *argv[])
@@ -48,8 +48,8 @@ int main(int argc, char *argv[])
 
     qmlRegisterType<PieChart>("Charts", 1, 0, "PieChart");
 
-    QSGView view;
-    view.setResizeMode(QSGView::SizeRootObjectToView);
+    QQuickView view;
+    view.setResizeMode(QQuickView::SizeRootObjectToView);
     view.setSource(QUrl::fromLocalFile("app.qml"));
     view.show();
     return app.exec();
index 5820c56..06d9892 100644 (file)
@@ -41,8 +41,8 @@
 #include <QPainter>
 
 //![0]
-PieChart::PieChart(QSGItem *parent)
-    : QSGPaintedItem(parent)
+PieChart::PieChart(QQuickItem *parent)
+    : QQuickPaintedItem(parent)
 {
 }
 //![0]
index a5afec5..d1beb71 100644 (file)
 #define PIECHART_H
 
 //![0]
-#include <QtDeclarative/QSGPaintedItem>
+#include <QtDeclarative/QQuickPaintedItem>
 #include <QColor>
 
-class PieChart : public QSGPaintedItem
+class PieChart : public QQuickPaintedItem
 {
     Q_OBJECT
     Q_PROPERTY(QString name READ name WRITE setName)
     Q_PROPERTY(QColor color READ color WRITE setColor)
 
 public:
-    PieChart(QSGItem *parent = 0);
+    PieChart(QQuickItem *parent = 0);
 
     QString name() const;
     void setName(const QString &name);
index ca6a97e..2670871 100644 (file)
@@ -39,7 +39,7 @@
 ****************************************************************************/
 //![0]
 #include "piechart.h"
-#include <QSGView>
+#include <QQuickView>
 #include <QGuiApplication>
 
 int main(int argc, char *argv[])
@@ -48,8 +48,8 @@ int main(int argc, char *argv[])
 
     qmlRegisterType<PieChart>("Charts", 1, 0, "PieChart");
 
-    QSGView view;
-    view.setResizeMode(QSGView::SizeRootObjectToView);
+    QQuickView view;
+    view.setResizeMode(QQuickView::SizeRootObjectToView);
     view.setSource(QUrl::fromLocalFile("app.qml"));
     view.show();
     return app.exec();
index 86407f1..ca25474 100644 (file)
@@ -40,8 +40,8 @@
 #include "piechart.h"
 #include <QPainter>
 
-PieChart::PieChart(QSGItem *parent)
-    : QSGPaintedItem(parent)
+PieChart::PieChart(QQuickItem *parent)
+    : QQuickPaintedItem(parent)
 {
 }
 
index 38f5c05..5205151 100644 (file)
 #ifndef PIECHART_H
 #define PIECHART_H
 
-#include <QtDeclarative/QSGPaintedItem>
+#include <QtDeclarative/QQuickPaintedItem>
 #include <QColor>
 
 //![0]
-class PieChart : public QSGPaintedItem
+class PieChart : public QQuickPaintedItem
 {
 //![0]
     Q_OBJECT
@@ -55,7 +55,7 @@ class PieChart : public QSGPaintedItem
 public:
 //![1]
 
-    PieChart(QSGItem *parent = 0);
+    PieChart(QQuickItem *parent = 0);
 
     QString name() const;
     void setName(const QString &name);
index ca6a97e..2670871 100644 (file)
@@ -39,7 +39,7 @@
 ****************************************************************************/
 //![0]
 #include "piechart.h"
-#include <QSGView>
+#include <QQuickView>
 #include <QGuiApplication>
 
 int main(int argc, char *argv[])
@@ -48,8 +48,8 @@ int main(int argc, char *argv[])
 
     qmlRegisterType<PieChart>("Charts", 1, 0, "PieChart");
 
-    QSGView view;
-    view.setResizeMode(QSGView::SizeRootObjectToView);
+    QQuickView view;
+    view.setResizeMode(QQuickView::SizeRootObjectToView);
     view.setSource(QUrl::fromLocalFile("app.qml"));
     view.show();
     return app.exec();
index 86ad6a7..5819088 100644 (file)
@@ -40,8 +40,8 @@
 #include "piechart.h"
 #include <QPainter>
 
-PieChart::PieChart(QSGItem *parent)
-    : QSGPaintedItem(parent)
+PieChart::PieChart(QQuickItem *parent)
+    : QQuickPaintedItem(parent)
 {
 }
 
index 5208f81..55be2a4 100644 (file)
 #define PIECHART_H
 
 #include <QColor>
-#include <QtDeclarative/QSGPaintedItem>
+#include <QtDeclarative/QQuickPaintedItem>
 
 //![0]
-class PieChart : public QSGPaintedItem
+class PieChart : public QQuickPaintedItem
 {
 //![0]
     Q_OBJECT
@@ -55,7 +55,7 @@ class PieChart : public QSGPaintedItem
 public:
 //![1]
 
-    PieChart(QSGItem *parent = 0);
+    PieChart(QQuickItem *parent = 0);
 
     QString name() const;
     void setName(const QString &name);
index d281276..c9b9a0b 100644 (file)
@@ -40,7 +40,7 @@
 #include "piechart.h"
 #include "pieslice.h"
 
-#include <QSGView>
+#include <QQuickView>
 #include <QGuiApplication>
 
 //![0]
@@ -55,8 +55,8 @@ int main(int argc, char *argv[])
     qmlRegisterType<PieSlice>("Charts", 1, 0, "PieSlice");
 //![1]
 
-    QSGView view;
-    view.setResizeMode(QSGView::SizeRootObjectToView);
+    QQuickView view;
+    view.setResizeMode(QQuickView::SizeRootObjectToView);
     view.setSource(QUrl::fromLocalFile("app.qml"));
     view.show();
     return app.exec();
index 5911f4d..f032887 100644 (file)
@@ -40,8 +40,8 @@
 #include "piechart.h"
 #include "pieslice.h"
 
-PieChart::PieChart(QSGItem *parent)
-    : QSGItem(parent)
+PieChart::PieChart(QQuickItem *parent)
+    : QQuickItem(parent)
 {
 }
 
index 9e81398..c1cdf30 100644 (file)
 #ifndef PIECHART_H
 #define PIECHART_H
 
-#include <QtDeclarative/QSGItem>
+#include <QtDeclarative/QQuickItem>
 
 class PieSlice;
 
 //![0]
-class PieChart : public QSGItem
+class PieChart : public QQuickItem
 {
     Q_OBJECT
     Q_PROPERTY(PieSlice* pieSlice READ pieSlice WRITE setPieSlice)
@@ -56,7 +56,7 @@ class PieChart : public QSGItem
 public:
 //![1]
 
-    PieChart(QSGItem *parent = 0);
+    PieChart(QQuickItem *parent = 0);
 
     QString name() const;
     void setName(const QString &name);
index 764ef23..176ca1e 100644 (file)
@@ -41,8 +41,8 @@
 
 #include <QPainter>
 
-PieSlice::PieSlice(QSGItem *parent)
-    : QSGPaintedItem(parent)
+PieSlice::PieSlice(QQuickItem *parent)
+    : QQuickPaintedItem(parent)
 {
 }
 
index 7163864..5960648 100644 (file)
 #ifndef PIESLICE_H
 #define PIESLICE_H
 
-#include <QtDeclarative/QSGPaintedItem>
+#include <QtDeclarative/QQuickPaintedItem>
 #include <QColor>
 
 //![0]
-class PieSlice : public QSGPaintedItem
+class PieSlice : public QQuickPaintedItem
 {
     Q_OBJECT
     Q_PROPERTY(QColor color READ color WRITE setColor)
 
 public:
-    PieSlice(QSGItem *parent = 0);
+    PieSlice(QQuickItem *parent = 0);
 
     QColor color() const;
     void setColor(const QColor &color);
index 64c18f7..78f6f25 100644 (file)
@@ -40,7 +40,7 @@
 #include "piechart.h"
 #include "pieslice.h"
 
-#include <QSGView>
+#include <QQuickView>
 #include <QGuiApplication>
 
 int main(int argc, char *argv[])
@@ -50,8 +50,8 @@ int main(int argc, char *argv[])
     qmlRegisterType<PieChart>("Charts", 1, 0, "PieChart");
     qmlRegisterType<PieSlice>("Charts", 1, 0, "PieSlice");
 
-    QSGView view;
-    view.setResizeMode(QSGView::SizeRootObjectToView);
+    QQuickView view;
+    view.setResizeMode(QQuickView::SizeRootObjectToView);
     view.setSource(QUrl::fromLocalFile("app.qml"));
     view.show();
     return app.exec();
index 248f4a2..876ef54 100644 (file)
@@ -40,8 +40,8 @@
 #include "piechart.h"
 #include "pieslice.h"
 
-PieChart::PieChart(QSGItem *parent)
-    : QSGItem(parent)
+PieChart::PieChart(QQuickItem *parent)
+    : QQuickItem(parent)
 {
 }
 
index e95b02f..feea3d2 100644 (file)
 #ifndef PIECHART_H
 #define PIECHART_H
 
-#include <QSGItem>
+#include <QQuickItem>
 
 class PieSlice;
 
 //![0]
-class PieChart : public QSGItem
+class PieChart : public QQuickItem
 {
     Q_OBJECT
     Q_PROPERTY(QDeclarativeListProperty<PieSlice> slices READ slices)
@@ -55,7 +55,7 @@ class PieChart : public QSGItem
 //![1]
 public:
 //![1]
-    PieChart(QSGItem *parent = 0);
+    PieChart(QQuickItem *parent = 0);
 
     QString name() const;
     void setName(const QString &name);
index 70338f0..839d153 100644 (file)
@@ -41,8 +41,8 @@
 
 #include <QPainter>
 
-PieSlice::PieSlice(QSGItem *parent)
-    : QSGPaintedItem(parent)
+PieSlice::PieSlice(QQuickItem *parent)
+    : QQuickPaintedItem(parent)
 {
 }
 
index 1204f9a..157e9cd 100644 (file)
 #ifndef PIESLICE_H
 #define PIESLICE_H
 
-#include <QtDeclarative/QSGPaintedItem>
+#include <QtDeclarative/QQuickPaintedItem>
 #include <QColor>
 
 //![0]
-class PieSlice : public QSGPaintedItem
+class PieSlice : public QQuickPaintedItem
 {
     Q_OBJECT
     Q_PROPERTY(QColor color READ color WRITE setColor)
@@ -53,7 +53,7 @@ class PieSlice : public QSGPaintedItem
 //![0]
 
 public:
-    PieSlice(QSGItem *parent = 0);
+    PieSlice(QQuickItem *parent = 0);
 
     QColor color() const;
     void setColor(const QColor &color);
index 5aa4a78..b9a6442 100644 (file)
@@ -40,8 +40,8 @@
 #include "piechart.h"
 #include "pieslice.h"
 
-PieChart::PieChart(QSGItem *parent)
-    : QSGItem(parent)
+PieChart::PieChart(QQuickItem *parent)
+    : QQuickItem(parent)
 {
 }
 
index 1e4f122..2d58360 100644 (file)
 #ifndef PIECHART_H
 #define PIECHART_H
 
-#include <QSGItem>
+#include <QQuickItem>
 
 class PieSlice;
 
-class PieChart : public QSGItem
+class PieChart : public QQuickItem
 {
     Q_OBJECT
     Q_PROPERTY(QDeclarativeListProperty<PieSlice> slices READ slices)
     Q_PROPERTY(QString name READ name WRITE setName)
 
 public:
-    PieChart(QSGItem *parent = 0);
+    PieChart(QQuickItem *parent = 0);
 
     QString name() const;
     void setName(const QString &name);
index 70338f0..839d153 100644 (file)
@@ -41,8 +41,8 @@
 
 #include <QPainter>
 
-PieSlice::PieSlice(QSGItem *parent)
-    : QSGPaintedItem(parent)
+PieSlice::PieSlice(QQuickItem *parent)
+    : QQuickPaintedItem(parent)
 {
 }
 
index 3096ee6..4251e49 100644 (file)
 #ifndef PIESLICE_H
 #define PIESLICE_H
 
-#include <QtDeclarative/QSGPaintedItem>
+#include <QtDeclarative/QQuickPaintedItem>
 #include <QColor>
 
-class PieSlice : public QSGPaintedItem
+class PieSlice : public QQuickPaintedItem
 {
     Q_OBJECT
     Q_PROPERTY(QColor color READ color WRITE setColor)
@@ -51,7 +51,7 @@ class PieSlice : public QSGPaintedItem
     Q_PROPERTY(int angleSpan READ angleSpan WRITE setAngleSpan)
 
 public:
-    PieSlice(QSGItem *parent = 0);
+    PieSlice(QQuickItem *parent = 0);
 
     QColor color() const;
     void setColor(const QColor &color);
index d582ed1..9c565c1 100644 (file)
 ****************************************************************************/
 
 #include "designersupport.h"
-#include <private/qsgitem_p.h>
+#include <private/qquickitem_p.h>
 
-#include <private/qsgshadereffectsource_p.h>
-#include <private/qsgrectangle_p.h>
+#include <private/qquickshadereffectsource_p.h>
+#include <private/qquickrectangle_p.h>
 #include <private/qdeclarativeengine_p.h>
-#include <private/qsgview_p.h>
+#include <private/qquickview_p.h>
 #include <private/qdeclarativestategroup_p.h>
 #include <QtGui/QImage>
 
@@ -57,31 +57,31 @@ DesignerSupport::DesignerSupport()
 
 DesignerSupport::~DesignerSupport()
 {
-    QHash<QSGItem*, QSGShaderEffectTexture*>::iterator iterator;
+    QHash<QQuickItem*, QQuickShaderEffectTexture*>::iterator iterator;
 
     for (iterator = m_itemTextureHash.begin(); iterator != m_itemTextureHash.end(); ++iterator) {
-        QSGShaderEffectTexture *texture = iterator.value();
-        QSGItem *item = iterator.key();
-        QSGItemPrivate::get(item)->derefFromEffectItem(true);
+        QQuickShaderEffectTexture *texture = iterator.value();
+        QQuickItem *item = iterator.key();
+        QQuickItemPrivate::get(item)->derefFromEffectItem(true);
         delete texture;
     }
 }
 
-void DesignerSupport::refFromEffectItem(QSGItem *referencedItem, bool hide)
+void DesignerSupport::refFromEffectItem(QQuickItem *referencedItem, bool hide)
 {
     if (referencedItem == 0)
         return;
 
-    QSGItemPrivate::get(referencedItem)->refFromEffectItem(hide);
-    QSGCanvasPrivate::get(referencedItem->canvas())->updateDirtyNode(referencedItem);
+    QQuickItemPrivate::get(referencedItem)->refFromEffectItem(hide);
+    QQuickCanvasPrivate::get(referencedItem->canvas())->updateDirtyNode(referencedItem);
 
-    Q_ASSERT(QSGItemPrivate::get(referencedItem)->rootNode);
+    Q_ASSERT(QQuickItemPrivate::get(referencedItem)->rootNode);
 
     if (!m_itemTextureHash.contains(referencedItem)) {
-        QSGShaderEffectTexture *texture = new QSGShaderEffectTexture(referencedItem);
+        QQuickShaderEffectTexture *texture = new QQuickShaderEffectTexture(referencedItem);
 
         texture->setLive(true);
-        texture->setItem(QSGItemPrivate::get(referencedItem)->rootNode);
+        texture->setItem(QQuickItemPrivate::get(referencedItem)->rootNode);
         texture->setRect(referencedItem->boundingRect());
         texture->setSize(referencedItem->boundingRect().size().toSize());
         texture->setRecursive(true);
@@ -96,23 +96,23 @@ void DesignerSupport::refFromEffectItem(QSGItem *referencedItem, bool hide)
     }
 }
 
-void DesignerSupport::derefFromEffectItem(QSGItem *referencedItem, bool unhide)
+void DesignerSupport::derefFromEffectItem(QQuickItem *referencedItem, bool unhide)
 {
     if (referencedItem == 0)
         return;
 
     delete m_itemTextureHash.take(referencedItem);
-    QSGItemPrivate::get(referencedItem)->derefFromEffectItem(unhide);
+    QQuickItemPrivate::get(referencedItem)->derefFromEffectItem(unhide);
 }
 
-QImage DesignerSupport::renderImageForItem(QSGItem *referencedItem, const QRectF &boundingRect, const QSize &imageSize)
+QImage DesignerSupport::renderImageForItem(QQuickItem *referencedItem, const QRectF &boundingRect, const QSize &imageSize)
 {
     if (referencedItem == 0 || referencedItem->parentItem() == 0) {
         qDebug() << __FILE__ << __LINE__ << "Warning: Item can be rendered.";
         return QImage();
     }
 
-    QSGShaderEffectTexture *renderTexture = m_itemTextureHash.value(referencedItem);
+    QQuickShaderEffectTexture *renderTexture = m_itemTextureHash.value(referencedItem);
 
     Q_ASSERT(renderTexture);
     if (renderTexture == 0)
@@ -130,54 +130,54 @@ QImage DesignerSupport::renderImageForItem(QSGItem *referencedItem, const QRectF
     return renderImage;
 }
 
-bool DesignerSupport::isDirty(QSGItem *referencedItem, DirtyType dirtyType)
+bool DesignerSupport::isDirty(QQuickItem *referencedItem, DirtyType dirtyType)
 {
     if (referencedItem == 0)
         return false;
 
-    return QSGItemPrivate::get(referencedItem)->dirtyAttributes & dirtyType;
+    return QQuickItemPrivate::get(referencedItem)->dirtyAttributes & dirtyType;
 }
 
-void DesignerSupport::resetDirty(QSGItem *referencedItem)
+void DesignerSupport::resetDirty(QQuickItem *referencedItem)
 {
     if (referencedItem == 0)
         return;
 
-    QSGItemPrivate::get(referencedItem)->dirtyAttributes = 0x0;
-    QSGItemPrivate::get(referencedItem)->removeFromDirtyList();
+    QQuickItemPrivate::get(referencedItem)->dirtyAttributes = 0x0;
+    QQuickItemPrivate::get(referencedItem)->removeFromDirtyList();
 }
 
-QTransform DesignerSupport::canvasTransform(QSGItem *referencedItem)
+QTransform DesignerSupport::canvasTransform(QQuickItem *referencedItem)
 {
     if (referencedItem == 0)
         return QTransform();
 
-    return QSGItemPrivate::get(referencedItem)->itemToCanvasTransform();
+    return QQuickItemPrivate::get(referencedItem)->itemToCanvasTransform();
 }
 
-QTransform DesignerSupport::parentTransform(QSGItem *referencedItem)
+QTransform DesignerSupport::parentTransform(QQuickItem *referencedItem)
 {
     if (referencedItem == 0)
         return QTransform();
 
     QTransform parentTransform;
 
-    QSGItemPrivate::get(referencedItem)->itemToParentTransform(parentTransform);
+    QQuickItemPrivate::get(referencedItem)->itemToParentTransform(parentTransform);
 
     return parentTransform;
 }
 
-QString propertyNameForAnchorLine(const QSGAnchorLine::AnchorLine &anchorLine)
+QString propertyNameForAnchorLine(const QQuickAnchorLine::AnchorLine &anchorLine)
 {
     switch (anchorLine) {
-        case QSGAnchorLine::Left: return QLatin1String("left");
-        case QSGAnchorLine::Right: return QLatin1String("right");
-        case QSGAnchorLine::Top: return QLatin1String("top");
-        case QSGAnchorLine::Bottom: return QLatin1String("bottom");
-        case QSGAnchorLine::HCenter: return QLatin1String("horizontalCenter");
-        case QSGAnchorLine::VCenter: return QLatin1String("verticalCenter");
-        case QSGAnchorLine::Baseline: return QLatin1String("baseline");
-        case QSGAnchorLine::Invalid:
+        case QQuickAnchorLine::Left: return QLatin1String("left");
+        case QQuickAnchorLine::Right: return QLatin1String("right");
+        case QQuickAnchorLine::Top: return QLatin1String("top");
+        case QQuickAnchorLine::Bottom: return QLatin1String("bottom");
+        case QQuickAnchorLine::HCenter: return QLatin1String("horizontalCenter");
+        case QQuickAnchorLine::VCenter: return QLatin1String("verticalCenter");
+        case QQuickAnchorLine::Baseline: return QLatin1String("baseline");
+        case QQuickAnchorLine::Invalid:
         default: return QString();
     }
 }
@@ -197,11 +197,11 @@ bool isValidAnchorName(const QString &name)
     return anchorNameList.contains(name);
 }
 
-bool DesignerSupport::isAnchoredTo(QSGItem *fromItem, QSGItem *toItem)
+bool DesignerSupport::isAnchoredTo(QQuickItem *fromItem, QQuickItem *toItem)
 {
-    Q_ASSERT(dynamic_cast<QSGItemPrivate*>(QSGItemPrivate::get(fromItem)));
-    QSGItemPrivate *fromItemPrivate = static_cast<QSGItemPrivate*>(QSGItemPrivate::get(fromItem));
-    QSGAnchors *anchors = fromItemPrivate->anchors();
+    Q_ASSERT(dynamic_cast<QQuickItemPrivate*>(QQuickItemPrivate::get(fromItem)));
+    QQuickItemPrivate *fromItemPrivate = static_cast<QQuickItemPrivate*>(QQuickItemPrivate::get(fromItem));
+    QQuickAnchors *anchors = fromItemPrivate->anchors();
     return anchors->fill() == toItem
             || anchors->centerIn() == toItem
             || anchors->bottom().item == toItem
@@ -213,9 +213,9 @@ bool DesignerSupport::isAnchoredTo(QSGItem *fromItem, QSGItem *toItem)
             || anchors->baseline().item == toItem;
 }
 
-bool DesignerSupport::areChildrenAnchoredTo(QSGItem *fromItem, QSGItem *toItem)
+bool DesignerSupport::areChildrenAnchoredTo(QQuickItem *fromItem, QQuickItem *toItem)
 {
-    foreach (QSGItem *childItem, fromItem->childItems()) {
+    foreach (QQuickItem *childItem, fromItem->childItems()) {
         if (childItem) {
             if (isAnchoredTo(childItem, toItem))
                 return true;
@@ -228,41 +228,41 @@ bool DesignerSupport::areChildrenAnchoredTo(QSGItem *fromItem, QSGItem *toItem)
     return false;
 }
 
-QSGAnchors *anchors(QSGItem *item)
+QQuickAnchors *anchors(QQuickItem *item)
 {
-    QSGItemPrivate *itemPrivate = static_cast<QSGItemPrivate*>(QSGItemPrivate::get(item));
+    QQuickItemPrivate *itemPrivate = static_cast<QQuickItemPrivate*>(QQuickItemPrivate::get(item));
     return itemPrivate->anchors();
 }
 
-QSGAnchors::Anchor anchorLineFlagForName(const QString &name)
+QQuickAnchors::Anchor anchorLineFlagForName(const QString &name)
 {
     if (name == QLatin1String("anchors.top"))
-        return QSGAnchors::TopAnchor;
+        return QQuickAnchors::TopAnchor;
 
     if (name == QLatin1String("anchors.left"))
-        return QSGAnchors::LeftAnchor;
+        return QQuickAnchors::LeftAnchor;
 
     if (name == QLatin1String("anchors.bottom"))
-         return QSGAnchors::BottomAnchor;
+         return QQuickAnchors::BottomAnchor;
 
     if (name == QLatin1String("anchors.right"))
-        return QSGAnchors::RightAnchor;
+        return QQuickAnchors::RightAnchor;
 
     if (name == QLatin1String("anchors.horizontalCenter"))
-        return QSGAnchors::HCenterAnchor;
+        return QQuickAnchors::HCenterAnchor;
 
     if (name == QLatin1String("anchors.verticalCenter"))
-         return QSGAnchors::VCenterAnchor;
+         return QQuickAnchors::VCenterAnchor;
 
     if (name == QLatin1String("anchors.baseline"))
-         return QSGAnchors::BaselineAnchor;
+         return QQuickAnchors::BaselineAnchor;
 
 
     Q_ASSERT_X(false, Q_FUNC_INFO, "wrong anchor name - this should never happen");
-    return QSGAnchors::LeftAnchor;
+    return QQuickAnchors::LeftAnchor;
 }
 
-bool DesignerSupport::hasAnchor(QSGItem *item, const QString &name)
+bool DesignerSupport::hasAnchor(QQuickItem *item, const QString &name)
 {
     if (!isValidAnchorName(name))
         return false;
@@ -297,19 +297,19 @@ bool DesignerSupport::hasAnchor(QSGItem *item, const QString &name)
     return anchors(item)->usedAnchors().testFlag(anchorLineFlagForName(name));
 }
 
-QSGItem *DesignerSupport::anchorFillTargetItem(QSGItem *item)
+QQuickItem *DesignerSupport::anchorFillTargetItem(QQuickItem *item)
 {
     return anchors(item)->fill();
 }
 
-QSGItem *DesignerSupport::anchorCenterInTargetItem(QSGItem *item)
+QQuickItem *DesignerSupport::anchorCenterInTargetItem(QQuickItem *item)
 {
     return anchors(item)->centerIn();
 }
 
 
 
-QPair<QString, QObject*> DesignerSupport::anchorLineTarget(QSGItem *item, const QString &name, QDeclarativeContext *context)
+QPair<QString, QObject*> DesignerSupport::anchorLineTarget(QQuickItem *item, const QString &name, QDeclarativeContext *context)
 {
     QObject *targetObject = 0;
     QString targetName;
@@ -323,8 +323,8 @@ QPair<QString, QObject*> DesignerSupport::anchorLineTarget(QSGItem *item, const
         if (!metaProperty.isValid())
             return QPair<QString, QObject*>();
 
-        QSGAnchorLine anchorLine = metaProperty.read().value<QSGAnchorLine>();
-        if (anchorLine.anchorLine != QSGAnchorLine::Invalid) {
+        QQuickAnchorLine anchorLine = metaProperty.read().value<QQuickAnchorLine>();
+        if (anchorLine.anchorLine != QQuickAnchorLine::Invalid) {
             targetObject = anchorLine.item;
             targetName = propertyNameForAnchorLine(anchorLine.anchorLine);
         }
@@ -334,7 +334,7 @@ QPair<QString, QObject*> DesignerSupport::anchorLineTarget(QSGItem *item, const
     return QPair<QString, QObject*>(targetName, targetObject);
 }
 
-void DesignerSupport::resetAnchor(QSGItem *item, const QString &name)
+void DesignerSupport::resetAnchor(QQuickItem *item, const QString &name)
 {
     if (name == QLatin1String("anchors.fill")) {
         anchors(item)->resetFill();
@@ -357,23 +357,23 @@ void DesignerSupport::resetAnchor(QSGItem *item, const QString &name)
     }
 }
 
-QList<QObject*> DesignerSupport::statesForItem(QSGItem *item)
+QList<QObject*> DesignerSupport::statesForItem(QQuickItem *item)
 {
     QList<QObject*> objectList;
-    QList<QDeclarativeState *> stateList = QSGItemPrivate::get(item)->_states()->states();
+    QList<QDeclarativeState *> stateList = QQuickItemPrivate::get(item)->_states()->states();
     qCopy(stateList.begin(), stateList.end(), objectList.begin());
 
     return objectList;
 }
 
-bool DesignerSupport::isComponentComplete(QSGItem *item)
+bool DesignerSupport::isComponentComplete(QQuickItem *item)
 {
-    return static_cast<QSGItemPrivate*>(QSGItemPrivate::get(item))->componentComplete;
+    return static_cast<QQuickItemPrivate*>(QQuickItemPrivate::get(item))->componentComplete;
 }
 
-int DesignerSupport::borderWidth(QSGItem *item)
+int DesignerSupport::borderWidth(QQuickItem *item)
 {
-    QSGRectangle *rectangle = qobject_cast<QSGRectangle*>(item);
+    QQuickRectangle *rectangle = qobject_cast<QQuickRectangle*>(item);
     if (rectangle)
         return rectangle->border()->width();
 
@@ -385,24 +385,24 @@ void DesignerSupport::refreshExpressions(QDeclarativeContext *context)
     QDeclarativeContextPrivate::get(context)->data->refreshExpressions();
 }
 
-void DesignerSupport::setRootItem(QSGView *view, QSGItem *item)
+void DesignerSupport::setRootItem(QQuickView *view, QQuickItem *item)
 {
-    QSGViewPrivate::get(view)->setRootObject(item);
+    QQuickViewPrivate::get(view)->setRootObject(item);
 }
 
-bool DesignerSupport::isValidWidth(QSGItem *item)
+bool DesignerSupport::isValidWidth(QQuickItem *item)
 {
-    return QSGItemPrivate::get(item)->heightValid;
+    return QQuickItemPrivate::get(item)->heightValid;
 }
 
-bool DesignerSupport::isValidHeight(QSGItem *item)
+bool DesignerSupport::isValidHeight(QQuickItem *item)
 {
-    return QSGItemPrivate::get(item)->widthValid;
+    return QQuickItemPrivate::get(item)->widthValid;
 }
 
-void DesignerSupport::updateDirtyNode(QSGItem *item)
+void DesignerSupport::updateDirtyNode(QQuickItem *item)
 {
-    QSGCanvasPrivate::get(item->canvas())->updateDirtyNode(item);
+    QQuickCanvasPrivate::get(item->canvas())->updateDirtyNode(item);
 }
 
 QT_END_NAMESPACE
index b52a4a2..8b9df68 100644 (file)
@@ -62,12 +62,12 @@ QT_BEGIN_NAMESPACE
 
 QT_MODULE(Declarative)
 
-class QSGItem;
-class QSGShaderEffectTexture;
+class QQuickItem;
+class QQuickShaderEffectTexture;
 class QImage;
 class QTransform;
 class QDeclarativeContext;
-class QSGView;
+class QQuickView;
 
 
 class Q_DECLARATIVE_EXPORT DesignerSupport
@@ -105,43 +105,43 @@ public:
     DesignerSupport();
     ~DesignerSupport();
 
-    void refFromEffectItem(QSGItem *referencedItem, bool hide = true);
-    void derefFromEffectItem(QSGItem *referencedItem, bool unhide = true);
+    void refFromEffectItem(QQuickItem *referencedItem, bool hide = true);
+    void derefFromEffectItem(QQuickItem *referencedItem, bool unhide = true);
 
-    QImage renderImageForItem(QSGItem *referencedItem, const QRectF &boundingRect, const QSize &imageSize);
+    QImage renderImageForItem(QQuickItem *referencedItem, const QRectF &boundingRect, const QSize &imageSize);
 
-    static bool isDirty(QSGItem *referencedItem, DirtyType dirtyType);
-    static void resetDirty(QSGItem *referencedItem);
+    static bool isDirty(QQuickItem *referencedItem, DirtyType dirtyType);
+    static void resetDirty(QQuickItem *referencedItem);
 
-    static QTransform canvasTransform(QSGItem *referencedItem);
-    static QTransform parentTransform(QSGItem *referencedItem);
+    static QTransform canvasTransform(QQuickItem *referencedItem);
+    static QTransform parentTransform(QQuickItem *referencedItem);
 
-    static bool isAnchoredTo(QSGItem *fromItem, QSGItem *toItem);
-    static bool areChildrenAnchoredTo(QSGItem *fromItem, QSGItem *toItem);
-    static bool hasAnchor(QSGItem *item, const QString &name);
-    static QSGItem *anchorFillTargetItem(QSGItem *item);
-    static QSGItem *anchorCenterInTargetItem(QSGItem *item);
-    static QPair<QString, QObject*> anchorLineTarget(QSGItem *item, const QString &name, QDeclarativeContext *context);
-    static void resetAnchor(QSGItem *item, const QString &name);
+    static bool isAnchoredTo(QQuickItem *fromItem, QQuickItem *toItem);
+    static bool areChildrenAnchoredTo(QQuickItem *fromItem, QQuickItem *toItem);
+    static bool hasAnchor(QQuickItem *item, const QString &name);
+    static QQuickItem *anchorFillTargetItem(QQuickItem *item);
+    static QQuickItem *anchorCenterInTargetItem(QQuickItem *item);
+    static QPair<QString, QObject*> anchorLineTarget(QQuickItem *item, const QString &name, QDeclarativeContext *context);
+    static void resetAnchor(QQuickItem *item, const QString &name);
 
 
-    static QList<QObject*> statesForItem(QSGItem *item);
+    static QList<QObject*> statesForItem(QQuickItem *item);
 
-    static bool isComponentComplete(QSGItem *item);
+    static bool isComponentComplete(QQuickItem *item);
 
-    static int borderWidth(QSGItem *item);
+    static int borderWidth(QQuickItem *item);
 
     static void refreshExpressions(QDeclarativeContext *context);
 
-    static void setRootItem(QSGView *view, QSGItem *item);
+    static void setRootItem(QQuickView *view, QQuickItem *item);
 
-    static bool isValidWidth(QSGItem *item);
-    static bool isValidHeight(QSGItem *item);
+    static bool isValidWidth(QQuickItem *item);
+    static bool isValidHeight(QQuickItem *item);
 
-    static void updateDirtyNode(QSGItem *item);
+    static void updateDirtyNode(QQuickItem *item);
 
 private:
-    QHash<QSGItem*, QSGShaderEffectTexture*> m_itemTextureHash;
+    QHash<QQuickItem*, QQuickShaderEffectTexture*> m_itemTextureHash;
 };
 
 QT_END_NAMESPACE
index 31ed75d..60b3e4b 100644 (file)
@@ -1,16 +1,16 @@
 SOURCES += \
-    $$PWD/qsgcanvasitem.cpp \
-    $$PWD/qsgcontext2d.cpp \
-    $$PWD/qsgcontext2dnode.cpp \
-    $$PWD/qsgcontext2dtile.cpp \
-    $$PWD/qsgcontext2dtexture.cpp \
-    $$PWD/qsgcontext2dcommandbuffer.cpp \
+    $$PWD/qquickcanvasitem.cpp \
+    $$PWD/qquickcontext2d.cpp \
+    $$PWD/qquickcontext2dnode.cpp \
+    $$PWD/qquickcontext2dtile.cpp \
+    $$PWD/qquickcontext2dtexture.cpp \
+    $$PWD/qquickcontext2dcommandbuffer.cpp \
 
 HEADERS += \
-    $$PWD/qsgcanvasitem_p.h \
-    $$PWD/qsgcontext2d_p.h \
-    $$PWD/qsgcontext2dnode_p.h \
-    $$PWD/qsgcontext2dtile_p.h \
-    $$PWD/qsgcontext2dtexture_p.h \
-    $$PWD/qsgcontext2dcommandbuffer_p.h \
+    $$PWD/qquickcanvasitem_p.h \
+    $$PWD/qquickcontext2d_p.h \
+    $$PWD/qquickcontext2dnode_p.h \
+    $$PWD/qquickcontext2dtile_p.h \
+    $$PWD/qquickcontext2dtexture_p.h \
+    $$PWD/qquickcontext2dcommandbuffer_p.h \
 
diff --git a/src/declarative/items/context2d/qquickcanvasitem.cpp b/src/declarative/items/context2d/qquickcanvasitem.cpp
new file mode 100644 (file)
index 0000000..86db5e6
--- /dev/null
@@ -0,0 +1,728 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include <private/qsgadaptationlayer_p.h>
+#include "qquickcanvasitem_p.h"
+#include <private/qquickitem_p.h>
+#include "qquickcontext2d_p.h"
+#include "qquickcontext2dnode_p.h"
+#include "qquickcontext2dtexture_p.h"
+#include <private/qdeclarativepixmapcache_p.h>
+
+#include <qdeclarativeinfo.h>
+#include <private/qdeclarativeengine_p.h>
+#include <QtCore/QBuffer>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickCanvasItemPrivate : public QQuickItemPrivate
+{
+public:
+    QQuickCanvasItemPrivate();
+    ~QQuickCanvasItemPrivate();
+    QQuickContext2D* context;
+    QQuickContext2DTexture* texture;
+    QSizeF canvasSize;
+    QSize tileSize;
+    QRectF canvasWindow;
+    QRectF dirtyRect;
+    uint renderInThread : 1;
+    uint hasCanvasSize :1;
+    uint hasTileSize :1;
+    uint hasCanvasWindow :1;
+    uint componentCompleted :1;
+    QQuickCanvasItem::RenderTarget renderTarget;
+    QHash<QUrl, QDeclarativePixmap*> images;
+    QUrl baseUrl;
+};
+
+QQuickCanvasItemPrivate::QQuickCanvasItemPrivate()
+    : QQuickItemPrivate()
+    , context(0)
+    , texture(0)
+    , canvasSize(1, 1)
+    , tileSize(1, 1)
+    , renderInThread(false)
+    , hasCanvasSize(false)
+    , hasTileSize(false)
+    , hasCanvasWindow(false)
+    , componentCompleted(false)
+    , renderTarget(QQuickCanvasItem::FramebufferObject)
+{
+}
+
+QQuickCanvasItemPrivate::~QQuickCanvasItemPrivate()
+{
+    qDeleteAll(images);
+}
+
+/*!
+    \qmlclass Canvas QQuickCanvasItem
+    \inqmlmodule QtQuick 2
+    \since QtQuick 2.0
+    \brief The Canvas item provides HTML5 like canvas element which enables you to
+    draw within the item area by using Javascript.
+    \inherits Item
+    \ingroup qml-basic-visual-elements
+
+    With the Canvas item, users can draw straight and curved lines, simple and
+    complex shapes, graphs, and referenced graphic images. can also add texts, colors,
+    shadows, gradients, and patterns, and do low level pixel operations, etc. The Canvas item
+    also enables you to save or export the canvas as a image file or serialize the image data
+    to data url string.
+
+    To define a drawing area in the Canvas item, just set the \c width and \c height properties.
+    For example, the following code creates a Canvas item which has a drawing area with a height of 100
+    pixels and width of 200 pixels:
+    \qml
+    import QtQuick 2.0
+    Canvas {
+      id:mycanvas
+      width:100
+      height:200
+    }
+    \endqml
+
+    Currently the Canvas item only supports the two-dimensional rendering context.
+
+    \section1 Thread Rendering and Render Target
+    The Canvas item supports two render targets:Canvas.Image and Canvas.FramebufferObject.
+    The Canvas.Image render target is a \a QImage object which is actually a block of system
+    memory. This render target support background thread rendering. So if some complex or long
+    running painting need to be done, the Canvas.Image with thread rendering mode should be
+    chosen to avoid blocking the UI. Otherwise the Canvas.FramebufferObject render target should
+    be chosen as it could be much faster with good OpenGL hardware accelaration than rendering into
+    system memory, especially when the CPU is already very busy.
+
+    The default render target is Canvas.Image and the default renderInThread property is
+    false.
+
+    \section1 Tiled Canvas
+    The Canvas item also supports tiled rendering mode by setting the proper canvasSize, tileSize
+    and the canvasWindow properties.
+
+    With tiled canvas, a virtually very large canvas can be provided by a relatively small canvas
+    window. The actual memory consumption only relates to the canvas window size. So the canvas size
+    can be chosen freely as needed. The painting code then doesn't need to worry about the coordinate
+    system and complex matrix transformations at all.
+
+    As a side effect, by setting a good tile size, the tiles overlapped with the canvas window could be
+    cached and don't need to redraw, which can improve the performance significantly in some situations.
+
+    \section1 Pixel Operations
+    The Canvas item support all HTML5 2d context pixel operations. In order to get better
+    pixel reading/writing performance, the Canvas.Image render target should be chosen. As
+    for Canvas.FramebufferObject render target, the pixel data need to be exchanged between
+    the system memory and the graphic card, which can't be benefit from the hardware acceleration
+    at all. And the OpenGL rendering may synchronise with the V-Sync signal to avoid the
+    {en.wikipedia.org/wiki/Screen_tearing}{screen tearing} which makes the pixel operations
+    even slower with the Canvas.FrambufferObject render target.
+
+    \section1 Tips for Porting Existing HTML5 Canvas applications
+
+    Although the Canvas item is provided as a HTML5 like API, and
+    the canvas context API is as compatible with HTML5 2d context standard
+    as possible, the working HTML5 canvas applications are still need to
+    be modified to run in the Canvas item:
+    \list
+    \o Removes and replaces all DOM API calls with QML property bindings or Canvas item methods.
+    \o Removes and replaces all HTML envent handlers with the \a MouseArea item.
+    \o Changes the setInterval/setTimeout function calls with the \a Timer item.
+    \o Puts the actual painting code into the \a QtQuick2::Canvas::onPaint handler and triggers the
+       painting by calling the Canvas's \c markDirty or \c requestPaint methods.
+    \o For drawing images, loads them by calling the Canvas's loadImage method and then request to paint
+       them in the onImageLoaded handler.
+    \endlist
+
+    \sa QtQuick2::Context2D
+*/
+
+QQuickCanvasItem::QQuickCanvasItem(QQuickItem *parent)
+    : QQuickItem(*(new QQuickCanvasItemPrivate), parent)
+{
+    setFlag(ItemHasContents);
+}
+
+QQuickCanvasItem::~QQuickCanvasItem()
+{
+    Q_D(QQuickCanvasItem);
+    delete d->context;
+}
+
+/*!
+    \qmlproperty size QtQuick2::Canvas::canvasSize
+     Holds the logical canvas size that the context paints on.
+
+     By default, the canvas size is the same size as the current canvas item size.
+     By setting the canvas size, tile size and canvas window, the Canvas
+     item can act as a virtual large canvas with many seperately rendered tile rectangle
+     areas. Only those tiles within the current canvas window would be painted by
+     the Canvas render engine.
+    \sa QtQuick2::Canvas::tileSize QtQuick2::Canvas::canvasWindow
+*/
+QSizeF QQuickCanvasItem::canvasSize() const
+{
+    Q_D(const QQuickCanvasItem);
+    return d->canvasSize;
+}
+
+void QQuickCanvasItem::setCanvasSize(const QSizeF & size)
+{
+    Q_D(QQuickCanvasItem);
+    if (d->canvasSize != size) {
+        d->hasCanvasSize = true;
+        d->canvasSize = size;
+        emit canvasSizeChanged();
+        polish();
+        update();
+    }
+}
+
+/*!
+    \qmlproperty size QtQuick2::Canvas::tileSize
+     Holds the canvas rendering tile size.
+
+     When the Canvas item in tiled mode by setting the canvas size, tile size and
+     the canvas window. The canvas render can improve the rendering performance
+     by rendering and caching tiles instead of rendering the whole canvas everytime.
+
+     Additionally, the canvas size could be infinitely large without allocating more
+     memories because only those tiles within the current visible region
+     are actually rendered.
+
+     By default, the tile size is the same with the canvas size.
+     \sa QtQuick2::Canvas::canvaasSize QtQuick2::Canvas::canvasWindow
+*/
+QSize QQuickCanvasItem::tileSize() const
+{
+    Q_D(const QQuickCanvasItem);
+    return d->tileSize;
+}
+
+void QQuickCanvasItem::setTileSize(const QSize & size)
+{
+    Q_D(QQuickCanvasItem);
+    if (d->tileSize != size) {
+        d->hasTileSize = true;
+        d->tileSize = size;
+
+        emit tileSizeChanged();
+        polish();
+        update();
+    }
+}
+
+/*!
+    \qmlproperty rect QtQuick2::Canvas::canvasWindow
+     Holds the current canvas visible window.
+
+     By default, the canvas window size is the same as the Canvas item
+     size with the topleft point as (0, 0).
+
+     If the canvas size is different with the Canvas item size, the Canvas
+     item can display different visible areas by changing the canvas window's size
+     and/or position.
+    \sa QtQuick2::Canvas::canvasSize QtQuick2::Canvas::tileSize
+*/
+QRectF QQuickCanvasItem::canvasWindow() const
+{
+    Q_D(const QQuickCanvasItem);
+    return d->canvasWindow;
+}
+
+void QQuickCanvasItem::setCanvasWindow(const QRectF& rect)
+{
+    Q_D(QQuickCanvasItem);
+    if (d->canvasWindow != rect) {
+        d->canvasWindow = rect;
+
+        d->hasCanvasWindow = true;
+        emit canvasWindowChanged();
+        polish();
+        update();
+    }
+}
+
+
+QQuickContext2D* QQuickCanvasItem::context() const
+{
+    Q_D(const QQuickCanvasItem);
+    return d->context;
+}
+/*!
+    \qmlproperty bool QtQuick2::Canvas::renderInThread
+     Holds the current canvas rendering mode.
+
+     By setting the renderInThread to true, complex and long
+     running painting can be rendered in a dedicated background
+     rendering thread to avoid blocking the main GUI.
+
+     Note: Different renderTarget may or may not support the
+     background rendering thread, if not, the renderInThread
+     property will be ignored.
+
+     The default value is false.
+    \sa QtQuick2::Canvas::renderTarget
+*/
+bool QQuickCanvasItem::renderInThread() const
+{
+    Q_D(const QQuickCanvasItem);
+    return d->renderInThread;
+}
+/*!
+    \qmlproperty bool QtQuick2::Canvas::renderTarget
+     Holds the current canvas render target.
+
+     \list
+     \o Canvas.Image  - render to an in memory image buffer, the render
+                        target supports background rendering.
+     \o Canvas.FramebufferObject - render to an OpenGL frame buffer,
+                                   this render target will ignore the
+                                   renderInThread property. The actual
+                                   rendering happens in the main QML rendering
+                                   process, which may be in a seperate render thread
+                                   or in the main GUI thread depends on the platforms.
+     \endlist
+
+     The default render target is \c Canvas.Image.
+    \sa QtQuick2::Canvas::renderInThread
+*/
+QQuickCanvasItem::RenderTarget QQuickCanvasItem::renderTarget() const
+{
+    Q_D(const QQuickCanvasItem);
+    return d->renderTarget;
+}
+
+void QQuickCanvasItem::setRenderTarget(RenderTarget target)
+{
+    Q_D(QQuickCanvasItem);
+    if (d->renderTarget != target) {
+        d->renderTarget = target;
+
+        if (d->componentCompleted)
+            createTexture();
+        emit renderTargetChanged();
+    }
+}
+
+void QQuickCanvasItem::_doPainting(const QRectF& region)
+{
+    Q_D(QQuickCanvasItem);
+    emit paint(QDeclarativeV8Handle::fromHandle(d->context->v8value())
+             , QQuickContext2DTexture::tiledRect(region, d->tileSize));
+    if (d->texture)
+        d->texture->wake();
+}
+
+/*!
+    \qmlproperty bool QtQuick2::Canvas::renderInThread
+     Holds the current canvas rendering mode.
+
+     When this property is true, all canvas painting commands
+     are rendered in a background rendering thread, otherwise
+     the rendering happens in the main GUI thread.
+
+     The default renderInThread value is false.
+*/
+void QQuickCanvasItem::setRenderInThread(bool renderInThread)
+{
+    Q_D(QQuickCanvasItem);
+    if (d->renderInThread != renderInThread) {
+        d->renderInThread = renderInThread;
+
+        if (d->componentCompleted)
+            createTexture();
+
+        if (d->renderInThread)
+            connect(this, SIGNAL(painted()), SLOT(update()));
+        else
+            disconnect(this, SIGNAL(painted()), this, SLOT(update()));
+        emit renderInThreadChanged();
+        polish();
+        update();
+    }
+}
+
+void QQuickCanvasItem::geometryChanged(const QRectF &newGeometry,
+                             const QRectF &oldGeometry)
+{
+    Q_D(QQuickCanvasItem);
+    QQuickItem::geometryChanged(newGeometry, oldGeometry);
+
+    const qreal w = newGeometry.width();
+    const qreal h = newGeometry.height();
+
+    if (!d->hasCanvasSize) {
+        d->canvasSize = QSizeF(w, h);
+        emit canvasSizeChanged();
+    }
+
+    if (!d->hasTileSize) {
+        d->tileSize = d->canvasSize.toSize();
+        emit tileSizeChanged();
+    }
+
+    if (!d->hasCanvasWindow) {
+        d->canvasWindow = newGeometry;
+        emit canvasWindowChanged();
+    }
+
+    polish();
+    update();
+}
+
+void QQuickCanvasItem::componentComplete()
+{
+    Q_D(QQuickCanvasItem);
+    QQuickItem::componentComplete();
+
+    if (!d->context)
+        createContext();
+    createTexture();
+
+    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 QQuickCanvasItem::updatePolish()
+{
+    Q_D(QQuickCanvasItem);
+    QQuickItem::updatePolish();
+    if (d->texture) {
+        if (!d->renderInThread && d->dirtyRect.isValid())
+            _doPainting(d->dirtyRect);
+
+        d->texture->canvasChanged(d->canvasSize.toSize()
+                                , d->tileSize
+                                , d->canvasWindow.toAlignedRect()
+                                , d->dirtyRect.toAlignedRect()
+                                , d->smooth);
+        d->dirtyRect = QRectF();
+    }
+}
+
+QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+    Q_D(QQuickCanvasItem);
+    QQuickContext2DNode *node = static_cast<QQuickContext2DNode *>(oldNode);
+    if (!node)
+        node = new QQuickContext2DNode(this);
+
+    node->setTexture(d->texture);
+    node->setSize(d->canvasWindow.size());
+    node->update();
+    return node;
+}
+
+void QQuickCanvasItem::createTexture()
+{
+    Q_D(QQuickCanvasItem);
+
+    if (!d->texture
+      || d->texture->threadRendering() != d->renderInThread
+      || d->texture->renderTarget() != d->renderTarget) {
+        if (d->texture) {
+            d->texture->deleteLater();
+            d->texture = 0;
+        }
+
+        if (d->renderTarget == QQuickCanvasItem::Image) {
+            d->texture = new QQuickContext2DImageTexture(d->renderInThread);
+        } else if (d->renderTarget == QQuickCanvasItem::FramebufferObject) {
+            d->texture = new QQuickContext2DFBOTexture();
+        }
+
+        if (d->renderInThread && !d->texture->supportThreadRendering()) {
+            qWarning("Canvas: render target does not support thread rendering, force to non-thread rendering mode.");
+            d->renderInThread = false;
+            emit renderInThreadChanged();
+        }
+
+        if (d->renderInThread)
+            connect(d->texture, SIGNAL(textureChanged()), this, SLOT(update()));
+
+        d->texture->setItem(this);
+    }
+}
+
+void QQuickCanvasItem::createContext()
+{
+    Q_D(QQuickCanvasItem);
+
+    delete d->context;
+
+    d->context = new QQuickContext2D(this);
+
+    QV8Engine *e = QDeclarativeEnginePrivate::getV8Engine(qmlEngine(this));
+    d->context->setV8Engine(e);
+}
+
+/*!
+  \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
+  returned, otherwise returns an invalid value.
+  */
+QDeclarativeV8Handle QQuickCanvasItem::getContext(const QString &contextId)
+{
+    Q_D(QQuickCanvasItem);
+
+    if (contextId.toLower() != QLatin1String("2d"))
+        return QDeclarativeV8Handle::fromHandle(v8::Undefined());
+
+    if (!d->context)
+        createContext();
+    return QDeclarativeV8Handle::fromHandle(d->context->v8value());
+}
+
+/*!
+  \qmlmethod void QtQuick2::Canvas::markDirty(rect region)
+
+  Mark the given \a region as dirty, so that when this region is visible
+  the canvas render will redraw it. During the rendering process, the
+  canvas renderer may emit the canvas' "paint" signal so the actual painting
+  scripts can be putted into the canvas's "onPaint" signal handler function.
+
+  \sa QtQuick2::Canvas::paint QtQuick2::Canvas::requestPaint
+  */
+void QQuickCanvasItem::markDirty(const QRectF& region)
+{
+    Q_D(QQuickCanvasItem);
+    d->dirtyRect |= region;
+    if (d->componentCompleted)
+        polish();
+    update();
+}
+
+
+/*!
+  \qmlmethod bool QtQuick2::Canvas::save(string filename)
+
+   Save the current canvas content into an image file \a filename.
+   The saved image format is automatically decided by the \a filename's
+   suffix.
+
+   Note: calling this method will force painting the whole canvas, not the
+   current canvas visible window.
+
+   \sa canvasWindow canvasSize toDataURL
+  */
+bool QQuickCanvasItem::save(const QString &filename) const
+{
+    Q_D(const QQuickCanvasItem);
+    QUrl url = d->baseUrl.resolved(QUrl::fromLocalFile(filename));
+    return toImage().save(url.toLocalFile());
+}
+
+QImage QQuickCanvasItem::loadedImage(const QUrl& url)
+{
+    Q_D(QQuickCanvasItem);
+    QUrl fullPathUrl = d->baseUrl.resolved(url);
+    if (!d->images.contains(fullPathUrl)) {
+        loadImage(url);
+    }
+    QDeclarativePixmap* pix = d->images.value(fullPathUrl);
+    if (pix->isLoading() || pix->isError()) {
+        return QImage();
+    }
+    return pix->pixmap().toImage();
+}
+
+/*!
+  \qmlmethod void QtQuick2::Canvas::loadImage(url image)
+    Loads the given \c image asynchronously, when the image is
+    ready, an imageLoaded signal will be emitted.
+    The loaded image can be unloaded by the \a QtQuick2::Canvas::unloadImage method.
+
+    Note: Only loaded images can be painted on the Canvas item.
+  \sa QtQuick2::Canvas::unloadImage QtQuick2::Canvas::imageLoaded QtQuick2::Canvas::isImageLoaded
+  \sa QtQuick2::Context2D::createImageData QtQuick2::Context2D::drawImage
+  */
+void QQuickCanvasItem::loadImage(const QUrl& url)
+{
+    Q_D(QQuickCanvasItem);
+    QUrl fullPathUrl = d->baseUrl.resolved(url);
+    if (!d->images.contains(fullPathUrl)) {
+        QDeclarativePixmap* pix = new QDeclarativePixmap();
+        d->images.insert(fullPathUrl, pix);
+
+        pix->load(qmlEngine(this)
+                , fullPathUrl
+                , QDeclarativePixmap::Cache | QDeclarativePixmap::Asynchronous);
+        pix->connectFinished(this, SIGNAL(imageLoaded()));
+    }
+}
+/*!
+  \qmlmethod void QtQuick2::Canvas::loadImage(url image)
+  Unloads the \c image.
+
+  If the image is unloaded from the Canvas item, it can't be painted by the canvas context
+  until it's loaded again.
+
+  \sa QtQuick2::Canvas::loadImage QtQuick2::Canvas::imageLoaded QtQuick2::Canvas::isImageLoaded
+  \sa QtQuick2::Context2D::createImageData QtQuick2::Context2D::drawImage
+  */
+void QQuickCanvasItem::unloadImage(const QUrl& url)
+{
+    Q_D(QQuickCanvasItem);
+    QUrl removeThis = d->baseUrl.resolved(url);
+    if (d->images.contains(removeThis)) {
+        delete d->images.value(removeThis);
+        d->images.remove(removeThis);
+    }
+}
+
+/*!
+  \qmlmethod void QtQuick2::Canvas::isImageError(url image)
+  Returns true if the image can't be loaded because of error happens.
+
+  \sa QtQuick2::Canvas::loadImage
+  */
+bool QQuickCanvasItem::isImageError(const QUrl& url) const
+{
+    Q_D(const QQuickCanvasItem);
+    QUrl fullPathUrl = d->baseUrl.resolved(url);
+    return d->images.contains(fullPathUrl)
+        && d->images.value(fullPathUrl)->isError();
+}
+
+/*!
+  \qmlmethod void QtQuick2::Canvas::isImageLoading(url image)
+  Returns true if the Canvas item still is loading the \c image.
+
+  \sa QtQuick2::Canvas::loadImage
+  */
+bool QQuickCanvasItem::isImageLoading(const QUrl& url) const
+{
+    Q_D(const QQuickCanvasItem);
+    QUrl fullPathUrl = d->baseUrl.resolved(url);
+    return d->images.contains(fullPathUrl)
+        && d->images.value(fullPathUrl)->isLoading();
+}
+/*!
+  \qmlmethod void QtQuick2::Canvas::isImageLoaded(url image)
+  Returns true if the \c image is sucessfully loaded and ready to use.
+
+  \sa QtQuick2::Canvas::loadImage
+  */
+bool QQuickCanvasItem::isImageLoaded(const QUrl& url) const
+{
+    Q_D(const QQuickCanvasItem);
+    QUrl fullPathUrl = d->baseUrl.resolved(url);
+    return d->images.contains(fullPathUrl)
+        && d->images.value(fullPathUrl)->isReady();
+}
+
+QImage QQuickCanvasItem::toImage(const QRectF& region) const
+{
+    Q_D(const QQuickCanvasItem);
+    if (d->texture) {
+        if (region.isEmpty())
+            return d->texture->toImage(canvasWindow());
+        else
+            return d->texture->toImage(region);
+    }
+    return QImage();
+}
+
+/*!
+  \qmlmethod string QtQuick2::Canvas::toDataURL(string mimeType)
+
+   Returns a data: URL for the image in the canvas.
+
+   The default \a mimeType is "image/png".
+
+   \sa QtQuick2::Canvas::save
+  */
+QString QQuickCanvasItem::toDataURL(const QString& mimeType) const
+{
+    QImage image = toImage();
+
+    if (!image.isNull()) {
+        QByteArray ba;
+        QBuffer buffer(&ba);
+        buffer.open(QIODevice::WriteOnly);
+        QString mime = mimeType.toLower();
+        QString type;
+        if (mime == QLatin1Literal("image/png")) {
+            type = QLatin1Literal("PNG");
+        } else if (mime == QLatin1Literal("image/bmp"))
+            type = QLatin1Literal("BMP");
+        else if (mime == QLatin1Literal("image/jpeg"))
+            type = QLatin1Literal("JPEG");
+        else if (mime == QLatin1Literal("image/x-portable-pixmap"))
+            type = QLatin1Literal("PPM");
+        else if (mime == QLatin1Literal("image/tiff"))
+            type = QLatin1Literal("TIFF");
+        else if (mime == QLatin1Literal("image/xpm"))
+            type = QLatin1Literal("XPM");
+        else
+            return QLatin1Literal("data:,");
+
+        image.save(&buffer, type.toAscii());
+        buffer.close();
+        QString dataUrl = QLatin1Literal("data:%1;base64,%2");
+        return dataUrl.arg(mime).arg(QLatin1String(ba.toBase64().constData()));
+    }
+    return QLatin1Literal("data:,");
+}
+
+/*!
+    \qmlsignal QtQuick2::Canvas::onPaint(QtQuick2::Context2D context, rect region)
+
+    This handler is called before the given \c region needs to be rendered.
+
+    This signal can be triggered by QtQuick2::Canvas::markdirty, QtQuick2::Canvas::requestPaint
+    or by changing the current canvas window.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Canvas::onPainted()
+
+    This handler is called after all context painting commands are executed and
+    the Canvas is actually rendered.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/context2d/qquickcanvasitem_p.h b/src/declarative/items/context2d/qquickcanvasitem_p.h
new file mode 100644 (file)
index 0000000..e026119
--- /dev/null
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** 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 QQUICKCANVASITEM_P_H
+#define QQUICKCANVASITEM_P_H
+
+#include <qquickitem.h>
+#include <private/qv8engine_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class QQuickContext2D;
+class QQuickCanvasItemPrivate;
+class Q_DECLARATIVE_EXPORT QQuickCanvasItem : public QQuickItem
+{
+    Q_OBJECT
+    Q_ENUMS(RenderTarget)
+    Q_ENUMS(ImageFilterMode)
+
+    Q_PROPERTY(QSizeF canvasSize READ canvasSize WRITE setCanvasSize NOTIFY canvasSizeChanged)
+    Q_PROPERTY(QSize tileSize READ tileSize WRITE setTileSize NOTIFY tileSizeChanged)
+    Q_PROPERTY(QRectF canvasWindow READ canvasWindow WRITE setCanvasWindow NOTIFY canvasWindowChanged)
+    Q_PROPERTY(bool renderInThread READ renderInThread WRITE setRenderInThread NOTIFY renderInThreadChanged)
+    Q_PROPERTY(RenderTarget renderTarget READ renderTarget WRITE setRenderTarget NOTIFY renderTargetChanged)
+public:
+    enum RenderTarget {
+        Image,
+        FramebufferObject
+    };
+
+    enum ImageFilterMode {
+        Threshold,
+        Mono,
+        GrayScale,
+        Brightness,
+        Invert,
+        Blur,
+        Opaque,
+        Convolute
+    };
+
+    QQuickCanvasItem(QQuickItem *parent = 0);
+    ~QQuickCanvasItem();
+
+    QSizeF canvasSize() const;
+    void setCanvasSize(const QSizeF &);
+
+    QSize tileSize() const;
+    void setTileSize(const QSize &);
+
+    QRectF canvasWindow() const;
+    void setCanvasWindow(const QRectF& rect);
+
+    bool renderInThread() const;
+    void setRenderInThread(bool renderInThread);
+
+    RenderTarget renderTarget() const;
+    void setRenderTarget(RenderTarget target);
+
+    QQuickContext2D* context() const;
+    QImage toImage(const QRectF& region = QRectF()) const;
+
+    QImage loadedImage(const QUrl& url);
+Q_SIGNALS:
+    void paint(QDeclarativeV8Handle context, const QRect &region);
+    void painted();
+    void canvasSizeChanged();
+    void tileSizeChanged();
+    void renderInThreadChanged();
+    void textureChanged();
+    void canvasWindowChanged();
+    void renderTargetChanged();
+    void imageLoaded();
+public Q_SLOTS:
+    QString toDataURL(const QString& type = QLatin1String("image/png")) const;
+    QDeclarativeV8Handle getContext(const QString & = QLatin1String("2d"));
+    void markDirty(const QRectF& region);
+    void requestPaint() {markDirty(canvasWindow());}
+    // Save current canvas to disk
+    bool save(const QString& filename) const;
+    void loadImage(const QUrl& url);
+    void unloadImage(const QUrl& url);
+    bool isImageLoaded(const QUrl& url) const;
+    bool isImageLoading(const QUrl& url) const;
+    bool isImageError(const QUrl& url) const;
+private Q_SLOTS:
+    void _doPainting(const QRectF& region);
+protected:
+    virtual void componentComplete();
+    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+    virtual void geometryChanged(const QRectF &newGeometry,
+                                 const QRectF &oldGeometry);
+    virtual void updatePolish();
+private:
+    void createContext();
+    void createTexture();
+    Q_DECLARE_PRIVATE(QQuickCanvasItem)
+    friend class QQuickContext2D;
+    friend class QQuickContext2DTexture;
+};
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickCanvasItem)
+
+QT_END_HEADER
+
+#endif //QQUICKCANVASITEM_P_H
diff --git a/src/declarative/items/context2d/qquickcontext2d.cpp b/src/declarative/items/context2d/qquickcontext2d.cpp
new file mode 100644 (file)
index 0000000..0c0865b
--- /dev/null
@@ -0,0 +1,3534 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qquickcontext2d_p.h"
+#include "qquickcontext2dcommandbuffer_p.h"
+#include "qquickcanvasitem_p.h"
+#include <private/qquickitem_p.h>
+#include <private/qquickshadereffectsource_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/qquickimage_p_p.h>
+
+#include <QtGui/qguiapplication.h>
+#include <qdeclarativeinfo.h>
+#include <QtCore/qmath.h>
+#include <private/qv8engine_p.h>
+
+#include <qdeclarativeengine.h>
+#include <private/qv8domerrors_p.h>
+#include <QtCore/qnumeric.h>
+
+QT_BEGIN_NAMESPACE
+/*!
+    \qmlclass Context2D QQuickContext2D
+    \inqmlmodule QtQuick 2
+    \since QtQuick 2.0
+    \brief The Context2D API allows you to draw 2d graphic shapes on the \c Canvas item.
+
+    The Context2D object can be created by \c Canvas item's \c getContext() method:
+    \code
+    Canvas {
+      id:canvas
+      onPaint:{
+         var ctx = canvas.getContext('2d');
+         //...
+      }
+    }
+    \endcode
+    The Context2D API implements the same \l {http://www.w3.org/TR/2dcontext}{W3C Canvas 2D Context API standard}
+    with some enhanced features.
+
+    The Context2D API provides the rendering \bold{context} which defines the methods and attributes needed to draw
+    on the \c Canvas item. The following assigns the canvas rendering context to a \c{context}
+    variable:
+    \code
+    var context = mycanvas.getContext("2d")
+    \endcode
+
+    The Context2D API renders the canvas as a coordinate system whose origin (0,0) is
+    at the top left corner, as shown in the figure below. Coordinates increase along
+    the \c{x} axis from left to right and along the \c{y} axis from top to bottom of
+    the canvas.
+    \image qml-item-canvas-context.gif
+*/
+static const double Q_PI   = 3.14159265358979323846;   // pi
+
+#define DEGREES(t) ((t) * 180.0 / Q_PI)
+
+#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");
+#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)
+{
+    v8::String::AsciiValue str(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);
+
+        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);
+
+        p+=3; //skip "rgb" or "hsl"
+        hasAlpha = (*p == 'a') ? true : false;
+
+        ++p; //skip "("
+
+        if (hasAlpha) ++p; //skip "a"
+
+        int rh, gs, bl, alpha = 255;
+
+        //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);
+        }
+
+        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) {
+    QFont font;
+     // ### this is simplified and incomplete
+    // ### TODO:get code from Qt webkit
+     QStringList tokens = fontString.split(QLatin1String(" "));
+     foreach (const QString &token, tokens) {
+         if (token == QLatin1String("italic"))
+             font.setItalic(true);
+         else if (token == QLatin1String("bold"))
+             font.setBold(true);
+         else if (token.endsWith(QLatin1String("px"))) {
+             QString number = token;
+             number.remove(QLatin1String("px"));
+             //font.setPointSizeF(number.trimmed().toFloat());
+             font.setPixelSize(number.trimmed().toInt());
+         } else
+             font.setFamily(token);
+     }
+
+     return font;
+}
+
+
+
+class QQuickContext2DEngineData : public QV8Engine::Deletable
+{
+public:
+    QQuickContext2DEngineData(QV8Engine *engine);
+    ~QQuickContext2DEngineData();
+
+    v8::Persistent<v8::Function> constructorContext;
+    v8::Persistent<v8::Function> constructorGradient;
+    v8::Persistent<v8::Function> constructorPattern;
+    v8::Persistent<v8::Function> constructorPixelArray;
+    v8::Persistent<v8::Function> constructorImageData;
+};
+
+V8_DEFINE_EXTENSION(QQuickContext2DEngineData, engineData)
+
+class QV8Context2DResource : public QV8ObjectResource
+{
+    V8_RESOURCE_TYPE(Context2DType)
+public:
+    QV8Context2DResource(QV8Engine *e) : QV8ObjectResource(e) {}
+    QQuickContext2D* context;
+};
+
+class QV8Context2DStyleResource : public QV8ObjectResource
+{
+    V8_RESOURCE_TYPE(Context2DStyleType)
+public:
+    QV8Context2DStyleResource(QV8Engine *e)
+      : QV8ObjectResource(e)
+      , patternRepeatX(false)
+      , patternRepeatY(false)
+    {}
+    QBrush brush;
+    bool patternRepeatX:1;
+    bool patternRepeatY:1;
+};
+
+class QV8Context2DPixelArrayResource : public QV8ObjectResource
+{
+    V8_RESOURCE_TYPE(Context2DPixelArrayType)
+public:
+    QV8Context2DPixelArrayResource(QV8Engine *e) : QV8ObjectResource(e) {}
+
+    QImage image;
+};
+
+QImage qt_image_convolute_filter(const QImage& src, const QVector<qreal>& weights, int radius = 0)
+{
+    int sides = radius ? radius : qRound(qSqrt(weights.size()));
+    int half = qFloor(sides/2);
+
+    QImage dst = QImage(src.size(), src.format());
+    int w = src.width();
+    int h = src.height();
+    for (int y = 0; y < dst.height(); ++y) {
+      QRgb *dr = (QRgb*)dst.scanLine(y);
+      for (int x = 0; x < dst.width(); ++x) {
+          unsigned char* dRgb = ((unsigned char*)&dr[x]);
+          unsigned char red=0, green=0, blue=0, alpha=0;
+          int sy = y;
+          int sx = x;
+
+          for (int cy=0; cy<sides; cy++) {
+             for (int cx=0; cx<sides; cx++) {
+               int scy = sy + cy - half;
+               int scx = sx + cx - half;
+               if (scy >= 0 && scy < w && scx >= 0 && scx < h) {
+                  const QRgb *sr = (const QRgb*)(src.constScanLine(scy));
+                  const unsigned char* sRgb = ((const unsigned char*)&sr[scx]);
+                  qreal wt = radius ? weights[0] : weights[cy*sides+cx];
+                  red += sRgb[0] * wt;
+                  green += sRgb[1] * wt;
+                  blue += sRgb[2] * wt;
+                  alpha += sRgb[3] * wt;
+               }
+             }
+          }
+          dRgb[0] = red;
+          dRgb[1] = green;
+          dRgb[2] = blue;
+          dRgb[3] = alpha;
+      }
+    }
+    return dst;
+}
+
+void qt_image_boxblur(QImage& image, int radius, bool quality)
+{
+    int passes = quality? 3: 1;
+    for (int i=0; i < passes; i++) {
+        image = qt_image_convolute_filter(image, QVector<qreal>() << 1.0/(radius * radius * 1.0), radius);
+    }
+}
+
+static QPainter::CompositionMode qt_composite_mode_from_string(const QString &compositeOperator)
+{
+    if (compositeOperator == QLatin1String("source-over")) {
+        return QPainter::CompositionMode_SourceOver;
+    } else if (compositeOperator == QLatin1String("source-out")) {
+        return QPainter::CompositionMode_SourceOut;
+    } else if (compositeOperator == QLatin1String("source-in")) {
+        return QPainter::CompositionMode_SourceIn;
+    } else if (compositeOperator == QLatin1String("source-atop")) {
+        return QPainter::CompositionMode_SourceAtop;
+    } else if (compositeOperator == QLatin1String("destination-atop")) {
+        return QPainter::CompositionMode_DestinationAtop;
+    } else if (compositeOperator == QLatin1String("destination-in")) {
+        return QPainter::CompositionMode_DestinationIn;
+    } else if (compositeOperator == QLatin1String("destination-out")) {
+        return QPainter::CompositionMode_DestinationOut;
+    } else if (compositeOperator == QLatin1String("destination-over")) {
+        return QPainter::CompositionMode_DestinationOver;
+    } else if (compositeOperator == QLatin1String("lighter")) {
+        return QPainter::CompositionMode_Lighten;
+    } else if (compositeOperator == QLatin1String("copy")) {
+        return QPainter::CompositionMode_Source;
+    } else if (compositeOperator == QLatin1String("xor")) {
+        return QPainter::CompositionMode_Xor;
+    } else if (compositeOperator == QLatin1String("qt-clear")) {
+        return QPainter::CompositionMode_Clear;
+    } else if (compositeOperator == QLatin1String("qt-destination")) {
+        return QPainter::CompositionMode_Destination;
+    } else if (compositeOperator == QLatin1String("qt-multiply")) {
+        return QPainter::CompositionMode_Multiply;
+    } else if (compositeOperator == QLatin1String("qt-screen")) {
+        return QPainter::CompositionMode_Screen;
+    } else if (compositeOperator == QLatin1String("qt-overlay")) {
+        return QPainter::CompositionMode_Overlay;
+    } else if (compositeOperator == QLatin1String("qt-darken")) {
+        return QPainter::CompositionMode_Darken;
+    } else if (compositeOperator == QLatin1String("qt-lighten")) {
+        return QPainter::CompositionMode_Lighten;
+    } else if (compositeOperator == QLatin1String("qt-color-dodge")) {
+        return QPainter::CompositionMode_ColorDodge;
+    } else if (compositeOperator == QLatin1String("qt-color-burn")) {
+        return QPainter::CompositionMode_ColorBurn;
+    } else if (compositeOperator == QLatin1String("qt-hard-light")) {
+        return QPainter::CompositionMode_HardLight;
+    } else if (compositeOperator == QLatin1String("qt-soft-light")) {
+        return QPainter::CompositionMode_SoftLight;
+    } else if (compositeOperator == QLatin1String("qt-difference")) {
+        return QPainter::CompositionMode_Difference;
+    } else if (compositeOperator == QLatin1String("qt-exclusion")) {
+        return QPainter::CompositionMode_Exclusion;
+    }
+    return QPainter::CompositionMode_SourceOver;
+}
+
+static QString qt_composite_mode_to_string(QPainter::CompositionMode op)
+{
+    switch (op) {
+    case QPainter::CompositionMode_SourceOver:
+        return QLatin1String("source-over");
+    case QPainter::CompositionMode_DestinationOver:
+        return QLatin1String("destination-over");
+    case QPainter::CompositionMode_Clear:
+        return QLatin1String("qt-clear");
+    case QPainter::CompositionMode_Source:
+        return QLatin1String("copy");
+    case QPainter::CompositionMode_Destination:
+        return QLatin1String("qt-destination");
+    case QPainter::CompositionMode_SourceIn:
+        return QLatin1String("source-in");
+    case QPainter::CompositionMode_DestinationIn:
+        return QLatin1String("destination-in");
+    case QPainter::CompositionMode_SourceOut:
+        return QLatin1String("source-out");
+    case QPainter::CompositionMode_DestinationOut:
+        return QLatin1String("destination-out");
+    case QPainter::CompositionMode_SourceAtop:
+        return QLatin1String("source-atop");
+    case QPainter::CompositionMode_DestinationAtop:
+        return QLatin1String("destination-atop");
+    case QPainter::CompositionMode_Xor:
+        return QLatin1String("xor");
+    case QPainter::CompositionMode_Plus:
+        return QLatin1String("plus");
+    case QPainter::CompositionMode_Multiply:
+        return QLatin1String("qt-multiply");
+    case QPainter::CompositionMode_Screen:
+        return QLatin1String("qt-screen");
+    case QPainter::CompositionMode_Overlay:
+        return QLatin1String("qt-overlay");
+    case QPainter::CompositionMode_Darken:
+        return QLatin1String("qt-darken");
+    case QPainter::CompositionMode_Lighten:
+        return QLatin1String("lighter");
+    case QPainter::CompositionMode_ColorDodge:
+        return QLatin1String("qt-color-dodge");
+    case QPainter::CompositionMode_ColorBurn:
+        return QLatin1String("qt-color-burn");
+    case QPainter::CompositionMode_HardLight:
+        return QLatin1String("qt-hard-light");
+    case QPainter::CompositionMode_SoftLight:
+        return QLatin1String("qt-soft-light");
+    case QPainter::CompositionMode_Difference:
+        return QLatin1String("qt-difference");
+    case QPainter::CompositionMode_Exclusion:
+        return QLatin1String("qt-exclusion");
+    default:
+        break;
+    }
+    return QString();
+}
+
+
+static v8::Local<v8::Object> qt_create_image_data(qreal w, qreal h, QV8Engine* engine, const QImage& image)
+{
+    QQuickContext2DEngineData *ed = engineData(engine);
+    v8::Local<v8::Object> imageData = ed->constructorImageData->NewInstance();
+    QV8Context2DPixelArrayResource *r = new QV8Context2DPixelArrayResource(engine);
+    if (image.isNull()) {
+        r->image = QImage(w, h, QImage::Format_ARGB32);
+        r->image.fill(0x00000000);
+    } else {
+        Q_ASSERT(image.width() == w && image.height() == h);
+        r->image = image.format() == QImage::Format_ARGB32 ? image : image.convertToFormat(QImage::Format_ARGB32);
+    }
+    v8::Local<v8::Object> pixelData = ed->constructorPixelArray->NewInstance();
+    pixelData->SetExternalResource(r);
+
+    imageData->SetInternalField(0, pixelData);
+    return imageData;
+}
+
+//static script functions
+
+/*!
+    \qmlproperty QtQuick2::Canvas QtQuick2::Context2D::canvas
+     Holds the canvas item that the context paints on.
+
+     This property is read only.
+*/
+static v8::Handle<v8::Value> ctx2d_canvas(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT(r)
+
+
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+    return engine->newQObject(r->context->canvas());
+}
+
+/*!
+    \qmlmethod object QtQuick2::Context2D::restore()
+    Pops the top state on the stack, restoring the context to that state.
+
+    \sa QtQuick2::Context2D::save()
+*/
+static v8::Handle<v8::Value> ctx2d_restore(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+    r->context->popState();
+    return args.This();
+}
+
+/*!
+    \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)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+    r->context->reset();
+    r->context->m_path = QPainterPath();
+    r->context->m_path.setFillRule(Qt::WindingFill);
+
+    return args.This();
+}
+
+/*!
+    \qmlmethod object QtQuick2::Context2D::save()
+    Pushes the current state onto the state stack.
+
+    Before changing any state attributes, you should save the current state
+    for future reference. The context maintains a stack of drawing states.
+    Each state consists of the current transformation matrix, clipping region,
+    and values of the following attributes:
+    \list
+    \o\a QtQuick2::Context2D::strokeStyle
+    \o\a QtQuick2::Context2D::fillStyle
+    \o\a QtQuick2::Context2D::fillRule
+    \o\a QtQuick2::Context2D::globalAlpha
+    \o\a QtQuick2::Context2D::lineWidth
+    \o\a QtQuick2::Context2D::lineCap
+    \o\a QtQuick2::Context2D::lineJoin
+    \o\a QtQuick2::Context2D::miterLimit
+    \o\a QtQuick2::Context2D::shadowOffsetX
+    \o\a QtQuick2::Context2D::shadowOffsetY
+    \o\a QtQuick2::Context2D::shadowBlur
+    \o\a QtQuick2::Context2D::shadowColor
+    \o\a QtQuick2::Context2D::globalCompositeOperation
+    \o\a QtQuick2::Context2D::font
+    \o\a QtQuick2::Context2D::textAlign
+    \o\a QtQuick2::Context2D::textBaseline
+    \endlist
+
+    The current path is NOT part of the drawing state. The path can be reset by
+    invoking the \a QtQuick2::Context2D::beginPath() method.
+*/
+static v8::Handle<v8::Value> ctx2d_save(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+    r->context->pushState();
+
+    return args.This();
+}
+
+// transformations
+/*!
+    \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);
+    \endcode
+    \image qml-item-canvas-rotate.png
+
+    The rotation transformation matrix is as follows:
+
+    \image qml-item-canvas-math-rotate.png
+
+    where the \c angle of rotation is in radians.
+
+*/
+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);
+    }
+
+    return args.This();
+}
+
+/*!
+    \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
+    vertical direction.
+    The following code doubles the horizontal size of an object drawn on the canvas and half its
+    vertical size:
+    \code
+    ctx.scale(2.0, 0.5);
+    \endcode
+    \image qml-item-canvas-scale.png
+
+*/
+static v8::Handle<v8::Value> ctx2d_scale(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+
+    if (args.Length() == 2) {
+        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);
+    }
+
+    return args.This();
+}
+
+/*!
+    \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,
+    rotating, and translating transformations in a single step.
+
+    Each point on the canvas is multiplied by the matrix before anything is
+    drawn. The \l{HTML5 Canvas API} defines the transformation matrix as:
+
+    \image qml-item-canvas-math.png
+    where:
+    \list
+    \o \c{a} is the scale factor in the horizontal (x) direction
+    \image qml-item-canvas-scalex.png
+    \o \c{c} is the skew factor in the x direction
+    \image qml-item-canvas-canvas-skewx.png
+    \o \c{e} is the translation in the x direction
+    \image qml-item-canvas-canvas-translate.png
+    \o \c{b} is the skew factor in the y (vertical) direction
+    \image qml-item-canvas-canvas-skewy.png
+    \o \c{d} is the scale factor in the y direction
+    \image qml-item-canvas-canvas-scaley.png
+    \o \c{f} is the translation in the y direction
+    \image qml-item-canvas-canvas-translatey.png
+    \o the last row remains constant
+    \endlist
+    The scale factors and skew factors are multiples; \c{e} and \c{f} are
+    coordinate space units, just like the units in the \a QtQuick2::Context2D::translate(x,y)
+    method.
+
+    \sa QtQuick2::Context2D::transform()
+*/
+static v8::Handle<v8::Value> ctx2d_setTransform(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+
+    if (args.Length() == 6) {
+        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);
+    }
+
+    return args.This();
+}
+
+/*!
+    \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.
+
+    The \a setTransform(a, b, c, d, e, f) method actually resets the current transform to the identity matrix,
+    and then invokes the transform(a, b, c, d, e, f) method with the same arguments.
+
+    \sa QtQuick2::Context2D::setTransform()
+*/
+static v8::Handle<v8::Value> ctx2d_transform(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+
+    if (args.Length() == 6) {
+        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);
+    }
+
+    return args.This();
+}
+
+/*!
+    \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,
+    \c y is the vertical distance that the origin is translated, in coordinate space units.
+    Translating the origin enables you to draw patterns of different objects on the canvas
+    without having to measure the coordinates manually for each shape.
+*/
+static v8::Handle<v8::Value> ctx2d_translate(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+
+    if (args.Length() == 2) {
+        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);
+    }
+
+    return args.This();
+}
+
+
+/*!
+    \qmlmethod object QtQuick2::Context2D::resetTransform()
+    Reset the transformation matrix to default value.
+
+    \sa QtQuick2::Context2D::transform(), QtQuick2::Context2D::setTransform(), QtQuick2::Context2D::reset()
+*/
+static v8::Handle<v8::Value> ctx2d_resetTransform(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+    r->context->state.matrix = QTransform();
+    r->context->buffer()->updateMatrix(r->context->state.matrix);
+
+    return args.This();
+}
+
+
+/*!
+    \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)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+    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
+
+/*!
+    \qmlproperty real QtQuick2::Context2D::globalAlpha
+     Holds the the current alpha value applied to rendering operations.
+     The value must be in the range from 0.0 (fully transparent) to 1.0 (fully opque).
+     The default value is 1.0.
+*/
+static v8::Handle<v8::Value> ctx2d_globalAlpha(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT(r)
+
+    return v8::Number::New(r->context->state.globalAlpha);
+}
+
+static void ctx2d_globalAlpha_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT_SETTER(r)
+
+    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);
+    }
+}
+
+/*!
+    \qmlproperty string QtQuick2::Context2D::globalCompositeOperation
+     Holds the the current the current composition operation, from the list below:
+     \list
+     \o source-atop      - A atop B. Display the source image wherever both images are opaque.
+                           Display the destination image wherever the destination image is opaque but the source image is transparent.
+                           Display transparency elsewhere.
+     \o source-in        - A in B. Display the source image wherever both the source image and destination image are opaque.
+                           Display transparency elsewhere.
+     \o source-out       - A out B. Display the source image wherever the source image is opaque and the destination image is transparent.
+                           Display transparency elsewhere.
+     \o source-over      - (default) A over B. Display the source image wherever the source image is opaque.
+                           Display the destination image elsewhere.
+     \o destination-atop - B atop A. Same as source-atop but using the destination image instead of the source image and vice versa.
+     \o destination-in   - B in A. Same as source-in but using the destination image instead of the source image and vice versa.
+     \o destination-out  - B out A. Same as source-out but using the destination image instead of the source image and vice versa.
+     \o destination-over - B over A. Same as source-over but using the destination image instead of the source image and vice versa.
+     \o lighter          - A plus B. Display the sum of the source image and destination image, with color values approaching 255 (100%) as a limit.
+     \o copy             - A (B is ignored). Display the source image instead of the destination image.
+     \o xor              - A xor B. Exclusive OR of the source image and destination image.
+     \endlist
+
+     Additionally, this property also accepts the compositon modes listed in \a {QPainter::CompositionMode}. According to the W3C standard, these
+     extension composition modes are provided as "vendorName-operationName" syntax, for example: \c {QPainter::CompositionMode_Exclusion} is porvided as
+     "qt-exclusion".
+*/
+static v8::Handle<v8::Value> ctx2d_globalCompositeOperation(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT(r)
+
+
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+    return engine->toString(qt_composite_mode_to_string(r->context->state.globalCompositeOperation));
+}
+
+static void ctx2d_globalCompositeOperation_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT_SETTER(r)
+
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+
+    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);
+    }
+}
+
+// colors and styles
+/*!
+    \qmlproperty variant QtQuick2::Context2D::fillStyle
+     Holds the current style used for filling shapes.
+     The style can be either a string containing a CSS color, a CanvasGradient or CanvasPattern object. Invalid values are ignored.
+     This property accepts several color syntaxes:
+     \list
+     \o 'rgb(red, green, blue)' - for example: 'rgb(255, 100, 55)' or 'rgb(100%, 70%, 30%)'
+     \o 'rgba(red, green, blue, alpha)' - for example: 'rgb(255, 100, 55, 1.0)' or 'rgb(100%, 70%, 30%, 0.5)'
+     \o 'hsl(hue, saturation, lightness)'
+     \o 'hsla(hue, saturation, lightness, alpha)'
+     \o '#RRGGBB' - for example: '#00FFCC'
+     \o Qt.rgba(red, green, blue, alpha) - for example: Qt.rgba(0.3, 0.7, 1, 1.0)
+     \endlist
+     If the \a fillStyle or \a strokeStyle is assigned many times in a loop, the last Qt.rgba() syntax should be chosen, as it has the
+     best performance, because it's already a valid QColor value, does not need to be parsed everytime.
+
+     The default value is  '#000000'.
+     \sa QtQuick2::Context2D::createLinearGradient
+     \sa QtQuick2::Context2D::createRadialGradient
+     \sa QtQuick2::Context2D::createPattern
+     \sa QtQuick2::Context2D::strokeStyle
+ */
+static v8::Handle<v8::Value> ctx2d_fillStyle(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    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;
+}
+
+static void ctx2d_fillStyle_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT_SETTER(r)
+
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+   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, 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(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;
+       }
+   }
+}
+/*!
+    \qmlproperty enumeration QtQuick2::Context2D::fillRule
+     Holds the current fill rule used for filling shapes. The following fill rules supported:
+     \list
+     \o Qt.OddEvenFill
+     \o Qt.WindingFill
+     \endlist
+     Note: Unlike the \a QPainterPath, the Canvas API uses the winding fill as the default fill rule.
+     The fillRule property is part of the context rendering state.
+
+     \sa QtQuick2::Context2D::fillStyle
+ */
+static v8::Handle<v8::Value> ctx2d_fillRule(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT(r)
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+    return engine->fromVariant(r->context->state.fillRule);
+}
+
+static void ctx2d_fillRule_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT_SETTER(r)
+
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+    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) == QStringLiteral("OddEvenFill"))
+               ||(value->IsNumber() && value->NumberValue() == Qt::OddEvenFill)) {
+        r->context->state.fillRule = Qt::OddEvenFill;
+    } else {
+        //error
+    }
+    r->context->m_path.setFillRule(r->context->state.fillRule);
+}
+/*!
+    \qmlproperty variant QtQuick2::Context2D::strokeStyle
+     Holds the current color or style to use for the lines around shapes,
+     The style can be either a string containing a CSS color, a CanvasGradient or CanvasPattern object.
+     Invalid values are ignored.
+
+     The default value is  '#000000'.
+
+     \sa QtQuick2::Context2D::createLinearGradient
+     \sa QtQuick2::Context2D::createRadialGradient
+     \sa QtQuick2::Context2D::createPattern
+     \sa QtQuick2::Context2D::fillStyle
+ */
+v8::Handle<v8::Value> ctx2d_strokeStyle(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    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;
+}
+
+static void ctx2d_strokeStyle_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT_SETTER(r)
+
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+    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, 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(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 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).
+
+   A gradient is a smooth transition between colors. There are two types of gradients: linear and radial.
+   Gradients must have two or more color stops, representing color shifts positioned from 0 to 1 between
+   to the gradient's starting and end points or circles.
+
+    \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
+  */
+
+static v8::Handle<v8::Value> ctx2d_createLinearGradient(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+
+    QV8Engine *engine = V8ENGINE();
+
+    if (args.Length() == 4) {
+        QQuickContext2DEngineData *ed = engineData(engine);
+        v8::Local<v8::Object> gradient = ed->constructorGradient->NewInstance();
+        QV8Context2DStyleResource *r = new QV8Context2DStyleResource(engine);
+        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;
+    }
+
+    return args.This();
+}
+
+/*!
+  \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
+  */
+
+static v8::Handle<v8::Value> ctx2d_createRadialGradient(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+
+    QV8Engine *engine = V8ENGINE();
+
+    if (args.Length() == 6) {
+        QQuickContext2DEngineData *ed = engineData(engine);
+        v8::Local<v8::Object> gradient = ed->constructorGradient->NewInstance();
+        QV8Context2DStyleResource *r = new QV8Context2DStyleResource(engine);
+
+        qreal x0 = args[0]->NumberValue();
+        qreal y0 = args[1]->NumberValue();
+        qreal r0 = args[2]->NumberValue();
+        qreal x1 = args[3]->NumberValue();
+        qreal y1 = args[4]->NumberValue();
+        qreal r1 = args[5]->NumberValue();
+
+        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;
+    }
+
+    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) {
+        QQuickContext2DEngineData *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.
+  Returns a CanvasPattern object that uses the given \c color and \c patternMode.
+  The valid pattern modes are:
+    \list
+    \o Qt.SolidPattern
+    \o Qt.Dense1Pattern
+    \o Qt.Dense2Pattern
+    \o Qt.Dense3Pattern
+    \o Qt.Dense4Pattern
+    \o Qt.Dense5Pattern
+    \o Qt.Dense6Pattern
+    \o Qt.Dense7Pattern
+    \o Qt.HorPattern
+    \o Qt.VerPattern
+    \o Qt.CrossPattern
+    \o Qt.BDiagPattern
+    \o Qt.FDiagPattern
+    \o Qt.DiagCrossPattern
+\endlist
+    \sa Qt::BrushStyle
+ */
+/*!
+  \qmlmethod variant createPattern(Image image, string repetition)
+  Returns a CanvasPattern object that uses the given image and repeats in the direction(s) given by the repetition argument.
+
+  The \a image parameter must be a valid Image item, a valid \a QtQuick2::CanvasImageData object or loaded image url, if there is no image data, throws an INVALID_STATE_ERR exception.
+
+  The allowed values for \a repetition are:
+
+  \list
+  \o "repeat"    - both directions
+  \o "repeat-x   - horizontal only
+  \o "repeat-y"  - vertical only
+  \o "no-repeat" - neither
+  \endlist
+
+  If the repetition argument is empty or null, the value "repeat" is used.
+
+  \sa QtQuick2::Context2D::strokeStyle
+  \sa QtQuick2::Context2D::fillStyle
+  */
+static v8::Handle<v8::Value> ctx2d_createPattern(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+
+    QV8Engine *engine = V8ENGINE();
+
+    if (args.Length() == 2) {
+        QQuickContext2DEngineData *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
+/*!
+    \qmlproperty string QtQuick2::Context2D::lineCap
+     Holds the the current line cap style.
+     The possible line cap styles are:
+    \list
+    \o butt - the end of each line has a flat edge perpendicular to the direction of the line, this is the default line cap value.
+    \o round - a semi-circle with the diameter equal to the width of the line must then be added on to the end of the line.
+    \o square - a rectangle with the length of the line width and the width of half the line width, placed flat against the edge perpendicular to the direction of the line.
+    \endlist
+    Other values are ignored.
+*/
+v8::Handle<v8::Value> ctx2d_lineCap(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT(r)
+
+
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+    switch (r->context->state.lineCap) {
+    case Qt::RoundCap:
+        return engine->toString(QLatin1String("round"));
+    case Qt::FlatCap:
+        return engine->toString(QLatin1String("butt"));
+    case Qt::SquareCap:
+        return engine->toString(QLatin1String("square"));
+    default:
+        break;
+    }
+    return engine->toString(QLatin1String("butt"));;
+}
+
+static void ctx2d_lineCap_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT_SETTER(r)
+
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+    QString lineCap = engine->toString(value);
+    Qt::PenCapStyle cap;
+    if (lineCap == QLatin1String("round"))
+        cap = Qt::RoundCap;
+    else if (lineCap == QLatin1String("butt"))
+        cap = Qt::FlatCap;
+    else if (lineCap == QLatin1String("square"))
+        cap = Qt::SquareCap;
+    else
+        return;
+
+    if (cap != r->context->state.lineCap) {
+        r->context->state.lineCap = cap;
+        r->context->buffer()->setLineCap(cap);
+    }
+}
+
+/*!
+    \qmlproperty string QtQuick2::Context2D::lineJoin
+     Holds the the current line join style. A join exists at any point in a subpath
+     shared by two consecutive lines. When a subpath is closed, then a join also exists
+     at its first point (equivalent to its last point) connecting the first and last lines in the subpath.
+
+    The possible line join styles are:
+    \list
+    \o bevel - this is all that is rendered at joins.
+    \o round - a filled arc connecting the two aforementioned corners of the join, abutting (and not overlapping) the aforementioned triangle, with the diameter equal to the line width and the origin at the point of the join, must be rendered at joins.
+    \o miter - a second filled triangle must (if it can given the miter length) be rendered at the join, this is the default line join style.
+    \endlist
+    Other values are ignored.
+*/
+v8::Handle<v8::Value> ctx2d_lineJoin(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT(r)
+
+
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+    switch (r->context->state.lineJoin) {
+    case Qt::RoundJoin:
+        return engine->toString(QLatin1String("round"));
+    case Qt::BevelJoin:
+        return engine->toString(QLatin1String("bevel"));
+    case Qt::MiterJoin:
+        return engine->toString(QLatin1String("miter"));
+    default:
+        break;
+    }
+    return engine->toString(QLatin1String("miter"));
+}
+
+static void ctx2d_lineJoin_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT_SETTER(r)
+
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+    QString lineJoin = engine->toString(value);
+    Qt::PenJoinStyle join;
+    if (lineJoin == QLatin1String("round"))
+        join = Qt::RoundJoin;
+    else if (lineJoin == QLatin1String("bevel"))
+        join = Qt::BevelJoin;
+    else if (lineJoin == QLatin1String("miter"))
+        join = Qt::MiterJoin;
+    else
+        return;
+
+    if (join != r->context->state.lineJoin) {
+        r->context->state.lineJoin = join;
+        r->context->buffer()->setLineJoin(join);
+    }
+}
+
+/*!
+    \qmlproperty real QtQuick2::Context2D::lineWidth
+     Holds the the current line width. Values that are not finite values greater than zero are ignored.
+ */
+v8::Handle<v8::Value> ctx2d_lineWidth(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT(r)
+
+
+    return v8::Number::New(r->context->state.lineWidth);
+}
+
+static void ctx2d_lineWidth_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT_SETTER(r)
+
+    qreal w = value->NumberValue();
+
+    if (w > 0 && qIsFinite(w) && w != r->context->state.lineWidth) {
+        r->context->state.lineWidth = w;
+        r->context->buffer()->setLineWidth(w);
+    }
+}
+
+/*!
+    \qmlproperty real QtQuick2::Context2D::miterLimit
+     Holds the current miter limit ratio.
+     The default miter limit value is 10.0.
+ */
+v8::Handle<v8::Value> ctx2d_miterLimit(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT(r)
+
+
+    return v8::Number::New(r->context->state.miterLimit);
+}
+
+static void ctx2d_miterLimit_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT_SETTER(r)
+
+    qreal ml = value->NumberValue();
+
+    if (ml > 0 && qIsFinite(ml) && ml != r->context->state.miterLimit) {
+        r->context->state.miterLimit = ml;
+        r->context->buffer()->setMiterLimit(ml);
+    }
+}
+
+// shadows
+/*!
+    \qmlproperty real QtQuick2::Context2D::shadowBlur
+     Holds the current level of blur applied to shadows
+ */
+v8::Handle<v8::Value> ctx2d_shadowBlur(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT(r)
+
+
+    return v8::Number::New(r->context->state.shadowBlur);
+}
+
+static void ctx2d_shadowBlur_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT_SETTER(r)
+    qreal blur = value->NumberValue();
+
+    if (blur > 0 && qIsFinite(blur) && blur != r->context->state.shadowBlur) {
+        r->context->state.shadowBlur = blur;
+        r->context->buffer()->setShadowBlur(blur);
+    }
+}
+
+/*!
+    \qmlproperty string QtQuick2::Context2D::shadowColor
+     Holds the current shadow color.
+ */
+v8::Handle<v8::Value> ctx2d_shadowColor(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT(r)
+
+
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+    return engine->toString(r->context->state.shadowColor.name());
+}
+
+static void ctx2d_shadowColor_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT_SETTER(r)
+
+    QColor color = qt_color_from_string(value);
+
+    if (color.isValid() && color != r->context->state.shadowColor) {
+        r->context->state.shadowColor = color;
+        r->context->buffer()->setShadowColor(color);
+    }
+}
+
+
+/*!
+    \qmlproperty qreal QtQuick2::Context2D::shadowOffsetX
+     Holds the current shadow offset in the positive horizontal distance.
+
+     \sa QtQuick2::Context2D::shadowOffsetY
+ */
+v8::Handle<v8::Value> ctx2d_shadowOffsetX(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT(r)
+
+
+    return v8::Number::New(r->context->state.shadowOffsetX);
+}
+
+static void ctx2d_shadowOffsetX_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT_SETTER(r)
+
+    qreal offsetX = value->NumberValue();
+    if (qIsFinite(offsetX) && offsetX != r->context->state.shadowOffsetX) {
+        r->context->state.shadowOffsetX = offsetX;
+        r->context->buffer()->setShadowOffsetX(offsetX);
+    }
+}
+/*!
+    \qmlproperty qreal QtQuick2::Context2D::shadowOffsetY
+     Holds the current shadow offset in the positive vertical distance.
+
+     \sa QtQuick2::Context2D::shadowOffsetX
+ */
+v8::Handle<v8::Value> ctx2d_shadowOffsetY(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT(r)
+
+
+    return v8::Number::New(r->context->state.shadowOffsetY);
+}
+
+static void ctx2d_shadowOffsetY_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT_SETTER(r)
+
+    qreal offsetY = value->NumberValue();
+    if (qIsFinite(offsetY) && offsetY != r->context->state.shadowOffsetY) {
+        r->context->state.shadowOffsetY = offsetY;
+        r->context->buffer()->setShadowOffsetY(offsetY);
+    }
+}
+
+v8::Handle<v8::Value> ctx2d_path(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT(r)
+    return r->context->m_v8path;
+}
+
+static void ctx2d_path_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT_SETTER(r)
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+    r->context->beginPath();
+    if (value->IsObject()) {
+        QDeclarativePath* path = qobject_cast<QDeclarativePath*>(engine->toQObject(value));
+        if (path)
+            r->context->m_path = path->path();
+    } else {
+        QString path = engine->toString(value->ToString());
+        QDeclarativeSvgParser::parsePathDataFast(path, r->context->m_path);
+    }
+    r->context->m_v8path = value;
+}
+
+//rects
+/*!
+  \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)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+
+    if (args.Length() == 4) {
+        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 object QtQuick2::Context2D::fillRect(real x, real y, real w, real h)
+   Paint the specified rectangular area using the fillStyle.
+
+   \sa QtQuick2::Context2D::fillStyle
+  */
+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) {
+        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 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.
+
+   \sa QtQuick2::Context2D::strokeStyle
+   \sa QtQuick2::Context2D::lineWidth
+   \sa QtQuick2::Context2D::lineJoin
+   \sa QtQuick2::Context2D::miterLimit
+  */
+static v8::Handle<v8::Value> ctx2d_strokeRect(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+
+    if (args.Length() == 4) {
+        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 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
+  See {http://www.w3.org/TR/2dcontext/#dom-context-2d-arc}{W3C 2d context standard for arc}
+  */
+static v8::Handle<v8::Value> ctx2d_arc(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+    if (args.Length() >= 5) {
+        bool antiClockwise = false;
+
+        if (args.Length() == 6)
+            antiClockwise = args[5]->BooleanValue();
+
+        qreal radius = args[2]->NumberValue();
+        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,
+                        args[3]->NumberValue(),
+                        args[4]->NumberValue(),
+                        antiClockwise);
+    }
+
+    return args.This();
+}
+
+/*!
+  \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:
+    \list
+    \o Call the context.beginPath() method to set a new path.
+    \o Call the context.moveTo(\c x, \c y) method to set your starting position on the canvas at the point (\c x,\c y).
+    \o To draw an arc or circle, call the context.arcTo(\c x1, \c y1, \c x2, \c y2,\c radius) method.
+       This adds an arc with starting point (\c x1,\c y1), ending point (\c x2, \c y2), and radius \c radius to the current subpath and connects
+       it to the previous subpath by a straight line.
+    \endlist
+    \image qml-item-canvas-arcTo.png
+    Both startAngle and endAngle are measured from the x axis in units of radians.
+
+    \image qml-item-canvas-startAngle.png
+    The anticlockwise has the value TRUE for each arc in the figure above because they are all drawn in the counterclockwise direction.
+  \sa  QtQuick2::Context2D::arc
+  \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-arcto}{W3C 2d context standard for arcTo}
+  */
+static v8::Handle<v8::Value> ctx2d_arcTo(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    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(),
+                          args[3]->NumberValue(),
+                          args[4]->NumberValue());
+    }
+
+    return args.This();
+}
+
+/*!
+  \qmlmethod object QtQuick2::Context2D::beginPath()
+
+   Resets the current path to a new path.
+  */
+static v8::Handle<v8::Value> ctx2d_beginPath(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+
+    r->context->beginPath();
+
+    return args.This();
+}
+
+/*!
+  \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).
+  After the curve is added, the current position is updated to be at the end point (\c x, \c y) of the curve.
+  The following code produces the path shown below:
+  \code
+  ctx.strokeStyle = Qt.rgba(0, 0, 0, 1);
+  ctx.lineWidth = 1;
+  ctx.beginPath();
+  ctx.moveTo(20, 0);//start point
+  ctx.bezierCurveTo(-10, 90, 210, 90, 180, 0);
+  ctx.stroke();
+  \endcode
+   \image qml-item-canvas-bezierCurveTo.png
+  \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-beziercurveto}{W3C 2d context standard for bezierCurveTo}
+  \sa {http://www.openrise.com/lab/FlowerPower/}{The beautiful flower demo by using bezierCurveTo}
+  */
+static v8::Handle<v8::Value> ctx2d_bezierCurveTo(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+
+    if (args.Length() == 6) {
+        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 object QtQuick2::Context2D::clip()
+
+   Creates the clipping region from the current path.
+   Any parts of the shape outside the clipping path are not displayed.
+   To create a complex shape using the \a clip() method:
+
+    \list 1
+    \o Call the \c{context.beginPath()} method to set the clipping path.
+    \o Define the clipping path by calling any combination of the \c{lineTo},
+    \c{arcTo}, \c{arc}, \c{moveTo}, etc and \c{closePath} methods.
+    \o Call the \c{context.clip()} method.
+    \endlist
+
+    The new shape displays.  The following shows how a clipping path can
+    modify how an image displays:
+
+    \image qml-canvas-clip-complex.png
+    \sa QtQuick2::Context2D::beginPath()
+    \sa QtQuick2::Context2D::closePath()
+    \sa QtQuick2::Context2D::stroke()
+    \sa QtQuick2::Context2D::fill()
+   \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-clip}{W3C 2d context standard for clip}
+  */
+static v8::Handle<v8::Value> ctx2d_clip(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+    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 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.
+
+   \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-closepath}{W3C 2d context standard for closePath}
+  */
+static v8::Handle<v8::Value> ctx2d_closePath(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+
+    r->context->closePath();
+
+    return args.This();
+}
+
+/*!
+  \qmlmethod object QtQuick2::Context2D::fill()
+
+   Fills the subpaths with the current fill style.
+
+   \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-fill}{W3C 2d context standard for fill}
+
+   \sa QtQuick2::Context2D::fillStyle
+  */
+static v8::Handle<v8::Value> ctx2d_fill(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r);
+
+    r->context->buffer()->fill(r->context->m_path);
+
+    return args.This();
+}
+
+/*!
+  \qmlmethod object QtQuick2::Context2D::lineTo(real x, real y)
+
+   Draws a line from the current position to the point (x, y).
+ */
+static v8::Handle<v8::Value> ctx2d_lineTo(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+
+    if (args.Length() == 2) {
+        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 object QtQuick2::Context2D::moveTo(real x, real y)
+
+   Creates a new subpath with the given point.
+ */
+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) {
+        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 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).
+
+   See {http://www.w3.org/TR/2dcontext/#dom-context-2d-quadraticcurveto}{W3C 2d context standard for  for quadraticCurveTo}
+ */
+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) {
+        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 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.
+ */
+static v8::Handle<v8::Value> ctx2d_rect(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+
+    if (args.Length() == 4) {
+        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 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.
+ */
+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) {
+        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 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.
+
+  The ellipse is composed of a clockwise curve, starting and finishing at zero degrees (the 3 o'clock position).
+ */
+static v8::Handle<v8::Value> ctx2d_ellipse(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+
+    if (args.Length() == 4) {
+        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 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).
+ */
+static v8::Handle<v8::Value> ctx2d_text(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+    QV8Engine *engine = V8ENGINE();
+    if (args.Length() == 3) {
+        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 object QtQuick2::Context2D::stroke()
+
+   Strokes the subpaths with the current stroke style.
+
+   See {http://www.w3.org/TR/2dcontext/#dom-context-2d-stroke}{W3C 2d context standard for stroke}
+
+   \sa QtQuick2::Context2D::strokeStyle
+  */
+static v8::Handle<v8::Value> ctx2d_stroke(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+
+    r->context->buffer()->stroke(r->context->m_path);
+
+    return args.This();
+}
+
+/*!
+  \qmlmethod object QtQuick2::Context2D::isPointInPath(real x, real y)
+
+   Returns true if the given point is in the current path.
+
+   \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-ispointinpath}{W3C 2d context standard for isPointInPath}
+  */
+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) {
+        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_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_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_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::caretBlinkRate is not supported");
+    return args.This();
+}
+// text
+/*!
+  \qmlproperty string QtQuick2::Context2D::font
+  Holds the current font settings.
+
+  The default font value is "10px sans-serif".
+  See {http://www.w3.org/TR/2dcontext/#dom-context-2d-font}{w3C 2d context standard for font}
+  */
+v8::Handle<v8::Value> ctx2d_font(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT(r)
+
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+    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)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT_SETTER(r)
+
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+    QString fs = engine->toString(value);
+    QFont font = qt_font_from_string(fs);
+    if (font != r->context->state.font) {
+        r->context->state.font = font;
+    }
+}
+
+/*!
+  \qmlproperty string QtQuick2::Context2D::textAlign
+
+  Holds the current text alignment settings.
+  The possible values are:
+  \list
+    \o start
+    \o end
+    \o left
+    \o right
+    \o center
+  \endlist
+  Other values are ignored. The default value is "start".
+  */
+v8::Handle<v8::Value> ctx2d_textAlign(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT(r)
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+    switch (r->context->state.textAlign) {
+    case QQuickContext2D::Start:
+        return engine->toString(QLatin1String("start"));
+   case QQuickContext2D::End:
+        return engine->toString(QLatin1String("end"));
+   case QQuickContext2D::Left:
+        return engine->toString(QLatin1String("left"));
+   case QQuickContext2D::Right:
+        return engine->toString(QLatin1String("right"));
+   case QQuickContext2D::Center:
+        return engine->toString(QLatin1String("center"));
+    default:
+        break;
+    }
+    return engine->toString(QLatin1String("start"));
+}
+
+static void ctx2d_textAlign_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT_SETTER(r)
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+
+    QString textAlign = engine->toString(value);
+
+    QQuickContext2D::TextAlignType ta;
+    if (textAlign == QLatin1String("start"))
+        ta = QQuickContext2D::Start;
+    else if (textAlign == QLatin1String("end"))
+        ta = QQuickContext2D::End;
+    else if (textAlign == QLatin1String("left"))
+        ta = QQuickContext2D::Left;
+    else if (textAlign == QLatin1String("right"))
+        ta = QQuickContext2D::Right;
+    else if (textAlign == QLatin1String("center"))
+        ta = QQuickContext2D::Center;
+    else
+        return;
+
+    if (ta != r->context->state.textAlign) {
+        r->context->state.textAlign = ta;
+    }
+}
+
+/*!
+  \qmlproperty string QtQuick2::Context2D::textBaseline
+
+  Holds the current baseline alignment settings.
+  The possible values are:
+  \list
+    \o top
+    \o hanging
+    \o middle
+    \o alphabetic
+    \o ideographic
+    \o bottom
+  \endlist
+  Other values are ignored. The default value is "alphabetic".
+  */
+v8::Handle<v8::Value> ctx2d_textBaseline(v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT(r)
+
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+    switch (r->context->state.textBaseline) {
+    case QQuickContext2D::Alphabetic:
+        return engine->toString(QLatin1String("alphabetic"));
+    case QQuickContext2D::Hanging:
+        return engine->toString(QLatin1String("hanging"));
+    case QQuickContext2D::Top:
+        return engine->toString(QLatin1String("top"));
+    case QQuickContext2D::Bottom:
+        return engine->toString(QLatin1String("bottom"));
+    case QQuickContext2D::Middle:
+        return engine->toString(QLatin1String("middle"));
+    default:
+        break;
+    }
+    return engine->toString(QLatin1String("alphabetic"));
+}
+
+static void ctx2d_textBaseline_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
+    CHECK_CONTEXT_SETTER(r)
+    QV8Engine *engine = V8ENGINE_ACCESSOR();
+    QString textBaseline = engine->toString(value);
+
+    QQuickContext2D::TextBaseLineType tb;
+    if (textBaseline == QLatin1String("alphabetic"))
+        tb = QQuickContext2D::Alphabetic;
+    else if (textBaseline == QLatin1String("hanging"))
+        tb = QQuickContext2D::Hanging;
+    else if (textBaseline == QLatin1String("top"))
+        tb = QQuickContext2D::Top;
+    else if (textBaseline == QLatin1String("bottom"))
+        tb = QQuickContext2D::Bottom;
+    else if (textBaseline == QLatin1String("middle"))
+        tb = QQuickContext2D::Middle;
+    else
+        return;
+
+    if (tb != r->context->state.textBaseline) {
+        r->context->state.textBaseline = tb;
+    }
+}
+
+/*!
+  \qmlmethod object QtQuick2::Context2D::fillText(text, x, y)
+  Fills the given text at the given position.
+  \sa QtQuick2::Context2D::font
+  \sa QtQuick2::Context2D::textAlign
+  \sa QtQuick2::Context2D::textBaseline
+  \sa QtQuick2::Context2D::strokeText
+  */
+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) {
+        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 object QtQuick2::Context2D::strokeText(text, x, y)
+  Strokes the given text at the given position.
+  \sa QtQuick2::Context2D::font
+  \sa QtQuick2::Context2D::textAlign
+  \sa QtQuick2::Context2D::textBaseline
+  \sa QtQuick2::Context2D::fillText
+  */
+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) {
+        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();
+}
+/*!
+  \qmlclass QtQuick2::TextMetrics
+    \inqmlmodule QtQuick 2
+    \since QtQuick 2.0
+    \brief The Context2D TextMetrics interface.
+    The TextMetrics object can be created by QtQuick2::Context2D::measureText method.
+    See {http://www.w3.org/TR/2dcontext/#textmetrics}{W3C 2d context TexMetrics} for more details.
+
+    \sa QtQuick2::Context2D::measureText
+    \sa QtQuick2::TextMetrics::width
+  */
+
+/*!
+  \qmlproperty int QtQuick2::TextMetrics::width
+  Holds the advance width of the text that was passed to the QtQuick2::Context2D::measureText() method.
+  This property is read only.
+  */
+
+/*!
+  \qmlmethod variant QtQuick2::Context2D::measureText(text)
+  Returns a TextMetrics object with the metrics of the given text in the current font.
+  */
+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) {
+        QFontMetrics fm(r->context->state.font);
+        uint width = fm.width(engine->toString(args[0]));
+        v8::Local<v8::Object> tm = v8::Object::New();
+        tm->Set(v8::String::New("width"), v8::Number::New(width));
+        return tm;
+    }
+    return v8::Undefined();
+}
+
+// drawing images
+/*!
+  \qmlmethod QtQuick2::Context2D::drawImage(variant image, real dx, real dy)
+  Draws the given \a image on the canvas at position (\a dx, \a dy).
+  Note:
+  The \a image type can be an Image 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.
+
+  \sa QtQuick2::CanvasImageData
+  \sa QtQuick2::Image
+  \sa QtQuick2::Canvas::loadImage
+  \sa QtQuick2::Canvas::isImageLoaded
+  \sa QtQuick2::Canvas::imageLoaded
+
+  \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-drawimage}{W3C 2d context standard for drawImage}
+  */
+/*!
+  \qmlmethod QtQuick2::Context2D::drawImage(variant image, real dx, real dy, real dw, real dh)
+  This is an overloaded function.
+  Draws the given item as \a image onto the canvas at point (\a dx, \a dy) and with width \a dw,
+  height \a dh.
+
+  Note:
+  The \a image type can be an Image 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.
+
+  \sa QtQuick2::CanvasImageData
+  \sa QtQuick2::Image
+  \sa QtQuick2::Canvas::loadImage
+  \sa QtQuick2::Canvas::isImageLoaded
+  \sa QtQuick2::Canvas::imageLoaded
+
+  \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-drawimage}{W3C 2d context standard for drawImage}
+  */
+/*!
+  \qmlmethod QtQuick2::Context2D::drawImage(variant image, real sx, real sy, real sw, sh, real dx, real dy, real dw, dh)
+  This is an overloaded function.
+  Draws the given item as \a image from source point (\a sx, \a sy) and source width \sw, source height \sh
+  onto the canvas at point (\a dx, \a dy) and with width \a dw, height \a dh.
+
+
+  Note:
+  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.
+
+  \sa QtQuick2::CanvasImageData
+  \sa QtQuick2::Image
+  \sa QtQuick2::Canvas::loadImage
+  \sa QtQuick2::Canvas::isImageLoaded
+  \sa QtQuick2::Canvas::imageLoaded
+
+  \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-drawimage}{W3C 2d context standard for drawImage}
+*/
+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();
+    qreal sx, sy, sw, sh, dx, dy, dw, dh;
+
+    if (!args.Length())
+        return args.This();
+
+    QImage image;
+    if (args[0]->IsString()) {
+        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()) {
+        QQuickImage *imageItem = qobject_cast<QQuickImage*>(engine->toQObject(args[0]->ToObject()));
+        QQuickCanvasItem *canvas = qobject_cast<QQuickCanvasItem*>(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 {
+            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.width();
+        sh = image.height();
+        dw = sw;
+        dh = sh;
+    } else if (args.Length() == 5) {
+        sx = 0;
+        sy = 0;
+        sw = image.width();
+        sh = image.height();
+        dx = args[1]->NumberValue();
+        dy = args[2]->NumberValue();
+        dw = args[3]->NumberValue();
+        dh = args[4]->NumberValue();
+    } else if (args.Length() == 9) {
+        sx = args[1]->NumberValue();
+        sy = args[2]->NumberValue();
+        sw = args[3]->NumberValue();
+        sh = args[4]->NumberValue();
+        dx = args[5]->NumberValue();
+        dy = args[6]->NumberValue();
+        dw = args[7]->NumberValue();
+        dh = args[8]->NumberValue();
+    } else {
+        return args.This();
+    }
+
+    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();
+}
+
+// pixel manipulation
+/*!
+  \qmlclass QtQuick2::CanvasImageData
+     The \a QtQuick2::CanvasImageData object holds the image pixel data.
+
+     The \a QtQuick2::CanvasImageData object has the actual dimensions of the data stored in
+     this object and holds the one-dimensional array containing the data in RGBA order,
+     as integers in the range 0 to 255.
+
+     \sa QtQuick2::CanvasImageData::width
+     \sa QtQuick2::CanvasImageData::height
+     \sa QtQuick2::CanvasImageData::data
+     \sa QtQuick2::Context2D::createImageData
+     \sa QtQuick2::Context2D::getImageData
+     \sa QtQuick2::Context2D::putImageData
+  */
+/*!
+  \qmlproperty QtQuick2::CanvasImageData::width
+  Holds the actual width dimension of the data in the ImageData object, in device pixels.
+ */
+v8::Handle<v8::Value> ctx2d_imageData_width(v8::Local<v8::String>, const v8::AccessorInfo &args)
+{
+    QV8Context2DPixelArrayResource *r = v8_resource_cast<QV8Context2DPixelArrayResource>(args.This()->GetInternalField(0)->ToObject());
+    if (!r)
+        return v8::Integer::New(0);
+    return v8::Integer::New(r->image.width());
+}
+
+/*!
+  \qmlproperty QtQuick2::CanvasImageData::height
+  Holds the actual height dimension of the data in the ImageData object, in device pixels.
+  */
+v8::Handle<v8::Value> ctx2d_imageData_height(v8::Local<v8::String>, const v8::AccessorInfo &args)
+{
+    QV8Context2DPixelArrayResource *r = v8_resource_cast<QV8Context2DPixelArrayResource>(args.This()->GetInternalField(0)->ToObject());
+    if (!r)
+        return v8::Integer::New(0);
+
+    return v8::Integer::New(r->image.height());
+}
+
+/*!
+  \qmlproperty QtQuick2::CanvasImageData::data
+  Holds the one-dimensional array containing the data in RGBA order, as integers in the range 0 to 255.
+ */
+v8::Handle<v8::Value> ctx2d_imageData_data(v8::Local<v8::String>, const v8::AccessorInfo &args)
+{
+    return args.This()->GetInternalField(0);
+}
+
+/*!
+  \qmlmethod void QtQuick2::CanvasImageData::mirrr( bool horizontal = false, bool vertical = true)
+  Mirrors the image data in place in the  \c horizontal and/or the \c vertical direction depending on
+  whether horizontal and vertical are set to true or false.
+  The default \c horizontal value is false, the default \c vertical value is true.
+*/
+static v8::Handle<v8::Value> ctx2d_imageData_mirror(const v8::Arguments &args)
+{
+    bool horizontal = false, vertical = true;
+    QV8Context2DPixelArrayResource *r = v8_resource_cast<QV8Context2DPixelArrayResource>(args.This()->GetInternalField(0)->ToObject());
+
+    if (!r) {
+        //error
+        return v8::Undefined();
+    }
+
+    if (args.Length() > 2) {
+      //error
+      return v8::Undefined();
+    }
+
+    if (args.Length() == 1) {
+        horizontal = args[0]->BooleanValue();
+    } else if (args.Length() == 2) {
+        horizontal = args[0]->BooleanValue();
+        vertical = args[1]->BooleanValue();
+    }
+    r->image = r->image.mirrored(horizontal, vertical);
+    return args.This();
+}
+
+/*!
+  \qmlmethod void QtQuick2::CanvasImageData::filter(enumeration mode, args)
+   Filters the image data as defined by one of the following modes:
+    \list
+    \o Canvas.Threshold - converts the image to black and white pixels depending
+                          if they are above or below the threshold defined by the level parameter.
+                          The level must be between 0.0 (black) and 1.0(white).
+                          If no level is specified, 0.5 is used.
+    \o Canvas.Mono - converts the image to the 1-bit per pixel format.
+    \o Canvas.GrayScale - converts any colors in the image to grayscale equivalents.
+    \o Canvas.Brightness -increase/decrease a fixed \c adjustment value to each pixel's RGB channel value.
+    \o Canvas.Invert - sets each pixel to its inverse value.
+    \o Canvas.Blur - executes a box blur with the pixel \c radius parameter specifying the range of the blurring for each pixel.
+                     the default blur \c radius is 3. This filter also accepts another \c quality parameter, if true, the filter will
+                     execute 3-passes box blur to simulate the Guassian blur. The default \c quality value is false.
+    \o Canvas.Opaque - sets the alpha channel to entirely opaque.
+    \o Canvas.Convolute - executes a generic {http://en.wikipedia.org/wiki/Convolution}{Convolution} filter, the second
+                          parameter contains the convoluton matrix data as a number array.
+    \endlist
+
+*/
+static v8::Handle<v8::Value> ctx2d_imageData_filter(const v8::Arguments &args)
+{
+    QV8Context2DPixelArrayResource *r = v8_resource_cast<QV8Context2DPixelArrayResource>(args.This()->GetInternalField(0)->ToObject());
+
+    if (!r) {
+        //error
+        return v8::Undefined();
+    }
+
+    if (args.Length() >= 1) {
+        int filterFlag = args[0]->IntegerValue();
+        switch (filterFlag) {
+        case QQuickCanvasItem::Mono :
+        {
+            r->image = r->image.convertToFormat(QImage::Format_Mono).convertToFormat(QImage::Format_ARGB32_Premultiplied);
+        }
+            break;
+        case QQuickCanvasItem::GrayScale :
+        {
+            for (int y = 0; y < r->image.height(); ++y) {
+              QRgb *row = (QRgb*)r->image.scanLine(y);
+              for (int x = 0; x < r->image.width(); ++x) {
+                  unsigned char* rgb = ((unsigned char*)&row[x]);
+                  rgb[0] = rgb[1] = rgb[2] = qGray(rgb[0], rgb[1], rgb[2]);
+              }
+            }
+        }
+            break;
+        case QQuickCanvasItem::Threshold :
+        {
+            qreal threshold = 0.5;
+            if (args.Length() > 1)
+                threshold = args[1]->NumberValue();
+
+            for (int y = 0; y < r->image.height(); ++y) {
+              QRgb *row = (QRgb*)r->image.scanLine(y);
+              for (int x = 0; x < r->image.width(); ++x) {
+                  unsigned char* rgb = ((unsigned char*)&row[x]);
+                  unsigned char v = qGray(rgb[0], rgb[1], rgb[2]) >= threshold*255 ? 255 : 0;
+                  rgb[0] = rgb[1] = rgb[2] = v;
+              }
+            }
+        }
+            break;
+        case QQuickCanvasItem::Brightness :
+        {
+            int adjustment = 1;
+            if (args.Length() > 1)
+                adjustment = args[1]->IntegerValue();
+
+            for (int y = 0; y < r->image.height(); ++y) {
+              QRgb *row = (QRgb*)r->image.scanLine(y);
+              for (int x = 0; x < r->image.width(); ++x) {
+                ((unsigned char*)&row[x])[0] += adjustment;
+                ((unsigned char*)&row[x])[1] += adjustment;
+                ((unsigned char*)&row[x])[2] += adjustment;
+              }
+            }
+        }
+            break;
+        case QQuickCanvasItem::Invert :
+        {
+            r->image.invertPixels();
+        }
+            break;
+        case QQuickCanvasItem::Blur :
+        {
+            int radius = 3;
+            bool quality = false;
+
+            if (args.Length() > 1)
+                radius = args[1]->IntegerValue() / 2;
+            if (args.Length() > 2)
+                quality = args[2]->BooleanValue();
+
+            qt_image_boxblur(r->image, radius, quality);
+        }
+            break;
+        case QQuickCanvasItem::Opaque :
+        {
+            for (int y = 0; y < r->image.height(); ++y) {
+              QRgb *row = (QRgb*)r->image.scanLine(y);
+              for (int x = 0; x < r->image.width(); ++x) {
+                ((unsigned char*)&row[x])[3] = 255;
+              }
+            }
+        }
+            break;
+        case QQuickCanvasItem::Convolute :
+        {
+            if (args.Length() > 1 && args[1]->IsArray()) {
+                v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(args[1]);
+                QVector<qreal> weights;
+                for (uint32_t i = 0; i < array->Length(); ++i)
+                    weights.append(array->Get(i)->NumberValue());
+                r->image = qt_image_convolute_filter(r->image, weights);
+            } else {
+                //error
+            }
+        }
+            break;
+        default:
+            break;
+        }
+    }
+
+    return args.This();
+}
+/*!
+  \qmlclass QtQuick2::CanvasPixelArray
+  The CanvasPixelArray object provides ordered, indexed access to the color components of each pixel of the image data.
+  The CanvasPixelArray can be accessed as normal Javascript array.
+    \sa QtQuick2::CanvasImageData
+    \sa {http://www.w3.org/TR/2dcontext/#canvaspixelarray}{W3C 2d context standard for PixelArray}
+  */
+
+/*!
+  \qmlproperty QtQuick2::CanvasPixelArray::length
+  The CanvasPixelArray object represents h×w×4 integers which w and h comes from CanvasImageData.
+  The length attribute of a CanvasPixelArray object must return this h×w×4 number value.
+  This property is read only.
+*/
+v8::Handle<v8::Value> ctx2d_pixelArray_length(v8::Local<v8::String>, const v8::AccessorInfo &args)
+{
+    QV8Context2DPixelArrayResource *r = v8_resource_cast<QV8Context2DPixelArrayResource>(args.This());
+    if (!r || r->image.isNull()) return v8::Undefined();
+
+    return v8::Integer::New(r->image.width() * r->image.height() * 4);
+}
+
+v8::Handle<v8::Value> ctx2d_pixelArray_indexed(uint32_t index, const v8::AccessorInfo& args)
+{
+    QV8Context2DPixelArrayResource *r = v8_resource_cast<QV8Context2DPixelArrayResource>(args.This());
+
+    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) {
+        case 0:
+            return v8::Integer::New(qRed(*pixel));
+        case 1:
+            return v8::Integer::New(qGreen(*pixel));
+        case 2:
+            return v8::Integer::New(qBlue(*pixel));
+        case 3:
+            return v8::Integer::New(qAlpha(*pixel));
+        }
+    }
+    return v8::Undefined();
+}
+
+v8::Handle<v8::Value> ctx2d_pixelArray_indexed_set(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
+{
+    QV8Context2DPixelArrayResource *r = v8_resource_cast<QV8Context2DPixelArrayResource>(info.This());
+
+    const int v = value->Uint32Value();
+    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;
+        switch (index % 4) {
+        case 0:
+            *pixel = qRgba(v, qGreen(*pixel), qBlue(*pixel), qAlpha(*pixel));
+            break;
+        case 1:
+            *pixel = qRgba(qRed(*pixel), v, qBlue(*pixel), qAlpha(*pixel));
+            break;
+        case 2:
+            *pixel = qRgba(qRed(*pixel), qGreen(*pixel), v, qAlpha(*pixel));
+            break;
+        case 3:
+            *pixel = qRgba(qRed(*pixel), qGreen(*pixel), qBlue(*pixel), v);
+            break;
+        }
+    }
+    return v8::Undefined();
+}
+/*!
+  \qmlmethod QtQuick2::CanvasImageData createImageData(real sw, real sh)
+   Creates a CanvasImageData object with the given dimensions(\a sw, \a sh).
+  */
+/*!
+  \qmlmethod QtQuick2::CanvasImageData createImageData(QtQuick2::CanvasImageData imageData)
+   Creates a CanvasImageData object with the same dimensions as the argument.
+  */
+/*!
+  \qmlmethod QtQuick2::CanvasImageData createImageData(Url imageUrl)
+   Creates a CanvasImageData object with the given image loaded from \a imageUrl.
+   Note:The \a imageUrl must be already loaded before this function call, if not, an empty
+   CanvasImageData obect will be returned.
+
+   \sa QtQuick2::Canvas::loadImage, QtQuick2::Canvas::unloadImage, QtQuick2::Canvas::isImageLoaded
+  */
+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) {
+        if (args[0]->IsObject()) {
+            v8::Local<v8::Object> imgData = args[0]->ToObject();
+            QV8Context2DPixelArrayResource *pa = v8_resource_cast<QV8Context2DPixelArrayResource>(imgData->GetInternalField(0)->ToObject());
+            if (pa) {
+                qreal w = imgData->Get(v8::String::New("width"))->NumberValue();
+                qreal h = imgData->Get(v8::String::New("height"))->NumberValue();
+                return qt_create_image_data(w, h, engine, QImage());
+            }
+        } else if (args[0]->IsString()) {
+            QImage image = r->context->createImage(QUrl(engine->toString(args[0]->ToString())));
+            return qt_create_image_data(image.width(), image.height(), engine, image);
+        }
+    } 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();
+}
+
+/*!
+  \qmlmethod QtQuick2::CanvasImageData getImageData(real sx, real sy, real sw, real sh)
+  Returns an CanvasImageData object containing the image data for the given rectangle of the canvas.
+  */
+static v8::Handle<v8::Value> ctx2d_getImageData(const v8::Arguments &args)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+
+    QV8Engine *engine = V8ENGINE();
+    if (args.Length() == 4) {
+        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(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));
+        v8::Local<v8::Object> imageData = qt_create_image_data(w, h, engine, image);
+
+        return imageData;
+    }
+    return v8::Null();
+}
+
+/*!
+  \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)
+{
+    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
+    CHECK_CONTEXT(r)
+    if (args.Length() != 3 && args.Length() != 7)
+        return v8::Undefined();
+
+    if (args[0]->IsNull() || !args[0]->IsObject()) {
+        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) {
+        w = imageData->Get(v8::String::New("width"))->NumberValue();
+        h = imageData->Get(v8::String::New("height"))->NumberValue();
+
+        if (args.Length() == 7) {
+            dirtyX = args[3]->NumberValue();
+            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;
+            }
+
+            if (dirtyHeight < 0) {
+                dirtyY = dirtyY+dirtyHeight;
+                dirtyHeight = -dirtyHeight;
+            }
+
+            if (dirtyX < 0) {
+                dirtyWidth = dirtyWidth+dirtyX;
+                dirtyX = 0;
+            }
+
+            if (dirtyY < 0) {
+                dirtyHeight = dirtyHeight+dirtyY;
+                dirtyY = 0;
+            }
+
+            if (dirtyX+dirtyWidth > w) {
+                dirtyWidth = w - dirtyX;
+            }
+
+            if (dirtyY+dirtyHeight > h) {
+                dirtyHeight = h - dirtyY;
+            }
+
+            if (dirtyWidth <=0 || dirtyHeight <= 0)
+                return args.This();
+        } else {
+            dirtyX = 0;
+            dirtyY = 0;
+            dirtyWidth = w;
+            dirtyHeight = h;
+        }
+
+        QImage image = pixelArray->image.copy(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
+        r->context->buffer()->drawImage(image, dirtyX, dirtyY, dirtyWidth, dirtyHeight, dx, dy, dirtyWidth, dirtyHeight);
+    }
+    return args.This();
+}
+
+/*!
+  \qmlclass QtQuick2::CanvasGradient
+    \inqmlmodule QtQuick 2
+    \since QtQuick 2.0
+    \brief The Context2D opaque CanvasGradient interface.
+  */
+
+/*!
+  \qmlmethod QtQuick2::CanvasGradient QtQuick2::CanvasGradient::addColorStop(real offsetof, string color)
+  Adds a color stop with the given color to the gradient at the given offset.
+  0.0 is the offset at one end of the gradient, 1.0 is the offset at the other end.
+
+  For example:
+  \code
+  var gradient = ctx.createLinearGradient(0, 0, 100, 100);
+  gradient.addColorStop(0.3, Qt.rgba(1, 0, 0, 1));
+  gradient.addColorStop(0.7, 'rgba(0, 255, 255, 1');
+  \endcode
+  */
+static v8::Handle<v8::Value> ctx2d_gradient_addColorStop(const v8::Arguments &args)
+{
+    QV8Context2DStyleResource *style = v8_resource_cast<QV8Context2DStyleResource>(args.This());
+    if (!style)
+        V8THROW_ERROR("Not a CanvasGradient object");
+
+    QV8Engine *engine = V8ENGINE();
+
+    if (args.Length() == 2) {
+
+        if (!style->brush.gradient())
+            V8THROW_ERROR("Not a valid CanvasGradient object, can't get the gradient information");
+        QGradient gradient = *(style->brush.gradient());
+        qreal pos = args[0]->NumberValue();
+        QColor color;
+
+        if (args[1]->IsObject()) {
+            color = engine->toVariant(args[1], qMetaTypeId<QColor>()).value<QColor>();
+        } else {
+            color = qt_color_from_string(args[1]);
+        }
+        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 {
+            V8THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "CanvasGradient: parameter color is not a valid color string");
+        }
+        style->brush = gradient;
+    }
+
+    return args.This();
+}
+
+
+void QQuickContext2D::beginPath()
+{
+    m_path = QPainterPath();
+    m_path.setFillRule(state.fillRule);
+}
+
+void QQuickContext2D::closePath()
+{
+    if (m_path.isEmpty())
+        return;
+
+    QRectF boundRect = m_path.boundingRect();
+    if (boundRect.width() || boundRect.height())
+        m_path.closeSubpath();
+    //FIXME:QPainterPath set the current point to (0,0) after close subpath
+    //should be the first point of the previous subpath
+}
+
+void QQuickContext2D::moveTo( qreal x, qreal y)
+{
+    //FIXME: moveTo should not close the previous subpath
+    m_path.moveTo(state.matrix.map(QPointF(x, y)));
+}
+
+void QQuickContext2D::lineTo( qreal x, qreal y)
+{
+    m_path.lineTo(state.matrix.map(QPointF(x, y)));
+}
+
+void QQuickContext2D::quadraticCurveTo(qreal cpx, qreal cpy,
+                                           qreal x, qreal y)
+{
+    m_path.quadTo(state.matrix.map(QPointF(cpx, cpy)),
+                      state.matrix.map(QPointF(x, y)));
+}
+
+void QQuickContext2D::bezierCurveTo(qreal cp1x, qreal cp1y,
+                                        qreal cp2x, qreal cp2y,
+                                        qreal x, qreal y)
+{
+    m_path.cubicTo(state.matrix.map(QPointF(cp1x, cp1y)),
+                       state.matrix.map(QPointF(cp2x, cp2y)),
+                       state.matrix.map(QPointF(x, y)));
+}
+
+void QQuickContext2D::addArcTo(const QPointF& p1, const QPointF& p2, float radius)
+{
+    QPointF p0(m_path.currentPosition());
+
+    QPointF p1p0((p0.x() - p1.x()), (p0.y() - p1.y()));
+    QPointF p1p2((p2.x() - p1.x()), (p2.y() - p1.y()));
+    float p1p0_length = qSqrt(p1p0.x() * p1p0.x() + p1p0.y() * p1p0.y());
+    float p1p2_length = qSqrt(p1p2.x() * p1p2.x() + p1p2.y() * p1p2.y());
+
+    double cos_phi = (p1p0.x() * p1p2.x() + p1p0.y() * p1p2.y()) / (p1p0_length * p1p2_length);
+
+    // The points p0, p1, and p2 are on the same straight line (HTML5, 4.8.11.1.8)
+    // We could have used areCollinear() here, but since we're reusing
+    // the variables computed above later on we keep this logic.
+    if (qFuzzyCompare(qAbs(cos_phi), 1.0)) {
+        m_path.lineTo(p1);
+        return;
+    }
+
+    float tangent = radius / tan(acos(cos_phi) / 2);
+    float factor_p1p0 = tangent / p1p0_length;
+    QPointF t_p1p0((p1.x() + factor_p1p0 * p1p0.x()), (p1.y() + factor_p1p0 * p1p0.y()));
+
+    QPointF orth_p1p0(p1p0.y(), -p1p0.x());
+    float orth_p1p0_length = sqrt(orth_p1p0.x() * orth_p1p0.x() + orth_p1p0.y() * orth_p1p0.y());
+    float factor_ra = radius / orth_p1p0_length;
+
+    // angle between orth_p1p0 and p1p2 to get the right vector orthographic to p1p0
+    double cos_alpha = (orth_p1p0.x() * p1p2.x() + orth_p1p0.y() * p1p2.y()) / (orth_p1p0_length * p1p2_length);
+    if (cos_alpha < 0.f)
+        orth_p1p0 = QPointF(-orth_p1p0.x(), -orth_p1p0.y());
+
+    QPointF p((t_p1p0.x() + factor_ra * orth_p1p0.x()), (t_p1p0.y() + factor_ra * orth_p1p0.y()));
+
+    // calculate angles for addArc
+    orth_p1p0 = QPointF(-orth_p1p0.x(), -orth_p1p0.y());
+    float sa = acos(orth_p1p0.x() / orth_p1p0_length);
+    if (orth_p1p0.y() < 0.f)
+        sa = 2 * Q_PI - sa;
+
+    // anticlockwise logic
+    bool anticlockwise = false;
+
+    float factor_p1p2 = tangent / p1p2_length;
+    QPointF t_p1p2((p1.x() + factor_p1p2 * p1p2.x()), (p1.y() + factor_p1p2 * p1p2.y()));
+    QPointF orth_p1p2((t_p1p2.x() - p.x()), (t_p1p2.y() - p.y()));
+    float orth_p1p2_length = sqrtf(orth_p1p2.x() * orth_p1p2.x() + orth_p1p2.y() * orth_p1p2.y());
+    float ea = acos(orth_p1p2.x() / orth_p1p2_length);
+    if (orth_p1p2.y() < 0)
+        ea = 2 * Q_PI - ea;
+    if ((sa > ea) && ((sa - ea) < Q_PI))
+        anticlockwise = true;
+    if ((sa < ea) && ((ea - sa) > Q_PI))
+        anticlockwise = true;
+
+    arc(p.x(), p.y(), radius, sa, ea, anticlockwise, false);
+}
+
+void QQuickContext2D::arcTo(qreal x1, qreal y1,
+                                qreal x2, qreal y2,
+                                qreal radius)
+{
+    QPointF st  = state.matrix.map(QPointF(x1, y1));
+    QPointF end = state.matrix.map(QPointF(x2, y2));
+
+    if (!m_path.elementCount()) {
+        m_path.moveTo(st);
+    } else if (st == m_path.currentPosition() || st == end || !radius) {
+        m_path.lineTo(st);
+    } else {
+        addArcTo(st, end, radius);
+    }
+}
+
+void QQuickContext2D::rect(qreal x, qreal y,
+                               qreal w, qreal h)
+{
+    m_path.addPolygon(state.matrix.map(QRectF(x, y, w, h)));
+}
+
+void QQuickContext2D::roundedRect(qreal x, qreal y,
+                               qreal w, qreal h,
+                               qreal xr, qreal yr)
+{
+    QPainterPath path;
+    path.addRoundedRect(QRectF(x, y, w, h), xr, yr, Qt::AbsoluteSize);
+    m_path.addPath(state.matrix.map(path));
+}
+
+void QQuickContext2D::ellipse(qreal x, qreal y,
+                           qreal w, qreal h)
+{
+    QPainterPath path;
+    path.addEllipse(x, y, w, h);
+    m_path.addPath(state.matrix.map(path));
+}
+
+void QQuickContext2D::text(const QString& str, qreal x, qreal y)
+{
+    QPainterPath path;
+    path.addText(x, y, state.font, str);
+    m_path.addPath(state.matrix.map(path));
+}
+
+void QQuickContext2D::arc(qreal xc,
+                       qreal yc,
+                       qreal radius,
+                       qreal sar,
+                       qreal ear,
+                       bool antiClockWise,
+                       bool transform)
+{
+
+    if (transform) {
+        QPointF point = state.matrix.map(QPointF(xc, yc));
+        xc = point.x();
+        yc = point.y();
+    }
+    //### HACK
+
+    // In Qt we don't switch the coordinate system for degrees
+    // and still use the 0,0 as bottom left for degrees so we need
+    // to switch
+    sar = -sar;
+    ear = -ear;
+    antiClockWise = !antiClockWise;
+    //end hack
+
+    float sa = DEGREES(sar);
+    float ea = DEGREES(ear);
+
+    double span = 0;
+
+    double xs     = xc - radius;
+    double ys     = yc - radius;
+    double width  = radius*2;
+    double height = radius*2;
+    if ((!antiClockWise && (ea - sa >= 360)) || (antiClockWise && (sa - ea >= 360)))
+        // If the anticlockwise argument is false and endAngle-startAngle is equal to or greater than 2*PI, or, if the
+        // anticlockwise argument is true and startAngle-endAngle is equal to or greater than 2*PI, then the arc is the whole
+        // circumference of this circle.
+        span = 360;
+    else {
+        if (!antiClockWise && (ea < sa)) {
+            span += 360;
+        } else if (antiClockWise && (sa < ea)) {
+            span -= 360;
+        }
+        //### this is also due to switched coordinate system
+        // we would end up with a 0 span instead of 360
+        if (!(qFuzzyCompare(span + (ea - sa) + 1, 1) &&
+              qFuzzyCompare(qAbs(span), 360))) {
+            span   += ea - sa;
+        }
+        if (!m_path.elementCount())
+            m_path.moveTo(xs, ys);
+    }
+
+
+    if (transform) {
+        QPointF currentPos = m_path.currentPosition();
+        QPointF startPos = QPointF(xc + radius  * qCos(sar),
+                                   yc - radius  * qSin(sar));
+        if (currentPos != startPos)
+            m_path.lineTo(startPos);
+    }
+
+    m_path.arcTo(xs, ys, width, height, sa, span);
+}
+
+int baseLineOffset(QQuickContext2D::TextBaseLineType value, const QFontMetrics &metrics)
+{
+    int offset = 0;
+    switch (value) {
+    case QQuickContext2D::Top:
+        break;
+    case QQuickContext2D::Alphabetic:
+    case QQuickContext2D::Middle:
+    case QQuickContext2D::Hanging:
+        offset = metrics.ascent();
+        break;
+    case QQuickContext2D::Bottom:
+        offset = metrics.height();
+       break;
+    }
+    return offset;
+}
+
+static int textAlignOffset(QQuickContext2D::TextAlignType value, const QFontMetrics &metrics, const QString &text)
+{
+    int offset = 0;
+    if (value == QQuickContext2D::Start)
+        value = QGuiApplication::layoutDirection() == Qt::LeftToRight ? QQuickContext2D::Left : QQuickContext2D::Right;
+    else if (value == QQuickContext2D::End)
+        value = QGuiApplication::layoutDirection() == Qt::LeftToRight ? QQuickContext2D::Right: QQuickContext2D::Left;
+    switch (value) {
+    case QQuickContext2D::Center:
+        offset = metrics.width(text)/2;
+        break;
+    case QQuickContext2D::Right:
+        offset = metrics.width(text);
+    case QQuickContext2D::Left:
+    default:
+        break;
+    }
+    return offset;
+}
+
+
+QImage QQuickContext2D::createImage(const QUrl& url)
+{
+    return m_canvas->loadedImage(url);
+}
+
+QPainterPath QQuickContext2D::createTextGlyphs(qreal x, qreal y, const QString& text)
+{
+    const QFontMetrics metrics(state.font);
+    int yoffset = baseLineOffset(static_cast<QQuickContext2D::TextBaseLineType>(state.textBaseline), metrics);
+    int xoffset = textAlignOffset(static_cast<QQuickContext2D::TextAlignType>(state.textAlign), metrics, text);
+
+    QPainterPath textPath;
+
+    textPath.addText(x - xoffset, y - yoffset+metrics.ascent(), state.font, text);
+    textPath = state.matrix.map(textPath);
+    return textPath;
+}
+
+
+bool QQuickContext2D::isPointInPath(qreal x, qreal y) const
+{
+    return m_path.contains(QPointF(x, y));
+}
+
+QQuickContext2D::QQuickContext2D(QQuickCanvasItem* item)
+    : m_canvas(item)
+    , m_buffer(new QQuickContext2DCommandBuffer)
+    , m_v8engine(0)
+{
+    reset();
+}
+
+QQuickContext2D::~QQuickContext2D()
+{
+}
+
+v8::Handle<v8::Object> QQuickContext2D::v8value() const
+{
+    return m_v8value;
+}
+
+QQuickContext2DEngineData::QQuickContext2DEngineData(QV8Engine *engine)
+{
+    v8::HandleScope handle_scope;
+    v8::Context::Scope scope(engine->context());
+
+    v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
+    ft->InstanceTemplate()->SetHasExternalResource(true);
+    ft->PrototypeTemplate()->SetAccessor(v8::String::New("canvas"), ctx2d_canvas, 0, v8::External::Wrap(engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("restore"), V8FUNCTION(ctx2d_restore, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("reset"), V8FUNCTION(ctx2d_reset, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("save"), V8FUNCTION(ctx2d_save, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("rotate"), V8FUNCTION(ctx2d_rotate, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("scale"), V8FUNCTION(ctx2d_scale, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("resetTransform"), V8FUNCTION(ctx2d_resetTransform, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("setTransform"), V8FUNCTION(ctx2d_setTransform, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("transform"), V8FUNCTION(ctx2d_transform, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("translate"), V8FUNCTION(ctx2d_translate, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("shear"), V8FUNCTION(ctx2d_shear, engine));
+    ft->InstanceTemplate()->SetAccessor(v8::String::New("globalAlpha"), ctx2d_globalAlpha, ctx2d_globalAlpha_set, v8::External::Wrap(engine));
+    ft->InstanceTemplate()->SetAccessor(v8::String::New("globalCompositeOperation"), ctx2d_globalCompositeOperation, ctx2d_globalCompositeOperation_set, v8::External::Wrap(engine));
+    ft->InstanceTemplate()->SetAccessor(v8::String::New("fillRule"), ctx2d_fillRule, ctx2d_fillRule_set, v8::External::Wrap(engine));
+    ft->InstanceTemplate()->SetAccessor(v8::String::New("fillStyle"), ctx2d_fillStyle, ctx2d_fillStyle_set, v8::External::Wrap(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));
+    ft->InstanceTemplate()->SetAccessor(v8::String::New("lineWidth"), ctx2d_lineWidth, ctx2d_lineWidth_set, v8::External::Wrap(engine));
+    ft->InstanceTemplate()->SetAccessor(v8::String::New("miterLimit"), ctx2d_miterLimit, ctx2d_miterLimit_set, v8::External::Wrap(engine));
+    ft->InstanceTemplate()->SetAccessor(v8::String::New("shadowBlur"), ctx2d_shadowBlur, ctx2d_shadowBlur_set, v8::External::Wrap(engine));
+    ft->InstanceTemplate()->SetAccessor(v8::String::New("shadowColor"), ctx2d_shadowColor, ctx2d_shadowColor_set, v8::External::Wrap(engine));
+    ft->InstanceTemplate()->SetAccessor(v8::String::New("shadowOffsetX"), ctx2d_shadowOffsetX, ctx2d_shadowOffsetX_set, v8::External::Wrap(engine));
+    ft->InstanceTemplate()->SetAccessor(v8::String::New("shadowOffsetY"), ctx2d_shadowOffsetY, ctx2d_shadowOffsetY_set, v8::External::Wrap(engine));
+    ft->InstanceTemplate()->SetAccessor(v8::String::New("path"), ctx2d_path, ctx2d_path_set, v8::External::Wrap(engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("clearRect"), V8FUNCTION(ctx2d_clearRect, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("fillRect"), V8FUNCTION(ctx2d_fillRect, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("strokeRect"), V8FUNCTION(ctx2d_strokeRect, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("arc"), V8FUNCTION(ctx2d_arc, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("arcTo"), V8FUNCTION(ctx2d_arcTo, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("beginPath"), V8FUNCTION(ctx2d_beginPath, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("bezierCurveTo"), V8FUNCTION(ctx2d_bezierCurveTo, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("clip"), V8FUNCTION(ctx2d_clip, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("closePath"), V8FUNCTION(ctx2d_closePath, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("fill"), V8FUNCTION(ctx2d_fill, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("lineTo"), V8FUNCTION(ctx2d_lineTo, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("moveTo"), V8FUNCTION(ctx2d_moveTo, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("quadraticCurveTo"), V8FUNCTION(ctx2d_quadraticCurveTo, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("rect"), V8FUNCTION(ctx2d_rect, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("roundedRect"), V8FUNCTION(ctx2d_roundedRect, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("text"), V8FUNCTION(ctx2d_text, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("ellipse"), V8FUNCTION(ctx2d_ellipse, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("stroke"), V8FUNCTION(ctx2d_stroke, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("isPointInPath"), V8FUNCTION(ctx2d_isPointInPath, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("drawFocusRing"), V8FUNCTION(ctx2d_drawFocusRing, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("caretBlinkRate"), V8FUNCTION(ctx2d_caretBlinkRate, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("setCaretSelectionRect"), V8FUNCTION(ctx2d_setCaretSelectionRect, engine));
+    ft->InstanceTemplate()->SetAccessor(v8::String::New("font"), ctx2d_font, ctx2d_font_set, v8::External::Wrap(engine));
+    ft->InstanceTemplate()->SetAccessor(v8::String::New("textAlign"), ctx2d_textAlign, ctx2d_textAlign_set, v8::External::Wrap(engine));
+    ft->InstanceTemplate()->SetAccessor(v8::String::New("textBaseline"), ctx2d_textBaseline, ctx2d_textBaseline_set, v8::External::Wrap(engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("fillText"), V8FUNCTION(ctx2d_fillText, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("measureText"), V8FUNCTION(ctx2d_measureText, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("strokeText"), V8FUNCTION(ctx2d_strokeText, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("drawImage"), V8FUNCTION(ctx2d_drawImage, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("createImageData"), V8FUNCTION(ctx2d_createImageData, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("getImageData"), V8FUNCTION(ctx2d_getImageData, engine));
+    ft->PrototypeTemplate()->Set(v8::String::New("putImageData"), V8FUNCTION(ctx2d_putImageData, engine));
+
+    constructorContext = qPersistentNew(ft->GetFunction());
+
+    v8::Local<v8::FunctionTemplate> ftGradient = v8::FunctionTemplate::New();
+    ftGradient->InstanceTemplate()->SetHasExternalResource(true);
+    ftGradient->PrototypeTemplate()->Set(v8::String::New("addColorStop"), V8FUNCTION(ctx2d_gradient_addColorStop, engine));
+    constructorGradient = qPersistentNew(ftGradient->GetFunction());
+
+    v8::Local<v8::FunctionTemplate> ftPattern = v8::FunctionTemplate::New();
+    ftPattern->InstanceTemplate()->SetHasExternalResource(true);
+    constructorPattern = qPersistentNew(ftPattern->GetFunction());
+
+    v8::Local<v8::FunctionTemplate> ftPixelArray = v8::FunctionTemplate::New();
+    ftPixelArray->InstanceTemplate()->SetHasExternalResource(true);
+    ftPixelArray->InstanceTemplate()->SetAccessor(v8::String::New("length"), ctx2d_pixelArray_length, 0, v8::External::Wrap(engine));
+    ftPixelArray->InstanceTemplate()->SetIndexedPropertyHandler(ctx2d_pixelArray_indexed, ctx2d_pixelArray_indexed_set, 0, 0, 0, v8::External::Wrap(engine));
+    constructorPixelArray = qPersistentNew(ftPixelArray->GetFunction());
+
+    v8::Local<v8::FunctionTemplate> ftImageData = v8::FunctionTemplate::New();
+    ftImageData->InstanceTemplate()->SetAccessor(v8::String::New("width"), ctx2d_imageData_width, 0, v8::External::Wrap(engine));
+    ftImageData->InstanceTemplate()->SetAccessor(v8::String::New("height"), ctx2d_imageData_height, 0, v8::External::Wrap(engine));
+    ftImageData->InstanceTemplate()->SetAccessor(v8::String::New("data"), ctx2d_imageData_data, 0, v8::External::Wrap(engine));
+    ftImageData->PrototypeTemplate()->Set(v8::String::New("mirror"), V8FUNCTION(ctx2d_imageData_mirror, engine));
+    ftImageData->PrototypeTemplate()->Set(v8::String::New("filter"), V8FUNCTION(ctx2d_imageData_filter, engine));
+    ftImageData->InstanceTemplate()->SetInternalFieldCount(1);
+    constructorImageData = qPersistentNew(ftImageData->GetFunction());
+}
+
+QQuickContext2DEngineData::~QQuickContext2DEngineData()
+{
+    qPersistentDispose(constructorContext);
+    qPersistentDispose(constructorGradient);
+    qPersistentDispose(constructorPattern);
+    qPersistentDispose(constructorImageData);
+    qPersistentDispose(constructorPixelArray);
+}
+
+void QQuickContext2D::popState()
+{
+    if (m_stateStack.isEmpty())
+        return;
+
+    QQuickContext2D::State newState = m_stateStack.pop();
+
+    if (state.matrix != newState.matrix)
+        buffer()->updateMatrix(newState.matrix);
+
+    if (newState.globalAlpha != state.globalAlpha)
+        buffer()->setGlobalAlpha(newState.globalAlpha);
+
+    if (newState.globalCompositeOperation != state.globalCompositeOperation)
+        buffer()->setGlobalCompositeOperation(newState.globalCompositeOperation);
+
+    if (newState.fillStyle != state.fillStyle)
+        buffer()->setFillStyle(newState.fillStyle);
+
+    if (newState.strokeStyle != state.strokeStyle)
+        buffer()->setStrokeStyle(newState.strokeStyle);
+
+    if (newState.lineWidth != state.lineWidth)
+        buffer()->setLineWidth(newState.lineWidth);
+
+    if (newState.lineCap != state.lineCap)
+        buffer()->setLineCap(newState.lineCap);
+
+    if (newState.lineJoin != state.lineJoin)
+        buffer()->setLineJoin(newState.lineJoin);
+
+    if (newState.miterLimit != state.miterLimit)
+        buffer()->setMiterLimit(newState.miterLimit);
+
+    if (newState.clipPath != state.clipPath) {
+        buffer()->clip(newState.clipPath);
+    }
+
+    if (newState.shadowBlur != state.shadowBlur)
+        buffer()->setShadowBlur(newState.shadowBlur);
+
+    if (newState.shadowColor != state.shadowColor)
+        buffer()->setShadowColor(newState.shadowColor);
+
+    if (newState.shadowOffsetX != state.shadowOffsetX)
+        buffer()->setShadowOffsetX(newState.shadowOffsetX);
+
+    if (newState.shadowOffsetY != state.shadowOffsetY)
+        buffer()->setShadowOffsetY(newState.shadowOffsetY);
+    state = newState;
+}
+void QQuickContext2D::pushState()
+{
+    m_stateStack.push(state);
+}
+
+void QQuickContext2D::reset()
+{
+    QQuickContext2D::State newState;
+    newState.matrix = QTransform();
+
+    QPainterPath defaultClipPath;
+
+    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 = 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;
+    newState.lineCap = Qt::FlatCap;
+    newState.lineJoin = Qt::MiterJoin;
+    newState.miterLimit = 10;
+    newState.shadowOffsetX = 0;
+    newState.shadowOffsetY = 0;
+    newState.shadowBlur = 0;
+    newState.shadowColor = qRgba(0, 0, 0, 0);
+    newState.globalCompositeOperation = QPainter::CompositionMode_SourceOver;
+    newState.font = QFont(QLatin1String("sans-serif"), 10);
+    newState.textAlign = QQuickContext2D::Start;
+    newState.textBaseline = QQuickContext2D::Alphabetic;
+
+    m_stateStack.clear();
+    m_stateStack.push(newState);
+    popState();
+    m_buffer->clearRect(0, 0, m_canvas->width(), m_canvas->height());
+}
+
+void QQuickContext2D::setV8Engine(QV8Engine *engine)
+{
+    v8::HandleScope handle_scope;
+    v8::Context::Scope scope(engine->context());
+
+    if (m_v8engine != engine) {
+        m_v8engine = engine;
+
+        qPersistentDispose(m_v8value);
+
+        if (m_v8engine == 0)
+            return;
+
+        QQuickContext2DEngineData *ed = engineData(engine);
+        m_v8value = qPersistentNew(ed->constructorContext->NewInstance());
+        QV8Context2DResource *r = new QV8Context2DResource(engine);
+        r->context = this;
+        m_v8value->SetExternalResource(r);
+    }
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/context2d/qquickcontext2d_p.h b/src/declarative/items/context2d/qquickcontext2d_p.h
new file mode 100644 (file)
index 0000000..3c5e89c
--- /dev/null
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** 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 QQUICKCONTEXT2D_P_H
+#define QQUICKCONTEXT2D_P_H
+
+#include <QtDeclarative/qdeclarative.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+
+#include <QtGui/qpainter.h>
+#include <QtGui/qpainterpath.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qstack.h>
+#include <private/qv8engine_p.h>
+
+
+
+#define QQUICKCONTEXT2D_DEBUG //enable this for just DEBUG purpose!
+
+#ifdef QQUICKCONTEXT2D_DEBUG
+#include <QElapsedTimer>
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickCanvasItem;
+class QQuickContext2DCommandBuffer;
+class QDeclarativePixmap;
+
+class Q_DECLARATIVE_EXPORT QQuickContext2D
+{
+public:
+    enum TextBaseLineType { Alphabetic=0, Top, Middle, Bottom, Hanging};
+    enum TextAlignType { Start=0, End, Left, Right, Center};
+    enum PaintCommand {
+        Invalid = 0,
+        UpdateMatrix,
+        ClearRect,
+        FillRect,
+        StrokeRect,
+        Fill,
+        Stroke,
+        Clip,
+        UpdateBrush,
+        GlobalAlpha,
+        GlobalCompositeOperation,
+        StrokeStyle,
+        FillStyle,
+        LineWidth,
+        LineCap,
+        LineJoin,
+        MiterLimit,
+        ShadowOffsetX,
+        ShadowOffsetY,
+        ShadowBlur,
+        ShadowColor,
+        Font,
+        TextBaseline,
+        TextAlign,
+        FillText,
+        StrokeText,
+        DrawImage,
+        GetImageData
+    };
+
+
+    struct State {
+        QTransform matrix;
+        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;
+        Qt::PenCapStyle lineCap;
+        Qt::PenJoinStyle lineJoin;
+        qreal miterLimit;
+        qreal shadowOffsetX;
+        qreal shadowOffsetY;
+        qreal shadowBlur;
+        QColor shadowColor;
+        QPainter::CompositionMode globalCompositeOperation;
+        QFont font;
+        QQuickContext2D::TextAlignType textAlign;
+        QQuickContext2D::TextBaseLineType textBaseline;
+    };
+
+    QQuickContext2D(QQuickCanvasItem* item);
+    ~QQuickContext2D();
+
+    inline QQuickCanvasItem*  canvas() const {return m_canvas;}
+    inline QQuickContext2DCommandBuffer* buffer() const {return m_buffer;}
+
+    v8::Handle<v8::Object> v8value() const;
+    void setV8Engine(QV8Engine *eng);
+    void popState();
+    void pushState();
+    void reset();
+
+    // path API
+    void beginPath();
+    void closePath();
+    void moveTo(qreal x, qreal y);
+    void lineTo(qreal x, qreal y);
+    void quadraticCurveTo(qreal cpx, qreal cpy, qreal x, qreal y);
+    void bezierCurveTo(qreal cp1x, qreal cp1y,
+                       qreal cp2x, qreal cp2y, qreal x, qreal y);
+    void arcTo(qreal x1, qreal y1, qreal x2, qreal y2, qreal radius);
+    void rect(qreal x, qreal y, qreal w, qreal h);
+    void roundedRect(qreal x, qreal y,qreal w, qreal h, qreal xr, qreal yr);
+    void ellipse(qreal x, qreal y,qreal w, qreal h);
+    void text(const QString& str, qreal x, qreal y);
+    void arc(qreal x, qreal y, qreal radius,
+             qreal startAngle, qreal endAngle,
+             bool anticlockwise, bool transform=true);
+    void addArcTo(const QPointF& p1, const QPointF& p2, float radius);
+
+    bool isPointInPath(qreal x, qreal y) const;
+
+    QPainterPath createTextGlyphs(qreal x, qreal y, const QString& text);
+    QImage createImage(const QUrl& url);
+
+    State state;
+    QStack<QQuickContext2D::State> m_stateStack;
+    QQuickCanvasItem* m_canvas;
+    QQuickContext2DCommandBuffer* m_buffer;
+    QPainterPath m_path;
+    v8::Local<v8::Value> m_fillStyle;
+    v8::Local<v8::Value> m_strokeStyle;
+    v8::Handle<v8::Value> m_v8path;
+    QV8Engine *m_v8engine;
+    v8::Persistent<v8::Object> m_v8value;
+};
+
+
+QT_END_NAMESPACE
+QML_DECLARE_TYPE(QQuickContext2D)
+
+QT_END_HEADER
+
+#endif // QQUICKCONTEXT2D_P_H
diff --git a/src/declarative/items/context2d/qquickcontext2dcommandbuffer.cpp b/src/declarative/items/context2d/qquickcontext2dcommandbuffer.cpp
new file mode 100644 (file)
index 0000000..e91a21c
--- /dev/null
@@ -0,0 +1,470 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qquickcontext2dcommandbuffer_p.h"
+#include "qquickcanvasitem_p.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_Premultiplied);
+    shadowImg.fill(0);
+    QPainter tmpPainter(&shadowImg);
+    tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
+    qreal shadowX = offsetX > 0? offsetX : 0;
+    qreal shadowY = offsetY > 0? offsetY : 0;
+
+    tmpPainter.drawImage(shadowX, shadowY, image);
+    tmpPainter.end();
+
+    if (blur > 0)
+        qt_image_boxblur(shadowImg, blur/2, true);
+
+    // blacken the image with shadow color...
+    tmpPainter.begin(&shadowImg);
+    tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
+    tmpPainter.fillRect(shadowImg.rect(), color);
+    tmpPainter.end();
+    return shadowImg;
+}
+
+static void fillRectShadow(QPainter* p, QRectF shadowRect, qreal offsetX, qreal offsetY, qreal blur, const QColor& color)
+{
+    QRectF r = shadowRect;
+    r.moveTo(0, 0);
+
+    QImage shadowImage(r.size().width() + 1, r.size().height() + 1, QImage::Format_ARGB32_Premultiplied);
+    QPainter tp;
+    tp.begin(&shadowImage);
+    tp.fillRect(r, p->brush());
+    tp.end();
+    shadowImage = makeShadowImage(shadowImage, offsetX, offsetY, blur, color);
+
+    qreal dx = shadowRect.left() + (offsetX < 0? offsetX:0);
+    qreal dy = shadowRect.top() + (offsetY < 0? offsetY:0);
+
+    p->drawImage(dx, dy, shadowImage);
+    p->fillRect(shadowRect, p->brush());
+}
+
+static void fillShadowPath(QPainter* p, const QPainterPath& path, qreal offsetX, qreal offsetY, qreal blur, const QColor& color)
+{
+    QRectF r = path.boundingRect();
+    QImage img(r.size().width() + r.left() + 1,
+               r.size().height() + r.top() + 1,
+               QImage::Format_ARGB32_Premultiplied);
+    img.fill(0);
+    QPainter tp(&img);
+    tp.fillPath(path.translated(0, 0), p->brush());
+    tp.end();
+
+    QImage shadowImage = makeShadowImage(img, offsetX, offsetY, blur, color);
+    qreal dx = r.left() + (offsetX < 0? offsetX:0);
+    qreal dy = r.top() + (offsetY < 0? offsetY:0);
+
+    p->drawImage(dx, dy, shadowImage);
+    p->fillPath(path, p->brush());
+}
+
+static void strokeShadowPath(QPainter* p, const QPainterPath& path, qreal offsetX, qreal offsetY, qreal blur, const QColor& color)
+{
+    QRectF r = path.boundingRect();
+    QImage img(r.size().width() + r.left() + 1,
+               r.size().height() + r.top() + 1,
+               QImage::Format_ARGB32_Premultiplied);
+    img.fill(0);
+    QPainter tp(&img);
+    tp.strokePath(path, p->pen());
+    tp.end();
+
+    QImage shadowImage = makeShadowImage(img, offsetX, offsetY, blur, color);
+    qreal dx = r.left() + (offsetX < 0? offsetX:0);
+    qreal dy = r.top() + (offsetY < 0? offsetY:0);
+    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 QQuickContext2DCommandBuffer::makePen(QQuickContext2D::State state)
+{
+    QPen pen;
+    pen.setWidthF(state.lineWidth);
+    pen.setCapStyle(state.lineCap);
+    pen.setJoinStyle(state.lineJoin);
+    pen.setMiterLimit(state.miterLimit);
+    pen.setBrush(state.strokeStyle);
+    return pen;
+}
+
+void QQuickContext2DCommandBuffer::setPainterState(QPainter* p, QQuickContext2D::State state, const QPen& pen)
+{
+   p->setTransform(state.matrix * p->transform());
+
+   if (pen != p->pen())
+       p->setPen(pen);
+
+   if (state.fillStyle != p->brush())
+       p->setBrush(state.fillStyle);
+
+   if (state.font != p->font())
+       p->setFont(state.font);
+
+   if (state.globalAlpha != p->opacity()) {
+       p->setOpacity(state.globalAlpha);
+   }
+
+   if (state.globalCompositeOperation != p->compositionMode())
+       p->setCompositionMode(state.globalCompositeOperation);
+}
+
+QQuickContext2D::State QQuickContext2DCommandBuffer::replay(QPainter* p, QQuickContext2D::State state)
+{
+    if (!p)
+        return state;
+
+    reset();
+
+    QTransform originMatrix = p->transform();
+
+    QPen pen = makePen(state);
+    setPainterState(p, state, pen);
+
+    while (hasNext()) {
+        QQuickContext2D::PaintCommand cmd = takeNextCommand();
+        switch (cmd) {
+        case QQuickContext2D::UpdateMatrix:
+        {
+            state.matrix = takeMatrix();
+            p->setTransform(state.matrix * originMatrix);
+            break;
+        }
+        case QQuickContext2D::ClearRect:
+        {
+            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 QQuickContext2D::FillRect:
+        {
+            QRectF r = takeRect();
+            if (HAS_SHADOW(state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor))
+                fillRectShadow(p, r, state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor);
+            else
+                p->fillRect(r, p->brush());
+            break;
+        }
+        case QQuickContext2D::ShadowColor:
+        {
+            state.shadowColor = takeColor();
+            break;
+        }
+        case QQuickContext2D::ShadowBlur:
+        {
+            state.shadowBlur = takeShadowBlur();
+            break;
+        }
+        case QQuickContext2D::ShadowOffsetX:
+        {
+            state.shadowOffsetX = takeShadowOffsetX();
+            break;
+        }
+        case QQuickContext2D::ShadowOffsetY:
+        {
+            state.shadowOffsetY = takeShadowOffsetY();
+            break;
+        }
+        case QQuickContext2D::FillStyle:
+        {
+            state.fillStyle = takeFillStyle();
+            state.fillPatternRepeatX = takeBool();
+            state.fillPatternRepeatY = takeBool();
+            p->setBrush(state.fillStyle);
+            break;
+        }
+        case QQuickContext2D::StrokeStyle:
+        {
+            state.strokeStyle = takeStrokeStyle();
+            state.strokePatternRepeatX = takeBool();
+            state.strokePatternRepeatY = takeBool();
+            pen.setBrush(state.strokeStyle);
+            p->setPen(pen);
+            break;
+        }
+        case QQuickContext2D::LineWidth:
+        {
+            state.lineWidth = takeLineWidth();
+            pen.setWidth(state.lineWidth);
+            p->setPen(pen);
+            break;
+        }
+        case QQuickContext2D::LineCap:
+        {
+            state.lineCap = takeLineCap();
+            pen.setCapStyle(state.lineCap);
+            p->setPen(pen);
+            break;
+        }
+        case QQuickContext2D::LineJoin:
+        {
+            state.lineJoin = takeLineJoin();
+            pen.setJoinStyle(state.lineJoin);
+            p->setPen(pen);
+            break;
+        }
+        case QQuickContext2D::MiterLimit:
+        {
+            state.miterLimit = takeMiterLimit();
+            pen.setMiterLimit(state.miterLimit);
+            p->setPen(pen);
+            break;
+        }
+        case QQuickContext2D::TextAlign:
+        case QQuickContext2D::TextBaseline:
+            break;
+        case QQuickContext2D::Fill:
+        {
+            QPainterPath path = takePath();
+            path.closeSubpath();
+            if (HAS_SHADOW(state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor))
+                fillShadowPath(p,path, state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor);
+            else
+                p->fillPath(path, p->brush());
+            break;
+        }
+        case QQuickContext2D::Stroke:
+        {
+            if (HAS_SHADOW(state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor))
+                strokeShadowPath(p,takePath(), state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor);
+            else
+                p->strokePath(takePath(), p->pen());
+            break;
+        }
+        case QQuickContext2D::Clip:
+        {
+            state.clipPath = takePath();
+            p->setClipping(true);
+            p->setClipPath(state.clipPath);
+            break;
+        }
+        case QQuickContext2D::GlobalAlpha:
+        {
+            state.globalAlpha = takeGlobalAlpha();
+            p->setOpacity(state.globalAlpha);
+            break;
+        }
+        case QQuickContext2D::GlobalCompositeOperation:
+        {
+            state.globalCompositeOperation = takeGlobalCompositeOperation();
+            p->setCompositionMode(state.globalCompositeOperation);
+            break;
+        }
+        case QQuickContext2D::DrawImage:
+        {
+            qreal sx = takeReal();
+            qreal sy = takeReal();
+            qreal sw = takeReal();
+            qreal sh = takeReal();
+            qreal dx = takeReal();
+            qreal dy = takeReal();
+            qreal dw = takeReal();
+            qreal dh = takeReal();
+            QImage image = takeImage();
+
+            if (!image.isNull()) {
+                if (sw == -1 || sh == -1) {
+                    sw = image.width();
+                    sh = image.height();
+                }
+                if (sx != 0 || sy != 0 || sw != image.width() || sh != image.height())
+                    image = image.copy(sx, sy, sw, sh);
+
+                image = image.scaled(dw, dh);
+
+                if (HAS_SHADOW(state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor)) {
+                    QImage shadow = makeShadowImage(image, state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor);
+                    qreal shadow_dx = dx + (state.shadowOffsetX < 0? state.shadowOffsetY:0);
+                    qreal shadow_dy = dy + (state.shadowOffsetX < 0? state.shadowOffsetY:0);
+                    p->drawImage(shadow_dx, shadow_dy, shadow);
+                }
+                p->drawImage(dx, dy, image);
+            }
+            break;
+        }
+        case QQuickContext2D::GetImageData:
+        {
+            //TODO:
+            break;
+        }
+        default:
+            break;
+        }
+    }
+
+    p->end();
+    return state;
+}
+
+QQuickContext2DCommandBuffer::QQuickContext2DCommandBuffer()
+    : cmdIdx(0)
+    , intIdx(0)
+    , boolIdx(0)
+    , realIdx(0)
+    , colorIdx(0)
+    , matrixIdx(0)
+    , brushIdx(0)
+    , pathIdx(0)
+    , imageIdx(0)
+{
+}
+
+
+QQuickContext2DCommandBuffer::~QQuickContext2DCommandBuffer()
+{
+}
+
+void QQuickContext2DCommandBuffer::clear()
+{
+    commands.clear();
+    ints.clear();
+    bools.clear();
+    reals.clear();
+    colors.clear();
+    matrixes.clear();
+    brushes.clear();
+    pathes.clear();
+    images.clear();
+    reset();
+}
+
+void QQuickContext2DCommandBuffer::reset()
+{
+    cmdIdx = 0;
+    intIdx = 0;
+    boolIdx = 0;
+    realIdx = 0;
+    colorIdx = 0;
+    matrixIdx = 0;
+    brushIdx = 0;
+    pathIdx = 0;
+    imageIdx = 0;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/items/context2d/qquickcontext2dcommandbuffer_p.h b/src/declarative/items/context2d/qquickcontext2dcommandbuffer_p.h
new file mode 100644 (file)
index 0000000..46964d3
--- /dev/null
@@ -0,0 +1,268 @@
+/****************************************************************************
+**
+** 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 QQUICKCONTEXT2DCOMMANDBUFFER_P_H
+#define QQUICKCONTEXT2DCOMMANDBUFFER_P_H
+
+#include "qquickcontext2d_p.h"
+#include <private/qdeclarativepixmapcache_p.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickCanvasItem;
+class QMutex;
+
+class QQuickContext2DCommandBuffer
+{
+public:
+    QQuickContext2DCommandBuffer();
+    ~QQuickContext2DCommandBuffer();
+    void reset();
+    void clear();
+    inline int size() {return commands.size();}
+    inline bool isEmpty() const {return commands.isEmpty(); }
+    inline bool hasNext() const {return cmdIdx < commands.size(); }
+    inline QQuickContext2D::PaintCommand takeNextCommand() { return commands[cmdIdx++]; }
+
+    inline qreal takeGlobalAlpha() { return takeReal(); }
+    inline QPainter::CompositionMode takeGlobalCompositeOperation(){ return static_cast<QPainter::CompositionMode>(takeInt()); }
+    inline QBrush takeStrokeStyle() { return takeBrush(); }
+    inline QBrush takeFillStyle() { return takeBrush(); }
+
+    inline qreal takeLineWidth() { return takeReal(); }
+    inline Qt::PenCapStyle takeLineCap() { return static_cast<Qt::PenCapStyle>(takeInt());}
+    inline Qt::PenJoinStyle takeLineJoin(){ return static_cast<Qt::PenJoinStyle>(takeInt());}
+    inline qreal takeMiterLimit() { return takeReal(); }
+
+    inline void setGlobalAlpha( qreal alpha)
+    {
+        commands << QQuickContext2D::GlobalAlpha;
+        reals << alpha;
+    }
+
+    inline void setGlobalCompositeOperation(QPainter::CompositionMode cm)
+    {
+        commands << QQuickContext2D::GlobalCompositeOperation;
+        ints << cm;
+    }
+
+    inline void setStrokeStyle(const QBrush &style, bool repeatX = false, bool repeatY = false)
+    {
+        commands << QQuickContext2D::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)
+    {
+        commands << QQuickContext2D::DrawImage;
+        images << image;
+        reals << sx << sy << sw << sh << dx << dy << dw << dh;
+    }
+
+    inline qreal takeShadowOffsetX() { return takeReal(); }
+    inline qreal takeShadowOffsetY() { return takeReal(); }
+    inline qreal takeShadowBlur() { return takeReal(); }
+    inline QColor takeShadowColor() { return takeColor(); }
+
+
+    inline void updateMatrix(const QTransform& matrix)
+    {
+        commands << QQuickContext2D::UpdateMatrix;
+        matrixes << matrix;
+    }
+
+    inline void clearRect(qreal x, qreal y, qreal w, qreal h)
+    {
+        commands << QQuickContext2D::ClearRect;
+        reals << x << y << w << h;
+    }
+
+    inline void fillRect(qreal x, qreal y, qreal w, qreal h)
+    {
+        commands << QQuickContext2D::FillRect;
+        reals << x << y << w << h;
+    }
+
+    inline void strokeRect(qreal x, qreal y, qreal w, qreal h)
+    {
+        QPainterPath p;
+        p.addRect(x, y, w, h);
+
+        commands << QQuickContext2D::Stroke;
+        pathes << p;
+    }
+
+
+    inline void fill(const QPainterPath& path)
+    {
+        commands << QQuickContext2D::Fill;
+        pathes << path;
+
+    }
+
+    inline void stroke(const QPainterPath& path)
+    {
+        commands << QQuickContext2D::Stroke;
+        pathes << path;
+    }
+
+    inline void clip(const QPainterPath& path)
+    {
+        commands << QQuickContext2D::Clip;
+        pathes << path;
+    }
+
+
+
+    inline void setFillStyle(const QBrush &style, bool repeatX = false, bool repeatY = false)
+    {
+        commands << QQuickContext2D::FillStyle;
+        brushes << style;
+        bools << repeatX << repeatY;
+    }
+
+
+    inline void setLineWidth( qreal w)
+    {
+        commands << QQuickContext2D::LineWidth;
+        reals << w;
+    }
+
+    inline void setLineCap(Qt::PenCapStyle  cap)
+    {
+        commands << QQuickContext2D::LineCap;
+        ints << cap;
+    }
+
+    inline void setLineJoin(Qt::PenJoinStyle join)
+    {
+        commands << QQuickContext2D::LineJoin;
+        ints << join;
+    }
+
+    inline void setMiterLimit( qreal limit)
+    {
+        commands << QQuickContext2D::MiterLimit;
+        reals << limit;
+    }
+
+    inline void setShadowOffsetX( qreal x)
+    {
+        commands << QQuickContext2D::ShadowOffsetX;
+        reals << x;
+    }
+
+    inline void setShadowOffsetY( qreal y)
+    {
+        commands << QQuickContext2D::ShadowOffsetY;
+        reals << y;
+    }
+
+    inline void setShadowBlur( qreal b)
+    {
+        commands << QQuickContext2D::ShadowBlur;
+        reals << b;
+    }
+
+    inline void setShadowColor(const QColor &color)
+    {
+        commands << QQuickContext2D::ShadowColor;
+        colors << color;
+    }
+
+    inline QTransform takeMatrix() { return matrixes[matrixIdx++]; }
+
+    // rects
+    inline QRectF takeRect() {
+        qreal x, y, w, h;
+        x = takeReal();
+        y = takeReal();
+        w = takeReal();
+        h = takeReal();
+        return QRectF(x, y, w ,h);
+    }
+
+    inline QPainterPath takePath() { return pathes[pathIdx++]; }
+
+    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++]; }
+
+    QQuickContext2D::State replay(QPainter* painter, QQuickContext2D::State state);
+private:
+    QPen makePen(QQuickContext2D::State state);
+    void setPainterState(QPainter* painter, QQuickContext2D::State state, const QPen& pen);
+    int cmdIdx;
+    int intIdx;
+    int boolIdx;
+    int realIdx;
+    int colorIdx;
+    int matrixIdx;
+    int brushIdx;
+    int pathIdx;
+    int imageIdx;
+    QVector<QQuickContext2D::PaintCommand> commands;
+
+    QVector<int> ints;
+    QVector<bool> bools;
+    QVector<qreal> reals;
+    QVector<QColor> colors;
+    QVector<QTransform> matrixes;
+    QVector<QBrush> brushes;
+    QVector<QPainterPath> pathes;
+    QVector<QImage> images;
+};
+
+QT_END_HEADER
+
+QT_END_NAMESPACE
+
+#endif // QQUICKCONTEXT2DCOMMANDBUFFER_P_H
diff --git a/src/declarative/items/context2d/qquickcontext2dnode.cpp b/src/declarative/items/context2d/qquickcontext2dnode.cpp
new file mode 100644 (file)
index 0000000..76b50d9
--- /dev/null
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qquickcontext2dnode_p.h"
+
+#include <private/qsgcontext_p.h>
+#include <QtCore/qmath.h>
+
+QT_BEGIN_NAMESPACE
+
+
+QQuickContext2DNode::QQuickContext2DNode(QQuickCanvasItem* item)
+    : QSGGeometryNode()
+    , m_item(item)
+    , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
+    , m_texture(0)
+    , m_size(1, 1)
+    , m_dirtyGeometry(false)
+    , m_dirtyTexture(false)
+{
+    setMaterial(&m_materialO);
+    setOpaqueMaterial(&m_material);
+    setGeometry(&m_geometry);
+    setFlag(UsePreprocess, true);
+}
+
+QQuickContext2DNode::~QQuickContext2DNode()
+{
+    delete m_texture;
+}
+
+void QQuickContext2DNode::setSize(const QSizeF& size)
+{
+    if (m_size != size) {
+        m_dirtyGeometry = true;
+        m_size = size;
+    }
+}
+
+void QQuickContext2DNode::preprocess()
+{
+    bool doDirty = false;
+    QSGDynamicTexture *t = qobject_cast<QSGDynamicTexture *>(m_material.texture());
+    if (t) {
+        doDirty = t->updateTexture();
+    }
+    if (doDirty) {
+        m_dirtyTexture = true;
+        markDirty(DirtyMaterial);
+    }
+}
+void QQuickContext2DNode::setTexture(QQuickContext2DTexture* texture)
+{
+    if (texture != m_texture) {
+        m_dirtyTexture = true;
+        m_texture = texture;
+    }
+}
+
+void QQuickContext2DNode::update()
+{
+    if (m_dirtyGeometry)
+        updateGeometry();
+    if (m_dirtyTexture)
+        updateTexture();
+
+    m_dirtyGeometry = false;
+    m_dirtyTexture = false;
+}
+
+void QQuickContext2DNode::updateTexture()
+{
+    m_material.setTexture(m_texture);
+    m_materialO.setTexture(m_texture);
+    markDirty(DirtyMaterial);
+}
+
+void QQuickContext2DNode::updateGeometry()
+{
+    QRectF source = m_texture->textureSubRect();
+    QSGGeometry::updateTexturedRectGeometry(&m_geometry,
+                                            QRectF(0, 0, m_size.width(), m_size.height()),
+                                            source);
+    markDirty(DirtyGeometry);
+}
+QT_END_NAMESPACE
diff --git a/src/declarative/items/context2d/qquickcontext2dnode_p.h b/src/declarative/items/context2d/qquickcontext2dnode_p.h
new file mode 100644 (file)
index 0000000..7403aca
--- /dev/null
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** 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 QQUICKCONTEXT2DNODE_P_H
+#define QQUICKCONTEXT2DNODE_P_H
+
+#include <qsgnode.h>
+#include <qsgtexturematerial.h>
+
+#include "qquickcanvasitem_p.h"
+#include "qquickcontext2dtexture_p.h"
+#include "qquickcontext2d_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickContext2DNode : public QSGGeometryNode
+{
+public:
+    QQuickContext2DNode(QQuickCanvasItem* item);
+    virtual ~QQuickContext2DNode();
+    void setTexture(QQuickContext2DTexture* texture);
+    void update();
+    void preprocess();
+    void setSize(const QSizeF& size);
+private:
+    void updateTexture();
+    void updateGeometry();
+
+    QQuickCanvasItem* m_item;
+    QSGOpaqueTextureMaterial m_material;
+    QSGTextureMaterial m_materialO;
+    QSGGeometry m_geometry;
+    QQuickContext2DTexture* m_texture;
+    QSizeF m_size;
+
+    bool m_dirtyGeometry;
+    bool m_dirtyTexture;
+};
+
+QT_END_HEADER
+
+QT_END_NAMESPACE
+
+#endif // QQUICKCONTEXT2DNODE_P_H
diff --git a/src/declarative/items/context2d/qquickcontext2dtexture.cpp b/src/declarative/items/context2d/qquickcontext2dtexture.cpp
new file mode 100644 (file)
index 0000000..9518f91
--- /dev/null
@@ -0,0 +1,777 @@
+/****************************************************************************
+**
+** 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 "qquickcontext2dtexture_p.h"
+#include "qquickcontext2dtile_p.h"
+#include "qquickcanvasitem_p.h"
+#include <private/qquickitem_p.h>
+#include <private/qsgtexture_p.h>
+#include "qquickcontext2dcommandbuffer_p.h"
+#include <QOpenGLPaintDevice>
+
+#include <QOpenGLFramebufferObject>
+#include <QOpenGLFramebufferObjectFormat>
+#include <QtCore/QThread>
+
+#define QT_MINIMUM_FBO_SIZE 64
+
+static inline int qt_next_power_of_two(int v)
+{
+    v--;
+    v |= v >> 1;
+    v |= v >> 2;
+    v |= v >> 4;
+    v |= v >> 8;
+    v |= v >> 16;
+    ++v;
+    return v;
+}
+
+
+Q_GLOBAL_STATIC(QThread, globalCanvasThreadRenderInstance)
+
+
+QQuickContext2DTexture::QQuickContext2DTexture()
+    : QSGDynamicTexture()
+    , m_context(0)
+    , m_canvasSize(QSize(1, 1))
+    , m_tileSize(QSize(1, 1))
+    , m_canvasWindow(QRect(0, 0, 1, 1))
+    , m_dirtyCanvas(false)
+    , m_dirtyTexture(false)
+    , m_threadRendering(false)
+    , m_smooth(false)
+    , m_tiledCanvas(false)
+    , m_doGrabImage(false)
+    , m_painting(false)
+{
+}
+
+QQuickContext2DTexture::~QQuickContext2DTexture()
+{
+   clearTiles();
+}
+
+QSize QQuickContext2DTexture::textureSize() const
+{
+    return m_canvasWindow.size();
+}
+
+void QQuickContext2DTexture::markDirtyTexture()
+{
+    lock();
+    m_dirtyTexture = true;
+    unlock();
+    emit textureChanged();
+}
+
+bool QQuickContext2DTexture::setCanvasSize(const QSize &size)
+{
+    if (m_canvasSize != size) {
+        m_canvasSize = size;
+        m_dirtyCanvas = true;
+        return true;
+    }
+    return false;
+}
+
+bool QQuickContext2DTexture::setTileSize(const QSize &size)
+{
+    if (m_tileSize != size) {
+        m_tileSize = size;
+        m_dirtyCanvas = true;
+        return true;
+    }
+    return false;
+}
+
+void QQuickContext2DTexture::setSmooth(bool smooth)
+{
+    m_smooth = smooth;
+}
+
+void QQuickContext2DTexture::setItem(QQuickCanvasItem* item)
+{
+    if (!item) {
+        lock();
+        m_item = 0;
+        m_context = 0;
+        unlock();
+        wake();
+    } else if (m_item != item) {
+        lock();
+        m_item = item;
+        m_context = item->context();
+        m_state = m_context->state;
+        unlock();
+        connect(this, SIGNAL(textureChanged()), m_item, SIGNAL(painted()));
+    }
+}
+
+bool QQuickContext2DTexture::setCanvasWindow(const QRect& r)
+{
+    if (m_canvasWindow != r) {
+        m_canvasWindow = r;
+        return true;
+    }
+    return false;
+}
+
+bool QQuickContext2DTexture::setDirtyRect(const QRect &r)
+{
+    bool doDirty = false;
+    if (m_tiledCanvas) {
+        foreach (QQuickContext2DTile* 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;
+}
+
+void QQuickContext2DTexture::canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth)
+{
+    lock();
+
+    QSize ts = tileSize;
+    if (ts.width() > canvasSize.width())
+        ts.setWidth(canvasSize.width());
+
+    if (ts.height() > canvasSize.height())
+        ts.setHeight(canvasSize.height());
+
+    setCanvasSize(canvasSize);
+    setTileSize(ts);
+
+    if (canvasSize == canvasWindow.size()) {
+        m_tiledCanvas = false;
+        m_dirtyCanvas = false;
+    } else {
+        m_tiledCanvas = true;
+    }
+
+    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);
+        }
+    }
+
+    setSmooth(smooth);
+    unlock();
+}
+
+void QQuickContext2DTexture::paintWithoutTiles()
+{
+    QQuickContext2DCommandBuffer* ccb = m_context->buffer();
+
+    if (ccb->isEmpty() && m_threadRendering && !m_doGrabImage) {
+        lock();
+        if (m_item)
+            QMetaObject::invokeMethod(m_item, "_doPainting", Qt::QueuedConnection, Q_ARG(QRectF, QRectF(0, 0, m_canvasSize.width(), m_canvasSize.height())));
+        wait();
+        unlock();
+    }
+    if (ccb->isEmpty()) {
+        return;
+    }
+
+    QPaintDevice* device = beginPainting();
+    if (!device) {
+        endPainting();
+        return;
+    }
+
+    QPainter p;
+    p.begin(device);
+    if (m_smooth)
+        p.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing
+                               | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
+    else
+        p.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing
+                                 | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, false);
+    p.setCompositionMode(QPainter::CompositionMode_SourceOver);
+    m_state = ccb->replay(&p, m_state);
+
+    ccb->clear();
+    markDirtyTexture();
+    endPainting();
+}
+
+bool QQuickContext2DTexture::canvasDestroyed()
+{
+    bool noCanvas = false;
+    lock();
+    noCanvas = m_item == 0;
+    unlock();
+    return noCanvas;
+}
+
+void QQuickContext2DTexture::paint()
+{
+    if (canvasDestroyed())
+        return;
+
+    if (!m_tiledCanvas) {
+        paintWithoutTiles();
+    } else {
+        QQuickContext2D::State oldState = m_state;
+        QQuickContext2DCommandBuffer* ccb = m_context->buffer();
+
+        lock();
+        QRect tiledRegion = createTiles(m_canvasWindow.intersected(QRect(QPoint(0, 0), m_canvasSize)));
+        unlock();
+
+        if (!tiledRegion.isEmpty()) {
+            if (m_threadRendering && !m_doGrabImage) {
+                QRect dirtyRect;
+
+                lock();
+                foreach (QQuickContext2DTile* tile, m_tiles) {
+                    if (tile->dirty()) {
+                        if (dirtyRect.isEmpty())
+                            dirtyRect = tile->rect();
+                        else
+                            dirtyRect |= tile->rect();
+                    }
+                }
+                unlock();
+
+                if (dirtyRect.isValid()) {
+                    lock();
+                    if (m_item)
+                        QMetaObject::invokeMethod(m_item, "_doPainting", Qt::QueuedConnection, Q_ARG(QRectF, dirtyRect));
+                    wait();
+                    unlock();
+                }
+            }
+
+            if (beginPainting()) {
+                foreach (QQuickContext2DTile* tile, m_tiles) {
+                    bool dirtyTile = false, dirtyCanvas = false, smooth = false;
+
+                    lock();
+                    dirtyTile = tile->dirty();
+                    smooth = m_smooth;
+                    dirtyCanvas  = m_dirtyCanvas;
+                    unlock();
+
+                    //canvas size or tile size may change during painting tiles
+                    if (dirtyCanvas) {
+                        if (m_threadRendering)
+                            QMetaObject::invokeMethod(this, "paint", Qt::QueuedConnection);
+                        endPainting();
+                        return;
+                    } else if (dirtyTile) {
+                        m_state = ccb->replay(tile->createPainter(smooth), oldState);
+                        tile->drawFinished();
+                        lock();
+                        tile->markDirty(false);
+                        unlock();
+                    }
+
+                    compositeTile(tile);
+                }
+                ccb->clear();
+                endPainting();
+                markDirtyTexture();
+            }
+        }
+    }
+}
+
+QRect QQuickContext2DTexture::tiledRect(const QRectF& window, const QSize& tileSize)
+{
+    if (window.isEmpty())
+        return QRect();
+
+    const int tw = tileSize.width();
+    const int th = tileSize.height();
+    const int h1 = window.left() / tw;
+    const int v1 = window.top() / th;
+
+    const int htiles = ((window.right() - h1 * tw) + tw - 1)/tw;
+    const int vtiles = ((window.bottom() - v1 * th) + th - 1)/th;
+
+    return QRect(h1 * tw, v1 * th, htiles * tw, vtiles * th);
+}
+
+QRect QQuickContext2DTexture::createTiles(const QRect& window)
+{
+    QList<QQuickContext2DTile*> oldTiles = m_tiles;
+    m_tiles.clear();
+
+    if (window.isEmpty()) {
+        m_dirtyCanvas = false;
+        return QRect();
+    }
+
+    QRect r = tiledRect(window, m_tileSize);
+
+    const int tw = m_tileSize.width();
+    const int th = m_tileSize.height();
+    const int h1 = window.left() / tw;
+    const int v1 = window.top() / th;
+
+
+    const int htiles = r.width() / tw;
+    const int vtiles = r.height() / th;
+
+    for (int yy = 0; yy < vtiles; ++yy) {
+        for (int xx = 0; xx < htiles; ++xx) {
+            int ht = xx + h1;
+            int vt = yy + v1;
+
+            QQuickContext2DTile* tile = 0;
+
+            QPoint pos(ht * tw, vt * th);
+            QRect rect(pos, m_tileSize);
+
+            for (int i = 0; i < oldTiles.size(); i++) {
+                if (oldTiles[i]->rect() == rect) {
+                    tile = oldTiles.takeAt(i);
+                    break;
+                }
+            }
+
+            if (!tile)
+                tile = createTile();
+
+            tile->setRect(rect);
+            m_tiles.append(tile);
+        }
+    }
+
+    qDeleteAll(oldTiles);
+
+    m_dirtyCanvas = false;
+    return r;
+}
+
+void QQuickContext2DTexture::clearTiles()
+{
+    qDeleteAll(m_tiles);
+    m_tiles.clear();
+}
+
+QQuickContext2DFBOTexture::QQuickContext2DFBOTexture()
+    : QQuickContext2DTexture()
+    , m_fbo(0)
+    , m_multisampledFbo(0)
+    , m_paint_device(0)
+{
+    m_threadRendering = false;
+}
+
+QQuickContext2DFBOTexture::~QQuickContext2DFBOTexture()
+{
+    delete m_fbo;
+    delete m_multisampledFbo;
+    delete m_paint_device;
+}
+
+bool QQuickContext2DFBOTexture::setCanvasSize(const QSize &size)
+{
+    QSize s = QSize(qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.width()))
+                  , qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.height())));
+
+    if (m_canvasSize != s) {
+        m_canvasSize = s;
+        m_dirtyCanvas = true;
+        return true;
+    }
+    return false;
+}
+
+bool QQuickContext2DFBOTexture::setTileSize(const QSize &size)
+{
+    QSize s = QSize(qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.width()))
+                  , qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.height())));
+    if (m_tileSize != s) {
+        m_tileSize = s;
+        m_dirtyCanvas = true;
+        return true;
+    }
+    return false;
+}
+
+bool QQuickContext2DFBOTexture::setCanvasWindow(const QRect& canvasWindow)
+{
+    QSize s = QSize(qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(canvasWindow.size().width()))
+                  , qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(canvasWindow.size().height())));
+
+
+    bool doChanged = false;
+    if (m_fboSize != s) {
+        m_fboSize = s;
+        doChanged = true;
+    }
+
+    if (m_canvasWindow != canvasWindow)
+        m_canvasWindow = canvasWindow;
+
+    return doChanged;
+}
+
+void QQuickContext2DFBOTexture::bind()
+{
+    glBindTexture(GL_TEXTURE_2D, textureId());
+    updateBindOptions();
+}
+
+QRectF QQuickContext2DFBOTexture::textureSubRect() const
+{
+    return QRectF(0
+                , 0
+                , qreal(m_canvasWindow.width()) / m_fboSize.width()
+                , qreal(m_canvasWindow.height()) / m_fboSize.height());
+}
+
+
+int QQuickContext2DFBOTexture::textureId() const
+{
+    return m_fbo? m_fbo->texture() : 0;
+}
+
+
+bool QQuickContext2DFBOTexture::updateTexture()
+{
+    if (!m_context->buffer()->isEmpty()) {
+        paint();
+    }
+
+    bool textureUpdated = m_dirtyTexture;
+
+    m_dirtyTexture = false;
+
+    if (m_doGrabImage) {
+        grabImage();
+        m_condition.wakeOne();
+        m_doGrabImage = false;
+    }
+    return textureUpdated;
+}
+
+QQuickContext2DTile* QQuickContext2DFBOTexture::createTile() const
+{
+    return new QQuickContext2DFBOTile();
+}
+
+void QQuickContext2DFBOTexture::grabImage()
+{
+    if (m_fbo) {
+        m_grabedImage = m_fbo->toImage();
+    }
+}
+
+bool QQuickContext2DFBOTexture::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 QQuickContext2DFBOTexture::toImage(const QRectF& region)
+{
+#define QML_CONTEXT2D_WAIT_MAX 5000
+
+    m_doGrabImage = true;
+    if (m_item)
+        m_item->update();
+
+    QImage grabbed;
+    m_mutex.lock();
+    bool ok = m_condition.wait(&m_mutex, QML_CONTEXT2D_WAIT_MAX);
+
+    if (!ok)
+        grabbed = QImage();
+
+    if (region.isValid())
+        grabbed = m_grabedImage.copy(region.toRect());
+    else
+        grabbed = m_grabedImage;
+    m_grabedImage = QImage();
+    return grabbed;
+}
+
+void QQuickContext2DFBOTexture::compositeTile(QQuickContext2DTile* tile)
+{
+    QQuickContext2DFBOTile* t = static_cast<QQuickContext2DFBOTile*>(tile);
+    QRect target = t->rect().intersect(m_canvasWindow);
+    if (target.isValid()) {
+        QRect source = target;
+
+        source.moveTo(source.topLeft() - t->rect().topLeft());
+        target.moveTo(target.topLeft() - m_canvasWindow.topLeft());
+
+        QOpenGLFramebufferObject::blitFramebuffer(m_fbo, target, t->fbo(), source);
+    }
+}
+QQuickCanvasItem::RenderTarget QQuickContext2DFBOTexture::renderTarget() const
+{
+    return QQuickCanvasItem::FramebufferObject;
+}
+QPaintDevice* QQuickContext2DFBOTexture::beginPainting()
+{
+    QQuickContext2DTexture::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) {
+        delete m_fbo;
+        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);
+        }
+    }
+
+    if (doMultisampling())
+        m_multisampledFbo->bind();
+    else
+        m_fbo->bind();
+
+
+    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 QQuickContext2DFBOTexture::endPainting()
+{
+    QQuickContext2DTexture::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();
+
+    if (thread->isRunning()) {
+        thread->exit(0);
+        thread->wait(1000);
+    }
+}
+
+QQuickContext2DImageTexture::QQuickContext2DImageTexture(bool threadRendering)
+    : QQuickContext2DTexture()
+    , m_texture(new QSGPlainTexture())
+{
+    m_texture->setOwnsTexture(true);
+    m_texture->setHasMipmaps(false);
+
+    m_threadRendering = threadRendering;
+
+    if (m_threadRendering) {
+        QThread* thread = globalCanvasThreadRenderInstance();
+        moveToThread(thread);
+
+        if (!thread->isRunning()) {
+            qAddPostRoutine(qt_quit_context2d_render_thread);
+            thread->start();
+        }
+    }
+}
+
+QQuickContext2DImageTexture::~QQuickContext2DImageTexture()
+{
+    delete m_texture;
+}
+
+int QQuickContext2DImageTexture::textureId() const
+{
+    return m_texture->textureId();
+}
+
+void QQuickContext2DImageTexture::lock()
+{
+    if (m_threadRendering)
+        m_mutex.lock();
+}
+void QQuickContext2DImageTexture::unlock()
+{
+    if (m_threadRendering)
+        m_mutex.unlock();
+}
+
+void QQuickContext2DImageTexture::wait()
+{
+    if (m_threadRendering)
+        m_waitCondition.wait(&m_mutex);
+}
+
+void QQuickContext2DImageTexture::wake()
+{
+    if (m_threadRendering)
+        m_waitCondition.wakeOne();
+}
+
+bool QQuickContext2DImageTexture::supportDirectRendering() const
+{
+    return !m_threadRendering;
+}
+
+QQuickCanvasItem::RenderTarget QQuickContext2DImageTexture::renderTarget() const
+{
+    return QQuickCanvasItem::Image;
+}
+
+void QQuickContext2DImageTexture::bind()
+{
+    m_texture->bind();
+}
+
+bool QQuickContext2DImageTexture::updateTexture()
+{
+    lock();
+    bool textureUpdated = m_dirtyTexture;
+    if (m_dirtyTexture) {
+        m_texture->setImage(m_image);
+        m_dirtyTexture = false;
+    }
+    unlock();
+    return textureUpdated;
+}
+
+QQuickContext2DTile* QQuickContext2DImageTexture::createTile() const
+{
+    return new QQuickContext2DImageTile();
+}
+
+void QQuickContext2DImageTexture::grabImage(const QRect& r)
+{
+    m_doGrabImage = true;
+    paint();
+    m_doGrabImage = false;
+    m_grabedImage = m_image.copy(r);
+}
+
+QImage QQuickContext2DImageTexture::toImage(const QRectF& region)
+{
+    QRect r = region.isValid() ? region.toRect() : QRect(QPoint(0, 0), m_canvasWindow.size());
+    if (threadRendering()) {
+        wake();
+        QMetaObject::invokeMethod(this, "grabImage", Qt::BlockingQueuedConnection, Q_ARG(QRect, r));
+    } else {
+        QMetaObject::invokeMethod(this, "grabImage", Qt::DirectConnection, Q_ARG(QRect, r));
+    }
+    QImage image = m_grabedImage;
+    m_grabedImage = QImage();
+    return image;
+}
+
+QPaintDevice* QQuickContext2DImageTexture::beginPainting()
+{
+     QQuickContext2DTexture::beginPainting();
+
+    if (m_canvasWindow.size().isEmpty())
+        return 0;
+
+    lock();
+    if (m_image.size() != m_canvasWindow.size()) {
+        m_image = QImage(m_canvasWindow.size(), QImage::Format_ARGB32_Premultiplied);
+        m_image.fill(0x00000000);
+    }
+    unlock();
+    return &m_image;
+}
+
+void QQuickContext2DImageTexture::compositeTile(QQuickContext2DTile* tile)
+{
+    Q_ASSERT(!tile->dirty());
+    QQuickContext2DImageTile* t = static_cast<QQuickContext2DImageTile*>(tile);
+    QRect target = t->rect().intersect(m_canvasWindow);
+    if (target.isValid()) {
+        QRect source = target;
+        source.moveTo(source.topLeft() - t->rect().topLeft());
+        target.moveTo(target.topLeft() - m_canvasWindow.topLeft());
+
+        lock();
+        m_painter.begin(&m_image);
+        m_painter.setCompositionMode(QPainter::CompositionMode_Source);
+        m_painter.drawImage(target, t->image(), source);
+        m_painter.end();
+        unlock();
+    }
+}
diff --git a/src/declarative/items/context2d/qquickcontext2dtexture_p.h b/src/declarative/items/context2d/qquickcontext2dtexture_p.h
new file mode 100644 (file)
index 0000000..ed45a09
--- /dev/null
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** 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 QQUICKCONTEXT2DTEXTURE_P_H
+#define QQUICKCONTEXT2DTEXTURE_P_H
+
+#include <qsgtexture.h>
+#include "qquickcanvasitem_p.h"
+#include "qquickcontext2d_p.h"
+
+#include <QOpenGLContext>
+#include <QOpenGLFramebufferObject>
+
+#include <QtCore/QMutex>
+#include <QtCore/QWaitCondition>
+#include <QtCore/QThread>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickContext2DTile;
+class QQuickContext2DCommandBuffer;
+
+class QQuickContext2DTexture : public QSGDynamicTexture
+{
+    Q_OBJECT
+public:
+    QQuickContext2DTexture();
+    ~QQuickContext2DTexture();
+
+    virtual bool hasAlphaChannel() const {return true;}
+    virtual bool hasMipmaps() const {return false;}
+    virtual QSize textureSize() const;
+    virtual void lock() {}
+    virtual void unlock() {}
+    virtual void wait() {}
+    virtual void wake() {}
+    bool threadRendering() const {return m_threadRendering;}
+    virtual bool supportThreadRendering() const = 0;
+    virtual bool supportDirectRendering() const = 0;
+    virtual QQuickCanvasItem::RenderTarget renderTarget() const = 0;
+    virtual QImage toImage(const QRectF& region = QRectF()) = 0;
+    static QRect tiledRect(const QRectF& window, const QSize& tileSize);
+
+    virtual bool setCanvasSize(const QSize &size);
+    virtual bool setTileSize(const QSize &size);
+    virtual bool setCanvasWindow(const QRect& canvasWindow);
+    void setSmooth(bool smooth);
+    bool setDirtyRect(const QRect &dirtyRect);
+    virtual void canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth);
+    bool canvasDestroyed();
+Q_SIGNALS:
+    void textureChanged();
+
+public Q_SLOTS:
+    void markDirtyTexture();
+    void setItem(QQuickCanvasItem* item);
+    void paint();
+
+protected:
+    void paintWithoutTiles();
+    virtual QPaintDevice* beginPainting() {m_painting = true; return 0; }
+    virtual void endPainting() {m_painting = false;}
+    virtual QQuickContext2DTile* createTile() const = 0;
+    virtual void compositeTile(QQuickContext2DTile* tile) = 0;
+
+    void clearTiles();
+    QRect createTiles(const QRect& window);
+
+    QList<QQuickContext2DTile*> m_tiles;
+    QQuickContext2D* m_context;
+
+    QQuickContext2D::State m_state;
+
+    QQuickCanvasItem* m_item;
+    QSize m_canvasSize;
+    QSize m_tileSize;
+    QRect m_canvasWindow;
+
+    uint m_dirtyCanvas : 1;
+    uint m_dirtyTexture : 1;
+    uint m_threadRendering : 1;
+    uint m_smooth : 1;
+    uint m_tiledCanvas : 1;
+    uint m_doGrabImage : 1;
+    uint m_painting : 1;
+};
+
+class QQuickContext2DFBOTexture : public QQuickContext2DTexture
+{
+    Q_OBJECT
+
+public:
+    QQuickContext2DFBOTexture();
+    ~QQuickContext2DFBOTexture();
+    virtual int textureId() const;
+    virtual bool updateTexture();
+    virtual QQuickContext2DTile* 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;}
+    virtual QQuickCanvasItem::RenderTarget renderTarget() const;
+    virtual void compositeTile(QQuickContext2DTile* tile);
+    virtual void bind();
+    virtual bool setCanvasSize(const QSize &size);
+    virtual bool setTileSize(const QSize &size);
+    virtual bool setCanvasWindow(const QRect& canvasWindow);
+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;
+    QPaintDevice *m_paint_device;
+};
+
+class QSGPlainTexture;
+class QQuickContext2DImageTexture : public QQuickContext2DTexture
+{
+    Q_OBJECT
+
+public:
+    QQuickContext2DImageTexture(bool threadRendering = true);
+    ~QQuickContext2DImageTexture();
+    virtual int textureId() const;
+    virtual void bind();
+    virtual bool supportThreadRendering() const {return true;}
+    virtual bool supportDirectRendering() const;
+    virtual QQuickCanvasItem::RenderTarget renderTarget() const;
+    virtual void lock();
+    virtual void unlock();
+    virtual void wait();
+    virtual void wake();
+
+    virtual bool updateTexture();
+    virtual QQuickContext2DTile* createTile() const;
+    virtual QImage toImage(const QRectF& region = QRectF());
+    virtual QPaintDevice* beginPainting();
+    virtual void compositeTile(QQuickContext2DTile* tile);
+
+private Q_SLOTS:
+    void grabImage(const QRect& r);
+private:
+    QImage m_image;
+    QImage m_grabedImage;
+    QMutex m_mutex;
+    QWaitCondition m_waitCondition;
+    QPainter m_painter;
+    QSGPlainTexture*  m_texture;
+};
+
+QT_END_HEADER
+
+QT_END_NAMESPACE
+
+#endif // QQUICKCONTEXT2DTEXTURE_P_H
diff --git a/src/declarative/items/context2d/qquickcontext2dtile.cpp b/src/declarative/items/context2d/qquickcontext2dtile.cpp
new file mode 100644 (file)
index 0000000..6217c66
--- /dev/null
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qquickcontext2dtile_p.h"
+
+#include <QOpenGLFramebufferObject>
+#include <QOpenGLFramebufferObjectFormat>
+#include <QOpenGLPaintDevice>
+
+QQuickContext2DTile::QQuickContext2DTile()
+    : m_dirty(true)
+    , m_rect(QRect(0, 0, 1, 1))
+    , m_device(0)
+{
+}
+
+QQuickContext2DTile::~QQuickContext2DTile()
+{
+    if (m_painter.isActive())
+        m_painter.end();
+}
+
+QPainter* QQuickContext2DTile::createPainter(bool smooth)
+{
+    if (m_painter.isActive())
+        m_painter.end();
+
+    if (m_device) {
+        aboutToDraw();
+        m_painter.begin(m_device);
+        m_painter.resetTransform();
+        m_painter.setCompositionMode(QPainter::CompositionMode_Source);
+
+#ifdef QQUICKCONTEXT2D_DEBUG
+        int v = 100;
+        int gray = (m_rect.x() / m_rect.width() + m_rect.y() / m_rect.height()) % 2;
+        if (gray)
+            v = 150;
+        m_painter.fillRect(QRect(0, 0, m_rect.width(), m_rect.height()), QColor(v, v, v, 255));
+#endif
+        if (smooth)
+            m_painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing
+                                   | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
+        else
+            m_painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing
+                                     | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, false);
+
+        m_painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
+        m_painter.translate(-m_rect.left(), -m_rect.top());
+        m_painter.setClipRect(m_rect);
+        m_painter.setClipping(false);
+        return &m_painter;
+    }
+
+    return 0;
+}
+
+QQuickContext2DFBOTile::QQuickContext2DFBOTile()
+    : QQuickContext2DTile()
+    , m_fbo(0)
+{
+}
+
+
+QQuickContext2DFBOTile::~QQuickContext2DFBOTile()
+{
+    delete m_fbo;
+}
+
+void QQuickContext2DFBOTile::aboutToDraw()
+{
+    m_fbo->bind();
+    if (!m_device) {
+        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 QQuickContext2DFBOTile::drawFinished()
+{
+    m_fbo->release();
+}
+
+void QQuickContext2DFBOTile::setRect(const QRect& r)
+{
+    if (m_rect == r)
+        return;
+    m_rect = r;
+    m_dirty = true;
+    if (!m_fbo || m_fbo->size() != r.size()) {
+        QOpenGLFramebufferObjectFormat format;
+        format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
+        format.setInternalTextureFormat(GL_RGBA);
+        format.setMipmap(false);
+
+        if (m_painter.isActive())
+            m_painter.end();
+
+        delete m_fbo;
+        m_fbo = new QOpenGLFramebufferObject(r.size(), format);
+    }
+}
+
+
+QQuickContext2DImageTile::QQuickContext2DImageTile()
+    : QQuickContext2DTile()
+{
+}
+
+QQuickContext2DImageTile::~QQuickContext2DImageTile()
+{
+}
+
+void QQuickContext2DImageTile::setRect(const QRect& r)
+{
+    if (m_rect == r)
+        return;
+    m_rect = r;
+    m_dirty = true;
+    if (m_image.size() != r.size()) {
+        m_image = QImage(r.size(), QImage::Format_ARGB32_Premultiplied);
+    }
+    m_device = &m_image;
+}
diff --git a/src/declarative/items/context2d/qquickcontext2dtile_p.h b/src/declarative/items/context2d/qquickcontext2dtile_p.h
new file mode 100644 (file)
index 0000000..92c59ef
--- /dev/null
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** 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 QQUICKCONTEXT2DTILE_P_H
+#define QQUICKCONTEXT2DTILE_P_H
+
+#include "qquickcontext2d_p.h"
+#include <QOpenGLFramebufferObject>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickContext2DTexture;
+class QQuickContext2DCommandBuffer;
+
+class QQuickContext2DTile
+{
+public:
+    QQuickContext2DTile();
+    ~QQuickContext2DTile();
+
+    bool dirty() const {return m_dirty;}
+    void markDirty(bool dirty) {m_dirty = dirty;}
+
+    QRect rect() const {return m_rect;}
+
+    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;
+    QPainter m_painter;
+};
+
+
+class QQuickContext2DFBOTile : public QQuickContext2DTile
+{
+public:
+    QQuickContext2DFBOTile();
+    ~QQuickContext2DFBOTile();
+    virtual void setRect(const QRect& r);
+    QOpenGLFramebufferObject* fbo() const {return m_fbo;}
+    void drawFinished();
+
+protected:
+    void aboutToDraw();
+private:
+
+
+    QOpenGLFramebufferObject *m_fbo;
+};
+
+class QQuickContext2DImageTile : public QQuickContext2DTile
+{
+public:
+    QQuickContext2DImageTile();
+    ~QQuickContext2DImageTile();
+    void setRect(const QRect& r);
+    const QImage& image() const {return m_image;}
+private:
+    QImage m_image;
+};
+QT_END_HEADER
+
+QT_END_NAMESPACE
+
+#endif // QQUICKCONTEXT2DTILE_P_H
diff --git a/src/declarative/items/context2d/qsgcanvasitem.cpp b/src/declarative/items/context2d/qsgcanvasitem.cpp
deleted file mode 100644 (file)
index b3b4eab..0000000
+++ /dev/null
@@ -1,728 +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$
-**
-****************************************************************************/
-
-#include <private/qsgadaptationlayer_p.h>
-#include "qsgcanvasitem_p.h"
-#include <private/qsgitem_p.h>
-#include "qsgcontext2d_p.h"
-#include "qsgcontext2dnode_p.h"
-#include "qsgcontext2dtexture_p.h"
-#include <private/qdeclarativepixmapcache_p.h>
-
-#include <qdeclarativeinfo.h>
-#include <private/qdeclarativeengine_p.h>
-#include <QtCore/QBuffer>
-
-QT_BEGIN_NAMESPACE
-
-class QSGCanvasItemPrivate : public QSGItemPrivate
-{
-public:
-    QSGCanvasItemPrivate();
-    ~QSGCanvasItemPrivate();
-    QSGContext2D* context;
-    QSGContext2DTexture* texture;
-    QSizeF canvasSize;
-    QSize tileSize;
-    QRectF canvasWindow;
-    QRectF dirtyRect;
-    uint renderInThread : 1;
-    uint hasCanvasSize :1;
-    uint hasTileSize :1;
-    uint hasCanvasWindow :1;
-    uint componentCompleted :1;
-    QSGCanvasItem::RenderTarget renderTarget;
-    QHash<QUrl, QDeclarativePixmap*> images;
-    QUrl baseUrl;
-};
-
-QSGCanvasItemPrivate::QSGCanvasItemPrivate()
-    : QSGItemPrivate()
-    , context(0)
-    , texture(0)
-    , canvasSize(1, 1)
-    , tileSize(1, 1)
-    , renderInThread(false)
-    , hasCanvasSize(false)
-    , hasTileSize(false)
-    , hasCanvasWindow(false)
-    , componentCompleted(false)
-    , renderTarget(QSGCanvasItem::FramebufferObject)
-{
-}
-
-QSGCanvasItemPrivate::~QSGCanvasItemPrivate()
-{
-    qDeleteAll(images);
-}
-
-/*!
-    \qmlclass Canvas QSGCanvasItem
-    \inqmlmodule QtQuick 2
-    \since QtQuick 2.0
-    \brief The Canvas item provides HTML5 like canvas element which enables you to
-    draw within the item area by using Javascript.
-    \inherits Item
-    \ingroup qml-basic-visual-elements
-
-    With the Canvas item, users can draw straight and curved lines, simple and
-    complex shapes, graphs, and referenced graphic images. can also add texts, colors,
-    shadows, gradients, and patterns, and do low level pixel operations, etc. The Canvas item
-    also enables you to save or export the canvas as a image file or serialize the image data
-    to data url string.
-
-    To define a drawing area in the Canvas item, just set the \c width and \c height properties.
-    For example, the following code creates a Canvas item which has a drawing area with a height of 100
-    pixels and width of 200 pixels:
-    \qml
-    import QtQuick 2.0
-    Canvas {
-      id:mycanvas
-      width:100
-      height:200
-    }
-    \endqml
-
-    Currently the Canvas item only supports the two-dimensional rendering context.
-
-    \section1 Thread Rendering and Render Target
-    The Canvas item supports two render targets:Canvas.Image and Canvas.FramebufferObject.
-    The Canvas.Image render target is a \a QImage object which is actually a block of system
-    memory. This render target support background thread rendering. So if some complex or long
-    running painting need to be done, the Canvas.Image with thread rendering mode should be
-    chosen to avoid blocking the UI. Otherwise the Canvas.FramebufferObject render target should
-    be chosen as it could be much faster with good OpenGL hardware accelaration than rendering into
-    system memory, especially when the CPU is already very busy.
-
-    The default render target is Canvas.Image and the default renderInThread property is
-    false.
-
-    \section1 Tiled Canvas
-    The Canvas item also supports tiled rendering mode by setting the proper canvasSize, tileSize
-    and the canvasWindow properties.
-
-    With tiled canvas, a virtually very large canvas can be provided by a relatively small canvas
-    window. The actual memory consumption only relates to the canvas window size. So the canvas size
-    can be chosen freely as needed. The painting code then doesn't need to worry about the coordinate
-    system and complex matrix transformations at all.
-
-    As a side effect, by setting a good tile size, the tiles overlapped with the canvas window could be
-    cached and don't need to redraw, which can improve the performance significantly in some situations.
-
-    \section1 Pixel Operations
-    The Canvas item support all HTML5 2d context pixel operations. In order to get better
-    pixel reading/writing performance, the Canvas.Image render target should be chosen. As
-    for Canvas.FramebufferObject render target, the pixel data need to be exchanged between
-    the system memory and the graphic card, which can't be benefit from the hardware acceleration
-    at all. And the OpenGL rendering may synchronise with the V-Sync signal to avoid the
-    {en.wikipedia.org/wiki/Screen_tearing}{screen tearing} which makes the pixel operations
-    even slower with the Canvas.FrambufferObject render target.
-
-    \section1 Tips for Porting Existing HTML5 Canvas applications
-
-    Although the Canvas item is provided as a HTML5 like API, and
-    the canvas context API is as compatible with HTML5 2d context standard
-    as possible, the working HTML5 canvas applications are still need to
-    be modified to run in the Canvas item:
-    \list
-    \o Removes and replaces all DOM API calls with QML property bindings or Canvas item methods.
-    \o Removes and replaces all HTML envent handlers with the \a MouseArea item.
-    \o Changes the setInterval/setTimeout function calls with the \a Timer item.
-    \o Puts the actual painting code into the \a QtQuick2::Canvas::onPaint handler and triggers the
-       painting by calling the Canvas's \c markDirty or \c requestPaint methods.
-    \o For drawing images, loads them by calling the Canvas's loadImage method and then request to paint
-       them in the onImageLoaded handler.
-    \endlist
-
-    \sa QtQuick2::Context2D
-*/
-
-QSGCanvasItem::QSGCanvasItem(QSGItem *parent)
-    : QSGItem(*(new QSGCanvasItemPrivate), parent)
-{
-    setFlag(ItemHasContents);
-}
-
-QSGCanvasItem::~QSGCanvasItem()
-{
-    Q_D(QSGCanvasItem);
-    delete d->context;
-}
-
-/*!
-    \qmlproperty size QtQuick2::Canvas::canvasSize
-     Holds the logical canvas size that the context paints on.
-
-     By default, the canvas size is the same size as the current canvas item size.
-     By setting the canvas size, tile size and canvas window, the Canvas
-     item can act as a virtual large canvas with many seperately rendered tile rectangle
-     areas. Only those tiles within the current canvas window would be painted by
-     the Canvas render engine.
-    \sa QtQuick2::Canvas::tileSize QtQuick2::Canvas::canvasWindow
-*/
-QSizeF QSGCanvasItem::canvasSize() const
-{
-    Q_D(const QSGCanvasItem);
-    return d->canvasSize;
-}
-
-void QSGCanvasItem::setCanvasSize(const QSizeF & size)
-{
-    Q_D(QSGCanvasItem);
-    if (d->canvasSize != size) {
-        d->hasCanvasSize = true;
-        d->canvasSize = size;
-        emit canvasSizeChanged();
-        polish();
-        update();
-    }
-}
-
-/*!
-    \qmlproperty size QtQuick2::Canvas::tileSize
-     Holds the canvas rendering tile size.
-
-     When the Canvas item in tiled mode by setting the canvas size, tile size and
-     the canvas window. The canvas render can improve the rendering performance
-     by rendering and caching tiles instead of rendering the whole canvas everytime.
-
-     Additionally, the canvas size could be infinitely large without allocating more
-     memories because only those tiles within the current visible region
-     are actually rendered.
-
-     By default, the tile size is the same with the canvas size.
-     \sa QtQuick2::Canvas::canvaasSize QtQuick2::Canvas::canvasWindow
-*/
-QSize QSGCanvasItem::tileSize() const
-{
-    Q_D(const QSGCanvasItem);
-    return d->tileSize;
-}
-
-void QSGCanvasItem::setTileSize(const QSize & size)
-{
-    Q_D(QSGCanvasItem);
-    if (d->tileSize != size) {
-        d->hasTileSize = true;
-        d->tileSize = size;
-
-        emit tileSizeChanged();
-        polish();
-        update();
-    }
-}
-
-/*!
-    \qmlproperty rect QtQuick2::Canvas::canvasWindow
-     Holds the current canvas visible window.
-
-     By default, the canvas window size is the same as the Canvas item
-     size with the topleft point as (0, 0).
-
-     If the canvas size is different with the Canvas item size, the Canvas
-     item can display different visible areas by changing the canvas window's size
-     and/or position.
-    \sa QtQuick2::Canvas::canvasSize QtQuick2::Canvas::tileSize
-*/
-QRectF QSGCanvasItem::canvasWindow() const
-{
-    Q_D(const QSGCanvasItem);
-    return d->canvasWindow;
-}
-
-void QSGCanvasItem::setCanvasWindow(const QRectF& rect)
-{
-    Q_D(QSGCanvasItem);
-    if (d->canvasWindow != rect) {
-        d->canvasWindow = rect;
-
-        d->hasCanvasWindow = true;
-        emit canvasWindowChanged();
-        polish();
-        update();
-    }
-}
-
-
-QSGContext2D* QSGCanvasItem::context() const
-{
-    Q_D(const QSGCanvasItem);
-    return d->context;
-}
-/*!
-    \qmlproperty bool QtQuick2::Canvas::renderInThread
-     Holds the current canvas rendering mode.
-
-     By setting the renderInThread to true, complex and long
-     running painting can be rendered in a dedicated background
-     rendering thread to avoid blocking the main GUI.
-
-     Note: Different renderTarget may or may not support the
-     background rendering thread, if not, the renderInThread
-     property will be ignored.
-
-     The default value is false.
-    \sa QtQuick2::Canvas::renderTarget
-*/
-bool QSGCanvasItem::renderInThread() const
-{
-    Q_D(const QSGCanvasItem);
-    return d->renderInThread;
-}
-/*!
-    \qmlproperty bool QtQuick2::Canvas::renderTarget
-     Holds the current canvas render target.
-
-     \list
-     \o Canvas.Image  - render to an in memory image buffer, the render
-                        target supports background rendering.
-     \o Canvas.FramebufferObject - render to an OpenGL frame buffer,
-                                   this render target will ignore the
-                                   renderInThread property. The actual
-                                   rendering happens in the main QML rendering
-                                   process, which may be in a seperate render thread
-                                   or in the main GUI thread depends on the platforms.
-     \endlist
-
-     The default render target is \c Canvas.Image.
-    \sa QtQuick2::Canvas::renderInThread
-*/
-QSGCanvasItem::RenderTarget QSGCanvasItem::renderTarget() const
-{
-    Q_D(const QSGCanvasItem);
-    return d->renderTarget;
-}
-
-void QSGCanvasItem::setRenderTarget(RenderTarget target)
-{
-    Q_D(QSGCanvasItem);
-    if (d->renderTarget != target) {
-        d->renderTarget = target;
-
-        if (d->componentCompleted)
-            createTexture();
-        emit renderTargetChanged();
-    }
-}
-
-void QSGCanvasItem::_doPainting(const QRectF& region)
-{
-    Q_D(QSGCanvasItem);
-    emit paint(QDeclarativeV8Handle::fromHandle(d->context->v8value())
-             , QSGContext2DTexture::tiledRect(region, d->tileSize));
-    if (d->texture)
-        d->texture->wake();
-}
-
-/*!
-    \qmlproperty bool QtQuick2::Canvas::renderInThread
-     Holds the current canvas rendering mode.
-
-     When this property is true, all canvas painting commands
-     are rendered in a background rendering thread, otherwise
-     the rendering happens in the main GUI thread.
-
-     The default renderInThread value is false.
-*/
-void QSGCanvasItem::setRenderInThread(bool renderInThread)
-{
-    Q_D(QSGCanvasItem);
-    if (d->renderInThread != renderInThread) {
-        d->renderInThread = renderInThread;
-
-        if (d->componentCompleted)
-            createTexture();
-
-        if (d->renderInThread)
-            connect(this, SIGNAL(painted()), SLOT(update()));
-        else
-            disconnect(this, SIGNAL(painted()), this, SLOT(update()));
-        emit renderInThreadChanged();
-        polish();
-        update();
-    }
-}
-
-void QSGCanvasItem::geometryChanged(const QRectF &newGeometry,
-                             const QRectF &oldGeometry)
-{
-    Q_D(QSGCanvasItem);
-    QSGItem::geometryChanged(newGeometry, oldGeometry);
-
-    const qreal w = newGeometry.width();
-    const qreal h = newGeometry.height();
-
-    if (!d->hasCanvasSize) {
-        d->canvasSize = QSizeF(w, h);
-        emit canvasSizeChanged();
-    }
-
-    if (!d->hasTileSize) {
-        d->tileSize = d->canvasSize.toSize();
-        emit tileSizeChanged();
-    }
-
-    if (!d->hasCanvasWindow) {
-        d->canvasWindow = newGeometry;
-        emit canvasWindowChanged();
-    }
-
-    polish();
-    update();
-}
-
-void QSGCanvasItem::componentComplete()
-{
-    Q_D(QSGCanvasItem);
-    QSGItem::componentComplete();
-
-    if (!d->context)
-        createContext();
-    createTexture();
-
-    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())
-            _doPainting(d->dirtyRect);
-
-        d->texture->canvasChanged(d->canvasSize.toSize()
-                                , d->tileSize
-                                , d->canvasWindow.toAlignedRect()
-                                , d->dirtyRect.toAlignedRect()
-                                , d->smooth);
-        d->dirtyRect = QRectF();
-    }
-}
-
-QSGNode *QSGCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
-{
-    Q_D(QSGCanvasItem);
-    QSGContext2DNode *node = static_cast<QSGContext2DNode *>(oldNode);
-    if (!node)
-        node = new QSGContext2DNode(this);
-
-    node->setTexture(d->texture);
-    node->setSize(d->canvasWindow.size());
-    node->update();
-    return node;
-}
-
-void QSGCanvasItem::createTexture()
-{
-    Q_D(QSGCanvasItem);
-
-    if (!d->texture
-      || d->texture->threadRendering() != d->renderInThread
-      || d->texture->renderTarget() != d->renderTarget) {
-        if (d->texture) {
-            d->texture->deleteLater();
-            d->texture = 0;
-        }
-
-        if (d->renderTarget == QSGCanvasItem::Image) {
-            d->texture = new QSGContext2DImageTexture(d->renderInThread);
-        } else if (d->renderTarget == QSGCanvasItem::FramebufferObject) {
-            d->texture = new QSGContext2DFBOTexture();
-        }
-
-        if (d->renderInThread && !d->texture->supportThreadRendering()) {
-            qWarning("Canvas: render target does not support thread rendering, force to non-thread rendering mode.");
-            d->renderInThread = false;
-            emit renderInThreadChanged();
-        }
-
-        if (d->renderInThread)
-            connect(d->texture, SIGNAL(textureChanged()), this, SLOT(update()));
-
-        d->texture->setItem(this);
-    }
-}
-
-void QSGCanvasItem::createContext()
-{
-    Q_D(QSGCanvasItem);
-
-    delete d->context;
-
-    d->context = new QSGContext2D(this);
-
-    QV8Engine *e = QDeclarativeEnginePrivate::getV8Engine(qmlEngine(this));
-    d->context->setV8Engine(e);
-}
-
-/*!
-  \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
-  returned, otherwise returns an invalid value.
-  */
-QDeclarativeV8Handle QSGCanvasItem::getContext(const QString &contextId)
-{
-    Q_D(QSGCanvasItem);
-
-    if (contextId.toLower() != QLatin1String("2d"))
-        return QDeclarativeV8Handle::fromHandle(v8::Undefined());
-
-    if (!d->context)
-        createContext();
-    return QDeclarativeV8Handle::fromHandle(d->context->v8value());
-}
-
-/*!
-  \qmlmethod void QtQuick2::Canvas::markDirty(rect region)
-
-  Mark the given \a region as dirty, so that when this region is visible
-  the canvas render will redraw it. During the rendering process, the
-  canvas renderer may emit the canvas' "paint" signal so the actual painting
-  scripts can be putted into the canvas's "onPaint" signal handler function.
-
-  \sa QtQuick2::Canvas::paint QtQuick2::Canvas::requestPaint
-  */
-void QSGCanvasItem::markDirty(const QRectF& region)
-{
-    Q_D(QSGCanvasItem);
-    d->dirtyRect |= region;
-    if (d->componentCompleted)
-        polish();
-    update();
-}
-
-
-/*!
-  \qmlmethod bool QtQuick2::Canvas::save(string filename)
-
-   Save the current canvas content into an image file \a filename.
-   The saved image format is automatically decided by the \a filename's
-   suffix.
-
-   Note: calling this method will force painting the whole canvas, not the
-   current canvas visible window.
-
-   \sa canvasWindow canvasSize toDataURL
-  */
-bool QSGCanvasItem::save(const QString &filename) const
-{
-    Q_D(const QSGCanvasItem);
-    QUrl url = d->baseUrl.resolved(QUrl::fromLocalFile(filename));
-    return toImage().save(url.toLocalFile());
-}
-
-QImage QSGCanvasItem::loadedImage(const QUrl& url)
-{
-    Q_D(QSGCanvasItem);
-    QUrl fullPathUrl = d->baseUrl.resolved(url);
-    if (!d->images.contains(fullPathUrl)) {
-        loadImage(url);
-    }
-    QDeclarativePixmap* pix = d->images.value(fullPathUrl);
-    if (pix->isLoading() || pix->isError()) {
-        return QImage();
-    }
-    return pix->pixmap().toImage();
-}
-
-/*!
-  \qmlmethod void QtQuick2::Canvas::loadImage(url image)
-    Loads the given \c image asynchronously, when the image is
-    ready, an imageLoaded signal will be emitted.
-    The loaded image can be unloaded by the \a QtQuick2::Canvas::unloadImage method.
-
-    Note: Only loaded images can be painted on the Canvas item.
-  \sa QtQuick2::Canvas::unloadImage QtQuick2::Canvas::imageLoaded QtQuick2::Canvas::isImageLoaded
-  \sa QtQuick2::Context2D::createImageData QtQuick2::Context2D::drawImage
-  */
-void QSGCanvasItem::loadImage(const QUrl& url)
-{
-    Q_D(QSGCanvasItem);
-    QUrl fullPathUrl = d->baseUrl.resolved(url);
-    if (!d->images.contains(fullPathUrl)) {
-        QDeclarativePixmap* pix = new QDeclarativePixmap();
-        d->images.insert(fullPathUrl, pix);
-
-        pix->load(qmlEngine(this)
-                , fullPathUrl
-                , QDeclarativePixmap::Cache | QDeclarativePixmap::Asynchronous);
-        pix->connectFinished(this, SIGNAL(imageLoaded()));
-    }
-}
-/*!
-  \qmlmethod void QtQuick2::Canvas::loadImage(url image)
-  Unloads the \c image.
-
-  If the image is unloaded from the Canvas item, it can't be painted by the canvas context
-  until it's loaded again.
-
-  \sa QtQuick2::Canvas::loadImage QtQuick2::Canvas::imageLoaded QtQuick2::Canvas::isImageLoaded
-  \sa QtQuick2::Context2D::createImageData QtQuick2::Context2D::drawImage
-  */
-void QSGCanvasItem::unloadImage(const QUrl& url)
-{
-    Q_D(QSGCanvasItem);
-    QUrl removeThis = d->baseUrl.resolved(url);
-    if (d->images.contains(removeThis)) {
-        delete d->images.value(removeThis);
-        d->images.remove(removeThis);
-    }
-}
-
-/*!
-  \qmlmethod void QtQuick2::Canvas::isImageError(url image)
-  Returns true if the image can't be loaded because of error happens.
-
-  \sa QtQuick2::Canvas::loadImage
-  */
-bool QSGCanvasItem::isImageError(const QUrl& url) const
-{
-    Q_D(const QSGCanvasItem);
-    QUrl fullPathUrl = d->baseUrl.resolved(url);
-    return d->images.contains(fullPathUrl)
-        && d->images.value(fullPathUrl)->isError();
-}
-
-/*!
-  \qmlmethod void QtQuick2::Canvas::isImageLoading(url image)
-  Returns true if the Canvas item still is loading the \c image.
-
-  \sa QtQuick2::Canvas::loadImage
-  */
-bool QSGCanvasItem::isImageLoading(const QUrl& url) const
-{
-    Q_D(const QSGCanvasItem);
-    QUrl fullPathUrl = d->baseUrl.resolved(url);
-    return d->images.contains(fullPathUrl)
-        && d->images.value(fullPathUrl)->isLoading();
-}
-/*!
-  \qmlmethod void QtQuick2::Canvas::isImageLoaded(url image)
-  Returns true if the \c image is sucessfully loaded and ready to use.
-
-  \sa QtQuick2::Canvas::loadImage
-  */
-bool QSGCanvasItem::isImageLoaded(const QUrl& url) const
-{
-    Q_D(const QSGCanvasItem);
-    QUrl fullPathUrl = d->baseUrl.resolved(url);
-    return d->images.contains(fullPathUrl)
-        && d->images.value(fullPathUrl)->isReady();
-}
-
-QImage QSGCanvasItem::toImage(const QRectF& region) const
-{
-    Q_D(const QSGCanvasItem);
-    if (d->texture) {
-        if (region.isEmpty())
-            return d->texture->toImage(canvasWindow());
-        else
-            return d->texture->toImage(region);
-    }
-    return QImage();
-}
-
-/*!
-  \qmlmethod string QtQuick2::Canvas::toDataURL(string mimeType)
-
-   Returns a data: URL for the image in the canvas.
-
-   The default \a mimeType is "image/png".
-
-   \sa QtQuick2::Canvas::save
-  */
-QString QSGCanvasItem::toDataURL(const QString& mimeType) const
-{
-    QImage image = toImage();
-
-    if (!image.isNull()) {
-        QByteArray ba;
-        QBuffer buffer(&ba);
-        buffer.open(QIODevice::WriteOnly);
-        QString mime = mimeType.toLower();
-        QString type;
-        if (mime == QLatin1Literal("image/png")) {
-            type = QLatin1Literal("PNG");
-        } else if (mime == QLatin1Literal("image/bmp"))
-            type = QLatin1Literal("BMP");
-        else if (mime == QLatin1Literal("image/jpeg"))
-            type = QLatin1Literal("JPEG");
-        else if (mime == QLatin1Literal("image/x-portable-pixmap"))
-            type = QLatin1Literal("PPM");
-        else if (mime == QLatin1Literal("image/tiff"))
-            type = QLatin1Literal("TIFF");
-        else if (mime == QLatin1Literal("image/xpm"))
-            type = QLatin1Literal("XPM");
-        else
-            return QLatin1Literal("data:,");
-
-        image.save(&buffer, type.toAscii());
-        buffer.close();
-        QString dataUrl = QLatin1Literal("data:%1;base64,%2");
-        return dataUrl.arg(mime).arg(QLatin1String(ba.toBase64().constData()));
-    }
-    return QLatin1Literal("data:,");
-}
-
-/*!
-    \qmlsignal QtQuick2::Canvas::onPaint(QtQuick2::Context2D context, rect region)
-
-    This handler is called before the given \c region needs to be rendered.
-
-    This signal can be triggered by QtQuick2::Canvas::markdirty, QtQuick2::Canvas::requestPaint
-    or by changing the current canvas window.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Canvas::onPainted()
-
-    This handler is called after all context painting commands are executed and
-    the Canvas is actually rendered.
-*/
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/context2d/qsgcanvasitem_p.h b/src/declarative/items/context2d/qsgcanvasitem_p.h
deleted file mode 100644 (file)
index 131a3f5..0000000
+++ /dev/null
@@ -1,148 +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 QSGCANVASITEM_P_H
-#define QSGCANVASITEM_P_H
-
-#include <qsgitem.h>
-#include <private/qv8engine_p.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-class QSGContext2D;
-class QSGCanvasItemPrivate;
-class Q_DECLARATIVE_EXPORT QSGCanvasItem : public QSGItem
-{
-    Q_OBJECT
-    Q_ENUMS(RenderTarget)
-    Q_ENUMS(ImageFilterMode)
-
-    Q_PROPERTY(QSizeF canvasSize READ canvasSize WRITE setCanvasSize NOTIFY canvasSizeChanged)
-    Q_PROPERTY(QSize tileSize READ tileSize WRITE setTileSize NOTIFY tileSizeChanged)
-    Q_PROPERTY(QRectF canvasWindow READ canvasWindow WRITE setCanvasWindow NOTIFY canvasWindowChanged)
-    Q_PROPERTY(bool renderInThread READ renderInThread WRITE setRenderInThread NOTIFY renderInThreadChanged)
-    Q_PROPERTY(RenderTarget renderTarget READ renderTarget WRITE setRenderTarget NOTIFY renderTargetChanged)
-public:
-    enum RenderTarget {
-        Image,
-        FramebufferObject
-    };
-
-    enum ImageFilterMode {
-        Threshold,
-        Mono,
-        GrayScale,
-        Brightness,
-        Invert,
-        Blur,
-        Opaque,
-        Convolute
-    };
-
-    QSGCanvasItem(QSGItem *parent = 0);
-    ~QSGCanvasItem();
-
-    QSizeF canvasSize() const;
-    void setCanvasSize(const QSizeF &);
-
-    QSize tileSize() const;
-    void setTileSize(const QSize &);
-
-    QRectF canvasWindow() const;
-    void setCanvasWindow(const QRectF& rect);
-
-    bool renderInThread() const;
-    void setRenderInThread(bool renderInThread);
-
-    RenderTarget renderTarget() const;
-    void setRenderTarget(RenderTarget target);
-
-    QSGContext2D* context() const;
-    QImage toImage(const QRectF& region = QRectF()) const;
-
-    QImage loadedImage(const QUrl& url);
-Q_SIGNALS:
-    void paint(QDeclarativeV8Handle context, const QRect &region);
-    void painted();
-    void canvasSizeChanged();
-    void tileSizeChanged();
-    void renderInThreadChanged();
-    void textureChanged();
-    void canvasWindowChanged();
-    void renderTargetChanged();
-    void imageLoaded();
-public Q_SLOTS:
-    QString toDataURL(const QString& type = QLatin1String("image/png")) const;
-    QDeclarativeV8Handle getContext(const QString & = QLatin1String("2d"));
-    void markDirty(const QRectF& region);
-    void requestPaint() {markDirty(canvasWindow());}
-    // Save current canvas to disk
-    bool save(const QString& filename) const;
-    void loadImage(const QUrl& url);
-    void unloadImage(const QUrl& url);
-    bool isImageLoaded(const QUrl& url) const;
-    bool isImageLoading(const QUrl& url) const;
-    bool isImageError(const QUrl& url) const;
-private Q_SLOTS:
-    void _doPainting(const QRectF& region);
-protected:
-    virtual void componentComplete();
-    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
-    virtual void geometryChanged(const QRectF &newGeometry,
-                                 const QRectF &oldGeometry);
-    virtual void updatePolish();
-private:
-    void createContext();
-    void createTexture();
-    Q_DECLARE_PRIVATE(QSGCanvasItem)
-    friend class QSGContext2D;
-    friend class QSGContext2DTexture;
-};
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGCanvasItem)
-
-QT_END_HEADER
-
-#endif //QSGCANVASITEM_P_H
diff --git a/src/declarative/items/context2d/qsgcontext2d.cpp b/src/declarative/items/context2d/qsgcontext2d.cpp
deleted file mode 100644 (file)
index 5944a02..0000000
+++ /dev/null
@@ -1,3534 +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$
-**
-****************************************************************************/
-
-#include "qsgcontext2d_p.h"
-#include "qsgcontext2dcommandbuffer_p.h"
-#include "qsgcanvasitem_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/qsgimage_p_p.h>
-
-#include <QtGui/qguiapplication.h>
-#include <qdeclarativeinfo.h>
-#include <QtCore/qmath.h>
-#include <private/qv8engine_p.h>
-
-#include <qdeclarativeengine.h>
-#include <private/qv8domerrors_p.h>
-#include <QtCore/qnumeric.h>
-
-QT_BEGIN_NAMESPACE
-/*!
-    \qmlclass Context2D QSGContext2D
-    \inqmlmodule QtQuick 2
-    \since QtQuick 2.0
-    \brief The Context2D API allows you to draw 2d graphic shapes on the \c Canvas item.
-
-    The Context2D object can be created by \c Canvas item's \c getContext() method:
-    \code
-    Canvas {
-      id:canvas
-      onPaint:{
-         var ctx = canvas.getContext('2d');
-         //...
-      }
-    }
-    \endcode
-    The Context2D API implements the same \l {http://www.w3.org/TR/2dcontext}{W3C Canvas 2D Context API standard}
-    with some enhanced features.
-
-    The Context2D API provides the rendering \bold{context} which defines the methods and attributes needed to draw
-    on the \c Canvas item. The following assigns the canvas rendering context to a \c{context}
-    variable:
-    \code
-    var context = mycanvas.getContext("2d")
-    \endcode
-
-    The Context2D API renders the canvas as a coordinate system whose origin (0,0) is
-    at the top left corner, as shown in the figure below. Coordinates increase along
-    the \c{x} axis from left to right and along the \c{y} axis from top to bottom of
-    the canvas.
-    \image qml-item-canvas-context.gif
-*/
-static const double Q_PI   = 3.14159265358979323846;   // pi
-
-#define DEGREES(t) ((t) * 180.0 / Q_PI)
-
-#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");
-#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)
-{
-    v8::String::AsciiValue str(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);
-
-        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);
-
-        p+=3; //skip "rgb" or "hsl"
-        hasAlpha = (*p == 'a') ? true : false;
-
-        ++p; //skip "("
-
-        if (hasAlpha) ++p; //skip "a"
-
-        int rh, gs, bl, alpha = 255;
-
-        //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);
-        }
-
-        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) {
-    QFont font;
-     // ### this is simplified and incomplete
-    // ### TODO:get code from Qt webkit
-     QStringList tokens = fontString.split(QLatin1String(" "));
-     foreach (const QString &token, tokens) {
-         if (token == QLatin1String("italic"))
-             font.setItalic(true);
-         else if (token == QLatin1String("bold"))
-             font.setBold(true);
-         else if (token.endsWith(QLatin1String("px"))) {
-             QString number = token;
-             number.remove(QLatin1String("px"));
-             //font.setPointSizeF(number.trimmed().toFloat());
-             font.setPixelSize(number.trimmed().toInt());
-         } else
-             font.setFamily(token);
-     }
-
-     return font;
-}
-
-
-
-class QSGContext2DEngineData : public QV8Engine::Deletable
-{
-public:
-    QSGContext2DEngineData(QV8Engine *engine);
-    ~QSGContext2DEngineData();
-
-    v8::Persistent<v8::Function> constructorContext;
-    v8::Persistent<v8::Function> constructorGradient;
-    v8::Persistent<v8::Function> constructorPattern;
-    v8::Persistent<v8::Function> constructorPixelArray;
-    v8::Persistent<v8::Function> constructorImageData;
-};
-
-V8_DEFINE_EXTENSION(QSGContext2DEngineData, engineData)
-
-class QV8Context2DResource : public QV8ObjectResource
-{
-    V8_RESOURCE_TYPE(Context2DType)
-public:
-    QV8Context2DResource(QV8Engine *e) : QV8ObjectResource(e) {}
-    QSGContext2D* context;
-};
-
-class QV8Context2DStyleResource : public QV8ObjectResource
-{
-    V8_RESOURCE_TYPE(Context2DStyleType)
-public:
-    QV8Context2DStyleResource(QV8Engine *e)
-      : QV8ObjectResource(e)
-      , patternRepeatX(false)
-      , patternRepeatY(false)
-    {}
-    QBrush brush;
-    bool patternRepeatX:1;
-    bool patternRepeatY:1;
-};
-
-class QV8Context2DPixelArrayResource : public QV8ObjectResource
-{
-    V8_RESOURCE_TYPE(Context2DPixelArrayType)
-public:
-    QV8Context2DPixelArrayResource(QV8Engine *e) : QV8ObjectResource(e) {}
-
-    QImage image;
-};
-
-QImage qt_image_convolute_filter(const QImage& src, const QVector<qreal>& weights, int radius = 0)
-{
-    int sides = radius ? radius : qRound(qSqrt(weights.size()));
-    int half = qFloor(sides/2);
-
-    QImage dst = QImage(src.size(), src.format());
-    int w = src.width();
-    int h = src.height();
-    for (int y = 0; y < dst.height(); ++y) {
-      QRgb *dr = (QRgb*)dst.scanLine(y);
-      for (int x = 0; x < dst.width(); ++x) {
-          unsigned char* dRgb = ((unsigned char*)&dr[x]);
-          unsigned char red=0, green=0, blue=0, alpha=0;
-          int sy = y;
-          int sx = x;
-
-          for (int cy=0; cy<sides; cy++) {
-             for (int cx=0; cx<sides; cx++) {
-               int scy = sy + cy - half;
-               int scx = sx + cx - half;
-               if (scy >= 0 && scy < w && scx >= 0 && scx < h) {
-                  const QRgb *sr = (const QRgb*)(src.constScanLine(scy));
-                  const unsigned char* sRgb = ((const unsigned char*)&sr[scx]);
-                  qreal wt = radius ? weights[0] : weights[cy*sides+cx];
-                  red += sRgb[0] * wt;
-                  green += sRgb[1] * wt;
-                  blue += sRgb[2] * wt;
-                  alpha += sRgb[3] * wt;
-               }
-             }
-          }
-          dRgb[0] = red;
-          dRgb[1] = green;
-          dRgb[2] = blue;
-          dRgb[3] = alpha;
-      }
-    }
-    return dst;
-}
-
-void qt_image_boxblur(QImage& image, int radius, bool quality)
-{
-    int passes = quality? 3: 1;
-    for (int i=0; i < passes; i++) {
-        image = qt_image_convolute_filter(image, QVector<qreal>() << 1.0/(radius * radius * 1.0), radius);
-    }
-}
-
-static QPainter::CompositionMode qt_composite_mode_from_string(const QString &compositeOperator)
-{
-    if (compositeOperator == QLatin1String("source-over")) {
-        return QPainter::CompositionMode_SourceOver;
-    } else if (compositeOperator == QLatin1String("source-out")) {
-        return QPainter::CompositionMode_SourceOut;
-    } else if (compositeOperator == QLatin1String("source-in")) {
-        return QPainter::CompositionMode_SourceIn;
-    } else if (compositeOperator == QLatin1String("source-atop")) {
-        return QPainter::CompositionMode_SourceAtop;
-    } else if (compositeOperator == QLatin1String("destination-atop")) {
-        return QPainter::CompositionMode_DestinationAtop;
-    } else if (compositeOperator == QLatin1String("destination-in")) {
-        return QPainter::CompositionMode_DestinationIn;
-    } else if (compositeOperator == QLatin1String("destination-out")) {
-        return QPainter::CompositionMode_DestinationOut;
-    } else if (compositeOperator == QLatin1String("destination-over")) {
-        return QPainter::CompositionMode_DestinationOver;
-    } else if (compositeOperator == QLatin1String("lighter")) {
-        return QPainter::CompositionMode_Lighten;
-    } else if (compositeOperator == QLatin1String("copy")) {
-        return QPainter::CompositionMode_Source;
-    } else if (compositeOperator == QLatin1String("xor")) {
-        return QPainter::CompositionMode_Xor;
-    } else if (compositeOperator == QLatin1String("qt-clear")) {
-        return QPainter::CompositionMode_Clear;
-    } else if (compositeOperator == QLatin1String("qt-destination")) {
-        return QPainter::CompositionMode_Destination;
-    } else if (compositeOperator == QLatin1String("qt-multiply")) {
-        return QPainter::CompositionMode_Multiply;
-    } else if (compositeOperator == QLatin1String("qt-screen")) {
-        return QPainter::CompositionMode_Screen;
-    } else if (compositeOperator == QLatin1String("qt-overlay")) {
-        return QPainter::CompositionMode_Overlay;
-    } else if (compositeOperator == QLatin1String("qt-darken")) {
-        return QPainter::CompositionMode_Darken;
-    } else if (compositeOperator == QLatin1String("qt-lighten")) {
-        return QPainter::CompositionMode_Lighten;
-    } else if (compositeOperator == QLatin1String("qt-color-dodge")) {
-        return QPainter::CompositionMode_ColorDodge;
-    } else if (compositeOperator == QLatin1String("qt-color-burn")) {
-        return QPainter::CompositionMode_ColorBurn;
-    } else if (compositeOperator == QLatin1String("qt-hard-light")) {
-        return QPainter::CompositionMode_HardLight;
-    } else if (compositeOperator == QLatin1String("qt-soft-light")) {
-        return QPainter::CompositionMode_SoftLight;
-    } else if (compositeOperator == QLatin1String("qt-difference")) {
-        return QPainter::CompositionMode_Difference;
-    } else if (compositeOperator == QLatin1String("qt-exclusion")) {
-        return QPainter::CompositionMode_Exclusion;
-    }
-    return QPainter::CompositionMode_SourceOver;
-}
-
-static QString qt_composite_mode_to_string(QPainter::CompositionMode op)
-{
-    switch (op) {
-    case QPainter::CompositionMode_SourceOver:
-        return QLatin1String("source-over");
-    case QPainter::CompositionMode_DestinationOver:
-        return QLatin1String("destination-over");
-    case QPainter::CompositionMode_Clear:
-        return QLatin1String("qt-clear");
-    case QPainter::CompositionMode_Source:
-        return QLatin1String("copy");
-    case QPainter::CompositionMode_Destination:
-        return QLatin1String("qt-destination");
-    case QPainter::CompositionMode_SourceIn:
-        return QLatin1String("source-in");
-    case QPainter::CompositionMode_DestinationIn:
-        return QLatin1String("destination-in");
-    case QPainter::CompositionMode_SourceOut:
-        return QLatin1String("source-out");
-    case QPainter::CompositionMode_DestinationOut:
-        return QLatin1String("destination-out");
-    case QPainter::CompositionMode_SourceAtop:
-        return QLatin1String("source-atop");
-    case QPainter::CompositionMode_DestinationAtop:
-        return QLatin1String("destination-atop");
-    case QPainter::CompositionMode_Xor:
-        return QLatin1String("xor");
-    case QPainter::CompositionMode_Plus:
-        return QLatin1String("plus");
-    case QPainter::CompositionMode_Multiply:
-        return QLatin1String("qt-multiply");
-    case QPainter::CompositionMode_Screen:
-        return QLatin1String("qt-screen");
-    case QPainter::CompositionMode_Overlay:
-        return QLatin1String("qt-overlay");
-    case QPainter::CompositionMode_Darken:
-        return QLatin1String("qt-darken");
-    case QPainter::CompositionMode_Lighten:
-        return QLatin1String("lighter");
-    case QPainter::CompositionMode_ColorDodge:
-        return QLatin1String("qt-color-dodge");
-    case QPainter::CompositionMode_ColorBurn:
-        return QLatin1String("qt-color-burn");
-    case QPainter::CompositionMode_HardLight:
-        return QLatin1String("qt-hard-light");
-    case QPainter::CompositionMode_SoftLight:
-        return QLatin1String("qt-soft-light");
-    case QPainter::CompositionMode_Difference:
-        return QLatin1String("qt-difference");
-    case QPainter::CompositionMode_Exclusion:
-        return QLatin1String("qt-exclusion");
-    default:
-        break;
-    }
-    return QString();
-}
-
-
-static v8::Local<v8::Object> qt_create_image_data(qreal w, qreal h, QV8Engine* engine, const QImage& image)
-{
-    QSGContext2DEngineData *ed = engineData(engine);
-    v8::Local<v8::Object> imageData = ed->constructorImageData->NewInstance();
-    QV8Context2DPixelArrayResource *r = new QV8Context2DPixelArrayResource(engine);
-    if (image.isNull()) {
-        r->image = QImage(w, h, QImage::Format_ARGB32);
-        r->image.fill(0x00000000);
-    } else {
-        Q_ASSERT(image.width() == w && image.height() == h);
-        r->image = image.format() == QImage::Format_ARGB32 ? image : image.convertToFormat(QImage::Format_ARGB32);
-    }
-    v8::Local<v8::Object> pixelData = ed->constructorPixelArray->NewInstance();
-    pixelData->SetExternalResource(r);
-
-    imageData->SetInternalField(0, pixelData);
-    return imageData;
-}
-
-//static script functions
-
-/*!
-    \qmlproperty QtQuick2::Canvas QtQuick2::Context2D::canvas
-     Holds the canvas item that the context paints on.
-
-     This property is read only.
-*/
-static v8::Handle<v8::Value> ctx2d_canvas(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT(r)
-
-
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-
-    return engine->newQObject(r->context->canvas());
-}
-
-/*!
-    \qmlmethod object QtQuick2::Context2D::restore()
-    Pops the top state on the stack, restoring the context to that state.
-
-    \sa QtQuick2::Context2D::save()
-*/
-static v8::Handle<v8::Value> ctx2d_restore(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-    r->context->popState();
-    return args.This();
-}
-
-/*!
-    \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)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-    r->context->reset();
-    r->context->m_path = QPainterPath();
-    r->context->m_path.setFillRule(Qt::WindingFill);
-
-    return args.This();
-}
-
-/*!
-    \qmlmethod object QtQuick2::Context2D::save()
-    Pushes the current state onto the state stack.
-
-    Before changing any state attributes, you should save the current state
-    for future reference. The context maintains a stack of drawing states.
-    Each state consists of the current transformation matrix, clipping region,
-    and values of the following attributes:
-    \list
-    \o\a QtQuick2::Context2D::strokeStyle
-    \o\a QtQuick2::Context2D::fillStyle
-    \o\a QtQuick2::Context2D::fillRule
-    \o\a QtQuick2::Context2D::globalAlpha
-    \o\a QtQuick2::Context2D::lineWidth
-    \o\a QtQuick2::Context2D::lineCap
-    \o\a QtQuick2::Context2D::lineJoin
-    \o\a QtQuick2::Context2D::miterLimit
-    \o\a QtQuick2::Context2D::shadowOffsetX
-    \o\a QtQuick2::Context2D::shadowOffsetY
-    \o\a QtQuick2::Context2D::shadowBlur
-    \o\a QtQuick2::Context2D::shadowColor
-    \o\a QtQuick2::Context2D::globalCompositeOperation
-    \o\a QtQuick2::Context2D::font
-    \o\a QtQuick2::Context2D::textAlign
-    \o\a QtQuick2::Context2D::textBaseline
-    \endlist
-
-    The current path is NOT part of the drawing state. The path can be reset by
-    invoking the \a QtQuick2::Context2D::beginPath() method.
-*/
-static v8::Handle<v8::Value> ctx2d_save(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-    r->context->pushState();
-
-    return args.This();
-}
-
-// transformations
-/*!
-    \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);
-    \endcode
-    \image qml-item-canvas-rotate.png
-
-    The rotation transformation matrix is as follows:
-
-    \image qml-item-canvas-math-rotate.png
-
-    where the \c angle of rotation is in radians.
-
-*/
-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);
-    }
-
-    return args.This();
-}
-
-/*!
-    \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
-    vertical direction.
-    The following code doubles the horizontal size of an object drawn on the canvas and half its
-    vertical size:
-    \code
-    ctx.scale(2.0, 0.5);
-    \endcode
-    \image qml-item-canvas-scale.png
-
-*/
-static v8::Handle<v8::Value> ctx2d_scale(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-
-    if (args.Length() == 2) {
-        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);
-    }
-
-    return args.This();
-}
-
-/*!
-    \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,
-    rotating, and translating transformations in a single step.
-
-    Each point on the canvas is multiplied by the matrix before anything is
-    drawn. The \l{HTML5 Canvas API} defines the transformation matrix as:
-
-    \image qml-item-canvas-math.png
-    where:
-    \list
-    \o \c{a} is the scale factor in the horizontal (x) direction
-    \image qml-item-canvas-scalex.png
-    \o \c{c} is the skew factor in the x direction
-    \image qml-item-canvas-canvas-skewx.png
-    \o \c{e} is the translation in the x direction
-    \image qml-item-canvas-canvas-translate.png
-    \o \c{b} is the skew factor in the y (vertical) direction
-    \image qml-item-canvas-canvas-skewy.png
-    \o \c{d} is the scale factor in the y direction
-    \image qml-item-canvas-canvas-scaley.png
-    \o \c{f} is the translation in the y direction
-    \image qml-item-canvas-canvas-translatey.png
-    \o the last row remains constant
-    \endlist
-    The scale factors and skew factors are multiples; \c{e} and \c{f} are
-    coordinate space units, just like the units in the \a QtQuick2::Context2D::translate(x,y)
-    method.
-
-    \sa QtQuick2::Context2D::transform()
-*/
-static v8::Handle<v8::Value> ctx2d_setTransform(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-
-    if (args.Length() == 6) {
-        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);
-    }
-
-    return args.This();
-}
-
-/*!
-    \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.
-
-    The \a setTransform(a, b, c, d, e, f) method actually resets the current transform to the identity matrix,
-    and then invokes the transform(a, b, c, d, e, f) method with the same arguments.
-
-    \sa QtQuick2::Context2D::setTransform()
-*/
-static v8::Handle<v8::Value> ctx2d_transform(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-
-    if (args.Length() == 6) {
-        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);
-    }
-
-    return args.This();
-}
-
-/*!
-    \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,
-    \c y is the vertical distance that the origin is translated, in coordinate space units.
-    Translating the origin enables you to draw patterns of different objects on the canvas
-    without having to measure the coordinates manually for each shape.
-*/
-static v8::Handle<v8::Value> ctx2d_translate(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-
-    if (args.Length() == 2) {
-        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);
-    }
-
-    return args.This();
-}
-
-
-/*!
-    \qmlmethod object QtQuick2::Context2D::resetTransform()
-    Reset the transformation matrix to default value.
-
-    \sa QtQuick2::Context2D::transform(), QtQuick2::Context2D::setTransform(), QtQuick2::Context2D::reset()
-*/
-static v8::Handle<v8::Value> ctx2d_resetTransform(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-    r->context->state.matrix = QTransform();
-    r->context->buffer()->updateMatrix(r->context->state.matrix);
-
-    return args.This();
-}
-
-
-/*!
-    \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)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-    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
-
-/*!
-    \qmlproperty real QtQuick2::Context2D::globalAlpha
-     Holds the the current alpha value applied to rendering operations.
-     The value must be in the range from 0.0 (fully transparent) to 1.0 (fully opque).
-     The default value is 1.0.
-*/
-static v8::Handle<v8::Value> ctx2d_globalAlpha(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT(r)
-
-    return v8::Number::New(r->context->state.globalAlpha);
-}
-
-static void ctx2d_globalAlpha_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT_SETTER(r)
-
-    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);
-    }
-}
-
-/*!
-    \qmlproperty string QtQuick2::Context2D::globalCompositeOperation
-     Holds the the current the current composition operation, from the list below:
-     \list
-     \o source-atop      - A atop B. Display the source image wherever both images are opaque.
-                           Display the destination image wherever the destination image is opaque but the source image is transparent.
-                           Display transparency elsewhere.
-     \o source-in        - A in B. Display the source image wherever both the source image and destination image are opaque.
-                           Display transparency elsewhere.
-     \o source-out       - A out B. Display the source image wherever the source image is opaque and the destination image is transparent.
-                           Display transparency elsewhere.
-     \o source-over      - (default) A over B. Display the source image wherever the source image is opaque.
-                           Display the destination image elsewhere.
-     \o destination-atop - B atop A. Same as source-atop but using the destination image instead of the source image and vice versa.
-     \o destination-in   - B in A. Same as source-in but using the destination image instead of the source image and vice versa.
-     \o destination-out  - B out A. Same as source-out but using the destination image instead of the source image and vice versa.
-     \o destination-over - B over A. Same as source-over but using the destination image instead of the source image and vice versa.
-     \o lighter          - A plus B. Display the sum of the source image and destination image, with color values approaching 255 (100%) as a limit.
-     \o copy             - A (B is ignored). Display the source image instead of the destination image.
-     \o xor              - A xor B. Exclusive OR of the source image and destination image.
-     \endlist
-
-     Additionally, this property also accepts the compositon modes listed in \a {QPainter::CompositionMode}. According to the W3C standard, these
-     extension composition modes are provided as "vendorName-operationName" syntax, for example: \c {QPainter::CompositionMode_Exclusion} is porvided as
-     "qt-exclusion".
-*/
-static v8::Handle<v8::Value> ctx2d_globalCompositeOperation(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT(r)
-
-
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-
-    return engine->toString(qt_composite_mode_to_string(r->context->state.globalCompositeOperation));
-}
-
-static void ctx2d_globalCompositeOperation_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT_SETTER(r)
-
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-
-
-    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);
-    }
-}
-
-// colors and styles
-/*!
-    \qmlproperty variant QtQuick2::Context2D::fillStyle
-     Holds the current style used for filling shapes.
-     The style can be either a string containing a CSS color, a CanvasGradient or CanvasPattern object. Invalid values are ignored.
-     This property accepts several color syntaxes:
-     \list
-     \o 'rgb(red, green, blue)' - for example: 'rgb(255, 100, 55)' or 'rgb(100%, 70%, 30%)'
-     \o 'rgba(red, green, blue, alpha)' - for example: 'rgb(255, 100, 55, 1.0)' or 'rgb(100%, 70%, 30%, 0.5)'
-     \o 'hsl(hue, saturation, lightness)'
-     \o 'hsla(hue, saturation, lightness, alpha)'
-     \o '#RRGGBB' - for example: '#00FFCC'
-     \o Qt.rgba(red, green, blue, alpha) - for example: Qt.rgba(0.3, 0.7, 1, 1.0)
-     \endlist
-     If the \a fillStyle or \a strokeStyle is assigned many times in a loop, the last Qt.rgba() syntax should be chosen, as it has the
-     best performance, because it's already a valid QColor value, does not need to be parsed everytime.
-
-     The default value is  '#000000'.
-     \sa QtQuick2::Context2D::createLinearGradient
-     \sa QtQuick2::Context2D::createRadialGradient
-     \sa QtQuick2::Context2D::createPattern
-     \sa QtQuick2::Context2D::strokeStyle
- */
-static v8::Handle<v8::Value> ctx2d_fillStyle(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
-    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;
-}
-
-static void ctx2d_fillStyle_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT_SETTER(r)
-
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-
-   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, 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(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;
-       }
-   }
-}
-/*!
-    \qmlproperty enumeration QtQuick2::Context2D::fillRule
-     Holds the current fill rule used for filling shapes. The following fill rules supported:
-     \list
-     \o Qt.OddEvenFill
-     \o Qt.WindingFill
-     \endlist
-     Note: Unlike the \a QPainterPath, the Canvas API uses the winding fill as the default fill rule.
-     The fillRule property is part of the context rendering state.
-
-     \sa QtQuick2::Context2D::fillStyle
- */
-static v8::Handle<v8::Value> ctx2d_fillRule(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT(r)
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-
-    return engine->fromVariant(r->context->state.fillRule);
-}
-
-static void ctx2d_fillRule_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT_SETTER(r)
-
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-
-    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) == QStringLiteral("OddEvenFill"))
-               ||(value->IsNumber() && value->NumberValue() == Qt::OddEvenFill)) {
-        r->context->state.fillRule = Qt::OddEvenFill;
-    } else {
-        //error
-    }
-    r->context->m_path.setFillRule(r->context->state.fillRule);
-}
-/*!
-    \qmlproperty variant QtQuick2::Context2D::strokeStyle
-     Holds the current color or style to use for the lines around shapes,
-     The style can be either a string containing a CSS color, a CanvasGradient or CanvasPattern object.
-     Invalid values are ignored.
-
-     The default value is  '#000000'.
-
-     \sa QtQuick2::Context2D::createLinearGradient
-     \sa QtQuick2::Context2D::createRadialGradient
-     \sa QtQuick2::Context2D::createPattern
-     \sa QtQuick2::Context2D::fillStyle
- */
-v8::Handle<v8::Value> ctx2d_strokeStyle(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
-    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;
-}
-
-static void ctx2d_strokeStyle_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT_SETTER(r)
-
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-
-    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, 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(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 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).
-
-   A gradient is a smooth transition between colors. There are two types of gradients: linear and radial.
-   Gradients must have two or more color stops, representing color shifts positioned from 0 to 1 between
-   to the gradient's starting and end points or circles.
-
-    \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
-  */
-
-static v8::Handle<v8::Value> ctx2d_createLinearGradient(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-
-    QV8Engine *engine = V8ENGINE();
-
-    if (args.Length() == 4) {
-        QSGContext2DEngineData *ed = engineData(engine);
-        v8::Local<v8::Object> gradient = ed->constructorGradient->NewInstance();
-        QV8Context2DStyleResource *r = new QV8Context2DStyleResource(engine);
-        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;
-    }
-
-    return args.This();
-}
-
-/*!
-  \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
-  */
-
-static v8::Handle<v8::Value> ctx2d_createRadialGradient(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 x0 = args[0]->NumberValue();
-        qreal y0 = args[1]->NumberValue();
-        qreal r0 = args[2]->NumberValue();
-        qreal x1 = args[3]->NumberValue();
-        qreal y1 = args[4]->NumberValue();
-        qreal r1 = args[5]->NumberValue();
-
-        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;
-    }
-
-    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.
-  Returns a CanvasPattern object that uses the given \c color and \c patternMode.
-  The valid pattern modes are:
-    \list
-    \o Qt.SolidPattern
-    \o Qt.Dense1Pattern
-    \o Qt.Dense2Pattern
-    \o Qt.Dense3Pattern
-    \o Qt.Dense4Pattern
-    \o Qt.Dense5Pattern
-    \o Qt.Dense6Pattern
-    \o Qt.Dense7Pattern
-    \o Qt.HorPattern
-    \o Qt.VerPattern
-    \o Qt.CrossPattern
-    \o Qt.BDiagPattern
-    \o Qt.FDiagPattern
-    \o Qt.DiagCrossPattern
-\endlist
-    \sa Qt::BrushStyle
- */
-/*!
-  \qmlmethod variant createPattern(Image image, string repetition)
-  Returns a CanvasPattern object that uses the given image and repeats in the direction(s) given by the repetition argument.
-
-  The \a image parameter must be a valid Image item, a valid \a QtQuick2::CanvasImageData object or loaded image url, if there is no image data, throws an INVALID_STATE_ERR exception.
-
-  The allowed values for \a repetition are:
-
-  \list
-  \o "repeat"    - both directions
-  \o "repeat-x   - horizontal only
-  \o "repeat-y"  - vertical only
-  \o "no-repeat" - neither
-  \endlist
-
-  If the repetition argument is empty or null, the value "repeat" is used.
-
-  \sa QtQuick2::Context2D::strokeStyle
-  \sa QtQuick2::Context2D::fillStyle
-  */
-static v8::Handle<v8::Value> ctx2d_createPattern(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-
-    QV8Engine *engine = V8ENGINE();
-
-    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
-/*!
-    \qmlproperty string QtQuick2::Context2D::lineCap
-     Holds the the current line cap style.
-     The possible line cap styles are:
-    \list
-    \o butt - the end of each line has a flat edge perpendicular to the direction of the line, this is the default line cap value.
-    \o round - a semi-circle with the diameter equal to the width of the line must then be added on to the end of the line.
-    \o square - a rectangle with the length of the line width and the width of half the line width, placed flat against the edge perpendicular to the direction of the line.
-    \endlist
-    Other values are ignored.
-*/
-v8::Handle<v8::Value> ctx2d_lineCap(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT(r)
-
-
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-    switch (r->context->state.lineCap) {
-    case Qt::RoundCap:
-        return engine->toString(QLatin1String("round"));
-    case Qt::FlatCap:
-        return engine->toString(QLatin1String("butt"));
-    case Qt::SquareCap:
-        return engine->toString(QLatin1String("square"));
-    default:
-        break;
-    }
-    return engine->toString(QLatin1String("butt"));;
-}
-
-static void ctx2d_lineCap_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT_SETTER(r)
-
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-
-    QString lineCap = engine->toString(value);
-    Qt::PenCapStyle cap;
-    if (lineCap == QLatin1String("round"))
-        cap = Qt::RoundCap;
-    else if (lineCap == QLatin1String("butt"))
-        cap = Qt::FlatCap;
-    else if (lineCap == QLatin1String("square"))
-        cap = Qt::SquareCap;
-    else
-        return;
-
-    if (cap != r->context->state.lineCap) {
-        r->context->state.lineCap = cap;
-        r->context->buffer()->setLineCap(cap);
-    }
-}
-
-/*!
-    \qmlproperty string QtQuick2::Context2D::lineJoin
-     Holds the the current line join style. A join exists at any point in a subpath
-     shared by two consecutive lines. When a subpath is closed, then a join also exists
-     at its first point (equivalent to its last point) connecting the first and last lines in the subpath.
-
-    The possible line join styles are:
-    \list
-    \o bevel - this is all that is rendered at joins.
-    \o round - a filled arc connecting the two aforementioned corners of the join, abutting (and not overlapping) the aforementioned triangle, with the diameter equal to the line width and the origin at the point of the join, must be rendered at joins.
-    \o miter - a second filled triangle must (if it can given the miter length) be rendered at the join, this is the default line join style.
-    \endlist
-    Other values are ignored.
-*/
-v8::Handle<v8::Value> ctx2d_lineJoin(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT(r)
-
-
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-    switch (r->context->state.lineJoin) {
-    case Qt::RoundJoin:
-        return engine->toString(QLatin1String("round"));
-    case Qt::BevelJoin:
-        return engine->toString(QLatin1String("bevel"));
-    case Qt::MiterJoin:
-        return engine->toString(QLatin1String("miter"));
-    default:
-        break;
-    }
-    return engine->toString(QLatin1String("miter"));
-}
-
-static void ctx2d_lineJoin_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT_SETTER(r)
-
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-
-    QString lineJoin = engine->toString(value);
-    Qt::PenJoinStyle join;
-    if (lineJoin == QLatin1String("round"))
-        join = Qt::RoundJoin;
-    else if (lineJoin == QLatin1String("bevel"))
-        join = Qt::BevelJoin;
-    else if (lineJoin == QLatin1String("miter"))
-        join = Qt::MiterJoin;
-    else
-        return;
-
-    if (join != r->context->state.lineJoin) {
-        r->context->state.lineJoin = join;
-        r->context->buffer()->setLineJoin(join);
-    }
-}
-
-/*!
-    \qmlproperty real QtQuick2::Context2D::lineWidth
-     Holds the the current line width. Values that are not finite values greater than zero are ignored.
- */
-v8::Handle<v8::Value> ctx2d_lineWidth(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT(r)
-
-
-    return v8::Number::New(r->context->state.lineWidth);
-}
-
-static void ctx2d_lineWidth_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT_SETTER(r)
-
-    qreal w = value->NumberValue();
-
-    if (w > 0 && qIsFinite(w) && w != r->context->state.lineWidth) {
-        r->context->state.lineWidth = w;
-        r->context->buffer()->setLineWidth(w);
-    }
-}
-
-/*!
-    \qmlproperty real QtQuick2::Context2D::miterLimit
-     Holds the current miter limit ratio.
-     The default miter limit value is 10.0.
- */
-v8::Handle<v8::Value> ctx2d_miterLimit(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT(r)
-
-
-    return v8::Number::New(r->context->state.miterLimit);
-}
-
-static void ctx2d_miterLimit_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT_SETTER(r)
-
-    qreal ml = value->NumberValue();
-
-    if (ml > 0 && qIsFinite(ml) && ml != r->context->state.miterLimit) {
-        r->context->state.miterLimit = ml;
-        r->context->buffer()->setMiterLimit(ml);
-    }
-}
-
-// shadows
-/*!
-    \qmlproperty real QtQuick2::Context2D::shadowBlur
-     Holds the current level of blur applied to shadows
- */
-v8::Handle<v8::Value> ctx2d_shadowBlur(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT(r)
-
-
-    return v8::Number::New(r->context->state.shadowBlur);
-}
-
-static void ctx2d_shadowBlur_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT_SETTER(r)
-    qreal blur = value->NumberValue();
-
-    if (blur > 0 && qIsFinite(blur) && blur != r->context->state.shadowBlur) {
-        r->context->state.shadowBlur = blur;
-        r->context->buffer()->setShadowBlur(blur);
-    }
-}
-
-/*!
-    \qmlproperty string QtQuick2::Context2D::shadowColor
-     Holds the current shadow color.
- */
-v8::Handle<v8::Value> ctx2d_shadowColor(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT(r)
-
-
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-
-    return engine->toString(r->context->state.shadowColor.name());
-}
-
-static void ctx2d_shadowColor_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT_SETTER(r)
-
-    QColor color = qt_color_from_string(value);
-
-    if (color.isValid() && color != r->context->state.shadowColor) {
-        r->context->state.shadowColor = color;
-        r->context->buffer()->setShadowColor(color);
-    }
-}
-
-
-/*!
-    \qmlproperty qreal QtQuick2::Context2D::shadowOffsetX
-     Holds the current shadow offset in the positive horizontal distance.
-
-     \sa QtQuick2::Context2D::shadowOffsetY
- */
-v8::Handle<v8::Value> ctx2d_shadowOffsetX(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT(r)
-
-
-    return v8::Number::New(r->context->state.shadowOffsetX);
-}
-
-static void ctx2d_shadowOffsetX_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT_SETTER(r)
-
-    qreal offsetX = value->NumberValue();
-    if (qIsFinite(offsetX) && offsetX != r->context->state.shadowOffsetX) {
-        r->context->state.shadowOffsetX = offsetX;
-        r->context->buffer()->setShadowOffsetX(offsetX);
-    }
-}
-/*!
-    \qmlproperty qreal QtQuick2::Context2D::shadowOffsetY
-     Holds the current shadow offset in the positive vertical distance.
-
-     \sa QtQuick2::Context2D::shadowOffsetX
- */
-v8::Handle<v8::Value> ctx2d_shadowOffsetY(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT(r)
-
-
-    return v8::Number::New(r->context->state.shadowOffsetY);
-}
-
-static void ctx2d_shadowOffsetY_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT_SETTER(r)
-
-    qreal offsetY = value->NumberValue();
-    if (qIsFinite(offsetY) && offsetY != r->context->state.shadowOffsetY) {
-        r->context->state.shadowOffsetY = offsetY;
-        r->context->buffer()->setShadowOffsetY(offsetY);
-    }
-}
-
-v8::Handle<v8::Value> ctx2d_path(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT(r)
-    return r->context->m_v8path;
-}
-
-static void ctx2d_path_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT_SETTER(r)
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-
-    r->context->beginPath();
-    if (value->IsObject()) {
-        QDeclarativePath* path = qobject_cast<QDeclarativePath*>(engine->toQObject(value));
-        if (path)
-            r->context->m_path = path->path();
-    } else {
-        QString path = engine->toString(value->ToString());
-        QDeclarativeSvgParser::parsePathDataFast(path, r->context->m_path);
-    }
-    r->context->m_v8path = value;
-}
-
-//rects
-/*!
-  \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)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-
-    if (args.Length() == 4) {
-        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 object QtQuick2::Context2D::fillRect(real x, real y, real w, real h)
-   Paint the specified rectangular area using the fillStyle.
-
-   \sa QtQuick2::Context2D::fillStyle
-  */
-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) {
-        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 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.
-
-   \sa QtQuick2::Context2D::strokeStyle
-   \sa QtQuick2::Context2D::lineWidth
-   \sa QtQuick2::Context2D::lineJoin
-   \sa QtQuick2::Context2D::miterLimit
-  */
-static v8::Handle<v8::Value> ctx2d_strokeRect(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-
-    if (args.Length() == 4) {
-        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 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
-  See {http://www.w3.org/TR/2dcontext/#dom-context-2d-arc}{W3C 2d context standard for arc}
-  */
-static v8::Handle<v8::Value> ctx2d_arc(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-    if (args.Length() >= 5) {
-        bool antiClockwise = false;
-
-        if (args.Length() == 6)
-            antiClockwise = args[5]->BooleanValue();
-
-        qreal radius = args[2]->NumberValue();
-        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,
-                        args[3]->NumberValue(),
-                        args[4]->NumberValue(),
-                        antiClockwise);
-    }
-
-    return args.This();
-}
-
-/*!
-  \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:
-    \list
-    \o Call the context.beginPath() method to set a new path.
-    \o Call the context.moveTo(\c x, \c y) method to set your starting position on the canvas at the point (\c x,\c y).
-    \o To draw an arc or circle, call the context.arcTo(\c x1, \c y1, \c x2, \c y2,\c radius) method.
-       This adds an arc with starting point (\c x1,\c y1), ending point (\c x2, \c y2), and radius \c radius to the current subpath and connects
-       it to the previous subpath by a straight line.
-    \endlist
-    \image qml-item-canvas-arcTo.png
-    Both startAngle and endAngle are measured from the x axis in units of radians.
-
-    \image qml-item-canvas-startAngle.png
-    The anticlockwise has the value TRUE for each arc in the figure above because they are all drawn in the counterclockwise direction.
-  \sa  QtQuick2::Context2D::arc
-  \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-arcto}{W3C 2d context standard for arcTo}
-  */
-static v8::Handle<v8::Value> ctx2d_arcTo(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    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(),
-                          args[3]->NumberValue(),
-                          args[4]->NumberValue());
-    }
-
-    return args.This();
-}
-
-/*!
-  \qmlmethod object QtQuick2::Context2D::beginPath()
-
-   Resets the current path to a new path.
-  */
-static v8::Handle<v8::Value> ctx2d_beginPath(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-
-    r->context->beginPath();
-
-    return args.This();
-}
-
-/*!
-  \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).
-  After the curve is added, the current position is updated to be at the end point (\c x, \c y) of the curve.
-  The following code produces the path shown below:
-  \code
-  ctx.strokeStyle = Qt.rgba(0, 0, 0, 1);
-  ctx.lineWidth = 1;
-  ctx.beginPath();
-  ctx.moveTo(20, 0);//start point
-  ctx.bezierCurveTo(-10, 90, 210, 90, 180, 0);
-  ctx.stroke();
-  \endcode
-   \image qml-item-canvas-bezierCurveTo.png
-  \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-beziercurveto}{W3C 2d context standard for bezierCurveTo}
-  \sa {http://www.openrise.com/lab/FlowerPower/}{The beautiful flower demo by using bezierCurveTo}
-  */
-static v8::Handle<v8::Value> ctx2d_bezierCurveTo(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-
-    if (args.Length() == 6) {
-        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 object QtQuick2::Context2D::clip()
-
-   Creates the clipping region from the current path.
-   Any parts of the shape outside the clipping path are not displayed.
-   To create a complex shape using the \a clip() method:
-
-    \list 1
-    \o Call the \c{context.beginPath()} method to set the clipping path.
-    \o Define the clipping path by calling any combination of the \c{lineTo},
-    \c{arcTo}, \c{arc}, \c{moveTo}, etc and \c{closePath} methods.
-    \o Call the \c{context.clip()} method.
-    \endlist
-
-    The new shape displays.  The following shows how a clipping path can
-    modify how an image displays:
-
-    \image qml-canvas-clip-complex.png
-    \sa QtQuick2::Context2D::beginPath()
-    \sa QtQuick2::Context2D::closePath()
-    \sa QtQuick2::Context2D::stroke()
-    \sa QtQuick2::Context2D::fill()
-   \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-clip}{W3C 2d context standard for clip}
-  */
-static v8::Handle<v8::Value> ctx2d_clip(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-    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 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.
-
-   \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-closepath}{W3C 2d context standard for closePath}
-  */
-static v8::Handle<v8::Value> ctx2d_closePath(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-
-    r->context->closePath();
-
-    return args.This();
-}
-
-/*!
-  \qmlmethod object QtQuick2::Context2D::fill()
-
-   Fills the subpaths with the current fill style.
-
-   \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-fill}{W3C 2d context standard for fill}
-
-   \sa QtQuick2::Context2D::fillStyle
-  */
-static v8::Handle<v8::Value> ctx2d_fill(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r);
-
-    r->context->buffer()->fill(r->context->m_path);
-
-    return args.This();
-}
-
-/*!
-  \qmlmethod object QtQuick2::Context2D::lineTo(real x, real y)
-
-   Draws a line from the current position to the point (x, y).
- */
-static v8::Handle<v8::Value> ctx2d_lineTo(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-
-    if (args.Length() == 2) {
-        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 object QtQuick2::Context2D::moveTo(real x, real y)
-
-   Creates a new subpath with the given point.
- */
-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) {
-        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 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).
-
-   See {http://www.w3.org/TR/2dcontext/#dom-context-2d-quadraticcurveto}{W3C 2d context standard for  for quadraticCurveTo}
- */
-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) {
-        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 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.
- */
-static v8::Handle<v8::Value> ctx2d_rect(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-
-    if (args.Length() == 4) {
-        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 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.
- */
-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) {
-        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 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.
-
-  The ellipse is composed of a clockwise curve, starting and finishing at zero degrees (the 3 o'clock position).
- */
-static v8::Handle<v8::Value> ctx2d_ellipse(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-
-    if (args.Length() == 4) {
-        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 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).
- */
-static v8::Handle<v8::Value> ctx2d_text(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-    QV8Engine *engine = V8ENGINE();
-    if (args.Length() == 3) {
-        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 object QtQuick2::Context2D::stroke()
-
-   Strokes the subpaths with the current stroke style.
-
-   See {http://www.w3.org/TR/2dcontext/#dom-context-2d-stroke}{W3C 2d context standard for stroke}
-
-   \sa QtQuick2::Context2D::strokeStyle
-  */
-static v8::Handle<v8::Value> ctx2d_stroke(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-
-    r->context->buffer()->stroke(r->context->m_path);
-
-    return args.This();
-}
-
-/*!
-  \qmlmethod object QtQuick2::Context2D::isPointInPath(real x, real y)
-
-   Returns true if the given point is in the current path.
-
-   \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-ispointinpath}{W3C 2d context standard for isPointInPath}
-  */
-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) {
-        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_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_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_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::caretBlinkRate is not supported");
-    return args.This();
-}
-// text
-/*!
-  \qmlproperty string QtQuick2::Context2D::font
-  Holds the current font settings.
-
-  The default font value is "10px sans-serif".
-  See {http://www.w3.org/TR/2dcontext/#dom-context-2d-font}{w3C 2d context standard for font}
-  */
-v8::Handle<v8::Value> ctx2d_font(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT(r)
-
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-
-    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)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT_SETTER(r)
-
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-    QString fs = engine->toString(value);
-    QFont font = qt_font_from_string(fs);
-    if (font != r->context->state.font) {
-        r->context->state.font = font;
-    }
-}
-
-/*!
-  \qmlproperty string QtQuick2::Context2D::textAlign
-
-  Holds the current text alignment settings.
-  The possible values are:
-  \list
-    \o start
-    \o end
-    \o left
-    \o right
-    \o center
-  \endlist
-  Other values are ignored. The default value is "start".
-  */
-v8::Handle<v8::Value> ctx2d_textAlign(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT(r)
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-    switch (r->context->state.textAlign) {
-    case QSGContext2D::Start:
-        return engine->toString(QLatin1String("start"));
-   case QSGContext2D::End:
-        return engine->toString(QLatin1String("end"));
-   case QSGContext2D::Left:
-        return engine->toString(QLatin1String("left"));
-   case QSGContext2D::Right:
-        return engine->toString(QLatin1String("right"));
-   case QSGContext2D::Center:
-        return engine->toString(QLatin1String("center"));
-    default:
-        break;
-    }
-    return engine->toString(QLatin1String("start"));
-}
-
-static void ctx2d_textAlign_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT_SETTER(r)
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-
-    QString textAlign = engine->toString(value);
-
-    QSGContext2D::TextAlignType ta;
-    if (textAlign == QLatin1String("start"))
-        ta = QSGContext2D::Start;
-    else if (textAlign == QLatin1String("end"))
-        ta = QSGContext2D::End;
-    else if (textAlign == QLatin1String("left"))
-        ta = QSGContext2D::Left;
-    else if (textAlign == QLatin1String("right"))
-        ta = QSGContext2D::Right;
-    else if (textAlign == QLatin1String("center"))
-        ta = QSGContext2D::Center;
-    else
-        return;
-
-    if (ta != r->context->state.textAlign) {
-        r->context->state.textAlign = ta;
-    }
-}
-
-/*!
-  \qmlproperty string QtQuick2::Context2D::textBaseline
-
-  Holds the current baseline alignment settings.
-  The possible values are:
-  \list
-    \o top
-    \o hanging
-    \o middle
-    \o alphabetic
-    \o ideographic
-    \o bottom
-  \endlist
-  Other values are ignored. The default value is "alphabetic".
-  */
-v8::Handle<v8::Value> ctx2d_textBaseline(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT(r)
-
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-    switch (r->context->state.textBaseline) {
-    case QSGContext2D::Alphabetic:
-        return engine->toString(QLatin1String("alphabetic"));
-    case QSGContext2D::Hanging:
-        return engine->toString(QLatin1String("hanging"));
-    case QSGContext2D::Top:
-        return engine->toString(QLatin1String("top"));
-    case QSGContext2D::Bottom:
-        return engine->toString(QLatin1String("bottom"));
-    case QSGContext2D::Middle:
-        return engine->toString(QLatin1String("middle"));
-    default:
-        break;
-    }
-    return engine->toString(QLatin1String("alphabetic"));
-}
-
-static void ctx2d_textBaseline_set(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(info.This());
-    CHECK_CONTEXT_SETTER(r)
-    QV8Engine *engine = V8ENGINE_ACCESSOR();
-    QString textBaseline = engine->toString(value);
-
-    QSGContext2D::TextBaseLineType tb;
-    if (textBaseline == QLatin1String("alphabetic"))
-        tb = QSGContext2D::Alphabetic;
-    else if (textBaseline == QLatin1String("hanging"))
-        tb = QSGContext2D::Hanging;
-    else if (textBaseline == QLatin1String("top"))
-        tb = QSGContext2D::Top;
-    else if (textBaseline == QLatin1String("bottom"))
-        tb = QSGContext2D::Bottom;
-    else if (textBaseline == QLatin1String("middle"))
-        tb = QSGContext2D::Middle;
-    else
-        return;
-
-    if (tb != r->context->state.textBaseline) {
-        r->context->state.textBaseline = tb;
-    }
-}
-
-/*!
-  \qmlmethod object QtQuick2::Context2D::fillText(text, x, y)
-  Fills the given text at the given position.
-  \sa QtQuick2::Context2D::font
-  \sa QtQuick2::Context2D::textAlign
-  \sa QtQuick2::Context2D::textBaseline
-  \sa QtQuick2::Context2D::strokeText
-  */
-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) {
-        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 object QtQuick2::Context2D::strokeText(text, x, y)
-  Strokes the given text at the given position.
-  \sa QtQuick2::Context2D::font
-  \sa QtQuick2::Context2D::textAlign
-  \sa QtQuick2::Context2D::textBaseline
-  \sa QtQuick2::Context2D::fillText
-  */
-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) {
-        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();
-}
-/*!
-  \qmlclass QtQuick2::TextMetrics
-    \inqmlmodule QtQuick 2
-    \since QtQuick 2.0
-    \brief The Context2D TextMetrics interface.
-    The TextMetrics object can be created by QtQuick2::Context2D::measureText method.
-    See {http://www.w3.org/TR/2dcontext/#textmetrics}{W3C 2d context TexMetrics} for more details.
-
-    \sa QtQuick2::Context2D::measureText
-    \sa QtQuick2::TextMetrics::width
-  */
-
-/*!
-  \qmlproperty int QtQuick2::TextMetrics::width
-  Holds the advance width of the text that was passed to the QtQuick2::Context2D::measureText() method.
-  This property is read only.
-  */
-
-/*!
-  \qmlmethod variant QtQuick2::Context2D::measureText(text)
-  Returns a TextMetrics object with the metrics of the given text in the current font.
-  */
-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) {
-        QFontMetrics fm(r->context->state.font);
-        uint width = fm.width(engine->toString(args[0]));
-        v8::Local<v8::Object> tm = v8::Object::New();
-        tm->Set(v8::String::New("width"), v8::Number::New(width));
-        return tm;
-    }
-    return v8::Undefined();
-}
-
-// drawing images
-/*!
-  \qmlmethod QtQuick2::Context2D::drawImage(variant image, real dx, real dy)
-  Draws the given \a image on the canvas at position (\a dx, \a dy).
-  Note:
-  The \a image type can be an Image 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.
-
-  \sa QtQuick2::CanvasImageData
-  \sa QtQuick2::Image
-  \sa QtQuick2::Canvas::loadImage
-  \sa QtQuick2::Canvas::isImageLoaded
-  \sa QtQuick2::Canvas::imageLoaded
-
-  \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-drawimage}{W3C 2d context standard for drawImage}
-  */
-/*!
-  \qmlmethod QtQuick2::Context2D::drawImage(variant image, real dx, real dy, real dw, real dh)
-  This is an overloaded function.
-  Draws the given item as \a image onto the canvas at point (\a dx, \a dy) and with width \a dw,
-  height \a dh.
-
-  Note:
-  The \a image type can be an Image 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.
-
-  \sa QtQuick2::CanvasImageData
-  \sa QtQuick2::Image
-  \sa QtQuick2::Canvas::loadImage
-  \sa QtQuick2::Canvas::isImageLoaded
-  \sa QtQuick2::Canvas::imageLoaded
-
-  \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-drawimage}{W3C 2d context standard for drawImage}
-  */
-/*!
-  \qmlmethod QtQuick2::Context2D::drawImage(variant image, real sx, real sy, real sw, sh, real dx, real dy, real dw, dh)
-  This is an overloaded function.
-  Draws the given item as \a image from source point (\a sx, \a sy) and source width \sw, source height \sh
-  onto the canvas at point (\a dx, \a dy) and with width \a dw, height \a dh.
-
-
-  Note:
-  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.
-
-  \sa QtQuick2::CanvasImageData
-  \sa QtQuick2::Image
-  \sa QtQuick2::Canvas::loadImage
-  \sa QtQuick2::Canvas::isImageLoaded
-  \sa QtQuick2::Canvas::imageLoaded
-
-  \sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-drawimage}{W3C 2d context standard for drawImage}
-*/
-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();
-    qreal sx, sy, sw, sh, dx, dy, dw, dh;
-
-    if (!args.Length())
-        return args.This();
-
-    QImage image;
-    if (args[0]->IsString()) {
-        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()));
-        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 {
-            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.width();
-        sh = image.height();
-        dw = sw;
-        dh = sh;
-    } else if (args.Length() == 5) {
-        sx = 0;
-        sy = 0;
-        sw = image.width();
-        sh = image.height();
-        dx = args[1]->NumberValue();
-        dy = args[2]->NumberValue();
-        dw = args[3]->NumberValue();
-        dh = args[4]->NumberValue();
-    } else if (args.Length() == 9) {
-        sx = args[1]->NumberValue();
-        sy = args[2]->NumberValue();
-        sw = args[3]->NumberValue();
-        sh = args[4]->NumberValue();
-        dx = args[5]->NumberValue();
-        dy = args[6]->NumberValue();
-        dw = args[7]->NumberValue();
-        dh = args[8]->NumberValue();
-    } else {
-        return args.This();
-    }
-
-    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();
-}
-
-// pixel manipulation
-/*!
-  \qmlclass QtQuick2::CanvasImageData
-     The \a QtQuick2::CanvasImageData object holds the image pixel data.
-
-     The \a QtQuick2::CanvasImageData object has the actual dimensions of the data stored in
-     this object and holds the one-dimensional array containing the data in RGBA order,
-     as integers in the range 0 to 255.
-
-     \sa QtQuick2::CanvasImageData::width
-     \sa QtQuick2::CanvasImageData::height
-     \sa QtQuick2::CanvasImageData::data
-     \sa QtQuick2::Context2D::createImageData
-     \sa QtQuick2::Context2D::getImageData
-     \sa QtQuick2::Context2D::putImageData
-  */
-/*!
-  \qmlproperty QtQuick2::CanvasImageData::width
-  Holds the actual width dimension of the data in the ImageData object, in device pixels.
- */
-v8::Handle<v8::Value> ctx2d_imageData_width(v8::Local<v8::String>, const v8::AccessorInfo &args)
-{
-    QV8Context2DPixelArrayResource *r = v8_resource_cast<QV8Context2DPixelArrayResource>(args.This()->GetInternalField(0)->ToObject());
-    if (!r)
-        return v8::Integer::New(0);
-    return v8::Integer::New(r->image.width());
-}
-
-/*!
-  \qmlproperty QtQuick2::CanvasImageData::height
-  Holds the actual height dimension of the data in the ImageData object, in device pixels.
-  */
-v8::Handle<v8::Value> ctx2d_imageData_height(v8::Local<v8::String>, const v8::AccessorInfo &args)
-{
-    QV8Context2DPixelArrayResource *r = v8_resource_cast<QV8Context2DPixelArrayResource>(args.This()->GetInternalField(0)->ToObject());
-    if (!r)
-        return v8::Integer::New(0);
-
-    return v8::Integer::New(r->image.height());
-}
-
-/*!
-  \qmlproperty QtQuick2::CanvasImageData::data
-  Holds the one-dimensional array containing the data in RGBA order, as integers in the range 0 to 255.
- */
-v8::Handle<v8::Value> ctx2d_imageData_data(v8::Local<v8::String>, const v8::AccessorInfo &args)
-{
-    return args.This()->GetInternalField(0);
-}
-
-/*!
-  \qmlmethod void QtQuick2::CanvasImageData::mirrr( bool horizontal = false, bool vertical = true)
-  Mirrors the image data in place in the  \c horizontal and/or the \c vertical direction depending on
-  whether horizontal and vertical are set to true or false.
-  The default \c horizontal value is false, the default \c vertical value is true.
-*/
-static v8::Handle<v8::Value> ctx2d_imageData_mirror(const v8::Arguments &args)
-{
-    bool horizontal = false, vertical = true;
-    QV8Context2DPixelArrayResource *r = v8_resource_cast<QV8Context2DPixelArrayResource>(args.This()->GetInternalField(0)->ToObject());
-
-    if (!r) {
-        //error
-        return v8::Undefined();
-    }
-
-    if (args.Length() > 2) {
-      //error
-      return v8::Undefined();
-    }
-
-    if (args.Length() == 1) {
-        horizontal = args[0]->BooleanValue();
-    } else if (args.Length() == 2) {
-        horizontal = args[0]->BooleanValue();
-        vertical = args[1]->BooleanValue();
-    }
-    r->image = r->image.mirrored(horizontal, vertical);
-    return args.This();
-}
-
-/*!
-  \qmlmethod void QtQuick2::CanvasImageData::filter(enumeration mode, args)
-   Filters the image data as defined by one of the following modes:
-    \list
-    \o Canvas.Threshold - converts the image to black and white pixels depending
-                          if they are above or below the threshold defined by the level parameter.
-                          The level must be between 0.0 (black) and 1.0(white).
-                          If no level is specified, 0.5 is used.
-    \o Canvas.Mono - converts the image to the 1-bit per pixel format.
-    \o Canvas.GrayScale - converts any colors in the image to grayscale equivalents.
-    \o Canvas.Brightness -increase/decrease a fixed \c adjustment value to each pixel's RGB channel value.
-    \o Canvas.Invert - sets each pixel to its inverse value.
-    \o Canvas.Blur - executes a box blur with the pixel \c radius parameter specifying the range of the blurring for each pixel.
-                     the default blur \c radius is 3. This filter also accepts another \c quality parameter, if true, the filter will
-                     execute 3-passes box blur to simulate the Guassian blur. The default \c quality value is false.
-    \o Canvas.Opaque - sets the alpha channel to entirely opaque.
-    \o Canvas.Convolute - executes a generic {http://en.wikipedia.org/wiki/Convolution}{Convolution} filter, the second
-                          parameter contains the convoluton matrix data as a number array.
-    \endlist
-
-*/
-static v8::Handle<v8::Value> ctx2d_imageData_filter(const v8::Arguments &args)
-{
-    QV8Context2DPixelArrayResource *r = v8_resource_cast<QV8Context2DPixelArrayResource>(args.This()->GetInternalField(0)->ToObject());
-
-    if (!r) {
-        //error
-        return v8::Undefined();
-    }
-
-    if (args.Length() >= 1) {
-        int filterFlag = args[0]->IntegerValue();
-        switch (filterFlag) {
-        case QSGCanvasItem::Mono :
-        {
-            r->image = r->image.convertToFormat(QImage::Format_Mono).convertToFormat(QImage::Format_ARGB32_Premultiplied);
-        }
-            break;
-        case QSGCanvasItem::GrayScale :
-        {
-            for (int y = 0; y < r->image.height(); ++y) {
-              QRgb *row = (QRgb*)r->image.scanLine(y);
-              for (int x = 0; x < r->image.width(); ++x) {
-                  unsigned char* rgb = ((unsigned char*)&row[x]);
-                  rgb[0] = rgb[1] = rgb[2] = qGray(rgb[0], rgb[1], rgb[2]);
-              }
-            }
-        }
-            break;
-        case QSGCanvasItem::Threshold :
-        {
-            qreal threshold = 0.5;
-            if (args.Length() > 1)
-                threshold = args[1]->NumberValue();
-
-            for (int y = 0; y < r->image.height(); ++y) {
-              QRgb *row = (QRgb*)r->image.scanLine(y);
-              for (int x = 0; x < r->image.width(); ++x) {
-                  unsigned char* rgb = ((unsigned char*)&row[x]);
-                  unsigned char v = qGray(rgb[0], rgb[1], rgb[2]) >= threshold*255 ? 255 : 0;
-                  rgb[0] = rgb[1] = rgb[2] = v;
-              }
-            }
-        }
-            break;
-        case QSGCanvasItem::Brightness :
-        {
-            int adjustment = 1;
-            if (args.Length() > 1)
-                adjustment = args[1]->IntegerValue();
-
-            for (int y = 0; y < r->image.height(); ++y) {
-              QRgb *row = (QRgb*)r->image.scanLine(y);
-              for (int x = 0; x < r->image.width(); ++x) {
-                ((unsigned char*)&row[x])[0] += adjustment;
-                ((unsigned char*)&row[x])[1] += adjustment;
-                ((unsigned char*)&row[x])[2] += adjustment;
-              }
-            }
-        }
-            break;
-        case QSGCanvasItem::Invert :
-        {
-            r->image.invertPixels();
-        }
-            break;
-        case QSGCanvasItem::Blur :
-        {
-            int radius = 3;
-            bool quality = false;
-
-            if (args.Length() > 1)
-                radius = args[1]->IntegerValue() / 2;
-            if (args.Length() > 2)
-                quality = args[2]->BooleanValue();
-
-            qt_image_boxblur(r->image, radius, quality);
-        }
-            break;
-        case QSGCanvasItem::Opaque :
-        {
-            for (int y = 0; y < r->image.height(); ++y) {
-              QRgb *row = (QRgb*)r->image.scanLine(y);
-              for (int x = 0; x < r->image.width(); ++x) {
-                ((unsigned char*)&row[x])[3] = 255;
-              }
-            }
-        }
-            break;
-        case QSGCanvasItem::Convolute :
-        {
-            if (args.Length() > 1 && args[1]->IsArray()) {
-                v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(args[1]);
-                QVector<qreal> weights;
-                for (uint32_t i = 0; i < array->Length(); ++i)
-                    weights.append(array->Get(i)->NumberValue());
-                r->image = qt_image_convolute_filter(r->image, weights);
-            } else {
-                //error
-            }
-        }
-            break;
-        default:
-            break;
-        }
-    }
-
-    return args.This();
-}
-/*!
-  \qmlclass QtQuick2::CanvasPixelArray
-  The CanvasPixelArray object provides ordered, indexed access to the color components of each pixel of the image data.
-  The CanvasPixelArray can be accessed as normal Javascript array.
-    \sa QtQuick2::CanvasImageData
-    \sa {http://www.w3.org/TR/2dcontext/#canvaspixelarray}{W3C 2d context standard for PixelArray}
-  */
-
-/*!
-  \qmlproperty QtQuick2::CanvasPixelArray::length
-  The CanvasPixelArray object represents h×w×4 integers which w and h comes from CanvasImageData.
-  The length attribute of a CanvasPixelArray object must return this h×w×4 number value.
-  This property is read only.
-*/
-v8::Handle<v8::Value> ctx2d_pixelArray_length(v8::Local<v8::String>, const v8::AccessorInfo &args)
-{
-    QV8Context2DPixelArrayResource *r = v8_resource_cast<QV8Context2DPixelArrayResource>(args.This());
-    if (!r || r->image.isNull()) return v8::Undefined();
-
-    return v8::Integer::New(r->image.width() * r->image.height() * 4);
-}
-
-v8::Handle<v8::Value> ctx2d_pixelArray_indexed(uint32_t index, const v8::AccessorInfo& args)
-{
-    QV8Context2DPixelArrayResource *r = v8_resource_cast<QV8Context2DPixelArrayResource>(args.This());
-
-    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) {
-        case 0:
-            return v8::Integer::New(qRed(*pixel));
-        case 1:
-            return v8::Integer::New(qGreen(*pixel));
-        case 2:
-            return v8::Integer::New(qBlue(*pixel));
-        case 3:
-            return v8::Integer::New(qAlpha(*pixel));
-        }
-    }
-    return v8::Undefined();
-}
-
-v8::Handle<v8::Value> ctx2d_pixelArray_indexed_set(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
-{
-    QV8Context2DPixelArrayResource *r = v8_resource_cast<QV8Context2DPixelArrayResource>(info.This());
-
-    const int v = value->Uint32Value();
-    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;
-        switch (index % 4) {
-        case 0:
-            *pixel = qRgba(v, qGreen(*pixel), qBlue(*pixel), qAlpha(*pixel));
-            break;
-        case 1:
-            *pixel = qRgba(qRed(*pixel), v, qBlue(*pixel), qAlpha(*pixel));
-            break;
-        case 2:
-            *pixel = qRgba(qRed(*pixel), qGreen(*pixel), v, qAlpha(*pixel));
-            break;
-        case 3:
-            *pixel = qRgba(qRed(*pixel), qGreen(*pixel), qBlue(*pixel), v);
-            break;
-        }
-    }
-    return v8::Undefined();
-}
-/*!
-  \qmlmethod QtQuick2::CanvasImageData createImageData(real sw, real sh)
-   Creates a CanvasImageData object with the given dimensions(\a sw, \a sh).
-  */
-/*!
-  \qmlmethod QtQuick2::CanvasImageData createImageData(QtQuick2::CanvasImageData imageData)
-   Creates a CanvasImageData object with the same dimensions as the argument.
-  */
-/*!
-  \qmlmethod QtQuick2::CanvasImageData createImageData(Url imageUrl)
-   Creates a CanvasImageData object with the given image loaded from \a imageUrl.
-   Note:The \a imageUrl must be already loaded before this function call, if not, an empty
-   CanvasImageData obect will be returned.
-
-   \sa QtQuick2::Canvas::loadImage, QtQuick2::Canvas::unloadImage, QtQuick2::Canvas::isImageLoaded
-  */
-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) {
-        if (args[0]->IsObject()) {
-            v8::Local<v8::Object> imgData = args[0]->ToObject();
-            QV8Context2DPixelArrayResource *pa = v8_resource_cast<QV8Context2DPixelArrayResource>(imgData->GetInternalField(0)->ToObject());
-            if (pa) {
-                qreal w = imgData->Get(v8::String::New("width"))->NumberValue();
-                qreal h = imgData->Get(v8::String::New("height"))->NumberValue();
-                return qt_create_image_data(w, h, engine, QImage());
-            }
-        } else if (args[0]->IsString()) {
-            QImage image = r->context->createImage(QUrl(engine->toString(args[0]->ToString())));
-            return qt_create_image_data(image.width(), image.height(), engine, image);
-        }
-    } 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();
-}
-
-/*!
-  \qmlmethod QtQuick2::CanvasImageData getImageData(real sx, real sy, real sw, real sh)
-  Returns an CanvasImageData object containing the image data for the given rectangle of the canvas.
-  */
-static v8::Handle<v8::Value> ctx2d_getImageData(const v8::Arguments &args)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-
-    QV8Engine *engine = V8ENGINE();
-    if (args.Length() == 4) {
-        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(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));
-        v8::Local<v8::Object> imageData = qt_create_image_data(w, h, engine, image);
-
-        return imageData;
-    }
-    return v8::Null();
-}
-
-/*!
-  \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)
-{
-    QV8Context2DResource *r = v8_resource_cast<QV8Context2DResource>(args.This());
-    CHECK_CONTEXT(r)
-    if (args.Length() != 3 && args.Length() != 7)
-        return v8::Undefined();
-
-    if (args[0]->IsNull() || !args[0]->IsObject()) {
-        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) {
-        w = imageData->Get(v8::String::New("width"))->NumberValue();
-        h = imageData->Get(v8::String::New("height"))->NumberValue();
-
-        if (args.Length() == 7) {
-            dirtyX = args[3]->NumberValue();
-            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;
-            }
-
-            if (dirtyHeight < 0) {
-                dirtyY = dirtyY+dirtyHeight;
-                dirtyHeight = -dirtyHeight;
-            }
-
-            if (dirtyX < 0) {
-                dirtyWidth = dirtyWidth+dirtyX;
-                dirtyX = 0;
-            }
-
-            if (dirtyY < 0) {
-                dirtyHeight = dirtyHeight+dirtyY;
-                dirtyY = 0;
-            }
-
-            if (dirtyX+dirtyWidth > w) {
-                dirtyWidth = w - dirtyX;
-            }
-
-            if (dirtyY+dirtyHeight > h) {
-                dirtyHeight = h - dirtyY;
-            }
-
-            if (dirtyWidth <=0 || dirtyHeight <= 0)
-                return args.This();
-        } else {
-            dirtyX = 0;
-            dirtyY = 0;
-            dirtyWidth = w;
-            dirtyHeight = h;
-        }
-
-        QImage image = pixelArray->image.copy(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
-        r->context->buffer()->drawImage(image, dirtyX, dirtyY, dirtyWidth, dirtyHeight, dx, dy, dirtyWidth, dirtyHeight);
-    }
-    return args.This();
-}
-
-/*!
-  \qmlclass QtQuick2::CanvasGradient
-    \inqmlmodule QtQuick 2
-    \since QtQuick 2.0
-    \brief The Context2D opaque CanvasGradient interface.
-  */
-
-/*!
-  \qmlmethod QtQuick2::CanvasGradient QtQuick2::CanvasGradient::addColorStop(real offsetof, string color)
-  Adds a color stop with the given color to the gradient at the given offset.
-  0.0 is the offset at one end of the gradient, 1.0 is the offset at the other end.
-
-  For example:
-  \code
-  var gradient = ctx.createLinearGradient(0, 0, 100, 100);
-  gradient.addColorStop(0.3, Qt.rgba(1, 0, 0, 1));
-  gradient.addColorStop(0.7, 'rgba(0, 255, 255, 1');
-  \endcode
-  */
-static v8::Handle<v8::Value> ctx2d_gradient_addColorStop(const v8::Arguments &args)
-{
-    QV8Context2DStyleResource *style = v8_resource_cast<QV8Context2DStyleResource>(args.This());
-    if (!style)
-        V8THROW_ERROR("Not a CanvasGradient object");
-
-    QV8Engine *engine = V8ENGINE();
-
-    if (args.Length() == 2) {
-
-        if (!style->brush.gradient())
-            V8THROW_ERROR("Not a valid CanvasGradient object, can't get the gradient information");
-        QGradient gradient = *(style->brush.gradient());
-        qreal pos = args[0]->NumberValue();
-        QColor color;
-
-        if (args[1]->IsObject()) {
-            color = engine->toVariant(args[1], qMetaTypeId<QColor>()).value<QColor>();
-        } else {
-            color = qt_color_from_string(args[1]);
-        }
-        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 {
-            V8THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "CanvasGradient: parameter color is not a valid color string");
-        }
-        style->brush = gradient;
-    }
-
-    return args.This();
-}
-
-
-void QSGContext2D::beginPath()
-{
-    m_path = QPainterPath();
-    m_path.setFillRule(state.fillRule);
-}
-
-void QSGContext2D::closePath()
-{
-    if (m_path.isEmpty())
-        return;
-
-    QRectF boundRect = m_path.boundingRect();
-    if (boundRect.width() || boundRect.height())
-        m_path.closeSubpath();
-    //FIXME:QPainterPath set the current point to (0,0) after close subpath
-    //should be the first point of the previous subpath
-}
-
-void QSGContext2D::moveTo( qreal x, qreal y)
-{
-    //FIXME: moveTo should not close the previous subpath
-    m_path.moveTo(state.matrix.map(QPointF(x, y)));
-}
-
-void QSGContext2D::lineTo( qreal x, qreal y)
-{
-    m_path.lineTo(state.matrix.map(QPointF(x, y)));
-}
-
-void QSGContext2D::quadraticCurveTo(qreal cpx, qreal cpy,
-                                           qreal x, qreal y)
-{
-    m_path.quadTo(state.matrix.map(QPointF(cpx, cpy)),
-                      state.matrix.map(QPointF(x, y)));
-}
-
-void QSGContext2D::bezierCurveTo(qreal cp1x, qreal cp1y,
-                                        qreal cp2x, qreal cp2y,
-                                        qreal x, qreal y)
-{
-    m_path.cubicTo(state.matrix.map(QPointF(cp1x, cp1y)),
-                       state.matrix.map(QPointF(cp2x, cp2y)),
-                       state.matrix.map(QPointF(x, y)));
-}
-
-void QSGContext2D::addArcTo(const QPointF& p1, const QPointF& p2, float radius)
-{
-    QPointF p0(m_path.currentPosition());
-
-    QPointF p1p0((p0.x() - p1.x()), (p0.y() - p1.y()));
-    QPointF p1p2((p2.x() - p1.x()), (p2.y() - p1.y()));
-    float p1p0_length = qSqrt(p1p0.x() * p1p0.x() + p1p0.y() * p1p0.y());
-    float p1p2_length = qSqrt(p1p2.x() * p1p2.x() + p1p2.y() * p1p2.y());
-
-    double cos_phi = (p1p0.x() * p1p2.x() + p1p0.y() * p1p2.y()) / (p1p0_length * p1p2_length);
-
-    // The points p0, p1, and p2 are on the same straight line (HTML5, 4.8.11.1.8)
-    // We could have used areCollinear() here, but since we're reusing
-    // the variables computed above later on we keep this logic.
-    if (qFuzzyCompare(qAbs(cos_phi), 1.0)) {
-        m_path.lineTo(p1);
-        return;
-    }
-
-    float tangent = radius / tan(acos(cos_phi) / 2);
-    float factor_p1p0 = tangent / p1p0_length;
-    QPointF t_p1p0((p1.x() + factor_p1p0 * p1p0.x()), (p1.y() + factor_p1p0 * p1p0.y()));
-
-    QPointF orth_p1p0(p1p0.y(), -p1p0.x());
-    float orth_p1p0_length = sqrt(orth_p1p0.x() * orth_p1p0.x() + orth_p1p0.y() * orth_p1p0.y());
-    float factor_ra = radius / orth_p1p0_length;
-
-    // angle between orth_p1p0 and p1p2 to get the right vector orthographic to p1p0
-    double cos_alpha = (orth_p1p0.x() * p1p2.x() + orth_p1p0.y() * p1p2.y()) / (orth_p1p0_length * p1p2_length);
-    if (cos_alpha < 0.f)
-        orth_p1p0 = QPointF(-orth_p1p0.x(), -orth_p1p0.y());
-
-    QPointF p((t_p1p0.x() + factor_ra * orth_p1p0.x()), (t_p1p0.y() + factor_ra * orth_p1p0.y()));
-
-    // calculate angles for addArc
-    orth_p1p0 = QPointF(-orth_p1p0.x(), -orth_p1p0.y());
-    float sa = acos(orth_p1p0.x() / orth_p1p0_length);
-    if (orth_p1p0.y() < 0.f)
-        sa = 2 * Q_PI - sa;
-
-    // anticlockwise logic
-    bool anticlockwise = false;
-
-    float factor_p1p2 = tangent / p1p2_length;
-    QPointF t_p1p2((p1.x() + factor_p1p2 * p1p2.x()), (p1.y() + factor_p1p2 * p1p2.y()));
-    QPointF orth_p1p2((t_p1p2.x() - p.x()), (t_p1p2.y() - p.y()));
-    float orth_p1p2_length = sqrtf(orth_p1p2.x() * orth_p1p2.x() + orth_p1p2.y() * orth_p1p2.y());
-    float ea = acos(orth_p1p2.x() / orth_p1p2_length);
-    if (orth_p1p2.y() < 0)
-        ea = 2 * Q_PI - ea;
-    if ((sa > ea) && ((sa - ea) < Q_PI))
-        anticlockwise = true;
-    if ((sa < ea) && ((ea - sa) > Q_PI))
-        anticlockwise = true;
-
-    arc(p.x(), p.y(), radius, sa, ea, anticlockwise, false);
-}
-
-void QSGContext2D::arcTo(qreal x1, qreal y1,
-                                qreal x2, qreal y2,
-                                qreal radius)
-{
-    QPointF st  = state.matrix.map(QPointF(x1, y1));
-    QPointF end = state.matrix.map(QPointF(x2, y2));
-
-    if (!m_path.elementCount()) {
-        m_path.moveTo(st);
-    } else if (st == m_path.currentPosition() || st == end || !radius) {
-        m_path.lineTo(st);
-    } else {
-        addArcTo(st, end, radius);
-    }
-}
-
-void QSGContext2D::rect(qreal x, qreal y,
-                               qreal w, qreal h)
-{
-    m_path.addPolygon(state.matrix.map(QRectF(x, y, w, h)));
-}
-
-void QSGContext2D::roundedRect(qreal x, qreal y,
-                               qreal w, qreal h,
-                               qreal xr, qreal yr)
-{
-    QPainterPath path;
-    path.addRoundedRect(QRectF(x, y, w, h), xr, yr, Qt::AbsoluteSize);
-    m_path.addPath(state.matrix.map(path));
-}
-
-void QSGContext2D::ellipse(qreal x, qreal y,
-                           qreal w, qreal h)
-{
-    QPainterPath path;
-    path.addEllipse(x, y, w, h);
-    m_path.addPath(state.matrix.map(path));
-}
-
-void QSGContext2D::text(const QString& str, qreal x, qreal y)
-{
-    QPainterPath path;
-    path.addText(x, y, state.font, str);
-    m_path.addPath(state.matrix.map(path));
-}
-
-void QSGContext2D::arc(qreal xc,
-                       qreal yc,
-                       qreal radius,
-                       qreal sar,
-                       qreal ear,
-                       bool antiClockWise,
-                       bool transform)
-{
-
-    if (transform) {
-        QPointF point = state.matrix.map(QPointF(xc, yc));
-        xc = point.x();
-        yc = point.y();
-    }
-    //### HACK
-
-    // In Qt we don't switch the coordinate system for degrees
-    // and still use the 0,0 as bottom left for degrees so we need
-    // to switch
-    sar = -sar;
-    ear = -ear;
-    antiClockWise = !antiClockWise;
-    //end hack
-
-    float sa = DEGREES(sar);
-    float ea = DEGREES(ear);
-
-    double span = 0;
-
-    double xs     = xc - radius;
-    double ys     = yc - radius;
-    double width  = radius*2;
-    double height = radius*2;
-    if ((!antiClockWise && (ea - sa >= 360)) || (antiClockWise && (sa - ea >= 360)))
-        // If the anticlockwise argument is false and endAngle-startAngle is equal to or greater than 2*PI, or, if the
-        // anticlockwise argument is true and startAngle-endAngle is equal to or greater than 2*PI, then the arc is the whole
-        // circumference of this circle.
-        span = 360;
-    else {
-        if (!antiClockWise && (ea < sa)) {
-            span += 360;
-        } else if (antiClockWise && (sa < ea)) {
-            span -= 360;
-        }
-        //### this is also due to switched coordinate system
-        // we would end up with a 0 span instead of 360
-        if (!(qFuzzyCompare(span + (ea - sa) + 1, 1) &&
-              qFuzzyCompare(qAbs(span), 360))) {
-            span   += ea - sa;
-        }
-        if (!m_path.elementCount())
-            m_path.moveTo(xs, ys);
-    }
-
-
-    if (transform) {
-        QPointF currentPos = m_path.currentPosition();
-        QPointF startPos = QPointF(xc + radius  * qCos(sar),
-                                   yc - radius  * qSin(sar));
-        if (currentPos != startPos)
-            m_path.lineTo(startPos);
-    }
-
-    m_path.arcTo(xs, ys, width, height, sa, span);
-}
-
-int baseLineOffset(QSGContext2D::TextBaseLineType value, const QFontMetrics &metrics)
-{
-    int offset = 0;
-    switch (value) {
-    case QSGContext2D::Top:
-        break;
-    case QSGContext2D::Alphabetic:
-    case QSGContext2D::Middle:
-    case QSGContext2D::Hanging:
-        offset = metrics.ascent();
-        break;
-    case QSGContext2D::Bottom:
-        offset = metrics.height();
-       break;
-    }
-    return offset;
-}
-
-static int textAlignOffset(QSGContext2D::TextAlignType value, const QFontMetrics &metrics, const QString &text)
-{
-    int offset = 0;
-    if (value == QSGContext2D::Start)
-        value = QGuiApplication::layoutDirection() == Qt::LeftToRight ? QSGContext2D::Left : QSGContext2D::Right;
-    else if (value == QSGContext2D::End)
-        value = QGuiApplication::layoutDirection() == Qt::LeftToRight ? QSGContext2D::Right: QSGContext2D::Left;
-    switch (value) {
-    case QSGContext2D::Center:
-        offset = metrics.width(text)/2;
-        break;
-    case QSGContext2D::Right:
-        offset = metrics.width(text);
-    case QSGContext2D::Left:
-    default:
-        break;
-    }
-    return offset;
-}
-
-
-QImage QSGContext2D::createImage(const QUrl& url)
-{
-    return m_canvas->loadedImage(url);
-}
-
-QPainterPath QSGContext2D::createTextGlyphs(qreal x, qreal y, const QString& text)
-{
-    const QFontMetrics metrics(state.font);
-    int yoffset = baseLineOffset(static_cast<QSGContext2D::TextBaseLineType>(state.textBaseline), metrics);
-    int xoffset = textAlignOffset(static_cast<QSGContext2D::TextAlignType>(state.textAlign), metrics, text);
-
-    QPainterPath textPath;
-
-    textPath.addText(x - xoffset, y - yoffset+metrics.ascent(), state.font, text);
-    textPath = state.matrix.map(textPath);
-    return textPath;
-}
-
-
-bool QSGContext2D::isPointInPath(qreal x, qreal y) const
-{
-    return m_path.contains(QPointF(x, y));
-}
-
-QSGContext2D::QSGContext2D(QSGCanvasItem* item)
-    : m_canvas(item)
-    , m_buffer(new QSGContext2DCommandBuffer)
-    , m_v8engine(0)
-{
-    reset();
-}
-
-QSGContext2D::~QSGContext2D()
-{
-}
-
-v8::Handle<v8::Object> QSGContext2D::v8value() const
-{
-    return m_v8value;
-}
-
-QSGContext2DEngineData::QSGContext2DEngineData(QV8Engine *engine)
-{
-    v8::HandleScope handle_scope;
-    v8::Context::Scope scope(engine->context());
-
-    v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
-    ft->InstanceTemplate()->SetHasExternalResource(true);
-    ft->PrototypeTemplate()->SetAccessor(v8::String::New("canvas"), ctx2d_canvas, 0, v8::External::Wrap(engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("restore"), V8FUNCTION(ctx2d_restore, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("reset"), V8FUNCTION(ctx2d_reset, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("save"), V8FUNCTION(ctx2d_save, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("rotate"), V8FUNCTION(ctx2d_rotate, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("scale"), V8FUNCTION(ctx2d_scale, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("resetTransform"), V8FUNCTION(ctx2d_resetTransform, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("setTransform"), V8FUNCTION(ctx2d_setTransform, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("transform"), V8FUNCTION(ctx2d_transform, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("translate"), V8FUNCTION(ctx2d_translate, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("shear"), V8FUNCTION(ctx2d_shear, engine));
-    ft->InstanceTemplate()->SetAccessor(v8::String::New("globalAlpha"), ctx2d_globalAlpha, ctx2d_globalAlpha_set, v8::External::Wrap(engine));
-    ft->InstanceTemplate()->SetAccessor(v8::String::New("globalCompositeOperation"), ctx2d_globalCompositeOperation, ctx2d_globalCompositeOperation_set, v8::External::Wrap(engine));
-    ft->InstanceTemplate()->SetAccessor(v8::String::New("fillRule"), ctx2d_fillRule, ctx2d_fillRule_set, v8::External::Wrap(engine));
-    ft->InstanceTemplate()->SetAccessor(v8::String::New("fillStyle"), ctx2d_fillStyle, ctx2d_fillStyle_set, v8::External::Wrap(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));
-    ft->InstanceTemplate()->SetAccessor(v8::String::New("lineWidth"), ctx2d_lineWidth, ctx2d_lineWidth_set, v8::External::Wrap(engine));
-    ft->InstanceTemplate()->SetAccessor(v8::String::New("miterLimit"), ctx2d_miterLimit, ctx2d_miterLimit_set, v8::External::Wrap(engine));
-    ft->InstanceTemplate()->SetAccessor(v8::String::New("shadowBlur"), ctx2d_shadowBlur, ctx2d_shadowBlur_set, v8::External::Wrap(engine));
-    ft->InstanceTemplate()->SetAccessor(v8::String::New("shadowColor"), ctx2d_shadowColor, ctx2d_shadowColor_set, v8::External::Wrap(engine));
-    ft->InstanceTemplate()->SetAccessor(v8::String::New("shadowOffsetX"), ctx2d_shadowOffsetX, ctx2d_shadowOffsetX_set, v8::External::Wrap(engine));
-    ft->InstanceTemplate()->SetAccessor(v8::String::New("shadowOffsetY"), ctx2d_shadowOffsetY, ctx2d_shadowOffsetY_set, v8::External::Wrap(engine));
-    ft->InstanceTemplate()->SetAccessor(v8::String::New("path"), ctx2d_path, ctx2d_path_set, v8::External::Wrap(engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("clearRect"), V8FUNCTION(ctx2d_clearRect, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("fillRect"), V8FUNCTION(ctx2d_fillRect, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("strokeRect"), V8FUNCTION(ctx2d_strokeRect, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("arc"), V8FUNCTION(ctx2d_arc, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("arcTo"), V8FUNCTION(ctx2d_arcTo, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("beginPath"), V8FUNCTION(ctx2d_beginPath, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("bezierCurveTo"), V8FUNCTION(ctx2d_bezierCurveTo, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("clip"), V8FUNCTION(ctx2d_clip, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("closePath"), V8FUNCTION(ctx2d_closePath, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("fill"), V8FUNCTION(ctx2d_fill, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("lineTo"), V8FUNCTION(ctx2d_lineTo, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("moveTo"), V8FUNCTION(ctx2d_moveTo, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("quadraticCurveTo"), V8FUNCTION(ctx2d_quadraticCurveTo, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("rect"), V8FUNCTION(ctx2d_rect, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("roundedRect"), V8FUNCTION(ctx2d_roundedRect, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("text"), V8FUNCTION(ctx2d_text, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("ellipse"), V8FUNCTION(ctx2d_ellipse, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("stroke"), V8FUNCTION(ctx2d_stroke, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("isPointInPath"), V8FUNCTION(ctx2d_isPointInPath, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("drawFocusRing"), V8FUNCTION(ctx2d_drawFocusRing, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("caretBlinkRate"), V8FUNCTION(ctx2d_caretBlinkRate, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("setCaretSelectionRect"), V8FUNCTION(ctx2d_setCaretSelectionRect, engine));
-    ft->InstanceTemplate()->SetAccessor(v8::String::New("font"), ctx2d_font, ctx2d_font_set, v8::External::Wrap(engine));
-    ft->InstanceTemplate()->SetAccessor(v8::String::New("textAlign"), ctx2d_textAlign, ctx2d_textAlign_set, v8::External::Wrap(engine));
-    ft->InstanceTemplate()->SetAccessor(v8::String::New("textBaseline"), ctx2d_textBaseline, ctx2d_textBaseline_set, v8::External::Wrap(engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("fillText"), V8FUNCTION(ctx2d_fillText, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("measureText"), V8FUNCTION(ctx2d_measureText, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("strokeText"), V8FUNCTION(ctx2d_strokeText, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("drawImage"), V8FUNCTION(ctx2d_drawImage, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("createImageData"), V8FUNCTION(ctx2d_createImageData, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("getImageData"), V8FUNCTION(ctx2d_getImageData, engine));
-    ft->PrototypeTemplate()->Set(v8::String::New("putImageData"), V8FUNCTION(ctx2d_putImageData, engine));
-
-    constructorContext = qPersistentNew(ft->GetFunction());
-
-    v8::Local<v8::FunctionTemplate> ftGradient = v8::FunctionTemplate::New();
-    ftGradient->InstanceTemplate()->SetHasExternalResource(true);
-    ftGradient->PrototypeTemplate()->Set(v8::String::New("addColorStop"), V8FUNCTION(ctx2d_gradient_addColorStop, engine));
-    constructorGradient = qPersistentNew(ftGradient->GetFunction());
-
-    v8::Local<v8::FunctionTemplate> ftPattern = v8::FunctionTemplate::New();
-    ftPattern->InstanceTemplate()->SetHasExternalResource(true);
-    constructorPattern = qPersistentNew(ftPattern->GetFunction());
-
-    v8::Local<v8::FunctionTemplate> ftPixelArray = v8::FunctionTemplate::New();
-    ftPixelArray->InstanceTemplate()->SetHasExternalResource(true);
-    ftPixelArray->InstanceTemplate()->SetAccessor(v8::String::New("length"), ctx2d_pixelArray_length, 0, v8::External::Wrap(engine));
-    ftPixelArray->InstanceTemplate()->SetIndexedPropertyHandler(ctx2d_pixelArray_indexed, ctx2d_pixelArray_indexed_set, 0, 0, 0, v8::External::Wrap(engine));
-    constructorPixelArray = qPersistentNew(ftPixelArray->GetFunction());
-
-    v8::Local<v8::FunctionTemplate> ftImageData = v8::FunctionTemplate::New();
-    ftImageData->InstanceTemplate()->SetAccessor(v8::String::New("width"), ctx2d_imageData_width, 0, v8::External::Wrap(engine));
-    ftImageData->InstanceTemplate()->SetAccessor(v8::String::New("height"), ctx2d_imageData_height, 0, v8::External::Wrap(engine));
-    ftImageData->InstanceTemplate()->SetAccessor(v8::String::New("data"), ctx2d_imageData_data, 0, v8::External::Wrap(engine));
-    ftImageData->PrototypeTemplate()->Set(v8::String::New("mirror"), V8FUNCTION(ctx2d_imageData_mirror, engine));
-    ftImageData->PrototypeTemplate()->Set(v8::String::New("filter"), V8FUNCTION(ctx2d_imageData_filter, engine));
-    ftImageData->InstanceTemplate()->SetInternalFieldCount(1);
-    constructorImageData = qPersistentNew(ftImageData->GetFunction());
-}
-
-QSGContext2DEngineData::~QSGContext2DEngineData()
-{
-    qPersistentDispose(constructorContext);
-    qPersistentDispose(constructorGradient);
-    qPersistentDispose(constructorPattern);
-    qPersistentDispose(constructorImageData);
-    qPersistentDispose(constructorPixelArray);
-}
-
-void QSGContext2D::popState()
-{
-    if (m_stateStack.isEmpty())
-        return;
-
-    QSGContext2D::State newState = m_stateStack.pop();
-
-    if (state.matrix != newState.matrix)
-        buffer()->updateMatrix(newState.matrix);
-
-    if (newState.globalAlpha != state.globalAlpha)
-        buffer()->setGlobalAlpha(newState.globalAlpha);
-
-    if (newState.globalCompositeOperation != state.globalCompositeOperation)
-        buffer()->setGlobalCompositeOperation(newState.globalCompositeOperation);
-
-    if (newState.fillStyle != state.fillStyle)
-        buffer()->setFillStyle(newState.fillStyle);
-
-    if (newState.strokeStyle != state.strokeStyle)
-        buffer()->setStrokeStyle(newState.strokeStyle);
-
-    if (newState.lineWidth != state.lineWidth)
-        buffer()->setLineWidth(newState.lineWidth);
-
-    if (newState.lineCap != state.lineCap)
-        buffer()->setLineCap(newState.lineCap);
-
-    if (newState.lineJoin != state.lineJoin)
-        buffer()->setLineJoin(newState.lineJoin);
-
-    if (newState.miterLimit != state.miterLimit)
-        buffer()->setMiterLimit(newState.miterLimit);
-
-    if (newState.clipPath != state.clipPath) {
-        buffer()->clip(newState.clipPath);
-    }
-
-    if (newState.shadowBlur != state.shadowBlur)
-        buffer()->setShadowBlur(newState.shadowBlur);
-
-    if (newState.shadowColor != state.shadowColor)
-        buffer()->setShadowColor(newState.shadowColor);
-
-    if (newState.shadowOffsetX != state.shadowOffsetX)
-        buffer()->setShadowOffsetX(newState.shadowOffsetX);
-
-    if (newState.shadowOffsetY != state.shadowOffsetY)
-        buffer()->setShadowOffsetY(newState.shadowOffsetY);
-    state = newState;
-}
-void QSGContext2D::pushState()
-{
-    m_stateStack.push(state);
-}
-
-void QSGContext2D::reset()
-{
-    QSGContext2D::State newState;
-    newState.matrix = QTransform();
-
-    QPainterPath defaultClipPath;
-
-    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 = 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;
-    newState.lineCap = Qt::FlatCap;
-    newState.lineJoin = Qt::MiterJoin;
-    newState.miterLimit = 10;
-    newState.shadowOffsetX = 0;
-    newState.shadowOffsetY = 0;
-    newState.shadowBlur = 0;
-    newState.shadowColor = qRgba(0, 0, 0, 0);
-    newState.globalCompositeOperation = QPainter::CompositionMode_SourceOver;
-    newState.font = QFont(QLatin1String("sans-serif"), 10);
-    newState.textAlign = QSGContext2D::Start;
-    newState.textBaseline = QSGContext2D::Alphabetic;
-
-    m_stateStack.clear();
-    m_stateStack.push(newState);
-    popState();
-    m_buffer->clearRect(0, 0, m_canvas->width(), m_canvas->height());
-}
-
-void QSGContext2D::setV8Engine(QV8Engine *engine)
-{
-    v8::HandleScope handle_scope;
-    v8::Context::Scope scope(engine->context());
-
-    if (m_v8engine != engine) {
-        m_v8engine = engine;
-
-        qPersistentDispose(m_v8value);
-
-        if (m_v8engine == 0)
-            return;
-
-        QSGContext2DEngineData *ed = engineData(engine);
-        m_v8value = qPersistentNew(ed->constructorContext->NewInstance());
-        QV8Context2DResource *r = new QV8Context2DResource(engine);
-        r->context = this;
-        m_v8value->SetExternalResource(r);
-    }
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/context2d/qsgcontext2d_p.h b/src/declarative/items/context2d/qsgcontext2d_p.h
deleted file mode 100644 (file)
index 10c1e33..0000000
+++ /dev/null
@@ -1,187 +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 QSGCONTEXT2D_P_H
-#define QSGCONTEXT2D_P_H
-
-#include <QtDeclarative/qdeclarative.h>
-#include <QtDeclarative/qdeclarativecomponent.h>
-
-#include <QtGui/qpainter.h>
-#include <QtGui/qpainterpath.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qstack.h>
-#include <private/qv8engine_p.h>
-
-
-
-#define QSGCONTEXT2D_DEBUG //enable this for just DEBUG purpose!
-
-#ifdef QSGCONTEXT2D_DEBUG
-#include <QElapsedTimer>
-#endif
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGCanvasItem;
-class QSGContext2DCommandBuffer;
-class QDeclarativePixmap;
-
-class Q_DECLARATIVE_EXPORT QSGContext2D
-{
-public:
-    enum TextBaseLineType { Alphabetic=0, Top, Middle, Bottom, Hanging};
-    enum TextAlignType { Start=0, End, Left, Right, Center};
-    enum PaintCommand {
-        Invalid = 0,
-        UpdateMatrix,
-        ClearRect,
-        FillRect,
-        StrokeRect,
-        Fill,
-        Stroke,
-        Clip,
-        UpdateBrush,
-        GlobalAlpha,
-        GlobalCompositeOperation,
-        StrokeStyle,
-        FillStyle,
-        LineWidth,
-        LineCap,
-        LineJoin,
-        MiterLimit,
-        ShadowOffsetX,
-        ShadowOffsetY,
-        ShadowBlur,
-        ShadowColor,
-        Font,
-        TextBaseline,
-        TextAlign,
-        FillText,
-        StrokeText,
-        DrawImage,
-        GetImageData
-    };
-
-
-    struct State {
-        QTransform matrix;
-        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;
-        Qt::PenCapStyle lineCap;
-        Qt::PenJoinStyle lineJoin;
-        qreal miterLimit;
-        qreal shadowOffsetX;
-        qreal shadowOffsetY;
-        qreal shadowBlur;
-        QColor shadowColor;
-        QPainter::CompositionMode globalCompositeOperation;
-        QFont font;
-        QSGContext2D::TextAlignType textAlign;
-        QSGContext2D::TextBaseLineType textBaseline;
-    };
-
-    QSGContext2D(QSGCanvasItem* item);
-    ~QSGContext2D();
-
-    inline QSGCanvasItem*  canvas() const {return m_canvas;}
-    inline QSGContext2DCommandBuffer* buffer() const {return m_buffer;}
-
-    v8::Handle<v8::Object> v8value() const;
-    void setV8Engine(QV8Engine *eng);
-    void popState();
-    void pushState();
-    void reset();
-
-    // path API
-    void beginPath();
-    void closePath();
-    void moveTo(qreal x, qreal y);
-    void lineTo(qreal x, qreal y);
-    void quadraticCurveTo(qreal cpx, qreal cpy, qreal x, qreal y);
-    void bezierCurveTo(qreal cp1x, qreal cp1y,
-                       qreal cp2x, qreal cp2y, qreal x, qreal y);
-    void arcTo(qreal x1, qreal y1, qreal x2, qreal y2, qreal radius);
-    void rect(qreal x, qreal y, qreal w, qreal h);
-    void roundedRect(qreal x, qreal y,qreal w, qreal h, qreal xr, qreal yr);
-    void ellipse(qreal x, qreal y,qreal w, qreal h);
-    void text(const QString& str, qreal x, qreal y);
-    void arc(qreal x, qreal y, qreal radius,
-             qreal startAngle, qreal endAngle,
-             bool anticlockwise, bool transform=true);
-    void addArcTo(const QPointF& p1, const QPointF& p2, float radius);
-
-    bool isPointInPath(qreal x, qreal y) const;
-
-    QPainterPath createTextGlyphs(qreal x, qreal y, const QString& text);
-    QImage createImage(const QUrl& url);
-
-    State state;
-    QStack<QSGContext2D::State> m_stateStack;
-    QSGCanvasItem* m_canvas;
-    QSGContext2DCommandBuffer* m_buffer;
-    QPainterPath m_path;
-    v8::Local<v8::Value> m_fillStyle;
-    v8::Local<v8::Value> m_strokeStyle;
-    v8::Handle<v8::Value> m_v8path;
-    QV8Engine *m_v8engine;
-    v8::Persistent<v8::Object> m_v8value;
-};
-
-
-QT_END_NAMESPACE
-QML_DECLARE_TYPE(QSGContext2D)
-
-QT_END_HEADER
-
-#endif // QSGCONTEXT2D_P_H
diff --git a/src/declarative/items/context2d/qsgcontext2dcommandbuffer.cpp b/src/declarative/items/context2d/qsgcontext2dcommandbuffer.cpp
deleted file mode 100644 (file)
index 29ed5fb..0000000
+++ /dev/null
@@ -1,470 +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$
-**
-****************************************************************************/
-
-#include "qsgcontext2dcommandbuffer_p.h"
-#include "qsgcanvasitem_p.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_Premultiplied);
-    shadowImg.fill(0);
-    QPainter tmpPainter(&shadowImg);
-    tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
-    qreal shadowX = offsetX > 0? offsetX : 0;
-    qreal shadowY = offsetY > 0? offsetY : 0;
-
-    tmpPainter.drawImage(shadowX, shadowY, image);
-    tmpPainter.end();
-
-    if (blur > 0)
-        qt_image_boxblur(shadowImg, blur/2, true);
-
-    // blacken the image with shadow color...
-    tmpPainter.begin(&shadowImg);
-    tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
-    tmpPainter.fillRect(shadowImg.rect(), color);
-    tmpPainter.end();
-    return shadowImg;
-}
-
-static void fillRectShadow(QPainter* p, QRectF shadowRect, qreal offsetX, qreal offsetY, qreal blur, const QColor& color)
-{
-    QRectF r = shadowRect;
-    r.moveTo(0, 0);
-
-    QImage shadowImage(r.size().width() + 1, r.size().height() + 1, QImage::Format_ARGB32_Premultiplied);
-    QPainter tp;
-    tp.begin(&shadowImage);
-    tp.fillRect(r, p->brush());
-    tp.end();
-    shadowImage = makeShadowImage(shadowImage, offsetX, offsetY, blur, color);
-
-    qreal dx = shadowRect.left() + (offsetX < 0? offsetX:0);
-    qreal dy = shadowRect.top() + (offsetY < 0? offsetY:0);
-
-    p->drawImage(dx, dy, shadowImage);
-    p->fillRect(shadowRect, p->brush());
-}
-
-static void fillShadowPath(QPainter* p, const QPainterPath& path, qreal offsetX, qreal offsetY, qreal blur, const QColor& color)
-{
-    QRectF r = path.boundingRect();
-    QImage img(r.size().width() + r.left() + 1,
-               r.size().height() + r.top() + 1,
-               QImage::Format_ARGB32_Premultiplied);
-    img.fill(0);
-    QPainter tp(&img);
-    tp.fillPath(path.translated(0, 0), p->brush());
-    tp.end();
-
-    QImage shadowImage = makeShadowImage(img, offsetX, offsetY, blur, color);
-    qreal dx = r.left() + (offsetX < 0? offsetX:0);
-    qreal dy = r.top() + (offsetY < 0? offsetY:0);
-
-    p->drawImage(dx, dy, shadowImage);
-    p->fillPath(path, p->brush());
-}
-
-static void strokeShadowPath(QPainter* p, const QPainterPath& path, qreal offsetX, qreal offsetY, qreal blur, const QColor& color)
-{
-    QRectF r = path.boundingRect();
-    QImage img(r.size().width() + r.left() + 1,
-               r.size().height() + r.top() + 1,
-               QImage::Format_ARGB32_Premultiplied);
-    img.fill(0);
-    QPainter tp(&img);
-    tp.strokePath(path, p->pen());
-    tp.end();
-
-    QImage shadowImage = makeShadowImage(img, offsetX, offsetY, blur, color);
-    qreal dx = r.left() + (offsetX < 0? offsetX:0);
-    qreal dy = r.top() + (offsetY < 0? offsetY:0);
-    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)
-{
-    QPen pen;
-    pen.setWidthF(state.lineWidth);
-    pen.setCapStyle(state.lineCap);
-    pen.setJoinStyle(state.lineJoin);
-    pen.setMiterLimit(state.miterLimit);
-    pen.setBrush(state.strokeStyle);
-    return pen;
-}
-
-void QSGContext2DCommandBuffer::setPainterState(QPainter* p, QSGContext2D::State state, const QPen& pen)
-{
-   p->setTransform(state.matrix * p->transform());
-
-   if (pen != p->pen())
-       p->setPen(pen);
-
-   if (state.fillStyle != p->brush())
-       p->setBrush(state.fillStyle);
-
-   if (state.font != p->font())
-       p->setFont(state.font);
-
-   if (state.globalAlpha != p->opacity()) {
-       p->setOpacity(state.globalAlpha);
-   }
-
-   if (state.globalCompositeOperation != p->compositionMode())
-       p->setCompositionMode(state.globalCompositeOperation);
-}
-
-QSGContext2D::State QSGContext2DCommandBuffer::replay(QPainter* p, QSGContext2D::State state)
-{
-    if (!p)
-        return state;
-
-    reset();
-
-    QTransform originMatrix = p->transform();
-
-    QPen pen = makePen(state);
-    setPainterState(p, state, pen);
-
-    while (hasNext()) {
-        QSGContext2D::PaintCommand cmd = takeNextCommand();
-        switch (cmd) {
-        case QSGContext2D::UpdateMatrix:
-        {
-            state.matrix = takeMatrix();
-            p->setTransform(state.matrix * originMatrix);
-            break;
-        }
-        case QSGContext2D::ClearRect:
-        {
-            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:
-        {
-            QRectF r = takeRect();
-            if (HAS_SHADOW(state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor))
-                fillRectShadow(p, r, state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor);
-            else
-                p->fillRect(r, p->brush());
-            break;
-        }
-        case QSGContext2D::ShadowColor:
-        {
-            state.shadowColor = takeColor();
-            break;
-        }
-        case QSGContext2D::ShadowBlur:
-        {
-            state.shadowBlur = takeShadowBlur();
-            break;
-        }
-        case QSGContext2D::ShadowOffsetX:
-        {
-            state.shadowOffsetX = takeShadowOffsetX();
-            break;
-        }
-        case QSGContext2D::ShadowOffsetY:
-        {
-            state.shadowOffsetY = takeShadowOffsetY();
-            break;
-        }
-        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;
-        }
-        case QSGContext2D::LineWidth:
-        {
-            state.lineWidth = takeLineWidth();
-            pen.setWidth(state.lineWidth);
-            p->setPen(pen);
-            break;
-        }
-        case QSGContext2D::LineCap:
-        {
-            state.lineCap = takeLineCap();
-            pen.setCapStyle(state.lineCap);
-            p->setPen(pen);
-            break;
-        }
-        case QSGContext2D::LineJoin:
-        {
-            state.lineJoin = takeLineJoin();
-            pen.setJoinStyle(state.lineJoin);
-            p->setPen(pen);
-            break;
-        }
-        case QSGContext2D::MiterLimit:
-        {
-            state.miterLimit = takeMiterLimit();
-            pen.setMiterLimit(state.miterLimit);
-            p->setPen(pen);
-            break;
-        }
-        case QSGContext2D::TextAlign:
-        case QSGContext2D::TextBaseline:
-            break;
-        case QSGContext2D::Fill:
-        {
-            QPainterPath path = takePath();
-            path.closeSubpath();
-            if (HAS_SHADOW(state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor))
-                fillShadowPath(p,path, state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor);
-            else
-                p->fillPath(path, p->brush());
-            break;
-        }
-        case QSGContext2D::Stroke:
-        {
-            if (HAS_SHADOW(state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor))
-                strokeShadowPath(p,takePath(), state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor);
-            else
-                p->strokePath(takePath(), p->pen());
-            break;
-        }
-        case QSGContext2D::Clip:
-        {
-            state.clipPath = takePath();
-            p->setClipping(true);
-            p->setClipPath(state.clipPath);
-            break;
-        }
-        case QSGContext2D::GlobalAlpha:
-        {
-            state.globalAlpha = takeGlobalAlpha();
-            p->setOpacity(state.globalAlpha);
-            break;
-        }
-        case QSGContext2D::GlobalCompositeOperation:
-        {
-            state.globalCompositeOperation = takeGlobalCompositeOperation();
-            p->setCompositionMode(state.globalCompositeOperation);
-            break;
-        }
-        case QSGContext2D::DrawImage:
-        {
-            qreal sx = takeReal();
-            qreal sy = takeReal();
-            qreal sw = takeReal();
-            qreal sh = takeReal();
-            qreal dx = takeReal();
-            qreal dy = takeReal();
-            qreal dw = takeReal();
-            qreal dh = takeReal();
-            QImage image = takeImage();
-
-            if (!image.isNull()) {
-                if (sw == -1 || sh == -1) {
-                    sw = image.width();
-                    sh = image.height();
-                }
-                if (sx != 0 || sy != 0 || sw != image.width() || sh != image.height())
-                    image = image.copy(sx, sy, sw, sh);
-
-                image = image.scaled(dw, dh);
-
-                if (HAS_SHADOW(state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor)) {
-                    QImage shadow = makeShadowImage(image, state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor);
-                    qreal shadow_dx = dx + (state.shadowOffsetX < 0? state.shadowOffsetY:0);
-                    qreal shadow_dy = dy + (state.shadowOffsetX < 0? state.shadowOffsetY:0);
-                    p->drawImage(shadow_dx, shadow_dy, shadow);
-                }
-                p->drawImage(dx, dy, image);
-            }
-            break;
-        }
-        case QSGContext2D::GetImageData:
-        {
-            //TODO:
-            break;
-        }
-        default:
-            break;
-        }
-    }
-
-    p->end();
-    return state;
-}
-
-QSGContext2DCommandBuffer::QSGContext2DCommandBuffer()
-    : cmdIdx(0)
-    , intIdx(0)
-    , boolIdx(0)
-    , realIdx(0)
-    , colorIdx(0)
-    , matrixIdx(0)
-    , brushIdx(0)
-    , pathIdx(0)
-    , imageIdx(0)
-{
-}
-
-
-QSGContext2DCommandBuffer::~QSGContext2DCommandBuffer()
-{
-}
-
-void QSGContext2DCommandBuffer::clear()
-{
-    commands.clear();
-    ints.clear();
-    bools.clear();
-    reals.clear();
-    colors.clear();
-    matrixes.clear();
-    brushes.clear();
-    pathes.clear();
-    images.clear();
-    reset();
-}
-
-void QSGContext2DCommandBuffer::reset()
-{
-    cmdIdx = 0;
-    intIdx = 0;
-    boolIdx = 0;
-    realIdx = 0;
-    colorIdx = 0;
-    matrixIdx = 0;
-    brushIdx = 0;
-    pathIdx = 0;
-    imageIdx = 0;
-}
-
-QT_END_NAMESPACE
-
diff --git a/src/declarative/items/context2d/qsgcontext2dcommandbuffer_p.h b/src/declarative/items/context2d/qsgcontext2dcommandbuffer_p.h
deleted file mode 100644 (file)
index cab82e2..0000000
+++ /dev/null
@@ -1,268 +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 QSGCONTEXT2DCOMMANDBUFFER_P_H
-#define QSGCONTEXT2DCOMMANDBUFFER_P_H
-
-#include "qsgcontext2d_p.h"
-#include <private/qdeclarativepixmapcache_p.h>
-
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGCanvasItem;
-class QMutex;
-
-class QSGContext2DCommandBuffer
-{
-public:
-    QSGContext2DCommandBuffer();
-    ~QSGContext2DCommandBuffer();
-    void reset();
-    void clear();
-    inline int size() {return commands.size();}
-    inline bool isEmpty() const {return commands.isEmpty(); }
-    inline bool hasNext() const {return cmdIdx < commands.size(); }
-    inline QSGContext2D::PaintCommand takeNextCommand() { return commands[cmdIdx++]; }
-
-    inline qreal takeGlobalAlpha() { return takeReal(); }
-    inline QPainter::CompositionMode takeGlobalCompositeOperation(){ return static_cast<QPainter::CompositionMode>(takeInt()); }
-    inline QBrush takeStrokeStyle() { return takeBrush(); }
-    inline QBrush takeFillStyle() { return takeBrush(); }
-
-    inline qreal takeLineWidth() { return takeReal(); }
-    inline Qt::PenCapStyle takeLineCap() { return static_cast<Qt::PenCapStyle>(takeInt());}
-    inline Qt::PenJoinStyle takeLineJoin(){ return static_cast<Qt::PenJoinStyle>(takeInt());}
-    inline qreal takeMiterLimit() { return takeReal(); }
-
-    inline void setGlobalAlpha( qreal alpha)
-    {
-        commands << QSGContext2D::GlobalAlpha;
-        reals << alpha;
-    }
-
-    inline void setGlobalCompositeOperation(QPainter::CompositionMode cm)
-    {
-        commands << QSGContext2D::GlobalCompositeOperation;
-        ints << cm;
-    }
-
-    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)
-    {
-        commands << QSGContext2D::DrawImage;
-        images << image;
-        reals << sx << sy << sw << sh << dx << dy << dw << dh;
-    }
-
-    inline qreal takeShadowOffsetX() { return takeReal(); }
-    inline qreal takeShadowOffsetY() { return takeReal(); }
-    inline qreal takeShadowBlur() { return takeReal(); }
-    inline QColor takeShadowColor() { return takeColor(); }
-
-
-    inline void updateMatrix(const QTransform& matrix)
-    {
-        commands << QSGContext2D::UpdateMatrix;
-        matrixes << matrix;
-    }
-
-    inline void clearRect(qreal x, qreal y, qreal w, qreal h)
-    {
-        commands << QSGContext2D::ClearRect;
-        reals << x << y << w << h;
-    }
-
-    inline void fillRect(qreal x, qreal y, qreal w, qreal h)
-    {
-        commands << QSGContext2D::FillRect;
-        reals << x << y << w << h;
-    }
-
-    inline void strokeRect(qreal x, qreal y, qreal w, qreal h)
-    {
-        QPainterPath p;
-        p.addRect(x, y, w, h);
-
-        commands << QSGContext2D::Stroke;
-        pathes << p;
-    }
-
-
-    inline void fill(const QPainterPath& path)
-    {
-        commands << QSGContext2D::Fill;
-        pathes << path;
-
-    }
-
-    inline void stroke(const QPainterPath& path)
-    {
-        commands << QSGContext2D::Stroke;
-        pathes << path;
-    }
-
-    inline void clip(const QPainterPath& path)
-    {
-        commands << QSGContext2D::Clip;
-        pathes << path;
-    }
-
-
-
-    inline void setFillStyle(const QBrush &style, bool repeatX = false, bool repeatY = false)
-    {
-        commands << QSGContext2D::FillStyle;
-        brushes << style;
-        bools << repeatX << repeatY;
-    }
-
-
-    inline void setLineWidth( qreal w)
-    {
-        commands << QSGContext2D::LineWidth;
-        reals << w;
-    }
-
-    inline void setLineCap(Qt::PenCapStyle  cap)
-    {
-        commands << QSGContext2D::LineCap;
-        ints << cap;
-    }
-
-    inline void setLineJoin(Qt::PenJoinStyle join)
-    {
-        commands << QSGContext2D::LineJoin;
-        ints << join;
-    }
-
-    inline void setMiterLimit( qreal limit)
-    {
-        commands << QSGContext2D::MiterLimit;
-        reals << limit;
-    }
-
-    inline void setShadowOffsetX( qreal x)
-    {
-        commands << QSGContext2D::ShadowOffsetX;
-        reals << x;
-    }
-
-    inline void setShadowOffsetY( qreal y)
-    {
-        commands << QSGContext2D::ShadowOffsetY;
-        reals << y;
-    }
-
-    inline void setShadowBlur( qreal b)
-    {
-        commands << QSGContext2D::ShadowBlur;
-        reals << b;
-    }
-
-    inline void setShadowColor(const QColor &color)
-    {
-        commands << QSGContext2D::ShadowColor;
-        colors << color;
-    }
-
-    inline QTransform takeMatrix() { return matrixes[matrixIdx++]; }
-
-    // rects
-    inline QRectF takeRect() {
-        qreal x, y, w, h;
-        x = takeReal();
-        y = takeReal();
-        w = takeReal();
-        h = takeReal();
-        return QRectF(x, y, w ,h);
-    }
-
-    inline QPainterPath takePath() { return pathes[pathIdx++]; }
-
-    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++]; }
-
-    QSGContext2D::State replay(QPainter* painter, QSGContext2D::State state);
-private:
-    QPen makePen(QSGContext2D::State state);
-    void setPainterState(QPainter* painter, QSGContext2D::State state, const QPen& pen);
-    int cmdIdx;
-    int intIdx;
-    int boolIdx;
-    int realIdx;
-    int colorIdx;
-    int matrixIdx;
-    int brushIdx;
-    int pathIdx;
-    int imageIdx;
-    QVector<QSGContext2D::PaintCommand> commands;
-
-    QVector<int> ints;
-    QVector<bool> bools;
-    QVector<qreal> reals;
-    QVector<QColor> colors;
-    QVector<QTransform> matrixes;
-    QVector<QBrush> brushes;
-    QVector<QPainterPath> pathes;
-    QVector<QImage> images;
-};
-
-QT_END_HEADER
-
-QT_END_NAMESPACE
-
-#endif // QSGCONTEXT2DCOMMANDBUFFER_P_H
diff --git a/src/declarative/items/context2d/qsgcontext2dnode.cpp b/src/declarative/items/context2d/qsgcontext2dnode.cpp
deleted file mode 100644 (file)
index 87de8cf..0000000
+++ /dev/null
@@ -1,124 +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$
-**
-****************************************************************************/
-
-#include "qsgcontext2dnode_p.h"
-
-#include <private/qsgcontext_p.h>
-#include <QtCore/qmath.h>
-
-QT_BEGIN_NAMESPACE
-
-
-QSGContext2DNode::QSGContext2DNode(QSGCanvasItem* item)
-    : QSGGeometryNode()
-    , m_item(item)
-    , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
-    , m_texture(0)
-    , m_size(1, 1)
-    , m_dirtyGeometry(false)
-    , m_dirtyTexture(false)
-{
-    setMaterial(&m_materialO);
-    setOpaqueMaterial(&m_material);
-    setGeometry(&m_geometry);
-    setFlag(UsePreprocess, true);
-}
-
-QSGContext2DNode::~QSGContext2DNode()
-{
-    delete m_texture;
-}
-
-void QSGContext2DNode::setSize(const QSizeF& size)
-{
-    if (m_size != size) {
-        m_dirtyGeometry = true;
-        m_size = size;
-    }
-}
-
-void QSGContext2DNode::preprocess()
-{
-    bool doDirty = false;
-    QSGDynamicTexture *t = qobject_cast<QSGDynamicTexture *>(m_material.texture());
-    if (t) {
-        doDirty = t->updateTexture();
-    }
-    if (doDirty) {
-        m_dirtyTexture = true;
-        markDirty(DirtyMaterial);
-    }
-}
-void QSGContext2DNode::setTexture(QSGContext2DTexture* texture)
-{
-    if (texture != m_texture) {
-        m_dirtyTexture = true;
-        m_texture = texture;
-    }
-}
-
-void QSGContext2DNode::update()
-{
-    if (m_dirtyGeometry)
-        updateGeometry();
-    if (m_dirtyTexture)
-        updateTexture();
-
-    m_dirtyGeometry = false;
-    m_dirtyTexture = false;
-}
-
-void QSGContext2DNode::updateTexture()
-{
-    m_material.setTexture(m_texture);
-    m_materialO.setTexture(m_texture);
-    markDirty(DirtyMaterial);
-}
-
-void QSGContext2DNode::updateGeometry()
-{
-    QRectF source = m_texture->textureSubRect();
-    QSGGeometry::updateTexturedRectGeometry(&m_geometry,
-                                            QRectF(0, 0, m_size.width(), m_size.height()),
-                                            source);
-    markDirty(DirtyGeometry);
-}
-QT_END_NAMESPACE
diff --git a/src/declarative/items/context2d/qsgcontext2dnode_p.h b/src/declarative/items/context2d/qsgcontext2dnode_p.h
deleted file mode 100644 (file)
index 88c3619..0000000
+++ /dev/null
@@ -1,86 +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 QSGCONTEXT2DNODE_P_H
-#define QSGCONTEXT2DNODE_P_H
-
-#include <qsgnode.h>
-#include <qsgtexturematerial.h>
-
-#include "qsgcanvasitem_p.h"
-#include "qsgcontext2dtexture_p.h"
-#include "qsgcontext2d_p.h"
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGContext2DNode : public QSGGeometryNode
-{
-public:
-    QSGContext2DNode(QSGCanvasItem* item);
-    virtual ~QSGContext2DNode();
-    void setTexture(QSGContext2DTexture* texture);
-    void update();
-    void preprocess();
-    void setSize(const QSizeF& size);
-private:
-    void updateTexture();
-    void updateGeometry();
-
-    QSGCanvasItem* m_item;
-    QSGOpaqueTextureMaterial m_material;
-    QSGTextureMaterial m_materialO;
-    QSGGeometry m_geometry;
-    QSGContext2DTexture* m_texture;
-    QSizeF m_size;
-
-    bool m_dirtyGeometry;
-    bool m_dirtyTexture;
-};
-
-QT_END_HEADER
-
-QT_END_NAMESPACE
-
-#endif // QSGCONTEXT2DNODE_P_H
diff --git a/src/declarative/items/context2d/qsgcontext2dtexture.cpp b/src/declarative/items/context2d/qsgcontext2dtexture.cpp
deleted file mode 100644 (file)
index 721f847..0000000
+++ /dev/null
@@ -1,777 +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 "qsgcontext2dtexture_p.h"
-#include "qsgcontext2dtile_p.h"
-#include "qsgcanvasitem_p.h"
-#include <private/qsgitem_p.h>
-#include <private/qsgtexture_p.h>
-#include "qsgcontext2dcommandbuffer_p.h"
-#include <QOpenGLPaintDevice>
-
-#include <QOpenGLFramebufferObject>
-#include <QOpenGLFramebufferObjectFormat>
-#include <QtCore/QThread>
-
-#define QT_MINIMUM_FBO_SIZE 64
-
-static inline int qt_next_power_of_two(int v)
-{
-    v--;
-    v |= v >> 1;
-    v |= v >> 2;
-    v |= v >> 4;
-    v |= v >> 8;
-    v |= v >> 16;
-    ++v;
-    return v;
-}
-
-
-Q_GLOBAL_STATIC(QThread, globalCanvasThreadRenderInstance)
-
-
-QSGContext2DTexture::QSGContext2DTexture()
-    : QSGDynamicTexture()
-    , m_context(0)
-    , m_canvasSize(QSize(1, 1))
-    , m_tileSize(QSize(1, 1))
-    , m_canvasWindow(QRect(0, 0, 1, 1))
-    , m_dirtyCanvas(false)
-    , m_dirtyTexture(false)
-    , m_threadRendering(false)
-    , m_smooth(false)
-    , m_tiledCanvas(false)
-    , m_doGrabImage(false)
-    , m_painting(false)
-{
-}
-
-QSGContext2DTexture::~QSGContext2DTexture()
-{
-   clearTiles();
-}
-
-QSize QSGContext2DTexture::textureSize() const
-{
-    return m_canvasWindow.size();
-}
-
-void QSGContext2DTexture::markDirtyTexture()
-{
-    lock();
-    m_dirtyTexture = true;
-    unlock();
-    emit textureChanged();
-}
-
-bool QSGContext2DTexture::setCanvasSize(const QSize &size)
-{
-    if (m_canvasSize != size) {
-        m_canvasSize = size;
-        m_dirtyCanvas = true;
-        return true;
-    }
-    return false;
-}
-
-bool QSGContext2DTexture::setTileSize(const QSize &size)
-{
-    if (m_tileSize != size) {
-        m_tileSize = size;
-        m_dirtyCanvas = true;
-        return true;
-    }
-    return false;
-}
-
-void QSGContext2DTexture::setSmooth(bool smooth)
-{
-    m_smooth = smooth;
-}
-
-void QSGContext2DTexture::setItem(QSGCanvasItem* item)
-{
-    if (!item) {
-        lock();
-        m_item = 0;
-        m_context = 0;
-        unlock();
-        wake();
-    } else if (m_item != item) {
-        lock();
-        m_item = item;
-        m_context = item->context();
-        m_state = m_context->state;
-        unlock();
-        connect(this, SIGNAL(textureChanged()), m_item, SIGNAL(painted()));
-    }
-}
-
-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;
-    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;
-}
-
-void QSGContext2DTexture::canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth)
-{
-    lock();
-
-    QSize ts = tileSize;
-    if (ts.width() > canvasSize.width())
-        ts.setWidth(canvasSize.width());
-
-    if (ts.height() > canvasSize.height())
-        ts.setHeight(canvasSize.height());
-
-    setCanvasSize(canvasSize);
-    setTileSize(ts);
-
-    if (canvasSize == canvasWindow.size()) {
-        m_tiledCanvas = false;
-        m_dirtyCanvas = false;
-    } else {
-        m_tiledCanvas = true;
-    }
-
-    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);
-        }
-    }
-
-    setSmooth(smooth);
-    unlock();
-}
-
-void QSGContext2DTexture::paintWithoutTiles()
-{
-    QSGContext2DCommandBuffer* ccb = m_context->buffer();
-
-    if (ccb->isEmpty() && m_threadRendering && !m_doGrabImage) {
-        lock();
-        if (m_item)
-            QMetaObject::invokeMethod(m_item, "_doPainting", Qt::QueuedConnection, Q_ARG(QRectF, QRectF(0, 0, m_canvasSize.width(), m_canvasSize.height())));
-        wait();
-        unlock();
-    }
-    if (ccb->isEmpty()) {
-        return;
-    }
-
-    QPaintDevice* device = beginPainting();
-    if (!device) {
-        endPainting();
-        return;
-    }
-
-    QPainter p;
-    p.begin(device);
-    if (m_smooth)
-        p.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing
-                               | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
-    else
-        p.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing
-                                 | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, false);
-    p.setCompositionMode(QPainter::CompositionMode_SourceOver);
-    m_state = ccb->replay(&p, m_state);
-
-    ccb->clear();
-    markDirtyTexture();
-    endPainting();
-}
-
-bool QSGContext2DTexture::canvasDestroyed()
-{
-    bool noCanvas = false;
-    lock();
-    noCanvas = m_item == 0;
-    unlock();
-    return noCanvas;
-}
-
-void QSGContext2DTexture::paint()
-{
-    if (canvasDestroyed())
-        return;
-
-    if (!m_tiledCanvas) {
-        paintWithoutTiles();
-    } else {
-        QSGContext2D::State oldState = m_state;
-        QSGContext2DCommandBuffer* ccb = m_context->buffer();
-
-        lock();
-        QRect tiledRegion = createTiles(m_canvasWindow.intersected(QRect(QPoint(0, 0), m_canvasSize)));
-        unlock();
-
-        if (!tiledRegion.isEmpty()) {
-            if (m_threadRendering && !m_doGrabImage) {
-                QRect dirtyRect;
-
-                lock();
-                foreach (QSGContext2DTile* tile, m_tiles) {
-                    if (tile->dirty()) {
-                        if (dirtyRect.isEmpty())
-                            dirtyRect = tile->rect();
-                        else
-                            dirtyRect |= tile->rect();
-                    }
-                }
-                unlock();
-
-                if (dirtyRect.isValid()) {
-                    lock();
-                    if (m_item)
-                        QMetaObject::invokeMethod(m_item, "_doPainting", Qt::QueuedConnection, Q_ARG(QRectF, dirtyRect));
-                    wait();
-                    unlock();
-                }
-            }
-
-            if (beginPainting()) {
-                foreach (QSGContext2DTile* tile, m_tiles) {
-                    bool dirtyTile = false, dirtyCanvas = false, smooth = false;
-
-                    lock();
-                    dirtyTile = tile->dirty();
-                    smooth = m_smooth;
-                    dirtyCanvas  = m_dirtyCanvas;
-                    unlock();
-
-                    //canvas size or tile size may change during painting tiles
-                    if (dirtyCanvas) {
-                        if (m_threadRendering)
-                            QMetaObject::invokeMethod(this, "paint", Qt::QueuedConnection);
-                        endPainting();
-                        return;
-                    } else if (dirtyTile) {
-                        m_state = ccb->replay(tile->createPainter(smooth), oldState);
-                        tile->drawFinished();
-                        lock();
-                        tile->markDirty(false);
-                        unlock();
-                    }
-
-                    compositeTile(tile);
-                }
-                ccb->clear();
-                endPainting();
-                markDirtyTexture();
-            }
-        }
-    }
-}
-
-QRect QSGContext2DTexture::tiledRect(const QRectF& window, const QSize& tileSize)
-{
-    if (window.isEmpty())
-        return QRect();
-
-    const int tw = tileSize.width();
-    const int th = tileSize.height();
-    const int h1 = window.left() / tw;
-    const int v1 = window.top() / th;
-
-    const int htiles = ((window.right() - h1 * tw) + tw - 1)/tw;
-    const int vtiles = ((window.bottom() - v1 * th) + th - 1)/th;
-
-    return QRect(h1 * tw, v1 * th, htiles * tw, vtiles * th);
-}
-
-QRect QSGContext2DTexture::createTiles(const QRect& window)
-{
-    QList<QSGContext2DTile*> oldTiles = m_tiles;
-    m_tiles.clear();
-
-    if (window.isEmpty()) {
-        m_dirtyCanvas = false;
-        return QRect();
-    }
-
-    QRect r = tiledRect(window, m_tileSize);
-
-    const int tw = m_tileSize.width();
-    const int th = m_tileSize.height();
-    const int h1 = window.left() / tw;
-    const int v1 = window.top() / th;
-
-
-    const int htiles = r.width() / tw;
-    const int vtiles = r.height() / th;
-
-    for (int yy = 0; yy < vtiles; ++yy) {
-        for (int xx = 0; xx < htiles; ++xx) {
-            int ht = xx + h1;
-            int vt = yy + v1;
-
-            QSGContext2DTile* tile = 0;
-
-            QPoint pos(ht * tw, vt * th);
-            QRect rect(pos, m_tileSize);
-
-            for (int i = 0; i < oldTiles.size(); i++) {
-                if (oldTiles[i]->rect() == rect) {
-                    tile = oldTiles.takeAt(i);
-                    break;
-                }
-            }
-
-            if (!tile)
-                tile = createTile();
-
-            tile->setRect(rect);
-            m_tiles.append(tile);
-        }
-    }
-
-    qDeleteAll(oldTiles);
-
-    m_dirtyCanvas = false;
-    return r;
-}
-
-void QSGContext2DTexture::clearTiles()
-{
-    qDeleteAll(m_tiles);
-    m_tiles.clear();
-}
-
-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()))
-                  , qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.height())));
-
-    if (m_canvasSize != s) {
-        m_canvasSize = s;
-        m_dirtyCanvas = true;
-        return true;
-    }
-    return false;
-}
-
-bool QSGContext2DFBOTexture::setTileSize(const QSize &size)
-{
-    QSize s = QSize(qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.width()))
-                  , qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.height())));
-    if (m_tileSize != s) {
-        m_tileSize = s;
-        m_dirtyCanvas = true;
-        return true;
-    }
-    return false;
-}
-
-bool QSGContext2DFBOTexture::setCanvasWindow(const QRect& canvasWindow)
-{
-    QSize s = QSize(qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(canvasWindow.size().width()))
-                  , qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(canvasWindow.size().height())));
-
-
-    bool doChanged = false;
-    if (m_fboSize != s) {
-        m_fboSize = s;
-        doChanged = true;
-    }
-
-    if (m_canvasWindow != canvasWindow)
-        m_canvasWindow = canvasWindow;
-
-    return doChanged;
-}
-
-void QSGContext2DFBOTexture::bind()
-{
-    glBindTexture(GL_TEXTURE_2D, textureId());
-    updateBindOptions();
-}
-
-QRectF QSGContext2DFBOTexture::textureSubRect() const
-{
-    return QRectF(0
-                , 0
-                , qreal(m_canvasWindow.width()) / m_fboSize.width()
-                , qreal(m_canvasWindow.height()) / m_fboSize.height());
-}
-
-
-int QSGContext2DFBOTexture::textureId() const
-{
-    return m_fbo? m_fbo->texture() : 0;
-}
-
-
-bool QSGContext2DFBOTexture::updateTexture()
-{
-    if (!m_context->buffer()->isEmpty()) {
-        paint();
-    }
-
-    bool textureUpdated = m_dirtyTexture;
-
-    m_dirtyTexture = false;
-
-    if (m_doGrabImage) {
-        grabImage();
-        m_condition.wakeOne();
-        m_doGrabImage = false;
-    }
-    return textureUpdated;
-}
-
-QSGContext2DTile* QSGContext2DFBOTexture::createTile() const
-{
-    return new QSGContext2DFBOTile();
-}
-
-void QSGContext2DFBOTexture::grabImage()
-{
-    if (m_fbo) {
-        m_grabedImage = m_fbo->toImage();
-    }
-}
-
-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
-
-    m_doGrabImage = true;
-    if (m_item)
-        m_item->update();
-
-    QImage grabbed;
-    m_mutex.lock();
-    bool ok = m_condition.wait(&m_mutex, QML_CONTEXT2D_WAIT_MAX);
-
-    if (!ok)
-        grabbed = QImage();
-
-    if (region.isValid())
-        grabbed = m_grabedImage.copy(region.toRect());
-    else
-        grabbed = m_grabedImage;
-    m_grabedImage = QImage();
-    return grabbed;
-}
-
-void QSGContext2DFBOTexture::compositeTile(QSGContext2DTile* tile)
-{
-    QSGContext2DFBOTile* t = static_cast<QSGContext2DFBOTile*>(tile);
-    QRect target = t->rect().intersect(m_canvasWindow);
-    if (target.isValid()) {
-        QRect source = target;
-
-        source.moveTo(source.topLeft() - t->rect().topLeft());
-        target.moveTo(target.topLeft() - m_canvasWindow.topLeft());
-
-        QOpenGLFramebufferObject::blitFramebuffer(m_fbo, target, t->fbo(), source);
-    }
-}
-QSGCanvasItem::RenderTarget QSGContext2DFBOTexture::renderTarget() const
-{
-    return QSGCanvasItem::FramebufferObject;
-}
-QPaintDevice* QSGContext2DFBOTexture::beginPainting()
-{
-    QSGContext2DTexture::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) {
-        delete m_fbo;
-        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);
-        }
-    }
-
-    if (doMultisampling())
-        m_multisampledFbo->bind();
-    else
-        m_fbo->bind();
-
-
-    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();
-
-    if (thread->isRunning()) {
-        thread->exit(0);
-        thread->wait(1000);
-    }
-}
-
-QSGContext2DImageTexture::QSGContext2DImageTexture(bool threadRendering)
-    : QSGContext2DTexture()
-    , m_texture(new QSGPlainTexture())
-{
-    m_texture->setOwnsTexture(true);
-    m_texture->setHasMipmaps(false);
-
-    m_threadRendering = threadRendering;
-
-    if (m_threadRendering) {
-        QThread* thread = globalCanvasThreadRenderInstance();
-        moveToThread(thread);
-
-        if (!thread->isRunning()) {
-            qAddPostRoutine(qt_quit_context2d_render_thread);
-            thread->start();
-        }
-    }
-}
-
-QSGContext2DImageTexture::~QSGContext2DImageTexture()
-{
-    delete m_texture;
-}
-
-int QSGContext2DImageTexture::textureId() const
-{
-    return m_texture->textureId();
-}
-
-void QSGContext2DImageTexture::lock()
-{
-    if (m_threadRendering)
-        m_mutex.lock();
-}
-void QSGContext2DImageTexture::unlock()
-{
-    if (m_threadRendering)
-        m_mutex.unlock();
-}
-
-void QSGContext2DImageTexture::wait()
-{
-    if (m_threadRendering)
-        m_waitCondition.wait(&m_mutex);
-}
-
-void QSGContext2DImageTexture::wake()
-{
-    if (m_threadRendering)
-        m_waitCondition.wakeOne();
-}
-
-bool QSGContext2DImageTexture::supportDirectRendering() const
-{
-    return !m_threadRendering;
-}
-
-QSGCanvasItem::RenderTarget QSGContext2DImageTexture::renderTarget() const
-{
-    return QSGCanvasItem::Image;
-}
-
-void QSGContext2DImageTexture::bind()
-{
-    m_texture->bind();
-}
-
-bool QSGContext2DImageTexture::updateTexture()
-{
-    lock();
-    bool textureUpdated = m_dirtyTexture;
-    if (m_dirtyTexture) {
-        m_texture->setImage(m_image);
-        m_dirtyTexture = false;
-    }
-    unlock();
-    return textureUpdated;
-}
-
-QSGContext2DTile* QSGContext2DImageTexture::createTile() const
-{
-    return new QSGContext2DImageTile();
-}
-
-void QSGContext2DImageTexture::grabImage(const QRect& r)
-{
-    m_doGrabImage = true;
-    paint();
-    m_doGrabImage = false;
-    m_grabedImage = m_image.copy(r);
-}
-
-QImage QSGContext2DImageTexture::toImage(const QRectF& region)
-{
-    QRect r = region.isValid() ? region.toRect() : QRect(QPoint(0, 0), m_canvasWindow.size());
-    if (threadRendering()) {
-        wake();
-        QMetaObject::invokeMethod(this, "grabImage", Qt::BlockingQueuedConnection, Q_ARG(QRect, r));
-    } else {
-        QMetaObject::invokeMethod(this, "grabImage", Qt::DirectConnection, Q_ARG(QRect, r));
-    }
-    QImage image = m_grabedImage;
-    m_grabedImage = QImage();
-    return image;
-}
-
-QPaintDevice* QSGContext2DImageTexture::beginPainting()
-{
-     QSGContext2DTexture::beginPainting();
-
-    if (m_canvasWindow.size().isEmpty())
-        return 0;
-
-    lock();
-    if (m_image.size() != m_canvasWindow.size()) {
-        m_image = QImage(m_canvasWindow.size(), QImage::Format_ARGB32_Premultiplied);
-        m_image.fill(0x00000000);
-    }
-    unlock();
-    return &m_image;
-}
-
-void QSGContext2DImageTexture::compositeTile(QSGContext2DTile* tile)
-{
-    Q_ASSERT(!tile->dirty());
-    QSGContext2DImageTile* t = static_cast<QSGContext2DImageTile*>(tile);
-    QRect target = t->rect().intersect(m_canvasWindow);
-    if (target.isValid()) {
-        QRect source = target;
-        source.moveTo(source.topLeft() - t->rect().topLeft());
-        target.moveTo(target.topLeft() - m_canvasWindow.topLeft());
-
-        lock();
-        m_painter.begin(&m_image);
-        m_painter.setCompositionMode(QPainter::CompositionMode_Source);
-        m_painter.drawImage(target, t->image(), source);
-        m_painter.end();
-        unlock();
-    }
-}
diff --git a/src/declarative/items/context2d/qsgcontext2dtexture_p.h b/src/declarative/items/context2d/qsgcontext2dtexture_p.h
deleted file mode 100644 (file)
index dbc383d..0000000
+++ /dev/null
@@ -1,205 +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 QSGCONTEXT2DTEXTURE_P_H
-#define QSGCONTEXT2DTEXTURE_P_H
-
-#include <qsgtexture.h>
-#include "qsgcanvasitem_p.h"
-#include "qsgcontext2d_p.h"
-
-#include <QOpenGLContext>
-#include <QOpenGLFramebufferObject>
-
-#include <QtCore/QMutex>
-#include <QtCore/QWaitCondition>
-#include <QtCore/QThread>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGContext2DTile;
-class QSGContext2DCommandBuffer;
-
-class QSGContext2DTexture : public QSGDynamicTexture
-{
-    Q_OBJECT
-public:
-    QSGContext2DTexture();
-    ~QSGContext2DTexture();
-
-    virtual bool hasAlphaChannel() const {return true;}
-    virtual bool hasMipmaps() const {return false;}
-    virtual QSize textureSize() const;
-    virtual void lock() {}
-    virtual void unlock() {}
-    virtual void wait() {}
-    virtual void wake() {}
-    bool threadRendering() const {return m_threadRendering;}
-    virtual bool supportThreadRendering() const = 0;
-    virtual bool supportDirectRendering() const = 0;
-    virtual QSGCanvasItem::RenderTarget renderTarget() const = 0;
-    virtual QImage toImage(const QRectF& region = QRectF()) = 0;
-    static QRect tiledRect(const QRectF& window, const QSize& tileSize);
-
-    virtual bool setCanvasSize(const QSize &size);
-    virtual bool setTileSize(const QSize &size);
-    virtual bool setCanvasWindow(const QRect& canvasWindow);
-    void setSmooth(bool smooth);
-    bool setDirtyRect(const QRect &dirtyRect);
-    virtual void canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth);
-    bool canvasDestroyed();
-Q_SIGNALS:
-    void textureChanged();
-
-public Q_SLOTS:
-    void markDirtyTexture();
-    void setItem(QSGCanvasItem* item);
-    void paint();
-
-protected:
-    void paintWithoutTiles();
-    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;
-
-    void clearTiles();
-    QRect createTiles(const QRect& window);
-
-    QList<QSGContext2DTile*> m_tiles;
-    QSGContext2D* m_context;
-
-    QSGContext2D::State m_state;
-
-    QSGCanvasItem* m_item;
-    QSize m_canvasSize;
-    QSize m_tileSize;
-    QRect m_canvasWindow;
-
-    uint m_dirtyCanvas : 1;
-    uint m_dirtyTexture : 1;
-    uint m_threadRendering : 1;
-    uint m_smooth : 1;
-    uint m_tiledCanvas : 1;
-    uint m_doGrabImage : 1;
-    uint m_painting : 1;
-};
-
-class QSGContext2DFBOTexture : public QSGContext2DTexture
-{
-    Q_OBJECT
-
-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;}
-    virtual QSGCanvasItem::RenderTarget renderTarget() const;
-    virtual void compositeTile(QSGContext2DTile* tile);
-    virtual void bind();
-    virtual bool setCanvasSize(const QSize &size);
-    virtual bool setTileSize(const QSize &size);
-    virtual bool setCanvasWindow(const QRect& canvasWindow);
-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;
-    QPaintDevice *m_paint_device;
-};
-
-class QSGPlainTexture;
-class QSGContext2DImageTexture : public QSGContext2DTexture
-{
-    Q_OBJECT
-
-public:
-    QSGContext2DImageTexture(bool threadRendering = true);
-    ~QSGContext2DImageTexture();
-    virtual int textureId() const;
-    virtual void bind();
-    virtual bool supportThreadRendering() const {return true;}
-    virtual bool supportDirectRendering() const;
-    virtual QSGCanvasItem::RenderTarget renderTarget() const;
-    virtual void lock();
-    virtual void unlock();
-    virtual void wait();
-    virtual void wake();
-
-    virtual bool updateTexture();
-    virtual QSGContext2DTile* createTile() const;
-    virtual QImage toImage(const QRectF& region = QRectF());
-    virtual QPaintDevice* beginPainting();
-    virtual void compositeTile(QSGContext2DTile* tile);
-
-private Q_SLOTS:
-    void grabImage(const QRect& r);
-private:
-    QImage m_image;
-    QImage m_grabedImage;
-    QMutex m_mutex;
-    QWaitCondition m_waitCondition;
-    QPainter m_painter;
-    QSGPlainTexture*  m_texture;
-};
-
-QT_END_HEADER
-
-QT_END_NAMESPACE
-
-#endif // QSGCONTEXT2DTEXTURE_P_H
diff --git a/src/declarative/items/context2d/qsgcontext2dtile.cpp b/src/declarative/items/context2d/qsgcontext2dtile.cpp
deleted file mode 100644 (file)
index 8c8ef83..0000000
+++ /dev/null
@@ -1,165 +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$
-**
-****************************************************************************/
-
-#include "qsgcontext2dtile_p.h"
-
-#include <QOpenGLFramebufferObject>
-#include <QOpenGLFramebufferObjectFormat>
-#include <QOpenGLPaintDevice>
-
-QSGContext2DTile::QSGContext2DTile()
-    : m_dirty(true)
-    , m_rect(QRect(0, 0, 1, 1))
-    , m_device(0)
-{
-}
-
-QSGContext2DTile::~QSGContext2DTile()
-{
-    if (m_painter.isActive())
-        m_painter.end();
-}
-
-QPainter* QSGContext2DTile::createPainter(bool smooth)
-{
-    if (m_painter.isActive())
-        m_painter.end();
-
-    if (m_device) {
-        aboutToDraw();
-        m_painter.begin(m_device);
-        m_painter.resetTransform();
-        m_painter.setCompositionMode(QPainter::CompositionMode_Source);
-
-#ifdef QSGCONTEXT2D_DEBUG
-        int v = 100;
-        int gray = (m_rect.x() / m_rect.width() + m_rect.y() / m_rect.height()) % 2;
-        if (gray)
-            v = 150;
-        m_painter.fillRect(QRect(0, 0, m_rect.width(), m_rect.height()), QColor(v, v, v, 255));
-#endif
-        if (smooth)
-            m_painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing
-                                   | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
-        else
-            m_painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing
-                                     | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, false);
-
-        m_painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
-        m_painter.translate(-m_rect.left(), -m_rect.top());
-        m_painter.setClipRect(m_rect);
-        m_painter.setClipping(false);
-        return &m_painter;
-    }
-
-    return 0;
-}
-
-QSGContext2DFBOTile::QSGContext2DFBOTile()
-    : QSGContext2DTile()
-    , m_fbo(0)
-{
-}
-
-
-QSGContext2DFBOTile::~QSGContext2DFBOTile()
-{
-    delete m_fbo;
-}
-
-void QSGContext2DFBOTile::aboutToDraw()
-{
-    m_fbo->bind();
-    if (!m_device) {
-        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)
-{
-    if (m_rect == r)
-        return;
-    m_rect = r;
-    m_dirty = true;
-    if (!m_fbo || m_fbo->size() != r.size()) {
-        QOpenGLFramebufferObjectFormat format;
-        format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
-        format.setInternalTextureFormat(GL_RGBA);
-        format.setMipmap(false);
-
-        if (m_painter.isActive())
-            m_painter.end();
-
-        delete m_fbo;
-        m_fbo = new QOpenGLFramebufferObject(r.size(), format);
-    }
-}
-
-
-QSGContext2DImageTile::QSGContext2DImageTile()
-    : QSGContext2DTile()
-{
-}
-
-QSGContext2DImageTile::~QSGContext2DImageTile()
-{
-}
-
-void QSGContext2DImageTile::setRect(const QRect& r)
-{
-    if (m_rect == r)
-        return;
-    m_rect = r;
-    m_dirty = true;
-    if (m_image.size() != r.size()) {
-        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
deleted file mode 100644 (file)
index 57b68ef..0000000
+++ /dev/null
@@ -1,112 +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 QSGCONTEXT2DTILE_P_H
-#define QSGCONTEXT2DTILE_P_H
-
-#include "qsgcontext2d_p.h"
-#include <QOpenGLFramebufferObject>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGContext2DTexture;
-class QSGContext2DCommandBuffer;
-
-class QSGContext2DTile
-{
-public:
-    QSGContext2DTile();
-    ~QSGContext2DTile();
-
-    bool dirty() const {return m_dirty;}
-    void markDirty(bool dirty) {m_dirty = dirty;}
-
-    QRect rect() const {return m_rect;}
-
-    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;
-    QPainter m_painter;
-};
-
-
-class QSGContext2DFBOTile : public QSGContext2DTile
-{
-public:
-    QSGContext2DFBOTile();
-    ~QSGContext2DFBOTile();
-    virtual void setRect(const QRect& r);
-    QOpenGLFramebufferObject* fbo() const {return m_fbo;}
-    void drawFinished();
-
-protected:
-    void aboutToDraw();
-private:
-
-
-    QOpenGLFramebufferObject *m_fbo;
-};
-
-class QSGContext2DImageTile : public QSGContext2DTile
-{
-public:
-    QSGContext2DImageTile();
-    ~QSGContext2DImageTile();
-    void setRect(const QRect& r);
-    const QImage& image() const {return m_image;}
-private:
-    QImage m_image;
-};
-QT_END_HEADER
-
-QT_END_NAMESPACE
-
-#endif // QSGCONTEXT2DTILE_P_H
index 025f67a..c3d6a2a 100644 (file)
 HEADERS += \
-    $$PWD/qsgevents_p_p.h \
-    $$PWD/qsgitemchangelistener_p.h \
-    $$PWD/qsganchors_p.h \
-    $$PWD/qsganchors_p_p.h \
-    $$PWD/qsgitem.h \
-    $$PWD/qsgitem_p.h \
-    $$PWD/qsgrectangle_p.h \
-    $$PWD/qsgrectangle_p_p.h \
-    $$PWD/qsgcanvas.h \
-    $$PWD/qsgcanvas_p.h \
-    $$PWD/qsgfocusscope_p.h \
-    $$PWD/qsgitemsmodule_p.h \
-    $$PWD/qsgpainteditem.h \
-    $$PWD/qsgpainteditem_p.h \
-    $$PWD/qsgtext_p.h \
-    $$PWD/qsgtext_p_p.h \
-    $$PWD/qsgtextnode_p.h \
-    $$PWD/qsgtextinput_p.h \
-    $$PWD/qsgtextinput_p_p.h \
-    $$PWD/qsgtextedit_p.h \
-    $$PWD/qsgtextedit_p_p.h \
-    $$PWD/qsgimagebase_p.h \
-    $$PWD/qsgimagebase_p_p.h \
-    $$PWD/qsgimage_p.h \
-    $$PWD/qsgimage_p_p.h \
-    $$PWD/qsgborderimage_p.h \
-    $$PWD/qsgborderimage_p_p.h \
-    $$PWD/qsgninepatchnode_p.h \
-    $$PWD/qsgscalegrid_p_p.h \
-    $$PWD/qsgmousearea_p.h \
-    $$PWD/qsgmousearea_p_p.h \
-    $$PWD/qsgpincharea_p.h \
-    $$PWD/qsgpincharea_p_p.h \
-    $$PWD/qsgflickable_p.h \
-    $$PWD/qsgflickable_p_p.h \
-    $$PWD/qsglistview_p.h \
-    $$PWD/qsgvisualadaptormodel_p.h \
-    $$PWD/qsgvisualdatamodel_p.h \
-    $$PWD/qsgvisualitemmodel_p.h \
-    $$PWD/qsgrepeater_p.h \
-    $$PWD/qsgrepeater_p_p.h \
-    $$PWD/qsggridview_p.h \
-    $$PWD/qsgpathview_p.h \
-    $$PWD/qsgpathview_p_p.h \
-    $$PWD/qsgpositioners_p.h \
-    $$PWD/qsgpositioners_p_p.h \
-    $$PWD/qsgloader_p.h \
-    $$PWD/qsgloader_p_p.h \
-    $$PWD/qsganimatedimage_p.h \
-    $$PWD/qsganimatedimage_p_p.h \
-    $$PWD/qsgflipable_p.h \
-    $$PWD/qsgtranslate_p.h \
-    $$PWD/qsgclipnode_p.h \
-    $$PWD/qsgview.h \
-    $$PWD/qsgview_p.h \
-    $$PWD/qsganimation_p.h \
-    $$PWD/qsganimation_p_p.h \
-    $$PWD/qsgstateoperations_p.h \
-    $$PWD/qsgimplicitsizeitem_p.h \
-    $$PWD/qsgimplicitsizeitem_p_p.h \
-    $$PWD/qsgspriteengine_p.h \
-    $$PWD/qsgsprite_p.h \
-    $$PWD/qsgspriteimage_p.h \
-    $$PWD/qsgdrag_p.h \
-    $$PWD/qsgdroparea_p.h \
-    $$PWD/qsgitemview_p.h \
-    $$PWD/qsgitemview_p_p.h
+    $$PWD/qquickevents_p_p.h \
+    $$PWD/qquickitemchangelistener_p.h \
+    $$PWD/qquickanchors_p.h \
+    $$PWD/qquickanchors_p_p.h \
+    $$PWD/qquickitem.h \
+    $$PWD/qquickitem_p.h \
+    $$PWD/qquickrectangle_p.h \
+    $$PWD/qquickrectangle_p_p.h \
+    $$PWD/qquickcanvas.h \
+    $$PWD/qquickcanvas_p.h \
+    $$PWD/qquickfocusscope_p.h \
+    $$PWD/qquickitemsmodule_p.h \
+    $$PWD/qquickpainteditem.h \
+    $$PWD/qquickpainteditem_p.h \
+    $$PWD/qquicktext_p.h \
+    $$PWD/qquicktext_p_p.h \
+    $$PWD/qquicktextnode_p.h \
+    $$PWD/qquicktextinput_p.h \
+    $$PWD/qquicktextinput_p_p.h \
+    $$PWD/qquicktextedit_p.h \
+    $$PWD/qquicktextedit_p_p.h \
+    $$PWD/qquickimagebase_p.h \
+    $$PWD/qquickimagebase_p_p.h \
+    $$PWD/qquickimage_p.h \
+    $$PWD/qquickimage_p_p.h \
+    $$PWD/qquickborderimage_p.h \
+    $$PWD/qquickborderimage_p_p.h \
+    $$PWD/qquickninepatchnode_p.h \
+    $$PWD/qquickscalegrid_p_p.h \
+    $$PWD/qquickmousearea_p.h \
+    $$PWD/qquickmousearea_p_p.h \
+    $$PWD/qquickpincharea_p.h \
+    $$PWD/qquickpincharea_p_p.h \
+    $$PWD/qquickflickable_p.h \
+    $$PWD/qquickflickable_p_p.h \
+    $$PWD/qquicklistview_p.h \
+    $$PWD/qquickvisualadaptormodel_p.h \
+    $$PWD/qquickvisualdatamodel_p.h \
+    $$PWD/qquickvisualitemmodel_p.h \
+    $$PWD/qquickrepeater_p.h \
+    $$PWD/qquickrepeater_p_p.h \
+    $$PWD/qquickgridview_p.h \
+    $$PWD/qquickpathview_p.h \
+    $$PWD/qquickpathview_p_p.h \
+    $$PWD/qquickpositioners_p.h \
+    $$PWD/qquickpositioners_p_p.h \
+    $$PWD/qquickloader_p.h \
+    $$PWD/qquickloader_p_p.h \
+    $$PWD/qquickanimatedimage_p.h \
+    $$PWD/qquickanimatedimage_p_p.h \
+    $$PWD/qquickflipable_p.h \
+    $$PWD/qquicktranslate_p.h \
+    $$PWD/qquickclipnode_p.h \
+    $$PWD/qquickview.h \
+    $$PWD/qquickview_p.h \
+    $$PWD/qquickanimation_p.h \
+    $$PWD/qquickanimation_p_p.h \
+    $$PWD/qquickstateoperations_p.h \
+    $$PWD/qquickimplicitsizeitem_p.h \
+    $$PWD/qquickimplicitsizeitem_p_p.h \
+    $$PWD/qquickspriteengine_p.h \
+    $$PWD/qquicksprite_p.h \
+    $$PWD/qquickspriteimage_p.h \
+    $$PWD/qquickdrag_p.h \
+    $$PWD/qquickdroparea_p.h \
+    $$PWD/qquickitemview_p.h \
+    $$PWD/qquickitemview_p_p.h
 
 SOURCES += \
-    $$PWD/qsgevents.cpp \
-    $$PWD/qsganchors.cpp \
-    $$PWD/qsgitem.cpp \
-    $$PWD/qsgrectangle.cpp \
-    $$PWD/qsgcanvas.cpp \
-    $$PWD/qsgfocusscope.cpp \
-    $$PWD/qsgitemsmodule.cpp \
-    $$PWD/qsgpainteditem.cpp \
-    $$PWD/qsgtext.cpp \
-    $$PWD/qsgtextnode.cpp \
-    $$PWD/qsgtextinput.cpp \
-    $$PWD/qsgtextedit.cpp \
-    $$PWD/qsgimagebase.cpp \
-    $$PWD/qsgimage.cpp \
-    $$PWD/qsgborderimage.cpp \
-    $$PWD/qsgninepatchnode.cpp \
-    $$PWD/qsgscalegrid.cpp \
-    $$PWD/qsgmousearea.cpp \
-    $$PWD/qsgpincharea.cpp \
-    $$PWD/qsgflickable.cpp \
-    $$PWD/qsglistview.cpp \
-    $$PWD/qsgvisualadaptormodel.cpp \
-    $$PWD/qsgvisualdatamodel.cpp \
-    $$PWD/qsgvisualitemmodel.cpp \
-    $$PWD/qsgrepeater.cpp \
-    $$PWD/qsggridview.cpp \
-    $$PWD/qsgpathview.cpp \
-    $$PWD/qsgpositioners.cpp \
-    $$PWD/qsgloader.cpp \
-    $$PWD/qsganimatedimage.cpp \
-    $$PWD/qsgflipable.cpp \
-    $$PWD/qsgtranslate.cpp \
-    $$PWD/qsgclipnode.cpp \
-    $$PWD/qsgview.cpp \
-    $$PWD/qsganimation.cpp \
-    $$PWD/qsgstateoperations.cpp \
-    $$PWD/qsgimplicitsizeitem.cpp \
-    $$PWD/qsgspriteengine.cpp \
-    $$PWD/qsgsprite.cpp \
-    $$PWD/qsgspriteimage.cpp \
-    $$PWD/qsgdrag.cpp \
-    $$PWD/qsgdroparea.cpp \
-    $$PWD/qsgitemview.cpp
+    $$PWD/qquickevents.cpp \
+    $$PWD/qquickanchors.cpp \
+    $$PWD/qquickitem.cpp \
+    $$PWD/qquickrectangle.cpp \
+    $$PWD/qquickcanvas.cpp \
+    $$PWD/qquickfocusscope.cpp \
+    $$PWD/qquickitemsmodule.cpp \
+    $$PWD/qquickpainteditem.cpp \
+    $$PWD/qquicktext.cpp \
+    $$PWD/qquicktextnode.cpp \
+    $$PWD/qquicktextinput.cpp \
+    $$PWD/qquicktextedit.cpp \
+    $$PWD/qquickimagebase.cpp \
+    $$PWD/qquickimage.cpp \
+    $$PWD/qquickborderimage.cpp \
+    $$PWD/qquickninepatchnode.cpp \
+    $$PWD/qquickscalegrid.cpp \
+    $$PWD/qquickmousearea.cpp \
+    $$PWD/qquickpincharea.cpp \
+    $$PWD/qquickflickable.cpp \
+    $$PWD/qquicklistview.cpp \
+    $$PWD/qquickvisualadaptormodel.cpp \
+    $$PWD/qquickvisualdatamodel.cpp \
+    $$PWD/qquickvisualitemmodel.cpp \
+    $$PWD/qquickrepeater.cpp \
+    $$PWD/qquickgridview.cpp \
+    $$PWD/qquickpathview.cpp \
+    $$PWD/qquickpositioners.cpp \
+    $$PWD/qquickloader.cpp \
+    $$PWD/qquickanimatedimage.cpp \
+    $$PWD/qquickflipable.cpp \
+    $$PWD/qquicktranslate.cpp \
+    $$PWD/qquickclipnode.cpp \
+    $$PWD/qquickview.cpp \
+    $$PWD/qquickanimation.cpp \
+    $$PWD/qquickstateoperations.cpp \
+    $$PWD/qquickimplicitsizeitem.cpp \
+    $$PWD/qquickspriteengine.cpp \
+    $$PWD/qquicksprite.cpp \
+    $$PWD/qquickspriteimage.cpp \
+    $$PWD/qquickdrag.cpp \
+    $$PWD/qquickdroparea.cpp \
+    $$PWD/qquickitemview.cpp
 
 SOURCES += \
-    $$PWD/qsgshadereffect.cpp \
-    $$PWD/qsgshadereffectmesh.cpp \
-    $$PWD/qsgshadereffectnode.cpp \
-    $$PWD/qsgshadereffectsource.cpp \
+    $$PWD/qquickshadereffect.cpp \
+    $$PWD/qquickshadereffectmesh.cpp \
+    $$PWD/qquickshadereffectnode.cpp \
+    $$PWD/qquickshadereffectsource.cpp \
 
 HEADERS += \
-    $$PWD/qsgshadereffect_p.h \
-    $$PWD/qsgshadereffectmesh_p.h \
-    $$PWD/qsgshadereffectnode_p.h \
-    $$PWD/qsgshadereffectsource_p.h \
+    $$PWD/qquickshadereffect_p.h \
+    $$PWD/qquickshadereffectmesh_p.h \
+    $$PWD/qquickshadereffectnode_p.h \
+    $$PWD/qquickshadereffectsource_p.h \
 
 include(context2d/context2d.pri)
diff --git a/src/declarative/items/qquickanchors.cpp b/src/declarative/items/qquickanchors.cpp
new file mode 100644 (file)
index 0000000..678347c
--- /dev/null
@@ -0,0 +1,1110 @@
+/****************************************************************************
+**
+** 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 "qquickanchors_p_p.h"
+
+#include "qquickitem.h"
+#include "qquickitem_p.h"
+
+#include <qdeclarativeinfo.h>
+
+QT_BEGIN_NAMESPACE
+
+//TODO: should we cache relationships, so we don't have to check each time (parent-child or sibling)?
+//TODO: support non-parent, non-sibling (need to find lowest common ancestor)
+
+static qreal hcenter(QQuickItem *item)
+{
+    qreal width = item->width();
+    int iw = width;
+    if (iw % 2)
+        return (width + 1) / 2;
+    else
+        return width / 2;
+}
+
+static qreal vcenter(QQuickItem *item)
+{
+    qreal height = item->height();
+    int ih = height;
+    if (ih % 2)
+        return (height + 1) / 2;
+    else
+        return height / 2;
+}
+
+//### const item?
+//local position
+static qreal position(QQuickItem *item, QQuickAnchorLine::AnchorLine anchorLine)
+{
+    qreal ret = 0.0;
+    switch (anchorLine) {
+    case QQuickAnchorLine::Left:
+        ret = item->x();
+        break;
+    case QQuickAnchorLine::Right:
+        ret = item->x() + item->width();
+        break;
+    case QQuickAnchorLine::Top:
+        ret = item->y();
+        break;
+    case QQuickAnchorLine::Bottom:
+        ret = item->y() + item->height();
+        break;
+    case QQuickAnchorLine::HCenter:
+        ret = item->x() + hcenter(item);
+        break;
+    case QQuickAnchorLine::VCenter:
+        ret = item->y() + vcenter(item);
+        break;
+    case QQuickAnchorLine::Baseline:
+        ret = item->y() + item->baselineOffset();
+        break;
+    default:
+        break;
+    }
+
+    return ret;
+}
+
+//position when origin is 0,0
+static qreal adjustedPosition(QQuickItem *item, QQuickAnchorLine::AnchorLine anchorLine)
+{
+    qreal ret = 0.0;
+    switch (anchorLine) {
+    case QQuickAnchorLine::Left:
+        ret = 0.0;
+        break;
+    case QQuickAnchorLine::Right:
+        ret = item->width();
+        break;
+    case QQuickAnchorLine::Top:
+        ret = 0.0;
+        break;
+    case QQuickAnchorLine::Bottom:
+        ret = item->height();
+        break;
+    case QQuickAnchorLine::HCenter:
+        ret = hcenter(item);
+        break;
+    case QQuickAnchorLine::VCenter:
+        ret = vcenter(item);
+        break;
+    case QQuickAnchorLine::Baseline:
+        ret = item->baselineOffset();
+        break;
+    default:
+        break;
+    }
+
+    return ret;
+}
+
+QQuickAnchors::QQuickAnchors(QQuickItem *item, QObject *parent)
+: QObject(*new QQuickAnchorsPrivate(item), parent)
+{
+}
+
+QQuickAnchors::~QQuickAnchors()
+{
+    Q_D(QQuickAnchors);
+    d->remDepend(d->fill);
+    d->remDepend(d->centerIn);
+    d->remDepend(d->left.item);
+    d->remDepend(d->right.item);
+    d->remDepend(d->top.item);
+    d->remDepend(d->bottom.item);
+    d->remDepend(d->vCenter.item);
+    d->remDepend(d->hCenter.item);
+    d->remDepend(d->baseline.item);
+}
+
+void QQuickAnchorsPrivate::fillChanged()
+{
+    Q_Q(QQuickAnchors);
+    if (!fill || !isItemComplete())
+        return;
+
+    if (updatingFill < 2) {
+        ++updatingFill;
+
+        qreal horizontalMargin = q->mirrored() ? rightMargin : leftMargin;
+
+        if (fill == item->parentItem()) {                         //child-parent
+            setItemPos(QPointF(horizontalMargin, topMargin));
+        } else if (fill->parentItem() == item->parentItem()) {   //siblings
+            setItemPos(QPointF(fill->x()+horizontalMargin, fill->y()+topMargin));
+        }
+        setItemSize(QSizeF(fill->width()-leftMargin-rightMargin, fill->height()-topMargin-bottomMargin));
+
+        --updatingFill;
+    } else {
+        // ### Make this certain :)
+        qmlInfo(item) << QQuickAnchors::tr("Possible anchor loop detected on fill.");
+    }
+
+}
+
+void QQuickAnchorsPrivate::centerInChanged()
+{
+    Q_Q(QQuickAnchors);
+    if (!centerIn || fill || !isItemComplete())
+        return;
+
+    if (updatingCenterIn < 2) {
+        ++updatingCenterIn;
+
+        qreal effectiveHCenterOffset = q->mirrored() ? -hCenterOffset : hCenterOffset;
+        if (centerIn == item->parentItem()) {
+            QPointF p(hcenter(item->parentItem()) - hcenter(item) + effectiveHCenterOffset,
+                      vcenter(item->parentItem()) - vcenter(item) + vCenterOffset);
+            setItemPos(p);
+
+        } else if (centerIn->parentItem() == item->parentItem()) {
+            QPointF p(centerIn->x() + hcenter(centerIn) - hcenter(item) + effectiveHCenterOffset,
+                      centerIn->y() + vcenter(centerIn) - vcenter(item) + vCenterOffset);
+            setItemPos(p);
+        }
+
+        --updatingCenterIn;
+    } else {
+        // ### Make this certain :)
+        qmlInfo(item) << QQuickAnchors::tr("Possible anchor loop detected on centerIn.");
+    }
+}
+
+void QQuickAnchorsPrivate::clearItem(QQuickItem *item)
+{
+    if (!item)
+        return;
+    if (fill == item)
+        fill = 0;
+    if (centerIn == item)
+        centerIn = 0;
+    if (left.item == item) {
+        left.item = 0;
+        usedAnchors &= ~QQuickAnchors::LeftAnchor;
+    }
+    if (right.item == item) {
+        right.item = 0;
+        usedAnchors &= ~QQuickAnchors::RightAnchor;
+    }
+    if (top.item == item) {
+        top.item = 0;
+        usedAnchors &= ~QQuickAnchors::TopAnchor;
+    }
+    if (bottom.item == item) {
+        bottom.item = 0;
+        usedAnchors &= ~QQuickAnchors::BottomAnchor;
+    }
+    if (vCenter.item == item) {
+        vCenter.item = 0;
+        usedAnchors &= ~QQuickAnchors::VCenterAnchor;
+    }
+    if (hCenter.item == item) {
+        hCenter.item = 0;
+        usedAnchors &= ~QQuickAnchors::HCenterAnchor;
+    }
+    if (baseline.item == item) {
+        baseline.item = 0;
+        usedAnchors &= ~QQuickAnchors::BaselineAnchor;
+    }
+}
+
+void QQuickAnchorsPrivate::addDepend(QQuickItem *item)
+{
+    if (!item)
+        return;
+
+    QQuickItemPrivate *p = QQuickItemPrivate::get(item);
+    p->addItemChangeListener(this, QQuickItemPrivate::Geometry);
+}
+
+void QQuickAnchorsPrivate::remDepend(QQuickItem *item)
+{
+    if (!item)
+        return;
+
+    QQuickItemPrivate *p = QQuickItemPrivate::get(item);
+    p->removeItemChangeListener(this, QQuickItemPrivate::Geometry);
+}
+
+bool QQuickAnchors::mirrored()
+{
+    Q_D(QQuickAnchors);
+    return QQuickItemPrivate::get(d->item)->effectiveLayoutMirror;
+}
+
+bool QQuickAnchorsPrivate::isItemComplete() const
+{
+    return componentComplete;
+}
+
+void QQuickAnchors::classBegin()
+{
+    Q_D(QQuickAnchors);
+    d->componentComplete = false;
+}
+
+void QQuickAnchors::componentComplete()
+{
+    Q_D(QQuickAnchors);
+    d->componentComplete = true;
+}
+
+void QQuickAnchorsPrivate::setItemHeight(qreal v)
+{
+    updatingMe = true;
+    item->setHeight(v);
+    updatingMe = false;
+}
+
+void QQuickAnchorsPrivate::setItemWidth(qreal v)
+{
+    updatingMe = true;
+    item->setWidth(v);
+    updatingMe = false;
+}
+
+void QQuickAnchorsPrivate::setItemX(qreal v)
+{
+    updatingMe = true;
+    item->setX(v);
+    updatingMe = false;
+}
+
+void QQuickAnchorsPrivate::setItemY(qreal v)
+{
+    updatingMe = true;
+    item->setY(v);
+    updatingMe = false;
+}
+
+void QQuickAnchorsPrivate::setItemPos(const QPointF &v)
+{
+    updatingMe = true;
+    item->setPos(v);
+    updatingMe = false;
+}
+
+void QQuickAnchorsPrivate::setItemSize(const QSizeF &v)
+{
+    updatingMe = true;
+    item->setSize(v);
+    updatingMe = false;
+}
+
+void QQuickAnchorsPrivate::updateMe()
+{
+    if (updatingMe) {
+        updatingMe = false;
+        return;
+    }
+
+    fillChanged();
+    centerInChanged();
+    updateHorizontalAnchors();
+    updateVerticalAnchors();
+}
+
+void QQuickAnchorsPrivate::updateOnComplete()
+{
+    fillChanged();
+    centerInChanged();
+    updateHorizontalAnchors();
+    updateVerticalAnchors();
+}
+
+void QQuickAnchorsPrivate::itemGeometryChanged(QQuickItem *, const QRectF &newG, const QRectF &oldG)
+{
+    fillChanged();
+    centerInChanged();
+    if (newG.x() != oldG.x() || newG.width() != oldG.width())
+        updateHorizontalAnchors();
+    if (newG.y() != oldG.y() || newG.height() != oldG.height())
+        updateVerticalAnchors();
+}
+
+QQuickItem *QQuickAnchors::fill() const
+{
+    Q_D(const QQuickAnchors);
+    return d->fill;
+}
+
+void QQuickAnchors::setFill(QQuickItem *f)
+{
+    Q_D(QQuickAnchors);
+    if (d->fill == f)
+        return;
+
+    if (!f) {
+        d->remDepend(d->fill);
+        d->fill = f;
+        emit fillChanged();
+        return;
+    }
+    if (f != d->item->parentItem() && f->parentItem() != d->item->parentItem()){
+        qmlInfo(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling.");
+        return;
+    }
+    d->remDepend(d->fill);
+    d->fill = f;
+    d->addDepend(d->fill);
+    emit fillChanged();
+    d->fillChanged();
+}
+
+void QQuickAnchors::resetFill()
+{
+    setFill(0);
+}
+
+QQuickItem *QQuickAnchors::centerIn() const
+{
+    Q_D(const QQuickAnchors);
+    return d->centerIn;
+}
+
+void QQuickAnchors::setCenterIn(QQuickItem* c)
+{
+    Q_D(QQuickAnchors);
+    if (d->centerIn == c)
+        return;
+
+    if (!c) {
+        d->remDepend(d->centerIn);
+        d->centerIn = c;
+        emit centerInChanged();
+        return;
+    }
+    if (c != d->item->parentItem() && c->parentItem() != d->item->parentItem()){
+        qmlInfo(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling.");
+        return;
+    }
+
+    d->remDepend(d->centerIn);
+    d->centerIn = c;
+    d->addDepend(d->centerIn);
+    emit centerInChanged();
+    d->centerInChanged();
+}
+
+void QQuickAnchors::resetCenterIn()
+{
+    setCenterIn(0);
+}
+
+bool QQuickAnchorsPrivate::calcStretch(const QQuickAnchorLine &edge1,
+                                    const QQuickAnchorLine &edge2,
+                                    qreal offset1,
+                                    qreal offset2,
+                                    QQuickAnchorLine::AnchorLine line,
+                                    qreal &stretch)
+{
+    bool edge1IsParent = (edge1.item == item->parentItem());
+    bool edge2IsParent = (edge2.item == item->parentItem());
+    bool edge1IsSibling = (edge1.item->parentItem() == item->parentItem());
+    bool edge2IsSibling = (edge2.item->parentItem() == item->parentItem());
+
+    bool invalid = false;
+    if ((edge2IsParent && edge1IsParent) || (edge2IsSibling && edge1IsSibling)) {
+        stretch = (position(edge2.item, edge2.anchorLine) + offset2)
+                    - (position(edge1.item, edge1.anchorLine) + offset1);
+    } else if (edge2IsParent && edge1IsSibling) {
+        stretch = (position(edge2.item, edge2.anchorLine) + offset2)
+                    - (position(item->parentItem(), line)
+                    + position(edge1.item, edge1.anchorLine) + offset1);
+    } else if (edge2IsSibling && edge1IsParent) {
+        stretch = (position(item->parentItem(), line) + position(edge2.item, edge2.anchorLine) + offset2)
+                    - (position(edge1.item, edge1.anchorLine) + offset1);
+    } else
+        invalid = true;
+
+    return invalid;
+}
+
+void QQuickAnchorsPrivate::updateVerticalAnchors()
+{
+    if (fill || centerIn || !isItemComplete())
+        return;
+
+    if (updatingVerticalAnchor < 2) {
+        ++updatingVerticalAnchor;
+        if (usedAnchors & QQuickAnchors::TopAnchor) {
+            //Handle stretching
+            bool invalid = true;
+            qreal height = 0.0;
+            if (usedAnchors & QQuickAnchors::BottomAnchor) {
+                invalid = calcStretch(top, bottom, topMargin, -bottomMargin, QQuickAnchorLine::Top, height);
+            } else if (usedAnchors & QQuickAnchors::VCenterAnchor) {
+                invalid = calcStretch(top, vCenter, topMargin, vCenterOffset, QQuickAnchorLine::Top, height);
+                height *= 2;
+            }
+            if (!invalid)
+                setItemHeight(height);
+
+            //Handle top
+            if (top.item == item->parentItem()) {
+                setItemY(adjustedPosition(top.item, top.anchorLine) + topMargin);
+            } else if (top.item->parentItem() == item->parentItem()) {
+                setItemY(position(top.item, top.anchorLine) + topMargin);
+            }
+        } else if (usedAnchors & QQuickAnchors::BottomAnchor) {
+            //Handle stretching (top + bottom case is handled above)
+            if (usedAnchors & QQuickAnchors::VCenterAnchor) {
+                qreal height = 0.0;
+                bool invalid = calcStretch(vCenter, bottom, vCenterOffset, -bottomMargin,
+                                              QQuickAnchorLine::Top, height);
+                if (!invalid)
+                    setItemHeight(height*2);
+            }
+
+            //Handle bottom
+            if (bottom.item == item->parentItem()) {
+                setItemY(adjustedPosition(bottom.item, bottom.anchorLine) - item->height() - bottomMargin);
+            } else if (bottom.item->parentItem() == item->parentItem()) {
+                setItemY(position(bottom.item, bottom.anchorLine) - item->height() - bottomMargin);
+            }
+        } else if (usedAnchors & QQuickAnchors::VCenterAnchor) {
+            //(stetching handled above)
+
+            //Handle vCenter
+            if (vCenter.item == item->parentItem()) {
+                setItemY(adjustedPosition(vCenter.item, vCenter.anchorLine)
+                              - vcenter(item) + vCenterOffset);
+            } else if (vCenter.item->parentItem() == item->parentItem()) {
+                setItemY(position(vCenter.item, vCenter.anchorLine) - vcenter(item) + vCenterOffset);
+            }
+        } else if (usedAnchors & QQuickAnchors::BaselineAnchor) {
+            //Handle baseline
+            if (baseline.item == item->parentItem()) {
+                setItemY(adjustedPosition(baseline.item, baseline.anchorLine) - item->baselineOffset() + baselineOffset);
+            } else if (baseline.item->parentItem() == item->parentItem()) {
+                setItemY(position(baseline.item, baseline.anchorLine) - item->baselineOffset() + baselineOffset);
+            }
+        }
+        --updatingVerticalAnchor;
+    } else {
+        // ### Make this certain :)
+        qmlInfo(item) << QQuickAnchors::tr("Possible anchor loop detected on vertical anchor.");
+    }
+}
+
+inline QQuickAnchorLine::AnchorLine reverseAnchorLine(QQuickAnchorLine::AnchorLine anchorLine)
+{
+    if (anchorLine == QQuickAnchorLine::Left) {
+        return QQuickAnchorLine::Right;
+    } else if (anchorLine == QQuickAnchorLine::Right) {
+        return QQuickAnchorLine::Left;
+    } else {
+        return anchorLine;
+    }
+}
+
+void QQuickAnchorsPrivate::updateHorizontalAnchors()
+{
+    Q_Q(QQuickAnchors);
+    if (fill || centerIn || !isItemComplete())
+        return;
+
+    if (updatingHorizontalAnchor < 3) {
+        ++updatingHorizontalAnchor;
+        qreal effectiveRightMargin, effectiveLeftMargin, effectiveHorizontalCenterOffset;
+        QQuickAnchorLine effectiveLeft, effectiveRight, effectiveHorizontalCenter;
+        QQuickAnchors::Anchor effectiveLeftAnchor, effectiveRightAnchor;
+        if (q->mirrored()) {
+            effectiveLeftAnchor = QQuickAnchors::RightAnchor;
+            effectiveRightAnchor = QQuickAnchors::LeftAnchor;
+            effectiveLeft.item = right.item;
+            effectiveLeft.anchorLine = reverseAnchorLine(right.anchorLine);
+            effectiveRight.item = left.item;
+            effectiveRight.anchorLine = reverseAnchorLine(left.anchorLine);
+            effectiveHorizontalCenter.item = hCenter.item;
+            effectiveHorizontalCenter.anchorLine = reverseAnchorLine(hCenter.anchorLine);
+            effectiveLeftMargin = rightMargin;
+            effectiveRightMargin = leftMargin;
+            effectiveHorizontalCenterOffset = -hCenterOffset;
+        } else {
+            effectiveLeftAnchor = QQuickAnchors::LeftAnchor;
+            effectiveRightAnchor = QQuickAnchors::RightAnchor;
+            effectiveLeft = left;
+            effectiveRight = right;
+            effectiveHorizontalCenter = hCenter;
+            effectiveLeftMargin = leftMargin;
+            effectiveRightMargin = rightMargin;
+            effectiveHorizontalCenterOffset = hCenterOffset;
+        }
+
+        if (usedAnchors & effectiveLeftAnchor) {
+            //Handle stretching
+            bool invalid = true;
+            qreal width = 0.0;
+            if (usedAnchors & effectiveRightAnchor) {
+                invalid = calcStretch(effectiveLeft, effectiveRight, effectiveLeftMargin, -effectiveRightMargin, QQuickAnchorLine::Left, width);
+            } else if (usedAnchors & QQuickAnchors::HCenterAnchor) {
+                invalid = calcStretch(effectiveLeft, effectiveHorizontalCenter, effectiveLeftMargin, effectiveHorizontalCenterOffset, QQuickAnchorLine::Left, width);
+                width *= 2;
+            }
+            if (!invalid)
+                setItemWidth(width);
+
+            //Handle left
+            if (effectiveLeft.item == item->parentItem()) {
+                setItemX(adjustedPosition(effectiveLeft.item, effectiveLeft.anchorLine) + effectiveLeftMargin);
+            } else if (effectiveLeft.item->parentItem() == item->parentItem()) {
+                setItemX(position(effectiveLeft.item, effectiveLeft.anchorLine) + effectiveLeftMargin);
+            }
+        } else if (usedAnchors & effectiveRightAnchor) {
+            //Handle stretching (left + right case is handled in updateLeftAnchor)
+            if (usedAnchors & QQuickAnchors::HCenterAnchor) {
+                qreal width = 0.0;
+                bool invalid = calcStretch(effectiveHorizontalCenter, effectiveRight, effectiveHorizontalCenterOffset, -effectiveRightMargin,
+                                              QQuickAnchorLine::Left, width);
+                if (!invalid)
+                    setItemWidth(width*2);
+            }
+
+            //Handle right
+            if (effectiveRight.item == item->parentItem()) {
+                setItemX(adjustedPosition(effectiveRight.item, effectiveRight.anchorLine) - item->width() - effectiveRightMargin);
+            } else if (effectiveRight.item->parentItem() == item->parentItem()) {
+                setItemX(position(effectiveRight.item, effectiveRight.anchorLine) - item->width() - effectiveRightMargin);
+            }
+        } else if (usedAnchors & QQuickAnchors::HCenterAnchor) {
+            //Handle hCenter
+            if (effectiveHorizontalCenter.item == item->parentItem()) {
+                setItemX(adjustedPosition(effectiveHorizontalCenter.item, effectiveHorizontalCenter.anchorLine) - hcenter(item) + effectiveHorizontalCenterOffset);
+            } else if (effectiveHorizontalCenter.item->parentItem() == item->parentItem()) {
+                setItemX(position(effectiveHorizontalCenter.item, effectiveHorizontalCenter.anchorLine) - hcenter(item) + effectiveHorizontalCenterOffset);
+            }
+        }
+        --updatingHorizontalAnchor;
+    } else {
+        // ### Make this certain :)
+        qmlInfo(item) << QQuickAnchors::tr("Possible anchor loop detected on horizontal anchor.");
+    }
+}
+
+QQuickAnchorLine QQuickAnchors::top() const
+{
+    Q_D(const QQuickAnchors);
+    return d->top;
+}
+
+void QQuickAnchors::setTop(const QQuickAnchorLine &edge)
+{
+    Q_D(QQuickAnchors);
+    if (!d->checkVAnchorValid(edge) || d->top == edge)
+        return;
+
+    d->usedAnchors |= TopAnchor;
+
+    if (!d->checkVValid()) {
+        d->usedAnchors &= ~TopAnchor;
+        return;
+    }
+
+    d->remDepend(d->top.item);
+    d->top = edge;
+    d->addDepend(d->top.item);
+    emit topChanged();
+    d->updateVerticalAnchors();
+}
+
+void QQuickAnchors::resetTop()
+{
+    Q_D(QQuickAnchors);
+    d->usedAnchors &= ~TopAnchor;
+    d->remDepend(d->top.item);
+    d->top = QQuickAnchorLine();
+    emit topChanged();
+    d->updateVerticalAnchors();
+}
+
+QQuickAnchorLine QQuickAnchors::bottom() const
+{
+    Q_D(const QQuickAnchors);
+    return d->bottom;
+}
+
+void QQuickAnchors::setBottom(const QQuickAnchorLine &edge)
+{
+    Q_D(QQuickAnchors);
+    if (!d->checkVAnchorValid(edge) || d->bottom == edge)
+        return;
+
+    d->usedAnchors |= BottomAnchor;
+
+    if (!d->checkVValid()) {
+        d->usedAnchors &= ~BottomAnchor;
+        return;
+    }
+
+    d->remDepend(d->bottom.item);
+    d->bottom = edge;
+    d->addDepend(d->bottom.item);
+    emit bottomChanged();
+    d->updateVerticalAnchors();
+}
+
+void QQuickAnchors::resetBottom()
+{
+    Q_D(QQuickAnchors);
+    d->usedAnchors &= ~BottomAnchor;
+    d->remDepend(d->bottom.item);
+    d->bottom = QQuickAnchorLine();
+    emit bottomChanged();
+    d->updateVerticalAnchors();
+}
+
+QQuickAnchorLine QQuickAnchors::verticalCenter() const
+{
+    Q_D(const QQuickAnchors);
+    return d->vCenter;
+}
+
+void QQuickAnchors::setVerticalCenter(const QQuickAnchorLine &edge)
+{
+    Q_D(QQuickAnchors);
+    if (!d->checkVAnchorValid(edge) || d->vCenter == edge)
+        return;
+
+    d->usedAnchors |= VCenterAnchor;
+
+    if (!d->checkVValid()) {
+        d->usedAnchors &= ~VCenterAnchor;
+        return;
+    }
+
+    d->remDepend(d->vCenter.item);
+    d->vCenter = edge;
+    d->addDepend(d->vCenter.item);
+    emit verticalCenterChanged();
+    d->updateVerticalAnchors();
+}
+
+void QQuickAnchors::resetVerticalCenter()
+{
+    Q_D(QQuickAnchors);
+    d->usedAnchors &= ~VCenterAnchor;
+    d->remDepend(d->vCenter.item);
+    d->vCenter = QQuickAnchorLine();
+    emit verticalCenterChanged();
+    d->updateVerticalAnchors();
+}
+
+QQuickAnchorLine QQuickAnchors::baseline() const
+{
+    Q_D(const QQuickAnchors);
+    return d->baseline;
+}
+
+void QQuickAnchors::setBaseline(const QQuickAnchorLine &edge)
+{
+    Q_D(QQuickAnchors);
+    if (!d->checkVAnchorValid(edge) || d->baseline == edge)
+        return;
+
+    d->usedAnchors |= BaselineAnchor;
+
+    if (!d->checkVValid()) {
+        d->usedAnchors &= ~BaselineAnchor;
+        return;
+    }
+
+    d->remDepend(d->baseline.item);
+    d->baseline = edge;
+    d->addDepend(d->baseline.item);
+    emit baselineChanged();
+    d->updateVerticalAnchors();
+}
+
+void QQuickAnchors::resetBaseline()
+{
+    Q_D(QQuickAnchors);
+    d->usedAnchors &= ~BaselineAnchor;
+    d->remDepend(d->baseline.item);
+    d->baseline = QQuickAnchorLine();
+    emit baselineChanged();
+    d->updateVerticalAnchors();
+}
+
+QQuickAnchorLine QQuickAnchors::left() const
+{
+    Q_D(const QQuickAnchors);
+    return d->left;
+}
+
+void QQuickAnchors::setLeft(const QQuickAnchorLine &edge)
+{
+    Q_D(QQuickAnchors);
+    if (!d->checkHAnchorValid(edge) || d->left == edge)
+        return;
+
+    d->usedAnchors |= LeftAnchor;
+
+    if (!d->checkHValid()) {
+        d->usedAnchors &= ~LeftAnchor;
+        return;
+    }
+
+    d->remDepend(d->left.item);
+    d->left = edge;
+    d->addDepend(d->left.item);
+    emit leftChanged();
+    d->updateHorizontalAnchors();
+}
+
+void QQuickAnchors::resetLeft()
+{
+    Q_D(QQuickAnchors);
+    d->usedAnchors &= ~LeftAnchor;
+    d->remDepend(d->left.item);
+    d->left = QQuickAnchorLine();
+    emit leftChanged();
+    d->updateHorizontalAnchors();
+}
+
+QQuickAnchorLine QQuickAnchors::right() const
+{
+    Q_D(const QQuickAnchors);
+    return d->right;
+}
+
+void QQuickAnchors::setRight(const QQuickAnchorLine &edge)
+{
+    Q_D(QQuickAnchors);
+    if (!d->checkHAnchorValid(edge) || d->right == edge)
+        return;
+
+    d->usedAnchors |= RightAnchor;
+
+    if (!d->checkHValid()) {
+        d->usedAnchors &= ~RightAnchor;
+        return;
+    }
+
+    d->remDepend(d->right.item);
+    d->right = edge;
+    d->addDepend(d->right.item);
+    emit rightChanged();
+    d->updateHorizontalAnchors();
+}
+
+void QQuickAnchors::resetRight()
+{
+    Q_D(QQuickAnchors);
+    d->usedAnchors &= ~RightAnchor;
+    d->remDepend(d->right.item);
+    d->right = QQuickAnchorLine();
+    emit rightChanged();
+    d->updateHorizontalAnchors();
+}
+
+QQuickAnchorLine QQuickAnchors::horizontalCenter() const
+{
+    Q_D(const QQuickAnchors);
+    return d->hCenter;
+}
+
+void QQuickAnchors::setHorizontalCenter(const QQuickAnchorLine &edge)
+{
+    Q_D(QQuickAnchors);
+    if (!d->checkHAnchorValid(edge) || d->hCenter == edge)
+        return;
+
+    d->usedAnchors |= HCenterAnchor;
+
+    if (!d->checkHValid()) {
+        d->usedAnchors &= ~HCenterAnchor;
+        return;
+    }
+
+    d->remDepend(d->hCenter.item);
+    d->hCenter = edge;
+    d->addDepend(d->hCenter.item);
+    emit horizontalCenterChanged();
+    d->updateHorizontalAnchors();
+}
+
+void QQuickAnchors::resetHorizontalCenter()
+{
+    Q_D(QQuickAnchors);
+    d->usedAnchors &= ~HCenterAnchor;
+    d->remDepend(d->hCenter.item);
+    d->hCenter = QQuickAnchorLine();
+    emit horizontalCenterChanged();
+    d->updateHorizontalAnchors();
+}
+
+qreal QQuickAnchors::leftMargin() const
+{
+    Q_D(const QQuickAnchors);
+    return d->leftMargin;
+}
+
+void QQuickAnchors::setLeftMargin(qreal offset)
+{
+    Q_D(QQuickAnchors);
+    if (d->leftMargin == offset)
+        return;
+    d->leftMargin = offset;
+    if (d->fill)
+        d->fillChanged();
+    else
+        d->updateHorizontalAnchors();
+    emit leftMarginChanged();
+}
+
+qreal QQuickAnchors::rightMargin() const
+{
+    Q_D(const QQuickAnchors);
+    return d->rightMargin;
+}
+
+void QQuickAnchors::setRightMargin(qreal offset)
+{
+    Q_D(QQuickAnchors);
+    if (d->rightMargin == offset)
+        return;
+    d->rightMargin = offset;
+    if (d->fill)
+        d->fillChanged();
+    else
+        d->updateHorizontalAnchors();
+    emit rightMarginChanged();
+}
+
+qreal QQuickAnchors::margins() const
+{
+    Q_D(const QQuickAnchors);
+    return d->margins;
+}
+
+void QQuickAnchors::setMargins(qreal offset)
+{
+    Q_D(QQuickAnchors);
+    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)
+        setRightMargin(offset);
+    if (!d->leftMargin || d->leftMargin == d->margins)
+        setLeftMargin(offset);
+    if (!d->topMargin || d->topMargin == d->margins)
+        setTopMargin(offset);
+    if (!d->bottomMargin || d->bottomMargin == d->margins)
+        setBottomMargin(offset);
+    d->margins = offset;
+    emit marginsChanged();
+
+}
+
+qreal QQuickAnchors::horizontalCenterOffset() const
+{
+    Q_D(const QQuickAnchors);
+    return d->hCenterOffset;
+}
+
+void QQuickAnchors::setHorizontalCenterOffset(qreal offset)
+{
+    Q_D(QQuickAnchors);
+    if (d->hCenterOffset == offset)
+        return;
+    d->hCenterOffset = offset;
+    if (d->centerIn)
+        d->centerInChanged();
+    else
+        d->updateHorizontalAnchors();
+    emit horizontalCenterOffsetChanged();
+}
+
+qreal QQuickAnchors::topMargin() const
+{
+    Q_D(const QQuickAnchors);
+    return d->topMargin;
+}
+
+void QQuickAnchors::setTopMargin(qreal offset)
+{
+    Q_D(QQuickAnchors);
+    if (d->topMargin == offset)
+        return;
+    d->topMargin = offset;
+    if (d->fill)
+        d->fillChanged();
+    else
+        d->updateVerticalAnchors();
+    emit topMarginChanged();
+}
+
+qreal QQuickAnchors::bottomMargin() const
+{
+    Q_D(const QQuickAnchors);
+    return d->bottomMargin;
+}
+
+void QQuickAnchors::setBottomMargin(qreal offset)
+{
+    Q_D(QQuickAnchors);
+    if (d->bottomMargin == offset)
+        return;
+    d->bottomMargin = offset;
+    if (d->fill)
+        d->fillChanged();
+    else
+        d->updateVerticalAnchors();
+    emit bottomMarginChanged();
+}
+
+qreal QQuickAnchors::verticalCenterOffset() const
+{
+    Q_D(const QQuickAnchors);
+    return d->vCenterOffset;
+}
+
+void QQuickAnchors::setVerticalCenterOffset(qreal offset)
+{
+    Q_D(QQuickAnchors);
+    if (d->vCenterOffset == offset)
+        return;
+    d->vCenterOffset = offset;
+    if (d->centerIn)
+        d->centerInChanged();
+    else
+        d->updateVerticalAnchors();
+    emit verticalCenterOffsetChanged();
+}
+
+qreal QQuickAnchors::baselineOffset() const
+{
+    Q_D(const QQuickAnchors);
+    return d->baselineOffset;
+}
+
+void QQuickAnchors::setBaselineOffset(qreal offset)
+{
+    Q_D(QQuickAnchors);
+    if (d->baselineOffset == offset)
+        return;
+    d->baselineOffset = offset;
+    d->updateVerticalAnchors();
+    emit baselineOffsetChanged();
+}
+
+QQuickAnchors::Anchors QQuickAnchors::usedAnchors() const
+{
+    Q_D(const QQuickAnchors);
+    return d->usedAnchors;
+}
+
+bool QQuickAnchorsPrivate::checkHValid() const
+{
+    if (usedAnchors & QQuickAnchors::LeftAnchor &&
+        usedAnchors & QQuickAnchors::RightAnchor &&
+        usedAnchors & QQuickAnchors::HCenterAnchor) {
+        qmlInfo(item) << QQuickAnchors::tr("Cannot specify left, right, and hcenter anchors.");
+        return false;
+    }
+
+    return true;
+}
+
+bool QQuickAnchorsPrivate::checkHAnchorValid(QQuickAnchorLine anchor) const
+{
+    if (!anchor.item) {
+        qmlInfo(item) << QQuickAnchors::tr("Cannot anchor to a null item.");
+        return false;
+    } else if (anchor.anchorLine & QQuickAnchorLine::Vertical_Mask) {
+        qmlInfo(item) << QQuickAnchors::tr("Cannot anchor a horizontal edge to a vertical edge.");
+        return false;
+    } else if (anchor.item != item->parentItem() && anchor.item->parentItem() != item->parentItem()){
+        qmlInfo(item) << QQuickAnchors::tr("Cannot anchor to an item that isn't a parent or sibling.");
+        return false;
+    } else if (anchor.item == item) {
+        qmlInfo(item) << QQuickAnchors::tr("Cannot anchor item to self.");
+        return false;
+    }
+
+    return true;
+}
+
+bool QQuickAnchorsPrivate::checkVValid() const
+{
+    if (usedAnchors & QQuickAnchors::TopAnchor &&
+        usedAnchors & QQuickAnchors::BottomAnchor &&
+        usedAnchors & QQuickAnchors::VCenterAnchor) {
+        qmlInfo(item) << QQuickAnchors::tr("Cannot specify top, bottom, and vcenter anchors.");
+        return false;
+    } else if (usedAnchors & QQuickAnchors::BaselineAnchor &&
+               (usedAnchors & QQuickAnchors::TopAnchor ||
+                usedAnchors & QQuickAnchors::BottomAnchor ||
+                usedAnchors & QQuickAnchors::VCenterAnchor)) {
+        qmlInfo(item) << QQuickAnchors::tr("Baseline anchor cannot be used in conjunction with top, bottom, or vcenter anchors.");
+        return false;
+    }
+
+    return true;
+}
+
+bool QQuickAnchorsPrivate::checkVAnchorValid(QQuickAnchorLine anchor) const
+{
+    if (!anchor.item) {
+        qmlInfo(item) << QQuickAnchors::tr("Cannot anchor to a null item.");
+        return false;
+    } else if (anchor.anchorLine & QQuickAnchorLine::Horizontal_Mask) {
+        qmlInfo(item) << QQuickAnchors::tr("Cannot anchor a vertical edge to a horizontal edge.");
+        return false;
+    } else if (anchor.item != item->parentItem() && anchor.item->parentItem() != item->parentItem()){
+        qmlInfo(item) << QQuickAnchors::tr("Cannot anchor to an item that isn't a parent or sibling.");
+        return false;
+    } else if (anchor.item == item){
+        qmlInfo(item) << QQuickAnchors::tr("Cannot anchor item to self.");
+        return false;
+    }
+
+    return true;
+}
+
+QT_END_NAMESPACE
+
+#include <moc_qquickanchors_p.cpp>
+
diff --git a/src/declarative/items/qquickanchors_p.h b/src/declarative/items/qquickanchors_p.h
new file mode 100644 (file)
index 0000000..5c66c2e
--- /dev/null
@@ -0,0 +1,201 @@
+// Commit: 2c7cab4172f1acc86fd49345a2847417e162f2c3
+/****************************************************************************
+**
+** 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 QQUICKANCHORS_P_H
+#define QQUICKANCHORS_P_H
+
+#include <qdeclarative.h>
+
+#include <QtCore/QObject>
+
+#include <private/qdeclarativeglobal_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickItem;
+class QQuickAnchorsPrivate;
+class QQuickAnchorLine;
+class Q_DECLARATIVE_PRIVATE_EXPORT QQuickAnchors : public QObject
+{
+    Q_OBJECT
+
+    Q_PROPERTY(QQuickAnchorLine left READ left WRITE setLeft RESET resetLeft NOTIFY leftChanged)
+    Q_PROPERTY(QQuickAnchorLine right READ right WRITE setRight RESET resetRight NOTIFY rightChanged)
+    Q_PROPERTY(QQuickAnchorLine horizontalCenter READ horizontalCenter WRITE setHorizontalCenter RESET resetHorizontalCenter NOTIFY horizontalCenterChanged)
+    Q_PROPERTY(QQuickAnchorLine top READ top WRITE setTop RESET resetTop NOTIFY topChanged)
+    Q_PROPERTY(QQuickAnchorLine bottom READ bottom WRITE setBottom RESET resetBottom NOTIFY bottomChanged)
+    Q_PROPERTY(QQuickAnchorLine verticalCenter READ verticalCenter WRITE setVerticalCenter RESET resetVerticalCenter NOTIFY verticalCenterChanged)
+    Q_PROPERTY(QQuickAnchorLine baseline READ baseline WRITE setBaseline RESET resetBaseline NOTIFY baselineChanged)
+    Q_PROPERTY(qreal margins READ margins WRITE setMargins NOTIFY marginsChanged)
+    Q_PROPERTY(qreal leftMargin READ leftMargin WRITE setLeftMargin NOTIFY leftMarginChanged)
+    Q_PROPERTY(qreal rightMargin READ rightMargin WRITE setRightMargin NOTIFY rightMarginChanged)
+    Q_PROPERTY(qreal horizontalCenterOffset READ horizontalCenterOffset WRITE setHorizontalCenterOffset NOTIFY horizontalCenterOffsetChanged)
+    Q_PROPERTY(qreal topMargin READ topMargin WRITE setTopMargin NOTIFY topMarginChanged)
+    Q_PROPERTY(qreal bottomMargin READ bottomMargin WRITE setBottomMargin NOTIFY bottomMarginChanged)
+    Q_PROPERTY(qreal verticalCenterOffset READ verticalCenterOffset WRITE setVerticalCenterOffset NOTIFY verticalCenterOffsetChanged)
+    Q_PROPERTY(qreal baselineOffset READ baselineOffset WRITE setBaselineOffset NOTIFY baselineOffsetChanged)
+    Q_PROPERTY(QQuickItem *fill READ fill WRITE setFill RESET resetFill NOTIFY fillChanged)
+    Q_PROPERTY(QQuickItem *centerIn READ centerIn WRITE setCenterIn RESET resetCenterIn NOTIFY centerInChanged)
+    Q_PROPERTY(bool mirrored READ mirrored NOTIFY mirroredChanged)
+
+public:
+    QQuickAnchors(QQuickItem *item, QObject *parent=0);
+    virtual ~QQuickAnchors();
+
+    enum Anchor {
+        LeftAnchor = 0x01,
+        RightAnchor = 0x02,
+        TopAnchor = 0x04,
+        BottomAnchor = 0x08,
+        HCenterAnchor = 0x10,
+        VCenterAnchor = 0x20,
+        BaselineAnchor = 0x40,
+        Horizontal_Mask = LeftAnchor | RightAnchor | HCenterAnchor,
+        Vertical_Mask = TopAnchor | BottomAnchor | VCenterAnchor | BaselineAnchor
+    };
+    Q_DECLARE_FLAGS(Anchors, Anchor)
+
+    QQuickAnchorLine left() const;
+    void setLeft(const QQuickAnchorLine &edge);
+    void resetLeft();
+
+    QQuickAnchorLine right() const;
+    void setRight(const QQuickAnchorLine &edge);
+    void resetRight();
+
+    QQuickAnchorLine horizontalCenter() const;
+    void setHorizontalCenter(const QQuickAnchorLine &edge);
+    void resetHorizontalCenter();
+
+    QQuickAnchorLine top() const;
+    void setTop(const QQuickAnchorLine &edge);
+    void resetTop();
+
+    QQuickAnchorLine bottom() const;
+    void setBottom(const QQuickAnchorLine &edge);
+    void resetBottom();
+
+    QQuickAnchorLine verticalCenter() const;
+    void setVerticalCenter(const QQuickAnchorLine &edge);
+    void resetVerticalCenter();
+
+    QQuickAnchorLine baseline() const;
+    void setBaseline(const QQuickAnchorLine &edge);
+    void resetBaseline();
+
+    qreal leftMargin() const;
+    void setLeftMargin(qreal);
+
+    qreal rightMargin() const;
+    void setRightMargin(qreal);
+
+    qreal horizontalCenterOffset() const;
+    void setHorizontalCenterOffset(qreal);
+
+    qreal topMargin() const;
+    void setTopMargin(qreal);
+
+    qreal bottomMargin() const;
+    void setBottomMargin(qreal);
+
+    qreal margins() const;
+    void setMargins(qreal);
+
+    qreal verticalCenterOffset() const;
+    void setVerticalCenterOffset(qreal);
+
+    qreal baselineOffset() const;
+    void setBaselineOffset(qreal);
+
+    QQuickItem *fill() const;
+    void setFill(QQuickItem *);
+    void resetFill();
+
+    QQuickItem *centerIn() const;
+    void setCenterIn(QQuickItem *);
+    void resetCenterIn();
+
+    Anchors usedAnchors() const;
+
+    bool mirrored();
+
+    void classBegin();
+    void componentComplete();
+
+Q_SIGNALS:
+    void leftChanged();
+    void rightChanged();
+    void topChanged();
+    void bottomChanged();
+    void verticalCenterChanged();
+    void horizontalCenterChanged();
+    void baselineChanged();
+    void fillChanged();
+    void centerInChanged();
+    void leftMarginChanged();
+    void rightMarginChanged();
+    void topMarginChanged();
+    void bottomMarginChanged();
+    void marginsChanged();
+    void verticalCenterOffsetChanged();
+    void horizontalCenterOffsetChanged();
+    void baselineOffsetChanged();
+    void mirroredChanged();
+
+private:
+    friend class QQuickItemPrivate;
+    Q_DISABLE_COPY(QQuickAnchors)
+    Q_DECLARE_PRIVATE(QQuickAnchors)
+};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickAnchors::Anchors)
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickAnchors)
+
+QT_END_HEADER
+
+#endif // QQUICKANCHORS_P_H
diff --git a/src/declarative/items/qquickanchors_p_p.h b/src/declarative/items/qquickanchors_p_p.h
new file mode 100644 (file)
index 0000000..eae7981
--- /dev/null
@@ -0,0 +1,173 @@
+// Commit: 2c7cab4172f1acc86fd49345a2847417e162f2c3
+/****************************************************************************
+**
+** 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 QQUICKANCHORS_P_P_H
+#define QQUICKANCHORS_P_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 "qquickanchors_p.h"
+#include "qquickitemchangelistener_p.h"
+#include <private/qobject_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickAnchorLine
+{
+public:
+    QQuickAnchorLine() : item(0), anchorLine(Invalid) {}
+
+    enum AnchorLine {
+        Invalid = 0x0,
+        Left = 0x01,
+        Right = 0x02,
+        Top = 0x04,
+        Bottom = 0x08,
+        HCenter = 0x10,
+        VCenter = 0x20,
+        Baseline = 0x40,
+        Horizontal_Mask = Left | Right | HCenter,
+        Vertical_Mask = Top | Bottom | VCenter | Baseline
+    };
+
+    QQuickItem *item;
+    AnchorLine anchorLine;
+};
+
+inline bool operator==(const QQuickAnchorLine& a, const QQuickAnchorLine& b)
+{
+    return a.item == b.item && a.anchorLine == b.anchorLine;
+}
+
+class QQuickAnchorsPrivate : public QObjectPrivate, public QQuickItemChangeListener
+{
+    Q_DECLARE_PUBLIC(QQuickAnchors)
+public:
+    QQuickAnchorsPrivate(QQuickItem *i)
+      : componentComplete(true), updatingMe(false), updatingHorizontalAnchor(0),
+        updatingVerticalAnchor(0), updatingFill(0), updatingCenterIn(0), item(i), usedAnchors(0), fill(0),
+        centerIn(0), leftMargin(0), rightMargin(0), topMargin(0), bottomMargin(0),
+        margins(0), vCenterOffset(0), hCenterOffset(0), baselineOffset(0)
+    {
+    }
+
+    void clearItem(QQuickItem *);
+
+    void addDepend(QQuickItem *);
+    void remDepend(QQuickItem *);
+    bool isItemComplete() const;
+
+    bool componentComplete:1;
+    bool updatingMe:1;
+    uint updatingHorizontalAnchor:2;
+    uint updatingVerticalAnchor:2;
+    uint updatingFill:2;
+    uint updatingCenterIn:2;
+
+    void setItemHeight(qreal);
+    void setItemWidth(qreal);
+    void setItemX(qreal);
+    void setItemY(qreal);
+    void setItemPos(const QPointF &);
+    void setItemSize(const QSizeF &);
+
+    void updateOnComplete();
+    void updateMe();
+
+    // QQuickItemGeometryListener interface
+    void itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &);
+    QQuickAnchorsPrivate *anchorPrivate() { return this; }
+
+    bool checkHValid() const;
+    bool checkVValid() const;
+    bool checkHAnchorValid(QQuickAnchorLine anchor) const;
+    bool checkVAnchorValid(QQuickAnchorLine anchor) const;
+    bool calcStretch(const QQuickAnchorLine &edge1, const QQuickAnchorLine &edge2, qreal offset1, qreal offset2, QQuickAnchorLine::AnchorLine line, qreal &stretch);
+
+    bool isMirrored() const;
+    void updateHorizontalAnchors();
+    void updateVerticalAnchors();
+    void fillChanged();
+    void centerInChanged();
+
+    QQuickItem *item;
+    QQuickAnchors::Anchors usedAnchors;
+
+    QQuickItem *fill;
+    QQuickItem *centerIn;
+
+    QQuickAnchorLine left;
+    QQuickAnchorLine right;
+    QQuickAnchorLine top;
+    QQuickAnchorLine bottom;
+    QQuickAnchorLine vCenter;
+    QQuickAnchorLine hCenter;
+    QQuickAnchorLine baseline;
+
+    qreal leftMargin;
+    qreal rightMargin;
+    qreal topMargin;
+    qreal bottomMargin;
+    qreal margins;
+    qreal vCenterOffset;
+    qreal hCenterOffset;
+    qreal baselineOffset;
+
+    static inline QQuickAnchorsPrivate *get(QQuickAnchors *o) {
+        return static_cast<QQuickAnchorsPrivate *>(QObjectPrivate::get(o));
+    }
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QQuickAnchorLine)
+
+#endif
diff --git a/src/declarative/items/qquickanimatedimage.cpp b/src/declarative/items/qquickanimatedimage.cpp
new file mode 100644 (file)
index 0000000..d4b08dd
--- /dev/null
@@ -0,0 +1,397 @@
+/****************************************************************************
+**
+** 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 "qquickanimatedimage_p.h"
+#include "qquickanimatedimage_p_p.h"
+
+#ifndef QT_NO_MOVIE
+
+#include <QtDeclarative/qdeclarativeinfo.h>
+#include <QtGui/qmovie.h>
+#include <QtNetwork/qnetworkrequest.h>
+#include <QtNetwork/qnetworkreply.h>
+
+#include <private/qdeclarativeengine_p.h>
+
+QT_BEGIN_NAMESPACE
+/*!
+    \qmlclass AnimatedImage QQuickAnimatedImage
+    \inqmlmodule QtQuick 2
+    \inherits Image
+    \ingroup basic-visual-elements
+
+    The AnimatedImage element extends the features of the \l Image element, providing
+    a way to play animations stored as images containing a series of frames,
+    such as those stored in GIF files.
+
+    Information about the current frame and totla length of the animation can be
+    obtained using the \l currentFrame and \l frameCount properties. You can
+    start, pause and stop the animation by changing the values of the \l playing
+    and \l paused properties.
+
+    The full list of supported formats can be determined with QMovie::supportedFormats().
+
+    \section1 Example Usage
+
+    \beginfloatleft
+    \image animatedimageitem.gif
+    \endfloat
+
+    The following QML shows how to display an animated image and obtain information
+    about its state, such as the current frame and total number of frames.
+    The result is an animated image with a simple progress indicator underneath it.
+
+    \bold Note: Unlike images, animated images are not cached or shared internally.
+
+    \clearfloat
+    \snippet doc/src/snippets/declarative/animatedimage.qml document
+
+    \sa BorderImage, Image
+*/
+
+/*!
+    \qmlproperty url QtQuick2::AnimatedImage::source
+
+    This property holds the URL that refers to the source image.
+
+    AnimatedImage can handle any image format supported by Qt, loaded from any
+    URL scheme supported by Qt.
+
+    \sa QDeclarativeImageProvider
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::AnimatedImage::asynchronous
+
+    Specifies that images on the local filesystem should be loaded
+    asynchronously in a separate thread.  The default value is
+    false, causing the user interface thread to block while the
+    image is loaded.  Setting \a asynchronous to true is useful where
+    maintaining a responsive user interface is more desirable
+    than having images immediately visible.
+
+    Note that this property is only valid for images read from the
+    local filesystem.  Images loaded via a network resource (e.g. HTTP)
+    are always loaded asynchonously.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::AnimatedImage::mirror
+
+    This property holds whether the image should be horizontally inverted
+    (effectively displaying a mirrored image).
+
+    The default value is false.
+*/
+
+QQuickAnimatedImage::QQuickAnimatedImage(QQuickItem *parent)
+    : QQuickImage(*(new QQuickAnimatedImagePrivate), parent)
+{
+}
+
+QQuickAnimatedImage::~QQuickAnimatedImage()
+{
+    Q_D(QQuickAnimatedImage);
+    delete d->_movie;
+}
+
+/*!
+  \qmlproperty bool QtQuick2::AnimatedImage::paused
+  This property holds whether the animated image is paused.
+
+  By default, this property is false. Set it to true when you want to pause
+  the animation.
+*/
+
+bool QQuickAnimatedImage::isPaused() const
+{
+    Q_D(const QQuickAnimatedImage);
+    if (!d->_movie)
+        return false;
+    return d->_movie->state()==QMovie::Paused;
+}
+
+void QQuickAnimatedImage::setPaused(bool pause)
+{
+    Q_D(QQuickAnimatedImage);
+    if (pause == d->paused)
+        return;
+    d->paused = pause;
+    if (!d->_movie)
+        return;
+    d->_movie->setPaused(pause);
+}
+
+/*!
+  \qmlproperty bool QtQuick2::AnimatedImage::playing
+  This property holds whether the animated image is playing.
+
+  By default, this property is true, meaning that the animation
+  will start playing immediately.
+*/
+
+bool QQuickAnimatedImage::isPlaying() const
+{
+    Q_D(const QQuickAnimatedImage);
+    if (!d->_movie)
+        return false;
+    return d->_movie->state()!=QMovie::NotRunning;
+}
+
+void QQuickAnimatedImage::setPlaying(bool play)
+{
+    Q_D(QQuickAnimatedImage);
+    if (play == d->playing)
+        return;
+    d->playing = play;
+    if (!d->_movie)
+        return;
+    if (play)
+        d->_movie->start();
+    else
+        d->_movie->stop();
+}
+
+/*!
+  \qmlproperty int QtQuick2::AnimatedImage::currentFrame
+  \qmlproperty int QtQuick2::AnimatedImage::frameCount
+
+  currentFrame is the frame that is currently visible. By monitoring this property
+  for changes, you can animate other items at the same time as the image.
+
+  frameCount is the number of frames in the animation. For some animation formats,
+  frameCount is unknown and has a value of zero.
+*/
+int QQuickAnimatedImage::currentFrame() const
+{
+    Q_D(const QQuickAnimatedImage);
+    if (!d->_movie)
+        return d->preset_currentframe;
+    return d->_movie->currentFrameNumber();
+}
+
+void QQuickAnimatedImage::setCurrentFrame(int frame)
+{
+    Q_D(QQuickAnimatedImage);
+    if (!d->_movie) {
+        d->preset_currentframe = frame;
+        return;
+    }
+    d->_movie->jumpToFrame(frame);
+}
+
+int QQuickAnimatedImage::frameCount() const
+{
+    Q_D(const QQuickAnimatedImage);
+    if (!d->_movie)
+        return 0;
+    return d->_movie->frameCount();
+}
+
+void QQuickAnimatedImage::setSource(const QUrl &url)
+{
+    Q_D(QQuickAnimatedImage);
+    if (url == d->url)
+        return;
+
+    delete d->_movie;
+    d->_movie = 0;
+
+    if (d->reply) {
+        d->reply->deleteLater();
+        d->reply = 0;
+    }
+
+    d->url = url;
+    emit sourceChanged(d->url);
+
+    if (isComponentComplete())
+        load();
+}
+
+void QQuickAnimatedImage::load()
+{
+    Q_D(QQuickAnimatedImage);
+
+    QQuickImageBase::Status oldStatus = d->status;
+    qreal oldProgress = d->progress;
+
+    if (d->url.isEmpty()) {
+        delete d->_movie;
+        d->setPixmap(QPixmap());
+        d->progress = 0;
+        d->status = Null;
+        if (d->status != oldStatus)
+            emit statusChanged(d->status);
+        if (d->progress != oldProgress)
+            emit progressChanged(d->progress);
+    } else {
+        QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(d->url);
+        if (!lf.isEmpty()) {
+            //### should be unified with movieRequestFinished
+            d->_movie = new QMovie(lf);
+            if (!d->_movie->isValid()){
+                qmlInfo(this) << "Error Reading Animated Image File " << d->url.toString();
+                delete d->_movie;
+                d->_movie = 0;
+                d->status = Error;
+                if (d->status != oldStatus)
+                    emit statusChanged(d->status);
+                return;
+            }
+            connect(d->_movie, SIGNAL(stateChanged(QMovie::MovieState)),
+                    this, SLOT(playingStatusChanged()));
+            connect(d->_movie, SIGNAL(frameChanged(int)),
+                    this, SLOT(movieUpdate()));
+            d->_movie->setCacheMode(QMovie::CacheAll);
+            if (d->playing)
+                d->_movie->start();
+            else
+                d->_movie->jumpToFrame(0);
+            if (d->paused)
+                d->_movie->setPaused(true);
+            d->setPixmap(d->_movie->currentPixmap());
+            d->status = Ready;
+            d->progress = 1.0;
+            if (d->status != oldStatus)
+                emit statusChanged(d->status);
+            if (d->progress != oldProgress)
+                emit progressChanged(d->progress);
+            return;
+        }
+
+        d->status = Loading;
+        d->progress = 0;
+        emit statusChanged(d->status);
+        emit progressChanged(d->progress);
+        QNetworkRequest req(d->url);
+        req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
+        d->reply = qmlEngine(this)->networkAccessManager()->get(req);
+        QObject::connect(d->reply, SIGNAL(finished()),
+                         this, SLOT(movieRequestFinished()));
+        QObject::connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)),
+                         this, SLOT(requestProgress(qint64,qint64)));
+    }
+}
+
+#define ANIMATEDIMAGE_MAXIMUM_REDIRECT_RECURSION 16
+
+void QQuickAnimatedImage::movieRequestFinished()
+{
+    Q_D(QQuickAnimatedImage);
+
+    d->redirectCount++;
+    if (d->redirectCount < ANIMATEDIMAGE_MAXIMUM_REDIRECT_RECURSION) {
+        QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
+        if (redirect.isValid()) {
+            QUrl url = d->reply->url().resolved(redirect.toUrl());
+            d->reply->deleteLater();
+            d->reply = 0;
+            setSource(url);
+            return;
+        }
+    }
+    d->redirectCount=0;
+
+    d->_movie = new QMovie(d->reply);
+    if (!d->_movie->isValid()){
+#ifndef QT_NO_DEBUG_STREAM
+        qmlInfo(this) << "Error Reading Animated Image File " << d->url;
+#endif
+        delete d->_movie;
+        d->_movie = 0;
+        d->status = Error;
+        emit statusChanged(d->status);
+        return;
+    }
+    connect(d->_movie, SIGNAL(stateChanged(QMovie::MovieState)),
+            this, SLOT(playingStatusChanged()));
+    connect(d->_movie, SIGNAL(frameChanged(int)),
+            this, SLOT(movieUpdate()));
+    d->_movie->setCacheMode(QMovie::CacheAll);
+    if (d->playing)
+        d->_movie->start();
+    if (d->paused || !d->playing) {
+        d->_movie->jumpToFrame(d->preset_currentframe);
+        d->preset_currentframe = 0;
+    }
+    if (d->paused)
+        d->_movie->setPaused(true);
+    d->setPixmap(d->_movie->currentPixmap());
+    d->status = Ready;
+    emit statusChanged(d->status);
+}
+
+void QQuickAnimatedImage::movieUpdate()
+{
+    Q_D(QQuickAnimatedImage);
+    d->setPixmap(d->_movie->currentPixmap());
+    emit frameChanged();
+}
+
+void QQuickAnimatedImage::playingStatusChanged()
+{
+    Q_D(QQuickAnimatedImage);
+    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) {
+        d->playing = (d->_movie->state() == QMovie::Paused);
+        emit pausedChanged();
+    }
+}
+
+void QQuickAnimatedImage::componentComplete()
+{
+    Q_D(QQuickAnimatedImage);
+    QQuickItem::componentComplete(); // NOT QQuickImage
+    if (d->url.isValid())
+        load();
+    if (!d->reply) {
+        setCurrentFrame(d->preset_currentframe);
+        d->preset_currentframe = 0;
+    }
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_MOVIE
diff --git a/src/declarative/items/qquickanimatedimage_p.h b/src/declarative/items/qquickanimatedimage_p.h
new file mode 100644 (file)
index 0000000..ae96e4c
--- /dev/null
@@ -0,0 +1,117 @@
+// Commit: 80d0fe9cbd92288a08d5ced8767f1edb651dae37
+/****************************************************************************
+**
+** 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 QQUICKANIMATEDIMAGE_P_H
+#define QQUICKANIMATEDIMAGE_P_H
+
+#include "qquickimage_p.h"
+
+#ifndef QT_NO_MOVIE
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QMovie;
+class QQuickAnimatedImagePrivate;
+
+class Q_AUTOTEST_EXPORT QQuickAnimatedImage : public QQuickImage
+{
+    Q_OBJECT
+
+    Q_PROPERTY(bool playing READ isPlaying WRITE setPlaying NOTIFY playingChanged)
+    Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged)
+    Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY frameChanged)
+    Q_PROPERTY(int frameCount READ frameCount)
+
+    // read-only for AnimatedImage
+    Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged)
+
+public:
+    QQuickAnimatedImage(QQuickItem *parent=0);
+    ~QQuickAnimatedImage();
+
+    bool isPlaying() const;
+    void setPlaying(bool play);
+
+    bool isPaused() const;
+    void setPaused(bool pause);
+
+    int currentFrame() const;
+    void setCurrentFrame(int frame);
+
+    int frameCount() const;
+
+    // Extends QQuickImage's src property*/
+    virtual void setSource(const QUrl&);
+
+Q_SIGNALS:
+    void playingChanged();
+    void pausedChanged();
+    void frameChanged();
+    void sourceSizeChanged();
+
+private Q_SLOTS:
+    void movieUpdate();
+    void movieRequestFinished();
+    void playingStatusChanged();
+
+protected:
+    virtual void load();
+    void componentComplete();
+
+private:
+    Q_DISABLE_COPY(QQuickAnimatedImage)
+    Q_DECLARE_PRIVATE(QQuickAnimatedImage)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickAnimatedImage)
+
+QT_END_HEADER
+
+#endif // QT_NO_MOVIE
+
+#endif // QQUICKANIMATEDIMAGE_P_H
diff --git a/src/declarative/items/qquickanimatedimage_p_p.h b/src/declarative/items/qquickanimatedimage_p_p.h
new file mode 100644 (file)
index 0000000..0d5dd4a
--- /dev/null
@@ -0,0 +1,88 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
+/****************************************************************************
+**
+** 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 QQUICKANIMATEDIMAGE_P_P_H
+#define QQUICKANIMATEDIMAGE_P_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 "qquickimage_p_p.h"
+
+#ifndef QT_NO_MOVIE
+
+QT_BEGIN_NAMESPACE
+
+class QMovie;
+class QNetworkReply;
+
+class QQuickAnimatedImagePrivate : public QQuickImagePrivate
+{
+    Q_DECLARE_PUBLIC(QQuickAnimatedImage)
+
+public:
+    QQuickAnimatedImagePrivate()
+      : playing(true), paused(false), preset_currentframe(0), _movie(0), reply(0), redirectCount(0)
+    {
+    }
+
+    bool playing;
+    bool paused;
+    int preset_currentframe;
+    QMovie *_movie;
+    QNetworkReply *reply;
+    int redirectCount;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_MOVIE
+
+#endif // QQUICKANIMATEDIMAGE_P_P_H
diff --git a/src/declarative/items/qquickanimation.cpp b/src/declarative/items/qquickanimation.cpp
new file mode 100644 (file)
index 0000000..55eb4e2
--- /dev/null
@@ -0,0 +1,792 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qquickanimation_p.h"
+#include "qquickanimation_p_p.h"
+#include "qquickstateoperations_p.h"
+
+#include <private/qdeclarativeproperty_p.h>
+#include <private/qdeclarativepath_p.h>
+
+#include <QtDeclarative/qdeclarativeinfo.h>
+#include <QtCore/qmath.h>
+#include <QtCore/qsequentialanimationgroup.h>
+#include <QtCore/qparallelanimationgroup.h>
+#include <QtGui/qtransform.h>
+
+QT_BEGIN_NAMESPACE
+
+QQuickParentAnimation::QQuickParentAnimation(QObject *parent)
+    : QDeclarativeAnimationGroup(*(new QQuickParentAnimationPrivate), parent)
+{
+    Q_D(QQuickParentAnimation);
+    d->topLevelGroup = new QSequentialAnimationGroup;
+    QDeclarative_setParent_noEvent(d->topLevelGroup, this);
+
+    d->startAction = new QActionAnimation;
+    QDeclarative_setParent_noEvent(d->startAction, d->topLevelGroup);
+    d->topLevelGroup->addAnimation(d->startAction);
+
+    d->ag = new QParallelAnimationGroup;
+    QDeclarative_setParent_noEvent(d->ag, d->topLevelGroup);
+    d->topLevelGroup->addAnimation(d->ag);
+
+    d->endAction = new QActionAnimation;
+    QDeclarative_setParent_noEvent(d->endAction, d->topLevelGroup);
+    d->topLevelGroup->addAnimation(d->endAction);
+}
+
+QQuickParentAnimation::~QQuickParentAnimation()
+{
+}
+
+QQuickItem *QQuickParentAnimation::target() const
+{
+    Q_D(const QQuickParentAnimation);
+    return d->target;
+}
+
+void QQuickParentAnimation::setTarget(QQuickItem *target)
+{
+    Q_D(QQuickParentAnimation);
+    if (target == d->target)
+        return;
+
+    d->target = target;
+    emit targetChanged();
+}
+
+QQuickItem *QQuickParentAnimation::newParent() const
+{
+    Q_D(const QQuickParentAnimation);
+    return d->newParent;
+}
+
+void QQuickParentAnimation::setNewParent(QQuickItem *newParent)
+{
+    Q_D(QQuickParentAnimation);
+    if (newParent == d->newParent)
+        return;
+
+    d->newParent = newParent;
+    emit newParentChanged();
+}
+
+QQuickItem *QQuickParentAnimation::via() const
+{
+    Q_D(const QQuickParentAnimation);
+    return d->via;
+}
+
+void QQuickParentAnimation::setVia(QQuickItem *via)
+{
+    Q_D(QQuickParentAnimation);
+    if (via == d->via)
+        return;
+
+    d->via = via;
+    emit viaChanged();
+}
+
+//### mirrors same-named function in QQuickItem
+QPointF QQuickParentAnimationPrivate::computeTransformOrigin(QQuickItem::TransformOrigin origin, qreal width, qreal height) const
+{
+    switch (origin) {
+    default:
+    case QQuickItem::TopLeft:
+        return QPointF(0, 0);
+    case QQuickItem::Top:
+        return QPointF(width / 2., 0);
+    case QQuickItem::TopRight:
+        return QPointF(width, 0);
+    case QQuickItem::Left:
+        return QPointF(0, height / 2.);
+    case QQuickItem::Center:
+        return QPointF(width / 2., height / 2.);
+    case QQuickItem::Right:
+        return QPointF(width, height / 2.);
+    case QQuickItem::BottomLeft:
+        return QPointF(0, height);
+    case QQuickItem::Bottom:
+        return QPointF(width / 2., height);
+    case QQuickItem::BottomRight:
+        return QPointF(width, height);
+    }
+}
+
+void QQuickParentAnimation::transition(QDeclarativeStateActions &actions,
+                        QDeclarativeProperties &modified,
+                        TransitionDirection direction)
+{
+    Q_D(QQuickParentAnimation);
+
+    struct QQuickParentAnimationData : public QAbstractAnimationAction
+    {
+        QQuickParentAnimationData() {}
+        ~QQuickParentAnimationData() { qDeleteAll(pc); }
+
+        QDeclarativeStateActions actions;
+        //### reverse should probably apply on a per-action basis
+        bool reverse;
+        QList<QQuickParentChange *> pc;
+        virtual void doAction()
+        {
+            for (int ii = 0; ii < actions.count(); ++ii) {
+                const QDeclarativeAction &action = actions.at(ii);
+                if (reverse)
+                    action.event->reverse();
+                else
+                    action.event->execute();
+            }
+        }
+    };
+
+    QQuickParentAnimationData *data = new QQuickParentAnimationData;
+    QQuickParentAnimationData *viaData = new QQuickParentAnimationData;
+
+    bool hasExplicit = false;
+    if (d->target && d->newParent) {
+        data->reverse = false;
+        QDeclarativeAction myAction;
+        QQuickParentChange *pc = new QQuickParentChange;
+        pc->setObject(d->target);
+        pc->setParent(d->newParent);
+        myAction.event = pc;
+        data->pc << pc;
+        data->actions << myAction;
+        hasExplicit = true;
+        if (d->via) {
+            viaData->reverse = false;
+            QDeclarativeAction myVAction;
+            QQuickParentChange *vpc = new QQuickParentChange;
+            vpc->setObject(d->target);
+            vpc->setParent(d->via);
+            myVAction.event = vpc;
+            viaData->pc << vpc;
+            viaData->actions << myVAction;
+        }
+        //### once actions have concept of modified,
+        //    loop to match appropriate ParentChanges and mark as modified
+    }
+
+    if (!hasExplicit)
+    for (int i = 0; i < actions.size(); ++i) {
+        QDeclarativeAction &action = actions[i];
+        if (action.event && action.event->typeName() == QLatin1String("ParentChange")
+            && (!d->target || static_cast<QQuickParentChange*>(action.event)->object() == d->target)) {
+
+            QQuickParentChange *pc = static_cast<QQuickParentChange*>(action.event);
+            QDeclarativeAction myAction = action;
+            data->reverse = action.reverseEvent;
+
+            //### this logic differs from PropertyAnimation
+            //    (probably a result of modified vs. done)
+            if (d->newParent) {
+                QQuickParentChange *epc = new QQuickParentChange;
+                epc->setObject(static_cast<QQuickParentChange*>(action.event)->object());
+                epc->setParent(d->newParent);
+                myAction.event = epc;
+                data->pc << epc;
+                data->actions << myAction;
+                pc = epc;
+            } else {
+                action.actionDone = true;
+                data->actions << myAction;
+            }
+
+            if (d->via) {
+                viaData->reverse = false;
+                QDeclarativeAction myAction;
+                QQuickParentChange *vpc = new QQuickParentChange;
+                vpc->setObject(pc->object());
+                vpc->setParent(d->via);
+                myAction.event = vpc;
+                viaData->pc << vpc;
+                viaData->actions << myAction;
+                QDeclarativeAction dummyAction;
+                QDeclarativeAction &xAction = pc->xIsSet() && i < actions.size()-1 ? actions[++i] : dummyAction;
+                QDeclarativeAction &yAction = pc->yIsSet() && i < actions.size()-1 ? actions[++i] : dummyAction;
+                QDeclarativeAction &sAction = pc->scaleIsSet() && i < actions.size()-1 ? actions[++i] : dummyAction;
+                QDeclarativeAction &rAction = pc->rotationIsSet() && i < actions.size()-1 ? actions[++i] : dummyAction;
+                QQuickItem *target = pc->object();
+                QQuickItem *targetParent = action.reverseEvent ? pc->originalParent() : pc->parent();
+
+                //### this mirrors the logic in QQuickParentChange.
+                bool ok;
+                const QTransform &transform = targetParent->itemTransform(d->via, &ok);
+                if (transform.type() >= QTransform::TxShear || !ok) {
+                    qmlInfo(this) << QQuickParentAnimation::tr("Unable to preserve appearance under complex transform");
+                    ok = false;
+                }
+
+                qreal scale = 1;
+                qreal rotation = 0;
+                bool isRotate = (transform.type() == QTransform::TxRotate) || (transform.m11() < 0);
+                if (ok && !isRotate) {
+                    if (transform.m11() == transform.m22())
+                        scale = transform.m11();
+                    else {
+                        qmlInfo(this) << QQuickParentAnimation::tr("Unable to preserve appearance under non-uniform scale");
+                        ok = false;
+                    }
+                } else if (ok && isRotate) {
+                    if (transform.m11() == transform.m22())
+                        scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12());
+                    else {
+                        qmlInfo(this) << QQuickParentAnimation::tr("Unable to preserve appearance under non-uniform scale");
+                        ok = false;
+                    }
+
+                    if (scale != 0)
+                        rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
+                    else {
+                        qmlInfo(this) << QQuickParentAnimation::tr("Unable to preserve appearance under scale of 0");
+                        ok = false;
+                    }
+                }
+
+                const QPointF &point = transform.map(QPointF(xAction.toValue.toReal(),yAction.toValue.toReal()));
+                qreal x = point.x();
+                qreal y = point.y();
+                if (ok && target->transformOrigin() != QQuickItem::TopLeft) {
+                    qreal w = target->width();
+                    qreal h = target->height();
+                    if (pc->widthIsSet() && i < actions.size() - 1)
+                        w = actions[++i].toValue.toReal();
+                    if (pc->heightIsSet() && i < actions.size() - 1)
+                        h = actions[++i].toValue.toReal();
+                    const QPointF &transformOrigin
+                            = d->computeTransformOrigin(target->transformOrigin(), w,h);
+                    qreal tempxt = transformOrigin.x();
+                    qreal tempyt = transformOrigin.y();
+                    QTransform t;
+                    t.translate(-tempxt, -tempyt);
+                    t.rotate(rotation);
+                    t.scale(scale, scale);
+                    t.translate(tempxt, tempyt);
+                    const QPointF &offset = t.map(QPointF(0,0));
+                    x += offset.x();
+                    y += offset.y();
+                }
+
+                if (ok) {
+                    //qDebug() << x << y << rotation << scale;
+                    xAction.toValue = x;
+                    yAction.toValue = y;
+                    sAction.toValue = sAction.toValue.toReal() * scale;
+                    rAction.toValue = rAction.toValue.toReal() + rotation;
+                }
+            }
+        }
+    }
+
+    if (data->actions.count()) {
+        if (direction == QDeclarativeAbstractAnimation::Forward) {
+            d->startAction->setAnimAction(d->via ? viaData : data, QActionAnimation::DeleteWhenStopped);
+            d->endAction->setAnimAction(d->via ? data : 0, QActionAnimation::DeleteWhenStopped);
+        } else {
+            d->endAction->setAnimAction(d->via ? viaData : data, QActionAnimation::DeleteWhenStopped);
+            d->startAction->setAnimAction(d->via ? data : 0, QActionAnimation::DeleteWhenStopped);
+        }
+    } else {
+        delete data;
+        delete viaData;
+    }
+
+    //take care of any child animations
+    bool valid = d->defaultProperty.isValid();
+    for (int ii = 0; ii < d->animations.count(); ++ii) {
+        if (valid)
+            d->animations.at(ii)->setDefaultTarget(d->defaultProperty);
+        d->animations.at(ii)->transition(actions, modified, direction);
+    }
+
+}
+
+QAbstractAnimation *QQuickParentAnimation::qtAnimation()
+{
+    Q_D(QQuickParentAnimation);
+    return d->topLevelGroup;
+}
+
+QQuickAnchorAnimation::QQuickAnchorAnimation(QObject *parent)
+: QDeclarativeAbstractAnimation(*(new QQuickAnchorAnimationPrivate), parent)
+{
+    Q_D(QQuickAnchorAnimation);
+    d->va = new QDeclarativeBulkValueAnimator;
+    QDeclarative_setParent_noEvent(d->va, this);
+}
+
+QQuickAnchorAnimation::~QQuickAnchorAnimation()
+{
+}
+
+QAbstractAnimation *QQuickAnchorAnimation::qtAnimation()
+{
+    Q_D(QQuickAnchorAnimation);
+    return d->va;
+}
+
+QDeclarativeListProperty<QQuickItem> QQuickAnchorAnimation::targets()
+{
+    Q_D(QQuickAnchorAnimation);
+    return QDeclarativeListProperty<QQuickItem>(this, d->targets);
+}
+
+int QQuickAnchorAnimation::duration() const
+{
+    Q_D(const QQuickAnchorAnimation);
+    return d->va->duration();
+}
+
+void QQuickAnchorAnimation::setDuration(int duration)
+{
+    if (duration < 0) {
+        qmlInfo(this) << tr("Cannot set a duration of < 0");
+        return;
+    }
+
+    Q_D(QQuickAnchorAnimation);
+    if (d->va->duration() == duration)
+        return;
+    d->va->setDuration(duration);
+    emit durationChanged(duration);
+}
+
+QEasingCurve QQuickAnchorAnimation::easing() const
+{
+    Q_D(const QQuickAnchorAnimation);
+    return d->va->easingCurve();
+}
+
+void QQuickAnchorAnimation::setEasing(const QEasingCurve &e)
+{
+    Q_D(QQuickAnchorAnimation);
+    if (d->va->easingCurve() == e)
+        return;
+
+    d->va->setEasingCurve(e);
+    emit easingChanged(e);
+}
+
+void QQuickAnchorAnimation::transition(QDeclarativeStateActions &actions,
+                        QDeclarativeProperties &modified,
+                        TransitionDirection direction)
+{
+    Q_UNUSED(modified);
+    Q_D(QQuickAnchorAnimation);
+    QDeclarativeAnimationPropertyUpdater *data = new QDeclarativeAnimationPropertyUpdater;
+    data->interpolatorType = QMetaType::QReal;
+    data->interpolator = d->interpolator;
+
+    data->reverse = direction == Backward ? true : false;
+    data->fromSourced = false;
+    data->fromDefined = false;
+
+    for (int ii = 0; ii < actions.count(); ++ii) {
+        QDeclarativeAction &action = actions[ii];
+        if (action.event && action.event->typeName() == QLatin1String("AnchorChanges")
+            && (d->targets.isEmpty() || d->targets.contains(static_cast<QQuickAnchorChanges*>(action.event)->object()))) {
+            data->actions << static_cast<QQuickAnchorChanges*>(action.event)->additionalActions();
+        }
+    }
+
+    if (data->actions.count()) {
+        if (!d->rangeIsSet) {
+            d->va->setStartValue(qreal(0));
+            d->va->setEndValue(qreal(1));
+            d->rangeIsSet = true;
+        }
+        d->va->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped);
+        d->va->setFromSourcedValue(&data->fromSourced);
+    } else {
+        delete data;
+    }
+}
+
+QQuickPathAnimation::QQuickPathAnimation(QObject *parent)
+: QDeclarativeAbstractAnimation(*(new QQuickPathAnimationPrivate), parent)
+{
+    Q_D(QQuickPathAnimation);
+    d->pa = new QDeclarativeBulkValueAnimator;
+    QDeclarative_setParent_noEvent(d->pa, this);
+}
+
+QQuickPathAnimation::~QQuickPathAnimation()
+{
+}
+
+int QQuickPathAnimation::duration() const
+{
+    Q_D(const QQuickPathAnimation);
+    return d->pa->duration();
+}
+
+void QQuickPathAnimation::setDuration(int duration)
+{
+    if (duration < 0) {
+        qmlInfo(this) << tr("Cannot set a duration of < 0");
+        return;
+    }
+
+    Q_D(QQuickPathAnimation);
+    if (d->pa->duration() == duration)
+        return;
+    d->pa->setDuration(duration);
+    emit durationChanged(duration);
+}
+
+QEasingCurve QQuickPathAnimation::easing() const
+{
+    Q_D(const QQuickPathAnimation);
+    return d->pa->easingCurve();
+}
+
+void QQuickPathAnimation::setEasing(const QEasingCurve &e)
+{
+    Q_D(QQuickPathAnimation);
+    if (d->pa->easingCurve() == e)
+        return;
+
+    d->pa->setEasingCurve(e);
+    emit easingChanged(e);
+}
+
+QDeclarativePath *QQuickPathAnimation::path() const
+{
+    Q_D(const QQuickPathAnimation);
+    return d->path;
+}
+
+void QQuickPathAnimation::setPath(QDeclarativePath *path)
+{
+    Q_D(QQuickPathAnimation);
+    if (d->path == path)
+        return;
+
+    d->path = path;
+    emit pathChanged();
+}
+
+QQuickItem *QQuickPathAnimation::target() const
+{
+    Q_D(const QQuickPathAnimation);
+    return d->target;
+}
+
+void QQuickPathAnimation::setTarget(QQuickItem *target)
+{
+    Q_D(QQuickPathAnimation);
+    if (d->target == target)
+        return;
+
+    d->target = target;
+    emit targetChanged();
+}
+
+QQuickPathAnimation::Orientation QQuickPathAnimation::orientation() const
+{
+    Q_D(const QQuickPathAnimation);
+    return d->orientation;
+}
+
+void QQuickPathAnimation::setOrientation(Orientation orientation)
+{
+    Q_D(QQuickPathAnimation);
+    if (d->orientation == orientation)
+        return;
+
+    d->orientation = orientation;
+    emit orientationChanged(d->orientation);
+}
+
+QPointF QQuickPathAnimation::anchorPoint() const
+{
+    Q_D(const QQuickPathAnimation);
+    return d->anchorPoint;
+}
+
+void QQuickPathAnimation::setAnchorPoint(const QPointF &point)
+{
+    Q_D(QQuickPathAnimation);
+    if (d->anchorPoint == point)
+        return;
+
+    d->anchorPoint = point;
+    emit anchorPointChanged(point);
+}
+
+qreal QQuickPathAnimation::orientationEntryInterval() const
+{
+    Q_D(const QQuickPathAnimation);
+    return d->entryInterval;
+}
+
+void QQuickPathAnimation::setOrientationEntryInterval(qreal interval)
+{
+    Q_D(QQuickPathAnimation);
+    if (d->entryInterval == interval)
+        return;
+    d->entryInterval = interval;
+    emit orientationEntryIntervalChanged(interval);
+}
+
+qreal QQuickPathAnimation::orientationExitInterval() const
+{
+    Q_D(const QQuickPathAnimation);
+    return d->exitInterval;
+}
+
+void QQuickPathAnimation::setOrientationExitInterval(qreal interval)
+{
+    Q_D(QQuickPathAnimation);
+    if (d->exitInterval == interval)
+        return;
+    d->exitInterval = interval;
+    emit orientationExitIntervalChanged(interval);
+}
+
+qreal QQuickPathAnimation::endRotation() const
+{
+    Q_D(const QQuickPathAnimation);
+    return d->endRotation.isNull ? qreal(0) : d->endRotation.value;
+}
+
+void QQuickPathAnimation::setEndRotation(qreal rotation)
+{
+    Q_D(QQuickPathAnimation);
+    if (!d->endRotation.isNull && d->endRotation == rotation)
+        return;
+
+    d->endRotation = rotation;
+    emit endRotationChanged(d->endRotation);
+}
+
+
+QAbstractAnimation *QQuickPathAnimation::qtAnimation()
+{
+    Q_D(QQuickPathAnimation);
+    return d->pa;
+}
+
+void QQuickPathAnimation::transition(QDeclarativeStateActions &actions,
+                                           QDeclarativeProperties &modified,
+                                           TransitionDirection direction)
+{
+    Q_D(QQuickPathAnimation);
+    QQuickPathAnimationUpdater *data = new QQuickPathAnimationUpdater;
+
+    data->orientation = d->orientation;
+    data->anchorPoint = d->anchorPoint;
+    data->entryInterval = d->entryInterval;
+    data->exitInterval = d->exitInterval;
+    data->endRotation = d->endRotation;
+    data->reverse = direction == Backward ? true : false;
+    data->fromSourced = false;
+    data->fromDefined = (d->path && d->path->hasStartX() && d->path->hasStartY()) ? true : false;
+    data->toDefined = d->path ? d->path->hasEnd() : false;
+    int origModifiedSize = modified.count();
+
+    for (int i = 0; i < actions.count(); ++i) {
+        QDeclarativeAction &action = actions[i];
+        if (action.event)
+            continue;
+        if (action.specifiedObject == d->target && action.property.name() == QLatin1String("x")) {
+            data->toX = action.toValue.toReal();
+            modified << action.property;
+            action.fromValue = action.toValue;
+        }
+        if (action.specifiedObject == d->target && action.property.name() == QLatin1String("y")) {
+            data->toY = action.toValue.toReal();
+            modified << action.property;
+            action.fromValue = action.toValue;
+        }
+    }
+
+    if (d->target && d->path &&
+        (modified.count() > origModifiedSize || data->toDefined)) {
+        data->target = d->target;
+        data->path = d->path;
+        if (!d->rangeIsSet) {
+            d->pa->setStartValue(qreal(0));
+            d->pa->setEndValue(qreal(1));
+            d->rangeIsSet = true;
+        }
+        /*
+            NOTE: The following block relies on the fact that the previous value hasn't
+            yet been deleted, and has the same target, etc, which may be a bit fragile.
+         */
+        if (d->pa->getAnimValue()) {
+            QQuickPathAnimationUpdater *prevData = static_cast<QQuickPathAnimationUpdater*>(d->pa->getAnimValue());
+
+            // get the original start angle that was used (so we can exactly reverse).
+            data->startRotation = prevData->startRotation;
+
+            // treat interruptions specially, otherwise we end up with strange paths
+            if ((data->reverse || prevData->reverse) && prevData->currentV > 0 && prevData->currentV < 1) {
+                if (!data->fromDefined && !data->toDefined && !prevData->painterPath.isEmpty()) {
+                    QPointF pathPos = QDeclarativePath::sequentialPointAt(prevData->painterPath, prevData->pathLength, prevData->attributePoints, prevData->prevBez, prevData->currentV);
+                    if (!prevData->anchorPoint.isNull())
+                        pathPos -= prevData->anchorPoint;
+                    if (pathPos == data->target->pos()) {   //only treat as interruption if we interrupted ourself
+                        data->painterPath = prevData->painterPath;
+                        data->toDefined = data->fromDefined = data->fromSourced = true;
+                        data->prevBez.isValid = false;
+                        data->interruptStart = prevData->currentV;
+                        data->startRotation = prevData->startRotation;
+                        data->pathLength = prevData->pathLength;
+                        data->attributePoints = prevData->attributePoints;
+                    }
+                }
+            }
+        }
+        d->pa->setFromSourcedValue(&data->fromSourced);
+        d->pa->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped);
+    } else {
+        d->pa->setFromSourcedValue(0);
+        d->pa->setAnimValue(0, QAbstractAnimation::DeleteWhenStopped);
+        delete data;
+    }
+}
+
+void QQuickPathAnimationUpdater::setValue(qreal v)
+{
+    if (interruptStart.isValid()) {
+        if (reverse)
+            v = 1 - v;
+        qreal end = reverse ? 0.0 : 1.0;
+        v = interruptStart + v * (end-interruptStart);
+    }
+    currentV = v;
+    bool atStart = ((reverse && v == 1.0) || (!reverse && v == 0.0));
+    if (!fromSourced && (!fromDefined || !toDefined)) {
+        qreal startX = reverse ? toX + anchorPoint.x() : target->x() + anchorPoint.x();
+        qreal startY = reverse ? toY + anchorPoint.y() : target->y() + anchorPoint.y();
+        qreal endX = reverse ? target->x() + anchorPoint.x() : toX + anchorPoint.x();
+        qreal endY = reverse ? target->y() + anchorPoint.y() : toY + anchorPoint.y();
+
+        prevBez.isValid = false;
+        painterPath = path->createPath(QPointF(startX, startY), QPointF(endX, endY), QStringList(), pathLength, attributePoints);
+        fromSourced = true;
+    }
+
+    qreal angle;
+    bool fixed = orientation == QQuickPathAnimation::Fixed;
+    QPointF currentPos = !painterPath.isEmpty() ? path->sequentialPointAt(painterPath, pathLength, attributePoints, prevBez, v, fixed ? 0 : &angle) : path->sequentialPointAt(v, fixed ? 0 : &angle);
+
+    //adjust position according to anchor point
+    if (!anchorPoint.isNull()) {
+        currentPos -= anchorPoint;
+        if (atStart) {
+            if (!anchorPoint.isNull() && !fixed)
+                target->setTransformOriginPoint(anchorPoint);
+        }
+    }
+
+    //### could cache properties rather than reconstructing each time
+    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) {
+        switch (orientation) {
+            case QQuickPathAnimation::RightFirst:
+                angle = -angle;
+                break;
+            case QQuickPathAnimation::TopFirst:
+                angle = -angle + 90;
+                break;
+            case QQuickPathAnimation::LeftFirst:
+                angle = -angle + 180;
+                break;
+            case QQuickPathAnimation::BottomFirst:
+                angle = -angle + 270;
+                break;
+            default:
+                angle = 0;
+                break;
+        }
+
+        if (atStart && !reverse) {
+            startRotation = target->rotation();
+
+            //shortest distance to correct orientation
+            qreal diff = angle - startRotation;
+            while (diff > 180.0) {
+                startRotation.value += 360.0;
+                diff -= 360.0;
+            }
+            while (diff < -180.0) {
+                startRotation.value -= 360.0;
+                diff += 360.0;
+            }
+        }
+
+        //smoothly transition to the desired orientation
+        if (startRotation.isValid()) {
+            if (reverse && v == 0.0)
+                angle = startRotation;
+            else if (v < entryInterval)
+                angle = angle * v / entryInterval + startRotation * (entryInterval - v) / entryInterval;
+        }
+        if (endRotation.isValid()) {
+            qreal exitStart = 1 - exitInterval;
+            if (!reverse && v == 1.0)
+                angle = endRotation;
+            else if (v > exitStart)
+                angle = endRotation * (v - exitStart) / exitInterval + angle * (exitInterval - (v - exitStart)) / exitInterval;
+        }
+        QDeclarativePropertyPrivate::write(QDeclarativeProperty(target, QStringLiteral("rotation")), angle, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
+    }
+
+    /*
+        NOTE: we don't always reset the transform origin, as it can cause a
+        visual jump if ending on an angle. This means that in some cases
+        (anchor point and orientation both specified, and ending at an angle)
+        the transform origin will always be set after running the path animation.
+     */
+    if ((reverse && v == 0.0) || (!reverse && v == 1.0)) {
+        if (!anchorPoint.isNull() && !fixed && qFuzzyIsNull(angle))
+            target->setTransformOriginPoint(QPointF());
+    }
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickanimation_p.h b/src/declarative/items/qquickanimation_p.h
new file mode 100644 (file)
index 0000000..2ce7224
--- /dev/null
@@ -0,0 +1,209 @@
+// Commit: e39a2e39451bf106a9845f8a60fc571faaa4dde5
+/****************************************************************************
+**
+** 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 QQUICKANIMATION_H
+#define QQUICKANIMATION_H
+
+#include "qquickitem.h"
+
+#include <private/qdeclarativeanimation_p.h>
+
+#include <QtCore/qabstractanimation.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickParentAnimationPrivate;
+class QQuickParentAnimation : public QDeclarativeAnimationGroup
+{
+    Q_OBJECT
+    Q_DECLARE_PRIVATE(QQuickParentAnimation)
+
+    Q_PROPERTY(QQuickItem *target READ target WRITE setTarget NOTIFY targetChanged)
+    Q_PROPERTY(QQuickItem *newParent READ newParent WRITE setNewParent NOTIFY newParentChanged)
+    Q_PROPERTY(QQuickItem *via READ via WRITE setVia NOTIFY viaChanged)
+
+public:
+    QQuickParentAnimation(QObject *parent=0);
+    virtual ~QQuickParentAnimation();
+
+    QQuickItem *target() const;
+    void setTarget(QQuickItem *);
+
+    QQuickItem *newParent() const;
+    void setNewParent(QQuickItem *);
+
+    QQuickItem *via() const;
+    void setVia(QQuickItem *);
+
+Q_SIGNALS:
+    void targetChanged();
+    void newParentChanged();
+    void viaChanged();
+
+protected:
+    virtual void transition(QDeclarativeStateActions &actions,
+                            QDeclarativeProperties &modified,
+                            TransitionDirection direction);
+    virtual QAbstractAnimation *qtAnimation();
+};
+
+class QQuickAnchorAnimationPrivate;
+class QQuickAnchorAnimation : public QDeclarativeAbstractAnimation
+{
+    Q_OBJECT
+    Q_DECLARE_PRIVATE(QQuickAnchorAnimation)
+    Q_PROPERTY(QDeclarativeListProperty<QQuickItem> targets READ targets)
+    Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
+    Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged)
+
+public:
+    QQuickAnchorAnimation(QObject *parent=0);
+    virtual ~QQuickAnchorAnimation();
+
+    QDeclarativeListProperty<QQuickItem> targets();
+
+    int duration() const;
+    void setDuration(int);
+
+    QEasingCurve easing() const;
+    void setEasing(const QEasingCurve &);
+
+Q_SIGNALS:
+    void durationChanged(int);
+    void easingChanged(const QEasingCurve&);
+
+protected:
+    virtual void transition(QDeclarativeStateActions &actions,
+                            QDeclarativeProperties &modified,
+                            TransitionDirection direction);
+    virtual QAbstractAnimation *qtAnimation();
+};
+
+class QQuickItem;
+class QDeclarativePath;
+class QQuickPathAnimationPrivate;
+class Q_AUTOTEST_EXPORT QQuickPathAnimation : public QDeclarativeAbstractAnimation
+{
+    Q_OBJECT
+    Q_DECLARE_PRIVATE(QQuickPathAnimation)
+
+    Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
+    Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged)
+    Q_PROPERTY(QDeclarativePath *path READ path WRITE setPath NOTIFY pathChanged)
+    Q_PROPERTY(QQuickItem *target READ target WRITE setTarget NOTIFY targetChanged)
+    Q_PROPERTY(Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged)
+    Q_PROPERTY(QPointF anchorPoint READ anchorPoint WRITE setAnchorPoint NOTIFY anchorPointChanged)
+    Q_PROPERTY(qreal orientationEntryInterval READ orientationEntryInterval WRITE setOrientationEntryInterval NOTIFY orientationEntryIntervalChanged)
+    Q_PROPERTY(qreal orientationExitInterval READ orientationExitInterval WRITE setOrientationExitInterval NOTIFY orientationExitIntervalChanged)
+    Q_PROPERTY(qreal endRotation READ endRotation WRITE setEndRotation NOTIFY endRotationChanged)
+
+public:
+    QQuickPathAnimation(QObject *parent=0);
+    virtual ~QQuickPathAnimation();
+
+    enum Orientation {
+        Fixed,
+        RightFirst,
+        LeftFirst,
+        BottomFirst,
+        TopFirst
+    };
+    Q_ENUMS(Orientation)
+
+    int duration() const;
+    void setDuration(int);
+
+    QEasingCurve easing() const;
+    void setEasing(const QEasingCurve &);
+
+    QDeclarativePath *path() const;
+    void setPath(QDeclarativePath *);
+
+    QQuickItem *target() const;
+    void setTarget(QQuickItem *);
+
+    Orientation orientation() const;
+    void setOrientation(Orientation orientation);
+
+    QPointF anchorPoint() const;
+    void setAnchorPoint(const QPointF &point);
+
+    qreal orientationEntryInterval() const;
+    void setOrientationEntryInterval(qreal);
+
+    qreal orientationExitInterval() const;
+    void setOrientationExitInterval(qreal);
+
+    qreal endRotation() const;
+    void setEndRotation(qreal);
+
+protected:
+    virtual void transition(QDeclarativeStateActions &actions,
+                            QDeclarativeProperties &modified,
+                            TransitionDirection direction);
+    virtual QAbstractAnimation *qtAnimation();
+
+Q_SIGNALS:
+    void durationChanged(int);
+    void easingChanged(const QEasingCurve &);
+    void pathChanged();
+    void targetChanged();
+    void orientationChanged(Orientation);
+    void anchorPointChanged(const QPointF &);
+    void orientationEntryIntervalChanged(qreal);
+    void orientationExitIntervalChanged(qreal);
+    void endRotationChanged(qreal);
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickParentAnimation)
+QML_DECLARE_TYPE(QQuickAnchorAnimation)
+QML_DECLARE_TYPE(QQuickPathAnimation)
+
+QT_END_HEADER
+
+#endif // QQUICKANIMATION_H
diff --git a/src/declarative/items/qquickanimation_p_p.h b/src/declarative/items/qquickanimation_p_p.h
new file mode 100644 (file)
index 0000000..de2b6d4
--- /dev/null
@@ -0,0 +1,153 @@
+// Commit: 0ade09152067324f74678f2de4d447b6e0280600
+/****************************************************************************
+**
+** 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 QQUICKANIMATION_P_H
+#define QQUICKANIMATION_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 "qquickanimation_p.h"
+
+#include <private/qdeclarativepath_p.h>
+#include <private/qdeclarativeanimation_p_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickParentAnimationPrivate : public QDeclarativeAnimationGroupPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickParentAnimation)
+public:
+    QQuickParentAnimationPrivate()
+    : QDeclarativeAnimationGroupPrivate(), target(0), newParent(0),
+       via(0), topLevelGroup(0), startAction(0), endAction(0) {}
+
+    QQuickItem *target;
+    QQuickItem *newParent;
+    QQuickItem *via;
+
+    QSequentialAnimationGroup *topLevelGroup;
+    QActionAnimation *startAction;
+    QActionAnimation *endAction;
+
+    QPointF computeTransformOrigin(QQuickItem::TransformOrigin origin, qreal width, qreal height) const;
+};
+
+class QQuickAnchorAnimationPrivate : public QDeclarativeAbstractAnimationPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickAnchorAnimation)
+public:
+    QQuickAnchorAnimationPrivate() : rangeIsSet(false), va(0),
+        interpolator(QVariantAnimationPrivate::getInterpolator(QMetaType::QReal)) {}
+
+    bool rangeIsSet;
+    QDeclarativeBulkValueAnimator *va;
+    QVariantAnimation::Interpolator interpolator;
+    QList<QQuickItem*> targets;
+};
+
+class QQuickPathAnimationUpdater : public QDeclarativeBulkValueUpdater
+{
+public:
+    QQuickPathAnimationUpdater() : path(0), target(0), reverse(false),
+        fromSourced(false), fromDefined(false), toDefined(false),
+        toX(0), toY(0), currentV(0), orientation(QQuickPathAnimation::Fixed),
+        entryInterval(0), exitInterval(0) {}
+    ~QQuickPathAnimationUpdater() {}
+
+        void setValue(qreal v);
+
+    QDeclarativePath *path;
+
+    QPainterPath painterPath;
+    QDeclarativeCachedBezier prevBez;
+    qreal pathLength;
+    QList<QDeclarativePath::AttributePoint> attributePoints;
+
+    QQuickItem *target;
+    bool reverse;
+    bool fromSourced;
+    bool fromDefined;
+    bool toDefined;
+    qreal toX;
+    qreal toY;
+    qreal currentV;
+    QDeclarativeNullableValue<qreal> interruptStart;
+    //TODO: bundle below into common struct
+    QQuickPathAnimation::Orientation orientation;
+    QPointF anchorPoint;
+    qreal entryInterval;
+    qreal exitInterval;
+    QDeclarativeNullableValue<qreal> endRotation;
+    QDeclarativeNullableValue<qreal> startRotation;
+};
+
+class QQuickPathAnimationPrivate : public QDeclarativeAbstractAnimationPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickPathAnimation)
+public:
+    QQuickPathAnimationPrivate() : path(0), target(0),
+        rangeIsSet(false), orientation(QQuickPathAnimation::Fixed), entryInterval(0), exitInterval(0), pa(0) {}
+
+    QDeclarativePath *path;
+    QQuickItem *target;
+    bool rangeIsSet;
+    QQuickPathAnimation::Orientation orientation;
+    QPointF anchorPoint;
+    qreal entryInterval;
+    qreal exitInterval;
+    QDeclarativeNullableValue<qreal> endRotation;
+    QDeclarativeBulkValueAnimator *pa;
+};
+
+
+QT_END_NAMESPACE
+
+#endif // QQUICKANIMATION_P_H
diff --git a/src/declarative/items/qquickborderimage.cpp b/src/declarative/items/qquickborderimage.cpp
new file mode 100644 (file)
index 0000000..92c1c6d
--- /dev/null
@@ -0,0 +1,601 @@
+/****************************************************************************
+**
+** 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 "qquickborderimage_p.h"
+#include "qquickborderimage_p_p.h"
+#include "qquickninepatchnode_p.h"
+
+#include <QtDeclarative/qdeclarativeinfo.h>
+#include <QtCore/qfile.h>
+
+#include <private/qdeclarativeengine_p.h>
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+    \qmlclass BorderImage QQuickBorderImage
+    \inqmlmodule QtQuick 2
+    \brief The BorderImage element provides an image that can be used as a border.
+    \inherits Item
+    \ingroup qml-basic-visual-elements
+
+    The BorderImage element is used to create borders out of images by scaling or tiling
+    parts of each image.
+
+    A BorderImage element breaks a source image, specified using the \l url property,
+    into 9 regions, as shown below:
+
+    \image declarative-scalegrid.png
+
+    When the image is scaled, regions of the source image are scaled or tiled to
+    create the displayed border image in the following way:
+
+    \list
+    \i The corners (regions 1, 3, 7, and 9) are not scaled at all.
+    \i Regions 2 and 8 are scaled according to
+       \l{BorderImage::horizontalTileMode}{horizontalTileMode}.
+    \i Regions 4 and 6 are scaled according to
+       \l{BorderImage::verticalTileMode}{verticalTileMode}.
+    \i The middle (region 5) is scaled according to both
+       \l{BorderImage::horizontalTileMode}{horizontalTileMode} and
+       \l{BorderImage::verticalTileMode}{verticalTileMode}.
+    \endlist
+
+    The regions of the image are defined using the \l border property group, which
+    describes the distance from each edge of the source image to use as a border.
+
+    \section1 Example Usage
+
+    The following examples show the effects of the different modes on an image.
+    Guide lines are overlaid onto the image to show the different regions of the
+    image as described above.
+
+    \beginfloatleft
+    \image qml-borderimage-normal-image.png
+    \endfloat
+
+    An unscaled image is displayed using an Image element. The \l border property is
+    used to determine the parts of the image that will lie inside the unscaled corner
+    areas and the parts that will be stretched horizontally and vertically.
+
+    \snippet doc/src/snippets/declarative/borderimage/normal-image.qml normal image
+
+    \clearfloat
+    \beginfloatleft
+    \image qml-borderimage-scaled.png
+    \endfloat
+
+    A BorderImage element is used to display the image, and it is given a size that is
+    larger than the original image. Since the \l horizontalTileMode property is set to
+    \l{BorderImage::horizontalTileMode}{BorderImage.Stretch}, the parts of image in
+    regions 2 and 8 are stretched horizontally. Since the \l verticalTileMode property
+    is set to \l{BorderImage::verticalTileMode}{BorderImage.Stretch}, the parts of image
+    in regions 4 and 6 are stretched vertically.
+
+    \snippet doc/src/snippets/declarative/borderimage/borderimage-scaled.qml scaled border image
+
+    \clearfloat
+    \beginfloatleft
+    \image qml-borderimage-tiled.png
+    \endfloat
+
+    Again, a large BorderImage element is used to display the image. With the
+    \l horizontalTileMode property set to \l{BorderImage::horizontalTileMode}{BorderImage.Repeat},
+    the parts of image in regions 2 and 8 are tiled so that they fill the space at the
+    top and bottom of the element. Similarly, the \l verticalTileMode property is set to
+    \l{BorderImage::verticalTileMode}{BorderImage.Repeat}, the parts of image in regions
+    4 and 6 are tiled so that they fill the space at the left and right of the element.
+
+    \snippet doc/src/snippets/declarative/borderimage/borderimage-tiled.qml tiled border image
+
+    \clearfloat
+    In some situations, the width of regions 2 and 8 may not be an exact multiple of the width
+    of the corresponding regions in the source image. Similarly, the height of regions 4 and 6
+    may not be an exact multiple of the height of the corresponding regions. It can be useful
+    to use \l{BorderImage::horizontalTileMode}{BorderImage.Round} instead of
+    \l{BorderImage::horizontalTileMode}{BorderImage.Repeat} in cases like these.
+
+    The \l{declarative/imageelements/borderimage}{BorderImage example} shows how a BorderImage
+    can be used to simulate a shadow effect on a rectangular item.
+
+    \section1 Quality and Performance
+
+    By default, any scaled regions of the image are rendered without smoothing to improve
+    rendering speed. Setting the \l smooth property improves rendering quality of scaled
+    regions, but may slow down rendering.
+
+    The source image may not be loaded instantaneously, depending on its original location.
+    Loading progress can be monitored with the \l progress property.
+
+    \sa Image, AnimatedImage
+ */
+
+/*!
+    \qmlproperty bool QtQuick2::BorderImage::asynchronous
+
+    Specifies that images on the local filesystem should be loaded
+    asynchronously in a separate thread.  The default value is
+    false, causing the user interface thread to block while the
+    image is loaded.  Setting \a asynchronous to true is useful where
+    maintaining a responsive user interface is more desirable
+    than having images immediately visible.
+
+    Note that this property is only valid for images read from the
+    local filesystem.  Images loaded via a network resource (e.g. HTTP)
+    are always loaded asynchonously.
+*/
+QQuickBorderImage::QQuickBorderImage(QQuickItem *parent)
+: QQuickImageBase(*(new QQuickBorderImagePrivate), parent)
+{
+}
+
+QQuickBorderImage::~QQuickBorderImage()
+{
+    Q_D(QQuickBorderImage);
+    if (d->sciReply)
+        d->sciReply->deleteLater();
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::BorderImage::status
+
+    This property describes the status of image loading.  It can be one of:
+
+    \list
+    \o BorderImage.Null - no image has been set
+    \o BorderImage.Ready - the image has been loaded
+    \o BorderImage.Loading - the image is currently being loaded
+    \o BorderImage.Error - an error occurred while loading the image
+    \endlist
+
+    \sa progress
+*/
+
+/*!
+    \qmlproperty real QtQuick2::BorderImage::progress
+
+    This property holds the progress of image loading, from 0.0 (nothing loaded)
+    to 1.0 (finished).
+
+    \sa status
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::BorderImage::smooth
+
+    Set this property if you want the image to be smoothly filtered when scaled or
+    transformed.  Smooth filtering gives better visual quality, but is slower.  If
+    the image is displayed at its natural size, this property has no visual or
+    performance effect.
+
+    By default, this property is set to false.
+
+    \note Generally scaling artifacts are only visible if the image is stationary on
+    the screen.  A common pattern when animating an image is to disable smooth
+    filtering at the beginning of the animation and enable it at the conclusion.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::BorderImage::cache
+
+    Specifies whether the image should be cached. The default value is
+    true. Setting \a cache to false is useful when dealing with large images,
+    to make sure that they aren't cached at the expense of small 'ui element' images.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::BorderImage::mirror
+
+    This property holds whether the image should be horizontally inverted
+    (effectively displaying a mirrored image).
+
+    The default value is false.
+*/
+
+/*!
+    \qmlproperty url QtQuick2::BorderImage::source
+
+    This property holds the URL that refers to the source image.
+
+    BorderImage can handle any image format supported by Qt, loaded from any
+    URL scheme supported by Qt.
+
+    This property can also be used to refer to .sci files, which are
+    written in a QML-specific, text-based format that specifies the
+    borders, the image file and the tile rules for a given border image.
+
+    The following .sci file sets the borders to 10 on each side for the
+    image \c picture.png:
+
+    \code
+    border.left: 10
+    border.top: 10
+    border.bottom: 10
+    border.right: 10
+    source: "picture.png"
+    \endcode
+
+    The URL may be absolute, or relative to the URL of the component.
+
+    \sa QDeclarativeImageProvider
+*/
+
+/*!
+    \qmlproperty QSize QtQuick2::BorderImage::sourceSize
+
+    This property holds the actual width and height of the loaded image.
+
+    In BorderImage, this property is read-only.
+
+    \sa Image::sourceSize
+*/
+void QQuickBorderImage::setSource(const QUrl &url)
+{
+    Q_D(QQuickBorderImage);
+    //equality is fairly expensive, so we bypass for simple, common case
+    if ((d->url.isEmpty() == url.isEmpty()) && url == d->url)
+        return;
+
+    if (d->sciReply) {
+        d->sciReply->deleteLater();
+        d->sciReply = 0;
+    }
+
+    d->url = url;
+    d->sciurl = QUrl();
+    emit sourceChanged(d->url);
+
+    if (isComponentComplete())
+        load();
+}
+
+void QQuickBorderImage::load()
+{
+    Q_D(QQuickBorderImage);
+    if (d->progress != 0.0) {
+        d->progress = 0.0;
+        emit progressChanged(d->progress);
+    }
+
+    if (d->url.isEmpty()) {
+        d->pix.clear(this);
+        d->status = Null;
+        setImplicitWidth(0);
+        setImplicitHeight(0);
+        emit statusChanged(d->status);
+        update();
+    } else {
+        d->status = Loading;
+        if (d->url.path().endsWith(QLatin1String("sci"))) {
+            QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(d->url);
+            if (!lf.isEmpty()) {
+                QFile file(lf);
+                file.open(QIODevice::ReadOnly);
+                setGridScaledImage(QQuickGridScaledImage(&file));
+            } else {
+                QNetworkRequest req(d->url);
+                d->sciReply = qmlEngine(this)->networkAccessManager()->get(req);
+                FAST_CONNECT(d->sciReply, SIGNAL(finished()), this, SLOT(sciRequestFinished()))
+            }
+        } else {
+
+            QDeclarativePixmap::Options options;
+            if (d->async)
+                options |= QDeclarativePixmap::Asynchronous;
+            if (d->cache)
+                options |= QDeclarativePixmap::Cache;
+            d->pix.clear(this);
+            d->pix.load(qmlEngine(this), d->url, options);
+
+            if (d->pix.isLoading()) {
+                d->pix.connectFinished(this, SLOT(requestFinished()));
+                d->pix.connectDownloadProgress(this, SLOT(requestProgress(qint64,qint64)));
+            } else {
+                QSize impsize = d->pix.implicitSize();
+                setImplicitWidth(impsize.width());
+                setImplicitHeight(impsize.height());
+
+                if (d->pix.isReady()) {
+                    d->status = Ready;
+                } else {
+                    d->status = Error;
+                    qmlInfo(this) << d->pix.error();
+                }
+
+                d->progress = 1.0;
+                emit statusChanged(d->status);
+                emit progressChanged(d->progress);
+                update();
+            }
+        }
+    }
+
+    emit statusChanged(d->status);
+}
+
+/*!
+    \qmlproperty int QtQuick2::BorderImage::border.left
+    \qmlproperty int QtQuick2::BorderImage::border.right
+    \qmlproperty int QtQuick2::BorderImage::border.top
+    \qmlproperty int QtQuick2::BorderImage::border.bottom
+
+    The 4 border lines (2 horizontal and 2 vertical) break the image into 9 sections,
+    as shown below:
+
+    \image declarative-scalegrid.png
+
+    Each border line (left, right, top, and bottom) specifies an offset in pixels
+    from the respective edge of the source image. By default, each border line has
+    a value of 0.
+
+    For example, the following definition sets the bottom line 10 pixels up from
+    the bottom of the image:
+
+    \qml
+    BorderImage {
+        border.bottom: 10
+        // ...
+    }
+    \endqml
+
+    The border lines can also be specified using a
+    \l {BorderImage::source}{.sci file}.
+*/
+
+QQuickScaleGrid *QQuickBorderImage::border()
+{
+    Q_D(QQuickBorderImage);
+    return d->getScaleGrid();
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::BorderImage::horizontalTileMode
+    \qmlproperty enumeration QtQuick2::BorderImage::verticalTileMode
+
+    This property describes how to repeat or stretch the middle parts of the border image.
+
+    \list
+    \o BorderImage.Stretch - Scales the image to fit to the available area.
+    \o BorderImage.Repeat - Tile the image until there is no more space. May crop the last image.
+    \o BorderImage.Round - Like Repeat, but scales the images down to ensure that the last image is not cropped.
+    \endlist
+
+    The default tile mode for each property is BorderImage.Stretch.
+*/
+QQuickBorderImage::TileMode QQuickBorderImage::horizontalTileMode() const
+{
+    Q_D(const QQuickBorderImage);
+    return d->horizontalTileMode;
+}
+
+void QQuickBorderImage::setHorizontalTileMode(TileMode t)
+{
+    Q_D(QQuickBorderImage);
+    if (t != d->horizontalTileMode) {
+        d->horizontalTileMode = t;
+        emit horizontalTileModeChanged();
+        update();
+    }
+}
+
+QQuickBorderImage::TileMode QQuickBorderImage::verticalTileMode() const
+{
+    Q_D(const QQuickBorderImage);
+    return d->verticalTileMode;
+}
+
+void QQuickBorderImage::setVerticalTileMode(TileMode t)
+{
+    Q_D(QQuickBorderImage);
+    if (t != d->verticalTileMode) {
+        d->verticalTileMode = t;
+        emit verticalTileModeChanged();
+        update();
+    }
+}
+
+void QQuickBorderImage::setGridScaledImage(const QQuickGridScaledImage& sci)
+{
+    Q_D(QQuickBorderImage);
+    if (!sci.isValid()) {
+        d->status = Error;
+        emit statusChanged(d->status);
+    } else {
+        QQuickScaleGrid *sg = border();
+        sg->setTop(sci.gridTop());
+        sg->setBottom(sci.gridBottom());
+        sg->setLeft(sci.gridLeft());
+        sg->setRight(sci.gridRight());
+        d->horizontalTileMode = sci.horizontalTileRule();
+        d->verticalTileMode = sci.verticalTileRule();
+
+        d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl()));
+
+        QDeclarativePixmap::Options options;
+        if (d->async)
+            options |= QDeclarativePixmap::Asynchronous;
+        if (d->cache)
+            options |= QDeclarativePixmap::Cache;
+        d->pix.clear(this);
+        d->pix.load(qmlEngine(this), d->sciurl, options);
+
+        if (d->pix.isLoading()) {
+            static int thisRequestProgress = -1;
+            static int thisRequestFinished = -1;
+            if (thisRequestProgress == -1) {
+                thisRequestProgress =
+                    QQuickBorderImage::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
+                thisRequestFinished =
+                    QQuickBorderImage::staticMetaObject.indexOfSlot("requestFinished()");
+            }
+
+            d->pix.connectFinished(this, thisRequestFinished);
+            d->pix.connectDownloadProgress(this, thisRequestProgress);
+
+        } else {
+
+            QSize impsize = d->pix.implicitSize();
+            setImplicitWidth(impsize.width());
+            setImplicitHeight(impsize.height());
+
+            if (d->pix.isReady()) {
+                d->status = Ready;
+            } else {
+                d->status = Error;
+                qmlInfo(this) << d->pix.error();
+            }
+
+            d->progress = 1.0;
+            emit statusChanged(d->status);
+            emit progressChanged(1.0);
+            update();
+
+        }
+    }
+}
+
+void QQuickBorderImage::requestFinished()
+{
+    Q_D(QQuickBorderImage);
+
+    QSize impsize = d->pix.implicitSize();
+    if (d->pix.isError()) {
+        d->status = Error;
+        qmlInfo(this) << d->pix.error();
+    } else {
+        d->status = Ready;
+    }
+
+    setImplicitWidth(impsize.width());
+    setImplicitHeight(impsize.height());
+
+    if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height())
+        emit sourceSizeChanged();
+
+    d->progress = 1.0;
+    emit statusChanged(d->status);
+    emit progressChanged(1.0);
+    update();
+}
+
+#define BORDERIMAGE_MAX_REDIRECT 16
+
+void QQuickBorderImage::sciRequestFinished()
+{
+    Q_D(QQuickBorderImage);
+
+    d->redirectCount++;
+    if (d->redirectCount < BORDERIMAGE_MAX_REDIRECT) {
+        QVariant redirect = d->sciReply->attribute(QNetworkRequest::RedirectionTargetAttribute);
+        if (redirect.isValid()) {
+            QUrl url = d->sciReply->url().resolved(redirect.toUrl());
+            setSource(url);
+            return;
+        }
+    }
+    d->redirectCount=0;
+
+    if (d->sciReply->error() != QNetworkReply::NoError) {
+        d->status = Error;
+        d->sciReply->deleteLater();
+        d->sciReply = 0;
+        emit statusChanged(d->status);
+    } else {
+        QQuickGridScaledImage sci(d->sciReply);
+        d->sciReply->deleteLater();
+        d->sciReply = 0;
+        setGridScaledImage(sci);
+    }
+}
+
+void QQuickBorderImage::doUpdate()
+{
+    update();
+}
+
+QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+    Q_D(QQuickBorderImage);
+
+    QSGTexture *texture = d->pix.texture(d->sceneGraphContext());
+
+    if (!texture || width() <= 0 || height() <= 0) {
+        delete oldNode;
+        return 0;
+    }
+
+    QQuickNinePatchNode *node = static_cast<QQuickNinePatchNode *>(oldNode);
+
+    if (!node) {
+        node = new QQuickNinePatchNode();
+    }
+
+    node->setTexture(texture);
+
+    // Don't implicitly create the scalegrid in the rendering thread...
+    if (d->border) {
+        const QQuickScaleGrid *border = d->getScaleGrid();
+        node->setInnerRect(QRectF(border->left(),
+                                  border->top(),
+                                  qMax(1, d->pix.width() - border->right() - border->left()),
+                                  qMax(1, d->pix.height() - border->bottom() - border->top())));
+    } else {
+        node->setInnerRect(QRectF(0, 0, width(), height()));
+    }
+    node->setRect(QRectF(0, 0, width(), height()));
+    node->setFiltering(d->smooth ? QSGTexture::Linear : QSGTexture::Nearest);
+    node->setHorzontalTileMode(d->horizontalTileMode);
+    node->setVerticalTileMode(d->verticalTileMode);
+    node->setMirror(d->mirror);
+    node->update();
+
+    return node;
+}
+
+void QQuickBorderImage::pixmapChange()
+{
+    Q_D(QQuickBorderImage);
+
+    d->pixmapChanged = true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickborderimage_p.h b/src/declarative/items/qquickborderimage_p.h
new file mode 100644 (file)
index 0000000..0af6fca
--- /dev/null
@@ -0,0 +1,110 @@
+// Commit: ebd4bc73c46c2962742a682b6a391fb68c482aec
+/****************************************************************************
+**
+** 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 QQUICKBORDERIMAGE_P_H
+#define QQUICKBORDERIMAGE_P_H
+
+#include "qquickimagebase_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickScaleGrid;
+class QQuickGridScaledImage;
+class QQuickBorderImagePrivate;
+class Q_AUTOTEST_EXPORT QQuickBorderImage : public QQuickImageBase
+{
+    Q_OBJECT
+    Q_ENUMS(TileMode)
+
+    Q_PROPERTY(QQuickScaleGrid *border READ border CONSTANT)
+    Q_PROPERTY(TileMode horizontalTileMode READ horizontalTileMode WRITE setHorizontalTileMode NOTIFY horizontalTileModeChanged)
+    Q_PROPERTY(TileMode verticalTileMode READ verticalTileMode WRITE setVerticalTileMode NOTIFY verticalTileModeChanged)
+    // read-only for BorderImage
+    Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged)
+
+public:
+    QQuickBorderImage(QQuickItem *parent=0);
+    ~QQuickBorderImage();
+
+    QQuickScaleGrid *border();
+
+    enum TileMode { Stretch = Qt::StretchTile, Repeat = Qt::RepeatTile, Round = Qt::RoundTile };
+
+    TileMode horizontalTileMode() const;
+    void setHorizontalTileMode(TileMode);
+
+    TileMode verticalTileMode() const;
+    void setVerticalTileMode(TileMode);
+
+    void setSource(const QUrl &url);
+
+Q_SIGNALS:
+    void horizontalTileModeChanged();
+    void verticalTileModeChanged();
+    void sourceSizeChanged();
+
+protected:
+    virtual void load();
+    virtual void pixmapChange();
+    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+
+private:
+    void setGridScaledImage(const QQuickGridScaledImage& sci);
+
+private Q_SLOTS:
+    void doUpdate();
+    void requestFinished();
+    void sciRequestFinished();
+
+private:
+    Q_DISABLE_COPY(QQuickBorderImage)
+    Q_DECLARE_PRIVATE(QQuickBorderImage)
+};
+
+QT_END_NAMESPACE
+QML_DECLARE_TYPE(QQuickBorderImage)
+QT_END_HEADER
+
+#endif // QQUICKBORDERIMAGE_P_H
diff --git a/src/declarative/items/qquickborderimage_p_p.h b/src/declarative/items/qquickborderimage_p_p.h
new file mode 100644 (file)
index 0000000..1875dc0
--- /dev/null
@@ -0,0 +1,103 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
+/****************************************************************************
+**
+** 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 QQUICKBORDERIMAGE_P_P_H
+#define QQUICKBORDERIMAGE_P_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 "qquickimagebase_p_p.h"
+#include "qquickscalegrid_p_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QNetworkReply;
+class QQuickBorderImagePrivate : public QQuickImageBasePrivate
+{
+    Q_DECLARE_PUBLIC(QQuickBorderImage)
+
+public:
+    QQuickBorderImagePrivate()
+      : border(0), sciReply(0),
+        horizontalTileMode(QQuickBorderImage::Stretch),
+        verticalTileMode(QQuickBorderImage::Stretch),
+        redirectCount(0), pixmapChanged(false)
+    {
+    }
+
+    ~QQuickBorderImagePrivate()
+    {
+    }
+
+
+    QQuickScaleGrid *getScaleGrid()
+    {
+        Q_Q(QQuickBorderImage);
+        if (!border) {
+            border = new QQuickScaleGrid(q);
+            FAST_CONNECT(border, SIGNAL(borderChanged()), q, SLOT(doUpdate()))
+        }
+        return border;
+    }
+
+    QQuickScaleGrid *border;
+    QUrl sciurl;
+    QNetworkReply *sciReply;
+    QQuickBorderImage::TileMode horizontalTileMode;
+    QQuickBorderImage::TileMode verticalTileMode;
+    int redirectCount;
+
+    bool pixmapChanged : 1;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKBORDERIMAGE_P_P_H
diff --git a/src/declarative/items/qquickcanvas.cpp b/src/declarative/items/qquickcanvas.cpp
new file mode 100644 (file)
index 0000000..8f87ce7
--- /dev/null
@@ -0,0 +1,2399 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qquickcanvas.h"
+#include "qquickcanvas_p.h"
+
+#include "qquickitem.h"
+#include "qquickitem_p.h"
+
+#include <private/qsgrenderer_p.h>
+#include <private/qsgflashnode_p.h>
+
+#include <private/qguiapplication_p.h>
+#include <QtGui/QInputPanel>
+
+#include <private/qabstractanimation_p.h>
+
+#include <QtGui/qpainter.h>
+#include <QtGui/qevent.h>
+#include <QtGui/qmatrix4x4.h>
+#include <QtCore/qvarlengtharray.h>
+#include <QtCore/qabstractanimation.h>
+#include <QtDeclarative/qdeclarativeincubator.h>
+
+#include <private/qdeclarativedebugtrace_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#define QQUICK_CANVAS_TIMING
+#ifdef QQUICK_CANVAS_TIMING
+static bool qquick_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)
+
+extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha);
+
+void QQuickCanvasPrivate::updateFocusItemTransform()
+{
+    Q_Q(QQuickCanvas);
+    QQuickItem *focus = q->activeFocusItem();
+    if (focus && qApp->inputPanel()->inputItem() == focus)
+        qApp->inputPanel()->setInputItemTransform(QQuickItemPrivate::get(focus)->itemToCanvasTransform());
+}
+
+class QQuickCanvasIncubationController : public QObject, public QDeclarativeIncubationController
+{
+public:
+    QQuickCanvasIncubationController(QQuickCanvasPrivate *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:
+    QQuickCanvasPrivate *m_canvas;
+    bool m_eventSent;
+};
+
+class QQuickCanvasPlainRenderLoop : public QObject, public QQuickCanvasRenderLoop
+{
+public:
+    QQuickCanvasPlainRenderLoop()
+        : updatePending(false)
+        , animationRunning(false)
+    {
+        qWarning("QQuickCanvas: using non-threaded render loop. Be very sure to not access scene graph "
+                 "objects outside the QQuickItem::updatePaintNode() call. Failing to do so will cause "
+                 "your code to crash on other platforms!");
+    }
+
+    virtual void paint() {
+        updatePending = false;
+        if (animationRunning && animationDriver())
+            animationDriver()->advance();
+        polishItems();
+        syncSceneGraph();
+        makeCurrent();
+        glViewport(0, 0, size.width(), size.height());
+        renderSceneGraph(size);
+        swapBuffers();
+
+        if (animationRunning)
+            maybeUpdate();
+    }
+
+    virtual QImage grab() {
+        return qt_gl_read_framebuffer(size, false, false);
+    }
+
+    virtual void startRendering() {
+        if (!glContext()) {
+            createGLContext();
+            makeCurrent();
+            initializeSceneGraph();
+        } else {
+            makeCurrent();
+        }
+        maybeUpdate();
+    }
+
+    virtual void stopRendering() { }
+
+    virtual void maybeUpdate() {
+        if (!updatePending) {
+            QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+            updatePending = true;
+        }
+    }
+
+    virtual void animationStarted() {
+        animationRunning = true;
+        maybeUpdate();
+    }
+
+    virtual void animationStopped() {
+        animationRunning = false;
+    }
+
+    virtual bool isRunning() const { return glContext(); } // Event loop is always running...
+    virtual void resize(const QSize &s) { size = s; }
+    virtual void setWindowSize(const QSize &s) { size = s; }
+
+    bool event(QEvent *e) {
+        if (e->type() == QEvent::User) {
+            paint();
+            return true;
+        }
+        return QObject::event(e);
+    }
+
+    QSize size;
+
+    uint updatePending : 1;
+    uint animationRunning : 1;
+};
+
+
+
+/*
+Focus behavior
+==============
+
+Prior to being added to a valid canvas items can set and clear focus with no
+effect.  Only once items are added to a canvas (by way of having a parent set that
+already belongs to a canvas) do the focus rules apply.  Focus goes back to
+having no effect if an item is removed from a canvas.
+
+When an item is moved into a new focus scope (either being added to a canvas
+for the first time, or having its parent changed), if the focus scope already has
+a scope focused item that takes precedence over the item being added.  Otherwise,
+the focus of the added tree is used.  In the case of of a tree of items being
+added to a canvas for the first time, which may have a conflicted focus state (two
+or more items in one scope having focus set), the same rule is applied item by item -
+thus the first item that has focus will get it (assuming the scope doesn't already
+have a scope focused item), and the other items will have their focus cleared.
+*/
+
+/*
+  Threaded Rendering
+  ==================
+
+  The threaded rendering uses a number of different variables to track potential
+  states used to handle resizing, initial paint, grabbing and driving animations
+  while ALWAYS keeping the GL context in the rendering thread and keeping the
+  overhead of normal one-shot paints and vblank driven animations at a minimum.
+
+  Resize, initial show and grab suffer slightly in this model as they are locked
+  to the rendering in the rendering thread, but this is a necessary evil for
+  the system to work.
+
+  Variables that are used:
+
+  Private::animationRunning: This is true while the animations are running, and only
+  written to inside locks.
+
+  RenderThread::isGuiBlocked: This is used to indicate that the GUI thread owns the
+  lock. This variable is an integer to allow for recursive calls to lockInGui()
+  without using a recursive mutex. See isGuiBlockPending.
+
+  RenderThread::isPaintComplete: This variable is cleared when rendering starts and
+  set once rendering is complete. It is monitored in the paintEvent(),
+  resizeEvent() and grab() functions to force them to wait for rendering to
+  complete.
+
+  RenderThread::isGuiBlockPending: This variable is set in the render thread just
+  before the sync event is sent to the GUI thread. It is used to avoid deadlocks
+  in the case where render thread waits while waiting for GUI to pick up the sync
+  event and GUI thread gets a resizeEvent, the initial paintEvent or a grab.
+  When this happens, we use the
+  exhaustSyncEvent() function to do the sync right there and mark the coming
+  sync event to be discarded. There can only ever be one sync incoming.
+
+  RenderThread::isRenderBlock: This variable is true when animations are not
+  running and the render thread has gone to sleep, waiting for more to do.
+
+  RenderThread::isExternalUpdatePending: This variable is set to false during
+  the sync phase in the GUI thread and to true in maybeUpdate(). It is an
+  indication to the render thread that another render pass needs to take
+  place, rather than the render thread going to sleep after completing its swap.
+
+  RenderThread::doGrab: This variable is set by the grab() function and
+  tells the renderer to do a grab after rendering is complete and before
+  swapping happens.
+
+  RenderThread::shouldExit: This variable is used to determine if the render
+  thread should do a nother pass. It is typically set as a result of show()
+  and unset as a result of hide() or during shutdown()
+
+  RenderThread::hasExited: Used by the GUI thread to synchronize the shutdown
+  after shouldExit has been set to true.
+ */
+
+// #define FOCUS_DEBUG
+// #define MOUSE_DEBUG
+// #define TOUCH_DEBUG
+// #define DIRTY_DEBUG
+// #define THREAD_DEBUG
+
+// #define FRAME_TIMING
+
+#ifdef FRAME_TIMING
+static QTime frameTimer;
+int sceneGraphRenderTime;
+int readbackTime;
+#endif
+
+QQuickItem::UpdatePaintNodeData::UpdatePaintNodeData()
+: transformNode(0)
+{
+}
+
+QQuickRootItem::QQuickRootItem()
+{
+}
+
+void QQuickCanvas::exposeEvent(QExposeEvent *)
+{
+    Q_D(QQuickCanvas);
+    d->thread->paint();
+}
+
+void QQuickCanvas::resizeEvent(QResizeEvent *)
+{
+    Q_D(QQuickCanvas);
+    d->thread->resize(size());
+}
+
+void QQuickCanvas::animationStarted()
+{
+    d_func()->thread->animationStarted();
+}
+
+void QQuickCanvas::animationStopped()
+{
+    d_func()->thread->animationStopped();
+}
+
+void QQuickCanvas::showEvent(QShowEvent *)
+{
+    Q_D(QQuickCanvas);
+    if (d->vsyncAnimations) {
+        if (!d->animationDriver) {
+            d->animationDriver = d->context->createAnimationDriver(this);
+            connect(d->animationDriver, SIGNAL(started()), this, SLOT(animationStarted()), Qt::DirectConnection);
+            connect(d->animationDriver, SIGNAL(stopped()), this, SLOT(animationStopped()), Qt::DirectConnection);
+        }
+        d->animationDriver->install();
+    }
+
+    if (!d->thread->isRunning()) {
+        d->thread->setWindowSize(size());
+        d->thread->startRendering();
+    }
+}
+
+void QQuickCanvas::hideEvent(QHideEvent *)
+{
+    Q_D(QQuickCanvas);
+    d->thread->stopRendering();
+}
+
+
+
+/*!
+    Sets weither this canvas should use vsync driven animations.
+
+    This option can only be set on one single QQuickCanvas, and that it's
+    vsync signal will then be used to drive all animations in the
+    process.
+
+    This feature is primarily useful for single QQuickCanvas, QML-only
+    applications.
+
+    \warning Enabling vsync on multiple QQuickCanvas instances has
+    undefined behavior.
+ */
+void QQuickCanvas::setVSyncAnimations(bool enabled)
+{
+    Q_D(QQuickCanvas);
+    if (visible()) {
+        qWarning("QQuickCanvas::setVSyncAnimations: Cannot be changed when widget is shown");
+        return;
+    }
+    d->vsyncAnimations = enabled;
+}
+
+
+
+/*!
+    Returns true if this canvas should use vsync driven animations;
+    otherwise returns false.
+ */
+bool QQuickCanvas::vsyncAnimations() const
+{
+    Q_D(const QQuickCanvas);
+    return d->vsyncAnimations;
+}
+
+void QQuickCanvasPrivate::initializeSceneGraph()
+{
+    if (!context)
+        context = QSGContext::createDefaultContext();
+
+    if (context->isReady())
+        return;
+
+    QOpenGLContext *glctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
+    context->initialize(glctx);
+
+    Q_Q(QQuickCanvas);
+    QObject::connect(context->renderer(), SIGNAL(sceneGraphChanged()), q, SLOT(maybeUpdate()),
+                     Qt::DirectConnection);
+
+    if (!QQuickItemPrivate::get(rootItem)->itemNode()->parent()) {
+        context->rootNode()->appendChildNode(QQuickItemPrivate::get(rootItem)->itemNode());
+    }
+
+    emit q_func()->sceneGraphInitialized();
+}
+
+void QQuickCanvasPrivate::polishItems()
+{
+    while (!itemsToPolish.isEmpty()) {
+        QSet<QQuickItem *>::Iterator iter = itemsToPolish.begin();
+        QQuickItem *item = *iter;
+        itemsToPolish.erase(iter);
+        QQuickItemPrivate::get(item)->polishScheduled = false;
+        item->updatePolish();
+    }
+    updateFocusItemTransform();
+}
+
+
+void QQuickCanvasPrivate::syncSceneGraph()
+{
+    updateDirtyNodes();
+}
+
+
+void QQuickCanvasPrivate::renderSceneGraph(const QSize &size)
+{
+    context->renderer()->setDeviceRect(QRect(QPoint(0, 0), size));
+    context->renderer()->setViewportRect(QRect(QPoint(0, 0), renderTarget ? renderTarget->size() : size));
+    context->renderer()->setProjectionMatrixToDeviceRect();
+
+    context->renderNextFrame(renderTarget);
+
+#ifdef FRAME_TIMING
+    sceneGraphRenderTime = frameTimer.elapsed();
+#endif
+
+#ifdef FRAME_TIMING
+//    int pixel;
+//    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
+    readbackTime = frameTimer.elapsed();
+#endif
+}
+
+
+// ### Do we need this?
+void QQuickCanvas::sceneGraphChanged()
+{
+//    Q_D(QQuickCanvas);
+//    d->needsRepaint = true;
+}
+
+QQuickCanvasPrivate::QQuickCanvasPrivate()
+    : rootItem(0)
+    , activeFocusItem(0)
+    , mouseGrabberItem(0)
+    , dirtyItemList(0)
+    , context(0)
+    , vsyncAnimations(false)
+    , thread(0)
+    , animationDriver(0)
+    , renderTarget(0)
+    , incubationController(0)
+{
+}
+
+QQuickCanvasPrivate::~QQuickCanvasPrivate()
+{
+}
+
+void QQuickCanvasPrivate::init(QQuickCanvas *c)
+{
+    QUnifiedTimer::instance(true)->setConsistentTiming(qmlFixedAnimationStep());
+
+    q_ptr = c;
+
+    Q_Q(QQuickCanvas);
+
+    rootItem = new QQuickRootItem;
+    QQuickItemPrivate *rootItemPrivate = QQuickItemPrivate::get(rootItem);
+    rootItemPrivate->canvas = q;
+    rootItemPrivate->flags |= QQuickItem::ItemIsFocusScope;
+
+    // QML always has focus. It is important that this call happens after the rootItem
+    // has a canvas..
+    rootItem->setFocus(true);
+
+    bool threaded = !qmlNoThreadedRenderer();
+
+    if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL)) {
+        qWarning("QQuickCanvas: platform does not support threaded rendering!");
+        threaded = false;
+    }
+
+    if (threaded)
+        thread = new QQuickCanvasRenderThread();
+    else
+        thread = new QQuickCanvasPlainRenderLoop();
+
+    thread->renderer = q;
+    thread->d = this;
+
+    context = QSGContext::createDefaultContext();
+    thread->moveContextToThread(context);
+
+    q->setSurfaceType(QWindow::OpenGLSurface);
+    q->setFormat(context->defaultSurfaceFormat());
+}
+
+void QQuickCanvasPrivate::transformTouchPoints(QList<QTouchEvent::TouchPoint> &touchPoints, const QTransform &transform)
+{
+    for (int i=0; i<touchPoints.count(); i++) {
+        QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
+        touchPoint.setRect(transform.mapRect(touchPoint.sceneRect()));
+        touchPoint.setStartPos(transform.map(touchPoint.startScenePos()));
+        touchPoint.setLastPos(transform.map(touchPoint.lastScenePos()));
+    }
+}
+
+
+/*!
+Translates the data in \a touchEvent to this canvas.  This method leaves the item local positions in
+\a touchEvent untouched (these are filled in later).
+*/
+void QQuickCanvasPrivate::translateTouchEvent(QTouchEvent *touchEvent)
+{
+//    Q_Q(QQuickCanvas);
+
+//    touchEvent->setWidget(q); // ### refactor...
+
+    QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
+    for (int i = 0; i < touchPoints.count(); ++i) {
+        QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
+
+        touchPoint.setScreenRect(touchPoint.sceneRect());
+        touchPoint.setStartScreenPos(touchPoint.startScenePos());
+        touchPoint.setLastScreenPos(touchPoint.lastScenePos());
+
+        touchPoint.setSceneRect(touchPoint.rect());
+        touchPoint.setStartScenePos(touchPoint.startPos());
+        touchPoint.setLastScenePos(touchPoint.lastPos());
+
+        if (touchPoint.isPrimary())
+            lastMousePosition = touchPoint.pos().toPoint();
+    }
+    touchEvent->setTouchPoints(touchPoints);
+}
+
+void QQuickCanvasPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, FocusOptions options)
+{
+    Q_Q(QQuickCanvas);
+
+    Q_ASSERT(item);
+    Q_ASSERT(scope || item == rootItem);
+
+#ifdef FOCUS_DEBUG
+    qWarning() << "QQuickCanvasPrivate::setFocusInScope():";
+    qWarning() << "    scope:" << (QObject *)scope;
+    if (scope)
+        qWarning() << "    scopeSubFocusItem:" << (QObject *)QQuickItemPrivate::get(scope)->subFocusItem;
+    qWarning() << "    item:" << (QObject *)item;
+    qWarning() << "    activeFocusItem:" << (QObject *)activeFocusItem;
+#endif
+
+    QQuickItemPrivate *scopePrivate = scope ? QQuickItemPrivate::get(scope) : 0;
+    QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+
+    QQuickItem *oldActiveFocusItem = 0;
+    QQuickItem *newActiveFocusItem = 0;
+
+    QVarLengthArray<QQuickItem *, 20> changed;
+
+    // Does this change the active focus?
+    if (item == rootItem || scopePrivate->activeFocus) {
+        oldActiveFocusItem = activeFocusItem;
+        newActiveFocusItem = item;
+        while (newActiveFocusItem->isFocusScope() && newActiveFocusItem->scopedFocusItem())
+            newActiveFocusItem = newActiveFocusItem->scopedFocusItem();
+
+        if (oldActiveFocusItem) {
+#ifndef QT_NO_IM
+            qApp->inputPanel()->commit();
+#endif
+
+            activeFocusItem = 0;
+            QFocusEvent event(QEvent::FocusOut, Qt::OtherFocusReason);
+            q->sendEvent(oldActiveFocusItem, &event);
+
+            QQuickItem *afi = oldActiveFocusItem;
+            while (afi != scope) {
+                if (QQuickItemPrivate::get(afi)->activeFocus) {
+                    QQuickItemPrivate::get(afi)->activeFocus = false;
+                    changed << afi;
+                }
+                afi = afi->parentItem();
+            }
+        }
+    }
+
+    if (item != rootItem) {
+        QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
+        // Correct focus chain in scope
+        if (oldSubFocusItem) {
+            QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
+            while (sfi != scope) {
+                QQuickItemPrivate::get(sfi)->subFocusItem = 0;
+                sfi = sfi->parentItem();
+            }
+        }
+        {
+            scopePrivate->subFocusItem = item;
+            QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
+            while (sfi != scope) {
+                QQuickItemPrivate::get(sfi)->subFocusItem = item;
+                sfi = sfi->parentItem();
+            }
+        }
+
+        if (oldSubFocusItem) {
+            QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
+            changed << oldSubFocusItem;
+        }
+    }
+
+    if (!(options & DontChangeFocusProperty)) {
+        // if (item != rootItem || q->hasFocus()) { // ### refactor: focus handling...
+            itemPrivate->focus = true;
+            changed << item;
+        // }
+    }
+
+    if (newActiveFocusItem) { // ### refactor:  && q->hasFocus()) {
+        activeFocusItem = newActiveFocusItem;
+
+        QQuickItemPrivate::get(newActiveFocusItem)->activeFocus = true;
+        changed << newActiveFocusItem;
+
+        QQuickItem *afi = newActiveFocusItem->parentItem();
+        while (afi && afi != scope) {
+            if (afi->isFocusScope()) {
+                QQuickItemPrivate::get(afi)->activeFocus = true;
+                changed << afi;
+            }
+            afi = afi->parentItem();
+        }
+
+        updateInputMethodData();
+
+        QFocusEvent event(QEvent::FocusIn, Qt::OtherFocusReason);
+        q->sendEvent(newActiveFocusItem, &event);
+    } else {
+        updateInputMethodData();
+    }
+
+    if (!changed.isEmpty())
+        notifyFocusChangesRecur(changed.data(), changed.count() - 1);
+}
+
+void QQuickCanvasPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item, FocusOptions options)
+{
+    Q_Q(QQuickCanvas);
+
+    Q_UNUSED(item);
+    Q_ASSERT(item);
+    Q_ASSERT(scope || item == rootItem);
+
+#ifdef FOCUS_DEBUG
+    qWarning() << "QQuickCanvasPrivate::clearFocusInScope():";
+    qWarning() << "    scope:" << (QObject *)scope;
+    qWarning() << "    item:" << (QObject *)item;
+    qWarning() << "    activeFocusItem:" << (QObject *)activeFocusItem;
+#endif
+
+    QQuickItemPrivate *scopePrivate = scope ? QQuickItemPrivate::get(scope) : 0;
+
+    QQuickItem *oldActiveFocusItem = 0;
+    QQuickItem *newActiveFocusItem = 0;
+
+    QVarLengthArray<QQuickItem *, 20> changed;
+
+    Q_ASSERT(item == rootItem || item == scopePrivate->subFocusItem);
+
+    // Does this change the active focus?
+    if (item == rootItem || scopePrivate->activeFocus) {
+        oldActiveFocusItem = activeFocusItem;
+        newActiveFocusItem = scope;
+
+        Q_ASSERT(oldActiveFocusItem);
+
+#ifndef QT_NO_IM
+        qApp->inputPanel()->commit();
+#endif
+
+        activeFocusItem = 0;
+        QFocusEvent event(QEvent::FocusOut, Qt::OtherFocusReason);
+        q->sendEvent(oldActiveFocusItem, &event);
+
+        QQuickItem *afi = oldActiveFocusItem;
+        while (afi != scope) {
+            if (QQuickItemPrivate::get(afi)->activeFocus) {
+                QQuickItemPrivate::get(afi)->activeFocus = false;
+                changed << afi;
+            }
+            afi = afi->parentItem();
+        }
+    }
+
+    if (item != rootItem) {
+        QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
+        // Correct focus chain in scope
+        if (oldSubFocusItem) {
+            QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
+            while (sfi != scope) {
+                QQuickItemPrivate::get(sfi)->subFocusItem = 0;
+                sfi = sfi->parentItem();
+            }
+        }
+        scopePrivate->subFocusItem = 0;
+
+        if (oldSubFocusItem && !(options & DontChangeFocusProperty)) {
+            QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
+            changed << oldSubFocusItem;
+        }
+    } else if (!(options & DontChangeFocusProperty)) {
+        QQuickItemPrivate::get(item)->focus = false;
+        changed << item;
+    }
+
+    if (newActiveFocusItem) {
+        Q_ASSERT(newActiveFocusItem == scope);
+        activeFocusItem = scope;
+
+        updateInputMethodData();
+
+        QFocusEvent event(QEvent::FocusIn, Qt::OtherFocusReason);
+        q->sendEvent(newActiveFocusItem, &event);
+    } else {
+        updateInputMethodData();
+    }
+
+    if (!changed.isEmpty())
+        notifyFocusChangesRecur(changed.data(), changed.count() - 1);
+}
+
+void QQuickCanvasPrivate::notifyFocusChangesRecur(QQuickItem **items, int remaining)
+{
+    QDeclarativeGuard<QQuickItem> item(*items);
+
+    if (remaining)
+        notifyFocusChangesRecur(items + 1, remaining - 1);
+
+    if (item) {
+        QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+
+        if (itemPrivate->notifiedFocus != itemPrivate->focus) {
+            itemPrivate->notifiedFocus = itemPrivate->focus;
+            emit item->focusChanged(itemPrivate->focus);
+        }
+
+        if (item && itemPrivate->notifiedActiveFocus != itemPrivate->activeFocus) {
+            itemPrivate->notifiedActiveFocus = itemPrivate->activeFocus;
+            itemPrivate->itemChange(QQuickItem::ItemActiveFocusHasChanged, itemPrivate->activeFocus);
+            emit item->activeFocusChanged(itemPrivate->activeFocus);
+        }
+    }
+}
+
+void QQuickCanvasPrivate::updateInputMethodData()
+{
+    QQuickItem *inputItem = 0;
+    if (activeFocusItem && activeFocusItem->flags() & QQuickItem::ItemAcceptsInputMethod)
+        inputItem = activeFocusItem;
+    qApp->inputPanel()->setInputItem(inputItem);
+}
+
+QVariant QQuickCanvas::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+    Q_D(const QQuickCanvas);
+    if (!d->activeFocusItem || !(QQuickItemPrivate::get(d->activeFocusItem)->flags & QQuickItem::ItemAcceptsInputMethod))
+        return QVariant();
+    QVariant value = d->activeFocusItem->inputMethodQuery(query);
+
+    //map geometry types
+    QVariant::Type type = value.type();
+    if (type == QVariant::RectF || type == QVariant::Rect) {
+        const QTransform transform = QQuickItemPrivate::get(d->activeFocusItem)->itemToCanvasTransform();
+        value = transform.mapRect(value.toRectF());
+    } else if (type == QVariant::PointF || type == QVariant::Point) {
+        const QTransform transform = QQuickItemPrivate::get(d->activeFocusItem)->itemToCanvasTransform();
+        value = transform.map(value.toPointF());
+    }
+    return value;
+}
+
+void QQuickCanvasPrivate::dirtyItem(QQuickItem *)
+{
+    Q_Q(QQuickCanvas);
+    q->maybeUpdate();
+}
+
+void QQuickCanvasPrivate::cleanup(QSGNode *n)
+{
+    Q_Q(QQuickCanvas);
+
+    Q_ASSERT(!cleanupNodeList.contains(n));
+    cleanupNodeList.append(n);
+    q->maybeUpdate();
+}
+
+
+QQuickCanvas::QQuickCanvas(QWindow *parent)
+    : QWindow(*(new QQuickCanvasPrivate), parent)
+{
+    Q_D(QQuickCanvas);
+    d->init(this);
+}
+
+QQuickCanvas::QQuickCanvas(QQuickCanvasPrivate &dd, QWindow *parent)
+    : QWindow(dd, parent)
+{
+    Q_D(QQuickCanvas);
+    d->init(this);
+}
+
+QQuickCanvas::~QQuickCanvas()
+{
+    Q_D(QQuickCanvas);
+
+    if (d->thread->isRunning()) {
+        d->thread->stopRendering();
+        delete d->thread;
+        d->thread = 0;
+    }
+
+    // ### should we change ~QQuickItem to handle this better?
+    // manually cleanup for the root item (item destructor only handles these when an item is parented)
+    QQuickItemPrivate *rootItemPrivate = QQuickItemPrivate::get(d->rootItem);
+    rootItemPrivate->removeFromDirtyList();
+
+    delete d->incubationController; d->incubationController = 0;
+
+    delete d->rootItem; d->rootItem = 0;
+    d->cleanupNodes();
+}
+
+QQuickItem *QQuickCanvas::rootItem() const
+{
+    Q_D(const QQuickCanvas);
+
+    return d->rootItem;
+}
+
+QQuickItem *QQuickCanvas::activeFocusItem() const
+{
+    Q_D(const QQuickCanvas);
+
+    return d->activeFocusItem;
+}
+
+QQuickItem *QQuickCanvas::mouseGrabberItem() const
+{
+    Q_D(const QQuickCanvas);
+
+    return d->mouseGrabberItem;
+}
+
+
+bool QQuickCanvasPrivate::clearHover()
+{
+    if (hoverItems.isEmpty())
+        return false;
+
+    QPointF pos = QCursor::pos(); // ### refactor: q->mapFromGlobal(QCursor::pos());
+
+    bool accepted = false;
+    foreach (QQuickItem* item, hoverItems)
+        accepted = sendHoverEvent(QEvent::HoverLeave, item, pos, pos, QGuiApplication::keyboardModifiers(), true) || accepted;
+    hoverItems.clear();
+    return accepted;
+}
+
+
+bool QQuickCanvas::event(QEvent *e)
+{
+    Q_D(QQuickCanvas);
+
+    switch (e->type()) {
+
+    case QEvent::TouchBegin:
+    case QEvent::TouchUpdate:
+    case QEvent::TouchEnd:
+    {
+        QTouchEvent *touch = static_cast<QTouchEvent *>(e);
+        d->translateTouchEvent(touch);
+        d->deliverTouchEvent(touch);
+        if (!touch->isAccepted())
+            return false;
+        break;
+    }
+    case QEvent::Leave:
+        d->clearHover();
+        d->lastMousePosition = QPoint();
+        break;
+    case QEvent::DragEnter:
+    case QEvent::DragLeave:
+    case QEvent::DragMove:
+    case QEvent::Drop:
+        d->deliverDragEvent(&d->dragGrabber, e);
+        break;
+    case QEvent::WindowDeactivate:
+        rootItem()->windowDeactivateEvent();
+        break;
+    default:
+        break;
+    }
+
+    return QWindow::event(e);
+}
+
+void QQuickCanvas::keyPressEvent(QKeyEvent *e)
+{
+    Q_D(QQuickCanvas);
+
+    if (d->activeFocusItem)
+        sendEvent(d->activeFocusItem, e);
+}
+
+void QQuickCanvas::keyReleaseEvent(QKeyEvent *e)
+{
+    Q_D(QQuickCanvas);
+
+    if (d->activeFocusItem)
+        sendEvent(d->activeFocusItem, e);
+}
+
+void QQuickCanvas::inputMethodEvent(QInputMethodEvent *e)
+{
+    Q_D(QQuickCanvas);
+
+    if (d->activeFocusItem)
+        sendEvent(d->activeFocusItem, e);
+}
+
+bool QQuickCanvasPrivate::deliverInitialMousePressEvent(QQuickItem *item, QMouseEvent *event)
+{
+    Q_Q(QQuickCanvas);
+
+    QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+    if (itemPrivate->opacity == 0.0)
+        return false;
+
+    if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
+        QPointF p = item->mapFromScene(event->windowPos());
+        if (!QRectF(0, 0, item->width(), item->height()).contains(p))
+            return false;
+    }
+
+    QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
+    for (int ii = children.count() - 1; ii >= 0; --ii) {
+        QQuickItem *child = children.at(ii);
+        if (!child->isVisible() || !child->isEnabled())
+            continue;
+        if (deliverInitialMousePressEvent(child, event))
+            return true;
+    }
+
+    if (itemPrivate->acceptedMouseButtons & event->button()) {
+        QPointF p = item->mapFromScene(event->windowPos());
+        if (QRectF(0, 0, item->width(), item->height()).contains(p)) {
+            QMouseEvent me(event->type(), p, event->windowPos(), event->screenPos(),
+                           event->button(), event->buttons(), event->modifiers());
+            me.accept();
+            mouseGrabberItem = item;
+            q->sendEvent(item, &me);
+            event->setAccepted(me.isAccepted());
+            if (me.isAccepted())
+                return true;
+            mouseGrabberItem->ungrabMouse();
+            mouseGrabberItem = 0;
+        }
+    }
+
+    return false;
+}
+
+bool QQuickCanvasPrivate::deliverMouseEvent(QMouseEvent *event)
+{
+    Q_Q(QQuickCanvas);
+
+    lastMousePosition = event->windowPos();
+
+    if (!mouseGrabberItem &&
+         event->type() == QEvent::MouseButtonPress &&
+         (event->button() & event->buttons()) == event->buttons()) {
+        return deliverInitialMousePressEvent(rootItem, event);
+    }
+
+    if (mouseGrabberItem) {
+        QQuickItemPrivate *mgPrivate = QQuickItemPrivate::get(mouseGrabberItem);
+        const QTransform &transform = mgPrivate->canvasToItemTransform();
+        QMouseEvent me(event->type(), transform.map(event->windowPos()), event->windowPos(), event->screenPos(),
+                       event->button(), event->buttons(), event->modifiers());
+        me.accept();
+        q->sendEvent(mouseGrabberItem, &me);
+        event->setAccepted(me.isAccepted());
+        if (me.isAccepted())
+            return true;
+    }
+
+    return false;
+}
+
+void QQuickCanvas::mousePressEvent(QMouseEvent *event)
+{
+    Q_D(QQuickCanvas);
+
+#ifdef MOUSE_DEBUG
+    qWarning() << "QQuickCanvas::mousePressEvent()" << event->pos() << event->button() << event->buttons();
+#endif
+
+    d->deliverMouseEvent(event);
+}
+
+void QQuickCanvas::mouseReleaseEvent(QMouseEvent *event)
+{
+    Q_D(QQuickCanvas);
+
+#ifdef MOUSE_DEBUG
+    qWarning() << "QQuickCanvas::mouseReleaseEvent()" << event->pos() << event->button() << event->buttons();
+#endif
+
+    if (!d->mouseGrabberItem) {
+        QWindow::mouseReleaseEvent(event);
+        return;
+    }
+
+    d->deliverMouseEvent(event);
+    d->mouseGrabberItem = 0;
+}
+
+void QQuickCanvas::mouseDoubleClickEvent(QMouseEvent *event)
+{
+    Q_D(QQuickCanvas);
+
+#ifdef MOUSE_DEBUG
+    qWarning() << "QQuickCanvas::mouseDoubleClickEvent()" << event->pos() << event->button() << event->buttons();
+#endif
+
+    if (!d->mouseGrabberItem && (event->button() & event->buttons()) == event->buttons()) {
+        if (d->deliverInitialMousePressEvent(d->rootItem, event))
+            event->accept();
+        else
+            event->ignore();
+        return;
+    }
+
+    d->deliverMouseEvent(event);
+}
+
+bool QQuickCanvasPrivate::sendHoverEvent(QEvent::Type type, QQuickItem *item,
+                                      const QPointF &scenePos, const QPointF &lastScenePos,
+                                      Qt::KeyboardModifiers modifiers, bool accepted)
+{
+    Q_Q(QQuickCanvas);
+    const QTransform transform = QQuickItemPrivate::get(item)->canvasToItemTransform();
+
+    //create copy of event
+    QHoverEvent hoverEvent(type, transform.map(scenePos), transform.map(lastScenePos), modifiers);
+    hoverEvent.setAccepted(accepted);
+
+    q->sendEvent(item, &hoverEvent);
+
+    return hoverEvent.isAccepted();
+}
+
+void QQuickCanvas::mouseMoveEvent(QMouseEvent *event)
+{
+    Q_D(QQuickCanvas);
+
+#ifdef MOUSE_DEBUG
+    qWarning() << "QQuickCanvas::mouseMoveEvent()" << event->pos() << event->button() << event->buttons();
+#endif
+
+    if (!d->mouseGrabberItem) {
+        if (d->lastMousePosition.isNull())
+            d->lastMousePosition = event->windowPos();
+        QPointF last = d->lastMousePosition;
+        d->lastMousePosition = event->windowPos();
+
+        bool accepted = event->isAccepted();
+        bool delivered = d->deliverHoverEvent(d->rootItem, event->windowPos(), last, event->modifiers(), accepted);
+        if (!delivered) {
+            //take care of any exits
+            accepted = d->clearHover();
+        }
+        event->setAccepted(accepted);
+        return;
+    }
+
+    d->deliverMouseEvent(event);
+}
+
+bool QQuickCanvasPrivate::deliverHoverEvent(QQuickItem *item, const QPointF &scenePos, const QPointF &lastScenePos,
+                                         Qt::KeyboardModifiers modifiers, bool &accepted)
+{
+    QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+    if (itemPrivate->opacity == 0.0)
+        return false;
+
+    if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
+        QPointF p = item->mapFromScene(scenePos);
+        if (!QRectF(0, 0, item->width(), item->height()).contains(p))
+            return false;
+    }
+
+    QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
+    for (int ii = children.count() - 1; ii >= 0; --ii) {
+        QQuickItem *child = children.at(ii);
+        if (!child->isVisible() || !child->isEnabled())
+            continue;
+        if (deliverHoverEvent(child, scenePos, lastScenePos, modifiers, accepted))
+            return true;
+    }
+
+    if (itemPrivate->hoverEnabled) {
+        QPointF p = item->mapFromScene(scenePos);
+        if (QRectF(0, 0, item->width(), item->height()).contains(p)) {
+            if (!hoverItems.isEmpty() && hoverItems[0] == item) {
+                //move
+                accepted = sendHoverEvent(QEvent::HoverMove, item, scenePos, lastScenePos, modifiers, accepted);
+            } else {
+                QList<QQuickItem *> itemsToHover;
+                QQuickItem* parent = item;
+                itemsToHover << item;
+                while ((parent = parent->parentItem()))
+                    itemsToHover << parent;
+
+                // Leaving from previous hovered items until we reach the item or one of its ancestors.
+                while (!hoverItems.isEmpty() && !itemsToHover.contains(hoverItems[0])) {
+                    sendHoverEvent(QEvent::HoverLeave, hoverItems[0], scenePos, lastScenePos, modifiers, accepted);
+                    hoverItems.removeFirst();
+                }
+
+                if (!hoverItems.isEmpty() && hoverItems[0] == item){//Not entering a new Item
+                    // ### Shouldn't we send moves for the parent items as well?
+                    accepted = sendHoverEvent(QEvent::HoverMove, item, scenePos, lastScenePos, modifiers, accepted);
+                } else {
+                    // Enter items that are not entered yet.
+                    int startIdx = -1;
+                    if (!hoverItems.isEmpty())
+                        startIdx = itemsToHover.indexOf(hoverItems[0]) - 1;
+                    if (startIdx == -1)
+                        startIdx = itemsToHover.count() - 1;
+
+                    for (int i = startIdx; i >= 0; i--) {
+                        QQuickItem *itemToHover = itemsToHover[i];
+                        if (QQuickItemPrivate::get(itemToHover)->hoverEnabled) {
+                            hoverItems.prepend(itemToHover);
+                            sendHoverEvent(QEvent::HoverEnter, itemToHover, scenePos, lastScenePos, modifiers, accepted);
+                        }
+                    }
+                }
+            }
+            return true;
+        }
+    }
+
+    return false;
+}
+
+bool QQuickCanvasPrivate::deliverWheelEvent(QQuickItem *item, QWheelEvent *event)
+{
+    Q_Q(QQuickCanvas);
+    QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+    if (itemPrivate->opacity == 0.0)
+        return false;
+
+    if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
+        QPointF p = item->mapFromScene(event->posF());
+        if (!QRectF(0, 0, item->width(), item->height()).contains(p))
+            return false;
+    }
+
+    QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
+    for (int ii = children.count() - 1; ii >= 0; --ii) {
+        QQuickItem *child = children.at(ii);
+        if (!child->isVisible() || !child->isEnabled())
+            continue;
+        if (deliverWheelEvent(child, event))
+            return true;
+    }
+
+    QPointF p = item->mapFromScene(event->posF());
+    if (QRectF(0, 0, item->width(), item->height()).contains(p)) {
+        QWheelEvent wheel(p, event->delta(), event->buttons(), event->modifiers(), event->orientation());
+        wheel.accept();
+        q->sendEvent(item, &wheel);
+        if (wheel.isAccepted()) {
+            event->accept();
+            return true;
+        }
+    }
+
+    return false;
+}
+
+#ifndef QT_NO_WHEELEVENT
+void QQuickCanvas::wheelEvent(QWheelEvent *event)
+{
+    Q_D(QQuickCanvas);
+#ifdef MOUSE_DEBUG
+    qWarning() << "QQuickCanvas::wheelEvent()" << event->pos() << event->delta() << event->orientation();
+#endif
+    event->ignore();
+    d->deliverWheelEvent(d->rootItem, event);
+}
+#endif // QT_NO_WHEELEVENT
+
+bool QQuickCanvasPrivate::deliverTouchEvent(QTouchEvent *event)
+{
+#ifdef TOUCH_DEBUG
+    if (event->type() == QEvent::TouchBegin)
+        qWarning("touchBeginEvent");
+    else if (event->type() == QEvent::TouchUpdate)
+        qWarning("touchUpdateEvent");
+    else if (event->type() == QEvent::TouchEnd)
+        qWarning("touchEndEvent");
+#endif
+
+    QHash<QQuickItem *, QList<QTouchEvent::TouchPoint> > updatedPoints;
+
+    if (event->type() == QTouchEvent::TouchBegin) {     // all points are new touch points
+        QSet<int> acceptedNewPoints;
+        deliverTouchPoints(rootItem, event, event->touchPoints(), &acceptedNewPoints, &updatedPoints);
+        if (acceptedNewPoints.count() > 0)
+            event->accept();
+        return event->isAccepted();
+    }
+
+    const QList<QTouchEvent::TouchPoint> &touchPoints = event->touchPoints();
+    QList<QTouchEvent::TouchPoint> newPoints;
+    QQuickItem *item = 0;
+    for (int i=0; i<touchPoints.count(); i++) {
+        const QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
+        switch (touchPoint.state()) {
+            case Qt::TouchPointPressed:
+                newPoints << touchPoint;
+                break;
+            case Qt::TouchPointMoved:
+            case Qt::TouchPointStationary:
+            case Qt::TouchPointReleased:
+                if (itemForTouchPointId.contains(touchPoint.id())) {
+                    item = itemForTouchPointId[touchPoint.id()];
+                    if (item)
+                        updatedPoints[item].append(touchPoint);
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+    if (newPoints.count() > 0 || updatedPoints.count() > 0) {
+        QSet<int> acceptedNewPoints;
+        int prevCount = updatedPoints.count();
+        deliverTouchPoints(rootItem, event, newPoints, &acceptedNewPoints, &updatedPoints);
+        if (acceptedNewPoints.count() > 0 || updatedPoints.count() != prevCount)
+            event->accept();
+    }
+
+    if (event->touchPointStates() & Qt::TouchPointReleased) {
+        for (int i=0; i<touchPoints.count(); i++) {
+            if (touchPoints[i].state() == Qt::TouchPointReleased)
+                itemForTouchPointId.remove(touchPoints[i].id());
+        }
+    }
+
+    return event->isAccepted();
+}
+
+bool QQuickCanvasPrivate::deliverTouchPoints(QQuickItem *item, QTouchEvent *event, const QList<QTouchEvent::TouchPoint> &newPoints, QSet<int> *acceptedNewPoints, QHash<QQuickItem *, QList<QTouchEvent::TouchPoint> > *updatedPoints)
+{
+    Q_Q(QQuickCanvas);
+    QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+
+    if (itemPrivate->opacity == 0.0)
+        return false;
+
+    if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
+        QRectF bounds(0, 0, item->width(), item->height());
+        for (int i=0; i<newPoints.count(); i++) {
+            QPointF p = item->mapFromScene(newPoints[i].scenePos());
+            if (!bounds.contains(p))
+                return false;
+        }
+    }
+
+    QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
+    for (int ii = children.count() - 1; ii >= 0; --ii) {
+        QQuickItem *child = children.at(ii);
+        if (!child->isEnabled())
+            continue;
+        if (deliverTouchPoints(child, event, newPoints, acceptedNewPoints, updatedPoints))
+            return true;
+    }
+
+    QList<QTouchEvent::TouchPoint> matchingPoints;
+    if (newPoints.count() > 0 && acceptedNewPoints->count() < newPoints.count()) {
+        QRectF bounds(0, 0, item->width(), item->height());
+        for (int i=0; i<newPoints.count(); i++) {
+            if (acceptedNewPoints->contains(newPoints[i].id()))
+                continue;
+            QPointF p = item->mapFromScene(newPoints[i].scenePos());
+            if (bounds.contains(p))
+                matchingPoints << newPoints[i];
+        }
+    }
+
+    if (matchingPoints.count() > 0 || (*updatedPoints)[item].count() > 0) {
+        QList<QTouchEvent::TouchPoint> &eventPoints = (*updatedPoints)[item];
+        eventPoints.append(matchingPoints);
+        transformTouchPoints(eventPoints, itemPrivate->canvasToItemTransform());
+
+        Qt::TouchPointStates eventStates;
+        for (int i=0; i<eventPoints.count(); i++)
+            eventStates |= eventPoints[i].state();
+        // if all points have the same state, set the event type accordingly
+        QEvent::Type eventType;
+        switch (eventStates) {
+            case Qt::TouchPointPressed:
+                eventType = QEvent::TouchBegin;
+                break;
+            case Qt::TouchPointReleased:
+                eventType = QEvent::TouchEnd;
+                break;
+            default:
+                eventType = QEvent::TouchUpdate;
+                break;
+        }
+
+        if (eventStates != Qt::TouchPointStationary) {
+            QTouchEvent touchEvent(eventType);
+            // touchEvent.setWidget(q); // ### refactor: what is the consequence of not setting the widget?
+            touchEvent.setDeviceType(event->deviceType());
+            touchEvent.setModifiers(event->modifiers());
+            touchEvent.setTouchPointStates(eventStates);
+            touchEvent.setTouchPoints(eventPoints);
+            touchEvent.setTimestamp(event->timestamp());
+
+            touchEvent.accept();
+            q->sendEvent(item, &touchEvent);
+
+            if (touchEvent.isAccepted()) {
+                for (int i=0; i<matchingPoints.count(); i++) {
+                    itemForTouchPointId[matchingPoints[i].id()] = item;
+                    acceptedNewPoints->insert(matchingPoints[i].id());
+                }
+            }
+        }
+    }
+
+    updatedPoints->remove(item);
+    if (acceptedNewPoints->count() == newPoints.count() && updatedPoints->isEmpty())
+        return true;
+
+    return false;
+}
+
+void QQuickCanvasPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QEvent *event)
+{
+    Q_Q(QQuickCanvas);
+    grabber->resetTarget();
+    QQuickDragGrabber::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());
+                QQuickDropEventEx::copyActions(&translatedEvent, *e);
+                q->sendEvent(**grabItem, &translatedEvent);
+                e->setAccepted(translatedEvent.isAccepted());
+                e->setDropAction(translatedEvent.dropAction());
+                grabber->setTarget(**grabItem);
+            }
+        }
+        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());
+                        QQuickDropEventEx::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);
+            }
+        }
+    }
+    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());
+        QQuickDropEventEx::copyActions(&enterEvent, *e);
+        event->setAccepted(deliverDragEvent(grabber, rootItem, &enterEvent));
+    }
+}
+
+bool QQuickCanvasPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQuickItem *item, QDragMoveEvent *event)
+{
+    Q_Q(QQuickCanvas);
+    bool accepted = false;
+    QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+    if (itemPrivate->opacity == 0.0 || !item->isVisible() || !item->isEnabled())
+        return false;
+
+    QPointF p = item->mapFromScene(event->pos());
+    if (QRectF(0, 0, item->width(), item->height()).contains(p)) {
+        if (event->type() == QEvent::DragMove || itemPrivate->flags & QQuickItem::ItemAcceptsDrops) {
+            QDragMoveEvent translatedEvent(
+                    p.toPoint(),
+                    event->possibleActions(),
+                    event->mimeData(),
+                    event->mouseButtons(),
+                    event->keyboardModifiers(),
+                    event->type());
+            QQuickDropEventEx::copyActions(&translatedEvent, *event);
+            q->sendEvent(item, &translatedEvent);
+            if (event->type() == QEvent::DragEnter) {
+                if (translatedEvent.isAccepted()) {
+                    grabber->grab(item);
+                    accepted = true;
+                }
+            } else {
+                accepted = true;
+            }
+        }
+    } else if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
+        return false;
+    }
+
+    QDragEnterEvent enterEvent(
+            event->pos(),
+            event->possibleActions(),
+            event->mimeData(),
+            event->mouseButtons(),
+            event->keyboardModifiers());
+    QQuickDropEventEx::copyActions(&enterEvent, *event);
+    QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
+    for (int ii = children.count() - 1; ii >= 0; --ii) {
+        if (deliverDragEvent(grabber, children.at(ii), &enterEvent))
+            return true;
+    }
+
+    return accepted;
+}
+
+bool QQuickCanvasPrivate::sendFilteredMouseEvent(QQuickItem *target, QQuickItem *item, QMouseEvent *event)
+{
+    if (!target)
+        return false;
+
+    QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(target);
+    if (targetPrivate->filtersChildMouseEvents)
+        if (target->childMouseEventFilter(item, event))
+            return true;
+
+    if (sendFilteredMouseEvent(target->parentItem(), item, event))
+        return true;
+
+    return false;
+}
+
+bool QQuickCanvas::sendEvent(QQuickItem *item, QEvent *e)
+{
+    Q_D(QQuickCanvas);
+
+    if (!item) {
+        qWarning("QQuickCanvas::sendEvent: Cannot send event to a null item");
+        return false;
+    }
+
+    Q_ASSERT(e);
+
+    switch (e->type()) {
+    case QEvent::KeyPress:
+    case QEvent::KeyRelease:
+        e->accept();
+        QQuickItemPrivate::get(item)->deliverKeyEvent(static_cast<QKeyEvent *>(e));
+        while (!e->isAccepted() && (item = item->parentItem())) {
+            e->accept();
+            QQuickItemPrivate::get(item)->deliverKeyEvent(static_cast<QKeyEvent *>(e));
+        }
+        break;
+    case QEvent::InputMethod:
+        e->accept();
+        QQuickItemPrivate::get(item)->deliverInputMethodEvent(static_cast<QInputMethodEvent *>(e));
+        while (!e->isAccepted() && (item = item->parentItem())) {
+            e->accept();
+            QQuickItemPrivate::get(item)->deliverInputMethodEvent(static_cast<QInputMethodEvent *>(e));
+        }
+        break;
+    case QEvent::FocusIn:
+    case QEvent::FocusOut:
+        QQuickItemPrivate::get(item)->deliverFocusEvent(static_cast<QFocusEvent *>(e));
+        break;
+    case QEvent::MouseButtonPress:
+    case QEvent::MouseButtonRelease:
+    case QEvent::MouseButtonDblClick:
+    case QEvent::MouseMove:
+        // 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)) {
+                se->accept();
+                QQuickItemPrivate::get(item)->deliverMouseEvent(se);
+            }
+        }
+        break;
+    case QEvent::Wheel:
+        QQuickItemPrivate::get(item)->deliverWheelEvent(static_cast<QWheelEvent *>(e));
+        break;
+    case QEvent::HoverEnter:
+    case QEvent::HoverLeave:
+    case QEvent::HoverMove:
+        QQuickItemPrivate::get(item)->deliverHoverEvent(static_cast<QHoverEvent *>(e));
+        break;
+    case QEvent::TouchBegin:
+    case QEvent::TouchUpdate:
+    case QEvent::TouchEnd:
+        QQuickItemPrivate::get(item)->deliverTouchEvent(static_cast<QTouchEvent *>(e));
+        break;
+    case QEvent::DragEnter:
+    case QEvent::DragMove:
+    case QEvent::DragLeave:
+    case QEvent::Drop:
+        QQuickItemPrivate::get(item)->deliverDragEvent(e);
+        break;
+    default:
+        break;
+    }
+
+    return false;
+}
+
+void QQuickCanvasPrivate::cleanupNodes()
+{
+    for (int ii = 0; ii < cleanupNodeList.count(); ++ii)
+        delete cleanupNodeList.at(ii);
+    cleanupNodeList.clear();
+}
+
+void QQuickCanvasPrivate::updateDirtyNodes()
+{
+#ifdef DIRTY_DEBUG
+    qWarning() << "QQuickCanvasPrivate::updateDirtyNodes():";
+#endif
+
+    cleanupNodes();
+
+    QQuickItem *updateList = dirtyItemList;
+    dirtyItemList = 0;
+    if (updateList) QQuickItemPrivate::get(updateList)->prevDirtyItem = &updateList;
+
+    while (updateList) {
+        QQuickItem *item = updateList;
+        QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(item);
+        itemPriv->removeFromDirtyList();
+
+#ifdef DIRTY_DEBUG
+        qWarning() << "   QSGNode:" << item << qPrintable(itemPriv->dirtyToString());
+#endif
+        updateDirtyNode(item);
+    }
+}
+
+void QQuickCanvasPrivate::updateDirtyNode(QQuickItem *item)
+{
+#ifdef QML_RUNTIME_TESTING
+    bool didFlash = false;
+#endif
+
+    QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(item);
+    quint32 dirty = itemPriv->dirtyAttributes;
+    itemPriv->dirtyAttributes = 0;
+
+    if ((dirty & QQuickItemPrivate::TransformUpdateMask) ||
+        (dirty & QQuickItemPrivate::Size && itemPriv->origin != QQuickItem::TopLeft &&
+         (itemPriv->scale != 1. || itemPriv->rotation != 0.))) {
+
+        QMatrix4x4 matrix;
+
+        if (itemPriv->x != 0. || itemPriv->y != 0.)
+            matrix.translate(itemPriv->x, itemPriv->y);
+
+        for (int ii = itemPriv->transforms.count() - 1; ii >= 0; --ii)
+            itemPriv->transforms.at(ii)->applyTo(&matrix);
+
+        if (itemPriv->scale != 1. || itemPriv->rotation != 0.) {
+            QPointF origin = item->transformOriginPoint();
+            matrix.translate(origin.x(), origin.y());
+            if (itemPriv->scale != 1.)
+                matrix.scale(itemPriv->scale, itemPriv->scale);
+            if (itemPriv->rotation != 0.)
+                matrix.rotate(itemPriv->rotation, 0, 0, 1);
+            matrix.translate(-origin.x(), -origin.y());
+        }
+
+        itemPriv->itemNode()->setMatrix(matrix);
+    }
+
+    bool clipEffectivelyChanged = dirty & QQuickItemPrivate::Clip &&
+                                  ((item->clip() == false) != (itemPriv->clipNode == 0));
+    bool effectRefEffectivelyChanged = dirty & QQuickItemPrivate::EffectReference &&
+                                  ((itemPriv->effectRefCount == 0) != (itemPriv->rootNode == 0));
+
+    if (clipEffectivelyChanged) {
+        QSGNode *parent = itemPriv->opacityNode ? (QSGNode *) itemPriv->opacityNode : (QSGNode *)itemPriv->itemNode();
+        QSGNode *child = itemPriv->rootNode ? (QSGNode *)itemPriv->rootNode : (QSGNode *)itemPriv->groupNode;
+
+        if (item->clip()) {
+            Q_ASSERT(itemPriv->clipNode == 0);
+            itemPriv->clipNode = new QQuickDefaultClipNode(item->boundingRect());
+            itemPriv->clipNode->update();
+
+            if (child)
+                parent->removeChildNode(child);
+            parent->appendChildNode(itemPriv->clipNode);
+            if (child)
+                itemPriv->clipNode->appendChildNode(child);
+
+        } else {
+            Q_ASSERT(itemPriv->clipNode != 0);
+            parent->removeChildNode(itemPriv->clipNode);
+            if (child)
+                itemPriv->clipNode->removeChildNode(child);
+            delete itemPriv->clipNode;
+            itemPriv->clipNode = 0;
+            if (child)
+                parent->appendChildNode(child);
+        }
+    }
+
+    if (dirty & QQuickItemPrivate::ChildrenUpdateMask)
+        itemPriv->childContainerNode()->removeAllChildNodes();
+
+    if (effectRefEffectivelyChanged) {
+        QSGNode *parent = itemPriv->clipNode;
+        if (!parent)
+            parent = itemPriv->opacityNode;
+        if (!parent)
+            parent = itemPriv->itemNode();
+        QSGNode *child = itemPriv->groupNode;
+
+        if (itemPriv->effectRefCount) {
+            Q_ASSERT(itemPriv->rootNode == 0);
+            itemPriv->rootNode = new QSGRootNode;
+
+            if (child)
+                parent->removeChildNode(child);
+            parent->appendChildNode(itemPriv->rootNode);
+            if (child)
+                itemPriv->rootNode->appendChildNode(child);
+        } else {
+            Q_ASSERT(itemPriv->rootNode != 0);
+            parent->removeChildNode(itemPriv->rootNode);
+            if (child)
+                itemPriv->rootNode->removeChildNode(child);
+            delete itemPriv->rootNode;
+            itemPriv->rootNode = 0;
+            if (child)
+                parent->appendChildNode(child);
+        }
+    }
+
+    if (dirty & QQuickItemPrivate::ChildrenUpdateMask) {
+        QSGNode *groupNode = itemPriv->groupNode;
+        if (groupNode)
+            groupNode->removeAllChildNodes();
+
+        QList<QQuickItem *> orderedChildren = itemPriv->paintOrderChildItems();
+        int ii = 0;
+
+        for (; ii < orderedChildren.count() && orderedChildren.at(ii)->z() < 0; ++ii) {
+            QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(orderedChildren.at(ii));
+            if (!childPrivate->explicitVisible && !childPrivate->effectRefCount)
+                continue;
+            if (childPrivate->itemNode()->parent())
+                childPrivate->itemNode()->parent()->removeChildNode(childPrivate->itemNode());
+
+            itemPriv->childContainerNode()->appendChildNode(childPrivate->itemNode());
+        }
+        itemPriv->beforePaintNode = itemPriv->groupNode ? itemPriv->groupNode->lastChild() : 0;
+
+        if (itemPriv->paintNode)
+            itemPriv->childContainerNode()->appendChildNode(itemPriv->paintNode);
+
+        for (; ii < orderedChildren.count(); ++ii) {
+            QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(orderedChildren.at(ii));
+            if (!childPrivate->explicitVisible && !childPrivate->effectRefCount)
+                continue;
+            if (childPrivate->itemNode()->parent())
+                childPrivate->itemNode()->parent()->removeChildNode(childPrivate->itemNode());
+
+            itemPriv->childContainerNode()->appendChildNode(childPrivate->itemNode());
+        }
+    }
+
+    if ((dirty & QQuickItemPrivate::Size) && itemPriv->clipNode) {
+        itemPriv->clipNode->setRect(item->boundingRect());
+        itemPriv->clipNode->update();
+    }
+
+    if (dirty & (QQuickItemPrivate::OpacityValue | QQuickItemPrivate::Visible | QQuickItemPrivate::HideReference)) {
+        qreal opacity = itemPriv->explicitVisible && itemPriv->hideRefCount == 0
+                      ? itemPriv->opacity : qreal(0);
+
+        if (opacity != 1 && !itemPriv->opacityNode) {
+            itemPriv->opacityNode = new QSGOpacityNode;
+
+            QSGNode *parent = itemPriv->itemNode();
+            QSGNode *child = itemPriv->clipNode;
+            if (!child)
+                child = itemPriv->rootNode;
+            if (!child)
+                child = itemPriv->groupNode;
+
+            if (child)
+                parent->removeChildNode(child);
+            parent->appendChildNode(itemPriv->opacityNode);
+            if (child)
+                itemPriv->opacityNode->appendChildNode(child);
+        }
+        if (itemPriv->opacityNode)
+            itemPriv->opacityNode->setOpacity(opacity);
+    }
+
+    if (dirty & QQuickItemPrivate::ContentUpdateMask) {
+
+        if (itemPriv->flags & QQuickItem::ItemHasContents) {
+            updatePaintNodeData.transformNode = itemPriv->itemNode();
+            itemPriv->paintNode = item->updatePaintNode(itemPriv->paintNode, &updatePaintNodeData);
+
+            Q_ASSERT(itemPriv->paintNode == 0 ||
+                     itemPriv->paintNode->parent() == 0 ||
+                     itemPriv->paintNode->parent() == itemPriv->childContainerNode());
+
+            if (itemPriv->paintNode && itemPriv->paintNode->parent() == 0) {
+                if (itemPriv->beforePaintNode)
+                    itemPriv->childContainerNode()->insertChildNodeAfter(itemPriv->paintNode, itemPriv->beforePaintNode);
+                else
+                    itemPriv->childContainerNode()->prependChildNode(itemPriv->paintNode);
+            }
+        } else if (itemPriv->paintNode) {
+            delete itemPriv->paintNode;
+            itemPriv->paintNode = 0;
+        }
+    }
+
+#ifndef QT_NO_DEBUG
+    // Check consistency.
+    const QSGNode *nodeChain[] = {
+        itemPriv->itemNodeInstance,
+        itemPriv->opacityNode,
+        itemPriv->clipNode,
+        itemPriv->rootNode,
+        itemPriv->groupNode,
+        itemPriv->paintNode,
+    };
+
+    int ip = 0;
+    for (;;) {
+        while (ip < 5 && nodeChain[ip] == 0)
+            ++ip;
+        if (ip == 5)
+            break;
+        int ic = ip + 1;
+        while (ic < 5 && nodeChain[ic] == 0)
+            ++ic;
+        const QSGNode *parent = nodeChain[ip];
+        const QSGNode *child = nodeChain[ic];
+        if (child == 0) {
+            Q_ASSERT(parent == itemPriv->groupNode || parent->childCount() == 0);
+        } else {
+            Q_ASSERT(parent == itemPriv->groupNode || parent->childCount() == 1);
+            Q_ASSERT(child->parent() == parent);
+            bool containsChild = false;
+            for (QSGNode *n = parent->firstChild(); n; n = n->nextSibling())
+                containsChild |= (n == child);
+            Q_ASSERT(containsChild);
+        }
+        ip = ic;
+    }
+#endif
+
+#ifdef QML_RUNTIME_TESTING
+    if (itemPriv->sceneGraphContext()->isFlashModeEnabled()) {
+        QSGFlashNode *flash = new QSGFlashNode();
+        flash->setRect(item->boundingRect());
+        itemPriv->childContainerNode()->appendChildNode(flash);
+        didFlash = true;
+    }
+    Q_Q(QQuickCanvas);
+    if (didFlash) {
+        q->maybeUpdate();
+    }
+#endif
+
+}
+
+void QQuickCanvas::maybeUpdate()
+{
+    Q_D(QQuickCanvas);
+
+    if (d->thread && d->thread->isRunning())
+        d->thread->maybeUpdate();
+}
+
+/*!
+    \fn void QSGEngine::sceneGraphInitialized();
+
+    This signal is emitted when the scene graph has been initialized.
+
+    This signal will be emitted from the scene graph rendering thread.
+ */
+
+/*!
+    Returns the QSGEngine used for this scene.
+
+    The engine will only be available once the scene graph has been
+    initialized. Register for the sceneGraphEngine() signal to get
+    notification about this.
+ */
+
+QSGEngine *QQuickCanvas::sceneGraphEngine() const
+{
+    Q_D(const QQuickCanvas);
+    if (d->context && d->context->isReady())
+        return d->context->engine();
+    return 0;
+}
+
+
+
+/*!
+    Sets the render target for this canvas to be \a fbo.
+
+    The specified fbo must be created in the context of the canvas
+    or one that shares with it.
+
+    \warning
+    This function can only be called from the thread doing
+    the rendering.
+ */
+
+void QQuickCanvas::setRenderTarget(QOpenGLFramebufferObject *fbo)
+{
+    Q_D(QQuickCanvas);
+    if (d->context && d->context && QThread::currentThread() != d->context->thread()) {
+        qWarning("QQuickCanvas::setRenderThread: Cannot set render target from outside the rendering thread");
+        return;
+    }
+
+    d->renderTarget = fbo;
+}
+
+
+
+/*!
+    Returns the render target for this canvas.
+
+    The default is to render to the surface of the canvas, in which
+    case the render target is 0.
+ */
+QOpenGLFramebufferObject *QQuickCanvas::renderTarget() const
+{
+    Q_D(const QQuickCanvas);
+    return d->renderTarget;
+}
+
+
+/*!
+    Grabs the contents of the framebuffer and returns it as an image.
+
+    This function might not work if the view is not visible.
+
+    \warning Calling this function will cause performance problems.
+
+    \warning This function can only be called from the GUI thread.
+ */
+QImage QQuickCanvas::grabFrameBuffer()
+{
+    Q_D(QQuickCanvas);
+    return d->thread ? d->thread->grab() : QImage();
+}
+
+/*!
+    Returns an incubation controller that splices incubation between frames
+    for this canvas.  QQuickView automatically installs this controller for you.
+
+    The controller is owned by the canvas and will be destroyed when the canvas
+    is deleted.
+*/
+QDeclarativeIncubationController *QQuickCanvas::incubationController() const
+{
+    Q_D(const QQuickCanvas);
+
+    if (!d->incubationController)
+        d->incubationController = new QQuickCanvasIncubationController(const_cast<QQuickCanvasPrivate *>(d));
+    return d->incubationController;
+}
+
+
+void QQuickCanvasRenderLoop::createGLContext()
+{
+    gl = new QOpenGLContext();
+    gl->setFormat(renderer->requestedFormat());
+    gl->create();
+}
+
+void QQuickCanvasRenderThread::run()
+{
+#ifdef THREAD_DEBUG
+    qDebug("QML Rendering Thread Started");
+#endif
+
+    if (!glContext()) {
+        createGLContext();
+        makeCurrent();
+        initializeSceneGraph();
+    } else {
+        makeCurrent();
+    }
+
+    while (!shouldExit) {
+        lock();
+
+        bool sizeChanged = false;
+        isExternalUpdatePending = false;
+
+        if (renderedSize != windowSize) {
+#ifdef THREAD_DEBUG
+            printf("                RenderThread: window has changed size...\n");
+#endif
+            glViewport(0, 0, windowSize.width(), windowSize.height());
+            sizeChanged = true;
+        }
+
+#ifdef THREAD_DEBUG
+        printf("                RenderThread: preparing to sync...\n");
+#endif
+
+        if (!isGuiBlocked) {
+            isGuiBlockPending = true;
+
+#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");
+#endif
+            wait();
+
+            isGuiBlockPending = false;
+        }
+
+#ifdef THREAD_DEBUG
+        printf("                RenderThread: Doing locked sync\n");
+#endif
+#ifdef QQUICK_CANVAS_TIMING
+        if (qquick_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 QQUICK_CANVAS_TIMING
+        if (qquick_canvas_timing)
+            syncTime = threadTimer.elapsed();
+#endif
+
+#ifdef THREAD_DEBUG
+        printf("                RenderThread: rendering... %d x %d\n", windowSize.width(), windowSize.height());
+#endif
+
+        renderSceneGraph(windowSize);
+#ifdef QQUICK_CANVAS_TIMING
+        if (qquick_canvas_timing)
+            renderTime = threadTimer.elapsed() - syncTime;
+#endif
+
+        // The content of the target buffer is undefined after swap() so grab needs
+        // to happen before swap();
+        if (doGrab) {
+#ifdef THREAD_DEBUG
+            printf("                RenderThread: doing a grab...\n");
+#endif
+            grabContent = qt_gl_read_framebuffer(windowSize, false, false);
+            doGrab = false;
+        }
+
+#ifdef THREAD_DEBUG
+        printf("                RenderThread: wait for swap...\n");
+#endif
+
+        swapBuffers();
+#ifdef THREAD_DEBUG
+        printf("                RenderThread: swap complete...\n");
+#endif
+#ifdef QQUICK_CANVAS_TIMING
+        if (qquick_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;
+        if (sizeChanged)
+            renderedSize = windowSize;
+
+        // Wake the GUI thread now that rendering is complete, to signal that painting
+        // is done, resizing is done or grabbing is completed. For grabbing, we're
+        // signalling this much later than needed (we could have done it before swap)
+        // but we don't want to lock an extra time.
+        wake();
+
+        if (!animationRunning && !isExternalUpdatePending && !shouldExit && !doGrab) {
+#ifdef THREAD_DEBUG
+            printf("                RenderThread: nothing to do, going to sleep...\n");
+#endif
+            isRenderBlocked = true;
+            wait();
+            isRenderBlocked = false;
+        }
+
+        unlock();
+
+        // Process any "deleteLater" objects...
+        QCoreApplication::processEvents();
+    }
+
+#ifdef THREAD_DEBUG
+    printf("                RenderThread: render loop exited... Good Night!\n");
+#endif
+
+    doneCurrent();
+
+    lock();
+    hasExited = true;
+#ifdef THREAD_DEBUG
+    printf("                RenderThread: waking GUI for final sleep..\n");
+#endif
+    wake();
+    unlock();
+
+#ifdef THREAD_DEBUG
+    printf("                RenderThread: All done...\n");
+#endif
+}
+
+
+
+bool QQuickCanvasRenderThread::event(QEvent *e)
+{
+    Q_ASSERT(QThread::currentThread() == qApp->thread());
+
+    if (e->type() == QEvent::User) {
+        if (!syncAlreadyHappened)
+            sync(false);
+
+        syncAlreadyHappened = false;
+
+        if (animationRunning && animationDriver()) {
+#ifdef THREAD_DEBUG
+            qDebug("GUI: Advancing animations...\n");
+#endif
+
+            animationDriver()->advance();
+
+#ifdef THREAD_DEBUG
+            qDebug("GUI: Animations advanced...\n");
+#endif
+        }
+
+        return true;
+    }
+
+    return QThread::event(e);
+}
+
+
+
+void QQuickCanvasRenderThread::exhaustSyncEvent()
+{
+    if (isGuiBlockPending) {
+        sync(true);
+        syncAlreadyHappened = true;
+    }
+}
+
+
+
+void QQuickCanvasRenderThread::sync(bool guiAlreadyLocked)
+{
+#ifdef THREAD_DEBUG
+    printf("GUI: sync - %s\n", guiAlreadyLocked ? "outside event" : "inside event");
+#endif
+    if (!guiAlreadyLocked)
+        lockInGui();
+
+    renderThreadAwakened = false;
+
+    polishItems();
+
+    wake();
+    wait();
+
+    if (!guiAlreadyLocked)
+        unlockInGui();
+}
+
+
+
+
+/*!
+    Acquires the mutex for the GUI thread. The function uses the isGuiBlocked
+    variable to keep track of how many recursion levels the gui is locket with.
+    We only actually acquire the mutex for the first level to avoid deadlocking
+    ourselves.
+ */
+
+void QQuickCanvasRenderThread::lockInGui()
+{
+    // We must avoid recursive locking in the GUI thread, hence we
+    // only lock when we are the first one to try to block.
+    if (!isGuiBlocked)
+        lock();
+
+    isGuiBlocked++;
+
+#ifdef THREAD_DEBUG
+    printf("GUI: aquired lock... %d\n", isGuiBlocked);
+#endif
+}
+
+
+
+void QQuickCanvasRenderThread::unlockInGui()
+{
+#ifdef THREAD_DEBUG
+    printf("GUI: releasing lock... %d\n", isGuiBlocked);
+#endif
+    --isGuiBlocked;
+    if (!isGuiBlocked)
+        unlock();
+}
+
+
+
+
+void QQuickCanvasRenderThread::animationStarted()
+{
+#ifdef THREAD_DEBUG
+    printf("GUI: animationStarted()\n");
+#endif
+
+    lockInGui();
+
+    animationRunning = true;
+
+    if (isRenderBlocked)
+        wake();
+
+    unlockInGui();
+}
+
+
+
+void QQuickCanvasRenderThread::animationStopped()
+{
+#ifdef THREAD_DEBUG
+    printf("GUI: animationStopped()...\n");
+#endif
+
+    lockInGui();
+    animationRunning = false;
+    unlockInGui();
+}
+
+
+void QQuickCanvasRenderThread::paint()
+{
+#ifdef THREAD_DEBUG
+    printf("GUI: paint called..\n");
+#endif
+
+    lockInGui();
+    exhaustSyncEvent();
+
+    isPaintCompleted = false;
+    while (isRunning() && !isPaintCompleted) {
+        if (isRenderBlocked)
+            wake();
+        wait();
+    }
+    unlockInGui();
+}
+
+
+
+void QQuickCanvasRenderThread::resize(const QSize &size)
+{
+#ifdef THREAD_DEBUG
+    printf("GUI: Resize Event: %dx%d\n", size.width(), size.height());
+#endif
+
+    if (!isRunning()) {
+        windowSize = size;
+        return;
+    }
+
+    lockInGui();
+    exhaustSyncEvent();
+
+    windowSize = size;
+
+    while (isRunning() && renderedSize != windowSize) {
+        if (isRenderBlocked)
+            wake();
+        wait();
+    }
+    unlockInGui();
+}
+
+
+
+void QQuickCanvasRenderThread::startRendering()
+{
+#ifdef THREAD_DEBUG
+    printf("GUI: Starting Render Thread\n");
+#endif
+    hasExited = false;
+    shouldExit = false;
+    isGuiBlocked = 0;
+    isGuiBlockPending = false;
+    start();
+}
+
+
+
+void QQuickCanvasRenderThread::stopRendering()
+{
+#ifdef THREAD_DEBUG
+    printf("GUI: stopping render thread\n");
+#endif
+
+    lockInGui();
+    exhaustSyncEvent();
+    shouldExit = true;
+
+    if (isRenderBlocked) {
+#ifdef THREAD_DEBUG
+        printf("GUI: waking up render thread\n");
+#endif
+        wake();
+    }
+
+    while (!hasExited) {
+#ifdef THREAD_DEBUG
+        printf("GUI: waiting for render thread to have exited..\n");
+#endif
+        wait();
+    }
+
+    unlockInGui();
+
+#ifdef THREAD_DEBUG
+    printf("GUI: waiting for render thread to terminate..\n");
+#endif
+    // Actually wait for the thread to terminate.  Otherwise we can delete it
+    // too early and crash.
+    QThread::wait();
+
+#ifdef THREAD_DEBUG
+    printf("GUI: thread has terminated and we're all good..\n");
+#endif
+
+}
+
+
+
+QImage QQuickCanvasRenderThread::grab()
+{
+    if (!isRunning())
+        return QImage();
+
+    if (QThread::currentThread() != qApp->thread()) {
+        qWarning("QQuickCanvas::grabFrameBuffer: can only be called from the GUI thread");
+        return QImage();
+    }
+
+#ifdef THREAD_DEBUG
+    printf("GUI: doing a pixelwise grab..\n");
+#endif
+
+    lockInGui();
+    exhaustSyncEvent();
+
+    doGrab = true;
+    isPaintCompleted = false;
+    while (isRunning() && !isPaintCompleted) {
+        if (isRenderBlocked)
+            wake();
+        wait();
+    }
+
+    QImage grabbed = grabContent;
+    grabContent = QImage();
+
+    unlockInGui();
+
+    return grabbed;
+}
+
+
+
+void QQuickCanvasRenderThread::maybeUpdate()
+{
+    Q_ASSERT_X(QThread::currentThread() == QCoreApplication::instance()->thread() || inSync,
+               "QQuickCanvas::update",
+               "Function can only be called from GUI thread or during QQuickItem::updatePaintNode()");
+
+    if (inSync) {
+        isExternalUpdatePending = true;
+
+    } else if (!renderThreadAwakened) {
+#ifdef THREAD_DEBUG
+        printf("GUI: doing update...\n");
+#endif
+        renderThreadAwakened = true;
+        lockInGui();
+        isExternalUpdatePending = true;
+        if (isRenderBlocked)
+            wake();
+        unlockInGui();
+    }
+}
+
+
+#include "moc_qquickcanvas.cpp"
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickcanvas.h b/src/declarative/items/qquickcanvas.h
new file mode 100644 (file)
index 0000000..8b69744
--- /dev/null
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** 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 QQUICKCANVAS_H
+#define QQUICKCANVAS_H
+
+#include <QtCore/qmetatype.h>
+#include <QtGui/qopengl.h>
+#include <QtGui/qwindow.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickItem;
+class QSGEngine;
+class QQuickCanvasPrivate;
+class QOpenGLFramebufferObject;
+class QDeclarativeIncubationController;
+
+class Q_DECLARATIVE_EXPORT QQuickCanvas : public QWindow
+{
+Q_OBJECT
+Q_DECLARE_PRIVATE(QQuickCanvas)
+public:
+    QQuickCanvas(QWindow *parent = 0);
+
+    virtual ~QQuickCanvas();
+
+    QQuickItem *rootItem() const;
+    QQuickItem *activeFocusItem() const;
+
+    QQuickItem *mouseGrabberItem() const;
+
+    bool sendEvent(QQuickItem *, QEvent *);
+
+    QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
+
+    QSGEngine *sceneGraphEngine() const;
+
+    void setVSyncAnimations(bool enabled);
+    bool vsyncAnimations() const;
+
+    QImage grabFrameBuffer();
+
+    void setRenderTarget(QOpenGLFramebufferObject *fbo);
+    QOpenGLFramebufferObject *renderTarget() const;
+
+    QDeclarativeIncubationController *incubationController() const;
+
+Q_SIGNALS:
+    void frameSwapped();
+    void sceneGraphInitialized();
+
+protected:
+    QQuickCanvas(QQuickCanvasPrivate &dd, QWindow *parent = 0);
+
+    virtual void exposeEvent(QExposeEvent *);
+    virtual void resizeEvent(QResizeEvent *);
+
+    virtual void showEvent(QShowEvent *);
+    virtual void hideEvent(QHideEvent *);
+
+    virtual bool event(QEvent *);
+    virtual void keyPressEvent(QKeyEvent *);
+    virtual void keyReleaseEvent(QKeyEvent *);
+    virtual void inputMethodEvent(QInputMethodEvent *);
+    virtual void mousePressEvent(QMouseEvent *);
+    virtual void mouseReleaseEvent(QMouseEvent *);
+    virtual void mouseDoubleClickEvent(QMouseEvent *);
+    virtual void mouseMoveEvent(QMouseEvent *);
+#ifndef QT_NO_WHEELEVENT
+    virtual void wheelEvent(QWheelEvent *);
+#endif
+
+private Q_SLOTS:
+    void sceneGraphChanged();
+    void maybeUpdate();
+    void animationStarted();
+    void animationStopped();
+
+private:
+    friend class QQuickItem;
+    friend class QQuickCanvasRenderLoop;
+    Q_DISABLE_COPY(QQuickCanvas)
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QQuickCanvas *)
+
+QT_END_HEADER
+
+#endif // QQUICKCANVAS_H
+
diff --git a/src/declarative/items/qquickcanvas_p.h b/src/declarative/items/qquickcanvas_p.h
new file mode 100644 (file)
index 0000000..5c68442
--- /dev/null
@@ -0,0 +1,308 @@
+/****************************************************************************
+**
+** 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 QQUICKCANVAS_P_H
+#define QQUICKCANVAS_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 "qquickitem.h"
+#include "qquickcanvas.h"
+#include <private/qdeclarativeguard_p.h>
+
+#include <private/qsgcontext_p.h>
+#include <private/qquickdrag_p.h>
+
+#include <QtCore/qthread.h>
+#include <QtCore/qmutex.h>
+#include <QtCore/qwaitcondition.h>
+#include <private/qwindow_p.h>
+#include <private/qopengl_p.h>
+#include <qopenglcontext.h>
+#include <QtGui/qopenglframebufferobject.h>
+#include <QtGui/qevent.h>
+#include <QtGui/qinputpanel.h>
+
+QT_BEGIN_NAMESPACE
+
+//Make it easy to identify and customize the root item if needed
+class QQuickRootItem : public QQuickItem
+{
+    Q_OBJECT
+public:
+    QQuickRootItem();
+};
+
+class QQuickCanvasPrivate;
+
+class QTouchEvent;
+class QQuickCanvasRenderLoop;
+class QQuickCanvasIncubationController;
+
+class QQuickCanvasPrivate : public QWindowPrivate
+{
+public:
+    Q_DECLARE_PUBLIC(QQuickCanvas)
+
+    static inline QQuickCanvasPrivate *get(QQuickCanvas *c) { return c->d_func(); }
+
+    QQuickCanvasPrivate();
+    virtual ~QQuickCanvasPrivate();
+
+    void init(QQuickCanvas *);
+
+    QQuickRootItem *rootItem;
+
+    QQuickItem *activeFocusItem;
+    QQuickItem *mouseGrabberItem;
+    QQuickDragGrabber dragGrabber;
+
+    // Mouse positions are saved in widget coordinates
+    QPointF lastMousePosition;
+    void translateTouchEvent(QTouchEvent *touchEvent);
+    static void transformTouchPoints(QList<QTouchEvent::TouchPoint> &touchPoints, const QTransform &transform);
+    bool deliverInitialMousePressEvent(QQuickItem *, QMouseEvent *);
+    bool deliverMouseEvent(QMouseEvent *);
+    bool sendFilteredMouseEvent(QQuickItem *, QQuickItem *, QMouseEvent *);
+    bool deliverWheelEvent(QQuickItem *, QWheelEvent *);
+    bool deliverTouchPoints(QQuickItem *, QTouchEvent *, const QList<QTouchEvent::TouchPoint> &, QSet<int> *,
+            QHash<QQuickItem *, QList<QTouchEvent::TouchPoint> > *);
+    bool deliverTouchEvent(QTouchEvent *);
+    bool deliverHoverEvent(QQuickItem *, const QPointF &scenePos, const QPointF &lastScenePos, Qt::KeyboardModifiers modifiers, bool &accepted);
+    bool sendHoverEvent(QEvent::Type, QQuickItem *, const QPointF &scenePos, const QPointF &lastScenePos,
+                        Qt::KeyboardModifiers modifiers, bool accepted);
+    bool clearHover();
+    void deliverDragEvent(QQuickDragGrabber *, QEvent *);
+    bool deliverDragEvent(QQuickDragGrabber *, QQuickItem *, QDragMoveEvent *);
+
+    QList<QQuickItem*> hoverItems;
+    enum FocusOption {
+        DontChangeFocusProperty = 0x01,
+    };
+    Q_DECLARE_FLAGS(FocusOptions, FocusOption)
+
+    void setFocusInScope(QQuickItem *scope, QQuickItem *item, FocusOptions = 0);
+    void clearFocusInScope(QQuickItem *scope, QQuickItem *item, FocusOptions = 0);
+    void notifyFocusChangesRecur(QQuickItem **item, int remaining);
+
+    void updateInputMethodData();
+    void updateFocusItemTransform();
+
+    void dirtyItem(QQuickItem *);
+    void cleanup(QSGNode *);
+
+    void initializeSceneGraph();
+    void polishItems();
+    void syncSceneGraph();
+    void renderSceneGraph(const QSize &size);
+
+    QQuickItem::UpdatePaintNodeData updatePaintNodeData;
+
+    QQuickItem *dirtyItemList;
+    QList<QSGNode *> cleanupNodeList;
+
+    QSet<QQuickItem *> itemsToPolish;
+
+    void updateDirtyNodes();
+    void cleanupNodes();
+    bool updateEffectiveOpacity(QQuickItem *);
+    void updateEffectiveOpacityRoot(QQuickItem *, qreal);
+    void updateDirtyNode(QQuickItem *);
+
+    QSGContext *context;
+
+    uint vsyncAnimations : 1;
+
+    QQuickCanvasRenderLoop *thread;
+    QSize widgetSize;
+    QSize viewportSize;
+
+    QAnimationDriver *animationDriver;
+
+    QOpenGLFramebufferObject *renderTarget;
+
+    QHash<int, QQuickItem *> itemForTouchPointId;
+
+    mutable QQuickCanvasIncubationController *incubationController;
+};
+
+class QQuickCanvasRenderLoop
+{
+public:
+    QQuickCanvasRenderLoop()
+        : d(0)
+        , renderer(0)
+        , gl(0)
+    {
+    }
+    virtual ~QQuickCanvasRenderLoop()
+    {
+        delete gl;
+    }
+
+    friend class QQuickCanvasPrivate;
+
+    virtual void paint() = 0;
+    virtual void resize(const QSize &size) = 0;
+    virtual void startRendering() = 0;
+    virtual void stopRendering() = 0;
+    virtual QImage grab() = 0;
+    virtual void setWindowSize(const QSize &size) = 0;
+    virtual void maybeUpdate() = 0;
+    virtual bool isRunning() const = 0;
+    virtual void animationStarted() = 0;
+    virtual void animationStopped() = 0;
+    virtual void moveContextToThread(QSGContext *) { }
+    virtual bool *allowMainThreadProcessing() { return 0; }
+
+protected:
+    void initializeSceneGraph() { d->initializeSceneGraph(); }
+    void syncSceneGraph() { d->syncSceneGraph(); }
+    void renderSceneGraph(const QSize &size) { d->renderSceneGraph(size); }
+    void polishItems() { d->polishItems(); }
+    QAnimationDriver *animationDriver() const { return d->animationDriver; }
+
+    inline QOpenGLContext *glContext() const { return gl; }
+    void createGLContext();
+    void makeCurrent() { gl->makeCurrent(renderer); }
+    void doneCurrent() { gl->doneCurrent(); }
+    void swapBuffers() {
+        gl->swapBuffers(renderer);
+        emit renderer->frameSwapped();
+    }
+
+private:
+    QQuickCanvasPrivate *d;
+    QQuickCanvas *renderer;
+
+    QOpenGLContext *gl;
+};
+
+class QQuickCanvasRenderThread : public QThread, public QQuickCanvasRenderLoop
+{
+    Q_OBJECT
+public:
+    QQuickCanvasRenderThread()
+        : mutex(QMutex::NonRecursive)
+        , allowMainThreadProcessingFlag(true)
+        , animationRunning(false)
+        , isGuiBlocked(0)
+        , isPaintCompleted(false)
+        , isGuiBlockPending(false)
+        , isRenderBlocked(false)
+        , isExternalUpdatePending(false)
+        , syncAlreadyHappened(false)
+        , inSync(false)
+        , doGrab(false)
+        , shouldExit(false)
+        , hasExited(false)
+        , renderThreadAwakened(false)
+    {}
+
+    inline void lock() { mutex.lock(); }
+    inline void unlock() { mutex.unlock(); }
+    inline void wait() { condition.wait(&mutex); }
+    inline void wake() { condition.wakeOne(); }
+
+    void lockInGui();
+    void unlockInGui();
+
+    void paint();
+    void resize(const QSize &size);
+    void startRendering();
+    void stopRendering();
+    void exhaustSyncEvent();
+    void sync(bool guiAlreadyLocked);
+    bool isRunning() const { return QThread::isRunning(); }
+    void setWindowSize(const QSize &size) { windowSize = size; }
+    void maybeUpdate();
+    void moveContextToThread(QSGContext *c) { c->moveToThread(this); }
+    bool *allowMainThreadProcessing() { return &allowMainThreadProcessingFlag; }
+
+    bool event(QEvent *);
+
+    QImage grab();
+
+public slots:
+    void animationStarted();
+    void animationStopped();
+
+public:
+    QMutex mutex;
+    QWaitCondition condition;
+
+    bool allowMainThreadProcessingFlag;
+
+    QSize windowSize;
+    QSize renderedSize;
+
+    uint animationRunning: 1;
+    int isGuiBlocked;
+    uint isPaintCompleted : 1;
+    uint isGuiBlockPending : 1;
+    uint isRenderBlocked : 1;
+    uint isExternalUpdatePending : 1;
+    uint syncAlreadyHappened : 1;
+    uint inSync : 1;
+    uint doGrab : 1;
+    uint shouldExit : 1;
+    uint hasExited : 1;
+    uint renderThreadAwakened : 1;
+
+    QImage grabContent;
+
+    void run();
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickCanvasPrivate::FocusOptions)
+
+QT_END_NAMESPACE
+
+#endif // QQUICKCANVAS_P_H
diff --git a/src/declarative/items/qquickclipnode.cpp b/src/declarative/items/qquickclipnode.cpp
new file mode 100644 (file)
index 0000000..4aeb2dc
--- /dev/null
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+
+#include "qquickclipnode_p.h"
+
+#include <QtGui/qvector2d.h>
+#include <QtCore/qmath.h>
+
+QQuickDefaultClipNode::QQuickDefaultClipNode(const QRectF &rect)
+    : m_rect(rect)
+    , m_radius(0)
+    , m_dirty_geometry(true)
+    , m_geometry(QSGGeometry::defaultAttributes_Point2D(), 0)
+{
+    setGeometry(&m_geometry);
+    setIsRectangular(true);
+}
+
+void QQuickDefaultClipNode::setRect(const QRectF &rect)
+{
+    m_rect = rect;
+    m_dirty_geometry = true;
+}
+
+void QQuickDefaultClipNode::setRadius(qreal radius)
+{
+    m_radius = radius;
+    m_dirty_geometry = true;
+    setIsRectangular(radius == 0);
+}
+
+void QQuickDefaultClipNode::update()
+{
+    if (m_dirty_geometry) {
+        updateGeometry();
+        m_dirty_geometry = false;
+    }
+}
+
+void QQuickDefaultClipNode::updateGeometry()
+{
+    QSGGeometry *g = geometry();
+
+    if (qFuzzyIsNull(m_radius)) {
+        g->allocate(4);
+        QSGGeometry::updateRectGeometry(g, m_rect);
+
+    } else {
+        int vertexCount = 0;
+
+        // Radius should never exceeds half of the width or half of the height
+        qreal radius = qMin(qMin(m_rect.width() / 2, m_rect.height() / 2), m_radius);
+        QRectF rect = m_rect;
+        rect.adjust(radius, radius, -radius, -radius);
+
+        int segments = qMin(30, qCeil(radius)); // Number of segments per corner.
+
+        g->allocate((segments + 1) * 2);
+
+        QVector2D *vertices = (QVector2D *)g->vertexData();
+
+        for (int part = 0; part < 2; ++part) {
+            for (int i = 0; i <= segments; ++i) {
+                //### Should change to calculate sin/cos only once.
+                qreal angle = qreal(0.5 * M_PI) * (part + i / qreal(segments));
+                qreal s = qFastSin(angle);
+                qreal c = qFastCos(angle);
+                qreal y = (part ? rect.bottom() : rect.top()) - radius * c; // current inner y-coordinate.
+                qreal lx = rect.left() - radius * s; // current inner left x-coordinate.
+                qreal rx = rect.right() + radius * s; // current inner right x-coordinate.
+
+                vertices[vertexCount++] = QVector2D(rx, y);
+                vertices[vertexCount++] = QVector2D(lx, y);
+            }
+        }
+
+        markDirty(DirtyGeometry);
+    }
+    setClipRect(m_rect);
+}
+
diff --git a/src/declarative/items/qquickclipnode_p.h b/src/declarative/items/qquickclipnode_p.h
new file mode 100644 (file)
index 0000000..0323c9a
--- /dev/null
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** 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 QQUICKCLIPNODE_P_H
+#define QQUICKCLIPNODE_P_H
+
+#include <qsgnode.h>
+
+class QQuickDefaultClipNode : public QSGClipNode
+{
+public:
+    QQuickDefaultClipNode(const QRectF &);
+
+    void setRect(const QRectF &);
+    QRectF rect() const { return m_rect; }
+
+    void setRadius(qreal radius);
+    qreal radius() const { return m_radius; }
+
+    virtual void update();
+
+private:
+    void updateGeometry();
+    QRectF m_rect;
+    qreal m_radius;
+
+    uint m_dirty_geometry : 1;
+    uint m_reserved : 31;
+
+    QSGGeometry m_geometry;
+};
+
+#endif // QQUICKCLIPNODE_P_H
diff --git a/src/declarative/items/qquickdrag.cpp b/src/declarative/items/qquickdrag.cpp
new file mode 100644 (file)
index 0000000..d3439b0
--- /dev/null
@@ -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 "qquickdrag_p.h"
+
+#include <private/qquickitem_p.h>
+#include <private/qquickevents_p_p.h>
+#include <private/qquickitemchangelistener_p.h>
+#include <private/qv8engine_p.h>
+
+#include <QtGui/qevent.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickDragAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener
+{
+    Q_DECLARE_PUBLIC(QQuickDragAttached)
+public:
+    static QQuickDragAttachedPrivate *get(QQuickDragAttached *attached) {
+        return static_cast<QQuickDragAttachedPrivate *>(QObjectPrivate::get(attached)); }
+
+    QQuickDragAttachedPrivate()
+        : attachedItem(0)
+        , mimeData(0)
+        , proposedAction(Qt::MoveAction)
+        , supportedActions(Qt::MoveAction | Qt::CopyAction | Qt::LinkAction)
+        , active(false)
+        , listening(false)
+    {
+    }
+
+    void itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &);
+    void start() { start(supportedActions); }
+    void start(Qt::DropActions supportedActions);
+    void setTarget(QQuickItem *item);
+
+    QQuickDragGrabber dragGrabber;
+
+    QDeclarativeGuard<QObject> source;
+    QDeclarativeGuard<QObject> target;
+    QQuickItem *attachedItem;
+    QQuickDragMimeData *mimeData;
+    Qt::DropAction proposedAction;
+    Qt::DropActions supportedActions;
+    bool active : 1;
+    bool listening : 1;
+    QPointF hotSpot;
+    QStringList keys;
+};
+
+/*!
+    \qmlclass Drag QQuickDrag
+    \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 QQuickDragAttachedPrivate::itemGeometryChanged(QQuickItem *, const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+    Q_Q(QQuickDragAttached);
+    if (newGeometry.topLeft() == oldGeometry.topLeft() || !active)
+        return;
+
+    if (QQuickCanvas *canvas = attachedItem->canvas()) {
+        QPoint scenePos = attachedItem->mapToScene(hotSpot).toPoint();
+        QDragMoveEvent event(scenePos, mimeData->m_supportedActions, mimeData, Qt::NoButton, Qt::NoModifier);
+        QQuickDropEventEx::setProposedAction(&event, proposedAction);
+        QQuickCanvasPrivate::get(canvas)->deliverDragEvent(&dragGrabber, &event);
+        if (target != dragGrabber.target()) {
+            target = dragGrabber.target();
+            emit q->targetChanged();
+        }
+    }
+}
+
+QQuickDragAttached::QQuickDragAttached(QObject *parent)
+    : QObject(*new QQuickDragAttachedPrivate, parent)
+{
+    Q_D(QQuickDragAttached);
+    d->attachedItem = qobject_cast<QQuickItem *>(parent);
+    d->source = d->attachedItem;
+}
+
+QQuickDragAttached::~QQuickDragAttached()
+{
+    Q_D(QQuickDragAttached);
+    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 QQuickDragAttached::isActive() const
+{
+    Q_D(const QQuickDragAttached);
+    return d->active;
+}
+
+void QQuickDragAttached::setActive(bool active)
+{
+    Q_D(QQuickDragAttached);
+    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 *QQuickDragAttached::source() const
+{
+    Q_D(const QQuickDragAttached);
+    return d->source;
+}
+
+void QQuickDragAttached::setSource(QObject *item)
+{
+    Q_D(QQuickDragAttached);
+    if (d->source != item) {
+        d->source = item;
+        emit sourceChanged();
+    }
+}
+
+void QQuickDragAttached::resetSource()
+{
+    Q_D(QQuickDragAttached);
+    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 *QQuickDragAttached::target() const
+{
+    Q_D(const QQuickDragAttached);
+    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 QQuickDragAttached::hotSpot() const
+{
+    Q_D(const QQuickDragAttached);
+    return d->hotSpot;
+}
+
+void QQuickDragAttached::setHotSpot(const QPointF &hotSpot)
+{
+    Q_D(QQuickDragAttached);
+    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 QQuickDragAttached::keys() const
+{
+    Q_D(const QQuickDragAttached);
+    return d->keys;
+}
+
+void QQuickDragAttached::setKeys(const QStringList &keys)
+{
+    Q_D(QQuickDragAttached);
+    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 QQuickDragAttached::supportedActions() const
+{
+    Q_D(const QQuickDragAttached);
+    return d->supportedActions;
+}
+
+void QQuickDragAttached::setSupportedActions(Qt::DropActions actions)
+{
+    Q_D(QQuickDragAttached);
+    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 QQuickDragAttached::proposedAction() const
+{
+    Q_D(const QQuickDragAttached);
+    return d->proposedAction;
+}
+
+void QQuickDragAttached::setProposedAction(Qt::DropAction action)
+{
+    Q_D(QQuickDragAttached);
+    if (d->proposedAction != action) {
+        d->proposedAction = action;
+        emit proposedActionChanged();
+        // send a move event with the new default action if active?
+    }
+}
+
+void QQuickDragAttachedPrivate::start(Qt::DropActions supportedActions)
+{
+    Q_Q(QQuickDragAttached);
+    Q_ASSERT(!active);
+
+    if (QQuickCanvas *canvas = attachedItem ? attachedItem->canvas() : 0) {
+        if (!mimeData)
+            mimeData = new QQuickDragMimeData;
+        if (!listening) {
+            QQuickItemPrivate::get(attachedItem)->addItemChangeListener(this, QQuickItemPrivate::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);
+        QQuickDropEventEx::setProposedAction(&event, proposedAction);
+        QQuickCanvasPrivate::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 QQuickDragAttached::start(QDeclarativeV8Function *args)
+{
+    Q_D(QQuickDragAttached);
+    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 QQuickDragAttached::drop()
+{
+    Q_D(QQuickDragAttached);
+    Qt::DropAction acceptedAction = Qt::IgnoreAction;
+
+    if (!d->active)
+        return acceptedAction;
+
+    QObject *target = 0;
+
+    if (QQuickCanvas *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);
+        QQuickDropEventEx::setProposedAction(&event, d->proposedAction);
+        QQuickCanvasPrivate::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 QQuickDragAttached::cancel()
+{
+    Q_D(QQuickDragAttached);
+    if (!d->active)
+        return;
+
+    if (QQuickCanvas *canvas = d->attachedItem->canvas()) {
+        QDragLeaveEvent event;
+        QQuickCanvasPrivate::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/qquickdrag_p.h b/src/declarative/items/qquickdrag_p.h
new file mode 100644 (file)
index 0000000..1d95029
--- /dev/null
@@ -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 QQUICKDRAG_P_H
+#define QQUICKDRAG_P_H
+
+#include <qquickitem.h>
+
+#include <private/qv8engine_p.h>
+
+#include <QtCore/qmimedata.h>
+#include <QtCore/qstringlist.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickItem;
+class QQuickDrag;
+class QQuickDragPrivate;
+
+class QQuickDragGrabber
+{
+    class Item : public QDeclarativeGuard<QQuickItem>
+    {
+    public:
+        Item(QQuickItem *item) : QDeclarativeGuard<QQuickItem>(item) {}
+
+        QIntrusiveListNode node;
+    protected:
+        void objectDestroyed(QQuickItem *) { delete this; }
+    };
+
+    typedef QIntrusiveList<Item, &Item::node> ItemList;
+
+public:
+    QQuickDragGrabber() : m_target(0) {}
+    ~QQuickDragGrabber() { 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(QQuickItem *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 QQuickDropEventEx : public QDropEvent
+{
+public:
+    void setProposedAction(Qt::DropAction action) { default_action = action; drop_action = action; }
+
+    static void setProposedAction(QDropEvent *event, Qt::DropAction action) {
+        static_cast<QQuickDropEventEx *>(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<QQuickDropEventEx *>(to)->copyActions(from);
+    }
+};
+
+class QQuickDragMimeData : public QMimeData
+{
+    Q_OBJECT
+public:
+    QQuickDragMimeData()
+        : 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 QQuickDragAttached;
+    friend class QQuickDragAttachedPrivate;
+};
+
+class QDeclarativeV8Function;
+
+class QQuickDragAttachedPrivate;
+class QQuickDragAttached : 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:
+    QQuickDragAttached(QObject *parent);
+    ~QQuickDragAttached();
+
+    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(QQuickDragAttached)
+};
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/declarative/items/qquickdroparea.cpp b/src/declarative/items/qquickdroparea.cpp
new file mode 100644 (file)
index 0000000..b9b9308
--- /dev/null
@@ -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 "qquickdroparea_p.h"
+#include "qquickdrag_p.h"
+#include "qquickitem_p.h"
+#include "qquickcanvas.h"
+
+#include <private/qdeclarativeengine_p.h>
+
+QQuickDropAreaDrag::QQuickDropAreaDrag(QQuickDropAreaPrivate *d, QObject *parent)
+    : QObject(parent)
+    , d(d)
+{
+}
+
+QQuickDropAreaDrag::~QQuickDropAreaDrag()
+{
+}
+
+class QQuickDropAreaPrivate : public QQuickItemPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickDropArea)
+
+public:
+    QQuickDropAreaPrivate();
+    ~QQuickDropAreaPrivate();
+
+    bool hasMatchingKey(const QStringList &keys) const;
+
+    QStringList getKeys(const QMimeData *mimeData) const;
+
+    QStringList keys;
+    QRegExp keyRegExp;
+    QPointF dragPosition;
+    QQuickDropAreaDrag *drag;
+    QDeclarativeGuard<QObject> source;
+    QDeclarativeGuard<QMimeData> mimeData;
+};
+
+QQuickDropAreaPrivate::QQuickDropAreaPrivate()
+    : drag(0)
+{
+}
+
+QQuickDropAreaPrivate::~QQuickDropAreaPrivate()
+{
+    delete drag;
+}
+
+/*!
+    \qmlclass DropArea QQuickDropArea
+    \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.
+*/
+
+QQuickDropArea::QQuickDropArea(QQuickItem *parent)
+    : QQuickItem(*new QQuickDropAreaPrivate, parent)
+{
+    setFlags(ItemAcceptsDrops);
+}
+
+QQuickDropArea::~QQuickDropArea()
+{
+}
+
+/*!
+    \qmlproperty bool QtQuick2::DropArea::containsDrag
+
+    This property identifies whether the DropArea currently contains any
+    dragged items.
+*/
+
+bool QQuickDropArea::containsDrag() const
+{
+    Q_D(const QQuickDropArea);
+    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 QQuickDropArea::keys() const
+{
+    Q_D(const QQuickDropArea);
+    return d->keys;
+}
+
+void QQuickDropArea::setKeys(const QStringList &keys)
+{
+    Q_D(QQuickDropArea);
+    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();
+    }
+}
+
+QQuickDropAreaDrag *QQuickDropArea::drag()
+{
+    Q_D(QQuickDropArea);
+    if (!d->drag)
+        d->drag = new QQuickDropAreaDrag(d);
+    return d->drag;
+}
+
+/*!
+    \qmlproperty Object QtQuick2::DropArea::drag.source
+
+    This property holds the source of a drag.
+*/
+
+QObject *QQuickDropAreaDrag::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 QQuickDropAreaDrag::x() const
+{
+    return d->dragPosition.x();
+}
+
+qreal QQuickDropAreaDrag::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 QQuickDropArea::dragMoveEvent(QDragMoveEvent *event)
+{
+    Q_D(QQuickDropArea);
+    if (!d->mimeData)
+        return;
+
+    d->dragPosition = event->pos();
+    if (d->drag)
+        emit d->drag->positionChanged();
+
+    event->accept();
+    QQuickDropEvent dragTargetEvent(d, event);
+    emit positionChanged(&dragTargetEvent);
+}
+
+bool QQuickDropAreaPrivate::hasMatchingKey(const QStringList &keys) const
+{
+    if (keyRegExp.isEmpty())
+        return true;
+
+    foreach (const QString &key, keys) {
+        if (keyRegExp.exactMatch(key))
+            return true;
+    }
+    return false;
+}
+
+QStringList QQuickDropAreaPrivate::getKeys(const QMimeData *mimeData) const
+{
+    if (const QQuickDragMimeData *dragMime = qobject_cast<const QQuickDragMimeData *>(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 QQuickDropArea::dragEnterEvent(QDragEnterEvent *event)
+{
+    Q_D(QQuickDropArea);
+    const QMimeData *mimeData = event->mimeData();
+    if (!d->effectiveEnable || d->mimeData || !mimeData || !d->hasMatchingKey(d->getKeys(mimeData)))
+        return;
+
+    d->dragPosition = event->pos();
+
+    event->accept();
+    QQuickDropEvent dragTargetEvent(d, event);
+    emit entered(&dragTargetEvent);
+
+    if (event->isAccepted()) {
+        d->mimeData = const_cast<QMimeData *>(mimeData);
+        if (QQuickDragMimeData *dragMime = qobject_cast<QQuickDragMimeData *>(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 QQuickDropArea::dragLeaveEvent(QDragLeaveEvent *)
+{
+    Q_D(QQuickDropArea);
+    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 QQuickDropArea::dropEvent(QDropEvent *event)
+{
+    Q_D(QQuickDropArea);
+    if (!d->mimeData)
+        return;
+
+    QQuickDropEvent dragTargetEvent(d, event);
+    emit dropped(&dragTargetEvent);
+
+    d->mimeData = 0;
+    d->source = 0;
+    emit containsDragChanged();
+    if (d->drag)
+        emit d->drag->sourceChanged();
+}
+
+/*!
+    \qmlclass DragEvent QQuickDragEvent
+    \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 *QQuickDropEvent::source()
+{
+    if (const QQuickDragMimeData *dragMime = qobject_cast<const QQuickDragMimeData *>(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 QQuickDropEvent::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 QQuickDropEvent::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/qquickdroparea_p.h b/src/declarative/items/qquickdroparea_p.h
new file mode 100644 (file)
index 0000000..31e2bd7
--- /dev/null
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** 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 QQUICKDROPAREA_P_H
+#define QQUICKDROPAREA_P_H
+
+#include "qquickitem.h"
+
+#include <private/qdeclarativeguard_p.h>
+#include <private/qv8engine_p.h>
+
+#include <QtGui/qevent.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickDropAreaPrivate;
+class QQuickDropEvent : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(qreal x READ x)
+    Q_PROPERTY(qreal y READ y)
+    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:
+    QQuickDropEvent(QQuickDropAreaPrivate *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 *);
+
+private:
+    QQuickDropAreaPrivate *d;
+    QDropEvent *event;
+};
+
+class QQuickDropAreaDrag : 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:
+    QQuickDropAreaDrag(QQuickDropAreaPrivate *d, QObject *parent = 0);
+    ~QQuickDropAreaDrag();
+
+    qreal x() const;
+    qreal y() const;
+    QObject *source() const;
+
+Q_SIGNALS:
+    void positionChanged();
+    void sourceChanged();
+
+private:
+    QQuickDropAreaPrivate *d;
+
+    friend class QQuickDropArea;
+    friend class QQuickDropAreaPrivate;
+};
+
+class QQuickDropAreaPrivate;
+class Q_AUTOTEST_EXPORT QQuickDropArea : public QQuickItem
+{
+    Q_OBJECT
+    Q_PROPERTY(bool containsDrag READ containsDrag NOTIFY containsDragChanged)
+    Q_PROPERTY(QStringList keys READ keys WRITE setKeys NOTIFY keysChanged)
+    Q_PROPERTY(QQuickDropAreaDrag *drag READ drag CONSTANT)
+
+public:
+    QQuickDropArea(QQuickItem *parent=0);
+    ~QQuickDropArea();
+
+    bool containsDrag() const;
+    void setContainsDrag(bool drag);
+
+    QStringList keys() const;
+    void setKeys(const QStringList &keys);
+
+    QQuickDropAreaDrag *drag();
+
+Q_SIGNALS:
+    void containsDragChanged();
+    void keysChanged();
+    void sourceChanged();
+
+    void entered(QQuickDropEvent *drag);
+    void exited();
+    void positionChanged(QQuickDropEvent *drag);
+    void dropped(QQuickDropEvent *drop);
+
+protected:
+    void dragMoveEvent(QDragMoveEvent *event);
+    void dragEnterEvent(QDragEnterEvent *event);
+    void dragLeaveEvent(QDragLeaveEvent *event);
+    void dropEvent(QDropEvent *event);
+
+private:
+    Q_DISABLE_COPY(QQuickDropArea)
+    Q_DECLARE_PRIVATE(QQuickDropArea)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickDropEvent)
+QML_DECLARE_TYPE(QQuickDropArea)
+
+QT_END_HEADER
+
+#endif // QQUICKDROPAREA_P_H
diff --git a/src/declarative/items/qquickevents.cpp b/src/declarative/items/qquickevents.cpp
new file mode 100644 (file)
index 0000000..c546dd3
--- /dev/null
@@ -0,0 +1,239 @@
+/****************************************************************************
+**
+** 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 "qquickevents_p_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+    \qmlclass KeyEvent QQuickKeyEvent
+    \inqmlmodule QtQuick 2
+    \ingroup qml-event-elements
+
+    \brief The KeyEvent object provides information about a key event.
+
+    For example, the following changes the Item's state property when the Enter
+    key is pressed:
+    \qml
+Item {
+    focus: true
+    Keys.onPressed: { if (event.key == Qt.Key_Enter) state = 'ShowDetails'; }
+}
+    \endqml
+*/
+
+/*!
+    \qmlproperty int QtQuick2::KeyEvent::key
+
+    This property holds the code of the key that was pressed or released.
+
+    See \l {Qt::Key}{Qt.Key} for the list of keyboard codes. These codes are
+    independent of the underlying window system. Note that this
+    function does not distinguish between capital and non-capital
+    letters, use the text() function (returning the Unicode text the
+    key generated) for this purpose.
+
+    A value of either 0 or \l {Qt::Key_unknown}{Qt.Key_Unknown} means that the event is not
+    the result of a known key; for example, it may be the result of
+    a compose sequence, a keyboard macro, or due to key event
+    compression.
+*/
+
+/*!
+    \qmlproperty string QtQuick2::KeyEvent::text
+
+    This property holds the Unicode text that the key generated.
+    The text returned can be an empty string in cases where modifier keys,
+    such as Shift, Control, Alt, and Meta, are being pressed or released.
+    In such cases \c key will contain a valid value
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::KeyEvent::isAutoRepeat
+
+    This property holds whether this event comes from an auto-repeating key.
+*/
+
+/*!
+    \qmlproperty int QtQuick2::KeyEvent::count
+
+    This property holds the number of keys involved in this event. If \l KeyEvent::text
+    is not empty, this is simply the length of the string.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::KeyEvent::accepted
+
+    Setting \a accepted to true prevents the key event from being
+    propagated to the item's parent.
+
+    Generally, if the item acts on the key event then it should be accepted
+    so that ancestor items do not also respond to the same event.
+*/
+
+/*!
+    \qmlproperty int QtQuick2::KeyEvent::modifiers
+
+    This property holds the keyboard modifier flags that existed immediately
+    before the event occurred.
+
+    It contains a bitwise combination of:
+    \list
+    \o Qt.NoModifier - No modifier key is pressed.
+    \o Qt.ShiftModifier - A Shift key on the keyboard is pressed.
+    \o Qt.ControlModifier - A Ctrl key on the keyboard is pressed.
+    \o Qt.AltModifier - An Alt key on the keyboard is pressed.
+    \o Qt.MetaModifier - A Meta key on the keyboard is pressed.
+    \o Qt.KeypadModifier - A keypad button is pressed.
+    \endlist
+
+    For example, to react to a Shift key + Enter key combination:
+    \qml
+    Item {
+        focus: true
+        Keys.onPressed: {
+            if ((event.key == Qt.Key_Enter) && (event.modifiers & Qt.ShiftModifier))
+                doSomething();
+        }
+    }
+    \endqml
+*/
+
+
+/*!
+    \qmlclass MouseEvent QQuickMouseEvent
+    \inqmlmodule QtQuick 2
+    \ingroup qml-event-elements
+
+    \brief The MouseEvent object provides information about a mouse event.
+
+    The position of the mouse can be found via the \l x and \l y properties.
+    The button that caused the event is available via the \l button property.
+
+    \sa MouseArea
+*/
+
+/*!
+    \internal
+    \class QQuickMouseEvent
+*/
+
+/*!
+    \qmlproperty int QtQuick2::MouseEvent::x
+    \qmlproperty int QtQuick2::MouseEvent::y
+
+    These properties hold the coordinates of the position supplied by the mouse event.
+*/
+
+
+/*!
+    \qmlproperty bool QtQuick2::MouseEvent::accepted
+
+    Setting \a accepted to true prevents the mouse event from being
+    propagated to items below this item.
+
+    Generally, if the item acts on the mouse event then it should be accepted
+    so that items lower in the stacking order do not also respond to the same event.
+*/
+
+/*!
+    \qmlproperty enumeration QtQuick2::MouseEvent::button
+
+    This property holds the button that caused the event.  It can be one of:
+    \list
+    \o Qt.LeftButton
+    \o Qt.RightButton
+    \o Qt.MiddleButton
+    \endlist
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::MouseEvent::wasHeld
+
+    This property is true if the mouse button has been held pressed longer the
+    threshold (800ms).
+*/
+
+/*!
+    \qmlproperty int QtQuick2::MouseEvent::buttons
+
+    This property holds the mouse buttons pressed when the event was generated.
+    For mouse move events, this is all buttons that are pressed down. For mouse
+    press and double click events this includes the button that caused the event.
+    For mouse release events this excludes the button that caused the event.
+
+    It contains a bitwise combination of:
+    \list
+    \o Qt.LeftButton
+    \o Qt.RightButton
+    \o Qt.MiddleButton
+    \endlist
+*/
+
+/*!
+    \qmlproperty int QtQuick2::MouseEvent::modifiers
+
+    This property holds the keyboard modifier flags that existed immediately
+    before the event occurred.
+
+    It contains a bitwise combination of:
+    \list
+    \o Qt.NoModifier - No modifier key is pressed.
+    \o Qt.ShiftModifier - A Shift key on the keyboard is pressed.
+    \o Qt.ControlModifier - A Ctrl key on the keyboard is pressed.
+    \o Qt.AltModifier - An Alt key on the keyboard is pressed.
+    \o Qt.MetaModifier - A Meta key on the keyboard is pressed.
+    \o Qt.KeypadModifier - A keypad button is pressed.
+    \endlist
+
+    For example, to react to a Shift key + Left mouse button click:
+    \qml
+    MouseArea {
+        onClicked: {
+            if ((mouse.button == Qt.LeftButton) && (mouse.modifiers & Qt.ShiftModifier))
+                doSomething();
+        }
+    }
+    \endqml
+*/
+
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickevents_p_p.h b/src/declarative/items/qquickevents_p_p.h
new file mode 100644 (file)
index 0000000..cbe75ab
--- /dev/null
@@ -0,0 +1,144 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
+/****************************************************************************
+**
+** 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 QQUICKEVENTS_P_P_H
+#define QQUICKEVENTS_P_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 <qdeclarative.h>
+
+#include <QtCore/qobject.h>
+#include <QtGui/qevent.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickKeyEvent : 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:
+    QQuickKeyEvent(QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, const QString &text=QString(), bool autorep=false, ushort count=1)
+        : event(type, key, modifiers, text, autorep, count) { event.setAccepted(false); }
+    QQuickKeyEvent(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;
+};
+
+// used in QtLocation
+class Q_DECLARATIVE_EXPORT QQuickMouseEvent : 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 wasHeld READ wasHeld)
+    Q_PROPERTY(bool isClick READ isClick)
+    Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
+
+public:
+    QQuickMouseEvent(int x, int y, Qt::MouseButton button, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers
+                  , bool isClick=false, bool wasHeld=false)
+        : _x(x), _y(y), _button(button), _buttons(buttons), _modifiers(modifiers)
+          , _wasHeld(wasHeld), _isClick(isClick), _accepted(true) {}
+
+    int x() const { return _x; }
+    int y() const { return _y; }
+    int button() const { return _button; }
+    int buttons() const { return _buttons; }
+    int modifiers() const { return _modifiers; }
+    bool wasHeld() const { return _wasHeld; }
+    bool isClick() const { return _isClick; }
+
+    // only for internal usage
+    void setX(int x) { _x = x; }
+    void setY(int y) { _y = y; }
+    void setPosition(const QPointF &point) { _x = point.x(); _y = point.y(); }
+
+    bool isAccepted() { return _accepted; }
+    void setAccepted(bool accepted) { _accepted = accepted; }
+
+private:
+    int _x;
+    int _y;
+    Qt::MouseButton _button;
+    Qt::MouseButtons _buttons;
+    Qt::KeyboardModifiers _modifiers;
+    bool _wasHeld;
+    bool _isClick;
+    bool _accepted;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickKeyEvent)
+QML_DECLARE_TYPE(QQuickMouseEvent)
+
+#endif // QQUICKEVENTS_P_P_H
diff --git a/src/declarative/items/qquickflickable.cpp b/src/declarative/items/qquickflickable.cpp
new file mode 100644 (file)
index 0000000..6554720
--- /dev/null
@@ -0,0 +1,1997 @@
+/****************************************************************************
+**
+** 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 "qquickflickable_p.h"
+#include "qquickflickable_p_p.h"
+#include "qquickcanvas.h"
+#include "qquickcanvas_p.h"
+
+#include <QtDeclarative/qdeclarativeinfo.h>
+#include <QtGui/qevent.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qstylehints.h>
+#include "qplatformdefs.h"
+
+QT_BEGIN_NAMESPACE
+
+// The maximum number of pixels a flick can overshoot
+#ifndef QML_FLICK_OVERSHOOT
+#define QML_FLICK_OVERSHOOT 200
+#endif
+
+// The number of samples to use in calculating the velocity of a flick
+#ifndef QML_FLICK_SAMPLEBUFFER
+#define QML_FLICK_SAMPLEBUFFER 3
+#endif
+
+// The number of samples to discard when calculating the flick velocity.
+// Touch panels often produce inaccurate results as the finger is lifted.
+#ifndef QML_FLICK_DISCARDSAMPLES
+#define QML_FLICK_DISCARDSAMPLES 1
+#endif
+
+// The default maximum velocity of a flick.
+#ifndef QML_FLICK_DEFAULTMAXVELOCITY
+#define QML_FLICK_DEFAULTMAXVELOCITY 2500
+#endif
+
+// The default deceleration of a flick.
+#ifndef QML_FLICK_DEFAULTDECELERATION
+#define QML_FLICK_DEFAULTDECELERATION 1500
+#endif
+
+// How much faster to decelerate when overshooting
+#ifndef QML_FLICK_OVERSHOOTFRICTION
+#define QML_FLICK_OVERSHOOTFRICTION 8
+#endif
+
+// FlickThreshold determines how far the "mouse" must have moved
+// before we perform a flick.
+static const int FlickThreshold = 20;
+
+// RetainGrabVelocity is the maxmimum instantaneous velocity that
+// will ensure the Flickable retains the grab on consecutive flicks.
+static const int RetainGrabVelocity = 15;
+
+QQuickFlickableVisibleArea::QQuickFlickableVisibleArea(QQuickFlickable *parent)
+    : QObject(parent), flickable(parent), m_xPosition(0.), m_widthRatio(0.)
+    , m_yPosition(0.), m_heightRatio(0.)
+{
+}
+
+qreal QQuickFlickableVisibleArea::widthRatio() const
+{
+    return m_widthRatio;
+}
+
+qreal QQuickFlickableVisibleArea::xPosition() const
+{
+    return m_xPosition;
+}
+
+qreal QQuickFlickableVisibleArea::heightRatio() const
+{
+    return m_heightRatio;
+}
+
+qreal QQuickFlickableVisibleArea::yPosition() const
+{
+    return m_yPosition;
+}
+
+void QQuickFlickableVisibleArea::updateVisible()
+{
+    QQuickFlickablePrivate *p = QQuickFlickablePrivate::get(flickable);
+
+    bool changeX = false;
+    bool changeY = false;
+    bool changeWidth = false;
+    bool changeHeight = false;
+
+    // Vertical
+    const qreal viewheight = flickable->height();
+    const qreal maxyextent = -flickable->maxYExtent() + flickable->minYExtent();
+    qreal pagePos = (-p->vData.move.value() + flickable->minYExtent()) / (maxyextent + viewheight);
+    qreal pageSize = viewheight / (maxyextent + viewheight);
+
+    if (pageSize != m_heightRatio) {
+        m_heightRatio = pageSize;
+        changeHeight = true;
+    }
+    if (pagePos != m_yPosition) {
+        m_yPosition = pagePos;
+        changeY = true;
+    }
+
+    // Horizontal
+    const qreal viewwidth = flickable->width();
+    const qreal maxxextent = -flickable->maxXExtent() + flickable->minXExtent();
+    pagePos = (-p->hData.move.value() + flickable->minXExtent()) / (maxxextent + viewwidth);
+    pageSize = viewwidth / (maxxextent + viewwidth);
+
+    if (pageSize != m_widthRatio) {
+        m_widthRatio = pageSize;
+        changeWidth = true;
+    }
+    if (pagePos != m_xPosition) {
+        m_xPosition = pagePos;
+        changeX = true;
+    }
+
+    if (changeX)
+        emit xPositionChanged(m_xPosition);
+    if (changeY)
+        emit yPositionChanged(m_yPosition);
+    if (changeWidth)
+        emit widthRatioChanged(m_widthRatio);
+    if (changeHeight)
+        emit heightRatioChanged(m_heightRatio);
+}
+
+
+QQuickFlickablePrivate::QQuickFlickablePrivate()
+  : contentItem(new QQuickItem)
+    , hData(this, &QQuickFlickablePrivate::setViewportX)
+    , vData(this, &QQuickFlickablePrivate::setViewportY)
+    , hMoved(false), vMoved(false)
+    , stealMouse(false), pressed(false), interactive(true), calcVelocity(false)
+    , pixelAligned(false)
+    , deceleration(QML_FLICK_DEFAULTDECELERATION)
+    , maxVelocity(QML_FLICK_DEFAULTMAXVELOCITY), reportedVelocitySmoothing(100)
+    , delayedPressEvent(0), delayedPressTarget(0), pressDelay(0), fixupDuration(400)
+    , fixupMode(Normal), vTime(0), visibleArea(0)
+    , flickableDirection(QQuickFlickable::AutoFlickDirection)
+    , boundsBehavior(QQuickFlickable::DragAndOvershootBounds)
+{
+}
+
+void QQuickFlickablePrivate::init()
+{
+    Q_Q(QQuickFlickable);
+    QDeclarative_setParent_noEvent(contentItem, q);
+    contentItem->setParentItem(q);
+    FAST_CONNECT(&timeline, SIGNAL(updated()), q, SLOT(ticked()))
+    FAST_CONNECT(&timeline, SIGNAL(completed()), q, SLOT(movementEnding()))
+    q->setAcceptedMouseButtons(Qt::LeftButton);
+    q->setFiltersChildMouseEvents(true);
+    QQuickItemPrivate *viewportPrivate = QQuickItemPrivate::get(contentItem);
+    viewportPrivate->addItemChangeListener(this, QQuickItemPrivate::Geometry);
+    lastPosTime.invalidate();
+}
+
+/*
+    Returns the amount to overshoot by given a velocity.
+    Will be roughly in range 0 - size/4
+*/
+qreal QQuickFlickablePrivate::overShootDistance(qreal size)
+{
+    if (maxVelocity <= 0)
+        return 0.0;
+
+    return qMin(qreal(QML_FLICK_OVERSHOOT), size/3);
+}
+
+void QQuickFlickablePrivate::AxisData::addVelocitySample(qreal v, qreal maxVelocity)
+{
+    if (v > maxVelocity)
+        v = maxVelocity;
+    else if (v < -maxVelocity)
+        v = -maxVelocity;
+    velocityBuffer.append(v);
+    if (velocityBuffer.count() > QML_FLICK_SAMPLEBUFFER)
+        velocityBuffer.remove(0);
+}
+
+void QQuickFlickablePrivate::AxisData::updateVelocity()
+{
+    velocity = 0;
+    if (velocityBuffer.count() > QML_FLICK_DISCARDSAMPLES) {
+        int count = velocityBuffer.count()-QML_FLICK_DISCARDSAMPLES;
+        for (int i = 0; i < count; ++i) {
+            qreal v = velocityBuffer.at(i);
+            velocity += v;
+        }
+        velocity /= count;
+    }
+}
+
+void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, const QRectF &newGeom, const QRectF &oldGeom)
+{
+    Q_Q(QQuickFlickable);
+    if (item == contentItem) {
+        if (newGeom.x() != oldGeom.x())
+            emit q->contentXChanged();
+        if (newGeom.y() != oldGeom.y())
+            emit q->contentYChanged();
+    }
+}
+
+void QQuickFlickablePrivate::flickX(qreal velocity)
+{
+    Q_Q(QQuickFlickable);
+    flick(hData, q->minXExtent(), q->maxXExtent(), q->width(), fixupX_callback, velocity);
+}
+
+void QQuickFlickablePrivate::flickY(qreal velocity)
+{
+    Q_Q(QQuickFlickable);
+    flick(vData, q->minYExtent(), q->maxYExtent(), q->height(), fixupY_callback, velocity);
+}
+
+void QQuickFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal,
+                                         QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity)
+{
+    Q_Q(QQuickFlickable);
+    qreal maxDistance = -1;
+    data.fixingUp = false;
+    // -ve velocity means list is moving up
+    if (velocity > 0) {
+        maxDistance = qAbs(minExtent - data.move.value());
+        data.flickTarget = minExtent;
+    } else {
+        maxDistance = qAbs(maxExtent - data.move.value());
+        data.flickTarget = maxExtent;
+    }
+    if (maxDistance > 0) {
+        qreal v = velocity;
+        if (maxVelocity != -1 && maxVelocity < qAbs(v)) {
+            if (v < 0)
+                v = -maxVelocity;
+            else
+                v = maxVelocity;
+        }
+        timeline.reset(data.move);
+        if (boundsBehavior == QQuickFlickable::DragAndOvershootBounds)
+            timeline.accel(data.move, v, deceleration);
+        else
+            timeline.accel(data.move, v, deceleration, maxDistance);
+        timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this));
+        if (!hData.flicking && q->xflick()) {
+            hData.flicking = true;
+            emit q->flickingChanged();
+            emit q->flickingHorizontallyChanged();
+            if (!vData.flicking)
+                emit q->flickStarted();
+        }
+        if (!vData.flicking && q->yflick()) {
+            vData.flicking = true;
+            emit q->flickingChanged();
+            emit q->flickingVerticallyChanged();
+            if (!hData.flicking)
+                emit q->flickStarted();
+        }
+    } else {
+        timeline.reset(data.move);
+        fixup(data, minExtent, maxExtent);
+    }
+}
+
+void QQuickFlickablePrivate::fixupY_callback(void *data)
+{
+    ((QQuickFlickablePrivate *)data)->fixupY();
+}
+
+void QQuickFlickablePrivate::fixupX_callback(void *data)
+{
+    ((QQuickFlickablePrivate *)data)->fixupX();
+}
+
+void QQuickFlickablePrivate::fixupX()
+{
+    Q_Q(QQuickFlickable);
+    fixup(hData, q->minXExtent(), q->maxXExtent());
+}
+
+void QQuickFlickablePrivate::fixupY()
+{
+    Q_Q(QQuickFlickable);
+    fixup(vData, q->minYExtent(), q->maxYExtent());
+}
+
+void QQuickFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
+{
+    if (data.move.value() > minExtent || maxExtent > minExtent) {
+        timeline.reset(data.move);
+        if (data.move.value() != minExtent) {
+            switch (fixupMode) {
+            case Immediate:
+                timeline.set(data.move, minExtent);
+                break;
+            case ExtentChanged:
+                // The target has changed. Don't start from the beginning; just complete the
+                // second half of the animation using the new extent.
+                timeline.move(data.move, minExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
+                data.fixingUp = true;
+                break;
+            default: {
+                    qreal dist = minExtent - data.move;
+                    timeline.move(data.move, minExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
+                    timeline.move(data.move, minExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
+                    data.fixingUp = true;
+                }
+            }
+        }
+    } else if (data.move.value() < maxExtent) {
+        timeline.reset(data.move);
+        switch (fixupMode) {
+        case Immediate:
+            timeline.set(data.move, maxExtent);
+            break;
+        case ExtentChanged:
+            // The target has changed. Don't start from the beginning; just complete the
+            // second half of the animation using the new extent.
+            timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
+            data.fixingUp = true;
+            break;
+        default: {
+                qreal dist = maxExtent - data.move;
+                timeline.move(data.move, maxExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
+                timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
+                data.fixingUp = true;
+            }
+        }
+    }
+    data.inOvershoot = false;
+    fixupMode = Normal;
+    vTime = timeline.time();
+}
+
+void QQuickFlickablePrivate::updateBeginningEnd()
+{
+    Q_Q(QQuickFlickable);
+    bool atBoundaryChange = false;
+
+    // Vertical
+    const int maxyextent = int(-q->maxYExtent());
+    const qreal ypos = -vData.move.value();
+    bool atBeginning = (ypos <= -q->minYExtent());
+    bool atEnd = (maxyextent <= ypos);
+
+    if (atBeginning != vData.atBeginning) {
+        vData.atBeginning = atBeginning;
+        atBoundaryChange = true;
+    }
+    if (atEnd != vData.atEnd) {
+        vData.atEnd = atEnd;
+        atBoundaryChange = true;
+    }
+
+    // Horizontal
+    const int maxxextent = int(-q->maxXExtent());
+    const qreal xpos = -hData.move.value();
+    atBeginning = (xpos <= -q->minXExtent());
+    atEnd = (maxxextent <= xpos);
+
+    if (atBeginning != hData.atBeginning) {
+        hData.atBeginning = atBeginning;
+        atBoundaryChange = true;
+    }
+    if (atEnd != hData.atEnd) {
+        hData.atEnd = atEnd;
+        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();
+
+    if (visibleArea)
+        visibleArea->updateVisible();
+}
+
+/*
+XXXTODO add docs describing moving, dragging, flicking properties, e.g.
+
+When the user starts dragging the Flickable, the dragging and moving properties
+will be true.
+
+If the velocity is sufficient when the drag is ended, flicking may begin.
+
+The moving properties will remain true until all dragging and flicking
+is finished.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Flickable::onDragStarted()
+
+    This handler is called when the view starts to be dragged due to user
+    interaction.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Flickable::onDragEnded()
+
+    This handler is called when the user stops dragging the view.
+
+    If the velocity of the drag is suffient at the time the
+    touch/mouse button is released then a flick will start.
+*/
+
+/*!
+    \qmlclass Flickable QQuickFlickable
+    \inqmlmodule QtQuick 2
+    \ingroup qml-basic-interaction-elements
+
+    \brief The Flickable item provides a surface that can be "flicked".
+    \inherits Item
+
+    The Flickable item places its children on a surface that can be dragged
+    and flicked, causing the view onto the child items to scroll. This
+    behavior forms the basis of Items that are designed to show large numbers
+    of child items, such as \l ListView and \l GridView.
+
+    In traditional user interfaces, views can be scrolled using standard
+    controls, such as scroll bars and arrow buttons. In some situations, it
+    is also possible to drag the view directly by pressing and holding a
+    mouse button while moving the cursor. In touch-based user interfaces,
+    this dragging action is often complemented with a flicking action, where
+    scrolling continues after the user has stopped touching the view.
+
+    Flickable does not automatically clip its contents. If it is not used as
+    a full-screen item, you should consider setting the \l{Item::}{clip} property
+    to true.
+
+    \section1 Example Usage
+
+    \div {class="float-right"}
+    \inlineimage flickable.gif
+    \enddiv
+
+    The following example shows a small view onto a large image in which the
+    user can drag or flick the image in order to view different parts of it.
+
+    \snippet doc/src/snippets/declarative/flickable.qml document
+
+    \clearfloat
+
+    Items declared as children of a Flickable are automatically parented to the
+    Flickable's \l contentItem.  This should be taken into account when
+    operating on the children of the Flickable; it is usually the children of
+    \c contentItem that are relevant.  For example, the bound of Items added
+    to the Flickable will be available by \c contentItem.childrenRect
+
+    \section1 Limitations
+
+    \note Due to an implementation detail, items placed inside a Flickable cannot anchor to it by
+    \c id. Use \c parent instead.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Flickable::onMovementStarted()
+
+    This handler is called when the view begins moving due to user
+    interaction.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Flickable::onMovementEnded()
+
+    This handler is called when the view stops moving due to user
+    interaction.  If a flick was generated, this handler will
+    be triggered once the flick stops.  If a flick was not
+    generated, the handler will be triggered when the
+    user stops dragging - i.e. a mouse or touch release.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Flickable::onFlickStarted()
+
+    This handler is called when the view is flicked.  A flick
+    starts from the point that the mouse or touch is released,
+    while still in motion.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Flickable::onFlickEnded()
+
+    This handler is called when the view stops moving due to a flick.
+*/
+
+/*!
+    \qmlproperty real QtQuick2::Flickable::visibleArea.xPosition
+    \qmlproperty real QtQuick2::Flickable::visibleArea.widthRatio
+    \qmlproperty real QtQuick2::Flickable::visibleArea.yPosition
+    \qmlproperty real QtQuick2::Flickable::visibleArea.heightRatio
+
+    These properties describe the position and size of the currently viewed area.
+    The size is defined as the percentage of the full view currently visible,
+    scaled to 0.0 - 1.0.  The page position is usually in the range 0.0 (beginning) to
+    1.0 minus size ratio (end), i.e. \c yPosition is in the range 0.0 to 1.0-\c heightRatio.
+    However, it is possible for the contents to be dragged outside of the normal
+    range, resulting in the page positions also being outside the normal range.
+
+    These properties are typically used to draw a scrollbar. For example:
+
+    \snippet doc/src/snippets/declarative/flickableScrollbar.qml 0
+    \dots 8
+    \snippet doc/src/snippets/declarative/flickableScrollbar.qml 1
+
+    \sa {declarative/ui-components/scrollbar}{scrollbar example}
+*/
+QQuickFlickable::QQuickFlickable(QQuickItem *parent)
+  : QQuickItem(*(new QQuickFlickablePrivate), parent)
+{
+    Q_D(QQuickFlickable);
+    d->init();
+}
+
+QQuickFlickable::QQuickFlickable(QQuickFlickablePrivate &dd, QQuickItem *parent)
+  : QQuickItem(dd, parent)
+{
+    Q_D(QQuickFlickable);
+    d->init();
+}
+
+QQuickFlickable::~QQuickFlickable()
+{
+}
+
+/*!
+    \qmlproperty real QtQuick2::Flickable::contentX
+    \qmlproperty real QtQuick2::Flickable::contentY
+
+    These properties hold the surface coordinate currently at the top-left
+    corner of the Flickable. For example, if you flick an image up 100 pixels,
+    \c contentY will be 100.
+*/
+qreal QQuickFlickable::contentX() const
+{
+    Q_D(const QQuickFlickable);
+    return -d->contentItem->x();
+}
+
+void QQuickFlickable::setContentX(qreal pos)
+{
+    Q_D(QQuickFlickable);
+    d->hData.explicitValue = true;
+    d->timeline.reset(d->hData.move);
+    d->vTime = d->timeline.time();
+    movementXEnding();
+    if (-pos != d->hData.move.value()) {
+        d->hData.move.setValue(-pos);
+        viewportMoved();
+    }
+}
+
+qreal QQuickFlickable::contentY() const
+{
+    Q_D(const QQuickFlickable);
+    return -d->contentItem->y();
+}
+
+void QQuickFlickable::setContentY(qreal pos)
+{
+    Q_D(QQuickFlickable);
+    d->vData.explicitValue = true;
+    d->timeline.reset(d->vData.move);
+    d->vTime = d->timeline.time();
+    movementYEnding();
+    if (-pos != d->vData.move.value()) {
+        d->vData.move.setValue(-pos);
+        viewportMoved();
+    }
+}
+
+/*!
+    \qmlproperty bool QtQuick2::Flickable::interactive
+
+    This property describes whether the user can interact with the Flickable.
+    A user cannot drag or flick a Flickable that is not interactive.
+
+    By default, this property is true.
+
+    This property is useful for temporarily disabling flicking. This allows
+    special interaction with Flickable's children; for example, you might want
+    to freeze a flickable map while scrolling through a pop-up dialog that
+    is a child of the Flickable.
+*/
+bool QQuickFlickable::isInteractive() const
+{
+    Q_D(const QQuickFlickable);
+    return d->interactive;
+}
+
+void QQuickFlickable::setInteractive(bool interactive)
+{
+    Q_D(QQuickFlickable);
+    if (interactive != d->interactive) {
+        d->interactive = interactive;
+        if (!interactive && (d->hData.flicking || d->vData.flicking)) {
+            d->timeline.clear();
+            d->vTime = d->timeline.time();
+            d->hData.flicking = false;
+            d->vData.flicking = false;
+            emit flickingChanged();
+            emit flickingHorizontallyChanged();
+            emit flickingVerticallyChanged();
+            emit flickEnded();
+        }
+        emit interactiveChanged();
+    }
+}
+
+/*!
+    \qmlproperty real QtQuick2::Flickable::horizontalVelocity
+    \qmlproperty real QtQuick2::Flickable::verticalVelocity
+
+    The instantaneous velocity of movement along the x and y axes, in pixels/sec.
+
+    The reported velocity is smoothed to avoid erratic output.
+*/
+qreal QQuickFlickable::horizontalVelocity() const
+{
+    Q_D(const QQuickFlickable);
+    return d->hData.smoothVelocity.value();
+}
+
+qreal QQuickFlickable::verticalVelocity() const
+{
+    Q_D(const QQuickFlickable);
+    return d->vData.smoothVelocity.value();
+}
+
+/*!
+    \qmlproperty bool QtQuick2::Flickable::atXBeginning
+    \qmlproperty bool QtQuick2::Flickable::atXEnd
+    \qmlproperty bool QtQuick2::Flickable::atYBeginning
+    \qmlproperty bool QtQuick2::Flickable::atYEnd
+
+    These properties are true if the flickable view is positioned at the beginning,
+    or end respecively.
+*/
+bool QQuickFlickable::isAtXEnd() const
+{
+    Q_D(const QQuickFlickable);
+    return d->hData.atEnd;
+}
+
+bool QQuickFlickable::isAtXBeginning() const
+{
+    Q_D(const QQuickFlickable);
+    return d->hData.atBeginning;
+}
+
+bool QQuickFlickable::isAtYEnd() const
+{
+    Q_D(const QQuickFlickable);
+    return d->vData.atEnd;
+}
+
+bool QQuickFlickable::isAtYBeginning() const
+{
+    Q_D(const QQuickFlickable);
+    return d->vData.atBeginning;
+}
+
+void QQuickFlickable::ticked()
+{
+    viewportMoved();
+}
+
+/*!
+    \qmlproperty Item QtQuick2::Flickable::contentItem
+
+    The internal item that contains the Items to be moved in the Flickable.
+
+    Items declared as children of a Flickable are automatically parented to the Flickable's contentItem.
+
+    Items created dynamically need to be explicitly parented to the \e contentItem:
+    \code
+    Flickable {
+        id: myFlickable
+        function addItem(file) {
+            var component = Qt.createComponent(file)
+            component.createObject(myFlickable.contentItem);
+        }
+    }
+    \endcode
+*/
+QQuickItem *QQuickFlickable::contentItem()
+{
+    Q_D(QQuickFlickable);
+    return d->contentItem;
+}
+
+QQuickFlickableVisibleArea *QQuickFlickable::visibleArea()
+{
+    Q_D(QQuickFlickable);
+    if (!d->visibleArea)
+        d->visibleArea = new QQuickFlickableVisibleArea(this);
+    return d->visibleArea;
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::Flickable::flickableDirection
+
+    This property determines which directions the view can be flicked.
+
+    \list
+    \o Flickable.AutoFlickDirection (default) - allows flicking vertically if the
+    \e contentHeight is not equal to the \e height of the Flickable.
+    Allows flicking horizontally if the \e contentWidth is not equal
+    to the \e width of the Flickable.
+    \o Flickable.HorizontalFlick - allows flicking horizontally.
+    \o Flickable.VerticalFlick - allows flicking vertically.
+    \o Flickable.HorizontalAndVerticalFlick - allows flicking in both directions.
+    \endlist
+*/
+QQuickFlickable::FlickableDirection QQuickFlickable::flickableDirection() const
+{
+    Q_D(const QQuickFlickable);
+    return d->flickableDirection;
+}
+
+void QQuickFlickable::setFlickableDirection(FlickableDirection direction)
+{
+    Q_D(QQuickFlickable);
+    if (direction != d->flickableDirection) {
+        d->flickableDirection = direction;
+        emit flickableDirectionChanged();
+    }
+}
+
+bool QQuickFlickable::pixelAligned() const
+{
+    Q_D(const QQuickFlickable);
+    return d->pixelAligned;
+}
+
+void QQuickFlickable::setPixelAligned(bool align)
+{
+    Q_D(QQuickFlickable);
+    if (align != d->pixelAligned) {
+        d->pixelAligned = align;
+        emit pixelAlignedChanged();
+    }
+}
+
+void QQuickFlickablePrivate::handleMousePressEvent(QMouseEvent *event)
+{
+    Q_Q(QQuickFlickable);
+    if (interactive && timeline.isActive()
+        && (qAbs(hData.smoothVelocity.value()) > RetainGrabVelocity
+            || qAbs(vData.smoothVelocity.value()) > RetainGrabVelocity)) {
+        stealMouse = true; // If we've been flicked then steal the click.
+    } else {
+        stealMouse = false;
+    }
+    q->setKeepMouseGrab(stealMouse);
+    pressed = true;
+    timeline.clear();
+    hData.reset();
+    vData.reset();
+    hData.dragMinBound = q->minXExtent();
+    vData.dragMinBound = q->minYExtent();
+    hData.dragMaxBound = q->maxXExtent();
+    vData.dragMaxBound = q->maxYExtent();
+    fixupMode = Normal;
+    lastPos = QPoint();
+    QQuickItemPrivate::start(lastPosTime);
+    pressPos = event->localPos();
+    hData.pressPos = hData.move.value();
+    vData.pressPos = vData.move.value();
+    hData.flicking = false;
+    vData.flicking = false;
+    QQuickItemPrivate::start(pressTime);
+    QQuickItemPrivate::start(velocityTime);
+}
+
+void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event)
+{
+    Q_Q(QQuickFlickable);
+    if (!interactive || !lastPosTime.isValid())
+        return;
+    bool rejectY = false;
+    bool rejectX = false;
+
+    bool stealY = stealMouse;
+    bool stealX = stealMouse;
+
+    if (q->yflick()) {
+        int dy = int(event->localPos().y() - pressPos.y());
+        if (qAbs(dy) > qApp->styleHints()->startDragDistance() || QQuickItemPrivate::elapsed(pressTime) > 200) {
+            if (!vMoved)
+                vData.dragStartOffset = dy;
+            qreal newY = dy + vData.pressPos - vData.dragStartOffset;
+            const qreal minY = vData.dragMinBound;
+            const qreal maxY = vData.dragMaxBound;
+            if (newY > minY)
+                newY = minY + (newY - minY) / 2;
+            if (newY < maxY && maxY - minY <= 0)
+                newY = maxY + (newY - maxY) / 2;
+            if (boundsBehavior == QQuickFlickable::StopAtBounds && (newY > minY || newY < maxY)) {
+                rejectY = true;
+                if (newY < maxY) {
+                    newY = maxY;
+                    rejectY = false;
+                }
+                if (newY > minY) {
+                    newY = minY;
+                    rejectY = false;
+                }
+            }
+            if (!rejectY && stealMouse) {
+                vData.move.setValue(qRound(newY));
+                vMoved = true;
+            }
+            if (qAbs(dy) > qApp->styleHints()->startDragDistance())
+                stealY = true;
+        }
+    }
+
+    if (q->xflick()) {
+        int dx = int(event->localPos().x() - pressPos.x());
+        if (qAbs(dx) > qApp->styleHints()->startDragDistance() || QQuickItemPrivate::elapsed(pressTime) > 200) {
+            if (!hMoved)
+                hData.dragStartOffset = dx;
+            qreal newX = dx + hData.pressPos - hData.dragStartOffset;
+            const qreal minX = hData.dragMinBound;
+            const qreal maxX = hData.dragMaxBound;
+            if (newX > minX)
+                newX = minX + (newX - minX) / 2;
+            if (newX < maxX && maxX - minX <= 0)
+                newX = maxX + (newX - maxX) / 2;
+            if (boundsBehavior == QQuickFlickable::StopAtBounds && (newX > minX || newX < maxX)) {
+                rejectX = true;
+                if (newX < maxX) {
+                    newX = maxX;
+                    rejectX = false;
+                }
+                if (newX > minX) {
+                    newX = minX;
+                    rejectX = false;
+                }
+            }
+            if (!rejectX && stealMouse) {
+                hData.move.setValue(qRound(newX));
+                hMoved = true;
+            }
+
+            if (qAbs(dx) > qApp->styleHints()->startDragDistance())
+                stealX = true;
+        }
+    }
+
+    stealMouse = stealX || stealY;
+    if (stealMouse)
+        q->setKeepMouseGrab(true);
+
+    if (rejectY) {
+        vData.velocityBuffer.clear();
+        vData.velocity = 0;
+    }
+    if (rejectX) {
+        hData.velocityBuffer.clear();
+        hData.velocity = 0;
+    }
+
+    if (hMoved || vMoved) {
+        draggingStarting();
+        q->movementStarting();
+        q->viewportMoved();
+    }
+
+    if (!lastPos.isNull()) {
+        qreal elapsed = qreal(QQuickItemPrivate::elapsed(lastPosTime)) / 1000.;
+        if (elapsed <= 0)
+            return;
+        QQuickItemPrivate::restart(lastPosTime);
+        qreal dy = event->localPos().y()-lastPos.y();
+        if (q->yflick() && !rejectY)
+            vData.addVelocitySample(dy/elapsed, maxVelocity);
+        qreal dx = event->localPos().x()-lastPos.x();
+        if (q->xflick() && !rejectX)
+            hData.addVelocitySample(dx/elapsed, maxVelocity);
+    }
+
+    lastPos = event->localPos();
+}
+
+void QQuickFlickablePrivate::handleMouseReleaseEvent(QMouseEvent *event)
+{
+    Q_Q(QQuickFlickable);
+    stealMouse = false;
+    q->setKeepMouseGrab(false);
+    pressed = false;
+
+    // if we drag then pause before release we should not cause a flick.
+    qint64 elapsed = QQuickItemPrivate::elapsed(lastPosTime);
+
+    vData.updateVelocity();
+    hData.updateVelocity();
+
+    draggingEnding();
+
+    if (!lastPosTime.isValid())
+        return;
+
+    vTime = timeline.time();
+
+    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) {
+        velocityTimeline.reset(vData.smoothVelocity);
+        vData.smoothVelocity.setValue(-velocity);
+        flickY(velocity);
+    } else {
+        fixupY();
+    }
+
+    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) {
+        velocityTimeline.reset(hData.smoothVelocity);
+        hData.smoothVelocity.setValue(-velocity);
+        flickX(velocity);
+    } else {
+        fixupX();
+    }
+
+    if (!timeline.isActive())
+        q->movementEnding();
+}
+
+void QQuickFlickable::mousePressEvent(QMouseEvent *event)
+{
+    Q_D(QQuickFlickable);
+    if (d->interactive) {
+        if (!d->pressed)
+            d->handleMousePressEvent(event);
+        event->accept();
+    } else {
+        QQuickItem::mousePressEvent(event);
+    }
+}
+
+void QQuickFlickable::mouseMoveEvent(QMouseEvent *event)
+{
+    Q_D(QQuickFlickable);
+    if (d->interactive) {
+        d->handleMouseMoveEvent(event);
+        event->accept();
+    } else {
+        QQuickItem::mouseMoveEvent(event);
+    }
+}
+
+void QQuickFlickable::mouseReleaseEvent(QMouseEvent *event)
+{
+    Q_D(QQuickFlickable);
+    if (d->interactive) {
+        d->clearDelayedPress();
+        d->handleMouseReleaseEvent(event);
+        event->accept();
+        ungrabMouse();
+    } else {
+        QQuickItem::mouseReleaseEvent(event);
+    }
+}
+
+void QQuickFlickable::wheelEvent(QWheelEvent *event)
+{
+    Q_D(QQuickFlickable);
+    if (!d->interactive) {
+        QQuickItem::wheelEvent(event);
+    } else if (yflick() && event->orientation() == Qt::Vertical) {
+        bool valid = false;
+        if (event->delta() > 0 && contentY() > -minYExtent()) {
+            d->vData.velocity = qMax(event->delta()*2 - d->vData.smoothVelocity.value(), qreal(d->maxVelocity/4));
+            valid = true;
+        } else if (event->delta() < 0 && contentY() < -maxYExtent()) {
+            d->vData.velocity = qMin(event->delta()*2 - d->vData.smoothVelocity.value(), qreal(-d->maxVelocity/4));
+            valid = true;
+        }
+        if (valid) {
+            d->vData.flicking = false;
+            d->flickY(d->vData.velocity);
+            if (d->vData.flicking) {
+                d->vMoved = true;
+                movementStarting();
+            }
+            event->accept();
+        }
+    } else if (xflick() && event->orientation() == Qt::Horizontal) {
+        bool valid = false;
+        if (event->delta() > 0 && contentX() > -minXExtent()) {
+            d->hData.velocity = qMax(event->delta()*2 - d->hData.smoothVelocity.value(), qreal(d->maxVelocity/4));
+            valid = true;
+        } else if (event->delta() < 0 && contentX() < -maxXExtent()) {
+            d->hData.velocity = qMin(event->delta()*2 - d->hData.smoothVelocity.value(), qreal(-d->maxVelocity/4));
+            valid = true;
+        }
+        if (valid) {
+            d->hData.flicking = false;
+            d->flickX(d->hData.velocity);
+            if (d->hData.flicking) {
+                d->hMoved = true;
+                movementStarting();
+            }
+            event->accept();
+        }
+    } else {
+        QQuickItem::wheelEvent(event);
+    }
+}
+
+bool QQuickFlickablePrivate::isOutermostPressDelay() const
+{
+    Q_Q(const QQuickFlickable);
+    QQuickItem *item = q->parentItem();
+    while (item) {
+        QQuickFlickable *flick = qobject_cast<QQuickFlickable*>(item);
+        if (flick && flick->pressDelay() > 0 && flick->isInteractive())
+            return false;
+        item = item->parentItem();
+    }
+
+    return true;
+}
+
+void QQuickFlickablePrivate::captureDelayedPress(QMouseEvent *event)
+{
+    Q_Q(QQuickFlickable);
+    if (!q->canvas() || pressDelay <= 0)
+        return;
+    if (!isOutermostPressDelay())
+        return;
+    delayedPressTarget = q->canvas()->mouseGrabberItem();
+    delayedPressEvent = new QMouseEvent(*event);
+    delayedPressEvent->setAccepted(false);
+    delayedPressTimer.start(pressDelay, q);
+}
+
+void QQuickFlickablePrivate::clearDelayedPress()
+{
+    if (delayedPressEvent) {
+        delayedPressTimer.stop();
+        delete delayedPressEvent;
+        delayedPressEvent = 0;
+    }
+}
+
+//XXX pixelAligned ignores the global position of the Flickable, i.e. assumes Flickable itself is pixel aligned.
+void QQuickFlickablePrivate::setViewportX(qreal x)
+{
+    contentItem->setX(pixelAligned ? qRound(x) : x);
+}
+
+void QQuickFlickablePrivate::setViewportY(qreal y)
+{
+    contentItem->setY(pixelAligned ? qRound(y) : y);
+}
+
+void QQuickFlickable::timerEvent(QTimerEvent *event)
+{
+    Q_D(QQuickFlickable);
+    if (event->timerId() == d->delayedPressTimer.timerId()) {
+        d->delayedPressTimer.stop();
+        if (d->delayedPressEvent) {
+            QQuickItem *grabber = canvas() ? canvas()->mouseGrabberItem() : 0;
+            if (!grabber || grabber != this) {
+                // We replay the mouse press but the grabber we had might not be interessted by the event (e.g. overlay)
+                // so we reset the grabber
+                if (canvas()->mouseGrabberItem() == d->delayedPressTarget)
+                    d->delayedPressTarget->ungrabMouse();
+                // Use the event handler that will take care of finding the proper item to propagate the event
+                QQuickCanvasPrivate::get(canvas())->deliverMouseEvent(d->delayedPressEvent);
+            }
+            delete d->delayedPressEvent;
+            d->delayedPressEvent = 0;
+        }
+    }
+}
+
+qreal QQuickFlickable::minYExtent() const
+{
+    Q_D(const QQuickFlickable);
+    return d->vData.startMargin;
+}
+
+qreal QQuickFlickable::minXExtent() const
+{
+    Q_D(const QQuickFlickable);
+    return d->hData.startMargin;
+}
+
+/* returns -ve */
+qreal QQuickFlickable::maxXExtent() const
+{
+    Q_D(const QQuickFlickable);
+    return width() - vWidth() - d->hData.endMargin;
+}
+/* returns -ve */
+qreal QQuickFlickable::maxYExtent() const
+{
+    Q_D(const QQuickFlickable);
+    return height() - vHeight() - d->vData.endMargin;
+}
+
+void QQuickFlickable::componentComplete()
+{
+    Q_D(QQuickFlickable);
+    QQuickItem::componentComplete();
+    if (!d->hData.explicitValue && d->hData.startMargin != 0.)
+        setContentX(-minXExtent());
+    if (!d->vData.explicitValue && d->vData.startMargin != 0.)
+        setContentY(-minYExtent());
+}
+
+void QQuickFlickable::viewportMoved()
+{
+    Q_D(QQuickFlickable);
+
+    qreal prevX = d->lastFlickablePosition.x();
+    qreal prevY = d->lastFlickablePosition.y();
+    if (d->pressed || d->calcVelocity) {
+        int elapsed = QQuickItemPrivate::restart(d->velocityTime);
+        if (elapsed > 0) {
+            qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / elapsed;
+            if (qAbs(horizontalVelocity) > 0) {
+                d->velocityTimeline.reset(d->hData.smoothVelocity);
+                d->velocityTimeline.move(d->hData.smoothVelocity, horizontalVelocity, d->reportedVelocitySmoothing);
+                d->velocityTimeline.move(d->hData.smoothVelocity, 0, d->reportedVelocitySmoothing);
+            }
+            qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / elapsed;
+            if (qAbs(verticalVelocity) > 0) {
+                d->velocityTimeline.reset(d->vData.smoothVelocity);
+                d->velocityTimeline.move(d->vData.smoothVelocity, verticalVelocity, d->reportedVelocitySmoothing);
+                d->velocityTimeline.move(d->vData.smoothVelocity, 0, d->reportedVelocitySmoothing);
+            }
+        }
+    } else {
+        if (d->timeline.time() > d->vTime) {
+            d->velocityTimeline.clear();
+            qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / (d->timeline.time() - d->vTime);
+            qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / (d->timeline.time() - d->vTime);
+            d->hData.smoothVelocity.setValue(horizontalVelocity);
+            d->vData.smoothVelocity.setValue(verticalVelocity);
+        }
+    }
+
+    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
+        d->vData.inOvershoot = true;
+        qreal maxDistance = d->overShootDistance(height());
+        d->timeline.reset(d->vData.move);
+        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->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
+        d->hData.inOvershoot = true;
+        qreal maxDistance = d->overShootDistance(width());
+        d->timeline.reset(d->hData.move);
+        d->timeline.accel(d->hData.move, -d->hData.smoothVelocity.value(), d->deceleration*QML_FLICK_OVERSHOOTFRICTION, maxDistance);
+        d->timeline.callback(QDeclarativeTimeLineCallback(&d->hData.move, d->fixupX_callback, d));
+    }
+
+    d->lastFlickablePosition = QPointF(d->hData.move.value(), d->vData.move.value());
+
+    d->vTime = d->timeline.time();
+    d->updateBeginningEnd();
+}
+
+void QQuickFlickable::geometryChanged(const QRectF &newGeometry,
+                             const QRectF &oldGeometry)
+{
+    Q_D(QQuickFlickable);
+    QQuickItem::geometryChanged(newGeometry, oldGeometry);
+
+    bool changed = false;
+    if (newGeometry.width() != oldGeometry.width()) {
+        if (xflick())
+            changed = true;
+        if (d->hData.viewSize < 0) {
+            d->contentItem->setWidth(width());
+            emit contentWidthChanged();
+        }
+        // Make sure that we're entirely in view.
+        if (!d->pressed && !d->hData.moving && !d->vData.moving) {
+            d->fixupMode = QQuickFlickablePrivate::Immediate;
+            d->fixupX();
+        }
+    }
+    if (newGeometry.height() != oldGeometry.height()) {
+        if (yflick())
+            changed = true;
+        if (d->vData.viewSize < 0) {
+            d->contentItem->setHeight(height());
+            emit contentHeightChanged();
+        }
+        // Make sure that we're entirely in view.
+        if (!d->pressed && !d->hData.moving && !d->vData.moving) {
+            d->fixupMode = QQuickFlickablePrivate::Immediate;
+            d->fixupY();
+        }
+    }
+
+    if (changed)
+        d->updateBeginningEnd();
+}
+
+void QQuickFlickable::cancelFlick()
+{
+    Q_D(QQuickFlickable);
+    d->timeline.reset(d->hData.move);
+    d->timeline.reset(d->vData.move);
+    movementEnding();
+}
+
+void QQuickFlickablePrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
+{
+    QQuickItem *i = qobject_cast<QQuickItem *>(o);
+    if (i) {
+        i->setParentItem(static_cast<QQuickFlickablePrivate*>(prop->data)->contentItem);
+    } else {
+        o->setParent(prop->object); // XXX todo - do we want this?
+    }
+}
+
+int QQuickFlickablePrivate::data_count(QDeclarativeListProperty<QObject> *)
+{
+    // XXX todo
+    return 0;
+}
+
+QObject *QQuickFlickablePrivate::data_at(QDeclarativeListProperty<QObject> *, int)
+{
+    // XXX todo
+    return 0;
+}
+
+void QQuickFlickablePrivate::data_clear(QDeclarativeListProperty<QObject> *)
+{
+    // XXX todo
+}
+
+QDeclarativeListProperty<QObject> QQuickFlickable::flickableData()
+{
+    Q_D(QQuickFlickable);
+    return QDeclarativeListProperty<QObject>(this, (void *)d, QQuickFlickablePrivate::data_append,
+                                             QQuickFlickablePrivate::data_count,
+                                             QQuickFlickablePrivate::data_at,
+                                             QQuickFlickablePrivate::data_clear);
+}
+
+QDeclarativeListProperty<QQuickItem> QQuickFlickable::flickableChildren()
+{
+    Q_D(QQuickFlickable);
+    return QQuickItemPrivate::get(d->contentItem)->children();
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::Flickable::boundsBehavior
+    This property holds whether the surface may be dragged
+    beyond the Fickable's boundaries, or overshoot the
+    Flickable's boundaries when flicked.
+
+    This enables the feeling that the edges of the view are soft,
+    rather than a hard physical boundary.
+
+    The \c boundsBehavior can be one of:
+
+    \list
+    \o Flickable.StopAtBounds - the contents can not be dragged beyond the boundary
+    of the flickable, and flicks will not overshoot.
+    \o Flickable.DragOverBounds - the contents can be dragged beyond the boundary
+    of the Flickable, but flicks will not overshoot.
+    \o Flickable.DragAndOvershootBounds (default) - the contents can be dragged
+    beyond the boundary of the Flickable, and can overshoot the
+    boundary when flicked.
+    \endlist
+*/
+QQuickFlickable::BoundsBehavior QQuickFlickable::boundsBehavior() const
+{
+    Q_D(const QQuickFlickable);
+    return d->boundsBehavior;
+}
+
+void QQuickFlickable::setBoundsBehavior(BoundsBehavior b)
+{
+    Q_D(QQuickFlickable);
+    if (b == d->boundsBehavior)
+        return;
+    d->boundsBehavior = b;
+    emit boundsBehaviorChanged();
+}
+
+/*!
+    \qmlproperty real QtQuick2::Flickable::contentWidth
+    \qmlproperty real QtQuick2::Flickable::contentHeight
+
+    The dimensions of the content (the surface controlled by Flickable).
+    This should typically be set to the combined size of the items placed in the
+    Flickable.
+
+    The following snippet shows how these properties are used to display
+    an image that is larger than the Flickable item itself:
+
+    \snippet doc/src/snippets/declarative/flickable.qml document
+
+    In some cases, the the content dimensions can be automatically set
+    using the \l {Item::childrenRect.width}{childrenRect.width}
+    and \l {Item::childrenRect.height}{childrenRect.height} properties.
+*/
+qreal QQuickFlickable::contentWidth() const
+{
+    Q_D(const QQuickFlickable);
+    return d->hData.viewSize;
+}
+
+void QQuickFlickable::setContentWidth(qreal w)
+{
+    Q_D(QQuickFlickable);
+    if (d->hData.viewSize == w)
+        return;
+    d->hData.viewSize = w;
+    if (w < 0)
+        d->contentItem->setWidth(width());
+    else
+        d->contentItem->setWidth(w);
+    d->hData.markExtentsDirty();
+    // Make sure that we're entirely in view.
+    if (!d->pressed && !d->hData.moving && !d->vData.moving) {
+        d->fixupMode = QQuickFlickablePrivate::Immediate;
+        d->fixupX();
+    } else if (!d->pressed && d->hData.fixingUp) {
+        d->fixupMode = QQuickFlickablePrivate::ExtentChanged;
+        d->fixupX();
+    }
+    emit contentWidthChanged();
+    d->updateBeginningEnd();
+}
+
+qreal QQuickFlickable::contentHeight() const
+{
+    Q_D(const QQuickFlickable);
+    return d->vData.viewSize;
+}
+
+void QQuickFlickable::setContentHeight(qreal h)
+{
+    Q_D(QQuickFlickable);
+    if (d->vData.viewSize == h)
+        return;
+    d->vData.viewSize = h;
+    if (h < 0)
+        d->contentItem->setHeight(height());
+    else
+        d->contentItem->setHeight(h);
+    d->vData.markExtentsDirty();
+    // Make sure that we're entirely in view.
+    if (!d->pressed && !d->hData.moving && !d->vData.moving) {
+        d->fixupMode = QQuickFlickablePrivate::Immediate;
+        d->fixupY();
+    } else if (!d->pressed && d->vData.fixingUp) {
+        d->fixupMode = QQuickFlickablePrivate::ExtentChanged;
+        d->fixupY();
+    }
+    emit contentHeightChanged();
+    d->updateBeginningEnd();
+}
+
+/*!
+    \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 QQuickFlickable::topMargin() const
+{
+    Q_D(const QQuickFlickable);
+    return d->vData.startMargin;
+}
+
+void QQuickFlickable::setTopMargin(qreal m)
+{
+    Q_D(QQuickFlickable);
+    if (d->vData.startMargin == m)
+        return;
+    d->vData.startMargin = m;
+    d->vData.markExtentsDirty();
+    if (!d->pressed && !d->hData.moving && !d->vData.moving) {
+        d->fixupMode = QQuickFlickablePrivate::Immediate;
+        d->fixupY();
+    }
+    emit topMarginChanged();
+    d->updateBeginningEnd();
+}
+
+qreal QQuickFlickable::bottomMargin() const
+{
+    Q_D(const QQuickFlickable);
+    return d->vData.endMargin;
+}
+
+void QQuickFlickable::setBottomMargin(qreal m)
+{
+    Q_D(QQuickFlickable);
+    if (d->vData.endMargin == m)
+        return;
+    d->vData.endMargin = m;
+    d->vData.markExtentsDirty();
+    if (!d->pressed && !d->hData.moving && !d->vData.moving) {
+        d->fixupMode = QQuickFlickablePrivate::Immediate;
+        d->fixupY();
+    }
+    emit bottomMarginChanged();
+    d->updateBeginningEnd();
+}
+
+qreal QQuickFlickable::leftMargin() const
+{
+    Q_D(const QQuickFlickable);
+    return d->hData.startMargin;
+}
+
+void QQuickFlickable::setLeftMargin(qreal m)
+{
+    Q_D(QQuickFlickable);
+    if (d->hData.startMargin == m)
+        return;
+    d->hData.startMargin = m;
+    d->hData.markExtentsDirty();
+    if (!d->pressed && !d->hData.moving && !d->vData.moving) {
+        d->fixupMode = QQuickFlickablePrivate::Immediate;
+        d->fixupX();
+    }
+    emit leftMarginChanged();
+    d->updateBeginningEnd();
+}
+
+qreal QQuickFlickable::rightMargin() const
+{
+    Q_D(const QQuickFlickable);
+    return d->hData.endMargin;
+}
+
+void QQuickFlickable::setRightMargin(qreal m)
+{
+    Q_D(QQuickFlickable);
+    if (d->hData.endMargin == m)
+        return;
+    d->hData.endMargin = m;
+    d->hData.markExtentsDirty();
+    if (!d->pressed && !d->hData.moving && !d->vData.moving) {
+        d->fixupMode = QQuickFlickablePrivate::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 QQuickFlickable::yOrigin() const
+{
+    Q_D(const QQuickFlickable);
+    return -minYExtent() + d->vData.startMargin;
+}
+
+qreal QQuickFlickable::xOrigin() const
+{
+    Q_D(const QQuickFlickable);
+    return -minXExtent() + d->hData.startMargin;
+}
+
+
+/*!
+    \qmlmethod QtQuick2::Flickable::resizeContent(real width, real height, QPointF center)
+
+    Resizes the content to \a width x \a height about \a center.
+
+    This does not scale the contents of the Flickable - it only resizes the \l contentWidth
+    and \l contentHeight.
+
+    Resizing the content may result in the content being positioned outside
+    the bounds of the Flickable.  Calling \l returnToBounds() will
+    move the content back within legal bounds.
+*/
+void QQuickFlickable::resizeContent(qreal w, qreal h, QPointF center)
+{
+    Q_D(QQuickFlickable);
+    if (w != d->hData.viewSize) {
+        qreal oldSize = d->hData.viewSize;
+        d->hData.viewSize = w;
+        d->contentItem->setWidth(w);
+        emit contentWidthChanged();
+        if (center.x() != 0) {
+            qreal pos = center.x() * w / oldSize;
+            setContentX(contentX() + pos - center.x());
+        }
+    }
+    if (h != d->vData.viewSize) {
+        qreal oldSize = d->vData.viewSize;
+        d->vData.viewSize = h;
+        d->contentItem->setHeight(h);
+        emit contentHeightChanged();
+        if (center.y() != 0) {
+            qreal pos = center.y() * h / oldSize;
+            setContentY(contentY() + pos - center.y());
+        }
+    }
+    d->updateBeginningEnd();
+}
+
+/*!
+    \qmlmethod QtQuick2::Flickable::returnToBounds()
+
+    Ensures the content is within legal bounds.
+
+    This may be called to ensure that the content is within legal bounds
+    after manually positioning the content.
+*/
+void QQuickFlickable::returnToBounds()
+{
+    Q_D(QQuickFlickable);
+    d->fixupX();
+    d->fixupY();
+}
+
+qreal QQuickFlickable::vWidth() const
+{
+    Q_D(const QQuickFlickable);
+    if (d->hData.viewSize < 0)
+        return width();
+    else
+        return d->hData.viewSize;
+}
+
+qreal QQuickFlickable::vHeight() const
+{
+    Q_D(const QQuickFlickable);
+    if (d->vData.viewSize < 0)
+        return height();
+    else
+        return d->vData.viewSize;
+}
+
+bool QQuickFlickable::xflick() const
+{
+    Q_D(const QQuickFlickable);
+    if (d->flickableDirection == QQuickFlickable::AutoFlickDirection)
+        return vWidth() != width();
+    return d->flickableDirection & QQuickFlickable::HorizontalFlick;
+}
+
+bool QQuickFlickable::yflick() const
+{
+    Q_D(const QQuickFlickable);
+    if (d->flickableDirection == QQuickFlickable::AutoFlickDirection)
+        return vHeight() !=  height();
+    return d->flickableDirection & QQuickFlickable::VerticalFlick;
+}
+
+void QQuickFlickable::mouseUngrabEvent()
+{
+    Q_D(QQuickFlickable);
+    if (d->pressed) {
+        // if our mouse grab has been removed (probably by another Flickable),
+        // fix our state
+        d->pressed = false;
+        d->draggingEnding();
+        d->stealMouse = false;
+        setKeepMouseGrab(false);
+    }
+}
+
+bool QQuickFlickable::sendMouseEvent(QMouseEvent *event)
+{
+    Q_D(QQuickFlickable);
+    QRectF myRect = mapRectToScene(QRectF(0, 0, width(), height()));
+
+    QQuickCanvas *c = canvas();
+    QQuickItem *grabber = c ? c->mouseGrabberItem() : 0;
+    bool disabledItem = grabber && !grabber->isEnabled();
+    bool stealThisEvent = d->stealMouse;
+    if ((stealThisEvent || myRect.contains(event->windowPos())) && (!grabber || !grabber->keepMouseGrab() || disabledItem)) {
+        QMouseEvent mouseEvent(event->type(), mapFromScene(event->windowPos()), event->windowPos(), event->screenPos(),
+                               event->button(), event->buttons(), event->modifiers());
+
+        mouseEvent.setAccepted(false);
+
+        switch (mouseEvent.type()) {
+        case QEvent::MouseMove:
+            d->handleMouseMoveEvent(&mouseEvent);
+            break;
+        case QEvent::MouseButtonPress:
+            if (d->pressed) // we are already pressed - this is a delayed replay
+                return false;
+
+            d->handleMousePressEvent(&mouseEvent);
+            d->captureDelayedPress(event);
+            stealThisEvent = d->stealMouse;   // Update stealThisEvent in case changed by function call above
+            break;
+        case QEvent::MouseButtonRelease:
+            if (d->delayedPressEvent) {
+                // We replay the mouse press but the grabber we had might not be interessted by the event (e.g. overlay)
+                // so we reset the grabber
+                if (c->mouseGrabberItem() == d->delayedPressTarget)
+                    d->delayedPressTarget->ungrabMouse();
+                //Use the event handler that will take care of finding the proper item to propagate the event
+                QQuickCanvasPrivate::get(canvas())->deliverMouseEvent(d->delayedPressEvent);
+                d->clearDelayedPress();
+                // We send the release
+                canvas()->sendEvent(c->mouseGrabberItem(), event);
+                // And the event has been consumed
+                d->stealMouse = false;
+                d->pressed = false;
+                return true;
+            }
+            d->handleMouseReleaseEvent(&mouseEvent);
+            break;
+        default:
+            break;
+        }
+        grabber = qobject_cast<QQuickItem*>(c->mouseGrabberItem());
+        if ((grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) || disabledItem) {
+            d->clearDelayedPress();
+            grabMouse();
+        }
+
+        return stealThisEvent || d->delayedPressEvent || disabledItem;
+    } else if (d->lastPosTime.isValid()) {
+        d->lastPosTime.invalidate();
+        returnToBounds();
+    }
+    if (event->type() == QEvent::MouseButtonRelease) {
+        d->lastPosTime.invalidate();
+        d->clearDelayedPress();
+        d->stealMouse = false;
+        d->pressed = false;
+    }
+    return false;
+}
+
+
+bool QQuickFlickable::childMouseEventFilter(QQuickItem *i, QEvent *e)
+{
+    Q_D(QQuickFlickable);
+    if (!isVisible() || !d->interactive || !isEnabled())
+        return QQuickItem::childMouseEventFilter(i, e);
+    switch (e->type()) {
+    case QEvent::MouseButtonPress:
+    case QEvent::MouseMove:
+    case QEvent::MouseButtonRelease:
+        return sendMouseEvent(static_cast<QMouseEvent *>(e));
+    default:
+        break;
+    }
+
+    return QQuickItem::childMouseEventFilter(i, e);
+}
+
+/*!
+    \qmlproperty real QtQuick2::Flickable::maximumFlickVelocity
+    This property holds the maximum velocity that the user can flick the view in pixels/second.
+
+    The default value is platform dependent.
+*/
+qreal QQuickFlickable::maximumFlickVelocity() const
+{
+    Q_D(const QQuickFlickable);
+    return d->maxVelocity;
+}
+
+void QQuickFlickable::setMaximumFlickVelocity(qreal v)
+{
+    Q_D(QQuickFlickable);
+    if (v == d->maxVelocity)
+        return;
+    d->maxVelocity = v;
+    emit maximumFlickVelocityChanged();
+}
+
+/*!
+    \qmlproperty real QtQuick2::Flickable::flickDeceleration
+    This property holds the rate at which a flick will decelerate.
+
+    The default value is platform dependent.
+*/
+qreal QQuickFlickable::flickDeceleration() const
+{
+    Q_D(const QQuickFlickable);
+    return d->deceleration;
+}
+
+void QQuickFlickable::setFlickDeceleration(qreal deceleration)
+{
+    Q_D(QQuickFlickable);
+    if (deceleration == d->deceleration)
+        return;
+    d->deceleration = deceleration;
+    emit flickDecelerationChanged();
+}
+
+bool QQuickFlickable::isFlicking() const
+{
+    Q_D(const QQuickFlickable);
+    return d->hData.flicking ||  d->vData.flicking;
+}
+
+/*!
+    \qmlproperty bool QtQuick2::Flickable::flicking
+    \qmlproperty bool QtQuick2::Flickable::flickingHorizontally
+    \qmlproperty bool QtQuick2::Flickable::flickingVertically
+
+    These properties describe whether the view is currently moving horizontally,
+    vertically or in either direction, due to the user flicking the view.
+*/
+bool QQuickFlickable::isFlickingHorizontally() const
+{
+    Q_D(const QQuickFlickable);
+    return d->hData.flicking;
+}
+
+bool QQuickFlickable::isFlickingVertically() const
+{
+    Q_D(const QQuickFlickable);
+    return d->vData.flicking;
+}
+
+/*!
+    \qmlproperty bool QtQuick2::Flickable::dragging
+    \qmlproperty bool QtQuick2::Flickable::draggingHorizontally
+    \qmlproperty bool QtQuick2::Flickable::draggingVertically
+
+    These properties describe whether the view is currently moving horizontally,
+    vertically or in either direction, due to the user dragging the view.
+*/
+bool QQuickFlickable::isDragging() const
+{
+    Q_D(const QQuickFlickable);
+    return d->hData.dragging ||  d->vData.dragging;
+}
+
+bool QQuickFlickable::isDraggingHorizontally() const
+{
+    Q_D(const QQuickFlickable);
+    return d->hData.dragging;
+}
+
+bool QQuickFlickable::isDraggingVertically() const
+{
+    Q_D(const QQuickFlickable);
+    return d->vData.dragging;
+}
+
+void QQuickFlickablePrivate::draggingStarting()
+{
+    Q_Q(QQuickFlickable);
+    bool wasDragging = hData.dragging || vData.dragging;
+    if (hMoved && !hData.dragging) {
+        hData.dragging = true;
+        emit q->draggingHorizontallyChanged();
+    }
+    if (vMoved && !vData.dragging) {
+        vData.dragging = true;
+        emit q->draggingVerticallyChanged();
+    }
+    if (!wasDragging && (hData.dragging || vData.dragging)) {
+        emit q->draggingChanged();
+        emit q->dragStarted();
+    }
+}
+
+void QQuickFlickablePrivate::draggingEnding()
+{
+    Q_Q(QQuickFlickable);
+    bool wasDragging = hData.dragging || vData.dragging;
+    if (hData.dragging) {
+        hData.dragging = false;
+        emit q->draggingHorizontallyChanged();
+    }
+    if (vData.dragging) {
+        vData.dragging = false;
+        emit q->draggingVerticallyChanged();
+    }
+    if (wasDragging && !hData.dragging && !vData.dragging) {
+        emit q->draggingChanged();
+        emit q->dragEnded();
+    }
+}
+
+/*!
+    \qmlproperty int QtQuick2::Flickable::pressDelay
+
+    This property holds the time to delay (ms) delivering a press to
+    children of the Flickable.  This can be useful where reacting
+    to a press before a flicking action has undesirable effects.
+
+    If the flickable is dragged/flicked before the delay times out
+    the press event will not be delivered.  If the button is released
+    within the timeout, both the press and release will be delivered.
+
+    Note that for nested Flickables with pressDelay set, the pressDelay of
+    inner Flickables is overridden by the outermost Flickable.
+*/
+int QQuickFlickable::pressDelay() const
+{
+    Q_D(const QQuickFlickable);
+    return d->pressDelay;
+}
+
+void QQuickFlickable::setPressDelay(int delay)
+{
+    Q_D(QQuickFlickable);
+    if (d->pressDelay == delay)
+        return;
+    d->pressDelay = delay;
+    emit pressDelayChanged();
+}
+
+/*!
+    \qmlproperty bool QtQuick2::Flickable::moving
+    \qmlproperty bool QtQuick2::Flickable::movingHorizontally
+    \qmlproperty bool QtQuick2::Flickable::movingVertically
+
+    These properties describe whether the view is currently moving horizontally,
+    vertically or in either direction, due to the user either dragging or
+    flicking the view.
+*/
+
+bool QQuickFlickable::isMoving() const
+{
+    Q_D(const QQuickFlickable);
+    return d->hData.moving || d->vData.moving;
+}
+
+bool QQuickFlickable::isMovingHorizontally() const
+{
+    Q_D(const QQuickFlickable);
+    return d->hData.moving;
+}
+
+bool QQuickFlickable::isMovingVertically() const
+{
+    Q_D(const QQuickFlickable);
+    return d->vData.moving;
+}
+
+void QQuickFlickable::movementStarting()
+{
+    Q_D(QQuickFlickable);
+    if (d->hMoved && !d->hData.moving) {
+        d->hData.moving = true;
+        emit movingChanged();
+        emit movingHorizontallyChanged();
+        if (!d->vData.moving)
+            emit movementStarted();
+    }
+    else if (d->vMoved && !d->vData.moving) {
+        d->vData.moving = true;
+        emit movingChanged();
+        emit movingVerticallyChanged();
+        if (!d->hData.moving)
+            emit movementStarted();
+    }
+}
+
+void QQuickFlickable::movementEnding()
+{
+    Q_D(QQuickFlickable);
+    movementXEnding();
+    movementYEnding();
+    d->hData.smoothVelocity.setValue(0);
+    d->vData.smoothVelocity.setValue(0);
+}
+
+void QQuickFlickable::movementXEnding()
+{
+    Q_D(QQuickFlickable);
+    if (d->hData.flicking) {
+        d->hData.flicking = false;
+        emit flickingChanged();
+        emit flickingHorizontallyChanged();
+        if (!d->vData.flicking)
+           emit flickEnded();
+    }
+    if (!d->pressed && !d->stealMouse) {
+        if (d->hData.moving) {
+            d->hData.moving = false;
+            d->hMoved = false;
+            emit movingChanged();
+            emit movingHorizontallyChanged();
+            if (!d->vData.moving)
+                emit movementEnded();
+        }
+    }
+    d->hData.fixingUp = false;
+}
+
+void QQuickFlickable::movementYEnding()
+{
+    Q_D(QQuickFlickable);
+    if (d->vData.flicking) {
+        d->vData.flicking = false;
+        emit flickingChanged();
+        emit flickingVerticallyChanged();
+        if (!d->hData.flicking)
+           emit flickEnded();
+    }
+    if (!d->pressed && !d->stealMouse) {
+        if (d->vData.moving) {
+            d->vData.moving = false;
+            d->vMoved = false;
+            emit movingChanged();
+            emit movingVerticallyChanged();
+            if (!d->hData.moving)
+                emit movementEnded();
+        }
+    }
+    d->vData.fixingUp = false;
+}
+
+void QQuickFlickablePrivate::updateVelocity()
+{
+    Q_Q(QQuickFlickable);
+    emit q->horizontalVelocityChanged();
+    emit q->verticalVelocityChanged();
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickflickable_p.h b/src/declarative/items/qquickflickable_p.h
new file mode 100644 (file)
index 0000000..fe4ac40
--- /dev/null
@@ -0,0 +1,277 @@
+// Commit: 1bcddaaf318fc37c71c5191913f3487c49444ec6
+/****************************************************************************
+**
+** 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 QQUICKFLICKABLE_P_H
+#define QQUICKFLICKABLE_P_H
+
+#include "qquickitem.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickFlickablePrivate;
+class QQuickFlickableVisibleArea;
+class Q_AUTOTEST_EXPORT QQuickFlickable : public QQuickItem
+{
+    Q_OBJECT
+
+    Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth NOTIFY contentWidthChanged)
+    Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight NOTIFY contentHeightChanged)
+    Q_PROPERTY(qreal contentX READ contentX WRITE setContentX NOTIFY contentXChanged)
+    Q_PROPERTY(qreal contentY READ contentY WRITE setContentY NOTIFY contentYChanged)
+    Q_PROPERTY(QQuickItem *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)
+
+    Q_PROPERTY(BoundsBehavior boundsBehavior READ boundsBehavior WRITE setBoundsBehavior NOTIFY boundsBehaviorChanged)
+    Q_PROPERTY(qreal maximumFlickVelocity READ maximumFlickVelocity WRITE setMaximumFlickVelocity NOTIFY maximumFlickVelocityChanged)
+    Q_PROPERTY(qreal flickDeceleration READ flickDeceleration WRITE setFlickDeceleration NOTIFY flickDecelerationChanged)
+    Q_PROPERTY(bool moving READ isMoving NOTIFY movingChanged)
+    Q_PROPERTY(bool movingHorizontally READ isMovingHorizontally NOTIFY movingHorizontallyChanged)
+    Q_PROPERTY(bool movingVertically READ isMovingVertically NOTIFY movingVerticallyChanged)
+    Q_PROPERTY(bool flicking READ isFlicking NOTIFY flickingChanged)
+    Q_PROPERTY(bool flickingHorizontally READ isFlickingHorizontally NOTIFY flickingHorizontallyChanged)
+    Q_PROPERTY(bool flickingVertically READ isFlickingVertically NOTIFY flickingVerticallyChanged)
+    Q_PROPERTY(bool dragging READ isDragging NOTIFY draggingChanged)
+    Q_PROPERTY(bool draggingHorizontally READ isDraggingHorizontally NOTIFY draggingHorizontallyChanged)
+    Q_PROPERTY(bool draggingVertically READ isDraggingVertically NOTIFY draggingVerticallyChanged)
+    Q_PROPERTY(FlickableDirection flickableDirection READ flickableDirection WRITE setFlickableDirection NOTIFY flickableDirectionChanged)
+
+    Q_PROPERTY(bool interactive READ isInteractive WRITE setInteractive NOTIFY interactiveChanged)
+    Q_PROPERTY(int pressDelay READ pressDelay WRITE setPressDelay NOTIFY pressDelayChanged)
+
+    Q_PROPERTY(bool atXEnd READ isAtXEnd NOTIFY isAtBoundaryChanged)
+    Q_PROPERTY(bool atYEnd READ isAtYEnd NOTIFY isAtBoundaryChanged)
+    Q_PROPERTY(bool atXBeginning READ isAtXBeginning NOTIFY isAtBoundaryChanged)
+    Q_PROPERTY(bool atYBeginning READ isAtYBeginning NOTIFY isAtBoundaryChanged)
+
+    Q_PROPERTY(QQuickFlickableVisibleArea *visibleArea READ visibleArea CONSTANT)
+
+    Q_PROPERTY(bool pixelAligned READ pixelAligned WRITE setPixelAligned NOTIFY pixelAlignedChanged)
+
+    Q_PROPERTY(QDeclarativeListProperty<QObject> flickableData READ flickableData)
+    Q_PROPERTY(QDeclarativeListProperty<QQuickItem> flickableChildren READ flickableChildren)
+    Q_CLASSINFO("DefaultProperty", "flickableData")
+
+    Q_ENUMS(FlickableDirection)
+    Q_ENUMS(BoundsBehavior)
+
+public:
+    QQuickFlickable(QQuickItem *parent=0);
+    ~QQuickFlickable();
+
+    QDeclarativeListProperty<QObject> flickableData();
+    QDeclarativeListProperty<QQuickItem> flickableChildren();
+
+    enum BoundsBehavior { StopAtBounds, DragOverBounds, DragAndOvershootBounds };
+    BoundsBehavior boundsBehavior() const;
+    void setBoundsBehavior(BoundsBehavior);
+
+    qreal contentWidth() const;
+    void setContentWidth(qreal);
+
+    qreal contentHeight() const;
+    void setContentHeight(qreal);
+
+    qreal contentX() const;
+    virtual void setContentX(qreal pos);
+
+    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;
+    bool isFlicking() const;
+    bool isFlickingHorizontally() const;
+    bool isFlickingVertically() const;
+    bool isDragging() const;
+    bool isDraggingHorizontally() const;
+    bool isDraggingVertically() const;
+
+    int pressDelay() const;
+    void setPressDelay(int delay);
+
+    qreal maximumFlickVelocity() const;
+    void setMaximumFlickVelocity(qreal);
+
+    qreal flickDeceleration() const;
+    void setFlickDeceleration(qreal);
+
+    bool isInteractive() const;
+    void setInteractive(bool);
+
+    qreal horizontalVelocity() const;
+    qreal verticalVelocity() const;
+
+    bool isAtXEnd() const;
+    bool isAtXBeginning() const;
+    bool isAtYEnd() const;
+    bool isAtYBeginning() const;
+
+    QQuickItem *contentItem();
+
+    enum FlickableDirection { AutoFlickDirection=0x00, HorizontalFlick=0x01, VerticalFlick=0x02, HorizontalAndVerticalFlick=0x03 };
+    FlickableDirection flickableDirection() const;
+    void setFlickableDirection(FlickableDirection);
+
+    bool pixelAligned() const;
+    void setPixelAligned(bool align);
+
+    Q_INVOKABLE void resizeContent(qreal w, qreal h, QPointF center);
+    Q_INVOKABLE void returnToBounds();
+
+Q_SIGNALS:
+    void contentWidthChanged();
+    void contentHeightChanged();
+    void contentXChanged();
+    void contentYChanged();
+    void topMarginChanged();
+    void bottomMarginChanged();
+    void leftMarginChanged();
+    void rightMarginChanged();
+    void yOriginChanged();
+    void xOriginChanged();
+    void movingChanged();
+    void movingHorizontallyChanged();
+    void movingVerticallyChanged();
+    void flickingChanged();
+    void flickingHorizontallyChanged();
+    void flickingVerticallyChanged();
+    void draggingChanged();
+    void draggingHorizontallyChanged();
+    void draggingVerticallyChanged();
+    void horizontalVelocityChanged();
+    void verticalVelocityChanged();
+    void isAtBoundaryChanged();
+    void flickableDirectionChanged();
+    void interactiveChanged();
+    void boundsBehaviorChanged();
+    void maximumFlickVelocityChanged();
+    void flickDecelerationChanged();
+    void pressDelayChanged();
+    void movementStarted();
+    void movementEnded();
+    void flickStarted();
+    void flickEnded();
+    void dragStarted();
+    void dragEnded();
+    void pixelAlignedChanged();
+
+protected:
+    virtual bool childMouseEventFilter(QQuickItem *, QEvent *);
+    virtual void mousePressEvent(QMouseEvent *event);
+    virtual void mouseMoveEvent(QMouseEvent *event);
+    virtual void mouseReleaseEvent(QMouseEvent *event);
+    virtual void wheelEvent(QWheelEvent *event);
+    virtual void timerEvent(QTimerEvent *event);
+
+    QQuickFlickableVisibleArea *visibleArea();
+
+protected Q_SLOTS:
+    virtual void ticked();
+    void movementStarting();
+    void movementEnding();
+
+protected:
+    void movementXEnding();
+    void movementYEnding();
+    virtual qreal minXExtent() const;
+    virtual qreal minYExtent() const;
+    virtual qreal maxXExtent() const;
+    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);
+    void mouseUngrabEvent();
+    bool sendMouseEvent(QMouseEvent *event);
+
+    bool xflick() const;
+    bool yflick() const;
+    void cancelFlick();
+
+protected:
+    QQuickFlickable(QQuickFlickablePrivate &dd, QQuickItem *parent);
+
+private:
+    Q_DISABLE_COPY(QQuickFlickable)
+    Q_DECLARE_PRIVATE(QQuickFlickable)
+    friend class QQuickFlickableVisibleArea;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickFlickable)
+
+QT_END_HEADER
+
+#endif // QQUICKFLICKABLE_P_H
diff --git a/src/declarative/items/qquickflickable_p_p.h b/src/declarative/items/qquickflickable_p_p.h
new file mode 100644 (file)
index 0000000..8ceea61
--- /dev/null
@@ -0,0 +1,262 @@
+// Commit: 160f1867868cdea916923652b00484ed11f90aaa
+/****************************************************************************
+**
+** 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 QQUICKFLICKABLE_P_P_H
+#define QQUICKFLICKABLE_P_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 "qquickflickable_p.h"
+#include "qquickitem_p.h"
+#include "qquickitemchangelistener_p.h"
+
+#include <QtDeclarative/qdeclarative.h>
+#include <QtCore/qdatetime.h>
+#include "qplatformdefs.h"
+
+#include <private/qdeclarativetimeline_p_p.h>
+#include <private/qdeclarativeanimation_p_p.h>
+
+QT_BEGIN_NAMESPACE
+
+// Really slow flicks can be annoying.
+const qreal MinimumFlickVelocity = 75.0;
+
+class QQuickFlickableVisibleArea;
+class QQuickFlickablePrivate : public QQuickItemPrivate, public QQuickItemChangeListener
+{
+    Q_DECLARE_PUBLIC(QQuickFlickable)
+
+public:
+    static inline QQuickFlickablePrivate *get(QQuickFlickable *o) { return o->d_func(); }
+
+    QQuickFlickablePrivate();
+    void init();
+
+    struct Velocity : public QDeclarativeTimeLineValue
+    {
+        Velocity(QQuickFlickablePrivate *p)
+            : parent(p) {}
+        virtual void setValue(qreal v) {
+            if (v != value()) {
+                QDeclarativeTimeLineValue::setValue(v);
+                parent->updateVelocity();
+            }
+        }
+        QQuickFlickablePrivate *parent;
+    };
+
+    struct AxisData {
+        AxisData(QQuickFlickablePrivate *fp, void (QQuickFlickablePrivate::*func)(qreal))
+            : 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() {
+            velocityBuffer.clear();
+            dragStartOffset = 0;
+            fixingUp = false;
+            inOvershoot = false;
+        }
+
+        void markExtentsDirty() {
+            minExtentDirty = true;
+            maxExtentDirty = true;
+            extentsChanged = true;
+        }
+
+        void addVelocitySample(qreal v, qreal maxVelocity);
+        void updateVelocity();
+
+        QDeclarativeTimeLineValueProxy<QQuickFlickablePrivate> move;
+        qreal viewSize;
+        qreal pressPos;
+        qreal dragStartOffset;
+        qreal dragMinBound;
+        qreal dragMaxBound;
+        qreal velocity;
+        qreal flickTarget;
+        qreal startMargin;
+        qreal endMargin;
+        QQuickFlickablePrivate::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);
+    void flickY(qreal velocity);
+    virtual void flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
+                        QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity);
+
+    void fixupX();
+    void fixupY();
+    virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent);
+
+    void updateBeginningEnd();
+
+    bool isOutermostPressDelay() const;
+    void captureDelayedPress(QMouseEvent *event);
+    void clearDelayedPress();
+
+    void setViewportX(qreal x);
+    void setViewportY(qreal y);
+
+    qreal overShootDistance(qreal size);
+
+    void itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &);
+
+    void draggingStarting();
+    void draggingEnding();
+
+public:
+    QQuickItem *contentItem;
+
+    AxisData hData;
+    AxisData vData;
+
+    QDeclarativeTimeLine timeline;
+    bool hMoved : 1;
+    bool vMoved : 1;
+    bool stealMouse : 1;
+    bool pressed : 1;
+    bool interactive : 1;
+    bool calcVelocity : 1;
+    bool pixelAligned : 1;
+    QElapsedTimer lastPosTime;
+    QPointF lastPos;
+    QPointF pressPos;
+    QElapsedTimer pressTime;
+    qreal deceleration;
+    qreal maxVelocity;
+    QElapsedTimer velocityTime;
+    QPointF lastFlickablePosition;
+    qreal reportedVelocitySmoothing;
+    QMouseEvent *delayedPressEvent;
+    QQuickItem *delayedPressTarget;
+    QBasicTimer delayedPressTimer;
+    int pressDelay;
+    int fixupDuration;
+
+    enum FixupMode { Normal, Immediate, ExtentChanged };
+    FixupMode fixupMode;
+
+    static void fixupY_callback(void *);
+    static void fixupX_callback(void *);
+
+    void updateVelocity();
+    int vTime;
+    QDeclarativeTimeLine velocityTimeline;
+    QQuickFlickableVisibleArea *visibleArea;
+    QQuickFlickable::FlickableDirection flickableDirection;
+    QQuickFlickable::BoundsBehavior boundsBehavior;
+
+    void handleMousePressEvent(QMouseEvent *);
+    void handleMouseMoveEvent(QMouseEvent *);
+    void handleMouseReleaseEvent(QMouseEvent *);
+
+    // flickableData property
+    static void data_append(QDeclarativeListProperty<QObject> *, QObject *);
+    static int data_count(QDeclarativeListProperty<QObject> *);
+    static QObject *data_at(QDeclarativeListProperty<QObject> *, int);
+    static void data_clear(QDeclarativeListProperty<QObject> *);
+};
+
+class QQuickFlickableVisibleArea : public QObject
+{
+    Q_OBJECT
+
+    Q_PROPERTY(qreal xPosition READ xPosition NOTIFY xPositionChanged)
+    Q_PROPERTY(qreal yPosition READ yPosition NOTIFY yPositionChanged)
+    Q_PROPERTY(qreal widthRatio READ widthRatio NOTIFY widthRatioChanged)
+    Q_PROPERTY(qreal heightRatio READ heightRatio NOTIFY heightRatioChanged)
+
+public:
+    QQuickFlickableVisibleArea(QQuickFlickable *parent=0);
+
+    qreal xPosition() const;
+    qreal widthRatio() const;
+    qreal yPosition() const;
+    qreal heightRatio() const;
+
+    void updateVisible();
+
+signals:
+    void xPositionChanged(qreal xPosition);
+    void yPositionChanged(qreal yPosition);
+    void widthRatioChanged(qreal widthRatio);
+    void heightRatioChanged(qreal heightRatio);
+
+private:
+    QQuickFlickable *flickable;
+    qreal m_xPosition;
+    qreal m_widthRatio;
+    qreal m_yPosition;
+    qreal m_heightRatio;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickFlickableVisibleArea)
+
+#endif // QQUICKFLICKABLE_P_P_H
diff --git a/src/declarative/items/qquickflipable.cpp b/src/declarative/items/qquickflipable.cpp
new file mode 100644 (file)
index 0000000..ed89f2a
--- /dev/null
@@ -0,0 +1,308 @@
+/****************************************************************************
+**
+** 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 "qquickflipable_p.h"
+#include "qquickitem_p.h"
+
+#include <private/qdeclarativeguard_p.h>
+
+#include <QtDeclarative/qdeclarativeinfo.h>
+
+QT_BEGIN_NAMESPACE
+
+// XXX todo - i think this needs work and a bit of a re-think
+
+class QQuickLocalTransform : public QQuickTransform
+{
+    Q_OBJECT
+public:
+    QQuickLocalTransform(QObject *parent) : QQuickTransform(parent) {}
+
+    void setTransform(const QTransform &t) {
+        transform = t;
+        update();
+    }
+    virtual void applyTo(QMatrix4x4 *matrix) const {
+        *matrix *= transform;
+    }
+private:
+    QTransform transform;
+};
+
+class QQuickFlipablePrivate : public QQuickItemPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickFlipable)
+public:
+    QQuickFlipablePrivate() : current(QQuickFlipable::Front), front(0), back(0), sideDirty(false) {}
+
+    virtual void transformChanged();
+    void updateSide();
+    void setBackTransform();
+
+    QQuickFlipable::Side current;
+    QDeclarativeGuard<QQuickLocalTransform> backTransform;
+    QDeclarativeGuard<QQuickItem> front;
+    QDeclarativeGuard<QQuickItem> back;
+
+    bool sideDirty;
+    bool wantBackXFlipped;
+    bool wantBackYFlipped;
+};
+
+/*!
+    \qmlclass Flipable QQuickFlipable
+    \inqmlmodule QtQuick 2
+    \ingroup qml-basic-interaction-elements
+    \brief The Flipable item provides a surface that can be flipped.
+    \inherits Item
+
+    Flipable is an item that can be visibly "flipped" between its front and
+    back sides, like a card. It is used together with \l Rotation, \l State
+    and \l Transition elements to produce a flipping effect.
+
+    The \l front and \l back properties are used to hold the items that are
+    shown respectively on the front and back sides of the flipable item.
+
+    \section1 Example Usage
+
+    The following example shows a Flipable item that flips whenever it is
+    clicked, rotating about the y-axis.
+
+    This flipable item has a \c flipped boolean property that is toggled
+    whenever the MouseArea within the flipable is clicked. When
+    \c flipped is true, the item changes to the "back" state; in this
+    state, the \c angle of the \l Rotation item is changed to 180
+    degrees to produce the flipping effect. When \c flipped is false, the
+    item reverts to the default state, in which the \c angle value is 0.
+
+    \snippet doc/src/snippets/declarative/flipable/flipable.qml 0
+
+    \image flipable.gif
+
+    The \l Transition creates the animation that changes the angle over
+    four seconds. When the item changes between its "back" and
+    default states, the NumberAnimation animates the angle between
+    its old and new values.
+
+    See \l {QML States} for details on state changes and the default
+    state, and \l {QML Animation and Transitions} for more information on how
+    animations work within transitions.
+
+    \sa {declarative/ui-components/flipable}{Flipable example}
+*/
+QQuickFlipable::QQuickFlipable(QQuickItem *parent)
+: QQuickItem(*(new QQuickFlipablePrivate), parent)
+{
+}
+
+QQuickFlipable::~QQuickFlipable()
+{
+}
+
+/*!
+  \qmlproperty Item QtQuick2::Flipable::front
+  \qmlproperty Item QtQuick2::Flipable::back
+
+  The front and back sides of the flipable.
+*/
+
+QQuickItem *QQuickFlipable::front()
+{
+    Q_D(const QQuickFlipable);
+    return d->front;
+}
+
+void QQuickFlipable::setFront(QQuickItem *front)
+{
+    Q_D(QQuickFlipable);
+    if (d->front) {
+        qmlInfo(this) << tr("front is a write-once property");
+        return;
+    }
+    d->front = front;
+    d->front->setParentItem(this);
+    if (Back == d->current)
+        d->front->setOpacity(0.);
+    emit frontChanged();
+}
+
+QQuickItem *QQuickFlipable::back()
+{
+    Q_D(const QQuickFlipable);
+    return d->back;
+}
+
+void QQuickFlipable::setBack(QQuickItem *back)
+{
+    Q_D(QQuickFlipable);
+    if (d->back) {
+        qmlInfo(this) << tr("back is a write-once property");
+        return;
+    }
+    if (back == 0)
+        return;
+    d->back = back;
+    d->back->setParentItem(this);
+
+    d->backTransform = new QQuickLocalTransform(d->back);
+    d->backTransform->prependToItem(d->back);
+
+    if (Front == d->current)
+        d->back->setOpacity(0.);
+    connect(back, SIGNAL(widthChanged()),
+            this, SLOT(retransformBack()));
+    connect(back, SIGNAL(heightChanged()),
+            this, SLOT(retransformBack()));
+    emit backChanged();
+}
+
+void QQuickFlipable::retransformBack()
+{
+    Q_D(QQuickFlipable);
+    if (d->current == QQuickFlipable::Back && d->back)
+        d->setBackTransform();
+}
+
+/*!
+  \qmlproperty enumeration QtQuick2::Flipable::side
+
+  The side of the Flipable currently visible. Possible values are \c
+  Flipable.Front and \c Flipable.Back.
+*/
+QQuickFlipable::Side QQuickFlipable::side() const
+{
+    Q_D(const QQuickFlipable);
+
+    const_cast<QQuickFlipablePrivate *>(d)->updateSide();
+    return d->current;
+}
+
+void QQuickFlipablePrivate::transformChanged()
+{
+    Q_Q(QQuickFlipable);
+
+    if (!sideDirty) {
+        sideDirty = true;
+        q->polish();
+    }
+
+    QQuickItemPrivate::transformChanged();
+}
+
+void QQuickFlipable::updatePolish()
+{
+    Q_D(QQuickFlipable);
+    d->updateSide();
+}
+
+// determination on the currently visible side of the flipable
+// has to be done on the complete scene transform to give
+// correct results.
+void QQuickFlipablePrivate::updateSide()
+{
+    Q_Q(QQuickFlipable);
+
+    if (!sideDirty)
+        return;
+
+    sideDirty = false;
+
+    QTransform sceneTransform;
+    itemToParentTransform(sceneTransform);
+
+    QPointF p1(0, 0);
+    QPointF p2(1, 0);
+    QPointF p3(1, 1);
+
+    QPointF scenep1 = sceneTransform.map(p1);
+    QPointF scenep2 = sceneTransform.map(p2);
+    QPointF scenep3 = sceneTransform.map(p3);
+#if 0
+    p1 = q->mapToParent(p1);
+    p2 = q->mapToParent(p2);
+    p3 = q->mapToParent(p3);
+#endif
+
+    qreal cross = (scenep1.x() - scenep2.x()) * (scenep3.y() - scenep2.y()) -
+                  (scenep1.y() - scenep2.y()) * (scenep3.x() - scenep2.x());
+
+    wantBackYFlipped = scenep1.x() >= scenep2.x();
+    wantBackXFlipped = scenep2.y() >= scenep3.y();
+
+    QQuickFlipable::Side newSide;
+    if (cross > 0) {
+        newSide = QQuickFlipable::Back;
+    } else {
+        newSide = QQuickFlipable::Front;
+    }
+
+    if (newSide != current) {
+        current = newSide;
+        if (current == QQuickFlipable::Back && back)
+            setBackTransform();
+        if (front)
+            front->setOpacity((current==QQuickFlipable::Front)?1.:0.);
+        if (back)
+            back->setOpacity((current==QQuickFlipable::Back)?1.:0.);
+        emit q->sideChanged();
+    }
+}
+
+/* Depends on the width/height of the back item, and so needs reevaulating
+   if those change.
+*/
+void QQuickFlipablePrivate::setBackTransform()
+{
+    QTransform mat;
+    mat.translate(back->width()/2,back->height()/2);
+    if (back->width() && wantBackYFlipped)
+        mat.rotate(180, Qt::YAxis);
+    if (back->height() && wantBackXFlipped)
+        mat.rotate(180, Qt::XAxis);
+    mat.translate(-back->width()/2,-back->height()/2);
+
+    if (backTransform)
+        backTransform->setTransform(mat);
+}
+
+QT_END_NAMESPACE
+
+#include "qquickflipable.moc"
diff --git a/src/declarative/items/qquickflipable_p.h b/src/declarative/items/qquickflipable_p.h
new file mode 100644 (file)
index 0000000..698ec0f
--- /dev/null
@@ -0,0 +1,104 @@
+// Commit: ebd4bc73c46c2962742a682b6a391fb68c482aec
+/****************************************************************************
+**
+** 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 QQUICKFLIPABLE_P_H
+#define QQUICKFLIPABLE_P_H
+
+#include "qquickitem.h"
+
+#include <QtGui/qtransform.h>
+#include <QtGui/qvector3d.h>
+#include <QtCore/qobject.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickFlipablePrivate;
+class Q_AUTOTEST_EXPORT QQuickFlipable : public QQuickItem
+{
+    Q_OBJECT
+
+    Q_ENUMS(Side)
+    Q_PROPERTY(QQuickItem *front READ front WRITE setFront NOTIFY frontChanged)
+    Q_PROPERTY(QQuickItem *back READ back WRITE setBack NOTIFY backChanged)
+    Q_PROPERTY(Side side READ side NOTIFY sideChanged)
+    //### flipAxis
+    //### flipRotation
+public:
+    QQuickFlipable(QQuickItem *parent=0);
+    ~QQuickFlipable();
+
+    QQuickItem *front();
+    void setFront(QQuickItem *);
+
+    QQuickItem *back();
+    void setBack(QQuickItem *);
+
+    enum Side { Front, Back };
+    Side side() const;
+
+Q_SIGNALS:
+    void frontChanged();
+    void backChanged();
+    void sideChanged();
+
+protected:
+    virtual void updatePolish();
+
+private Q_SLOTS:
+    void retransformBack();
+
+private:
+    Q_DISABLE_COPY(QQuickFlipable)
+    Q_DECLARE_PRIVATE(QQuickFlipable)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickFlipable)
+
+QT_END_HEADER
+
+#endif // QQUICKFLIPABLE_P_H
diff --git a/src/declarative/items/qquickfocusscope.cpp b/src/declarative/items/qquickfocusscope.cpp
new file mode 100644 (file)
index 0000000..b807fe5
--- /dev/null
@@ -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 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 "qquickfocusscope_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+    \qmlclass FocusScope QQuickFocusScope
+    \inqmlmodule QtQuick 2
+    \ingroup qml-basic-interaction-elements
+
+    \brief The FocusScope object explicitly creates a focus scope.
+    \inherits Item
+
+    Focus scopes assist in keyboard focus handling when building reusable QML
+    components.  All the details are covered in the
+    \l {qmlfocus}{keyboard focus documentation}.
+
+    \sa {declarative/keyinteraction/focus}{Keyboard focus example}
+*/
+QQuickFocusScope::QQuickFocusScope(QQuickItem *parent)
+: QQuickItem(parent)
+{
+    setFlag(ItemIsFocusScope);
+}
+
+QQuickFocusScope::~QQuickFocusScope()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickfocusscope_p.h b/src/declarative/items/qquickfocusscope_p.h
new file mode 100644 (file)
index 0000000..ff1a389
--- /dev/null
@@ -0,0 +1,68 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
+/****************************************************************************
+**
+** 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 QQUICKFOCUSSCOPE_P_H
+#define QQUICKFOCUSSCOPE_P_H
+
+#include "qquickitem.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class Q_AUTOTEST_EXPORT QQuickFocusScope : public QQuickItem
+{
+    Q_OBJECT
+public:
+    QQuickFocusScope(QQuickItem *parent=0);
+    virtual ~QQuickFocusScope();
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickFocusScope)
+
+QT_END_HEADER
+
+#endif // QQUICKFOCUSSCOPE_P_H
diff --git a/src/declarative/items/qquickgridview.cpp b/src/declarative/items/qquickgridview.cpp
new file mode 100644 (file)
index 0000000..a194772
--- /dev/null
@@ -0,0 +1,1930 @@
+/****************************************************************************
+**
+** 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 "qquickgridview_p.h"
+#include "qquickvisualitemmodel_p.h"
+#include "qquickflickable_p_p.h"
+#include "qquickitemview_p_p.h"
+
+#include <private/qdeclarativesmoothedanimation_p_p.h>
+#include <private/qlistmodelinterface_p.h>
+
+#include <QtGui/qevent.h>
+#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
+{
+public:
+    FxGridItemSG(QQuickItem *i, QQuickGridView *v, bool own) : FxViewItem(i, own), view(v) {
+        attached = static_cast<QQuickGridViewAttached*>(qmlAttachedPropertiesObject<QQuickGridView>(item));
+        if (attached)
+            static_cast<QQuickGridViewAttached*>(attached)->setView(view);
+    }
+
+    ~FxGridItemSG() {}
+
+    qreal position() const {
+        return rowPos();
+    }
+
+    qreal endPosition() const {
+        return endRowPos();
+    }
+
+    qreal size() const {
+        return view->flow() == QQuickGridView::LeftToRight ? view->cellHeight() : view->cellWidth();
+    }
+
+    qreal sectionSize() const {
+        return 0.0;
+    }
+
+    qreal rowPos() const {
+        if (view->flow() == QQuickGridView::LeftToRight)
+            return item->y();
+        else
+            return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -view->cellWidth()-item->x() : item->x());
+    }
+
+    qreal colPos() const {
+        if (view->flow() == QQuickGridView::LeftToRight) {
+            if (view->effectiveLayoutDirection() == Qt::RightToLeft) {
+                qreal colSize = view->cellWidth();
+                int columns = view->width()/colSize;
+                return colSize * (columns-1) - item->x();
+            } else {
+                return item->x();
+            }
+        } else {
+            return item->y();
+        }
+    }
+    qreal endRowPos() const {
+        if (view->flow() == QQuickGridView::LeftToRight) {
+            return item->y() + view->cellHeight();
+        } else {
+            if (view->effectiveLayoutDirection() == Qt::RightToLeft)
+                return -item->x();
+            else
+                return item->x() + view->cellWidth();
+        }
+    }
+    void setPosition(qreal col, qreal row) {
+        if (view->effectiveLayoutDirection() == Qt::RightToLeft) {
+            if (view->flow() == QQuickGridView::LeftToRight) {
+                int columns = view->width()/view->cellWidth();
+                item->setPos(QPointF((view->cellWidth() * (columns-1) - col), row));
+            } else {
+                item->setPos(QPointF(-view->cellWidth()-row, col));
+            }
+        } else {
+            if (view->flow() == QQuickGridView::LeftToRight)
+                item->setPos(QPointF(col, row));
+            else
+                item->setPos(QPointF(row, col));
+        }
+    }
+    bool contains(qreal x, qreal y) const {
+        return (x >= item->x() && x < item->x() + view->cellWidth() &&
+                y >= item->y() && y < item->y() + view->cellHeight());
+    }
+
+    QQuickGridView *view;
+};
+
+//----------------------------------------------------------------------------
+
+class QQuickGridViewPrivate : public QQuickItemViewPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickGridView)
+
+public:
+    virtual Qt::Orientation layoutOrientation() const;
+    virtual bool isContentFlowReversed() const;
+    bool isRightToLeftTopToBottom() const;
+
+    virtual qreal positionAt(int index) const;
+    virtual qreal endPositionAt(int index) const;
+    virtual qreal originPosition() const;
+    virtual qreal lastPosition() const;
+
+    qreal rowSize() const;
+    qreal colSize() const;
+    qreal colPosAt(int modelIndex) const;
+    qreal rowPosAt(int modelIndex) const;
+    qreal snapPosAt(qreal pos) const;
+    FxViewItem *snapItemAt(qreal pos) const;
+    int snapIndex() const;
+
+    virtual bool addVisibleItems(qreal fillFrom, qreal fillTo, bool doBuffer);
+    virtual bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo);
+    virtual void visibleItemsChanged();
+
+    virtual FxViewItem *newViewItem(int index, QQuickItem *item);
+    virtual void repositionPackageItemAt(QQuickItem *item, int index);
+    virtual void resetItemPosition(FxViewItem *item, FxViewItem *toItem);
+    virtual void resetFirstItemPosition();
+    virtual void moveItemBy(FxViewItem *item, qreal forwards, qreal backwards);
+
+    virtual void createHighlight();
+    virtual void updateHighlight();
+    virtual void resetHighlightPosition();
+
+    virtual void setPosition(qreal pos);
+    virtual void layoutVisibleItems();
+    bool applyInsertionChange(const QDeclarativeChangeSet::Insert &, FxViewItem *, InsertionsResult *);
+
+    virtual qreal headerSize() const;
+    virtual qreal footerSize() const;
+    virtual bool showHeaderForIndex(int index) const;
+    virtual bool showFooterForIndex(int index) const;
+    virtual void updateHeader();
+    virtual void updateFooter();
+
+    virtual void changedVisibleIndex(int newIndex);
+    virtual void initializeCurrentItem();
+
+    virtual void updateViewport();
+    virtual void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
+    virtual void fixupPosition();
+    virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent);
+    virtual void flick(QQuickItemViewPrivate::AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
+                        QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity);
+
+    QQuickGridView::Flow flow;
+    qreal cellWidth;
+    qreal cellHeight;
+    int columns;
+    QQuickGridView::SnapMode snapMode;
+
+    QSmoothedAnimation *highlightXAnimator;
+    QSmoothedAnimation *highlightYAnimator;
+
+    QQuickGridViewPrivate()
+        : flow(QQuickGridView::LeftToRight)
+        , cellWidth(100), cellHeight(100), columns(1)
+        , snapMode(QQuickGridView::NoSnap)
+        , highlightXAnimator(0), highlightYAnimator(0)
+    {}
+};
+
+Qt::Orientation QQuickGridViewPrivate::layoutOrientation() const
+{
+    return flow == QQuickGridView::LeftToRight ? Qt::Vertical : Qt::Horizontal;
+}
+
+bool QQuickGridViewPrivate::isContentFlowReversed() const
+{
+    return isRightToLeftTopToBottom();
+}
+
+bool QQuickGridViewPrivate::isRightToLeftTopToBottom() const
+{
+    Q_Q(const QQuickGridView);
+    return flow == QQuickGridView::TopToBottom && q->effectiveLayoutDirection() == Qt::RightToLeft;
+}
+
+void QQuickGridViewPrivate::changedVisibleIndex(int newIndex)
+{
+    visibleIndex = newIndex / columns * columns;
+}
+
+void QQuickGridViewPrivate::setPosition(qreal pos)
+{
+    Q_Q(QQuickGridView);
+    if (flow == QQuickGridView::LeftToRight) {
+        q->QQuickFlickable::setContentY(pos);
+        q->QQuickFlickable::setContentX(0);
+    } else {
+        if (q->effectiveLayoutDirection() == Qt::LeftToRight)
+            q->QQuickFlickable::setContentX(pos);
+        else
+            q->QQuickFlickable::setContentX(-pos-size());
+        q->QQuickFlickable::setContentY(0);
+    }
+}
+
+qreal QQuickGridViewPrivate::originPosition() const
+{
+    qreal pos = 0;
+    if (!visibleItems.isEmpty())
+        pos = static_cast<FxGridItemSG*>(visibleItems.first())->rowPos() - visibleIndex / columns * rowSize();
+    return pos;
+}
+
+qreal QQuickGridViewPrivate::lastPosition() const
+{
+    qreal pos = 0;
+    if (model && model->count()) {
+        // get end position of last item
+        pos = (rowPosAt(model->count() - 1) + rowSize());
+    }
+    return pos;
+}
+
+qreal QQuickGridViewPrivate::positionAt(int index) const
+{
+    return rowPosAt(index);
+}
+
+qreal QQuickGridViewPrivate::endPositionAt(int index) const
+{
+    return rowPosAt(index) + rowSize();
+}
+
+qreal QQuickGridViewPrivate::rowSize() const {
+    return flow == QQuickGridView::LeftToRight ? cellHeight : cellWidth;
+}
+qreal QQuickGridViewPrivate::colSize() const {
+    return flow == QQuickGridView::LeftToRight ? cellWidth : cellHeight;
+}
+
+qreal QQuickGridViewPrivate::colPosAt(int modelIndex) const
+{
+    if (FxViewItem *item = visibleItem(modelIndex))
+        return static_cast<FxGridItemSG*>(item)->colPos();
+    if (!visibleItems.isEmpty()) {
+        if (modelIndex < visibleIndex) {
+            int count = (visibleIndex - modelIndex) % columns;
+            int col = static_cast<FxGridItemSG*>(visibleItems.first())->colPos() / colSize();
+            col = (columns - count + col) % columns;
+            return col * colSize();
+        } else {
+            int count = columns - 1 - (modelIndex - visibleItems.last()->index - 1) % columns;
+            return static_cast<FxGridItemSG*>(visibleItems.last())->colPos() - count * colSize();
+        }
+    }
+    return (modelIndex % columns) * colSize();
+}
+
+qreal QQuickGridViewPrivate::rowPosAt(int modelIndex) const
+{
+    if (FxViewItem *item = visibleItem(modelIndex))
+        return static_cast<FxGridItemSG*>(item)->rowPos();
+    if (!visibleItems.isEmpty()) {
+        if (modelIndex < visibleIndex) {
+            FxGridItemSG *firstItem = static_cast<FxGridItemSG*>(visibleItems.first());
+            int firstCol = firstItem->colPos() / colSize();
+            int col = visibleIndex - modelIndex + (columns - firstCol - 1);
+            int rows = col / columns;
+            return firstItem->rowPos() - rows * rowSize();
+        } else {
+            FxGridItemSG *lastItem = static_cast<FxGridItemSG*>(visibleItems.last());
+            int count = modelIndex - lastItem->index;
+            int col = lastItem->colPos() + count * colSize();
+            int rows = col / (columns * colSize());
+            return lastItem->rowPos() + rows * rowSize();
+        }
+    }
+    return (modelIndex / columns) * rowSize();
+}
+
+
+qreal QQuickGridViewPrivate::snapPosAt(qreal pos) const
+{
+    Q_Q(const QQuickGridView);
+    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()) {
+            maxExtent = q->minXExtent();
+            minExtent = q->maxXExtent();
+        } else {
+            maxExtent = flow == QQuickGridView::LeftToRight ? -q->maxYExtent() : -q->maxXExtent();
+            minExtent = flow == QQuickGridView::LeftToRight ? -q->minYExtent() : -q->minXExtent();
+        }
+        if (snapPos > maxExtent)
+            snapPos = maxExtent;
+        if (snapPos < minExtent)
+            snapPos = minExtent;
+    }
+    return snapPos;
+}
+
+FxViewItem *QQuickGridViewPrivate::snapItemAt(qreal pos) const
+{
+    for (int i = 0; i < visibleItems.count(); ++i) {
+        FxViewItem *item = visibleItems.at(i);
+        if (item->index == -1)
+            continue;
+        qreal itemTop = item->position();
+        if (itemTop+rowSize()/2 >= pos && itemTop - rowSize()/2 <= pos)
+            return item;
+    }
+    return 0;
+}
+
+int QQuickGridViewPrivate::snapIndex() const
+{
+    int index = currentIndex;
+    for (int i = 0; i < visibleItems.count(); ++i) {
+        FxGridItemSG *item = static_cast<FxGridItemSG*>(visibleItems.at(i));
+        if (item->index == -1)
+            continue;
+        qreal itemTop = item->position();
+        FxGridItemSG *hItem = static_cast<FxGridItemSG*>(highlight);
+        if (itemTop >= hItem->rowPos()-rowSize()/2 && itemTop < hItem->rowPos()+rowSize()/2) {
+            index = item->index;
+            if (item->colPos() >= hItem->colPos()-colSize()/2 && item->colPos() < hItem->colPos()+colSize()/2)
+                return item->index;
+        }
+    }
+    return index;
+}
+
+FxViewItem *QQuickGridViewPrivate::newViewItem(int modelIndex, QQuickItem *item)
+{
+    Q_Q(QQuickGridView);
+    Q_UNUSED(modelIndex);
+    return new FxGridItemSG(item, q, false);
+}
+
+bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool doBuffer)
+{
+    int colPos = colPosAt(visibleIndex);
+    int rowPos = rowPosAt(visibleIndex);
+    if (visibleItems.count()) {
+        FxGridItemSG *lastItem = static_cast<FxGridItemSG*>(visibleItems.last());
+        rowPos = lastItem->rowPos();
+        colPos = lastItem->colPos() + colSize();
+        if (colPos > colSize() * (columns-1)) {
+            colPos = 0;
+            rowPos += rowSize();
+        }
+    }
+
+    int modelIndex = findLastVisibleIndex();
+    modelIndex = modelIndex < 0 ? visibleIndex : modelIndex + 1;
+
+    if (visibleItems.count() && (fillFrom > rowPos + rowSize()*2
+        || fillTo < rowPosAt(visibleIndex) - rowSize())) {
+        // We've jumped more than a page.  Estimate which items are now
+        // visible and fill from there.
+        int count = (fillFrom - (rowPos + rowSize())) / (rowSize()) * columns;
+        for (int i = 0; i < visibleItems.count(); ++i)
+            releaseItem(visibleItems.at(i));
+        visibleItems.clear();
+        modelIndex += count;
+        if (modelIndex >= model->count())
+            modelIndex = model->count() - 1;
+        else if (modelIndex < 0)
+            modelIndex = 0;
+        modelIndex = modelIndex / columns * columns;
+        visibleIndex = modelIndex;
+        colPos = colPosAt(visibleIndex);
+        rowPos = rowPosAt(visibleIndex);
+    }
+
+    int colNum = colPos / colSize();
+    FxGridItemSG *item = 0;
+    bool changed = false;
+
+    while (modelIndex < model->count() && rowPos <= fillTo + rowSize()*(columns - colNum)/(columns+1)) {
+//        qDebug() << "refill: append item" << modelIndex;
+        if (!(item = static_cast<FxGridItemSG*>(createItem(modelIndex))))
+            break;
+        item->setPosition(colPos, rowPos);
+        visibleItems.append(item);
+        colPos += colSize();
+        colNum++;
+        if (colPos > colSize() * (columns-1)) {
+            colPos = 0;
+            colNum = 0;
+            rowPos += rowSize();
+        }
+        ++modelIndex;
+        changed = true;
+        if (doBuffer) // never buffer more than one item per frame
+            break;
+    }
+
+    if (visibleItems.count()) {
+        FxGridItemSG *firstItem = static_cast<FxGridItemSG*>(visibleItems.first());
+        rowPos = firstItem->rowPos();
+        colPos = firstItem->colPos() - colSize();
+        if (colPos < 0) {
+            colPos = colSize() * (columns - 1);
+            rowPos -= rowSize();
+        }
+    }
+
+    colNum = colPos / colSize();
+    while (visibleIndex > 0 && rowPos + rowSize() - 1 >= fillFrom - rowSize()*(colNum+1)/(columns+1)){
+//        qDebug() << "refill: prepend item" << visibleIndex-1 << "top pos" << rowPos << colPos;
+        if (!(item = static_cast<FxGridItemSG*>(createItem(visibleIndex-1))))
+            break;
+        --visibleIndex;
+        item->setPosition(colPos, rowPos);
+        visibleItems.prepend(item);
+        colPos -= colSize();
+        colNum--;
+        if (colPos < 0) {
+            colPos = colSize() * (columns - 1);
+            colNum = columns-1;
+            rowPos -= rowSize();
+        }
+        changed = true;
+        if (doBuffer) // never buffer more than one item per frame
+            break;
+    }
+
+    return changed;
+}
+
+bool QQuickGridViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal bufferTo)
+{
+    FxGridItemSG *item = 0;
+    bool changed = false;
+
+    while (visibleItems.count() > 1
+           && (item = static_cast<FxGridItemSG*>(visibleItems.first()))
+                && item->rowPos()+rowSize()-1 < bufferFrom - rowSize()*(item->colPos()/colSize()+1)/(columns+1)) {
+        if (item->attached->delayRemove())
+            break;
+//            qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endRowPos();
+        if (item->index != -1)
+            visibleIndex++;
+        visibleItems.removeFirst();
+        releaseItem(item);
+        changed = true;
+    }
+    while (visibleItems.count() > 1
+           && (item = static_cast<FxGridItemSG*>(visibleItems.last()))
+                && item->rowPos() > bufferTo + rowSize()*(columns - item->colPos()/colSize())/(columns+1)) {
+        if (item->attached->delayRemove())
+            break;
+//            qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1;
+        visibleItems.removeLast();
+        releaseItem(item);
+        changed = true;
+    }
+
+    return changed;
+}
+
+void QQuickGridViewPrivate::visibleItemsChanged()
+{
+    updateHeader();
+    updateFooter();
+    updateViewport();
+}
+
+void QQuickGridViewPrivate::updateViewport()
+{
+    Q_Q(QQuickGridView);
+    columns = (int)qMax((flow == QQuickGridView::LeftToRight ? q->width() : q->height()) / colSize(), qreal(1.));
+    QQuickItemViewPrivate::updateViewport();
+}
+
+void QQuickGridViewPrivate::layoutVisibleItems()
+{
+    if (visibleItems.count()) {
+        FxGridItemSG *firstItem = static_cast<FxGridItemSG*>(visibleItems.first());
+        qreal rowPos = firstItem->rowPos();
+        qreal colPos = firstItem->colPos();
+        int col = visibleIndex % columns;
+        if (colPos != col * colSize()) {
+            colPos = col * colSize();
+            firstItem->setPosition(colPos, rowPos);
+        }
+        for (int i = 1; i < visibleItems.count(); ++i) {
+            FxGridItemSG *item = static_cast<FxGridItemSG*>(visibleItems.at(i));
+            colPos += colSize();
+            if (colPos > colSize() * (columns-1)) {
+                colPos = 0;
+                rowPos += rowSize();
+            }
+            item->setPosition(colPos, rowPos);
+        }
+    }
+}
+
+void QQuickGridViewPrivate::repositionPackageItemAt(QQuickItem *item, int index)
+{
+    Q_Q(QQuickGridView);
+    qreal pos = position();
+    if (flow == QQuickGridView::LeftToRight) {
+        if (item->y() + item->height() > pos && item->y() < pos + q->height())
+            item->setPos(QPointF(colPosAt(index), rowPosAt(index)));
+    } else {
+        if (item->x() + item->width() > pos && item->x() < pos + q->width()) {
+            if (isRightToLeftTopToBottom())
+                item->setPos(QPointF(-rowPosAt(index)-item->width(), colPosAt(index)));
+            else
+                item->setPos(QPointF(rowPosAt(index), colPosAt(index)));
+        }
+    }
+}
+
+void QQuickGridViewPrivate::resetItemPosition(FxViewItem *item, FxViewItem *toItem)
+{
+    if (item == toItem)
+        return;
+    FxGridItemSG *toGridItem = static_cast<FxGridItemSG*>(toItem);
+    static_cast<FxGridItemSG*>(item)->setPosition(toGridItem->colPos(), toGridItem->rowPos());
+}
+
+void QQuickGridViewPrivate::resetFirstItemPosition()
+{
+    FxGridItemSG *item = static_cast<FxGridItemSG*>(visibleItems.first());
+    item->setPosition(0, 0);
+}
+
+void QQuickGridViewPrivate::moveItemBy(FxViewItem *item, qreal forwards, qreal backwards)
+{
+    int moveCount = (forwards / rowSize()) - (backwards / rowSize());
+
+    FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(item);
+    gridItem->setPosition(gridItem->colPos(), gridItem->rowPos() + ((moveCount / columns) * rowSize()));
+}
+
+void QQuickGridViewPrivate::createHighlight()
+{
+    Q_Q(QQuickGridView);
+    bool changed = false;
+    if (highlight) {
+        if (trackedItem == highlight)
+            trackedItem = 0;
+        delete highlight;
+        highlight = 0;
+
+        delete highlightXAnimator;
+        delete highlightYAnimator;
+        highlightXAnimator = 0;
+        highlightYAnimator = 0;
+
+        changed = true;
+    }
+
+    if (currentItem) {
+        QQuickItem *item = createHighlightItem();
+        if (item) {
+            FxGridItemSG *newHighlight = new FxGridItemSG(item, q, true);
+            if (autoHighlight)
+                resetHighlightPosition();
+            highlightXAnimator = new QSmoothedAnimation(q);
+            highlightXAnimator->target = QDeclarativeProperty(item, QLatin1String("x"));
+            highlightXAnimator->userDuration = highlightMoveDuration;
+            highlightYAnimator = new QSmoothedAnimation(q);
+            highlightYAnimator->target = QDeclarativeProperty(item, QLatin1String("y"));
+            highlightYAnimator->userDuration = highlightMoveDuration;
+
+            highlight = newHighlight;
+            changed = true;
+        }
+    }
+    if (changed)
+        emit q->highlightItemChanged();
+}
+
+void QQuickGridViewPrivate::updateHighlight()
+{
+    applyPendingChanges();
+
+    if ((!currentItem && highlight) || (currentItem && !highlight))
+        createHighlight();
+    bool strictHighlight = haveHighlightRange && highlightRange == QQuickGridView::StrictlyEnforceRange;
+    if (currentItem && autoHighlight && highlight && (!strictHighlight || !pressed)) {
+        // auto-update highlight
+        highlightXAnimator->to = currentItem->item->x();
+        highlightYAnimator->to = currentItem->item->y();
+        highlight->item->setWidth(currentItem->item->width());
+        highlight->item->setHeight(currentItem->item->height());
+
+        highlightXAnimator->restart();
+        highlightYAnimator->restart();
+    }
+    updateTrackedItem();
+}
+
+void QQuickGridViewPrivate::resetHighlightPosition()
+{
+    if (highlight && currentItem) {
+        FxGridItemSG *cItem = static_cast<FxGridItemSG*>(currentItem);
+        static_cast<FxGridItemSG*>(highlight)->setPosition(cItem->colPos(), cItem->rowPos());
+    }
+}
+
+qreal QQuickGridViewPrivate::headerSize() const
+{
+    if (!header)
+        return 0.0;
+    return flow == QQuickGridView::LeftToRight ? header->item->height() : header->item->width();
+}
+
+qreal QQuickGridViewPrivate::footerSize() const
+{
+    if (!footer)
+        return 0.0;
+    return flow == QQuickGridView::LeftToRight? footer->item->height() : footer->item->width();
+}
+
+bool QQuickGridViewPrivate::showHeaderForIndex(int index) const
+{
+    return index / columns == 0;
+}
+
+bool QQuickGridViewPrivate::showFooterForIndex(int index) const
+{
+    return index / columns == (model->count()-1) / columns;
+}
+
+void QQuickGridViewPrivate::updateFooter()
+{
+    Q_Q(QQuickGridView);
+    bool created = false;
+    if (!footer) {
+        QQuickItem *item = createComponentItem(footerComponent, true);
+        if (!item)
+            return;
+        item->setZ(1);
+        footer = new FxGridItemSG(item, q, true);
+        created = true;
+    }
+
+    FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(footer);
+    qreal colOffset = 0;
+    qreal rowOffset = 0;
+    if (q->effectiveLayoutDirection() == Qt::RightToLeft) {
+        if (flow == QQuickGridView::TopToBottom)
+            rowOffset = gridItem->item->width() - cellWidth;
+        else
+            colOffset = gridItem->item->width() - cellWidth;
+    }
+    if (visibleItems.count()) {
+        qreal endPos = lastPosition();
+        if (findLastVisibleIndex() == model->count()-1) {
+            gridItem->setPosition(colOffset, endPos + rowOffset);
+        } else {
+            qreal visiblePos = isRightToLeftTopToBottom() ? -position() : position() + size();
+            if (endPos <= visiblePos || gridItem->endPosition() <= endPos + rowOffset)
+                gridItem->setPosition(colOffset, endPos + rowOffset);
+        }
+    } else {
+        gridItem->setPosition(colOffset, rowOffset);
+    }
+
+    if (created)
+        emit q->footerItemChanged();
+}
+
+void QQuickGridViewPrivate::updateHeader()
+{
+    Q_Q(QQuickGridView);
+    bool created = false;
+    if (!header) {
+        QQuickItem *item = createComponentItem(headerComponent, true);
+        if (!item)
+            return;
+        item->setZ(1);
+        header = new FxGridItemSG(item, q, true);
+        created = true;
+    }
+
+    FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(header);
+    qreal colOffset = 0;
+    qreal rowOffset = -headerSize();
+    if (q->effectiveLayoutDirection() == Qt::RightToLeft) {
+        if (flow == QQuickGridView::TopToBottom)
+            rowOffset += gridItem->item->width()-cellWidth;
+        else
+            colOffset = gridItem->item->width()-cellWidth;
+    }
+    if (visibleItems.count()) {
+        qreal startPos = originPosition();
+        if (visibleIndex == 0) {
+            gridItem->setPosition(colOffset, startPos + rowOffset);
+        } else {
+            qreal tempPos = isRightToLeftTopToBottom() ? -position()-size() : position();
+            qreal headerPos = isRightToLeftTopToBottom() ? gridItem->rowPos() + cellWidth - headerSize() : gridItem->rowPos();
+            if (tempPos <= startPos || headerPos > startPos + rowOffset)
+                gridItem->setPosition(colOffset, startPos + rowOffset);
+        }
+    } else {
+        if (isRightToLeftTopToBottom())
+            gridItem->setPosition(colOffset, rowOffset);
+        else
+            gridItem->setPosition(colOffset, -headerSize());
+    }
+
+    if (created)
+        emit q->headerItemChanged();
+}
+
+void QQuickGridViewPrivate::initializeCurrentItem()
+{
+    if (currentItem && currentIndex >= 0) {
+        FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(currentItem);
+        if (gridItem)
+            gridItem->setPosition(colPosAt(currentIndex), rowPosAt(currentIndex));
+    }
+}
+
+void QQuickGridViewPrivate::itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+    Q_Q(QQuickGridView);
+    QQuickItemViewPrivate::itemGeometryChanged(item, newGeometry, oldGeometry);
+    if (!q->isComponentComplete())
+        return;
+    if (item == q) {
+        if (newGeometry.height() != oldGeometry.height() || newGeometry.width() != oldGeometry.width()) {
+            updateViewport();
+            forceLayout = true;
+            q->polish();
+        }
+    }
+}
+
+void QQuickGridViewPrivate::fixupPosition()
+{
+    moveReason = Other;
+    if (flow == QQuickGridView::LeftToRight)
+        fixupY();
+    else
+        fixupX();
+}
+
+void QQuickGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
+{
+    if ((flow == QQuickGridView::TopToBottom && &data == &vData)
+        || (flow == QQuickGridView::LeftToRight && &data == &hData))
+        return;
+
+    fixupMode = moveReason == Mouse ? fixupMode : Immediate;
+
+    qreal viewPos = isRightToLeftTopToBottom() ? -position()-size() : position();
+
+    bool strictHighlightRange = haveHighlightRange && highlightRange == QQuickGridView::StrictlyEnforceRange;
+    if (snapMode != QQuickGridView::NoSnap) {
+        qreal tempPosition = isRightToLeftTopToBottom() ? -position()-size() : position();
+        if (snapMode == QQuickGridView::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;
+        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() + highlightRangeStart - size(), -maxExtent), -minExtent);
+                else
+                    pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent);
+            }
+        } else if (bottomItem && isInBounds) {
+            if (isRightToLeftTopToBottom())
+                pos = qMax(qMin(-bottomItem->position() + highlightRangeEnd - size(), -maxExtent), -minExtent);
+            else
+                pos = qMax(qMin(bottomItem->position() - highlightRangeEnd, -maxExtent), -minExtent);
+        } else {
+            QQuickItemViewPrivate::fixup(data, minExtent, maxExtent);
+            return;
+        }
+
+        qreal dist = qAbs(data.move + pos);
+        if (dist > 0) {
+            timeline.reset(data.move);
+            if (fixupMode != Immediate) {
+                timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
+                data.fixingUp = true;
+            } else {
+                timeline.set(data.move, -pos);
+            }
+            vTime = timeline.time();
+        }
+    } else if (haveHighlightRange && highlightRange == QQuickGridView::StrictlyEnforceRange) {
+        if (currentItem) {
+            updateHighlight();
+            qreal pos = static_cast<FxGridItemSG*>(currentItem)->rowPos();
+            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);
+            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 {
+        QQuickItemViewPrivate::fixup(data, minExtent, maxExtent);
+    }
+    data.inOvershoot = false;
+    fixupMode = Normal;
+}
+
+void QQuickGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
+                                        QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity)
+{
+    Q_Q(QQuickGridView);
+    data.fixingUp = false;
+    moveReason = Mouse;
+    if ((!haveHighlightRange || highlightRange != QQuickGridView::StrictlyEnforceRange)
+        && snapMode == QQuickGridView::NoSnap) {
+        QQuickItemViewPrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, velocity);
+        return;
+    }
+    qreal maxDistance = 0;
+    qreal dataValue = isRightToLeftTopToBottom() ? -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 == QQuickGridView::SnapOneRow) {
+                // 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());
+            }
+        }
+        if (snapMode == QQuickGridView::NoSnap && highlightRange != QQuickGridView::StrictlyEnforceRange)
+            data.flickTarget = minExtent;
+    } else {
+        if (data.move.value() > maxExtent) {
+            if (snapMode == QQuickGridView::SnapOneRow) {
+                // 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());
+            }
+        }
+        if (snapMode == QQuickGridView::NoSnap && highlightRange != QQuickGridView::StrictlyEnforceRange)
+            data.flickTarget = maxExtent;
+    }
+    bool overShoot = boundsBehavior == QQuickFlickable::DragAndOvershootBounds;
+    if (maxDistance > 0 || overShoot) {
+        // This mode requires the grid to stop exactly on a row boundary.
+        qreal v = velocity;
+        if (maxVelocity != -1 && maxVelocity < qAbs(v)) {
+            if (v < 0)
+                v = -maxVelocity;
+            else
+                v = maxVelocity;
+        }
+        qreal accel = deceleration;
+        qreal v2 = v * v;
+        qreal overshootDist = 0.0;
+        if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QQuickGridView::SnapOneRow) {
+            // + rowSize()/4 to encourage moving at least one item in the flick direction
+            qreal dist = v2 / (accel * 2.0) + rowSize()/4;
+            dist = qMin(dist, maxDistance);
+            if (v > 0)
+                dist = -dist;
+            if (snapMode != QQuickGridView::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
+                qreal adjv2 = accel * 2.0f * qAbs(adjDist);
+                if (adjv2 > v2) {
+                    v2 = adjv2;
+                    v = qSqrt(v2);
+                    if (dist > 0)
+                        v = -v;
+                }
+            }
+            dist = adjDist;
+            accel = v2 / (2.0f * qAbs(dist));
+        } else {
+            data.flickTarget = velocity > 0 ? minExtent : maxExtent;
+            overshootDist = overShoot ? overShootDistance(vSize) : 0;
+        }
+        timeline.reset(data.move);
+        timeline.accel(data.move, v, accel, maxDistance + overshootDist);
+        timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this));
+        if (!hData.flicking && q->xflick()) {
+            hData.flicking = true;
+            emit q->flickingChanged();
+            emit q->flickingHorizontallyChanged();
+            emit q->flickStarted();
+        }
+        if (!vData.flicking && q->yflick()) {
+            vData.flicking = true;
+            emit q->flickingChanged();
+            emit q->flickingVerticallyChanged();
+            emit q->flickStarted();
+        }
+    } else {
+        timeline.reset(data.move);
+        fixup(data, minExtent, maxExtent);
+    }
+}
+
+
+//----------------------------------------------------------------------------
+/*!
+    \qmlclass GridView QQuickGridView
+    \inqmlmodule QtQuick 2
+    \ingroup qml-view-elements
+
+    \inherits Flickable
+    \brief The GridView item provides a grid view of items provided by a model.
+
+    A GridView displays data from models created from built-in QML elements like ListModel
+    and XmlListModel, or custom model classes defined in C++ that inherit from
+    QAbstractListModel.
+
+    A GridView has a \l model, which defines the data to be displayed, and
+    a \l delegate, which defines how the data should be displayed. Items in a
+    GridView are laid out horizontally or vertically. Grid views are inherently flickable
+    as GridView inherits from \l Flickable.
+
+    \section1 Example Usage
+
+    The following example shows the definition of a simple list model defined
+    in a file called \c ContactModel.qml:
+
+    \snippet doc/src/snippets/declarative/gridview/ContactModel.qml 0
+
+    \div {class="float-right"}
+    \inlineimage gridview-simple.png
+    \enddiv
+
+    This model can be referenced as \c ContactModel in other QML files. See \l{QML Modules}
+    for more information about creating reusable components like this.
+
+    Another component can display this model data in a GridView, as in the following
+    example, which creates a \c ContactModel component for its model, and a \l Column element
+    (containing \l Image and \l Text elements) for its delegate.
+
+    \clearfloat
+    \snippet doc/src/snippets/declarative/gridview/gridview.qml import
+    \codeline
+    \snippet doc/src/snippets/declarative/gridview/gridview.qml classdocs simple
+
+    \div {class="float-right"}
+    \inlineimage gridview-highlight.png
+    \enddiv
+
+    The view will create a new delegate for each item in the model. Note that the delegate
+    is able to access the model's \c name and \c portrait data directly.
+
+    An improved grid view is shown below. The delegate is visually improved and is moved
+    into a separate \c contactDelegate component.
+
+    \clearfloat
+    \snippet doc/src/snippets/declarative/gridview/gridview.qml classdocs advanced
+
+    The currently selected item is highlighted with a blue \l Rectangle using the \l highlight property,
+    and \c focus is set to \c true to enable keyboard navigation for the grid view.
+    The grid view itself is a focus scope (see \l{qmlfocus#Acquiring Focus and Focus Scopes}{the focus documentation page} for more details).
+
+    Delegates are instantiated as needed and may be destroyed at any time.
+    State should \e never be stored in a delegate.
+
+    GridView attaches a number of properties to the root item of the delegate, for example
+    \c {GridView.isCurrentItem}.  In the following example, the root delegate item can access
+    this attached property directly as \c GridView.isCurrentItem, while the child
+    \c contactInfo object must refer to this property as \c wrapper.GridView.isCurrentItem.
+
+    \snippet doc/src/snippets/declarative/gridview/gridview.qml isCurrentItem
+
+    \note Views do not set the \l{Item::}{clip} property automatically.
+    If the view is not clipped by another item or the screen, it will be necessary
+    to set this property to true in order to clip the items that are partially or
+    fully outside the view.
+
+    \sa {declarative/modelviews/gridview}{GridView example}
+*/
+
+QQuickGridView::QQuickGridView(QQuickItem *parent)
+    : QQuickItemView(*(new QQuickGridViewPrivate), parent)
+{
+}
+
+QQuickGridView::~QQuickGridView()
+{
+}
+
+void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight)
+{
+    Q_D(QQuickGridView);
+    if (d->autoHighlight != autoHighlight) {
+        if (!autoHighlight && d->highlightXAnimator) {
+            d->highlightXAnimator->stop();
+            d->highlightYAnimator->stop();
+        }
+        QQuickItemView::setHighlightFollowsCurrentItem(autoHighlight);
+    }
+}
+
+/*!
+    \qmlattachedproperty bool QtQuick2::GridView::isCurrentItem
+    This attached property is true if this delegate is the current item; otherwise false.
+
+    It is attached to each instance of the delegate.
+*/
+
+/*!
+    \qmlattachedproperty GridView QtQuick2::GridView::view
+    This attached property holds the view that manages this delegate instance.
+
+    It is attached to each instance of the delegate.
+
+    \snippet doc/src/snippets/declarative/gridview/gridview.qml isCurrentItem
+*/
+
+/*!
+    \qmlattachedproperty bool QtQuick2::GridView::delayRemove
+    This attached property holds whether the delegate may be destroyed.
+
+    It is attached to each instance of the delegate.
+
+    It is sometimes necessary to delay the destruction of an item
+    until an animation completes.
+
+    The example below ensures that the animation completes before
+    the item is removed from the grid.
+
+    \snippet doc/src/snippets/declarative/gridview/gridview.qml delayRemove
+*/
+
+/*!
+    \qmlattachedsignal QtQuick2::GridView::onAdd()
+    This attached handler is called immediately after an item is added to the view.
+*/
+
+/*!
+    \qmlattachedsignal QtQuick2::GridView::onRemove()
+    This attached handler is called immediately before an item is removed from the view.
+*/
+
+
+/*!
+  \qmlproperty model QtQuick2::GridView::model
+  This property holds the model providing data for the grid.
+
+    The model provides the set of data that is used to create the items
+    in the view. Models can be created directly in QML using \l ListModel, \l XmlListModel
+    or \l VisualItemModel, or provided by C++ model classes. If a C++ model class is
+    used, it must be a subclass of \l QAbstractItemModel or a simple list.
+
+  \sa {qmlmodels}{Data Models}
+*/
+
+/*!
+    \qmlproperty Component QtQuick2::GridView::delegate
+
+    The delegate provides a template defining each item instantiated by the view.
+    The index is exposed as an accessible \c index property.  Properties of the
+    model are also available depending upon the type of \l {qmlmodels}{Data Model}.
+
+    The number of elements in the delegate has a direct effect on the
+    flicking performance of the view.  If at all possible, place functionality
+    that is not needed for the normal display of the delegate in a \l Loader which
+    can load additional elements when needed.
+
+    The GridView will layout the items based on the size of the root item
+    in the delegate.
+
+    \note Delegates are instantiated as needed and may be destroyed at any time.
+    State should \e never be stored in a delegate.
+*/
+
+/*!
+  \qmlproperty int QtQuick2::GridView::currentIndex
+  \qmlproperty Item QtQuick2::GridView::currentItem
+
+    The \c currentIndex property holds the index of the current item, and
+    \c currentItem holds the current item.  Setting the currentIndex to -1
+    will clear the highlight and set currentItem to null.
+
+    If highlightFollowsCurrentItem is \c true, setting either of these
+    properties will smoothly scroll the GridView so that the current
+    item becomes visible.
+
+    Note that the position of the current item
+    may only be approximate until it becomes visible in the view.
+*/
+
+
+/*!
+  \qmlproperty Item QtQuick2::GridView::highlightItem
+
+  This holds the highlight item created from the \l highlight component.
+
+  The highlightItem is managed by the view unless
+  \l highlightFollowsCurrentItem is set to false.
+
+  \sa highlight, highlightFollowsCurrentItem
+*/
+
+
+/*!
+  \qmlproperty int QtQuick2::GridView::count
+  This property holds the number of items in the view.
+*/
+
+
+/*!
+  \qmlproperty Component QtQuick2::GridView::highlight
+  This property holds the component to use as the highlight.
+
+  An instance of the highlight component is created for each view.
+  The geometry of the resulting component instance will be managed by the view
+  so as to stay with the current item, unless the highlightFollowsCurrentItem property is false.
+
+  \sa highlightItem, highlightFollowsCurrentItem
+*/
+
+/*!
+  \qmlproperty bool QtQuick2::GridView::highlightFollowsCurrentItem
+  This property sets whether the highlight is managed by the view.
+
+    If this property is true (the default value), the highlight is moved smoothly
+    to follow the current item.  Otherwise, the
+    highlight is not moved by the view, and any movement must be implemented
+    by the highlight.
+
+    Here is a highlight with its motion defined by a \l {SpringAnimation} item:
+
+    \snippet doc/src/snippets/declarative/gridview/gridview.qml highlightFollowsCurrentItem
+*/
+
+
+/*!
+    \qmlproperty int QtQuick2::GridView::highlightMoveDuration
+    This property holds the move animation duration of the highlight delegate.
+
+    highlightFollowsCurrentItem must be true for this property
+    to have effect.
+
+    The default value for the duration is 150ms.
+
+    \sa highlightFollowsCurrentItem
+*/
+
+/*!
+    \qmlproperty real QtQuick2::GridView::preferredHighlightBegin
+    \qmlproperty real QtQuick2::GridView::preferredHighlightEnd
+    \qmlproperty enumeration QtQuick2::GridView::highlightRangeMode
+
+    These properties define the preferred range of the highlight (for the current item)
+    within the view. The \c preferredHighlightBegin value must be less than the
+    \c preferredHighlightEnd value.
+
+    These properties affect the position of the current item when the view is scrolled.
+    For example, if the currently selected item should stay in the middle of the
+    view when it is scrolled, set the \c preferredHighlightBegin and
+    \c preferredHighlightEnd values to the top and bottom coordinates of where the middle
+    item would be. If the \c currentItem is changed programmatically, the view will
+    automatically scroll so that the current item is in the middle of the view.
+    Furthermore, the behavior of the current item index will occur whether or not a
+    highlight exists.
+
+    Valid values for \c highlightRangeMode are:
+
+    \list
+    \o GridView.ApplyRange - the view attempts to maintain the highlight within the range.
+       However, the highlight can move outside of the range at the ends of the view or due
+       to mouse interaction.
+    \o GridView.StrictlyEnforceRange - the highlight never moves outside of the range.
+       The current item changes if a keyboard or mouse action would cause the highlight to move
+       outside of the range.
+    \o GridView.NoHighlightRange - this is the default value.
+    \endlist
+*/
+
+
+/*!
+  \qmlproperty enumeration QtQuick2::GridView::layoutDirection
+  This property holds the layout direction of the grid.
+
+    Possible values:
+
+  \list
+  \o Qt.LeftToRight (default) - Items will be laid out starting in the top, left corner. The flow is
+  dependent on the \l GridView::flow property.
+  \o Qt.RightToLeft - Items will be laid out starting in the top, right corner. The flow is dependent
+  on the \l GridView::flow property.
+  \endlist
+
+  \bold Note: If GridView::flow is set to GridView.LeftToRight, this is not to be confused if
+  GridView::layoutDirection is set to Qt.RightToLeft. The GridView.LeftToRight flow value simply
+  indicates that the flow is horizontal.
+*/
+
+
+/*!
+    \qmlproperty enumeration QtQuick2::GridView::effectiveLayoutDirection
+    This property holds the effective layout direction of the grid.
+
+    When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} for locale layouts,
+    the visual layout direction of the grid will be mirrored. However, the
+    property \l {GridView::layoutDirection}{layoutDirection} will remain unchanged.
+
+    \sa GridView::layoutDirection, {LayoutMirroring}{LayoutMirroring}
+*/
+/*!
+  \qmlproperty bool QtQuick2::GridView::keyNavigationWraps
+  This property holds whether the grid wraps key navigation
+
+    If this is true, key navigation that would move the current item selection
+    past one end of the view instead wraps around and moves the selection to
+    the other end of the view.
+
+    By default, key navigation is not wrapped.
+*/
+/*!
+    \qmlproperty int QtQuick2::GridView::cacheBuffer
+    This property determines whether delegates are retained outside the
+    visible area of the view.
+
+    If non-zero the view will keep as many delegates
+    instantiated as will fit within the buffer specified.  For example,
+    if in a vertical view the delegate is 20 pixels high and \c cacheBuffer is
+    set to 40, then up to 2 delegates above and 2 delegates below the visible
+    area may be retained.
+
+    Note that cacheBuffer is not a pixel buffer - it only maintains additional
+    instantiated delegates.
+
+    Setting this value can make scrolling the list smoother at the expense
+    of additional memory usage.  It is not a substitute for creating efficient
+    delegates; the fewer elements in a delegate, the faster a view may be
+    scrolled.
+*/
+void QQuickGridView::setHighlightMoveDuration(int duration)
+{
+    Q_D(QQuickGridView);
+    if (d->highlightMoveDuration != duration) {
+        if (d->highlightYAnimator) {
+            d->highlightXAnimator->userDuration = duration;
+            d->highlightYAnimator->userDuration = duration;
+        }
+        QQuickItemView::setHighlightMoveDuration(duration);
+    }
+}
+
+/*!
+  \qmlproperty enumeration QtQuick2::GridView::flow
+  This property holds the flow of the grid.
+
+    Possible values:
+
+    \list
+    \o GridView.LeftToRight (default) - Items are laid out from left to right, and the view scrolls vertically
+    \o GridView.TopToBottom - Items are laid out from top to bottom, and the view scrolls horizontally
+    \endlist
+*/
+QQuickGridView::Flow QQuickGridView::flow() const
+{
+    Q_D(const QQuickGridView);
+    return d->flow;
+}
+
+void QQuickGridView::setFlow(Flow flow)
+{
+    Q_D(QQuickGridView);
+    if (d->flow != flow) {
+        d->flow = flow;
+        if (d->flow == LeftToRight) {
+            setContentWidth(-1);
+            setFlickableDirection(VerticalFlick);
+        } else {
+            setContentHeight(-1);
+            setFlickableDirection(HorizontalFlick);
+        }
+        setContentX(0);
+        setContentY(0);
+        d->regenerate();
+        emit flowChanged();
+    }
+}
+
+
+/*!
+  \qmlproperty real QtQuick2::GridView::cellWidth
+  \qmlproperty real QtQuick2::GridView::cellHeight
+
+  These properties holds the width and height of each cell in the grid.
+
+  The default cell size is 100x100.
+*/
+qreal QQuickGridView::cellWidth() const
+{
+    Q_D(const QQuickGridView);
+    return d->cellWidth;
+}
+
+void QQuickGridView::setCellWidth(qreal cellWidth)
+{
+    Q_D(QQuickGridView);
+    if (cellWidth != d->cellWidth && cellWidth > 0) {
+        d->cellWidth = qMax(qreal(1), cellWidth);
+        d->updateViewport();
+        emit cellWidthChanged();
+        d->forceLayout = true;
+        d->layout();
+    }
+}
+
+qreal QQuickGridView::cellHeight() const
+{
+    Q_D(const QQuickGridView);
+    return d->cellHeight;
+}
+
+void QQuickGridView::setCellHeight(qreal cellHeight)
+{
+    Q_D(QQuickGridView);
+    if (cellHeight != d->cellHeight && cellHeight > 0) {
+        d->cellHeight = qMax(qreal(1), cellHeight);
+        d->updateViewport();
+        emit cellHeightChanged();
+        d->forceLayout = true;
+        d->layout();
+    }
+}
+/*!
+    \qmlproperty enumeration QtQuick2::GridView::snapMode
+
+    This property determines how the view scrolling will settle following a drag or flick.
+    The possible values are:
+
+    \list
+    \o GridView.NoSnap (default) - the view stops anywhere within the visible area.
+    \o GridView.SnapToRow - the view settles with a row (or column for \c GridView.TopToBottom flow)
+    aligned with the start of the view.
+    \o GridView.SnapOneRow - the view will settle no more than one row (or column for \c GridView.TopToBottom flow)
+    away from the first visible row at the time the mouse button is released.
+    This mode is particularly useful for moving one page at a time.
+    \endlist
+
+*/
+QQuickGridView::SnapMode QQuickGridView::snapMode() const
+{
+    Q_D(const QQuickGridView);
+    return d->snapMode;
+}
+
+void QQuickGridView::setSnapMode(SnapMode mode)
+{
+    Q_D(QQuickGridView);
+    if (d->snapMode != mode) {
+        d->snapMode = mode;
+        emit snapModeChanged();
+    }
+}
+
+
+/*!
+    \qmlproperty Component QtQuick2::GridView::footer
+    This property holds the component to use as the footer.
+
+    An instance of the footer component is created for each view.  The
+    footer is positioned at the end of the view, after any items.
+
+    \sa header
+*/
+/*!
+    \qmlproperty Component QtQuick2::GridView::header
+    This property holds the component to use as the header.
+
+    An instance of the header component is created for each view.  The
+    header is positioned at the beginning of the view, before any items.
+
+    \sa footer
+*/
+void QQuickGridView::viewportMoved()
+{
+    Q_D(QQuickGridView);
+    QQuickItemView::viewportMoved();
+    if (!d->itemCount)
+        return;
+    if (d->inViewportMoved)
+        return;
+    d->inViewportMoved = true;
+
+    d->lazyRelease = true;
+    if (d->hData.flicking || d->vData.flicking) {
+        if (yflick()) {
+            if (d->vData.velocity > 0)
+                d->bufferMode = QQuickGridViewPrivate::BufferBefore;
+            else if (d->vData.velocity < 0)
+                d->bufferMode = QQuickGridViewPrivate::BufferAfter;
+        }
+
+        if (xflick()) {
+            if (d->hData.velocity > 0)
+                d->bufferMode = QQuickGridViewPrivate::BufferBefore;
+            else if (d->hData.velocity < 0)
+                d->bufferMode = QQuickGridViewPrivate::BufferAfter;
+        }
+    }
+    d->refill();
+    if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving)
+        d->moveReason = QQuickGridViewPrivate::Mouse;
+    if (d->moveReason != QQuickGridViewPrivate::SetIndex) {
+        if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) {
+            // reposition highlight
+            qreal pos = d->highlight->position();
+            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();
+                d->highlightYAnimator->stop();
+                static_cast<FxGridItemSG*>(d->highlight)->setPosition(static_cast<FxGridItemSG*>(d->highlight)->colPos(), pos);
+            } else {
+                d->updateHighlight();
+            }
+
+            // update current index
+            int idx = d->snapIndex();
+            if (idx >= 0 && idx != d->currentIndex) {
+                d->updateCurrent(idx);
+                if (d->currentItem && static_cast<FxGridItemSG*>(d->currentItem)->colPos() != static_cast<FxGridItemSG*>(d->highlight)->colPos() && d->autoHighlight) {
+                    if (d->flow == LeftToRight)
+                        d->highlightXAnimator->to = d->currentItem->item->x();
+                    else
+                        d->highlightYAnimator->to = d->currentItem->item->y();
+                }
+            }
+        }
+    }
+
+    d->inViewportMoved = false;
+}
+
+void QQuickGridView::keyPressEvent(QKeyEvent *event)
+{
+    Q_D(QQuickGridView);
+    if (d->model && d->model->count() && d->interactive) {
+        d->moveReason = QQuickGridViewPrivate::SetIndex;
+        int oldCurrent = currentIndex();
+        switch (event->key()) {
+        case Qt::Key_Up:
+            moveCurrentIndexUp();
+            break;
+        case Qt::Key_Down:
+            moveCurrentIndexDown();
+            break;
+        case Qt::Key_Left:
+            moveCurrentIndexLeft();
+            break;
+        case Qt::Key_Right:
+            moveCurrentIndexRight();
+            break;
+        default:
+            break;
+        }
+        if (oldCurrent != currentIndex()) {
+            event->accept();
+            return;
+        }
+    }
+    event->ignore();
+    QQuickItemView::keyPressEvent(event);
+}
+/*!
+    \qmlmethod QtQuick2::GridView::moveCurrentIndexUp()
+
+    Move the currentIndex up one item in the view.
+    The current index will wrap if keyNavigationWraps is true and it
+    is currently at the end. This method has no effect if the \l count is zero.
+
+    \bold Note: methods should only be called after the Component has completed.
+*/
+
+
+void QQuickGridView::moveCurrentIndexUp()
+{
+    Q_D(QQuickGridView);
+    const int count = d->model ? d->model->count() : 0;
+    if (!count)
+        return;
+    if (d->flow == QQuickGridView::LeftToRight) {
+        if (currentIndex() >= d->columns || d->wrap) {
+            int index = currentIndex() - d->columns;
+            setCurrentIndex((index >= 0 && index < count) ? index : count-1);
+        }
+    } else {
+        if (currentIndex() > 0 || d->wrap) {
+            int index = currentIndex() - 1;
+            setCurrentIndex((index >= 0 && index < count) ? index : count-1);
+        }
+    }
+}
+
+/*!
+    \qmlmethod QtQuick2::GridView::moveCurrentIndexDown()
+
+    Move the currentIndex down one item in the view.
+    The current index will wrap if keyNavigationWraps is true and it
+    is currently at the end. This method has no effect if the \l count is zero.
+
+    \bold Note: methods should only be called after the Component has completed.
+*/
+void QQuickGridView::moveCurrentIndexDown()
+{
+    Q_D(QQuickGridView);
+    const int count = d->model ? d->model->count() : 0;
+    if (!count)
+        return;
+    if (d->flow == QQuickGridView::LeftToRight) {
+        if (currentIndex() < count - d->columns || d->wrap) {
+            int index = currentIndex()+d->columns;
+            setCurrentIndex((index >= 0 && index < count) ? index : 0);
+        }
+    } else {
+        if (currentIndex() < count - 1 || d->wrap) {
+            int index = currentIndex() + 1;
+            setCurrentIndex((index >= 0 && index < count) ? index : 0);
+        }
+    }
+}
+
+/*!
+    \qmlmethod QtQuick2::GridView::moveCurrentIndexLeft()
+
+    Move the currentIndex left one item in the view.
+    The current index will wrap if keyNavigationWraps is true and it
+    is currently at the end. This method has no effect if the \l count is zero.
+
+    \bold Note: methods should only be called after the Component has completed.
+*/
+void QQuickGridView::moveCurrentIndexLeft()
+{
+    Q_D(QQuickGridView);
+    const int count = d->model ? d->model->count() : 0;
+    if (!count)
+        return;
+    if (effectiveLayoutDirection() == Qt::LeftToRight) {
+        if (d->flow == QQuickGridView::LeftToRight) {
+            if (currentIndex() > 0 || d->wrap) {
+                int index = currentIndex() - 1;
+                setCurrentIndex((index >= 0 && index < count) ? index : count-1);
+            }
+        } else {
+            if (currentIndex() >= d->columns || d->wrap) {
+                int index = currentIndex() - d->columns;
+                setCurrentIndex((index >= 0 && index < count) ? index : count-1);
+            }
+        }
+    } else {
+        if (d->flow == QQuickGridView::LeftToRight) {
+            if (currentIndex() < count - 1 || d->wrap) {
+                int index = currentIndex() + 1;
+                setCurrentIndex((index >= 0 && index < count) ? index : 0);
+            }
+        } else {
+            if (currentIndex() < count - d->columns || d->wrap) {
+                int index = currentIndex() + d->columns;
+                setCurrentIndex((index >= 0 && index < count) ? index : 0);
+            }
+        }
+    }
+}
+
+
+/*!
+    \qmlmethod QtQuick2::GridView::moveCurrentIndexRight()
+
+    Move the currentIndex right one item in the view.
+    The current index will wrap if keyNavigationWraps is true and it
+    is currently at the end. This method has no effect if the \l count is zero.
+
+    \bold Note: methods should only be called after the Component has completed.
+*/
+void QQuickGridView::moveCurrentIndexRight()
+{
+    Q_D(QQuickGridView);
+    const int count = d->model ? d->model->count() : 0;
+    if (!count)
+        return;
+    if (effectiveLayoutDirection() == Qt::LeftToRight) {
+        if (d->flow == QQuickGridView::LeftToRight) {
+            if (currentIndex() < count - 1 || d->wrap) {
+                int index = currentIndex() + 1;
+                setCurrentIndex((index >= 0 && index < count) ? index : 0);
+            }
+        } else {
+            if (currentIndex() < count - d->columns || d->wrap) {
+                int index = currentIndex()+d->columns;
+                setCurrentIndex((index >= 0 && index < count) ? index : 0);
+            }
+        }
+    } else {
+        if (d->flow == QQuickGridView::LeftToRight) {
+            if (currentIndex() > 0 || d->wrap) {
+                int index = currentIndex() - 1;
+                setCurrentIndex((index >= 0 && index < count) ? index : count-1);
+            }
+        } else {
+            if (currentIndex() >= d->columns || d->wrap) {
+                int index = currentIndex() - d->columns;
+                setCurrentIndex((index >= 0 && index < count) ? index : count-1);
+            }
+        }
+    }
+}
+
+bool QQuickGridViewPrivate::applyInsertionChange(const QDeclarativeChangeSet::Insert &change, FxViewItem *firstVisible, InsertionsResult *insertResult)
+{
+    Q_Q(QQuickGridView);
+
+    int modelIndex = change.index;
+    int count = change.count;
+
+    int index = visibleItems.count() ? mapFromModel(modelIndex) : 0;
+
+    if (index < 0) {
+        int i = visibleItems.count() - 1;
+        while (i > 0 && visibleItems.at(i)->index == -1)
+            --i;
+        if (visibleItems.at(i)->index + 1 == modelIndex) {
+            // Special case of appending an item to the model.
+            index = visibleItems.count();
+        } else {
+            if (modelIndex <= visibleIndex) {
+                // Insert before visible items
+                visibleIndex += count;
+                for (int i = 0; i < visibleItems.count(); ++i) {
+                    FxViewItem *item = visibleItems.at(i);
+                    if (item->index != -1 && item->index >= modelIndex)
+                        item->index += count;
+                }
+            }
+            return true;
+        }
+    }
+
+    qreal tempPos = isRightToLeftTopToBottom() ? -position()-size()+q->width()+1 : position();
+    int colPos = 0;
+    int rowPos = 0;
+    if (visibleItems.count()) {
+        if (index < visibleItems.count()) {
+            FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(visibleItems.at(index));
+            colPos = gridItem->colPos();
+            rowPos = gridItem->rowPos();
+        } else {
+            // appending items to visible list
+            FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(visibleItems.at(index-1));
+            colPos = gridItem->colPos() + colSize();
+            rowPos = gridItem->rowPos();
+            if (colPos > colSize() * (columns-1)) {
+                colPos = 0;
+                rowPos += rowSize();
+            }
+        }
+    }
+
+    // Update the indexes of the following visible items.
+    for (int i = 0; i < visibleItems.count(); ++i) {
+        FxViewItem *item = visibleItems.at(i);
+        if (item->index != -1 && item->index >= modelIndex)
+            item->index += count;
+    }
+
+    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--;
+        }
+    } 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;
+        }
+    }
+
+    updateVisibleIndex();
+
+    return insertResult->addedItems.count() > prevAddedCount;
+}
+
+/*!
+    \qmlmethod QtQuick2::GridView::positionViewAtIndex(int index, PositionMode mode)
+
+    Positions the view such that the \a index is at the position specified by
+    \a mode:
+
+    \list
+    \o GridView.Beginning - position item at the top (or left for \c GridView.TopToBottom flow) of the view.
+    \o GridView.Center - position item in the center of the view.
+    \o GridView.End - position item at bottom (or right for horizontal orientation) of the view.
+    \o GridView.Visible - if any part of the item is visible then take no action, otherwise
+    bring the item into view.
+    \o GridView.Contain - ensure the entire item is visible.  If the item is larger than
+    the view the item is positioned at the top (or left for \c GridView.TopToBottom flow) of the view.
+    \endlist
+
+    If positioning the view at the index would cause empty space to be displayed at
+    the beginning or end of the view, the view will be positioned at the boundary.
+
+    It is not recommended to use \l {Flickable::}{contentX} or \l {Flickable::}{contentY} to position the view
+    at a particular index.  This is unreliable since removing items from the start
+    of the view does not cause all other items to be repositioned.
+    The correct way to bring an item into view is with \c positionViewAtIndex.
+
+    \bold Note: methods should only be called after the Component has completed.  To position
+    the view at startup, this method should be called by Component.onCompleted.  For
+    example, to position the view at the end:
+
+    \code
+    Component.onCompleted: positionViewAtIndex(count - 1, GridView.Beginning)
+    \endcode
+*/
+
+/*!
+    \qmlmethod QtQuick2::GridView::positionViewAtBeginning()
+    \qmlmethod QtQuick2::GridView::positionViewAtEnd()
+
+    Positions the view at the beginning or end, taking into account any header or footer.
+
+    It is not recommended to use \l {Flickable::}{contentX} or \l {Flickable::}{contentY} to position the view
+    at a particular index.  This is unreliable since removing items from the start
+    of the list does not cause all other items to be repositioned, and because
+    the actual start of the view can vary based on the size of the delegates.
+
+    \bold Note: methods should only be called after the Component has completed.  To position
+    the view at startup, this method should be called by Component.onCompleted.  For
+    example, to position the view at the end on startup:
+
+    \code
+    Component.onCompleted: positionViewAtEnd()
+    \endcode
+*/
+
+/*!
+    \qmlmethod int QtQuick2::GridView::indexAt(int x, int y)
+
+    Returns the index of the visible item containing the point \a x, \a y in content
+    coordinates.  If there is no item at the point specified, or the item is
+    not visible -1 is returned.
+
+    If the item is outside the visible area, -1 is returned, regardless of
+    whether an item will exist at that point when scrolled into view.
+
+    \bold Note: methods should only be called after the Component has completed.
+*/
+
+QQuickGridViewAttached *QQuickGridView::qmlAttachedProperties(QObject *obj)
+{
+    return new QQuickGridViewAttached(obj);
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickgridview_p.h b/src/declarative/items/qquickgridview_p.h
new file mode 100644 (file)
index 0000000..b02c0a8
--- /dev/null
@@ -0,0 +1,146 @@
+// Commit: 95814418f9d6adeba365c795462e8afb00138211
+/****************************************************************************
+**
+** 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 QQUICKGRIDVIEW_P_H
+#define QQUICKGRIDVIEW_P_H
+
+#include "qquickitemview_p.h"
+
+#include <private/qdeclarativeguard_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class QQuickVisualModel;
+class QQuickGridViewAttached;
+class QQuickGridViewPrivate;
+class Q_AUTOTEST_EXPORT QQuickGridView : public QQuickItemView
+{
+    Q_OBJECT
+    Q_DECLARE_PRIVATE(QQuickGridView)
+
+    Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged)
+    Q_PROPERTY(qreal cellWidth READ cellWidth WRITE setCellWidth NOTIFY cellWidthChanged)
+    Q_PROPERTY(qreal cellHeight READ cellHeight WRITE setCellHeight NOTIFY cellHeightChanged)
+
+    Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged)
+
+    Q_ENUMS(SnapMode)
+    Q_ENUMS(Flow)
+    Q_CLASSINFO("DefaultProperty", "data")
+
+public:
+    QQuickGridView(QQuickItem *parent=0);
+    ~QQuickGridView();
+
+    virtual void setHighlightFollowsCurrentItem(bool);
+    virtual void setHighlightMoveDuration(int);
+
+    enum Flow { LeftToRight, TopToBottom };
+    Flow flow() const;
+    void setFlow(Flow);
+
+    qreal cellWidth() const;
+    void setCellWidth(qreal);
+
+    qreal cellHeight() const;
+    void setCellHeight(qreal);
+
+    enum SnapMode { NoSnap, SnapToRow, SnapOneRow };
+    SnapMode snapMode() const;
+    void setSnapMode(SnapMode mode);
+
+    static QQuickGridViewAttached *qmlAttachedProperties(QObject *);
+
+public Q_SLOTS:
+    void moveCurrentIndexUp();
+    void moveCurrentIndexDown();
+    void moveCurrentIndexLeft();
+    void moveCurrentIndexRight();
+
+Q_SIGNALS:
+    void cellWidthChanged();
+    void cellHeightChanged();
+    void highlightMoveDurationChanged();
+    void flowChanged();
+    void snapModeChanged();
+
+protected:
+    virtual void viewportMoved();
+    virtual void keyPressEvent(QKeyEvent *);
+};
+
+class QQuickGridViewAttached : public QQuickItemViewAttached
+{
+    Q_OBJECT
+public:
+    QQuickGridViewAttached(QObject *parent)
+        : QQuickItemViewAttached(parent), m_view(0) {}
+    ~QQuickGridViewAttached() {}
+
+    Q_PROPERTY(QQuickGridView *view READ view NOTIFY viewChanged)
+    QQuickGridView *view() { return m_view; }
+    void setView(QQuickGridView *view) {
+        if (view != m_view) {
+            m_view = view;
+            emit viewChanged();
+        }
+    }
+
+Q_SIGNALS:
+    void viewChanged();
+
+public:
+    QDeclarativeGuard<QQuickGridView> m_view;
+};
+
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickGridView)
+QML_DECLARE_TYPEINFO(QQuickGridView, QML_HAS_ATTACHED_PROPERTIES)
+
+QT_END_HEADER
+
+#endif // QQUICKGRIDVIEW_P_H
diff --git a/src/declarative/items/qquickimage.cpp b/src/declarative/items/qquickimage.cpp
new file mode 100644 (file)
index 0000000..0737957
--- /dev/null
@@ -0,0 +1,753 @@
+/****************************************************************************
+**
+** 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 "qquickimage_p.h"
+#include "qquickimage_p_p.h"
+
+#include <private/qsgtextureprovider_p.h>
+
+#include <private/qsgcontext_p.h>
+#include <private/qsgadaptationlayer_p.h>
+
+#include <QtGui/qpainter.h>
+#include <qmath.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickImageTextureProvider : public QSGTextureProvider
+{
+    Q_OBJECT
+public:
+    QQuickImageTextureProvider()
+        : m_texture(0)
+        , m_smooth(false)
+    {
+    }
+
+    QSGTexture *texture() const {
+
+        if (m_texture->isAtlasTexture())
+            const_cast<QQuickImageTextureProvider *>(this)->m_texture = m_texture->removedFromAtlas();
+
+        if (m_texture) {
+            m_texture->setFiltering(m_smooth ? QSGTexture::Linear : QSGTexture::Nearest);
+            m_texture->setMipmapFiltering(QSGTexture::Nearest);
+            m_texture->setHorizontalWrapMode(QSGTexture::ClampToEdge);
+            m_texture->setVerticalWrapMode(QSGTexture::ClampToEdge);
+        }
+        return m_texture;
+    }
+
+    friend class QQuickImage;
+
+    QSGTexture *m_texture;
+    bool m_smooth;
+};
+
+#include "qquickimage.moc"
+
+QQuickImagePrivate::QQuickImagePrivate()
+    : fillMode(QQuickImage::Stretch)
+    , paintedWidth(0)
+    , paintedHeight(0)
+    , pixmapChanged(false)
+    , hAlign(QQuickImage::AlignHCenter)
+    , vAlign(QQuickImage::AlignVCenter)
+    , provider(0)
+{
+}
+
+/*!
+    \qmlclass Image QQuickImage
+    \inqmlmodule QtQuick 2
+    \ingroup qml-basic-visual-elements
+    \brief The Image element displays an image in a declarative user interface
+    \inherits Item
+
+    The Image element is used to display images in a declarative user interface.
+
+    The source of the image is specified as a URL using the \l source property.
+    Images can be supplied in any of the standard image formats supported by Qt,
+    including bitmap formats such as PNG and JPEG, and vector graphics formats
+    such as SVG. If you need to display animated images, use the \l AnimatedImage
+    element.
+
+    If the \l{Item::width}{width} and \l{Item::height}{height} properties are not
+    specified, the Image element automatically uses the size of the loaded image.
+    By default, specifying the width and height of the element causes the image
+    to be scaled to that size. This behavior can be changed by setting the
+    \l fillMode property, allowing the image to be stretched and tiled instead.
+
+    \section1 Example Usage
+
+    The following example shows the simplest usage of the Image element.
+
+    \snippet doc/src/snippets/declarative/image.qml document
+
+    \beginfloatleft
+    \image declarative-qtlogo.png
+    \endfloat
+
+    \clearfloat
+
+    \section1 Performance
+
+    By default, locally available images are loaded immediately, and the user interface
+    is blocked until loading is complete. If a large image is to be loaded, it may be
+    preferable to load the image in a low priority thread, by enabling the \l asynchronous
+    property.
+
+    If the image is obtained from a network rather than a local resource, it is
+    automatically loaded asynchronously, and the \l progress and \l status properties
+    are updated as appropriate.
+
+    Images are cached and shared internally, so if several Image elements have the same \l source,
+    only one copy of the image will be loaded.
+
+    \bold Note: Images are often the greatest user of memory in QML user interfaces.  It is recommended
+    that images which do not form part of the user interface have their
+    size bounded via the \l sourceSize property. This is especially important for content
+    that is loaded from external sources or provided by the user.
+
+    \sa {declarative/imageelements/image}{Image example}, QDeclarativeImageProvider
+*/
+
+QQuickImage::QQuickImage(QQuickItem *parent)
+    : QQuickImageBase(*(new QQuickImagePrivate), parent)
+{
+}
+
+QQuickImage::QQuickImage(QQuickImagePrivate &dd, QQuickItem *parent)
+    : QQuickImageBase(dd, parent)
+{
+}
+
+QQuickImage::~QQuickImage()
+{
+    Q_D(QQuickImage);
+    if (d->provider)
+        d->provider->deleteLater();
+}
+
+void QQuickImagePrivate::setPixmap(const QPixmap &pixmap)
+{
+    Q_Q(QQuickImage);
+    pix.setPixmap(pixmap);
+
+    q->pixmapChange();
+    status = pix.isNull() ? QQuickImageBase::Null : QQuickImageBase::Ready;
+
+    q->update();
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::Image::fillMode
+
+    Set this property to define what happens when the source image has a different size
+    than the item.
+
+    \list
+    \o Image.Stretch - the image is scaled to fit
+    \o Image.PreserveAspectFit - the image is scaled uniformly to fit without cropping
+    \o Image.PreserveAspectCrop - the image is scaled uniformly to fill, cropping if necessary
+    \o Image.Tile - the image is duplicated horizontally and vertically
+    \o Image.TileVertically - the image is stretched horizontally and tiled vertically
+    \o Image.TileHorizontally - the image is stretched vertically and tiled horizontally
+    \o Image.Pad - the image is not transformed
+    \endlist
+
+    \table
+
+    \row
+    \o \image declarative-qtlogo-stretch.png
+    \o Stretch (default)
+    \qml
+    Image {
+        width: 130; height: 100
+        smooth: true
+        source: "qtlogo.png"
+    }
+    \endqml
+
+    \row
+    \o \image declarative-qtlogo-preserveaspectfit.png
+    \o PreserveAspectFit
+    \qml
+    Image {
+        width: 130; height: 100
+        fillMode: Image.PreserveAspectFit
+        smooth: true
+        source: "qtlogo.png"
+    }
+    \endqml
+
+    \row
+    \o \image declarative-qtlogo-preserveaspectcrop.png
+    \o PreserveAspectCrop
+    \qml
+    Image {
+        width: 130; height: 100
+        fillMode: Image.PreserveAspectCrop
+        smooth: true
+        source: "qtlogo.png"
+        clip: true
+    }
+    \endqml
+
+    \row
+    \o \image declarative-qtlogo-tile.png
+    \o Tile
+    \qml
+    Image {
+        width: 120; height: 120
+        fillMode: Image.Tile
+        source: "qtlogo.png"
+    }
+    \endqml
+
+    \row
+    \o \image declarative-qtlogo-tilevertically.png
+    \o TileVertically
+    \qml
+    Image {
+        width: 120; height: 120
+        fillMode: Image.TileVertically
+        smooth: true
+        source: "qtlogo.png"
+    }
+    \endqml
+
+    \row
+    \o \image declarative-qtlogo-tilehorizontally.png
+    \o TileHorizontally
+    \qml
+    Image {
+        width: 120; height: 120
+        fillMode: Image.TileHorizontally
+        smooth: true
+        source: "qtlogo.png"
+    }
+    \endqml
+
+    \endtable
+
+    Note that \c clip is \c false by default which means that the element might
+    paint outside its bounding rectangle even if the fillMode is set to \c PreserveAspectCrop.
+
+    \sa {declarative/imageelements/image}{Image example}
+*/
+QQuickImage::FillMode QQuickImage::fillMode() const
+{
+    Q_D(const QQuickImage);
+    return d->fillMode;
+}
+
+void QQuickImage::setFillMode(FillMode mode)
+{
+    Q_D(QQuickImage);
+    if (d->fillMode == mode)
+        return;
+    d->fillMode = mode;
+    update();
+    updatePaintedGeometry();
+    emit fillModeChanged();
+}
+
+/*!
+
+    \qmlproperty real QtQuick2::Image::paintedWidth
+    \qmlproperty real QtQuick2::Image::paintedHeight
+
+    These properties hold the size of the image that is actually painted.
+    In most cases it is the same as \c width and \c height, but when using a
+    \c fillMode \c PreserveAspectFit or \c fillMode \c PreserveAspectCrop
+    \c paintedWidth or \c paintedHeight can be smaller or larger than
+    \c width and \c height of the Image element.
+*/
+qreal QQuickImage::paintedWidth() const
+{
+    Q_D(const QQuickImage);
+    return d->paintedWidth;
+}
+
+qreal QQuickImage::paintedHeight() const
+{
+    Q_D(const QQuickImage);
+    return d->paintedHeight;
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::Image::status
+
+    This property holds the status of image loading.  It can be one of:
+    \list
+    \o Image.Null - no image has been set
+    \o Image.Ready - the image has been loaded
+    \o Image.Loading - the image is currently being loaded
+    \o Image.Error - an error occurred while loading the image
+    \endlist
+
+    Use this status to provide an update or respond to the status change in some way.
+    For example, you could:
+
+    \list
+    \o Trigger a state change:
+    \qml
+        State { name: 'loaded'; when: image.status == Image.Ready }
+    \endqml
+
+    \o Implement an \c onStatusChanged signal handler:
+    \qml
+        Image {
+            id: image
+            onStatusChanged: if (image.status == Image.Ready) console.log('Loaded')
+        }
+    \endqml
+
+    \o Bind to the status value:
+    \qml
+        Text { text: image.status == Image.Ready ? 'Loaded' : 'Not loaded' }
+    \endqml
+    \endlist
+
+    \sa progress
+*/
+
+/*!
+    \qmlproperty real QtQuick2::Image::progress
+
+    This property holds the progress of image loading, from 0.0 (nothing loaded)
+    to 1.0 (finished).
+
+    \sa status
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::Image::smooth
+
+    Set this property if you want the image to be smoothly filtered when scaled or
+    transformed.  Smooth filtering gives better visual quality, but is slower.  If
+    the image is displayed at its natural size, this property has no visual or
+    performance effect.
+
+    \note Generally scaling artifacts are only visible if the image is stationary on
+    the screen.  A common pattern when animating an image is to disable smooth
+    filtering at the beginning of the animation and reenable it at the conclusion.
+*/
+
+/*!
+    \qmlproperty QSize QtQuick2::Image::sourceSize
+
+    This property holds the actual width and height of the loaded image.
+
+    Unlike the \l {Item::}{width} and \l {Item::}{height} properties, which scale
+    the painting of the image, this property sets the actual number of pixels
+    stored for the loaded image so that large images do not use more
+    memory than necessary. For example, this ensures the image in memory is no
+    larger than 1024x1024 pixels, regardless of the Image's \l {Item::}{width} and
+    \l {Item::}{height} values:
+
+    \code
+    Rectangle {
+        width: ...
+        height: ...
+
+        Image {
+           anchors.fill: parent
+           source: "reallyBigImage.jpg"
+           sourceSize.width: 1024
+           sourceSize.height: 1024
+        }
+    }
+    \endcode
+
+    If the image's actual size is larger than the sourceSize, the image is scaled down.
+    If only one dimension of the size is set to greater than 0, the
+    other dimension is set in proportion to preserve the source image's aspect ratio.
+    (The \l fillMode is independent of this.)
+
+    If the source is an instrinsically scalable image (eg. SVG), this property
+    determines the size of the loaded image regardless of intrinsic size.
+    Avoid changing this property dynamically; rendering an SVG is \e slow compared
+    to an image.
+
+    If the source is a non-scalable image (eg. JPEG), the loaded image will
+    be no greater than this property specifies. For some formats (currently only JPEG),
+    the whole image will never actually be loaded into memory.
+
+    Since QtQuick 1.1 the sourceSize can be cleared to the natural size of the image
+    by setting sourceSize to \c undefined.
+
+    \note \e {Changing this property dynamically causes the image source to be reloaded,
+    potentially even from the network, if it is not in the disk cache.}
+*/
+
+/*!
+    \qmlproperty url QtQuick2::Image::source
+
+    Image can handle any image format supported by Qt, loaded from any URL scheme supported by Qt.
+
+    The URL may be absolute, or relative to the URL of the component.
+
+    \sa QDeclarativeImageProvider
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::Image::asynchronous
+
+    Specifies that images on the local filesystem should be loaded
+    asynchronously in a separate thread.  The default value is
+    false, causing the user interface thread to block while the
+    image is loaded.  Setting \a asynchronous to true is useful where
+    maintaining a responsive user interface is more desirable
+    than having images immediately visible.
+
+    Note that this property is only valid for images read from the
+    local filesystem.  Images loaded via a network resource (e.g. HTTP)
+    are always loaded asynchonously.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::Image::cache
+
+    Specifies whether the image should be cached. The default value is
+    true. Setting \a cache to false is useful when dealing with large images,
+    to make sure that they aren't cached at the expense of small 'ui element' images.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::Image::mirror
+
+    This property holds whether the image should be horizontally inverted
+    (effectively displaying a mirrored image).
+
+    The default value is false.
+*/
+
+/*!
+    \qmlproperty enumeration QtQuick2::Image::horizontalAlignment
+    \qmlproperty enumeration QtQuick2::Image::verticalAlignment
+
+    Sets the horizontal and vertical alignment of the image. By default, the image is top-left aligned.
+
+    The valid values for \c horizontalAlignment are \c Image.AlignLeft, \c Image.AlignRight and \c Image.AlignHCenter.
+    The valid values for \c verticalAlignment are \c Image.AlignTop, \c Image.AlignBottom
+    and \c Image.AlignVCenter.
+*/
+void QQuickImage::updatePaintedGeometry()
+{
+    Q_D(QQuickImage);
+
+    if (d->fillMode == PreserveAspectFit) {
+        if (!d->pix.width() || !d->pix.height()) {
+            setImplicitWidth(0);
+            setImplicitHeight(0);
+            return;
+        }
+        qreal w = widthValid() ? width() : d->pix.width();
+        qreal widthScale = w / qreal(d->pix.width());
+        qreal h = heightValid() ? height() : d->pix.height();
+        qreal heightScale = h / qreal(d->pix.height());
+        if (widthScale <= heightScale) {
+            d->paintedWidth = w;
+            d->paintedHeight = widthScale * qreal(d->pix.height());
+        } else if (heightScale < widthScale) {
+            d->paintedWidth = heightScale * qreal(d->pix.width());
+            d->paintedHeight = h;
+        }
+        if (widthValid() && !heightValid()) {
+            setImplicitHeight(d->paintedHeight);
+        } else {
+            setImplicitHeight(d->pix.height());
+        }
+        if (heightValid() && !widthValid()) {
+            setImplicitWidth(d->paintedWidth);
+        } else {
+            setImplicitWidth(d->pix.width());
+        }
+    } else if (d->fillMode == PreserveAspectCrop) {
+        if (!d->pix.width() || !d->pix.height())
+            return;
+        qreal widthScale = width() / qreal(d->pix.width());
+        qreal heightScale = height() / qreal(d->pix.height());
+        if (widthScale < heightScale) {
+            widthScale = heightScale;
+        } else if (heightScale < widthScale) {
+            heightScale = widthScale;
+        }
+
+        d->paintedHeight = heightScale * qreal(d->pix.height());
+        d->paintedWidth = widthScale * qreal(d->pix.width());
+    } else if (d->fillMode == Pad) {
+        d->paintedWidth = d->pix.width();
+        d->paintedHeight = d->pix.height();
+    } else {
+        d->paintedWidth = width();
+        d->paintedHeight = height();
+    }
+    emit paintedGeometryChanged();
+}
+
+void QQuickImage::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+    QQuickImageBase::geometryChanged(newGeometry, oldGeometry);
+    updatePaintedGeometry();
+}
+
+QRectF QQuickImage::boundingRect() const
+{
+    Q_D(const QQuickImage);
+    return QRectF(0, 0, qMax(width(), d->paintedWidth), qMax(height(), d->paintedHeight));
+}
+
+QSGTextureProvider *QQuickImage::textureProvider() const
+{
+    Q_D(const QQuickImage);
+    if (!d->provider) {
+        // Make sure it gets thread affinity on the rendering thread so deletion works properly..
+        Q_ASSERT_X(d->canvas
+                   && d->sceneGraphContext()
+                   && QThread::currentThread() == d->sceneGraphContext()->thread(),
+                   "QQuickImage::textureProvider",
+                   "Cannot be used outside the GUI thread");
+        QQuickImagePrivate *dd = const_cast<QQuickImagePrivate *>(d);
+        dd->provider = new QQuickImageTextureProvider;
+        dd->provider->m_texture = d->pix.texture(d->sceneGraphContext());
+    }
+
+    return d->provider;
+}
+
+QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+    Q_D(QQuickImage);
+
+    QSGTexture *texture = d->pix.texture(d->sceneGraphContext());
+
+    // Copy over the current texture state into the texture provider...
+    if (d->provider) {
+        d->provider->m_smooth = d->smooth;
+        d->provider->m_texture = texture;
+    }
+
+    if (!texture || width() <= 0 || height() <= 0) {
+        delete oldNode;
+        return 0;
+    }
+
+    QSGImageNode *node = static_cast<QSGImageNode *>(oldNode);
+    if (!node) {
+        d->pixmapChanged = true;
+        node = d->sceneGraphContext()->createImageNode();
+        node->setTexture(texture);
+    }
+
+    if (d->pixmapChanged) {
+        // force update the texture in the node to trigger reconstruction of
+        // geometry and the likes when a atlas segment has changed.
+        node->setTexture(0);
+        node->setTexture(texture);
+        d->pixmapChanged = false;
+    }
+
+    QRectF targetRect;
+    QRectF sourceRect;
+    QSGTexture::WrapMode hWrap = QSGTexture::ClampToEdge;
+    QSGTexture::WrapMode vWrap = QSGTexture::ClampToEdge;
+
+    qreal pixWidth = (d->fillMode == PreserveAspectFit) ? d->paintedWidth : d->pix.width();
+    qreal pixHeight = (d->fillMode == PreserveAspectFit) ? d->paintedHeight : d->pix.height();
+
+    int xOffset = 0;
+    if (d->hAlign == QQuickImage::AlignHCenter)
+        xOffset = qCeil((width() - pixWidth) / 2.);
+    else if (d->hAlign == QQuickImage::AlignRight)
+        xOffset = qCeil(width() - pixWidth);
+
+    int yOffset = 0;
+    if (d->vAlign == QQuickImage::AlignVCenter)
+        yOffset = qCeil((height() - pixHeight) / 2.);
+    else if (d->vAlign == QQuickImage::AlignBottom)
+        yOffset = qCeil(height() - pixHeight);
+
+    switch (d->fillMode) {
+    default:
+    case Stretch:
+        targetRect = QRectF(0, 0, width(), height());
+        sourceRect = d->pix.rect();
+        break;
+
+    case PreserveAspectFit:
+        targetRect = QRectF(xOffset, yOffset, d->paintedWidth, d->paintedHeight);
+        sourceRect = d->pix.rect();
+        break;
+
+    case PreserveAspectCrop: {
+        targetRect = QRect(0, 0, width(), height());
+        qreal wscale = width() / qreal(d->pix.width());
+        qreal hscale = height() / qreal(d->pix.height());
+
+        if (wscale > hscale) {
+            int src = (hscale / wscale) * qreal(d->pix.height());
+            int y = 0;
+            if (d->vAlign == QQuickImage::AlignVCenter)
+                y = qCeil((d->pix.height() - src) / 2.);
+            else if (d->vAlign == QQuickImage::AlignBottom)
+                y = qCeil(d->pix.height() - src);
+            sourceRect = QRectF(0, y, d->pix.width(), src);
+
+        } else {
+            int src = (wscale / hscale) * qreal(d->pix.width());
+            int x = 0;
+            if (d->hAlign == QQuickImage::AlignHCenter)
+                x = qCeil((d->pix.width() - src) / 2.);
+            else if (d->hAlign == QQuickImage::AlignRight)
+                x = qCeil(d->pix.width() - src);
+            sourceRect = QRectF(x, 0, src, d->pix.height());
+        }
+        }
+        break;
+
+    case Tile:
+        targetRect = QRectF(0, 0, width(), height());
+        sourceRect = QRectF(-xOffset, -yOffset, width(), height());
+        hWrap = QSGTexture::Repeat;
+        vWrap = QSGTexture::Repeat;
+        break;
+
+    case TileHorizontally:
+        targetRect = QRectF(0, 0, width(), height());
+        sourceRect = QRectF(-xOffset, 0, width(), d->pix.height());
+        hWrap = QSGTexture::Repeat;
+        break;
+
+    case TileVertically:
+        targetRect = QRectF(0, 0, width(), height());
+        sourceRect = QRectF(0, -yOffset, d->pix.width(), height());
+        vWrap = QSGTexture::Repeat;
+        break;
+
+    case Pad:
+        qreal w = qMin(qreal(d->pix.width()), width());
+        qreal h = qMin(qreal(d->pix.height()), height());
+        qreal x = (d->pix.width() > width()) ? -xOffset : 0;
+        qreal y = (d->pix.height() > height()) ? -yOffset : 0;
+        targetRect = QRectF(x + xOffset, y + yOffset, w, h);
+        sourceRect = QRectF(x, y, w, h);
+        break;
+    };
+
+    QRectF nsrect(sourceRect.x() / d->pix.width(),
+                  sourceRect.y() / d->pix.height(),
+                  sourceRect.width() / d->pix.width(),
+                  sourceRect.height() / d->pix.height());
+
+    if (d->mirror) {
+        qreal oldLeft = nsrect.left();
+        nsrect.setLeft(nsrect.right());
+        nsrect.setRight(oldLeft);
+    }
+
+    node->setHorizontalWrapMode(hWrap);
+    node->setVerticalWrapMode(vWrap);
+    node->setFiltering(d->smooth ? QSGTexture::Linear : QSGTexture::Nearest);
+
+    node->setTargetRect(targetRect);
+    node->setSourceRect(nsrect);
+    node->update();
+
+    return node;
+}
+
+void QQuickImage::pixmapChange()
+{
+    Q_D(QQuickImage);
+    // PreserveAspectFit calculates the implicit size differently so we
+    // don't call our superclass pixmapChange(), since that would
+    // result in the implicit size being set incorrectly, then updated
+    // in updatePaintedGeometry()
+    if (d->fillMode != PreserveAspectFit)
+        QQuickImageBase::pixmapChange();
+    updatePaintedGeometry();
+    d->pixmapChanged = true;
+
+    // Make sure we update the texture provider when the image has changed.
+    if (d->provider)
+        update();
+}
+
+QQuickImage::VAlignment QQuickImage::verticalAlignment() const
+{
+    Q_D(const QQuickImage);
+    return d->vAlign;
+}
+
+void QQuickImage::setVerticalAlignment(VAlignment align)
+{
+    Q_D(QQuickImage);
+    if (d->vAlign == align)
+        return;
+
+    d->vAlign = align;
+    update();
+    updatePaintedGeometry();
+    emit verticalAlignmentChanged(align);
+}
+
+QQuickImage::HAlignment QQuickImage::horizontalAlignment() const
+{
+    Q_D(const QQuickImage);
+    return d->hAlign;
+}
+
+void QQuickImage::setHorizontalAlignment(HAlignment align)
+{
+    Q_D(QQuickImage);
+    if (d->hAlign == align)
+        return;
+
+    d->hAlign = align;
+    update();
+    updatePaintedGeometry();
+    emit horizontalAlignmentChanged(align);
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickimage_p.h b/src/declarative/items/qquickimage_p.h
new file mode 100644 (file)
index 0000000..0d1c8dc
--- /dev/null
@@ -0,0 +1,122 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
+/****************************************************************************
+**
+** 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 QQUICKIMAGE_P_H
+#define QQUICKIMAGE_P_H
+
+#include "qquickimagebase_p.h"
+#include <private/qsgtextureprovider_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickImagePrivate;
+class Q_AUTOTEST_EXPORT QQuickImage : public QQuickImageBase
+{
+    Q_OBJECT
+    Q_ENUMS(FillMode)
+    Q_ENUMS(HAlignment)
+    Q_ENUMS(VAlignment)
+
+    Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged)
+    Q_PROPERTY(qreal paintedWidth READ paintedWidth NOTIFY paintedGeometryChanged)
+    Q_PROPERTY(qreal paintedHeight READ paintedHeight NOTIFY paintedGeometryChanged)
+    Q_PROPERTY(HAlignment horizontalAlignment READ horizontalAlignment WRITE setHorizontalAlignment NOTIFY horizontalAlignmentChanged)
+    Q_PROPERTY(VAlignment verticalAlignment READ verticalAlignment WRITE setVerticalAlignment NOTIFY verticalAlignmentChanged)
+
+public:
+    QQuickImage(QQuickItem *parent=0);
+    ~QQuickImage();
+
+    enum HAlignment { AlignLeft = Qt::AlignLeft,
+                       AlignRight = Qt::AlignRight,
+                       AlignHCenter = Qt::AlignHCenter };
+    enum VAlignment { AlignTop = Qt::AlignTop,
+                       AlignBottom = Qt::AlignBottom,
+                       AlignVCenter = Qt::AlignVCenter };
+
+    enum FillMode { Stretch, PreserveAspectFit, PreserveAspectCrop, Tile, TileVertically, TileHorizontally, Pad };
+
+    FillMode fillMode() const;
+    void setFillMode(FillMode);
+
+    qreal paintedWidth() const;
+    qreal paintedHeight() const;
+
+    QRectF boundingRect() const;
+
+    HAlignment horizontalAlignment() const;
+    void setHorizontalAlignment(HAlignment align);
+
+    VAlignment verticalAlignment() const;
+    void setVerticalAlignment(VAlignment align);
+
+    bool isTextureProvider() const { return true; }
+    QSGTextureProvider *textureProvider() const;
+
+Q_SIGNALS:
+    void fillModeChanged();
+    void paintedGeometryChanged();
+    void horizontalAlignmentChanged(HAlignment alignment);
+    void verticalAlignmentChanged(VAlignment alignment);
+
+protected:
+    QQuickImage(QQuickImagePrivate &dd, QQuickItem *parent);
+    void pixmapChange();
+    void updatePaintedGeometry();
+
+    virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
+    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+
+private:
+    Q_DISABLE_COPY(QQuickImage)
+    Q_DECLARE_PRIVATE(QQuickImage)
+};
+
+QT_END_NAMESPACE
+QML_DECLARE_TYPE(QQuickImage)
+QT_END_HEADER
+
+#endif // QQUICKIMAGE_P_H
diff --git a/src/declarative/items/qquickimage_p_p.h b/src/declarative/items/qquickimage_p_p.h
new file mode 100644 (file)
index 0000000..b343821
--- /dev/null
@@ -0,0 +1,85 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
+/****************************************************************************
+**
+** 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 QQUICKIMAGE_P_P_H
+#define QQUICKIMAGE_P_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 "qquickimagebase_p_p.h"
+#include "qquickimage_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickImageTextureProvider;
+
+class QQuickImagePrivate : public QQuickImageBasePrivate
+{
+    Q_DECLARE_PUBLIC(QQuickImage)
+
+public:
+    QQuickImagePrivate();
+
+    QQuickImage::FillMode fillMode;
+    qreal paintedWidth;
+    qreal paintedHeight;
+    void setPixmap(const QPixmap &pix);
+
+    bool pixmapChanged : 1;
+    QQuickImage::HAlignment hAlign;
+    QQuickImage::VAlignment vAlign;
+
+    QQuickImageTextureProvider *provider;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKIMAGE_P_P_H
diff --git a/src/declarative/items/qquickimagebase.cpp b/src/declarative/items/qquickimagebase.cpp
new file mode 100644 (file)
index 0000000..3eb196d
--- /dev/null
@@ -0,0 +1,291 @@
+/****************************************************************************
+**
+** 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 "qquickimagebase_p.h"
+#include "qquickimagebase_p_p.h"
+
+#include <QtDeclarative/qdeclarativeinfo.h>
+
+QT_BEGIN_NAMESPACE
+
+QQuickImageBase::QQuickImageBase(QQuickItem *parent)
+: QQuickImplicitSizeItem(*(new QQuickImageBasePrivate), parent)
+{
+    setFlag(ItemHasContents);
+}
+
+QQuickImageBase::QQuickImageBase(QQuickImageBasePrivate &dd, QQuickItem *parent)
+: QQuickImplicitSizeItem(dd, parent)
+{
+    setFlag(ItemHasContents);
+}
+
+QQuickImageBase::~QQuickImageBase()
+{
+}
+
+QQuickImageBase::Status QQuickImageBase::status() const
+{
+    Q_D(const QQuickImageBase);
+    return d->status;
+}
+
+
+qreal QQuickImageBase::progress() const
+{
+    Q_D(const QQuickImageBase);
+    return d->progress;
+}
+
+
+bool QQuickImageBase::asynchronous() const
+{
+    Q_D(const QQuickImageBase);
+    return d->async;
+}
+
+void QQuickImageBase::setAsynchronous(bool async)
+{
+    Q_D(QQuickImageBase);
+    if (d->async != async) {
+        d->async = async;
+        emit asynchronousChanged();
+    }
+}
+
+QUrl QQuickImageBase::source() const
+{
+    Q_D(const QQuickImageBase);
+    return d->url;
+}
+
+void QQuickImageBase::setSource(const QUrl &url)
+{
+    Q_D(QQuickImageBase);
+    //equality is fairly expensive, so we bypass for simple, common case
+    if ((d->url.isEmpty() == url.isEmpty()) && url == d->url)
+        return;
+
+    d->url = url;
+    emit sourceChanged(d->url);
+
+    if (isComponentComplete())
+        load();
+}
+
+void QQuickImageBase::setSourceSize(const QSize& size)
+{
+    Q_D(QQuickImageBase);
+    if (d->sourcesize == size)
+        return;
+
+    d->sourcesize = size;
+    d->explicitSourceSize = true;
+    emit sourceSizeChanged();
+    if (isComponentComplete())
+        load();
+}
+
+QSize QQuickImageBase::sourceSize() const
+{
+    Q_D(const QQuickImageBase);
+
+    int width = d->sourcesize.width();
+    int height = d->sourcesize.height();
+    return QSize(width != -1 ? width : d->pix.width(), height != -1 ? height : d->pix.height());
+}
+
+void QQuickImageBase::resetSourceSize()
+{
+    Q_D(QQuickImageBase);
+    if (!d->explicitSourceSize)
+        return;
+    d->explicitSourceSize = false;
+    d->sourcesize = QSize();
+    emit sourceSizeChanged();
+    if (isComponentComplete())
+        load();
+}
+
+bool QQuickImageBase::cache() const
+{
+    Q_D(const QQuickImageBase);
+    return d->cache;
+}
+
+void QQuickImageBase::setCache(bool cache)
+{
+    Q_D(QQuickImageBase);
+    if (d->cache == cache)
+        return;
+
+    d->cache = cache;
+    emit cacheChanged();
+    if (isComponentComplete())
+        load();
+}
+
+QPixmap QQuickImageBase::pixmap() const
+{
+    Q_D(const QQuickImageBase);
+    return d->pix.pixmap();
+}
+
+void QQuickImageBase::setMirror(bool mirror)
+{
+    Q_D(QQuickImageBase);
+    if (mirror == d->mirror)
+        return;
+
+    d->mirror = mirror;
+
+    if (isComponentComplete())
+        update();
+
+    emit mirrorChanged();
+}
+
+bool QQuickImageBase::mirror() const
+{
+    Q_D(const QQuickImageBase);
+    return d->mirror;
+}
+
+void QQuickImageBase::load()
+{
+    Q_D(QQuickImageBase);
+
+    if (d->url.isEmpty()) {
+        d->pix.clear(this);
+        d->status = Null;
+        d->progress = 0.0;
+        pixmapChange();
+        emit progressChanged(d->progress);
+        emit statusChanged(d->status);
+        update();
+    } else {
+        QDeclarativePixmap::Options options;
+        if (d->async)
+            options |= QDeclarativePixmap::Asynchronous;
+        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()) {
+            d->progress = 0.0;
+            d->status = Loading;
+            emit progressChanged(d->progress);
+            emit statusChanged(d->status);
+
+            static int thisRequestProgress = -1;
+            static int thisRequestFinished = -1;
+            if (thisRequestProgress == -1) {
+                thisRequestProgress =
+                    QQuickImageBase::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
+                thisRequestFinished =
+                    QQuickImageBase::staticMetaObject.indexOfSlot("requestFinished()");
+            }
+
+            d->pix.connectFinished(this, thisRequestFinished);
+            d->pix.connectDownloadProgress(this, thisRequestProgress);
+
+        } else {
+            requestFinished();
+        }
+    }
+}
+
+void QQuickImageBase::requestFinished()
+{
+    Q_D(QQuickImageBase);
+
+    QQuickImageBase::Status oldStatus = d->status;
+    qreal oldProgress = d->progress;
+
+    if (d->pix.isError()) {
+        d->status = Error;
+        qmlInfo(this) << d->pix.error();
+    } else {
+        d->status = Ready;
+    }
+
+    d->progress = 1.0;
+
+    pixmapChange();
+
+    if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height())
+        emit sourceSizeChanged();
+
+    if (d->status != oldStatus)
+        emit statusChanged(d->status);
+    if (d->progress != oldProgress)
+        emit progressChanged(d->progress);
+
+    update();
+}
+
+void QQuickImageBase::requestProgress(qint64 received, qint64 total)
+{
+    Q_D(QQuickImageBase);
+    if (d->status == Loading && total > 0) {
+        d->progress = qreal(received)/total;
+        emit progressChanged(d->progress);
+    }
+}
+
+void QQuickImageBase::componentComplete()
+{
+    Q_D(QQuickImageBase);
+    QQuickItem::componentComplete();
+    if (d->url.isValid())
+        load();
+}
+
+void QQuickImageBase::pixmapChange()
+{
+    Q_D(QQuickImageBase);
+    setImplicitWidth(d->pix.width());
+    setImplicitHeight(d->pix.height());
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickimagebase_p.h b/src/declarative/items/qquickimagebase_p.h
new file mode 100644 (file)
index 0000000..f15ab6e
--- /dev/null
@@ -0,0 +1,119 @@
+// Commit: af05f64d3edc860c3cf79c7f0bdf2377faae5f40
+/****************************************************************************
+**
+** 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 QQUICKIMAGEBASE_P_H
+#define QQUICKIMAGEBASE_P_H
+
+#include "qquickimplicitsizeitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QQuickImageBasePrivate;
+class Q_AUTOTEST_EXPORT QQuickImageBase : public QQuickImplicitSizeItem
+{
+    Q_OBJECT
+    Q_ENUMS(Status)
+
+    Q_PROPERTY(Status status READ status NOTIFY statusChanged)
+    Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+    Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
+    Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged)
+    Q_PROPERTY(bool cache READ cache WRITE setCache NOTIFY cacheChanged)
+    Q_PROPERTY(QSize sourceSize READ sourceSize WRITE setSourceSize RESET resetSourceSize NOTIFY sourceSizeChanged)
+    Q_PROPERTY(bool mirror READ mirror WRITE setMirror NOTIFY mirrorChanged)
+
+public:
+    QQuickImageBase(QQuickItem *parent=0);
+    ~QQuickImageBase();
+    enum Status { Null, Ready, Loading, Error };
+    Status status() const;
+    qreal progress() const;
+
+    QUrl source() const;
+    virtual void setSource(const QUrl &url);
+
+    bool asynchronous() const;
+    void setAsynchronous(bool);
+
+    bool cache() const;
+    void setCache(bool);
+
+    QPixmap pixmap() const;
+
+    virtual void setSourceSize(const QSize&);
+    QSize sourceSize() const;
+    void resetSourceSize();
+
+    virtual void setMirror(bool mirror);
+    bool mirror() const;
+
+Q_SIGNALS:
+    void sourceChanged(const QUrl &);
+    void sourceSizeChanged();
+    void statusChanged(QQuickImageBase::Status);
+    void progressChanged(qreal progress);
+    void asynchronousChanged();
+    void cacheChanged();
+    void mirrorChanged();
+
+protected:
+    virtual void load();
+    virtual void componentComplete();
+    virtual void pixmapChange();
+    QQuickImageBase(QQuickImageBasePrivate &dd, QQuickItem *parent);
+
+private Q_SLOTS:
+    virtual void requestFinished();
+    void requestProgress(qint64,qint64);
+
+private:
+    Q_DISABLE_COPY(QQuickImageBase)
+    Q_DECLARE_PRIVATE(QQuickImageBase)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QQUICKIMAGEBASE_P_H
diff --git a/src/declarative/items/qquickimagebase_p_p.h b/src/declarative/items/qquickimagebase_p_p.h
new file mode 100644 (file)
index 0000000..2347a82
--- /dev/null
@@ -0,0 +1,93 @@
+// Commit: 6f78a6080b84cc3ef96b73a4ff58d1b5a72f08f4
+/****************************************************************************
+**
+** 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 QQUICKIMAGEBASE_P_P_H
+#define QQUICKIMAGEBASE_P_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 "qquickimplicitsizeitem_p_p.h"
+#include "qquickimagebase_p.h"
+
+#include <private/qdeclarativepixmapcache_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QNetworkReply;
+class QQuickImageBasePrivate : public QQuickImplicitSizeItemPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickImageBase)
+
+public:
+    QQuickImageBasePrivate()
+      : status(QQuickImageBase::Null),
+        progress(0.0),
+        explicitSourceSize(false),
+        async(false),
+        cache(true),
+        mirror(false)
+    {
+    }
+
+    QDeclarativePixmap pix;
+    QQuickImageBase::Status status;
+    QUrl url;
+    qreal progress;
+    QSize sourcesize;
+    bool explicitSourceSize : 1;
+    bool async : 1;
+    bool cache : 1;
+    bool mirror: 1;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKIMAGEBASE_P_P_H
diff --git a/src/declarative/items/qquickimplicitsizeitem.cpp b/src/declarative/items/qquickimplicitsizeitem.cpp
new file mode 100644 (file)
index 0000000..807fb48
--- /dev/null
@@ -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 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 "qquickimplicitsizeitem_p.h"
+#include "qquickimplicitsizeitem_p_p.h"
+
+QT_BEGIN_NAMESPACE
+
+void QQuickImplicitSizeItemPrivate::implicitWidthChanged()
+{
+    Q_Q(QQuickImplicitSizeItem);
+    emit q->implicitWidthChanged();
+}
+
+void QQuickImplicitSizeItemPrivate::implicitHeightChanged()
+{
+    Q_Q(QQuickImplicitSizeItem);
+    emit q->implicitHeightChanged();
+}
+
+QQuickImplicitSizeItem::QQuickImplicitSizeItem(QQuickItem *parent)
+    : QQuickItem(*(new QQuickImplicitSizeItemPrivate), parent)
+{
+}
+
+QQuickImplicitSizeItem::QQuickImplicitSizeItem(QQuickImplicitSizeItemPrivate &dd, QQuickItem *parent)
+    : QQuickItem(dd, parent)
+{
+}
+
+
+void QQuickImplicitSizePaintedItemPrivate::implicitWidthChanged()
+{
+    Q_Q(QQuickImplicitSizePaintedItem);
+    emit q->implicitWidthChanged();
+}
+
+void QQuickImplicitSizePaintedItemPrivate::implicitHeightChanged()
+{
+    Q_Q(QQuickImplicitSizePaintedItem);
+    emit q->implicitHeightChanged();
+}
+
+QQuickImplicitSizePaintedItem::QQuickImplicitSizePaintedItem(QQuickItem *parent)
+    : QQuickPaintedItem(*(new QQuickImplicitSizePaintedItemPrivate), parent)
+{
+}
+
+QQuickImplicitSizePaintedItem::QQuickImplicitSizePaintedItem(QQuickImplicitSizePaintedItemPrivate &dd, QQuickItem *parent)
+    : QQuickPaintedItem(dd, parent)
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickimplicitsizeitem_p.h b/src/declarative/items/qquickimplicitsizeitem_p.h
new file mode 100644 (file)
index 0000000..eaa9b39
--- /dev/null
@@ -0,0 +1,101 @@
+// Commit: 6f78a6080b84cc3ef96b73a4ff58d1b5a72f08f4
+/****************************************************************************
+**
+** 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 QQUICKIMPLICITSIZEITEM_H
+#define QQUICKIMPLICITSIZEITEM_H
+
+#include "qquickpainteditem.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QQuickImplicitSizeItemPrivate;
+class Q_AUTOTEST_EXPORT QQuickImplicitSizeItem : public QQuickItem
+{
+    Q_OBJECT
+    Q_PROPERTY(qreal implicitWidth READ implicitWidth NOTIFY implicitWidthChanged)
+    Q_PROPERTY(qreal implicitHeight READ implicitHeight NOTIFY implicitHeightChanged)
+
+public:
+    QQuickImplicitSizeItem(QQuickItem *parent = 0);
+
+protected:
+    QQuickImplicitSizeItem(QQuickImplicitSizeItemPrivate &dd, QQuickItem *parent);
+
+Q_SIGNALS:
+    void implicitWidthChanged();
+    void implicitHeightChanged();
+
+private:
+    Q_DISABLE_COPY(QQuickImplicitSizeItem)
+    Q_DECLARE_PRIVATE(QQuickImplicitSizeItem)
+};
+
+class QQuickImplicitSizePaintedItemPrivate;
+class Q_AUTOTEST_EXPORT QQuickImplicitSizePaintedItem : public QQuickPaintedItem
+{
+    Q_OBJECT
+    Q_PROPERTY(qreal implicitWidth READ implicitWidth NOTIFY implicitWidthChanged)
+    Q_PROPERTY(qreal implicitHeight READ implicitHeight NOTIFY implicitHeightChanged)
+
+public:
+    QQuickImplicitSizePaintedItem(QQuickItem *parent = 0);
+
+protected:
+    QQuickImplicitSizePaintedItem(QQuickImplicitSizePaintedItemPrivate &dd, QQuickItem *parent);
+    virtual void drawContents(QPainter *, const QRect &) {};
+
+Q_SIGNALS:
+    void implicitWidthChanged();
+    void implicitHeightChanged();
+
+private:
+    Q_DISABLE_COPY(QQuickImplicitSizePaintedItem)
+    Q_DECLARE_PRIVATE(QQuickImplicitSizePaintedItem)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QQUICKIMPLICITSIZEITEM_H
diff --git a/src/declarative/items/qquickimplicitsizeitem_p_p.h b/src/declarative/items/qquickimplicitsizeitem_p_p.h
new file mode 100644 (file)
index 0000000..683fcc1
--- /dev/null
@@ -0,0 +1,92 @@
+// Commit: 6f78a6080b84cc3ef96b73a4ff58d1b5a72f08f4
+/****************************************************************************
+**
+** 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 QQUICKIMPLICITSIZEITEM_P_H
+#define QQUICKIMPLICITSIZEITEM_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 "qquickitem_p.h"
+#include "qquickpainteditem_p.h"
+#include "qquickimplicitsizeitem_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickImplicitSizeItemPrivate : public QQuickItemPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickImplicitSizeItem)
+
+public:
+    QQuickImplicitSizeItemPrivate()
+    {
+    }
+
+    virtual void implicitWidthChanged();
+    virtual void implicitHeightChanged();
+};
+
+
+class QQuickImplicitSizePaintedItemPrivate : public QQuickPaintedItemPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickImplicitSizePaintedItem)
+
+public:
+    QQuickImplicitSizePaintedItemPrivate()
+    {
+    }
+
+    virtual void implicitWidthChanged();
+    virtual void implicitHeightChanged();
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKIMPLICITSIZEITEM_P_H
diff --git a/src/declarative/items/qquickitem.cpp b/src/declarative/items/qquickitem.cpp
new file mode 100644 (file)
index 0000000..b6951d9
--- /dev/null
@@ -0,0 +1,5038 @@
+/****************************************************************************
+**
+** 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 "qquickitem.h"
+
+#include "qquickcanvas.h"
+#include <QtDeclarative/qjsengine.h>
+#include "qquickcanvas_p.h"
+
+#include "qquickevents_p_p.h"
+
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qdeclarativeinfo.h>
+#include <QtGui/qpen.h>
+#include <QtGui/qcursor.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qinputpanel.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qcoreevent.h>
+#include <QtCore/qnumeric.h>
+
+#include <private/qdeclarativeengine_p.h>
+#include <private/qdeclarativestategroup_p.h>
+#include <private/qdeclarativeopenmetaobject_p.h>
+#include <private/qdeclarativestate_p.h>
+#include <private/qlistmodelinterface_p.h>
+#include <private/qquickitem_p.h>
+
+#include <float.h>
+
+// XXX todo Readd parentNotifier for faster parent bindings
+// XXX todo Check that elements that create items handle memory correctly after visual ownership change
+
+QT_BEGIN_NAMESPACE
+
+/*!
+    \qmlclass Transform QQuickTransform
+    \inqmlmodule QtQuick 2
+    \ingroup qml-transform-elements
+    \brief The Transform elements provide a way of building advanced transformations on Items.
+
+    The Transform element is a base type which cannot be instantiated directly.
+    The following concrete Transform types are available:
+
+    \list
+    \o \l Rotation
+    \o \l Scale
+    \o \l Translate
+    \endlist
+
+    The Transform elements let you create and control advanced transformations that can be configured
+    independently using specialized properties.
+
+    You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
+    one at a time.
+*/
+
+/*!
+    \qmlclass Translate QQuickTranslate
+    \inqmlmodule QtQuick 2
+    \ingroup qml-transform-elements
+    \brief The Translate object provides a way to move an Item without changing its x or y properties.
+
+    The Translate object provides independent control over position in addition to the Item's x and y properties.
+
+    The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
+    to lay the items out as if they had not been transformed:
+    \qml
+    import QtQuick 1.0
+
+    Row {
+        Rectangle {
+            width: 100; height: 100
+            color: "blue"
+            transform: Translate { y: 20 }
+        }
+        Rectangle {
+            width: 100; height: 100
+            color: "red"
+            transform: Translate { y: -20 }
+        }
+    }
+    \endqml
+
+    \image translate.png
+*/
+
+/*!
+    \qmlproperty real QtQuick2::Translate::x
+
+    The translation along the X axis.
+*/
+
+/*!
+    \qmlproperty real QtQuick2::Translate::y
+
+    The translation along the Y axis.
+*/
+
+/*!
+    \qmlclass Scale QQuickScale
+    \inqmlmodule QtQuick 2
+    \ingroup qml-transform-elements
+    \brief The Scale element provides a way to scale an Item.
+
+    The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
+    it allows a different scale for the x and y axes, and allows the scale to be relative to an
+    arbitrary point.
+
+    The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
+    \qml
+    Rectangle {
+        width: 100; height: 100
+        color: "blue"
+        transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
+    }
+    \endqml
+
+    \sa Rotation, Translate
+*/
+
+/*!
+    \qmlproperty real QtQuick2::Scale::origin.x
+    \qmlproperty real QtQuick2::Scale::origin.y
+
+    The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
+    the rest of the item grows). By default the origin is 0, 0.
+*/
+
+/*!
+    \qmlproperty real QtQuick2::Scale::xScale
+
+    The scaling factor for the X axis.
+*/
+
+/*!
+    \qmlproperty real QtQuick2::Scale::yScale
+
+    The scaling factor for the Y axis.
+*/
+
+/*!
+    \qmlclass Rotation QQuickRotation
+    \inqmlmodule QtQuick 2
+    \ingroup qml-transform-elements
+    \brief The Rotation object provides a way to rotate an Item.
+
+    The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
+    Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
+
+    The following example rotates a Rectangle around its interior point 25, 25:
+    \qml
+    Rectangle {
+        width: 100; height: 100
+        color: "blue"
+        transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
+    }
+    \endqml
+
+    Rotation also provides a way to specify 3D-like rotations for Items. For these types of
+    rotations you must specify the axis to rotate around in addition to the origin point.
+
+    The following example shows various 3D-like rotations applied to an \l Image.
+    \snippet doc/src/snippets/declarative/rotation.qml 0
+
+    \image axisrotation.png
+
+    \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
+*/
+
+/*!
+    \qmlproperty real QtQuick2::Rotation::origin.x
+    \qmlproperty real QtQuick2::Rotation::origin.y
+
+    The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
+    the rest of the item rotates). By default the origin is 0, 0.
+*/
+
+/*!
+    \qmlproperty real QtQuick2::Rotation::axis.x
+    \qmlproperty real QtQuick2::Rotation::axis.y
+    \qmlproperty real QtQuick2::Rotation::axis.z
+
+    The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
+    as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
+
+    For a typical 3D-like rotation you will usually specify both the origin and the axis.
+
+    \image 3d-rotation-axis.png
+*/
+
+/*!
+    \qmlproperty real QtQuick2::Rotation::angle
+
+    The angle to rotate, in degrees clockwise.
+*/
+
+QQuickTransformPrivate::QQuickTransformPrivate()
+{
+}
+
+QQuickTransform::QQuickTransform(QObject *parent)
+: QObject(*(new QQuickTransformPrivate), parent)
+{
+}
+
+QQuickTransform::QQuickTransform(QQuickTransformPrivate &dd, QObject *parent)
+: QObject(dd, parent)
+{
+}
+
+QQuickTransform::~QQuickTransform()
+{
+    Q_D(QQuickTransform);
+    for (int ii = 0; ii < d->items.count(); ++ii) {
+        QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
+        p->transforms.removeOne(this);
+        p->dirty(QQuickItemPrivate::Transform);
+    }
+}
+
+void QQuickTransform::update()
+{
+    Q_D(QQuickTransform);
+    for (int ii = 0; ii < d->items.count(); ++ii) {
+        QQuickItemPrivate *p = QQuickItemPrivate::get(d->items.at(ii));
+        p->dirty(QQuickItemPrivate::Transform);
+    }
+}
+
+QQuickContents::QQuickContents(QQuickItem *item)
+: m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
+{
+    //### optimize
+    connect(this, SIGNAL(rectChanged(QRectF)), m_item, SIGNAL(childrenRectChanged(QRectF)));
+}
+
+QQuickContents::~QQuickContents()
+{
+    QList<QQuickItem *> children = m_item->childItems();
+    for (int i = 0; i < children.count(); ++i) {
+        QQuickItem *child = children.at(i);
+        QQuickItemPrivate::get(child)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
+    }
+}
+
+QRectF QQuickContents::rectF() const
+{
+    return QRectF(m_x, m_y, m_width, m_height);
+}
+
+void QQuickContents::calcHeight(QQuickItem *changed)
+{
+    qreal oldy = m_y;
+    qreal oldheight = m_height;
+
+    if (changed) {
+        qreal top = oldy;
+        qreal bottom = oldy + oldheight;
+        qreal y = changed->y();
+        if (y + changed->height() > bottom)
+            bottom = y + changed->height();
+        if (y < top)
+            top = y;
+        m_y = top;
+        m_height = bottom - top;
+    } else {
+        qreal top = FLT_MAX;
+        qreal bottom = 0;
+        QList<QQuickItem *> children = m_item->childItems();
+        for (int i = 0; i < children.count(); ++i) {
+            QQuickItem *child = children.at(i);
+            qreal y = child->y();
+            if (y + child->height() > bottom)
+                bottom = y + child->height();
+            if (y < top)
+                top = y;
+        }
+        if (!children.isEmpty())
+            m_y = top;
+        m_height = qMax(bottom - top, qreal(0.0));
+    }
+
+    if (m_height != oldheight || m_y != oldy)
+        emit rectChanged(rectF());
+}
+
+void QQuickContents::calcWidth(QQuickItem *changed)
+{
+    qreal oldx = m_x;
+    qreal oldwidth = m_width;
+
+    if (changed) {
+        qreal left = oldx;
+        qreal right = oldx + oldwidth;
+        qreal x = changed->x();
+        if (x + changed->width() > right)
+            right = x + changed->width();
+        if (x < left)
+            left = x;
+        m_x = left;
+        m_width = right - left;
+    } else {
+        qreal left = FLT_MAX;
+        qreal right = 0;
+        QList<QQuickItem *> children = m_item->childItems();
+        for (int i = 0; i < children.count(); ++i) {
+            QQuickItem *child = children.at(i);
+            qreal x = child->x();
+            if (x + child->width() > right)
+                right = x + child->width();
+            if (x < left)
+                left = x;
+        }
+        if (!children.isEmpty())
+            m_x = left;
+        m_width = qMax(right - left, qreal(0.0));
+    }
+
+    if (m_width != oldwidth || m_x != oldx)
+        emit rectChanged(rectF());
+}
+
+void QQuickContents::complete()
+{
+    QList<QQuickItem *> children = m_item->childItems();
+    for (int i = 0; i < children.count(); ++i) {
+        QQuickItem *child = children.at(i);
+        QQuickItemPrivate::get(child)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
+        //###what about changes to visibility?
+    }
+
+    calcGeometry();
+}
+
+void QQuickContents::itemGeometryChanged(QQuickItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+    Q_UNUSED(changed)
+    //### we can only pass changed if the left edge has moved left, or the right edge has moved right
+    if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
+        calcWidth(/*changed*/);
+    if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
+        calcHeight(/*changed*/);
+}
+
+void QQuickContents::itemDestroyed(QQuickItem *item)
+{
+    if (item)
+        QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
+    calcGeometry();
+}
+
+void QQuickContents::childRemoved(QQuickItem *item)
+{
+    if (item)
+        QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
+    calcGeometry();
+}
+
+void QQuickContents::childAdded(QQuickItem *item)
+{
+    if (item)
+        QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Destroyed);
+    calcWidth(item);
+    calcHeight(item);
+}
+
+QQuickItemKeyFilter::QQuickItemKeyFilter(QQuickItem *item)
+: m_processPost(false), m_next(0)
+{
+    QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):0;
+    if (p) {
+        m_next = p->keyHandler;
+        p->keyHandler = this;
+    }
+}
+
+QQuickItemKeyFilter::~QQuickItemKeyFilter()
+{
+}
+
+void QQuickItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
+{
+    if (m_next) m_next->keyPressed(event, post);
+}
+
+void QQuickItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
+{
+    if (m_next) m_next->keyReleased(event, post);
+}
+
+void QQuickItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
+{
+    if (m_next)
+        m_next->inputMethodEvent(event, post);
+    else
+        event->ignore();
+}
+
+QVariant QQuickItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+    if (m_next) return m_next->inputMethodQuery(query);
+    return QVariant();
+}
+
+void QQuickItemKeyFilter::componentComplete()
+{
+    if (m_next) m_next->componentComplete();
+}
+/*!
+    \qmlclass KeyNavigation QQuickKeyNavigationAttached
+    \inqmlmodule QtQuick 2
+    \ingroup qml-basic-interaction-elements
+    \brief The KeyNavigation attached property supports key navigation by arrow keys.
+
+    Key-based user interfaces commonly allow the use of arrow keys to navigate between
+    focusable items.  The KeyNavigation attached property enables this behavior by providing a
+    convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
+
+    The following example provides key navigation for a 2x2 grid of items:
+
+    \snippet doc/src/snippets/declarative/keynavigation.qml 0
+
+    The top-left item initially receives focus by setting \l {Item::}{focus} to
+    \c true. When an arrow key is pressed, the focus will move to the
+    appropriate item, as defined by the value that has been set for
+    the KeyNavigation \l left, \l right, \l up or \l down properties.
+
+    Note that if a KeyNavigation attached property receives the key press and release
+    events for a requested arrow or tab key, the event is accepted and does not
+    propagate any further.
+
+    By default, KeyNavigation receives key events after the item to which it is attached.
+    If the item accepts the key event, the KeyNavigation attached property will not
+    receive an event for that key.  Setting the \l priority property to
+    \c KeyNavigation.BeforeItem allows the event to be used for key navigation
+    before the item, rather than after.
+
+    If item to which the focus is switching is not enabled or visible, an attempt will
+    be made to skip this item and focus on the next. This is possible if there are
+    a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
+    or visible, they will also be skipped.
+
+    KeyNavigation will implicitly set the other direction to return focus to this item. So if you set
+    \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this
+    item. However, if that item's KeyNavigation has had right explicitly set then no change will occur.
+    This means that the above example could have been written, with the same behaviour, without specifing
+    KeyNavigation.right or KeyNavigation.down for any of the items.
+
+    \sa {Keys}{Keys attached property}
+*/
+
+/*!
+    \qmlproperty Item QtQuick2::KeyNavigation::left
+    \qmlproperty Item QtQuick2::KeyNavigation::right
+    \qmlproperty Item QtQuick2::KeyNavigation::up
+    \qmlproperty Item QtQuick2::KeyNavigation::down
+    \qmlproperty Item QtQuick2::KeyNavigation::tab
+    \qmlproperty Item QtQuick2::KeyNavigation::backtab
+
+    These properties hold the item to assign focus to
+    when the left, right, up or down cursor keys, or the
+    tab key are pressed.
+*/
+
+/*!
+    \qmlproperty Item QtQuick2::KeyNavigation::tab
+    \qmlproperty Item QtQuick2::KeyNavigation::backtab
+
+    These properties hold the item to assign focus to
+    when the Tab key or Shift+Tab key combination (Backtab) are pressed.
+*/
+
+QQuickKeyNavigationAttached::QQuickKeyNavigationAttached(QObject *parent)
+: QObject(*(new QQuickKeyNavigationAttachedPrivate), parent),
+  QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
+{
+    m_processPost = true;
+}
+
+QQuickKeyNavigationAttached *
+QQuickKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
+{
+    return new QQuickKeyNavigationAttached(obj);
+}
+
+QQuickItem *QQuickKeyNavigationAttached::left() const
+{
+    Q_D(const QQuickKeyNavigationAttached);
+    return d->left;
+}
+
+void QQuickKeyNavigationAttached::setLeft(QQuickItem *i)
+{
+    Q_D(QQuickKeyNavigationAttached);
+    if (d->left == i)
+        return;
+    d->left = i;
+    d->leftSet = true;
+    QQuickKeyNavigationAttached* other =
+            qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
+    if (other && !other->d_func()->rightSet){
+        other->d_func()->right = qobject_cast<QQuickItem*>(parent());
+        emit other->rightChanged();
+    }
+    emit leftChanged();
+}
+
+QQuickItem *QQuickKeyNavigationAttached::right() const
+{
+    Q_D(const QQuickKeyNavigationAttached);
+    return d->right;
+}
+
+void QQuickKeyNavigationAttached::setRight(QQuickItem *i)
+{
+    Q_D(QQuickKeyNavigationAttached);
+    if (d->right == i)
+        return;
+    d->right = i;
+    d->rightSet = true;
+    QQuickKeyNavigationAttached* other =
+            qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
+    if (other && !other->d_func()->leftSet){
+        other->d_func()->left = qobject_cast<QQuickItem*>(parent());
+        emit other->leftChanged();
+    }
+    emit rightChanged();
+}
+
+QQuickItem *QQuickKeyNavigationAttached::up() const
+{
+    Q_D(const QQuickKeyNavigationAttached);
+    return d->up;
+}
+
+void QQuickKeyNavigationAttached::setUp(QQuickItem *i)
+{
+    Q_D(QQuickKeyNavigationAttached);
+    if (d->up == i)
+        return;
+    d->up = i;
+    d->upSet = true;
+    QQuickKeyNavigationAttached* other =
+            qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
+    if (other && !other->d_func()->downSet){
+        other->d_func()->down = qobject_cast<QQuickItem*>(parent());
+        emit other->downChanged();
+    }
+    emit upChanged();
+}
+
+QQuickItem *QQuickKeyNavigationAttached::down() const
+{
+    Q_D(const QQuickKeyNavigationAttached);
+    return d->down;
+}
+
+void QQuickKeyNavigationAttached::setDown(QQuickItem *i)
+{
+    Q_D(QQuickKeyNavigationAttached);
+    if (d->down == i)
+        return;
+    d->down = i;
+    d->downSet = true;
+    QQuickKeyNavigationAttached* other =
+            qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
+    if (other && !other->d_func()->upSet) {
+        other->d_func()->up = qobject_cast<QQuickItem*>(parent());
+        emit other->upChanged();
+    }
+    emit downChanged();
+}
+
+QQuickItem *QQuickKeyNavigationAttached::tab() const
+{
+    Q_D(const QQuickKeyNavigationAttached);
+    return d->tab;
+}
+
+void QQuickKeyNavigationAttached::setTab(QQuickItem *i)
+{
+    Q_D(QQuickKeyNavigationAttached);
+    if (d->tab == i)
+        return;
+    d->tab = i;
+    d->tabSet = true;
+    QQuickKeyNavigationAttached* other =
+            qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
+    if (other && !other->d_func()->backtabSet) {
+        other->d_func()->backtab = qobject_cast<QQuickItem*>(parent());
+        emit other->backtabChanged();
+    }
+    emit tabChanged();
+}
+
+QQuickItem *QQuickKeyNavigationAttached::backtab() const
+{
+    Q_D(const QQuickKeyNavigationAttached);
+    return d->backtab;
+}
+
+void QQuickKeyNavigationAttached::setBacktab(QQuickItem *i)
+{
+    Q_D(QQuickKeyNavigationAttached);
+    if (d->backtab == i)
+        return;
+    d->backtab = i;
+    d->backtabSet = true;
+    QQuickKeyNavigationAttached* other =
+            qobject_cast<QQuickKeyNavigationAttached*>(qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(i));
+    if (other && !other->d_func()->tabSet) {
+        other->d_func()->tab = qobject_cast<QQuickItem*>(parent());
+        emit other->tabChanged();
+    }
+    emit backtabChanged();
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::KeyNavigation::priority
+
+    This property determines whether the keys are processed before
+    or after the attached item's own key handling.
+
+    \list
+    \o KeyNavigation.BeforeItem - process the key events before normal
+    item key processing.  If the event is used for key navigation, it will be accepted and will not
+    be passed on to the item.
+    \o KeyNavigation.AfterItem (default) - process the key events after normal item key
+    handling.  If the item accepts the key event it will not be
+    handled by the KeyNavigation attached property handler.
+    \endlist
+*/
+QQuickKeyNavigationAttached::Priority QQuickKeyNavigationAttached::priority() const
+{
+    return m_processPost ? AfterItem : BeforeItem;
+}
+
+void QQuickKeyNavigationAttached::setPriority(Priority order)
+{
+    bool processPost = order == AfterItem;
+    if (processPost != m_processPost) {
+        m_processPost = processPost;
+        emit priorityChanged();
+    }
+}
+
+void QQuickKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
+{
+    Q_D(QQuickKeyNavigationAttached);
+    event->ignore();
+
+    if (post != m_processPost) {
+        QQuickItemKeyFilter::keyPressed(event, post);
+        return;
+    }
+
+    bool mirror = false;
+    switch (event->key()) {
+    case Qt::Key_Left: {
+        if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
+            mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
+        QQuickItem* leftItem = mirror ? d->right : d->left;
+        if (leftItem) {
+            setFocusNavigation(leftItem, mirror ? "right" : "left");
+            event->accept();
+        }
+        break;
+    }
+    case Qt::Key_Right: {
+        if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
+            mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
+        QQuickItem* rightItem = mirror ? d->left : d->right;
+        if (rightItem) {
+            setFocusNavigation(rightItem, mirror ? "left" : "right");
+            event->accept();
+        }
+        break;
+    }
+    case Qt::Key_Up:
+        if (d->up) {
+            setFocusNavigation(d->up, "up");
+            event->accept();
+        }
+        break;
+    case Qt::Key_Down:
+        if (d->down) {
+            setFocusNavigation(d->down, "down");
+            event->accept();
+        }
+        break;
+    case Qt::Key_Tab:
+        if (d->tab) {
+            setFocusNavigation(d->tab, "tab");
+            event->accept();
+        }
+        break;
+    case Qt::Key_Backtab:
+        if (d->backtab) {
+            setFocusNavigation(d->backtab, "backtab");
+            event->accept();
+        }
+        break;
+    default:
+        break;
+    }
+
+    if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
+}
+
+void QQuickKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
+{
+    Q_D(QQuickKeyNavigationAttached);
+    event->ignore();
+
+    if (post != m_processPost) {
+        QQuickItemKeyFilter::keyReleased(event, post);
+        return;
+    }
+
+    bool mirror = false;
+    switch (event->key()) {
+    case Qt::Key_Left:
+        if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
+            mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
+        if (mirror ? d->right : d->left)
+            event->accept();
+        break;
+    case Qt::Key_Right:
+        if (QQuickItem *parentItem = qobject_cast<QQuickItem*>(parent()))
+            mirror = QQuickItemPrivate::get(parentItem)->effectiveLayoutMirror;
+        if (mirror ? d->left : d->right)
+            event->accept();
+        break;
+    case Qt::Key_Up:
+        if (d->up) {
+            event->accept();
+        }
+        break;
+    case Qt::Key_Down:
+        if (d->down) {
+            event->accept();
+        }
+        break;
+    case Qt::Key_Tab:
+        if (d->tab) {
+            event->accept();
+        }
+        break;
+    case Qt::Key_Backtab:
+        if (d->backtab) {
+            event->accept();
+        }
+        break;
+    default:
+        break;
+    }
+
+    if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
+}
+
+void QQuickKeyNavigationAttached::setFocusNavigation(QQuickItem *currentItem, const char *dir)
+{
+    QQuickItem *initialItem = currentItem;
+    bool isNextItem = false;
+    do {
+        isNextItem = false;
+        if (currentItem->isVisible() && currentItem->isEnabled()) {
+            currentItem->setFocus(true);
+        } else {
+            QObject *attached =
+                qmlAttachedPropertiesObject<QQuickKeyNavigationAttached>(currentItem, false);
+            if (attached) {
+                QQuickItem *tempItem = qvariant_cast<QQuickItem*>(attached->property(dir));
+                if (tempItem) {
+                    currentItem = tempItem;
+                    isNextItem = true;
+                }
+            }
+        }
+    }
+    while (currentItem != initialItem && isNextItem);
+}
+
+const QQuickKeysAttached::SigMap QQuickKeysAttached::sigMap[] = {
+    { Qt::Key_Left, "leftPressed" },
+    { Qt::Key_Right, "rightPressed" },
+    { Qt::Key_Up, "upPressed" },
+    { Qt::Key_Down, "downPressed" },
+    { Qt::Key_Tab, "tabPressed" },
+    { Qt::Key_Backtab, "backtabPressed" },
+    { Qt::Key_Asterisk, "asteriskPressed" },
+    { Qt::Key_NumberSign, "numberSignPressed" },
+    { Qt::Key_Escape, "escapePressed" },
+    { Qt::Key_Return, "returnPressed" },
+    { Qt::Key_Enter, "enterPressed" },
+    { Qt::Key_Delete, "deletePressed" },
+    { Qt::Key_Space, "spacePressed" },
+    { Qt::Key_Back, "backPressed" },
+    { Qt::Key_Cancel, "cancelPressed" },
+    { Qt::Key_Select, "selectPressed" },
+    { Qt::Key_Yes, "yesPressed" },
+    { Qt::Key_No, "noPressed" },
+    { Qt::Key_Context1, "context1Pressed" },
+    { Qt::Key_Context2, "context2Pressed" },
+    { Qt::Key_Context3, "context3Pressed" },
+    { Qt::Key_Context4, "context4Pressed" },
+    { Qt::Key_Call, "callPressed" },
+    { Qt::Key_Hangup, "hangupPressed" },
+    { Qt::Key_Flip, "flipPressed" },
+    { Qt::Key_Menu, "menuPressed" },
+    { Qt::Key_VolumeUp, "volumeUpPressed" },
+    { Qt::Key_VolumeDown, "volumeDownPressed" },
+    { 0, 0 }
+};
+
+bool QQuickKeysAttachedPrivate::isConnected(const char *signalName)
+{
+    return isSignalConnected(signalIndex(signalName));
+}
+
+/*!
+    \qmlclass Keys QQuickKeysAttached
+    \inqmlmodule QtQuick 2
+    \ingroup qml-basic-interaction-elements
+    \brief The Keys attached property provides key handling to Items.
+
+    All visual primitives support key handling via the Keys
+    attached property.  Keys can be handled via the onPressed
+    and onReleased signal properties.
+
+    The signal properties have a \l KeyEvent parameter, named
+    \e event which contains details of the event.  If a key is
+    handled \e event.accepted should be set to true to prevent the
+    event from propagating up the item hierarchy.
+
+    \section1 Example Usage
+
+    The following example shows how the general onPressed handler can
+    be used to test for a certain key; in this case, the left cursor
+    key:
+
+    \snippet doc/src/snippets/declarative/keys/keys-pressed.qml key item
+
+    Some keys may alternatively be handled via specific signal properties,
+    for example \e onSelectPressed.  These handlers automatically set
+    \e event.accepted to true.
+
+    \snippet doc/src/snippets/declarative/keys/keys-handler.qml key item
+
+    See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
+
+    \section1 Key Handling Priorities
+
+    The Keys attached property can be configured to handle key events
+    before or after the item it is attached to. This makes it possible
+    to intercept events in order to override an item's default behavior,
+    or act as a fallback for keys not handled by the item.
+
+    If \l priority is Keys.BeforeItem (default) the order of key event processing is:
+
+    \list 1
+    \o Items specified in \c forwardTo
+    \o specific key handlers, e.g. onReturnPressed
+    \o onKeyPress, onKeyRelease handlers
+    \o Item specific key handling, e.g. TextInput key handling
+    \o parent item
+    \endlist
+
+    If priority is Keys.AfterItem the order of key event processing is:
+
+    \list 1
+    \o Item specific key handling, e.g. TextInput key handling
+    \o Items specified in \c forwardTo
+    \o specific key handlers, e.g. onReturnPressed
+    \o onKeyPress, onKeyRelease handlers
+    \o parent item
+    \endlist
+
+    If the event is accepted during any of the above steps, key
+    propagation stops.
+
+    \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::Keys::enabled
+
+    This flags enables key handling if true (default); otherwise
+    no key handlers will be called.
+*/
+
+/*!
+    \qmlproperty enumeration QtQuick2::Keys::priority
+
+    This property determines whether the keys are processed before
+    or after the attached item's own key handling.
+
+    \list
+    \o Keys.BeforeItem (default) - process the key events before normal
+    item key processing.  If the event is accepted it will not
+    be passed on to the item.
+    \o Keys.AfterItem - process the key events after normal item key
+    handling.  If the item accepts the key event it will not be
+    handled by the Keys attached property handler.
+    \endlist
+*/
+
+/*!
+    \qmlproperty list<Object> QtQuick2::Keys::forwardTo
+
+    This property provides a way to forward key presses, key releases, and keyboard input
+    coming from input methods to other items. This can be useful when you want
+    one item to handle some keys (e.g. the up and down arrow keys), and another item to
+    handle other keys (e.g. the left and right arrow keys).  Once an item that has been
+    forwarded keys accepts the event it is no longer forwarded to items later in the
+    list.
+
+    This example forwards key events to two lists:
+    \qml
+    Item {
+        ListView {
+            id: list1
+            // ...
+        }
+        ListView {
+            id: list2
+            // ...
+        }
+        Keys.forwardTo: [list1, list2]
+        focus: true
+    }
+    \endqml
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
+
+    This handler is called when a key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
+
+    This handler is called when a key has been released. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
+
+    This handler is called when the digit '0' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
+
+    This handler is called when the digit '1' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
+
+    This handler is called when the digit '2' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
+
+    This handler is called when the digit '3' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
+
+    This handler is called when the digit '4' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
+
+    This handler is called when the digit '5' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
+
+    This handler is called when the digit '6' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
+
+    This handler is called when the digit '7' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
+
+    This handler is called when the digit '8' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
+
+    This handler is called when the digit '9' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
+
+    This handler is called when the Left arrow has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
+
+    This handler is called when the Right arrow has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
+
+    This handler is called when the Up arrow has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
+
+    This handler is called when the Down arrow has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
+
+    This handler is called when the Tab key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
+
+    This handler is called when the Shift+Tab key combination (Backtab) has
+    been pressed. The \a event parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
+
+    This handler is called when the Asterisk '*' has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
+
+    This handler is called when the Escape key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
+
+    This handler is called when the Return key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
+
+    This handler is called when the Enter key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
+
+    This handler is called when the Delete key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
+
+    This handler is called when the Space key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
+
+    This handler is called when the Back key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
+
+    This handler is called when the Cancel key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
+
+    This handler is called when the Select key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
+
+    This handler is called when the Yes key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
+
+    This handler is called when the No key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
+
+    This handler is called when the Context1 key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
+
+    This handler is called when the Context2 key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
+
+    This handler is called when the Context3 key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
+
+    This handler is called when the Context4 key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
+
+    This handler is called when the Call key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
+
+    This handler is called when the Hangup key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
+
+    This handler is called when the Flip key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
+
+    This handler is called when the Menu key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
+
+    This handler is called when the VolumeUp key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
+
+    This handler is called when the VolumeDown key has been pressed. The \a event
+    parameter provides information about the event.
+*/
+
+QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
+: QObject(*(new QQuickKeysAttachedPrivate), parent),
+  QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
+{
+    Q_D(QQuickKeysAttached);
+    m_processPost = false;
+    d->item = qobject_cast<QQuickItem*>(parent);
+}
+
+QQuickKeysAttached::~QQuickKeysAttached()
+{
+}
+
+QQuickKeysAttached::Priority QQuickKeysAttached::priority() const
+{
+    return m_processPost ? AfterItem : BeforeItem;
+}
+
+void QQuickKeysAttached::setPriority(Priority order)
+{
+    bool processPost = order == AfterItem;
+    if (processPost != m_processPost) {
+        m_processPost = processPost;
+        emit priorityChanged();
+    }
+}
+
+void QQuickKeysAttached::componentComplete()
+{
+    Q_D(QQuickKeysAttached);
+    if (d->item) {
+        for (int ii = 0; ii < d->targets.count(); ++ii) {
+            QQuickItem *targetItem = d->targets.at(ii);
+            if (targetItem && (targetItem->flags() & QQuickItem::ItemAcceptsInputMethod)) {
+                d->item->setFlag(QQuickItem::ItemAcceptsInputMethod);
+                break;
+            }
+        }
+    }
+}
+
+void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
+{
+    Q_D(QQuickKeysAttached);
+    if (post != m_processPost || !d->enabled || d->inPress) {
+        event->ignore();
+        QQuickItemKeyFilter::keyPressed(event, post);
+        return;
+    }
+
+    // first process forwards
+    if (d->item && d->item->canvas()) {
+        d->inPress = true;
+        for (int ii = 0; ii < d->targets.count(); ++ii) {
+            QQuickItem *i = d->targets.at(ii);
+            if (i && i->isVisible()) {
+                d->item->canvas()->sendEvent(i, event);
+                if (event->isAccepted()) {
+                    d->inPress = false;
+                    return;
+                }
+            }
+        }
+        d->inPress = false;
+    }
+
+    QQuickKeyEvent ke(*event);
+    QByteArray keySignal = keyToSignal(event->key());
+    if (!keySignal.isEmpty()) {
+        keySignal += "(QQuickKeyEvent*)";
+        if (d->isConnected(keySignal)) {
+            // If we specifically handle a key then default to accepted
+            ke.setAccepted(true);
+            int idx = QQuickKeysAttached::staticMetaObject.indexOfSignal(keySignal);
+            metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QQuickKeyEvent*, &ke));
+        }
+    }
+    if (!ke.isAccepted())
+        emit pressed(&ke);
+    event->setAccepted(ke.isAccepted());
+
+    if (!event->isAccepted()) QQuickItemKeyFilter::keyPressed(event, post);
+}
+
+void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
+{
+    Q_D(QQuickKeysAttached);
+    if (post != m_processPost || !d->enabled || d->inRelease) {
+        event->ignore();
+        QQuickItemKeyFilter::keyReleased(event, post);
+        return;
+    }
+
+    if (d->item && d->item->canvas()) {
+        d->inRelease = true;
+        for (int ii = 0; ii < d->targets.count(); ++ii) {
+            QQuickItem *i = d->targets.at(ii);
+            if (i && i->isVisible()) {
+                d->item->canvas()->sendEvent(i, event);
+                if (event->isAccepted()) {
+                    d->inRelease = false;
+                    return;
+                }
+            }
+        }
+        d->inRelease = false;
+    }
+
+    QQuickKeyEvent ke(*event);
+    emit released(&ke);
+    event->setAccepted(ke.isAccepted());
+
+    if (!event->isAccepted()) QQuickItemKeyFilter::keyReleased(event, post);
+}
+
+void QQuickKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
+{
+    Q_D(QQuickKeysAttached);
+    if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
+        d->inIM = true;
+        for (int ii = 0; ii < d->targets.count(); ++ii) {
+            QQuickItem *i = d->targets.at(ii);
+            if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod)) {
+                d->item->canvas()->sendEvent(i, event);
+                if (event->isAccepted()) {
+                    d->imeItem = i;
+                    d->inIM = false;
+                    return;
+                }
+            }
+        }
+        d->inIM = false;
+    }
+    QQuickItemKeyFilter::inputMethodEvent(event, post);
+}
+
+QVariant QQuickKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+    Q_D(const QQuickKeysAttached);
+    if (d->item) {
+        for (int ii = 0; ii < d->targets.count(); ++ii) {
+            QQuickItem *i = d->targets.at(ii);
+            if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod) && i == d->imeItem) {
+                //### how robust is i == d->imeItem check?
+                QVariant v = i->inputMethodQuery(query);
+                if (v.userType() == QVariant::RectF)
+                    v = d->item->mapRectFromItem(i, v.toRectF());  //### cost?
+                return v;
+            }
+        }
+    }
+    return QQuickItemKeyFilter::inputMethodQuery(query);
+}
+
+QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
+{
+    return new QQuickKeysAttached(obj);
+}
+
+/*!
+    \qmlclass LayoutMirroring QQuickLayoutMirroringAttached
+    \inqmlmodule QtQuick 2
+    \ingroup qml-utility-elements
+    \brief The LayoutMirroring attached property is used to mirror layout behavior.
+
+    The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
+    \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
+    and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
+    anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
+    horizontal layout of child items.
+
+    Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
+    only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
+    behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
+    for an item, mirroring is not enabled.
+
+    The following example shows mirroring in action. The \l Row below is specified as being anchored
+    to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
+    reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
+    from left to right by default, they are now positioned from right to left instead, as demonstrated
+    by the numbering and opacity of the items:
+
+    \snippet doc/src/snippets/declarative/layoutmirroring.qml 0
+
+    \image layoutmirroring.png
+
+    Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
+    layout versions of an application to target different language areas. The \l childrenInherit
+    property allows layout mirroring to be applied without manually setting layout configurations
+    for every item in an application. Keep in mind, however, that mirroring does not affect any
+    positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
+    mirroring enabled, it will often be necessary to apply some layout fixes to support the
+    desired layout direction. Also, it may be necessary to disable the mirroring of individual
+    child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
+    mirroring is not the desired behavior, or if the child item already implements mirroring in
+    some custom way.
+
+    See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
+    other related features to implement right-to-left support for an application.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::LayoutMirroring::enabled
+
+    This property holds whether the item's layout is mirrored horizontally. Setting this to true
+    horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
+    and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
+    (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
+    this also mirrors the horizontal layout direction of the item.
+
+    The default value is false.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
+
+    This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
+    is inherited by its children.
+
+    The default value is false.
+*/
+
+
+QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
+{
+    if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) {
+        itemPrivate = QQuickItemPrivate::get(item);
+        itemPrivate->attachedLayoutDirection = this;
+    } else
+        qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
+}
+
+QQuickLayoutMirroringAttached * QQuickLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
+{
+    return new QQuickLayoutMirroringAttached(object);
+}
+
+bool QQuickLayoutMirroringAttached::enabled() const
+{
+    return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
+}
+
+void QQuickLayoutMirroringAttached::setEnabled(bool enabled)
+{
+    if (!itemPrivate)
+        return;
+
+    itemPrivate->isMirrorImplicit = false;
+    if (enabled != itemPrivate->effectiveLayoutMirror) {
+        itemPrivate->setLayoutMirror(enabled);
+        if (itemPrivate->inheritMirrorFromItem)
+             itemPrivate->resolveLayoutMirror();
+    }
+}
+
+void QQuickLayoutMirroringAttached::resetEnabled()
+{
+    if (itemPrivate && !itemPrivate->isMirrorImplicit) {
+        itemPrivate->isMirrorImplicit = true;
+        itemPrivate->resolveLayoutMirror();
+    }
+}
+
+bool QQuickLayoutMirroringAttached::childrenInherit() const
+{
+    return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
+}
+
+void QQuickLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
+    if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
+        itemPrivate->inheritMirrorFromItem = childrenInherit;
+        itemPrivate->resolveLayoutMirror();
+        childrenInheritChanged();
+    }
+}
+
+void QQuickItemPrivate::resolveLayoutMirror()
+{
+    Q_Q(QQuickItem);
+    if (QQuickItem *parentItem = q->parentItem()) {
+        QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parentItem);
+        setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
+    } else {
+        setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
+    }
+}
+
+void QQuickItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
+{
+    inherit = inherit || inheritMirrorFromItem;
+    if (!isMirrorImplicit && inheritMirrorFromItem)
+        mirror = effectiveLayoutMirror;
+    if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
+        return;
+
+    inheritMirrorFromParent = inherit;
+    inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
+
+    if (isMirrorImplicit)
+        setLayoutMirror(inherit ? inheritedLayoutMirror : false);
+    for (int i = 0; i < childItems.count(); ++i) {
+        if (QQuickItem *child = qobject_cast<QQuickItem *>(childItems.at(i))) {
+            QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
+            childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
+        }
+    }
+}
+
+void QQuickItemPrivate::setLayoutMirror(bool mirror)
+{
+    if (mirror != effectiveLayoutMirror) {
+        effectiveLayoutMirror = mirror;
+        if (_anchors) {
+            QQuickAnchorsPrivate *anchor_d = QQuickAnchorsPrivate::get(_anchors);
+            anchor_d->fillChanged();
+            anchor_d->centerInChanged();
+            anchor_d->updateHorizontalAnchors();
+            emit _anchors->mirroredChanged();
+        }
+        mirrorChange();
+        if (attachedLayoutDirection) {
+            emit attachedLayoutDirection->enabledChanged();
+        }
+    }
+}
+
+/*!
+    \class QQuickItem
+    \brief The QQuickItem class provides the most basic of all visual items in QML.
+
+    All visual items in Qt Declarative inherit from QQuickItem.  Although QQuickItem
+    has no visual appearance, it defines all the properties that are
+    common across visual items - such as the x and y position, the
+    width and height, \l {anchor-layout}{anchoring} and key handling.
+
+    You can subclass QQuickItem to provide your own custom visual item that inherits
+    these features. Note that, because it does not draw anything, QQuickItem sets the
+    QGraphicsItem::ItemHasNoContents flag. If you subclass QQuickItem to create a visual
+    item, you will need to unset this flag.
+
+*/
+
+/*!
+    \qmlclass Item QQuickItem
+    \inqmlmodule QtQuick 2
+    \ingroup qml-basic-visual-elements
+    \brief The Item is the most basic of all visual items in QML.
+
+    All visual items in Qt Declarative inherit from Item.  Although Item
+    has no visual appearance, it defines all the properties that are
+    common across visual items - such as the x and y position, the
+    width and height, \l {anchor-layout}{anchoring} and key handling.
+
+    Item is also useful for grouping items together.
+
+    \qml
+    Item {
+        Image {
+            source: "tile.png"
+        }
+        Image {
+            x: 80
+            width: 100
+            height: 100
+            source: "tile.png"
+        }
+        Image {
+            x: 190
+            width: 100
+            height: 100
+            fillMode: Image.Tile
+            source: "tile.png"
+        }
+    }
+    \endqml
+
+
+    \section1 Key Handling
+
+    Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
+    attached property.  The \e Keys attached property provides basic handlers such
+    as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
+    as well as handlers for specific keys, such as
+    \l {Keys::onCancelPressed}{onCancelPressed}.  The example below
+    assigns \l {qmlfocus}{focus} to the item and handles
+    the Left key via the general \e onPressed handler and the Select key via the
+    onSelectPressed handler:
+
+    \qml
+    Item {
+        focus: true
+        Keys.onPressed: {
+            if (event.key == Qt.Key_Left) {
+                console.log("move left");
+                event.accepted = true;
+            }
+        }
+        Keys.onSelectPressed: console.log("Selected");
+    }
+    \endqml
+
+    See the \l {Keys}{Keys} attached property for detailed documentation.
+
+    \section1 Layout Mirroring
+
+    Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
+
+*/
+
+/*!
+    \fn void QQuickItem::childrenRectChanged(const QRectF &)
+    \internal
+*/
+
+/*!
+    \fn void QQuickItem::baselineOffsetChanged(qreal)
+    \internal
+*/
+
+/*!
+    \fn void QQuickItem::stateChanged(const QString &state)
+    \internal
+*/
+
+/*!
+    \fn void QQuickItem::parentChanged(QQuickItem *)
+    \internal
+*/
+
+/*!
+    \fn void QQuickItem::smoothChanged(bool)
+    \internal
+*/
+
+/*!
+    \fn void QQuickItem::clipChanged(bool)
+    \internal
+*/
+
+/*! \fn void QQuickItem::transformOriginChanged(TransformOrigin)
+  \internal
+*/
+
+/*!
+    \fn void QQuickItem::focusChanged(bool)
+    \internal
+*/
+
+/*!
+    \fn void QQuickItem::activeFocusChanged(bool)
+    \internal
+*/
+/*!
+    \fn QQuickItem::QQuickItem(QQuickItem *parent)
+
+    Constructs a QQuickItem with the given \a parent.
+*/
+QQuickItem::QQuickItem(QQuickItem* parent)
+: QObject(*(new QQuickItemPrivate), parent)
+{
+    Q_D(QQuickItem);
+    d->init(parent);
+}
+
+/*! \internal
+*/
+QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
+: QObject(dd, parent)
+{
+    Q_D(QQuickItem);
+    d->init(parent);
+}
+
+#ifndef QT_NO_DEBUG
+static int qt_item_count = 0;
+
+static void qt_print_item_count()
+{
+    qDebug("Number of leaked items: %i", qt_item_count);
+    qt_item_count = -1;
+}
+#endif
+
+/*!
+    Destroys the QQuickItem.
+*/
+QQuickItem::~QQuickItem()
+{
+#ifndef QT_NO_DEBUG
+    --qt_item_count;
+    if (qt_item_count < 0)
+        qDebug("Item destroyed after qt_print_item_count() was called.");
+#endif
+
+    Q_D(QQuickItem);
+
+    if (d->parentItem)
+        setParentItem(0);
+    else if (d->canvas && d->itemNodeInstance)
+        QQuickCanvasPrivate::get(d->canvas)->cleanup(d->itemNodeInstance); // cleanup root
+    // XXX todo - optimize
+    while (!d->childItems.isEmpty())
+        d->childItems.first()->setParentItem(0);
+
+    for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
+        QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
+        if (anchor)
+            anchor->clearItem(this);
+    }
+
+    // XXX todo - the original checks if the parent is being destroyed
+    for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
+        QQuickAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
+        if (anchor && anchor->item && anchor->item->parent() != this) //child will be deleted anyway
+            anchor->updateOnComplete();
+    }
+
+    for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
+        const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
+        if (change.types & QQuickItemPrivate::Destroyed)
+            change.listener->itemDestroyed(this);
+    }
+    d->changeListeners.clear();
+    delete d->_anchorLines; d->_anchorLines = 0;
+    delete d->_anchors; d->_anchors = 0;
+    delete d->_stateGroup; d->_stateGroup = 0;
+    delete d->_contents; d->_contents = 0;
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::Item::transformOrigin
+    This property holds the origin point around which scale and rotation transform.
+
+    Nine transform origins are available, as shown in the image below.
+
+    \image declarative-transformorigin.png
+
+    This example rotates an image around its bottom-right corner.
+    \qml
+    Image {
+        source: "myimage.png"
+        transformOrigin: Item.BottomRight
+        rotation: 45
+    }
+    \endqml
+
+    The default transform origin is \c Item.Center.
+
+    To set an arbitrary transform origin point use the \l Scale or \l Rotation
+    transform elements.
+*/
+
+/*!
+    \qmlproperty Item QtQuick2::Item::parent
+    This property holds the parent of the item.
+*/
+
+/*!
+    \property QQuickItem::parent
+    This property holds the parent of the item.
+*/
+void QQuickItem::setParentItem(QQuickItem *parentItem)
+{
+    Q_D(QQuickItem);
+    if (parentItem == d->parentItem)
+        return;
+
+    d->removeFromDirtyList();
+
+    QQuickItem *oldParentItem = d->parentItem;
+    QQuickItem *scopeFocusedItem = 0;
+
+    if (oldParentItem) {
+        QQuickItemPrivate *op = QQuickItemPrivate::get(oldParentItem);
+
+        QQuickItem *scopeItem = 0;
+
+        if (d->canvas && hasFocus()) {
+            scopeItem = oldParentItem;
+            while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
+            scopeFocusedItem = this;
+        } else if (d->canvas && !isFocusScope() && d->subFocusItem) {
+            scopeItem = oldParentItem;
+            while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
+            scopeFocusedItem = d->subFocusItem;
+        }
+
+        if (scopeFocusedItem)
+            QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
+                                                                QQuickCanvasPrivate::DontChangeFocusProperty);
+
+        op->removeChild(this);
+    }
+
+    d->parentItem = parentItem;
+
+    QQuickCanvas *parentCanvas = parentItem?QQuickItemPrivate::get(parentItem)->canvas:0;
+    if (d->canvas != parentCanvas) {
+        QQuickItemPrivate::InitializationState initState;
+        initState.clear();
+        d->initCanvas(&initState, parentCanvas);
+    }
+
+    d->dirty(QQuickItemPrivate::ParentChanged);
+
+    if (d->parentItem)
+        QQuickItemPrivate::get(d->parentItem)->addChild(this);
+
+    d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
+    d->setEffectiveEnableRecur(d->calcEffectiveEnable());
+
+    if (scopeFocusedItem && d->parentItem && d->canvas) {
+        // We need to test whether this item becomes scope focused
+        QQuickItem *scopeItem = 0;
+        scopeItem = d->parentItem;
+        while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
+
+        if (scopeItem->scopedFocusItem()) {
+            QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
+            emit scopeFocusedItem->focusChanged(false);
+        } else {
+            QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
+                                                              QQuickCanvasPrivate::DontChangeFocusProperty);
+        }
+    }
+
+    d->resolveLayoutMirror();
+
+    d->itemChange(ItemParentHasChanged, d->parentItem);
+
+    emit parentChanged(d->parentItem);
+}
+
+void QQuickItem::stackBefore(const QQuickItem *sibling)
+{
+    Q_D(QQuickItem);
+    if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
+        qWarning("QQuickItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
+        return;
+    }
+
+    QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
+
+    int myIndex = parentPrivate->childItems.indexOf(this);
+    int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
+
+    Q_ASSERT(myIndex != -1 && siblingIndex != -1);
+
+    if (myIndex == siblingIndex - 1)
+        return;
+
+    parentPrivate->childItems.removeAt(myIndex);
+
+    if (myIndex < siblingIndex) --siblingIndex;
+
+    parentPrivate->childItems.insert(siblingIndex, this);
+
+    parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
+
+    for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
+        QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
+}
+
+void QQuickItem::stackAfter(const QQuickItem *sibling)
+{
+    Q_D(QQuickItem);
+    if (!sibling || sibling == this || !d->parentItem || d->parentItem != QQuickItemPrivate::get(sibling)->parentItem) {
+        qWarning("QQuickItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
+        return;
+    }
+
+    QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
+
+    int myIndex = parentPrivate->childItems.indexOf(this);
+    int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
+
+    Q_ASSERT(myIndex != -1 && siblingIndex != -1);
+
+    if (myIndex == siblingIndex + 1)
+        return;
+
+    parentPrivate->childItems.removeAt(myIndex);
+
+    if (myIndex < siblingIndex) --siblingIndex;
+
+    parentPrivate->childItems.insert(siblingIndex + 1, this);
+
+    parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
+
+    for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
+        QQuickItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
+}
+
+/*!
+    Returns the QQuickItem parent of this item.
+*/
+QQuickItem *QQuickItem::parentItem() const
+{
+    Q_D(const QQuickItem);
+    return d->parentItem;
+}
+
+QSGEngine *QQuickItem::sceneGraphEngine() const
+{
+    return canvas()->sceneGraphEngine();
+}
+
+QQuickCanvas *QQuickItem::canvas() const
+{
+    Q_D(const QQuickItem);
+    return d->canvas;
+}
+
+static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
+{
+    return lhs->z() < rhs->z();
+}
+
+QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
+{
+    // XXX todo - optimize, don't sort and return items that are
+    // ignored anyway, like invisible or disabled items.
+    QList<QQuickItem *> items = childItems;
+    qStableSort(items.begin(), items.end(), itemZOrder_sort);
+    return items;
+}
+
+void QQuickItemPrivate::addChild(QQuickItem *child)
+{
+    Q_Q(QQuickItem);
+
+    Q_ASSERT(!childItems.contains(child));
+
+    childItems.append(child);
+
+    dirty(QQuickItemPrivate::ChildrenChanged);
+
+    itemChange(QQuickItem::ItemChildAddedChange, child);
+
+    emit q->childrenChanged();
+}
+
+void QQuickItemPrivate::removeChild(QQuickItem *child)
+{
+    Q_Q(QQuickItem);
+
+    Q_ASSERT(child);
+    Q_ASSERT(childItems.contains(child));
+    childItems.removeOne(child);
+    Q_ASSERT(!childItems.contains(child));
+
+    dirty(QQuickItemPrivate::ChildrenChanged);
+
+    itemChange(QQuickItem::ItemChildRemovedChange, child);
+
+    emit q->childrenChanged();
+}
+
+void QQuickItemPrivate::InitializationState::clear()
+{
+    focusScope = 0;
+}
+
+void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
+{
+    focusScope = fs;
+}
+
+QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
+{
+    if (!focusScope) {
+        QQuickItem *fs = item->parentItem();
+        while (!fs->isFocusScope())
+            fs = fs->parentItem();
+        focusScope = fs;
+    }
+    return focusScope;
+}
+
+void QQuickItemPrivate::initCanvas(InitializationState *state, QQuickCanvas *c)
+{
+    Q_Q(QQuickItem);
+
+    if (canvas) {
+        removeFromDirtyList();
+        QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
+        if (polishScheduled)
+            c->itemsToPolish.remove(q);
+        if (c->mouseGrabberItem == q)
+            c->mouseGrabberItem = 0;
+        if ( hoverEnabled )
+            c->hoverItems.removeAll(q);
+        if (itemNodeInstance)
+            c->cleanup(itemNodeInstance);
+    }
+
+    canvas = c;
+
+    if (canvas && polishScheduled)
+        QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
+
+    itemNodeInstance = 0;
+    opacityNode = 0;
+    clipNode = 0;
+    rootNode = 0;
+    groupNode = 0;
+    paintNode = 0;
+    beforePaintNode = 0;
+
+    InitializationState _dummy;
+    InitializationState *childState = state;
+
+    if (c && q->isFocusScope()) {
+        _dummy.clear(q);
+        childState = &_dummy;
+    }
+
+    for (int ii = 0; ii < childItems.count(); ++ii) {
+        QQuickItem *child = childItems.at(ii);
+        QQuickItemPrivate::get(child)->initCanvas(childState, c);
+    }
+
+    if (c && focus) {
+        // Fixup
+        if (state->getFocusScope(q)->scopedFocusItem()) {
+            focus = false;
+            emit q->focusChanged(false);
+        } else {
+            QQuickCanvasPrivate::get(canvas)->setFocusInScope(state->getFocusScope(q), q);
+        }
+    }
+
+    dirty(Canvas);
+
+    itemChange(QQuickItem::ItemSceneChange, c);
+}
+
+/*!
+Returns a transform that maps points from canvas space into item space.
+*/
+QTransform QQuickItemPrivate::canvasToItemTransform() const
+{
+    // XXX todo - optimize
+    return itemToCanvasTransform().inverted();
+}
+
+/*!
+Returns a transform that maps points from item space into canvas space.
+*/
+QTransform QQuickItemPrivate::itemToCanvasTransform() const
+{
+    // XXX todo
+    QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
+    itemToParentTransform(rv);
+    return rv;
+}
+
+/*!
+Motifies \a t with this items local transform relative to its parent.
+*/
+void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
+{
+    if (x || y)
+        t.translate(x, y);
+
+    if (!transforms.isEmpty()) {
+        QMatrix4x4 m(t);
+        for (int ii = transforms.count() - 1; ii >= 0; --ii)
+            transforms.at(ii)->applyTo(&m);
+        t = m.toTransform();
+    }
+
+    if (scale != 1. || rotation != 0.) {
+        QPointF tp = computeTransformOrigin();
+        t.translate(tp.x(), tp.y());
+        t.scale(scale, scale);
+        t.rotate(rotation);
+        t.translate(-tp.x(), -tp.y());
+    }
+}
+
+
+/*!
+    \qmlproperty real QtQuick2::Item::childrenRect.x
+    \qmlproperty real QtQuick2::Item::childrenRect.y
+    \qmlproperty real QtQuick2::Item::childrenRect.width
+    \qmlproperty real QtQuick2::Item::childrenRect.height
+
+    The childrenRect properties allow an item access to the geometry of its
+    children. This property is useful if you have an item that needs to be
+    sized to fit its children.
+*/
+
+
+/*!
+    \qmlproperty list<Item> QtQuick2::Item::children
+    \qmlproperty list<Object> QtQuick2::Item::resources
+
+    The children property contains the list of visual children of this item.
+    The resources property contains non-visual resources that you want to
+    reference by name.
+
+    Generally you can rely on Item's default property to handle all this for
+    you, but it can come in handy in some cases.
+
+    \qml
+    Item {
+        children: [
+            Text {},
+            Rectangle {}
+        ]
+        resources: [
+            Component {
+                id: myComponent
+                Text {}
+            }
+        ]
+    }
+    \endqml
+*/
+
+/*!
+    Returns true if construction of the QML component is complete; otherwise
+    returns false.
+
+    It is often desirable to delay some processing until the component is
+    completed.
+
+    \sa componentComplete()
+*/
+bool QQuickItem::isComponentComplete() const
+{
+    Q_D(const QQuickItem);
+    return d->componentComplete;
+}
+
+QQuickItemPrivate::QQuickItemPrivate()
+: _anchors(0), _contents(0), baselineOffset(0), _anchorLines(0), _stateGroup(0), origin(QQuickItem::Center),
+
+  flags(0), widthValid(false), heightValid(false), componentComplete(true),
+  keepMouse(false), hoverEnabled(false), smooth(false), focus(false), activeFocus(false), notifiedFocus(false),
+  notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
+  effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
+  inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
+  inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
+
+  canvas(0), parentItem(0),
+
+  subFocusItem(0),
+
+  x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
+  z(0), scale(1), rotation(0), opacity(1),
+
+  attachedLayoutDirection(0), acceptedMouseButtons(0),
+  imHints(Qt::ImhMultiLine),
+
+  keyHandler(0),
+
+  dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
+
+  itemNodeInstance(0), opacityNode(0), clipNode(0), rootNode(0), groupNode(0), paintNode(0)
+  , beforePaintNode(0), effectRefCount(0), hideRefCount(0)
+{
+}
+
+void QQuickItemPrivate::init(QQuickItem *parent)
+{
+#ifndef QT_NO_DEBUG
+    ++qt_item_count;
+    static bool atexit_registered = false;
+    if (!atexit_registered) {
+        atexit(qt_print_item_count);
+        atexit_registered = true;
+    }
+#endif
+
+    Q_Q(QQuickItem);
+    baselineOffset.invalidate();
+
+    if (parent) {
+        q->setParentItem(parent);
+        QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent);
+        setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
+    }
+}
+
+void QQuickItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
+{
+    if (!o)
+        return;
+
+    QQuickItem *that = static_cast<QQuickItem *>(prop->object);
+
+    // This test is measurably (albeit only slightly) faster than qobject_cast<>()
+    const QMetaObject *mo = o->metaObject();
+    while (mo && mo != &QQuickItem::staticMetaObject) {
+        mo = mo->d.superdata;
+    }
+
+    if (mo) {
+        QQuickItem *item = static_cast<QQuickItem *>(o);
+        item->setParentItem(that);
+    } else {
+        if (o->inherits("QGraphicsItem"))
+            qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
+
+        // XXX todo - do we really want this behavior?
+        o->setParent(that);
+    }
+}
+
+/*!
+    \qmlproperty list<Object> QtQuick2::Item::data
+    \default
+
+    The data property allows you to freely mix visual children and resources
+    in an item.  If you assign a visual item to the data list it becomes
+    a child and if you assign any other object type, it is added as a resource.
+
+    So you can write:
+    \qml
+    Item {
+        Text {}
+        Rectangle {}
+        Timer {}
+    }
+    \endqml
+
+    instead of:
+    \qml
+    Item {
+        children: [
+            Text {},
+            Rectangle {}
+        ]
+        resources: [
+            Timer {}
+        ]
+    }
+    \endqml
+
+    data is a behind-the-scenes property: you should never need to explicitly
+    specify it.
+ */
+
+int QQuickItemPrivate::data_count(QDeclarativeListProperty<QObject> *prop)
+{
+    Q_UNUSED(prop);
+    // XXX todo
+    return 0;
+}
+
+QObject *QQuickItemPrivate::data_at(QDeclarativeListProperty<QObject> *prop, int i)
+{
+    Q_UNUSED(prop);
+    Q_UNUSED(i);
+    // XXX todo
+    return 0;
+}
+
+void QQuickItemPrivate::data_clear(QDeclarativeListProperty<QObject> *prop)
+{
+    Q_UNUSED(prop);
+    // XXX todo
+}
+
+QObject *QQuickItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index)
+{
+    const QObjectList children = prop->object->children();
+    if (index < children.count())
+        return children.at(index);
+    else
+        return 0;
+}
+
+void QQuickItemPrivate::resources_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
+{
+    // XXX todo - do we really want this behavior?
+    o->setParent(prop->object);
+}
+
+int QQuickItemPrivate::resources_count(QDeclarativeListProperty<QObject> *prop)
+{
+    return prop->object->children().count();
+}
+
+void QQuickItemPrivate::resources_clear(QDeclarativeListProperty<QObject> *prop)
+{
+    // XXX todo - do we really want this behavior?
+    const QObjectList children = prop->object->children();
+    for (int index = 0; index < children.count(); index++)
+        children.at(index)->setParent(0);
+}
+
+QQuickItem *QQuickItemPrivate::children_at(QDeclarativeListProperty<QQuickItem> *prop, int index)
+{
+    QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
+    if (index >= p->childItems.count() || index < 0)
+        return 0;
+    else
+        return p->childItems.at(index);
+}
+
+void QQuickItemPrivate::children_append(QDeclarativeListProperty<QQuickItem> *prop, QQuickItem *o)
+{
+    if (!o)
+        return;
+
+    QQuickItem *that = static_cast<QQuickItem *>(prop->object);
+    if (o->parentItem() == that)
+        o->setParentItem(0);
+
+    o->setParentItem(that);
+}
+
+int QQuickItemPrivate::children_count(QDeclarativeListProperty<QQuickItem> *prop)
+{
+    QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
+    return p->childItems.count();
+}
+
+void QQuickItemPrivate::children_clear(QDeclarativeListProperty<QQuickItem> *prop)
+{
+    QQuickItem *that = static_cast<QQuickItem *>(prop->object);
+    QQuickItemPrivate *p = QQuickItemPrivate::get(that);
+    while (!p->childItems.isEmpty())
+        p->childItems.at(0)->setParentItem(0);
+}
+
+int QQuickItemPrivate::transform_count(QDeclarativeListProperty<QQuickTransform> *prop)
+{
+    QQuickItem *that = static_cast<QQuickItem *>(prop->object);
+    return QQuickItemPrivate::get(that)->transforms.count();
+}
+
+void QQuickTransform::appendToItem(QQuickItem *item)
+{
+    Q_D(QQuickTransform);
+    if (!item)
+        return;
+
+    QQuickItemPrivate *p = QQuickItemPrivate::get(item);
+
+    if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
+        p->transforms.removeOne(this);
+        p->transforms.append(this);
+    } else {
+        p->transforms.append(this);
+        d->items.append(item);
+    }
+
+    p->dirty(QQuickItemPrivate::Transform);
+}
+
+void QQuickTransform::prependToItem(QQuickItem *item)
+{
+    Q_D(QQuickTransform);
+    if (!item)
+        return;
+
+    QQuickItemPrivate *p = QQuickItemPrivate::get(item);
+
+    if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
+        p->transforms.removeOne(this);
+        p->transforms.prepend(this);
+    } else {
+        p->transforms.prepend(this);
+        d->items.append(item);
+    }
+
+    p->dirty(QQuickItemPrivate::Transform);
+}
+
+void QQuickItemPrivate::transform_append(QDeclarativeListProperty<QQuickTransform> *prop, QQuickTransform *transform)
+{
+    if (!transform)
+        return;
+
+    QQuickItem *that = static_cast<QQuickItem *>(prop->object);
+    transform->appendToItem(that);
+}
+
+QQuickTransform *QQuickItemPrivate::transform_at(QDeclarativeListProperty<QQuickTransform> *prop, int idx)
+{
+    QQuickItem *that = static_cast<QQuickItem *>(prop->object);
+    QQuickItemPrivate *p = QQuickItemPrivate::get(that);
+
+    if (idx < 0 || idx >= p->transforms.count())
+        return 0;
+    else
+        return p->transforms.at(idx);
+}
+
+void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform> *prop)
+{
+    QQuickItem *that = static_cast<QQuickItem *>(prop->object);
+    QQuickItemPrivate *p = QQuickItemPrivate::get(that);
+
+    for (int ii = 0; ii < p->transforms.count(); ++ii) {
+        QQuickTransform *t = p->transforms.at(ii);
+        QQuickTransformPrivate *tp = QQuickTransformPrivate::get(t);
+        tp->items.removeOne(that);
+    }
+
+    p->transforms.clear();
+
+    p->dirty(QQuickItemPrivate::Transform);
+}
+
+/*!
+    \property QQuickItem::childrenRect
+    \brief The geometry of an item's children.
+
+    This property holds the (collective) position and size of the item's children.
+*/
+
+/*!
+  \qmlproperty real QtQuick2::Item::x
+  \qmlproperty real QtQuick2::Item::y
+  \qmlproperty real QtQuick2::Item::width
+  \qmlproperty real QtQuick2::Item::height
+
+  Defines the item's position and size relative to its parent.
+
+  \qml
+  Item { x: 100; y: 100; width: 100; height: 100 }
+  \endqml
+ */
+
+/*!
+  \qmlproperty real QtQuick2::Item::z
+
+  Sets the stacking order of sibling items.  By default the stacking order is 0.
+
+  Items with a higher stacking value are drawn on top of siblings with a
+  lower stacking order.  Items with the same stacking value are drawn
+  bottom up in the order they appear.  Items with a negative stacking
+  value are drawn under their parent's content.
+
+  The following example shows the various effects of stacking order.
+
+  \table
+  \row
+  \o \image declarative-item_stacking1.png
+  \o Same \c z - later children above earlier children:
+  \qml
+  Item {
+      Rectangle {
+          color: "red"
+          width: 100; height: 100
+      }
+      Rectangle {
+          color: "blue"
+          x: 50; y: 50; width: 100; height: 100
+      }
+  }
+  \endqml
+  \row
+  \o \image declarative-item_stacking2.png
+  \o Higher \c z on top:
+  \qml
+  Item {
+      Rectangle {
+          z: 1
+          color: "red"
+          width: 100; height: 100
+      }
+      Rectangle {
+          color: "blue"
+          x: 50; y: 50; width: 100; height: 100
+      }
+  }
+  \endqml
+  \row
+  \o \image declarative-item_stacking3.png
+  \o Same \c z - children above parents:
+  \qml
+  Item {
+      Rectangle {
+          color: "red"
+          width: 100; height: 100
+          Rectangle {
+              color: "blue"
+              x: 50; y: 50; width: 100; height: 100
+          }
+      }
+  }
+  \endqml
+  \row
+  \o \image declarative-item_stacking4.png
+  \o Lower \c z below:
+  \qml
+  Item {
+      Rectangle {
+          color: "red"
+          width: 100; height: 100
+          Rectangle {
+              z: -1
+              color: "blue"
+              x: 50; y: 50; width: 100; height: 100
+          }
+      }
+  }
+  \endqml
+  \endtable
+ */
+
+/*!
+    \qmlproperty bool QtQuick2::Item::visible
+
+    This property holds whether the item is visible. By default this is true.
+
+    Setting this property directly affects the \c visible value of child
+    items. When set to \c false, the \c visible values of all child items also
+    become \c false. When set to \c true, the \c visible values of child items
+    are returned to \c true, unless they have explicitly been set to \c false.
+
+    (Because of this flow-on behavior, using the \c visible property may not
+    have the intended effect if a property binding should only respond to
+    explicit property changes. In such cases it may be better to use the
+    \l opacity property instead.)
+
+    Setting this property to \c false automatically causes \l focus to be set
+    to \c false, and this item will longer receive mouse and keyboard events.
+    (In contrast, setting the \l opacity to 0 does not affect the \l focus
+    property and the receiving of key events.)
+
+    \note This property's value is only affected by changes to this property or
+    the parent's \c visible property. It does not change, for example, if this
+    item moves off-screen, or if the \l opacity changes to 0.
+*/
+
+
+/*!
+  \qmlproperty AnchorLine QtQuick2::Item::anchors.top
+  \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
+  \qmlproperty AnchorLine QtQuick2::Item::anchors.left
+  \qmlproperty AnchorLine QtQuick2::Item::anchors.right
+  \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
+  \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
+  \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
+
+  \qmlproperty Item QtQuick2::Item::anchors.fill
+  \qmlproperty Item QtQuick2::Item::anchors.centerIn
+
+  \qmlproperty real QtQuick2::Item::anchors.margins
+  \qmlproperty real QtQuick2::Item::anchors.topMargin
+  \qmlproperty real QtQuick2::Item::anchors.bottomMargin
+  \qmlproperty real QtQuick2::Item::anchors.leftMargin
+  \qmlproperty real QtQuick2::Item::anchors.rightMargin
+  \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
+  \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
+  \qmlproperty real QtQuick2::Item::anchors.baselineOffset
+
+  \qmlproperty bool QtQuick2::Item::anchors.mirrored
+
+  Anchors provide a way to position an item by specifying its
+  relationship with other items.
+
+  Margins apply to top, bottom, left, right, and fill anchors.
+  The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
+  Note that margins are anchor-specific and are not applied if an item does not
+  use anchors.
+
+  Offsets apply for horizontal center, vertical center, and baseline anchors.
+
+  \table
+  \row
+  \o \image declarative-anchors_example.png
+  \o Text anchored to Image, horizontally centered and vertically below, with a margin.
+  \qml
+  Item {
+      Image {
+          id: pic
+          // ...
+      }
+      Text {
+          id: label
+          anchors.horizontalCenter: pic.horizontalCenter
+          anchors.top: pic.bottom
+          anchors.topMargin: 5
+          // ...
+      }
+  }
+  \endqml
+  \row
+  \o \image declarative-anchors_example2.png
+  \o
+  Left of Text anchored to right of Image, with a margin. The y
+  property of both defaults to 0.
+
+  \qml
+  Item {
+      Image {
+          id: pic
+          // ...
+      }
+      Text {
+          id: label
+          anchors.left: pic.right
+          anchors.leftMargin: 5
+          // ...
+      }
+  }
+  \endqml
+  \endtable
+
+  \c anchors.fill provides a convenient way for one item to have the
+  same geometry as another item, and is equivalent to connecting all
+  four directional anchors.
+
+  To clear an anchor value, set it to \c undefined.
+
+  \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
+
+  \note You can only anchor an item to siblings or a parent.
+
+  For more information see \l {anchor-layout}{Anchor Layouts}.
+*/
+
+/*!
+  \property QQuickItem::baselineOffset
+  \brief The position of the item's baseline in local coordinates.
+
+  The baseline of a \l Text item is the imaginary line on which the text
+  sits. Controls containing text usually set their baseline to the
+  baseline of their text.
+
+  For non-text items, a default baseline offset of 0 is used.
+*/
+QQuickAnchors *QQuickItemPrivate::anchors() const
+{
+    if (!_anchors) {
+        Q_Q(const QQuickItem);
+        _anchors = new QQuickAnchors(const_cast<QQuickItem *>(q));
+        if (!componentComplete)
+            _anchors->classBegin();
+    }
+    return _anchors;
+}
+
+QQuickItemPrivate::AnchorLines *QQuickItemPrivate::anchorLines() const
+{
+    Q_Q(const QQuickItem);
+    if (!_anchorLines) _anchorLines =
+        new AnchorLines(const_cast<QQuickItem *>(q));
+    return _anchorLines;
+}
+
+void QQuickItemPrivate::siblingOrderChanged()
+{
+    Q_Q(QQuickItem);
+    for (int ii = 0; ii < changeListeners.count(); ++ii) {
+        const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
+        if (change.types & QQuickItemPrivate::SiblingOrder) {
+            change.listener->itemSiblingOrderChanged(q);
+        }
+    }
+}
+
+QDeclarativeListProperty<QObject> QQuickItemPrivate::data()
+{
+    return QDeclarativeListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
+                                             QQuickItemPrivate::data_count,
+                                             QQuickItemPrivate::data_at,
+                                             QQuickItemPrivate::data_clear);
+}
+
+QRectF QQuickItem::childrenRect()
+{
+    Q_D(QQuickItem);
+    if (!d->_contents) {
+        d->_contents = new QQuickContents(this);
+        if (d->componentComplete)
+            d->_contents->complete();
+    }
+    return d->_contents->rectF();
+}
+
+QList<QQuickItem *> QQuickItem::childItems() const
+{
+    Q_D(const QQuickItem);
+    return d->childItems;
+}
+
+bool QQuickItem::clip() const
+{
+    return flags() & ItemClipsChildrenToShape;
+}
+
+void QQuickItem::setClip(bool c)
+{
+    if (clip() == c)
+        return;
+
+    setFlag(ItemClipsChildrenToShape, c);
+
+    emit clipChanged(c);
+}
+
+
+/*!
+  This function is called to handle this item's changes in
+  geometry from \a oldGeometry to \a newGeometry. If the two
+  geometries are the same, it doesn't do anything.
+ */
+void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+    Q_D(QQuickItem);
+
+    if (d->_anchors)
+        QQuickAnchorsPrivate::get(d->_anchors)->updateMe();
+
+    for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
+        const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
+        if (change.types & QQuickItemPrivate::Geometry)
+            change.listener->itemGeometryChanged(this, newGeometry, oldGeometry);
+    }
+
+    if (newGeometry.x() != oldGeometry.x())
+        emit xChanged();
+    if (newGeometry.y() != oldGeometry.y())
+        emit yChanged();
+    if (newGeometry.width() != oldGeometry.width())
+        emit widthChanged();
+    if (newGeometry.height() != oldGeometry.height())
+        emit heightChanged();
+}
+
+/*!
+    Called by the rendering thread when it is time to sync the state of the QML objects with the
+    scene graph objects. The function should return the root of the scene graph subtree for
+    this item. \a oldNode is the node that was returned the last time the function was called.
+
+    The main thread is blocked while this function is executed so it is safe to read
+    values from the QQuickItem instance and other objects in the main thread.
+
+    \warning This is the only function in which it is allowed to make use of scene graph
+    objects from the main thread. Use of scene graph objects outside this function will
+    result in race conditions and potential crashes.
+ */
+
+QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+    delete oldNode;
+    return 0;
+}
+
+QSGTransformNode *QQuickItemPrivate::createTransformNode()
+{
+    return new QSGTransformNode;
+}
+
+void QQuickItem::updatePolish()
+{
+}
+
+void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
+{
+    ChangeListener change(listener, types);
+    changeListeners.removeOne(change);
+}
+
+void QQuickItem::keyPressEvent(QKeyEvent *event)
+{
+    event->ignore();
+}
+
+void QQuickItem::keyReleaseEvent(QKeyEvent *event)
+{
+    event->ignore();
+}
+
+void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
+{
+    event->ignore();
+}
+
+void QQuickItem::focusInEvent(QFocusEvent *)
+{
+}
+
+void QQuickItem::focusOutEvent(QFocusEvent *)
+{
+}
+
+void QQuickItem::mousePressEvent(QMouseEvent *event)
+{
+    event->ignore();
+}
+
+void QQuickItem::mouseMoveEvent(QMouseEvent *event)
+{
+    event->ignore();
+}
+
+void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
+{
+    event->ignore();
+}
+
+void QQuickItem::mouseDoubleClickEvent(QMouseEvent *event)
+{
+    mousePressEvent(event);
+}
+
+void QQuickItem::mouseUngrabEvent()
+{
+    // XXX todo
+}
+
+void QQuickItem::wheelEvent(QWheelEvent *event)
+{
+    event->ignore();
+}
+
+void QQuickItem::touchEvent(QTouchEvent *event)
+{
+    event->ignore();
+}
+
+void QQuickItem::hoverEnterEvent(QHoverEvent *event)
+{
+    Q_UNUSED(event);
+}
+
+void QQuickItem::hoverMoveEvent(QHoverEvent *event)
+{
+    Q_UNUSED(event);
+}
+
+void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
+{
+    Q_UNUSED(event);
+}
+
+void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
+{
+    Q_UNUSED(event);
+}
+
+void QQuickItem::dragMoveEvent(QDragMoveEvent *event)
+{
+
+    Q_UNUSED(event);
+}
+
+void QQuickItem::dragLeaveEvent(QDragLeaveEvent *event)
+{
+
+    Q_UNUSED(event);
+}
+
+void QQuickItem::dropEvent(QDropEvent *event)
+{
+    Q_UNUSED(event);
+}
+
+bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
+{
+    return false;
+}
+
+void QQuickItem::windowDeactivateEvent()
+{
+    foreach (QQuickItem* item, childItems()) {
+        item->windowDeactivateEvent();
+    }
+}
+
+Qt::InputMethodHints QQuickItem::inputMethodHints() const
+{
+    Q_D(const QQuickItem);
+    return d->imHints;
+}
+
+void QQuickItem::setInputMethodHints(Qt::InputMethodHints hints)
+{
+    Q_D(QQuickItem);
+    d->imHints = hints;
+
+    if (!d->canvas || d->canvas->activeFocusItem() != this)
+        return;
+
+    QInputPanel *p = qApp->inputPanel();
+    if (p->inputItem() == this)
+        qApp->inputPanel()->update(Qt::ImHints);
+}
+
+void QQuickItem::updateMicroFocus()
+{
+    QInputPanel *p = qApp->inputPanel();
+    if (p->inputItem() == this)
+        qApp->inputPanel()->update(Qt::ImQueryInput);
+}
+
+QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+    Q_D(const QQuickItem);
+    QVariant v;
+
+    switch (query) {
+    case Qt::ImEnabled:
+        v = (bool)(flags() & ItemAcceptsInputMethod);
+        break;
+    case Qt::ImHints:
+        v = (int)inputMethodHints();
+        break;
+    case Qt::ImCursorRectangle:
+    case Qt::ImFont:
+    case Qt::ImCursorPosition:
+    case Qt::ImSurroundingText:
+    case Qt::ImCurrentSelection:
+    case Qt::ImMaximumTextLength:
+    case Qt::ImAnchorPosition:
+    case Qt::ImPreferredLanguage:
+        if (d->keyHandler)
+            v = d->keyHandler->inputMethodQuery(query);
+    default:
+        break;
+    }
+
+    return v;
+}
+
+QQuickAnchorLine QQuickItemPrivate::left() const
+{
+    return anchorLines()->left;
+}
+
+QQuickAnchorLine QQuickItemPrivate::right() const
+{
+    return anchorLines()->right;
+}
+
+QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
+{
+    return anchorLines()->hCenter;
+}
+
+QQuickAnchorLine QQuickItemPrivate::top() const
+{
+    return anchorLines()->top;
+}
+
+QQuickAnchorLine QQuickItemPrivate::bottom() const
+{
+    return anchorLines()->bottom;
+}
+
+QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
+{
+    return anchorLines()->vCenter;
+}
+
+QQuickAnchorLine QQuickItemPrivate::baseline() const
+{
+    return anchorLines()->baseline;
+}
+
+qreal QQuickItem::baselineOffset() const
+{
+    Q_D(const QQuickItem);
+    if (!d->baselineOffset.isValid()) {
+        return 0.0;
+    } else
+        return d->baselineOffset;
+}
+
+void QQuickItem::setBaselineOffset(qreal offset)
+{
+    Q_D(QQuickItem);
+    if (offset == d->baselineOffset)
+        return;
+
+    d->baselineOffset = offset;
+
+    for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
+        const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
+        if (change.types & QQuickItemPrivate::Geometry) {
+            QQuickAnchorsPrivate *anchor = change.listener->anchorPrivate();
+            if (anchor)
+                anchor->updateVerticalAnchors();
+        }
+    }
+    emit baselineOffsetChanged(offset);
+}
+
+void QQuickItem::update()
+{
+    Q_D(QQuickItem);
+    Q_ASSERT(flags() & ItemHasContents);
+    d->dirty(QQuickItemPrivate::Content);
+}
+
+void QQuickItem::polish()
+{
+    Q_D(QQuickItem);
+    if (!d->polishScheduled) {
+        d->polishScheduled = true;
+        if (d->canvas) {
+            QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
+            bool maybeupdate = p->itemsToPolish.isEmpty();
+            p->itemsToPolish.insert(this);
+            if (maybeupdate) d->canvas->maybeUpdate();
+        }
+    }
+}
+
+void QQuickItem::mapFromItem(QDeclarativeV8Function *args) const
+{
+    if (args->Length() != 0) {
+        v8::Local<v8::Value> item = (*args)[0];
+        QV8Engine *engine = args->engine();
+
+        QQuickItem *itemObj = 0;
+        if (!item->IsNull())
+            itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
+
+        if (!itemObj && !item->IsNull()) {
+            qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
+                          << "\" which is neither null nor an Item";
+            return;
+        }
+
+        v8::Local<v8::Object> rv = v8::Object::New();
+        args->returnValue(rv);
+
+        qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
+        qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
+
+        QPointF p = mapFromItem(itemObj, QPointF(x, y));
+
+        rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
+        rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
+    }
+}
+
+QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
+{
+    Q_D(const QQuickItem);
+
+    // XXX todo - we need to be able to handle common parents better and detect
+    // invalid cases
+    if (ok) *ok = true;
+
+    QTransform t = d->itemToCanvasTransform();
+    if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
+
+    return t;
+}
+
+void QQuickItem::mapToItem(QDeclarativeV8Function *args) const
+{
+    if (args->Length() != 0) {
+        v8::Local<v8::Value> item = (*args)[0];
+        QV8Engine *engine = args->engine();
+
+        QQuickItem *itemObj = 0;
+        if (!item->IsNull())
+            itemObj = qobject_cast<QQuickItem*>(engine->toQObject(item));
+
+        if (!itemObj && !item->IsNull()) {
+            qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
+                          << "\" which is neither null nor an Item";
+            return;
+        }
+
+        v8::Local<v8::Object> rv = v8::Object::New();
+        args->returnValue(rv);
+
+        qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
+        qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
+
+        QPointF p = mapToItem(itemObj, QPointF(x, y));
+
+        rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
+        rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
+    }
+}
+
+void QQuickItem::forceActiveFocus()
+{
+    setFocus(true);
+    QQuickItem *parent = parentItem();
+    while (parent) {
+        if (parent->flags() & QQuickItem::ItemIsFocusScope) {
+            parent->setFocus(true);
+        }
+        parent = parent->parentItem();
+    }
+}
+
+QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
+{
+    // XXX todo - should this include transform etc.?
+    const QList<QQuickItem *> children = childItems();
+    for (int i = children.count()-1; i >= 0; --i) {
+        QQuickItem *child = children.at(i);
+        if (child->isVisible() && child->x() <= x
+                && child->x() + child->width() >= x
+                && child->y() <= y
+                && child->y() + child->height() >= y)
+            return child;
+    }
+    return 0;
+}
+
+QDeclarativeListProperty<QObject> QQuickItemPrivate::resources()
+{
+    return QDeclarativeListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
+                                             QQuickItemPrivate::resources_count,
+                                             QQuickItemPrivate::resources_at,
+                                             QQuickItemPrivate::resources_clear);
+}
+
+QDeclarativeListProperty<QQuickItem> QQuickItemPrivate::children()
+{
+    return QDeclarativeListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
+                                             QQuickItemPrivate::children_count,
+                                             QQuickItemPrivate::children_at,
+                                             QQuickItemPrivate::children_clear);
+
+}
+
+QDeclarativeListProperty<QDeclarativeState> QQuickItemPrivate::states()
+{
+    return _states()->statesProperty();
+}
+
+QDeclarativeListProperty<QDeclarativeTransition> QQuickItemPrivate::transitions()
+{
+    return _states()->transitionsProperty();
+}
+
+QString QQuickItemPrivate::state() const
+{
+    if (!_stateGroup)
+        return QString();
+    else
+        return _stateGroup->state();
+}
+
+void QQuickItemPrivate::setState(const QString &state)
+{
+    _states()->setState(state);
+}
+
+QString QQuickItem::state() const
+{
+    Q_D(const QQuickItem);
+    return d->state();
+}
+
+void QQuickItem::setState(const QString &state)
+{
+    Q_D(QQuickItem);
+    d->setState(state);
+}
+
+QDeclarativeListProperty<QQuickTransform> QQuickItem::transform()
+{
+    Q_D(QQuickItem);
+    return QDeclarativeListProperty<QQuickTransform>(this, 0, d->transform_append, d->transform_count,
+                                                  d->transform_at, d->transform_clear);
+}
+
+void QQuickItem::classBegin()
+{
+    Q_D(QQuickItem);
+    d->componentComplete = false;
+    if (d->_stateGroup)
+        d->_stateGroup->classBegin();
+    if (d->_anchors)
+        d->_anchors->classBegin();
+}
+
+void QQuickItem::componentComplete()
+{
+    Q_D(QQuickItem);
+    d->componentComplete = true;
+    if (d->_stateGroup)
+        d->_stateGroup->componentComplete();
+    if (d->_anchors) {
+        d->_anchors->componentComplete();
+        QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
+    }
+    if (d->keyHandler)
+        d->keyHandler->componentComplete();
+    if (d->_contents)
+        d->_contents->complete();
+}
+
+QDeclarativeStateGroup *QQuickItemPrivate::_states()
+{
+    Q_Q(QQuickItem);
+    if (!_stateGroup) {
+        _stateGroup = new QDeclarativeStateGroup;
+        if (!componentComplete)
+            _stateGroup->classBegin();
+        FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
+                     q, SIGNAL(stateChanged(QString)))
+    }
+
+    return _stateGroup;
+}
+
+QQuickItemPrivate::AnchorLines::AnchorLines(QQuickItem *q)
+{
+    left.item = q;
+    left.anchorLine = QQuickAnchorLine::Left;
+    right.item = q;
+    right.anchorLine = QQuickAnchorLine::Right;
+    hCenter.item = q;
+    hCenter.anchorLine = QQuickAnchorLine::HCenter;
+    top.item = q;
+    top.anchorLine = QQuickAnchorLine::Top;
+    bottom.item = q;
+    bottom.anchorLine = QQuickAnchorLine::Bottom;
+    vCenter.item = q;
+    vCenter.anchorLine = QQuickAnchorLine::VCenter;
+    baseline.item = q;
+    baseline.anchorLine = QQuickAnchorLine::Baseline;
+}
+
+QPointF QQuickItemPrivate::computeTransformOrigin() const
+{
+    switch (origin) {
+    default:
+    case QQuickItem::TopLeft:
+        return QPointF(0, 0);
+    case QQuickItem::Top:
+        return QPointF(width / 2., 0);
+    case QQuickItem::TopRight:
+        return QPointF(width, 0);
+    case QQuickItem::Left:
+        return QPointF(0, height / 2.);
+    case QQuickItem::Center:
+        return QPointF(width / 2., height / 2.);
+    case QQuickItem::Right:
+        return QPointF(width, height / 2.);
+    case QQuickItem::BottomLeft:
+        return QPointF(0, height);
+    case QQuickItem::Bottom:
+        return QPointF(width / 2., height);
+    case QQuickItem::BottomRight:
+        return QPointF(width, height);
+    }
+}
+
+void QQuickItemPrivate::transformChanged()
+{
+}
+
+void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
+{
+    Q_Q(QQuickItem);
+
+    Q_ASSERT(e->isAccepted());
+    if (keyHandler) {
+        if (e->type() == QEvent::KeyPress)
+            keyHandler->keyPressed(e, false);
+        else
+            keyHandler->keyReleased(e, false);
+
+        if (e->isAccepted())
+            return;
+        else
+            e->accept();
+    }
+
+    if (e->type() == QEvent::KeyPress)
+        q->keyPressEvent(e);
+    else
+        q->keyReleaseEvent(e);
+
+    if (e->isAccepted())
+        return;
+
+    if (keyHandler) {
+        e->accept();
+
+        if (e->type() == QEvent::KeyPress)
+            keyHandler->keyPressed(e, true);
+        else
+            keyHandler->keyReleased(e, true);
+    }
+}
+
+void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
+{
+    Q_Q(QQuickItem);
+
+    Q_ASSERT(e->isAccepted());
+    if (keyHandler) {
+        keyHandler->inputMethodEvent(e, false);
+
+        if (e->isAccepted())
+            return;
+        else
+            e->accept();
+    }
+
+    q->inputMethodEvent(e);
+
+    if (e->isAccepted())
+        return;
+
+    if (keyHandler) {
+        e->accept();
+
+        keyHandler->inputMethodEvent(e, true);
+    }
+}
+
+void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
+{
+    Q_Q(QQuickItem);
+
+    if (e->type() == QEvent::FocusIn) {
+        q->focusInEvent(e);
+    } else {
+        q->focusOutEvent(e);
+    }
+}
+
+void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
+{
+    Q_Q(QQuickItem);
+
+    Q_ASSERT(e->isAccepted());
+
+    switch (e->type()) {
+    default:
+        Q_ASSERT(!"Unknown event type");
+    case QEvent::MouseMove:
+        q->mouseMoveEvent(e);
+        break;
+    case QEvent::MouseButtonPress:
+        q->mousePressEvent(e);
+        break;
+    case QEvent::MouseButtonRelease:
+        q->mouseReleaseEvent(e);
+        break;
+    case QEvent::MouseButtonDblClick:
+        q->mouseDoubleClickEvent(e);
+        break;
+    }
+}
+
+void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
+{
+    Q_Q(QQuickItem);
+    q->wheelEvent(e);
+}
+
+void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
+{
+    Q_Q(QQuickItem);
+    q->touchEvent(e);
+}
+
+void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
+{
+    Q_Q(QQuickItem);
+    switch (e->type()) {
+    default:
+        Q_ASSERT(!"Unknown event type");
+    case QEvent::HoverEnter:
+        q->hoverEnterEvent(e);
+        break;
+    case QEvent::HoverLeave:
+        q->hoverLeaveEvent(e);
+        break;
+    case QEvent::HoverMove:
+        q->hoverMoveEvent(e);
+        break;
+    }
+}
+
+void QQuickItemPrivate::deliverDragEvent(QEvent *e)
+{
+    Q_Q(QQuickItem);
+    switch (e->type()) {
+    default:
+        Q_ASSERT(!"Unknown event type");
+    case QEvent::DragEnter:
+        q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
+        break;
+    case QEvent::DragLeave:
+        q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
+        break;
+    case QEvent::DragMove:
+        q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
+        break;
+    case QEvent::Drop:
+        q->dropEvent(static_cast<QDropEvent *>(e));
+        break;
+    }
+}
+
+void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
+{
+    Q_UNUSED(change);
+    Q_UNUSED(value);
+}
+
+/*! \internal */
+// XXX todo - do we want/need this anymore?
+// Note that it's now used for varying clip rect
+QRectF QQuickItem::boundingRect() const
+{
+    Q_D(const QQuickItem);
+    return QRectF(0, 0, d->width, d->height);
+}
+
+QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
+{
+    Q_D(const QQuickItem);
+    return d->origin;
+}
+
+void QQuickItem::setTransformOrigin(TransformOrigin origin)
+{
+    Q_D(QQuickItem);
+    if (origin == d->origin)
+        return;
+
+    d->origin = origin;
+    d->dirty(QQuickItemPrivate::TransformOrigin);
+
+    emit transformOriginChanged(d->origin);
+}
+
+QPointF QQuickItem::transformOriginPoint() const
+{
+    Q_D(const QQuickItem);
+    if (!d->transformOriginPoint.isNull())
+        return d->transformOriginPoint;
+    return d->computeTransformOrigin();
+}
+
+void QQuickItem::setTransformOriginPoint(const QPointF &point)
+{
+    Q_D(QQuickItem);
+    if (d->transformOriginPoint == point)
+        return;
+
+    d->transformOriginPoint = point;
+    d->dirty(QQuickItemPrivate::TransformOrigin);
+}
+
+qreal QQuickItem::z() const
+{
+    Q_D(const QQuickItem);
+    return d->z;
+}
+
+void QQuickItem::setZ(qreal v)
+{
+    Q_D(QQuickItem);
+    if (d->z == v)
+        return;
+
+    d->z = v;
+
+    d->dirty(QQuickItemPrivate::ZValue);
+    if (d->parentItem)
+        QQuickItemPrivate::get(d->parentItem)->dirty(QQuickItemPrivate::ChildrenStackingChanged);
+
+    emit zChanged();
+}
+
+
+/*!
+  \qmlproperty real QtQuick2::Item::rotation
+  This property holds the rotation of the item in degrees clockwise.
+
+  This specifies how many degrees to rotate the item around its transformOrigin.
+  The default rotation is 0 degrees (i.e. not rotated at all).
+
+  \table
+  \row
+  \o \image declarative-rotation.png
+  \o
+  \qml
+  Rectangle {
+      color: "blue"
+      width: 100; height: 100
+      Rectangle {
+          color: "red"
+          x: 25; y: 25; width: 50; height: 50
+          rotation: 30
+      }
+  }
+  \endqml
+  \endtable
+
+  \sa transform, Rotation
+*/
+
+/*!
+  \qmlproperty real QtQuick2::Item::scale
+  This property holds the scale of the item.
+
+  A scale of less than 1 means the item will be displayed smaller than
+  normal, and a scale of greater than 1 means the item will be
+  displayed larger than normal.  A negative scale means the item will
+  be mirrored.
+
+  By default, items are displayed at a scale of 1 (i.e. at their
+  normal size).
+
+  Scaling is from the item's transformOrigin.
+
+  \table
+  \row
+  \o \image declarative-scale.png
+  \o
+  \qml
+  Rectangle {
+      color: "blue"
+      width: 100; height: 100
+      Rectangle {
+          color: "green"
+          width: 25; height: 25
+      }
+      Rectangle {
+          color: "red"
+          x: 25; y: 25; width: 50; height: 50
+          scale: 1.4
+      }
+  }
+  \endqml
+  \endtable
+
+  \sa transform, Scale
+*/
+
+/*!
+  \qmlproperty real QtQuick2::Item::opacity
+
+  This property holds the opacity of the item.  Opacity is specified as a
+  number between 0 (fully transparent) and 1 (fully opaque).  The default is 1.
+
+  When this property is set, the specified opacity is also applied
+  individually to child items.  In almost all cases this is what you want,
+  but in some cases it may produce undesired results. For example in the
+  second set of rectangles below, the red rectangle has specified an opacity
+  of 0.5, which affects the opacity of its blue child rectangle even though
+  the child has not specified an opacity.
+
+  \table
+  \row
+  \o \image declarative-item_opacity1.png
+  \o
+  \qml
+    Item {
+        Rectangle {
+            color: "red"
+            width: 100; height: 100
+            Rectangle {
+                color: "blue"
+                x: 50; y: 50; width: 100; height: 100
+            }
+        }
+    }
+  \endqml
+  \row
+  \o \image declarative-item_opacity2.png
+  \o
+  \qml
+    Item {
+        Rectangle {
+            opacity: 0.5
+            color: "red"
+            width: 100; height: 100
+            Rectangle {
+                color: "blue"
+                x: 50; y: 50; width: 100; height: 100
+            }
+        }
+    }
+  \endqml
+  \endtable
+
+  If an item's opacity is set to 0, the item will no longer receive mouse
+  events, but will continue to receive key events and will retain the keyboard
+  \l focus if it has been set. (In contrast, setting the \l visible property
+  to \c false stops both mouse and keyboard events, and also removes focus
+  from the item.)
+*/
+
+/*!
+  Returns a value indicating whether mouse input should
+  remain with this item exclusively.
+
+  \sa setKeepMouseGrab()
+ */
+
+qreal QQuickItem::rotation() const
+{
+    Q_D(const QQuickItem);
+    return d->rotation;
+}
+
+void QQuickItem::setRotation(qreal r)
+{
+    Q_D(QQuickItem);
+    if (d->rotation == r)
+        return;
+
+    d->rotation = r;
+
+    d->dirty(QQuickItemPrivate::BasicTransform);
+
+    d->itemChange(ItemRotationHasChanged, r);
+
+    emit rotationChanged();
+}
+
+qreal QQuickItem::scale() const
+{
+    Q_D(const QQuickItem);
+    return d->scale;
+}
+
+void QQuickItem::setScale(qreal s)
+{
+    Q_D(QQuickItem);
+    if (d->scale == s)
+        return;
+
+    d->scale = s;
+
+    d->dirty(QQuickItemPrivate::BasicTransform);
+
+    emit scaleChanged();
+}
+
+qreal QQuickItem::opacity() const
+{
+    Q_D(const QQuickItem);
+    return d->opacity;
+}
+
+void QQuickItem::setOpacity(qreal o)
+{
+    Q_D(QQuickItem);
+    if (d->opacity == o)
+        return;
+
+    d->opacity = o;
+
+    d->dirty(QQuickItemPrivate::OpacityValue);
+
+    d->itemChange(ItemOpacityHasChanged, o);
+
+    emit opacityChanged();
+}
+
+bool QQuickItem::isVisible() const
+{
+    Q_D(const QQuickItem);
+    return d->effectiveVisible;
+}
+
+void QQuickItem::setVisible(bool v)
+{
+    Q_D(QQuickItem);
+    if (v == d->explicitVisible)
+        return;
+
+    d->explicitVisible = v;
+
+    d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
+}
+
+bool QQuickItem::isEnabled() const
+{
+    Q_D(const QQuickItem);
+    return d->effectiveEnable;
+}
+
+void QQuickItem::setEnabled(bool e)
+{
+    Q_D(QQuickItem);
+    if (e == d->explicitEnable)
+        return;
+
+    d->explicitEnable = e;
+
+    d->setEffectiveEnableRecur(d->calcEffectiveEnable());
+}
+
+bool QQuickItemPrivate::calcEffectiveVisible() const
+{
+    // XXX todo - Should the effective visible of an element with no parent just be the current
+    // effective visible?  This would prevent pointless re-processing in the case of an element
+    // moving to/from a no-parent situation, but it is different from what graphics view does.
+    return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
+}
+
+void QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
+{
+    Q_Q(QQuickItem);
+
+    if (newEffectiveVisible && !explicitVisible) {
+        // This item locally overrides visibility
+        return;
+    }
+
+    if (newEffectiveVisible == effectiveVisible) {
+        // No change necessary
+        return;
+    }
+
+    effectiveVisible = newEffectiveVisible;
+    dirty(Visible);
+    if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
+
+    if (canvas) {
+        QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
+        if (canvasPriv->mouseGrabberItem == q)
+            q->ungrabMouse();
+    }
+
+    for (int ii = 0; ii < childItems.count(); ++ii)
+        QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
+
+    for (int ii = 0; ii < changeListeners.count(); ++ii) {
+        const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
+        if (change.types & QQuickItemPrivate::Visibility)
+            change.listener->itemVisibilityChanged(q);
+    }
+
+    emit q->visibleChanged();
+}
+
+bool QQuickItemPrivate::calcEffectiveEnable() const
+{
+    // XXX todo - Should the effective enable of an element with no parent just be the current
+    // effective enable?  This would prevent pointless re-processing in the case of an element
+    // moving to/from a no-parent situation, but it is different from what graphics view does.
+    return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
+}
+
+void QQuickItemPrivate::setEffectiveEnableRecur(bool newEffectiveEnable)
+{
+    Q_Q(QQuickItem);
+
+    // XXX todo - need to fixup focus
+
+    if (newEffectiveEnable && !explicitEnable) {
+        // This item locally overrides enable
+        return;
+    }
+
+    if (newEffectiveEnable == effectiveEnable) {
+        // No change necessary
+        return;
+    }
+
+    effectiveEnable = newEffectiveEnable;
+
+    if (canvas) {
+        QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
+        if (canvasPriv->mouseGrabberItem == q)
+            q->ungrabMouse();
+    }
+
+    for (int ii = 0; ii < childItems.count(); ++ii)
+        QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(newEffectiveEnable);
+
+    emit q->enabledChanged();
+}
+
+QString QQuickItemPrivate::dirtyToString() const
+{
+#define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
+    if (!rv.isEmpty()) \
+        rv.append(QLatin1String("|")); \
+    rv.append(QLatin1String(#value)); \
+}
+
+//    QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
+    QString rv;
+
+    DIRTY_TO_STRING(TransformOrigin);
+    DIRTY_TO_STRING(Transform);
+    DIRTY_TO_STRING(BasicTransform);
+    DIRTY_TO_STRING(Position);
+    DIRTY_TO_STRING(Size);
+    DIRTY_TO_STRING(ZValue);
+    DIRTY_TO_STRING(Content);
+    DIRTY_TO_STRING(Smooth);
+    DIRTY_TO_STRING(OpacityValue);
+    DIRTY_TO_STRING(ChildrenChanged);
+    DIRTY_TO_STRING(ChildrenStackingChanged);
+    DIRTY_TO_STRING(ParentChanged);
+    DIRTY_TO_STRING(Clip);
+    DIRTY_TO_STRING(Canvas);
+    DIRTY_TO_STRING(EffectReference);
+    DIRTY_TO_STRING(Visible);
+    DIRTY_TO_STRING(HideReference);
+
+    return rv;
+}
+
+void QQuickItemPrivate::dirty(DirtyType type)
+{
+    Q_Q(QQuickItem);
+    if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
+        transformChanged();
+
+    if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
+        dirtyAttributes |= type;
+        if (canvas) {
+            addToDirtyList();
+            QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
+        }
+    }
+}
+
+void QQuickItemPrivate::addToDirtyList()
+{
+    Q_Q(QQuickItem);
+
+    Q_ASSERT(canvas);
+    if (!prevDirtyItem) {
+        Q_ASSERT(!nextDirtyItem);
+
+        QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
+        nextDirtyItem = p->dirtyItemList;
+        if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
+        prevDirtyItem = &p->dirtyItemList;
+        p->dirtyItemList = q;
+        p->dirtyItem(q);
+    }
+    Q_ASSERT(prevDirtyItem);
+}
+
+void QQuickItemPrivate::removeFromDirtyList()
+{
+    if (prevDirtyItem) {
+        if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
+        *prevDirtyItem = nextDirtyItem;
+        prevDirtyItem = 0;
+        nextDirtyItem = 0;
+    }
+    Q_ASSERT(!prevDirtyItem);
+    Q_ASSERT(!nextDirtyItem);
+}
+
+void QQuickItemPrivate::refFromEffectItem(bool hide)
+{
+    ++effectRefCount;
+    if (1 == effectRefCount) {
+        dirty(EffectReference);
+        if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
+    }
+    if (hide) {
+        if (++hideRefCount == 1)
+            dirty(HideReference);
+    }
+}
+
+void QQuickItemPrivate::derefFromEffectItem(bool unhide)
+{
+    Q_ASSERT(effectRefCount);
+    --effectRefCount;
+    if (0 == effectRefCount) {
+        dirty(EffectReference);
+        if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
+    }
+    if (unhide) {
+        if (--hideRefCount == 0)
+            dirty(HideReference);
+    }
+}
+
+void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
+{
+    Q_Q(QQuickItem);
+    switch (change) {
+    case QQuickItem::ItemChildAddedChange:
+        q->itemChange(change, data);
+        if (_contents && componentComplete)
+            _contents->childAdded(data.item);
+        for (int ii = 0; ii < changeListeners.count(); ++ii) {
+            const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
+            if (change.types & QQuickItemPrivate::Children) {
+                change.listener->itemChildAdded(q, data.item);
+            }
+        }
+        break;
+    case QQuickItem::ItemChildRemovedChange:
+        q->itemChange(change, data);
+        if (_contents && componentComplete)
+            _contents->childRemoved(data.item);
+        for (int ii = 0; ii < changeListeners.count(); ++ii) {
+            const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
+            if (change.types & QQuickItemPrivate::Children) {
+                change.listener->itemChildRemoved(q, data.item);
+            }
+        }
+        break;
+    case QQuickItem::ItemSceneChange:
+        q->itemChange(change, data);
+        break;
+    case QQuickItem::ItemVisibleHasChanged:
+        q->itemChange(change, data);
+        for (int ii = 0; ii < changeListeners.count(); ++ii) {
+            const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
+            if (change.types & QQuickItemPrivate::Visibility) {
+                change.listener->itemVisibilityChanged(q);
+            }
+        }
+        break;
+    case QQuickItem::ItemParentHasChanged:
+        q->itemChange(change, data);
+        for (int ii = 0; ii < changeListeners.count(); ++ii) {
+            const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
+            if (change.types & QQuickItemPrivate::Parent) {
+                change.listener->itemParentChanged(q, data.item);
+            }
+        }
+        break;
+    case QQuickItem::ItemOpacityHasChanged:
+        q->itemChange(change, data);
+        for (int ii = 0; ii < changeListeners.count(); ++ii) {
+            const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
+            if (change.types & QQuickItemPrivate::Opacity) {
+                change.listener->itemOpacityChanged(q);
+            }
+        }
+        break;
+    case QQuickItem::ItemActiveFocusHasChanged:
+        q->itemChange(change, data);
+        break;
+    case QQuickItem::ItemRotationHasChanged:
+        q->itemChange(change, data);
+        for (int ii = 0; ii < changeListeners.count(); ++ii) {
+            const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
+            if (change.types & QQuickItemPrivate::Rotation) {
+                change.listener->itemRotationChanged(q);
+            }
+        }
+        break;
+    }
+}
+
+/*!
+    \property QQuickItem::smooth
+    \brief whether the item is smoothly transformed.
+
+    This property is provided purely for the purpose of optimization. Turning
+    smooth transforms off is faster, but looks worse; turning smooth
+    transformations on is slower, but looks better.
+
+    By default smooth transformations are off.
+*/
+
+/*!
+    Returns true if the item should be drawn with antialiasing and
+    smooth pixmap filtering, false otherwise.
+
+    The default is false.
+
+    \sa setSmooth()
+*/
+bool QQuickItem::smooth() const
+{
+    Q_D(const QQuickItem);
+    return d->smooth;
+}
+
+/*!
+    Sets whether the item should be drawn with antialiasing and
+    smooth pixmap filtering to \a smooth.
+
+    \sa smooth()
+*/
+void QQuickItem::setSmooth(bool smooth)
+{
+    Q_D(QQuickItem);
+    if (d->smooth == smooth)
+        return;
+
+    d->smooth = smooth;
+    d->dirty(QQuickItemPrivate::Smooth);
+
+    emit smoothChanged(smooth);
+}
+
+QQuickItem::Flags QQuickItem::flags() const
+{
+    Q_D(const QQuickItem);
+    return (QQuickItem::Flags)d->flags;
+}
+
+void QQuickItem::setFlag(Flag flag, bool enabled)
+{
+    Q_D(QQuickItem);
+    if (enabled)
+        setFlags((Flags)(d->flags | (quint32)flag));
+    else
+        setFlags((Flags)(d->flags & ~(quint32)flag));
+}
+
+void QQuickItem::setFlags(Flags flags)
+{
+    Q_D(QQuickItem);
+
+    if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
+        if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
+            qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
+            flags &= ~ItemIsFocusScope;
+        } else if (d->flags & ItemIsFocusScope) {
+            qWarning("QQuickItem: Cannot unset FocusScope flag.");
+            flags |= ItemIsFocusScope;
+        }
+    }
+
+    if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
+        d->dirty(QQuickItemPrivate::Clip);
+
+    d->flags = flags;
+}
+
+qreal QQuickItem::x() const
+{
+    Q_D(const QQuickItem);
+    return d->x;
+}
+
+qreal QQuickItem::y() const
+{
+    Q_D(const QQuickItem);
+    return d->y;
+}
+
+QPointF QQuickItem::pos() const
+{
+    Q_D(const QQuickItem);
+    return QPointF(d->x, d->y);
+}
+
+void QQuickItem::setX(qreal v)
+{
+    Q_D(QQuickItem);
+    if (d->x == v)
+        return;
+
+    qreal oldx = d->x;
+    d->x = v;
+
+    d->dirty(QQuickItemPrivate::Position);
+
+    geometryChanged(QRectF(x(), y(), width(), height()),
+                    QRectF(oldx, y(), width(), height()));
+}
+
+void QQuickItem::setY(qreal v)
+{
+    Q_D(QQuickItem);
+    if (d->y == v)
+        return;
+
+    qreal oldy = d->y;
+    d->y = v;
+
+    d->dirty(QQuickItemPrivate::Position);
+
+    geometryChanged(QRectF(x(), y(), width(), height()),
+                    QRectF(x(), oldy, width(), height()));
+}
+
+void QQuickItem::setPos(const QPointF &pos)
+{
+    Q_D(QQuickItem);
+    if (QPointF(d->x, d->y) == pos)
+        return;
+
+    qreal oldx = d->x;
+    qreal oldy = d->y;
+
+    d->x = pos.x();
+    d->y = pos.y();
+
+    d->dirty(QQuickItemPrivate::Position);
+
+    geometryChanged(QRectF(x(), y(), width(), height()),
+                    QRectF(oldx, oldy, width(), height()));
+}
+
+qreal QQuickItem::width() const
+{
+    Q_D(const QQuickItem);
+    return d->width;
+}
+
+void QQuickItem::setWidth(qreal w)
+{
+    Q_D(QQuickItem);
+    if (qIsNaN(w))
+        return;
+
+    d->widthValid = true;
+    if (d->width == w)
+        return;
+
+    qreal oldWidth = d->width;
+    d->width = w;
+
+    d->dirty(QQuickItemPrivate::Size);
+
+    geometryChanged(QRectF(x(), y(), width(), height()),
+                    QRectF(x(), y(), oldWidth, height()));
+}
+
+void QQuickItem::resetWidth()
+{
+    Q_D(QQuickItem);
+    d->widthValid = false;
+    setImplicitWidth(implicitWidth());
+}
+
+void QQuickItemPrivate::implicitWidthChanged()
+{
+    Q_Q(QQuickItem);
+    emit q->implicitWidthChanged();
+}
+
+qreal QQuickItemPrivate::getImplicitWidth() const
+{
+    return implicitWidth;
+}
+/*!
+    Returns the width of the item that is implied by other properties that determine the content.
+*/
+qreal QQuickItem::implicitWidth() const
+{
+    Q_D(const QQuickItem);
+    return d->getImplicitWidth();
+}
+
+/*!
+    \qmlproperty real QtQuick2::Item::implicitWidth
+    \qmlproperty real QtQuick2::Item::implicitHeight
+
+    Defines the natural width or height of the Item if no \l width or \l height is specified.
+
+    The default implicit size for most items is 0x0, however some elements have an inherent
+    implicit size which cannot be overridden, e.g. Image, Text.
+
+    Setting the implicit size is useful for defining components that have a preferred size
+    based on their content, for example:
+
+    \qml
+    // Label.qml
+    import QtQuick 1.1
+
+    Item {
+        property alias icon: image.source
+        property alias label: text.text
+        implicitWidth: text.implicitWidth + image.implicitWidth
+        implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
+        Image { id: image }
+        Text {
+            id: text
+            wrapMode: Text.Wrap
+            anchors.left: image.right; anchors.right: parent.right
+            anchors.verticalCenter: parent.verticalCenter
+        }
+    }
+    \endqml
+
+    \bold Note: using implicitWidth of Text or TextEdit and setting the width explicitly
+    incurs a performance penalty as the text must be laid out twice.
+*/
+
+/*!
+    Sets the implied width of the item to \a w.
+    This is the width implied by other properties that determine the content.
+*/
+void QQuickItem::setImplicitWidth(qreal w)
+{
+    Q_D(QQuickItem);
+    bool changed = w != d->implicitWidth;
+    d->implicitWidth = w;
+    if (d->width == w || widthValid()) {
+        if (changed)
+            d->implicitWidthChanged();
+        return;
+    }
+
+    qreal oldWidth = d->width;
+    d->width = w;
+
+    d->dirty(QQuickItemPrivate::Size);
+
+    geometryChanged(QRectF(x(), y(), width(), height()),
+                    QRectF(x(), y(), oldWidth, height()));
+
+    if (changed)
+        d->implicitWidthChanged();
+}
+
+/*!
+    Returns whether the width property has been set explicitly.
+*/
+bool QQuickItem::widthValid() const
+{
+    Q_D(const QQuickItem);
+    return d->widthValid;
+}
+
+qreal QQuickItem::height() const
+{
+    Q_D(const QQuickItem);
+    return d->height;
+}
+
+void QQuickItem::setHeight(qreal h)
+{
+    Q_D(QQuickItem);
+    if (qIsNaN(h))
+        return;
+
+    d->heightValid = true;
+    if (d->height == h)
+        return;
+
+    qreal oldHeight = d->height;
+    d->height = h;
+
+    d->dirty(QQuickItemPrivate::Size);
+
+    geometryChanged(QRectF(x(), y(), width(), height()),
+                    QRectF(x(), y(), width(), oldHeight));
+}
+
+void QQuickItem::resetHeight()
+{
+    Q_D(QQuickItem);
+    d->heightValid = false;
+    setImplicitHeight(implicitHeight());
+}
+
+void QQuickItemPrivate::implicitHeightChanged()
+{
+    Q_Q(QQuickItem);
+    emit q->implicitHeightChanged();
+}
+
+qreal QQuickItemPrivate::getImplicitHeight() const
+{
+    return implicitHeight;
+}
+
+/*!
+    Returns the height of the item that is implied by other properties that determine the content.
+*/
+qreal QQuickItem::implicitHeight() const
+{
+    Q_D(const QQuickItem);
+    return d->getImplicitHeight();
+}
+
+
+/*!
+    Sets the implied height of the item to \a h.
+    This is the height implied by other properties that determine the content.
+*/
+void QQuickItem::setImplicitHeight(qreal h)
+{
+    Q_D(QQuickItem);
+    bool changed = h != d->implicitHeight;
+    d->implicitHeight = h;
+    if (d->height == h || heightValid()) {
+        if (changed)
+            d->implicitHeightChanged();
+        return;
+    }
+
+    qreal oldHeight = d->height;
+    d->height = h;
+
+    d->dirty(QQuickItemPrivate::Size);
+
+    geometryChanged(QRectF(x(), y(), width(), height()),
+                    QRectF(x(), y(), width(), oldHeight));
+
+    if (changed)
+        d->implicitHeightChanged();
+}
+
+/*!
+    Returns whether the height property has been set explicitly.
+*/
+bool QQuickItem::heightValid() const
+{
+    Q_D(const QQuickItem);
+    return d->heightValid;
+}
+
+void QQuickItem::setSize(const QSizeF &size)
+{
+    Q_D(QQuickItem);
+    d->heightValid = true;
+    d->widthValid = true;
+
+    if (QSizeF(d->width, d->height) == size)
+        return;
+
+    qreal oldHeight = d->height;
+    qreal oldWidth = d->width;
+    d->height = size.height();
+    d->width = size.width();
+
+    d->dirty(QQuickItemPrivate::Size);
+
+    geometryChanged(QRectF(x(), y(), width(), height()),
+                    QRectF(x(), y(), oldWidth, oldHeight));
+}
+
+bool QQuickItem::hasActiveFocus() const
+{
+    Q_D(const QQuickItem);
+    return d->activeFocus;
+}
+
+bool QQuickItem::hasFocus() const
+{
+    Q_D(const QQuickItem);
+    return d->focus;
+}
+
+void QQuickItem::setFocus(bool focus)
+{
+    Q_D(QQuickItem);
+    if (d->focus == focus)
+        return;
+
+    if (d->canvas) {
+        // Need to find our nearest focus scope
+        QQuickItem *scope = parentItem();
+        while (scope && !scope->isFocusScope())
+            scope = scope->parentItem();
+        if (focus)
+            QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
+        else
+            QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
+    } else {
+        d->focus = focus;
+        emit focusChanged(focus);
+    }
+}
+
+bool QQuickItem::isFocusScope() const
+{
+    return flags() & ItemIsFocusScope;
+}
+
+QQuickItem *QQuickItem::scopedFocusItem() const
+{
+    Q_D(const QQuickItem);
+    if (!isFocusScope())
+        return 0;
+    else
+        return d->subFocusItem;
+}
+
+
+Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
+{
+    Q_D(const QQuickItem);
+    return d->acceptedMouseButtons;
+}
+
+void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
+{
+    Q_D(QQuickItem);
+    d->acceptedMouseButtons = buttons;
+}
+
+bool QQuickItem::filtersChildMouseEvents() const
+{
+    Q_D(const QQuickItem);
+    return d->filtersChildMouseEvents;
+}
+
+void QQuickItem::setFiltersChildMouseEvents(bool filter)
+{
+    Q_D(QQuickItem);
+    d->filtersChildMouseEvents = filter;
+}
+
+bool QQuickItem::isUnderMouse() const
+{
+    Q_D(const QQuickItem);
+    if (!d->canvas)
+        return false;
+
+    QPoint cursorPos = QCursor::pos();
+    if (QRectF(0, 0, width(), height()).contains(mapFromScene(cursorPos))) // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
+        return true;
+    return false;
+}
+
+bool QQuickItem::acceptHoverEvents() const
+{
+    Q_D(const QQuickItem);
+    return d->hoverEnabled;
+}
+
+void QQuickItem::setAcceptHoverEvents(bool enabled)
+{
+    Q_D(QQuickItem);
+    d->hoverEnabled = enabled;
+}
+
+void QQuickItem::grabMouse()
+{
+    Q_D(QQuickItem);
+    if (!d->canvas)
+        return;
+    QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
+    if (canvasPriv->mouseGrabberItem == this)
+        return;
+
+    QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
+    canvasPriv->mouseGrabberItem = this;
+    if (oldGrabber)
+        oldGrabber->mouseUngrabEvent();
+}
+
+void QQuickItem::ungrabMouse()
+{
+    Q_D(QQuickItem);
+    if (!d->canvas)
+        return;
+    QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
+    if (canvasPriv->mouseGrabberItem != this) {
+        qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
+        return;
+    }
+
+    canvasPriv->mouseGrabberItem = 0;
+    mouseUngrabEvent();
+}
+
+bool QQuickItem::keepMouseGrab() const
+{
+    Q_D(const QQuickItem);
+    return d->keepMouse;
+}
+
+/*!
+  The flag indicating whether the mouse should remain
+  with this item is set to \a keep.
+
+  This is useful for items that wish to grab and keep mouse
+  interaction following a predefined gesture.  For example,
+  an item that is interested in horizontal mouse movement
+  may set keepMouseGrab to true once a threshold has been
+  exceeded.  Once keepMouseGrab has been set to true, filtering
+  items will not react to mouse events.
+
+  If the item does not indicate that it wishes to retain mouse grab,
+  a filtering item may steal the grab. For example, Flickable may attempt
+  to steal a mouse grab if it detects that the user has begun to
+  move the viewport.
+
+  \sa keepMouseGrab()
+ */
+void QQuickItem::setKeepMouseGrab(bool keep)
+{
+    Q_D(QQuickItem);
+    d->keepMouse = keep;
+}
+
+/*!
+    \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
+
+    Maps the point (\a x, \a y), which is in \a item's coordinate system, to
+    this item's coordinate system, and returns an object with \c x and \c y
+    properties matching the mapped cooordinate.
+
+    If \a item is a \c null value, this maps the point from the coordinate
+    system of the root QML view.
+*/
+/*!
+    \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
+
+    Maps the point (\a x, \a y), which is in this item's coordinate system, to
+    \a item's coordinate system, and returns an object with \c x and \c y
+    properties matching the mapped cooordinate.
+
+    If \a item is a \c null value, this maps \a x and \a y to the coordinate
+    system of the root QML view.
+*/
+QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
+{
+    QPointF p = mapToScene(point);
+    if (item)
+        p = item->mapFromScene(p);
+    return p;
+}
+
+QPointF QQuickItem::mapToScene(const QPointF &point) const
+{
+    Q_D(const QQuickItem);
+    return d->itemToCanvasTransform().map(point);
+}
+
+QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
+{
+    Q_D(const QQuickItem);
+    QTransform t = d->itemToCanvasTransform();
+    if (item)
+        t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
+    return t.mapRect(rect);
+}
+
+QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
+{
+    Q_D(const QQuickItem);
+    return d->itemToCanvasTransform().mapRect(rect);
+}
+
+QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
+{
+    QPointF p = item?item->mapToScene(point):point;
+    return mapFromScene(p);
+}
+
+QPointF QQuickItem::mapFromScene(const QPointF &point) const
+{
+    Q_D(const QQuickItem);
+    return d->canvasToItemTransform().map(point);
+}
+
+QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
+{
+    Q_D(const QQuickItem);
+    QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
+    t *= d->canvasToItemTransform();
+    return t.mapRect(rect);
+}
+
+QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
+{
+    Q_D(const QQuickItem);
+    return d->canvasToItemTransform().mapRect(rect);
+}
+
+
+/*!
+    \qmlmethod QtQuick2::Item::forceActiveFocus()
+
+    Forces active focus on the item.
+
+    This method sets focus on the item and makes sure that all the focus scopes
+    higher in the object hierarchy are also given the focus.
+*/
+
+/*!
+    Forces active focus on the item.
+
+    This method sets focus on the item and makes sure that all the focus scopes
+    higher in the object hierarchy are also given the focus.
+*/
+
+/*!
+  \qmlmethod QtQuick2::Item::childAt(real x, real y)
+
+  Returns the visible child item at point (\a x, \a y), which is in this
+  item's coordinate system, or \c null if there is no such item.
+*/
+
+/*!
+  Returns the visible child item at point (\a x, \a y), which is in this
+  item's coordinate system, or 0 if there is no such item.
+*/
+
+/*!
+  \qmlproperty list<State> QtQuick2::Item::states
+  This property holds a list of states defined by the item.
+
+  \qml
+  Item {
+      states: [
+          State {
+              // ...
+          },
+          State {
+              // ...
+          }
+          // ...
+      ]
+  }
+  \endqml
+
+  \sa {qmlstate}{States}
+*/
+/*!
+  \qmlproperty list<Transition> QtQuick2::Item::transitions
+  This property holds a list of transitions defined by the item.
+
+  \qml
+  Item {
+      transitions: [
+          Transition {
+              // ...
+          },
+          Transition {
+              // ...
+          }
+          // ...
+      ]
+  }
+  \endqml
+
+  \sa {QML Animation and Transitions}{Transitions}
+*/
+/*
+  \qmlproperty list<Filter> QtQuick2::Item::filter
+  This property holds a list of graphical filters to be applied to the item.
+
+  \l {Filter}{Filters} include things like \l {Blur}{blurring}
+  the item, or giving it a \l Reflection.  Some
+  filters may not be available on all canvases; if a filter is not
+  available on a certain canvas, it will simply not be applied for
+  that canvas (but the QML will still be considered valid).
+
+  \qml
+  Item {
+      filter: [
+          Blur {
+              // ...
+          },
+          Reflection {
+              // ...
+          }
+          // ...
+      ]
+  }
+  \endqml
+*/
+
+/*!
+  \qmlproperty bool QtQuick2::Item::clip
+  This property holds whether clipping is enabled. The default clip value is \c false.
+
+  If clipping is enabled, an item will clip its own painting, as well
+  as the painting of its children, to its bounding rectangle.
+
+  Non-rectangular clipping regions are not supported for performance reasons.
+*/
+
+/*!
+  \property QQuickItem::clip
+  This property holds whether clipping is enabled. The default clip value is \c false.
+
+  If clipping is enabled, an item will clip its own painting, as well
+  as the painting of its children, to its bounding rectangle. If you set
+  clipping during an item's paint operation, remember to re-set it to
+  prevent clipping the rest of your scene.
+
+  Non-rectangular clipping regions are not supported for performance reasons.
+*/
+
+/*!
+  \qmlproperty string QtQuick2::Item::state
+
+  This property holds the name of the current state of the item.
+
+  This property is often used in scripts to change between states. For
+  example:
+
+  \js
+  function toggle() {
+      if (button.state == 'On')
+          button.state = 'Off';
+      else
+          button.state = 'On';
+  }
+  \endjs
+
+  If the item is in its base state (i.e. no explicit state has been
+  set), \c state will be a blank string. Likewise, you can return an
+  item to its base state by setting its current state to \c ''.
+
+  \sa {qmlstates}{States}
+*/
+
+/*!
+  \qmlproperty list<Transform> QtQuick2::Item::transform
+  This property holds the list of transformations to apply.
+
+  For more information see \l Transform.
+*/
+
+/*!
+    \enum QQuickItem::TransformOrigin
+
+    Controls the point about which simple transforms like scale apply.
+
+    \value TopLeft The top-left corner of the item.
+    \value Top The center point of the top of the item.
+    \value TopRight The top-right corner of the item.
+    \value Left The left most point of the vertical middle.
+    \value Center The center of the item.
+    \value Right The right most point of the vertical middle.
+    \value BottomLeft The bottom-left corner of the item.
+    \value Bottom The center point of the bottom of the item.
+    \value BottomRight The bottom-right corner of the item.
+*/
+
+
+/*!
+  \qmlproperty bool QtQuick2::Item::activeFocus
+
+  This property indicates whether the item has active focus.
+
+  An item with active focus will receive keyboard input,
+  or is a FocusScope ancestor of the item that will receive keyboard input.
+
+  Usually, activeFocus is gained by setting focus on an item and its enclosing
+  FocusScopes. In the following example \c input will have activeFocus.
+  \qml
+  Rectangle {
+      FocusScope {
+          focus: true
+          TextInput {
+              id: input
+              focus: true
+          }
+      }
+  }
+  \endqml
+
+  \sa focus, {qmlfocus}{Keyboard Focus}
+*/
+
+/*!
+  \qmlproperty bool QtQuick2::Item::focus
+  This property indicates whether the item has focus within the enclosing focus scope. If true, this item
+  will gain active focus when the enclosing focus scope gains active focus.
+  In the following example, \c input will be given active focus when \c scope gains active focus.
+  \qml
+  Rectangle {
+      FocusScope {
+          id: scope
+          TextInput {
+              id: input
+              focus: true
+          }
+      }
+  }
+  \endqml
+
+  For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
+  On a practical level, that means the following QML will give active focus to \c input on startup.
+
+  \qml
+  Rectangle {
+      TextInput {
+          id: input
+          focus: true
+      }
+  }
+  \endqml
+
+  \sa activeFocus, {qmlfocus}{Keyboard Focus}
+*/
+
+
+/*!
+  \property QQuickItem::anchors
+  \internal
+*/
+
+/*!
+  \property QQuickItem::left
+  \internal
+*/
+
+/*!
+  \property QQuickItem::right
+  \internal
+*/
+
+/*!
+  \property QQuickItem::horizontalCenter
+  \internal
+*/
+
+/*!
+  \property QQuickItem::top
+  \internal
+*/
+
+/*!
+  \property QQuickItem::bottom
+  \internal
+*/
+
+/*!
+  \property QQuickItem::verticalCenter
+  \internal
+*/
+
+/*!
+  \property QQuickItem::focus
+  \internal
+*/
+
+/*!
+  \property QQuickItem::transform
+  \internal
+*/
+
+/*!
+  \property QQuickItem::transformOrigin
+  \internal
+*/
+
+/*!
+  \property QQuickItem::activeFocus
+  \internal
+*/
+
+/*!
+  \property QQuickItem::baseline
+  \internal
+*/
+
+/*!
+  \property QQuickItem::data
+  \internal
+*/
+
+/*!
+  \property QQuickItem::resources
+  \internal
+*/
+
+/*!
+  \property QQuickItem::state
+  \internal
+*/
+
+/*!
+  \property QQuickItem::states
+  \internal
+*/
+
+/*!
+  \property QQuickItem::transformOriginPoint
+  \internal
+*/
+
+/*!
+  \property QQuickItem::transitions
+  \internal
+*/
+
+bool QQuickItem::event(QEvent *ev)
+{
+#if 0
+    if (ev->type() == QEvent::PolishRequest) {
+        Q_D(QQuickItem);
+        d->polishScheduled = false;
+        updatePolish();
+        return true;
+    } else {
+        return QObject::event(ev);
+    }
+#endif
+    if (ev->type() == QEvent::InputMethodQuery) {
+        QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
+        Qt::InputMethodQueries queries = query->queries();
+        for (uint i = 0; i < 32; ++i) {
+            Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
+            if (q) {
+                QVariant v = inputMethodQuery(q);
+                query->setValue(q, v);
+            }
+        }
+        query->accept();
+        return true;
+    } else if (ev->type() == QEvent::InputMethod) {
+        inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
+        return true;
+    }
+    return QObject::event(ev);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug debug, QQuickItem *item)
+{
+    if (!item) {
+        debug << "QQuickItem(0)";
+        return debug;
+    }
+
+    debug << item->metaObject()->className() << "(this =" << ((void*)item)
+          << ", name=" << item->objectName()
+          << ", parent =" << ((void*)item->parentItem())
+          << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
+          << ", z =" << item->z() << ')';
+    return debug;
+}
+#endif
+
+qint64 QQuickItemPrivate::consistentTime = -1;
+void QQuickItemPrivate::setConsistentTime(qint64 t)
+{
+    consistentTime = t;
+}
+
+class QElapsedTimerConsistentTimeHack
+{
+public:
+    void start() {
+        t1 = QQuickItemPrivate::consistentTime;
+        t2 = 0;
+    }
+    qint64 elapsed() {
+        return QQuickItemPrivate::consistentTime - t1;
+    }
+    qint64 restart() {
+        qint64 val = QQuickItemPrivate::consistentTime - t1;
+        t1 = QQuickItemPrivate::consistentTime;
+        t2 = 0;
+        return val;
+    }
+
+private:
+    qint64 t1;
+    qint64 t2;
+};
+
+void QQuickItemPrivate::start(QElapsedTimer &t)
+{
+    if (QQuickItemPrivate::consistentTime == -1)
+        t.start();
+    else
+        ((QElapsedTimerConsistentTimeHack*)&t)->start();
+}
+
+qint64 QQuickItemPrivate::elapsed(QElapsedTimer &t)
+{
+    if (QQuickItemPrivate::consistentTime == -1)
+        return t.elapsed();
+    else
+        return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
+}
+
+qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
+{
+    if (QQuickItemPrivate::consistentTime == -1)
+        return t.restart();
+    else
+        return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
+}
+
+/*!
+    \fn bool QQuickItem::isTextureProvider() const
+
+    Returns true if this item is a texture provider. The default
+    implementation returns false.
+
+    This function can be called from any thread.
+ */
+
+/*!
+    \fn QSGTextureProvider *QQuickItem::textureProvider() const
+
+    Returns the texture provider for an item. The default implementation
+    returns 0.
+
+    This function may only be called on the rendering thread.
+ */
+
+QT_END_NAMESPACE
+
+#include <moc_qquickitem.cpp>
diff --git a/src/declarative/items/qquickitem.h b/src/declarative/items/qquickitem.h
new file mode 100644 (file)
index 0000000..be50677
--- /dev/null
@@ -0,0 +1,414 @@
+// Commit: 6f78a6080b84cc3ef96b73a4ff58d1b5a72f08f4
+/****************************************************************************
+**
+** 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 QQUICKITEM_H
+#define QQUICKITEM_H
+
+#include <QtDeclarative/qdeclarative.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QList>
+#include <QtGui/qevent.h>
+#include <QtGui/qfont.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickItem;
+class QQuickTransformPrivate;
+class QQuickTransform : public QObject
+{
+    Q_OBJECT
+public:
+    QQuickTransform(QObject *parent = 0);
+    ~QQuickTransform();
+
+    void appendToItem(QQuickItem *);
+    void prependToItem(QQuickItem *);
+
+    virtual void applyTo(QMatrix4x4 *matrix) const = 0;
+
+protected Q_SLOTS:
+    void update();
+
+protected:
+    QQuickTransform(QQuickTransformPrivate &dd, QObject *parent);
+
+private:
+    Q_DECLARE_PRIVATE(QQuickTransform)
+};
+
+class QDeclarativeV8Function;
+class QDeclarativeState;
+class QQuickAnchorLine;
+class QDeclarativeTransition;
+class QQuickKeyEvent;
+class QQuickAnchors;
+class QQuickItemPrivate;
+class QQuickCanvas;
+class QSGEngine;
+class QTouchEvent;
+class QSGNode;
+class QSGTransformNode;
+class QSGTextureProvider;
+
+class Q_DECLARATIVE_EXPORT QQuickItem : public QObject, public QDeclarativeParserStatus
+{
+    Q_OBJECT
+    Q_INTERFACES(QDeclarativeParserStatus)
+
+    Q_PROPERTY(QQuickItem *parent READ parentItem WRITE setParentItem NOTIFY parentChanged DESIGNABLE false FINAL)
+    Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QDeclarativeListProperty<QObject> data READ data DESIGNABLE false)
+    Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QDeclarativeListProperty<QObject> resources READ resources DESIGNABLE false)
+    Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QDeclarativeListProperty<QQuickItem> children READ children NOTIFY childrenChanged DESIGNABLE false)
+
+    Q_PROPERTY(QPointF pos READ pos FINAL)
+    Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged FINAL)
+    Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged FINAL)
+    Q_PROPERTY(qreal z READ z WRITE setZ NOTIFY zChanged FINAL)
+    Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY widthChanged RESET resetWidth FINAL)
+    Q_PROPERTY(qreal height READ height WRITE setHeight NOTIFY heightChanged RESET resetHeight FINAL)
+
+    Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged FINAL)
+    Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
+    Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL)
+
+    Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QDeclarativeListProperty<QDeclarativeState> states READ states DESIGNABLE false)
+    Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QDeclarativeListProperty<QDeclarativeTransition> transitions READ transitions DESIGNABLE false)
+    Q_PROPERTY(QString state READ state WRITE setState NOTIFY stateChanged)
+    Q_PROPERTY(QRectF childrenRect READ childrenRect NOTIFY childrenRectChanged DESIGNABLE false FINAL)
+    Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQuickAnchors * anchors READ anchors DESIGNABLE false CONSTANT FINAL)
+    Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQuickAnchorLine left READ left CONSTANT FINAL)
+    Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQuickAnchorLine right READ right CONSTANT FINAL)
+    Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQuickAnchorLine horizontalCenter READ horizontalCenter CONSTANT FINAL)
+    Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQuickAnchorLine top READ top CONSTANT FINAL)
+    Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQuickAnchorLine bottom READ bottom CONSTANT FINAL)
+    Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQuickAnchorLine verticalCenter READ verticalCenter CONSTANT FINAL)
+    Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQuickAnchorLine baseline READ baseline CONSTANT FINAL)
+    Q_PROPERTY(qreal baselineOffset READ baselineOffset WRITE setBaselineOffset NOTIFY baselineOffsetChanged)
+
+    Q_PROPERTY(bool clip READ clip WRITE setClip NOTIFY clipChanged)
+
+    Q_PROPERTY(bool focus READ hasFocus WRITE setFocus NOTIFY focusChanged FINAL)
+    Q_PROPERTY(bool activeFocus READ hasActiveFocus NOTIFY activeFocusChanged FINAL)
+
+    Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged)
+    Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged)
+    Q_PROPERTY(TransformOrigin transformOrigin READ transformOrigin WRITE setTransformOrigin NOTIFY transformOriginChanged)
+    Q_PROPERTY(QPointF transformOriginPoint READ transformOriginPoint)  // XXX todo - notify?
+    Q_PROPERTY(QDeclarativeListProperty<QQuickTransform> transform READ transform DESIGNABLE false FINAL)
+
+    Q_PROPERTY(bool smooth READ smooth WRITE setSmooth NOTIFY smoothChanged)
+    Q_PROPERTY(qreal implicitWidth READ implicitWidth WRITE setImplicitWidth NOTIFY implicitWidthChanged)
+    Q_PROPERTY(qreal implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged)
+
+    Q_ENUMS(TransformOrigin)
+    Q_CLASSINFO("DefaultProperty", "data")
+
+public:
+    enum Flag {
+        ItemClipsChildrenToShape  = 0x01,
+        ItemAcceptsInputMethod    = 0x02,
+        ItemIsFocusScope          = 0x04,
+        ItemHasContents           = 0x08,
+        ItemAcceptsDrops          = 0x10
+        // Remember to increment the size of QQuickItemPrivate::flags
+    };
+    Q_DECLARE_FLAGS(Flags, Flag)
+
+    enum ItemChange {
+        ItemChildAddedChange,      // value.item
+        ItemChildRemovedChange,    // value.item
+        ItemSceneChange,           // value.canvas
+        ItemVisibleHasChanged,     // value.realValue
+        ItemParentHasChanged,      // value.item
+        ItemOpacityHasChanged,     // value.realValue
+        ItemActiveFocusHasChanged, // value.boolValue
+        ItemRotationHasChanged     // value.realValue
+    };
+
+    union ItemChangeData {
+        ItemChangeData(QQuickItem *v) : item(v) {}
+        ItemChangeData(QQuickCanvas *v) : canvas(v) {}
+        ItemChangeData(qreal v) : realValue(v) {}
+        ItemChangeData(bool v) : boolValue(v) {}
+
+        QQuickItem *item;
+        QQuickCanvas *canvas;
+        qreal realValue;
+        bool boolValue;
+    };
+
+    enum TransformOrigin {
+        TopLeft, Top, TopRight,
+        Left, Center, Right,
+        BottomLeft, Bottom, BottomRight
+    };
+
+    QQuickItem(QQuickItem *parent = 0);
+    virtual ~QQuickItem();
+
+    QSGEngine *sceneGraphEngine() const;
+
+    QQuickCanvas *canvas() const;
+    QQuickItem *parentItem() const;
+    void setParentItem(QQuickItem *parent);
+    void stackBefore(const QQuickItem *);
+    void stackAfter(const QQuickItem *);
+
+    QRectF childrenRect();
+    QList<QQuickItem *> childItems() const;
+
+    bool clip() const;
+    void setClip(bool);
+
+    QString state() const;
+    void setState(const QString &);
+
+    qreal baselineOffset() const;
+    void setBaselineOffset(qreal);
+
+    QDeclarativeListProperty<QQuickTransform> transform();
+
+    qreal x() const;
+    qreal y() const;
+    QPointF pos() const;
+    void setX(qreal);
+    void setY(qreal);
+    void setPos(const QPointF &);
+
+    qreal width() const;
+    void setWidth(qreal);
+    void resetWidth();
+    qreal implicitWidth() const;
+
+    qreal height() const;
+    void setHeight(qreal);
+    void resetHeight();
+    qreal implicitHeight() const;
+
+    void setSize(const QSizeF &size);
+
+    TransformOrigin transformOrigin() const;
+    void setTransformOrigin(TransformOrigin);
+    QPointF transformOriginPoint() const;
+    void setTransformOriginPoint(const QPointF &);
+
+    qreal z() const;
+    void setZ(qreal);
+
+    qreal rotation() const;
+    void setRotation(qreal);
+    qreal scale() const;
+    void setScale(qreal);
+
+    qreal opacity() const;
+    void setOpacity(qreal);
+
+    bool isVisible() const;
+    void setVisible(bool);
+
+    bool isEnabled() const;
+    void setEnabled(bool);
+
+    bool smooth() const;
+    void setSmooth(bool);
+
+    Flags flags() const;
+    void setFlag(Flag flag, bool enabled = true);
+    void setFlags(Flags flags);
+
+    virtual QRectF boundingRect() const;
+
+    bool hasActiveFocus() const;
+    bool hasFocus() const;
+    void setFocus(bool);
+    bool isFocusScope() const;
+    QQuickItem *scopedFocusItem() const;
+
+    Qt::MouseButtons acceptedMouseButtons() const;
+    void setAcceptedMouseButtons(Qt::MouseButtons buttons);
+    bool acceptHoverEvents() const;
+    void setAcceptHoverEvents(bool enabled);
+
+    bool isUnderMouse() const;
+    void grabMouse();
+    void ungrabMouse();
+    bool keepMouseGrab() const;
+    void setKeepMouseGrab(bool);
+    bool filtersChildMouseEvents() const;
+    void setFiltersChildMouseEvents(bool filter);
+
+    QTransform itemTransform(QQuickItem *, bool *) const;
+    QPointF mapToItem(const QQuickItem *item, const QPointF &point) const;
+    QPointF mapToScene(const QPointF &point) const;
+    QRectF mapRectToItem(const QQuickItem *item, const QRectF &rect) const;
+    QRectF mapRectToScene(const QRectF &rect) const;
+    QPointF mapFromItem(const QQuickItem *item, const QPointF &point) const;
+    QPointF mapFromScene(const QPointF &point) const;
+    QRectF mapRectFromItem(const QQuickItem *item, const QRectF &rect) const;
+    QRectF mapRectFromScene(const QRectF &rect) const;
+
+    void polish();
+
+    Q_INVOKABLE void mapFromItem(QDeclarativeV8Function*) const;
+    Q_INVOKABLE void mapToItem(QDeclarativeV8Function*) const;
+    Q_INVOKABLE void forceActiveFocus();
+    Q_INVOKABLE QQuickItem *childAt(qreal x, qreal y) const;
+
+    Qt::InputMethodHints inputMethodHints() const;
+    void setInputMethodHints(Qt::InputMethodHints hints);
+    virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
+
+    struct UpdatePaintNodeData {
+       QSGTransformNode *transformNode;
+    private:
+       friend class QQuickCanvasPrivate;
+       UpdatePaintNodeData();
+    };
+
+    virtual bool isTextureProvider() const { return false; }
+    virtual QSGTextureProvider *textureProvider() const { return 0; }
+
+public Q_SLOTS:
+    void update();
+    void updateMicroFocus();
+
+Q_SIGNALS:
+    void childrenRectChanged(const QRectF &);
+    void baselineOffsetChanged(qreal);
+    void stateChanged(const QString &);
+    void focusChanged(bool);
+    void activeFocusChanged(bool);
+    void parentChanged(QQuickItem *);
+    void transformOriginChanged(TransformOrigin);
+    void smoothChanged(bool);
+    void clipChanged(bool);
+
+    // XXX todo
+    void childrenChanged();
+    void opacityChanged();
+    void enabledChanged();
+    void visibleChanged();
+    void rotationChanged();
+    void scaleChanged();
+
+    void xChanged();
+    void yChanged();
+    void widthChanged();
+    void heightChanged();
+    void zChanged();
+    void implicitWidthChanged();
+    void implicitHeightChanged();
+
+protected:
+    virtual bool event(QEvent *);
+
+    bool isComponentComplete() const;
+    virtual void itemChange(ItemChange, const ItemChangeData &);
+
+    void setImplicitWidth(qreal);
+    bool widthValid() const; // ### better name?
+    void setImplicitHeight(qreal);
+    bool heightValid() const; // ### better name?
+
+    virtual void classBegin();
+    virtual void componentComplete();
+
+    virtual void keyPressEvent(QKeyEvent *event);
+    virtual void keyReleaseEvent(QKeyEvent *event);
+    virtual void inputMethodEvent(QInputMethodEvent *);
+    virtual void focusInEvent(QFocusEvent *);
+    virtual void focusOutEvent(QFocusEvent *);
+    virtual void mousePressEvent(QMouseEvent *event);
+    virtual void mouseMoveEvent(QMouseEvent *event);
+    virtual void mouseReleaseEvent(QMouseEvent *event);
+    virtual void mouseDoubleClickEvent(QMouseEvent *event);
+    virtual void mouseUngrabEvent(); // XXX todo - params?
+    virtual void wheelEvent(QWheelEvent *event);
+    virtual void touchEvent(QTouchEvent *event);
+    virtual void hoverEnterEvent(QHoverEvent *event);
+    virtual void hoverMoveEvent(QHoverEvent *event);
+    virtual void hoverLeaveEvent(QHoverEvent *event);
+    virtual void dragEnterEvent(QDragEnterEvent *);
+    virtual void dragMoveEvent(QDragMoveEvent *);
+    virtual void dragLeaveEvent(QDragLeaveEvent *);
+    virtual void dropEvent(QDropEvent *);
+    virtual bool childMouseEventFilter(QQuickItem *, QEvent *);
+    virtual void windowDeactivateEvent();
+
+    virtual void geometryChanged(const QRectF &newGeometry,
+                                 const QRectF &oldGeometry);
+
+    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+    virtual void updatePolish();
+
+protected:
+    QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent = 0);
+
+private:
+    friend class QQuickCanvas;
+    friend class QQuickCanvasPrivate;
+    friend class QSGRenderer;
+    Q_DISABLE_COPY(QQuickItem)
+    Q_DECLARE_PRIVATE(QQuickItem)
+};
+
+// XXX todo
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickItem::Flags)
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug Q_DECLARATIVE_EXPORT operator<<(QDebug debug, QQuickItem *item);
+#endif
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickItem)
+QML_DECLARE_TYPE(QQuickTransform)
+
+QT_END_HEADER
+
+#endif // QQUICKITEM_H
diff --git a/src/declarative/items/qquickitem_p.h b/src/declarative/items/qquickitem_p.h
new file mode 100644 (file)
index 0000000..94b195f
--- /dev/null
@@ -0,0 +1,716 @@
+// Commit: 5c783d0a9a912816813945387903857a314040b5
+/****************************************************************************
+**
+** 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 QQUICKITEM_P_H
+#define QQUICKITEM_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 "qquickitem.h"
+
+#include "qquickanchors_p.h"
+#include "qquickanchors_p_p.h"
+#include "qquickitemchangelistener_p.h"
+
+#include "qquickcanvas_p.h"
+
+#include <qsgnode.h>
+#include "qquickclipnode_p.h"
+
+#include <private/qpodvector_p.h>
+#include <private/qdeclarativestate_p.h>
+#include <private/qdeclarativenullablevalue_p_p.h>
+#include <private/qdeclarativenotifier_p.h>
+#include <private/qdeclarativeglobal_p.h>
+
+#include <qdeclarative.h>
+#include <qdeclarativecontext.h>
+
+#include <QtCore/qlist.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qelapsedtimer.h>
+
+QT_BEGIN_NAMESPACE
+
+class QNetworkReply;
+class QQuickItemKeyFilter;
+class QQuickLayoutMirroringAttached;
+
+//### merge into private?
+class QQuickContents : public QObject, public QQuickItemChangeListener
+{
+    Q_OBJECT
+public:
+    QQuickContents(QQuickItem *item);
+    ~QQuickContents();
+
+    QRectF rectF() const;
+
+    void childRemoved(QQuickItem *item);
+    void childAdded(QQuickItem *item);
+
+    void calcGeometry() { calcWidth(); calcHeight(); }
+    void complete();
+
+Q_SIGNALS:
+    void rectChanged(QRectF);
+
+protected:
+    void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
+    void itemDestroyed(QQuickItem *item);
+    //void itemVisibilityChanged(QQuickItem *item)
+
+private:
+    void calcHeight(QQuickItem *changed = 0);
+    void calcWidth(QQuickItem *changed = 0);
+
+    QQuickItem *m_item;
+    qreal m_x;
+    qreal m_y;
+    qreal m_width;
+    qreal m_height;
+};
+
+class QQuickTransformPrivate : public QObjectPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickTransform);
+public:
+    static QQuickTransformPrivate* get(QQuickTransform *transform) { return transform->d_func(); }
+
+    QQuickTransformPrivate();
+
+    QList<QQuickItem *> items;
+};
+
+class Q_DECLARATIVE_EXPORT QQuickItemPrivate : public QObjectPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickItem)
+
+public:
+    static QQuickItemPrivate* get(QQuickItem *item) { return item->d_func(); }
+    static const QQuickItemPrivate* get(const QQuickItem *item) { return item->d_func(); }
+
+    QQuickItemPrivate();
+    void init(QQuickItem *parent);
+
+    QDeclarativeListProperty<QObject> data();
+    QDeclarativeListProperty<QObject> resources();
+    QDeclarativeListProperty<QQuickItem> children();
+
+    QDeclarativeListProperty<QDeclarativeState> states();
+    QDeclarativeListProperty<QDeclarativeTransition> transitions();
+
+    QString state() const;
+    void setState(const QString &);
+
+    QQuickAnchorLine left() const;
+    QQuickAnchorLine right() const;
+    QQuickAnchorLine horizontalCenter() const;
+    QQuickAnchorLine top() const;
+    QQuickAnchorLine bottom() const;
+    QQuickAnchorLine verticalCenter() const;
+    QQuickAnchorLine baseline() const;
+
+    // data property
+    static void data_append(QDeclarativeListProperty<QObject> *, QObject *);
+    static int data_count(QDeclarativeListProperty<QObject> *);
+    static QObject *data_at(QDeclarativeListProperty<QObject> *, int);
+    static void data_clear(QDeclarativeListProperty<QObject> *);
+
+    // resources property
+    static QObject *resources_at(QDeclarativeListProperty<QObject> *, int);
+    static void resources_append(QDeclarativeListProperty<QObject> *, QObject *);
+    static int resources_count(QDeclarativeListProperty<QObject> *);
+    static void resources_clear(QDeclarativeListProperty<QObject> *);
+
+    // children property
+    static void children_append(QDeclarativeListProperty<QQuickItem> *, QQuickItem *);
+    static int children_count(QDeclarativeListProperty<QQuickItem> *);
+    static QQuickItem *children_at(QDeclarativeListProperty<QQuickItem> *, int);
+    static void children_clear(QDeclarativeListProperty<QQuickItem> *);
+
+    // transform property
+    static int transform_count(QDeclarativeListProperty<QQuickTransform> *list);
+    static void transform_append(QDeclarativeListProperty<QQuickTransform> *list, QQuickTransform *);
+    static QQuickTransform *transform_at(QDeclarativeListProperty<QQuickTransform> *list, int);
+    static void transform_clear(QDeclarativeListProperty<QQuickTransform> *list);
+
+    QQuickAnchors *anchors() const;
+    mutable QQuickAnchors *_anchors;
+    QQuickContents *_contents;
+
+    QDeclarativeNullableValue<qreal> baselineOffset;
+
+    struct AnchorLines {
+        AnchorLines(QQuickItem *);
+        QQuickAnchorLine left;
+        QQuickAnchorLine right;
+        QQuickAnchorLine hCenter;
+        QQuickAnchorLine top;
+        QQuickAnchorLine bottom;
+        QQuickAnchorLine vCenter;
+        QQuickAnchorLine baseline;
+    };
+    mutable AnchorLines *_anchorLines;
+    AnchorLines *anchorLines() const;
+
+    enum ChangeType {
+        Geometry = 0x01,
+        SiblingOrder = 0x02,
+        Visibility = 0x04,
+        Opacity = 0x08,
+        Destroyed = 0x10,
+        Parent = 0x20,
+        Children = 0x40,
+        Rotation = 0x80,
+    };
+
+    Q_DECLARE_FLAGS(ChangeTypes, ChangeType)
+
+    struct ChangeListener {
+        ChangeListener(QQuickItemChangeListener *l, QQuickItemPrivate::ChangeTypes t) : listener(l), types(t) {}
+        QQuickItemChangeListener *listener;
+        QQuickItemPrivate::ChangeTypes types;
+        bool operator==(const ChangeListener &other) const { return listener == other.listener && types == other.types; }
+    };
+
+    void addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types) {
+        changeListeners.append(ChangeListener(listener, types));
+    }
+    void removeItemChangeListener(QQuickItemChangeListener *, ChangeTypes types);
+    QPODVector<ChangeListener,4> changeListeners;
+
+    QDeclarativeStateGroup *_states();
+    QDeclarativeStateGroup *_stateGroup;
+
+    QQuickItem::TransformOrigin origin:5;
+    quint32 flags:5;
+    bool widthValid:1;
+    bool heightValid:1;
+    bool componentComplete:1;
+    bool keepMouse:1;
+    bool hoverEnabled:1;
+    bool smooth:1;
+    bool focus:1;
+    bool activeFocus:1;
+    bool notifiedFocus:1;
+    bool notifiedActiveFocus:1;
+    bool filtersChildMouseEvents:1;
+    bool explicitVisible:1;
+    bool effectiveVisible:1;
+    bool explicitEnable:1;
+    bool effectiveEnable:1;
+    bool polishScheduled:1;
+    bool inheritedLayoutMirror:1;
+    bool effectiveLayoutMirror:1;
+    bool isMirrorImplicit:1;
+    bool inheritMirrorFromParent:1;
+    bool inheritMirrorFromItem:1;
+    bool childrenDoNotOverlap:1;
+    quint32 dummy:1;
+
+    QQuickCanvas *canvas;
+    QSGContext *sceneGraphContext() const { Q_ASSERT(canvas); return static_cast<QQuickCanvasPrivate *>(QObjectPrivate::get(canvas))->context; }
+
+    QQuickItem *parentItem;
+    QList<QQuickItem *> childItems;
+    QList<QQuickItem *> paintOrderChildItems() const;
+    void addChild(QQuickItem *);
+    void removeChild(QQuickItem *);
+    void siblingOrderChanged();
+
+    class InitializationState {
+    public:
+        QQuickItem *getFocusScope(QQuickItem *item);
+        void clear();
+        void clear(QQuickItem *focusScope);
+    private:
+        QQuickItem *focusScope;
+    };
+    void initCanvas(InitializationState *, QQuickCanvas *);
+
+    QQuickItem *subFocusItem;
+
+    QTransform canvasToItemTransform() const;
+    QTransform itemToCanvasTransform() const;
+    void itemToParentTransform(QTransform &) const;
+
+    qreal x;
+    qreal y;
+    qreal width;
+    qreal height;
+    qreal implicitWidth;
+    qreal implicitHeight;
+
+    qreal z;
+    qreal scale;
+    qreal rotation;
+    qreal opacity;
+
+    QQuickLayoutMirroringAttached* attachedLayoutDirection;
+
+    Qt::MouseButtons acceptedMouseButtons;
+    Qt::InputMethodHints imHints;
+
+    QPointF transformOriginPoint;
+
+    virtual qreal getImplicitWidth() const;
+    virtual qreal getImplicitHeight() const;
+    virtual void implicitWidthChanged();
+    virtual void implicitHeightChanged();
+
+    void resolveLayoutMirror();
+    void setImplicitLayoutMirror(bool mirror, bool inherit);
+    void setLayoutMirror(bool mirror);
+    bool isMirrored() const {
+        return effectiveLayoutMirror;
+    }
+
+    QPointF computeTransformOrigin() const;
+    QList<QQuickTransform *> transforms;
+    virtual void transformChanged();
+
+    QQuickItemKeyFilter *keyHandler;
+    void deliverKeyEvent(QKeyEvent *);
+    void deliverInputMethodEvent(QInputMethodEvent *);
+    void deliverFocusEvent(QFocusEvent *);
+    void deliverMouseEvent(QMouseEvent *);
+    void deliverWheelEvent(QWheelEvent *);
+    void deliverTouchEvent(QTouchEvent *);
+    void deliverHoverEvent(QHoverEvent *);
+    void deliverDragEvent(QEvent *);
+
+    bool calcEffectiveVisible() const;
+    void setEffectiveVisibleRecur(bool);
+    bool calcEffectiveEnable() const;
+    void setEffectiveEnableRecur(bool);
+
+    // XXX todo
+    enum DirtyType {
+        TransformOrigin         = 0x00000001,
+        Transform               = 0x00000002,
+        BasicTransform          = 0x00000004,
+        Position                = 0x00000008,
+        Size                    = 0x00000010,
+
+        ZValue                  = 0x00000020,
+        Content                 = 0x00000040,
+        Smooth                  = 0x00000080,
+        OpacityValue            = 0x00000100,
+        ChildrenChanged         = 0x00000200,
+        ChildrenStackingChanged = 0x00000400,
+        ParentChanged           = 0x00000800,
+
+        Clip                    = 0x00001000,
+        Canvas                  = 0x00002000,
+
+        EffectReference         = 0x00008000,
+        Visible                 = 0x00010000,
+        HideReference           = 0x00020000,
+        // When you add an attribute here, don't forget to update
+        // dirtyToString()
+
+        TransformUpdateMask     = TransformOrigin | Transform | BasicTransform | Position | Size | Canvas,
+        ComplexTransformUpdateMask     = Transform | Canvas,
+        ContentUpdateMask       = Size | Content | Smooth | Canvas,
+        ChildrenUpdateMask      = ChildrenChanged | ChildrenStackingChanged | EffectReference | Canvas,
+
+    };
+    quint32 dirtyAttributes;
+    QString dirtyToString() const;
+    void dirty(DirtyType);
+    void addToDirtyList();
+    void removeFromDirtyList();
+    QQuickItem *nextDirtyItem;
+    QQuickItem**prevDirtyItem;
+
+    inline QSGTransformNode *itemNode();
+    inline QSGNode *childContainerNode();
+
+    /*
+      QSGNode order is:
+         - itemNode
+         - (opacityNode)
+         - (clipNode)
+         - (effectNode)
+         - groupNode
+     */
+
+    QSGTransformNode *itemNodeInstance;
+    QSGOpacityNode *opacityNode;
+    QQuickDefaultClipNode *clipNode;
+    QSGRootNode *rootNode;
+    QSGNode *groupNode;
+    QSGNode *paintNode;
+    QSGNode *beforePaintNode;
+
+    virtual QSGTransformNode *createTransformNode();
+
+    // A reference from an effect item means that this item is used by the effect, so
+    // it should insert a root node.
+    void refFromEffectItem(bool hide);
+    void derefFromEffectItem(bool unhide);
+    int effectRefCount;
+    int hideRefCount;
+
+    void itemChange(QQuickItem::ItemChange, const QQuickItem::ItemChangeData &);
+
+    virtual void mirrorChange() {}
+
+    static qint64 consistentTime;
+    static void setConsistentTime(qint64 t);
+    static void start(QElapsedTimer &);
+    static qint64 elapsed(QElapsedTimer &);
+    static qint64 restart(QElapsedTimer &);
+};
+
+/*
+    Key filters can be installed on a QQuickItem, but not removed.  Currently they
+    are only used by attached objects (which are only destroyed on Item
+    destruction), so this isn't a problem.  If in future this becomes any form
+    of public API, they will have to support removal too.
+*/
+class QQuickItemKeyFilter
+{
+public:
+    QQuickItemKeyFilter(QQuickItem * = 0);
+    virtual ~QQuickItemKeyFilter();
+
+    virtual void keyPressed(QKeyEvent *event, bool post);
+    virtual void keyReleased(QKeyEvent *event, bool post);
+    virtual void inputMethodEvent(QInputMethodEvent *event, bool post);
+    virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
+    virtual void componentComplete();
+
+    bool m_processPost;
+
+private:
+    QQuickItemKeyFilter *m_next;
+};
+
+class QQuickKeyNavigationAttachedPrivate : public QObjectPrivate
+{
+public:
+    QQuickKeyNavigationAttachedPrivate()
+        : QObjectPrivate(),
+          left(0), right(0), up(0), down(0), tab(0), backtab(0),
+          leftSet(false), rightSet(false), upSet(false), downSet(false),
+          tabSet(false), backtabSet(false) {}
+
+    QQuickItem *left;
+    QQuickItem *right;
+    QQuickItem *up;
+    QQuickItem *down;
+    QQuickItem *tab;
+    QQuickItem *backtab;
+    bool leftSet : 1;
+    bool rightSet : 1;
+    bool upSet : 1;
+    bool downSet : 1;
+    bool tabSet : 1;
+    bool backtabSet : 1;
+};
+
+class QQuickKeyNavigationAttached : public QObject, public QQuickItemKeyFilter
+{
+    Q_OBJECT
+    Q_DECLARE_PRIVATE(QQuickKeyNavigationAttached)
+
+    Q_PROPERTY(QQuickItem *left READ left WRITE setLeft NOTIFY leftChanged)
+    Q_PROPERTY(QQuickItem *right READ right WRITE setRight NOTIFY rightChanged)
+    Q_PROPERTY(QQuickItem *up READ up WRITE setUp NOTIFY upChanged)
+    Q_PROPERTY(QQuickItem *down READ down WRITE setDown NOTIFY downChanged)
+    Q_PROPERTY(QQuickItem *tab READ tab WRITE setTab NOTIFY tabChanged)
+    Q_PROPERTY(QQuickItem *backtab READ backtab WRITE setBacktab NOTIFY backtabChanged)
+    Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
+
+    Q_ENUMS(Priority)
+
+public:
+    QQuickKeyNavigationAttached(QObject * = 0);
+
+    QQuickItem *left() const;
+    void setLeft(QQuickItem *);
+    QQuickItem *right() const;
+    void setRight(QQuickItem *);
+    QQuickItem *up() const;
+    void setUp(QQuickItem *);
+    QQuickItem *down() const;
+    void setDown(QQuickItem *);
+    QQuickItem *tab() const;
+    void setTab(QQuickItem *);
+    QQuickItem *backtab() const;
+    void setBacktab(QQuickItem *);
+
+    enum Priority { BeforeItem, AfterItem };
+    Priority priority() const;
+    void setPriority(Priority);
+
+    static QQuickKeyNavigationAttached *qmlAttachedProperties(QObject *);
+
+Q_SIGNALS:
+    void leftChanged();
+    void rightChanged();
+    void upChanged();
+    void downChanged();
+    void tabChanged();
+    void backtabChanged();
+    void priorityChanged();
+
+private:
+    virtual void keyPressed(QKeyEvent *event, bool post);
+    virtual void keyReleased(QKeyEvent *event, bool post);
+    void setFocusNavigation(QQuickItem *currentItem, const char *dir);
+};
+
+class QQuickLayoutMirroringAttached : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(bool enabled READ enabled WRITE setEnabled RESET resetEnabled NOTIFY enabledChanged)
+    Q_PROPERTY(bool childrenInherit READ childrenInherit WRITE setChildrenInherit NOTIFY childrenInheritChanged)
+
+public:
+    explicit QQuickLayoutMirroringAttached(QObject *parent = 0);
+
+    bool enabled() const;
+    void setEnabled(bool);
+    void resetEnabled();
+
+    bool childrenInherit() const;
+    void setChildrenInherit(bool);
+
+    static QQuickLayoutMirroringAttached *qmlAttachedProperties(QObject *);
+Q_SIGNALS:
+    void enabledChanged();
+    void childrenInheritChanged();
+private:
+    friend class QQuickItemPrivate;
+    QQuickItemPrivate *itemPrivate;
+};
+
+class QQuickKeysAttachedPrivate : public QObjectPrivate
+{
+public:
+    QQuickKeysAttachedPrivate()
+        : QObjectPrivate(), inPress(false), inRelease(false)
+        , inIM(false), enabled(true), imeItem(0), item(0)
+    {}
+
+    bool isConnected(const char *signalName);
+
+    //loop detection
+    bool inPress:1;
+    bool inRelease:1;
+    bool inIM:1;
+
+    bool enabled : 1;
+
+    QQuickItem *imeItem;
+    QList<QQuickItem *> targets;
+    QQuickItem *item;
+};
+
+class QQuickKeysAttached : public QObject, public QQuickItemKeyFilter
+{
+    Q_OBJECT
+    Q_DECLARE_PRIVATE(QQuickKeysAttached)
+
+    Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
+    Q_PROPERTY(QDeclarativeListProperty<QQuickItem> forwardTo READ forwardTo)
+    Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
+
+    Q_ENUMS(Priority)
+
+public:
+    QQuickKeysAttached(QObject *parent=0);
+    ~QQuickKeysAttached();
+
+    bool enabled() const { Q_D(const QQuickKeysAttached); return d->enabled; }
+    void setEnabled(bool enabled) {
+        Q_D(QQuickKeysAttached);
+        if (enabled != d->enabled) {
+            d->enabled = enabled;
+            emit enabledChanged();
+        }
+    }
+
+    enum Priority { BeforeItem, AfterItem};
+    Priority priority() const;
+    void setPriority(Priority);
+
+    QDeclarativeListProperty<QQuickItem> forwardTo() {
+        Q_D(QQuickKeysAttached);
+        return QDeclarativeListProperty<QQuickItem>(this, d->targets);
+    }
+
+    virtual void componentComplete();
+
+    static QQuickKeysAttached *qmlAttachedProperties(QObject *);
+
+Q_SIGNALS:
+    void enabledChanged();
+    void priorityChanged();
+    void pressed(QQuickKeyEvent *event);
+    void released(QQuickKeyEvent *event);
+    void digit0Pressed(QQuickKeyEvent *event);
+    void digit1Pressed(QQuickKeyEvent *event);
+    void digit2Pressed(QQuickKeyEvent *event);
+    void digit3Pressed(QQuickKeyEvent *event);
+    void digit4Pressed(QQuickKeyEvent *event);
+    void digit5Pressed(QQuickKeyEvent *event);
+    void digit6Pressed(QQuickKeyEvent *event);
+    void digit7Pressed(QQuickKeyEvent *event);
+    void digit8Pressed(QQuickKeyEvent *event);
+    void digit9Pressed(QQuickKeyEvent *event);
+
+    void leftPressed(QQuickKeyEvent *event);
+    void rightPressed(QQuickKeyEvent *event);
+    void upPressed(QQuickKeyEvent *event);
+    void downPressed(QQuickKeyEvent *event);
+    void tabPressed(QQuickKeyEvent *event);
+    void backtabPressed(QQuickKeyEvent *event);
+
+    void asteriskPressed(QQuickKeyEvent *event);
+    void numberSignPressed(QQuickKeyEvent *event);
+    void escapePressed(QQuickKeyEvent *event);
+    void returnPressed(QQuickKeyEvent *event);
+    void enterPressed(QQuickKeyEvent *event);
+    void deletePressed(QQuickKeyEvent *event);
+    void spacePressed(QQuickKeyEvent *event);
+    void backPressed(QQuickKeyEvent *event);
+    void cancelPressed(QQuickKeyEvent *event);
+    void selectPressed(QQuickKeyEvent *event);
+    void yesPressed(QQuickKeyEvent *event);
+    void noPressed(QQuickKeyEvent *event);
+    void context1Pressed(QQuickKeyEvent *event);
+    void context2Pressed(QQuickKeyEvent *event);
+    void context3Pressed(QQuickKeyEvent *event);
+    void context4Pressed(QQuickKeyEvent *event);
+    void callPressed(QQuickKeyEvent *event);
+    void hangupPressed(QQuickKeyEvent *event);
+    void flipPressed(QQuickKeyEvent *event);
+    void menuPressed(QQuickKeyEvent *event);
+    void volumeUpPressed(QQuickKeyEvent *event);
+    void volumeDownPressed(QQuickKeyEvent *event);
+
+private:
+    virtual void keyPressed(QKeyEvent *event, bool post);
+    virtual void keyReleased(QKeyEvent *event, bool post);
+    virtual void inputMethodEvent(QInputMethodEvent *, bool post);
+    virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
+
+    const QByteArray keyToSignal(int key) {
+        QByteArray keySignal;
+        if (key >= Qt::Key_0 && key <= Qt::Key_9) {
+            keySignal = "digit0Pressed";
+            keySignal[5] = '0' + (key - Qt::Key_0);
+        } else {
+            int i = 0;
+            while (sigMap[i].key && sigMap[i].key != key)
+                ++i;
+            keySignal = sigMap[i].sig;
+        }
+        return keySignal;
+    }
+
+    struct SigMap {
+        int key;
+        const char *sig;
+    };
+
+    static const SigMap sigMap[];
+};
+
+QSGTransformNode *QQuickItemPrivate::itemNode()
+{
+    if (!itemNodeInstance) {
+        itemNodeInstance = createTransformNode();
+        itemNodeInstance->setFlag(QSGNode::OwnedByParent, false);
+#ifdef QML_RUNTIME_TESTING
+        Q_Q(QQuickItem);
+        itemNodeInstance->description = QString::fromLatin1("QQuickItem(%1)").arg(QString::fromLatin1(q->metaObject()->className()));
+#endif
+    }
+    return itemNodeInstance;
+}
+
+QSGNode *QQuickItemPrivate::childContainerNode()
+{
+    if (!groupNode) {
+        groupNode = new QSGNode();
+        if (rootNode)
+            rootNode->appendChildNode(groupNode);
+        else if (clipNode)
+            clipNode->appendChildNode(groupNode);
+        else if (opacityNode)
+            opacityNode->appendChildNode(groupNode);
+        else
+            itemNode()->appendChildNode(groupNode);
+        groupNode->setFlag(QSGNode::ChildrenDoNotOverlap, childrenDoNotOverlap);
+#ifdef QML_RUNTIME_TESTING
+        groupNode->description = QLatin1String("group");
+#endif
+    }
+    return groupNode;
+}
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickItemPrivate::ChangeTypes);
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickKeysAttached)
+QML_DECLARE_TYPEINFO(QQuickKeysAttached, QML_HAS_ATTACHED_PROPERTIES)
+QML_DECLARE_TYPE(QQuickKeyNavigationAttached)
+QML_DECLARE_TYPEINFO(QQuickKeyNavigationAttached, QML_HAS_ATTACHED_PROPERTIES)
+QML_DECLARE_TYPE(QQuickLayoutMirroringAttached)
+QML_DECLARE_TYPEINFO(QQuickLayoutMirroringAttached, QML_HAS_ATTACHED_PROPERTIES)
+
+#endif // QQUICKITEM_P_H
diff --git a/src/declarative/items/qquickitemchangelistener_p.h b/src/declarative/items/qquickitemchangelistener_p.h
new file mode 100644 (file)
index 0000000..a021658
--- /dev/null
@@ -0,0 +1,82 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
+/****************************************************************************
+**
+** 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 QQUICKITEMCHANGELISTENER_P_H
+#define QQUICKITEMCHANGELISTENER_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
+
+class QRectF;
+class QQuickItem;
+class QQuickAnchorsPrivate;
+class QQuickItemChangeListener
+{
+public:
+    virtual void itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &) {}
+    virtual void itemSiblingOrderChanged(QQuickItem *) {}
+    virtual void itemVisibilityChanged(QQuickItem *) {}
+    virtual void itemOpacityChanged(QQuickItem *) {}
+    virtual void itemDestroyed(QQuickItem *) {}
+    virtual void itemChildAdded(QQuickItem *, QQuickItem *) {}
+    virtual void itemChildRemoved(QQuickItem *, QQuickItem *) {}
+    virtual void itemParentChanged(QQuickItem *, QQuickItem *) {}
+    virtual void itemRotationChanged(QQuickItem *) {}
+
+    virtual QQuickAnchorsPrivate *anchorPrivate() { return 0; }
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKITEMCHANGELISTENER_P_H
diff --git a/src/declarative/items/qquickitemsmodule.cpp b/src/declarative/items/qquickitemsmodule.cpp
new file mode 100644 (file)
index 0000000..38b5a91
--- /dev/null
@@ -0,0 +1,228 @@
+/****************************************************************************
+**
+** 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 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 "qquickitemsmodule_p.h"
+
+#include "qquickitem.h"
+#include "qquickitem_p.h"
+#include "qquickevents_p_p.h"
+#include "qquickrectangle_p.h"
+#include "qquickfocusscope_p.h"
+#include "qquicktext_p.h"
+#include "qquicktextinput_p.h"
+#include "qquicktextedit_p.h"
+#include "qquickimage_p.h"
+#include "qquickborderimage_p.h"
+#include "qquickscalegrid_p_p.h"
+#include "qquickmousearea_p.h"
+#include "qquickpincharea_p.h"
+#include "qquickflickable_p.h"
+#include "qquickflickable_p_p.h"
+#include "qquicklistview_p.h"
+#include "qquickvisualitemmodel_p.h"
+#include "qquickvisualdatamodel_p.h"
+#include "qquickgridview_p.h"
+#include "qquickpathview_p.h"
+#include <private/qdeclarativepath_p.h>
+#include <private/qdeclarativepathinterpolator_p.h>
+#include "qquickpositioners_p.h"
+#include "qquickrepeater_p.h"
+#include "qquickloader_p.h"
+#include "qquickanimatedimage_p.h"
+#include "qquickflipable_p.h"
+#include "qquicktranslate_p.h"
+#include "qquickstateoperations_p.h"
+#include "qquickanimation_p.h"
+#include <private/qquickshadereffect_p.h>
+#include <private/qquickshadereffectsource_p.h>
+//#include <private/qquickpincharea_p.h>
+#include <private/qquickcanvasitem_p.h>
+#include <private/qquickcontext2d_p.h>
+#include "qquicksprite_p.h"
+#include "qquickspriteimage_p.h"
+#include "qquickdrag_p.h"
+#include "qquickdroparea_p.h"
+
+static QDeclarativePrivate::AutoParentResult qquickitem_autoParent(QObject *obj, QObject *parent)
+{
+    QQuickItem *item = qobject_cast<QQuickItem *>(obj);
+    if (!item)
+        return QDeclarativePrivate::IncompatibleObject;
+
+    QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent);
+    if (!parentItem)
+        return QDeclarativePrivate::IncompatibleParent;
+
+    item->setParentItem(parentItem);
+    return QDeclarativePrivate::Parented;
+}
+
+static void qt_quickitems_defineModule(const char *uri, int major, int minor)
+{
+    QDeclarativePrivate::RegisterAutoParent autoparent = { 0, &qquickitem_autoParent };
+    QDeclarativePrivate::qmlregister(QDeclarativePrivate::AutoParentRegistration, &autoparent);
+
+#ifdef QT_NO_MOVIE
+    qmlRegisterTypeNotAvailable(uri,major,minor,"AnimatedImage", qApp->translate("QQuickAnimatedImage","Qt was built without support for QMovie"));
+#else
+    qmlRegisterType<QQuickAnimatedImage>(uri,major,minor,"AnimatedImage");
+#endif
+    qmlRegisterType<QQuickBorderImage>(uri,major,minor,"BorderImage");
+    qmlRegisterType<QQuickColumn>(uri,major,minor,"Column");
+    qmlRegisterType<QQuickFlickable>(uri,major,minor,"Flickable");
+    qmlRegisterType<QQuickFlipable>(uri,major,minor,"Flipable");
+    qmlRegisterType<QQuickFlow>(uri,major,minor,"Flow");
+//    qmlRegisterType<QDeclarativeFocusPanel>(uri,major,minor,"FocusPanel");
+    qmlRegisterType<QQuickFocusScope>(uri,major,minor,"FocusScope");
+    qmlRegisterType<QQuickGradient>(uri,major,minor,"Gradient");
+    qmlRegisterType<QQuickGradientStop>(uri,major,minor,"GradientStop");
+    qmlRegisterType<QQuickGrid>(uri,major,minor,"Grid");
+    qmlRegisterType<QQuickGridView>(uri,major,minor,"GridView");
+    qmlRegisterType<QQuickImage>(uri,major,minor,"Image");
+    qmlRegisterType<QQuickItem>(uri,major,minor,"Item");
+    qmlRegisterType<QQuickListView>(uri,major,minor,"ListView");
+    qmlRegisterType<QQuickLoader>(uri,major,minor,"Loader");
+    qmlRegisterType<QQuickMouseArea>(uri,major,minor,"MouseArea");
+    qmlRegisterType<QDeclarativePath>(uri,major,minor,"Path");
+    qmlRegisterType<QDeclarativePathAttribute>(uri,major,minor,"PathAttribute");
+    qmlRegisterType<QDeclarativePathCubic>(uri,major,minor,"PathCubic");
+    qmlRegisterType<QDeclarativePathLine>(uri,major,minor,"PathLine");
+    qmlRegisterType<QDeclarativePathPercent>(uri,major,minor,"PathPercent");
+    qmlRegisterType<QDeclarativePathQuad>(uri,major,minor,"PathQuad");
+    qmlRegisterType<QDeclarativePathCatmullRomCurve>("QtQuick",2,0,"PathCurve");
+    qmlRegisterType<QDeclarativePathArc>("QtQuick",2,0,"PathArc");
+    qmlRegisterType<QDeclarativePathSvg>("QtQuick",2,0,"PathSvg");
+    qmlRegisterType<QQuickPathView>(uri,major,minor,"PathView");
+    qmlRegisterUncreatableType<QQuickBasePositioner>(uri,major,minor,"Positioner",
+                                                  QStringLiteral("Positioner is an abstract type that is only available as an attached property."));
+#ifndef QT_NO_VALIDATOR
+    qmlRegisterType<QIntValidator>(uri,major,minor,"IntValidator");
+    qmlRegisterType<QDoubleValidator>(uri,major,minor,"DoubleValidator");
+    qmlRegisterType<QRegExpValidator>(uri,major,minor,"RegExpValidator");
+#endif
+    qmlRegisterType<QQuickRectangle>(uri,major,minor,"Rectangle");
+    qmlRegisterType<QQuickRepeater>(uri,major,minor,"Repeater");
+    qmlRegisterType<QQuickRow>(uri,major,minor,"Row");
+    qmlRegisterType<QQuickTranslate>(uri,major,minor,"Translate");
+    qmlRegisterType<QQuickRotation>(uri,major,minor,"Rotation");
+    qmlRegisterType<QQuickScale>(uri,major,minor,"Scale");
+    qmlRegisterType<QQuickText>(uri,major,minor,"Text");
+    qmlRegisterType<QQuickTextEdit>(uri,major,minor,"TextEdit");
+    qmlRegisterType<QQuickTextInput>(uri,major,minor,"TextInput");
+    qmlRegisterType<QQuickViewSection>(uri,major,minor,"ViewSection");
+    qmlRegisterType<QQuickVisualDataModel>(uri,major,minor,"VisualDataModel");
+    qmlRegisterType<QQuickVisualDataGroup>(uri,major,minor,"VisualDataGroup");
+    qmlRegisterType<QQuickVisualItemModel>(uri,major,minor,"VisualItemModel");
+
+    qmlRegisterType<QQuickAnchors>();
+    qmlRegisterType<QQuickKeyEvent>();
+    qmlRegisterType<QQuickMouseEvent>();
+    qmlRegisterType<QQuickTransform>();
+    qmlRegisterType<QDeclarativePathElement>();
+    qmlRegisterType<QDeclarativeCurve>();
+    qmlRegisterType<QQuickScaleGrid>();
+    qmlRegisterType<QQuickTextLine>();
+#ifndef QT_NO_VALIDATOR
+    qmlRegisterType<QValidator>();
+#endif
+    qmlRegisterType<QQuickVisualModel>();
+    qmlRegisterType<QQuickPen>();
+    qmlRegisterType<QQuickFlickableVisibleArea>();
+    qRegisterMetaType<QQuickAnchorLine>("QQuickAnchorLine");
+
+    qmlRegisterUncreatableType<QQuickKeyNavigationAttached>(uri,major,minor,"KeyNavigation",QQuickKeyNavigationAttached::tr("KeyNavigation is only available via attached properties"));
+    qmlRegisterUncreatableType<QQuickKeysAttached>(uri,major,minor,"Keys",QQuickKeysAttached::tr("Keys is only available via attached properties"));
+    qmlRegisterUncreatableType<QQuickLayoutMirroringAttached>(uri,major,minor,"LayoutMirroring", QQuickLayoutMirroringAttached::tr("LayoutMirroring is only available via attached properties"));
+
+    qmlRegisterType<QQuickPinchArea>(uri,major,minor,"PinchArea");
+    qmlRegisterType<QQuickPinch>(uri,major,minor,"Pinch");
+    qmlRegisterType<QQuickPinchEvent>();
+
+    qmlRegisterType<QQuickShaderEffectItem>("QtQuick", 2, 0, "ShaderEffectItem"); // TODO: Remove after grace period.
+    qmlRegisterType<QQuickShaderEffect>("QtQuick", 2, 0, "ShaderEffect");
+    qmlRegisterType<QQuickShaderEffectSource>("QtQuick", 2, 0, "ShaderEffectSource");
+    qmlRegisterUncreatableType<QQuickShaderEffectMesh>("QtQuick", 2, 0, "ShaderEffectMesh", QQuickShaderEffectMesh::tr("Cannot create instance of abstract class ShaderEffectMesh."));
+    qmlRegisterType<QQuickGridMesh>("QtQuick", 2, 0, "GridMesh");
+
+    qmlRegisterUncreatableType<QQuickPaintedItem>("QtQuick", 2, 0, "PaintedItem", QQuickPaintedItem::tr("Cannot create instance of abstract class PaintedItem"));
+
+    qmlRegisterType<QQuickCanvasItem>("QtQuick", 2, 0, "Canvas");
+
+    qmlRegisterType<QQuickSprite>("QtQuick", 2, 0, "Sprite");
+    qmlRegisterType<QQuickSpriteImage>("QtQuick", 2, 0, "SpriteImage");
+
+    qmlRegisterType<QQuickParentChange>(uri, major, minor,"ParentChange");
+    qmlRegisterType<QQuickAnchorChanges>(uri, major, minor,"AnchorChanges");
+    qmlRegisterType<QQuickAnchorSet>();
+    qmlRegisterType<QQuickAnchorAnimation>(uri, major, minor,"AnchorAnimation");
+    qmlRegisterType<QQuickParentAnimation>(uri, major, minor,"ParentAnimation");
+    qmlRegisterType<QQuickPathAnimation>("QtQuick",2,0,"PathAnimation");
+    qmlRegisterType<QDeclarativePathInterpolator>("QtQuick",2,0,"PathInterpolator");
+
+    qmlRegisterType<QQuickDropArea>("QtQuick", 2, 0, "DropArea");
+    qmlRegisterType<QQuickDropEvent>();
+    qmlRegisterType<QQuickDropAreaDrag>();
+    qmlRegisterUncreatableType<QQuickDrag>("QtQuick", 2, 0, "Drag", QQuickDragAttached::tr("Drag is only available via attached properties"));
+}
+
+void QQuickItemsModule::defineModule()
+{
+    static bool initialized = false;
+    if (initialized)
+        return;
+    initialized = true;
+
+    // XXX todo -  Remove before final integration...
+    QByteArray mode = qgetenv("QMLSCENE_IMPORT_NAME");
+    QByteArray name = "QtQuick";
+    int majorVersion = 2;
+    int minorVersion = 0;
+    if (mode == "quick1") {
+        majorVersion = 1;
+    } else if (mode == "qt") {
+        name = "Qt";
+        majorVersion = 4;
+        minorVersion = 7;
+    }
+
+    qt_quickitems_defineModule(name, majorVersion, minorVersion);
+}
+
diff --git a/src/declarative/items/qquickitemsmodule_p.h b/src/declarative/items/qquickitemsmodule_p.h
new file mode 100644 (file)
index 0000000..d368200
--- /dev/null
@@ -0,0 +1,65 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
+/****************************************************************************
+**
+** 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 QQUICKITEMSMODULE_P_H
+#define QQUICKITEMSMODULE_P_H
+
+#include <qdeclarative.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickItemsModule
+{
+public:
+    static void defineModule();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QQUICKITEMSMODULE_P_H
+
diff --git a/src/declarative/items/qquickitemview.cpp b/src/declarative/items/qquickitemview.cpp
new file mode 100644 (file)
index 0000000..b3429de
--- /dev/null
@@ -0,0 +1,1676 @@
+/****************************************************************************
+**
+** 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 "qquickitemview_p_p.h"
+
+QT_BEGIN_NAMESPACE
+
+
+FxViewItem::FxViewItem(QQuickItem *i, bool own)
+    : item(i), ownItem(own), index(-1)
+{
+}
+
+FxViewItem::~FxViewItem()
+{
+    if (ownItem && item) {
+        item->setParentItem(0);
+        item->deleteLater();
+        item = 0;
+    }
+}
+
+
+QQuickItemViewChangeSet::QQuickItemViewChangeSet()
+    : active(false)
+{
+    reset();
+}
+
+bool QQuickItemViewChangeSet::hasPendingChanges() const
+{
+    return !pendingChanges.isEmpty();
+}
+
+void QQuickItemViewChangeSet::applyChanges(const QDeclarativeChangeSet &changeSet)
+{
+    pendingChanges.apply(changeSet);
+
+    int moveId = -1;
+    int moveOffset;
+
+    foreach (const QDeclarativeChangeSet::Remove &r, changeSet.removes()) {
+        itemCount -= r.count;
+        if (moveId == -1 && newCurrentIndex >= r.index + r.count) {
+            newCurrentIndex -= r.count;
+            currentChanged = true;
+        } else if (moveId == -1 && newCurrentIndex >= r.index && newCurrentIndex < r.index + r.count) {
+            // current item has been removed.
+            if (r.isMove()) {
+                moveId = r.moveId;
+                moveOffset = newCurrentIndex - r.index;
+            } else {
+                currentRemoved = true;
+                newCurrentIndex = -1;
+                if (itemCount)
+                    newCurrentIndex = qMin(r.index, itemCount - 1);
+            }
+            currentChanged = true;
+        }
+    }
+    foreach (const QDeclarativeChangeSet::Insert &i, changeSet.inserts()) {
+        if (moveId == -1) {
+            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;
+    }
+}
+
+void QQuickItemViewChangeSet::prepare(int currentIndex, int count)
+{
+    if (active)
+        return;
+    reset();
+    active = true;
+    itemCount = count;
+    newCurrentIndex = currentIndex;
+}
+
+void QQuickItemViewChangeSet::reset()
+{
+    itemCount = 0;
+    newCurrentIndex = -1;
+    pendingChanges.clear();
+    removedItems.clear();
+    active = false;
+    currentChanged = false;
+    currentRemoved = false;
+}
+
+
+QQuickItemView::QQuickItemView(QQuickFlickablePrivate &dd, QQuickItem *parent)
+    : QQuickFlickable(dd, parent)
+{
+    Q_D(QQuickItemView);
+    d->init();
+}
+
+QQuickItemView::~QQuickItemView()
+{
+    Q_D(QQuickItemView);
+    d->clear();
+    if (d->ownModel)
+        delete d->model;
+    delete d->header;
+    delete d->footer;
+}
+
+
+QQuickItem *QQuickItemView::currentItem() const
+{
+    Q_D(const QQuickItemView);
+    if (!d->currentItem)
+        return 0;
+    const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges();
+    return d->currentItem->item;
+}
+
+QVariant QQuickItemView::model() const
+{
+    Q_D(const QQuickItemView);
+    return d->modelVariant;
+}
+
+void QQuickItemView::setModel(const QVariant &model)
+{
+    Q_D(QQuickItemView);
+    if (d->modelVariant == model)
+        return;
+    if (d->model) {
+        disconnect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
+                this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
+        disconnect(d->model, SIGNAL(createdItem(int,QQuickItem*)), this, SLOT(createdItem(int,QQuickItem*)));
+        disconnect(d->model, SIGNAL(destroyingItem(QQuickItem*)), this, SLOT(destroyingItem(QQuickItem*)));
+    }
+
+    QQuickVisualModel *oldModel = d->model;
+
+    d->clear();
+    d->setPosition(d->contentStartPosition());
+    d->model = 0;
+    d->modelVariant = model;
+
+    QObject *object = qvariant_cast<QObject*>(model);
+    QQuickVisualModel *vim = 0;
+    if (object && (vim = qobject_cast<QQuickVisualModel *>(object))) {
+        if (d->ownModel) {
+            delete oldModel;
+            d->ownModel = false;
+        }
+        d->model = vim;
+    } else {
+        if (!d->ownModel) {
+            d->model = new QQuickVisualDataModel(qmlContext(this), this);
+            d->ownModel = true;
+            if (isComponentComplete())
+                static_cast<QQuickVisualDataModel *>(d->model.data())->componentComplete();
+        } else {
+            d->model = oldModel;
+        }
+        if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model))
+            dataModel->setModel(model);
+    }
+
+    if (d->model) {
+        d->bufferMode = QQuickItemViewPrivate::BufferBefore | QQuickItemViewPrivate::BufferAfter;
+        if (isComponentComplete()) {
+            updateSections();
+            d->refill();
+            if ((d->currentIndex >= d->model->count() || d->currentIndex < 0) && !d->currentIndexCleared) {
+                setCurrentIndex(0);
+            } else {
+                d->moveReason = QQuickItemViewPrivate::SetIndex;
+                d->updateCurrent(d->currentIndex);
+                if (d->highlight && d->currentItem) {
+                    if (d->autoHighlight)
+                        d->resetHighlightPosition();
+                    d->updateTrackedItem();
+                }
+                d->moveReason = QQuickItemViewPrivate::Other;
+            }
+            d->updateViewport();
+        }
+        connect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
+                this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
+        connect(d->model, SIGNAL(createdItem(int,QQuickItem*)), this, SLOT(createdItem(int,QQuickItem*)));
+        connect(d->model, SIGNAL(destroyingItem(QQuickItem*)), this, SLOT(destroyingItem(QQuickItem*)));
+        emit countChanged();
+    }
+    emit modelChanged();
+}
+
+QDeclarativeComponent *QQuickItemView::delegate() const
+{
+    Q_D(const QQuickItemView);
+    if (d->model) {
+        if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model))
+            return dataModel->delegate();
+    }
+
+    return 0;
+}
+
+void QQuickItemView::setDelegate(QDeclarativeComponent *delegate)
+{
+    Q_D(QQuickItemView);
+    if (delegate == this->delegate())
+        return;
+    if (!d->ownModel) {
+        d->model = new QQuickVisualDataModel(qmlContext(this));
+        d->ownModel = true;
+    }
+    if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model)) {
+        int oldCount = dataModel->count();
+        dataModel->setDelegate(delegate);
+        if (isComponentComplete()) {
+            for (int i = 0; i < d->visibleItems.count(); ++i)
+                d->releaseItem(d->visibleItems.at(i));
+            d->visibleItems.clear();
+            d->releaseItem(d->currentItem);
+            d->currentItem = 0;
+            updateSections();
+            d->refill();
+            d->moveReason = QQuickItemViewPrivate::SetIndex;
+            d->updateCurrent(d->currentIndex);
+            if (d->highlight && d->currentItem) {
+                if (d->autoHighlight)
+                    d->resetHighlightPosition();
+                d->updateTrackedItem();
+            }
+            d->moveReason = QQuickItemViewPrivate::Other;
+            d->updateViewport();
+        }
+        if (oldCount != dataModel->count())
+            emit countChanged();
+    }
+    emit delegateChanged();
+}
+
+
+int QQuickItemView::count() const
+{
+    Q_D(const QQuickItemView);
+    if (!d->model)
+        return 0;
+    const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges();
+    return d->model->count();
+}
+
+int QQuickItemView::currentIndex() const
+{
+    Q_D(const QQuickItemView);
+    const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges();
+    return d->currentIndex;
+}
+
+void QQuickItemView::setCurrentIndex(int index)
+{
+    Q_D(QQuickItemView);
+    if (d->requestedIndex >= 0)  // currently creating item
+        return;
+    d->currentIndexCleared = (index == -1);
+
+    d->applyPendingChanges();
+    if (index == d->currentIndex)
+        return;
+    if (isComponentComplete() && d->isValid()) {
+        d->moveReason = QQuickItemViewPrivate::SetIndex;
+        d->updateCurrent(index);
+    } else if (d->currentIndex != index) {
+        d->currentIndex = index;
+        emit currentIndexChanged();
+    }
+}
+
+
+bool QQuickItemView::isWrapEnabled() const
+{
+    Q_D(const QQuickItemView);
+    return d->wrap;
+}
+
+void QQuickItemView::setWrapEnabled(bool wrap)
+{
+    Q_D(QQuickItemView);
+    if (d->wrap == wrap)
+        return;
+    d->wrap = wrap;
+    emit keyNavigationWrapsChanged();
+}
+
+int QQuickItemView::cacheBuffer() const
+{
+    Q_D(const QQuickItemView);
+    return d->buffer;
+}
+
+void QQuickItemView::setCacheBuffer(int b)
+{
+    Q_D(QQuickItemView);
+    if (d->buffer != b) {
+        d->buffer = b;
+        if (isComponentComplete()) {
+            d->bufferMode = QQuickItemViewPrivate::BufferBefore | QQuickItemViewPrivate::BufferAfter;
+            d->refill();
+        }
+        emit cacheBufferChanged();
+    }
+}
+
+
+Qt::LayoutDirection QQuickItemView::layoutDirection() const
+{
+    Q_D(const QQuickItemView);
+    return d->layoutDirection;
+}
+
+void QQuickItemView::setLayoutDirection(Qt::LayoutDirection layoutDirection)
+{
+    Q_D(QQuickItemView);
+    if (d->layoutDirection != layoutDirection) {
+        d->layoutDirection = layoutDirection;
+        d->regenerate();
+        emit layoutDirectionChanged();
+        emit effectiveLayoutDirectionChanged();
+    }
+}
+
+Qt::LayoutDirection QQuickItemView::effectiveLayoutDirection() const
+{
+    Q_D(const QQuickItemView);
+    if (d->effectiveLayoutMirror)
+        return d->layoutDirection == Qt::RightToLeft ? Qt::LeftToRight : Qt::RightToLeft;
+    else
+        return d->layoutDirection;
+}
+
+
+QDeclarativeComponent *QQuickItemView::header() const
+{
+    Q_D(const QQuickItemView);
+    return d->headerComponent;
+}
+
+QQuickItem *QQuickItemView::headerItem() const
+{
+    Q_D(const QQuickItemView);
+    const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges();
+    return d->header ? d->header->item : 0;
+}
+
+void QQuickItemView::setHeader(QDeclarativeComponent *headerComponent)
+{
+    Q_D(QQuickItemView);
+    if (d->headerComponent != headerComponent) {
+        d->applyPendingChanges();
+        delete d->header;
+        d->header = 0;
+        d->headerComponent = headerComponent;
+
+        d->markExtentsDirty();
+
+        if (isComponentComplete()) {
+            d->updateHeader();
+            d->updateFooter();
+            d->updateViewport();
+            d->fixupPosition();
+        } else {
+            emit headerItemChanged();
+        }
+        emit headerChanged();
+    }
+}
+
+QDeclarativeComponent *QQuickItemView::footer() const
+{
+    Q_D(const QQuickItemView);
+    return d->footerComponent;
+}
+
+QQuickItem *QQuickItemView::footerItem() const
+{
+    Q_D(const QQuickItemView);
+    const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges();
+    return d->footer ? d->footer->item : 0;
+}
+
+void QQuickItemView::setFooter(QDeclarativeComponent *footerComponent)
+{
+    Q_D(QQuickItemView);
+    if (d->footerComponent != footerComponent) {
+        d->applyPendingChanges();
+        delete d->footer;
+        d->footer = 0;
+        d->footerComponent = footerComponent;
+
+        if (isComponentComplete()) {
+            d->updateFooter();
+            d->updateViewport();
+            d->fixupPosition();
+        } else {
+            emit footerItemChanged();
+        }
+        emit footerChanged();
+    }
+}
+
+QDeclarativeComponent *QQuickItemView::highlight() const
+{
+    Q_D(const QQuickItemView);
+    const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges();
+    return d->highlightComponent;
+}
+
+void QQuickItemView::setHighlight(QDeclarativeComponent *highlightComponent)
+{
+    Q_D(QQuickItemView);
+    if (highlightComponent != d->highlightComponent) {
+        d->applyPendingChanges();
+        d->highlightComponent = highlightComponent;
+        d->createHighlight();
+        if (d->currentItem)
+            d->updateHighlight();
+        emit highlightChanged();
+    }
+}
+
+QQuickItem *QQuickItemView::highlightItem() const
+{
+    Q_D(const QQuickItemView);
+    const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges();
+    return d->highlight ? d->highlight->item : 0;
+}
+
+bool QQuickItemView::highlightFollowsCurrentItem() const
+{
+    Q_D(const QQuickItemView);
+    return d->autoHighlight;
+}
+
+void QQuickItemView::setHighlightFollowsCurrentItem(bool autoHighlight)
+{
+    Q_D(QQuickItemView);
+    if (d->autoHighlight != autoHighlight) {
+        d->autoHighlight = autoHighlight;
+        if (autoHighlight)
+            d->updateHighlight();
+        emit highlightFollowsCurrentItemChanged();
+    }
+}
+
+QQuickItemView::HighlightRangeMode QQuickItemView::highlightRangeMode() const
+{
+    Q_D(const QQuickItemView);
+    return static_cast<QQuickItemView::HighlightRangeMode>(d->highlightRange);
+}
+
+void QQuickItemView::setHighlightRangeMode(HighlightRangeMode mode)
+{
+    Q_D(QQuickItemView);
+    if (d->highlightRange == mode)
+        return;
+    d->highlightRange = mode;
+    d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
+    emit highlightRangeModeChanged();
+}
+
+//###Possibly rename these properties, since they are very useful even without a highlight?
+qreal QQuickItemView::preferredHighlightBegin() const
+{
+    Q_D(const QQuickItemView);
+    return d->highlightRangeStart;
+}
+
+void QQuickItemView::setPreferredHighlightBegin(qreal start)
+{
+    Q_D(QQuickItemView);
+    d->highlightRangeStartValid = true;
+    if (d->highlightRangeStart == start)
+        return;
+    d->highlightRangeStart = start;
+    d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
+    emit preferredHighlightBeginChanged();
+}
+
+void QQuickItemView::resetPreferredHighlightBegin()
+{
+    Q_D(QQuickItemView);
+    d->highlightRangeStartValid = false;
+    if (d->highlightRangeStart == 0)
+        return;
+    d->highlightRangeStart = 0;
+    emit preferredHighlightBeginChanged();
+}
+
+qreal QQuickItemView::preferredHighlightEnd() const
+{
+    Q_D(const QQuickItemView);
+    return d->highlightRangeEnd;
+}
+
+void QQuickItemView::setPreferredHighlightEnd(qreal end)
+{
+    Q_D(QQuickItemView);
+    d->highlightRangeEndValid = true;
+    if (d->highlightRangeEnd == end)
+        return;
+    d->highlightRangeEnd = end;
+    d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
+    emit preferredHighlightEndChanged();
+}
+
+void QQuickItemView::resetPreferredHighlightEnd()
+{
+    Q_D(QQuickItemView);
+    d->highlightRangeEndValid = false;
+    if (d->highlightRangeEnd == 0)
+        return;
+    d->highlightRangeEnd = 0;
+    emit preferredHighlightEndChanged();
+}
+
+int QQuickItemView::highlightMoveDuration() const
+{
+    Q_D(const QQuickItemView);
+    return d->highlightMoveDuration;
+}
+
+void QQuickItemView::setHighlightMoveDuration(int duration)
+{
+    Q_D(QQuickItemView);
+    if (d->highlightMoveDuration != duration) {
+        d->highlightMoveDuration = duration;
+        emit highlightMoveDurationChanged();
+    }
+}
+
+void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode)
+{
+    Q_Q(QQuickItemView);
+    if (!isValid())
+        return;
+    if (mode < QQuickItemView::Beginning || mode > QQuickItemView::Contain)
+        return;
+
+    applyPendingChanges();
+    int idx = qMax(qMin(index, model->count()-1), 0);
+
+    qreal pos = isContentFlowReversed() ? -position() - size() : position();
+    FxViewItem *item = visibleItem(idx);
+    qreal maxExtent;
+    if (layoutOrientation() == Qt::Vertical)
+        maxExtent = -q->maxYExtent();
+    else
+        maxExtent = isContentFlowReversed() ? q->minXExtent()-size(): -q->maxXExtent();
+    if (!item) {
+        int itemPos = positionAt(idx);
+        changedVisibleIndex(idx);
+        // save the currently visible items in case any of them end up visible again
+        QList<FxViewItem *> oldVisible = visibleItems;
+        visibleItems.clear();
+        setPosition(qMin(qreal(itemPos), maxExtent));
+        // now release the reference to all the old visible items.
+        for (int i = 0; i < oldVisible.count(); ++i)
+            releaseItem(oldVisible.at(i));
+        item = visibleItem(idx);
+    }
+    if (item) {
+        const qreal itemPos = item->position();
+        switch (mode) {
+        case QQuickItemView::Beginning:
+            pos = itemPos;
+            if (index < 0 && header)
+                pos -= headerSize();
+            break;
+        case QQuickItemView::Center:
+            pos = itemPos - (size() - item->size())/2;
+            break;
+        case QQuickItemView::End:
+            pos = itemPos - size() + item->size();
+            if (index >= model->count() && footer)
+                pos += footerSize();
+            break;
+        case QQuickItemView::Visible:
+            if (itemPos > pos + size())
+                pos = itemPos - size() + item->size();
+            else if (item->endPosition() <= pos)
+                pos = itemPos;
+            break;
+        case QQuickItemView::Contain:
+            if (item->endPosition() >= pos + size())
+                pos = itemPos - size() + item->size();
+            if (itemPos < pos)
+                pos = itemPos;
+        }
+        pos = qMin(pos, maxExtent);
+        qreal minExtent;
+        if (layoutOrientation() == Qt::Vertical)
+            minExtent = -q->minYExtent();
+        else
+            minExtent = isContentFlowReversed() ? q->maxXExtent()-size(): -q->minXExtent();
+        pos = qMax(pos, minExtent);
+        moveReason = QQuickItemViewPrivate::Other;
+        q->cancelFlick();
+        setPosition(pos);
+
+        if (highlight) {
+            if (autoHighlight)
+                resetHighlightPosition();
+            updateHighlight();
+        }
+    }
+    fixupPosition();
+}
+
+void QQuickItemView::positionViewAtIndex(int index, int mode)
+{
+    Q_D(QQuickItemView);
+    if (!d->isValid() || index < 0 || index >= d->model->count())
+        return;
+    d->positionViewAtIndex(index, mode);
+}
+
+
+void QQuickItemView::positionViewAtBeginning()
+{
+    Q_D(QQuickItemView);
+    if (!d->isValid())
+        return;
+    d->positionViewAtIndex(-1, Beginning);
+}
+
+void QQuickItemView::positionViewAtEnd()
+{
+    Q_D(QQuickItemView);
+    if (!d->isValid())
+        return;
+    d->positionViewAtIndex(d->model->count(), End);
+}
+
+int QQuickItemView::indexAt(qreal x, qreal y) const
+{
+    Q_D(const QQuickItemView);
+    for (int i = 0; i < d->visibleItems.count(); ++i) {
+        const FxViewItem *item = d->visibleItems.at(i);
+        if (item->contains(x, y))
+            return item->index;
+    }
+
+    return -1;
+}
+
+void QQuickItemViewPrivate::applyPendingChanges()
+{
+    Q_Q(QQuickItemView);
+    if (q->isComponentComplete() && currentChanges.hasPendingChanges())
+        layout();
+}
+
+// for debugging only
+void QQuickItemViewPrivate::checkVisible() const
+{
+    int skip = 0;
+    for (int i = 0; i < visibleItems.count(); ++i) {
+        FxViewItem *item = visibleItems.at(i);
+        if (item->index == -1) {
+            ++skip;
+        } else if (item->index != visibleIndex + i - skip) {
+            qFatal("index %d %d %d", visibleIndex, i, item->index);
+        }
+    }
+}
+
+void QQuickItemViewPrivate::itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+    Q_Q(QQuickItemView);
+    QQuickFlickablePrivate::itemGeometryChanged(item, newGeometry, oldGeometry);
+    if (!q->isComponentComplete())
+        return;
+
+    if (header && header->item == item) {
+        updateHeader();
+        markExtentsDirty();
+        if (!q->isMoving() && !q->isFlicking())
+            fixupPosition();
+    } else if (footer && footer->item == item) {
+        updateFooter();
+        markExtentsDirty();
+        if (!q->isMoving() && !q->isFlicking())
+            fixupPosition();
+    }
+
+    if (currentItem && currentItem->item == item)
+        updateHighlight();
+    if (trackedItem && trackedItem->item == item)
+        q->trackedPositionChanged();
+}
+
+void QQuickItemView::destroyRemoved()
+{
+    Q_D(QQuickItemView);
+    for (QList<FxViewItem*>::Iterator it = d->visibleItems.begin();
+            it != d->visibleItems.end();) {
+        FxViewItem *item = *it;
+        if (item->index == -1 && item->attached->delayRemove() == false) {
+            d->releaseItem(item);
+            it = d->visibleItems.erase(it);
+        } else {
+            ++it;
+        }
+    }
+
+    // Correct the positioning of the items
+    d->updateSections();
+    d->forceLayout = true;
+    d->layout();
+}
+
+void QQuickItemView::modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset)
+{
+    Q_D(QQuickItemView);
+    if (reset) {
+        d->moveReason = QQuickItemViewPrivate::SetIndex;
+        d->regenerate();
+        if (d->highlight && d->currentItem) {
+            if (d->autoHighlight)
+                d->resetHighlightPosition();
+            d->updateTrackedItem();
+        }
+        d->moveReason = QQuickItemViewPrivate::Other;
+
+        emit countChanged();
+    } else {
+        d->currentChanges.prepare(d->currentIndex, d->itemCount);
+        d->currentChanges.applyChanges(changeSet);
+        polish();
+    }
+}
+
+void QQuickItemView::createdItem(int index, QQuickItem *item)
+{
+    Q_D(QQuickItemView);
+    if (d->requestedIndex != index) {
+        item->setParentItem(contentItem());
+        d->unrequestedItems.insert(item, index);
+        d->repositionPackageItemAt(item, index);
+    }
+}
+
+void QQuickItemView::destroyingItem(QQuickItem *item)
+{
+    Q_D(QQuickItemView);
+    d->unrequestedItems.remove(item);
+}
+
+void QQuickItemView::animStopped()
+{
+    Q_D(QQuickItemView);
+    d->bufferMode = QQuickItemViewPrivate::NoBuffer;
+    if (d->haveHighlightRange && d->highlightRange == QQuickItemView::StrictlyEnforceRange)
+        d->updateHighlight();
+}
+
+
+void QQuickItemView::trackedPositionChanged()
+{
+    Q_D(QQuickItemView);
+    if (!d->trackedItem || !d->currentItem)
+        return;
+    if (d->moveReason == QQuickItemViewPrivate::SetIndex) {
+        qreal trackedPos = d->trackedItem->position();
+        qreal trackedSize = d->trackedItem->size();
+        if (d->trackedItem != d->currentItem) {
+            trackedSize += d->currentItem->sectionSize();
+        }
+        qreal viewPos = d->isContentFlowReversed() ? -d->position()-d->size() : d->position();
+        qreal pos = viewPos;
+        if (d->haveHighlightRange) {
+            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())
+                    pos = d->startPosition();
+            }
+        } else {
+            qreal trackedEndPos = d->trackedItem->endPosition();
+            qreal toItemPos = d->currentItem->position();
+            qreal toItemEndPos = d->currentItem->endPosition();
+
+            if (d->header && d->showHeaderForIndex(d->currentIndex)) {
+                trackedPos -= d->headerSize();
+                trackedEndPos -= d->headerSize();
+                toItemPos -= d->headerSize();
+                toItemEndPos -= d->headerSize();
+            } else if (d->footer && d->showFooterForIndex(d->currentIndex)) {
+                trackedPos += d->footerSize();
+                trackedEndPos += d->footerSize();
+                toItemPos += d->footerSize();
+                toItemEndPos += d->footerSize();
+            }
+
+            if (trackedPos < viewPos && toItemPos < viewPos) {
+                pos = qMax(trackedPos, toItemPos);
+            } else if (trackedEndPos >= viewPos + d->size()
+                && toItemEndPos >= viewPos + d->size()) {
+                if (trackedEndPos <= toItemEndPos) {
+                    pos = trackedEndPos - d->size();
+                    if (trackedSize > d->size())
+                        pos = trackedPos;
+                } else {
+                    pos = toItemEndPos - d->size();
+                    if (d->currentItem->size() > d->size())
+                        pos = d->currentItem->position();
+                }
+            }
+        }
+        if (viewPos != pos) {
+            cancelFlick();
+            d->calcVelocity = true;
+            d->setPosition(pos);
+            d->calcVelocity = false;
+        }
+    }
+}
+
+void QQuickItemView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+    Q_D(QQuickItemView);
+    d->markExtentsDirty();
+    QQuickFlickable::geometryChanged(newGeometry, oldGeometry);
+}
+
+
+qreal QQuickItemView::minYExtent() const
+{
+    Q_D(const QQuickItemView);
+    if (d->layoutOrientation() == Qt::Horizontal)
+        return QQuickFlickable::minYExtent();
+
+    if (d->vData.minExtentDirty) {
+        d->minExtent = d->vData.startMargin-d->startPosition();
+        if (d->header)
+            d->minExtent += d->headerSize();
+        if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
+            d->minExtent += d->highlightRangeStart;
+            if (d->visibleItem(0))
+                d->minExtent -= d->visibleItem(0)->sectionSize();
+            d->minExtent = qMax(d->minExtent, -(d->endPositionAt(0) - d->highlightRangeEnd));
+        }
+        d->vData.minExtentDirty = false;
+    }
+
+    return d->minExtent;
+}
+
+qreal QQuickItemView::maxYExtent() const
+{
+    Q_D(const QQuickItemView);
+    if (d->layoutOrientation() == Qt::Horizontal)
+        return height();
+
+    if (d->vData.maxExtentDirty) {
+        if (!d->model || !d->model->count()) {
+            d->maxExtent = d->header ? -d->headerSize() : 0;
+            d->maxExtent += height();
+        } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
+            d->maxExtent = -(d->positionAt(d->model->count()-1) - d->highlightRangeStart);
+            if (d->highlightRangeEnd != d->highlightRangeStart)
+                d->maxExtent = qMin(d->maxExtent, -(d->endPosition() - d->highlightRangeEnd));
+        } else {
+            d->maxExtent = -(d->endPosition() - height());
+        }
+
+        if (d->footer)
+            d->maxExtent -= d->footerSize();
+        d->maxExtent -= d->vData.endMargin;
+        qreal minY = minYExtent();
+        if (d->maxExtent > minY)
+            d->maxExtent = minY;
+        d->vData.maxExtentDirty = false;
+    }
+    return d->maxExtent;
+}
+
+qreal QQuickItemView::minXExtent() const
+{
+    Q_D(const QQuickItemView);
+    if (d->layoutOrientation() == Qt::Vertical)
+        return QQuickFlickable::minXExtent();
+
+    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->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;
+            if (d->header)
+                d->minExtent += d->headerSize();
+        }
+        if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
+            d->minExtent += highlightStart;
+            d->minExtent = d->isContentFlowReversed()
+                                ? qMin(d->minExtent, endPositionFirstItem + highlightEnd)
+                                : qMax(d->minExtent, -(endPositionFirstItem - highlightEnd));
+        }
+        d->hData.minExtentDirty = false;
+    }
+
+    return d->minExtent;
+}
+
+qreal QQuickItemView::maxXExtent() const
+{
+    Q_D(const QQuickItemView);
+    if (d->layoutOrientation() == Qt::Vertical)
+        return width();
+
+    if (d->hData.maxExtentDirty) {
+        qreal highlightStart;
+        qreal highlightEnd;
+        qreal lastItemPosition = 0;
+        d->maxExtent = 0;
+        if (d->isContentFlowReversed()) {
+            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;
+            highlightEnd = d->highlightRangeEnd;
+            if (d->model && d->model->count())
+                lastItemPosition = d->positionAt(d->model->count()-1);
+        }
+        if (!d->model || !d->model->count()) {
+            if (!d->isContentFlowReversed())
+                d->maxExtent = d->header ? -d->headerSize() : 0;
+            d->maxExtent += width();
+        } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
+            d->maxExtent = -(lastItemPosition - highlightStart);
+            if (highlightEnd != highlightStart) {
+                d->maxExtent = d->isContentFlowReversed()
+                        ? qMax(d->maxExtent, -(d->endPosition() - highlightEnd))
+                        : qMin(d->maxExtent, -(d->endPosition() - highlightEnd));
+            }
+        } else {
+            d->maxExtent = -(d->endPosition() - width());
+        }
+        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->hData.maxExtentDirty = false;
+    }
+
+    return d->maxExtent;
+}
+
+void QQuickItemView::setContentX(qreal pos)
+{
+    Q_D(QQuickItemView);
+    // Positioning the view manually should override any current movement state
+    d->moveReason = QQuickItemViewPrivate::Other;
+    QQuickFlickable::setContentX(pos);
+}
+
+void QQuickItemView::setContentY(qreal pos)
+{
+    Q_D(QQuickItemView);
+    // Positioning the view manually should override any current movement state
+    d->moveReason = QQuickItemViewPrivate::Other;
+    QQuickFlickable::setContentY(pos);
+}
+
+qreal QQuickItemView::xOrigin() const
+{
+    Q_D(const QQuickItemView);
+    if (d->isContentFlowReversed())
+        return -maxXExtent() + d->size() - d->hData.startMargin;
+    else
+        return -minXExtent() + d->hData.startMargin;
+}
+
+void QQuickItemView::updatePolish()
+{
+    Q_D(QQuickItemView);
+    QQuickFlickable::updatePolish();
+    d->layout();
+}
+
+void QQuickItemView::componentComplete()
+{
+    Q_D(QQuickItemView);
+    if (d->model && d->ownModel)
+        static_cast<QQuickVisualDataModel *>(d->model.data())->componentComplete();
+
+    QQuickFlickable::componentComplete();
+
+    updateSections();
+    d->updateHeader();
+    d->updateFooter();
+    d->updateViewport();
+    d->setPosition(d->contentStartPosition());
+    if (d->isValid()) {
+        d->refill();
+        d->moveReason = QQuickItemViewPrivate::SetIndex;
+        if (d->currentIndex < 0 && !d->currentIndexCleared)
+            d->updateCurrent(0);
+        else
+            d->updateCurrent(d->currentIndex);
+        if (d->highlight && d->currentItem) {
+            if (d->autoHighlight)
+                d->resetHighlightPosition();
+            d->updateTrackedItem();
+        }
+        d->moveReason = QQuickItemViewPrivate::Other;
+        d->fixupPosition();
+    }
+    if (d->model && d->model->count())
+        emit countChanged();
+}
+
+
+
+QQuickItemViewPrivate::QQuickItemViewPrivate()
+    : itemCount(0)
+    , buffer(0), bufferMode(BufferBefore | BufferAfter)
+    , layoutDirection(Qt::LeftToRight)
+    , moveReason(Other)
+    , visibleIndex(0)
+    , currentIndex(-1), currentItem(0)
+    , trackedItem(0), requestedIndex(-1)
+    , highlightComponent(0), highlight(0)
+    , highlightRange(QQuickItemView::NoHighlightRange)
+    , highlightRangeStart(0), highlightRangeEnd(0)
+    , highlightMoveDuration(150)
+    , headerComponent(0), header(0), footerComponent(0), footer(0)
+    , minExtent(0), maxExtent(0)
+    , ownModel(false), wrap(false), lazyRelease(false), deferredRelease(false)
+    , inApplyModelChanges(false), inViewportMoved(false), forceLayout(false), currentIndexCleared(false)
+    , haveHighlightRange(false), autoHighlight(true), highlightRangeStartValid(false), highlightRangeEndValid(false)
+{
+}
+
+bool QQuickItemViewPrivate::isValid() const
+{
+    return model && model->count() && model->isValid();
+}
+
+qreal QQuickItemViewPrivate::position() const
+{
+    Q_Q(const QQuickItemView);
+    return layoutOrientation() == Qt::Vertical ? q->contentY() : q->contentX();
+}
+
+qreal QQuickItemViewPrivate::size() const
+{
+    Q_Q(const QQuickItemView);
+    return layoutOrientation() == Qt::Vertical ? q->height() : q->width();
+}
+
+qreal QQuickItemViewPrivate::startPosition() const
+{
+    return isContentFlowReversed() ? -lastPosition() : originPosition();
+}
+
+qreal QQuickItemViewPrivate::endPosition() const
+{
+    return isContentFlowReversed() ? -originPosition() : lastPosition();
+}
+
+qreal QQuickItemViewPrivate::contentStartPosition() const
+{
+    Q_Q(const QQuickItemView);
+    qreal pos = -headerSize();
+    if (layoutOrientation() == Qt::Vertical)
+        pos -= vData.startMargin;
+    else if (isContentFlowReversed())
+        pos -= hData.endMargin;
+    else
+        pos -= hData.startMargin;
+
+    return pos;
+}
+
+int QQuickItemViewPrivate::findLastVisibleIndex(int defaultValue) const
+{
+    if (visibleItems.count()) {
+        int i = visibleItems.count() - 1;
+        while (i > 0 && visibleItems.at(i)->index == -1)
+            --i;
+        if (visibleItems.at(i)->index != -1)
+            return visibleItems.at(i)->index;
+    }
+    return defaultValue;
+}
+
+FxViewItem *QQuickItemViewPrivate::visibleItem(int modelIndex) const {
+    if (modelIndex >= visibleIndex && modelIndex < visibleIndex + visibleItems.count()) {
+        for (int i = modelIndex - visibleIndex; i < visibleItems.count(); ++i) {
+            FxViewItem *item = visibleItems.at(i);
+            if (item->index == modelIndex)
+                return item;
+        }
+    }
+    return 0;
+}
+
+FxViewItem *QQuickItemViewPrivate::firstVisibleItem() const {
+    const qreal pos = isContentFlowReversed() ? -position()-size() : position();
+    for (int i = 0; i < visibleItems.count(); ++i) {
+        FxViewItem *item = visibleItems.at(i);
+        if (item->index != -1 && item->endPosition() > pos)
+            return item;
+    }
+    return visibleItems.count() ? visibleItems.first() : 0;
+}
+
+// Map a model index to visibleItems list index.
+// These may differ if removed items are still present in the visible list,
+// e.g. doing a removal animation
+int QQuickItemViewPrivate::mapFromModel(int modelIndex) const
+{
+    if (modelIndex < visibleIndex || modelIndex >= visibleIndex + visibleItems.count())
+        return -1;
+    for (int i = 0; i < visibleItems.count(); ++i) {
+        FxViewItem *item = visibleItems.at(i);
+        if (item->index == modelIndex)
+            return i;
+        if (item->index > modelIndex)
+            return -1;
+    }
+    return -1; // Not in visibleList
+}
+
+void QQuickItemViewPrivate::init()
+{
+    Q_Q(QQuickItemView);
+    QQuickItemPrivate::get(contentItem)->childrenDoNotOverlap = true;
+    q->setFlag(QQuickItem::ItemIsFocusScope);
+    addItemChangeListener(this, Geometry);
+    QObject::connect(q, SIGNAL(movementEnded()), q, SLOT(animStopped()));
+    q->setFlickableDirection(QQuickFlickable::VerticalFlick);
+}
+
+void QQuickItemViewPrivate::updateCurrent(int modelIndex)
+{
+    Q_Q(QQuickItemView);
+    applyPendingChanges();
+
+    if (!q->isComponentComplete() || !isValid() || modelIndex < 0 || modelIndex >= model->count()) {
+        if (currentItem) {
+            currentItem->attached->setIsCurrentItem(false);
+            releaseItem(currentItem);
+            currentItem = 0;
+            currentIndex = modelIndex;
+            emit q->currentIndexChanged();
+            updateHighlight();
+        } else if (currentIndex != modelIndex) {
+            currentIndex = modelIndex;
+            emit q->currentIndexChanged();
+        }
+        return;
+    }
+
+    if (currentItem && currentIndex == modelIndex) {
+        updateHighlight();
+        return;
+    }
+
+    FxViewItem *oldCurrentItem = currentItem;
+    currentIndex = modelIndex;
+    currentItem = createItem(modelIndex);
+    if (oldCurrentItem && (!currentItem || oldCurrentItem->item != currentItem->item))
+        oldCurrentItem->attached->setIsCurrentItem(false);
+    if (currentItem) {
+        currentItem->item->setFocus(true);
+        currentItem->attached->setIsCurrentItem(true);
+        initializeCurrentItem();
+    }
+
+    updateHighlight();
+    emit q->currentIndexChanged();
+    releaseItem(oldCurrentItem);
+}
+
+void QQuickItemViewPrivate::clear()
+{
+    currentChanges.reset();
+    timeline.clear();
+
+    for (int i = 0; i < visibleItems.count(); ++i)
+        releaseItem(visibleItems.at(i));
+    visibleItems.clear();
+    visibleIndex = 0;
+
+    releaseItem(currentItem);
+    currentItem = 0;
+    createHighlight();
+    trackedItem = 0;
+
+    markExtentsDirty();
+    itemCount = 0;
+}
+
+
+void QQuickItemViewPrivate::mirrorChange()
+{
+    Q_Q(QQuickItemView);
+    regenerate();
+    emit q->effectiveLayoutDirectionChanged();
+}
+
+void QQuickItemViewPrivate::refill()
+{
+    if (isContentFlowReversed())
+        refill(-position()-size(), -position());
+    else
+        refill(position(), position()+size());
+}
+
+void QQuickItemViewPrivate::refill(qreal from, qreal to, bool doBuffer)
+{
+    Q_Q(QQuickItemView);
+    if (!isValid() || !q->isComponentComplete())
+        return;
+
+    currentChanges.reset();
+
+    int prevCount = itemCount;
+    itemCount = model->count();
+    qreal bufferFrom = from - buffer;
+    qreal bufferTo = to + buffer;
+    qreal fillFrom = from;
+    qreal fillTo = to;
+    if (doBuffer && (bufferMode & BufferAfter))
+        fillTo = bufferTo;
+    if (doBuffer && (bufferMode & BufferBefore))
+        fillFrom = bufferFrom;
+
+    // Item creation and release is staggered in order to avoid
+    // creating/releasing multiple items in one frame
+    // while flicking (as much as possible).
+
+    bool changed = addVisibleItems(fillFrom, fillTo, doBuffer);
+
+    if (!lazyRelease || !changed || deferredRelease) { // avoid destroying items in the same frame that we create
+        if (removeNonVisibleItems(bufferFrom, bufferTo))
+            changed = true;
+        deferredRelease = false;
+    } else {
+        deferredRelease = true;
+    }
+
+    if (changed) {
+        markExtentsDirty();
+        visibleItemsChanged();
+    } else if (!doBuffer && buffer && bufferMode != NoBuffer) {
+        refill(from, to, true);
+    }
+
+    lazyRelease = false;
+    if (prevCount != itemCount)
+        emit q->countChanged();
+}
+
+void QQuickItemViewPrivate::regenerate()
+{
+    Q_Q(QQuickItemView);
+    if (q->isComponentComplete()) {
+        currentChanges.reset();
+        delete header;
+        header = 0;
+        delete footer;
+        footer = 0;
+        updateHeader();
+        updateFooter();
+        clear();
+        updateViewport();
+        setPosition(contentStartPosition());
+        refill();
+        updateCurrent(currentIndex);
+    }
+}
+
+void QQuickItemViewPrivate::updateViewport()
+{
+    Q_Q(QQuickItemView);
+    if (isValid()) {
+        if (layoutOrientation() == Qt::Vertical)
+            q->setContentHeight(endPosition() - startPosition());
+        else
+            q->setContentWidth(endPosition() - startPosition());
+    }
+}
+
+void QQuickItemViewPrivate::layout()
+{
+    Q_Q(QQuickItemView);
+    if (inApplyModelChanges)
+        return;
+
+    if (!isValid() && !visibleItems.count()) {
+        clear();
+        setPosition(contentStartPosition());
+        return;
+    }
+
+    if (!applyModelChanges() && !forceLayout)
+        return;
+    forceLayout = false;
+
+    layoutVisibleItems();
+    refill();
+
+    markExtentsDirty();
+
+    updateHighlight();
+
+    if (!q->isMoving() && !q->isFlicking()) {
+        fixupPosition();
+        refill();
+    }
+
+    updateHeader();
+    updateFooter();
+    updateViewport();
+    updateUnrequestedPositions();
+}
+
+bool QQuickItemViewPrivate::applyModelChanges()
+{
+    Q_Q(QQuickItemView);
+    if (!q->isComponentComplete() || !currentChanges.hasPendingChanges() || inApplyModelChanges)
+        return false;
+    inApplyModelChanges = true;
+
+    updateUnrequestedIndexes();
+    moveReason = QQuickItemViewPrivate::Other;
+
+    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;
+    qreal removedBeforeFirstVisibleBy = 0;
+
+    const QVector<QDeclarativeChangeSet::Remove> &removals = currentChanges.pendingChanges.removes();
+    for (int i=0; i<removals.count(); i++) {
+        itemCount -= removals[i].count;
+
+        // Remove the items from the visible list, skipping anything already marked for removal
+        QList<FxViewItem*>::Iterator it = visibleItems.begin();
+        while (it != visibleItems.end()) {
+            FxViewItem *item = *it;
+            if (item->index == -1 || item->index < removals[i].index) {
+                // already removed, or before removed items
+                if (item->index < removals[i].index && !removedVisible)
+                    removedVisible = true;
+                ++it;
+            } else if (item->index >= removals[i].index + removals[i].count) {
+                // after removed items
+                item->index -= removals[i].count;
+                ++it;
+            } else {
+                // removed item
+                removedVisible = true;
+                if (!removals[i].isMove())
+                    item->attached->emitRemove();
+
+                if (item->attached->delayRemove() && !removals[i].isMove()) {
+                    item->index = -1;
+                    QObject::connect(item->attached, SIGNAL(delayRemoveChanged()), q, SLOT(destroyRemoved()), Qt::QueuedConnection);
+                    ++it;
+                } else {
+                    if (firstVisible && item->position() < firstVisible->position() && item != visibleItems.first())
+                        removedBeforeFirstVisibleBy += item->size();
+                    if (removals[i].isMove()) {
+                        currentChanges.removedItems.insert(removals[i].moveKey(item->index), item);
+                    } else {
+                        if (item == firstVisible)
+                            firstVisible = 0;
+                        currentChanges.removedItems.insertMulti(QDeclarativeChangeSet::MoveKey(), item);
+                    }
+                    it = visibleItems.erase(it);
+                }
+            }
+        }
+
+    }
+    if (!removals.isEmpty())
+        updateVisibleIndex();
+
+    const QVector<QDeclarativeChangeSet::Insert> &insertions = currentChanges.pendingChanges.inserts();
+    bool addedVisible = false;
+    InsertionsResult insertResult;
+    bool allInsertionsBeforeVisible = true;
+
+    for (int i=0; i<insertions.count(); i++) {
+        bool wasEmpty = visibleItems.isEmpty();
+        if (applyInsertionChange(insertions[i], firstVisible, &insertResult))
+            addedVisible = true;
+        if (insertions[i].index >= visibleIndex)
+            allInsertionsBeforeVisible = false;
+        if (wasEmpty && !visibleItems.isEmpty())
+            resetFirstItemPosition();
+        itemCount += insertions[i].count;
+    }
+    for (int i=0; i<insertResult.addedItems.count(); ++i)
+        insertResult.addedItems.at(i)->attached->emitAdd();
+
+    // 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) {
+        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 (insertResult.movedBackwards.count() && origVisibleItemsFirst)
+            resetItemPosition(visibleItems.first(), origVisibleItemsFirst);
+        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.
+    for (QHash<QDeclarativeChangeSet::MoveKey, FxViewItem *>::Iterator it = currentChanges.removedItems.begin();
+         it != currentChanges.removedItems.end(); ++it) {
+        releaseItem(it.value());
+    }
+    currentChanges.removedItems.clear();
+
+    if (currentChanges.currentChanged) {
+        if (currentChanges.currentRemoved && currentItem) {
+            currentItem->attached->setIsCurrentItem(false);
+            releaseItem(currentItem);
+            currentItem = 0;
+        }
+        if (!currentIndexCleared)
+            updateCurrent(currentChanges.newCurrentIndex);
+    }
+    currentChanges.reset();
+
+    updateSections();
+    if (prevCount != itemCount)
+        emit q->countChanged();
+
+    bool visibleAffected = removedVisible || addedVisible || !currentChanges.pendingChanges.changes().isEmpty();
+    if (!visibleAffected && viewportChanged)
+        updateViewport();
+
+    inApplyModelChanges = false;
+    return visibleAffected;
+}
+
+FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex)
+{
+    Q_Q(QQuickItemView);
+
+    requestedIndex = modelIndex;
+    FxViewItem *viewItem = 0;
+
+    if (QQuickItem *item = model->item(modelIndex, false)) {
+        viewItem = newViewItem(modelIndex, item);
+        if (viewItem) {
+            viewItem->index = 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
+            // until after bindings are evaluated
+            initializeViewItem(viewItem);
+
+            unrequestedItems.remove(viewItem->item);
+        }
+    }
+    requestedIndex = -1;
+    return viewItem;
+}
+
+
+void QQuickItemViewPrivate::releaseItem(FxViewItem *item)
+{
+    Q_Q(QQuickItemView);
+    if (!item || !model)
+        return;
+    if (trackedItem == item)
+        trackedItem = 0;
+    QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item->item);
+    itemPrivate->removeItemChangeListener(this, QQuickItemPrivate::Geometry);
+    if (model->release(item->item) == 0) {
+        // item was not destroyed, and we no longer reference it.
+        unrequestedItems.insert(item->item, model->indexOf(item->item, q));
+    }
+    delete item;
+}
+
+QQuickItem *QQuickItemViewPrivate::createHighlightItem()
+{
+    return createComponentItem(highlightComponent, true, true);
+}
+
+QQuickItem *QQuickItemViewPrivate::createComponentItem(QDeclarativeComponent *component, bool receiveItemGeometryChanges, bool createDefault)
+{
+    Q_Q(QQuickItemView);
+
+    QQuickItem *item = 0;
+    if (component) {
+        QDeclarativeContext *creationContext = component->creationContext();
+        QDeclarativeContext *context = new QDeclarativeContext(
+                creationContext ? creationContext : qmlContext(q));
+        QObject *nobj = component->create(context);
+        if (nobj) {
+            QDeclarative_setParent_noEvent(context, nobj);
+            item = qobject_cast<QQuickItem *>(nobj);
+            if (!item)
+                delete nobj;
+        } else {
+            delete context;
+        }
+    } else if (createDefault) {
+        item = new QQuickItem;
+    }
+    if (item) {
+        QDeclarative_setParent_noEvent(item, q->contentItem());
+        item->setParentItem(q->contentItem());
+        if (receiveItemGeometryChanges) {
+            QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+            itemPrivate->addItemChangeListener(this, QQuickItemPrivate::Geometry);
+        }
+    }
+    return item;
+}
+
+void QQuickItemViewPrivate::updateTrackedItem()
+{
+    Q_Q(QQuickItemView);
+    FxViewItem *item = currentItem;
+    if (highlight)
+        item = highlight;
+    trackedItem = item;
+
+    if (trackedItem)
+        q->trackedPositionChanged();
+}
+
+void QQuickItemViewPrivate::updateUnrequestedIndexes()
+{
+    Q_Q(QQuickItemView);
+    for (QHash<QQuickItem*,int>::iterator it = unrequestedItems.begin(); it != unrequestedItems.end(); ++it)
+        *it = model->indexOf(it.key(), q);
+}
+
+void QQuickItemViewPrivate::updateUnrequestedPositions()
+{
+    for (QHash<QQuickItem*,int>::const_iterator it = unrequestedItems.begin(); it != unrequestedItems.end(); ++it)
+        repositionPackageItemAt(it.key(), it.value());
+}
+
+void QQuickItemViewPrivate::updateVisibleIndex()
+{
+    visibleIndex = 0;
+    for (QList<FxViewItem*>::Iterator it = visibleItems.begin(); it != visibleItems.end(); ++it) {
+        if ((*it)->index != -1) {
+            visibleIndex = (*it)->index;
+            break;
+        }
+    }
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickitemview_p.h b/src/declarative/items/qquickitemview_p.h
new file mode 100644 (file)
index 0000000..8bb6353
--- /dev/null
@@ -0,0 +1,294 @@
+/****************************************************************************
+**
+** 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 QQUICKITEMVIEW_P_H
+#define QQUICKITEMVIEW_P_H
+
+#include "qquickflickable_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeChangeSet;
+
+class QQuickItemViewPrivate;
+
+class Q_AUTOTEST_EXPORT QQuickItemView : public QQuickFlickable
+{
+    Q_OBJECT
+
+    Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged)
+    Q_PROPERTY(QDeclarativeComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
+    Q_PROPERTY(int count READ count NOTIFY countChanged)
+
+    Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
+    Q_PROPERTY(QQuickItem *currentItem READ currentItem NOTIFY currentIndexChanged)
+
+    Q_PROPERTY(bool keyNavigationWraps READ isWrapEnabled WRITE setWrapEnabled NOTIFY keyNavigationWrapsChanged)
+    Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)
+
+    Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
+    Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
+
+    Q_PROPERTY(QDeclarativeComponent *header READ header WRITE setHeader NOTIFY headerChanged)
+    Q_PROPERTY(QQuickItem *headerItem READ headerItem NOTIFY headerItemChanged)
+    Q_PROPERTY(QDeclarativeComponent *footer READ footer WRITE setFooter NOTIFY footerChanged)
+    Q_PROPERTY(QQuickItem *footerItem READ footerItem NOTIFY footerItemChanged)
+
+    Q_PROPERTY(QDeclarativeComponent *highlight READ highlight WRITE setHighlight NOTIFY highlightChanged)
+    Q_PROPERTY(QQuickItem *highlightItem READ highlightItem NOTIFY highlightItemChanged)
+    Q_PROPERTY(bool highlightFollowsCurrentItem READ highlightFollowsCurrentItem WRITE setHighlightFollowsCurrentItem NOTIFY highlightFollowsCurrentItemChanged)
+    Q_PROPERTY(HighlightRangeMode highlightRangeMode READ highlightRangeMode WRITE setHighlightRangeMode NOTIFY highlightRangeModeChanged)
+    Q_PROPERTY(qreal preferredHighlightBegin READ preferredHighlightBegin WRITE setPreferredHighlightBegin NOTIFY preferredHighlightBeginChanged RESET resetPreferredHighlightBegin)
+    Q_PROPERTY(qreal preferredHighlightEnd READ preferredHighlightEnd WRITE setPreferredHighlightEnd NOTIFY preferredHighlightEndChanged RESET resetPreferredHighlightEnd)
+    Q_PROPERTY(int highlightMoveDuration READ highlightMoveDuration WRITE setHighlightMoveDuration NOTIFY highlightMoveDurationChanged)
+
+    Q_ENUMS(HighlightRangeMode)
+    Q_ENUMS(PositionMode)
+
+public:
+    QQuickItemView(QQuickFlickablePrivate &dd, QQuickItem *parent = 0);
+    ~QQuickItemView();
+
+    QVariant model() const;
+    void setModel(const QVariant &);
+
+    QDeclarativeComponent *delegate() const;
+    void setDelegate(QDeclarativeComponent *);
+
+    int count() const;
+
+    int currentIndex() const;
+    void setCurrentIndex(int idx);
+
+    QQuickItem *currentItem() const;
+
+    bool isWrapEnabled() const;
+    void setWrapEnabled(bool);
+
+    int cacheBuffer() const;
+    void setCacheBuffer(int);
+
+    Qt::LayoutDirection layoutDirection() const;
+    void setLayoutDirection(Qt::LayoutDirection);
+    Qt::LayoutDirection effectiveLayoutDirection() const;
+
+    QDeclarativeComponent *footer() const;
+    void setFooter(QDeclarativeComponent *);
+    QQuickItem *footerItem() const;
+
+    QDeclarativeComponent *header() const;
+    void setHeader(QDeclarativeComponent *);
+    QQuickItem *headerItem() const;
+
+    QDeclarativeComponent *highlight() const;
+    void setHighlight(QDeclarativeComponent *);
+
+    QQuickItem *highlightItem() const;
+
+    bool highlightFollowsCurrentItem() const;
+    virtual void setHighlightFollowsCurrentItem(bool);
+
+    enum HighlightRangeMode { NoHighlightRange, ApplyRange, StrictlyEnforceRange };
+    HighlightRangeMode highlightRangeMode() const;
+    void setHighlightRangeMode(HighlightRangeMode mode);
+
+    qreal preferredHighlightBegin() const;
+    void setPreferredHighlightBegin(qreal);
+    void resetPreferredHighlightBegin();
+
+    qreal preferredHighlightEnd() const;
+    void setPreferredHighlightEnd(qreal);
+    void resetPreferredHighlightEnd();
+
+    int highlightMoveDuration() const;
+    virtual void setHighlightMoveDuration(int);
+
+    enum PositionMode { Beginning, Center, End, Visible, Contain };
+
+    Q_INVOKABLE void positionViewAtIndex(int index, int mode);
+    Q_INVOKABLE int indexAt(qreal x, qreal y) const;
+    Q_INVOKABLE void positionViewAtBeginning();
+    Q_INVOKABLE void positionViewAtEnd();
+
+    virtual void setContentX(qreal pos);
+    virtual void setContentY(qreal pos);
+    virtual qreal xOrigin() const;
+
+signals:
+    void modelChanged();
+    void delegateChanged();
+    void countChanged();
+    void currentIndexChanged();
+
+    void keyNavigationWrapsChanged();
+    void cacheBufferChanged();
+
+    void layoutDirectionChanged();
+    void effectiveLayoutDirectionChanged();
+
+    void headerChanged();
+    void footerChanged();
+    void headerItemChanged();
+    void footerItemChanged();
+
+    void highlightChanged();
+    void highlightItemChanged();
+    void highlightFollowsCurrentItemChanged();
+    void highlightRangeModeChanged();
+    void preferredHighlightBeginChanged();
+    void preferredHighlightEndChanged();
+    void highlightMoveDurationChanged();
+
+protected:
+    virtual void updatePolish();
+    virtual void componentComplete();
+    virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
+    virtual qreal minYExtent() const;
+    virtual qreal maxYExtent() const;
+    virtual qreal minXExtent() const;
+    virtual qreal maxXExtent() const;
+
+protected slots:
+    virtual void updateSections() {}
+    void destroyRemoved();
+    void createdItem(int index, QQuickItem *item);
+    void modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset);
+    void destroyingItem(QQuickItem *item);
+    void animStopped();
+    void trackedPositionChanged();
+
+
+
+private:
+    Q_DECLARE_PRIVATE(QQuickItemView)
+};
+
+
+class Q_AUTOTEST_EXPORT QQuickItemViewAttached : public QObject
+{
+    Q_OBJECT
+
+    Q_PROPERTY(bool isCurrentItem READ isCurrentItem NOTIFY currentItemChanged)
+    Q_PROPERTY(bool delayRemove READ delayRemove WRITE setDelayRemove NOTIFY delayRemoveChanged)
+
+    Q_PROPERTY(QString section READ section NOTIFY sectionChanged)
+    Q_PROPERTY(QString previousSection READ prevSection NOTIFY prevSectionChanged)
+    Q_PROPERTY(QString nextSection READ nextSection NOTIFY nextSectionChanged)
+
+public:
+    QQuickItemViewAttached(QObject *parent)
+        : QObject(parent), m_isCurrent(false), m_delayRemove(false) {}
+    ~QQuickItemViewAttached() {}
+
+    bool isCurrentItem() const { return m_isCurrent; }
+    void setIsCurrentItem(bool c) {
+        if (m_isCurrent != c) {
+            m_isCurrent = c;
+            emit currentItemChanged();
+        }
+    }
+
+    bool delayRemove() const { return m_delayRemove; }
+    void setDelayRemove(bool delay) {
+        if (m_delayRemove != delay) {
+            m_delayRemove = delay;
+            emit delayRemoveChanged();
+        }
+    }
+
+    QString section() const { return m_section; }
+    void setSection(const QString &sect) {
+        if (m_section != sect) {
+            m_section = sect;
+            emit sectionChanged();
+        }
+    }
+
+    QString prevSection() const { return m_prevSection; }
+    void setPrevSection(const QString &sect) {
+        if (m_prevSection != sect) {
+            m_prevSection = sect;
+            emit prevSectionChanged();
+        }
+    }
+
+    QString nextSection() const { return m_nextSection; }
+    void setNextSection(const QString &sect) {
+        if (m_nextSection != sect) {
+            m_nextSection = sect;
+            emit nextSectionChanged();
+        }
+    }
+
+    void emitAdd() { emit add(); }
+    void emitRemove() { emit remove(); }
+
+signals:
+    void currentItemChanged();
+    void delayRemoveChanged();
+
+    void add();
+    void remove();
+
+    void sectionChanged();
+    void prevSectionChanged();
+    void nextSectionChanged();
+
+public:
+    bool m_isCurrent : 1;
+    bool m_delayRemove : 1;
+
+    // current only used by list view
+    mutable QString m_section;
+    QString m_prevSection;
+    QString m_nextSection;
+};
+
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif // QQUICKITEMVIEW_P_H
+
diff --git a/src/declarative/items/qquickitemview_p_p.h b/src/declarative/items/qquickitemview_p_p.h
new file mode 100644 (file)
index 0000000..398de84
--- /dev/null
@@ -0,0 +1,256 @@
+/****************************************************************************
+**
+** 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 QQUICKITEMVIEW_P_P_H
+#define QQUICKITEMVIEW_P_P_H
+
+#include "qquickitemview_p.h"
+#include "qquickflickable_p_p.h"
+#include "qquickvisualdatamodel_p.h"
+#include <private/qdeclarativechangeset_p.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class FxViewItem
+{
+public:
+    FxViewItem(QQuickItem *, bool own);
+    ~FxViewItem();
+
+    // these are positions and sizes along the current direction of scrolling/flicking
+    virtual qreal position() const = 0;
+    virtual qreal endPosition() const = 0;
+    virtual qreal size() const = 0;
+    virtual qreal sectionSize() const = 0;
+
+    virtual bool contains(qreal x, qreal y) const = 0;
+
+    QQuickItem *item;
+    bool ownItem;
+    int index;
+    QQuickItemViewAttached *attached;
+};
+
+class QQuickItemViewChangeSet
+{
+public:
+    QQuickItemViewChangeSet();
+
+    bool hasPendingChanges() const;
+    void prepare(int currentIndex, int count);
+    void reset();
+
+    void applyChanges(const QDeclarativeChangeSet &changeSet);
+
+    int itemCount;
+    int newCurrentIndex;
+    QDeclarativeChangeSet pendingChanges;
+    QHash<QDeclarativeChangeSet::MoveKey, FxViewItem *> removedItems;
+
+    bool active : 1;
+    bool currentChanged : 1;
+    bool currentRemoved : 1;
+};
+
+class QQuickItemViewPrivate : public QQuickFlickablePrivate
+{
+    Q_DECLARE_PUBLIC(QQuickItemView)
+public:
+    QQuickItemViewPrivate();
+
+    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 };
+
+    bool isValid() const;
+    qreal position() const;
+    qreal size() const;
+    qreal startPosition() const;
+    qreal endPosition() const;
+    qreal contentStartPosition() const;
+    int findLastVisibleIndex(int defaultValue = -1) const;
+    FxViewItem *visibleItem(int modelIndex) const;
+    FxViewItem *firstVisibleItem() const;
+    int mapFromModel(int modelIndex) const;
+
+    virtual void init();
+    virtual void clear();
+    virtual void updateViewport();
+
+    void regenerate();
+    void layout();
+    void refill();
+    void refill(qreal from, qreal to, bool doBuffer = false);
+    void mirrorChange();
+
+    FxViewItem *createItem(int modelIndex);
+    virtual void releaseItem(FxViewItem *item);
+
+    QQuickItem *createHighlightItem();
+    QQuickItem *createComponentItem(QDeclarativeComponent *component, bool receiveItemGeometryChanges, bool createDefault = false);
+
+    void updateCurrent(int modelIndex);
+    void updateTrackedItem();
+    void updateUnrequestedIndexes();
+    void updateUnrequestedPositions();
+    void updateVisibleIndex();
+    void positionViewAtIndex(int index, int mode);
+    void applyPendingChanges();
+    bool applyModelChanges();
+
+    void checkVisible() const;
+
+    void markExtentsDirty() {
+        if (layoutOrientation() == Qt::Vertical)
+            vData.markExtentsDirty();
+        else
+            hData.markExtentsDirty();
+    }
+
+    QDeclarativeGuard<QQuickVisualModel> model;
+    QVariant modelVariant;
+    int itemCount;
+    int buffer;
+    int bufferMode;
+    Qt::LayoutDirection layoutDirection;
+
+    MovementReason moveReason;
+
+    QList<FxViewItem *> visibleItems;
+    int visibleIndex;
+    int currentIndex;
+    FxViewItem *currentItem;
+    FxViewItem *trackedItem;
+    QHash<QQuickItem*,int> unrequestedItems;
+    int requestedIndex;
+    QQuickItemViewChangeSet currentChanges;
+
+    // XXX split into struct
+    QDeclarativeComponent *highlightComponent;
+    FxViewItem *highlight;
+    int highlightRange;     // enum value
+    qreal highlightRangeStart;
+    qreal highlightRangeEnd;
+    int highlightMoveDuration;
+
+    QDeclarativeComponent *headerComponent;
+    FxViewItem *header;
+    QDeclarativeComponent *footerComponent;
+    FxViewItem *footer;
+
+    mutable qreal minExtent;
+    mutable qreal maxExtent;
+
+    bool ownModel : 1;
+    bool wrap : 1;
+    bool lazyRelease : 1;
+    bool deferredRelease : 1;
+    bool inApplyModelChanges : 1;
+    bool inViewportMoved : 1;
+    bool forceLayout : 1;
+    bool currentIndexCleared : 1;
+    bool haveHighlightRange : 1;
+    bool autoHighlight : 1;
+    bool highlightRangeStartValid : 1;
+    bool highlightRangeEndValid : 1;
+
+protected:
+    virtual Qt::Orientation layoutOrientation() const = 0;
+    virtual bool isContentFlowReversed() const = 0;
+
+    virtual qreal positionAt(int index) const = 0;
+    virtual qreal endPositionAt(int index) const = 0;
+    virtual qreal originPosition() const = 0;
+    virtual qreal lastPosition() const = 0;
+
+    virtual qreal headerSize() const = 0;
+    virtual qreal footerSize() const = 0;
+    virtual bool showHeaderForIndex(int index) const = 0;
+    virtual bool showFooterForIndex(int index) const = 0;
+    virtual void updateHeader() = 0;
+    virtual void updateFooter() = 0;
+
+    virtual void createHighlight() = 0;
+    virtual void updateHighlight() = 0;
+    virtual void resetHighlightPosition() = 0;
+
+    virtual void setPosition(qreal pos) = 0;
+    virtual void fixupPosition() = 0;
+
+    virtual bool addVisibleItems(qreal fillFrom, qreal fillTo, bool doBuffer) = 0;
+    virtual bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo) = 0;
+    virtual void visibleItemsChanged() = 0;
+
+    virtual FxViewItem *newViewItem(int index, QQuickItem *item) = 0;
+    virtual void repositionPackageItemAt(QQuickItem *item, int index) = 0;
+    virtual void resetItemPosition(FxViewItem *item, FxViewItem *toItem) = 0;
+    virtual void resetFirstItemPosition() = 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 &, FxViewItem *, InsertionsResult *) = 0;
+
+    virtual void initializeViewItem(FxViewItem *) {}
+    virtual void initializeCurrentItem() {}
+    virtual void updateSections() {}
+
+    virtual void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
+};
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QQUICKITEMVIEW_P_P_H
diff --git a/src/declarative/items/qquicklistview.cpp b/src/declarative/items/qquicklistview.cpp
new file mode 100644 (file)
index 0000000..e43a831
--- /dev/null
@@ -0,0 +1,2500 @@
+/****************************************************************************
+**
+** 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 "qquicklistview_p.h"
+#include "qquickitemview_p_p.h"
+#include "qquickvisualitemmodel_p.h"
+
+#include <QtDeclarative/qdeclarativeexpression.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativeinfo.h>
+#include <QtGui/qevent.h>
+#include <QtCore/qmath.h>
+#include <QtCore/qcoreapplication.h>
+
+#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 QQuickListViewPrivate : public QQuickItemViewPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickListView)
+public:
+    static QQuickListViewPrivate* get(QQuickListView *item) { return item->d_func(); }
+
+    virtual Qt::Orientation layoutOrientation() const;
+    virtual bool isContentFlowReversed() const;
+    bool isRightToLeft() const;
+
+    virtual qreal positionAt(int index) const;
+    virtual qreal endPositionAt(int index) const;
+    virtual qreal originPosition() const;
+    virtual qreal lastPosition() const;
+
+    FxViewItem *itemBefore(int modelIndex) const;
+    QString sectionAt(int modelIndex);
+    qreal snapPosAt(qreal pos);
+    FxViewItem *snapItemAt(qreal pos);
+
+    virtual void init();
+    virtual void clear();
+
+    virtual bool addVisibleItems(qreal fillFrom, qreal fillTo, bool doBuffer);
+    virtual bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo);
+    virtual void visibleItemsChanged();
+
+    virtual FxViewItem *newViewItem(int index, QQuickItem *item);
+    virtual void initializeViewItem(FxViewItem *item);
+    virtual void releaseItem(FxViewItem *item);
+    virtual void repositionPackageItemAt(QQuickItem *item, int index);
+    virtual void resetItemPosition(FxViewItem *item, FxViewItem *toItem);
+    virtual void resetFirstItemPosition();
+    virtual void moveItemBy(FxViewItem *item, qreal forwards, qreal backwards);
+
+    virtual void createHighlight();
+    virtual void updateHighlight();
+    virtual void resetHighlightPosition();
+
+    virtual void setPosition(qreal pos);
+    virtual void layoutVisibleItems();
+    bool applyInsertionChange(const QDeclarativeChangeSet::Insert &, FxViewItem *firstVisible, InsertionsResult *);
+
+    virtual void updateSections();
+    QQuickItem *getSectionItem(const QString &section);
+    void releaseSectionItem(QQuickItem *item);
+    void updateInlineSection(FxListItemSG *);
+    void updateCurrentSection();
+    void updateStickySections();
+
+    virtual qreal headerSize() const;
+    virtual qreal footerSize() const;
+    virtual bool showHeaderForIndex(int index) const;
+    virtual bool showFooterForIndex(int index) const;
+    virtual void updateHeader();
+    virtual void updateFooter();
+
+    virtual void changedVisibleIndex(int newIndex);
+    virtual void initializeCurrentItem();
+
+    void updateAverage();
+
+    void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
+    virtual void fixupPosition();
+    virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent);
+    virtual void flick(QQuickItemViewPrivate::AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
+                        QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity);
+
+    QQuickListView::Orientation orient;
+    qreal visiblePos;
+    qreal averageSize;
+    qreal spacing;
+    QQuickListView::SnapMode snapMode;
+
+    QSmoothedAnimation *highlightPosAnimator;
+    QSmoothedAnimation *highlightSizeAnimator;
+    qreal highlightMoveSpeed;
+    qreal highlightResizeSpeed;
+    int highlightResizeDuration;
+
+    QQuickViewSection *sectionCriteria;
+    QString currentSection;
+    static const int sectionCacheSize = 5;
+    QQuickItem *sectionCache[sectionCacheSize];
+    QQuickItem *currentSectionItem;
+    QString currentStickySection;
+    QQuickItem *nextSectionItem;
+    QString nextStickySection;
+    QString lastVisibleSection;
+    QString nextSection;
+
+    qreal overshootDist;
+    bool correctFlick : 1;
+    bool inFlickCorrection : 1;
+
+    QQuickListViewPrivate()
+        : orient(QQuickListView::Vertical)
+        , visiblePos(0)
+        , averageSize(100.0), spacing(0.0)
+        , snapMode(QQuickListView::NoSnap)
+        , highlightPosAnimator(0), highlightSizeAnimator(0)
+        , highlightMoveSpeed(400), highlightResizeSpeed(400), highlightResizeDuration(-1)
+        , sectionCriteria(0), currentSectionItem(0), nextSectionItem(0)
+        , overshootDist(0.0), correctFlick(false), inFlickCorrection(false)
+    {}
+
+    friend class QQuickViewSection;
+};
+
+//----------------------------------------------------------------------------
+
+QQuickViewSection::QQuickViewSection(QQuickListView *parent)
+    : QObject(parent), m_criteria(FullString), m_delegate(0), m_labelPositioning(InlineLabels)
+    , m_view(parent ? QQuickListViewPrivate::get(parent) : 0)
+{
+}
+
+void QQuickViewSection::setProperty(const QString &property)
+{
+    if (property != m_property) {
+        m_property = property;
+        emit propertyChanged();
+        m_view->updateSections();
+    }
+}
+
+void QQuickViewSection::setCriteria(QQuickViewSection::SectionCriteria criteria)
+{
+    if (criteria != m_criteria) {
+        m_criteria = criteria;
+        emit criteriaChanged();
+        m_view->updateSections();
+    }
+}
+
+void QQuickViewSection::setDelegate(QDeclarativeComponent *delegate)
+{
+    if (delegate != m_delegate) {
+        m_delegate = delegate;
+        emit delegateChanged();
+        m_view->updateSections();
+    }
+}
+
+QString QQuickViewSection::sectionString(const QString &value)
+{
+    if (m_criteria == FirstCharacter)
+        return value.isEmpty() ? QString() : value.at(0);
+    else
+        return value;
+}
+
+void QQuickViewSection::setLabelPositioning(int l)
+{
+    if (m_labelPositioning != l) {
+        m_labelPositioning = l;
+        emit labelPositioningChanged();
+        m_view->updateSections();
+    }
+}
+
+//----------------------------------------------------------------------------
+
+class FxListItemSG : public FxViewItem
+{
+public:
+    FxListItemSG(QQuickItem *i, QQuickListView *v, bool own) : FxViewItem(i, own), section(0), view(v) {
+        attached = static_cast<QQuickListViewAttached*>(qmlAttachedPropertiesObject<QQuickListView>(item));
+        if (attached)
+            static_cast<QQuickListViewAttached*>(attached)->setView(view);
+    }
+
+    ~FxListItemSG() {}
+
+    qreal position() const {
+        if (section) {
+            if (view->orientation() == QQuickListView::Vertical)
+                return section->y();
+            else
+                return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -section->width()-section->x() : section->x());
+        } else {
+            return itemPosition();
+        }
+    }
+    qreal itemPosition() const {
+        if (view->orientation() == QQuickListView::Vertical)
+            return item->y();
+        else
+            return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -item->width()-item->x() : item->x());
+    }
+    qreal size() const {
+        if (section)
+            return (view->orientation() == QQuickListView::Vertical ? item->height()+section->height() : item->width()+section->width());
+        else
+            return (view->orientation() == QQuickListView::Vertical ? item->height() : item->width());
+    }
+    qreal itemSize() const {
+        return (view->orientation() == QQuickListView::Vertical ? item->height() : item->width());
+    }
+    qreal sectionSize() const {
+        if (section)
+            return (view->orientation() == QQuickListView::Vertical ? section->height() : section->width());
+        return 0.0;
+    }
+    qreal endPosition() const {
+        if (view->orientation() == QQuickListView::Vertical) {
+            return item->y() + item->height();
+        } else {
+            return (view->effectiveLayoutDirection() == Qt::RightToLeft
+                    ? -item->x()
+                    : item->x() + item->width());
+        }
+    }
+    void setPosition(qreal pos) {
+        if (view->orientation() == QQuickListView::Vertical) {
+            if (section) {
+                section->setY(pos);
+                pos += section->height();
+            }
+            item->setY(pos);
+        } else {
+            if (view->effectiveLayoutDirection() == Qt::RightToLeft) {
+                if (section) {
+                    section->setX(-section->width()-pos);
+                    pos += section->width();
+                }
+                item->setX(-item->width()-pos);
+            } else {
+                if (section) {
+                    section->setX(pos);
+                    pos += section->width();
+                }
+                item->setX(pos);
+            }
+        }
+    }
+    void setSize(qreal size) {
+        if (view->orientation() == QQuickListView::Vertical)
+            item->setHeight(size);
+        else
+            item->setWidth(size);
+    }
+    bool contains(qreal x, qreal y) const {
+        return (x >= item->x() && x < item->x() + item->width() &&
+                y >= item->y() && y < item->y() + item->height());
+    }
+
+    QQuickItem *section;
+    QQuickListView *view;
+};
+
+//----------------------------------------------------------------------------
+
+bool QQuickListViewPrivate::isContentFlowReversed() const
+{
+    return isRightToLeft();
+}
+
+Qt::Orientation QQuickListViewPrivate::layoutOrientation() const
+{
+    return static_cast<Qt::Orientation>(orient);
+}
+
+bool QQuickListViewPrivate::isRightToLeft() const
+{
+    Q_Q(const QQuickListView);
+    return orient == QQuickListView::Horizontal && q->effectiveLayoutDirection() == Qt::RightToLeft;
+}
+
+// Returns the item before modelIndex, if created.
+// May return an item marked for removal.
+FxViewItem *QQuickListViewPrivate::itemBefore(int modelIndex) const
+{
+    if (modelIndex < visibleIndex)
+        return 0;
+    int idx = 1;
+    int lastIndex = -1;
+    while (idx < visibleItems.count()) {
+        FxViewItem *item = visibleItems.at(idx);
+        if (item->index != -1)
+            lastIndex = item->index;
+        if (item->index == modelIndex)
+            return visibleItems.at(idx-1);
+        ++idx;
+    }
+    if (lastIndex == modelIndex-1)
+        return visibleItems.last();
+    return 0;
+}
+
+void QQuickListViewPrivate::setPosition(qreal pos)
+{
+    Q_Q(QQuickListView);
+    if (orient == QQuickListView::Vertical) {
+        q->QQuickFlickable::setContentY(pos);
+    } else {
+        if (isRightToLeft())
+            q->QQuickFlickable::setContentX(-pos-size());
+        else
+            q->QQuickFlickable::setContentX(pos);
+    }
+}
+
+qreal QQuickListViewPrivate::originPosition() const
+{
+    qreal pos = 0;
+    if (!visibleItems.isEmpty()) {
+        pos = (*visibleItems.constBegin())->position();
+        if (visibleIndex > 0)
+            pos -= visibleIndex * (averageSize + spacing);
+    }
+    return pos;
+}
+
+qreal QQuickListViewPrivate::lastPosition() const
+{
+    qreal pos = 0;
+    if (!visibleItems.isEmpty()) {
+        int invisibleCount = visibleItems.count() - visibleIndex;
+        for (int i = visibleItems.count()-1; i >= 0; --i) {
+            if (visibleItems.at(i)->index != -1) {
+                invisibleCount = model->count() - visibleItems.at(i)->index - 1;
+                break;
+            }
+        }
+        pos = (*(--visibleItems.constEnd()))->endPosition() + invisibleCount * (averageSize + spacing);
+    } else if (model && model->count()) {
+        pos = (model->count() * averageSize + (model->count()-1) * spacing);
+    }
+    return pos;
+}
+
+qreal QQuickListViewPrivate::positionAt(int modelIndex) const
+{
+    if (FxViewItem *item = visibleItem(modelIndex))
+        return item->position();
+    if (!visibleItems.isEmpty()) {
+        if (modelIndex < visibleIndex) {
+            int count = visibleIndex - modelIndex;
+            qreal cs = 0;
+            if (modelIndex == currentIndex && currentItem) {
+                cs = currentItem->size() + spacing;
+                --count;
+            }
+            return (*visibleItems.constBegin())->position() - count * (averageSize + spacing) - cs;
+        } else {
+            int count = modelIndex - findLastVisibleIndex(visibleIndex) - 1;
+            return (*(--visibleItems.constEnd()))->endPosition() + spacing + count * (averageSize + spacing);
+        }
+    }
+    return 0;
+}
+
+qreal QQuickListViewPrivate::endPositionAt(int modelIndex) const
+{
+    if (FxViewItem *item = visibleItem(modelIndex))
+        return item->endPosition();
+    if (!visibleItems.isEmpty()) {
+        if (modelIndex < visibleIndex) {
+            int count = visibleIndex - modelIndex;
+            return (*visibleItems.constBegin())->position() - (count - 1) * (averageSize + spacing) - spacing;
+        } else {
+            int count = modelIndex - findLastVisibleIndex(visibleIndex) - 1;
+            return (*(--visibleItems.constEnd()))->endPosition() + count * (averageSize + spacing);
+        }
+    }
+    return 0;
+}
+
+QString QQuickListViewPrivate::sectionAt(int modelIndex)
+{
+    if (FxViewItem *item = visibleItem(modelIndex))
+        return item->attached->section();
+
+    QString section;
+    if (sectionCriteria) {
+        QString propValue = model->stringValue(modelIndex, sectionCriteria->property());
+        section = sectionCriteria->sectionString(propValue);
+    }
+
+    return section;
+}
+
+qreal QQuickListViewPrivate::snapPosAt(qreal pos)
+{
+    if (FxViewItem *snapItem = snapItemAt(pos))
+        return snapItem->position();
+    if (visibleItems.count()) {
+        qreal firstPos = (*visibleItems.constBegin())->position();
+        qreal endPos = (*(--visibleItems.constEnd()))->position();
+        if (pos < firstPos) {
+            return firstPos - qRound((firstPos - pos) / averageSize) * averageSize;
+        } else if (pos > endPos)
+            return endPos + qRound((pos - endPos) / averageSize) * averageSize;
+    }
+    return qRound((pos - originPosition()) / averageSize) * averageSize + originPosition();
+}
+
+FxViewItem *QQuickListViewPrivate::snapItemAt(qreal pos)
+{
+    FxViewItem *snapItem = 0;
+    qreal prevItemSize = 0;
+    for (int i = 0; i < visibleItems.count(); ++i) {
+        FxViewItem *item = visibleItems.at(i);
+        if (item->index == -1)
+            continue;
+        qreal itemTop = item->position();
+        if (highlight && itemTop >= pos && item->endPosition() <= pos + highlight->size())
+            return item;
+        if (itemTop+item->size()/2 >= pos && itemTop-prevItemSize/2 < pos)
+            snapItem = item;
+        prevItemSize = item->size();
+    }
+    return snapItem;
+}
+
+void QQuickListViewPrivate::changedVisibleIndex(int newIndex)
+{
+    visiblePos = positionAt(newIndex);
+    visibleIndex = newIndex;
+}
+
+void QQuickListViewPrivate::init()
+{
+    QQuickItemViewPrivate::init();
+    ::memset(sectionCache, 0, sizeof(QQuickItem*) * sectionCacheSize);
+}
+
+void QQuickListViewPrivate::clear()
+{
+    for (int i = 0; i < sectionCacheSize; ++i) {
+        delete sectionCache[i];
+        sectionCache[i] = 0;
+    }
+    visiblePos = 0;
+    currentSectionItem = 0;
+    nextSectionItem = 0;
+    lastVisibleSection = QString();
+    QQuickItemViewPrivate::clear();
+}
+
+FxViewItem *QQuickListViewPrivate::newViewItem(int modelIndex, QQuickItem *item)
+{
+    Q_Q(QQuickListView);
+
+    FxListItemSG *listItem = new FxListItemSG(item, q, false);
+    listItem->index = modelIndex;
+
+    // initialise attached properties
+    if (sectionCriteria) {
+        QString propValue = model->stringValue(modelIndex, sectionCriteria->property());
+        listItem->attached->m_section = sectionCriteria->sectionString(propValue);
+        if (modelIndex > 0) {
+            if (FxViewItem *item = itemBefore(modelIndex))
+                listItem->attached->m_prevSection = item->attached->section();
+            else
+                listItem->attached->m_prevSection = sectionAt(modelIndex-1);
+        }
+        if (modelIndex < model->count()-1) {
+            if (FxViewItem *item = visibleItem(modelIndex+1))
+                listItem->attached->m_nextSection = static_cast<QQuickListViewAttached*>(item->attached)->section();
+            else
+                listItem->attached->m_nextSection = sectionAt(modelIndex+1);
+        }
+    }
+
+    return listItem;
+}
+
+void QQuickListViewPrivate::initializeViewItem(FxViewItem *item)
+{
+    QQuickItemViewPrivate::initializeViewItem(item);
+
+    QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item->item);
+    itemPrivate->addItemChangeListener(this, QQuickItemPrivate::Geometry);
+
+    if (sectionCriteria && sectionCriteria->delegate()) {
+        if (item->attached->m_prevSection != item->attached->m_section)
+            updateInlineSection(static_cast<FxListItemSG*>(item));
+    }
+}
+
+void QQuickListViewPrivate::releaseItem(FxViewItem *item)
+{
+    if (item) {
+        FxListItemSG* listItem = static_cast<FxListItemSG*>(item);
+        if (listItem->section) {
+            int i = 0;
+            do {
+                if (!sectionCache[i]) {
+                    sectionCache[i] = listItem->section;
+                    sectionCache[i]->setVisible(false);
+                    listItem->section = 0;
+                    break;
+                }
+                ++i;
+            } while (i < sectionCacheSize);
+            delete listItem->section;
+        }
+    }
+    QQuickItemViewPrivate::releaseItem(item);
+}
+
+bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool doBuffer)
+{
+    qreal itemEnd = visiblePos;
+    if (visibleItems.count()) {
+        visiblePos = (*visibleItems.constBegin())->position();
+        itemEnd = (*(--visibleItems.constEnd()))->endPosition() + spacing;
+    }
+
+    int modelIndex = findLastVisibleIndex();
+    bool haveValidItems = modelIndex >= 0;
+    modelIndex = modelIndex < 0 ? visibleIndex : modelIndex + 1;
+
+    if (haveValidItems && (fillFrom > itemEnd+averageSize+spacing
+        || fillTo < visiblePos - averageSize - spacing)) {
+        // We've jumped more than a page.  Estimate which items are now
+        // visible and fill from there.
+        int count = (fillFrom - itemEnd) / (averageSize + spacing);
+        for (int i = 0; i < visibleItems.count(); ++i)
+            releaseItem(visibleItems.at(i));
+        visibleItems.clear();
+        modelIndex += count;
+        if (modelIndex >= model->count()) {
+            count -= modelIndex - model->count() + 1;
+            modelIndex = model->count() - 1;
+        } else if (modelIndex < 0) {
+            count -= modelIndex;
+            modelIndex = 0;
+        }
+        visibleIndex = modelIndex;
+        visiblePos = itemEnd + count * (averageSize + spacing);
+        itemEnd = visiblePos;
+    }
+
+    bool changed = false;
+    FxListItemSG *item = 0;
+    qreal pos = itemEnd;
+    while (modelIndex < model->count() && pos <= fillTo) {
+//        qDebug() << "refill: append item" << modelIndex << "pos" << pos;
+        if (!(item = static_cast<FxListItemSG*>(createItem(modelIndex))))
+            break;
+        item->setPosition(pos);
+        pos += item->size() + spacing;
+        visibleItems.append(item);
+        ++modelIndex;
+        changed = true;
+        if (doBuffer) // never buffer more than one item per frame
+            break;
+    }
+    while (visibleIndex > 0 && visibleIndex <= model->count() && visiblePos >= fillFrom) {
+//        qDebug() << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos;
+        if (!(item = static_cast<FxListItemSG*>(createItem(visibleIndex-1))))
+            break;
+        --visibleIndex;
+        visiblePos -= item->size() + spacing;
+        item->setPosition(visiblePos);
+        visibleItems.prepend(item);
+        changed = true;
+        if (doBuffer) // never buffer more than one item per frame
+            break;
+    }
+
+    return changed;
+}
+
+bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal bufferTo)
+{
+    FxViewItem *item = 0;
+    bool changed = false;
+
+    while (visibleItems.count() > 1 && (item = visibleItems.first()) && item->endPosition() <= bufferFrom) {
+        if (item->attached->delayRemove())
+            break;
+        if (item->size() == 0)
+            break;
+//            qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endPosition();
+        if (item->index != -1)
+            visibleIndex++;
+        visibleItems.removeFirst();
+        releaseItem(item);
+        changed = true;
+    }
+    while (visibleItems.count() > 1 && (item = visibleItems.last()) && item->position() > bufferTo) {
+        if (item->attached->delayRemove())
+            break;
+//            qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1 << item->position();
+        visibleItems.removeLast();
+        releaseItem(item);
+        changed = true;
+    }
+
+    return changed;
+}
+
+void QQuickListViewPrivate::visibleItemsChanged()
+{
+    if (visibleItems.count())
+        visiblePos = (*visibleItems.constBegin())->position();
+    updateAverage();
+    if (currentIndex >= 0 && currentItem && !visibleItem(currentIndex)) {
+        static_cast<FxListItemSG*>(currentItem)->setPosition(positionAt(currentIndex));
+        updateHighlight();
+    }
+    if (sectionCriteria)
+        updateCurrentSection();
+    updateHeader();
+    updateFooter();
+    updateViewport();
+    updateUnrequestedPositions();
+}
+
+void QQuickListViewPrivate::layoutVisibleItems()
+{
+    if (!visibleItems.isEmpty()) {
+        bool fixedCurrent = currentItem && (*visibleItems.constBegin())->item == currentItem->item;
+        qreal sum = (*visibleItems.constBegin())->size();
+        qreal pos = (*visibleItems.constBegin())->position() + (*visibleItems.constBegin())->size() + spacing;
+        for (int i=1; i < visibleItems.count(); ++i) {
+            FxListItemSG *item = static_cast<FxListItemSG*>(visibleItems.at(i));
+            item->setPosition(pos);
+            pos += item->size() + spacing;
+            sum += item->size();
+            fixedCurrent = fixedCurrent || (currentItem && item->item == currentItem->item);
+        }
+        averageSize = qRound(sum / visibleItems.count());
+
+        // move current item if it is not a visible item.
+        if (currentIndex >= 0 && currentItem && !fixedCurrent) {
+            static_cast<FxListItemSG*>(currentItem)->setPosition(positionAt(currentIndex));
+        }
+    }
+}
+
+void QQuickListViewPrivate::repositionPackageItemAt(QQuickItem *item, int index)
+{
+    Q_Q(QQuickListView);
+    qreal pos = position();
+    if (orient == QQuickListView::Vertical) {
+        if (item->y() + item->height() > pos && item->y() < pos + q->height())
+            item->setY(positionAt(index));
+    } else {
+        if (item->x() + item->width() > pos && item->x() < pos + q->width()) {
+            if (isRightToLeft())
+                item->setX(-positionAt(index)-item->width());
+            else
+                item->setX(positionAt(index));
+        }
+    }
+}
+
+void QQuickListViewPrivate::resetItemPosition(FxViewItem *item, FxViewItem *toItem)
+{
+    if (item == toItem)
+        return;
+    static_cast<FxListItemSG*>(item)->setPosition(toItem->position());
+}
+
+void QQuickListViewPrivate::resetFirstItemPosition()
+{
+    FxListItemSG *item = static_cast<FxListItemSG*>(visibleItems.first());
+    item->setPosition(0);
+}
+
+void QQuickListViewPrivate::moveItemBy(FxViewItem *item, qreal forwards, qreal backwards)
+{
+    qreal diff = forwards - backwards;
+    static_cast<FxListItemSG*>(item)->setPosition(item->position() + diff);
+}
+
+void QQuickListViewPrivate::createHighlight()
+{
+    Q_Q(QQuickListView);
+    bool changed = false;
+    if (highlight) {
+        if (trackedItem == highlight)
+            trackedItem = 0;
+        delete highlight;
+        highlight = 0;
+
+        delete highlightPosAnimator;
+        delete highlightSizeAnimator;
+        highlightPosAnimator = 0;
+        highlightSizeAnimator = 0;
+
+        changed = true;
+    }
+
+    if (currentItem) {
+        QQuickItem *item = createHighlightItem();
+        if (item) {
+            FxListItemSG *newHighlight = new FxListItemSG(item, q, true);
+
+            if (autoHighlight) {
+                newHighlight->setSize(static_cast<FxListItemSG*>(currentItem)->itemSize());
+                newHighlight->setPosition(static_cast<FxListItemSG*>(currentItem)->itemPosition());
+            }
+            const QLatin1String posProp(orient == QQuickListView::Vertical ? "y" : "x");
+            highlightPosAnimator = new QSmoothedAnimation(q);
+            highlightPosAnimator->target = QDeclarativeProperty(item, posProp);
+            highlightPosAnimator->velocity = highlightMoveSpeed;
+            highlightPosAnimator->userDuration = highlightMoveDuration;
+
+            const QLatin1String sizeProp(orient == QQuickListView::Vertical ? "height" : "width");
+            highlightSizeAnimator = new QSmoothedAnimation(q);
+            highlightSizeAnimator->velocity = highlightResizeSpeed;
+            highlightSizeAnimator->userDuration = highlightResizeDuration;
+            highlightSizeAnimator->target = QDeclarativeProperty(item, sizeProp);
+
+            highlight = newHighlight;
+            changed = true;
+        }
+    }
+    if (changed)
+        emit q->highlightItemChanged();
+}
+
+void QQuickListViewPrivate::updateHighlight()
+{
+    applyPendingChanges();
+
+    if ((!currentItem && highlight) || (currentItem && !highlight))
+        createHighlight();
+    bool strictHighlight = haveHighlightRange && highlightRange == QQuickListView::StrictlyEnforceRange;
+    if (currentItem && autoHighlight && highlight && (!strictHighlight || !pressed)) {
+        // auto-update highlight
+        FxListItemSG *listItem = static_cast<FxListItemSG*>(currentItem);
+        highlightPosAnimator->to = isRightToLeft()
+                ? -listItem->itemPosition()-listItem->itemSize()
+                : listItem->itemPosition();
+        highlightSizeAnimator->to = listItem->itemSize();
+        if (orient == QQuickListView::Vertical) {
+            if (highlight->item->width() == 0)
+                highlight->item->setWidth(currentItem->item->width());
+        } else {
+            if (highlight->item->height() == 0)
+                highlight->item->setHeight(currentItem->item->height());
+        }
+
+        highlightPosAnimator->restart();
+        highlightSizeAnimator->restart();
+    }
+    updateTrackedItem();
+}
+
+void QQuickListViewPrivate::resetHighlightPosition()
+{
+    if (highlight && currentItem)
+        static_cast<FxListItemSG*>(highlight)->setPosition(static_cast<FxListItemSG*>(currentItem)->itemPosition());
+}
+
+QQuickItem * QQuickListViewPrivate::getSectionItem(const QString &section)
+{
+    Q_Q(QQuickListView);
+    QQuickItem *sectionItem = 0;
+    int i = sectionCacheSize-1;
+    while (i >= 0 && !sectionCache[i])
+        --i;
+    if (i >= 0) {
+        sectionItem = sectionCache[i];
+        sectionCache[i] = 0;
+        sectionItem->setVisible(true);
+        QDeclarativeContext *context = QDeclarativeEngine::contextForObject(sectionItem)->parentContext();
+        context->setContextProperty(QLatin1String("section"), section);
+    } else {
+        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) {
+            QDeclarative_setParent_noEvent(context, nobj);
+            sectionItem = qobject_cast<QQuickItem *>(nobj);
+            if (!sectionItem) {
+                delete nobj;
+            } else {
+                sectionItem->setZ(2);
+                QDeclarative_setParent_noEvent(sectionItem, contentItem);
+                sectionItem->setParentItem(contentItem);
+            }
+        } else {
+            delete context;
+        }
+        sectionCriteria->delegate()->completeCreate();
+    }
+
+    return sectionItem;
+}
+
+void QQuickListViewPrivate::releaseSectionItem(QQuickItem *item)
+{
+    int i = 0;
+    do {
+        if (!sectionCache[i]) {
+            sectionCache[i] = item;
+            sectionCache[i]->setVisible(false);
+            return;
+        }
+        ++i;
+    } while (i < sectionCacheSize);
+    delete item;
+}
+
+void QQuickListViewPrivate::updateInlineSection(FxListItemSG *listItem)
+{
+    if (!sectionCriteria || !sectionCriteria->delegate())
+        return;
+    if (listItem->attached->m_prevSection != listItem->attached->m_section
+            && (sectionCriteria->labelPositioning() & QQuickViewSection::InlineLabels
+                || (listItem->index == 0 && sectionCriteria->labelPositioning() & QQuickViewSection::CurrentLabelAtStart))) {
+        if (!listItem->section) {
+            qreal pos = listItem->position();
+            listItem->section = getSectionItem(listItem->attached->m_section);
+            listItem->setPosition(pos);
+        } else {
+            QDeclarativeContext *context = QDeclarativeEngine::contextForObject(listItem->section)->parentContext();
+            context->setContextProperty(QLatin1String("section"), listItem->attached->m_section);
+        }
+    } else if (listItem->section) {
+        qreal pos = listItem->position();
+        releaseSectionItem(listItem->section);
+        listItem->section = 0;
+        listItem->setPosition(pos);
+    }
+}
+
+void QQuickListViewPrivate::updateStickySections()
+{
+    if (!sectionCriteria || visibleItems.isEmpty()
+            || (!sectionCriteria->labelPositioning() && !currentSectionItem && !nextSectionItem))
+        return;
+
+    bool isRtl = isRightToLeft();
+    qreal viewPos = isRightToLeft() ? -position()-size() : position();
+    QQuickItem *sectionItem = 0;
+    QQuickItem *lastSectionItem = 0;
+    int index = 0;
+    while (index < visibleItems.count()) {
+        if (QQuickItem *section = static_cast<FxListItemSG *>(visibleItems.at(index))->section) {
+            // Find the current section header and last visible section header
+            // and hide them if they will overlap a static section header.
+            qreal sectionPos = orient == QQuickListView::Vertical ? section->y() : section->x();
+            qreal sectionSize = orient == QQuickListView::Vertical ? section->height() : section->width();
+            bool visTop = true;
+            if (sectionCriteria->labelPositioning() & QQuickViewSection::CurrentLabelAtStart)
+                visTop = isRtl ? -sectionPos-sectionSize >= viewPos : sectionPos >= viewPos;
+            bool visBot = true;
+            if (sectionCriteria->labelPositioning() & QQuickViewSection::NextLabelAtEnd)
+                visBot = isRtl ? -sectionPos <= viewPos + size() : sectionPos + sectionSize < viewPos + size();
+            section->setVisible(visBot && visTop);
+            if (visTop && !sectionItem)
+                sectionItem = section;
+            if (isRtl) {
+               if (-sectionPos <= viewPos + size())
+                    lastSectionItem = section;
+            } else {
+                if (sectionPos + sectionSize < viewPos + size())
+                    lastSectionItem = section;
+            }
+        }
+        ++index;
+    }
+
+    // Current section header
+    if (sectionCriteria->labelPositioning() & QQuickViewSection::CurrentLabelAtStart) {
+        if (!currentSectionItem) {
+            currentSectionItem = getSectionItem(currentSection);
+        } else if (currentStickySection != currentSection) {
+            QDeclarativeContext *context = QDeclarativeEngine::contextForObject(currentSectionItem)->parentContext();
+            context->setContextProperty(QLatin1String("section"), currentSection);
+        }
+        currentStickySection = currentSection;
+        if (!currentSectionItem)
+            return;
+
+        qreal sectionSize = orient == QQuickListView::Vertical ? currentSectionItem->height() : currentSectionItem->width();
+        bool atBeginning = orient == QQuickListView::Vertical ? vData.atBeginning : (isRightToLeft() ? hData.atEnd : hData.atBeginning);
+        currentSectionItem->setVisible(!atBeginning && (!header || header->endPosition() < viewPos));
+        qreal pos = isRtl ? position() + size() - sectionSize : viewPos;
+        if (sectionItem) {
+            qreal sectionPos = orient == QQuickListView::Vertical ? sectionItem->y() : sectionItem->x();
+            pos = isRtl ? qMax(pos, sectionPos + sectionSize) : qMin(pos, sectionPos - sectionSize);
+        }
+        if (header)
+            pos = isRtl ? qMin(header->endPosition(), pos) : qMax(header->endPosition(), pos);
+        if (footer)
+            pos = isRtl ? qMax(-footer->position(), pos) : qMin(footer->position() - sectionSize, pos);
+        if (orient == QQuickListView::Vertical)
+            currentSectionItem->setY(pos);
+        else
+            currentSectionItem->setX(pos);
+    } else if (currentSectionItem) {
+        releaseSectionItem(currentSectionItem);
+        currentSectionItem = 0;
+    }
+
+    // Next section footer
+    if (sectionCriteria->labelPositioning() & QQuickViewSection::NextLabelAtEnd) {
+        if (!nextSectionItem) {
+            nextSectionItem = getSectionItem(nextSection);
+        } else if (nextStickySection != nextSection) {
+            QDeclarativeContext *context = QDeclarativeEngine::contextForObject(nextSectionItem)->parentContext();
+            context->setContextProperty(QLatin1String("section"), nextSection);
+        }
+        nextStickySection = nextSection;
+        if (!nextSectionItem)
+            return;
+
+        qreal sectionSize = orient == QQuickListView::Vertical ? nextSectionItem->height() : nextSectionItem->width();
+        nextSectionItem->setVisible(!nextSection.isEmpty());
+        qreal pos = isRtl ? position() : viewPos + size() - sectionSize;
+        if (lastSectionItem) {
+            qreal sectionPos = orient == QQuickListView::Vertical ? lastSectionItem->y() : lastSectionItem->x();
+            pos = isRtl ? qMin(pos, sectionPos - sectionSize) : qMax(pos, sectionPos + sectionSize);
+        }
+        if (header)
+            pos = isRtl ? qMin(header->endPosition() - sectionSize, pos) : qMax(header->endPosition(), pos);
+        if (orient == QQuickListView::Vertical)
+            nextSectionItem->setY(pos);
+        else
+            nextSectionItem->setX(pos);
+    } else if (nextSectionItem) {
+        releaseSectionItem(nextSectionItem);
+        nextSectionItem = 0;
+    }
+}
+
+void QQuickListViewPrivate::updateSections()
+{
+    Q_Q(QQuickListView);
+    if (!q->isComponentComplete())
+        return;
+
+    QQuickItemViewPrivate::updateSections();
+
+    if (sectionCriteria && !visibleItems.isEmpty()) {
+        QString prevSection;
+        if (visibleIndex > 0)
+            prevSection = sectionAt(visibleIndex-1);
+        QQuickListViewAttached *prevAtt = 0;
+        int idx = -1;
+        for (int i = 0; i < visibleItems.count(); ++i) {
+            QQuickListViewAttached *attached = static_cast<QQuickListViewAttached*>(visibleItems.at(i)->attached);
+            attached->setPrevSection(prevSection);
+            if (visibleItems.at(i)->index != -1) {
+                QString propValue = model->stringValue(visibleItems.at(i)->index, sectionCriteria->property());
+                attached->setSection(sectionCriteria->sectionString(propValue));
+                idx = visibleItems.at(i)->index;
+            }
+            updateInlineSection(static_cast<FxListItemSG*>(visibleItems.at(i)));
+            if (prevAtt)
+                prevAtt->setNextSection(attached->section());
+            prevSection = attached->section();
+            prevAtt = attached;
+        }
+        if (prevAtt) {
+            if (idx > 0 && idx < model->count()-1)
+                prevAtt->setNextSection(sectionAt(idx+1));
+            else
+                prevAtt->setNextSection(QString());
+        }
+    }
+
+    lastVisibleSection = QString();
+    updateCurrentSection();
+    updateStickySections();
+}
+
+void QQuickListViewPrivate::updateCurrentSection()
+{
+    Q_Q(QQuickListView);
+    if (!sectionCriteria || visibleItems.isEmpty()) {
+        if (!currentSection.isEmpty()) {
+            currentSection.clear();
+            emit q->currentSectionChanged();
+        }
+        return;
+    }
+    bool inlineSections = sectionCriteria->labelPositioning() & QQuickViewSection::InlineLabels;
+    qreal sectionThreshold = position();
+    if (currentSectionItem && !inlineSections)
+        sectionThreshold += orient == QQuickListView::Vertical ? currentSectionItem->height() : currentSectionItem->width();
+    int index = 0;
+    int modelIndex = visibleIndex;
+    while (index < visibleItems.count() && visibleItems.at(index)->endPosition() <= sectionThreshold) {
+        if (visibleItems.at(index)->index != -1)
+            modelIndex = visibleItems.at(index)->index;
+        ++index;
+    }
+
+    QString newSection = currentSection;
+    if (index < visibleItems.count())
+        newSection = visibleItems.at(index)->attached->section();
+    else
+        newSection = (*visibleItems.constBegin())->attached->section();
+    if (newSection != currentSection) {
+        currentSection = newSection;
+        updateStickySections();
+        emit q->currentSectionChanged();
+    }
+
+    if (sectionCriteria->labelPositioning() & QQuickViewSection::NextLabelAtEnd) {
+        // Don't want to scan for next section on every movement, so remember
+        // the last section in the visible area and only scan for the next
+        // section when that changes.  Clearing lastVisibleSection will also
+        // force searching.
+        QString lastSection = currentSection;
+        qreal endPos = isRightToLeft() ? -position() : position() + size();
+        if (nextSectionItem && !inlineSections)
+            endPos -= orient == QQuickListView::Vertical ? nextSectionItem->height() : nextSectionItem->width();
+        while (index < visibleItems.count() && static_cast<FxListItemSG*>(visibleItems.at(index))->itemPosition() < endPos) {
+            if (visibleItems.at(index)->index != -1)
+                modelIndex = visibleItems.at(index)->index;
+            lastSection = visibleItems.at(index)->attached->section();
+            ++index;
+        }
+
+        if (lastVisibleSection != lastSection) {
+            nextSection = QString();
+            lastVisibleSection = lastSection;
+            for (int i = modelIndex; i < itemCount; ++i) {
+                QString section = sectionAt(i);
+                if (section != lastSection) {
+                    nextSection = section;
+                    updateStickySections();
+                    break;
+                }
+            }
+        }
+    }
+}
+
+void QQuickListViewPrivate::initializeCurrentItem()
+{
+    QQuickItemViewPrivate::initializeCurrentItem();
+
+    if (currentItem) {
+        FxListItemSG *listItem = static_cast<FxListItemSG *>(currentItem);
+
+        if (currentIndex == visibleIndex - 1 && visibleItems.count()) {
+            // We can calculate exact postion in this case
+            listItem->setPosition(visibleItems.first()->position() - currentItem->size() - spacing);
+        } else {
+            // Create current item now and position as best we can.
+            // Its position will be corrected when it becomes visible.
+            listItem->setPosition(positionAt(currentIndex));
+        }
+
+        // Avoid showing section delegate twice.  We still need the section heading so that
+        // currentItem positioning works correctly.
+        // This is slightly sub-optimal, but section heading caching minimizes the impact.
+        if (listItem->section)
+            listItem->section->setVisible(false);
+
+        if (visibleItems.isEmpty())
+            averageSize = listItem->size();
+    }
+}
+
+void QQuickListViewPrivate::updateAverage()
+{
+    if (!visibleItems.count())
+        return;
+    qreal sum = 0.0;
+    for (int i = 0; i < visibleItems.count(); ++i)
+        sum += visibleItems.at(i)->size();
+    averageSize = qRound(sum / visibleItems.count());
+}
+
+qreal QQuickListViewPrivate::headerSize() const
+{
+    return header ? header->size() : 0.0;
+}
+
+qreal QQuickListViewPrivate::footerSize() const
+{
+    return footer ? footer->size() : 0.0;
+}
+
+bool QQuickListViewPrivate::showHeaderForIndex(int index) const
+{
+    return index == 0;
+}
+
+bool QQuickListViewPrivate::showFooterForIndex(int index) const
+{
+    return index == model->count()-1;
+}
+
+void QQuickListViewPrivate::updateFooter()
+{
+    Q_Q(QQuickListView);
+    bool created = false;
+    if (!footer) {
+        QQuickItem *item = createComponentItem(footerComponent, true);
+        if (!item)
+            return;
+        item->setZ(1);
+        footer = new FxListItemSG(item, q, true);
+        created = true;
+    }
+
+    FxListItemSG *listItem = static_cast<FxListItemSG*>(footer);
+    if (visibleItems.count()) {
+        qreal endPos = lastPosition();
+        if (findLastVisibleIndex() == model->count()-1) {
+            listItem->setPosition(endPos);
+        } else {
+            qreal visiblePos = position() + q->height();
+            if (endPos <= visiblePos || listItem->position() < endPos)
+                listItem->setPosition(endPos);
+        }
+    } else {
+        listItem->setPosition(visiblePos);
+    }
+
+    if (created)
+        emit q->footerItemChanged();
+}
+
+void QQuickListViewPrivate::updateHeader()
+{
+    Q_Q(QQuickListView);
+    bool created = false;
+    if (!header) {
+        QQuickItem *item = createComponentItem(headerComponent, true);
+        if (!item)
+            return;
+        item->setZ(1);
+        header = new FxListItemSG(item, q, true);
+        created = true;
+    }
+
+    FxListItemSG *listItem = static_cast<FxListItemSG*>(header);
+    if (listItem) {
+        if (visibleItems.count()) {
+            qreal startPos = originPosition();
+            if (visibleIndex == 0) {
+                listItem->setPosition(startPos - headerSize());
+            } else {
+                if (position() <= startPos || listItem->position() > startPos - headerSize())
+                    listItem->setPosition(startPos - headerSize());
+            }
+        } else {
+            listItem->setPosition(-headerSize());
+        }
+    }
+
+    if (created)
+        emit q->headerItemChanged();
+}
+
+void QQuickListViewPrivate::itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+    Q_Q(QQuickListView);
+    QQuickItemViewPrivate::itemGeometryChanged(item, newGeometry, oldGeometry);
+    if (!q->isComponentComplete())
+        return;
+    if (item != contentItem && (!highlight || item != highlight->item)) {
+        if ((orient == QQuickListView::Vertical && newGeometry.height() != oldGeometry.height())
+            || (orient == QQuickListView::Horizontal && newGeometry.width() != oldGeometry.width())) {
+            forceLayout = true;
+            q->polish();
+        }
+    }
+}
+
+void QQuickListViewPrivate::fixupPosition()
+{
+    if ((haveHighlightRange && highlightRange == QQuickListView::StrictlyEnforceRange)
+        || snapMode != QQuickListView::NoSnap)
+        moveReason = Other;
+    if (orient == QQuickListView::Vertical)
+        fixupY();
+    else
+        fixupX();
+}
+
+void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
+{
+    if ((orient == QQuickListView::Horizontal && &data == &vData)
+        || (orient == QQuickListView::Vertical && &data == &hData))
+        return;
+
+    correctFlick = false;
+    fixupMode = moveReason == Mouse ? fixupMode : Immediate;
+    bool strictHighlightRange = haveHighlightRange && highlightRange == QQuickListView::StrictlyEnforceRange;
+
+    qreal viewPos = isRightToLeft() ? -position()-size() : position();
+
+    if (snapMode != QQuickListView::NoSnap && moveReason != QQuickListViewPrivate::SetIndex) {
+        qreal tempPosition = isRightToLeft() ? -position()-size() : position();
+        if (snapMode == QQuickListView::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 || 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() + highlightRangeStart - size(), -maxExtent), -minExtent);
+                else
+                    pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent);
+            }
+        } else if (bottomItem && isInBounds) {
+            if (isRightToLeft())
+                pos = qMax(qMin(-bottomItem->position() + highlightRangeEnd - size(), -maxExtent), -minExtent);
+            else
+                pos = qMax(qMin(bottomItem->position() - highlightRangeEnd, -maxExtent), -minExtent);
+        } else {
+            QQuickItemViewPrivate::fixup(data, minExtent, maxExtent);
+            return;
+        }
+
+        qreal dist = qAbs(data.move + pos);
+        if (dist > 0) {
+            timeline.reset(data.move);
+            if (fixupMode != Immediate) {
+                timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
+                data.fixingUp = true;
+            } else {
+                timeline.set(data.move, -pos);
+            }
+            vTime = timeline.time();
+        }
+    } else if (currentItem && strictHighlightRange && moveReason != QQuickListViewPrivate::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 {
+        QQuickItemViewPrivate::fixup(data, minExtent, maxExtent);
+    }
+    data.inOvershoot = false;
+    fixupMode = Normal;
+}
+
+void QQuickListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
+                                        QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity)
+{
+    Q_Q(QQuickListView);
+
+    data.fixingUp = false;
+    moveReason = Mouse;
+    if ((!haveHighlightRange || highlightRange != QQuickListView::StrictlyEnforceRange) && snapMode == QQuickListView::NoSnap) {
+        correctFlick = true;
+        QQuickItemViewPrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, velocity);
+        return;
+    }
+    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 == QQuickListView::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());
+            }
+        }
+        if (snapMode == QQuickListView::NoSnap && highlightRange != QQuickListView::StrictlyEnforceRange)
+            data.flickTarget = minExtent;
+    } else {
+        if (data.move.value() > maxExtent) {
+            if (snapMode == QQuickListView::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());
+            }
+        }
+        if (snapMode == QQuickListView::NoSnap && highlightRange != QQuickListView::StrictlyEnforceRange)
+            data.flickTarget = maxExtent;
+    }
+    bool overShoot = boundsBehavior == QQuickFlickable::DragAndOvershootBounds;
+    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.
+        // Since list items can have variable sizes, the boundary will be
+        // reevaluated and adjusted as we approach the boundary.
+        qreal v = velocity;
+        if (maxVelocity != -1 && maxVelocity < qAbs(v)) {
+            if (v < 0)
+                v = -maxVelocity;
+            else
+                v = maxVelocity;
+        }
+        if (!hData.flicking && !vData.flicking) {
+            // the initial flick - estimate boundary
+            qreal accel = deceleration;
+            qreal v2 = v * v;
+            overshootDist = 0.0;
+            // + averageSize/4 to encourage moving at least one item in the flick direction
+            qreal dist = v2 / (accel * 2.0) + averageSize/4;
+            if (maxDistance > 0)
+                dist = qMin(dist, maxDistance);
+            if (v > 0)
+                dist = -dist;
+            if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QQuickListView::SnapOneItem) {
+                if (snapMode != QQuickListView::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) {
+                        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
+                    qreal adjv2 = accel * 2.0f * qAbs(adjDist);
+                    if (adjv2 > v2) {
+                        v2 = adjv2;
+                        v = qSqrt(v2);
+                        if (dist > 0)
+                            v = -v;
+                    }
+                }
+                dist = adjDist;
+                accel = v2 / (2.0f * qAbs(dist));
+            } else if (overShoot) {
+                data.flickTarget = data.move.value() - dist;
+                if (data.flickTarget >= minExtent) {
+                    overshootDist = overShootDistance(vSize);
+                    data.flickTarget += overshootDist;
+                } else if (data.flickTarget <= maxExtent) {
+                    overshootDist = overShootDistance(vSize);
+                    data.flickTarget -= overshootDist;
+                }
+            }
+            timeline.reset(data.move);
+            timeline.accel(data.move, v, accel, maxDistance + overshootDist);
+            timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this));
+            if (!hData.flicking && q->xflick()) {
+                hData.flicking = true;
+                emit q->flickingChanged();
+                emit q->flickingHorizontallyChanged();
+                emit q->flickStarted();
+            }
+            if (!vData.flicking && q->yflick()) {
+                vData.flicking = true;
+                emit q->flickingChanged();
+                emit q->flickingVerticallyChanged();
+                emit q->flickStarted();
+            }
+            correctFlick = true;
+        } else {
+            // reevaluate the target boundary.
+            qreal newtarget = data.flickTarget;
+            if (snapMode != QQuickListView::NoSnap || highlightRange == QQuickListView::StrictlyEnforceRange) {
+                qreal tempFlickTarget = isRightToLeft() ? -data.flickTarget+size() : data.flickTarget;
+                newtarget = -snapPosAt(-(tempFlickTarget - highlightRangeStart)) + highlightRangeStart;
+                newtarget = isRightToLeft() ? -newtarget+size() : newtarget;
+            }
+            if (velocity < 0 && newtarget <= maxExtent)
+                newtarget = maxExtent - overshootDist;
+            else if (velocity > 0 && newtarget >= minExtent)
+                newtarget = minExtent + overshootDist;
+            if (newtarget == data.flickTarget) { // boundary unchanged - nothing to do
+                if (qAbs(velocity) < MinimumFlickVelocity)
+                    correctFlick = false;
+                return;
+            }
+            data.flickTarget = newtarget;
+            qreal dist = -newtarget + data.move.value();
+            if ((v < 0 && dist < 0) || (v > 0 && dist > 0)) {
+                correctFlick = false;
+                timeline.reset(data.move);
+                fixup(data, minExtent, maxExtent);
+                return;
+            }
+            timeline.reset(data.move);
+            timeline.accelDistance(data.move, v, -dist);
+            timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this));
+        }
+    } else {
+        correctFlick = false;
+        timeline.reset(data.move);
+        fixup(data, minExtent, maxExtent);
+    }
+}
+
+//----------------------------------------------------------------------------
+
+/*!
+    \qmlclass ListView QQuickListView
+    \inqmlmodule QtQuick 2
+    \ingroup qml-view-elements
+    \inherits Flickable
+    \brief The ListView item provides a list view of items provided by a model.
+
+    A ListView displays data from models created from built-in QML elements like ListModel
+    and XmlListModel, or custom model classes defined in C++ that inherit from
+    QAbstractListModel.
+
+    A ListView has a \l model, which defines the data to be displayed, and
+    a \l delegate, which defines how the data should be displayed. Items in a
+    ListView are laid out horizontally or vertically. List views are inherently
+    flickable because ListView inherits from \l Flickable.
+
+    \section1 Example Usage
+
+    The following example shows the definition of a simple list model defined
+    in a file called \c ContactModel.qml:
+
+    \snippet doc/src/snippets/declarative/listview/ContactModel.qml 0
+
+    Another component can display this model data in a ListView, like this:
+
+    \snippet doc/src/snippets/declarative/listview/listview.qml import
+    \codeline
+    \snippet doc/src/snippets/declarative/listview/listview.qml classdocs simple
+
+    \image listview-simple.png
+
+    Here, the ListView creates a \c ContactModel component for its model, and a \l Text element
+    for its delegate. The view will create a new \l Text component for each item in the model. Notice
+    the delegate is able to access the model's \c name and \c number data directly.
+
+    An improved list view is shown below. The delegate is visually improved and is moved
+    into a separate \c contactDelegate component.
+
+    \snippet doc/src/snippets/declarative/listview/listview.qml classdocs advanced
+    \image listview-highlight.png
+
+    The currently selected item is highlighted with a blue \l Rectangle using the \l highlight property,
+    and \c focus is set to \c true to enable keyboard navigation for the list view.
+    The list view itself is a focus scope (see \l{qmlfocus#Acquiring Focus and Focus Scopes}{the focus documentation page} for more details).
+
+    Delegates are instantiated as needed and may be destroyed at any time.
+    State should \e never be stored in a delegate.
+
+    ListView attaches a number of properties to the root item of the delegate, for example
+    \c {ListView.isCurrentItem}.  In the following example, the root delegate item can access
+    this attached property directly as \c ListView.isCurrentItem, while the child
+    \c contactInfo object must refer to this property as \c wrapper.ListView.isCurrentItem.
+
+    \snippet doc/src/snippets/declarative/listview/listview.qml isCurrentItem
+
+    \note Views do not enable \e clip automatically.  If the view
+    is not clipped by another item or the screen, it will be necessary
+    to set \e {clip: true} in order to have the out of view items clipped
+    nicely.
+
+    \sa {QML Data Models}, GridView, {declarative/modelviews/listview}{ListView examples}
+*/
+QQuickListView::QQuickListView(QQuickItem *parent)
+    : QQuickItemView(*(new QQuickListViewPrivate), parent)
+{
+}
+
+QQuickListView::~QQuickListView()
+{
+}
+
+/*!
+    \qmlattachedproperty bool QtQuick2::ListView::isCurrentItem
+    This attached property is true if this delegate is the current item; otherwise false.
+
+    It is attached to each instance of the delegate.
+
+    This property may be used to adjust the appearance of the current item, for example:
+
+    \snippet doc/src/snippets/declarative/listview/listview.qml isCurrentItem
+*/
+
+/*!
+    \qmlattachedproperty ListView QtQuick2::ListView::view
+    This attached property holds the view that manages this delegate instance.
+
+    It is attached to each instance of the delegate.
+*/
+
+/*!
+    \qmlattachedproperty string QtQuick2::ListView::previousSection
+    This attached property holds the section of the previous element.
+
+    It is attached to each instance of the delegate.
+
+    The section is evaluated using the \l {ListView::section.property}{section} properties.
+*/
+
+/*!
+    \qmlattachedproperty string QtQuick2::ListView::nextSection
+    This attached property holds the section of the next element.
+
+    It is attached to each instance of the delegate.
+
+    The section is evaluated using the \l {ListView::section.property}{section} properties.
+*/
+
+/*!
+    \qmlattachedproperty string QtQuick2::ListView::section
+    This attached property holds the section of this element.
+
+    It is attached to each instance of the delegate.
+
+    The section is evaluated using the \l {ListView::section.property}{section} properties.
+*/
+
+/*!
+    \qmlattachedproperty bool QtQuick2::ListView::delayRemove
+    This attached property holds whether the delegate may be destroyed.
+
+    It is attached to each instance of the delegate.
+
+    It is sometimes necessary to delay the destruction of an item
+    until an animation completes.
+
+    The example delegate below ensures that the animation completes before
+    the item is removed from the list.
+
+    \snippet doc/src/snippets/declarative/listview/listview.qml delayRemove
+*/
+
+/*!
+    \qmlattachedsignal QtQuick2::ListView::onAdd()
+    This attached handler is called immediately after an item is added to the view.
+*/
+
+/*!
+    \qmlattachedsignal QtQuick2::ListView::onRemove()
+    This attached handler is called immediately before an item is removed from the view.
+*/
+
+/*!
+    \qmlproperty model QtQuick2::ListView::model
+    This property holds the model providing data for the list.
+
+    The model provides the set of data that is used to create the items
+    in the view. Models can be created directly in QML using \l ListModel, \l XmlListModel
+    or \l VisualItemModel, or provided by C++ model classes. If a C++ model class is
+    used, it must be a subclass of \l QAbstractItemModel or a simple list.
+
+    \sa {qmlmodels}{Data Models}
+*/
+
+/*!
+    \qmlproperty Component QtQuick2::ListView::delegate
+
+    The delegate provides a template defining each item instantiated by the view.
+    The index is exposed as an accessible \c index property.  Properties of the
+    model are also available depending upon the type of \l {qmlmodels}{Data Model}.
+
+    The number of elements in the delegate has a direct effect on the
+    flicking performance of the view.  If at all possible, place functionality
+    that is not needed for the normal display of the delegate in a \l Loader which
+    can load additional elements when needed.
+
+    The ListView will lay out the items based on the size of the root item
+    in the delegate.
+
+    It is recommended that the delagate's size be a whole number to avoid sub-pixel
+    alignment of items.
+
+    \note Delegates are instantiated as needed and may be destroyed at any time.
+    State should \e never be stored in a delegate.
+*/
+/*!
+    \qmlproperty int QtQuick2::ListView::currentIndex
+    \qmlproperty Item QtQuick2::ListView::currentItem
+
+    The \c currentIndex property holds the index of the current item, and
+    \c currentItem holds the current item.   Setting the currentIndex to -1
+    will clear the highlight and set currentItem to null.
+
+    If highlightFollowsCurrentItem is \c true, setting either of these
+    properties will smoothly scroll the ListView so that the current
+    item becomes visible.
+
+    Note that the position of the current item
+    may only be approximate until it becomes visible in the view.
+*/
+
+/*!
+  \qmlproperty Item QtQuick2::ListView::highlightItem
+
+    This holds the highlight item created from the \l highlight component.
+
+  The \c highlightItem is managed by the view unless
+  \l highlightFollowsCurrentItem is set to false.
+
+  \sa highlight, highlightFollowsCurrentItem
+*/
+
+/*!
+  \qmlproperty int QtQuick2::ListView::count
+  This property holds the number of items in the view.
+*/
+
+/*!
+    \qmlproperty Component QtQuick2::ListView::highlight
+    This property holds the component to use as the highlight.
+
+    An instance of the highlight component is created for each list.
+    The geometry of the resulting component instance is managed by the list
+    so as to stay with the current item, unless the highlightFollowsCurrentItem
+    property is false.
+
+    \sa highlightItem, highlightFollowsCurrentItem, {declarative/modelviews/listview}{ListView examples}
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::ListView::highlightFollowsCurrentItem
+    This property holds whether the highlight is managed by the view.
+
+    If this property is true (the default value), the highlight is moved smoothly
+    to follow the current item.  Otherwise, the
+    highlight is not moved by the view, and any movement must be implemented
+    by the highlight.
+
+    Here is a highlight with its motion defined by a \l {SpringAnimation} item:
+
+    \snippet doc/src/snippets/declarative/listview/listview.qml highlightFollowsCurrentItem
+
+    Note that the highlight animation also affects the way that the view
+    is scrolled.  This is because the view moves to maintain the
+    highlight within the preferred highlight range (or visible viewport).
+
+    \sa highlight, highlightMoveSpeed
+*/
+//###Possibly rename these properties, since they are very useful even without a highlight?
+/*!
+    \qmlproperty real QtQuick2::ListView::preferredHighlightBegin
+    \qmlproperty real QtQuick2::ListView::preferredHighlightEnd
+    \qmlproperty enumeration QtQuick2::ListView::highlightRangeMode
+
+    These properties define the preferred range of the highlight (for the current item)
+    within the view. The \c preferredHighlightBegin value must be less than the
+    \c preferredHighlightEnd value.
+
+    These properties affect the position of the current item when the list is scrolled.
+    For example, if the currently selected item should stay in the middle of the
+    list when the view is scrolled, set the \c preferredHighlightBegin and
+    \c preferredHighlightEnd values to the top and bottom coordinates of where the middle
+    item would be. If the \c currentItem is changed programmatically, the list will
+    automatically scroll so that the current item is in the middle of the view.
+    Furthermore, the behavior of the current item index will occur whether or not a
+    highlight exists.
+
+    Valid values for \c highlightRangeMode are:
+
+    \list
+    \o ListView.ApplyRange - the view attempts to maintain the highlight within the range.
+       However, the highlight can move outside of the range at the ends of the list or due
+       to mouse interaction.
+    \o ListView.StrictlyEnforceRange - the highlight never moves outside of the range.
+       The current item changes if a keyboard or mouse action would cause the highlight to move
+       outside of the range.
+    \o ListView.NoHighlightRange - this is the default value.
+    \endlist
+*/
+void QQuickListView::setHighlightFollowsCurrentItem(bool autoHighlight)
+{
+    Q_D(QQuickListView);
+    if (d->autoHighlight != autoHighlight) {
+        if (!autoHighlight) {
+            if (d->highlightPosAnimator)
+                d->highlightPosAnimator->stop();
+            if (d->highlightSizeAnimator)
+                d->highlightSizeAnimator->stop();
+        }
+        QQuickItemView::setHighlightFollowsCurrentItem(autoHighlight);
+    }
+}
+
+/*!
+    \qmlproperty real QtQuick2::ListView::spacing
+
+    This property holds the spacing between items.
+
+    The default value is 0.
+*/
+qreal QQuickListView::spacing() const
+{
+    Q_D(const QQuickListView);
+    return d->spacing;
+}
+
+void QQuickListView::setSpacing(qreal spacing)
+{
+    Q_D(QQuickListView);
+    if (spacing != d->spacing) {
+        d->spacing = spacing;
+        d->forceLayout = true;
+        d->layout();
+        emit spacingChanged();
+    }
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::ListView::orientation
+    This property holds the orientation of the list.
+
+    Possible values:
+
+    \list
+    \o ListView.Horizontal - Items are laid out horizontally
+    \o ListView.Vertical (default) - Items are laid out vertically
+    \endlist
+
+    \table
+    \row
+    \o Horizontal orientation:
+    \image ListViewHorizontal.png
+
+    \row
+    \o Vertical orientation:
+    \image listview-highlight.png
+    \endtable
+*/
+QQuickListView::Orientation QQuickListView::orientation() const
+{
+    Q_D(const QQuickListView);
+    return d->orient;
+}
+
+void QQuickListView::setOrientation(QQuickListView::Orientation orientation)
+{
+    Q_D(QQuickListView);
+    if (d->orient != orientation) {
+        d->orient = orientation;
+        if (d->orient == Vertical) {
+            setContentWidth(-1);
+            setFlickableDirection(VerticalFlick);
+            setContentX(0);
+        } else {
+            setContentHeight(-1);
+            setFlickableDirection(HorizontalFlick);
+            setContentY(0);
+        }
+        d->regenerate();
+        emit orientationChanged();
+    }
+}
+
+/*!
+  \qmlproperty enumeration QtQuick2::ListView::layoutDirection
+  This property holds the layout direction of the horizontal list.
+
+  Possible values:
+
+  \list
+  \o Qt.LeftToRight (default) - Items will be laid out from left to right.
+  \o Qt.RightToLeft - Items will be laid out from right to let.
+  \endlist
+
+  \sa ListView::effectiveLayoutDirection
+*/
+
+
+/*!
+    \qmlproperty enumeration QtQuick2::ListView::effectiveLayoutDirection
+    This property holds the effective layout direction of the horizontal list.
+
+    When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} for locale layouts,
+    the visual layout direction of the horizontal list will be mirrored. However, the
+    property \l {ListView::layoutDirection}{layoutDirection} will remain unchanged.
+
+    \sa ListView::layoutDirection, {LayoutMirroring}{LayoutMirroring}
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::ListView::keyNavigationWraps
+    This property holds whether the list wraps key navigation.
+
+    If this is true, key navigation that would move the current item selection
+    past the end of the list instead wraps around and moves the selection to
+    the start of the list, and vice-versa.
+
+    By default, key navigation is not wrapped.
+*/
+
+
+/*!
+    \qmlproperty int QtQuick2::ListView::cacheBuffer
+    This property determines whether delegates are retained outside the
+    visible area of the view.
+
+    If this value is non-zero, the view keeps as many delegates
+    instantiated as it can fit within the buffer specified.  For example,
+    if in a vertical view the delegate is 20 pixels high and \c cacheBuffer is
+    set to 40, then up to 2 delegates above and 2 delegates below the visible
+    area may be retained.
+
+    Note that cacheBuffer is not a pixel buffer - it only maintains additional
+    instantiated delegates.
+
+    Setting this value can improve the smoothness of scrolling behavior at the expense
+    of additional memory usage.  It is not a substitute for creating efficient
+    delegates; the fewer elements in a delegate, the faster a view can be
+    scrolled.
+*/
+
+
+/*!
+    \qmlproperty string QtQuick2::ListView::section.property
+    \qmlproperty enumeration QtQuick2::ListView::section.criteria
+    \qmlproperty Component QtQuick2::ListView::section.delegate
+    \qmlproperty enumeration QtQuick2::ListView::section.labelPositioning
+
+    These properties determine the expression to be evaluated and appearance
+    of the section labels.
+
+    \c section.property holds the name of the property that is the basis
+    of each section.
+
+    \c section.criteria holds the criteria for forming each section based on
+    \c section.property. This value can be one of:
+
+    \list
+    \o ViewSection.FullString (default) - sections are created based on the
+    \c section.property value.
+    \o ViewSection.FirstCharacter - sections are created based on the first
+    character of the \c section.property value (for example, 'A', 'B', 'C'
+    sections, etc. for an address book)
+    \endlist
+
+    \c section.delegate holds the delegate component for each section.
+
+    \c section.labelPositioning determines whether the current and/or
+    next section labels stick to the start/end of the view, and whether
+    the labels are shown inline.  This value can be a combination of:
+
+    \list
+    \o ViewSection.InlineLabels - section labels are shown inline between
+    the item delegates separating sections (default).
+    \o ViewSection.CurrentLabelAtStart - the current section label sticks to the
+    start of the view as it is moved.
+    \o ViewSection.NextLabelAtEnd - the next section label (beyond all visible
+    sections) sticks to the end of the view as it is moved. \note Enabling
+    \c ViewSection.NextLabelAtEnd requires the view to scan ahead for the next
+    section, which has performance implications, especially for slower models.
+    \endlist
+
+    Each item in the list has attached properties named \c ListView.section,
+    \c ListView.previousSection and \c ListView.nextSection.
+
+    For example, here is a ListView that displays a list of animals, separated
+    into sections. Each item in the ListView is placed in a different section
+    depending on the "size" property of the model item. The \c sectionHeading
+    delegate component provides the light blue bar that marks the beginning of
+    each section.
+
+
+    \snippet examples/declarative/modelviews/listview/sections.qml 0
+
+    \image qml-listview-sections-example.png
+
+    \note Adding sections to a ListView does not automatically re-order the
+    list items by the section criteria.
+    If the model is not ordered by section, then it is possible that
+    the sections created will not be unique; each boundary between
+    differing sections will result in a section header being created
+    even if that section exists elsewhere.
+
+    \sa {declarative/modelviews/listview}{ListView examples}
+*/
+QQuickViewSection *QQuickListView::sectionCriteria()
+{
+    Q_D(QQuickListView);
+    if (!d->sectionCriteria) {
+        d->sectionCriteria = new QQuickViewSection(this);
+        connect(d->sectionCriteria, SIGNAL(propertyChanged()), this, SLOT(updateSections()));
+    }
+    return d->sectionCriteria;
+}
+
+/*!
+    \qmlproperty string QtQuick2::ListView::currentSection
+    This property holds the section that is currently at the beginning of the view.
+*/
+QString QQuickListView::currentSection() const
+{
+    Q_D(const QQuickListView);
+    return d->currentSection;
+}
+
+/*!
+    \qmlproperty real QtQuick2::ListView::highlightMoveSpeed
+    \qmlproperty int QtQuick2::ListView::highlightMoveDuration
+    \qmlproperty real QtQuick2::ListView::highlightResizeSpeed
+    \qmlproperty int QtQuick2::ListView::highlightResizeDuration
+
+    These properties hold the move and resize animation speed of the highlight delegate.
+
+    \l highlightFollowsCurrentItem must be true for these properties
+    to have effect.
+
+    The default value for the speed properties is 400 pixels/second.
+    The default value for the duration properties is -1, i.e. the
+    highlight will take as much time as necessary to move at the set speed.
+
+    These properties have the same characteristics as a SmoothedAnimation.
+
+    \sa highlightFollowsCurrentItem
+*/
+qreal QQuickListView::highlightMoveSpeed() const
+{
+    Q_D(const QQuickListView);
+    return d->highlightMoveSpeed;
+}
+
+void QQuickListView::setHighlightMoveSpeed(qreal speed)
+{
+    Q_D(QQuickListView);
+    if (d->highlightMoveSpeed != speed) {
+        d->highlightMoveSpeed = speed;
+        if (d->highlightPosAnimator)
+            d->highlightPosAnimator->velocity = d->highlightMoveSpeed;
+        emit highlightMoveSpeedChanged();
+    }
+}
+
+void QQuickListView::setHighlightMoveDuration(int duration)
+{
+    Q_D(QQuickListView);
+    if (d->highlightMoveDuration != duration) {
+        if (d->highlightPosAnimator)
+            d->highlightPosAnimator->userDuration = duration;
+        QQuickItemView::setHighlightMoveDuration(duration);
+    }
+}
+
+qreal QQuickListView::highlightResizeSpeed() const
+{
+    Q_D(const QQuickListView);
+    return d->highlightResizeSpeed;
+}
+
+void QQuickListView::setHighlightResizeSpeed(qreal speed)
+{
+    Q_D(QQuickListView);
+    if (d->highlightResizeSpeed != speed) {
+        d->highlightResizeSpeed = speed;
+        if (d->highlightSizeAnimator)
+            d->highlightSizeAnimator->velocity = d->highlightResizeSpeed;
+        emit highlightResizeSpeedChanged();
+    }
+}
+
+int QQuickListView::highlightResizeDuration() const
+{
+    Q_D(const QQuickListView);
+    return d->highlightResizeDuration;
+}
+
+void QQuickListView::setHighlightResizeDuration(int duration)
+{
+    Q_D(QQuickListView);
+    if (d->highlightResizeDuration != duration) {
+        d->highlightResizeDuration = duration;
+        if (d->highlightSizeAnimator)
+            d->highlightSizeAnimator->userDuration = d->highlightResizeDuration;
+        emit highlightResizeDurationChanged();
+    }
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::ListView::snapMode
+
+    This property determines how the view scrolling will settle following a drag or flick.
+    The possible values are:
+
+    \list
+    \o ListView.NoSnap (default) - the view stops anywhere within the visible area.
+    \o ListView.SnapToItem - the view settles with an item aligned with the start of
+    the view.
+    \o ListView.SnapOneItem - the view settles no more than one item away from the first
+    visible item at the time the mouse button is released.  This mode is particularly
+    useful for moving one page at a time.
+    \endlist
+
+    \c snapMode does not affect the \l currentIndex.  To update the
+    \l currentIndex as the list is moved, set \l highlightRangeMode
+    to \c ListView.StrictlyEnforceRange.
+
+    \sa highlightRangeMode
+*/
+QQuickListView::SnapMode QQuickListView::snapMode() const
+{
+    Q_D(const QQuickListView);
+    return d->snapMode;
+}
+
+void QQuickListView::setSnapMode(SnapMode mode)
+{
+    Q_D(QQuickListView);
+    if (d->snapMode != mode) {
+        d->snapMode = mode;
+        emit snapModeChanged();
+    }
+}
+
+
+/*!
+    \qmlproperty Component QtQuick2::ListView::footer
+    This property holds the component to use as the footer.
+
+    An instance of the footer component is created for each view.  The
+    footer is positioned at the end of the view, after any items.
+
+    \sa header
+*/
+
+
+/*!
+    \qmlproperty Component QtQuick2::ListView::header
+    This property holds the component to use as the header.
+
+    An instance of the header component is created for each view.  The
+    header is positioned at the beginning of the view, before any items.
+
+    \sa footer
+*/
+
+void QQuickListView::viewportMoved()
+{
+    Q_D(QQuickListView);
+    QQuickItemView::viewportMoved();
+    if (!d->itemCount)
+        return;
+    // Recursion can occur due to refill changing the content size.
+    if (d->inViewportMoved)
+        return;
+    d->inViewportMoved = true;
+    d->lazyRelease = true;
+    d->refill();
+    if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving)
+        d->moveReason = QQuickListViewPrivate::Mouse;
+    if (d->moveReason != QQuickListViewPrivate::SetIndex) {
+        if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) {
+            // reposition highlight
+            qreal pos = d->highlight->position();
+            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);
+            } else {
+                d->updateHighlight();
+            }
+
+            // update current index
+            if (FxViewItem *snapItem = d->snapItemAt(d->highlight->position())) {
+                if (snapItem->index >= 0 && snapItem->index != d->currentIndex)
+                    d->updateCurrent(snapItem->index);
+            }
+        }
+    }
+
+    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.
+        if (yflick() && !d->vData.inOvershoot) {
+            if (d->vData.velocity > 0) {
+                const qreal minY = minYExtent();
+                if ((minY - d->vData.move.value() < height()/2 || d->vData.flickTarget - d->vData.move.value() < height()/2)
+                    && minY != d->vData.flickTarget)
+                    d->flickY(-d->vData.smoothVelocity.value());
+                d->bufferMode = QQuickListViewPrivate::BufferBefore;
+            } else if (d->vData.velocity < 0) {
+                const qreal maxY = maxYExtent();
+                if ((d->vData.move.value() - maxY < height()/2 || d->vData.move.value() - d->vData.flickTarget < height()/2)
+                    && maxY != d->vData.flickTarget)
+                    d->flickY(-d->vData.smoothVelocity.value());
+                d->bufferMode = QQuickListViewPrivate::BufferAfter;
+            }
+        }
+
+        if (xflick() && !d->hData.inOvershoot) {
+            if (d->hData.velocity > 0) {
+                const qreal minX = minXExtent();
+                if ((minX - d->hData.move.value() < width()/2 || d->hData.flickTarget - d->hData.move.value() < width()/2)
+                    && minX != d->hData.flickTarget)
+                    d->flickX(-d->hData.smoothVelocity.value());
+                d->bufferMode = d->isRightToLeft() ? QQuickListViewPrivate::BufferAfter : QQuickListViewPrivate::BufferBefore;
+            } else if (d->hData.velocity < 0) {
+                const qreal maxX = maxXExtent();
+                if ((d->hData.move.value() - maxX < width()/2 || d->hData.move.value() - d->hData.flickTarget < width()/2)
+                    && maxX != d->hData.flickTarget)
+                    d->flickX(-d->hData.smoothVelocity.value());
+                d->bufferMode = d->isRightToLeft() ? QQuickListViewPrivate::BufferBefore : QQuickListViewPrivate::BufferAfter;
+            }
+        }
+        d->inFlickCorrection = false;
+    }
+    if (d->sectionCriteria) {
+        d->updateCurrentSection();
+        d->updateStickySections();
+    }
+    d->inViewportMoved = false;
+}
+
+void QQuickListView::keyPressEvent(QKeyEvent *event)
+{
+    Q_D(QQuickListView);
+    if (d->model && d->model->count() && d->interactive) {
+        if ((d->orient == QQuickListView::Horizontal && !d->isRightToLeft() && event->key() == Qt::Key_Left)
+                    || (d->orient == QQuickListView::Horizontal && d->isRightToLeft() && event->key() == Qt::Key_Right)
+                    || (d->orient == QQuickListView::Vertical && event->key() == Qt::Key_Up)) {
+            if (currentIndex() > 0 || (d->wrap && !event->isAutoRepeat())) {
+                decrementCurrentIndex();
+                event->accept();
+                return;
+            } else if (d->wrap) {
+                event->accept();
+                return;
+            }
+        } else if ((d->orient == QQuickListView::Horizontal && !d->isRightToLeft() && event->key() == Qt::Key_Right)
+                    || (d->orient == QQuickListView::Horizontal && d->isRightToLeft() && event->key() == Qt::Key_Left)
+                    || (d->orient == QQuickListView::Vertical && event->key() == Qt::Key_Down)) {
+            if (currentIndex() < d->model->count() - 1 || (d->wrap && !event->isAutoRepeat())) {
+                incrementCurrentIndex();
+                event->accept();
+                return;
+            } else if (d->wrap) {
+                event->accept();
+                return;
+            }
+        }
+    }
+    event->ignore();
+    QQuickItemView::keyPressEvent(event);
+}
+
+void QQuickListView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+    Q_D(QQuickListView);
+    if (d->isRightToLeft() && d->orient == QQuickListView::Horizontal) {
+        // maintain position relative to the right edge
+        int dx = newGeometry.width() - oldGeometry.width();
+        setContentX(contentX() - dx);
+    }
+    QQuickItemView::geometryChanged(newGeometry, oldGeometry);
+}
+
+
+/*!
+    \qmlmethod QtQuick2::ListView::incrementCurrentIndex()
+
+    Increments the current index.  The current index will wrap
+    if keyNavigationWraps is true and it is currently at the end.
+    This method has no effect if the \l count is zero.
+
+    \bold Note: methods should only be called after the Component has completed.
+*/
+void QQuickListView::incrementCurrentIndex()
+{
+    Q_D(QQuickListView);
+    int count = d->model ? d->model->count() : 0;
+    if (count && (currentIndex() < count - 1 || d->wrap)) {
+        d->moveReason = QQuickListViewPrivate::SetIndex;
+        int index = currentIndex()+1;
+        setCurrentIndex((index >= 0 && index < count) ? index : 0);
+    }
+}
+
+/*!
+    \qmlmethod QtQuick2::ListView::decrementCurrentIndex()
+
+    Decrements the current index.  The current index will wrap
+    if keyNavigationWraps is true and it is currently at the beginning.
+    This method has no effect if the \l count is zero.
+
+    \bold Note: methods should only be called after the Component has completed.
+*/
+void QQuickListView::decrementCurrentIndex()
+{
+    Q_D(QQuickListView);
+    int count = d->model ? d->model->count() : 0;
+    if (count && (currentIndex() > 0 || d->wrap)) {
+        d->moveReason = QQuickListViewPrivate::SetIndex;
+        int index = currentIndex()-1;
+        setCurrentIndex((index >= 0 && index < count) ? index : count-1);
+    }
+}
+
+void QQuickListView::updateSections()
+{
+    Q_D(QQuickListView);
+    if (isComponentComplete() && d->model) {
+        QList<QByteArray> roles;
+        if (d->sectionCriteria && !d->sectionCriteria->property().isEmpty())
+            roles << d->sectionCriteria->property().toUtf8();
+        d->model->setWatchedRoles(roles);
+        d->updateSections();
+        if (d->itemCount) {
+            d->forceLayout = true;
+            d->layout();
+        }
+    }
+}
+
+bool QQuickListViewPrivate::applyInsertionChange(const QDeclarativeChangeSet::Insert &change, FxViewItem *firstVisible, InsertionsResult *insertResult)
+{
+    Q_Q(QQuickListView);
+
+    int modelIndex = change.index;
+    int count = change.count;
+
+
+    qreal tempPos = isRightToLeft() ? -position()-size() : position();
+    int index = visibleItems.count() ? mapFromModel(modelIndex) : 0;
+
+    if (index < 0) {
+        int i = visibleItems.count() - 1;
+        while (i > 0 && visibleItems.at(i)->index == -1)
+            --i;
+        if (i == 0 && visibleItems.first()->index == -1) {
+            // there are no visible items except items marked for removal
+            index = visibleItems.count();
+        } else if (visibleItems.at(i)->index + 1 == modelIndex
+            && visibleItems.at(i)->endPosition() <= buffer+tempPos+size()) {
+            // Special case of appending an item to the model.
+            index = visibleItems.count();
+        } else {
+            if (modelIndex < visibleIndex) {
+                // Insert before visible items
+                visibleIndex += count;
+                for (int i = 0; i < visibleItems.count(); ++i) {
+                    FxViewItem *item = visibleItems.at(i);
+                    if (item->index != -1 && item->index >= modelIndex)
+                        item->index += count;
+                }
+            }
+            return true;
+        }
+    }
+
+    // index can be the next item past the end of the visible items list (i.e. appended)
+    int pos = 0;
+    if (visibleItems.count()) {
+        pos = index < visibleItems.count() ? visibleItems.at(index)->position()
+                                                : visibleItems.last()->endPosition()+spacing;
+    }
+
+    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; --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()) {
+                    insertResult->addedItems.append(item);
+                    insertResult->sizeAddedBeforeVisible += item->size();
+                }
+                pos -= item->size() + spacing;
+            }
+            index++;
+        }
+    } else {
+        int i = 0;
+        int to = buffer+tempPos+size();
+        for (i = 0; i < count && pos <= to; ++i) {
+            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);
+            pos += item->size() + spacing;
+            ++index;
+        }
+    }
+
+    for (; index < visibleItems.count(); ++index) {
+        FxViewItem *item = visibleItems.at(index);
+        if (item->index != -1)
+            item->index += count;
+    }
+
+    updateVisibleIndex();
+
+    return insertResult->addedItems.count() > prevAddedCount;
+}
+
+
+/*!
+    \qmlmethod QtQuick2::ListView::positionViewAtIndex(int index, PositionMode mode)
+
+    Positions the view such that the \a index is at the position specified by
+    \a mode:
+
+    \list
+    \o ListView.Beginning - position item at the top (or left for horizontal orientation) of the view.
+    \o ListView.Center - position item in the center of the view.
+    \o ListView.End - position item at bottom (or right for horizontal orientation) of the view.
+    \o ListView.Visible - if any part of the item is visible then take no action, otherwise
+    bring the item into view.
+    \o ListView.Contain - ensure the entire item is visible.  If the item is larger than
+    the view the item is positioned at the top (or left for horizontal orientation) of the view.
+    \endlist
+
+    If positioning the view at \a index would cause empty space to be displayed at
+    the beginning or end of the view, the view will be positioned at the boundary.
+
+    It is not recommended to use \l {Flickable::}{contentX} or \l {Flickable::}{contentY} to position the view
+    at a particular index.  This is unreliable since removing items from the start
+    of the list does not cause all other items to be repositioned, and because
+    the actual start of the view can vary based on the size of the delegates.
+    The correct way to bring an item into view is with \c positionViewAtIndex.
+
+    \bold Note: methods should only be called after the Component has completed.  To position
+    the view at startup, this method should be called by Component.onCompleted.  For
+    example, to position the view at the end:
+
+    \code
+    Component.onCompleted: positionViewAtIndex(count - 1, ListView.Beginning)
+    \endcode
+*/
+
+/*!
+    \qmlmethod QtQuick2::ListView::positionViewAtBeginning()
+    \qmlmethod QtQuick2::ListView::positionViewAtEnd()
+
+    Positions the view at the beginning or end, taking into account any header or footer.
+
+    It is not recommended to use \l {Flickable::}{contentX} or \l {Flickable::}{contentY} to position the view
+    at a particular index.  This is unreliable since removing items from the start
+    of the list does not cause all other items to be repositioned, and because
+    the actual start of the view can vary based on the size of the delegates.
+
+    \bold Note: methods should only be called after the Component has completed.  To position
+    the view at startup, this method should be called by Component.onCompleted.  For
+    example, to position the view at the end on startup:
+
+    \code
+    Component.onCompleted: positionViewAtEnd()
+    \endcode
+*/
+
+/*!
+    \qmlmethod int QtQuick2::ListView::indexAt(int x, int y)
+
+    Returns the index of the visible item containing the point \a x, \a y in content
+    coordinates.  If there is no item at the point specified, or the item is
+    not visible -1 is returned.
+
+    If the item is outside the visible area, -1 is returned, regardless of
+    whether an item will exist at that point when scrolled into view.
+
+    \bold Note: methods should only be called after the Component has completed.
+*/
+
+QQuickListViewAttached *QQuickListView::qmlAttachedProperties(QObject *obj)
+{
+    return new QQuickListViewAttached(obj);
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquicklistview_p.h b/src/declarative/items/qquicklistview_p.h
new file mode 100644 (file)
index 0000000..0266e23
--- /dev/null
@@ -0,0 +1,215 @@
+// Commit: 95814418f9d6adeba365c795462e8afb00138211
+/****************************************************************************
+**
+** 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 QQUICKLISTVIEW_P_H
+#define QQUICKLISTVIEW_P_H
+
+#include "qquickitemview_p.h"
+
+#include <private/qdeclarativeguard_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickListView;
+class QQuickListViewPrivate;
+class Q_AUTOTEST_EXPORT QQuickViewSection : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(QString property READ property WRITE setProperty NOTIFY propertyChanged)
+    Q_PROPERTY(SectionCriteria criteria READ criteria WRITE setCriteria NOTIFY criteriaChanged)
+    Q_PROPERTY(QDeclarativeComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
+    Q_PROPERTY(int labelPositioning READ labelPositioning WRITE setLabelPositioning NOTIFY labelPositioningChanged)
+    Q_ENUMS(SectionCriteria)
+    Q_ENUMS(LabelPositioning)
+public:
+    QQuickViewSection(QQuickListView *parent=0);
+
+    QString property() const { return m_property; }
+    void setProperty(const QString &);
+
+    enum SectionCriteria { FullString, FirstCharacter };
+    SectionCriteria criteria() const { return m_criteria; }
+    void setCriteria(SectionCriteria);
+
+    QDeclarativeComponent *delegate() const { return m_delegate; }
+    void setDelegate(QDeclarativeComponent *delegate);
+
+    QString sectionString(const QString &value);
+
+    enum LabelPositioning { InlineLabels = 0x01, CurrentLabelAtStart = 0x02, NextLabelAtEnd = 0x04 };
+    int labelPositioning() { return m_labelPositioning; }
+    void setLabelPositioning(int pos);
+
+Q_SIGNALS:
+    void propertyChanged();
+    void criteriaChanged();
+    void delegateChanged();
+    void labelPositioningChanged();
+
+private:
+    QString m_property;
+    SectionCriteria m_criteria;
+    QDeclarativeComponent *m_delegate;
+    int m_labelPositioning;
+    QQuickListViewPrivate *m_view;
+};
+
+
+class QQuickVisualModel;
+class QQuickListViewAttached;
+class Q_AUTOTEST_EXPORT QQuickListView : public QQuickItemView
+{
+    Q_OBJECT
+    Q_DECLARE_PRIVATE(QQuickListView)
+
+    // XXX deprecate these two properties (only duration should be necessary)
+    Q_PROPERTY(qreal highlightMoveSpeed READ highlightMoveSpeed WRITE setHighlightMoveSpeed NOTIFY highlightMoveSpeedChanged)
+    Q_PROPERTY(qreal highlightResizeSpeed READ highlightResizeSpeed WRITE setHighlightResizeSpeed NOTIFY highlightResizeSpeedChanged)
+
+    Q_PROPERTY(int highlightResizeDuration READ highlightResizeDuration WRITE setHighlightResizeDuration NOTIFY highlightResizeDurationChanged)
+
+    Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged)
+    Q_PROPERTY(Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged)
+
+    Q_PROPERTY(QQuickViewSection *section READ sectionCriteria CONSTANT)
+    Q_PROPERTY(QString currentSection READ currentSection NOTIFY currentSectionChanged)
+
+    Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged)
+
+    Q_ENUMS(Orientation)
+    Q_ENUMS(SnapMode)
+    Q_CLASSINFO("DefaultProperty", "data")
+
+public:
+    QQuickListView(QQuickItem *parent=0);
+    ~QQuickListView();
+
+    qreal spacing() const;
+    void setSpacing(qreal spacing);
+
+    enum Orientation { Horizontal = Qt::Horizontal, Vertical = Qt::Vertical };
+    Orientation orientation() const;
+    void setOrientation(Orientation);
+
+    QQuickViewSection *sectionCriteria();
+    QString currentSection() const;
+
+    virtual void setHighlightFollowsCurrentItem(bool);
+
+    qreal highlightMoveSpeed() const;
+    void setHighlightMoveSpeed(qreal);
+
+    qreal highlightResizeSpeed() const;
+    void setHighlightResizeSpeed(qreal);
+
+    int highlightResizeDuration() const;
+    void setHighlightResizeDuration(int);
+
+    virtual void setHighlightMoveDuration(int);
+
+    enum SnapMode { NoSnap, SnapToItem, SnapOneItem };
+    SnapMode snapMode() const;
+    void setSnapMode(SnapMode mode);
+
+    static QQuickListViewAttached *qmlAttachedProperties(QObject *);
+
+public Q_SLOTS:
+    void incrementCurrentIndex();
+    void decrementCurrentIndex();
+
+Q_SIGNALS:
+    void spacingChanged();
+    void orientationChanged();
+    void currentSectionChanged();
+    void highlightMoveSpeedChanged();
+    void highlightResizeSpeedChanged();
+    void highlightResizeDurationChanged();
+    void snapModeChanged();
+
+protected:
+    virtual void viewportMoved();
+    virtual void keyPressEvent(QKeyEvent *);
+    virtual void geometryChanged(const QRectF &newGeometry,const QRectF &oldGeometry);
+
+protected Q_SLOTS:
+    void updateSections();
+};
+
+class QQuickListViewAttached : public QQuickItemViewAttached
+{
+    Q_OBJECT
+
+public:
+    QQuickListViewAttached(QObject *parent)
+        : QQuickItemViewAttached(parent), m_view(0) {}
+    ~QQuickListViewAttached() {}
+
+    Q_PROPERTY(QQuickListView *view READ view NOTIFY viewChanged)
+    QQuickListView *view() { return m_view; }
+    void setView(QQuickListView *view) {
+        if (view != m_view) {
+            m_view = view;
+            emit viewChanged();
+        }
+    }
+
+Q_SIGNALS:
+    void viewChanged();
+
+public:
+    QDeclarativeGuard<QQuickListView> m_view;
+};
+
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPEINFO(QQuickListView, QML_HAS_ATTACHED_PROPERTIES)
+QML_DECLARE_TYPE(QQuickListView)
+QML_DECLARE_TYPE(QQuickViewSection)
+
+QT_END_HEADER
+
+#endif // QQUICKLISTVIEW_P_H
diff --git a/src/declarative/items/qquickloader.cpp b/src/declarative/items/qquickloader.cpp
new file mode 100644 (file)
index 0000000..cef98a6
--- /dev/null
@@ -0,0 +1,853 @@
+/****************************************************************************
+**
+** 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 "qquickloader_p_p.h"
+
+#include <QtDeclarative/qdeclarativeinfo.h>
+
+#include <private/qdeclarativeengine_p.h>
+#include <private/qdeclarativeglobal_p.h>
+
+#include <private/qdeclarativecomponent_p.h>
+
+#include <private/qv8_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QQuickLoaderPrivate::QQuickLoaderPrivate()
+    : item(0), component(0), itemContext(0), incubator(0), updatingSize(false),
+      itemWidthValid(false), itemHeightValid(false),
+      active(true), loadingFromSource(false), asynchronous(false)
+{
+}
+
+QQuickLoaderPrivate::~QQuickLoaderPrivate()
+{
+    delete incubator;
+    disposeInitialPropertyValues();
+}
+
+void QQuickLoaderPrivate::itemGeometryChanged(QQuickItem *resizeItem, const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+    if (resizeItem == item) {
+        if (!updatingSize && newGeometry.width() != oldGeometry.width())
+            itemWidthValid = true;
+        if (!updatingSize && newGeometry.height() != oldGeometry.height())
+            itemHeightValid = true;
+        _q_updateSize(false);
+    }
+    QQuickItemChangeListener::itemGeometryChanged(resizeItem, newGeometry, oldGeometry);
+}
+
+void QQuickLoaderPrivate::clear()
+{
+    disposeInitialPropertyValues();
+
+    if (incubator)
+        incubator->clear();
+
+    if (loadingFromSource && component) {
+        component->deleteLater();
+        component = 0;
+    }
+    source = QUrl();
+
+    if (item) {
+        QQuickItemPrivate *p = QQuickItemPrivate::get(item);
+        p->removeItemChangeListener(this, QQuickItemPrivate::Geometry);
+
+        // We can't delete immediately because our item may have triggered
+        // the Loader to load a different item.
+        item->setParentItem(0);
+        item->setVisible(false);
+        item->deleteLater();
+        item = 0;
+    }
+}
+
+void QQuickLoaderPrivate::initResize()
+{
+    QQuickItemPrivate *p = QQuickItemPrivate::get(item);
+    p->addItemChangeListener(this, QQuickItemPrivate::Geometry);
+    // We may override the item's size, so we need to remember
+    // whether the item provided its own valid size.
+    itemWidthValid = p->widthValid;
+    itemHeightValid = p->heightValid;
+    _q_updateSize();
+}
+
+/*!
+    \qmlclass Loader QQuickLoader
+    \inqmlmodule QtQuick 2
+    \ingroup qml-utility-elements
+    \inherits Item
+
+    \brief The Loader item allows dynamically loading an Item-based
+    subtree from a URL or Component.
+
+    Loader is used to dynamically load visual QML components. It can load a
+    QML file (using the \l source property) or a \l Component object (using
+    the \l sourceComponent property). It is useful for delaying the creation
+    of a component until it is required: for example, when a component should
+    be created on demand, or when a component should not be created
+    unnecessarily for performance reasons.
+
+    Here is a Loader that loads "Page1.qml" as a component when the
+    \l MouseArea is clicked:
+
+    \snippet doc/src/snippets/declarative/loader/simple.qml 0
+
+    The loaded item can be accessed using the \l item property.
+
+    If the \l source or \l sourceComponent changes, any previously instantiated
+    items are destroyed. Setting \l source to an empty string or setting
+    \l sourceComponent to \c undefined destroys the currently loaded item,
+    freeing resources and leaving the Loader empty.
+
+    \section2 Loader sizing behavior
+
+    Loader is like any other visual item and must be positioned and sized
+    accordingly to become visible.
+
+    \list
+    \o If an explicit size is not specified for the Loader, the Loader
+    is automatically resized to the size of the loaded item once the
+    component is loaded.
+    \o If the size of the Loader is specified explicitly by setting
+    the width, height or by anchoring, the loaded item will be resized
+    to the size of the Loader.
+    \endlist
+
+    In both scenarios the size of the item and the Loader are identical.
+    This ensures that anchoring to the Loader is equivalent to anchoring
+    to the loaded item.
+
+    \table
+    \row
+    \o sizeloader.qml
+    \o sizeitem.qml
+    \row
+    \o \snippet doc/src/snippets/declarative/loader/sizeloader.qml 0
+    \o \snippet doc/src/snippets/declarative/loader/sizeitem.qml 0
+    \row
+    \o The red rectangle will be sized to the size of the root item.
+    \o The red rectangle will be 50x50, centered in the root item.
+    \endtable
+
+
+    \section2 Receiving signals from loaded items
+
+    Any signals emitted from the loaded item can be received using the
+    \l Connections element. For example, the following \c application.qml
+    loads \c MyItem.qml, and is able to receive the \c message signal from
+    the loaded item through a \l Connections object:
+
+    \table
+    \row
+    \o application.qml
+    \o MyItem.qml
+    \row
+    \o \snippet doc/src/snippets/declarative/loader/connections.qml 0
+    \o \snippet doc/src/snippets/declarative/loader/MyItem.qml 0
+    \endtable
+
+    Alternatively, since \c MyItem.qml is loaded within the scope of the
+    Loader, it could also directly call any function defined in the Loader or
+    its parent \l Item.
+
+
+    \section2 Focus and key events
+
+    Loader is a focus scope. Its \l {Item::}{focus} property must be set to
+    \c true for any of its children to get the \e {active focus}. (See
+    \l{qmlfocus#Acquiring Focus and Focus Scopes}{the focus documentation page}
+    for more details.) Any key events received in the loaded item should likely
+    also be \l {KeyEvent::}{accepted} so they are not propagated to the Loader.
+
+    For example, the following \c application.qml loads \c KeyReader.qml when
+    the \l MouseArea is clicked.  Notice the \l {Item::}{focus} property is
+    set to \c true for the Loader as well as the \l Item in the dynamically
+    loaded object:
+
+    \table
+    \row
+    \o application.qml
+    \o KeyReader.qml
+    \row
+    \o \snippet doc/src/snippets/declarative/loader/focus.qml 0
+    \o \snippet doc/src/snippets/declarative/loader/KeyReader.qml 0
+    \endtable
+
+    Once \c KeyReader.qml is loaded, it accepts key events and sets
+    \c event.accepted to \c true so that the event is not propagated to the
+    parent \l Rectangle.
+
+    \sa {dynamic-object-creation}{Dynamic Object Creation}
+*/
+
+QQuickLoader::QQuickLoader(QQuickItem *parent)
+  : QQuickImplicitSizeItem(*(new QQuickLoaderPrivate), parent)
+{
+    setFlag(ItemIsFocusScope);
+}
+
+QQuickLoader::~QQuickLoader()
+{
+    Q_D(QQuickLoader);
+    if (d->item) {
+        QQuickItemPrivate *p = QQuickItemPrivate::get(d->item);
+        p->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
+    }
+}
+
+/*!
+    \qmlproperty bool QtQuick2::Loader::active
+    This property is \c true if the Loader is currently active.
+    The default value for the \l active property is \c true.
+
+    If the Loader is inactive, changing the \l source or \l sourceComponent
+    will not cause the item to be instantiated until the Loader is made active.
+
+    Setting the value to inactive will cause any \l item loaded by the loader
+    to be released, but will not affect the \l source or \l sourceComponent.
+
+    The \l status of an inactive loader is always \c Null.
+
+    \sa source, sourceComponent
+ */
+bool QQuickLoader::active() const
+{
+    Q_D(const QQuickLoader);
+    return d->active;
+}
+
+void QQuickLoader::setActive(bool newVal)
+{
+    Q_D(QQuickLoader);
+    if (d->active != newVal) {
+        d->active = newVal;
+        if (newVal == true) {
+            if (d->loadingFromSource) {
+                loadFromSource();
+            } else {
+                loadFromSourceComponent();
+            }
+        } else {
+            if (d->item) {
+                QQuickItemPrivate *p = QQuickItemPrivate::get(d->item);
+                p->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
+
+                // We can't delete immediately because our item may have triggered
+                // the Loader to load a different item.
+                d->item->setParentItem(0);
+                d->item->setVisible(false);
+                d->item->deleteLater();
+                d->item = 0;
+                emit itemChanged();
+            }
+            emit statusChanged();
+        }
+        emit activeChanged();
+    }
+}
+
+
+/*!
+    \qmlproperty url QtQuick2::Loader::source
+    This property holds the URL of the QML component to instantiate.
+
+    Note the QML component must be an \l{Item}-based component. The loader
+    cannot load non-visual components.
+
+    To unload the currently loaded item, set this property to an empty string,
+    or set \l sourceComponent to \c undefined. Setting \c source to a
+    new URL will also cause the item created by the previous URL to be unloaded.
+
+    \sa sourceComponent, status, progress
+*/
+QUrl QQuickLoader::source() const
+{
+    Q_D(const QQuickLoader);
+    return d->source;
+}
+
+void QQuickLoader::setSource(const QUrl &url)
+{
+    setSource(url, true); // clear previous values
+}
+
+void QQuickLoader::setSource(const QUrl &url, bool needsClear)
+{
+    Q_D(QQuickLoader);
+    if (d->source == url)
+        return;
+
+    if (needsClear)
+        d->clear();
+
+    d->source = url;
+    d->loadingFromSource = true;
+
+    if (d->active)
+        loadFromSource();
+    else
+        emit sourceChanged();
+}
+
+void QQuickLoader::loadFromSource()
+{
+    Q_D(QQuickLoader);
+    if (d->source.isEmpty()) {
+        emit sourceChanged();
+        emit statusChanged();
+        emit progressChanged();
+        emit itemChanged();
+        return;
+    }
+
+    if (isComponentComplete()) {
+        d->component = new QDeclarativeComponent(qmlEngine(this), d->source, this);
+        d->load();
+    }
+}
+
+/*!
+    \qmlproperty Component QtQuick2::Loader::sourceComponent
+    This property holds the \l{Component} to instantiate.
+
+    \qml
+    Item {
+        Component {
+            id: redSquare
+            Rectangle { color: "red"; width: 10; height: 10 }
+        }
+
+        Loader { sourceComponent: redSquare }
+        Loader { sourceComponent: redSquare; x: 10 }
+    }
+    \endqml
+
+    To unload the currently loaded item, set this property to an empty string
+    or \c undefined.
+
+    \sa source, progress
+*/
+
+QDeclarativeComponent *QQuickLoader::sourceComponent() const
+{
+    Q_D(const QQuickLoader);
+    return d->component;
+}
+
+void QQuickLoader::setSourceComponent(QDeclarativeComponent *comp)
+{
+    Q_D(QQuickLoader);
+    if (comp == d->component)
+        return;
+
+    d->clear();
+
+    d->component = comp;
+    d->loadingFromSource = false;
+
+    if (d->active)
+        loadFromSourceComponent();
+    else
+        emit sourceComponentChanged();
+}
+
+void QQuickLoader::resetSourceComponent()
+{
+    setSourceComponent(0);
+}
+
+void QQuickLoader::loadFromSourceComponent()
+{
+    Q_D(QQuickLoader);
+    if (!d->component) {
+        emit sourceComponentChanged();
+        emit statusChanged();
+        emit progressChanged();
+        emit itemChanged();
+        return;
+    }
+
+    if (isComponentComplete())
+        d->load();
+}
+
+/*!
+    \qmlmethod object QtQuick2::Loader::setSource(url source, object properties)
+
+    Creates an object instance of the given \a source component that will have
+    the given \a properties. The \a properties argument is optional.  The instance
+    will be accessible via the \l item property once loading and instantiation
+    is complete.
+
+    If the \l active property is \c false at the time when this function is called,
+    the given \a source component will not be loaded but the \a source and initial
+    \a properties will be cached.  When the loader is made \l active, an instance of
+    the \a source component will be created with the initial \a properties set.
+
+    Setting the initial property values of an instance of a component in this manner
+    will \e not trigger any associated \l{Behavior}s.
+
+    Note that the cached \a properties will be cleared if the \l source or \l sourceComponent
+    is changed after calling this function but prior to setting the loader \l active.
+
+    Example:
+    \table
+    \row
+    \o
+    \qml
+    // ExampleComponent.qml
+    import QtQuick 2.0
+    Rectangle {
+        id: rect
+        color: "red"
+        width: 10
+        height: 10
+
+        Behavior on color {
+            NumberAnimation {
+                target: rect
+                property: "width"
+                to: (rect.width + 20)
+                duration: 0
+            }
+        }
+    }
+    \endqml
+    \o
+    \qml
+    // example.qml
+    import QtQuick 2.0
+    Item {
+        Loader {
+            id: squareLoader
+            onLoaded: console.log(squareLoader.item.width); // prints [10], not [30]
+        }
+
+        Component.onCompleted: {
+            squareLoader.setSource("ExampleComponent.qml", { "color": "blue" });
+            // will trigger the onLoaded code when complete.
+        }
+    }
+    \endqml
+    \endtable
+
+    \sa source, active
+*/
+void QQuickLoader::setSource(QDeclarativeV8Function *args)
+{
+    Q_ASSERT(args);
+    Q_D(QQuickLoader);
+
+    bool ipvError = false;
+    args->returnValue(v8::Undefined());
+    v8::Handle<v8::Object> ipv = d->extractInitialPropertyValues(args, this, &ipvError);
+    if (ipvError)
+        return;
+
+    d->clear();
+    QUrl sourceUrl = d->resolveSourceUrl(args);
+    if (!ipv.IsEmpty()) {
+        d->disposeInitialPropertyValues();
+        d->initialPropertyValues = qPersistentNew(ipv);
+        d->qmlGlobalForIpv = qPersistentNew(args->qmlGlobal());
+    }
+
+    setSource(sourceUrl, false); // already cleared and set ipv above.
+}
+
+void QQuickLoaderPrivate::disposeInitialPropertyValues()
+{
+    if (!initialPropertyValues.IsEmpty())
+        qPersistentDispose(initialPropertyValues);
+    if (!qmlGlobalForIpv.IsEmpty())
+        qPersistentDispose(qmlGlobalForIpv);
+}
+
+void QQuickLoaderPrivate::load()
+{
+    Q_Q(QQuickLoader);
+
+    if (!q->isComponentComplete() || !component)
+        return;
+
+    if (!component->isLoading()) {
+        _q_sourceLoaded();
+    } else {
+        QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)),
+                q, SLOT(_q_sourceLoaded()));
+        QObject::connect(component, SIGNAL(progressChanged(qreal)),
+                q, SIGNAL(progressChanged()));
+        emit q->statusChanged();
+        emit q->progressChanged();
+        if (loadingFromSource)
+            emit q->sourceChanged();
+        else
+            emit q->sourceComponentChanged();
+        emit q->itemChanged();
+    }
+}
+
+void QQuickLoaderIncubator::setInitialState(QObject *o)
+{
+    loader->setInitialState(o);
+}
+
+void QQuickLoaderPrivate::setInitialState(QObject *obj)
+{
+    Q_Q(QQuickLoader);
+
+    QQuickItem *item = qobject_cast<QQuickItem*>(obj);
+    if (item) {
+        QDeclarative_setParent_noEvent(itemContext, obj);
+        QDeclarative_setParent_noEvent(item, q);
+        item->setParentItem(q);
+    }
+
+    if (initialPropertyValues.IsEmpty())
+        return;
+
+    QDeclarativeComponentPrivate *d = QDeclarativeComponentPrivate::get(component);
+    Q_ASSERT(d && d->engine);
+    d->initializeObjectWithInitialProperties(qmlGlobalForIpv, initialPropertyValues, obj);
+}
+
+void QQuickLoaderIncubator::statusChanged(Status status)
+{
+    loader->incubatorStateChanged(status);
+}
+
+void QQuickLoaderPrivate::incubatorStateChanged(QDeclarativeIncubator::Status status)
+{
+    Q_Q(QQuickLoader);
+    if (status == QDeclarativeIncubator::Loading || status == QDeclarativeIncubator::Null)
+        return;
+
+    if (status == QDeclarativeIncubator::Ready) {
+        QObject *obj = incubator->object();
+        item = qobject_cast<QQuickItem*>(obj);
+        if (item) {
+            initResize();
+        } else {
+            qmlInfo(q) << QQuickLoader::tr("Loader does not support loading non-visual elements.");
+            delete itemContext;
+            itemContext = 0;
+            delete obj;
+        }
+    } 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 QQuickLoaderPrivate::_q_sourceLoaded()
+{
+    Q_Q(QQuickLoader);
+    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();
+        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 QQuickLoaderIncubator(this, asynchronous ? QDeclarativeIncubator::Asynchronous : QDeclarativeIncubator::AsynchronousIfNested);
+
+    component->create(*incubator, itemContext);
+
+    if (incubator->status() == QDeclarativeIncubator::Loading)
+        emit q->statusChanged();
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::Loader::status
+
+    This property holds the status of QML loading.  It can be one of:
+    \list
+    \o Loader.Null - the loader is inactive or no QML source has been set
+    \o Loader.Ready - the QML source has been loaded
+    \o Loader.Loading - the QML source is currently being loaded
+    \o Loader.Error - an error occurred while loading the QML source
+    \endlist
+
+    Use this status to provide an update or respond to the status change in some way.
+    For example, you could:
+
+    \list
+    \o Trigger a state change:
+    \qml
+        State { name: 'loaded'; when: loader.status == Loader.Ready }
+    \endqml
+
+    \o Implement an \c onStatusChanged signal handler:
+    \qml
+        Loader {
+            id: loader
+            onStatusChanged: if (loader.status == Loader.Ready) console.log('Loaded')
+        }
+    \endqml
+
+    \o Bind to the status value:
+    \qml
+        Text { text: loader.status == Loader.Ready ? 'Loaded' : 'Not loaded' }
+    \endqml
+    \endlist
+
+    Note that if the source is a local file, the status will initially be Ready (or Error). While
+    there will be no onStatusChanged signal in that case, the onLoaded will still be invoked.
+
+    \sa progress
+*/
+
+QQuickLoader::Status QQuickLoader::status() const
+{
+    Q_D(const QQuickLoader);
+
+    if (!d->active)
+        return Null;
+
+    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;
+
+    return d->source.isEmpty() ? Null : Error;
+}
+
+void QQuickLoader::componentComplete()
+{
+    Q_D(QQuickLoader);
+    QQuickItem::componentComplete();
+    if (active()) {
+        if (d->loadingFromSource) {
+            d->component = new QDeclarativeComponent(qmlEngine(this), d->source, this);
+        }
+        d->load();
+    }
+}
+
+/*!
+    \qmlsignal QtQuick2::Loader::onLoaded()
+
+    This handler is called when the \l status becomes \c Loader.Ready, or on successful
+    initial load.
+*/
+
+
+/*!
+\qmlproperty real QtQuick2::Loader::progress
+
+This property holds the progress of loading QML data from the network, from
+0.0 (nothing loaded) to 1.0 (finished).  Most QML files are quite small, so
+this value will rapidly change from 0 to 1.
+
+\sa status
+*/
+qreal QQuickLoader::progress() const
+{
+    Q_D(const QQuickLoader);
+
+    if (d->item)
+        return 1.0;
+
+    if (d->component)
+        return d->component->progress();
+
+    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 QQuickLoader::asynchronous() const
+{
+    Q_D(const QQuickLoader);
+    return d->asynchronous;
+}
+
+void QQuickLoader::setAsynchronous(bool a)
+{
+    Q_D(QQuickLoader);
+    if (d->asynchronous == a)
+        return;
+
+    d->asynchronous = a;
+    emit asynchronousChanged();
+}
+
+void QQuickLoaderPrivate::_q_updateSize(bool loaderGeometryChanged)
+{
+    Q_Q(QQuickLoader);
+    if (!item || updatingSize)
+        return;
+
+    updatingSize = true;
+
+    if (!itemWidthValid)
+        q->setImplicitWidth(item->implicitWidth());
+    else
+        q->setImplicitWidth(item->width());
+    if (loaderGeometryChanged && q->widthValid())
+        item->setWidth(q->width());
+
+    if (!itemHeightValid)
+        q->setImplicitHeight(item->implicitHeight());
+    else
+        q->setImplicitHeight(item->height());
+    if (loaderGeometryChanged && q->heightValid())
+        item->setHeight(q->height());
+
+    updatingSize = false;
+}
+
+/*!
+    \qmlproperty Item QtQuick2::Loader::item
+    This property holds the top-level item that is currently loaded.
+*/
+QQuickItem *QQuickLoader::item() const
+{
+    Q_D(const QQuickLoader);
+    return d->item;
+}
+
+void QQuickLoader::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+    Q_D(QQuickLoader);
+    if (newGeometry != oldGeometry) {
+        d->_q_updateSize();
+    }
+    QQuickItem::geometryChanged(newGeometry, oldGeometry);
+}
+
+QUrl QQuickLoaderPrivate::resolveSourceUrl(QDeclarativeV8Function *args)
+{
+    QV8Engine *v8engine = args->engine();
+    QString arg = v8engine->toString((*args)[0]->ToString());
+    if (arg.isEmpty())
+        return QUrl();
+
+    QDeclarativeContextData *context = args->context();
+    Q_ASSERT(context);
+    return context->resolvedUrl(QUrl(arg));
+}
+
+v8::Handle<v8::Object> QQuickLoaderPrivate::extractInitialPropertyValues(QDeclarativeV8Function *args, QObject *loader, bool *error)
+{
+    v8::Local<v8::Object> valuemap;
+    if (args->Length() >= 2) {
+        v8::Local<v8::Value> v = (*args)[1];
+        if (!v->IsObject() || v->IsArray()) {
+            *error = true;
+            qmlInfo(loader) << loader->tr("setSource: value is not an object");
+        } else {
+            *error = false;
+            valuemap = v8::Local<v8::Object>::Cast(v);
+        }
+    }
+
+    return valuemap;
+}
+
+#include <moc_qquickloader_p.cpp>
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickloader_p.h b/src/declarative/items/qquickloader_p.h
new file mode 100644 (file)
index 0000000..3dcab4c
--- /dev/null
@@ -0,0 +1,123 @@
+// Commit: 6f78a6080b84cc3ef96b73a4ff58d1b5a72f08f4
+/****************************************************************************
+**
+** 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 QQUICKLOADER_P_H
+#define QQUICKLOADER_P_H
+
+#include "qquickimplicitsizeitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickLoaderPrivate;
+class Q_AUTOTEST_EXPORT QQuickLoader : public QQuickImplicitSizeItem
+{
+    Q_OBJECT
+    Q_ENUMS(Status)
+
+    Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
+    Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+    Q_PROPERTY(QDeclarativeComponent *sourceComponent READ sourceComponent WRITE setSourceComponent RESET resetSourceComponent NOTIFY sourceComponentChanged)
+    Q_PROPERTY(QQuickItem *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:
+    QQuickLoader(QQuickItem *parent = 0);
+    virtual ~QQuickLoader();
+
+    bool active() const;
+    void setActive(bool newVal);
+
+    Q_INVOKABLE void setSource(QDeclarativeV8Function *);
+
+    QUrl source() const;
+    void setSource(const QUrl &);
+
+    QDeclarativeComponent *sourceComponent() const;
+    void setSourceComponent(QDeclarativeComponent *);
+    void resetSourceComponent();
+
+    enum Status { Null, Ready, Loading, Error };
+    Status status() const;
+    qreal progress() const;
+
+    bool asynchronous() const;
+    void setAsynchronous(bool a);
+
+    QQuickItem *item() const;
+
+Q_SIGNALS:
+    void itemChanged();
+    void activeChanged();
+    void sourceChanged();
+    void sourceComponentChanged();
+    void statusChanged();
+    void progressChanged();
+    void loaded();
+    void asynchronousChanged();
+
+protected:
+    void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
+    void componentComplete();
+
+private:
+    void setSource(const QUrl &sourceUrl, bool needsClear);
+    void loadFromSource();
+    void loadFromSourceComponent();
+    Q_DISABLE_COPY(QQuickLoader)
+    Q_DECLARE_PRIVATE(QQuickLoader)
+    Q_PRIVATE_SLOT(d_func(), void _q_sourceLoaded())
+    Q_PRIVATE_SLOT(d_func(), void _q_updateSize())
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickLoader)
+
+QT_END_HEADER
+
+#endif // QQUICKLOADER_P_H
diff --git a/src/declarative/items/qquickloader_p_p.h b/src/declarative/items/qquickloader_p_p.h
new file mode 100644 (file)
index 0000000..63d73e8
--- /dev/null
@@ -0,0 +1,121 @@
+// Commit: 5d2817cd668a705729df1727de49adf00713ac97
+/****************************************************************************
+**
+** 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 QQUICKLOADER_P_P_H
+#define QQUICKLOADER_P_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 "qquickloader_p.h"
+#include "qquickimplicitsizeitem_p_p.h"
+#include "qquickitemchangelistener_p.h"
+#include <qdeclarativeincubator.h>
+
+#include <private/qv8_p.h>
+
+QT_BEGIN_NAMESPACE
+
+
+class QQuickLoaderPrivate;
+class QQuickLoaderIncubator : public QDeclarativeIncubator
+{
+public:
+    QQuickLoaderIncubator(QQuickLoaderPrivate *l, IncubationMode mode) : QDeclarativeIncubator(mode), loader(l) {}
+
+protected:
+    virtual void statusChanged(Status);
+    virtual void setInitialState(QObject *);
+
+private:
+    QQuickLoaderPrivate *loader;
+};
+
+class QDeclarativeContext;
+class QQuickLoaderPrivate : public QQuickImplicitSizeItemPrivate, public QQuickItemChangeListener
+{
+    Q_DECLARE_PUBLIC(QQuickLoader)
+
+public:
+    QQuickLoaderPrivate();
+    ~QQuickLoaderPrivate();
+
+    void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
+    void clear();
+    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);
+
+    QUrl source;
+    QQuickItem *item;
+    QDeclarativeComponent *component;
+    QDeclarativeContext *itemContext;
+    QQuickLoaderIncubator *incubator;
+    v8::Persistent<v8::Object> initialPropertyValues;
+    v8::Persistent<v8::Object> qmlGlobalForIpv;
+    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);
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKLOADER_P_P_H
diff --git a/src/declarative/items/qquickmousearea.cpp b/src/declarative/items/qquickmousearea.cpp
new file mode 100644 (file)
index 0000000..19e7fd4
--- /dev/null
@@ -0,0 +1,1131 @@
+/****************************************************************************
+**
+** 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 "qquickmousearea_p.h"
+#include "qquickmousearea_p_p.h"
+#include "qquickcanvas.h"
+#include "qquickevents_p_p.h"
+#include "qquickdrag_p.h"
+
+#include <QtGui/qevent.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qstylehints.h>
+
+#include <float.h>
+
+QT_BEGIN_NAMESPACE
+static const int PressAndHoldDelay = 800;
+
+QQuickDrag::QQuickDrag(QObject *parent)
+: QObject(parent), _target(0), _axis(XandYAxis), _xmin(-FLT_MAX),
+_xmax(FLT_MAX), _ymin(-FLT_MAX), _ymax(FLT_MAX), _active(false), _filterChildren(false)
+{
+}
+
+QQuickDrag::~QQuickDrag()
+{
+}
+
+QQuickItem *QQuickDrag::target() const
+{
+    return _target;
+}
+
+void QQuickDrag::setTarget(QQuickItem *t)
+{
+    if (_target == t)
+        return;
+    _target = t;
+    emit targetChanged();
+}
+
+void QQuickDrag::resetTarget()
+{
+    if (_target == 0)
+        return;
+    _target = 0;
+    emit targetChanged();
+}
+
+QQuickDrag::Axis QQuickDrag::axis() const
+{
+    return _axis;
+}
+
+void QQuickDrag::setAxis(QQuickDrag::Axis a)
+{
+    if (_axis == a)
+        return;
+    _axis = a;
+    emit axisChanged();
+}
+
+qreal QQuickDrag::xmin() const
+{
+    return _xmin;
+}
+
+void QQuickDrag::setXmin(qreal m)
+{
+    if (_xmin == m)
+        return;
+    _xmin = m;
+    emit minimumXChanged();
+}
+
+qreal QQuickDrag::xmax() const
+{
+    return _xmax;
+}
+
+void QQuickDrag::setXmax(qreal m)
+{
+    if (_xmax == m)
+        return;
+    _xmax = m;
+    emit maximumXChanged();
+}
+
+qreal QQuickDrag::ymin() const
+{
+    return _ymin;
+}
+
+void QQuickDrag::setYmin(qreal m)
+{
+    if (_ymin == m)
+        return;
+    _ymin = m;
+    emit minimumYChanged();
+}
+
+qreal QQuickDrag::ymax() const
+{
+    return _ymax;
+}
+
+void QQuickDrag::setYmax(qreal m)
+{
+    if (_ymax == m)
+        return;
+    _ymax = m;
+    emit maximumYChanged();
+}
+
+bool QQuickDrag::active() const
+{
+    return _active;
+}
+
+void QQuickDrag::setActive(bool drag)
+{
+    if (_active == drag)
+        return;
+    _active = drag;
+    emit activeChanged();
+}
+
+bool QQuickDrag::filterChildren() const
+{
+    return _filterChildren;
+}
+
+void QQuickDrag::setFilterChildren(bool filter)
+{
+    if (_filterChildren == filter)
+        return;
+    _filterChildren = filter;
+    emit filterChildrenChanged();
+}
+
+QQuickDragAttached *QQuickDrag::qmlAttachedProperties(QObject *obj)
+{
+    return new QQuickDragAttached(obj);
+}
+
+QQuickMouseAreaPrivate::QQuickMouseAreaPrivate()
+: absorb(true), hovered(false), pressed(false), longPress(false),
+  moved(false), stealMouse(false), doubleClick(false), preventStealing(false),
+  drag(0)
+{
+}
+
+QQuickMouseAreaPrivate::~QQuickMouseAreaPrivate()
+{
+    delete drag;
+}
+
+void QQuickMouseAreaPrivate::init()
+{
+    Q_Q(QQuickMouseArea);
+    q->setAcceptedMouseButtons(Qt::LeftButton);
+    q->setFiltersChildMouseEvents(true);
+}
+
+void QQuickMouseAreaPrivate::saveEvent(QMouseEvent *event)
+{
+    lastPos = event->localPos();
+    lastScenePos = event->windowPos();
+    lastButton = event->button();
+    lastButtons = event->buttons();
+    lastModifiers = event->modifiers();
+}
+
+bool QQuickMouseAreaPrivate::isPressAndHoldConnected()
+{
+    Q_Q(QQuickMouseArea);
+    static int idx = QObjectPrivate::get(q)->signalIndex("pressAndHold(QQuickMouseEvent*)");
+    return QObjectPrivate::get(q)->isSignalConnected(idx);
+}
+
+bool QQuickMouseAreaPrivate::isDoubleClickConnected()
+{
+    Q_Q(QQuickMouseArea);
+    static int idx = QObjectPrivate::get(q)->signalIndex("doubleClicked(QQuickMouseEvent*)");
+    return QObjectPrivate::get(q)->isSignalConnected(idx);
+}
+
+bool QQuickMouseAreaPrivate::isClickConnected()
+{
+    Q_Q(QQuickMouseArea);
+    static int idx = QObjectPrivate::get(q)->signalIndex("clicked(QQuickMouseEvent*)");
+    return QObjectPrivate::get(q)->isSignalConnected(idx);
+}
+
+void QQuickMouseAreaPrivate::propagate(QQuickMouseEvent* event, PropagateType t)
+{
+    Q_Q(QQuickMouseArea);
+    QPointF scenePos = q->mapToScene(QPointF(event->x(), event->y()));
+    propagateHelper(event, canvas->rootItem(), scenePos, t);
+}
+
+bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *item,const QPointF &sp, PropagateType sig)
+{
+    //Based off of QQuickCanvas::deliverInitialMousePressEvent
+    //But specific to MouseArea, so doesn't belong in canvas
+    Q_Q(const QQuickMouseArea);
+    QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+    if (itemPrivate->opacity == 0.0)
+        return false;
+
+    if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
+        QPointF p = item->mapFromScene(sp);
+        if (!QRectF(0, 0, item->width(), item->height()).contains(p))
+            return false;
+    }
+
+    QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
+    for (int ii = children.count() - 1; ii >= 0; --ii) {
+        QQuickItem *child = children.at(ii);
+        if (!child->isVisible() || !child->isEnabled())
+            continue;
+        if (propagateHelper(ev, child, sp, sig))
+            return true;
+    }
+
+    QQuickMouseArea* ma = qobject_cast<QQuickMouseArea*>(item);
+    if (ma && ma != q && itemPrivate->acceptedMouseButtons & ev->button()) {
+        switch (sig) {
+        case Click:
+            if (!ma->d_func()->isClickConnected())
+                return false;
+            break;
+        case DoubleClick:
+            if (!ma->d_func()->isDoubleClickConnected())
+                return false;
+            break;
+        case PressAndHold:
+            if (!ma->d_func()->isPressAndHoldConnected())
+                return false;
+            break;
+        }
+        QPointF p = item->mapFromScene(sp);
+        if (QRectF(0, 0, item->width(), item->height()).contains(p)) {
+            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) {
+            case Click: emit ma->clicked(ev); break;
+            case DoubleClick: emit ma->doubleClicked(ev); break;
+            case PressAndHold: emit ma->pressAndHold(ev); break;
+            }
+            if (ev->isAccepted())
+                return true;
+        }
+    }
+    return false;
+
+}
+
+/*!
+    \qmlclass MouseArea QQuickMouseArea
+    \inqmlmodule QtQuick 2
+    \ingroup qml-basic-interaction-elements
+    \brief The MouseArea item enables simple mouse handling.
+    \inherits Item
+
+    A MouseArea is an invisible item that is typically used in conjunction with
+    a visible item in order to provide mouse handling for that item.
+    By effectively acting as a proxy, the logic for mouse handling can be
+    contained within a MouseArea item.
+
+    For basic key handling, see the \l{Keys}{Keys attached property}.
+
+    The \l enabled property is used to enable and disable mouse handling for
+    the proxied item. When disabled, the mouse area becomes transparent to
+    mouse events.
+
+    The \l pressed read-only property indicates whether or not the user is
+    holding down a mouse button over the mouse area. This property is often
+    used in bindings between properties in a user interface. The containsMouse
+    read-only property indicates the presence of the mouse cursor over the
+    mouse area but, by default, only when a mouse button is held down; see below
+    for further details.
+
+    Information about the mouse position and button clicks are provided via
+    signals for which event handler properties are defined. The most commonly
+    used involved handling mouse presses and clicks: onClicked, onDoubleClicked,
+    onPressed, onReleased and onPressAndHold.
+
+    By default, MouseArea items only report mouse clicks and not changes to the
+    position of the mouse cursor. Setting the hoverEnabled property ensures that
+    handlers defined for onPositionChanged, onEntered and onExited are used and
+    that the containsMouse property is updated even when no mouse buttons are
+    pressed.
+
+    \section1 Example Usage
+
+    \div {class="float-right"}
+    \inlineimage qml-mousearea-snippet.png
+    \enddiv
+
+    The following example uses a MouseArea in a \l Rectangle that changes
+    the \l Rectangle color to red when clicked:
+
+    \snippet doc/src/snippets/declarative/mousearea/mousearea.qml import
+    \codeline
+    \snippet doc/src/snippets/declarative/mousearea/mousearea.qml intro
+
+    \clearfloat
+    Many MouseArea signals pass a \l{MouseEvent}{mouse} parameter that contains
+    additional information about the mouse event, such as the position, button,
+    and any key modifiers.
+
+    Here is an extension of the previous example that produces a different
+    color when the area is right clicked:
+
+    \snippet doc/src/snippets/declarative/mousearea/mousearea.qml intro-extended
+
+  Behavioral Change in QtQuick 2.0
+
+  From QtQuick 2.0, the signals clicked, doubleClicked and pressAndHold have a different interaction
+  model with regards to the delivery of events to multiple overlapping MouseAreas. These signals will now propagate
+  to all MouseAreas in the area, in painting order, until accepted by one of them. A signal is accepted by
+  default if there is a signal handler for it, use mouse.accepted = false; to ignore. This propagation
+  can send the signal to MouseAreas other than the one which accepted the press event, although that MouseArea
+  will receive the signal first.
+
+  Note that to get the same behavior as a QtQuick 1.0 MouseArea{} with regard to absorbing all mouse events, you will
+  now need to add empty signal handlers for these three signals.
+
+    \sa MouseEvent, {declarative/touchinteraction/mousearea}{MouseArea example}
+*/
+
+/*!
+    \qmlsignal QtQuick2::MouseArea::onEntered()
+
+    This handler is called when the mouse enters the mouse area.
+
+    By default the onEntered handler is only called while a button is
+    pressed. Setting hoverEnabled to true enables handling of
+    onEntered when no mouse button is pressed.
+
+    \sa hoverEnabled
+*/
+
+/*!
+    \qmlsignal QtQuick2::MouseArea::onExited()
+
+    This handler is called when the mouse exits the mouse area.
+
+    By default the onExited handler is only called while a button is
+    pressed. Setting hoverEnabled to true enables handling of
+    onExited when no mouse button is pressed.
+
+    The example below shows a fairly typical relationship between
+    two MouseAreas, with \c mouseArea2 on top of \c mouseArea1. Moving the
+    mouse into \c mouseArea2 from \c mouseArea1 will cause \c onExited
+    to be called for \c mouseArea1.
+    \qml
+    Rectangle {
+        width: 400; height: 400
+        MouseArea {
+            id: mouseArea1
+            anchors.fill: parent
+            hoverEnabled: true
+        }
+        MouseArea {
+            id: mouseArea2
+            width: 100; height: 100
+            anchors.centerIn: parent
+            hoverEnabled: true
+        }
+    }
+    \endqml
+
+    If instead you give the two mouseAreas a parent-child relationship,
+    moving the mouse into \c mouseArea2 from \c mouseArea1 will \b not
+    cause \c onExited to be called for \c mouseArea1. Instead, they will
+    both be considered to be simultaneously hovered.
+
+    \sa hoverEnabled
+*/
+
+/*!
+    \qmlsignal QtQuick2::MouseArea::onPositionChanged(MouseEvent mouse)
+
+    This handler is called when the mouse position changes.
+
+    The \l {MouseEvent}{mouse} parameter provides information about the mouse, including the x and y
+    position, and any buttons currently pressed.
+
+    The \e accepted property of the MouseEvent parameter is ignored in this handler.
+
+    By default the onPositionChanged handler is only called while a button is
+    pressed.  Setting hoverEnabled to true enables handling of
+    onPositionChanged when no mouse button is pressed.
+*/
+
+/*!
+    \qmlsignal QtQuick2::MouseArea::onClicked(MouseEvent mouse)
+
+    This handler is called when there is a click. A click is defined as a press followed by a release,
+    both inside the MouseArea (pressing, moving outside the MouseArea, and then moving back inside and
+    releasing is also considered a click).
+
+    The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y
+    position of the release of the click, and whether the click was held.
+
+    The \e accepted property of the MouseEvent parameter is ignored in this handler.
+*/
+
+/*!
+    \qmlsignal QtQuick2::MouseArea::onPressed(MouseEvent mouse)
+
+    This handler is called when there is a press.
+    The \l {MouseEvent}{mouse} parameter provides information about the press, including the x and y
+    position and which button was pressed.
+
+    The \e accepted property of the MouseEvent parameter determines whether this MouseArea
+    will handle the press and all future mouse events until release.  The default is to accept
+    the event and not allow other MouseArea beneath this one to handle the event.  If \e accepted
+    is set to false, no further events will be sent to this MouseArea until the button is next
+    pressed.
+*/
+
+/*!
+    \qmlsignal QtQuick2::MouseArea::onReleased(MouseEvent mouse)
+
+    This handler is called when there is a release.
+    The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y
+    position of the release of the click, and whether the click was held.
+
+    The \e accepted property of the MouseEvent parameter is ignored in this handler.
+
+    \sa onCanceled
+*/
+
+/*!
+    \qmlsignal QtQuick2::MouseArea::onPressAndHold(MouseEvent mouse)
+
+    This handler is called when there is a long press (currently 800ms).
+    The \l {MouseEvent}{mouse} parameter provides information about the press, including the x and y
+    position of the press, and which button is pressed.
+
+    The \e accepted property of the MouseEvent parameter is ignored in this handler.
+*/
+
+/*!
+    \qmlsignal QtQuick2::MouseArea::onDoubleClicked(MouseEvent mouse)
+
+    This handler is called when there is a double-click (a press followed by a release followed by a press).
+    The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y
+    position of the release of the click, and whether the click was held.
+
+    If the \e accepted property of the \l {MouseEvent}{mouse} parameter is set to false
+    in the handler, the onPressed/onReleased/onClicked handlers will be called for the second
+    click; otherwise they are suppressed.  The accepted property defaults to true.
+*/
+
+/*!
+    \qmlsignal QtQuick2::MouseArea::onCanceled()
+
+    This handler is called when mouse events have been canceled, either because an event was not accepted, or
+    because another element stole the mouse event handling.
+
+    This signal is for advanced use: it is useful when there is more than one MouseArea
+    that is handling input, or when there is a MouseArea inside a \l Flickable. In the latter
+    case, if you execute some logic on the pressed signal and then start dragging, the
+    \l Flickable will steal the mouse handling from the MouseArea. In these cases, to reset
+    the logic when the MouseArea has lost the mouse handling to the \l Flickable,
+    \c onCanceled should be used in addition to onReleased.
+*/
+QQuickMouseArea::QQuickMouseArea(QQuickItem *parent)
+  : QQuickItem(*(new QQuickMouseAreaPrivate), parent)
+{
+    Q_D(QQuickMouseArea);
+    d->init();
+}
+
+QQuickMouseArea::~QQuickMouseArea()
+{
+}
+
+/*!
+    \qmlproperty real QtQuick2::MouseArea::mouseX
+    \qmlproperty real QtQuick2::MouseArea::mouseY
+    These properties hold the coordinates of the mouse cursor.
+
+    If the hoverEnabled property is false then these properties will only be valid
+    while a button is pressed, and will remain valid as long as the button is held
+    down even if the mouse is moved outside the area.
+
+    By default, this property is false.
+
+    If hoverEnabled is true then these properties will be valid when:
+    \list
+        \i no button is pressed, but the mouse is within the MouseArea (containsMouse is true).
+        \i a button is pressed and held, even if it has since moved out of the area.
+    \endlist
+
+    The coordinates are relative to the MouseArea.
+*/
+qreal QQuickMouseArea::mouseX() const
+{
+    Q_D(const QQuickMouseArea);
+    return d->lastPos.x();
+}
+
+qreal QQuickMouseArea::mouseY() const
+{
+    Q_D(const QQuickMouseArea);
+    return d->lastPos.y();
+}
+
+/*!
+    \qmlproperty bool QtQuick2::MouseArea::enabled
+    This property holds whether the item accepts mouse events.
+
+    By default, this property is true.
+*/
+bool QQuickMouseArea::isEnabled() const
+{
+    Q_D(const QQuickMouseArea);
+    return d->absorb;
+}
+
+void QQuickMouseArea::setEnabled(bool a)
+{
+    Q_D(QQuickMouseArea);
+    if (a != d->absorb) {
+        d->absorb = a;
+        emit enabledChanged();
+    }
+}
+
+/*!
+    \qmlproperty bool QtQuick2::MouseArea::preventStealing
+    This property holds whether the mouse events may be stolen from this
+    MouseArea.
+
+    If a MouseArea is placed within an item that filters child mouse
+    events, such as Flickable, the mouse
+    events may be stolen from the MouseArea if a gesture is recognized
+    by the parent element, e.g. a flick gesture.  If preventStealing is
+    set to true, no element will steal the mouse events.
+
+    Note that setting preventStealing to true once an element has started
+    stealing events will have no effect until the next press event.
+
+    By default this property is false.
+*/
+bool QQuickMouseArea::preventStealing() const
+{
+    Q_D(const QQuickMouseArea);
+    return d->preventStealing;
+}
+
+void QQuickMouseArea::setPreventStealing(bool prevent)
+{
+    Q_D(QQuickMouseArea);
+    if (prevent != d->preventStealing) {
+        d->preventStealing = prevent;
+        setKeepMouseGrab(d->preventStealing && d->absorb);
+        emit preventStealingChanged();
+    }
+}
+
+/*!
+    \qmlproperty MouseButtons QtQuick2::MouseArea::pressedButtons
+    This property holds the mouse buttons currently pressed.
+
+    It contains a bitwise combination of:
+    \list
+    \o Qt.LeftButton
+    \o Qt.RightButton
+    \o Qt.MiddleButton
+    \endlist
+
+    The code below displays "right" when the right mouse buttons is pressed:
+
+    \snippet doc/src/snippets/declarative/mousearea/mousearea.qml mousebuttons
+
+    \sa acceptedButtons
+*/
+Qt::MouseButtons QQuickMouseArea::pressedButtons() const
+{
+    Q_D(const QQuickMouseArea);
+    return d->lastButtons;
+}
+
+void QQuickMouseArea::mousePressEvent(QMouseEvent *event)
+{
+    Q_D(QQuickMouseArea);
+    d->moved = false;
+    d->stealMouse = d->preventStealing;
+    if (!d->absorb)
+        QQuickItem::mousePressEvent(event);
+    else {
+        d->longPress = false;
+        d->saveEvent(event);
+        if (d->drag) {
+            d->dragX = drag()->axis() & QQuickDrag::XAxis;
+            d->dragY = drag()->axis() & QQuickDrag::YAxis;
+        }
+        if (d->drag)
+            d->drag->setActive(false);
+        setHovered(true);
+        d->startScene = event->windowPos();
+        d->pressAndHoldTimer.start(PressAndHoldDelay, this);
+        setKeepMouseGrab(d->stealMouse);
+        event->setAccepted(setPressed(true));
+
+    }
+}
+
+void QQuickMouseArea::mouseMoveEvent(QMouseEvent *event)
+{
+    Q_D(QQuickMouseArea);
+    if (!d->absorb) {
+        QQuickItem::mouseMoveEvent(event);
+        return;
+    }
+
+    d->saveEvent(event);
+
+    // ### we should skip this if these signals aren't used
+    // ### can GV handle this for us?
+    bool contains = boundingRect().contains(d->lastPos);
+    if (d->hovered && !contains)
+        setHovered(false);
+    else if (!d->hovered && contains)
+        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())
+                    : d->drag->target()->pos();
+        }
+
+        QPointF startLocalPos;
+        QPointF curLocalPos;
+        if (drag()->target()->parentItem()) {
+            startLocalPos = drag()->target()->parentItem()->mapFromScene(d->startScene);
+            curLocalPos = drag()->target()->parentItem()->mapFromScene(event->windowPos());
+        } else {
+            startLocalPos = d->startScene;
+            curLocalPos = event->windowPos();
+        }
+
+        const int dragThreshold = qApp->styleHints()->startDragDistance();
+        qreal dx = qAbs(curLocalPos.x() - startLocalPos.x());
+        qreal dy = qAbs(curLocalPos.y() - startLocalPos.y());
+
+        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();
+            dragPos.setX(x);
+        }
+        if (d->dragY && d->drag->active()) {
+            qreal y = (curLocalPos.y() - startLocalPos.y()) + startPos.y();
+            if (y < drag()->ymin())
+                y = drag()->ymin();
+            else if (y > drag()->ymax())
+                y = drag()->ymax();
+            dragPos.setY(y);
+        }
+        d->drag->target()->setPos(dragPos);
+
+        if (!keepMouseGrab()) {
+            if ((!d->dragY && dy < dragThreshold && d->dragX && dx > dragThreshold)
+                || (!d->dragX && dx < dragThreshold && d->dragY && dy > dragThreshold)
+                || (d->dragX && d->dragY && (dx > dragThreshold || dy > dragThreshold))) {
+                setKeepMouseGrab(true);
+                d->stealMouse = true;
+            }
+        }
+
+        d->moved = true;
+    }
+    QQuickMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress);
+    emit mouseXChanged(&me);
+    me.setPosition(d->lastPos);
+    emit mouseYChanged(&me);
+    me.setPosition(d->lastPos);
+    emit positionChanged(&me);
+}
+
+void QQuickMouseArea::mouseReleaseEvent(QMouseEvent *event)
+{
+    Q_D(QQuickMouseArea);
+    d->stealMouse = false;
+    if (!d->absorb) {
+        QQuickItem::mouseReleaseEvent(event);
+    } else {
+        d->saveEvent(event);
+        setPressed(false);
+        if (d->drag)
+            d->drag->setActive(false);
+        // If we don't accept hover, we need to reset containsMouse.
+        if (!acceptHoverEvents())
+            setHovered(false);
+        QQuickCanvas *c = canvas();
+        if (c && c->mouseGrabberItem() == this)
+            ungrabMouse();
+        setKeepMouseGrab(false);
+
+    }
+    d->doubleClick = false;
+}
+
+void QQuickMouseArea::mouseDoubleClickEvent(QMouseEvent *event)
+{
+    Q_D(QQuickMouseArea);
+    if (d->absorb) {
+        d->saveEvent(event);
+        QQuickMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, true, false);
+        me.setAccepted(d->isDoubleClickConnected());
+        emit this->doubleClicked(&me);
+        if (!me.isAccepted())
+            d->propagate(&me, QQuickMouseAreaPrivate::DoubleClick);
+        d->doubleClick = d->isDoubleClickConnected() || me.isAccepted();
+    }
+    QQuickItem::mouseDoubleClickEvent(event);
+}
+
+void QQuickMouseArea::hoverEnterEvent(QHoverEvent *event)
+{
+    Q_D(QQuickMouseArea);
+    if (!d->absorb) {
+        QQuickItem::hoverEnterEvent(event);
+    } else {
+        d->lastPos = event->posF();
+        d->lastModifiers = event->modifiers();
+        setHovered(true);
+        QQuickMouseEvent me(d->lastPos.x(), d->lastPos.y(), Qt::NoButton, Qt::NoButton, d->lastModifiers, false, false);
+        emit mouseXChanged(&me);
+        me.setPosition(d->lastPos);
+        emit mouseYChanged(&me);
+        me.setPosition(d->lastPos);
+    }
+}
+
+void QQuickMouseArea::hoverMoveEvent(QHoverEvent *event)
+{
+    Q_D(QQuickMouseArea);
+    if (!d->absorb) {
+        QQuickItem::hoverMoveEvent(event);
+    } else {
+        d->lastPos = event->posF();
+        d->lastModifiers = event->modifiers();
+        QQuickMouseEvent me(d->lastPos.x(), d->lastPos.y(), Qt::NoButton, Qt::NoButton, d->lastModifiers, false, false);
+        emit mouseXChanged(&me);
+        me.setPosition(d->lastPos);
+        emit mouseYChanged(&me);
+        me.setPosition(d->lastPos);
+        emit positionChanged(&me);
+    }
+}
+
+void QQuickMouseArea::hoverLeaveEvent(QHoverEvent *event)
+{
+    Q_D(QQuickMouseArea);
+    if (!d->absorb)
+        QQuickItem::hoverLeaveEvent(event);
+    else
+        setHovered(false);
+}
+
+void QQuickMouseArea::ungrabMouse()
+{
+    Q_D(QQuickMouseArea);
+    if (d->pressed) {
+        // if our mouse grab has been removed (probably by Flickable), fix our
+        // state
+        d->pressed = false;
+        d->stealMouse = false;
+        setKeepMouseGrab(false);
+        emit canceled();
+        emit pressedChanged();
+        if (d->hovered) {
+            d->hovered = false;
+            emit hoveredChanged();
+        }
+    }
+}
+
+void QQuickMouseArea::mouseUngrabEvent()
+{
+    ungrabMouse();
+}
+
+bool QQuickMouseArea::sendMouseEvent(QMouseEvent *event)
+{
+    Q_D(QQuickMouseArea);
+    QRectF myRect = mapRectToScene(QRectF(0, 0, width(), height()));
+
+    QQuickCanvas *c = canvas();
+    QQuickItem *grabber = c ? c->mouseGrabberItem() : 0;
+    bool stealThisEvent = d->stealMouse;
+    if ((stealThisEvent || myRect.contains(event->windowPos())) && (!grabber || !grabber->keepMouseGrab())) {
+        QMouseEvent mouseEvent(event->type(), mapFromScene(event->windowPos()), event->windowPos(), event->screenPos(),
+                               event->button(), event->buttons(), event->modifiers());
+        mouseEvent.setAccepted(false);
+
+        switch (event->type()) {
+        case QEvent::MouseMove:
+            mouseMoveEvent(&mouseEvent);
+            break;
+        case QEvent::MouseButtonPress:
+            mousePressEvent(&mouseEvent);
+            break;
+        case QEvent::MouseButtonRelease:
+            mouseReleaseEvent(&mouseEvent);
+            break;
+        default:
+            break;
+        }
+        grabber = c->mouseGrabberItem();
+        if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this)
+            grabMouse();
+
+        return stealThisEvent;
+    }
+    if (event->type() == QEvent::MouseButtonRelease) {
+        if (d->pressed) {
+            d->pressed = false;
+            d->stealMouse = false;
+            if (c && c->mouseGrabberItem() == this)
+                ungrabMouse();
+            emit canceled();
+            emit pressedChanged();
+            if (d->hovered) {
+                d->hovered = false;
+                emit hoveredChanged();
+            }
+        }
+    }
+    return false;
+}
+
+bool QQuickMouseArea::childMouseEventFilter(QQuickItem *i, QEvent *e)
+{
+    Q_D(QQuickMouseArea);
+    if (!d->absorb || !isVisible() || !d->drag || !d->drag->filterChildren())
+        return QQuickItem::childMouseEventFilter(i, e);
+    switch (e->type()) {
+    case QEvent::MouseButtonPress:
+    case QEvent::MouseMove:
+    case QEvent::MouseButtonRelease:
+        return sendMouseEvent(static_cast<QMouseEvent *>(e));
+    default:
+        break;
+    }
+
+    return QQuickItem::childMouseEventFilter(i, e);
+}
+
+void QQuickMouseArea::timerEvent(QTimerEvent *event)
+{
+    Q_D(QQuickMouseArea);
+    if (event->timerId() == d->pressAndHoldTimer.timerId()) {
+        d->pressAndHoldTimer.stop();
+        bool dragged = d->drag && d->drag->active();
+        if (d->pressed && dragged == false && d->hovered == true) {
+            d->longPress = true;
+            QQuickMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress);
+            me.setAccepted(d->isPressAndHoldConnected());
+            emit pressAndHold(&me);
+            if (!me.isAccepted())
+                d->propagate(&me, QQuickMouseAreaPrivate::PressAndHold);
+            if (!me.isAccepted()) // no one handled the long press - allow click
+                d->longPress = false;
+        }
+    }
+}
+
+void QQuickMouseArea::windowDeactivateEvent()
+{
+    ungrabMouse();
+    QQuickItem::windowDeactivateEvent();
+}
+
+void QQuickMouseArea::geometryChanged(const QRectF &newGeometry,
+                                            const QRectF &oldGeometry)
+{
+    Q_D(QQuickMouseArea);
+    QQuickItem::geometryChanged(newGeometry, oldGeometry);
+
+    if (d->lastScenePos.isNull)
+        d->lastScenePos = mapToScene(d->lastPos);
+    else if (newGeometry.x() != oldGeometry.x() || newGeometry.y() != oldGeometry.y())
+        d->lastPos = mapFromScene(d->lastScenePos);
+}
+
+void QQuickMouseArea::itemChange(ItemChange change, const ItemChangeData &value)
+{
+    Q_D(QQuickMouseArea);
+    switch (change) {
+    case ItemVisibleHasChanged:
+        if (acceptHoverEvents() && d->hovered != (isVisible() && isUnderMouse()))
+            setHovered(!d->hovered);
+        break;
+    default:
+        break;
+    }
+
+    QQuickItem::itemChange(change, value);
+}
+
+/*!
+    \qmlproperty bool QtQuick2::MouseArea::hoverEnabled
+    This property holds whether hover events are handled.
+
+    By default, mouse events are only handled in response to a button event, or when a button is
+    pressed.  Hover enables handling of all mouse events even when no mouse button is
+    pressed.
+
+    This property affects the containsMouse property and the onEntered, onExited and
+    onPositionChanged signals.
+*/
+bool QQuickMouseArea::hoverEnabled() const
+{
+    return acceptHoverEvents();
+}
+
+void QQuickMouseArea::setHoverEnabled(bool h)
+{
+    if (h == acceptHoverEvents())
+        return;
+
+    setAcceptHoverEvents(h);
+    emit hoverEnabledChanged();
+}
+
+
+/*!
+    \qmlproperty bool QtQuick2::MouseArea::containsMouse
+    This property holds whether the mouse is currently inside the mouse area.
+
+    \warning This property is not updated if the area moves under the mouse: \e containsMouse will not change.
+    In addition, if hoverEnabled is false, containsMouse will only be valid when the mouse is pressed.
+*/
+bool QQuickMouseArea::hovered() const
+{
+    Q_D(const QQuickMouseArea);
+    return d->hovered;
+}
+
+/*!
+    \qmlproperty bool QtQuick2::MouseArea::pressed
+    This property holds whether the mouse area is currently pressed.
+*/
+bool QQuickMouseArea::pressed() const
+{
+    Q_D(const QQuickMouseArea);
+    return d->pressed;
+}
+
+void QQuickMouseArea::setHovered(bool h)
+{
+    Q_D(QQuickMouseArea);
+    if (d->hovered != h) {
+        d->hovered = h;
+        emit hoveredChanged();
+        d->hovered ? emit entered() : emit exited();
+    }
+}
+/*!
+    \qmlproperty QtQuick2::Qt::MouseButtons MouseArea::acceptedButtons
+    This property holds the mouse buttons that the mouse area reacts to.
+
+    The available buttons are:
+    \list
+    \o Qt.LeftButton
+    \o Qt.RightButton
+    \o Qt.MiddleButton
+    \endlist
+
+    To accept more than one button the flags can be combined with the
+    "|" (or) operator:
+
+    \code
+    MouseArea { acceptedButtons: Qt.LeftButton | Qt.RightButton }
+    \endcode
+
+    The default value is \c Qt.LeftButton.
+*/
+Qt::MouseButtons QQuickMouseArea::acceptedButtons() const
+{
+    return acceptedMouseButtons();
+}
+
+void QQuickMouseArea::setAcceptedButtons(Qt::MouseButtons buttons)
+{
+    if (buttons != acceptedMouseButtons()) {
+        setAcceptedMouseButtons(buttons);
+        emit acceptedButtonsChanged();
+    }
+}
+
+bool QQuickMouseArea::setPressed(bool p)
+{
+    Q_D(QQuickMouseArea);
+    bool dragged = d->drag && d->drag->active();
+    bool isclick = d->pressed == true && p == false && dragged == false && d->hovered == true;
+
+    if (d->pressed != p) {
+        d->pressed = p;
+        QQuickMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, isclick, d->longPress);
+        if (d->pressed) {
+            if (!d->doubleClick)
+                emit pressed(&me);
+            me.setPosition(d->lastPos);
+            emit mouseXChanged(&me);
+            me.setPosition(d->lastPos);
+            emit mouseYChanged(&me);
+            emit pressedChanged();
+        } else {
+            emit released(&me);
+            me.setPosition(d->lastPos);
+            emit pressedChanged();
+            if (isclick && !d->longPress && !d->doubleClick){
+                me.setAccepted(d->isClickConnected());
+                emit clicked(&me);
+                if (!me.isAccepted())
+                    d->propagate(&me, QQuickMouseAreaPrivate::Click);
+            }
+        }
+
+        return me.isAccepted();
+    }
+    return false;
+}
+
+/*!
+    \qmlproperty Item QtQuick2::MouseArea::drag.target
+    \qmlproperty bool QtQuick2::MouseArea::drag.active
+    \qmlproperty enumeration QtQuick2::MouseArea::drag.axis
+    \qmlproperty real QtQuick2::MouseArea::drag.minimumX
+    \qmlproperty real QtQuick2::MouseArea::drag.maximumX
+    \qmlproperty real QtQuick2::MouseArea::drag.minimumY
+    \qmlproperty real QtQuick2::MouseArea::drag.maximumY
+    \qmlproperty bool QtQuick2::MouseArea::drag.filterChildren
+
+    \c drag provides a convenient way to make an item draggable.
+
+    \list
+    \i \c drag.target specifies the id of the item to drag.
+    \i \c drag.active specifies if the target item is currently being dragged.
+    \i \c drag.axis specifies whether dragging can be done horizontally (\c Drag.XAxis), vertically (\c Drag.YAxis), or both (\c Drag.XandYAxis)
+    \i \c drag.minimum and \c drag.maximum limit how far the target can be dragged along the corresponding axes.
+    \endlist
+
+    The following example displays a \l Rectangle that can be dragged along the X-axis. The opacity
+    of the rectangle is reduced when it is dragged to the right.
+
+    \snippet doc/src/snippets/declarative/mousearea/mousearea.qml drag
+
+    \note Items cannot be dragged if they are anchored for the requested
+    \c drag.axis. For example, if \c anchors.left or \c anchors.right was set
+    for \c rect in the above example, it cannot be dragged along the X-axis.
+    This can be avoided by settng the anchor value to \c undefined in
+    an \l onPressed handler.
+
+    If \c drag.filterChildren is set to true, a drag can override descendant MouseAreas.  This
+    enables a parent MouseArea to handle drags, for example, while descendants handle clicks:
+
+    \snippet doc/src/snippets/declarative/mousearea/mouseareadragfilter.qml dragfilter
+
+*/
+
+QQuickDrag *QQuickMouseArea::drag()
+{
+    Q_D(QQuickMouseArea);
+    if (!d->drag)
+        d->drag = new QQuickDrag;
+    return d->drag;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickmousearea_p.h b/src/declarative/items/qquickmousearea_p.h
new file mode 100644 (file)
index 0000000..6f15ff6
--- /dev/null
@@ -0,0 +1,226 @@
+// 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 QQUICKMOUSEAREA_P_H
+#define QQUICKMOUSEAREA_P_H
+
+#include "qquickitem.h"
+
+#include <QtCore/qstringlist.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickDragAttached;
+class QQuickMouseEvent;
+class Q_AUTOTEST_EXPORT QQuickDrag : public QObject
+{
+    Q_OBJECT
+
+    Q_ENUMS(Axis)
+    Q_PROPERTY(QQuickItem *target READ target WRITE setTarget NOTIFY targetChanged RESET resetTarget)
+    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)
+    Q_PROPERTY(qreal minimumY READ ymin WRITE setYmin NOTIFY minimumYChanged)
+    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)
+    //### consider drag and drop
+
+public:
+    QQuickDrag(QObject *parent=0);
+    ~QQuickDrag();
+
+    QQuickItem *target() const;
+    void setTarget(QQuickItem *target);
+    void resetTarget();
+
+    enum Axis { XAxis=0x01, YAxis=0x02, XandYAxis=0x03 };
+    Axis axis() const;
+    void setAxis(Axis);
+
+    qreal xmin() const;
+    void setXmin(qreal);
+    qreal xmax() const;
+    void setXmax(qreal);
+    qreal ymin() const;
+    void setYmin(qreal);
+    qreal ymax() const;
+    void setYmax(qreal);
+
+    bool active() const;
+    void setActive(bool);
+
+    bool filterChildren() const;
+    void setFilterChildren(bool);
+
+    static QQuickDragAttached *qmlAttachedProperties(QObject *obj);
+
+Q_SIGNALS:
+    void targetChanged();
+    void axisChanged();
+    void minimumXChanged();
+    void maximumXChanged();
+    void minimumYChanged();
+    void maximumYChanged();
+    void activeChanged();
+    void filterChildrenChanged();
+
+private:
+    QQuickItem *_target;
+    Axis _axis;
+    qreal _xmin;
+    qreal _xmax;
+    qreal _ymin;
+    qreal _ymax;
+    bool _active : 1;
+    bool _filterChildren: 1;
+    Q_DISABLE_COPY(QQuickDrag)
+};
+
+class QQuickMouseAreaPrivate;
+// used in QtLocation
+class Q_DECLARATIVE_EXPORT QQuickMouseArea : public QQuickItem
+{
+    Q_OBJECT
+
+    Q_PROPERTY(qreal mouseX READ mouseX NOTIFY mouseXChanged)
+    Q_PROPERTY(qreal mouseY READ mouseY NOTIFY mouseYChanged)
+    Q_PROPERTY(bool containsMouse READ hovered NOTIFY hoveredChanged)
+    Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged)
+    Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
+    Q_PROPERTY(Qt::MouseButtons pressedButtons READ pressedButtons NOTIFY pressedChanged)
+    Q_PROPERTY(Qt::MouseButtons acceptedButtons READ acceptedButtons WRITE setAcceptedButtons NOTIFY acceptedButtonsChanged)
+    Q_PROPERTY(bool hoverEnabled READ hoverEnabled WRITE setHoverEnabled NOTIFY hoverEnabledChanged)
+    Q_PROPERTY(QQuickDrag *drag READ drag CONSTANT) //### add flicking to QQuickDrag or add a QDeclarativeFlick ???
+    Q_PROPERTY(bool preventStealing READ preventStealing WRITE setPreventStealing NOTIFY preventStealingChanged)
+
+public:
+    QQuickMouseArea(QQuickItem *parent=0);
+    ~QQuickMouseArea();
+
+    qreal mouseX() const;
+    qreal mouseY() const;
+
+    bool isEnabled() const;
+    void setEnabled(bool);
+
+    bool hovered() const;
+    bool pressed() const;
+
+    Qt::MouseButtons pressedButtons() const;
+
+    Qt::MouseButtons acceptedButtons() const;
+    void setAcceptedButtons(Qt::MouseButtons buttons);
+
+    bool hoverEnabled() const;
+    void setHoverEnabled(bool h);
+
+    QQuickDrag *drag();
+
+    bool preventStealing() const;
+    void setPreventStealing(bool prevent);
+
+Q_SIGNALS:
+    void hoveredChanged();
+    void pressedChanged();
+    void enabledChanged();
+    void acceptedButtonsChanged();
+    void hoverEnabledChanged();
+    void positionChanged(QQuickMouseEvent *mouse);
+    void mouseXChanged(QQuickMouseEvent *mouse);
+    void mouseYChanged(QQuickMouseEvent *mouse);
+    void preventStealingChanged();
+
+    void pressed(QQuickMouseEvent *mouse);
+    void pressAndHold(QQuickMouseEvent *mouse);
+    void released(QQuickMouseEvent *mouse);
+    void clicked(QQuickMouseEvent *mouse);
+    void doubleClicked(QQuickMouseEvent *mouse);
+    void entered();
+    void exited();
+    void canceled();
+
+protected:
+    void setHovered(bool);
+    bool setPressed(bool);
+    bool sendMouseEvent(QMouseEvent *event);
+
+    virtual void mousePressEvent(QMouseEvent *event);
+    virtual void mouseReleaseEvent(QMouseEvent *event);
+    virtual void mouseDoubleClickEvent(QMouseEvent *event);
+    virtual void mouseMoveEvent(QMouseEvent *event);
+    virtual void mouseUngrabEvent();
+    virtual void hoverEnterEvent(QHoverEvent *event);
+    virtual void hoverMoveEvent(QHoverEvent *event);
+    virtual void hoverLeaveEvent(QHoverEvent *event);
+    virtual bool childMouseEventFilter(QQuickItem *i, QEvent *e);
+    virtual void timerEvent(QTimerEvent *event);
+    virtual void windowDeactivateEvent();
+
+    virtual void geometryChanged(const QRectF &newGeometry,
+                                 const QRectF &oldGeometry);
+    virtual void itemChange(ItemChange change, const ItemChangeData& value);
+
+private:
+    void handlePress();
+    void handleRelease();
+    void ungrabMouse();
+
+private:
+    Q_DISABLE_COPY(QQuickMouseArea)
+    Q_DECLARE_PRIVATE(QQuickMouseArea)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickDrag)
+QML_DECLARE_TYPEINFO(QQuickDrag, QML_HAS_ATTACHED_PROPERTIES)
+QML_DECLARE_TYPE(QQuickMouseArea)
+
+QT_END_HEADER
+
+#endif // QQUICKMOUSEAREA_P_H
diff --git a/src/declarative/items/qquickmousearea_p_p.h b/src/declarative/items/qquickmousearea_p_p.h
new file mode 100644 (file)
index 0000000..9f81bf9
--- /dev/null
@@ -0,0 +1,111 @@
+// 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 QQUICKMOUSEAREA_P_P_H
+#define QQUICKMOUSEAREA_P_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 "qquickitem_p.h"
+
+#include <QtGui/qevent.h>
+#include <QtCore/qbasictimer.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickMouseEvent;
+class QQuickMouseArea;
+class QQuickMouseAreaPrivate : public QQuickItemPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickMouseArea)
+
+public:
+    QQuickMouseAreaPrivate();
+    ~QQuickMouseAreaPrivate();
+    void init();
+
+    void saveEvent(QMouseEvent *event);
+    enum PropagateType{
+        Click,
+        DoubleClick,
+        PressAndHold
+    };
+    void propagate(QQuickMouseEvent* event, PropagateType);
+    bool propagateHelper(QQuickMouseEvent*, QQuickItem*,const QPointF &, PropagateType);
+
+    bool isPressAndHoldConnected();
+    bool isDoubleClickConnected();
+    bool isClickConnected();
+
+    bool absorb : 1;
+    bool hovered : 1;
+    bool pressed : 1;
+    bool longPress : 1;
+    bool moved : 1;
+    bool dragX : 1;
+    bool dragY : 1;
+    bool stealMouse : 1;
+    bool doubleClick : 1;
+    bool preventStealing : 1;
+    QQuickDrag *drag;
+    QPointF startScene;
+    QPointF targetStartPos;
+    QPointF lastPos;
+    QDeclarativeNullableValue<QPointF> lastScenePos;
+    Qt::MouseButton lastButton;
+    Qt::MouseButtons lastButtons;
+    Qt::KeyboardModifiers lastModifiers;
+    QBasicTimer pressAndHoldTimer;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKMOUSEAREA_P_P_H
diff --git a/src/declarative/items/qquickninepatchnode.cpp b/src/declarative/items/qquickninepatchnode.cpp
new file mode 100644 (file)
index 0000000..2974725
--- /dev/null
@@ -0,0 +1,302 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qquickninepatchnode_p.h"
+#include <private/qsgadaptationlayer_p.h>
+#include <private/qmath_p.h>
+
+QQuickNinePatchNode::QQuickNinePatchNode()
+    : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0)
+    , m_horizontalTileMode(QQuickBorderImage::Stretch)
+    , m_verticalTileMode(QQuickBorderImage::Stretch)
+    , m_dirtyGeometry(false)
+    , m_mirror(false)
+{
+    setOpaqueMaterial(&m_material);
+    setMaterial(&m_materialO);
+    setGeometry(&m_geometry);
+    m_geometry.setDrawingMode(GL_TRIANGLES);
+#ifdef QML_RUNTIME_TESTING
+    description = QLatin1String("borderimage");
+#endif
+}
+
+void QQuickNinePatchNode::setInnerRect(const QRectF &rect)
+{
+    if (m_innerRect == rect)
+        return;
+    m_innerRect = rect;
+    m_dirtyGeometry = true;
+}
+
+void QQuickNinePatchNode::setRect(const QRectF &rect)
+{
+    if (m_targetRect == rect)
+        return;
+    m_targetRect = rect;
+    m_dirtyGeometry = true;
+}
+
+void QQuickNinePatchNode::setHorzontalTileMode(QQuickBorderImage::TileMode mode)
+{
+    if (mode == QQuickBorderImage::TileMode(m_horizontalTileMode))
+        return;
+    m_horizontalTileMode = mode;
+    m_dirtyGeometry = true;
+}
+
+
+void QQuickNinePatchNode::setVerticalTileMode(QQuickBorderImage::TileMode mode)
+{
+    if (mode == QQuickBorderImage::TileMode(m_verticalTileMode))
+        return;
+    m_verticalTileMode = mode;
+    m_dirtyGeometry = true;
+}
+
+
+void QQuickNinePatchNode::setFiltering(QSGTexture::Filtering filtering)
+{
+    if (m_material.filtering() == filtering)
+        return;
+
+    m_material.setFiltering(filtering);
+    m_materialO.setFiltering(filtering);
+    markDirty(DirtyMaterial);
+}
+
+QSGTexture::Filtering QQuickNinePatchNode::filtering() const
+{
+    return m_material.filtering();
+}
+
+void QQuickNinePatchNode::setTexture(QSGTexture *texture)
+{
+    if (texture == m_material.texture())
+        return;
+    m_material.setTexture(texture);
+    m_materialO.setTexture(texture);
+    markDirty(DirtyMaterial);
+}
+
+QSGTexture *QQuickNinePatchNode::texture() const
+{
+    return m_material.texture();
+}
+
+void QQuickNinePatchNode::setMirror(bool m)
+{
+    if (m_mirror == m)
+        return;
+    m_mirror = m;
+    m_dirtyGeometry = true;
+}
+
+
+void QQuickNinePatchNode::update()
+{
+    if (!m_dirtyGeometry)
+        return;
+
+    // For stretch this algorithm could be simplified to use less vertices
+    // as more vertices could be reused then, but I doubt its where our main
+    // problem will lie. This way, we at least share the algorithm between all
+
+    Q_ASSERT(m_material.texture());
+
+    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();
+
+//    qDebug() << m_innerRect << m_targetRect << m_horizontalTileMode << m_verticalTileMode;
+
+    int xChunkCount = 0; // Number of chunks
+    float xChunkSize = 0; // Size of chunk in pixels
+    float xTexSize = m_innerRect.width(); // Size of the texture to stretch/tile
+    float xSize = m_targetRect.width() - m_innerRect.left() - rightBorder; // Size of area to fill with chunks
+
+    if (m_horizontalTileMode == QQuickBorderImage::Repeat) {
+        xChunkCount = qCeil(xSize / xTexSize);
+        xChunkSize = xTexSize;
+    } else if (m_horizontalTileMode == QQuickBorderImage::Round) {
+        xChunkCount = qCeil(xSize / xTexSize);
+        qreal fullWidth = xChunkCount * xTexSize;
+        xChunkSize = xTexSize * xSize / fullWidth;
+    } else {
+        xChunkCount = 1;
+        xChunkSize = xSize;
+    }
+
+    int yChunkCount = 0;
+    float yChunkSize = 0; // Relative to target rect.
+    float yTexSize = m_innerRect.height(); // Size of the texture to stretch/tile
+    float ySize = m_targetRect.height() - m_innerRect.top() - bottomBorder;
+
+    if (m_verticalTileMode == QQuickBorderImage::Repeat) {
+        yChunkCount = qCeil(ySize / yTexSize);
+        yChunkSize = yTexSize;
+    } else if (m_verticalTileMode == QQuickBorderImage::Round) {
+        yChunkCount = qCeil(ySize / yTexSize);
+        qreal fullHeight = yChunkCount * yTexSize;
+        yChunkSize = yTexSize * ySize / fullHeight;
+    } else {
+        yChunkCount = 1;
+        yChunkSize = ySize;
+    }
+
+    int xTotalChunkCount = xChunkCount + 2;
+    int yTotalChunkCount = yChunkCount + 2;
+
+    int totalChunkCount = xTotalChunkCount * yTotalChunkCount;
+    int vertexCount = totalChunkCount * 4;
+    int indexCount = totalChunkCount * 6;
+
+    if (vertexCount != m_geometry.vertexCount() || indexCount != m_geometry.indexCount())
+        m_geometry.allocate(vertexCount, indexCount);
+
+    QSGGeometry::TexturedPoint2D *v = m_geometry.vertexDataAsTexturedPoint2D();
+
+
+    // Fill in the vertices.. The loop below is pretty much an exact replica
+    // of the one inside fillRow.
+    float yTexChunk1 = m_innerRect.top() / th;
+    float yTexChunk2 = m_innerRect.bottom() / th;
+
+    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, textureSubRect, textureSize);
+
+        // Special case the last one
+        if (yc == yChunkCount - 1) {
+            float t = m_verticalTileMode == QQuickBorderImage::Repeat
+                    ? yTexChunk1 + (yTexChunk2 - yTexChunk1) * (m_targetRect.height() - bottomBorder - yy) / yChunkSize
+                    : yTexChunk2;
+            fillRow(v, m_targetRect.height() - bottomBorder, t, xChunkCount, xChunkSize, textureSubRect, textureSize);
+        } else {
+            fillRow(v, yy + yChunkSize, yTexChunk2, xChunkCount, xChunkSize, textureSubRect, textureSize);
+        }
+    }
+
+    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();
+        for (int i=0; i<m_geometry.vertexCount(); ++i) {
+            v->x = m_targetRect.width() - v->x;
+            ++v;
+        }
+    }
+
+//    v = m_geometry.vertexDataAsTexturedPoint2D();
+//    for (int i=0; i<m_geometry.vertexCount(); ++i) {
+//        printf("Vertex: %d:  (%.3f, %.3f) - (%.3f, %.3f)\n",
+//               i,
+//               v->x, v->y, v->tx, v->ty);
+//        ++v;
+//    }
+
+    quint16 *i = m_geometry.indexDataAsUShort();
+    int row = xTotalChunkCount * 2;
+    for (int r=0; r<yTotalChunkCount; ++r) {
+        int offset = r * row * 2;
+        for (int c=0; c<xTotalChunkCount; ++c) {
+            *i++ = offset + c * 2;
+            *i++ = offset + c * 2 + 1;
+            *i++ = offset + c * 2 + row;
+            *i++ = offset + c * 2 + 1;
+            *i++ = offset + c * 2 + row + 1;
+            *i++ = offset + c * 2 + row;
+        }
+    }
+
+//    i = m_geometry.indexDataAsUShort();
+//    for (int idx=0; idx<m_geometry.indexCount(); idx+=6) {
+//        printf("%2d: ", idx / 6);
+//        for (int s=0; s<6; ++s)
+//            printf(" %d", i[idx + s]);
+//        printf("\n");
+//    }
+
+    markDirty(QSGNode::DirtyGeometry);
+}
+
+void QQuickNinePatchNode::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
+{
+    ty = tsr.y() + ty * tsr.width();
+
+    float tw = ts.width();
+    float rightBorder = tw - m_innerRect.right();
+    float xTexChunk1 = tsr.left() + tsr.width() * m_innerRect.left() / tw;
+    float xTexChunk2 = tsr.left() + tsr.width() * m_innerRect.right() / tw;
+
+    v++->set(0, y, tsr.left(), ty);
+    v++->set(m_innerRect.x(), y, xTexChunk1, ty);
+
+    for (int xc=0; xc<xChunkCount; ++xc) {
+        float xx = m_innerRect.x() + xChunkSize * xc;
+        v++->set(xx, y, xTexChunk1, ty);
+
+        // Special case the last one
+        if (xc == xChunkCount - 1) {
+            float t = m_horizontalTileMode == QQuickBorderImage::Repeat
+                    ? xTexChunk1 + (xTexChunk2 - xTexChunk1) * (m_targetRect.width() - rightBorder - xx) / xChunkSize
+                    : xTexChunk2;
+            v->set(m_targetRect.width() - rightBorder, y, t, ty);
+        } else {
+            v->set(xx + xChunkSize, y, xTexChunk2, ty);
+        }
+        ++v;
+    }
+
+    v++->set(m_targetRect.width() - rightBorder, y, xTexChunk2, ty);
+    v++->set(m_targetRect.width(), y, tsr.right(), ty);
+}
diff --git a/src/declarative/items/qquickninepatchnode_p.h b/src/declarative/items/qquickninepatchnode_p.h
new file mode 100644 (file)
index 0000000..cdb0fd8
--- /dev/null
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** 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 QQUICKNINEPATCHNODE_H
+#define QQUICKNINEPATCHNODE_H
+
+#include "qsgnode.h"
+#include "qsgtexturematerial.h"
+#include "qquickborderimage_p.h"
+
+class TextureReference;
+
+class QQuickNinePatchNode : public QSGGeometryNode
+{
+public:
+    QQuickNinePatchNode();
+
+    void setTexture(QSGTexture *texture);
+    QSGTexture *texture() const;
+
+    void setRect(const QRectF &rect);
+    QRectF rect() const { return m_targetRect; }
+
+    void setInnerRect(const QRectF &rect);
+    QRectF innerRect() const { return m_innerRect; }
+
+    void setFiltering(QSGTexture::Filtering filtering);
+    QSGTexture::Filtering filtering() const;
+
+    void setHorzontalTileMode(QQuickBorderImage::TileMode mode);
+    QQuickBorderImage::TileMode horizontalTileMode() const {
+        return (QQuickBorderImage::TileMode) m_horizontalTileMode;
+    }
+
+    void setVerticalTileMode(QQuickBorderImage::TileMode mode);
+    QQuickBorderImage::TileMode verticalTileMode() const {
+        return (QQuickBorderImage::TileMode) m_verticalTileMode;
+    }
+
+    void setMirror(bool m);
+    bool mirror() const { return m_mirror; }
+
+    void update();
+
+private:
+    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;
+    QSGTextureMaterial m_materialO;
+    QSGGeometry m_geometry;
+
+    uint m_horizontalTileMode : 2;
+    uint m_verticalTileMode : 2;
+
+    uint m_dirtyGeometry : 1;
+    uint m_mirror : 1;
+};
+
+#endif // QQUICKNINEPATCHNODE_H
diff --git a/src/declarative/items/qquickpainteditem.cpp b/src/declarative/items/qquickpainteditem.cpp
new file mode 100644 (file)
index 0000000..5e5eb79
--- /dev/null
@@ -0,0 +1,537 @@
+/****************************************************************************
+**
+** 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 "qquickpainteditem.h"
+#include <private/qquickpainteditem_p.h>
+
+#include <private/qsgpainternode_p.h>
+#include <private/qsgcontext_p.h>
+#include <private/qsgadaptationlayer_p.h>
+
+#include <qmath.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+    \class QQuickPaintedItem
+    \brief The QQuickPaintedItem class provides a way to use the QPainter API in the
+    QML Scene Graph.
+
+    \inmodule QtDeclarative
+
+    The QQuickPaintedItem 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.
+    When the render target is a QImage, QPainter first renders into the image then
+    the content is uploaded to the texture.
+    When a QOpenGLFramebufferObject is used, QPainter paints directly onto the texture.
+    Call update() to trigger a repaint.
+
+    To enable QPainter to do anti-aliased rendering, use setAntialiasing().
+
+    QQuickPaintedItem is meant to make it easier to port old code that is using the
+    QPainter API to the QML Scene Graph API and it should be used only for that purpose.
+
+    To write your own painted item, you first create a subclass of QQuickPaintedItem, and then
+    start by implementing its only pure virtual public function: paint(), which implements
+    the actual painting. To get the size of the area painted by the item, use
+    contentsBoundingRect().
+*/
+
+/*!
+    \enum QQuickPaintedItem::RenderTarget
+
+    This enum describes QQuickPaintedItem's render targets. The render target is the
+    surface QPainter paints onto before the item is rendered on screen.
+
+    \value Image The default; QPainter paints into a QImage using the raster paint engine.
+    The image's content needs to be uploaded to graphics memory afterward, this operation
+    can potentially be slow if the item is large. This render target allows high quality
+    anti-aliasing and fast item resizing.
+
+    \value FramebufferObject QPainter paints into a QOpenGLFramebufferObject using the GL
+    paint engine. Painting can be faster as no texture upload is required, but anti-aliasing
+    quality is not as good as if using an image. This render target allows faster rendering
+    in some cases, but you should avoid using it if the item is resized often.
+
+    \sa setRenderTarget()
+*/
+
+/*!
+    \enum QQuickPaintedItem::PerformanceHint
+
+    This enum describes flags that you can enable to improve rendering
+    performance in QQuickPaintedItem. By default, none of these flags are set.
+
+    \value FastFBOResizing If your item gets resized often and you are using the
+    QQuickPaintedItem::FramebufferObject render target, set this flag to true to reduce the
+    item resizing time at the cost of using more graphics memory. Resizing a Framebuffer object
+    is a costly operation, by enabling this property the Framebuffer Object will use a texture
+    larger than the actual size of the item to avoid as much as possible resizing it.
+*/
+
+/*!
+    \internal
+*/
+QQuickPaintedItemPrivate::QQuickPaintedItemPrivate()
+    : QQuickItemPrivate()
+    , contentsScale(1.0)
+    , fillColor(Qt::transparent)
+    , renderTarget(QQuickPaintedItem::Image)
+    , performanceHints(0)
+    , geometryDirty(false)
+    , contentsDirty(false)
+    , opaquePainting(false)
+    , antialiasing(false)
+    , mipmap(false)
+{
+}
+
+/*!
+    Constructs a QQuickPaintedItem with the given \a parent item.
+ */
+QQuickPaintedItem::QQuickPaintedItem(QQuickItem *parent)
+    : QQuickItem(*(new QQuickPaintedItemPrivate), parent)
+{
+    setFlag(ItemHasContents);
+}
+
+/*!
+    \internal
+*/
+QQuickPaintedItem::QQuickPaintedItem(QQuickPaintedItemPrivate &dd, QQuickItem *parent)
+    : QQuickItem(dd, parent)
+{
+    setFlag(ItemHasContents);
+}
+
+/*!
+    Destroys the QQuickPaintedItem.
+*/
+QQuickPaintedItem::~QQuickPaintedItem()
+{
+}
+
+/*!
+    Schedules a redraw of the area covered by \a rect in this item. You can call this function
+    whenever your item needs to be redrawn, such as if it changes appearance or size.
+
+    This function does not cause an immediate paint; instead it schedules a paint request that
+    is processed by the QML Scene Graph when the next frame is rendered. The item will only be
+    redrawn if it is visible.
+
+    Note that calling this function will trigger a repaint of the whole scene.
+
+    \sa paint()
+*/
+void QQuickPaintedItem::update(const QRect &rect)
+{
+    Q_D(QQuickPaintedItem);
+    d->contentsDirty = true;
+
+    if (rect.isNull() && !d->dirtyRect.isNull())
+        d->dirtyRect = contentsBoundingRect().toAlignedRect();
+    else
+        d->dirtyRect |= (contentsBoundingRect() & rect).toAlignedRect();
+    QQuickItem::update();
+}
+
+/*!
+    Returns true if this item is opaque; otherwise, false is returned.
+
+    By default, painted items are not opaque.
+
+    \sa setOpaquePainting()
+*/
+bool QQuickPaintedItem::opaquePainting() const
+{
+    Q_D(const QQuickPaintedItem);
+    return d->opaquePainting;
+}
+
+/*!
+    If \a opaque is true, the item is opaque; otherwise, it is considered as translucent.
+
+    Opaque items are not blended with the rest of the scene, you should set this to true
+    if the content of the item is opaque to speed up rendering.
+
+    By default, painted items are not opaque.
+
+    \sa opaquePainting()
+*/
+void QQuickPaintedItem::setOpaquePainting(bool opaque)
+{
+    Q_D(QQuickPaintedItem);
+
+    if (d->opaquePainting == opaque)
+        return;
+
+    d->opaquePainting = opaque;
+    QQuickItem::update();
+}
+
+/*!
+    Returns true if antialiased painting is enabled; otherwise, false is returned.
+
+    By default, antialiasing is not enabled.
+
+    \sa setAntialiasing()
+*/
+bool QQuickPaintedItem::antialiasing() const
+{
+    Q_D(const QQuickPaintedItem);
+    return d->antialiasing;
+}
+
+/*!
+    If \a enable is true, antialiased painting is enabled.
+
+    By default, antialiasing is not enabled.
+
+    \sa antialiasing()
+*/
+void QQuickPaintedItem::setAntialiasing(bool enable)
+{
+    Q_D(QQuickPaintedItem);
+
+    if (d->antialiasing == enable)
+        return;
+
+    d->antialiasing = enable;
+    update();
+}
+
+/*!
+    Returns true if mipmaps are enabled; otherwise, false is returned.
+
+    By default, mipmapping is not enabled.
+
+    \sa setMipmap()
+*/
+bool QQuickPaintedItem::mipmap() const
+{
+    Q_D(const QQuickPaintedItem);
+    return d->mipmap;
+}
+
+/*!
+    If \a enable is true, mipmapping is enabled on the associated texture.
+
+    Mipmapping increases rendering speed and reduces aliasing artifacts when the item is
+    scaled down.
+
+    By default, mipmapping is not enabled.
+
+    \sa mipmap()
+*/
+void QQuickPaintedItem::setMipmap(bool enable)
+{
+    Q_D(QQuickPaintedItem);
+
+    if (d->mipmap == enable)
+        return;
+
+    d->mipmap = enable;
+    update();
+}
+
+/*!
+    Returns the performance hints.
+
+    By default, no performance hint is enabled/
+
+    \sa setPerformanceHint(), setPerformanceHints()
+*/
+QQuickPaintedItem::PerformanceHints QQuickPaintedItem::performanceHints() const
+{
+    Q_D(const QQuickPaintedItem);
+    return d->performanceHints;
+}
+
+/*!
+    Sets the given performance \a hint on the item if \a enabled is true;
+    otherwise clears the performance hint.
+
+    By default, no performance hint is enabled/
+
+    \sa setPerformanceHints(), performanceHints()
+*/
+void QQuickPaintedItem::setPerformanceHint(QQuickPaintedItem::PerformanceHint hint, bool enabled)
+{
+    Q_D(QQuickPaintedItem);
+    PerformanceHints oldHints = d->performanceHints;
+    if (enabled)
+        d->performanceHints |= hint;
+    else
+        d->performanceHints &= ~hint;
+    if (oldHints != d->performanceHints)
+       update();
+}
+
+/*!
+    Sets the performance hints to \a hints
+
+    By default, no performance hint is enabled/
+
+    \sa setPerformanceHint(), performanceHints()
+*/
+void QQuickPaintedItem::setPerformanceHints(QQuickPaintedItem::PerformanceHints hints)
+{
+    Q_D(QQuickPaintedItem);
+    if (d->performanceHints == hints)
+        return;
+    d->performanceHints = hints;
+    update();
+}
+
+/*!
+    This function returns the outer bounds of the item as a rectangle; all painting must be
+    restricted to inside an item's bounding rect.
+
+    If the contents size has not been set it reflects the size of the item; otherwise
+    it reflects the contents size scaled by the contents scale.
+
+    Use this function to know the area painted by the item.
+
+    \sa QQuickItem::width(), QQuickItem::height(), contentsSize(), contentsScale()
+*/
+QRectF QQuickPaintedItem::contentsBoundingRect() const
+{
+    Q_D(const QQuickPaintedItem);
+
+    qreal w = d->width;
+    QSizeF sz = d->contentsSize * d->contentsScale;
+    if (w < sz.width())
+        w = sz.width();
+    qreal h = d->height;
+    if (h < sz.height())
+        h = sz.height();
+
+    return QRectF(0, 0, w, h);
+}
+
+/*!
+    \property QQuickPaintedItem::contentsSize
+    \brief The size of the contents
+
+    The contents size is the size of the item in regards to how it is painted
+    using the paint() function.  This is distinct from the size of the
+    item in regards to height() and width().
+*/
+QSize QQuickPaintedItem::contentsSize() const
+{
+    Q_D(const QQuickPaintedItem);
+    return d->contentsSize;
+}
+
+void QQuickPaintedItem::setContentsSize(const QSize &size)
+{
+    Q_D(QQuickPaintedItem);
+
+    if (d->contentsSize == size)
+        return;
+
+    d->contentsSize = size;
+    update();
+}
+
+/*!
+    This convenience function is equivalent to calling setContentsSize(QSize()).
+*/
+void QQuickPaintedItem::resetContentsSize()
+{
+    setContentsSize(QSize());
+}
+
+/*!
+    \property QQuickPaintedItem::contentsScale
+    \brief The scale of the contents
+
+    All painting happening in paint() is scaled by the contents scale. This is distinct
+    from the scale of the item in regards to scale().
+
+    The default value is 1.
+*/
+qreal QQuickPaintedItem::contentsScale() const
+{
+    Q_D(const QQuickPaintedItem);
+    return d->contentsScale;
+}
+
+void QQuickPaintedItem::setContentsScale(qreal scale)
+{
+    Q_D(QQuickPaintedItem);
+
+    if (d->contentsScale == scale)
+        return;
+
+    d->contentsScale = scale;
+    update();
+}
+
+/*!
+    \property QQuickPaintedItem::fillColor
+    \brief The item's background fill color.
+
+    By default, the fill color is set to Qt::transparent.
+*/
+QColor QQuickPaintedItem::fillColor() const
+{
+    Q_D(const QQuickPaintedItem);
+    return d->fillColor;
+}
+
+void QQuickPaintedItem::setFillColor(const QColor &c)
+{
+    Q_D(QQuickPaintedItem);
+
+    if (d->fillColor == c)
+        return;
+
+    d->fillColor = c;
+    update();
+
+    emit fillColorChanged();
+}
+
+/*!
+    \property QQuickPaintedItem::renderTarget
+    \brief The item's render target.
+
+    This property defines which render target the QPainter renders into, it can be either
+    QQuickPaintedItem::Image or QQuickPaintedItem::FramebufferObject. Both have certains benefits,
+    typically performance versus quality. Using a framebuffer object avoids a costly upload
+    of the image contents to the texture in graphics memory, while using an image enables
+    high quality anti-aliasing.
+
+    \warning Resizing a framebuffer object is a costly operation, avoid using
+    the QQuickPaintedItem::FramebufferObject render target if the item gets resized often.
+
+    By default, the render target is QQuickPaintedItem::Image.
+*/
+QQuickPaintedItem::RenderTarget QQuickPaintedItem::renderTarget() const
+{
+    Q_D(const QQuickPaintedItem);
+    return d->renderTarget;
+}
+
+void QQuickPaintedItem::setRenderTarget(RenderTarget target)
+{
+    Q_D(QQuickPaintedItem);
+
+    if (d->renderTarget == target)
+        return;
+
+    d->renderTarget = target;
+    update();
+
+    emit renderTargetChanged();
+}
+
+/*!
+    \fn virtual void QQuickPaintedItem::paint(QPainter *painter) = 0
+
+    This function, which is usually called by the QML Scene Graph, paints the
+    contents of an item in local coordinates.
+
+    The function is called after the item has been filled with the fillColor.
+
+    Reimplement this function in a QQuickPaintedItem subclass to provide the
+    item's painting implementation, using \a painter.
+
+    \note The QML Scene Graph uses two separate threads, the main thread does things such as
+    processing events or updating animations while a second thread does the actual OpenGL rendering.
+    As a consequence, paint() is not called from the main GUI thread but from the GL enabled
+    renderer thread. At the moment paint() is called, the GUI thread is blocked and this is
+    therefore thread-safe.
+*/
+
+/*!
+    This function is called after the item's geometry has changed.
+*/
+void QQuickPaintedItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+    Q_D(QQuickPaintedItem);
+    d->geometryDirty = true;
+    QQuickItem::geometryChanged(newGeometry, oldGeometry);
+}
+
+
+/*!
+    This function is called when the Scene Graph node associated to the item needs to
+    be updated.
+*/
+QSGNode *QQuickPaintedItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
+{
+    Q_UNUSED(data);
+    Q_D(QQuickPaintedItem);
+
+    if (width() <= 0 || height() <= 0) {
+        delete oldNode;
+        return 0;
+    }
+
+    QSGPainterNode *node = static_cast<QSGPainterNode *>(oldNode);
+    if (!node)
+        node = new QSGPainterNode(this);
+
+    QRectF br = contentsBoundingRect();
+
+    node->setPreferredRenderTarget(d->renderTarget);
+    node->setFastFBOResizing(d->performanceHints & FastFBOResizing);
+    node->setSize(QSize(qRound(br.width()), qRound(br.height())));
+    node->setSmoothPainting(d->antialiasing);
+    node->setLinearFiltering(d->smooth);
+    node->setMipmapping(d->mipmap);
+    node->setOpaquePainting(d->opaquePainting);
+    node->setFillColor(d->fillColor);
+    node->setContentsScale(d->contentsScale);
+    node->setDirty(d->contentsDirty || d->geometryDirty, d->dirtyRect);
+    node->update();
+
+    d->contentsDirty = false;
+    d->geometryDirty = false;
+    d->dirtyRect = QRect();
+
+    return node;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickpainteditem.h b/src/declarative/items/qquickpainteditem.h
new file mode 100644 (file)
index 0000000..5f461fd
--- /dev/null
@@ -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 QQUICKPAINTEDITEM_P_H
+#define QQUICKPAINTEDITEM_P_H
+
+#include <qquickitem.h>
+#include <QtGui/qcolor.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QQuickPaintedItemPrivate;
+class Q_DECLARATIVE_EXPORT QQuickPaintedItem : public QQuickItem
+{
+    Q_OBJECT
+    Q_ENUMS(RenderTarget)
+
+    Q_PROPERTY(QSize contentsSize READ contentsSize WRITE setContentsSize NOTIFY contentsSizeChanged)
+    Q_PROPERTY(QColor fillColor READ fillColor WRITE setFillColor NOTIFY fillColorChanged)
+    Q_PROPERTY(qreal contentsScale READ contentsScale WRITE setContentsScale NOTIFY contentsScaleChanged)
+    Q_PROPERTY(RenderTarget renderTarget READ renderTarget WRITE setRenderTarget NOTIFY renderTargetChanged)
+public:
+    QQuickPaintedItem(QQuickItem *parent = 0);
+    virtual ~QQuickPaintedItem();
+
+    enum RenderTarget {
+        Image,
+        FramebufferObject
+    };
+
+    enum PerformanceHint {
+        FastFBOResizing = 0x1
+    };
+    Q_DECLARE_FLAGS(PerformanceHints, PerformanceHint)
+
+    void update(const QRect &rect = QRect());
+
+    bool opaquePainting() const;
+    void setOpaquePainting(bool opaque);
+
+    bool antialiasing() const;
+    void setAntialiasing(bool enable);
+
+    bool mipmap() const;
+    void setMipmap(bool enable);
+
+    PerformanceHints performanceHints() const;
+    void setPerformanceHint(PerformanceHint hint, bool enabled = true);
+    void setPerformanceHints(PerformanceHints hints);
+
+    QRectF contentsBoundingRect() const;
+
+    QSize contentsSize() const;
+    void setContentsSize(const QSize &);
+    void resetContentsSize();
+
+    qreal contentsScale() const;
+    void setContentsScale(qreal);
+
+    QColor fillColor() const;
+    void setFillColor(const QColor&);
+
+    RenderTarget renderTarget() const;
+    void setRenderTarget(RenderTarget target);
+
+    virtual void paint(QPainter *painter) = 0;
+
+Q_SIGNALS:
+    void fillColorChanged();
+    void contentsSizeChanged();
+    void contentsScaleChanged();
+    void renderTargetChanged();
+
+protected:
+    QQuickPaintedItem(QQuickPaintedItemPrivate &dd, QQuickItem *parent = 0);
+    virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
+    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+
+private:
+    Q_DISABLE_COPY(QQuickPaintedItem)
+    Q_DECLARE_PRIVATE(QQuickPaintedItem)
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickPaintedItem::PerformanceHints)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QQUICKPAINTEDITEM_P_H
diff --git a/src/declarative/items/qquickpainteditem_p.h b/src/declarative/items/qquickpainteditem_p.h
new file mode 100644 (file)
index 0000000..00061d9
--- /dev/null
@@ -0,0 +1,73 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
+/****************************************************************************
+**
+** 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 QQUICKPAINTEDITEM_P_P_H
+#define QQUICKPAINTEDITEM_P_P_H
+
+#include "qquickitem_p.h"
+#include <QtGui/qcolor.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickPaintedItemPrivate : public QQuickItemPrivate
+{
+public:
+    QQuickPaintedItemPrivate();
+
+    QSize contentsSize;
+    qreal contentsScale;
+    QColor fillColor;
+    QQuickPaintedItem::RenderTarget renderTarget;
+    QQuickPaintedItem::PerformanceHints performanceHints;
+
+    QRect dirtyRect;
+
+    bool geometryDirty : 1;
+    bool contentsDirty : 1;
+    bool opaquePainting: 1;
+    bool antialiasing: 1;
+    bool mipmap: 1;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKPAINTEDITEM_P_P_H
diff --git a/src/declarative/items/qquickpathview.cpp b/src/declarative/items/qquickpathview.cpp
new file mode 100644 (file)
index 0000000..dc73bf2
--- /dev/null
@@ -0,0 +1,1738 @@
+/****************************************************************************
+**
+** 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 "qquickpathview_p.h"
+#include "qquickpathview_p_p.h"
+#include "qquickcanvas.h"
+
+#include <private/qdeclarativestate_p.h>
+#include <private/qdeclarativeopenmetaobject_p.h>
+#include <private/qlistmodelinterface_p.h>
+#include <private/qdeclarativechangeset_p.h>
+
+#include <QtGui/qevent.h>
+#include <QtGui/qevent.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qstylehints.h>
+#include <QtCore/qmath.h>
+#include <math.h>
+
+QT_BEGIN_NAMESPACE
+
+inline qreal qmlMod(qreal x, qreal y)
+{
+#ifdef QT_USE_MATH_H_FLOATS
+    if (sizeof(qreal) == sizeof(float))
+        return fmodf(float(x), float(y));
+    else
+#endif
+        return fmod(x, y);
+}
+
+static QDeclarativeOpenMetaObjectType *qPathViewAttachedType = 0;
+
+QQuickPathViewAttached::QQuickPathViewAttached(QObject *parent)
+: QObject(parent), m_percent(-1), m_view(0), m_onPath(false), m_isCurrent(false)
+{
+    if (qPathViewAttachedType) {
+        m_metaobject = new QDeclarativeOpenMetaObject(this, qPathViewAttachedType);
+        m_metaobject->setCached(true);
+    } else {
+        m_metaobject = new QDeclarativeOpenMetaObject(this);
+    }
+}
+
+QQuickPathViewAttached::~QQuickPathViewAttached()
+{
+}
+
+QVariant QQuickPathViewAttached::value(const QByteArray &name) const
+{
+    return m_metaobject->value(name);
+}
+void QQuickPathViewAttached::setValue(const QByteArray &name, const QVariant &val)
+{
+    m_metaobject->setValue(name, val);
+}
+
+
+void QQuickPathViewPrivate::init()
+{
+    Q_Q(QQuickPathView);
+    offset = 0;
+    q->setAcceptedMouseButtons(Qt::LeftButton);
+    q->setFlag(QQuickItem::ItemIsFocusScope);
+    q->setFiltersChildMouseEvents(true);
+    FAST_CONNECT(&tl, SIGNAL(updated()), q, SLOT(ticked()))
+    lastPosTime.invalidate();
+    FAST_CONNECT(&tl, SIGNAL(completed()), q, SLOT(movementEnding()))
+}
+
+QQuickItem *QQuickPathViewPrivate::getItem(int modelIndex, bool onPath)
+{
+    Q_Q(QQuickPathView);
+    requestedIndex = modelIndex;
+    QQuickItem *item = model->item(modelIndex, false);
+    if (item) {
+        if (!attType) {
+            // pre-create one metatype to share with all attached objects
+            attType = new QDeclarativeOpenMetaObjectType(&QQuickPathViewAttached::staticMetaObject, qmlEngine(q));
+            foreach (const QString &attr, path->attributes())
+                attType->createProperty(attr.toUtf8());
+        }
+        qPathViewAttachedType = attType;
+        QQuickPathViewAttached *att = static_cast<QQuickPathViewAttached *>(qmlAttachedPropertiesObject<QQuickPathView>(item));
+        qPathViewAttachedType = 0;
+        if (att) {
+            att->m_view = q;
+            att->setOnPath(onPath);
+        }
+        item->setParentItem(q);
+        QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+        itemPrivate->addItemChangeListener(this, QQuickItemPrivate::Geometry);
+    }
+    requestedIndex = -1;
+    return item;
+}
+
+void QQuickPathViewPrivate::releaseItem(QQuickItem *item)
+{
+    if (!item || !model)
+        return;
+    QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+    itemPrivate->removeItemChangeListener(this, QQuickItemPrivate::Geometry);
+    if (model->release(item) == 0) {
+        // item was not destroyed, and we no longer reference it.
+        if (QQuickPathViewAttached *att = attached(item))
+            att->setOnPath(false);
+    }
+}
+
+QQuickPathViewAttached *QQuickPathViewPrivate::attached(QQuickItem *item)
+{
+    return static_cast<QQuickPathViewAttached *>(qmlAttachedPropertiesObject<QQuickPathView>(item, false));
+}
+
+void QQuickPathViewPrivate::clear()
+{
+    if (currentItem) {
+        releaseItem(currentItem);
+        currentItem = 0;
+    }
+    for (int i=0; i<items.count(); i++){
+        QQuickItem *p = items[i];
+        releaseItem(p);
+    }
+    items.clear();
+}
+
+void QQuickPathViewPrivate::updateMappedRange()
+{
+    if (model && pathItems != -1 && pathItems < modelCount)
+        mappedRange = qreal(pathItems)/modelCount;
+    else
+        mappedRange = 1.0;
+}
+
+qreal QQuickPathViewPrivate::positionOfIndex(qreal index) const
+{
+    qreal pos = -1.0;
+
+    if (model && index >= 0 && index < modelCount) {
+        qreal start = 0.0;
+        if (haveHighlightRange && highlightRangeMode != QQuickPathView::NoHighlightRange)
+            start = highlightRangeStart;
+        qreal globalPos = index + offset;
+        globalPos = qmlMod(globalPos, qreal(modelCount)) / modelCount;
+        if (pathItems != -1 && pathItems < modelCount) {
+            globalPos += start * mappedRange;
+            globalPos = qmlMod(globalPos, 1.0);
+            if (globalPos < mappedRange)
+                pos = globalPos / mappedRange;
+        } else {
+            pos = qmlMod(globalPos + start, 1.0);
+        }
+    }
+
+    return pos;
+}
+
+void QQuickPathViewPrivate::createHighlight()
+{
+    Q_Q(QQuickPathView);
+    if (!q->isComponentComplete())
+        return;
+
+    bool changed = false;
+    if (highlightItem) {
+        highlightItem->setParentItem(0);
+        highlightItem->deleteLater();
+        highlightItem = 0;
+        changed = true;
+    }
+
+    QQuickItem *item = 0;
+    if (highlightComponent) {
+        QDeclarativeContext *creationContext = highlightComponent->creationContext();
+        QDeclarativeContext *highlightContext = new QDeclarativeContext(
+                creationContext ? creationContext : qmlContext(q));
+        QObject *nobj = highlightComponent->create(highlightContext);
+        if (nobj) {
+            QDeclarative_setParent_noEvent(highlightContext, nobj);
+            item = qobject_cast<QQuickItem *>(nobj);
+            if (!item)
+                delete nobj;
+        } else {
+            delete highlightContext;
+        }
+    } else {
+        item = new QQuickItem;
+    }
+    if (item) {
+        QDeclarative_setParent_noEvent(item, q);
+        item->setParentItem(q);
+        highlightItem = item;
+        changed = true;
+    }
+    if (changed)
+        emit q->highlightItemChanged();
+}
+
+void QQuickPathViewPrivate::updateHighlight()
+{
+    Q_Q(QQuickPathView);
+    if (!q->isComponentComplete() || !isValid())
+        return;
+    if (highlightItem) {
+        if (haveHighlightRange && highlightRangeMode == QQuickPathView::StrictlyEnforceRange) {
+            updateItem(highlightItem, highlightRangeStart);
+        } else {
+            qreal target = currentIndex;
+
+            offsetAdj = 0.0;
+            tl.reset(moveHighlight);
+            moveHighlight.setValue(highlightPosition);
+
+            const int duration = highlightMoveDuration;
+
+            if (target - highlightPosition > modelCount/2) {
+                highlightUp = false;
+                qreal distance = modelCount - target + highlightPosition;
+                tl.move(moveHighlight, 0.0, QEasingCurve(QEasingCurve::InQuad), int(duration * highlightPosition / distance));
+                tl.set(moveHighlight, modelCount-0.01);
+                tl.move(moveHighlight, target, QEasingCurve(QEasingCurve::OutQuad), int(duration * (modelCount-target) / distance));
+            } else if (target - highlightPosition <= -modelCount/2) {
+                highlightUp = true;
+                qreal distance = modelCount - highlightPosition + target;
+                tl.move(moveHighlight, modelCount-0.01, QEasingCurve(QEasingCurve::InQuad), int(duration * (modelCount-highlightPosition) / distance));
+                tl.set(moveHighlight, 0.0);
+                tl.move(moveHighlight, target, QEasingCurve(QEasingCurve::OutQuad), int(duration * target / distance));
+            } else {
+                highlightUp = highlightPosition - target < 0;
+                tl.move(moveHighlight, target, QEasingCurve(QEasingCurve::InOutQuad), duration);
+            }
+        }
+    }
+}
+
+void QQuickPathViewPrivate::setHighlightPosition(qreal pos)
+{
+    if (pos != highlightPosition) {
+        qreal start = 0.0;
+        qreal end = 1.0;
+        if (haveHighlightRange && highlightRangeMode != QQuickPathView::NoHighlightRange) {
+            start = highlightRangeStart;
+            end = highlightRangeEnd;
+        }
+
+        qreal range = qreal(modelCount);
+        // calc normalized position of highlight relative to offset
+        qreal relativeHighlight = qmlMod(pos + offset, range) / range;
+
+        if (!highlightUp && relativeHighlight > end * mappedRange) {
+            qreal diff = 1.0 - relativeHighlight;
+            setOffset(offset + diff * range);
+        } else if (highlightUp && relativeHighlight >= (end - start) * mappedRange) {
+            qreal diff = relativeHighlight - (end - start) * mappedRange;
+            setOffset(offset - diff * range - 0.00001);
+        }
+
+        highlightPosition = pos;
+        qreal pathPos = positionOfIndex(pos);
+        updateItem(highlightItem, pathPos);
+        if (QQuickPathViewAttached *att = attached(highlightItem))
+            att->setOnPath(pathPos != -1.0);
+    }
+}
+
+void QQuickPathView::pathUpdated()
+{
+    Q_D(QQuickPathView);
+    QList<QQuickItem*>::iterator it = d->items.begin();
+    while (it != d->items.end()) {
+        QQuickItem *item = *it;
+        if (QQuickPathViewAttached *att = d->attached(item))
+            att->m_percent = -1;
+        ++it;
+    }
+    refill();
+}
+
+void QQuickPathViewPrivate::updateItem(QQuickItem *item, qreal percent)
+{
+    if (QQuickPathViewAttached *att = attached(item)) {
+        if (qFuzzyCompare(att->m_percent, percent))
+            return;
+        att->m_percent = percent;
+        foreach (const QString &attr, path->attributes())
+            att->setValue(attr.toUtf8(), path->attributeAt(attr, percent));
+    }
+    QPointF pf = path->pointAt(percent);
+    item->setX(qRound(pf.x() - item->width()/2));
+    item->setY(qRound(pf.y() - item->height()/2));
+}
+
+void QQuickPathViewPrivate::regenerate()
+{
+    Q_Q(QQuickPathView);
+    if (!q->isComponentComplete())
+        return;
+
+    clear();
+
+    if (!isValid())
+        return;
+
+    firstIndex = -1;
+    updateMappedRange();
+    q->refill();
+}
+
+/*!
+    \qmlclass PathView QQuickPathView
+    \inqmlmodule QtQuick 2
+    \ingroup qml-view-elements
+    \brief The PathView element lays out model-provided items on a path.
+    \inherits Item
+
+    A PathView displays data from models created from built-in QML elements like ListModel
+    and XmlListModel, or custom model classes defined in C++ that inherit from
+    QAbstractListModel.
+
+    The view has a \l model, which defines the data to be displayed, and
+    a \l delegate, which defines how the data should be displayed.
+    The \l delegate is instantiated for each item on the \l path.
+    The items may be flicked to move them along the path.
+
+    For example, if there is a simple list model defined in a file \c ContactModel.qml like this:
+
+    \snippet doc/src/snippets/declarative/pathview/ContactModel.qml 0
+
+    This data can be represented as a PathView, like this:
+
+    \snippet doc/src/snippets/declarative/pathview/pathview.qml 0
+
+    \image pathview.gif
+
+    (Note the above example uses PathAttribute to scale and modify the
+    opacity of the items as they rotate. This additional code can be seen in the
+    PathAttribute documentation.)
+
+    PathView does not automatically handle keyboard navigation.  This is because
+    the keys to use for navigation will depend upon the shape of the path.  Navigation
+    can be added quite simply by setting \c focus to \c true and calling
+    \l decrementCurrentIndex() or \l incrementCurrentIndex(), for example to navigate
+    using the left and right arrow keys:
+
+    \qml
+    PathView {
+        // ...
+        focus: true
+        Keys.onLeftPressed: decrementCurrentIndex()
+        Keys.onRightPressed: incrementCurrentIndex()
+    }
+    \endqml
+
+    The path view itself is a focus scope (see \l{qmlfocus#Acquiring Focus and Focus Scopes}{the focus documentation page} for more details).
+
+    Delegates are instantiated as needed and may be destroyed at any time.
+    State should \e never be stored in a delegate.
+
+    PathView attaches a number of properties to the root item of the delegate, for example
+    \c {PathView.isCurrentItem}.  In the following example, the root delegate item can access
+    this attached property directly as \c PathView.isCurrentItem, while the child
+    \c nameText object must refer to this property as \c wrapper.PathView.isCurrentItem.
+
+    \snippet doc/src/snippets/declarative/pathview/pathview.qml 1
+
+    \bold Note that views do not enable \e clip automatically.  If the view
+    is not clipped by another item or the screen, it will be necessary
+    to set \e {clip: true} in order to have the out of view items clipped
+    nicely.
+
+    \sa Path, {declarative/modelviews/pathview}{PathView example}
+*/
+
+QQuickPathView::QQuickPathView(QQuickItem *parent)
+  : QQuickItem(*(new QQuickPathViewPrivate), parent)
+{
+    Q_D(QQuickPathView);
+    d->init();
+}
+
+QQuickPathView::~QQuickPathView()
+{
+    Q_D(QQuickPathView);
+    d->clear();
+    if (d->attType)
+        d->attType->release();
+    if (d->ownModel)
+        delete d->model;
+}
+
+/*!
+    \qmlattachedproperty PathView QtQuick2::PathView::view
+    This attached property holds the view that manages this delegate instance.
+
+    It is attached to each instance of the delegate.
+*/
+
+/*!
+    \qmlattachedproperty bool QtQuick2::PathView::onPath
+    This attached property holds whether the item is currently on the path.
+
+    If a pathItemCount has been set, it is possible that some items may
+    be instantiated, but not considered to be currently on the path.
+    Usually, these items would be set invisible, for example:
+
+    \qml
+    Component {
+        Rectangle {
+            visible: PathView.onPath
+            // ...
+        }
+    }
+    \endqml
+
+    It is attached to each instance of the delegate.
+*/
+
+/*!
+    \qmlattachedproperty bool QtQuick2::PathView::isCurrentItem
+    This attached property is true if this delegate is the current item; otherwise false.
+
+    It is attached to each instance of the delegate.
+
+    This property may be used to adjust the appearance of the current item.
+
+    \snippet doc/src/snippets/declarative/pathview/pathview.qml 1
+*/
+
+/*!
+    \qmlproperty model QtQuick2::PathView::model
+    This property holds the model providing data for the view.
+
+    The model provides a set of data that is used to create the items for the view.
+    For large or dynamic datasets the model is usually provided by a C++ model object.
+    Models can also be created directly in QML, using the ListModel element.
+
+    \sa {qmlmodels}{Data Models}
+*/
+QVariant QQuickPathView::model() const
+{
+    Q_D(const QQuickPathView);
+    return d->modelVariant;
+}
+
+void QQuickPathView::setModel(const QVariant &model)
+{
+    Q_D(QQuickPathView);
+    if (d->modelVariant == model)
+        return;
+
+    if (d->model) {
+        disconnect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
+                this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
+        disconnect(d->model, SIGNAL(createdItem(int,QQuickItem*)), this, SLOT(createdItem(int,QQuickItem*)));
+        for (int i=0; i<d->items.count(); i++){
+            QQuickItem *p = d->items[i];
+            d->model->release(p);
+        }
+        d->items.clear();
+    }
+
+    d->modelVariant = model;
+    QObject *object = qvariant_cast<QObject*>(model);
+    QQuickVisualModel *vim = 0;
+    if (object && (vim = qobject_cast<QQuickVisualModel *>(object))) {
+        if (d->ownModel) {
+            delete d->model;
+            d->ownModel = false;
+        }
+        d->model = vim;
+    } else {
+        if (!d->ownModel) {
+            d->model = new QQuickVisualDataModel(qmlContext(this));
+            d->ownModel = true;
+            if (isComponentComplete())
+                static_cast<QQuickVisualDataModel *>(d->model.data())->componentComplete();
+        }
+        if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model))
+            dataModel->setModel(model);
+    }
+    d->modelCount = 0;
+    if (d->model) {
+        connect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
+                this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
+        connect(d->model, SIGNAL(createdItem(int,QQuickItem*)), this, SLOT(createdItem(int,QQuickItem*)));
+        d->modelCount = d->model->count();
+        if (d->model->count())
+            d->offset = qmlMod(d->offset, qreal(d->model->count()));
+        if (d->offset < 0)
+            d->offset = d->model->count() + d->offset;
+}
+    d->regenerate();
+    if (d->currentIndex < d->modelCount)
+        setOffset(qmlMod(d->modelCount - d->currentIndex, d->modelCount));
+    else
+        d->fixOffset();
+    emit countChanged();
+    emit modelChanged();
+}
+
+/*!
+    \qmlproperty int QtQuick2::PathView::count
+    This property holds the number of items in the model.
+*/
+int QQuickPathView::count() const
+{
+    Q_D(const QQuickPathView);
+    return d->model ? d->modelCount : 0;
+}
+
+/*!
+    \qmlproperty Path QtQuick2::PathView::path
+    This property holds the path used to lay out the items.
+    For more information see the \l Path documentation.
+*/
+QDeclarativePath *QQuickPathView::path() const
+{
+    Q_D(const QQuickPathView);
+    return d->path;
+}
+
+void QQuickPathView::setPath(QDeclarativePath *path)
+{
+    Q_D(QQuickPathView);
+    if (d->path == path)
+        return;
+    if (d->path)
+        disconnect(d->path, SIGNAL(changed()), this, SLOT(pathUpdated()));
+    d->path = path;
+    connect(d->path, SIGNAL(changed()), this, SLOT(pathUpdated()));
+    if (d->isValid() && isComponentComplete()) {
+        d->clear();
+        if (d->attType) {
+            d->attType->release();
+            d->attType = 0;
+        }
+        d->regenerate();
+    }
+    emit pathChanged();
+}
+
+/*!
+    \qmlproperty int QtQuick2::PathView::currentIndex
+    This property holds the index of the current item.
+*/
+int QQuickPathView::currentIndex() const
+{
+    Q_D(const QQuickPathView);
+    return d->currentIndex;
+}
+
+void QQuickPathView::setCurrentIndex(int idx)
+{
+    Q_D(QQuickPathView);
+    if (d->model && d->modelCount)
+        idx = qAbs(idx % d->modelCount);
+    if (d->model && idx != d->currentIndex) {
+        if (d->currentItem) {
+            if (QQuickPathViewAttached *att = d->attached(d->currentItem))
+                att->setIsCurrentItem(false);
+            d->releaseItem(d->currentItem);
+        }
+        d->currentItem = 0;
+        d->moveReason = QQuickPathViewPrivate::SetIndex;
+        d->currentIndex = idx;
+        if (d->modelCount) {
+            int itemIndex = (idx - d->firstIndex + d->modelCount) % d->modelCount;
+            if (itemIndex < d->items.count()) {
+                d->currentItem = d->model->item(d->currentIndex, true);
+                d->currentItem->setFocus(true);
+                if (QQuickPathViewAttached *att = d->attached(d->currentItem))
+                    att->setIsCurrentItem(true);
+            } else {
+                d->currentItem = d->getItem(d->currentIndex, false);
+                d->updateItem(d->currentItem, d->currentIndex < d->firstIndex ? 0.0 : 1.0);
+                if (QQuickPathViewAttached *att = d->attached(d->currentItem))
+                    att->setIsCurrentItem(true);
+                if (d->model->completePending())
+                    d->model->completeItem();
+            }
+            if (d->haveHighlightRange && d->highlightRangeMode == QQuickPathView::StrictlyEnforceRange)
+                d->snapToCurrent();
+            d->currentItemOffset = d->positionOfIndex(d->currentIndex);
+            d->updateHighlight();
+        }
+        emit currentIndexChanged();
+    }
+}
+
+QQuickItem *QQuickPathView::currentItem() const
+{
+    Q_D(const QQuickPathView);
+    return d->currentItem;
+}
+
+/*!
+    \qmlmethod QtQuick2::PathView::incrementCurrentIndex()
+
+    Increments the current index.
+
+    \bold Note: methods should only be called after the Component has completed.
+*/
+void QQuickPathView::incrementCurrentIndex()
+{
+    Q_D(QQuickPathView);
+    d->moveDirection = QQuickPathViewPrivate::Positive;
+    setCurrentIndex(currentIndex()+1);
+}
+
+/*!
+    \qmlmethod QtQuick2::PathView::decrementCurrentIndex()
+
+    Decrements the current index.
+
+    \bold Note: methods should only be called after the Component has completed.
+*/
+void QQuickPathView::decrementCurrentIndex()
+{
+    Q_D(QQuickPathView);
+    if (d->model && d->modelCount) {
+        int idx = currentIndex()-1;
+        if (idx < 0)
+            idx = d->modelCount - 1;
+        d->moveDirection = QQuickPathViewPrivate::Negative;
+        setCurrentIndex(idx);
+    }
+}
+
+/*!
+    \qmlproperty real QtQuick2::PathView::offset
+
+    The offset specifies how far along the path the items are from their initial positions.
+    This is a real number that ranges from 0.0 to the count of items in the model.
+*/
+qreal QQuickPathView::offset() const
+{
+    Q_D(const QQuickPathView);
+    return d->offset;
+}
+
+void QQuickPathView::setOffset(qreal offset)
+{
+    Q_D(QQuickPathView);
+    d->setOffset(offset);
+    d->updateCurrent();
+}
+
+void QQuickPathViewPrivate::setOffset(qreal o)
+{
+    Q_Q(QQuickPathView);
+    if (offset != o) {
+        if (isValid() && q->isComponentComplete()) {
+            offset = qmlMod(o, qreal(modelCount));
+            if (offset < 0)
+                offset += qreal(modelCount);
+            q->refill();
+        } else {
+            offset = o;
+        }
+        emit q->offsetChanged();
+    }
+}
+
+void QQuickPathViewPrivate::setAdjustedOffset(qreal o)
+{
+    setOffset(o+offsetAdj);
+}
+
+/*!
+    \qmlproperty Component QtQuick2::PathView::highlight
+    This property holds the component to use as the highlight.
+
+    An instance of the highlight component will be created for each view.
+    The geometry of the resultant component instance will be managed by the view
+    so as to stay with the current item.
+
+    The below example demonstrates how to make a simple highlight.  Note the use
+    of the \l{PathView::onPath}{PathView.onPath} attached property to ensure that
+    the highlight is hidden when flicked away from the path.
+
+    \qml
+    Component {
+        Rectangle {
+            visible: PathView.onPath
+            // ...
+        }
+    }
+    \endqml
+
+    \sa highlightItem, highlightRangeMode
+*/
+
+QDeclarativeComponent *QQuickPathView::highlight() const
+{
+    Q_D(const QQuickPathView);
+    return d->highlightComponent;
+}
+
+void QQuickPathView::setHighlight(QDeclarativeComponent *highlight)
+{
+    Q_D(QQuickPathView);
+    if (highlight != d->highlightComponent) {
+        d->highlightComponent = highlight;
+        d->createHighlight();
+        d->updateHighlight();
+        emit highlightChanged();
+    }
+}
+
+/*!
+  \qmlproperty Item QtQuick2::PathView::highlightItem
+
+  \c highlightItem holds the highlight item, which was created
+  from the \l highlight component.
+
+  \sa highlight
+*/
+QQuickItem *QQuickPathView::highlightItem()
+{
+    Q_D(const QQuickPathView);
+    return d->highlightItem;
+}
+/*!
+    \qmlproperty real QtQuick2::PathView::preferredHighlightBegin
+    \qmlproperty real QtQuick2::PathView::preferredHighlightEnd
+    \qmlproperty enumeration QtQuick2::PathView::highlightRangeMode
+
+    These properties set the preferred range of the highlight (current item)
+    within the view.  The preferred values must be in the range 0.0-1.0.
+
+    If highlightRangeMode is set to \e PathView.NoHighlightRange
+
+    If highlightRangeMode is set to \e PathView.ApplyRange the view will
+    attempt to maintain the highlight within the range, however
+    the highlight can move outside of the range at the ends of the path
+    or due to a mouse interaction.
+
+    If highlightRangeMode is set to \e PathView.StrictlyEnforceRange the highlight will never
+    move outside of the range.  This means that the current item will change
+    if a keyboard or mouse action would cause the highlight to move
+    outside of the range.
+
+    Note that this is the correct way to influence where the
+    current item ends up when the view moves. For example, if you want the
+    currently selected item to be in the middle of the path, then set the
+    highlight range to be 0.5,0.5 and highlightRangeMode to PathView.StrictlyEnforceRange.
+    Then, when the path scrolls,
+    the currently selected item will be the item at that position. This also applies to
+    when the currently selected item changes - it will scroll to within the preferred
+    highlight range. Furthermore, the behaviour of the current item index will occur
+    whether or not a highlight exists.
+
+    The default value is \e PathView.StrictlyEnforceRange.
+
+    Note that a valid range requires preferredHighlightEnd to be greater
+    than or equal to preferredHighlightBegin.
+*/
+qreal QQuickPathView::preferredHighlightBegin() const
+{
+    Q_D(const QQuickPathView);
+    return d->highlightRangeStart;
+}
+
+void QQuickPathView::setPreferredHighlightBegin(qreal start)
+{
+    Q_D(QQuickPathView);
+    if (d->highlightRangeStart == start || start < 0 || start > 1.0)
+        return;
+    d->highlightRangeStart = start;
+    d->haveHighlightRange = d->highlightRangeMode != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
+    refill();
+    emit preferredHighlightBeginChanged();
+}
+
+qreal QQuickPathView::preferredHighlightEnd() const
+{
+    Q_D(const QQuickPathView);
+    return d->highlightRangeEnd;
+}
+
+void QQuickPathView::setPreferredHighlightEnd(qreal end)
+{
+    Q_D(QQuickPathView);
+    if (d->highlightRangeEnd == end || end < 0 || end > 1.0)
+        return;
+    d->highlightRangeEnd = end;
+    d->haveHighlightRange = d->highlightRangeMode != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
+    refill();
+    emit preferredHighlightEndChanged();
+}
+
+QQuickPathView::HighlightRangeMode QQuickPathView::highlightRangeMode() const
+{
+    Q_D(const QQuickPathView);
+    return d->highlightRangeMode;
+}
+
+void QQuickPathView::setHighlightRangeMode(HighlightRangeMode mode)
+{
+    Q_D(QQuickPathView);
+    if (d->highlightRangeMode == mode)
+        return;
+    d->highlightRangeMode = mode;
+    d->haveHighlightRange = d->highlightRangeMode != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
+    emit highlightRangeModeChanged();
+}
+
+/*!
+    \qmlproperty int QtQuick2::PathView::highlightMoveDuration
+    This property holds the move animation duration of the highlight delegate.
+
+    If the highlightRangeMode is StrictlyEnforceRange then this property
+    determines the speed that the items move along the path.
+
+    The default value for the duration is 300ms.
+*/
+int QQuickPathView::highlightMoveDuration() const
+{
+    Q_D(const QQuickPathView);
+    return d->highlightMoveDuration;
+}
+
+void QQuickPathView::setHighlightMoveDuration(int duration)
+{
+    Q_D(QQuickPathView);
+    if (d->highlightMoveDuration == duration)
+        return;
+    d->highlightMoveDuration = duration;
+    emit highlightMoveDurationChanged();
+}
+
+/*!
+    \qmlproperty real QtQuick2::PathView::dragMargin
+    This property holds the maximum distance from the path that initiate mouse dragging.
+
+    By default the path can only be dragged by clicking on an item.  If
+    dragMargin is greater than zero, a drag can be initiated by clicking
+    within dragMargin pixels of the path.
+*/
+qreal QQuickPathView::dragMargin() const
+{
+    Q_D(const QQuickPathView);
+    return d->dragMargin;
+}
+
+void QQuickPathView::setDragMargin(qreal dragMargin)
+{
+    Q_D(QQuickPathView);
+    if (d->dragMargin == dragMargin)
+        return;
+    d->dragMargin = dragMargin;
+    emit dragMarginChanged();
+}
+
+/*!
+    \qmlproperty real QtQuick2::PathView::flickDeceleration
+    This property holds the rate at which a flick will decelerate.
+
+    The default is 100.
+*/
+qreal QQuickPathView::flickDeceleration() const
+{
+    Q_D(const QQuickPathView);
+    return d->deceleration;
+}
+
+void QQuickPathView::setFlickDeceleration(qreal dec)
+{
+    Q_D(QQuickPathView);
+    if (d->deceleration == dec)
+        return;
+    d->deceleration = dec;
+    emit flickDecelerationChanged();
+}
+
+/*!
+    \qmlproperty bool QtQuick2::PathView::interactive
+
+    A user cannot drag or flick a PathView that is not interactive.
+
+    This property is useful for temporarily disabling flicking. This allows
+    special interaction with PathView's children.
+*/
+bool QQuickPathView::isInteractive() const
+{
+    Q_D(const QQuickPathView);
+    return d->interactive;
+}
+
+void QQuickPathView::setInteractive(bool interactive)
+{
+    Q_D(QQuickPathView);
+    if (interactive != d->interactive) {
+        d->interactive = interactive;
+        if (!interactive)
+            d->tl.clear();
+        emit interactiveChanged();
+    }
+}
+
+/*!
+    \qmlproperty bool QtQuick2::PathView::moving
+
+    This property holds whether the view is currently moving
+    due to the user either dragging or flicking the view.
+*/
+bool QQuickPathView::isMoving() const
+{
+    Q_D(const QQuickPathView);
+    return d->moving;
+}
+
+/*!
+    \qmlproperty bool QtQuick2::PathView::flicking
+
+    This property holds whether the view is currently moving
+    due to the user flicking the view.
+*/
+bool QQuickPathView::isFlicking() const
+{
+    Q_D(const QQuickPathView);
+    return d->flicking;
+}
+
+/*!
+    \qmlsignal QtQuick2::PathView::onMovementStarted()
+
+    This handler is called when the view begins moving due to user
+    interaction.
+*/
+
+/*!
+    \qmlsignal QtQuick2::PathView::onMovementEnded()
+
+    This handler is called when the view stops moving due to user
+    interaction.  If a flick was generated, this handler will
+    be triggered once the flick stops.  If a flick was not
+    generated, the handler will be triggered when the
+    user stops dragging - i.e. a mouse or touch release.
+*/
+
+/*!
+    \qmlsignal QtQuick2::PathView::onFlickStarted()
+
+    This handler is called when the view is flicked.  A flick
+    starts from the point that the mouse or touch is released,
+    while still in motion.
+*/
+
+/*!
+    \qmlsignal QtQuick2::PathView::onFlickEnded()
+
+    This handler is called when the view stops moving due to a flick.
+*/
+
+/*!
+    \qmlproperty Component QtQuick2::PathView::delegate
+
+    The delegate provides a template defining each item instantiated by the view.
+    The index is exposed as an accessible \c index property.  Properties of the
+    model are also available depending upon the type of \l {qmlmodels}{Data Model}.
+
+    The number of elements in the delegate has a direct effect on the
+    flicking performance of the view when pathItemCount is specified.  If at all possible, place functionality
+    that is not needed for the normal display of the delegate in a \l Loader which
+    can load additional elements when needed.
+
+    Note that the PathView will layout the items based on the size of the root
+    item in the delegate.
+
+    Here is an example delegate:
+    \snippet doc/src/snippets/declarative/pathview/pathview.qml 1
+*/
+QDeclarativeComponent *QQuickPathView::delegate() const
+{
+    Q_D(const QQuickPathView);
+     if (d->model) {
+        if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model))
+            return dataModel->delegate();
+    }
+
+    return 0;
+}
+
+void QQuickPathView::setDelegate(QDeclarativeComponent *delegate)
+{
+    Q_D(QQuickPathView);
+    if (delegate == this->delegate())
+        return;
+    if (!d->ownModel) {
+        d->model = new QQuickVisualDataModel(qmlContext(this));
+        d->ownModel = true;
+    }
+    if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model)) {
+        int oldCount = dataModel->count();
+        dataModel->setDelegate(delegate);
+        d->modelCount = dataModel->count();
+        d->regenerate();
+        if (oldCount != dataModel->count())
+            emit countChanged();
+        emit delegateChanged();
+    }
+}
+
+/*!
+  \qmlproperty int QtQuick2::PathView::pathItemCount
+  This property holds the number of items visible on the path at any one time.
+*/
+int QQuickPathView::pathItemCount() const
+{
+    Q_D(const QQuickPathView);
+    return d->pathItems;
+}
+
+void QQuickPathView::setPathItemCount(int i)
+{
+    Q_D(QQuickPathView);
+    if (i == d->pathItems)
+        return;
+    if (i < 1)
+        i = 1;
+    d->pathItems = i;
+    d->updateMappedRange();
+    if (d->isValid() && isComponentComplete()) {
+        d->regenerate();
+    }
+    emit pathItemCountChanged();
+}
+
+QPointF QQuickPathViewPrivate::pointNear(const QPointF &point, qreal *nearPercent) const
+{
+    //XXX maybe do recursively at increasing resolution.
+    qreal mindist = 1e10; // big number
+    QPointF nearPoint = path->pointAt(0);
+    qreal nearPc = 0;
+    for (qreal i=1; i < 1000; i++) {
+        QPointF pt = path->pointAt(i/1000.0);
+        QPointF diff = pt - point;
+        qreal dist = diff.x()*diff.x() + diff.y()*diff.y();
+        if (dist < mindist) {
+            nearPoint = pt;
+            nearPc = i;
+            mindist = dist;
+        }
+    }
+
+    if (nearPercent)
+        *nearPercent = nearPc / 1000.0;
+
+    return nearPoint;
+}
+
+void QQuickPathView::mousePressEvent(QMouseEvent *event)
+{
+    Q_D(QQuickPathView);
+    if (d->interactive) {
+        d->handleMousePressEvent(event);
+        event->accept();
+    } else {
+        QQuickItem::mousePressEvent(event);
+    }
+}
+
+void QQuickPathViewPrivate::handleMousePressEvent(QMouseEvent *event)
+{
+    Q_Q(QQuickPathView);
+    if (!interactive || !items.count())
+        return;
+    QPointF scenePoint = q->mapToScene(event->localPos());
+    int idx = 0;
+    for (; idx < items.count(); ++idx) {
+        QRectF rect = items.at(idx)->boundingRect();
+        rect = items.at(idx)->mapRectToScene(rect);
+        if (rect.contains(scenePoint))
+            break;
+    }
+    if (idx == items.count() && dragMargin == 0.)  // didn't click on an item
+        return;
+
+    startPoint = pointNear(event->localPos(), &startPc);
+    if (idx == items.count()) {
+        qreal distance = qAbs(event->localPos().x() - startPoint.x()) + qAbs(event->localPos().y() - startPoint.y());
+        if (distance > dragMargin)
+            return;
+    }
+
+    if (tl.isActive() && flicking)
+        stealMouse = true; // If we've been flicked then steal the click.
+    else
+        stealMouse = false;
+
+    lastElapsed = 0;
+    lastDist = 0;
+    QQuickItemPrivate::start(lastPosTime);
+    tl.clear();
+}
+
+void QQuickPathView::mouseMoveEvent(QMouseEvent *event)
+{
+    Q_D(QQuickPathView);
+    if (d->interactive) {
+        d->handleMouseMoveEvent(event);
+        if (d->stealMouse)
+            setKeepMouseGrab(true);
+        event->accept();
+    } else {
+        QQuickItem::mouseMoveEvent(event);
+    }
+}
+
+void QQuickPathViewPrivate::handleMouseMoveEvent(QMouseEvent *event)
+{
+    Q_Q(QQuickPathView);
+    if (!interactive || !lastPosTime.isValid())
+        return;
+
+    qreal newPc;
+    QPointF pathPoint = pointNear(event->localPos(), &newPc);
+    if (!stealMouse) {
+        QPointF delta = pathPoint - startPoint;
+        if (qAbs(delta.x()) > qApp->styleHints()->startDragDistance() || qAbs(delta.y()) > qApp->styleHints()->startDragDistance()) {
+            stealMouse = true;
+            startPc = newPc;
+        }
+    }
+
+    if (stealMouse) {
+        moveReason = QQuickPathViewPrivate::Mouse;
+        qreal diff = (newPc - startPc)*modelCount*mappedRange;
+        if (diff) {
+            q->setOffset(offset + diff);
+
+            if (diff > modelCount/2)
+                diff -= modelCount;
+            else if (diff < -modelCount/2)
+                diff += modelCount;
+
+            lastElapsed = QQuickItemPrivate::restart(lastPosTime);
+            lastDist = diff;
+            startPc = newPc;
+        }
+        if (!moving) {
+            moving = true;
+            emit q->movingChanged();
+            emit q->movementStarted();
+        }
+    }
+}
+
+void QQuickPathView::mouseReleaseEvent(QMouseEvent *event)
+{
+    Q_D(QQuickPathView);
+    if (d->interactive) {
+        d->handleMouseReleaseEvent(event);
+        event->accept();
+        ungrabMouse();
+    } else {
+        QQuickItem::mouseReleaseEvent(event);
+    }
+}
+
+void QQuickPathViewPrivate::handleMouseReleaseEvent(QMouseEvent *)
+{
+    Q_Q(QQuickPathView);
+    stealMouse = false;
+    q->setKeepMouseGrab(false);
+    if (!interactive || !lastPosTime.isValid())
+        return;
+
+    qreal elapsed = qreal(lastElapsed + QQuickItemPrivate::elapsed(lastPosTime)) / 1000.;
+    qreal velocity = elapsed > 0. ? lastDist / elapsed : 0;
+    if (model && modelCount && qAbs(velocity) > 1.) {
+        qreal count = pathItems == -1 ? modelCount : pathItems;
+        if (qAbs(velocity) > count * 2) // limit velocity
+            velocity = (velocity > 0 ? count : -count) * 2;
+        // Calculate the distance to be travelled
+        qreal v2 = velocity*velocity;
+        qreal accel = deceleration/10;
+        // + 0.25 to encourage moving at least one item in the flick direction
+        qreal dist = qMin(qreal(modelCount-1), qreal(v2 / (accel * 2.0) + 0.25));
+        if (haveHighlightRange && highlightRangeMode == QQuickPathView::StrictlyEnforceRange) {
+            // round to nearest item.
+            if (velocity > 0.)
+                dist = qRound(dist + offset) - offset;
+            else
+                dist = qRound(dist - offset) + offset;
+            // Calculate accel required to stop on item boundary
+            if (dist <= 0.) {
+                dist = 0.;
+                accel = 0.;
+            } else {
+                accel = v2 / (2.0f * qAbs(dist));
+            }
+        }
+        offsetAdj = 0.0;
+        moveOffset.setValue(offset);
+        tl.accel(moveOffset, velocity, accel, dist);
+        tl.callback(QDeclarativeTimeLineCallback(&moveOffset, fixOffsetCallback, this));
+        if (!flicking) {
+            flicking = true;
+            emit q->flickingChanged();
+            emit q->flickStarted();
+        }
+    } else {
+        fixOffset();
+    }
+
+    lastPosTime.invalidate();
+    if (!tl.isActive())
+        q->movementEnding();
+}
+
+bool QQuickPathView::sendMouseEvent(QMouseEvent *event)
+{
+    Q_D(QQuickPathView);
+    QRectF myRect = mapRectToScene(QRectF(0, 0, width(), height()));
+    QQuickCanvas *c = canvas();
+    QQuickItem *grabber = c ? c->mouseGrabberItem() : 0;
+    bool stealThisEvent = d->stealMouse;
+    if ((stealThisEvent || myRect.contains(event->windowPos())) && (!grabber || !grabber->keepMouseGrab())) {
+        QMouseEvent mouseEvent(event->type(), mapFromScene(event->windowPos()), event->windowPos(), event->screenPos(),
+                               event->button(), event->buttons(), event->modifiers());
+        mouseEvent.setAccepted(false);
+
+        switch (mouseEvent.type()) {
+        case QEvent::MouseMove:
+            d->handleMouseMoveEvent(&mouseEvent);
+            break;
+        case QEvent::MouseButtonPress:
+            d->handleMousePressEvent(&mouseEvent);
+            stealThisEvent = d->stealMouse;   // Update stealThisEvent in case changed by function call above
+            break;
+        case QEvent::MouseButtonRelease:
+            d->handleMouseReleaseEvent(&mouseEvent);
+            break;
+        default:
+            break;
+        }
+        grabber = c->mouseGrabberItem();
+        if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this)
+            grabMouse();
+
+        return d->stealMouse;
+    } else if (d->lastPosTime.isValid()) {
+        d->lastPosTime.invalidate();
+        d->fixOffset();
+    }
+    if (event->type() == QEvent::MouseButtonRelease)
+        d->stealMouse = false;
+    return false;
+}
+
+bool QQuickPathView::childMouseEventFilter(QQuickItem *i, QEvent *e)
+{
+    Q_D(QQuickPathView);
+    if (!isVisible() || !d->interactive)
+        return QQuickItem::childMouseEventFilter(i, e);
+
+    switch (e->type()) {
+    case QEvent::MouseButtonPress:
+    case QEvent::MouseMove:
+    case QEvent::MouseButtonRelease:
+        return sendMouseEvent(static_cast<QMouseEvent *>(e));
+    default:
+        break;
+    }
+
+    return QQuickItem::childMouseEventFilter(i, e);
+}
+
+void QQuickPathView::mouseUngrabEvent()
+{
+    Q_D(QQuickPathView);
+    if (d->stealMouse) {
+        // if our mouse grab has been removed (probably by a Flickable),
+        // fix our state
+        d->stealMouse = false;
+        setKeepMouseGrab(false);
+        d->lastPosTime.invalidate();
+    }
+}
+
+void QQuickPathView::updatePolish()
+{
+    QQuickItem::updatePolish();
+    refill();
+}
+
+void QQuickPathView::componentComplete()
+{
+    Q_D(QQuickPathView);
+    if (d->model && d->ownModel)
+        static_cast<QQuickVisualDataModel *>(d->model.data())->componentComplete();
+
+    QQuickItem::componentComplete();
+
+    d->createHighlight();
+    // It is possible that a refill has already happended to to Path
+    // bindings being handled in the componentComplete().  If so
+    // don't do it again.
+    if (d->items.count() == 0 && d->model) {
+        d->modelCount = d->model->count();
+        d->regenerate();
+    }
+    d->updateHighlight();
+
+    if (d->modelCount)
+        emit countChanged();
+}
+
+void QQuickPathView::refill()
+{
+    Q_D(QQuickPathView);
+    if (!d->isValid() || !isComponentComplete())
+        return;
+
+    d->layoutScheduled = false;
+    bool currentVisible = false;
+
+    // first move existing items and remove items off path
+    int idx = d->firstIndex;
+    QList<QQuickItem*>::iterator it = d->items.begin();
+    while (it != d->items.end()) {
+        qreal pos = d->positionOfIndex(idx);
+        QQuickItem *item = *it;
+        if (pos >= 0.0) {
+            d->updateItem(item, pos);
+            if (idx == d->currentIndex) {
+                currentVisible = true;
+                d->currentItemOffset = pos;
+            }
+            ++it;
+        } else {
+            // qDebug() << "release";
+            d->updateItem(item, 1.0);
+            d->releaseItem(item);
+            if (it == d->items.begin()) {
+                if (++d->firstIndex >= d->modelCount)
+                    d->firstIndex = 0;
+            }
+            it = d->items.erase(it);
+        }
+        ++idx;
+        if (idx >= d->modelCount)
+            idx = 0;
+    }
+    if (!d->items.count())
+        d->firstIndex = -1;
+
+    if (d->modelCount) {
+        // add items to beginning and end
+        int count = d->pathItems == -1 ? d->modelCount : qMin(d->pathItems, d->modelCount);
+        if (d->items.count() < count) {
+            int idx = qRound(d->modelCount - d->offset) % d->modelCount;
+            qreal startPos = 0.0;
+            if (d->haveHighlightRange && d->highlightRangeMode != QQuickPathView::NoHighlightRange)
+                startPos = d->highlightRangeStart;
+            if (d->firstIndex >= 0) {
+                startPos = d->positionOfIndex(d->firstIndex);
+                idx = (d->firstIndex + d->items.count()) % d->modelCount;
+            }
+            qreal pos = d->positionOfIndex(idx);
+            while ((pos > startPos || !d->items.count()) && d->items.count() < count) {
+                // qDebug() << "append" << idx;
+                QQuickItem *item = d->getItem(idx);
+                if (d->model->completePending())
+                    item->setZ(idx+1);
+                if (d->currentIndex == idx) {
+                    currentVisible = true;
+                    d->currentItemOffset = pos;
+                }
+                if (d->items.count() == 0)
+                    d->firstIndex = idx;
+                d->items.append(item);
+                d->updateItem(item, pos);
+                if (d->model->completePending())
+                    d->model->completeItem();
+                ++idx;
+                if (idx >= d->modelCount)
+                    idx = 0;
+                pos = d->positionOfIndex(idx);
+            }
+
+            idx = d->firstIndex - 1;
+            if (idx < 0)
+                idx = d->modelCount - 1;
+            pos = d->positionOfIndex(idx);
+            while ((pos >= 0.0 && pos < startPos) && d->items.count() < count) {
+                // qDebug() << "prepend" << idx;
+                QQuickItem *item = d->getItem(idx);
+                if (d->model->completePending())
+                    item->setZ(idx+1);
+                if (d->currentIndex == idx) {
+                    currentVisible = true;
+                    d->currentItemOffset = pos;
+                }
+                d->items.prepend(item);
+                d->updateItem(item, pos);
+                if (d->model->completePending())
+                    d->model->completeItem();
+                d->firstIndex = idx;
+                idx = d->firstIndex - 1;
+                if (idx < 0)
+                    idx = d->modelCount - 1;
+                pos = d->positionOfIndex(idx);
+            }
+        }
+    }
+
+    if (!currentVisible) {
+        d->currentItemOffset = 1.0;
+        if (d->currentItem) {
+            if (QQuickPathViewAttached *att = d->attached(d->currentItem))
+                att->setOnPath(false);
+        } else if (d->currentIndex >= 0 && d->currentIndex < d->modelCount) {
+            d->currentItem = d->getItem(d->currentIndex, false);
+            d->updateItem(d->currentItem, d->currentIndex < d->firstIndex ? 0.0 : 1.0);
+            if (QQuickPathViewAttached *att = d->attached(d->currentItem))
+                att->setIsCurrentItem(true);
+            if (d->model->completePending())
+                d->model->completeItem();
+        }
+    } else if (!d->currentItem) {
+        d->currentItem = d->model->item(d->currentIndex, true);
+        d->currentItem->setFocus(true);
+        if (QQuickPathViewAttached *att = d->attached(d->currentItem))
+            att->setIsCurrentItem(true);
+    }
+
+    if (d->highlightItem && d->haveHighlightRange && d->highlightRangeMode == QQuickPathView::StrictlyEnforceRange) {
+        d->updateItem(d->highlightItem, d->highlightRangeStart);
+        if (QQuickPathViewAttached *att = d->attached(d->highlightItem))
+            att->setOnPath(true);
+    } else if (d->highlightItem && d->moveReason != QQuickPathViewPrivate::SetIndex) {
+        d->updateItem(d->highlightItem, d->currentItemOffset);
+        if (QQuickPathViewAttached *att = d->attached(d->highlightItem))
+            att->setOnPath(currentVisible);
+    }
+    while (d->itemCache.count())
+        d->releaseItem(d->itemCache.takeLast());
+}
+
+void QQuickPathView::modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset)
+{
+    Q_D(QQuickPathView);
+    if (!d->model || !d->model->isValid() || !d->path || !isComponentComplete())
+        return;
+
+    if (reset) {
+        d->modelCount = d->model->count();
+        d->regenerate();
+        emit countChanged();
+        return;
+    }
+
+    if (changeSet.removes().isEmpty() && changeSet.inserts().isEmpty())
+        return;
+
+    const int modelCount = d->modelCount;
+    int moveId = -1;
+    int moveOffset;
+    bool currentChanged = false;
+    bool changedOffset = false;
+    bool removed = false;
+    bool inserted = false;
+    foreach (const QDeclarativeChangeSet::Remove &r, changeSet.removes()) {
+        removed = true;
+        if (moveId == -1 && d->currentIndex >= r.index + r.count) {
+            d->currentIndex -= r.count;
+            currentChanged = true;
+        } else if (moveId == -1 && d->currentIndex >= r.index && d->currentIndex < r.index + r.count) {
+            // current item has been removed.
+            d->currentIndex = qMin(r.index, d->modelCount - r.count - 1);
+            if (r.isMove()) {
+                moveId = r.moveId;
+                moveOffset = d->currentIndex - r.index;
+            } else if (d->currentItem) {
+                if (QQuickPathViewAttached *att = d->attached(d->currentItem))
+                    att->setIsCurrentItem(true);
+                d->releaseItem(d->currentItem);
+                d->currentItem = 0;
+            }
+            currentChanged = true;
+        }
+
+        if (r.index > d->currentIndex) {
+            if (d->offset >= r.count) {
+                changedOffset = true;
+                d->offset -= r.count;
+                d->offsetAdj -= r.count;
+            }
+        }
+        d->modelCount -= r.count;
+    }
+    foreach (const QDeclarativeChangeSet::Insert &i, changeSet.inserts()) {
+        inserted = true;
+        if (d->modelCount) {
+            if (moveId == -1 && i.index <= d->currentIndex) {
+                d->currentIndex += i.count;
+            } else if (d->offset != 0) {
+                if (moveId != -1 && moveId == i.moveId)
+                    d->currentIndex = i.index + moveOffset;
+                d->offset += i.count;
+                d->offsetAdj += i.count;
+            }
+        }
+        d->modelCount += i.count;
+    }
+
+    d->itemCache += d->items;
+    d->items.clear();
+
+    if (!d->modelCount) {
+        while (d->itemCache.count())
+            d->releaseItem(d->itemCache.takeLast());
+        d->offset = 0;
+        changedOffset = true;
+        d->tl.reset(d->moveOffset);
+    } else if (removed) {
+        d->regenerate();
+        d->updateCurrent();
+        if (!d->flicking && !d->moving && d->haveHighlightRange && d->highlightRangeMode == QQuickPathView::StrictlyEnforceRange)
+            d->snapToCurrent();
+    } else if (inserted) {
+        d->firstIndex = -1;
+        d->updateMappedRange();
+        d->scheduleLayout();
+    }
+    if (changedOffset)
+        emit offsetChanged();
+    if (currentChanged)
+        emit currentIndexChanged();
+    if (d->modelCount != modelCount)
+        emit countChanged();
+}
+
+void QQuickPathView::createdItem(int index, QQuickItem *item)
+{
+    Q_D(QQuickPathView);
+    if (d->requestedIndex != index) {
+        if (!d->attType) {
+            // pre-create one metatype to share with all attached objects
+            d->attType = new QDeclarativeOpenMetaObjectType(&QQuickPathViewAttached::staticMetaObject, qmlEngine(this));
+            foreach (const QString &attr, d->path->attributes())
+                d->attType->createProperty(attr.toUtf8());
+        }
+        qPathViewAttachedType = d->attType;
+        QQuickPathViewAttached *att = static_cast<QQuickPathViewAttached *>(qmlAttachedPropertiesObject<QQuickPathView>(item));
+        qPathViewAttachedType = 0;
+        if (att) {
+            att->m_view = this;
+            att->setOnPath(false);
+        }
+        item->setParentItem(this);
+        d->updateItem(item, index < d->firstIndex ? 0.0 : 1.0);
+    }
+}
+
+void QQuickPathView::destroyingItem(QQuickItem *item)
+{
+    Q_UNUSED(item);
+}
+
+void QQuickPathView::ticked()
+{
+    Q_D(QQuickPathView);
+    d->updateCurrent();
+}
+
+void QQuickPathView::movementEnding()
+{
+    Q_D(QQuickPathView);
+    if (d->flicking) {
+        d->flicking = false;
+        emit flickingChanged();
+        emit flickEnded();
+    }
+    if (d->moving && !d->stealMouse) {
+        d->moving = false;
+        emit movingChanged();
+        emit movementEnded();
+    }
+}
+
+// find the item closest to the snap position
+int QQuickPathViewPrivate::calcCurrentIndex()
+{
+    int current = -1;
+    if (modelCount && model && items.count()) {
+        offset = qmlMod(offset, modelCount);
+        if (offset < 0)
+            offset += modelCount;
+        current = qRound(qAbs(qmlMod(modelCount - offset, modelCount)));
+        current = current % modelCount;
+    }
+
+    return current;
+}
+
+void QQuickPathViewPrivate::updateCurrent()
+{
+    Q_Q(QQuickPathView);
+    if (moveReason != Mouse)
+        return;
+    if (!modelCount || !haveHighlightRange || highlightRangeMode != QQuickPathView::StrictlyEnforceRange)
+        return;
+
+    int idx = calcCurrentIndex();
+    if (model && idx != currentIndex) {
+        if (currentItem) {
+            if (QQuickPathViewAttached *att = attached(currentItem))
+                att->setIsCurrentItem(false);
+            releaseItem(currentItem);
+        }
+        currentIndex = idx;
+        currentItem = 0;
+        int itemIndex = (idx - firstIndex + modelCount) % modelCount;
+        if (itemIndex < items.count()) {
+            currentItem = model->item(currentIndex, true);
+            currentItem->setFocus(true);
+            if (QQuickPathViewAttached *att = attached(currentItem))
+                att->setIsCurrentItem(true);
+        } else if (currentIndex >= 0 && currentIndex < modelCount) {
+            currentItem = getItem(currentIndex, false);
+            updateItem(currentItem, currentIndex < firstIndex ? 0.0 : 1.0);
+            if (QQuickPathViewAttached *att = attached(currentItem))
+                att->setIsCurrentItem(true);
+            if (model->completePending())
+                model->completeItem();
+        }
+        emit q->currentIndexChanged();
+    }
+}
+
+void QQuickPathViewPrivate::fixOffsetCallback(void *d)
+{
+    ((QQuickPathViewPrivate *)d)->fixOffset();
+}
+
+void QQuickPathViewPrivate::fixOffset()
+{
+    Q_Q(QQuickPathView);
+    if (model && items.count()) {
+        if (haveHighlightRange && highlightRangeMode == QQuickPathView::StrictlyEnforceRange) {
+            int curr = calcCurrentIndex();
+            if (curr != currentIndex)
+                q->setCurrentIndex(curr);
+            else
+                snapToCurrent();
+        }
+    }
+}
+
+void QQuickPathViewPrivate::snapToCurrent()
+{
+    if (!model || modelCount <= 0)
+        return;
+
+    qreal targetOffset = qmlMod(modelCount - currentIndex, modelCount);
+
+    moveReason = Other;
+    offsetAdj = 0.0;
+    tl.reset(moveOffset);
+    moveOffset.setValue(offset);
+
+    const int duration = highlightMoveDuration;
+
+    if (moveDirection == Positive || (moveDirection == Shortest && targetOffset - offset > modelCount/2)) {
+        qreal distance = modelCount - targetOffset + offset;
+        if (targetOffset > moveOffset) {
+            tl.move(moveOffset, 0.0, QEasingCurve(QEasingCurve::InQuad), int(duration * offset / distance));
+            tl.set(moveOffset, modelCount);
+            tl.move(moveOffset, targetOffset, QEasingCurve(offset == 0.0 ? QEasingCurve::InOutQuad : QEasingCurve::OutQuad), int(duration * (modelCount-targetOffset) / distance));
+        } else {
+            tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InOutQuad), duration);
+        }
+    } else if (moveDirection == Negative || targetOffset - offset <= -modelCount/2) {
+        qreal distance = modelCount - offset + targetOffset;
+        if (targetOffset < moveOffset) {
+            tl.move(moveOffset, modelCount, QEasingCurve(targetOffset == 0 ? QEasingCurve::InOutQuad : QEasingCurve::InQuad), int(duration * (modelCount-offset) / distance));
+            tl.set(moveOffset, 0.0);
+            tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::OutQuad), int(duration * targetOffset / distance));
+        } else {
+            tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InOutQuad), duration);
+        }
+    } else {
+        tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InOutQuad), duration);
+    }
+    moveDirection = Shortest;
+}
+
+QQuickPathViewAttached *QQuickPathView::qmlAttachedProperties(QObject *obj)
+{
+    return new QQuickPathViewAttached(obj);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/items/qquickpathview_p.h b/src/declarative/items/qquickpathview_p.h
new file mode 100644 (file)
index 0000000..657d721
--- /dev/null
@@ -0,0 +1,257 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
+/****************************************************************************
+**
+** 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 QQUICKPATHVIEW_P_H
+#define QQUICKPATHVIEW_P_H
+
+#include "qquickitem.h"
+
+#include <private/qdeclarativepath_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeChangeSet;
+
+class QQuickPathViewPrivate;
+class QQuickPathViewAttached;
+class Q_AUTOTEST_EXPORT QQuickPathView : public QQuickItem
+{
+    Q_OBJECT
+
+    Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged)
+    Q_PROPERTY(QDeclarativePath *path READ path WRITE setPath NOTIFY pathChanged)
+    Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
+    Q_PROPERTY(QQuickItem *currentItem READ currentItem NOTIFY currentIndexChanged)
+    Q_PROPERTY(qreal offset READ offset WRITE setOffset NOTIFY offsetChanged)
+
+    Q_PROPERTY(QDeclarativeComponent *highlight READ highlight WRITE setHighlight NOTIFY highlightChanged)
+    Q_PROPERTY(QQuickItem *highlightItem READ highlightItem NOTIFY highlightItemChanged)
+
+    Q_PROPERTY(qreal preferredHighlightBegin READ preferredHighlightBegin WRITE setPreferredHighlightBegin NOTIFY preferredHighlightBeginChanged)
+    Q_PROPERTY(qreal preferredHighlightEnd READ preferredHighlightEnd WRITE setPreferredHighlightEnd NOTIFY preferredHighlightEndChanged)
+    Q_PROPERTY(HighlightRangeMode highlightRangeMode READ highlightRangeMode WRITE setHighlightRangeMode NOTIFY highlightRangeModeChanged)
+    Q_PROPERTY(int highlightMoveDuration READ highlightMoveDuration WRITE setHighlightMoveDuration NOTIFY highlightMoveDurationChanged)
+
+    Q_PROPERTY(qreal dragMargin READ dragMargin WRITE setDragMargin NOTIFY dragMarginChanged)
+    Q_PROPERTY(qreal flickDeceleration READ flickDeceleration WRITE setFlickDeceleration NOTIFY flickDecelerationChanged)
+    Q_PROPERTY(bool interactive READ isInteractive WRITE setInteractive NOTIFY interactiveChanged)
+
+    Q_PROPERTY(bool moving READ isMoving NOTIFY movingChanged)
+    Q_PROPERTY(bool flicking READ isFlicking NOTIFY flickingChanged)
+
+    Q_PROPERTY(int count READ count NOTIFY countChanged)
+    Q_PROPERTY(QDeclarativeComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
+    Q_PROPERTY(int pathItemCount READ pathItemCount WRITE setPathItemCount NOTIFY pathItemCountChanged)
+
+    Q_ENUMS(HighlightRangeMode)
+
+public:
+    QQuickPathView(QQuickItem *parent=0);
+    virtual ~QQuickPathView();
+
+    QVariant model() const;
+    void setModel(const QVariant &);
+
+    QDeclarativePath *path() const;
+    void setPath(QDeclarativePath *);
+
+    int currentIndex() const;
+    void setCurrentIndex(int idx);
+
+    QQuickItem *currentItem() const;
+
+    qreal offset() const;
+    void setOffset(qreal offset);
+
+    QDeclarativeComponent *highlight() const;
+    void setHighlight(QDeclarativeComponent *highlight);
+    QQuickItem *highlightItem();
+
+    enum HighlightRangeMode { NoHighlightRange, ApplyRange, StrictlyEnforceRange };
+    HighlightRangeMode highlightRangeMode() const;
+    void setHighlightRangeMode(HighlightRangeMode mode);
+
+    qreal preferredHighlightBegin() const;
+    void setPreferredHighlightBegin(qreal);
+
+    qreal preferredHighlightEnd() const;
+    void setPreferredHighlightEnd(qreal);
+
+    int highlightMoveDuration() const;
+    void setHighlightMoveDuration(int);
+
+    qreal dragMargin() const;
+    void setDragMargin(qreal margin);
+
+    qreal flickDeceleration() const;
+    void setFlickDeceleration(qreal dec);
+
+    bool isInteractive() const;
+    void setInteractive(bool);
+
+    bool isMoving() const;
+    bool isFlicking() const;
+
+    int count() const;
+
+    QDeclarativeComponent *delegate() const;
+    void setDelegate(QDeclarativeComponent *);
+
+    int pathItemCount() const;
+    void setPathItemCount(int);
+
+    static QQuickPathViewAttached *qmlAttachedProperties(QObject *);
+
+public Q_SLOTS:
+    void incrementCurrentIndex();
+    void decrementCurrentIndex();
+
+Q_SIGNALS:
+    void currentIndexChanged();
+    void offsetChanged();
+    void modelChanged();
+    void countChanged();
+    void pathChanged();
+    void preferredHighlightBeginChanged();
+    void preferredHighlightEndChanged();
+    void highlightRangeModeChanged();
+    void dragMarginChanged();
+    void snapPositionChanged();
+    void delegateChanged();
+    void pathItemCountChanged();
+    void flickDecelerationChanged();
+    void interactiveChanged();
+    void movingChanged();
+    void flickingChanged();
+    void highlightChanged();
+    void highlightItemChanged();
+    void highlightMoveDurationChanged();
+    void movementStarted();
+    void movementEnded();
+    void flickStarted();
+    void flickEnded();
+
+protected:
+    virtual void updatePolish();
+    void mousePressEvent(QMouseEvent *event);
+    void mouseMoveEvent(QMouseEvent *event);
+    void mouseReleaseEvent(QMouseEvent *);
+    bool sendMouseEvent(QMouseEvent *event);
+    bool childMouseEventFilter(QQuickItem *, QEvent *);
+    void mouseUngrabEvent();
+    void componentComplete();
+
+private Q_SLOTS:
+    void refill();
+    void ticked();
+    void movementEnding();
+    void modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset);
+    void createdItem(int index, QQuickItem *item);
+    void destroyingItem(QQuickItem *item);
+    void pathUpdated();
+
+private:
+    friend class QQuickPathViewAttached;
+    Q_DISABLE_COPY(QQuickPathView)
+    Q_DECLARE_PRIVATE(QQuickPathView)
+};
+
+class QDeclarativeOpenMetaObject;
+class QQuickPathViewAttached : public QObject
+{
+    Q_OBJECT
+
+    Q_PROPERTY(QQuickPathView *view READ view CONSTANT)
+    Q_PROPERTY(bool isCurrentItem READ isCurrentItem NOTIFY currentItemChanged)
+    Q_PROPERTY(bool onPath READ isOnPath NOTIFY pathChanged)
+
+public:
+    QQuickPathViewAttached(QObject *parent);
+    ~QQuickPathViewAttached();
+
+    QQuickPathView *view() { return m_view; }
+
+    bool isCurrentItem() const { return m_isCurrent; }
+    void setIsCurrentItem(bool c) {
+        if (m_isCurrent != c) {
+            m_isCurrent = c;
+            emit currentItemChanged();
+        }
+    }
+
+    QVariant value(const QByteArray &name) const;
+    void setValue(const QByteArray &name, const QVariant &val);
+
+    bool isOnPath() const { return m_onPath; }
+    void setOnPath(bool on) {
+        if (on != m_onPath) {
+            m_onPath = on;
+            emit pathChanged();
+        }
+    }
+    qreal m_percent;
+
+Q_SIGNALS:
+    void currentItemChanged();
+    void pathChanged();
+
+private:
+    friend class QQuickPathViewPrivate;
+    friend class QQuickPathView;
+    QQuickPathView *m_view;
+    QDeclarativeOpenMetaObject *m_metaobject;
+    bool m_onPath : 1;
+    bool m_isCurrent : 1;
+};
+
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickPathView)
+QML_DECLARE_TYPEINFO(QQuickPathView, QML_HAS_ATTACHED_PROPERTIES)
+QT_END_HEADER
+
+#endif // QQUICKPATHVIEW_P_H
diff --git a/src/declarative/items/qquickpathview_p_p.h b/src/declarative/items/qquickpathview_p_p.h
new file mode 100644 (file)
index 0000000..87d9313
--- /dev/null
@@ -0,0 +1,194 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
+/****************************************************************************
+**
+** 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 QQUICKPATHVIEW_P_P_H
+#define QQUICKPATHVIEW_P_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 "qquickpathview_p.h"
+#include "qquickitem_p.h"
+#include "qquickvisualdatamodel_p.h"
+
+#include <QtDeclarative/qdeclarative.h>
+#include <QtCore/qdatetime.h>
+#include <QtCore/qcoreapplication.h>
+
+#include <private/qdeclarativeanimation_p_p.h>
+#include <private/qdeclarativeguard_p.h>
+#include <private/qdeclarativetimeline_p_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeOpenMetaObjectType;
+class QQuickPathViewAttached;
+class QQuickPathViewPrivate : public QQuickItemPrivate, public QQuickItemChangeListener
+{
+    Q_DECLARE_PUBLIC(QQuickPathView)
+
+public:
+    QQuickPathViewPrivate()
+      : path(0), currentIndex(0), currentItemOffset(0.0), startPc(0), lastDist(0)
+        , lastElapsed(0), offset(0.0), offsetAdj(0.0), mappedRange(1.0)
+        , stealMouse(false), ownModel(false), interactive(true), haveHighlightRange(true)
+        , autoHighlight(true), highlightUp(false), layoutScheduled(false)
+        , moving(false), flicking(false)
+        , dragMargin(0), deceleration(100)
+        , moveOffset(this, &QQuickPathViewPrivate::setAdjustedOffset)
+        , firstIndex(-1), pathItems(-1), requestedIndex(-1)
+        , moveReason(Other), moveDirection(Shortest), attType(0), highlightComponent(0), highlightItem(0)
+        , moveHighlight(this, &QQuickPathViewPrivate::setHighlightPosition)
+        , highlightPosition(0)
+        , highlightRangeStart(0), highlightRangeEnd(0)
+        , highlightRangeMode(QQuickPathView::StrictlyEnforceRange)
+        , highlightMoveDuration(300), modelCount(0)
+    {
+    }
+
+    void init();
+
+    void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) {
+        if ((newGeometry.size() != oldGeometry.size())
+            && (!highlightItem || item != highlightItem)) {
+            if (QQuickPathViewAttached *att = attached(item))
+                att->m_percent = -1;
+            scheduleLayout();
+        }
+    }
+
+    void scheduleLayout() {
+        Q_Q(QQuickPathView);
+        if (!layoutScheduled) {
+            layoutScheduled = true;
+            q->polish();
+        }
+    }
+
+    QQuickItem *getItem(int modelIndex, bool onPath = true);
+    void releaseItem(QQuickItem *item);
+    QQuickPathViewAttached *attached(QQuickItem *item);
+    void clear();
+    void updateMappedRange();
+    qreal positionOfIndex(qreal index) const;
+    void createHighlight();
+    void updateHighlight();
+    void setHighlightPosition(qreal pos);
+    bool isValid() const {
+        return model && model->count() > 0 && model->isValid() && path;
+    }
+
+    void handleMousePressEvent(QMouseEvent *event);
+    void handleMouseMoveEvent(QMouseEvent *event);
+    void handleMouseReleaseEvent(QMouseEvent *);
+
+    int calcCurrentIndex();
+    void updateCurrent();
+    static void fixOffsetCallback(void*);
+    void fixOffset();
+    void setOffset(qreal offset);
+    void setAdjustedOffset(qreal offset);
+    void regenerate();
+    void updateItem(QQuickItem *, qreal);
+    void snapToCurrent();
+    QPointF pointNear(const QPointF &point, qreal *nearPercent=0) const;
+
+    QDeclarativePath *path;
+    int currentIndex;
+    QDeclarativeGuard<QQuickItem> currentItem;
+    qreal currentItemOffset;
+    qreal startPc;
+    QPointF startPoint;
+    qreal lastDist;
+    int lastElapsed;
+    qreal offset;
+    qreal offsetAdj;
+    qreal mappedRange;
+    bool stealMouse : 1;
+    bool ownModel : 1;
+    bool interactive : 1;
+    bool haveHighlightRange : 1;
+    bool autoHighlight : 1;
+    bool highlightUp : 1;
+    bool layoutScheduled : 1;
+    bool moving : 1;
+    bool flicking : 1;
+    QElapsedTimer lastPosTime;
+    QPointF lastPos;
+    qreal dragMargin;
+    qreal deceleration;
+    QDeclarativeTimeLine tl;
+    QDeclarativeTimeLineValueProxy<QQuickPathViewPrivate> moveOffset;
+    int firstIndex;
+    int pathItems;
+    int requestedIndex;
+    QList<QQuickItem *> items;
+    QList<QQuickItem *> itemCache;
+    QDeclarativeGuard<QQuickVisualModel> model;
+    QVariant modelVariant;
+    enum MovementReason { Other, SetIndex, Mouse };
+    MovementReason moveReason;
+    enum MovementDirection { Shortest, Negative, Positive };
+    MovementDirection moveDirection;
+    QDeclarativeOpenMetaObjectType *attType;
+    QDeclarativeComponent *highlightComponent;
+    QQuickItem *highlightItem;
+    QDeclarativeTimeLineValueProxy<QQuickPathViewPrivate> moveHighlight;
+    qreal highlightPosition;
+    qreal highlightRangeStart;
+    qreal highlightRangeEnd;
+    QQuickPathView::HighlightRangeMode highlightRangeMode;
+    int highlightMoveDuration;
+    int modelCount;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/declarative/items/qquickpincharea.cpp b/src/declarative/items/qquickpincharea.cpp
new file mode 100644 (file)
index 0000000..c1f60ae
--- /dev/null
@@ -0,0 +1,600 @@
+/****************************************************************************
+**
+** 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 QtSG 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 "qquickpincharea_p_p.h"
+#include "qquickcanvas.h"
+
+#include <QtGui/qevent.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qstylehints.h>
+
+#include <float.h>
+#include <math.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+    \qmlclass PinchEvent QQuickPinchEvent
+    \inqmlmodule QtQuick 2
+    \ingroup qml-event-elements
+    \brief The PinchEvent object provides information about a pinch event.
+
+    \bold {The PinchEvent element was added in QtQuick 1.1}
+
+    The \c center, \c startCenter, \c previousCenter properties provide the center position between the two touch points.
+
+    The \c scale and \c previousScale properties provide the scale factor.
+
+    The \c angle, \c previousAngle and \c rotation properties provide the angle between the two points and the amount of rotation.
+
+    The \c point1, \c point2, \c startPoint1, \c startPoint2 properties provide the positions of the touch points.
+
+    The \c accepted property may be set to false in the \c onPinchStarted handler if the gesture should not
+    be handled.
+
+    \sa PinchArea
+*/
+
+/*!
+    \qmlproperty QPointF QtQuick2::PinchEvent::center
+    \qmlproperty QPointF QtQuick2::PinchEvent::startCenter
+    \qmlproperty QPointF QtQuick2::PinchEvent::previousCenter
+
+    These properties hold the position of the center point between the two touch points.
+
+    \list
+    \o \c center is the current center point
+    \o \c previousCenter is the center point of the previous event.
+    \o \c startCenter is the center point when the gesture began
+    \endlist
+*/
+
+/*!
+    \qmlproperty real QtQuick2::PinchEvent::scale
+    \qmlproperty real QtQuick2::PinchEvent::previousScale
+
+    These properties hold the scale factor determined by the change in distance between the two touch points.
+
+    \list
+    \o \c scale is the current scale factor.
+    \o \c previousScale is the scale factor of the previous event.
+    \endlist
+
+    When a pinch gesture is started, the scale is 1.0.
+*/
+
+/*!
+    \qmlproperty real QtQuick2::PinchEvent::angle
+    \qmlproperty real QtQuick2::PinchEvent::previousAngle
+    \qmlproperty real QtQuick2::PinchEvent::rotation
+
+    These properties hold the angle between the two touch points.
+
+    \list
+    \o \c angle is the current angle between the two points in the range -180 to 180.
+    \o \c previousAngle is the angle of the previous event.
+    \o \c rotation is the total rotation since the pinch gesture started.
+    \endlist
+
+    When a pinch gesture is started, the rotation is 0.0.
+*/
+
+/*!
+    \qmlproperty QPointF QtQuick2::PinchEvent::point1
+    \qmlproperty QPointF QtQuick2::PinchEvent::startPoint1
+    \qmlproperty QPointF QtQuick2::PinchEvent::point2
+    \qmlproperty QPointF QtQuick2::PinchEvent::startPoint2
+
+    These properties provide the actual touch points generating the pinch.
+
+    \list
+    \o \c point1 and \c point2 hold the current positions of the points.
+    \o \c startPoint1 and \c startPoint2 hold the positions of the points when the second point was touched.
+    \endlist
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::PinchEvent::accepted
+
+    Setting this property to false in the \c PinchArea::onPinchStarted handler
+    will result in no further pinch events being generated, and the gesture
+    ignored.
+*/
+
+/*!
+    \qmlproperty int QtQuick2::PinchEvent::pointCount
+
+    Holds the number of points currently touched.  The PinchArea will not react
+    until two touch points have initited a gesture, but will remain active until
+    all touch points have been released.
+*/
+
+QQuickPinch::QQuickPinch()
+    : m_target(0), m_minScale(1.0), m_maxScale(1.0)
+    , m_minRotation(0.0), m_maxRotation(0.0)
+    , m_axis(NoDrag), m_xmin(-FLT_MAX), m_xmax(FLT_MAX)
+    , m_ymin(-FLT_MAX), m_ymax(FLT_MAX), m_active(false)
+{
+}
+
+QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate()
+{
+    delete pinch;
+}
+
+/*!
+    \qmlclass PinchArea QQuickPinchArea
+    \inqmlmodule QtQuick 2
+    \brief The PinchArea item enables simple pinch gesture handling.
+    \inherits Item
+
+    \bold {The PinchArea element was added in QtQuick 1.1}
+
+    A PinchArea is an invisible item that is typically used in conjunction with
+    a visible item in order to provide pinch gesture handling for that item.
+
+    The \l enabled property is used to enable and disable pinch handling for
+    the proxied item. When disabled, the pinch area becomes transparent to
+    mouse/touch events.
+
+    PinchArea can be used in two ways:
+
+    \list
+    \o setting a \c pinch.target to provide automatic interaction with an element
+    \o using the onPinchStarted, onPinchUpdated and onPinchFinished handlers
+    \endlist
+
+    \sa PinchEvent
+*/
+
+/*!
+    \qmlsignal QtQuick2::PinchArea::onPinchStarted()
+
+    This handler is called when the pinch area detects that a pinch gesture has started.
+
+    The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
+    including the scale, center and angle of the pinch.
+
+    To ignore this gesture set the \c pinch.accepted property to false.  The gesture
+    will be cancelled and no further events will be sent.
+*/
+
+/*!
+    \qmlsignal QtQuick2::PinchArea::onPinchUpdated()
+
+    This handler is called when the pinch area detects that a pinch gesture has changed.
+
+    The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
+    including the scale, center and angle of the pinch.
+*/
+
+/*!
+    \qmlsignal QtQuick2::PinchArea::onPinchFinished()
+
+    This handler is called when the pinch area detects that a pinch gesture has finished.
+
+    The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
+    including the scale, center and angle of the pinch.
+*/
+
+
+/*!
+    \qmlproperty Item QtQuick2::PinchArea::pinch.target
+    \qmlproperty bool QtQuick2::PinchArea::pinch.active
+    \qmlproperty real QtQuick2::PinchArea::pinch.minimumScale
+    \qmlproperty real QtQuick2::PinchArea::pinch.maximumScale
+    \qmlproperty real QtQuick2::PinchArea::pinch.minimumRotation
+    \qmlproperty real QtQuick2::PinchArea::pinch.maximumRotation
+    \qmlproperty enumeration QtQuick2::PinchArea::pinch.dragAxis
+    \qmlproperty real QtQuick2::PinchArea::pinch.minimumX
+    \qmlproperty real QtQuick2::PinchArea::pinch.maximumX
+    \qmlproperty real QtQuick2::PinchArea::pinch.minimumY
+    \qmlproperty real QtQuick2::PinchArea::pinch.maximumY
+
+    \c pinch provides a convenient way to make an item react to pinch gestures.
+
+    \list
+    \i \c pinch.target specifies the id of the item to drag.
+    \i \c pinch.active specifies if the target item is currently being dragged.
+    \i \c pinch.minimumScale and \c pinch.maximumScale limit the range of the Item::scale property.
+    \i \c pinch.minimumRotation and \c pinch.maximumRotation limit the range of the Item::rotation property.
+    \i \c pinch.dragAxis specifies whether dragging in not allowed (\c Pinch.NoDrag), can be done horizontally (\c Pinch.XAxis), vertically (\c Pinch.YAxis), or both (\c Pinch.XandYAxis)
+    \i \c pinch.minimum and \c pinch.maximum limit how far the target can be dragged along the corresponding axes.
+    \endlist
+*/
+
+QQuickPinchArea::QQuickPinchArea(QQuickItem *parent)
+  : QQuickItem(*(new QQuickPinchAreaPrivate), parent)
+{
+    Q_D(QQuickPinchArea);
+    d->init();
+}
+
+QQuickPinchArea::~QQuickPinchArea()
+{
+}
+/*!
+    \qmlproperty bool QtQuick2::PinchArea::enabled
+    This property holds whether the item accepts pinch gestures.
+
+    This property defaults to true.
+*/
+bool QQuickPinchArea::isEnabled() const
+{
+    Q_D(const QQuickPinchArea);
+    return d->absorb;
+}
+
+void QQuickPinchArea::setEnabled(bool a)
+{
+    Q_D(QQuickPinchArea);
+    if (a != d->absorb) {
+        d->absorb = a;
+        emit enabledChanged();
+    }
+}
+
+void QQuickPinchArea::touchEvent(QTouchEvent *event)
+{
+    Q_D(QQuickPinchArea);
+    if (!d->absorb || !isVisible()) {
+        QQuickItem::event(event);
+        return;
+    }
+
+    switch (event->type()) {
+    case QEvent::TouchBegin:
+    case QEvent::TouchUpdate:
+        d->touchPoints.clear();
+        for (int i = 0; i < event->touchPoints().count(); ++i) {
+            if (!(event->touchPoints().at(i).state() & Qt::TouchPointReleased)) {
+                d->touchPoints << event->touchPoints().at(i);
+            }
+        }
+        updatePinch();
+        break;
+    case QEvent::TouchEnd:
+        d->touchPoints.clear();
+        updatePinch();
+        break;
+    default:
+        QQuickItem::event(event);
+    }
+}
+
+void QQuickPinchArea::updatePinch()
+{
+    Q_D(QQuickPinchArea);
+    if (d->touchPoints.count() == 0) {
+        if (d->inPinch) {
+            d->inPinch = false;
+            QPointF pinchCenter = mapFromScene(d->sceneLastCenter);
+            QQuickPinchEvent pe(pinchCenter, d->pinchLastScale, d->pinchLastAngle, d->pinchRotation);
+            pe.setStartCenter(d->pinchStartCenter);
+            pe.setPreviousCenter(pinchCenter);
+            pe.setPreviousAngle(d->pinchLastAngle);
+            pe.setPreviousScale(d->pinchLastScale);
+            pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
+            pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
+            pe.setPoint1(mapFromScene(d->lastPoint1));
+            pe.setPoint2(mapFromScene(d->lastPoint2));
+            emit pinchFinished(&pe);
+            d->pinchStartDist = 0;
+            d->pinchActivated = false;
+            if (d->pinch && d->pinch->target())
+                d->pinch->setActive(false);
+        }
+        d->initPinch = false;
+        d->pinchRejected = false;
+        d->stealMouse = false;
+        setKeepMouseGrab(false);
+        QQuickCanvas *c = canvas();
+        if (c && c->mouseGrabberItem() == this)
+            ungrabMouse();
+        return;
+    }
+    QTouchEvent::TouchPoint touchPoint1 = d->touchPoints.at(0);
+    QTouchEvent::TouchPoint touchPoint2 = d->touchPoints.at(d->touchPoints. count() >= 2 ? 1 : 0);
+    if (d->touchPoints.count() == 2
+        && (touchPoint1.state() & Qt::TouchPointPressed || touchPoint2.state() & Qt::TouchPointPressed)) {
+        d->id1 = touchPoint1.id();
+        d->sceneStartPoint1 = touchPoint1.scenePos();
+        d->sceneStartPoint2 = touchPoint2.scenePos();
+        d->pinchActivated = true;
+        d->initPinch = true;
+    }
+    if (d->pinchActivated && !d->pinchRejected){
+        const int dragThreshold = qApp->styleHints()->startDragDistance();
+        QPointF p1 = touchPoint1.scenePos();
+        QPointF p2 = touchPoint2.scenePos();
+        qreal dx = p1.x() - p2.x();
+        qreal dy = p1.y() - p2.y();
+        qreal dist = sqrt(dx*dx + dy*dy);
+        QPointF sceneCenter = (p1 + p2)/2;
+        qreal angle = QLineF(p1, p2).angle();
+        if (d->touchPoints.count() == 1) {
+            // If we only have one point then just move the center
+            if (d->id1 == touchPoint1.id())
+                sceneCenter = d->sceneLastCenter + touchPoint1.scenePos() - d->lastPoint1;
+            else
+                sceneCenter = d->sceneLastCenter + touchPoint2.scenePos() - d->lastPoint2;
+            angle = d->pinchLastAngle;
+        }
+        d->id1 = touchPoint1.id();
+        if (angle > 180)
+            angle -= 360;
+        if (!d->inPinch || d->initPinch) {
+            if (d->touchPoints.count() >= 2
+                    && (qAbs(p1.x()-d->sceneStartPoint1.x()) > dragThreshold
+                    || qAbs(p1.y()-d->sceneStartPoint1.y()) > dragThreshold
+                    || qAbs(p2.x()-d->sceneStartPoint2.x()) > dragThreshold
+                    || qAbs(p2.y()-d->sceneStartPoint2.y()) > dragThreshold)) {
+                d->initPinch = false;
+                d->sceneStartCenter = sceneCenter;
+                d->sceneLastCenter = sceneCenter;
+                d->pinchStartCenter = mapFromScene(sceneCenter);
+                d->pinchStartDist = dist;
+                d->pinchStartAngle = angle;
+                d->pinchLastScale = 1.0;
+                d->pinchLastAngle = angle;
+                d->pinchRotation = 0.0;
+                d->lastPoint1 = p1;
+                d->lastPoint2 = p2;
+                QQuickPinchEvent pe(d->pinchStartCenter, 1.0, angle, 0.0);
+                pe.setStartCenter(d->pinchStartCenter);
+                pe.setPreviousCenter(d->pinchStartCenter);
+                pe.setPreviousAngle(d->pinchLastAngle);
+                pe.setPreviousScale(d->pinchLastScale);
+                pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
+                pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
+                pe.setPoint1(mapFromScene(d->lastPoint1));
+                pe.setPoint2(mapFromScene(d->lastPoint2));
+                pe.setPointCount(d->touchPoints.count());
+                emit pinchStarted(&pe);
+                if (pe.accepted()) {
+                    d->inPinch = true;
+                    d->stealMouse = true;
+                    QQuickCanvas *c = canvas();
+                    if (c && c->mouseGrabberItem() != this)
+                        grabMouse();
+                    setKeepMouseGrab(true);
+                    if (d->pinch && d->pinch->target()) {
+                        d->pinchStartPos = pinch()->target()->pos();
+                        d->pinchStartScale = d->pinch->target()->scale();
+                        d->pinchStartRotation = d->pinch->target()->rotation();
+                        d->pinch->setActive(true);
+                    }
+                } else {
+                    d->pinchRejected = true;
+                }
+            }
+        } else if (d->pinchStartDist > 0) {
+            qreal scale = dist ? dist / d->pinchStartDist : d->pinchLastScale;
+            qreal da = d->pinchLastAngle - angle;
+            if (da > 180)
+                da -= 360;
+            else if (da < -180)
+                da += 360;
+            d->pinchRotation += da;
+            QPointF pinchCenter = mapFromScene(sceneCenter);
+            QQuickPinchEvent pe(pinchCenter, scale, angle, d->pinchRotation);
+            pe.setStartCenter(d->pinchStartCenter);
+            pe.setPreviousCenter(mapFromScene(d->sceneLastCenter));
+            pe.setPreviousAngle(d->pinchLastAngle);
+            pe.setPreviousScale(d->pinchLastScale);
+            pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
+            pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
+            pe.setPoint1(touchPoint1.pos());
+            pe.setPoint2(touchPoint2.pos());
+            pe.setPointCount(d->touchPoints.count());
+            d->pinchLastScale = scale;
+            d->sceneLastCenter = sceneCenter;
+            d->pinchLastAngle = angle;
+            d->lastPoint1 = touchPoint1.scenePos();
+            d->lastPoint2 = touchPoint2.scenePos();
+            emit pinchUpdated(&pe);
+            if (d->pinch && d->pinch->target()) {
+                qreal s = d->pinchStartScale * scale;
+                s = qMin(qMax(pinch()->minimumScale(),s), pinch()->maximumScale());
+                pinch()->target()->setScale(s);
+                QPointF pos = sceneCenter - d->sceneStartCenter + d->pinchStartPos;
+                if (pinch()->axis() & QQuickPinch::XAxis) {
+                    qreal x = pos.x();
+                    if (x < pinch()->xmin())
+                        x = pinch()->xmin();
+                    else if (x > pinch()->xmax())
+                        x = pinch()->xmax();
+                    pinch()->target()->setX(x);
+                }
+                if (pinch()->axis() & QQuickPinch::YAxis) {
+                    qreal y = pos.y();
+                    if (y < pinch()->ymin())
+                        y = pinch()->ymin();
+                    else if (y > pinch()->ymax())
+                        y = pinch()->ymax();
+                    pinch()->target()->setY(y);
+                }
+                if (d->pinchStartRotation >= pinch()->minimumRotation()
+                        && d->pinchStartRotation <= pinch()->maximumRotation()) {
+                    qreal r = d->pinchRotation + d->pinchStartRotation;
+                    r = qMin(qMax(pinch()->minimumRotation(),r), pinch()->maximumRotation());
+                    pinch()->target()->setRotation(r);
+                }
+            }
+        }
+    }
+}
+
+void QQuickPinchArea::mousePressEvent(QMouseEvent *event)
+{
+    Q_D(QQuickPinchArea);
+    d->stealMouse = false;
+    if (!d->absorb)
+        QQuickItem::mousePressEvent(event);
+    else {
+        setKeepMouseGrab(false);
+        event->setAccepted(true);
+    }
+}
+
+void QQuickPinchArea::mouseMoveEvent(QMouseEvent *event)
+{
+    Q_D(QQuickPinchArea);
+    if (!d->absorb) {
+        QQuickItem::mouseMoveEvent(event);
+        return;
+    }
+}
+
+void QQuickPinchArea::mouseReleaseEvent(QMouseEvent *event)
+{
+    Q_D(QQuickPinchArea);
+    d->stealMouse = false;
+    if (!d->absorb) {
+        QQuickItem::mouseReleaseEvent(event);
+    } else {
+        QQuickCanvas *c = canvas();
+        if (c && c->mouseGrabberItem() == this)
+            ungrabMouse();
+        setKeepMouseGrab(false);
+    }
+}
+
+void QQuickPinchArea::mouseUngrabEvent()
+{
+    setKeepMouseGrab(false);
+}
+
+bool QQuickPinchArea::sendMouseEvent(QMouseEvent *event)
+{
+    Q_D(QQuickPinchArea);
+    QRectF myRect = mapRectToScene(QRectF(0, 0, width(), height()));
+
+    QQuickCanvas *c = canvas();
+    QQuickItem *grabber = c ? c->mouseGrabberItem() : 0;
+    bool stealThisEvent = d->stealMouse;
+    if ((stealThisEvent || myRect.contains(event->windowPos())) && (!grabber || !grabber->keepMouseGrab())) {
+        QMouseEvent mouseEvent(event->type(), mapFromScene(event->windowPos()), event->windowPos(), event->screenPos(),
+                               event->button(), event->buttons(), event->modifiers());
+        mouseEvent.setAccepted(false);
+
+        switch (mouseEvent.type()) {
+        case QEvent::MouseMove:
+            mouseMoveEvent(&mouseEvent);
+            break;
+        case QEvent::MouseButtonPress:
+            mousePressEvent(&mouseEvent);
+            break;
+        case QEvent::MouseButtonRelease:
+            mouseReleaseEvent(&mouseEvent);
+            break;
+        default:
+            break;
+        }
+        grabber = c->mouseGrabberItem();
+        if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this)
+            grabMouse();
+
+        return stealThisEvent;
+    }
+    if (event->type() == QEvent::MouseButtonRelease) {
+        d->stealMouse = false;
+        if (c && c->mouseGrabberItem() == this)
+            ungrabMouse();
+        setKeepMouseGrab(false);
+    }
+    return false;
+}
+
+bool QQuickPinchArea::childMouseEventFilter(QQuickItem *i, QEvent *e)
+{
+    Q_D(QQuickPinchArea);
+    if (!d->absorb || !isVisible())
+        return QQuickItem::childMouseEventFilter(i, e);
+    switch (e->type()) {
+    case QEvent::MouseButtonPress:
+    case QEvent::MouseMove:
+    case QEvent::MouseButtonRelease:
+        return sendMouseEvent(static_cast<QMouseEvent *>(e));
+        break;
+    case QEvent::TouchBegin:
+    case QEvent::TouchUpdate: {
+            QTouchEvent *touch = static_cast<QTouchEvent*>(e);
+            d->touchPoints.clear();
+            for (int i = 0; i < touch->touchPoints().count(); ++i)
+                if (!(touch->touchPoints().at(i).state() & Qt::TouchPointReleased))
+                    d->touchPoints << touch->touchPoints().at(i);
+            updatePinch();
+        }
+        return d->inPinch;
+    case QEvent::TouchEnd:
+        d->touchPoints.clear();
+        updatePinch();
+        break;
+    default:
+        break;
+    }
+
+    return QQuickItem::childMouseEventFilter(i, e);
+}
+
+void QQuickPinchArea::geometryChanged(const QRectF &newGeometry,
+                                            const QRectF &oldGeometry)
+{
+    QQuickItem::geometryChanged(newGeometry, oldGeometry);
+}
+
+void QQuickPinchArea::itemChange(ItemChange change, const ItemChangeData &value)
+{
+    QQuickItem::itemChange(change, value);
+}
+
+QQuickPinch *QQuickPinchArea::pinch()
+{
+    Q_D(QQuickPinchArea);
+    if (!d->pinch)
+        d->pinch = new QQuickPinch;
+    return d->pinch;
+}
+
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/items/qquickpincharea_p.h b/src/declarative/items/qquickpincharea_p.h
new file mode 100644 (file)
index 0000000..c98a1fd
--- /dev/null
@@ -0,0 +1,315 @@
+// Commit: f707672eb4c51ea82fbd98e1da16ece61a74c690
+/****************************************************************************
+**
+** 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 QtSG 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 QQUICKPINCHAREA_H
+#define QQUICKPINCHAREA_H
+
+#include "qquickitem.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class Q_AUTOTEST_EXPORT QQuickPinch : public QObject
+{
+    Q_OBJECT
+
+    Q_ENUMS(Axis)
+    Q_PROPERTY(QQuickItem *target READ target WRITE setTarget RESET resetTarget)
+    Q_PROPERTY(qreal minimumScale READ minimumScale WRITE setMinimumScale NOTIFY minimumScaleChanged)
+    Q_PROPERTY(qreal maximumScale READ maximumScale WRITE setMaximumScale NOTIFY maximumScaleChanged)
+    Q_PROPERTY(qreal minimumRotation READ minimumRotation WRITE setMinimumRotation NOTIFY minimumRotationChanged)
+    Q_PROPERTY(qreal maximumRotation READ maximumRotation WRITE setMaximumRotation NOTIFY maximumRotationChanged)
+    Q_PROPERTY(Axis dragAxis READ axis WRITE setAxis NOTIFY dragAxisChanged)
+    Q_PROPERTY(qreal minimumX READ xmin WRITE setXmin NOTIFY minimumXChanged)
+    Q_PROPERTY(qreal maximumX READ xmax WRITE setXmax NOTIFY maximumXChanged)
+    Q_PROPERTY(qreal minimumY READ ymin WRITE setYmin NOTIFY minimumYChanged)
+    Q_PROPERTY(qreal maximumY READ ymax WRITE setYmax NOTIFY maximumYChanged)
+    Q_PROPERTY(bool active READ active NOTIFY activeChanged)
+
+public:
+    QQuickPinch();
+
+    QQuickItem *target() const { return m_target; }
+    void setTarget(QQuickItem *target) {
+        if (target == m_target)
+            return;
+        m_target = target;
+        emit targetChanged();
+    }
+    void resetTarget() {
+        if (!m_target)
+            return;
+        m_target = 0;
+        emit targetChanged();
+    }
+
+    qreal minimumScale() const { return m_minScale; }
+    void setMinimumScale(qreal s) {
+        if (s == m_minScale)
+            return;
+        m_minScale = s;
+        emit minimumScaleChanged();
+    }
+    qreal maximumScale() const { return m_maxScale; }
+    void setMaximumScale(qreal s) {
+        if (s == m_maxScale)
+            return;
+        m_maxScale = s;
+        emit maximumScaleChanged();
+    }
+
+    qreal minimumRotation() const { return m_minRotation; }
+    void setMinimumRotation(qreal r) {
+        if (r == m_minRotation)
+            return;
+        m_minRotation = r;
+        emit minimumRotationChanged();
+    }
+    qreal maximumRotation() const { return m_maxRotation; }
+    void setMaximumRotation(qreal r) {
+        if (r == m_maxRotation)
+            return;
+        m_maxRotation = r;
+        emit maximumRotationChanged();
+    }
+
+    enum Axis { NoDrag=0x00, XAxis=0x01, YAxis=0x02, XandYAxis=0x03 };
+    Axis axis() const { return m_axis; }
+    void setAxis(Axis a) {
+        if (a == m_axis)
+            return;
+        m_axis = a;
+        emit dragAxisChanged();
+    }
+
+    qreal xmin() const { return m_xmin; }
+    void setXmin(qreal x) {
+        if (x == m_xmin)
+            return;
+        m_xmin = x;
+        emit minimumXChanged();
+    }
+    qreal xmax() const { return m_xmax; }
+    void setXmax(qreal x) {
+        if (x == m_xmax)
+            return;
+        m_xmax = x;
+        emit maximumXChanged();
+    }
+    qreal ymin() const { return m_ymin; }
+    void setYmin(qreal y) {
+        if (y == m_ymin)
+            return;
+        m_ymin = y;
+        emit minimumYChanged();
+    }
+    qreal ymax() const { return m_ymax; }
+    void setYmax(qreal y) {
+        if (y == m_ymax)
+            return;
+        m_ymax = y;
+        emit maximumYChanged();
+    }
+
+    bool active() const { return m_active; }
+    void setActive(bool a) {
+        if (a == m_active)
+            return;
+        m_active = a;
+        emit activeChanged();
+    }
+
+signals:
+    void targetChanged();
+    void minimumScaleChanged();
+    void maximumScaleChanged();
+    void minimumRotationChanged();
+    void maximumRotationChanged();
+    void dragAxisChanged();
+    void minimumXChanged();
+    void maximumXChanged();
+    void minimumYChanged();
+    void maximumYChanged();
+    void activeChanged();
+
+private:
+    QQuickItem *m_target;
+    qreal m_minScale;
+    qreal m_maxScale;
+    qreal m_minRotation;
+    qreal m_maxRotation;
+    Axis m_axis;
+    qreal m_xmin;
+    qreal m_xmax;
+    qreal m_ymin;
+    qreal m_ymax;
+    bool m_active;
+};
+
+class Q_AUTOTEST_EXPORT QQuickPinchEvent : public QObject
+{
+    Q_OBJECT
+
+    Q_PROPERTY(QPointF center READ center)
+    Q_PROPERTY(QPointF startCenter READ startCenter)
+    Q_PROPERTY(QPointF previousCenter READ previousCenter)
+    Q_PROPERTY(qreal scale READ scale)
+    Q_PROPERTY(qreal previousScale READ previousScale)
+    Q_PROPERTY(qreal angle READ angle)
+    Q_PROPERTY(qreal previousAngle READ previousAngle)
+    Q_PROPERTY(qreal rotation READ rotation)
+    Q_PROPERTY(QPointF point1 READ point1)
+    Q_PROPERTY(QPointF startPoint1 READ startPoint1)
+    Q_PROPERTY(QPointF point2 READ point2)
+    Q_PROPERTY(QPointF startPoint2 READ startPoint2)
+    Q_PROPERTY(int pointCount READ pointCount)
+    Q_PROPERTY(bool accepted READ accepted WRITE setAccepted)
+
+public:
+    QQuickPinchEvent(QPointF c, qreal s, qreal a, qreal r)
+        : QObject(), m_center(c), m_scale(s), m_angle(a), m_rotation(r)
+        , m_pointCount(0), m_accepted(true) {}
+
+    QPointF center() const { return m_center; }
+    QPointF startCenter() const { return m_startCenter; }
+    void setStartCenter(QPointF c) { m_startCenter = c; }
+    QPointF previousCenter() const { return m_lastCenter; }
+    void setPreviousCenter(QPointF c) { m_lastCenter = c; }
+    qreal scale() const { return m_scale; }
+    qreal previousScale() const { return m_lastScale; }
+    void setPreviousScale(qreal s) { m_lastScale = s; }
+    qreal angle() const { return m_angle; }
+    qreal previousAngle() const { return m_lastAngle; }
+    void setPreviousAngle(qreal a) { m_lastAngle = a; }
+    qreal rotation() const { return m_rotation; }
+    QPointF point1() const { return m_point1; }
+    void setPoint1(QPointF p) { m_point1 = p; }
+    QPointF startPoint1() const { return m_startPoint1; }
+    void setStartPoint1(QPointF p) { m_startPoint1 = p; }
+    QPointF point2() const { return m_point2; }
+    void setPoint2(QPointF p) { m_point2 = p; }
+    QPointF startPoint2() const { return m_startPoint2; }
+    void setStartPoint2(QPointF p) { m_startPoint2 = p; }
+    int pointCount() const { return m_pointCount; }
+    void setPointCount(int count) { m_pointCount = count; }
+
+    bool accepted() const { return m_accepted; }
+    void setAccepted(bool a) { m_accepted = a; }
+
+private:
+    QPointF m_center;
+    QPointF m_startCenter;
+    QPointF m_lastCenter;
+    qreal m_scale;
+    qreal m_lastScale;
+    qreal m_angle;
+    qreal m_lastAngle;
+    qreal m_rotation;
+    QPointF m_point1;
+    QPointF m_point2;
+    QPointF m_startPoint1;
+    QPointF m_startPoint2;
+    int m_pointCount;
+    bool m_accepted;
+};
+
+
+class QQuickMouseEvent;
+class QQuickPinchAreaPrivate;
+class Q_AUTOTEST_EXPORT QQuickPinchArea : public QQuickItem
+{
+    Q_OBJECT
+
+    Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
+    Q_PROPERTY(QQuickPinch *pinch READ pinch CONSTANT)
+
+public:
+    QQuickPinchArea(QQuickItem *parent=0);
+    ~QQuickPinchArea();
+
+    bool isEnabled() const;
+    void setEnabled(bool);
+
+    QQuickPinch *pinch();
+
+Q_SIGNALS:
+    void enabledChanged();
+    void pinchStarted(QQuickPinchEvent *pinch);
+    void pinchUpdated(QQuickPinchEvent *pinch);
+    void pinchFinished(QQuickPinchEvent *pinch);
+
+protected:
+    virtual void mousePressEvent(QMouseEvent *event);
+    virtual void mouseReleaseEvent(QMouseEvent *event);
+    virtual void mouseMoveEvent(QMouseEvent *event);
+    virtual void mouseUngrabEvent();
+    virtual bool sendMouseEvent(QMouseEvent *event);
+    virtual bool childMouseEventFilter(QQuickItem *i, QEvent *e);
+    virtual void touchEvent(QTouchEvent *event);
+
+    virtual void geometryChanged(const QRectF &newGeometry,
+                                 const QRectF &oldGeometry);
+    virtual void itemChange(ItemChange change, const ItemChangeData& value);
+
+private:
+    void updatePinch();
+    void handlePress();
+    void handleRelease();
+
+private:
+    Q_DISABLE_COPY(QQuickPinchArea)
+    Q_DECLARE_PRIVATE(QQuickPinchArea)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickPinch)
+QML_DECLARE_TYPE(QQuickPinchEvent)
+QML_DECLARE_TYPE(QQuickPinchArea)
+
+QT_END_HEADER
+
+#endif // QQUICKPINCHAREA_H
+
diff --git a/src/declarative/items/qquickpincharea_p_p.h b/src/declarative/items/qquickpincharea_p_p.h
new file mode 100644 (file)
index 0000000..1c9d5c5
--- /dev/null
@@ -0,0 +1,116 @@
+// Commit: f707672eb4c51ea82fbd98e1da16ece61a74c690
+/****************************************************************************
+**
+** 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 QtSG 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 QQUICKPINCHAREA_P_H
+#define QQUICKPINCHAREA_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 <qevent.h>
+
+#include "qquickitem_p.h"
+#include "qquickpincharea_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickPinch;
+class QQuickPinchAreaPrivate : public QQuickItemPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickPinchArea)
+public:
+    QQuickPinchAreaPrivate()
+      : absorb(true), stealMouse(false), inPinch(false)
+      , pinchRejected(false), pinchActivated(false), initPinch(false)
+      , pinch(0), pinchStartDist(0), pinchStartScale(1.0)
+      , pinchLastScale(1.0), pinchStartRotation(0.0), pinchStartAngle(0.0)
+      , pinchLastAngle(0.0), pinchRotation(0.0)
+    {
+    }
+
+    ~QQuickPinchAreaPrivate();
+
+    void init()
+    {
+        Q_Q(QQuickPinchArea);
+        q->setAcceptedMouseButtons(Qt::LeftButton);
+        q->setFiltersChildMouseEvents(true);
+    }
+
+    bool absorb : 1;
+    bool stealMouse : 1;
+    bool inPinch : 1;
+    bool pinchRejected : 1;
+    bool pinchActivated : 1;
+    bool initPinch : 1;
+    QQuickPinch *pinch;
+    QPointF sceneStartPoint1;
+    QPointF sceneStartPoint2;
+    QPointF lastPoint1;
+    QPointF lastPoint2;
+    qreal pinchStartDist;
+    qreal pinchStartScale;
+    qreal pinchLastScale;
+    qreal pinchStartRotation;
+    qreal pinchStartAngle;
+    qreal pinchLastAngle;
+    qreal pinchRotation;
+    QPointF sceneStartCenter;
+    QPointF pinchStartCenter;
+    QPointF sceneLastCenter;
+    QPointF pinchStartPos;
+    QList<QTouchEvent::TouchPoint> touchPoints;
+    int id1;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKPINCHAREA_P_H
+
diff --git a/src/declarative/items/qquickpositioners.cpp b/src/declarative/items/qquickpositioners.cpp
new file mode 100644 (file)
index 0000000..15cd35c
--- /dev/null
@@ -0,0 +1,1533 @@
+/****************************************************************************
+**
+** 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 "qquickpositioners_p.h"
+#include "qquickpositioners_p_p.h"
+
+#include <QtDeclarative/qdeclarative.h>
+#include <QtDeclarative/qdeclarativeinfo.h>
+#include <QtCore/qmath.h>
+#include <QtCore/qcoreapplication.h>
+
+#include <private/qdeclarativestate_p.h>
+#include <private/qdeclarativestategroup_p.h>
+#include <private/qdeclarativestateoperations_p.h>
+#include <private/qdeclarativetransition_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static const QQuickItemPrivate::ChangeTypes watchedChanges
+    = QQuickItemPrivate::Geometry
+    | QQuickItemPrivate::SiblingOrder
+    | QQuickItemPrivate::Visibility
+    | QQuickItemPrivate::Destroyed;
+
+void QQuickBasePositionerPrivate::watchChanges(QQuickItem *other)
+{
+    QQuickItemPrivate *otherPrivate = QQuickItemPrivate::get(other);
+    otherPrivate->addItemChangeListener(this, watchedChanges);
+}
+
+void QQuickBasePositionerPrivate::unwatchChanges(QQuickItem* other)
+{
+    QQuickItemPrivate *otherPrivate = QQuickItemPrivate::get(other);
+    otherPrivate->removeItemChangeListener(this, watchedChanges);
+}
+
+QQuickBasePositioner::QQuickBasePositioner(PositionerType at, QQuickItem *parent)
+    : QQuickImplicitSizeItem(*(new QQuickBasePositionerPrivate), parent)
+{
+    Q_D(QQuickBasePositioner);
+    d->init(at);
+}
+/*!
+    \internal
+    \class QQuickBasePositioner
+    \brief The QQuickBasePositioner class provides a base for QQuickGraphics layouts.
+
+    To create a QQuickGraphics Positioner, simply subclass QQuickBasePositioner and implement
+    doLayout(), which is automatically called when the layout might need
+    updating. In doLayout() use the setX and setY functions from QQuickBasePositioner, and the
+    base class will apply the positions along with the appropriate transitions. The items to
+    position are provided in order as the protected member positionedItems.
+
+    You also need to set a PositionerType, to declare whether you are positioning the x, y or both
+    for the child items. Depending on the chosen type, only x or y changes will be applied.
+
+    Note that the subclass is responsible for adding the spacing in between items.
+
+    Positioning is usually delayed until before a frame is rendered, to batch multiple repositioning
+    changes into one calculation.
+*/
+
+QQuickBasePositioner::QQuickBasePositioner(QQuickBasePositionerPrivate &dd, PositionerType at, QQuickItem *parent)
+    : QQuickImplicitSizeItem(dd, parent)
+{
+    Q_D(QQuickBasePositioner);
+    d->init(at);
+}
+
+QQuickBasePositioner::~QQuickBasePositioner()
+{
+    Q_D(QQuickBasePositioner);
+    for (int i = 0; i < positionedItems.count(); ++i)
+        d->unwatchChanges(positionedItems.at(i).item);
+    positionedItems.clear();
+}
+
+void QQuickBasePositioner::updatePolish()
+{
+    Q_D(QQuickBasePositioner);
+    if (d->positioningDirty)
+        prePositioning();
+}
+
+int QQuickBasePositioner::spacing() const
+{
+    Q_D(const QQuickBasePositioner);
+    return d->spacing;
+}
+
+void QQuickBasePositioner::setSpacing(int s)
+{
+    Q_D(QQuickBasePositioner);
+    if (s==d->spacing)
+        return;
+    d->spacing = s;
+    d->setPositioningDirty();
+    emit spacingChanged();
+}
+
+QDeclarativeTransition *QQuickBasePositioner::move() const
+{
+    Q_D(const QQuickBasePositioner);
+    return d->moveTransition;
+}
+
+void QQuickBasePositioner::setMove(QDeclarativeTransition *mt)
+{
+    Q_D(QQuickBasePositioner);
+    if (mt == d->moveTransition)
+        return;
+    d->moveTransition = mt;
+    emit moveChanged();
+}
+
+QDeclarativeTransition *QQuickBasePositioner::add() const
+{
+    Q_D(const QQuickBasePositioner);
+    return d->addTransition;
+}
+
+void QQuickBasePositioner::setAdd(QDeclarativeTransition *add)
+{
+    Q_D(QQuickBasePositioner);
+    if (add == d->addTransition)
+        return;
+
+    d->addTransition = add;
+    emit addChanged();
+}
+
+void QQuickBasePositioner::componentComplete()
+{
+    QQuickItem::componentComplete();
+    positionedItems.reserve(childItems().count());
+    prePositioning();
+    reportConflictingAnchors();
+}
+
+void QQuickBasePositioner::itemChange(ItemChange change, const ItemChangeData &value)
+{
+    Q_D(QQuickBasePositioner);
+    if (change == ItemChildAddedChange){
+        d->setPositioningDirty();
+    } else if (change == ItemChildRemovedChange) {
+        QQuickItem *child = value.item;
+        QQuickBasePositioner::PositionedItem posItem(child);
+        int idx = positionedItems.find(posItem);
+        if (idx >= 0) {
+            d->unwatchChanges(child);
+            positionedItems.remove(idx);
+        }
+        d->setPositioningDirty();
+    }
+
+    QQuickItem::itemChange(change, value);
+}
+
+void QQuickBasePositioner::prePositioning()
+{
+    Q_D(QQuickBasePositioner);
+    if (!isComponentComplete())
+        return;
+
+    if (d->doingPositioning)
+        return;
+
+    d->positioningDirty = false;
+    d->doingPositioning = true;
+    //Need to order children by creation order modified by stacking order
+    QList<QQuickItem *> children = childItems();
+
+    QPODVector<PositionedItem,8> oldItems;
+    positionedItems.copyAndClear(oldItems);
+    for (int ii = 0; ii < children.count(); ++ii) {
+        QQuickItem *child = children.at(ii);
+        QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
+        PositionedItem *item = 0;
+        PositionedItem posItem(child);
+        int wIdx = oldItems.find(posItem);
+        if (wIdx < 0) {
+            d->watchChanges(child);
+            positionedItems.append(posItem);
+            item = &positionedItems[positionedItems.count()-1];
+            item->isNew = true;
+            if (!childPrivate->explicitVisible || !child->width() || !child->height())
+                item->isVisible = false;
+        } else {
+            item = &oldItems[wIdx];
+            // Items are only omitted from positioning if they are explicitly hidden
+            // i.e. their positioning is not affected if an ancestor is hidden.
+            if (!childPrivate->explicitVisible || !child->width() || !child->height()) {
+                item->isVisible = false;
+            } else if (!item->isVisible) {
+                item->isVisible = true;
+                item->isNew = true;
+            } else {
+                item->isNew = false;
+            }
+            positionedItems.append(*item);
+        }
+    }
+    QSizeF contentSize(0,0);
+    doPositioning(&contentSize);
+    updateAttachedProperties();
+    if (!d->addActions.isEmpty() || !d->moveActions.isEmpty())
+        finishApplyTransitions();
+    d->doingPositioning = false;
+    //Set implicit size to the size of its children
+    setImplicitHeight(contentSize.height());
+    setImplicitWidth(contentSize.width());
+}
+
+void QQuickBasePositioner::positionX(int x, const PositionedItem &target)
+{
+    Q_D(QQuickBasePositioner);
+    if (d->type == Horizontal || d->type == Both) {
+        if (target.isNew) {
+            if (!d->addTransition || !d->addTransition->enabled())
+                target.item->setX(x);
+            else
+                d->addActions << QDeclarativeAction(target.item, QLatin1String("x"), QVariant(x));
+        } else if (x != target.item->x()) {
+            if (!d->moveTransition || !d->moveTransition->enabled())
+                target.item->setX(x);
+            else
+                d->moveActions << QDeclarativeAction(target.item, QLatin1String("x"), QVariant(x));
+        }
+    }
+}
+
+void QQuickBasePositioner::positionY(int y, const PositionedItem &target)
+{
+    Q_D(QQuickBasePositioner);
+    if (d->type == Vertical || d->type == Both) {
+        if (target.isNew) {
+            if (!d->addTransition || !d->addTransition->enabled())
+                target.item->setY(y);
+            else
+                d->addActions << QDeclarativeAction(target.item, QLatin1String("y"), QVariant(y));
+        } else if (y != target.item->y()) {
+            if (!d->moveTransition || !d->moveTransition->enabled())
+                target.item->setY(y);
+            else
+                d->moveActions << QDeclarativeAction(target.item, QLatin1String("y"), QVariant(y));
+        }
+    }
+}
+
+void QQuickBasePositioner::finishApplyTransitions()
+{
+    Q_D(QQuickBasePositioner);
+    // Note that if a transition is not set the transition manager will
+    // apply the changes directly, in the case add/move aren't set
+    d->addTransitionManager.transition(d->addActions, d->addTransition);
+    d->moveTransitionManager.transition(d->moveActions, d->moveTransition);
+    d->addActions.clear();
+    d->moveActions.clear();
+}
+
+QQuickPositionerAttached *QQuickBasePositioner::qmlAttachedProperties(QObject *obj)
+{
+    return new QQuickPositionerAttached(obj);
+}
+
+void QQuickBasePositioner::updateAttachedProperties(QQuickPositionerAttached *specificProperty, QQuickItem *specificPropertyOwner) const
+{
+    // If this function is deemed too expensive or shows up in profiles, it could
+    // be changed to run only when there are attached properties present. This
+    // could be a flag in the positioner that is set by the attached property
+    // constructor.
+    QQuickPositionerAttached *prevLastProperty = 0;
+    QQuickPositionerAttached *lastProperty = 0;
+
+    int visibleItemIndex = 0;
+    for (int ii = 0; ii < positionedItems.count(); ++ii) {
+        const PositionedItem &child = positionedItems.at(ii);
+        if (!child.item)
+            continue;
+
+        QQuickPositionerAttached *property = 0;
+
+        if (specificProperty) {
+            if (specificPropertyOwner == child.item) {
+                property = specificProperty;
+            }
+        } else {
+            property = static_cast<QQuickPositionerAttached *>(qmlAttachedPropertiesObject<QQuickBasePositioner>(child.item, false));
+        }
+
+        if (child.isVisible) {
+            if (property) {
+              property->setIndex(visibleItemIndex);
+              property->setIsFirstItem(visibleItemIndex == 0);
+
+              if (property->isLastItem())
+                prevLastProperty = property;
+            }
+
+            lastProperty = property;
+            ++visibleItemIndex;
+        } else if (property) {
+            property->setIndex(-1);
+            property->setIsFirstItem(false);
+            property->setIsLastItem(false);
+        }
+    }
+
+    if (prevLastProperty && prevLastProperty != lastProperty)
+        prevLastProperty->setIsLastItem(false);
+    if (lastProperty)
+      lastProperty->setIsLastItem(true);
+}
+
+/*!
+    \qmlclass Positioner QQuickPositionerAttached
+    \inqmlmodule QtQuick 2
+    \ingroup qml-positioning-elements
+    \brief The Positioner type provides attached properties that contain details on where an item exists in a positioner.
+
+    Positioner items (such as Column, Row, Flow and Grid) provide automatic layout
+    for child items. Attaching this property allows a child item to determine
+    where it exists within the positioner.
+*/
+
+QQuickPositionerAttached::QQuickPositionerAttached(QObject *parent) : QObject(parent), m_index(-1), m_isFirstItem(false), m_isLastItem(false)
+{
+    QQuickItem *attachedItem = qobject_cast<QQuickItem *>(parent);
+    if (attachedItem) {
+        QQuickBasePositioner *positioner = qobject_cast<QQuickBasePositioner *>(attachedItem->parent());
+        if (positioner) {
+            positioner->updateAttachedProperties(this, attachedItem);
+        }
+    }
+}
+
+/*!
+    \qmlattachedproperty Item QtQuick2::Positioner::index
+
+    This property allows the item to determine
+    its index within the positioner.
+*/
+void QQuickPositionerAttached::setIndex(int index)
+{
+    if (m_index == index)
+        return;
+    m_index = index;
+    emit indexChanged();
+}
+
+/*!
+    \qmlattachedproperty Item QtQuick2::Positioner::isFirstItem
+    \qmlattachedproperty Item QtQuick2::Positioner::isLastItem
+
+    These properties allow the item to determine if it
+    is the first or last item in the positioner, respectively.
+*/
+void QQuickPositionerAttached::setIsFirstItem(bool isFirstItem)
+{
+    if (m_isFirstItem == isFirstItem)
+        return;
+    m_isFirstItem = isFirstItem;
+    emit isFirstItemChanged();
+}
+
+void QQuickPositionerAttached::setIsLastItem(bool isLastItem)
+{
+    if (m_isLastItem == isLastItem)
+        return;
+    m_isLastItem = isLastItem;
+    emit isLastItemChanged();
+}
+
+/*!
+  \qmlclass Column QQuickColumn
+    \inqmlmodule QtQuick 2
+  \ingroup qml-positioning-elements
+  \brief The Column item arranges its children vertically.
+  \inherits Item
+
+  The Column item positions its child items so that they are vertically
+  aligned and not overlapping.
+
+  Spacing between items can be added using the \l spacing property.
+  Transitions can be used for cases where items managed by a Column are
+  added or moved. These are stored in the \l add and \l move properties
+  respectively.
+
+  See \l{Using QML Positioner and Repeater Items} for more details about this item and other
+  related items.
+
+  \section1 Example Usage
+
+  The following example positions differently shaped rectangles using a Column
+  item.
+
+  \image verticalpositioner_example.png
+
+  \snippet doc/src/snippets/declarative/column/vertical-positioner.qml document
+
+  \section1 Using Transitions
+
+  Transitions can be used to animate items that are added to, moved within,
+  or removed from a Column item. The \l add and \l move properties can be set to
+  the transitions that will be applied when items are added to, removed from,
+  or re-positioned within a Column item.
+
+  The use of transitions with positioners is described in more detail in the
+  \l{Using QML Positioner and Repeater Items#Using Transitions}{Using QML
+  Positioner and Repeater Items} document.
+
+  \image verticalpositioner_transition.gif
+
+  \qml
+  Column {
+      spacing: 2
+      add: Transition {
+          // Define an animation for adding a new item...
+      }
+      move: Transition {
+          // Define an animation for moving items within the column...
+      }
+      // ...
+  }
+  \endqml
+
+  \section1 Limitations
+
+  Note that the positioner assumes that the x and y positions of its children
+  will not change. If you manually change the x or y properties in script, bind
+  the x or y properties, use anchors on a child of a positioner, or have the
+  height of a child depend on the position of a child, then the
+  positioner may exhibit strange behavior. If you need to perform any of these
+  actions, consider positioning the items without the use of a Column.
+
+  Items with a width or height of 0 will not be positioned.
+
+  Positioning is batched and syncronized with painting to reduce the number of
+  calculations needed. This means that positioners may not reposition items immediately
+  when changes occur, but it will have moved by the next frame.
+
+  \sa Row, Grid, Flow, Positioner, {declarative/positioners}{Positioners example}
+*/
+/*!
+    \qmlproperty Transition QtQuick2::Column::add
+
+    This property holds the transition to be applied when adding an
+    item to the positioner. The transition will only be applied to the
+    added item(s).  Positioner transitions will only affect the
+    position (x, y) of items.
+
+    For a positioner, adding an item can mean that either the object
+    has been created or reparented, and thus is now a child or the
+    positioner, or that the object has had its opacity increased from
+    zero, and thus is now visible.
+
+    \sa move
+*/
+/*!
+    \qmlproperty Transition QtQuick2::Column::move
+
+    This property holds the transition to apply when moving an item
+    within the positioner.  Positioner transitions will only affect
+    the position (x, y) of items.
+
+    This transition can be performed when other items are added or removed
+    from the positioner, or when items resize themselves.
+
+    \image positioner-move.gif
+
+    \qml
+    Column {
+        move: Transition {
+            NumberAnimation {
+                properties: "y"
+                duration: 1000
+            }
+        }
+    }
+    \endqml
+
+    \sa add, {declarative/positioners}{Positioners example}
+*/
+/*!
+  \qmlproperty int QtQuick2::Column::spacing
+
+  The spacing is the amount in pixels left empty between adjacent
+  items. The default spacing is 0.
+
+  \sa Grid::spacing
+*/
+QQuickColumn::QQuickColumn(QQuickItem *parent)
+: QQuickBasePositioner(Vertical, parent)
+{
+}
+
+void QQuickColumn::doPositioning(QSizeF *contentSize)
+{
+    int voffset = 0;
+
+    for (int ii = 0; ii < positionedItems.count(); ++ii) {
+        const PositionedItem &child = positionedItems.at(ii);
+        if (!child.item || !child.isVisible)
+            continue;
+
+        if (child.item->y() != voffset)
+            positionY(voffset, child);
+
+        contentSize->setWidth(qMax(contentSize->width(), child.item->width()));
+
+        voffset += child.item->height();
+        voffset += spacing();
+    }
+
+    if (voffset != 0)//If we positioned any items, undo the spacing from the last item
+        voffset -= spacing();
+    contentSize->setHeight(voffset);
+}
+
+void QQuickColumn::reportConflictingAnchors()
+{
+    QQuickBasePositionerPrivate *d = static_cast<QQuickBasePositionerPrivate*>(QQuickBasePositionerPrivate::get(this));
+    for (int ii = 0; ii < positionedItems.count(); ++ii) {
+        const PositionedItem &child = positionedItems.at(ii);
+        if (child.item) {
+            QQuickAnchors *anchors = QQuickItemPrivate::get(static_cast<QQuickItem *>(child.item))->_anchors;
+            if (anchors) {
+                QQuickAnchors::Anchors usedAnchors = anchors->usedAnchors();
+                if (usedAnchors & QQuickAnchors::TopAnchor ||
+                    usedAnchors & QQuickAnchors::BottomAnchor ||
+                    usedAnchors & QQuickAnchors::VCenterAnchor ||
+                    anchors->fill() || anchors->centerIn()) {
+                    d->anchorConflict = true;
+                    break;
+                }
+            }
+        }
+    }
+    if (d->anchorConflict) {
+        qmlInfo(this) << "Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column";
+    }
+}
+/*!
+  \qmlclass Row QQuickRow
+    \inqmlmodule QtQuick 2
+  \ingroup qml-positioning-elements
+  \brief The Row item arranges its children horizontally.
+  \inherits Item
+
+  The Row item positions its child items so that they are horizontally
+  aligned and not overlapping.
+
+  Use \l spacing to set the spacing between items in a Row, and use the
+  \l add and \l move properties to set the transitions that should be applied
+  when items are added to, removed from, or re-positioned within the Row.
+
+  See \l{Using QML Positioner and Repeater Items} for more details about this item and other
+  related items.
+
+  \section1 Example Usage
+
+  The following example lays out differently shaped rectangles using a Row.
+
+  \image horizontalpositioner_example.png
+
+  \snippet doc/src/snippets/declarative/row/row.qml document
+
+  \section1 Using Transitions
+
+  Transitions can be used to animate items that are added to, moved within,
+  or removed from a Grid item. The \l add and \l move properties can be set to
+  the transitions that will be applied when items are added to, removed from,
+  or re-positioned within a Row item.
+
+  \section1 Limitations
+
+  Note that the positioner assumes that the x and y positions of its children
+  will not change. If you manually change the x or y properties in script, bind
+  the x or y properties, use anchors on a child of a positioner, or have the
+  width of a child depend on the position of a child, then the
+  positioner may exhibit strange behaviour. If you need to perform any of these
+  actions, consider positioning the items without the use of a Row.
+
+  Items with a width or height of 0 will not be positioned.
+
+  Positioning is batched and syncronized with painting to reduce the number of
+  calculations needed. This means that positioners may not reposition items immediately
+  when changes occur, but it will have moved by the next frame.
+
+  \sa Column, Grid, Flow, Positioner, {declarative/positioners}{Positioners example}
+*/
+/*!
+    \qmlproperty Transition QtQuick2::Row::add
+
+    This property holds the transition to be applied when adding an
+    item to the positioner. The transition will only be applied to the
+    added item(s).  Positioner transitions will only affect the
+    position (x, y) of items.
+
+    For a positioner, adding an item can mean that either the object
+    has been created or reparented, and thus is now a child or the
+    positioner, or that the object has had its opacity increased from
+    zero, and thus is now visible.
+
+    \sa move
+*/
+/*!
+    \qmlproperty Transition QtQuick2::Row::move
+
+    This property holds the transition to be applied when moving an
+    item within the positioner. Positioner transitions will only affect
+    the position (x, y) of items.
+
+    This transition can be performed when other items are added or removed
+    from the positioner, or when items resize themselves.
+
+    \qml
+    Row {
+        id: positioner
+        move: Transition {
+            NumberAnimation {
+                properties: "x"
+                duration: 1000
+            }
+        }
+    }
+    \endqml
+
+    \sa add, {declarative/positioners}{Positioners example}
+*/
+/*!
+  \qmlproperty int QtQuick2::Row::spacing
+
+  The spacing is the amount in pixels left empty between adjacent
+  items. The default spacing is 0.
+
+  \sa Grid::spacing
+*/
+
+QQuickRow::QQuickRow(QQuickItem *parent)
+: QQuickBasePositioner(Horizontal, parent)
+{
+}
+/*!
+    \qmlproperty enumeration QtQuick2::Row::layoutDirection
+
+    This property holds the layoutDirection of the row.
+
+    Possible values:
+
+    \list
+    \o Qt.LeftToRight (default) - Items are laid out from left to right. If the width of the row is explicitly set,
+    the left anchor remains to the left of the row.
+    \o Qt.RightToLeft - Items are laid out from right to left. If the width of the row is explicitly set,
+    the right anchor remains to the right of the row.
+    \endlist
+
+    \sa Grid::layoutDirection, Flow::layoutDirection, {declarative/righttoleft/layoutdirection}{Layout directions example}
+*/
+
+Qt::LayoutDirection QQuickRow::layoutDirection() const
+{
+    return QQuickBasePositionerPrivate::getLayoutDirection(this);
+}
+
+void QQuickRow::setLayoutDirection(Qt::LayoutDirection layoutDirection)
+{
+    QQuickBasePositionerPrivate *d = static_cast<QQuickBasePositionerPrivate* >(QQuickBasePositionerPrivate::get(this));
+    if (d->layoutDirection != layoutDirection) {
+        d->layoutDirection = layoutDirection;
+        // For RTL layout the positioning changes when the width changes.
+        if (d->layoutDirection == Qt::RightToLeft)
+            d->addItemChangeListener(d, QQuickItemPrivate::Geometry);
+        else
+            d->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
+        prePositioning();
+        emit layoutDirectionChanged();
+        emit effectiveLayoutDirectionChanged();
+    }
+}
+/*!
+    \qmlproperty enumeration QtQuick2::Row::effectiveLayoutDirection
+    This property holds the effective layout direction of the row positioner.
+
+    When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} for locale layouts,
+    the visual layout direction of the row positioner will be mirrored. However, the
+    property \l {Row::layoutDirection}{layoutDirection} will remain unchanged.
+
+    \sa Row::layoutDirection, {LayoutMirroring}{LayoutMirroring}
+*/
+
+Qt::LayoutDirection QQuickRow::effectiveLayoutDirection() const
+{
+    return QQuickBasePositionerPrivate::getEffectiveLayoutDirection(this);
+}
+
+void QQuickRow::doPositioning(QSizeF *contentSize)
+{
+    QQuickBasePositionerPrivate *d = static_cast<QQuickBasePositionerPrivate* >(QQuickBasePositionerPrivate::get(this));
+    int hoffset = 0;
+
+    QList<int> hoffsets;
+    for (int ii = 0; ii < positionedItems.count(); ++ii) {
+        const PositionedItem &child = positionedItems.at(ii);
+        if (!child.item || !child.isVisible)
+            continue;
+
+        if (d->isLeftToRight()) {
+            if (child.item->x() != hoffset)
+                positionX(hoffset, child);
+        } else {
+            hoffsets << hoffset;
+        }
+
+        contentSize->setHeight(qMax(contentSize->height(), child.item->height()));
+
+        hoffset += child.item->width();
+        hoffset += spacing();
+    }
+
+    if (hoffset != 0)//If we positioned any items, undo the extra spacing from the last item
+        hoffset -= spacing();
+    contentSize->setWidth(hoffset);
+
+    if (d->isLeftToRight())
+        return;
+
+    //Right to Left layout
+    int end = 0;
+    if (!widthValid())
+        end = contentSize->width();
+    else
+        end = width();
+
+    int acc = 0;
+    for (int ii = 0; ii < positionedItems.count(); ++ii) {
+        const PositionedItem &child = positionedItems.at(ii);
+        if (!child.item || !child.isVisible)
+            continue;
+        hoffset = end - hoffsets[acc++] - child.item->width();
+        if (child.item->x() != hoffset)
+            positionX(hoffset, child);
+    }
+}
+
+void QQuickRow::reportConflictingAnchors()
+{
+    QQuickBasePositionerPrivate *d = static_cast<QQuickBasePositionerPrivate*>(QQuickBasePositionerPrivate::get(this));
+    for (int ii = 0; ii < positionedItems.count(); ++ii) {
+        const PositionedItem &child = positionedItems.at(ii);
+        if (child.item) {
+            QQuickAnchors *anchors = QQuickItemPrivate::get(static_cast<QQuickItem *>(child.item))->_anchors;
+            if (anchors) {
+                QQuickAnchors::Anchors usedAnchors = anchors->usedAnchors();
+                if (usedAnchors & QQuickAnchors::LeftAnchor ||
+                    usedAnchors & QQuickAnchors::RightAnchor ||
+                    usedAnchors & QQuickAnchors::HCenterAnchor ||
+                    anchors->fill() || anchors->centerIn()) {
+                    d->anchorConflict = true;
+                    break;
+                }
+            }
+        }
+    }
+    if (d->anchorConflict)
+        qmlInfo(this) << "Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row";
+}
+
+/*!
+  \qmlclass Grid QQuickGrid
+    \inqmlmodule QtQuick 2
+  \ingroup qml-positioning-elements
+  \brief The Grid item positions its children in a grid.
+  \inherits Item
+
+  The Grid item positions its child items so that they are
+  aligned in a grid and are not overlapping.
+
+  The grid positioner calculates a grid of rectangular cells of sufficient
+  size to hold all items, placing the items in the cells, from left to right
+  and top to bottom. Each item is positioned in the top-left corner of its
+  cell with position (0, 0).
+
+  A Grid defaults to four columns, and as many rows as are necessary to
+  fit all child items. The number of rows and columns can be constrained
+  by setting the \l rows and \l columns properties.
+
+  Spacing can be added between child items by setting the \l spacing
+  property. The amount of spacing applied will be the same in the
+  horizontal and vertical directions.
+
+  See \l{Using QML Positioner and Repeater Items} for more details about this item and other
+  related items.
+
+  \section1 Example Usage
+
+  The following example demonstrates this.
+
+  \image gridLayout_example.png
+
+  \snippet doc/src/snippets/declarative/grid/grid.qml document
+
+  \section1 Using Transitions
+
+  Transitions can be used to animate items that are added to, moved within,
+  or removed from a Grid item. The \l add and \l move properties can be set to
+  the transitions that will be applied when items are added to, removed from,
+  or re-positioned within a Grid item.
+
+  \section1 Limitations
+
+  Note that the positioner assumes that the x and y positions of its children
+  will not change. If you manually change the x or y properties in script, bind
+  the x or y properties, use anchors on a child of a positioner, or have the
+  width or height of a child depend on the position of a child, then the
+  positioner may exhibit strange behaviour. If you need to perform any of these
+  actions, consider positioning the items without the use of a Grid.
+
+  Items with a width or height of 0 will not be positioned.
+
+  Positioning is batched and syncronized with painting to reduce the number of
+  calculations needed. This means that positioners may not reposition items immediately
+  when changes occur, but it will have moved by the next frame.
+
+  \sa Flow, Row, Column, Positioner, {declarative/positioners}{Positioners example}
+*/
+/*!
+    \qmlproperty Transition QtQuick2::Grid::add
+
+    This property holds the transition to be applied when adding an
+    item to the positioner. The transition will only be applied to the
+    added item(s).  Positioner transitions will only affect the
+    position (x, y) of items.
+
+    For a positioner, adding an item can mean that either the object
+    has been created or reparented, and thus is now a child or the
+    positioner, or that the object has had its opacity increased from
+    zero, and thus is now visible.
+
+    \sa move
+*/
+/*!
+    \qmlproperty Transition QtQuick2::Grid::move
+
+    This property holds the transition to be applied when moving an
+    item within the positioner. Positioner transitions will only affect
+    the position (x, y) of items.
+
+    This transition can be performed when other items are added or removed
+    from the positioner, or when items resize themselves.
+
+    \qml
+    Grid {
+        move: Transition {
+            NumberAnimation {
+                properties: "x,y"
+                duration: 1000
+            }
+        }
+    }
+    \endqml
+
+    \sa add, {declarative/positioners}{Positioners example}
+*/
+/*!
+  \qmlproperty int QtQuick2::Grid::spacing
+
+  The spacing is the amount in pixels left empty between adjacent
+  items. The default spacing is 0.
+
+  The below example places a Grid containing a red, a blue and a
+  green rectangle on a gray background. The area the grid positioner
+  occupies is colored white. The positioner on the left has the
+  no spacing (the default), and the positioner on the right has
+  a spacing of 6.
+
+  \inlineimage qml-grid-no-spacing.png
+  \inlineimage qml-grid-spacing.png
+
+  \sa rows, columns
+*/
+QQuickGrid::QQuickGrid(QQuickItem *parent) :
+    QQuickBasePositioner(Both, parent), m_rows(-1), m_columns(-1), m_rowSpacing(-1), m_columnSpacing(-1), m_flow(LeftToRight)
+{
+}
+
+/*!
+    \qmlproperty int QtQuick2::Grid::columns
+
+    This property holds the number of columns in the grid. The default
+    number of columns is 4.
+
+    If the grid does not have enough items to fill the specified
+    number of columns, some columns will be of zero width.
+*/
+
+/*!
+    \qmlproperty int QtQuick2::Grid::rows
+    This property holds the number of rows in the grid.
+
+    If the grid does not have enough items to fill the specified
+    number of rows, some rows will be of zero width.
+*/
+
+void QQuickGrid::setColumns(const int columns)
+{
+    if (columns == m_columns)
+        return;
+    m_columns = columns;
+    prePositioning();
+    emit columnsChanged();
+}
+
+void QQuickGrid::setRows(const int rows)
+{
+    if (rows == m_rows)
+        return;
+    m_rows = rows;
+    prePositioning();
+    emit rowsChanged();
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::Grid::flow
+    This property holds the flow of the layout.
+
+    Possible values are:
+
+    \list
+    \o Grid.LeftToRight (default) - Items are positioned next to
+       each other in the \l layoutDirection, then wrapped to the next line.
+    \o Grid.TopToBottom - Items are positioned next to each
+       other from top to bottom, then wrapped to the next column.
+    \endlist
+*/
+QQuickGrid::Flow QQuickGrid::flow() const
+{
+    return m_flow;
+}
+
+void QQuickGrid::setFlow(Flow flow)
+{
+    if (m_flow != flow) {
+        m_flow = flow;
+        prePositioning();
+        emit flowChanged();
+    }
+}
+
+/*!
+    \qmlproperty int QtQuick2::Grid::rowSpacing
+
+    This property holds the spacing in pixels between rows.
+
+    \sa columnSpacing
+    \since QtQuick2.0
+*/
+void QQuickGrid::setRowSpacing(const int rowSpacing)
+{
+    if (rowSpacing == m_rowSpacing)
+        return;
+    m_rowSpacing = rowSpacing;
+    prePositioning();
+    emit rowSpacingChanged();
+}
+
+/*!
+    \qmlproperty int QtQuick2::Grid::columnSpacing
+
+    This property holds the spacing in pixels between columns.
+
+    \sa rowSpacing
+    \since QtQuick2.0
+*/
+void QQuickGrid::setColumnSpacing(const int columnSpacing)
+{
+    if (columnSpacing == m_columnSpacing)
+        return;
+    m_columnSpacing = columnSpacing;
+    prePositioning();
+    emit columnSpacingChanged();
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::Grid::layoutDirection
+
+    This property holds the layout direction of the layout.
+
+    Possible values are:
+
+    \list
+    \o Qt.LeftToRight (default) - Items are positioned from the top to bottom,
+    and left to right. The flow direction is dependent on the
+    \l Grid::flow property.
+    \o Qt.RightToLeft - Items are positioned from the top to bottom,
+    and right to left. The flow direction is dependent on the
+    \l Grid::flow property.
+    \endlist
+
+    \sa Flow::layoutDirection, Row::layoutDirection, {declarative/righttoleft/layoutdirection}{Layout directions example}
+*/
+Qt::LayoutDirection QQuickGrid::layoutDirection() const
+{
+    return QQuickBasePositionerPrivate::getLayoutDirection(this);
+}
+
+void QQuickGrid::setLayoutDirection(Qt::LayoutDirection layoutDirection)
+{
+    QQuickBasePositionerPrivate *d = static_cast<QQuickBasePositionerPrivate*>(QQuickBasePositionerPrivate::get(this));
+    if (d->layoutDirection != layoutDirection) {
+        d->layoutDirection = layoutDirection;
+        // For RTL layout the positioning changes when the width changes.
+        if (d->layoutDirection == Qt::RightToLeft)
+            d->addItemChangeListener(d, QQuickItemPrivate::Geometry);
+        else
+            d->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
+        prePositioning();
+        emit layoutDirectionChanged();
+        emit effectiveLayoutDirectionChanged();
+    }
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::Grid::effectiveLayoutDirection
+    This property holds the effective layout direction of the grid positioner.
+
+    When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} for locale layouts,
+    the visual layout direction of the grid positioner will be mirrored. However, the
+    property \l {Grid::layoutDirection}{layoutDirection} will remain unchanged.
+
+    \sa Grid::layoutDirection, {LayoutMirroring}{LayoutMirroring}
+*/
+Qt::LayoutDirection QQuickGrid::effectiveLayoutDirection() const
+{
+    return QQuickBasePositionerPrivate::getEffectiveLayoutDirection(this);
+}
+
+void QQuickGrid::doPositioning(QSizeF *contentSize)
+{
+    QQuickBasePositionerPrivate *d = static_cast<QQuickBasePositionerPrivate*>(QQuickBasePositionerPrivate::get(this));
+    int c = m_columns;
+    int r = m_rows;
+    //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)
+            visibleItems.append(positionedItems[i]);
+
+    int numVisible = visibleItems.count();
+    if (m_columns <= 0 && m_rows <= 0){
+        c = 4;
+        r = (numVisible+3)/4;
+    } else if (m_rows <= 0){
+        r = (numVisible+(m_columns-1))/m_columns;
+    } else if (m_columns <= 0){
+        c = (numVisible+(m_rows-1))/m_rows;
+    }
+
+    if (r==0 || c==0)
+        return; //Nothing to do
+
+    QList<int> maxColWidth;
+    QList<int> maxRowHeight;
+    int childIndex =0;
+    if (m_flow == LeftToRight) {
+        for (int i=0; i < r; i++){
+            for (int j=0; j < c; j++){
+                if (j==0)
+                    maxRowHeight << 0;
+                if (i==0)
+                    maxColWidth << 0;
+
+                if (childIndex == visibleItems.count())
+                    break;
+
+                const PositionedItem &child = visibleItems.at(childIndex++);
+                if (child.item->width() > maxColWidth[j])
+                    maxColWidth[j] = child.item->width();
+                if (child.item->height() > maxRowHeight[i])
+                    maxRowHeight[i] = child.item->height();
+            }
+        }
+    } else {
+        for (int j=0; j < c; j++){
+            for (int i=0; i < r; i++){
+                if (j==0)
+                    maxRowHeight << 0;
+                if (i==0)
+                    maxColWidth << 0;
+
+                if (childIndex == visibleItems.count())
+                    break;
+
+                const PositionedItem &child = visibleItems.at(childIndex++);
+                if (child.item->width() > maxColWidth[j])
+                    maxColWidth[j] = child.item->width();
+                if (child.item->height() > maxRowHeight[i])
+                    maxRowHeight[i] = child.item->height();
+            }
+        }
+    }
+
+    int columnSpacing = m_columnSpacing;
+    if (columnSpacing == -1)
+        columnSpacing = spacing();
+
+    int rowSpacing = m_rowSpacing;
+    if (rowSpacing == -1)
+        rowSpacing = spacing();
+
+    int widthSum = 0;
+    for (int j=0; j < maxColWidth.size(); j++){
+        if (j)
+            widthSum += columnSpacing;
+        widthSum += maxColWidth[j];
+    }
+
+    int heightSum = 0;
+    for (int i=0; i < maxRowHeight.size(); i++){
+        if (i)
+            heightSum += rowSpacing;
+        heightSum += maxRowHeight[i];
+    }
+
+    contentSize->setHeight(heightSum);
+    contentSize->setWidth(widthSum);
+
+    int end = 0;
+    if (widthValid())
+        end = width();
+    else
+        end = widthSum;
+
+    int xoffset=0;
+    if (!d->isLeftToRight())
+        xoffset = end;
+    int yoffset=0;
+    int curRow =0;
+    int curCol =0;
+    for (int i = 0; i < visibleItems.count(); ++i) {
+        const PositionedItem &child = visibleItems.at(i);
+        int childXOffset = xoffset;
+        if (!d->isLeftToRight())
+            childXOffset -= child.item->width();
+        if ((child.item->x() != childXOffset) || (child.item->y() != yoffset)){
+            positionX(childXOffset, child);
+            positionY(yoffset, child);
+        }
+
+        if (m_flow == LeftToRight) {
+            if (d->isLeftToRight())
+                xoffset += maxColWidth[curCol]+columnSpacing;
+            else
+                xoffset -= maxColWidth[curCol]+columnSpacing;
+            curCol++;
+            curCol%=c;
+            if (!curCol){
+                yoffset += maxRowHeight[curRow]+rowSpacing;
+                if (d->isLeftToRight())
+                    xoffset = 0;
+                else
+                    xoffset = end;
+                curRow++;
+                if (curRow>=r)
+                    break;
+            }
+        } else {
+            yoffset+=maxRowHeight[curRow]+rowSpacing;
+            curRow++;
+            curRow%=r;
+            if (!curRow){
+                if (d->isLeftToRight())
+                    xoffset += maxColWidth[curCol]+columnSpacing;
+                else
+                    xoffset -= maxColWidth[curCol]+columnSpacing;
+                yoffset=0;
+                curCol++;
+                if (curCol>=c)
+                    break;
+            }
+        }
+    }
+}
+
+void QQuickGrid::reportConflictingAnchors()
+{
+    QQuickBasePositionerPrivate *d = static_cast<QQuickBasePositionerPrivate*>(QQuickBasePositionerPrivate::get(this));
+    for (int ii = 0; ii < positionedItems.count(); ++ii) {
+        const PositionedItem &child = positionedItems.at(ii);
+        if (child.item) {
+            QQuickAnchors *anchors = QQuickItemPrivate::get(static_cast<QQuickItem *>(child.item))->_anchors;
+            if (anchors && (anchors->usedAnchors() || anchors->fill() || anchors->centerIn())) {
+                d->anchorConflict = true;
+                break;
+            }
+        }
+    }
+    if (d->anchorConflict)
+        qmlInfo(this) << "Cannot specify anchors for items inside Grid";
+}
+
+/*!
+  \qmlclass Flow QQuickFlow
+    \inqmlmodule QtQuick 2
+  \ingroup qml-positioning-elements
+  \brief The Flow item arranges its children side by side, wrapping as necessary.
+  \inherits Item
+
+  The Flow item positions its child items like words on a page, wrapping them
+  to create rows or columns of items that do not overlap.
+
+  Spacing between items can be added using the \l spacing property.
+  Transitions can be used for cases where items managed by a Column are
+  added or moved. These are stored in the \l add and \l move properties
+  respectively.
+
+  See \l{Using QML Positioner and Repeater Items} for more details about this item and other
+  related items.
+
+  \section1 Example Usage
+
+  The following example positions \l Text items within a parent item using
+  a Flow item.
+
+  \image qml-flow-snippet.png
+
+  \snippet doc/src/snippets/declarative/flow.qml flow item
+
+  \section1 Using Transitions
+
+  Transitions can be used to animate items that are added to, moved within,
+  or removed from a Flow item. The \l add and \l move properties can be set to
+  the transitions that will be applied when items are added to, removed from,
+  or re-positioned within a Flow item.
+
+  The use of transitions with positioners is described in more detail in the
+  \l{Using QML Positioner and Repeater Items#Using Transitions}{Using QML
+  Positioner and Repeater Items} document.
+
+  \section1 Limitations
+
+  Note that the positioner assumes that the x and y positions of its children
+  will not change. If you manually change the x or y properties in script, bind
+  the x or y properties, use anchors on a child of a positioner, or have the
+  width or height of a child depend on the position of a child, then the
+  positioner may exhibit strange behaviour.  If you need to perform any of these
+  actions, consider positioning the items without the use of a Flow.
+
+  Items with a width or height of 0 will not be positioned.
+
+  Positioning is batched and syncronized with painting to reduce the number of
+  calculations needed. This means that positioners may not reposition items immediately
+  when changes occur, but it will have moved by the next frame.
+
+  \sa Column, Row, Grid, Positioner, {declarative/positioners}{Positioners example}
+*/
+/*!
+    \qmlproperty Transition QtQuick2::Flow::add
+
+    This property holds the transition to be applied when adding an
+    item to the positioner. The transition will only be applied to the
+    added item(s).  Positioner transitions will only affect the
+    position (x, y) of items.
+
+    For a positioner, adding an item can mean that either the object
+    has been created or reparented, and thus is now a child or the
+    positioner, or that the object has had its opacity increased from
+    zero, and thus is now visible.
+
+    \sa move
+*/
+/*!
+    \qmlproperty Transition QtQuick2::Flow::move
+
+    This property holds the transition to be applied when moving an
+    item within the positioner. Positioner transitions will only affect
+    the position (x, y) of items.
+
+    This transition can be performed when other items are added or removed
+    from the positioner, or when items resize themselves.
+
+    \qml
+    Flow {
+        id: positioner
+        move: Transition {
+            NumberAnimation {
+                properties: "x,y"
+                ease: "easeOutBounce"
+            }
+        }
+    }
+    \endqml
+
+    \sa add, {declarative/positioners}{Positioners example}
+*/
+/*!
+  \qmlproperty int QtQuick2::Flow::spacing
+
+  spacing is the amount in pixels left empty between each adjacent
+  item, and defaults to 0.
+
+  \sa Grid::spacing
+*/
+
+class QQuickFlowPrivate : public QQuickBasePositionerPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickFlow)
+
+public:
+    QQuickFlowPrivate()
+        : QQuickBasePositionerPrivate(), flow(QQuickFlow::LeftToRight)
+    {}
+
+    QQuickFlow::Flow flow;
+};
+
+QQuickFlow::QQuickFlow(QQuickItem *parent)
+: QQuickBasePositioner(*(new QQuickFlowPrivate), Both, parent)
+{
+    Q_D(QQuickFlow);
+    // Flow layout requires relayout if its own size changes too.
+    d->addItemChangeListener(d, QQuickItemPrivate::Geometry);
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::Flow::flow
+    This property holds the flow of the layout.
+
+    Possible values are:
+
+    \list
+    \o Flow.LeftToRight (default) - Items are positioned next to
+    to each other according to the \l layoutDirection until the width of the Flow
+    is exceeded, then wrapped to the next line.
+    \o Flow.TopToBottom - Items are positioned next to each
+    other from top to bottom until the height of the Flow is exceeded,
+    then wrapped to the next column.
+    \endlist
+*/
+QQuickFlow::Flow QQuickFlow::flow() const
+{
+    Q_D(const QQuickFlow);
+    return d->flow;
+}
+
+void QQuickFlow::setFlow(Flow flow)
+{
+    Q_D(QQuickFlow);
+    if (d->flow != flow) {
+        d->flow = flow;
+        prePositioning();
+        emit flowChanged();
+    }
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::Flow::layoutDirection
+
+    This property holds the layout direction of the layout.
+
+    Possible values are:
+
+    \list
+    \o Qt.LeftToRight (default) - Items are positioned from the top to bottom,
+    and left to right. The flow direction is dependent on the
+    \l Flow::flow property.
+    \o Qt.RightToLeft - Items are positioned from the top to bottom,
+    and right to left. The flow direction is dependent on the
+    \l Flow::flow property.
+    \endlist
+
+    \sa Grid::layoutDirection, Row::layoutDirection, {declarative/righttoleft/layoutdirection}{Layout directions example}
+*/
+
+Qt::LayoutDirection QQuickFlow::layoutDirection() const
+{
+    Q_D(const QQuickFlow);
+    return d->layoutDirection;
+}
+
+void QQuickFlow::setLayoutDirection(Qt::LayoutDirection layoutDirection)
+{
+    Q_D(QQuickFlow);
+    if (d->layoutDirection != layoutDirection) {
+        d->layoutDirection = layoutDirection;
+        prePositioning();
+        emit layoutDirectionChanged();
+        emit effectiveLayoutDirectionChanged();
+    }
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::Flow::effectiveLayoutDirection
+    This property holds the effective layout direction of the flow positioner.
+
+    When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} for locale layouts,
+    the visual layout direction of the grid positioner will be mirrored. However, the
+    property \l {Flow::layoutDirection}{layoutDirection} will remain unchanged.
+
+    \sa Flow::layoutDirection, {LayoutMirroring}{LayoutMirroring}
+*/
+
+Qt::LayoutDirection QQuickFlow::effectiveLayoutDirection() const
+{
+    return QQuickBasePositionerPrivate::getEffectiveLayoutDirection(this);
+}
+
+void QQuickFlow::doPositioning(QSizeF *contentSize)
+{
+    Q_D(QQuickFlow);
+
+    int hoffset = 0;
+    int voffset = 0;
+    int linemax = 0;
+    QList<int> hoffsets;
+
+    for (int i = 0; i < positionedItems.count(); ++i) {
+        const PositionedItem &child = positionedItems.at(i);
+        if (!child.item || !child.isVisible)
+            continue;
+
+        if (d->flow == LeftToRight)  {
+            if (widthValid() && hoffset && hoffset + child.item->width() > width()) {
+                hoffset = 0;
+                voffset += linemax + spacing();
+                linemax = 0;
+            }
+        } else {
+            if (heightValid() && voffset && voffset + child.item->height() > height()) {
+                voffset = 0;
+                hoffset += linemax + spacing();
+                linemax = 0;
+            }
+        }
+
+        if (d->isLeftToRight()) {
+            if (child.item->x() != hoffset)
+                positionX(hoffset, child);
+        } else {
+            hoffsets << hoffset;
+        }
+        if (child.item->y() != voffset)
+            positionY(voffset, child);
+
+        contentSize->setWidth(qMax(contentSize->width(), hoffset + child.item->width()));
+        contentSize->setHeight(qMax(contentSize->height(), voffset + child.item->height()));
+
+        if (d->flow == LeftToRight)  {
+            hoffset += child.item->width();
+            hoffset += spacing();
+            linemax = qMax(linemax, qCeil(child.item->height()));
+        } else {
+            voffset += child.item->height();
+            voffset += spacing();
+            linemax = qMax(linemax, qCeil(child.item->width()));
+        }
+    }
+    if (d->isLeftToRight())
+        return;
+
+    int end;
+    if (widthValid())
+        end = width();
+    else
+        end = contentSize->width();
+    int acc = 0;
+    for (int i = 0; i < positionedItems.count(); ++i) {
+        const PositionedItem &child = positionedItems.at(i);
+        if (!child.item || !child.isVisible)
+            continue;
+        hoffset = end - hoffsets[acc++] - child.item->width();
+        if (child.item->x() != hoffset)
+            positionX(hoffset, child);
+    }
+}
+
+void QQuickFlow::reportConflictingAnchors()
+{
+    Q_D(QQuickFlow);
+    for (int ii = 0; ii < positionedItems.count(); ++ii) {
+        const PositionedItem &child = positionedItems.at(ii);
+        if (child.item) {
+            QQuickAnchors *anchors = QQuickItemPrivate::get(static_cast<QQuickItem *>(child.item))->_anchors;
+            if (anchors && (anchors->usedAnchors() || anchors->fill() || anchors->centerIn())) {
+                d->anchorConflict = true;
+                break;
+            }
+        }
+    }
+    if (d->anchorConflict)
+        qmlInfo(this) << "Cannot specify anchors for items inside Flow";
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickpositioners_p.h b/src/declarative/items/qquickpositioners_p.h
new file mode 100644 (file)
index 0000000..b8e8879
--- /dev/null
@@ -0,0 +1,295 @@
+// Commit: 2c7cab4172f1acc86fd49345a2847417e162f2c3
+/****************************************************************************
+**
+** 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 QQUICKPOSITIONERS_P_H
+#define QQUICKPOSITIONERS_P_H
+
+#include "qquickimplicitsizeitem_p.h"
+
+#include <private/qdeclarativestate_p.h>
+#include <private/qpodvector_p.h>
+
+#include <QtCore/qobject.h>
+#include <QtCore/qstring.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickBasePositionerPrivate;
+
+class QQuickPositionerAttached : public QObject
+{
+    Q_OBJECT
+
+public:
+    QQuickPositionerAttached(QObject *parent);
+
+    Q_PROPERTY(int index READ index NOTIFY indexChanged)
+    Q_PROPERTY(bool isFirstItem READ isFirstItem NOTIFY isFirstItemChanged)
+    Q_PROPERTY(bool isLastItem READ isLastItem NOTIFY isLastItemChanged)
+
+    int index() const { return m_index; }
+    void setIndex(int index);
+
+    bool isFirstItem() const { return m_isFirstItem; }
+    void setIsFirstItem(bool isFirstItem);
+
+    bool isLastItem() const { return m_isLastItem; }
+    void setIsLastItem(bool isLastItem);
+
+Q_SIGNALS:
+    void indexChanged();
+    void isFirstItemChanged();
+    void isLastItemChanged();
+
+private:
+    int m_index;
+    bool m_isFirstItem;
+    bool m_isLastItem;
+};
+
+class Q_DECLARATIVE_PRIVATE_EXPORT QQuickBasePositioner : public QQuickImplicitSizeItem
+{
+    Q_OBJECT
+
+    Q_PROPERTY(int spacing READ spacing WRITE setSpacing NOTIFY spacingChanged)
+    Q_PROPERTY(QDeclarativeTransition *move READ move WRITE setMove NOTIFY moveChanged)
+    Q_PROPERTY(QDeclarativeTransition *add READ add WRITE setAdd NOTIFY addChanged)
+public:
+    enum PositionerType { None = 0x0, Horizontal = 0x1, Vertical = 0x2, Both = 0x3 };
+    QQuickBasePositioner(PositionerType, QQuickItem *parent);
+    ~QQuickBasePositioner();
+
+    int spacing() const;
+    void setSpacing(int);
+
+    QDeclarativeTransition *move() const;
+    void setMove(QDeclarativeTransition *);
+
+    QDeclarativeTransition *add() const;
+    void setAdd(QDeclarativeTransition *);
+
+    static QQuickPositionerAttached *qmlAttachedProperties(QObject *obj);
+
+    void updateAttachedProperties(QQuickPositionerAttached *specificProperty = 0, QQuickItem *specificPropertyOwner = 0) const;
+
+protected:
+    QQuickBasePositioner(QQuickBasePositionerPrivate &dd, PositionerType at, QQuickItem *parent);
+    virtual void componentComplete();
+    virtual void itemChange(ItemChange, const ItemChangeData &);
+    void finishApplyTransitions();
+
+    virtual void updatePolish();
+
+Q_SIGNALS:
+    void spacingChanged();
+    void moveChanged();
+    void addChanged();
+
+protected Q_SLOTS:
+    void prePositioning();
+
+protected:
+    virtual void doPositioning(QSizeF *contentSize)=0;
+    virtual void reportConflictingAnchors()=0;
+    class PositionedItem {
+    public :
+        PositionedItem(QQuickItem *i) : item(i), isNew(false), isVisible(true) {}
+        bool operator==(const PositionedItem &other) const { return other.item == item; }
+        QQuickItem *item;
+        bool isNew;
+        bool isVisible;
+    };
+
+    QPODVector<PositionedItem,8> positionedItems;
+    void positionX(int,const PositionedItem &target);
+    void positionY(int,const PositionedItem &target);
+
+private:
+    Q_DISABLE_COPY(QQuickBasePositioner)
+    Q_DECLARE_PRIVATE(QQuickBasePositioner)
+};
+
+class Q_AUTOTEST_EXPORT QQuickColumn : public QQuickBasePositioner
+{
+    Q_OBJECT
+public:
+    QQuickColumn(QQuickItem *parent=0);
+
+protected:
+    virtual void doPositioning(QSizeF *contentSize);
+    virtual void reportConflictingAnchors();
+private:
+    Q_DISABLE_COPY(QQuickColumn)
+};
+
+class Q_AUTOTEST_EXPORT QQuickRow: public QQuickBasePositioner
+{
+    Q_OBJECT
+    Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
+    Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
+public:
+    QQuickRow(QQuickItem *parent=0);
+
+    Qt::LayoutDirection layoutDirection() const;
+    void setLayoutDirection (Qt::LayoutDirection);
+    Qt::LayoutDirection effectiveLayoutDirection() const;
+
+Q_SIGNALS:
+    void layoutDirectionChanged();
+    void effectiveLayoutDirectionChanged();
+
+protected:
+    virtual void doPositioning(QSizeF *contentSize);
+    virtual void reportConflictingAnchors();
+private:
+    Q_DISABLE_COPY(QQuickRow)
+};
+
+class Q_AUTOTEST_EXPORT QQuickGrid : public QQuickBasePositioner
+{
+    Q_OBJECT
+    Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged)
+    Q_PROPERTY(int columns READ columns WRITE setColumns NOTIFY columnsChanged)
+    Q_PROPERTY(int rowSpacing READ rowSpacing WRITE setRowSpacing NOTIFY rowSpacingChanged)
+    Q_PROPERTY(int columnSpacing READ columnSpacing WRITE setColumnSpacing NOTIFY columnSpacingChanged)
+    Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged)
+    Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
+    Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
+
+public:
+    QQuickGrid(QQuickItem *parent=0);
+
+    int rows() const {return m_rows;}
+    void setRows(const int rows);
+
+    int columns() const {return m_columns;}
+    void setColumns(const int columns);
+
+    int rowSpacing() const { return m_rowSpacing; }
+    void setRowSpacing(int);
+
+    int columnSpacing() const { return m_columnSpacing; }
+    void setColumnSpacing(int);
+
+    Q_ENUMS(Flow)
+    enum Flow { LeftToRight, TopToBottom };
+    Flow flow() const;
+    void setFlow(Flow);
+
+    Qt::LayoutDirection layoutDirection() const;
+    void setLayoutDirection (Qt::LayoutDirection);
+    Qt::LayoutDirection effectiveLayoutDirection() const;
+
+Q_SIGNALS:
+    void rowsChanged();
+    void columnsChanged();
+    void flowChanged();
+    void layoutDirectionChanged();
+    void effectiveLayoutDirectionChanged();
+    void rowSpacingChanged();
+    void columnSpacingChanged();
+
+protected:
+    virtual void doPositioning(QSizeF *contentSize);
+    virtual void reportConflictingAnchors();
+
+private:
+    int m_rows;
+    int m_columns;
+    int m_rowSpacing;
+    int m_columnSpacing;
+    Flow m_flow;
+    Q_DISABLE_COPY(QQuickGrid)
+};
+
+class QQuickFlowPrivate;
+class Q_AUTOTEST_EXPORT QQuickFlow: public QQuickBasePositioner
+{
+    Q_OBJECT
+    Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged)
+    Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
+    Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
+public:
+    QQuickFlow(QQuickItem *parent=0);
+
+    Q_ENUMS(Flow)
+    enum Flow { LeftToRight, TopToBottom };
+    Flow flow() const;
+    void setFlow(Flow);
+
+    Qt::LayoutDirection layoutDirection() const;
+    void setLayoutDirection (Qt::LayoutDirection);
+    Qt::LayoutDirection effectiveLayoutDirection() const;
+
+Q_SIGNALS:
+    void flowChanged();
+    void layoutDirectionChanged();
+    void effectiveLayoutDirectionChanged();
+
+protected:
+    virtual void doPositioning(QSizeF *contentSize);
+    virtual void reportConflictingAnchors();
+protected:
+    QQuickFlow(QQuickFlowPrivate &dd, QQuickItem *parent);
+private:
+    Q_DISABLE_COPY(QQuickFlow)
+    Q_DECLARE_PRIVATE(QQuickFlow)
+};
+
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickColumn)
+QML_DECLARE_TYPE(QQuickRow)
+QML_DECLARE_TYPE(QQuickGrid)
+QML_DECLARE_TYPE(QQuickFlow)
+
+QML_DECLARE_TYPE(QQuickBasePositioner)
+QML_DECLARE_TYPEINFO(QQuickBasePositioner, QML_HAS_ATTACHED_PROPERTIES)
+
+QT_END_HEADER
+
+#endif // QQUICKPOSITIONERS_P_H
diff --git a/src/declarative/items/qquickpositioners_p_p.h b/src/declarative/items/qquickpositioners_p_p.h
new file mode 100644 (file)
index 0000000..86c6c74
--- /dev/null
@@ -0,0 +1,164 @@
+// Commit: 2c7cab4172f1acc86fd49345a2847417e162f2c3
+/****************************************************************************
+**
+** 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 QQUICKPOSITIONERS_P_P_H
+#define QQUICKPOSITIONERS_P_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 "qquickpositioners_p.h"
+#include "qquickimplicitsizeitem_p_p.h"
+
+#include <private/qdeclarativestate_p.h>
+#include <private/qdeclarativetransitionmanager_p_p.h>
+#include <private/qdeclarativestateoperations_p.h>
+
+#include <QtCore/qobject.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qtimer.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickBasePositionerPrivate : public QQuickImplicitSizeItemPrivate, public QQuickItemChangeListener
+{
+    Q_DECLARE_PUBLIC(QQuickBasePositioner)
+
+public:
+    QQuickBasePositionerPrivate()
+        : spacing(0), type(QQuickBasePositioner::None)
+        , moveTransition(0), addTransition(0), positioningDirty(false)
+        , doingPositioning(false), anchorConflict(false), layoutDirection(Qt::LeftToRight)
+    {
+    }
+
+    void init(QQuickBasePositioner::PositionerType at)
+    {
+        type = at;
+        childrenDoNotOverlap = true;
+    }
+
+    int spacing;
+
+    QQuickBasePositioner::PositionerType type;
+    QDeclarativeTransition *moveTransition;
+    QDeclarativeTransition *addTransition;
+    QDeclarativeStateOperation::ActionList addActions;
+    QDeclarativeStateOperation::ActionList moveActions;
+    QDeclarativeTransitionManager addTransitionManager;
+    QDeclarativeTransitionManager moveTransitionManager;
+
+    void watchChanges(QQuickItem *other);
+    void unwatchChanges(QQuickItem* other);
+    void setPositioningDirty() {
+        Q_Q(QQuickBasePositioner);
+        if (!positioningDirty) {
+            positioningDirty = true;
+            q->polish();
+        }
+    }
+
+    bool positioningDirty : 1;
+    bool doingPositioning : 1;
+    bool anchorConflict : 1;
+
+    Qt::LayoutDirection layoutDirection;
+
+    void mirrorChange() {
+        if (type != QQuickBasePositioner::Vertical)
+            setPositioningDirty();
+    }
+    bool isLeftToRight() const {
+        if (type == QQuickBasePositioner::Vertical)
+            return true;
+        else
+            return effectiveLayoutMirror ? layoutDirection == Qt::RightToLeft : layoutDirection == Qt::LeftToRight;
+    }
+
+    virtual void itemSiblingOrderChanged(QQuickItem* other)
+    {
+        Q_UNUSED(other);
+        setPositioningDirty();
+    }
+
+    void itemGeometryChanged(QQuickItem *, const QRectF &newGeometry, const QRectF &oldGeometry)
+    {
+        if (newGeometry.size() != oldGeometry.size())
+            setPositioningDirty();
+    }
+
+    virtual void itemVisibilityChanged(QQuickItem *)
+    {
+        setPositioningDirty();
+    }
+
+    void itemDestroyed(QQuickItem *item)
+    {
+        Q_Q(QQuickBasePositioner);
+        q->positionedItems.removeOne(QQuickBasePositioner::PositionedItem(item));
+    }
+
+    static Qt::LayoutDirection getLayoutDirection(const QQuickBasePositioner *positioner)
+    {
+        return positioner->d_func()->layoutDirection;
+    }
+
+    static Qt::LayoutDirection getEffectiveLayoutDirection(const QQuickBasePositioner *positioner)
+    {
+        if (positioner->d_func()->effectiveLayoutMirror)
+            return positioner->d_func()->layoutDirection == Qt::RightToLeft ? Qt::LeftToRight : Qt::RightToLeft;
+        else
+            return positioner->d_func()->layoutDirection;
+    }
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKPOSITIONERS_P_P_H
diff --git a/src/declarative/items/qquickrectangle.cpp b/src/declarative/items/qquickrectangle.cpp
new file mode 100644 (file)
index 0000000..a7f592e
--- /dev/null
@@ -0,0 +1,555 @@
+/****************************************************************************
+**
+** 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 "qquickrectangle_p.h"
+#include "qquickrectangle_p_p.h"
+
+#include <private/qsgcontext_p.h>
+#include <private/qsgadaptationlayer_p.h>
+
+#include <QtGui/qpixmapcache.h>
+#include <QtCore/qstringbuilder.h>
+#include <QtCore/qmath.h>
+
+QT_BEGIN_NAMESPACE
+
+// XXX todo - should we change rectangle to draw entirely within its width/height?
+/*!
+    \internal
+    \class QQuickPen
+    \brief The QQuickPen class provides a pen used for drawing rectangle borders on a QQuickView.
+
+    By default, the pen is invalid and nothing is drawn. You must either set a color (then the default
+    width is 1) or a width (then the default color is black).
+
+    A width of 1 indicates is a single-pixel line on the border of the item being painted.
+
+    Example:
+    \qml
+    Rectangle {
+        border.width: 2
+        border.color: "red"
+    }
+    \endqml
+*/
+
+QQuickPen::QQuickPen(QObject *parent)
+    : QObject(parent)
+    , m_width(1)
+    , m_color("#000000")
+    , m_aligned(true)
+    , m_valid(false)
+{
+}
+
+qreal QQuickPen::width() const
+{
+    return m_width;
+}
+
+void QQuickPen::setWidth(qreal w)
+{
+    if (m_width == w && m_valid)
+        return;
+
+    m_width = w;
+    m_valid = m_color.alpha() && (qRound(m_width) >= 1 || (!m_aligned && m_width > 0));
+    emit penChanged();
+}
+
+QColor QQuickPen::color() const
+{
+    return m_color;
+}
+
+void QQuickPen::setColor(const QColor &c)
+{
+    m_color = c;
+    m_valid = m_color.alpha() && (qRound(m_width) >= 1 || (!m_aligned && m_width > 0));
+    emit penChanged();
+}
+
+bool QQuickPen::aligned() const
+{
+    return m_aligned;
+}
+
+void QQuickPen::setAligned(bool aligned)
+{
+    if (aligned == m_aligned)
+        return;
+    m_aligned = aligned;
+    m_valid = m_color.alpha() && (qRound(m_width) >= 1 || (!m_aligned && m_width > 0));
+    emit penChanged();
+}
+
+bool QQuickPen::isValid() const
+{
+    return m_valid;
+}
+
+/*!
+    \qmlclass GradientStop QQuickGradientStop
+    \inqmlmodule QtQuick 2
+    \ingroup qml-basic-visual-elements
+    \brief The GradientStop item defines the color at a position in a Gradient.
+
+    \sa Gradient
+*/
+
+/*!
+    \qmlproperty real QtQuick2::GradientStop::position
+    \qmlproperty color QtQuick2::GradientStop::color
+
+    The position and color properties describe the color used at a given
+    position in a gradient, as represented by a gradient stop.
+
+    The default position is 0.0; the default color is black.
+
+    \sa Gradient
+*/
+QQuickGradientStop::QQuickGradientStop(QObject *parent)
+    : QObject(parent)
+{
+}
+
+qreal QQuickGradientStop::position() const
+{
+    return m_position;
+}
+
+void QQuickGradientStop::setPosition(qreal position)
+{
+    m_position = position; updateGradient();
+}
+
+QColor QQuickGradientStop::color() const
+{
+    return m_color;
+}
+
+void QQuickGradientStop::setColor(const QColor &color)
+{
+    m_color = color; updateGradient();
+}
+
+void QQuickGradientStop::updateGradient()
+{
+    if (QQuickGradient *grad = qobject_cast<QQuickGradient*>(parent()))
+        grad->doUpdate();
+}
+
+/*!
+    \qmlclass Gradient QQuickGradient
+    \inqmlmodule QtQuick 2
+    \ingroup qml-basic-visual-elements
+    \brief The Gradient item defines a gradient fill.
+
+    A gradient is defined by two or more colors, which will be blended seamlessly.
+
+    The colors are specified as a set of GradientStop child items, each of
+    which defines a position on the gradient from 0.0 to 1.0 and a color.
+    The position of each GradientStop is defined by setting its
+    \l{GradientStop::}{position} property; its color is defined using its
+    \l{GradientStop::}{color} property.
+
+    A gradient without any gradient stops is rendered as a solid white fill.
+
+    Note that this item is not a visual representation of a gradient. To display a
+    gradient, use a visual element (like \l Rectangle) which supports the use
+    of gradients.
+
+    \section1 Example Usage
+
+    \div {class="float-right"}
+    \inlineimage qml-gradient.png
+    \enddiv
+
+    The following example declares a \l Rectangle item with a gradient starting
+    with red, blending to yellow at one third of the height of the rectangle,
+    and ending with green:
+
+    \snippet doc/src/snippets/declarative/gradient.qml code
+
+    \clearfloat
+    \section1 Performance and Limitations
+
+    Calculating gradients can be computationally expensive compared to the use
+    of solid color fills or images. Consider using gradients for static items
+    in a user interface.
+
+    In Qt 4.7, only vertical, linear gradients can be applied to items. If you
+    need to apply different orientations of gradients, a combination of rotation
+    and clipping will need to be applied to the relevant items. This can
+    introduce additional performance requirements for your application.
+
+    The use of animations involving gradient stops may not give the desired
+    result. An alternative way to animate gradients is to use pre-generated
+    images or SVG drawings containing gradients.
+
+    \sa GradientStop
+*/
+
+/*!
+    \qmlproperty list<GradientStop> QtQuick2::Gradient::stops
+    \default
+
+    This property holds the gradient stops describing the gradient.
+
+    By default, this property contains an empty list.
+
+    To set the gradient stops, define them as children of the Gradient element.
+*/
+QQuickGradient::QQuickGradient(QObject *parent)
+: QObject(parent), m_gradient(0)
+{
+}
+
+QQuickGradient::~QQuickGradient()
+{
+    delete m_gradient;
+}
+
+QDeclarativeListProperty<QQuickGradientStop> QQuickGradient::stops()
+{
+    return QDeclarativeListProperty<QQuickGradientStop>(this, m_stops);
+}
+
+const QGradient *QQuickGradient::gradient() const
+{
+    if (!m_gradient && !m_stops.isEmpty()) {
+        m_gradient = new QLinearGradient(0,0,0,1.0);
+        for (int i = 0; i < m_stops.count(); ++i) {
+            const QQuickGradientStop *stop = m_stops.at(i);
+            m_gradient->setCoordinateMode(QGradient::ObjectBoundingMode);
+            m_gradient->setColorAt(stop->position(), stop->color());
+        }
+    }
+
+    return m_gradient;
+}
+
+void QQuickGradient::doUpdate()
+{
+    delete m_gradient;
+    m_gradient = 0;
+    emit updated();
+}
+
+int QQuickRectanglePrivate::doUpdateSlotIdx = -1;
+
+/*!
+    \qmlclass Rectangle QQuickRectangle
+    \inqmlmodule QtQuick 2
+    \ingroup qml-basic-visual-elements
+    \brief The Rectangle item provides a filled rectangle with an optional border.
+    \inherits Item
+
+    Rectangle items are used to fill areas with solid color or gradients, and are
+    often used to hold other items.
+
+    \section1 Appearance
+
+    Each Rectangle item is painted using either a solid fill color, specified using
+    the \l color property, or a gradient, defined using a Gradient element and set
+    using the \l gradient property. If both a color and a gradient are specified,
+    the gradient is used.
+
+    You can add an optional border to a rectangle with its own color and thickness
+    by settting the \l border.color and \l border.width properties.
+
+    You can also create rounded rectangles using the \l radius property. Since this
+    introduces curved edges to the corners of a rectangle, it may be appropriate to
+    set the \l smooth property to improve its appearance.
+
+    \section1 Example Usage
+
+    \div {class="float-right"}
+    \inlineimage declarative-rect.png
+    \enddiv
+
+    The following example shows the effects of some of the common properties on a
+    Rectangle item, which in this case is used to create a square:
+
+    \snippet doc/src/snippets/declarative/rectangle/rectangle.qml document
+
+    \clearfloat
+    \section1 Performance
+
+    Using the \l smooth property improves the appearance of a rounded rectangle at
+    the cost of rendering performance. You should consider unsetting this property
+    for rectangles in motion, and only set it when they are stationary.
+
+    \sa Image
+*/
+
+QQuickRectangle::QQuickRectangle(QQuickItem *parent)
+: QQuickItem(*(new QQuickRectanglePrivate), parent)
+{
+    setFlag(ItemHasContents);
+}
+
+void QQuickRectangle::doUpdate()
+{
+    Q_D(QQuickRectangle);
+    qreal penMargin = 0;
+    qreal penOffset = 0;
+    if (d->pen && d->pen->isValid()) {
+        if (d->pen->aligned()) {
+            const int pw = qRound(d->pen->width());
+            penMargin = qreal(0.5) * pw;
+            penOffset = (pw & 1) * qreal(0.5);
+        } else {
+            penMargin = qreal(0.5) * d->pen->width();
+        }
+    }
+    if (penMargin != d->penMargin || penOffset != d->penOffset) {
+        d->penMargin = penMargin;
+        d->penOffset = penOffset;
+        d->dirty(QQuickItemPrivate::Size); // update clip
+    }
+    update();
+}
+
+/*!
+    \qmlproperty int QtQuick2::Rectangle::border.width
+    \qmlproperty color QtQuick2::Rectangle::border.color
+
+    The width and color used to draw the border of the rectangle.
+
+    A width of 1 creates a thin line. For no line, use a width of 0 or a transparent color.
+
+    \note The width of the rectangle's border does not affect the geometry of the
+    rectangle itself or its position relative to other items if anchors are used.
+
+    If \c border.width is an odd number, the rectangle is painted at a half-pixel offset to retain
+    border smoothness. Also, the border is rendered evenly on either side of the
+    rectangle's boundaries, and the spare pixel is rendered to the right and below the
+    rectangle (as documented for QRect rendering). This can cause unintended effects if
+    \c border.width is 1 and the rectangle is \l{Item::clip}{clipped} by a parent item:
+
+    \div {class="float-right"}
+    \inlineimage rect-border-width.png
+    \enddiv
+
+    \snippet doc/src/snippets/declarative/rectangle/rect-border-width.qml 0
+
+    \clearfloat
+    Here, the innermost rectangle's border is clipped on the bottom and right edges by its
+    parent. To avoid this, the border width can be set to two instead of one.
+*/
+QQuickPen *QQuickRectangle::border()
+{
+    Q_D(QQuickRectangle);
+    return d->getPen();
+}
+
+/*!
+    \qmlproperty Gradient QtQuick2::Rectangle::gradient
+
+    The gradient to use to fill the rectangle.
+
+    This property allows for the construction of simple vertical gradients.
+    Other gradients may by formed by adding rotation to the rectangle.
+
+    \div {class="float-left"}
+    \inlineimage declarative-rect_gradient.png
+    \enddiv
+
+    \snippet doc/src/snippets/declarative/rectangle/rectangle-gradient.qml rectangles
+    \clearfloat
+
+    If both a gradient and a color are specified, the gradient will be used.
+
+    \sa Gradient, color
+*/
+QQuickGradient *QQuickRectangle::gradient() const
+{
+    Q_D(const QQuickRectangle);
+    return d->gradient;
+}
+
+void QQuickRectangle::setGradient(QQuickGradient *gradient)
+{
+    Q_D(QQuickRectangle);
+    if (d->gradient == gradient)
+        return;
+    static int updatedSignalIdx = -1;
+    if (updatedSignalIdx < 0)
+        updatedSignalIdx = QQuickGradient::staticMetaObject.indexOfSignal("updated()");
+    if (d->doUpdateSlotIdx < 0)
+        d->doUpdateSlotIdx = QQuickRectangle::staticMetaObject.indexOfSlot("doUpdate()");
+    if (d->gradient)
+        QMetaObject::disconnect(d->gradient, updatedSignalIdx, this, d->doUpdateSlotIdx);
+    d->gradient = gradient;
+    if (d->gradient)
+        QMetaObject::connect(d->gradient, updatedSignalIdx, this, d->doUpdateSlotIdx);
+    update();
+}
+
+/*!
+    \qmlproperty real QtQuick2::Rectangle::radius
+    This property holds the corner radius used to draw a rounded rectangle.
+
+    If radius is non-zero, the rectangle will be painted as a rounded rectangle, otherwise it will be
+    painted as a normal rectangle. The same radius is used by all 4 corners; there is currently
+    no way to specify different radii for different corners.
+*/
+qreal QQuickRectangle::radius() const
+{
+    Q_D(const QQuickRectangle);
+    return d->radius;
+}
+
+void QQuickRectangle::setRadius(qreal radius)
+{
+    Q_D(QQuickRectangle);
+    if (d->radius == radius)
+        return;
+
+    d->radius = radius;
+    update();
+    emit radiusChanged();
+}
+
+/*!
+    \qmlproperty color QtQuick2::Rectangle::color
+    This property holds the color used to fill the rectangle.
+
+    The default color is white.
+
+    \div {class="float-right"}
+    \inlineimage rect-color.png
+    \enddiv
+
+    The following example shows rectangles with colors specified
+    using hexadecimal and named color notation:
+
+    \snippet doc/src/snippets/declarative/rectangle/rectangle-colors.qml rectangles
+
+    \clearfloat
+    If both a gradient and a color are specified, the gradient will be used.
+
+    \sa gradient
+*/
+QColor QQuickRectangle::color() const
+{
+    Q_D(const QQuickRectangle);
+    return d->color;
+}
+
+void QQuickRectangle::setColor(const QColor &c)
+{
+    Q_D(QQuickRectangle);
+    if (d->color == c)
+        return;
+
+    d->color = c;
+    update();
+    emit colorChanged();
+}
+
+QSGNode *QQuickRectangle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
+{
+    Q_UNUSED(data);
+    Q_D(QQuickRectangle);
+
+    if (width() <= 0 || height() <= 0) {
+        delete oldNode;
+        return 0;
+    }
+
+    QSGRectangleNode *rectangle = static_cast<QSGRectangleNode *>(oldNode);
+    if (!rectangle) rectangle = d->sceneGraphContext()->createRectangleNode();
+
+    rectangle->setRect(QRectF(0, 0, width(), height()));
+    rectangle->setColor(d->color);
+
+    if (d->pen && d->pen->isValid()) {
+        rectangle->setPenColor(d->pen->color());
+        rectangle->setPenWidth(d->pen->width());
+        rectangle->setAligned(d->pen->aligned());
+    } else {
+        rectangle->setPenWidth(0);
+    }
+
+    rectangle->setRadius(d->radius);
+
+    QGradientStops stops;
+    if (d->gradient) {
+        QList<QQuickGradientStop *> qxstops = d->gradient->m_stops;
+        for (int i = 0; i < qxstops.size(); ++i){
+            int j = 0;
+            while (j < stops.size() && stops.at(j).first < qxstops[i]->position())
+                j++;
+            stops.insert(j, QGradientStop(qxstops.at(i)->position(), qxstops.at(i)->color()));
+        }
+    }
+    rectangle->setGradientStops(stops);
+
+    rectangle->update();
+
+    return rectangle;
+}
+/*!
+    \qmlproperty bool QtQuick2::Rectangle::smooth
+
+    Set this property if you want the item to be smoothly scaled or
+    transformed.  Smooth filtering gives better visual quality, but is slower.  If
+    the item is displayed at its natural size, this property has no visual or
+    performance effect.
+
+    \note Generally scaling artifacts are only visible if the item is stationary on
+    the screen.  A common pattern when animating an item is to disable smooth
+    filtering at the beginning of the animation and reenable it at the conclusion.
+
+    \image rect-smooth.png
+    On this image, smooth is turned off on the top half and on on the bottom half.
+*/
+
+QRectF QQuickRectangle::boundingRect() const
+{
+    Q_D(const QQuickRectangle);
+    return QRectF(d->penOffset - d->penMargin, d->penOffset - d->penMargin,
+                  d->width + 2 * d->penMargin, d->height + 2 * d->penMargin);
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickrectangle_p.h b/src/declarative/items/qquickrectangle_p.h
new file mode 100644 (file)
index 0000000..838b944
--- /dev/null
@@ -0,0 +1,189 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
+/****************************************************************************
+**
+** 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 QQUICKRECTANGLE_P_H
+#define QQUICKRECTANGLE_P_H
+
+#include "qquickitem.h"
+
+#include <QtGui/qbrush.h>
+
+#include <private/qdeclarativeglobal_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class Q_DECLARATIVE_PRIVATE_EXPORT QQuickPen : public QObject
+{
+    Q_OBJECT
+
+    Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY penChanged)
+    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY penChanged)
+    Q_PROPERTY(bool aligned READ aligned WRITE setAligned NOTIFY penChanged)
+public:
+    QQuickPen(QObject *parent=0);
+
+    qreal width() const;
+    void setWidth(qreal w);
+
+    QColor color() const;
+    void setColor(const QColor &c);
+
+    bool aligned() const;
+    void setAligned(bool aligned);
+
+    bool isValid() const;
+
+Q_SIGNALS:
+    void penChanged();
+
+private:
+    qreal m_width;
+    QColor m_color;
+    bool m_aligned : 1;
+    bool m_valid : 1;
+};
+
+class Q_AUTOTEST_EXPORT QQuickGradientStop : public QObject
+{
+    Q_OBJECT
+
+    Q_PROPERTY(qreal position READ position WRITE setPosition)
+    Q_PROPERTY(QColor color READ color WRITE setColor)
+
+public:
+    QQuickGradientStop(QObject *parent=0);
+
+    qreal position() const;
+    void setPosition(qreal position);
+
+    QColor color() const;
+    void setColor(const QColor &color);
+
+private:
+    void updateGradient();
+
+private:
+    qreal m_position;
+    QColor m_color;
+};
+
+class Q_AUTOTEST_EXPORT QQuickGradient : public QObject
+{
+    Q_OBJECT
+
+    Q_PROPERTY(QDeclarativeListProperty<QQuickGradientStop> stops READ stops)
+    Q_CLASSINFO("DefaultProperty", "stops")
+
+public:
+    QQuickGradient(QObject *parent=0);
+    ~QQuickGradient();
+
+    QDeclarativeListProperty<QQuickGradientStop> stops();
+
+    const QGradient *gradient() const;
+
+Q_SIGNALS:
+    void updated();
+
+private:
+    void doUpdate();
+
+private:
+    QList<QQuickGradientStop *> m_stops;
+    mutable QGradient *m_gradient;
+    friend class QQuickRectangle;
+    friend class QQuickGradientStop;
+};
+
+class QQuickRectanglePrivate;
+class Q_DECLARATIVE_PRIVATE_EXPORT QQuickRectangle : public QQuickItem
+{
+    Q_OBJECT
+
+    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
+    Q_PROPERTY(QQuickGradient *gradient READ gradient WRITE setGradient)
+    Q_PROPERTY(QQuickPen * border READ border CONSTANT)
+    Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged)
+public:
+    QQuickRectangle(QQuickItem *parent=0);
+
+    QColor color() const;
+    void setColor(const QColor &);
+
+    QQuickPen *border();
+
+    QQuickGradient *gradient() const;
+    void setGradient(QQuickGradient *gradient);
+
+    qreal radius() const;
+    void setRadius(qreal radius);
+
+    virtual QRectF boundingRect() const;
+
+Q_SIGNALS:
+    void colorChanged();
+    void radiusChanged();
+
+protected:
+    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+
+private Q_SLOTS:
+    void doUpdate();
+
+private:
+    Q_DISABLE_COPY(QQuickRectangle)
+    Q_DECLARE_PRIVATE(QQuickRectangle)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickPen)
+QML_DECLARE_TYPE(QQuickGradientStop)
+QML_DECLARE_TYPE(QQuickGradient)
+QML_DECLARE_TYPE(QQuickRectangle)
+
+QT_END_HEADER
+
+#endif // QQUICKRECTANGLE_P_H
diff --git a/src/declarative/items/qquickrectangle_p_p.h b/src/declarative/items/qquickrectangle_p_p.h
new file mode 100644 (file)
index 0000000..93140ce
--- /dev/null
@@ -0,0 +1,103 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
+/****************************************************************************
+**
+** 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 QQUICKRECTANGLE_P_P_H
+#define QQUICKRECTANGLE_P_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 "qquickitem_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickGradient;
+class QQuickRectangle;
+class QQuickRectanglePrivate : public QQuickItemPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickRectangle)
+
+public:
+    QQuickRectanglePrivate() :
+    color(Qt::white), gradient(0), pen(0), radius(0), penMargin(0), penOffset(0)
+    {
+    }
+
+    ~QQuickRectanglePrivate()
+    {
+        delete pen;
+    }
+
+    QColor color;
+    QQuickGradient *gradient;
+    QQuickPen *pen;
+    qreal radius;
+    qreal penMargin;
+    qreal penOffset;
+    static int doUpdateSlotIdx;
+
+    QQuickPen *getPen() {
+        if (!pen) {
+            Q_Q(QQuickRectangle);
+            pen = new QQuickPen;
+            static int penChangedSignalIdx = -1;
+            if (penChangedSignalIdx < 0)
+                penChangedSignalIdx = QQuickPen::staticMetaObject.indexOfSignal("penChanged()");
+            if (doUpdateSlotIdx < 0)
+                doUpdateSlotIdx = QQuickRectangle::staticMetaObject.indexOfSlot("doUpdate()");
+            QMetaObject::connect(pen, penChangedSignalIdx, q, doUpdateSlotIdx);
+        }
+        return pen;
+    }
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKRECTANGLE_P_P_H
diff --git a/src/declarative/items/qquickrepeater.cpp b/src/declarative/items/qquickrepeater.cpp
new file mode 100644 (file)
index 0000000..48632ef
--- /dev/null
@@ -0,0 +1,438 @@
+/****************************************************************************
+**
+** 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 "qquickrepeater_p.h"
+#include "qquickrepeater_p_p.h"
+#include "qquickvisualdatamodel_p.h"
+
+#include <private/qdeclarativeglobal_p.h>
+#include <private/qdeclarativelistaccessor_p.h>
+#include <private/qlistmodelinterface_p.h>
+#include <private/qdeclarativechangeset_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QQuickRepeaterPrivate::QQuickRepeaterPrivate()
+: model(0), ownModel(false)
+{
+}
+
+QQuickRepeaterPrivate::~QQuickRepeaterPrivate()
+{
+    if (ownModel)
+        delete model;
+}
+
+/*!
+    \qmlclass Repeater QQuickRepeater
+    \inqmlmodule QtQuick 2
+    \ingroup qml-utility-elements
+    \inherits Item
+
+    \brief The Repeater element allows you to repeat an Item-based component using a model.
+
+    The Repeater element is used to create a large number of
+    similar items. Like other view elements, a Repeater has a \l model and a \l delegate:
+    for each entry in the model, the delegate is instantiated
+    in a context seeded with data from the model. A Repeater item is usually
+    enclosed in a positioner element such as \l Row or \l Column to visually
+    position the multiple delegate items created by the Repeater.
+
+    The following Repeater creates three instances of a \l Rectangle item within
+    a \l Row:
+
+    \snippet doc/src/snippets/declarative/repeaters/repeater.qml import
+    \codeline
+    \snippet doc/src/snippets/declarative/repeaters/repeater.qml simple
+
+    \image repeater-simple.png
+
+    A Repeater's \l model can be any of the supported \l {qmlmodels}{data models}.
+    Additionally, like delegates for other views, a Repeater delegate can access
+    its index within the repeater, as well as the model data relevant to the
+    delegate. See the \l delegate property documentation for details.
+
+    Items instantiated by the Repeater are inserted, in order, as
+    children of the Repeater's parent.  The insertion starts immediately after
+    the repeater's position in its parent stacking list.  This allows
+    a Repeater to be used inside a layout. For example, the following Repeater's
+    items are stacked between a red rectangle and a blue rectangle:
+
+    \snippet doc/src/snippets/declarative/repeaters/repeater.qml layout
+
+    \image repeater.png
+
+
+    \note A Repeater item owns all items it instantiates. Removing or dynamically destroying
+    an item created by a Repeater results in unpredictable behavior.
+
+
+    \section2 Considerations when using Repeater
+
+    The Repeater element creates all of its delegate items when the repeater is first
+    created. This can be inefficient if there are a large number of delegate items and
+    not all of the items are required to be visible at the same time. If this is the case,
+    consider using other view elements like ListView (which only creates delegate items
+    when they are scrolled into view) or use the \l {Dynamic Object Creation} methods to
+    create items as they are required.
+
+    Also, note that Repeater is \l {Item}-based, and can only repeat \l {Item}-derived objects.
+    For example, it cannot be used to repeat QtObjects:
+    \badcode
+    Item {
+        //XXX does not work! Can't repeat QtObject as it doesn't derive from Item.
+        Repeater {
+            model: 10
+            QtObject {}
+        }
+    }
+    \endcode
+ */
+
+/*!
+    \qmlsignal QtQuick2::Repeater::onItemAdded(int index, Item item)
+
+    This handler is called when an item is added to the repeater. The \a index
+    parameter holds the index at which the item has been inserted within the
+    repeater, and the \a item parameter holds the \l Item that has been added.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Repeater::onItemRemoved(int index, Item item)
+
+    This handler is called when an item is removed from the repeater. The \a index
+    parameter holds the index at which the item was removed from the repeater,
+    and the \a item parameter holds the \l Item that was removed.
+
+    Do not keep a reference to \a item if it was created by this repeater, as
+    in these cases it will be deleted shortly after the handler is called.
+*/
+QQuickRepeater::QQuickRepeater(QQuickItem *parent)
+  : QQuickItem(*(new QQuickRepeaterPrivate), parent)
+{
+}
+
+QQuickRepeater::~QQuickRepeater()
+{
+}
+
+/*!
+    \qmlproperty any QtQuick2::Repeater::model
+
+    The model providing data for the repeater.
+
+    This property can be set to any of the supported \l {qmlmodels}{data models}:
+
+    \list
+    \o A number that indicates the number of delegates to be created by the repeater
+    \o A model (e.g. a ListModel item, or a QAbstractItemModel subclass)
+    \o A string list
+    \o An object list
+    \endlist
+
+    The type of model affects the properties that are exposed to the \l delegate.
+
+    \sa {qmlmodels}{Data Models}
+*/
+QVariant QQuickRepeater::model() const
+{
+    Q_D(const QQuickRepeater);
+    return d->dataSource;
+}
+
+void QQuickRepeater::setModel(const QVariant &model)
+{
+    Q_D(QQuickRepeater);
+    if (d->dataSource == model)
+        return;
+
+    clear();
+    if (d->model) {
+        disconnect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
+                this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
+        /*
+        disconnect(d->model, SIGNAL(createdItem(int,QQuickItem*)), this, SLOT(createdItem(int,QQuickItem*)));
+        disconnect(d->model, SIGNAL(destroyingItem(QQuickItem*)), this, SLOT(destroyingItem(QQuickItem*)));
+    */
+    }
+    d->dataSource = model;
+    QObject *object = qvariant_cast<QObject*>(model);
+    QQuickVisualModel *vim = 0;
+    if (object && (vim = qobject_cast<QQuickVisualModel *>(object))) {
+        if (d->ownModel) {
+            delete d->model;
+            d->ownModel = false;
+        }
+        d->model = vim;
+    } else {
+        if (!d->ownModel) {
+            d->model = new QQuickVisualDataModel(qmlContext(this));
+            d->ownModel = true;
+            if (isComponentComplete())
+                static_cast<QQuickVisualDataModel *>(d->model)->componentComplete();
+        }
+        if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model))
+            dataModel->setModel(model);
+    }
+    if (d->model) {
+        connect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
+                this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
+        /*
+        connect(d->model, SIGNAL(createdItem(int,QQuickItem*)), this, SLOT(createdItem(int,QQuickItem*)));
+        connect(d->model, SIGNAL(destroyingItem(QQuickItem*)), this, SLOT(destroyingItem(QQuickItem*)));
+        */
+        regenerate();
+    }
+    emit modelChanged();
+    emit countChanged();
+}
+
+/*!
+    \qmlproperty Component QtQuick2::Repeater::delegate
+    \default
+
+    The delegate provides a template defining each item instantiated by the repeater.
+
+    Delegates are exposed to a read-only \c index property that indicates the index
+    of the delegate within the repeater. For example, the following \l Text delegate
+    displays the index of each repeated item:
+
+    \table
+    \row
+    \o \snippet doc/src/snippets/declarative/repeaters/repeater.qml index
+    \o \image repeater-index.png
+    \endtable
+
+    If the \l model is a \l{QStringList-based model}{string list} or
+    \l{QObjectList-based model}{object list}, the delegate is also exposed to
+    a read-only \c modelData property that holds the string or object data. For
+    example:
+
+    \table
+    \row
+    \o \snippet doc/src/snippets/declarative/repeaters/repeater.qml modeldata
+    \o \image repeater-modeldata.png
+    \endtable
+
+    If the \l model is a model object (such as a \l ListModel) the delegate
+    can access all model roles as named properties, in the same way that delegates
+    do for view classes like ListView.
+
+    \sa {QML Data Models}
+ */
+QDeclarativeComponent *QQuickRepeater::delegate() const
+{
+    Q_D(const QQuickRepeater);
+    if (d->model) {
+        if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model))
+            return dataModel->delegate();
+    }
+
+    return 0;
+}
+
+void QQuickRepeater::setDelegate(QDeclarativeComponent *delegate)
+{
+    Q_D(QQuickRepeater);
+    if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model))
+       if (delegate == dataModel->delegate())
+           return;
+
+    if (!d->ownModel) {
+        d->model = new QQuickVisualDataModel(qmlContext(this));
+        d->ownModel = true;
+    }
+    if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model)) {
+        dataModel->setDelegate(delegate);
+        regenerate();
+        emit delegateChanged();
+    }
+}
+
+/*!
+    \qmlproperty int QtQuick2::Repeater::count
+
+    This property holds the number of items in the repeater.
+*/
+int QQuickRepeater::count() const
+{
+    Q_D(const QQuickRepeater);
+    if (d->model)
+        return d->model->count();
+    return 0;
+}
+
+/*!
+    \qmlmethod Item QtQuick2::Repeater::itemAt(index)
+
+    Returns the \l Item that has been created at the given \a index, or \c null
+    if no item exists at \a index.
+*/
+QQuickItem *QQuickRepeater::itemAt(int index) const
+{
+    Q_D(const QQuickRepeater);
+    if (index >= 0 && index < d->deletables.count())
+        return d->deletables[index];
+    return 0;
+}
+
+void QQuickRepeater::componentComplete()
+{
+    Q_D(QQuickRepeater);
+    if (d->model && d->ownModel)
+        static_cast<QQuickVisualDataModel *>(d->model)->componentComplete();
+    QQuickItem::componentComplete();
+    regenerate();
+    if (d->model && d->model->count())
+        emit countChanged();
+}
+
+void QQuickRepeater::itemChange(ItemChange change, const ItemChangeData &value)
+{
+    QQuickItem::itemChange(change, value);
+    if (change == ItemParentHasChanged) {
+        regenerate();
+    }
+}
+
+void QQuickRepeater::clear()
+{
+    Q_D(QQuickRepeater);
+    bool complete = isComponentComplete();
+
+    if (d->model) {
+        while (d->deletables.count() > 0) {
+            QQuickItem *item = d->deletables.takeLast();
+            if (complete)
+                emit itemRemoved(d->deletables.count()-1, item);
+            d->model->release(item);
+        }
+    }
+    d->deletables.clear();
+}
+
+void QQuickRepeater::regenerate()
+{
+    Q_D(QQuickRepeater);
+    if (!isComponentComplete())
+        return;
+
+    clear();
+
+    if (!d->model || !d->model->count() || !d->model->isValid() || !parentItem() || !isComponentComplete())
+        return;
+
+    for (int ii = 0; ii < count(); ++ii) {
+        QQuickItem *item = d->model->item(ii);
+        if (item) {
+            QDeclarative_setParent_noEvent(item, parentItem());
+            item->setParentItem(parentItem());
+            item->stackBefore(this);
+            d->deletables << item;
+            emit itemAdded(ii, item);
+        }
+    }
+}
+
+void QQuickRepeater::modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset)
+{
+    Q_D(QQuickRepeater);
+
+    if (!isComponentComplete())
+        return;
+
+    if (reset) {
+        regenerate();
+        emit countChanged();
+    }
+
+    int difference = 0;
+    QHash<int, QList<QPointer<QQuickItem> > > moved;
+    foreach (const QDeclarativeChangeSet::Remove &remove, changeSet.removes()) {
+        int index = qMin(remove.index, d->deletables.count());
+        int count = qMin(remove.index + remove.count, d->deletables.count()) - index;
+        if (remove.isMove()) {
+            moved.insert(remove.moveId, d->deletables.mid(index, count));
+            d->deletables.erase(
+                    d->deletables.begin() + index,
+                    d->deletables.begin() + index + count);
+        } else while (count--) {
+            QQuickItem *item = d->deletables.takeAt(index);
+            emit itemRemoved(index, item);
+            if (item)
+                d->model->release(item);
+        }
+
+        difference -= remove.count;
+    }
+
+    foreach (const QDeclarativeChangeSet::Insert &insert, changeSet.inserts()) {
+        int index = qMin(insert.index, d->deletables.count());
+        if (insert.isMove()) {
+            QList<QPointer<QQuickItem> > items = moved.value(insert.moveId);
+            d->deletables = d->deletables.mid(0, index) + items + d->deletables.mid(index);
+            QQuickItem *stackBefore = index + items.count() < d->deletables.count()
+                    ? d->deletables.at(index + items.count())
+                    : this;
+            for (int i = index; i < index + items.count(); ++i)
+                d->deletables.at(i)->stackBefore(stackBefore);
+        } else for (int i = 0; i < insert.count; ++i) {
+            int modelIndex = index + i;
+            QQuickItem *item = d->model->item(modelIndex);
+            if (item) {
+                QDeclarative_setParent_noEvent(item, parentItem());
+                item->setParentItem(parentItem());
+                if (modelIndex < d->deletables.count())
+                    item->stackBefore(d->deletables.at(modelIndex));
+                else
+                    item->stackBefore(this);
+                d->deletables.insert(modelIndex, item);
+                emit itemAdded(modelIndex, item);
+            }
+        }
+        difference += insert.count;
+    }
+
+    if (difference != 0)
+        emit countChanged();
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickrepeater_p.h b/src/declarative/items/qquickrepeater_p.h
new file mode 100644 (file)
index 0000000..66e583e
--- /dev/null
@@ -0,0 +1,110 @@
+// Commit: ebd4bc73c46c2962742a682b6a391fb68c482aec
+/****************************************************************************
+**
+** 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 QQUICKREPEATER_P_H
+#define QQUICKREPEATER_P_H
+
+#include "qquickitem.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeChangeSet;
+
+class QQuickRepeaterPrivate;
+class Q_AUTOTEST_EXPORT QQuickRepeater : public QQuickItem
+{
+    Q_OBJECT
+
+    Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged)
+    Q_PROPERTY(QDeclarativeComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
+    Q_PROPERTY(int count READ count NOTIFY countChanged)
+    Q_CLASSINFO("DefaultProperty", "delegate")
+
+public:
+    QQuickRepeater(QQuickItem *parent=0);
+    virtual ~QQuickRepeater();
+
+    QVariant model() const;
+    void setModel(const QVariant &);
+
+    QDeclarativeComponent *delegate() const;
+    void setDelegate(QDeclarativeComponent *);
+
+    int count() const;
+
+    Q_INVOKABLE QQuickItem *itemAt(int index) const;
+
+Q_SIGNALS:
+    void modelChanged();
+    void delegateChanged();
+    void countChanged();
+
+    void itemAdded(int index, QQuickItem *item);
+    void itemRemoved(int index, QQuickItem *item);
+
+private:
+    void clear();
+    void regenerate();
+
+protected:
+    virtual void componentComplete();
+    void itemChange(ItemChange change, const ItemChangeData &value);
+
+private Q_SLOTS:
+    void modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset);
+
+private:
+    Q_DISABLE_COPY(QQuickRepeater)
+    Q_DECLARE_PRIVATE(QQuickRepeater)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickRepeater)
+
+QT_END_HEADER
+
+#endif // QQUICKREPEATER_P_H
diff --git a/src/declarative/items/qquickrepeater_p_p.h b/src/declarative/items/qquickrepeater_p_p.h
new file mode 100644 (file)
index 0000000..a1ec159
--- /dev/null
@@ -0,0 +1,83 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
+/****************************************************************************
+**
+** 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 QQUICKREPEATER_P_P_H
+#define QQUICKREPEATER_P_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 "qquickrepeater_p.h"
+#include "qquickitem_p.h"
+
+#include <QtCore/qpointer.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeContext;
+class QQuickVisualModel;
+class QQuickRepeaterPrivate : public QQuickItemPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickRepeater)
+
+public:
+    QQuickRepeaterPrivate();
+    ~QQuickRepeaterPrivate();
+
+    QQuickVisualModel *model;
+    QVariant dataSource;
+    bool ownModel;
+
+    QList<QPointer<QQuickItem> > deletables;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKREPEATER_P_P_H
diff --git a/src/declarative/items/qquickscalegrid.cpp b/src/declarative/items/qquickscalegrid.cpp
new file mode 100644 (file)
index 0000000..9a8f652
--- /dev/null
@@ -0,0 +1,214 @@
+/****************************************************************************
+**
+** 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 "qquickscalegrid_p_p.h"
+
+#include <QtDeclarative/qdeclarative.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+    \internal
+    \class QQuickScaleGrid
+    \brief The QQuickScaleGrid class allows you to specify a 3x3 grid to use in scaling an image.
+*/
+
+QQuickScaleGrid::QQuickScaleGrid(QObject *parent) : QObject(parent), _left(0), _top(0), _right(0), _bottom(0)
+{
+}
+
+QQuickScaleGrid::~QQuickScaleGrid()
+{
+}
+
+bool QQuickScaleGrid::isNull() const
+{
+    return !_left && !_top && !_right && !_bottom;
+}
+
+void QQuickScaleGrid::setLeft(int pos)
+{
+    if (_left != pos) {
+        _left = pos;
+        emit borderChanged();
+    }
+}
+
+void QQuickScaleGrid::setTop(int pos)
+{
+    if (_top != pos) {
+        _top = pos;
+        emit borderChanged();
+    }
+}
+
+void QQuickScaleGrid::setRight(int pos)
+{
+    if (_right != pos) {
+        _right = pos;
+        emit borderChanged();
+    }
+}
+
+void QQuickScaleGrid::setBottom(int pos)
+{
+    if (_bottom != pos) {
+        _bottom = pos;
+        emit borderChanged();
+    }
+}
+
+QQuickGridScaledImage::QQuickGridScaledImage()
+: _l(-1), _r(-1), _t(-1), _b(-1),
+  _h(QQuickBorderImage::Stretch), _v(QQuickBorderImage::Stretch)
+{
+}
+
+QQuickGridScaledImage::QQuickGridScaledImage(const QQuickGridScaledImage &o)
+: _l(o._l), _r(o._r), _t(o._t), _b(o._b), _h(o._h), _v(o._v), _pix(o._pix)
+{
+}
+
+QQuickGridScaledImage &QQuickGridScaledImage::operator=(const QQuickGridScaledImage &o)
+{
+    _l = o._l;
+    _r = o._r;
+    _t = o._t;
+    _b = o._b;
+    _h = o._h;
+    _v = o._v;
+    _pix = o._pix;
+    return *this;
+}
+
+QQuickGridScaledImage::QQuickGridScaledImage(QIODevice *data)
+: _l(-1), _r(-1), _t(-1), _b(-1), _h(QQuickBorderImage::Stretch), _v(QQuickBorderImage::Stretch)
+{
+    int l = -1;
+    int r = -1;
+    int t = -1;
+    int b = -1;
+    QString imgFile;
+
+    QByteArray raw;
+    while (raw = data->readLine(), !raw.isEmpty()) {
+        QString line = QString::fromUtf8(raw.trimmed());
+        if (line.isEmpty() || line.startsWith(QLatin1Char('#')))
+            continue;
+
+        int colonId = line.indexOf(QLatin1Char(':'));
+        if (colonId <= 0)
+            return;
+
+        QStringList list;
+        list.append(line.left(colonId).trimmed());
+        list.append(line.mid(colonId+1).trimmed());
+
+        if (list[0] == QLatin1String("border.left"))
+            l = list[1].toInt();
+        else if (list[0] == QLatin1String("border.right"))
+            r = list[1].toInt();
+        else if (list[0] == QLatin1String("border.top"))
+            t = list[1].toInt();
+        else if (list[0] == QLatin1String("border.bottom"))
+            b = list[1].toInt();
+        else if (list[0] == QLatin1String("source"))
+            imgFile = list[1];
+        else if (list[0] == QLatin1String("horizontalTileRule"))
+            _h = stringToRule(list[1]);
+        else if (list[0] == QLatin1String("verticalTileRule"))
+            _v = stringToRule(list[1]);
+    }
+
+    if (l < 0 || r < 0 || t < 0 || b < 0 || imgFile.isEmpty())
+        return;
+
+    _l = l; _r = r; _t = t; _b = b;
+
+    _pix = imgFile;
+    if (_pix.startsWith(QLatin1Char('"')) && _pix.endsWith(QLatin1Char('"')))
+        _pix = _pix.mid(1, _pix.size() - 2); // remove leading/trailing quotes.
+}
+
+QQuickBorderImage::TileMode QQuickGridScaledImage::stringToRule(const QString &s)
+{
+    if (s == QLatin1String("Stretch"))
+        return QQuickBorderImage::Stretch;
+    if (s == QLatin1String("Repeat"))
+        return QQuickBorderImage::Repeat;
+    if (s == QLatin1String("Round"))
+        return QQuickBorderImage::Round;
+
+    qWarning("QQuickGridScaledImage: Invalid tile rule specified. Using Stretch.");
+    return QQuickBorderImage::Stretch;
+}
+
+bool QQuickGridScaledImage::isValid() const
+{
+    return _l >= 0;
+}
+
+int QQuickGridScaledImage::gridLeft() const
+{
+    return _l;
+}
+
+int QQuickGridScaledImage::gridRight() const
+{
+    return _r;
+}
+
+int QQuickGridScaledImage::gridTop() const
+{
+    return _t;
+}
+
+int QQuickGridScaledImage::gridBottom() const
+{
+    return _b;
+}
+
+QString QQuickGridScaledImage::pixmapUrl() const
+{
+    return _pix;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickscalegrid_p_p.h b/src/declarative/items/qquickscalegrid_p_p.h
new file mode 100644 (file)
index 0000000..8d93c3b
--- /dev/null
@@ -0,0 +1,134 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
+/****************************************************************************
+**
+** 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 QQUICKSCALEGRID_P_P_H
+#define QQUICKSCALEGRID_P_P_H
+
+#include "qquickborderimage_p.h"
+
+#include <QtDeclarative/qdeclarative.h>
+#include <QtCore/qobject.h>
+
+#include <private/qdeclarativepixmapcache_p.h>
+#include <private/qdeclarativeglobal_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class Q_DECLARATIVE_PRIVATE_EXPORT QQuickScaleGrid : public QObject
+{
+    Q_OBJECT
+    Q_ENUMS(TileRule)
+
+    Q_PROPERTY(int left READ left WRITE setLeft NOTIFY borderChanged)
+    Q_PROPERTY(int top READ top WRITE setTop NOTIFY borderChanged)
+    Q_PROPERTY(int right READ right WRITE setRight NOTIFY borderChanged)
+    Q_PROPERTY(int bottom READ bottom WRITE setBottom NOTIFY borderChanged)
+
+public:
+    QQuickScaleGrid(QObject *parent=0);
+    ~QQuickScaleGrid();
+
+    bool isNull() const;
+
+    int left() const { return _left; }
+    void setLeft(int);
+
+    int top() const { return _top; }
+    void setTop(int);
+
+    int right() const { return _right; }
+    void setRight(int);
+
+    int  bottom() const { return _bottom; }
+    void setBottom(int);
+
+Q_SIGNALS:
+    void borderChanged();
+
+private:
+    int _left;
+    int _top;
+    int _right;
+    int _bottom;
+};
+
+class Q_DECLARATIVE_PRIVATE_EXPORT QQuickGridScaledImage
+{
+public:
+    QQuickGridScaledImage();
+    QQuickGridScaledImage(const QQuickGridScaledImage &);
+    QQuickGridScaledImage(QIODevice*);
+    QQuickGridScaledImage &operator=(const QQuickGridScaledImage &);
+    bool isValid() const;
+    int gridLeft() const;
+    int gridRight() const;
+    int gridTop() const;
+    int gridBottom() const;
+    QQuickBorderImage::TileMode horizontalTileRule() const { return _h; }
+    QQuickBorderImage::TileMode verticalTileRule() const { return _v; }
+
+    QString pixmapUrl() const;
+
+private:
+    static QQuickBorderImage::TileMode stringToRule(const QString &);
+
+private:
+    int _l;
+    int _r;
+    int _t;
+    int _b;
+    QQuickBorderImage::TileMode _h;
+    QQuickBorderImage::TileMode _v;
+    QString _pix;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickScaleGrid)
+
+QT_END_HEADER
+
+#endif // QQUICKSCALEGRID_P_P_H
diff --git a/src/declarative/items/qquickshadereffect.cpp b/src/declarative/items/qquickshadereffect.cpp
new file mode 100644 (file)
index 0000000..a3b57be
--- /dev/null
@@ -0,0 +1,649 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include <private/qquickshadereffect_p.h>
+#include <private/qquickshadereffectnode_p.h>
+
+#include "qsgmaterial.h"
+#include "qquickitem_p.h"
+
+#include <private/qsgcontext_p.h>
+#include <private/qsgtextureprovider_p.h>
+#include "qquickcanvas.h"
+
+#include "qquickimage_p.h"
+#include "qquickshadereffectsource_p.h"
+
+#include <QtCore/qsignalmapper.h>
+#include <QtGui/qopenglframebufferobject.h>
+
+QT_BEGIN_NAMESPACE
+
+static const char qt_default_vertex_code[] =
+    "uniform highp mat4 qt_Matrix;                                  \n"
+    "attribute highp vec4 qt_Vertex;                                \n"
+    "attribute highp vec2 qt_MultiTexCoord0;                        \n"
+    "varying highp vec2 qt_TexCoord0;                               \n"
+    "void main() {                                                  \n"
+    "    qt_TexCoord0 = qt_MultiTexCoord0;                          \n"
+    "    gl_Position = qt_Matrix * qt_Vertex;                       \n"
+    "}";
+
+static const char qt_default_fragment_code[] =
+    "varying highp vec2 qt_TexCoord0;                                   \n"
+    "uniform sampler2D source;                                          \n"
+    "uniform lowp float qt_Opacity;                                     \n"
+    "void main() {                                                      \n"
+    "    gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;   \n"
+    "}";
+
+static const char qt_position_attribute_name[] = "qt_Vertex";
+static const char qt_texcoord_attribute_name[] = "qt_MultiTexCoord0";
+
+const char *qtPositionAttributeName()
+{
+    return qt_position_attribute_name;
+}
+
+const char *qtTexCoordAttributeName()
+{
+    return qt_texcoord_attribute_name;
+}
+
+// TODO: Remove after grace period.
+QQuickShaderEffectItem::QQuickShaderEffectItem(QQuickItem *parent)
+    : QQuickShaderEffect(parent)
+{
+    qWarning("ShaderEffectItem has been deprecated. Use ShaderEffect instead.");
+}
+
+
+/*!
+    \qmlclass ShaderEffect QQuickShaderEffect
+    \inqmlmodule QtQuick 2
+    \ingroup qml-basic-visual-elements
+    \brief The ShaderEffect element applies custom shaders to a rectangle.
+    \inherits Item
+
+    The ShaderEffect element applies a custom OpenGL
+    \l{vertexShader}{vertex} and \l{fragmentShader}{fragment} shader to a
+    rectangle. It allows you to write effects such as drop shadow, blur,
+    colorize and page curl directly in QML.
+
+    There are two types of input to the \l vertexShader:
+    uniform variables and attributes. Some are predefined:
+    \list
+    \o uniform mat4 qt_Matrix - combined transformation
+       matrix, the product of the matrices from the root item to this
+       ShaderEffect, and an orthogonal projection.
+    \o uniform float qt_Opacity - combined opacity, the product of the
+       opacities from the root item to this ShaderEffect.
+    \o attribute vec4 qt_Vertex - vertex position, the top-left vertex has
+       position (0, 0), the bottom-right (\l{Item::width}{width},
+       \l{Item::height}{height}).
+    \o attribute vec2 qt_MultiTexCoord0 - texture coordinate, the top-left
+       coordinate is (0, 0), the bottom-right (1, 1).
+    \endlist
+
+    In addition, any property that can be mapped to an OpenGL Shading Language
+    (GLSL) type is available as a uniform variable. The following list shows
+    how properties are mapped to GLSL uniform variables:
+    \list
+    \o bool, int, qreal -> bool, int, float - If the type in the shader is not
+       the same as in QML, the value is converted automatically.
+    \o QColor -> vec4 - When colors are passed to the shader, they are first
+       premultiplied. Thus Qt.rgba(0.2, 0.6, 1.0, 0.5) becomes
+       vec4(0.1, 0.3, 0.5, 0.5) in the shader, for example.
+    \o QRect, QRectF -> vec4 - Qt.rect(x, y, w, h) becomes vec4(x, y, w, h) in
+       the shader.
+    \o QPoint, QPointF, QSize, QSizeF -> vec2
+    \o QVector3D -> vec3
+    \o QTransform -> mat4
+    \o \l Image, \l ShaderEffectSource -> sampler2D - Origin is in the top-left
+       corner, and the color values are premultiplied.
+    \endlist
+
+    The output from the \l fragmentShader should be premultiplied. If
+    \l blending is enabled, source-over blending is used. However, additive
+    blending can be achieved by outputting zero in the alpha channel.
+
+    \row
+    \o \image declarative-shadereffectitem.png
+    \o \qml
+        import QtQuick 2.0
+
+        Rectangle {
+            width: 200; height: 100
+            Row {
+                Image { id: img; sourceSize { width: 100; height: 100 } source: "qt-logo.png" }
+                ShaderEffect {
+                    width: 100; height: 100
+                    property variant src: img
+                    vertexShader: "
+                        uniform highp mat4 qt_Matrix;
+                        attribute highp vec4 qt_Vertex;
+                        attribute highp vec2 qt_MultiTexCoord0;
+                        varying highp vec2 coord;
+                        void main() {
+                            coord = qt_MultiTexCoord0;
+                            gl_Position = qt_Matrix * qt_Vertex;
+                        }"
+                    fragmentShader: "
+                        varying highp vec2 coord;
+                        uniform sampler2D src;
+                        uniform lowp float qt_Opacity;
+                        void main() {
+                            lowp vec4 tex = texture2D(src, coord);
+                            gl_FragColor = vec4(vec3(dot(tex.rgb, vec3(0.344, 0.5, 0.156))), tex.a) * qt_Opacity;
+                        }"
+                }
+            }
+        }
+        \endqml
+    \endrow
+
+    By default, the ShaderEffect consists of four vertices, one for each
+    corner. For non-linear vertex transformations, like page curl, you can
+    specify a fine grid of vertices by specifying a \l mesh resolution.
+
+    \note Scene Graph textures have origin in the top-left corner rather than
+    bottom-left which is common in OpenGL.
+*/
+
+QQuickShaderEffect::QQuickShaderEffect(QQuickItem *parent)
+    : QQuickItem(parent)
+    , m_meshResolution(1, 1)
+    , m_mesh(0)
+    , m_cullMode(NoCulling)
+    , m_blending(true)
+    , m_dirtyData(true)
+    , m_programDirty(true)
+    , m_dirtyMesh(true)
+    , m_dirtyGeometry(true)
+{
+    setFlag(QQuickItem::ItemHasContents);
+}
+
+QQuickShaderEffect::~QQuickShaderEffect()
+{
+    reset();
+}
+
+void QQuickShaderEffect::componentComplete()
+{
+    updateProperties();
+    QQuickItem::componentComplete();
+}
+
+/*!
+    \qmlproperty string QtQuick2::ShaderEffect::fragmentShader
+
+    This property holds the fragment shader's GLSL source code.
+    The default shader passes the texture coordinate along to the fragment
+    shader as "varying highp vec2 qt_TexCoord0".
+*/
+
+void QQuickShaderEffect::setFragmentShader(const QByteArray &code)
+{
+    if (m_source.fragmentCode.constData() == code.constData())
+        return;
+    m_source.fragmentCode = code;
+    if (isComponentComplete()) {
+        reset();
+        updateProperties();
+    }
+    emit fragmentShaderChanged();
+}
+
+/*!
+    \qmlproperty string QtQuick2::ShaderEffect::vertexShader
+
+    This property holds the vertex shader's GLSL source code.
+    The default shader expects the texture coordinate to be passed from the
+    vertex shader as "varying highp vec2 qt_TexCoord0", and it samples from a
+    sampler2D named "source".
+*/
+
+void QQuickShaderEffect::setVertexShader(const QByteArray &code)
+{
+    if (m_source.vertexCode.constData() == code.constData())
+        return;
+    m_source.vertexCode = code;
+    if (isComponentComplete()) {
+        reset();
+        updateProperties();
+    }
+    emit vertexShaderChanged();
+}
+
+/*!
+    \qmlproperty bool QtQuick2::ShaderEffect::blending
+
+    If this property is true, the output from the \l fragmentShader is blended
+    with the background using source-over blend mode. If false, the background
+    is disregarded. Blending decreases the performance, so you should set this
+    property to false when blending is not needed. The default value is true.
+*/
+
+void QQuickShaderEffect::setBlending(bool enable)
+{
+    if (blending() == enable)
+        return;
+
+    m_blending = enable;
+    update();
+
+    emit blendingChanged();
+}
+
+/*!
+    \qmlproperty variant QtQuick2::ShaderEffect::mesh
+
+    This property defines the mesh used to draw the ShaderEffect. It can hold
+    any mesh object deriving from \l QQuickShaderEffectMesh, such as \l GridMesh.
+    If a size value is assigned to this property, the ShaderEffect implicitly
+    uses a \l GridMesh with the value as
+    \l{GridMesh::resolution}{mesh resolution}. By default, this property is
+    the size 1x1.
+
+    \sa GridMesh
+*/
+
+QVariant QQuickShaderEffect::mesh() const
+{
+    return m_mesh ? qVariantFromValue(static_cast<QObject *>(m_mesh))
+                  : qVariantFromValue(m_meshResolution);
+}
+
+void QQuickShaderEffect::setMesh(const QVariant &mesh)
+{
+    QQuickShaderEffectMesh *newMesh = qobject_cast<QQuickShaderEffectMesh *>(qVariantValue<QObject *>(mesh));
+    if (newMesh && newMesh == m_mesh)
+        return;
+    if (m_mesh)
+        disconnect(m_mesh, SIGNAL(geometryChanged()), this, 0);
+    m_mesh = newMesh;
+    if (m_mesh) {
+        connect(m_mesh, SIGNAL(geometryChanged()), this, SLOT(updateGeometry()));
+    } else {
+        if (qVariantCanConvert<QSize>(mesh)) {
+            m_meshResolution = mesh.toSize();
+        } else {
+            QList<QByteArray> res = mesh.toByteArray().split('x');
+            bool ok = res.size() == 2;
+            if (ok) {
+                int w = res.at(0).toInt(&ok);
+                if (ok) {
+                    int h = res.at(1).toInt(&ok);
+                    if (ok)
+                        m_meshResolution = QSize(w, h);
+                }
+            }
+            if (!ok)
+                qWarning("ShaderEffect: mesh property must be size or object deriving from QQuickShaderEffectMesh.");
+        }
+        m_defaultMesh.setResolution(m_meshResolution);
+    }
+
+    m_dirtyMesh = true;
+    update();
+    emit meshChanged();
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::ShaderEffect::cullMode
+
+    This property defines which sides of the element should be visible.
+
+    \list
+    \o ShaderEffect.NoCulling - Both sides are visible
+    \o ShaderEffect.BackFaceCulling - only front side is visible
+    \o ShaderEffect.FrontFaceCulling - only back side is visible
+    \endlist
+
+    The default is NoCulling.
+*/
+
+void QQuickShaderEffect::setCullMode(CullMode face)
+{
+    if (face == m_cullMode)
+        return;
+    m_cullMode = face;
+    update();
+    emit cullModeChanged();
+}
+
+void QQuickShaderEffect::changeSource(int index)
+{
+    Q_ASSERT(index >= 0 && index < m_sources.size());
+    QVariant v = property(m_sources.at(index).name.constData());
+    setSource(v, index);
+}
+
+void QQuickShaderEffect::updateData()
+{
+    m_dirtyData = true;
+    update();
+}
+
+void QQuickShaderEffect::updateGeometry()
+{
+    m_dirtyGeometry = true;
+    update();
+}
+
+void QQuickShaderEffect::setSource(const QVariant &var, int index)
+{
+    Q_ASSERT(index >= 0 && index < m_sources.size());
+
+    SourceData &source = m_sources[index];
+
+    source.sourceObject = 0;
+    if (var.isNull()) {
+        return;
+    } else if (!qVariantCanConvert<QObject *>(var)) {
+        qWarning("Could not assign source of type '%s' to property '%s'.", var.typeName(), source.name.constData());
+        return;
+    }
+
+    QObject *obj = qVariantValue<QObject *>(var);
+    QQuickItem *item = qobject_cast<QQuickItem *>(obj);
+    if (!item || !item->isTextureProvider()) {
+        qWarning("ShaderEffect: source uniform [%s] is not assigned a valid texture provider: %s [%s]",
+                 source.name.constData(), qPrintable(obj->objectName()), obj->metaObject()->className());
+        return;
+    }
+
+    source.sourceObject = item;
+
+
+    // TODO: Find better solution.
+    // 'item' needs a canvas to get a scenegraph node.
+    // The easiest way to make sure it gets a canvas is to
+    // make it a part of the same item tree as 'this'.
+    if (item && item->parentItem() == 0) {
+        item->setParentItem(this);
+        item->setVisible(false);
+    }
+}
+
+void QQuickShaderEffect::disconnectPropertySignals()
+{
+    disconnect(this, 0, this, SLOT(updateData()));
+    for (int i = 0; i < m_sources.size(); ++i) {
+        SourceData &source = m_sources[i];
+        disconnect(this, 0, source.mapper, 0);
+        disconnect(source.mapper, 0, this, 0);
+    }
+}
+
+void QQuickShaderEffect::connectPropertySignals()
+{
+    QSet<QByteArray>::const_iterator it;
+    for (it = m_source.uniformNames.begin(); it != m_source.uniformNames.end(); ++it) {
+        int pi = metaObject()->indexOfProperty(it->constData());
+        if (pi >= 0) {
+            QMetaProperty mp = metaObject()->property(pi);
+            if (!mp.hasNotifySignal())
+                qWarning("QQuickShaderEffect: property '%s' does not have notification method!", it->constData());
+            QByteArray signalName("2");
+            signalName.append(mp.notifySignal().signature());
+            connect(this, signalName, this, SLOT(updateData()));
+        } else {
+            qWarning("QQuickShaderEffect: '%s' does not have a matching property!", it->constData());
+        }
+    }
+    for (int i = 0; i < m_sources.size(); ++i) {
+        SourceData &source = m_sources[i];
+        int pi = metaObject()->indexOfProperty(source.name.constData());
+        if (pi >= 0) {
+            QMetaProperty mp = metaObject()->property(pi);
+            QByteArray signalName("2");
+            signalName.append(mp.notifySignal().signature());
+            connect(this, signalName, source.mapper, SLOT(map()));
+            source.mapper->setMapping(this, i);
+            connect(source.mapper, SIGNAL(mapped(int)), this, SLOT(changeSource(int)));
+        } else {
+            qWarning("QQuickShaderEffect: '%s' does not have a matching source!", source.name.constData());
+        }
+    }
+}
+
+void QQuickShaderEffect::reset()
+{
+    disconnectPropertySignals();
+
+    m_source.attributeNames.clear();
+    m_source.uniformNames.clear();
+    m_source.respectsOpacity = false;
+    m_source.respectsMatrix = false;
+    m_source.className = metaObject()->className();
+
+    for (int i = 0; i < m_sources.size(); ++i) {
+        const SourceData &source = m_sources.at(i);
+        delete source.mapper;
+        QQuickItem *item = qobject_cast<QQuickItem *>(source.sourceObject);
+        if (item && item->parentItem() == this)
+            item->setParentItem(0);
+    }
+    m_sources.clear();
+
+    m_programDirty = true;
+    m_dirtyMesh = true;
+}
+
+void QQuickShaderEffect::updateProperties()
+{
+    QByteArray vertexCode = m_source.vertexCode;
+    QByteArray fragmentCode = m_source.fragmentCode;
+    if (vertexCode.isEmpty())
+        vertexCode = qt_default_vertex_code;
+    if (fragmentCode.isEmpty())
+        fragmentCode = qt_default_fragment_code;
+
+    lookThroughShaderCode(vertexCode);
+    lookThroughShaderCode(fragmentCode);
+
+    if (!m_mesh && !m_source.attributeNames.contains(qt_position_attribute_name))
+        qWarning("QQuickShaderEffect: Missing reference to \'%s\'.", qt_position_attribute_name);
+    if (!m_mesh && !m_source.attributeNames.contains(qt_texcoord_attribute_name))
+        qWarning("QQuickShaderEffect: Missing reference to \'%s\'.", qt_texcoord_attribute_name);
+    if (!m_source.respectsMatrix)
+        qWarning("QQuickShaderEffect: Missing reference to \'qt_Matrix\'.");
+    if (!m_source.respectsOpacity)
+        qWarning("QQuickShaderEffect: Missing reference to \'qt_Opacity\'.");
+
+    for (int i = 0; i < m_sources.size(); ++i) {
+        QVariant v = property(m_sources.at(i).name);
+        setSource(v, i);
+    }
+
+    connectPropertySignals();
+}
+
+void QQuickShaderEffect::lookThroughShaderCode(const QByteArray &code)
+{
+    // Regexp for matching attributes and uniforms.
+    // In human readable form: attribute|uniform [lowp|mediump|highp] <type> <name>
+    static QRegExp re(QLatin1String("\\b(attribute|uniform)\\b\\s*\\b(?:lowp|mediump|highp)?\\b\\s*\\b(\\w+)\\b\\s*\\b(\\w+)"));
+    Q_ASSERT(re.isValid());
+
+    int pos = -1;
+
+    QString wideCode = QString::fromLatin1(code.constData(), code.size());
+
+    while ((pos = re.indexIn(wideCode, pos + 1)) != -1) {
+        QByteArray decl = re.cap(1).toLatin1(); // uniform or attribute
+        QByteArray type = re.cap(2).toLatin1(); // type
+        QByteArray name = re.cap(3).toLatin1(); // variable name
+
+        if (decl == "attribute") {
+            m_source.attributeNames.append(name);
+        } else {
+            Q_ASSERT(decl == "uniform");
+
+            if (name == "qt_Matrix") {
+                m_source.respectsMatrix = true;
+            } else if (name == "qt_ModelViewProjectionMatrix") {
+                // TODO: Remove after grace period.
+                qWarning("ShaderEffect: qt_ModelViewProjectionMatrix is deprecated. Use qt_Matrix instead.");
+                m_source.respectsMatrix = true;
+            } else if (name == "qt_Opacity") {
+                m_source.respectsOpacity = true;
+            } else {
+                m_source.uniformNames.insert(name);
+                if (type == "sampler2D") {
+                    SourceData d;
+                    d.mapper = new QSignalMapper;
+                    d.name = name;
+                    d.sourceObject = 0;
+                    m_sources.append(d);
+                }
+            }
+        }
+    }
+}
+
+void QQuickShaderEffect::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+    m_dirtyGeometry = true;
+    QQuickItem::geometryChanged(newGeometry, oldGeometry);
+}
+
+QSGNode *QQuickShaderEffect::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+    QQuickShaderEffectNode *node = static_cast<QQuickShaderEffectNode *>(oldNode);
+
+    // In the case of a bad vertex shader, don't try to create a node...
+    if (m_source.attributeNames.isEmpty()) {
+        if (node)
+            delete node;
+        return 0;
+    }
+
+    if (!node) {
+        node = new QQuickShaderEffectNode;
+        m_programDirty = true;
+        m_dirtyData = true;
+        m_dirtyGeometry = true;
+    }
+
+    QQuickShaderEffectMaterial *material = node->shaderMaterial();
+
+    if (m_dirtyMesh) {
+        node->setGeometry(0);
+        m_dirtyMesh = false;
+        m_dirtyGeometry = true;
+    }
+
+    if (m_dirtyGeometry) {
+        node->setFlag(QSGNode::OwnsGeometry, false);
+        QSGGeometry *geometry = node->geometry();
+        QRectF rect(0, 0, width(), height());
+        QQuickShaderEffectMesh *mesh = m_mesh ? m_mesh : &m_defaultMesh;
+
+        geometry = mesh->updateGeometry(geometry, m_source.attributeNames, rect);
+        if (!geometry) {
+            delete node;
+            return 0;
+        }
+
+        node->setGeometry(geometry);
+        node->setFlag(QSGNode::OwnsGeometry, true);
+
+        m_dirtyGeometry = false;
+    }
+
+    if (m_programDirty) {
+        QQuickShaderEffectProgram s = m_source;
+        if (s.fragmentCode.isEmpty())
+            s.fragmentCode = qt_default_fragment_code;
+        if (s.vertexCode.isEmpty())
+            s.vertexCode = qt_default_vertex_code;
+        s.className = metaObject()->className();
+
+        material->setProgramSource(s);
+        node->markDirty(QSGNode::DirtyMaterial);
+        m_programDirty = false;
+    }
+
+    // Update blending
+    if (bool(material->flags() & QSGMaterial::Blending) != m_blending) {
+        material->setFlag(QSGMaterial::Blending, m_blending);
+        node->markDirty(QSGNode::DirtyMaterial);
+    }
+
+    if (int(material->cullMode()) != int(m_cullMode)) {
+        material->setCullMode(QQuickShaderEffectMaterial::CullMode(m_cullMode));
+        node->markDirty(QSGNode::DirtyMaterial);
+    }
+
+    if (m_dirtyData) {
+        QVector<QPair<QByteArray, QVariant> > values;
+        QVector<QPair<QByteArray, QSGTextureProvider *> > textures;
+        const QVector<QPair<QByteArray, QSGTextureProvider *> > &oldTextures = material->textureProviders();
+
+        for (QSet<QByteArray>::const_iterator it = m_source.uniformNames.begin();
+             it != m_source.uniformNames.end(); ++it) {
+            values.append(qMakePair(*it, property(*it)));
+        }
+        for (int i = 0; i < oldTextures.size(); ++i) {
+            QSGTextureProvider *t = oldTextures.at(i).second;
+            if (t)
+                disconnect(t, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture()));
+        }
+        for (int i = 0; i < m_sources.size(); ++i) {
+            const SourceData &source = m_sources.at(i);
+            QSGTextureProvider *t = source.sourceObject->textureProvider();
+            textures.append(qMakePair(source.name, t));
+            if (t)
+                connect(t, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture()), Qt::DirectConnection);
+        }
+        material->setUniforms(values);
+        material->setTextureProviders(textures);
+        node->markDirty(QSGNode::DirtyMaterial);
+        m_dirtyData = false;
+    }
+
+    return node;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickshadereffect_p.h b/src/declarative/items/qquickshadereffect_p.h
new file mode 100644 (file)
index 0000000..257fa40
--- /dev/null
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** 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 QQUICKSHADEREFFECT_P_H
+#define QQUICKSHADEREFFECT_P_H
+
+#include "qquickitem.h"
+
+#include "qsgmaterial.h"
+#include <private/qsgadaptationlayer_p.h>
+#include <private/qquickshadereffectnode_p.h>
+#include "qquickshadereffectmesh_p.h"
+
+#include <QtCore/qpointer.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+const char *qtPositionAttributeName();
+const char *qtTexCoordAttributeName();
+
+class QSGContext;
+class QSignalMapper;
+class QQuickCustomMaterialShader;
+
+class QQuickShaderEffect : public QQuickItem
+{
+    Q_OBJECT
+    Q_PROPERTY(QByteArray fragmentShader READ fragmentShader WRITE setFragmentShader NOTIFY fragmentShaderChanged)
+    Q_PROPERTY(QByteArray vertexShader READ vertexShader WRITE setVertexShader NOTIFY vertexShaderChanged)
+    Q_PROPERTY(bool blending READ blending WRITE setBlending NOTIFY blendingChanged)
+    Q_PROPERTY(QVariant mesh READ mesh WRITE setMesh NOTIFY meshChanged)
+    Q_PROPERTY(CullMode culling READ cullMode WRITE setCullMode NOTIFY cullModeChanged)
+    Q_ENUMS(CullMode)
+
+public:
+    enum CullMode
+    {
+        NoCulling = QQuickShaderEffectMaterial::NoCulling,
+        BackFaceCulling = QQuickShaderEffectMaterial::BackFaceCulling,
+        FrontFaceCulling = QQuickShaderEffectMaterial::FrontFaceCulling
+    };
+
+    QQuickShaderEffect(QQuickItem *parent = 0);
+    ~QQuickShaderEffect();
+
+    virtual void componentComplete();
+
+    QByteArray fragmentShader() const { return m_source.fragmentCode; }
+    void setFragmentShader(const QByteArray &code);
+
+    QByteArray vertexShader() const { return m_source.vertexCode; }
+    void setVertexShader(const QByteArray &code);
+
+    bool blending() const { return m_blending; }
+    void setBlending(bool enable);
+
+    QVariant mesh() const;
+    void setMesh(const QVariant &mesh);
+
+    CullMode cullMode() const { return m_cullMode; }
+    void setCullMode(CullMode face);
+
+Q_SIGNALS:
+    void fragmentShaderChanged();
+    void vertexShaderChanged();
+    void blendingChanged();
+    void meshChanged();
+    void cullModeChanged();
+
+protected:
+    virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
+    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+
+private Q_SLOTS:
+    void changeSource(int index);
+    void updateData();
+    void updateGeometry();
+
+private:
+    friend class QQuickCustomMaterialShader;
+    friend class QQuickShaderEffectNode;
+
+    void setSource(const QVariant &var, int index);
+    void disconnectPropertySignals();
+    void connectPropertySignals();
+    void reset();
+    void updateProperties();
+    void lookThroughShaderCode(const QByteArray &code);
+
+    QQuickShaderEffectProgram m_source;
+    QSize m_meshResolution;
+    QQuickShaderEffectMesh *m_mesh;
+    QQuickGridMesh m_defaultMesh;
+    CullMode m_cullMode;
+
+    struct SourceData
+    {
+        QSignalMapper *mapper;
+        QPointer<QQuickItem> sourceObject;
+        QByteArray name;
+    };
+    QVector<SourceData> m_sources;
+
+    uint m_blending : 1;
+    uint m_dirtyData : 1;
+
+    uint m_programDirty : 1;
+    uint m_dirtyMesh : 1;
+    uint m_dirtyGeometry : 1;
+};
+
+// TODO: Remove after grace period.
+class QQuickShaderEffectItem : public QQuickShaderEffect
+{
+public:
+    QQuickShaderEffectItem(QQuickItem *parent = 0);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QQUICKSHADEREFFECT_P_H
diff --git a/src/declarative/items/qquickshadereffectmesh.cpp b/src/declarative/items/qquickshadereffectmesh.cpp
new file mode 100644 (file)
index 0000000..79b37d4
--- /dev/null
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qquickshadereffectmesh_p.h"
+#include "qsggeometry.h"
+#include "qquickshadereffect_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QQuickShaderEffectMesh::QQuickShaderEffectMesh(QObject *parent)
+    : QObject(parent)
+{
+}
+
+/*!
+    \qmlclass GridMesh QQuickGridMesh
+    \inqmlmodule QtQuick 2
+    \ingroup qml-utility-elements
+    \brief GridMesh defines a mesh with vertices arranged in a grid.
+
+    GridMesh defines a rectangular mesh consisting of vertices arranged in an
+    evenly spaced grid. It is used to generate \l{QSGGeometry}{geometry}.
+    The grid resolution is specified with the \l resolution property.
+*/
+
+QQuickGridMesh::QQuickGridMesh(QObject *parent)
+    : QQuickShaderEffectMesh(parent)
+    , m_resolution(1, 1)
+{
+    connect(this, SIGNAL(resolutionChanged()), this, SIGNAL(geometryChanged()));
+}
+
+QSGGeometry *QQuickGridMesh::updateGeometry(QSGGeometry *geometry, const QVector<QByteArray> &attributes, const QRectF &dstRect) const
+{
+    int vmesh = m_resolution.height();
+    int hmesh = m_resolution.width();
+    int attrCount = attributes.count();
+
+    if (!geometry) {
+        bool error = true;
+        switch (attrCount) {
+        case 0:
+            qWarning("QQuickGridMesh:: No attributes specified.");
+            break;
+        case 1:
+            if (attributes.at(0) == qtPositionAttributeName()) {
+                error = false;
+                break;
+            }
+            qWarning("QQuickGridMesh:: Missing \'%s\' attribute.",
+                     qtPositionAttributeName());
+            break;
+        case 2:
+            if (attributes.contains(qtPositionAttributeName())
+                && attributes.contains(qtTexCoordAttributeName()))
+            {
+                error = false;
+                break;
+            }
+            qWarning("QQuickGridMesh:: Missing \'%s\' or \'%s\' attribute.",
+                     qtPositionAttributeName(), qtTexCoordAttributeName());
+            break;
+        default:
+            qWarning("QQuickGridMesh:: Too many attributes specified.");
+            break;
+        }
+
+        geometry = new QSGGeometry(attrCount == 1
+                                   ? QSGGeometry::defaultAttributes_Point2D()
+                                   : QSGGeometry::defaultAttributes_TexturedPoint2D(),
+                                   (vmesh + 1) * (hmesh + 1), vmesh * 2 * (hmesh + 2),
+                                   GL_UNSIGNED_SHORT);
+
+    } else {
+        geometry->allocate((vmesh + 1) * (hmesh + 1), vmesh * 2 * (hmesh + 2));
+    }
+
+    QSGGeometry::Point2D *vdata = static_cast<QSGGeometry::Point2D *>(geometry->vertexData());
+
+    bool positionFirst = attributes.at(0) == qtPositionAttributeName();
+
+    QRectF srcRect(0, 0, 1, 1);
+    for (int iy = 0; iy <= vmesh; ++iy) {
+        float fy = iy / float(vmesh);
+        float y = float(dstRect.top()) + fy * float(dstRect.height());
+        float ty = float(srcRect.top()) + fy * float(srcRect.height());
+        for (int ix = 0; ix <= hmesh; ++ix) {
+            float fx = ix / float(hmesh);
+            for (int ia = 0; ia < attrCount; ++ia) {
+                if (positionFirst == (ia == 0)) {
+                    vdata->x = float(dstRect.left()) + fx * float(dstRect.width());
+                    vdata->y = y;
+                    ++vdata;
+                } else {
+                    vdata->x = float(srcRect.left()) + fx * float(srcRect.width());
+                    vdata->y = ty;
+                    ++vdata;
+                }
+            }
+        }
+    }
+
+    quint16 *indices = (quint16 *)geometry->indexDataAsUShort();
+    int i = 0;
+    for (int iy = 0; iy < vmesh; ++iy) {
+        *(indices++) = i + hmesh + 1;
+        for (int ix = 0; ix <= hmesh; ++ix, ++i) {
+            *(indices++) = i + hmesh + 1;
+            *(indices++) = i;
+        }
+        *(indices++) = i - 1;
+    }
+
+    return geometry;
+}
+
+/*!
+    \qmlproperty size QtQuick2::GridMesh::resolution
+
+    This property holds the grid resolution. The resolution's width and height
+    specify the number of cells or spacings between vertices horizontally and
+    vertically respectively. The minimum and default is 1x1, which corresponds
+    to four vertices in total, one in each corner.
+    For non-linear vertex transformations, you probably want to set the
+    resolution higher.
+
+    \row
+    \o \image declarative-gridmesh.png
+    \o \qml
+        import QtQuick 2.0
+
+        ShaderEffect {
+            width: 200
+            height: 200
+            mesh: GridMesh {
+                resolution: Qt.size(20, 20)
+            }
+            property variant source: Image {
+                source: "qt-logo.png"
+                sourceSize { width: 200; height: 200 }
+                smooth: true
+            }
+            vertexShader: "
+                uniform highp mat4 qt_Matrix;
+                attribute highp vec4 qt_Vertex;
+                attribute highp vec2 qt_MultiTexCoord0;
+                varying highp vec2 qt_TexCoord0;
+                uniform highp float width;
+                void main() {
+                    highp vec4 pos = qt_Vertex;
+                    highp float d = .5 * smoothstep(0., 1., qt_MultiTexCoord0.y);
+                    pos.x = width * mix(d, 1.0 - d, qt_MultiTexCoord0.x);
+                    gl_Position = qt_Matrix * pos;
+                    qt_TexCoord0 = qt_MultiTexCoord0;
+                }"
+        }
+        \endqml
+    \endrow
+*/
+
+void QQuickGridMesh::setResolution(const QSize &res)
+{
+    if (res == m_resolution)
+        return;
+    if (res.width() < 1 || res.height() < 1) {
+        return;
+    }
+    m_resolution = res;
+    emit resolutionChanged();
+}
+
+QSize QQuickGridMesh::resolution() const
+{
+    return m_resolution;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickshadereffectmesh_p.h b/src/declarative/items/qquickshadereffectmesh_p.h
new file mode 100644 (file)
index 0000000..40549f7
--- /dev/null
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qdeclarativeparserstatus.h"
+
+#include <QtGui/qcolor.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qsize.h>
+#include <QtCore/qvariant.h>
+#include <QtGui/qopenglfunctions.h>
+
+#ifndef QQUICKSHADEREFFECTMESH_P_H
+#define QQUICKSHADEREFFECTMESH_P_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QSGGeometry;
+class QRectF;
+
+class Q_DECLARATIVE_EXPORT QQuickShaderEffectMesh : public QObject
+{
+    Q_OBJECT
+public:
+    QQuickShaderEffectMesh(QObject *parent = 0);
+    // If 'geometry' != 0, 'attributes' is the same as last time the function was called.
+    virtual QSGGeometry *updateGeometry(QSGGeometry *geometry, const QVector<QByteArray> &attributes, const QRectF &rect) const = 0;
+
+Q_SIGNALS:
+    // Emitted when the geometry needs to be updated.
+    void geometryChanged();
+};
+
+class QQuickGridMesh : public QQuickShaderEffectMesh
+{
+    Q_OBJECT
+    Q_PROPERTY(QSize resolution READ resolution WRITE setResolution NOTIFY resolutionChanged)
+public:
+    QQuickGridMesh(QObject *parent = 0);
+    virtual QSGGeometry *updateGeometry(QSGGeometry *geometry, const QVector<QByteArray> &attributes, const QRectF &rect) const;
+
+    void setResolution(const QSize &res);
+    QSize resolution() const;
+
+Q_SIGNALS:
+    void resolutionChanged();
+
+private:
+    QSize m_resolution;
+};
+
+inline QColor qt_premultiply_color(const QColor &c)
+{
+    return QColor::fromRgbF(c.redF() * c.alphaF(), c.greenF() * c.alphaF(), c.blueF() * c.alphaF(), c.alphaF());
+}
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QQUICKSHADEREFFECTMESH_P_H
diff --git a/src/declarative/items/qquickshadereffectnode.cpp b/src/declarative/items/qquickshadereffectnode.cpp
new file mode 100644 (file)
index 0000000..67ca124
--- /dev/null
@@ -0,0 +1,316 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include <private/qquickshadereffectnode_p.h>
+
+#include "qquickshadereffectmesh_p.h"
+#include <private/qsgtextureprovider_p.h>
+#include <private/qsgrenderer_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickCustomMaterialShader : public QSGMaterialShader
+{
+public:
+    QQuickCustomMaterialShader(const QQuickShaderEffectMaterialKey &key, const QVector<QByteArray> &attributes);
+    virtual void deactivate();
+    virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
+    virtual char const *const *attributeNames() const;
+
+protected:
+    friend class QQuickShaderEffectNode;
+
+    virtual void initialize();
+    virtual const char *vertexShader() const;
+    virtual const char *fragmentShader() const;
+
+    const QQuickShaderEffectMaterialKey m_key;
+    QVector<const char *> m_attributeNames;
+    const QVector<QByteArray> m_attributes;
+
+    QVector<int> m_uniformLocs;
+    int m_opacityLoc;
+    int m_matrixLoc;
+    uint m_textureIndicesSet;
+};
+
+QQuickCustomMaterialShader::QQuickCustomMaterialShader(const QQuickShaderEffectMaterialKey &key, const QVector<QByteArray> &attributes)
+    : m_key(key)
+    , m_attributes(attributes)
+    , m_textureIndicesSet(false)
+{
+    for (int i = 0; i < attributes.count(); ++i)
+        m_attributeNames.append(attributes.at(i).constData());
+    m_attributeNames.append(0);
+}
+
+void QQuickCustomMaterialShader::deactivate()
+{
+    QSGMaterialShader::deactivate();
+    glDisable(GL_CULL_FACE);
+}
+
+void QQuickCustomMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
+{
+    Q_ASSERT(newEffect != 0);
+
+    const QQuickShaderEffectMaterial *material = static_cast<const QQuickShaderEffectMaterial *>(newEffect);
+
+    if (!m_textureIndicesSet) {
+        for (int i = 0; i < material->m_textures.size(); ++i)
+            program()->setUniformValue(material->m_textures.at(i).first.constData(), i);
+        m_textureIndicesSet = true;
+    }
+
+    if (m_uniformLocs.size() != material->m_uniformValues.size()) {
+        m_uniformLocs.reserve(material->m_uniformValues.size());
+        for (int i = 0; i < material->m_uniformValues.size(); ++i) {
+            const QByteArray &name = material->m_uniformValues.at(i).first;
+            m_uniformLocs.append(program()->uniformLocation(name.constData()));
+        }
+    }
+
+    QOpenGLFunctions *functions = state.context()->functions();
+    for (int i = material->m_textures.size() - 1; i >= 0; --i) {
+        functions->glActiveTexture(GL_TEXTURE0 + i);
+        if (QSGTextureProvider *provider = material->m_textures.at(i).second) {
+            if (QSGTexture *texture = provider->texture()) {
+                texture->bind();
+                continue;
+            }
+        }
+        qWarning("ShaderEffectItem: source or provider missing when binding textures");
+        glBindTexture(GL_TEXTURE_2D, 0);
+    }
+
+    if (material->m_source.respectsOpacity)
+        program()->setUniformValue(m_opacityLoc, state.opacity());
+
+    for (int i = 0; i < material->m_uniformValues.count(); ++i) {
+        const QVariant &v = material->m_uniformValues.at(i).second;
+
+        switch (v.type()) {
+        case QVariant::Color:
+            program()->setUniformValue(m_uniformLocs.at(i), qt_premultiply_color(qvariant_cast<QColor>(v)));
+            break;
+        case QVariant::Double:
+            program()->setUniformValue(m_uniformLocs.at(i), (float) qvariant_cast<double>(v));
+            break;
+        case QVariant::Transform:
+            program()->setUniformValue(m_uniformLocs.at(i), qvariant_cast<QTransform>(v));
+            break;
+        case QVariant::Int:
+            program()->setUniformValue(m_uniformLocs.at(i), v.toInt());
+            break;
+        case QVariant::Bool:
+            program()->setUniformValue(m_uniformLocs.at(i), GLint(v.toBool()));
+            break;
+        case QVariant::Size:
+        case QVariant::SizeF:
+            program()->setUniformValue(m_uniformLocs.at(i), v.toSizeF());
+            break;
+        case QVariant::Point:
+        case QVariant::PointF:
+            program()->setUniformValue(m_uniformLocs.at(i), v.toPointF());
+            break;
+        case QVariant::Rect:
+        case QVariant::RectF:
+            {
+                QRectF r = v.toRectF();
+                program()->setUniformValue(m_uniformLocs.at(i), r.x(), r.y(), r.width(), r.height());
+            }
+            break;
+        case QVariant::Vector3D:
+            program()->setUniformValue(m_uniformLocs.at(i), qvariant_cast<QVector3D>(v));
+            break;
+        default:
+            break;
+        }
+    }
+
+    const QQuickShaderEffectMaterial *oldMaterial = static_cast<const QQuickShaderEffectMaterial *>(oldEffect);
+    if (oldEffect == 0 || material->cullMode() != oldMaterial->cullMode()) {
+        switch (material->cullMode()) {
+        case QQuickShaderEffectMaterial::FrontFaceCulling:
+            glEnable(GL_CULL_FACE);
+            glCullFace(GL_FRONT);
+            break;
+        case QQuickShaderEffectMaterial::BackFaceCulling:
+            glEnable(GL_CULL_FACE);
+            glCullFace(GL_BACK);
+            break;
+        default:
+            glDisable(GL_CULL_FACE);
+            break;
+        }
+    }
+
+    if ((state.isMatrixDirty()) && material->m_source.respectsMatrix)
+        program()->setUniformValue(m_matrixLoc, state.combinedMatrix());
+}
+
+char const *const *QQuickCustomMaterialShader::attributeNames() const
+{
+    return m_attributeNames.constData();
+}
+
+void QQuickCustomMaterialShader::initialize()
+{
+    m_opacityLoc = program()->uniformLocation("qt_Opacity");
+    m_matrixLoc = program()->uniformLocation("qt_Matrix");
+    // TODO: Remove after grace period.
+    if (m_matrixLoc == -1)
+        m_matrixLoc = program()->uniformLocation("qt_ModelViewProjectionMatrix");
+}
+
+const char *QQuickCustomMaterialShader::vertexShader() const
+{
+    return m_key.vertexCode.constData();
+}
+
+const char *QQuickCustomMaterialShader::fragmentShader() const
+{
+    return m_key.fragmentCode.constData();
+}
+
+
+bool QQuickShaderEffectMaterialKey::operator == (const QQuickShaderEffectMaterialKey &other) const
+{
+    return vertexCode == other.vertexCode && fragmentCode == other.fragmentCode && className == other.className;
+}
+
+uint qHash(const QQuickShaderEffectMaterialKey &key)
+{
+    return qHash(qMakePair(qMakePair(key.vertexCode, key.fragmentCode), key.className));
+}
+
+
+QHash<QQuickShaderEffectMaterialKey, QSharedPointer<QSGMaterialType> > QQuickShaderEffectMaterial::materialMap;
+
+QQuickShaderEffectMaterial::QQuickShaderEffectMaterial()
+    : m_cullMode(NoCulling)
+{
+    setFlag(Blending, true);
+}
+
+QSGMaterialType *QQuickShaderEffectMaterial::type() const
+{
+    return m_type.data();
+}
+
+QSGMaterialShader *QQuickShaderEffectMaterial::createShader() const
+{
+    return new QQuickCustomMaterialShader(m_source, m_source.attributeNames);
+}
+
+int QQuickShaderEffectMaterial::compare(const QSGMaterial *other) const
+{
+    return this - static_cast<const QQuickShaderEffectMaterial *>(other);
+}
+
+void QQuickShaderEffectMaterial::setCullMode(QQuickShaderEffectMaterial::CullMode face)
+{
+    m_cullMode = face;
+}
+
+QQuickShaderEffectMaterial::CullMode QQuickShaderEffectMaterial::cullMode() const
+{
+    return m_cullMode;
+}
+
+void QQuickShaderEffectMaterial::setProgramSource(const QQuickShaderEffectProgram &source)
+{
+    m_source = source;
+    m_type = materialMap.value(m_source);
+    if (m_type.isNull()) {
+        m_type = QSharedPointer<QSGMaterialType>(new QSGMaterialType);
+        materialMap.insert(m_source, m_type);
+    }
+}
+
+void QQuickShaderEffectMaterial::setUniforms(const QVector<QPair<QByteArray, QVariant> > &uniformValues)
+{
+    m_uniformValues = uniformValues;
+}
+
+void QQuickShaderEffectMaterial::setTextureProviders(const QVector<QPair<QByteArray, QSGTextureProvider *> > &textures)
+{
+    m_textures = textures;
+}
+
+const QVector<QPair<QByteArray, QSGTextureProvider *> > &QQuickShaderEffectMaterial::textureProviders() const
+{
+    return m_textures;
+}
+
+void QQuickShaderEffectMaterial::updateTextures() const
+{
+    for (int i = 0; i < m_textures.size(); ++i) {
+        if (QSGTextureProvider *provider = m_textures.at(i).second) {
+            if (QSGDynamicTexture *texture = qobject_cast<QSGDynamicTexture *>(provider->texture()))
+                texture->updateTexture();
+        }
+    }
+}
+
+
+QQuickShaderEffectNode::QQuickShaderEffectNode()
+{
+    QSGNode::setFlag(UsePreprocess, true);
+    setMaterial(&m_material);
+}
+
+QQuickShaderEffectNode::~QQuickShaderEffectNode()
+{
+}
+
+void QQuickShaderEffectNode::markDirtyTexture()
+{
+    markDirty(DirtyMaterial);
+}
+
+void QQuickShaderEffectNode::preprocess()
+{
+    Q_ASSERT(material());
+    static_cast<QQuickShaderEffectMaterial *>(material())->updateTextures();
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickshadereffectnode_p.h b/src/declarative/items/qquickshadereffectnode_p.h
new file mode 100644 (file)
index 0000000..50213ff
--- /dev/null
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** 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 QQUICKSHADEREFFECTNODE_P_H
+#define QQUICKSHADEREFFECTNODE_P_H
+
+#include "qsgnode.h"
+#include "qsgmaterial.h"
+#include <private/qsgtextureprovider_p.h>
+#include <qquickitem.h>
+
+#include <QtCore/qsharedpointer.h>
+#include <QtCore/qpointer.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+struct QQuickShaderEffectMaterialKey {
+    QByteArray vertexCode;
+    QByteArray fragmentCode;
+    const char *className;
+
+    bool operator == (const QQuickShaderEffectMaterialKey &other) const;
+};
+
+uint qHash(const QQuickShaderEffectMaterialKey &key);
+
+// TODO: Implement support for multisampling.
+struct QQuickShaderEffectProgram : public QQuickShaderEffectMaterialKey
+{
+    QQuickShaderEffectProgram() : respectsOpacity(false), respectsMatrix(false) {}
+
+    QVector<QByteArray> attributeNames;
+    QSet<QByteArray> uniformNames;
+
+    uint respectsOpacity : 1;
+    uint respectsMatrix : 1;
+};
+
+
+class QQuickCustomMaterialShader;
+class QQuickShaderEffectMaterial : public QSGMaterial
+{
+public:
+    enum CullMode
+    {
+        NoCulling,
+        BackFaceCulling,
+        FrontFaceCulling
+    };
+
+    QQuickShaderEffectMaterial();
+    virtual QSGMaterialType *type() const;
+    virtual QSGMaterialShader *createShader() const;
+    virtual int compare(const QSGMaterial *other) const;
+
+    void setCullMode(CullMode face);
+    CullMode cullMode() const;
+
+    void setProgramSource(const QQuickShaderEffectProgram &);
+    void setUniforms(const QVector<QPair<QByteArray, QVariant> > &uniformValues);
+    void setTextureProviders(const QVector<QPair<QByteArray, QSGTextureProvider *> > &textures);
+    const QVector<QPair<QByteArray, QSGTextureProvider *> > &textureProviders() const;
+    void updateTextures() const;
+
+protected:
+    friend class QQuickCustomMaterialShader;
+
+    // The type pointer needs to be unique. It is not safe to let the type object be part of the
+    // QQuickShaderEffectMaterial, since it can be deleted and a new one constructed on top of the old
+    // one. The new QQuickShaderEffectMaterial would then get the same type pointer as the old one, and
+    // CustomMaterialShaders based on the old one would incorrectly be used together with the new
+    // one. To guarantee that the type pointer is unique, the type object must live as long as
+    // there are any CustomMaterialShaders of that type.
+    QSharedPointer<QSGMaterialType> m_type;
+
+    QQuickShaderEffectProgram m_source;
+    QVector<QPair<QByteArray, QVariant> > m_uniformValues;
+    QVector<QPair<QByteArray, QSGTextureProvider *> > m_textures;
+    CullMode m_cullMode;
+
+    static QHash<QQuickShaderEffectMaterialKey, QSharedPointer<QSGMaterialType> > materialMap;
+};
+
+
+class QSGShaderEffectMesh;
+
+class QQuickShaderEffectNode : public QObject, public QSGGeometryNode
+{
+    Q_OBJECT
+public:
+    QQuickShaderEffectNode();
+    virtual ~QQuickShaderEffectNode();
+
+    virtual void preprocess();
+
+    QQuickShaderEffectMaterial *shaderMaterial() { return &m_material; }
+
+private Q_SLOTS:
+    void markDirtyTexture();
+
+private:
+    QQuickShaderEffectMaterial m_material;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QQUICKSHADEREFFECTNODE_P_H
diff --git a/src/declarative/items/qquickshadereffectsource.cpp b/src/declarative/items/qquickshadereffectsource.cpp
new file mode 100644 (file)
index 0000000..587f7ba
--- /dev/null
@@ -0,0 +1,905 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qquickshadereffectsource_p.h"
+
+#include "qquickitem_p.h"
+#include "qquickcanvas_p.h"
+#include <private/qsgadaptationlayer_p.h>
+#include <private/qsgrenderer_p.h>
+
+#include "qopenglframebufferobject.h"
+#include "qmath.h"
+#include <private/qsgtexture_p.h>
+
+QT_BEGIN_NAMESPACE
+
+DEFINE_BOOL_CONFIG_OPTION(qmlFboOverlay, QML_FBO_OVERLAY)
+
+class QQuickShaderEffectSourceTextureProvider : public QSGTextureProvider
+{
+    Q_OBJECT
+public:
+    QQuickShaderEffectSourceTextureProvider()
+        : sourceTexture(0)
+    {
+    }
+
+    QSGTexture *texture() const {
+        sourceTexture->setMipmapFiltering(mipmapFiltering);
+        sourceTexture->setFiltering(filtering);
+        sourceTexture->setHorizontalWrapMode(horizontalWrap);
+        sourceTexture->setVerticalWrapMode(verticalWrap);
+        return sourceTexture;
+    }
+
+    QQuickShaderEffectTexture *sourceTexture;
+
+    QSGTexture::Filtering mipmapFiltering;
+    QSGTexture::Filtering filtering;
+    QSGTexture::WrapMode horizontalWrap;
+    QSGTexture::WrapMode verticalWrap;
+};
+#include "qquickshadereffectsource.moc"
+
+
+QQuickShaderEffectSourceNode::QQuickShaderEffectSourceNode()
+{
+    setFlag(UsePreprocess, true);
+}
+
+void QQuickShaderEffectSourceNode::markDirtyTexture()
+{
+    markDirty(DirtyMaterial);
+}
+
+
+QQuickShaderEffectTexture::QQuickShaderEffectTexture(QQuickItem *shaderSource)
+    : QSGDynamicTexture()
+    , m_item(0)
+    , m_format(GL_RGBA)
+    , m_shaderSource(shaderSource)
+    , m_renderer(0)
+    , m_fbo(0)
+    , m_secondaryFbo(0)
+#ifdef QSG_DEBUG_FBO_OVERLAY
+    , m_debugOverlay(0)
+#endif
+    , m_context(QQuickItemPrivate::get(shaderSource)->sceneGraphContext())
+    , m_mipmap(false)
+    , m_live(true)
+    , m_recursive(false)
+    , m_dirtyTexture(true)
+    , m_multisamplingSupportChecked(false)
+    , m_multisampling(false)
+    , m_grab(false)
+{
+}
+
+QQuickShaderEffectTexture::~QQuickShaderEffectTexture()
+{
+    delete m_renderer;
+    delete m_fbo;
+    delete m_secondaryFbo;
+#ifdef QSG_DEBUG_FBO_OVERLAY
+    delete m_debugOverlay;
+#endif
+}
+
+int QQuickShaderEffectTexture::textureId() const
+{
+    return m_fbo ? m_fbo->texture() : 0;
+}
+
+bool QQuickShaderEffectTexture::hasAlphaChannel() const
+{
+    return m_format != GL_RGB;
+}
+
+bool QQuickShaderEffectTexture::hasMipmaps() const
+{
+    return m_mipmap;
+}
+
+
+void QQuickShaderEffectTexture::bind()
+{
+#ifndef QT_NO_DEBUG
+    if (!m_recursive && m_fbo && ((m_multisampling && m_secondaryFbo->isBound()) || m_fbo->isBound()))
+        qWarning("ShaderEffectSource: \'recursive\' must be set to true when rendering recursively.");
+#endif
+    glBindTexture(GL_TEXTURE_2D, m_fbo ? m_fbo->texture() : 0);
+    updateBindOptions();
+}
+
+bool QQuickShaderEffectTexture::updateTexture()
+{
+    if ((m_live || m_grab) && m_dirtyTexture) {
+        grab();
+        m_grab = false;
+        return true;
+    }
+    return false;
+}
+
+void QQuickShaderEffectTexture::setHasMipmaps(bool mipmap)
+{
+    if (mipmap == m_mipmap)
+        return;
+    m_mipmap = mipmap;
+    if (m_mipmap && m_fbo && !m_fbo->format().mipmap())
+        markDirtyTexture();
+}
+
+
+void QQuickShaderEffectTexture::setItem(QSGNode *item)
+{
+    if (item == m_item)
+        return;
+    m_item = item;
+    markDirtyTexture();
+}
+
+void QQuickShaderEffectTexture::setRect(const QRectF &rect)
+{
+    if (rect == m_rect)
+        return;
+    m_rect = rect;
+    markDirtyTexture();
+}
+
+void QQuickShaderEffectTexture::setSize(const QSize &size)
+{
+    if (size == m_size)
+        return;
+    m_size = size;
+    markDirtyTexture();
+}
+
+void QQuickShaderEffectTexture::setFormat(GLenum format)
+{
+    if (format == m_format)
+        return;
+    m_format = format;
+    markDirtyTexture();
+}
+
+void QQuickShaderEffectTexture::setLive(bool live)
+{
+    if (live == m_live)
+        return;
+    m_live = live;
+    markDirtyTexture();
+}
+
+void QQuickShaderEffectTexture::scheduleUpdate()
+{
+    if (m_grab)
+        return;
+    m_grab = true;
+    if (m_dirtyTexture)
+        emit textureChanged();
+}
+
+void QQuickShaderEffectTexture::setRecursive(bool recursive)
+{
+    m_recursive = recursive;
+}
+
+void QQuickShaderEffectTexture::markDirtyTexture()
+{
+    m_dirtyTexture = true;
+    if (m_live || m_grab)
+        emit textureChanged();
+}
+
+void QQuickShaderEffectTexture::grab()
+{
+    if (!m_item || m_size.isNull()) {
+        delete m_fbo;
+        delete m_secondaryFbo;
+        m_fbo = m_secondaryFbo = 0;
+        m_dirtyTexture = false;
+        return;
+    }
+    QSGNode *root = m_item;
+    while (root->firstChild() && root->type() != QSGNode::RootNodeType)
+        root = root->firstChild();
+    if (root->type() != QSGNode::RootNodeType)
+        return;
+
+    if (m_size.isEmpty()) {
+        delete m_fbo;
+        delete m_secondaryFbo;
+        m_secondaryFbo = m_fbo = 0;
+        return;
+    }
+
+    if (!m_renderer) {
+        m_renderer = m_context->createRenderer();
+        connect(m_renderer, SIGNAL(sceneGraphChanged()), this, SLOT(markDirtyTexture()), Qt::DirectConnection);
+    }
+    m_renderer->setRootNode(static_cast<QSGRootNode *>(root));
+
+    bool deleteFboLater = false;
+    if (!m_fbo || m_fbo->size() != m_size || m_fbo->format().internalTextureFormat() != m_format
+        || (!m_fbo->format().mipmap() && m_mipmap))
+    {
+        if (!m_multisamplingSupportChecked) {
+            QList<QByteArray> extensions = QByteArray((const char *)glGetString(GL_EXTENSIONS)).split(' ');
+            m_multisampling = extensions.contains("GL_EXT_framebuffer_multisample")
+                            && extensions.contains("GL_EXT_framebuffer_blit");
+            m_multisamplingSupportChecked = true;
+        }
+        if (m_multisampling) {
+            // Don't delete the FBO right away in case it is used recursively.
+            deleteFboLater = true;
+            delete m_secondaryFbo;
+            QOpenGLFramebufferObjectFormat format;
+
+            format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
+            format.setInternalTextureFormat(m_format);
+            format.setSamples(8);
+            m_secondaryFbo = new QOpenGLFramebufferObject(m_size, format);
+        } else {
+            QOpenGLFramebufferObjectFormat format;
+            format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
+            format.setInternalTextureFormat(m_format);
+            format.setMipmap(m_mipmap);
+            if (m_recursive) {
+                deleteFboLater = true;
+                delete m_secondaryFbo;
+                m_secondaryFbo = new QOpenGLFramebufferObject(m_size, format);
+                glBindTexture(GL_TEXTURE_2D, m_secondaryFbo->texture());
+                updateBindOptions(true);
+            } else {
+                delete m_fbo;
+                delete m_secondaryFbo;
+                m_fbo = new QOpenGLFramebufferObject(m_size, format);
+                m_secondaryFbo = 0;
+                glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
+                updateBindOptions(true);
+            }
+        }
+    }
+
+    if (m_recursive && !m_secondaryFbo) {
+        // m_fbo already created, m_recursive was just set.
+        Q_ASSERT(m_fbo);
+        Q_ASSERT(!m_multisampling);
+
+        m_secondaryFbo = new QOpenGLFramebufferObject(m_size, m_fbo->format());
+        glBindTexture(GL_TEXTURE_2D, m_secondaryFbo->texture());
+        updateBindOptions(true);
+    }
+
+    // Render texture.
+    root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip and opacity update.
+    m_renderer->nodeChanged(root, QSGNode::DirtyForceUpdate); // Force render list update.
+
+#ifdef QSG_DEBUG_FBO_OVERLAY
+    if (qmlFboOverlay()) {
+        if (!m_debugOverlay)
+            m_debugOverlay = m_context->createRectangleNode();
+        m_debugOverlay->setRect(QRectF(0, 0, m_size.width(), m_size.height()));
+        m_debugOverlay->setColor(QColor(0xff, 0x00, 0x80, 0x40));
+        m_debugOverlay->setPenColor(QColor());
+        m_debugOverlay->setPenWidth(0);
+        m_debugOverlay->setRadius(0);
+        m_debugOverlay->update();
+        root->appendChildNode(m_debugOverlay);
+    }
+#endif
+
+    m_dirtyTexture = false;
+
+    QOpenGLContext *ctx = m_context->glContext();
+    m_renderer->setDeviceRect(m_size);
+    m_renderer->setViewportRect(m_size);
+    QRectF mirrored(m_rect.left(), m_rect.bottom(), m_rect.width(), -m_rect.height());
+    m_renderer->setProjectionMatrixToRect(mirrored);
+    m_renderer->setClearColor(Qt::transparent);
+
+    if (m_multisampling) {
+        m_renderer->renderScene(QSGBindableFbo(m_secondaryFbo));
+
+        if (deleteFboLater) {
+            delete m_fbo;
+            QOpenGLFramebufferObjectFormat format;
+            format.setInternalTextureFormat(m_format);
+            format.setAttachment(QOpenGLFramebufferObject::NoAttachment);
+            format.setMipmap(m_mipmap);
+            format.setSamples(0);
+            m_fbo = new QOpenGLFramebufferObject(m_size, format);
+            glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
+            updateBindOptions(true);
+        }
+
+        QRect r(QPoint(), m_size);
+        QOpenGLFramebufferObject::blitFramebuffer(m_fbo, r, m_secondaryFbo, r);
+    } else {
+        if (m_recursive) {
+            m_renderer->renderScene(QSGBindableFbo(m_secondaryFbo));
+
+            if (deleteFboLater) {
+                delete m_fbo;
+                QOpenGLFramebufferObjectFormat format;
+                format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
+                format.setInternalTextureFormat(m_format);
+                format.setMipmap(m_mipmap);
+                m_fbo = new QOpenGLFramebufferObject(m_size, format);
+                glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
+                updateBindOptions(true);
+            }
+            qSwap(m_fbo, m_secondaryFbo);
+        } else {
+            m_renderer->renderScene(QSGBindableFbo(m_fbo));
+        }
+    }
+
+    if (m_mipmap) {
+        glBindTexture(GL_TEXTURE_2D, textureId());
+        ctx->functions()->glGenerateMipmap(GL_TEXTURE_2D);
+    }
+
+    root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip, opacity and render list update.
+
+#ifdef QSG_DEBUG_FBO_OVERLAY
+    if (qmlFboOverlay())
+        root->removeChildNode(m_debugOverlay);
+#endif
+    if (m_recursive)
+        markDirtyTexture(); // Continuously update if 'live' and 'recursive'.
+}
+
+QImage QQuickShaderEffectTexture::toImage() const
+{
+    if (m_fbo)
+        return m_fbo->toImage();
+
+    return QImage();
+}
+
+/*!
+    \qmlclass ShaderEffectSource QQuickShaderEffectSource
+    \since 5.0
+    \ingroup qml-basic-visual-elements
+    \brief The ShaderEffectSource element renders a QML element into a texture
+    and displays it.
+    \inherits Item
+
+    The ShaderEffectSource element renders \l sourceItem into a texture and
+    displays it in the scene. \l sourceItem is drawn into the texture as though
+    it was a fully opaque root element. Thus \l sourceItem itself can be
+    invisible, but still appear in the texture.
+
+    ShaderEffectSource can be used as:
+    \list
+    \o a texture source in a \l ShaderEffect.
+       This allows you to apply custom shader effects to any QML element.
+    \o a cache for a complex element.
+       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.
+       ShaderEffectSource allows you to apply an opacity to elements as a group
+       rather than each element individually.
+    \endlist
+
+    \table
+    \row
+    \o \image declarative-shadereffectsource.png
+    \o \qml
+        import QtQuick 2.0
+
+        Rectangle {
+            width: 200
+            height: 100
+            gradient: Gradient {
+                GradientStop { position: 0; color: "white" }
+                GradientStop { position: 1; color: "black" }
+            }
+            Row {
+                opacity: 0.5
+                Item {
+                    id: foo
+                    width: 100; height: 100
+                    Rectangle { x: 5; y: 5; width: 60; height: 60; color: "red" }
+                    Rectangle { x: 20; y: 20; width: 60; height: 60; color: "orange" }
+                    Rectangle { x: 35; y: 35; width: 60; height: 60; color: "yellow" }
+                }
+                ShaderEffectSource {
+                    width: 100; height: 100
+                    sourceItem: foo
+                }
+            }
+        }
+        \endqml
+    \endrow
+    \endtable
+
+    The ShaderEffectSource element does not redirect any mouse or keyboard
+    input to \l sourceItem. If you hide the \l sourceItem by setting
+    \l{Item::visible}{visible} to false or \l{Item::opacity}{opacity} to zero,
+    it will no longer react to input. In cases where the ShaderEffectSource is
+    meant to replace the \l sourceItem, you typically want to hide the
+    \l sourceItem while still handling input. For this, you can use
+    the \l hideSource property.
+
+    \note If \l sourceItem is a \l Rectangle with border, by default half the
+    border width falls outside the texture. To get the whole border, you can
+    extend the \l sourceRect.
+
+    \warning In most cases, using a ShaderEffectSource will decrease
+    performance, and in all cases, it will increase video memory usage.
+    Rendering through a ShaderEffectSource might also lead to lower quality
+    since some OpenGL implementations support multisampled backbuffer,
+    but not multisampled framebuffer objects.
+*/
+
+QQuickShaderEffectSource::QQuickShaderEffectSource(QQuickItem *parent)
+    : QQuickItem(parent)
+    , m_provider(0)
+    , m_texture(0)
+    , m_wrapMode(ClampToEdge)
+    , m_sourceItem(0)
+    , m_textureSize(0, 0)
+    , m_format(RGBA)
+    , m_live(true)
+    , m_hideSource(false)
+    , m_mipmap(false)
+    , m_recursive(false)
+    , m_grab(true)
+{
+    setFlag(ItemHasContents);
+}
+
+QQuickShaderEffectSource::~QQuickShaderEffectSource()
+{
+    if (m_texture)
+        m_texture->deleteLater();
+
+    if (m_provider)
+        m_provider->deleteLater();
+
+    if (m_sourceItem)
+        QQuickItemPrivate::get(m_sourceItem)->derefFromEffectItem(m_hideSource);
+}
+
+void QQuickShaderEffectSource::ensureTexture()
+{
+    if (m_texture)
+        return;
+
+    Q_ASSERT_X(QQuickItemPrivate::get(this)->canvas
+               && QQuickItemPrivate::get(this)->sceneGraphContext()
+               && QThread::currentThread() == QQuickItemPrivate::get(this)->sceneGraphContext()->thread(),
+               "QQuickShaderEffectSource::ensureTexture",
+               "Cannot be used outside the rendering thread");
+
+    m_texture = new QQuickShaderEffectTexture(this);
+    connect(m_texture, SIGNAL(textureChanged()), this, SLOT(update()));
+}
+
+QSGTextureProvider *QQuickShaderEffectSource::textureProvider() const
+{
+    if (!m_provider) {
+        // Make sure it gets thread affinity on the rendering thread so deletion works properly..
+        Q_ASSERT_X(QQuickItemPrivate::get(this)->canvas
+                   && QQuickItemPrivate::get(this)->sceneGraphContext()
+                   && QThread::currentThread() == QQuickItemPrivate::get(this)->sceneGraphContext()->thread(),
+                   "QQuickShaderEffectSource::textureProvider",
+                   "Cannot be used outside the rendering thread");
+        const_cast<QQuickShaderEffectSource *>(this)->m_provider = new QQuickShaderEffectSourceTextureProvider();
+
+        const_cast<QQuickShaderEffectSource *>(this)->ensureTexture();
+        connect(m_texture, SIGNAL(textureChanged()), m_provider, SIGNAL(textureChanged()), Qt::DirectConnection);
+        m_provider->sourceTexture = m_texture;
+    }
+    return m_provider;
+}
+
+/*!
+    \qmlproperty enumeration ShaderEffectSource::wrapMode
+
+    This property defines the OpenGL wrap modes associated with the texture.
+    Modifying this property makes most sense when the element is used as a
+    source texture of a \l ShaderEffect.
+
+    \list
+    \o ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
+    \o ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
+    \o ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
+    \o ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
+    \endlist
+
+    \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
+    wrap mode with non-power-of-two textures.
+*/
+
+QQuickShaderEffectSource::WrapMode QQuickShaderEffectSource::wrapMode() const
+{
+    return m_wrapMode;
+}
+
+void QQuickShaderEffectSource::setWrapMode(WrapMode mode)
+{
+    if (mode == m_wrapMode)
+        return;
+    m_wrapMode = mode;
+    update();
+    emit wrapModeChanged();
+}
+
+/*!
+    \qmlproperty Item ShaderEffectSource::sourceItem
+
+    This property holds the element to be rendered into the texture.
+*/
+
+QQuickItem *QQuickShaderEffectSource::sourceItem() const
+{
+    return m_sourceItem;
+}
+
+void QQuickShaderEffectSource::setSourceItem(QQuickItem *item)
+{
+    if (item == m_sourceItem)
+        return;
+    if (m_sourceItem)
+        QQuickItemPrivate::get(m_sourceItem)->derefFromEffectItem(m_hideSource);
+    m_sourceItem = item;
+    if (m_sourceItem) {
+        // TODO: Find better solution.
+        // 'm_sourceItem' needs a canvas to get a scenegraph node.
+        // The easiest way to make sure it gets a canvas is to
+        // make it a part of the same item tree as 'this'.
+        if (m_sourceItem->parentItem() == 0) {
+            m_sourceItem->setParentItem(this);
+            m_sourceItem->setVisible(false);
+        }
+        QQuickItemPrivate::get(m_sourceItem)->refFromEffectItem(m_hideSource);
+    }
+    update();
+    emit sourceItemChanged();
+}
+
+/*!
+    \qmlproperty rect ShaderEffectSource::sourceRect
+
+    This property defines which rectangular area of the \l sourceItem to
+    render into the texture. The source rectangle can be larger than
+    \l sourceItem itself. If the rectangle is null, which is the default,
+    the whole \l sourceItem is rendered to texture.
+*/
+
+QRectF QQuickShaderEffectSource::sourceRect() const
+{
+    return m_sourceRect;
+}
+
+void QQuickShaderEffectSource::setSourceRect(const QRectF &rect)
+{
+    if (rect == m_sourceRect)
+        return;
+    m_sourceRect = rect;
+    update();
+    emit sourceRectChanged();
+}
+
+/*!
+    \qmlproperty size ShaderEffectSource::textureSize
+
+    This property holds the requested size of the texture. If it is empty,
+    which is the default, the size of the source rectangle is used.
+
+    \note Some platforms have a limit on how small framebuffer objects can be,
+    which means the actual texture size might be larger than the requested
+    size.
+*/
+
+QSize QQuickShaderEffectSource::textureSize() const
+{
+    return m_textureSize;
+}
+
+void QQuickShaderEffectSource::setTextureSize(const QSize &size)
+{
+    if (size == m_textureSize)
+        return;
+    m_textureSize = size;
+    update();
+    emit textureSizeChanged();
+}
+
+/*!
+    \qmlproperty enumeration ShaderEffectSource::format
+
+    This property defines the internal OpenGL format of the texture.
+    Modifying this property makes most sense when the element is used as a
+    source texture of a \l ShaderEffect. Depending on the OpenGL
+    implementation, this property might allow you to save some texture memory.
+
+    \list
+    \o ShaderEffectSource.Alpha - GL_ALPHA
+    \o ShaderEffectSource.RGB - GL_RGB
+    \o ShaderEffectSource.RGBA - GL_RGBA
+    \endlist
+
+    \note Some OpenGL implementations do not support the GL_ALPHA format.
+*/
+
+QQuickShaderEffectSource::Format QQuickShaderEffectSource::format() const
+{
+    return m_format;
+}
+
+void QQuickShaderEffectSource::setFormat(QQuickShaderEffectSource::Format format)
+{
+    if (format == m_format)
+        return;
+    m_format = format;
+    update();
+    emit formatChanged();
+}
+
+/*!
+    \qmlproperty bool ShaderEffectSource::live
+
+    If this property is true, the texture is updated whenever the
+    \l sourceItem changes. Otherwise, it will be a frozen image of the
+    \l sourceItem. The property is true by default.
+*/
+
+bool QQuickShaderEffectSource::live() const
+{
+    return m_live;
+}
+
+void QQuickShaderEffectSource::setLive(bool live)
+{
+    if (live == m_live)
+        return;
+    m_live = live;
+    update();
+    emit liveChanged();
+}
+
+/*!
+    \qmlproperty bool ShaderEffectSource::hideSource
+
+    If this property is true, the \l sourceItem is hidden, though it will still
+    be rendered into the texture. As opposed to hiding the \l sourceItem by
+    setting \l{Item::visible}{visible} to false, setting this property to true
+    will not prevent mouse or keyboard input from reaching \l sourceItem.
+    The property is useful when the ShaderEffectSource is anchored on top of,
+    and meant to replace the \l sourceItem.
+*/
+
+bool QQuickShaderEffectSource::hideSource() const
+{
+    return m_hideSource;
+}
+
+void QQuickShaderEffectSource::setHideSource(bool hide)
+{
+    if (hide == m_hideSource)
+        return;
+    if (m_sourceItem) {
+        QQuickItemPrivate::get(m_sourceItem)->refFromEffectItem(hide);
+        QQuickItemPrivate::get(m_sourceItem)->derefFromEffectItem(m_hideSource);
+    }
+    m_hideSource = hide;
+    update();
+    emit hideSourceChanged();
+}
+
+/*!
+    \qmlproperty bool ShaderEffectSource::mipmap
+
+    If this property is true, mipmaps are generated for the texture.
+
+    \note Some OpenGL ES 2 implementations do not support mipmapping of
+    non-power-of-two textures.
+*/
+
+bool QQuickShaderEffectSource::mipmap() const
+{
+    return m_mipmap;
+}
+
+void QQuickShaderEffectSource::setMipmap(bool enabled)
+{
+    if (enabled == m_mipmap)
+        return;
+    m_mipmap = enabled;
+    update();
+    emit mipmapChanged();
+}
+
+/*!
+    \qmlproperty bool ShaderEffectSource::recursive
+
+    Set this property to true if the ShaderEffectSource has a dependency on
+    itself. ShaderEffectSources form a dependency chain, where one
+    ShaderEffectSource can be part of the \l sourceItem of another.
+    If there is a loop in this chain, a ShaderEffectSource could end up trying
+    to render into the same texture it is using as source, which is not allowed
+    by OpenGL. When this property is set to true, an extra texture is allocated
+    so that ShaderEffectSource can keep a copy of the texture from the previous
+    frame. It can then render into one texture and use the texture from the
+    previous frame as source.
+
+    Setting both this property and \l live to true will cause the scene graph
+    to render continuously. Since the ShaderEffectSource depends on itself,
+    updating it means that it immediately becomes dirty again.
+*/
+
+bool QQuickShaderEffectSource::recursive() const
+{
+    return m_recursive;
+}
+
+void QQuickShaderEffectSource::setRecursive(bool enabled)
+{
+    if (enabled == m_recursive)
+        return;
+    m_recursive = enabled;
+    emit recursiveChanged();
+}
+
+/*!
+    \qmlmethod ShaderEffectSource::scheduleUpdate()
+
+    Schedules a re-rendering of the texture for the next frame.
+    Use this to update the texture when \l live is false.
+*/
+
+void QQuickShaderEffectSource::scheduleUpdate()
+{
+    if (m_grab)
+        return;
+    m_grab = true;
+    update();
+}
+
+static void get_wrap_mode(QQuickShaderEffectSource::WrapMode mode, QSGTexture::WrapMode *hWrap, QSGTexture::WrapMode *vWrap)
+{
+    switch (mode) {
+    case QQuickShaderEffectSource::RepeatHorizontally:
+        *hWrap = QSGTexture::Repeat;
+        *vWrap = QSGTexture::ClampToEdge;
+        break;
+    case QQuickShaderEffectSource::RepeatVertically:
+        *vWrap = QSGTexture::Repeat;
+        *hWrap = QSGTexture::ClampToEdge;
+        break;
+    case QQuickShaderEffectSource::Repeat:
+        *hWrap = *vWrap = QSGTexture::Repeat;
+        break;
+    default:
+        // QQuickShaderEffectSource::ClampToEdge
+        *hWrap = *vWrap = QSGTexture::ClampToEdge;
+        break;
+    }
+}
+
+
+QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+    if (!m_sourceItem || m_sourceItem->width() == 0 || m_sourceItem->height() == 0) {
+        delete oldNode;
+        return 0;
+    }
+
+    ensureTexture();
+
+    QQuickShaderEffectTexture *tex = qobject_cast<QQuickShaderEffectTexture *>(m_texture);
+    tex->setLive(m_live);
+    tex->setItem(QQuickItemPrivate::get(m_sourceItem)->itemNode());
+    QRectF sourceRect = m_sourceRect.width() == 0 || m_sourceRect.height() == 0
+                      ? QRectF(0, 0, m_sourceItem->width(), m_sourceItem->height())
+                      : m_sourceRect;
+    tex->setRect(sourceRect);
+    QSize textureSize = m_textureSize.isEmpty()
+                      ? QSize(qCeil(qAbs(sourceRect.width())), qCeil(qAbs(sourceRect.height())))
+                      : m_textureSize;
+    Q_ASSERT(!textureSize.isEmpty());
+    QQuickItemPrivate *d = static_cast<QQuickItemPrivate *>(QObjectPrivate::get(this));
+    const QSize minTextureSize = d->sceneGraphContext()->minimumFBOSize();
+    // Keep power-of-two by doubling the size.
+    while (textureSize.width() < minTextureSize.width())
+        textureSize.rwidth() *= 2;
+    while (textureSize.height() < minTextureSize.height())
+        textureSize.rheight() *= 2;
+
+    tex->setSize(textureSize);
+    tex->setRecursive(m_recursive);
+    tex->setFormat(GLenum(m_format));
+    tex->setHasMipmaps(m_mipmap);
+
+    if (m_grab)
+        tex->scheduleUpdate();
+    m_grab = false;
+
+    QSGTexture::Filtering filtering = QQuickItemPrivate::get(this)->smooth
+                                            ? QSGTexture::Linear
+                                            : QSGTexture::Nearest;
+    QSGTexture::Filtering mmFiltering = m_mipmap ? filtering : QSGTexture::None;
+    QSGTexture::WrapMode hWrap, vWrap;
+    get_wrap_mode(m_wrapMode, &hWrap, &vWrap);
+
+    if (m_provider) {
+        m_provider->mipmapFiltering = mmFiltering;
+        m_provider->filtering = filtering;
+        m_provider->horizontalWrap = hWrap;
+        m_provider->verticalWrap = vWrap;
+    }
+
+    // Don't create the paint node if we're not spanning any area
+    if (width() == 0 || height() == 0) {
+        delete oldNode;
+        return 0;
+    }
+
+    QQuickShaderEffectSourceNode *node = static_cast<QQuickShaderEffectSourceNode *>(oldNode);
+    if (!node) {
+        node = new QQuickShaderEffectSourceNode;
+        node->setTexture(m_texture);
+        connect(m_texture, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture()), Qt::DirectConnection);
+    }
+
+    // If live and recursive, update continuously.
+    if (m_live && m_recursive)
+        node->markDirty(QSGNode::DirtyMaterial);
+
+    node->setMipmapFiltering(mmFiltering);
+    node->setFiltering(filtering);
+    node->setHorizontalWrapMode(hWrap);
+    node->setVerticalWrapMode(vWrap);
+    node->setTargetRect(QRectF(0, 0, width(), height()));
+    node->setSourceRect(QRectF(0, 0, 1, 1));
+    node->update();
+
+    return node;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickshadereffectsource_p.h b/src/declarative/items/qquickshadereffectsource_p.h
new file mode 100644 (file)
index 0000000..8117c06
--- /dev/null
@@ -0,0 +1,255 @@
+/****************************************************************************
+**
+** 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 QQUICKSHADEREFFECTSOURCE_P_H
+#define QQUICKSHADEREFFECTSOURCE_P_H
+
+#include "qquickitem.h"
+#include <private/qsgtextureprovider_p.h>
+#include <private/qsgadaptationlayer_p.h>
+#include <private/qsgcontext_p.h>
+#include <private/qsgdefaultimagenode_p.h>
+
+#include "qpointer.h"
+#include "qsize.h"
+#include "qrect.h"
+
+#define QSG_DEBUG_FBO_OVERLAY
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QSGNode;
+class UpdatePaintNodeData;
+class QOpenGLFramebufferObject;
+
+class QQuickShaderEffectSourceTextureProvider;
+
+class QQuickShaderEffectSourceNode : public QObject, public QSGDefaultImageNode
+{
+    Q_OBJECT
+
+public:
+    QQuickShaderEffectSourceNode();
+
+private Q_SLOTS:
+    void markDirtyTexture();
+};
+
+class Q_DECLARATIVE_EXPORT QQuickShaderEffectTexture : public QSGDynamicTexture
+{
+    Q_OBJECT
+public:
+    QQuickShaderEffectTexture(QQuickItem *shaderSource);
+    ~QQuickShaderEffectTexture();
+
+    virtual bool updateTexture();
+
+    // The item's "paint node", not effect node.
+    QSGNode *item() const { return m_item; }
+    void setItem(QSGNode *item);
+
+    QRectF rect() const { return m_rect; }
+    void setRect(const QRectF &rect);
+
+    QSize size() const { return m_size; }
+    void setSize(const QSize &size);
+
+    void setHasMipmaps(bool mipmap);
+
+    void bind();
+
+    bool hasAlphaChannel() const;
+    bool hasMipmaps() const;
+    int textureId() const;
+    QSize textureSize() const { return m_size; }
+
+    GLenum format() const { return m_format; }
+    void setFormat(GLenum format);
+
+    bool live() const { return bool(m_live); }
+    void setLive(bool live);
+
+    bool recursive() const { return bool(m_recursive); }
+    void setRecursive(bool recursive);
+
+    void scheduleUpdate();
+
+    QImage toImage() const;
+
+Q_SIGNALS:
+    void textureChanged();
+
+public Q_SLOTS:
+    void markDirtyTexture();
+
+private:
+    void grab();
+
+    QSGNode *m_item;
+    QRectF m_rect;
+    QSize m_size;
+    GLenum m_format;
+
+    QQuickItem *m_shaderSource;
+    QSGRenderer *m_renderer;
+    QOpenGLFramebufferObject *m_fbo;
+    QOpenGLFramebufferObject *m_secondaryFbo;
+
+#ifdef QSG_DEBUG_FBO_OVERLAY
+    QSGRectangleNode *m_debugOverlay;
+#endif
+
+    QSGContext *m_context;
+
+    uint m_mipmap : 1;
+    uint m_live : 1;
+    uint m_recursive : 1;
+    uint m_dirtyTexture : 1;
+    uint m_multisamplingSupportChecked : 1;
+    uint m_multisampling : 1;
+    uint m_grab : 1;
+};
+
+class Q_DECLARATIVE_EXPORT QQuickShaderEffectSource : public QQuickItem
+{
+    Q_OBJECT
+    Q_PROPERTY(WrapMode wrapMode READ wrapMode WRITE setWrapMode NOTIFY wrapModeChanged)
+    Q_PROPERTY(QQuickItem *sourceItem READ sourceItem WRITE setSourceItem NOTIFY sourceItemChanged)
+    Q_PROPERTY(QRectF sourceRect READ sourceRect WRITE setSourceRect NOTIFY sourceRectChanged)
+    Q_PROPERTY(QSize textureSize READ textureSize WRITE setTextureSize NOTIFY textureSizeChanged)
+    Q_PROPERTY(Format format READ format WRITE setFormat NOTIFY formatChanged)
+    Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged)
+    Q_PROPERTY(bool hideSource READ hideSource WRITE setHideSource NOTIFY hideSourceChanged)
+    Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged)
+    Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged)
+
+    Q_ENUMS(Format WrapMode)
+public:
+    enum WrapMode {
+        ClampToEdge,
+        RepeatHorizontally,
+        RepeatVertically,
+        Repeat
+    };
+
+    enum Format {
+        Alpha = GL_ALPHA,
+        RGB = GL_RGB,
+        RGBA = GL_RGBA
+    };
+
+    QQuickShaderEffectSource(QQuickItem *parent = 0);
+    ~QQuickShaderEffectSource();
+
+    WrapMode wrapMode() const;
+    void setWrapMode(WrapMode mode);
+
+    QQuickItem *sourceItem() const;
+    void setSourceItem(QQuickItem *item);
+
+    QRectF sourceRect() const;
+    void setSourceRect(const QRectF &rect);
+
+    QSize textureSize() const;
+    void setTextureSize(const QSize &size);
+
+    Format format() const;
+    void setFormat(Format format);
+
+    bool live() const;
+    void setLive(bool live);
+
+    bool hideSource() const;
+    void setHideSource(bool hide);
+
+    bool mipmap() const;
+    void setMipmap(bool enabled);
+
+    bool recursive() const;
+    void setRecursive(bool enabled);
+
+    bool isTextureProvider() const { return true; }
+    QSGTextureProvider *textureProvider() const;
+
+    Q_INVOKABLE void scheduleUpdate();
+
+Q_SIGNALS:
+    void wrapModeChanged();
+    void sourceItemChanged();
+    void sourceRectChanged();
+    void textureSizeChanged();
+    void formatChanged();
+    void liveChanged();
+    void hideSourceChanged();
+    void mipmapChanged();
+    void recursiveChanged();
+
+    void textureChanged();
+
+protected:
+    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+
+private:
+    void ensureTexture();
+
+    QQuickShaderEffectSourceTextureProvider *m_provider;
+    QQuickShaderEffectTexture *m_texture;
+    WrapMode m_wrapMode;
+    QPointer<QQuickItem> m_sourceItem;
+    QRectF m_sourceRect;
+    QSize m_textureSize;
+    Format m_format;
+    uint m_live : 1;
+    uint m_hideSource : 1;
+    uint m_mipmap : 1;
+    uint m_recursive : 1;
+    uint m_grab : 1;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QQUICKSHADEREFFECTSOURCE_P_H
diff --git a/src/declarative/items/qquicksprite.cpp b/src/declarative/items/qquicksprite.cpp
new file mode 100644 (file)
index 0000000..b476905
--- /dev/null
@@ -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 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 "qquicksprite_p.h"
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+    \qmlclass Sprite QQuickSprite
+    \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)
+
+QQuickSprite::QQuickSprite(QObject *parent) :
+    QQuickStochasticState(parent)
+    , m_generatedCount(0)
+    , m_framesPerRow(0)
+    , m_frameHeight(0)
+    , m_frameWidth(0)
+    , m_rowY(0)
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquicksprite_p.h b/src/declarative/items/qquicksprite_p.h
new file mode 100644 (file)
index 0000000..e7f3bbc
--- /dev/null
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** 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 QQUICKSPRITE_P_H
+#define QQUICKSPRITE_P_H
+
+#include <QObject>
+#include <QUrl>
+#include <QVariantMap>
+#include <QDeclarativeListProperty>
+#include "qquickspriteengine_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+
+class QQuickSprite : public QQuickStochasticState
+{
+    Q_OBJECT
+    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)
+
+public:
+    explicit QQuickSprite(QObject *parent = 0);
+
+    QUrl source() const
+    {
+        return m_source;
+    }
+
+    int frameHeight() const
+    {
+        return m_frameHeight;
+    }
+
+    int frameWidth() const
+    {
+        return m_frameWidth;
+    }
+
+
+signals:
+
+    void sourceChanged(QUrl arg);
+
+    void frameHeightChanged(int arg);
+
+    void frameWidthChanged(int arg);
+
+public slots:
+
+    void setSource(QUrl arg)
+    {
+        if (m_source != arg) {
+            m_source = arg;
+            emit sourceChanged(arg);
+        }
+    }
+
+    void setFrameHeight(int arg)
+    {
+        if (m_frameHeight != arg) {
+            m_frameHeight = arg;
+            emit frameHeightChanged(arg);
+        }
+    }
+
+    void setFrameWidth(int arg)
+    {
+        if (m_frameWidth != arg) {
+            m_frameWidth = arg;
+            emit frameWidthChanged(arg);
+        }
+    }
+
+
+private:
+    friend class QSGImageParticle;
+    friend class QQuickSpriteEngine;
+    friend class QQuickStochasticEngine;
+    int m_generatedCount;
+    int m_framesPerRow;
+    QUrl m_source;
+    int m_frameHeight;
+    int m_frameWidth;
+    int m_rowY;
+
+};
+
+QT_END_NAMESPACE
+QT_END_HEADER
+#endif // QQUICKSPRITE_P_H
diff --git a/src/declarative/items/qquickspriteengine.cpp b/src/declarative/items/qquickspriteengine.cpp
new file mode 100644 (file)
index 0000000..9cf21eb
--- /dev/null
@@ -0,0 +1,500 @@
+/****************************************************************************
+**
+** 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 "qquickspriteengine_p.h"
+#include "qquicksprite_p.h"
+#include <QDebug>
+#include <QPainter>
+#include <QSet>
+#include <QtGui>
+
+QT_BEGIN_NAMESPACE
+
+/* TODO: Split out image logic from stochastic state logic
+   Also make sharable
+   Also solve the state data initialization/transfer issue so as to not need to make friends
+*/
+
+QQuickStochasticEngine::QQuickStochasticEngine(QObject *parent) :
+    QObject(parent), m_timeOffset(0)
+{
+    //Default size 1
+    setCount(1);
+    m_advanceTime.start();
+}
+
+QQuickStochasticEngine::QQuickStochasticEngine(QList<QQuickStochasticState*> states, QObject *parent) :
+    QObject(parent), m_states(states), m_timeOffset(0)
+{
+    //Default size 1
+    setCount(1);
+    m_advanceTime.start();
+}
+
+QQuickStochasticEngine::~QQuickStochasticEngine()
+{
+}
+
+QQuickSpriteEngine::QQuickSpriteEngine(QObject *parent)
+    : QQuickStochasticEngine(parent)
+{
+}
+
+QQuickSpriteEngine::QQuickSpriteEngine(QList<QQuickSprite*> sprites, QObject *parent)
+    : QQuickStochasticEngine(parent)
+{
+    foreach (QQuickSprite* sprite, sprites)
+        m_states << (QQuickStochasticState*)sprite;
+}
+
+QQuickSpriteEngine::~QQuickSpriteEngine()
+{
+}
+
+
+int QQuickSpriteEngine::maxFrames()
+{
+    return m_maxFrames;
+}
+
+/* States too large to fit in one row are split into multiple rows
+   This is more efficient for the implementation, but should remain an implementation detail (invisible from QML)
+   Therefore the below functions abstract sprite from the viewpoint of classes that pass the details onto shaders
+   But States maintain their listed index for internal structures
+TODO: All these calculations should be pre-calculated and cached during initialization for a significant performance boost
+TODO: Above idea needs to have the varying duration offset added to it
+*/
+int QQuickSpriteEngine::spriteState(int sprite)
+{
+    int state = m_things[sprite];
+    if (!m_sprites[state]->m_generatedCount)
+        return state;
+    int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow;
+    int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
+    return state + extra;
+}
+
+int QQuickSpriteEngine::spriteStart(int sprite)
+{
+    int state = m_things[sprite];
+    if (!m_sprites[state]->m_generatedCount)
+        return m_startTimes[sprite];
+    int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow;
+    int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
+    return state + extra*rowDuration;
+}
+
+int QQuickSpriteEngine::spriteFrames(int sprite)
+{
+    int state = m_things[sprite];
+    if (!m_sprites[state]->m_generatedCount)
+        return m_sprites[state]->frames();
+    int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow;
+    int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
+    if (extra == m_sprites[state]->m_generatedCount - 1)//last state
+        return m_sprites[state]->frames() % m_sprites[state]->m_framesPerRow;
+    else
+        return m_sprites[state]->m_framesPerRow;
+}
+
+int QQuickSpriteEngine::spriteDuration(int sprite)
+{
+    int state = m_things[sprite];
+    if (!m_sprites[state]->m_generatedCount)
+        return m_duration[sprite];
+    int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow;
+    int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
+    if (extra == m_sprites[state]->m_generatedCount - 1)//last state
+        return (m_duration[sprite] * m_sprites[state]->frames()) % rowDuration;
+    else
+        return rowDuration;
+}
+
+int QQuickSpriteEngine::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 QQuickSpriteEngine::spriteWidth(int sprite)
+{
+    int state = m_things[sprite];
+    return m_sprites[state]->m_frameWidth;
+}
+
+int QQuickSpriteEngine::spriteHeight(int sprite)
+{
+    int state = m_things[sprite];
+    return m_sprites[state]->m_frameHeight;
+}
+
+int QQuickSpriteEngine::spriteCount()//TODO: Actually image state count, need to rename these things to make sense together
+{
+    return m_imageStateCount;
+}
+
+void QQuickStochasticEngine::setGoal(int state, int sprite, bool jump)
+{
+    if (sprite >= m_things.count() || state >= m_states.count())
+        return;
+    if (!jump){
+        m_goals[sprite] = state;
+        return;
+    }
+
+    if (m_things[sprite] == state)
+        return;//Already there
+    m_things[sprite] = state;
+    m_duration[sprite] = m_states[state]->variedDuration();
+    m_goals[sprite] = -1;
+    restart(sprite);
+    emit stateChanged(sprite);
+    emit m_states[state]->entered();
+    return;
+}
+
+QImage QQuickSpriteEngine::assembledImage()
+{
+    int h = 0;
+    int w = 0;
+    m_maxFrames = 0;
+    m_imageStateCount = 0;
+    int maxSize = 0;
+
+    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
+    foreach (QQuickStochasticState* s, m_states){
+        QQuickSprite* sprite = qobject_cast<QQuickSprite*>(s);
+        if (sprite)
+            m_sprites << sprite;
+        else
+            qDebug() << "Error: Non-sprite in QQuickSpriteEngine";
+    }
+
+    foreach (QQuickSprite* state, m_sprites){
+        if (state->frames() > m_maxFrames)
+            m_maxFrames = state->frames();
+
+        QImage img(state->source().toLocalFile());
+        if (img.isNull()) {
+            qWarning() << "SpriteEngine: loading image failed..." << state->source().toLocalFile();
+            return QImage();
+        }
+
+        //Check that the frame sizes are the same within one engine
+        if (!state->m_frameWidth)
+            state->m_frameWidth = img.width() / state->frames();
+
+        if (!state->m_frameHeight)
+            state->m_frameHeight = img.height();
+
+        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, 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
+    QImage image(w, h, QImage::Format_ARGB32);
+    image.fill(0);
+    QPainter p(&image);
+    int y = 0;
+    foreach (QQuickSprite* 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{//Chopping up image case
+            state->m_framesPerRow = image.width()/frameWidth;
+            state->m_rowY = y;
+            int x = 0;
+            int curX = 0;
+            int curY = 0;
+            int framesLeft = state->frames();
+            while (framesLeft > 0){
+                if (image.width() - x + curX <= img.width()){//finish a row in image (dest)
+                    int copied = image.width() - x;
+                    Q_ASSERT(!(copied % frameWidth));//XXX: Just checking
+                    framesLeft -= copied/frameWidth;
+                    p.drawImage(x,y,img.copy(curX,curY,copied,frameHeight));
+                    y += frameHeight;
+                    curX += copied;
+                    x = 0;
+                    if (curX == img.width()){
+                        curX = 0;
+                        curY += frameHeight;
+                    }
+                }else{//finish a row in img (src)
+                    int copied = img.width() - curX;
+                    Q_ASSERT(!(copied % frameWidth));//XXX: Just checking
+                    framesLeft -= copied/frameWidth;
+                    p.drawImage(x,y,img.copy(curX,curY,copied,frameHeight));
+                    curY += frameHeight;
+                    x += copied;
+                    curX = 0;
+                }
+            }
+            if (x)
+                y += frameHeight;
+        }
+    }
+
+    if (image.height() > maxSize){
+        qWarning() << "SpriteEngine: Too many animations to fit in one texture...";
+        qWarning() << "SpriteEngine: Your texture max size today is " << maxSize;
+        return QImage();
+    }
+    return image;
+}
+
+void QQuickStochasticEngine::setCount(int c)
+{
+    m_things.resize(c);
+    m_goals.resize(c);
+    m_duration.resize(c);
+    m_startTimes.resize(c);
+}
+
+void QQuickStochasticEngine::start(int index, int state)
+{
+    if (index >= m_things.count())
+        return;
+    m_things[index] = state;
+    m_duration[index] = m_states[state]->variedDuration();
+    m_goals[index] = -1;
+    restart(index);
+}
+
+void QQuickStochasticEngine::stop(int index)
+{
+    if (index >= m_things.count())
+        return;
+    //Will never change until start is called again with a new state - this is not a 'pause'
+    for (int i=0; i<m_stateUpdates.count(); i++)
+        m_stateUpdates[i].second.removeAll(index);
+}
+
+void QQuickStochasticEngine::restart(int index)
+{
+    m_startTimes[index] = m_timeOffset + m_advanceTime.elapsed();
+    int time = m_duration[index] * m_states[m_things[index]]->frames() + m_startTimes[index];
+    for (int i=0; i<m_stateUpdates.count(); i++)
+        m_stateUpdates[i].second.removeAll(index);
+    addToUpdateList(time, index);
+}
+
+uint QQuickStochasticEngine::updateSprites(uint time)//### would returning a list of changed idxs be faster than signals?
+{
+    //Sprite State Update;
+    QSet<int> changedIndexes;
+    while (!m_stateUpdates.isEmpty() && time >= m_stateUpdates.first().first){
+        foreach (int idx, m_stateUpdates.first().second){
+            if (idx >= m_things.count())
+                continue;//TODO: Proper fix(because this does happen and I'm just ignoring it)
+            int stateIdx = m_things[idx];
+            int nextIdx = -1;
+            int goalPath = goalSeek(stateIdx, idx);
+            if (goalPath == -1){//Random
+                qreal r =(qreal) qrand() / (qreal) RAND_MAX;
+                qreal total = 0.0;
+                for (QVariantMap::const_iterator iter=m_states[stateIdx]->m_to.constBegin();
+                    iter!=m_states[stateIdx]->m_to.constEnd(); iter++)
+                    total += (*iter).toReal();
+                r*=total;
+                for (QVariantMap::const_iterator iter= m_states[stateIdx]->m_to.constBegin();
+                        iter!=m_states[stateIdx]->m_to.constEnd(); iter++){
+                    if (r < (*iter).toReal()){
+                        bool superBreak = false;
+                        for (int i=0; i<m_states.count(); i++){
+                            if (m_states[i]->name() == iter.key()){
+                                nextIdx = i;
+                                superBreak = true;
+                                break;
+                            }
+                        }
+                        if (superBreak)
+                            break;
+                    }
+                    r -= (*iter).toReal();
+                }
+            }else{//Random out of shortest paths to goal
+                nextIdx = goalPath;
+            }
+            if (nextIdx == -1)//No to states means stay here
+                nextIdx = stateIdx;
+
+            m_things[idx] = nextIdx;
+            m_duration[idx] = m_states[nextIdx]->variedDuration();
+            m_startTimes[idx] = time;
+            if (nextIdx != stateIdx){
+                changedIndexes << idx;
+                emit m_states[nextIdx]->entered();
+            }
+            addToUpdateList((m_duration[idx] * m_states[nextIdx]->frames()) + time, idx);
+        }
+        m_stateUpdates.pop_front();
+    }
+
+    m_timeOffset = time;
+    m_advanceTime.start();
+    //TODO: emit this when a psuedostate changes too
+    foreach (int idx, changedIndexes){//Batched so that update list doesn't change midway
+        emit stateChanged(idx);
+    }
+    if (m_stateUpdates.isEmpty())
+        return -1;
+    return m_stateUpdates.first().first;
+}
+
+int QQuickStochasticEngine::goalSeek(int curIdx, int spriteIdx, int dist)
+{
+    QString goalName;
+    if (m_goals[spriteIdx] != -1)
+        goalName = m_states[m_goals[spriteIdx]]->name();
+    else
+        goalName = m_globalGoal;
+    if (goalName.isEmpty())
+        return -1;
+    //TODO: caching instead of excessively redoing iterative deepening (which was chosen arbitarily anyways)
+    // Paraphrased - implement in an *efficient* manner
+    for (int i=0; i<m_states.count(); i++)
+        if (m_states[curIdx]->name() == goalName)
+            return curIdx;
+    if (dist < 0)
+        dist = m_states.count();
+    QQuickStochasticState* curState = m_states[curIdx];
+    for (QVariantMap::const_iterator iter = curState->m_to.constBegin();
+        iter!=curState->m_to.constEnd(); iter++){
+        if (iter.key() == goalName)
+            for (int i=0; i<m_states.count(); i++)
+                if (m_states[i]->name() == goalName)
+                    return i;
+    }
+    QSet<int> options;
+    for (int i=1; i<dist; i++){
+        for (QVariantMap::const_iterator iter = curState->m_to.constBegin();
+            iter!=curState->m_to.constEnd(); iter++){
+            int option = -1;
+            for (int j=0; j<m_states.count(); j++)//One place that could be a lot more efficient...
+                if (m_states[j]->name() == iter.key())
+                    if (goalSeek(j, spriteIdx, i) != -1)
+                        option = j;
+            if (option != -1)
+                options << option;
+        }
+        if (!options.isEmpty()){
+            if (options.count()==1)
+                return *(options.begin());
+            int option = -1;
+            qreal r =(qreal) qrand() / (qreal) RAND_MAX;
+            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();
+            r *= total;
+            for (QVariantMap::const_iterator iter = curState->m_to.constBegin();
+                iter!=curState->m_to.constEnd(); iter++){
+                bool superContinue = true;
+                for (int j=0; j<m_states.count(); j++)
+                    if (m_states[j]->name() == iter.key())
+                        if (options.contains(j))
+                            superContinue = false;
+                if (superContinue)
+                    continue;
+                if (r < (*iter).toReal()){
+                    bool superBreak = false;
+                    for (int j=0; j<m_states.count(); j++){
+                        if (m_states[j]->name() == iter.key()){
+                            option = j;
+                            superBreak = true;
+                            break;
+                        }
+                    }
+                    if (superBreak)
+                        break;
+                }
+                r-=(*iter).toReal();
+            }
+            return option;
+        }
+    }
+    return -1;
+}
+
+void QQuickStochasticEngine::addToUpdateList(uint t, int idx)
+{
+    for (int i=0; i<m_stateUpdates.count(); i++){
+        if (m_stateUpdates[i].first==t){
+            m_stateUpdates[i].second << idx;
+            return;
+        }else if (m_stateUpdates[i].first > t){
+            QList<int> tmpList;
+            tmpList << idx;
+            m_stateUpdates.insert(i, qMakePair(t, tmpList));
+            return;
+        }
+    }
+    QList<int> tmpList;
+    tmpList << idx;
+    m_stateUpdates << qMakePair(t, tmpList);
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickspriteengine_p.h b/src/declarative/items/qquickspriteengine_p.h
new file mode 100644 (file)
index 0000000..6d527d1
--- /dev/null
@@ -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 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 QQUICKSPRITEENGINE_P_H
+#define QQUICKSPRITEENGINE_P_H
+
+#include <QObject>
+#include <QVector>
+#include <QTimer>
+#include <QTime>
+#include <QList>
+#include <QDeclarativeListProperty>
+#include <QImage>
+#include <QPair>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickSprite;
+class Q_AUTOTEST_EXPORT QQuickStochasticState : public QObject //For internal use
+{
+    Q_OBJECT
+    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)
+
+public:
+    QQuickStochasticState(QObject* parent = 0)
+        : QObject(parent)
+        , m_frames(1)
+        , m_duration(1000)
+    {
+    }
+
+    int duration() const
+    {
+        return m_duration;
+    }
+
+    QString name() const
+    {
+        return m_name;
+    }
+
+    QVariantMap to() const
+    {
+        return m_to;
+    }
+
+    qreal speedModifer() const
+    {
+        return m_speedModifier;
+    }
+
+    int durationVariance() const
+    {
+        return m_durationVariance;
+    }
+
+
+    int variedDuration() const
+    {
+        return m_duration
+                + (m_durationVariance * ((qreal)qrand()/RAND_MAX) * 2)
+                - m_durationVariance;
+    }
+
+    int frames() const
+    {
+        return m_frames;
+    }
+
+signals:
+    void durationChanged(int arg);
+
+    void nameChanged(QString arg);
+
+    void toChanged(QVariantMap arg);
+
+    void speedModifierChanged(qreal arg);
+
+    void durationVarianceChanged(int arg);
+
+    void entered();//### Just playing around - don't expect full state API
+    void framesChanged(int arg);
+
+public slots:
+    void setDuration(int arg)
+    {
+        if (m_duration != arg) {
+            m_duration = arg;
+            emit durationChanged(arg);
+        }
+    }
+
+    void setName(QString arg)
+    {
+        if (m_name != arg) {
+            m_name = arg;
+            emit nameChanged(arg);
+        }
+    }
+
+    void setTo(QVariantMap arg)
+    {
+        if (m_to != arg) {
+            m_to = arg;
+            emit toChanged(arg);
+        }
+    }
+
+    void setSpeedModifier(qreal arg)
+    {
+        if (m_speedModifier != arg) {
+            m_speedModifier = arg;
+            emit speedModifierChanged(arg);
+        }
+    }
+
+    void setDurationVariance(int arg)
+    {
+        if (m_durationVariance != arg) {
+            m_durationVariance = arg;
+            emit durationVarianceChanged(arg);
+        }
+    }
+
+    void setFrames(int arg)
+    {
+        if (m_frames != arg) {
+            m_frames = arg;
+            emit framesChanged(arg);
+        }
+    }
+
+private:
+    QString m_name;
+    int m_frames;
+    QVariantMap m_to;
+    int m_duration;
+    qreal m_speedModifier;
+    int m_durationVariance;
+
+    friend class QQuickStochasticEngine;
+};
+
+class Q_AUTOTEST_EXPORT QQuickStochasticEngine : public QObject
+{
+    Q_OBJECT
+    //TODO: Optimize single state case?
+    Q_PROPERTY(QString globalGoal READ globalGoal WRITE setGlobalGoal NOTIFY globalGoalChanged)
+    Q_PROPERTY(QDeclarativeListProperty<QQuickStochasticState> states READ states)
+public:
+    explicit QQuickStochasticEngine(QObject *parent = 0);
+    QQuickStochasticEngine(QList<QQuickStochasticState*> states, QObject *parent=0);
+    ~QQuickStochasticEngine();
+
+    QDeclarativeListProperty<QQuickStochasticState> states()
+    {
+        return QDeclarativeListProperty<QQuickStochasticState>(this, m_states);
+    }
+
+    QString globalGoal() const
+    {
+        return m_globalGoal;
+    }
+
+    int count() const {return m_things.count();}
+    void setCount(int c);
+
+
+
+    void setGoal(int state, int sprite=0, bool jump=false);
+    void start(int index=0, int state=0);
+    void stop(int index=0);
+    int curState(int index=0) {return m_things[index];}
+
+    QQuickStochasticState* state(int idx){return m_states[idx];}
+    int stateIndex(QQuickStochasticState* s){return m_states.indexOf(s);}
+    int stateCount() {return m_states.count();}
+private:
+signals:
+
+    void globalGoalChanged(QString arg);
+    void stateChanged(int idx);
+
+public slots:
+    void setGlobalGoal(QString arg)
+    {
+        if (m_globalGoal != arg) {
+            m_globalGoal = arg;
+            emit globalGoalChanged(arg);
+        }
+    }
+
+    uint updateSprites(uint time);
+
+protected:
+    friend class QSGParticleSystem;
+    void restart(int index);
+    void addToUpdateList(uint t, int idx);
+    int goalSeek(int curState, int idx, int dist=-1);
+    QList<QQuickStochasticState*> m_states;
+    //### Consider struct or class for the four data variables?
+    QVector<int> m_things;//int is the index in m_states of the current state
+    QVector<int> m_goals;
+    QVector<int> m_duration;
+    QVector<int> m_startTimes;
+    QList<QPair<uint, QList<int> > > m_stateUpdates;//### This could be done faster - priority queue?
+
+    QTime m_advanceTime;
+    uint m_timeOffset;
+    QString m_globalGoal;
+    int m_maxFrames;
+    int m_imageStateCount;
+};
+
+class QQuickSpriteEngine : public QQuickStochasticEngine
+{
+    Q_OBJECT
+    Q_PROPERTY(QDeclarativeListProperty<QQuickSprite> sprites READ sprites)
+public:
+    explicit QQuickSpriteEngine(QObject *parent = 0);
+    QQuickSpriteEngine(QList<QQuickSprite*> sprites, QObject *parent=0);
+    ~QQuickSpriteEngine();
+    QDeclarativeListProperty<QQuickSprite> sprites()
+    {
+        return QDeclarativeListProperty<QQuickSprite>(this, m_sprites);
+    }
+
+
+    int spriteState(int sprite=0);
+    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();
+private:
+    QList<QQuickSprite*> m_sprites;
+};
+
+//Common use is to have your own list property which is transparently an engine
+inline void spriteAppend(QDeclarativeListProperty<QQuickSprite> *p, QQuickSprite* s)
+{
+    reinterpret_cast<QList<QQuickSprite *> *>(p->data)->append(s);
+    p->object->metaObject()->invokeMethod(p->object, "createEngine");
+}
+
+inline QQuickSprite* spriteAt(QDeclarativeListProperty<QQuickSprite> *p, int idx)
+{
+    return reinterpret_cast<QList<QQuickSprite *> *>(p->data)->at(idx);
+}
+
+inline void spriteClear(QDeclarativeListProperty<QQuickSprite> *p)
+{
+    reinterpret_cast<QList<QQuickSprite *> *>(p->data)->clear();
+    p->object->metaObject()->invokeMethod(p->object, "createEngine");
+}
+
+inline int spriteCount(QDeclarativeListProperty<QQuickSprite> *p)
+{
+    return reinterpret_cast<QList<QQuickSprite *> *>(p->data)->count();
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QQUICKSPRITEENGINE_P_H
diff --git a/src/declarative/items/qquickspriteimage.cpp b/src/declarative/items/qquickspriteimage.cpp
new file mode 100644 (file)
index 0000000..36ab734
--- /dev/null
@@ -0,0 +1,421 @@
+/****************************************************************************
+**
+** 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 "qquickspriteimage_p.h"
+#include "qquicksprite_p.h"
+#include "qquickspriteengine_p.h"
+#include <private/qsgcontext_p.h>
+#include <private/qsgadaptationlayer_p.h>
+#include <qsgnode.h>
+#include <qsgengine.h>
+#include <qsgtexturematerial.h>
+#include <qsgtexture.h>
+#include <QFile>
+#include <cmath>
+#include <qmath.h>
+#include <QDebug>
+
+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 QQuickSpriteMaterial : public QSGMaterial
+{
+public:
+    QQuickSpriteMaterial();
+    virtual ~QQuickSpriteMaterial();
+    virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; }
+    virtual QSGMaterialShader *createShader() const;
+    virtual int compare(const QSGMaterial *other) const
+    {
+        return this - static_cast<const QQuickSpriteMaterial *>(other);
+    }
+
+    QSGTexture *texture;
+
+    qreal timestamp;
+    float interpolate;
+    float frameDuration;
+    float frameCount;
+    float animT;
+    float animX;
+    float animY;
+    float animWidth;
+    float animHeight;
+    float sheetWidth;
+    float sheetHeight;
+    float elementWidth;
+    float elementHeight;
+};
+
+QQuickSpriteMaterial::QQuickSpriteMaterial()
+    : timestamp(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);
+}
+
+QQuickSpriteMaterial::~QQuickSpriteMaterial()
+{
+    delete texture;
+}
+
+class SpriteMaterialData : public QSGMaterialShader
+{
+public:
+    SpriteMaterialData(const char *vertexFile = 0, const char *fragmentFile = 0)
+    {
+    }
+
+    void deactivate() {
+        QSGMaterialShader::deactivate();
+
+        for (int i=0; i<8; ++i) {
+            program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0);
+        }
+    }
+
+    virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *)
+    {
+        QQuickSpriteMaterial *m = static_cast<QQuickSpriteMaterial *>(newEffect);
+        m->texture->bind();
+
+        program()->setUniformValue(m_opacity_id, state.opacity());
+        program()->setUniformValue(m_timestamp_id, (float) m->timestamp);
+        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("qt_Matrix");
+        m_opacity_id = program()->uniformLocation("qt_Opacity");
+        m_timestamp_id = program()->uniformLocation("timestamp");
+        m_animData_id = program()->uniformLocation("animData");
+        m_animPos_id = program()->uniformLocation("animPos");
+        m_animSheetSize_id = program()->uniformLocation("animSheetSize");
+    }
+
+    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",
+            0
+        };
+        return attr;
+    }
+
+    int m_matrix_id;
+    int m_opacity_id;
+    int m_timestamp_id;
+    int m_animData_id;
+    int m_animPos_id;
+    int m_animSheetSize_id;
+
+    static float chunkOfBytes[1024];
+};
+
+float SpriteMaterialData::chunkOfBytes[1024];
+
+QSGMaterialShader *QQuickSpriteMaterial::createShader() const
+{
+    return new SpriteMaterialData;
+}
+
+struct SpriteVertex {
+    float tx;
+    float ty;
+};
+
+struct SpriteVertices {
+    SpriteVertex v1;
+    SpriteVertex v2;
+    SpriteVertex v3;
+    SpriteVertex v4;
+};
+
+/*!
+    \qmlclass SpriteImage QQuickSpriteImage
+    \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?
+QQuickSpriteImage::QQuickSpriteImage(QQuickItem *parent) :
+    QQuickItem(parent)
+    , m_node(0)
+    , m_material(0)
+    , m_spriteEngine(0)
+    , m_pleaseReset(false)
+    , m_running(true)
+    , m_interpolate(true)
+{
+    setFlag(ItemHasContents);
+    connect(this, SIGNAL(runningChanged(bool)),
+            this, SLOT(update()));
+}
+
+QDeclarativeListProperty<QQuickSprite> QQuickSpriteImage::sprites()
+{
+    return QDeclarativeListProperty<QQuickSprite>(this, &m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear);
+}
+
+void QQuickSpriteImage::createEngine()
+{
+    //TODO: delay until component complete
+    if (m_spriteEngine)
+        delete m_spriteEngine;
+    if (m_sprites.count())
+        m_spriteEngine = new QQuickSpriteEngine(m_sprites, this);
+    else
+        m_spriteEngine = 0;
+    reset();
+}
+
+static QSGGeometry::Attribute SpriteImage_Attributes[] = {
+    QSGGeometry::Attribute::create(0, 2, GL_FLOAT),         // tex
+};
+
+static QSGGeometry::AttributeSet SpriteImage_AttributeSet =
+{
+    1, // Attribute Count
+    2 * sizeof(float),
+    SpriteImage_Attributes
+};
+
+QSGGeometryNode* QQuickSpriteImage::buildNode()
+{
+    if (!m_spriteEngine) {
+        qWarning() << "SpriteImage: No sprite engine...";
+        return 0;
+    }
+
+    m_material = new QQuickSpriteMaterial();
+
+    QImage image = m_spriteEngine->assembledImage();
+    if (image.isNull())
+        return 0;
+    m_material->texture = sceneGraphEngine()->createTextureFromImage(image);
+    m_material->texture->setFiltering(QSGTexture::Linear);
+    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;
+    QSGGeometry *g = new QSGGeometry(SpriteImage_AttributeSet, vCount, iCount);
+    g->setDrawingMode(GL_TRIANGLES);
+
+    SpriteVertices *p = (SpriteVertices *) g->vertexData();
+
+    p->v1.tx = 0;
+    p->v1.ty = 0;
+
+    p->v2.tx = 1.0;
+    p->v2.ty = 0;
+
+    p->v3.tx = 0;
+    p->v3.ty = 1.0;
+
+    p->v4.tx = 1.0;
+    p->v4.ty = 1.0;
+
+    quint16 *indices = g->indexDataAsUShort();
+    indices[0] = 0;
+    indices[1] = 1;
+    indices[2] = 2;
+    indices[3] = 1;
+    indices[4] = 3;
+    indices[5] = 2;
+
+
+    m_timestamp.start();
+    m_node = new QSGGeometryNode();
+    m_node->setGeometry(g);
+    m_node->setMaterial(m_material);
+    m_node->setFlag(QSGGeometryNode::OwnsMaterial);
+    return m_node;
+}
+
+void QQuickSpriteImage::reset()
+{
+    m_pleaseReset = true;
+}
+
+QSGNode *QQuickSpriteImage::updatePaintNode(QSGNode *, UpdatePaintNodeData *)
+{
+    if (m_pleaseReset) {
+        delete m_node;
+        delete m_material;
+
+        m_node = 0;
+        m_material = 0;
+        m_pleaseReset = false;
+    }
+
+    prepareNextFrame();
+
+    if (m_running) {
+        update();
+        if (m_node)
+            m_node->markDirty(QSGNode::DirtyMaterial);
+    }
+
+    return m_node;
+}
+
+void QQuickSpriteImage::prepareNextFrame()
+{
+    if (m_node == 0)
+        m_node = buildNode();
+    if (m_node == 0) //error creating node
+        return;
+
+    uint timeInt = m_timestamp.elapsed();
+    qreal time =  timeInt / 1000.;
+    m_material->timestamp = time;
+    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 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();
+    }
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickspriteimage_p.h b/src/declarative/items/qquickspriteimage_p.h
new file mode 100644 (file)
index 0000000..1ffc95d
--- /dev/null
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** 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 QQUICKSPRITEIMAGE_P_H
+#define QQUICKSPRITEIMAGE_P_H
+
+#include <QQuickItem>
+#include <QTime>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QSGContext;
+class QQuickSprite;
+class QQuickSpriteEngine;
+class QSGGeometryNode;
+class QQuickSpriteMaterial;
+class QQuickSpriteImage : public QQuickItem
+{
+    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<QQuickSprite> sprites READ sprites)
+    Q_CLASSINFO("DefaultProperty", "sprites")
+
+public:
+    explicit QQuickSpriteImage(QQuickItem *parent = 0);
+
+    QDeclarativeListProperty<QQuickSprite> sprites();
+
+    bool running() const
+    {
+        return m_running;
+    }
+
+    bool interpolate() const
+    {
+        return m_interpolate;
+    }
+
+signals:
+
+    void runningChanged(bool arg);
+    void interpolateChanged(bool arg);
+
+public slots:
+
+void setRunning(bool arg)
+{
+    if (m_running != arg) {
+        m_running = arg;
+        emit runningChanged(arg);
+    }
+}
+
+void setInterpolate(bool arg)
+{
+    if (m_interpolate != arg) {
+        m_interpolate = arg;
+        emit interpolateChanged(arg);
+    }
+}
+
+private slots:
+    void createEngine();
+protected:
+    void reset();
+    QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+private:
+    void prepareNextFrame();
+    QSGGeometryNode* buildNode();
+    QSGGeometryNode *m_node;
+    QQuickSpriteMaterial *m_material;
+    QList<QQuickSprite*> m_sprites;
+    QQuickSpriteEngine* m_spriteEngine;
+    QTime m_timestamp;
+    int m_maxFrames;
+    bool m_pleaseReset;
+    bool m_running;
+    bool m_interpolate;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QQUICKSPRITEIMAGE_P_H
diff --git a/src/declarative/items/qquickstateoperations.cpp b/src/declarative/items/qquickstateoperations.cpp
new file mode 100644 (file)
index 0000000..8c53e0a
--- /dev/null
@@ -0,0 +1,1346 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qquickstateoperations_p.h"
+#include "qquickitem_p.h"
+
+#include <private/qdeclarativestate_p_p.h>
+
+#include <QtDeclarative/qdeclarativeinfo.h>
+#include <QtCore/qmath.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickParentChangePrivate : public QDeclarativeStateOperationPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickParentChange)
+public:
+    QQuickParentChangePrivate() : target(0), parent(0), origParent(0), origStackBefore(0),
+        rewindParent(0), rewindStackBefore(0) {}
+
+    QQuickItem *target;
+    QDeclarativeGuard<QQuickItem> parent;
+    QDeclarativeGuard<QQuickItem> origParent;
+    QDeclarativeGuard<QQuickItem> origStackBefore;
+    QQuickItem *rewindParent;
+    QQuickItem *rewindStackBefore;
+
+    QDeclarativeNullableValue<QDeclarativeScriptString> xString;
+    QDeclarativeNullableValue<QDeclarativeScriptString> yString;
+    QDeclarativeNullableValue<QDeclarativeScriptString> widthString;
+    QDeclarativeNullableValue<QDeclarativeScriptString> heightString;
+    QDeclarativeNullableValue<QDeclarativeScriptString> scaleString;
+    QDeclarativeNullableValue<QDeclarativeScriptString> rotationString;
+
+    void doChange(QQuickItem *targetParent, QQuickItem *stackBefore = 0);
+};
+
+void QQuickParentChangePrivate::doChange(QQuickItem *targetParent, QQuickItem *stackBefore)
+{
+    if (targetParent && target && target->parentItem()) {
+        Q_Q(QQuickParentChange);
+        bool ok;
+        const QTransform &transform = target->parentItem()->itemTransform(targetParent, &ok);
+        if (transform.type() >= QTransform::TxShear || !ok) {
+            qmlInfo(q) << QQuickParentChange::tr("Unable to preserve appearance under complex transform");
+            ok = false;
+        }
+
+        qreal scale = 1;
+        qreal rotation = 0;
+        bool isRotate = (transform.type() == QTransform::TxRotate) || (transform.m11() < 0);
+        if (ok && !isRotate) {
+            if (transform.m11() == transform.m22())
+                scale = transform.m11();
+            else {
+                qmlInfo(q) << QQuickParentChange::tr("Unable to preserve appearance under non-uniform scale");
+                ok = false;
+            }
+        } else if (ok && isRotate) {
+            if (transform.m11() == transform.m22())
+                scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12());
+            else {
+                qmlInfo(q) << QQuickParentChange::tr("Unable to preserve appearance under non-uniform scale");
+                ok = false;
+            }
+
+            if (scale != 0)
+                rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
+            else {
+                qmlInfo(q) << QQuickParentChange::tr("Unable to preserve appearance under scale of 0");
+                ok = false;
+            }
+        }
+
+        const QPointF &point = transform.map(QPointF(target->x(),target->y()));
+        qreal x = point.x();
+        qreal y = point.y();
+
+        // setParentItem will update the transformOriginPoint if needed
+        target->setParentItem(targetParent);
+
+        if (ok && target->transformOrigin() != QQuickItem::TopLeft) {
+            qreal tempxt = target->transformOriginPoint().x();
+            qreal tempyt = target->transformOriginPoint().y();
+            QTransform t;
+            t.translate(-tempxt, -tempyt);
+            t.rotate(rotation);
+            t.scale(scale, scale);
+            t.translate(tempxt, tempyt);
+            const QPointF &offset = t.map(QPointF(0,0));
+            x += offset.x();
+            y += offset.y();
+        }
+
+        if (ok) {
+            //qDebug() << x << y << rotation << scale;
+            target->setX(x);
+            target->setY(y);
+            target->setRotation(target->rotation() + rotation);
+            target->setScale(target->scale() * scale);
+        }
+    } else if (target) {
+        target->setParentItem(targetParent);
+    }
+
+    //restore the original stack position.
+    //### if stackBefore has also been reparented this won't work
+    if (stackBefore)
+        target->stackBefore(stackBefore);
+}
+
+QQuickParentChange::QQuickParentChange(QObject *parent)
+    : QDeclarativeStateOperation(*(new QQuickParentChangePrivate), parent)
+{
+}
+
+QQuickParentChange::~QQuickParentChange()
+{
+}
+
+QDeclarativeScriptString QQuickParentChange::x() const
+{
+    Q_D(const QQuickParentChange);
+    return d->xString.value;
+}
+
+void QQuickParentChange::setX(QDeclarativeScriptString x)
+{
+    Q_D(QQuickParentChange);
+    d->xString = x;
+}
+
+bool QQuickParentChange::xIsSet() const
+{
+    Q_D(const QQuickParentChange);
+    return d->xString.isValid();
+}
+
+QDeclarativeScriptString QQuickParentChange::y() const
+{
+    Q_D(const QQuickParentChange);
+    return d->yString.value;
+}
+
+void QQuickParentChange::setY(QDeclarativeScriptString y)
+{
+    Q_D(QQuickParentChange);
+    d->yString = y;
+}
+
+bool QQuickParentChange::yIsSet() const
+{
+    Q_D(const QQuickParentChange);
+    return d->yString.isValid();
+}
+
+QDeclarativeScriptString QQuickParentChange::width() const
+{
+    Q_D(const QQuickParentChange);
+    return d->widthString.value;
+}
+
+void QQuickParentChange::setWidth(QDeclarativeScriptString width)
+{
+    Q_D(QQuickParentChange);
+    d->widthString = width;
+}
+
+bool QQuickParentChange::widthIsSet() const
+{
+    Q_D(const QQuickParentChange);
+    return d->widthString.isValid();
+}
+
+QDeclarativeScriptString QQuickParentChange::height() const
+{
+    Q_D(const QQuickParentChange);
+    return d->heightString.value;
+}
+
+void QQuickParentChange::setHeight(QDeclarativeScriptString height)
+{
+    Q_D(QQuickParentChange);
+    d->heightString = height;
+}
+
+bool QQuickParentChange::heightIsSet() const
+{
+    Q_D(const QQuickParentChange);
+    return d->heightString.isValid();
+}
+
+QDeclarativeScriptString QQuickParentChange::scale() const
+{
+    Q_D(const QQuickParentChange);
+    return d->scaleString.value;
+}
+
+void QQuickParentChange::setScale(QDeclarativeScriptString scale)
+{
+    Q_D(QQuickParentChange);
+    d->scaleString = scale;
+}
+
+bool QQuickParentChange::scaleIsSet() const
+{
+    Q_D(const QQuickParentChange);
+    return d->scaleString.isValid();
+}
+
+QDeclarativeScriptString QQuickParentChange::rotation() const
+{
+    Q_D(const QQuickParentChange);
+    return d->rotationString.value;
+}
+
+void QQuickParentChange::setRotation(QDeclarativeScriptString rotation)
+{
+    Q_D(QQuickParentChange);
+    d->rotationString = rotation;
+}
+
+bool QQuickParentChange::rotationIsSet() const
+{
+    Q_D(const QQuickParentChange);
+    return d->rotationString.isValid();
+}
+
+QQuickItem *QQuickParentChange::originalParent() const
+{
+    Q_D(const QQuickParentChange);
+    return d->origParent;
+}
+
+QQuickItem *QQuickParentChange::object() const
+{
+    Q_D(const QQuickParentChange);
+    return d->target;
+}
+
+void QQuickParentChange::setObject(QQuickItem *target)
+{
+    Q_D(QQuickParentChange);
+    d->target = target;
+}
+
+QQuickItem *QQuickParentChange::parent() const
+{
+    Q_D(const QQuickParentChange);
+    return d->parent;
+}
+
+void QQuickParentChange::setParent(QQuickItem *parent)
+{
+    Q_D(QQuickParentChange);
+    d->parent = parent;
+}
+
+QDeclarativeStateOperation::ActionList QQuickParentChange::actions()
+{
+    Q_D(QQuickParentChange);
+    if (!d->target || !d->parent)
+        return ActionList();
+
+    ActionList actions;
+
+    QDeclarativeAction a;
+    a.event = this;
+    actions << a;
+
+    if (d->xString.isValid()) {
+        bool ok = false;
+        QString script = d->xString.value.script();
+        qreal x = script.toFloat(&ok);
+        if (ok) {
+            QDeclarativeAction xa(d->target, QLatin1String("x"), x);
+            actions << xa;
+        } else {
+            QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
+            newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("x")));
+            QDeclarativeAction xa;
+            xa.property = newBinding->property();
+            xa.toBinding = newBinding;
+            xa.fromValue = xa.property.read();
+            xa.deletableToBinding = true;
+            actions << xa;
+        }
+    }
+
+    if (d->yString.isValid()) {
+        bool ok = false;
+        QString script = d->yString.value.script();
+        qreal y = script.toFloat(&ok);
+        if (ok) {
+            QDeclarativeAction ya(d->target, QLatin1String("y"), y);
+            actions << ya;
+        } else {
+            QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
+            newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("y")));
+            QDeclarativeAction ya;
+            ya.property = newBinding->property();
+            ya.toBinding = newBinding;
+            ya.fromValue = ya.property.read();
+            ya.deletableToBinding = true;
+            actions << ya;
+        }
+    }
+
+    if (d->scaleString.isValid()) {
+        bool ok = false;
+        QString script = d->scaleString.value.script();
+        qreal scale = script.toFloat(&ok);
+        if (ok) {
+            QDeclarativeAction sa(d->target, QLatin1String("scale"), scale);
+            actions << sa;
+        } else {
+            QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
+            newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("scale")));
+            QDeclarativeAction sa;
+            sa.property = newBinding->property();
+            sa.toBinding = newBinding;
+            sa.fromValue = sa.property.read();
+            sa.deletableToBinding = true;
+            actions << sa;
+        }
+    }
+
+    if (d->rotationString.isValid()) {
+        bool ok = false;
+        QString script = d->rotationString.value.script();
+        qreal rotation = script.toFloat(&ok);
+        if (ok) {
+            QDeclarativeAction ra(d->target, QLatin1String("rotation"), rotation);
+            actions << ra;
+        } else {
+            QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
+            newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("rotation")));
+            QDeclarativeAction ra;
+            ra.property = newBinding->property();
+            ra.toBinding = newBinding;
+            ra.fromValue = ra.property.read();
+            ra.deletableToBinding = true;
+            actions << ra;
+        }
+    }
+
+    if (d->widthString.isValid()) {
+        bool ok = false;
+        QString script = d->widthString.value.script();
+        qreal width = script.toFloat(&ok);
+        if (ok) {
+            QDeclarativeAction wa(d->target, QLatin1String("width"), width);
+            actions << wa;
+        } else {
+            QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
+            newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("width")));
+            QDeclarativeAction wa;
+            wa.property = newBinding->property();
+            wa.toBinding = newBinding;
+            wa.fromValue = wa.property.read();
+            wa.deletableToBinding = true;
+            actions << wa;
+        }
+    }
+
+    if (d->heightString.isValid()) {
+        bool ok = false;
+        QString script = d->heightString.value.script();
+        qreal height = script.toFloat(&ok);
+        if (ok) {
+            QDeclarativeAction ha(d->target, QLatin1String("height"), height);
+            actions << ha;
+        } else {
+            QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
+            newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("height")));
+            QDeclarativeAction ha;
+            ha.property = newBinding->property();
+            ha.toBinding = newBinding;
+            ha.fromValue = ha.property.read();
+            ha.deletableToBinding = true;
+            actions << ha;
+        }
+    }
+
+    return actions;
+}
+
+void QQuickParentChange::saveOriginals()
+{
+    Q_D(QQuickParentChange);
+    saveCurrentValues();
+    d->origParent = d->rewindParent;
+    d->origStackBefore = d->rewindStackBefore;
+}
+
+/*void QQuickParentChange::copyOriginals(QDeclarativeActionEvent *other)
+{
+    Q_D(QQuickParentChange);
+    QQuickParentChange *pc = static_cast<QQuickParentChange*>(other);
+
+    d->origParent = pc->d_func()->rewindParent;
+    d->origStackBefore = pc->d_func()->rewindStackBefore;
+
+    saveCurrentValues();
+}*/
+
+void QQuickParentChange::execute(Reason)
+{
+    Q_D(QQuickParentChange);
+    d->doChange(d->parent);
+}
+
+bool QQuickParentChange::isReversable()
+{
+    return true;
+}
+
+void QQuickParentChange::reverse(Reason)
+{
+    Q_D(QQuickParentChange);
+    d->doChange(d->origParent, d->origStackBefore);
+}
+
+QString QQuickParentChange::typeName() const
+{
+    return QLatin1String("ParentChange");
+}
+
+bool QQuickParentChange::override(QDeclarativeActionEvent*other)
+{
+    Q_D(QQuickParentChange);
+    if (other->typeName() != QLatin1String("ParentChange"))
+        return false;
+    if (QQuickParentChange *otherPC = static_cast<QQuickParentChange*>(other))
+        return (d->target == otherPC->object());
+    return false;
+}
+
+void QQuickParentChange::saveCurrentValues()
+{
+    Q_D(QQuickParentChange);
+    if (!d->target) {
+        d->rewindParent = 0;
+        d->rewindStackBefore = 0;
+        return;
+    }
+
+    d->rewindParent = d->target->parentItem();
+    d->rewindStackBefore = 0;
+
+    if (!d->rewindParent)
+        return;
+
+    QList<QQuickItem *> children = d->rewindParent->childItems();
+    for (int ii = 0; ii < children.count() - 1; ++ii) {
+        if (children.at(ii) == d->target) {
+            d->rewindStackBefore = children.at(ii + 1);
+            break;
+        }
+    }
+}
+
+void QQuickParentChange::rewind()
+{
+    Q_D(QQuickParentChange);
+    d->doChange(d->rewindParent, d->rewindStackBefore);
+}
+
+class QQuickAnchorSetPrivate : public QObjectPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickAnchorSet)
+public:
+    QQuickAnchorSetPrivate()
+      : usedAnchors(0), resetAnchors(0), fill(0),
+        centerIn(0)/*, leftMargin(0), rightMargin(0), topMargin(0), bottomMargin(0),
+        margins(0), vCenterOffset(0), hCenterOffset(0), baselineOffset(0)*/
+    {
+    }
+
+    QQuickAnchors::Anchors usedAnchors;
+    QQuickAnchors::Anchors resetAnchors;
+
+    QQuickItem *fill;
+    QQuickItem *centerIn;
+
+    QDeclarativeScriptString leftScript;
+    QDeclarativeScriptString rightScript;
+    QDeclarativeScriptString topScript;
+    QDeclarativeScriptString bottomScript;
+    QDeclarativeScriptString hCenterScript;
+    QDeclarativeScriptString vCenterScript;
+    QDeclarativeScriptString baselineScript;
+
+    /*qreal leftMargin;
+    qreal rightMargin;
+    qreal topMargin;
+    qreal bottomMargin;
+    qreal margins;
+    qreal vCenterOffset;
+    qreal hCenterOffset;
+    qreal baselineOffset;*/
+};
+
+QQuickAnchorSet::QQuickAnchorSet(QObject *parent)
+  : QObject(*new QQuickAnchorSetPrivate, parent)
+{
+}
+
+QQuickAnchorSet::~QQuickAnchorSet()
+{
+}
+
+QDeclarativeScriptString QQuickAnchorSet::top() const
+{
+    Q_D(const QQuickAnchorSet);
+    return d->topScript;
+}
+
+void QQuickAnchorSet::setTop(const QDeclarativeScriptString &edge)
+{
+    Q_D(QQuickAnchorSet);
+    d->usedAnchors |= QQuickAnchors::TopAnchor;
+    d->topScript = edge;
+    if (edge.script() == QLatin1String("undefined"))
+        resetTop();
+}
+
+void QQuickAnchorSet::resetTop()
+{
+    Q_D(QQuickAnchorSet);
+    d->usedAnchors &= ~QQuickAnchors::TopAnchor;
+    d->topScript = QDeclarativeScriptString();
+    d->resetAnchors |= QQuickAnchors::TopAnchor;
+}
+
+QDeclarativeScriptString QQuickAnchorSet::bottom() const
+{
+    Q_D(const QQuickAnchorSet);
+    return d->bottomScript;
+}
+
+void QQuickAnchorSet::setBottom(const QDeclarativeScriptString &edge)
+{
+    Q_D(QQuickAnchorSet);
+    d->usedAnchors |= QQuickAnchors::BottomAnchor;
+    d->bottomScript = edge;
+    if (edge.script() == QLatin1String("undefined"))
+        resetBottom();
+}
+
+void QQuickAnchorSet::resetBottom()
+{
+    Q_D(QQuickAnchorSet);
+    d->usedAnchors &= ~QQuickAnchors::BottomAnchor;
+    d->bottomScript = QDeclarativeScriptString();
+    d->resetAnchors |= QQuickAnchors::BottomAnchor;
+}
+
+QDeclarativeScriptString QQuickAnchorSet::verticalCenter() const
+{
+    Q_D(const QQuickAnchorSet);
+    return d->vCenterScript;
+}
+
+void QQuickAnchorSet::setVerticalCenter(const QDeclarativeScriptString &edge)
+{
+    Q_D(QQuickAnchorSet);
+    d->usedAnchors |= QQuickAnchors::VCenterAnchor;
+    d->vCenterScript = edge;
+    if (edge.script() == QLatin1String("undefined"))
+        resetVerticalCenter();
+}
+
+void QQuickAnchorSet::resetVerticalCenter()
+{
+    Q_D(QQuickAnchorSet);
+    d->usedAnchors &= ~QQuickAnchors::VCenterAnchor;
+    d->vCenterScript = QDeclarativeScriptString();
+    d->resetAnchors |= QQuickAnchors::VCenterAnchor;
+}
+
+QDeclarativeScriptString QQuickAnchorSet::baseline() const
+{
+    Q_D(const QQuickAnchorSet);
+    return d->baselineScript;
+}
+
+void QQuickAnchorSet::setBaseline(const QDeclarativeScriptString &edge)
+{
+    Q_D(QQuickAnchorSet);
+    d->usedAnchors |= QQuickAnchors::BaselineAnchor;
+    d->baselineScript = edge;
+    if (edge.script() == QLatin1String("undefined"))
+        resetBaseline();
+}
+
+void QQuickAnchorSet::resetBaseline()
+{
+    Q_D(QQuickAnchorSet);
+    d->usedAnchors &= ~QQuickAnchors::BaselineAnchor;
+    d->baselineScript = QDeclarativeScriptString();
+    d->resetAnchors |= QQuickAnchors::BaselineAnchor;
+}
+
+QDeclarativeScriptString QQuickAnchorSet::left() const
+{
+    Q_D(const QQuickAnchorSet);
+    return d->leftScript;
+}
+
+void QQuickAnchorSet::setLeft(const QDeclarativeScriptString &edge)
+{
+    Q_D(QQuickAnchorSet);
+    d->usedAnchors |= QQuickAnchors::LeftAnchor;
+    d->leftScript = edge;
+    if (edge.script() == QLatin1String("undefined"))
+        resetLeft();
+}
+
+void QQuickAnchorSet::resetLeft()
+{
+    Q_D(QQuickAnchorSet);
+    d->usedAnchors &= ~QQuickAnchors::LeftAnchor;
+    d->leftScript = QDeclarativeScriptString();
+    d->resetAnchors |= QQuickAnchors::LeftAnchor;
+}
+
+QDeclarativeScriptString QQuickAnchorSet::right() const
+{
+    Q_D(const QQuickAnchorSet);
+    return d->rightScript;
+}
+
+void QQuickAnchorSet::setRight(const QDeclarativeScriptString &edge)
+{
+    Q_D(QQuickAnchorSet);
+    d->usedAnchors |= QQuickAnchors::RightAnchor;
+    d->rightScript = edge;
+    if (edge.script() == QLatin1String("undefined"))
+        resetRight();
+}
+
+void QQuickAnchorSet::resetRight()
+{
+    Q_D(QQuickAnchorSet);
+    d->usedAnchors &= ~QQuickAnchors::RightAnchor;
+    d->rightScript = QDeclarativeScriptString();
+    d->resetAnchors |= QQuickAnchors::RightAnchor;
+}
+
+QDeclarativeScriptString QQuickAnchorSet::horizontalCenter() const
+{
+    Q_D(const QQuickAnchorSet);
+    return d->hCenterScript;
+}
+
+void QQuickAnchorSet::setHorizontalCenter(const QDeclarativeScriptString &edge)
+{
+    Q_D(QQuickAnchorSet);
+    d->usedAnchors |= QQuickAnchors::HCenterAnchor;
+    d->hCenterScript = edge;
+    if (edge.script() == QLatin1String("undefined"))
+        resetHorizontalCenter();
+}
+
+void QQuickAnchorSet::resetHorizontalCenter()
+{
+    Q_D(QQuickAnchorSet);
+    d->usedAnchors &= ~QQuickAnchors::HCenterAnchor;
+    d->hCenterScript = QDeclarativeScriptString();
+    d->resetAnchors |= QQuickAnchors::HCenterAnchor;
+}
+
+QQuickItem *QQuickAnchorSet::fill() const
+{
+    Q_D(const QQuickAnchorSet);
+    return d->fill;
+}
+
+void QQuickAnchorSet::setFill(QQuickItem *f)
+{
+    Q_D(QQuickAnchorSet);
+    d->fill = f;
+}
+
+void QQuickAnchorSet::resetFill()
+{
+    setFill(0);
+}
+
+QQuickItem *QQuickAnchorSet::centerIn() const
+{
+    Q_D(const QQuickAnchorSet);
+    return d->centerIn;
+}
+
+void QQuickAnchorSet::setCenterIn(QQuickItem* c)
+{
+    Q_D(QQuickAnchorSet);
+    d->centerIn = c;
+}
+
+void QQuickAnchorSet::resetCenterIn()
+{
+    setCenterIn(0);
+}
+
+
+class QQuickAnchorChangesPrivate : public QDeclarativeStateOperationPrivate
+{
+public:
+    QQuickAnchorChangesPrivate()
+        : target(0), anchorSet(new QQuickAnchorSet),
+          leftBinding(0), rightBinding(0), hCenterBinding(0),
+          topBinding(0), bottomBinding(0), vCenterBinding(0), baselineBinding(0),
+          origLeftBinding(0), origRightBinding(0), origHCenterBinding(0),
+          origTopBinding(0), origBottomBinding(0), origVCenterBinding(0),
+          origBaselineBinding(0)
+    {
+
+    }
+    ~QQuickAnchorChangesPrivate() { delete anchorSet; }
+
+    QQuickItem *target;
+    QQuickAnchorSet *anchorSet;
+
+    QDeclarativeBinding *leftBinding;
+    QDeclarativeBinding *rightBinding;
+    QDeclarativeBinding *hCenterBinding;
+    QDeclarativeBinding *topBinding;
+    QDeclarativeBinding *bottomBinding;
+    QDeclarativeBinding *vCenterBinding;
+    QDeclarativeBinding *baselineBinding;
+
+    QDeclarativeAbstractBinding *origLeftBinding;
+    QDeclarativeAbstractBinding *origRightBinding;
+    QDeclarativeAbstractBinding *origHCenterBinding;
+    QDeclarativeAbstractBinding *origTopBinding;
+    QDeclarativeAbstractBinding *origBottomBinding;
+    QDeclarativeAbstractBinding *origVCenterBinding;
+    QDeclarativeAbstractBinding *origBaselineBinding;
+
+    QQuickAnchorLine rewindLeft;
+    QQuickAnchorLine rewindRight;
+    QQuickAnchorLine rewindHCenter;
+    QQuickAnchorLine rewindTop;
+    QQuickAnchorLine rewindBottom;
+    QQuickAnchorLine rewindVCenter;
+    QQuickAnchorLine rewindBaseline;
+
+    qreal fromX;
+    qreal fromY;
+    qreal fromWidth;
+    qreal fromHeight;
+
+    qreal toX;
+    qreal toY;
+    qreal toWidth;
+    qreal toHeight;
+
+    qreal rewindX;
+    qreal rewindY;
+    qreal rewindWidth;
+    qreal rewindHeight;
+
+    bool applyOrigLeft;
+    bool applyOrigRight;
+    bool applyOrigHCenter;
+    bool applyOrigTop;
+    bool applyOrigBottom;
+    bool applyOrigVCenter;
+    bool applyOrigBaseline;
+
+    QDeclarativeNullableValue<qreal> origWidth;
+    QDeclarativeNullableValue<qreal> origHeight;
+    qreal origX;
+    qreal origY;
+
+    QList<QDeclarativeAbstractBinding*> oldBindings;
+
+    QDeclarativeProperty leftProp;
+    QDeclarativeProperty rightProp;
+    QDeclarativeProperty hCenterProp;
+    QDeclarativeProperty topProp;
+    QDeclarativeProperty bottomProp;
+    QDeclarativeProperty vCenterProp;
+    QDeclarativeProperty baselineProp;
+};
+
+QQuickAnchorChanges::QQuickAnchorChanges(QObject *parent)
+ : QDeclarativeStateOperation(*(new QQuickAnchorChangesPrivate), parent)
+{
+}
+
+QQuickAnchorChanges::~QQuickAnchorChanges()
+{
+}
+
+QQuickAnchorChanges::ActionList QQuickAnchorChanges::actions()
+{
+    Q_D(QQuickAnchorChanges);
+    d->leftBinding = d->rightBinding = d->hCenterBinding = d->topBinding
+                   = d->bottomBinding = d->vCenterBinding = d->baselineBinding = 0;
+
+    d->leftProp = QDeclarativeProperty(d->target, QLatin1String("anchors.left"));
+    d->rightProp = QDeclarativeProperty(d->target, QLatin1String("anchors.right"));
+    d->hCenterProp = QDeclarativeProperty(d->target, QLatin1String("anchors.horizontalCenter"));
+    d->topProp = QDeclarativeProperty(d->target, QLatin1String("anchors.top"));
+    d->bottomProp = QDeclarativeProperty(d->target, QLatin1String("anchors.bottom"));
+    d->vCenterProp = QDeclarativeProperty(d->target, QLatin1String("anchors.verticalCenter"));
+    d->baselineProp = QDeclarativeProperty(d->target, QLatin1String("anchors.baseline"));
+
+    if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::LeftAnchor) {
+        d->leftBinding = new QDeclarativeBinding(d->anchorSet->d_func()->leftScript.script(), d->target, qmlContext(this));
+        d->leftBinding->setTarget(d->leftProp);
+    }
+    if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::RightAnchor) {
+        d->rightBinding = new QDeclarativeBinding(d->anchorSet->d_func()->rightScript.script(), d->target, qmlContext(this));
+        d->rightBinding->setTarget(d->rightProp);
+    }
+    if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::HCenterAnchor) {
+        d->hCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->hCenterScript.script(), d->target, qmlContext(this));
+        d->hCenterBinding->setTarget(d->hCenterProp);
+    }
+    if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::TopAnchor) {
+        d->topBinding = new QDeclarativeBinding(d->anchorSet->d_func()->topScript.script(), d->target, qmlContext(this));
+        d->topBinding->setTarget(d->topProp);
+    }
+    if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::BottomAnchor) {
+        d->bottomBinding = new QDeclarativeBinding(d->anchorSet->d_func()->bottomScript.script(), d->target, qmlContext(this));
+        d->bottomBinding->setTarget(d->bottomProp);
+    }
+    if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::VCenterAnchor) {
+        d->vCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->vCenterScript.script(), d->target, qmlContext(this));
+        d->vCenterBinding->setTarget(d->vCenterProp);
+    }
+    if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::BaselineAnchor) {
+        d->baselineBinding = new QDeclarativeBinding(d->anchorSet->d_func()->baselineScript.script(), d->target, qmlContext(this));
+        d->baselineBinding->setTarget(d->baselineProp);
+    }
+
+    QDeclarativeAction a;
+    a.event = this;
+    return ActionList() << a;
+}
+
+QQuickAnchorSet *QQuickAnchorChanges::anchors()
+{
+    Q_D(QQuickAnchorChanges);
+    return d->anchorSet;
+}
+
+QQuickItem *QQuickAnchorChanges::object() const
+{
+    Q_D(const QQuickAnchorChanges);
+    return d->target;
+}
+
+void QQuickAnchorChanges::setObject(QQuickItem *target)
+{
+    Q_D(QQuickAnchorChanges);
+    d->target = target;
+}
+
+void QQuickAnchorChanges::execute(Reason reason)
+{
+    Q_D(QQuickAnchorChanges);
+    if (!d->target)
+        return;
+
+    QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
+    //incorporate any needed "reverts"
+    if (d->applyOrigLeft) {
+        if (!d->origLeftBinding)
+            targetPrivate->anchors()->resetLeft();
+        QDeclarativePropertyPrivate::setBinding(d->leftProp, d->origLeftBinding);
+    }
+    if (d->applyOrigRight) {
+        if (!d->origRightBinding)
+            targetPrivate->anchors()->resetRight();
+        QDeclarativePropertyPrivate::setBinding(d->rightProp, d->origRightBinding);
+    }
+    if (d->applyOrigHCenter) {
+        if (!d->origHCenterBinding)
+            targetPrivate->anchors()->resetHorizontalCenter();
+        QDeclarativePropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding);
+    }
+    if (d->applyOrigTop) {
+        if (!d->origTopBinding)
+            targetPrivate->anchors()->resetTop();
+        QDeclarativePropertyPrivate::setBinding(d->topProp, d->origTopBinding);
+    }
+    if (d->applyOrigBottom) {
+        if (!d->origBottomBinding)
+            targetPrivate->anchors()->resetBottom();
+        QDeclarativePropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding);
+    }
+    if (d->applyOrigVCenter) {
+        if (!d->origVCenterBinding)
+            targetPrivate->anchors()->resetVerticalCenter();
+        QDeclarativePropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding);
+    }
+    if (d->applyOrigBaseline) {
+        if (!d->origBaselineBinding)
+            targetPrivate->anchors()->resetBaseline();
+        QDeclarativePropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding);
+    }
+
+    //destroy old bindings
+    if (reason == ActualChange) {
+        for (int i = 0; i < d->oldBindings.size(); ++i) {
+            QDeclarativeAbstractBinding *binding = d->oldBindings.at(i);
+            if (binding)
+                binding->destroy();
+        }
+        d->oldBindings.clear();
+    }
+
+    //reset any anchors that have been specified as "undefined"
+    if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::LeftAnchor) {
+        targetPrivate->anchors()->resetLeft();
+        QDeclarativePropertyPrivate::setBinding(d->leftProp, 0);
+    }
+    if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::RightAnchor) {
+        targetPrivate->anchors()->resetRight();
+        QDeclarativePropertyPrivate::setBinding(d->rightProp, 0);
+    }
+    if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::HCenterAnchor) {
+        targetPrivate->anchors()->resetHorizontalCenter();
+        QDeclarativePropertyPrivate::setBinding(d->hCenterProp, 0);
+    }
+    if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::TopAnchor) {
+        targetPrivate->anchors()->resetTop();
+        QDeclarativePropertyPrivate::setBinding(d->topProp, 0);
+    }
+    if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::BottomAnchor) {
+        targetPrivate->anchors()->resetBottom();
+        QDeclarativePropertyPrivate::setBinding(d->bottomProp, 0);
+    }
+    if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::VCenterAnchor) {
+        targetPrivate->anchors()->resetVerticalCenter();
+        QDeclarativePropertyPrivate::setBinding(d->vCenterProp, 0);
+    }
+    if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::BaselineAnchor) {
+        targetPrivate->anchors()->resetBaseline();
+        QDeclarativePropertyPrivate::setBinding(d->baselineProp, 0);
+    }
+
+    //set any anchors that have been specified
+    if (d->leftBinding)
+        QDeclarativePropertyPrivate::setBinding(d->leftBinding->property(), d->leftBinding);
+    if (d->rightBinding)
+        QDeclarativePropertyPrivate::setBinding(d->rightBinding->property(), d->rightBinding);
+    if (d->hCenterBinding)
+        QDeclarativePropertyPrivate::setBinding(d->hCenterBinding->property(), d->hCenterBinding);
+    if (d->topBinding)
+        QDeclarativePropertyPrivate::setBinding(d->topBinding->property(), d->topBinding);
+    if (d->bottomBinding)
+        QDeclarativePropertyPrivate::setBinding(d->bottomBinding->property(), d->bottomBinding);
+    if (d->vCenterBinding)
+        QDeclarativePropertyPrivate::setBinding(d->vCenterBinding->property(), d->vCenterBinding);
+    if (d->baselineBinding)
+        QDeclarativePropertyPrivate::setBinding(d->baselineBinding->property(), d->baselineBinding);
+}
+
+bool QQuickAnchorChanges::isReversable()
+{
+    return true;
+}
+
+void QQuickAnchorChanges::reverse(Reason reason)
+{
+    Q_D(QQuickAnchorChanges);
+    if (!d->target)
+        return;
+
+    QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
+    //reset any anchors set by the state
+    if (d->leftBinding) {
+        targetPrivate->anchors()->resetLeft();
+        QDeclarativePropertyPrivate::setBinding(d->leftBinding->property(), 0);
+        if (reason == ActualChange) {
+            d->leftBinding->destroy(); d->leftBinding = 0;
+        }
+    }
+    if (d->rightBinding) {
+        targetPrivate->anchors()->resetRight();
+        QDeclarativePropertyPrivate::setBinding(d->rightBinding->property(), 0);
+        if (reason == ActualChange) {
+            d->rightBinding->destroy(); d->rightBinding = 0;
+        }
+    }
+    if (d->hCenterBinding) {
+        targetPrivate->anchors()->resetHorizontalCenter();
+        QDeclarativePropertyPrivate::setBinding(d->hCenterBinding->property(), 0);
+        if (reason == ActualChange) {
+            d->hCenterBinding->destroy(); d->hCenterBinding = 0;
+        }
+    }
+    if (d->topBinding) {
+        targetPrivate->anchors()->resetTop();
+        QDeclarativePropertyPrivate::setBinding(d->topBinding->property(), 0);
+        if (reason == ActualChange) {
+            d->topBinding->destroy(); d->topBinding = 0;
+        }
+    }
+    if (d->bottomBinding) {
+        targetPrivate->anchors()->resetBottom();
+        QDeclarativePropertyPrivate::setBinding(d->bottomBinding->property(), 0);
+        if (reason == ActualChange) {
+            d->bottomBinding->destroy(); d->bottomBinding = 0;
+        }
+    }
+    if (d->vCenterBinding) {
+        targetPrivate->anchors()->resetVerticalCenter();
+        QDeclarativePropertyPrivate::setBinding(d->vCenterBinding->property(), 0);
+        if (reason == ActualChange) {
+            d->vCenterBinding->destroy(); d->vCenterBinding = 0;
+        }
+    }
+    if (d->baselineBinding) {
+        targetPrivate->anchors()->resetBaseline();
+        QDeclarativePropertyPrivate::setBinding(d->baselineBinding->property(), 0);
+        if (reason == ActualChange) {
+            d->baselineBinding->destroy(); d->baselineBinding = 0;
+        }
+    }
+
+    //restore previous anchors
+    if (d->origLeftBinding)
+        QDeclarativePropertyPrivate::setBinding(d->leftProp, d->origLeftBinding);
+    if (d->origRightBinding)
+        QDeclarativePropertyPrivate::setBinding(d->rightProp, d->origRightBinding);
+    if (d->origHCenterBinding)
+        QDeclarativePropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding);
+    if (d->origTopBinding)
+        QDeclarativePropertyPrivate::setBinding(d->topProp, d->origTopBinding);
+    if (d->origBottomBinding)
+        QDeclarativePropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding);
+    if (d->origVCenterBinding)
+        QDeclarativePropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding);
+    if (d->origBaselineBinding)
+        QDeclarativePropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding);
+
+    //restore any absolute geometry changed by the state's anchors
+    QQuickAnchors::Anchors stateVAnchors = d->anchorSet->d_func()->usedAnchors & QQuickAnchors::Vertical_Mask;
+    QQuickAnchors::Anchors origVAnchors = targetPrivate->anchors()->usedAnchors() & QQuickAnchors::Vertical_Mask;
+    QQuickAnchors::Anchors stateHAnchors = d->anchorSet->d_func()->usedAnchors & QQuickAnchors::Horizontal_Mask;
+    QQuickAnchors::Anchors origHAnchors = targetPrivate->anchors()->usedAnchors() & QQuickAnchors::Horizontal_Mask;
+
+    bool stateSetWidth = (stateHAnchors &&
+                          stateHAnchors != QQuickAnchors::LeftAnchor &&
+                          stateHAnchors != QQuickAnchors::RightAnchor &&
+                          stateHAnchors != QQuickAnchors::HCenterAnchor);
+    bool origSetWidth = (origHAnchors &&
+                         origHAnchors != QQuickAnchors::LeftAnchor &&
+                         origHAnchors != QQuickAnchors::RightAnchor &&
+                         origHAnchors != QQuickAnchors::HCenterAnchor);
+    if (d->origWidth.isValid() && stateSetWidth && !origSetWidth)
+        d->target->setWidth(d->origWidth.value);
+
+    bool stateSetHeight = (stateVAnchors &&
+                           stateVAnchors != QQuickAnchors::TopAnchor &&
+                           stateVAnchors != QQuickAnchors::BottomAnchor &&
+                           stateVAnchors != QQuickAnchors::VCenterAnchor &&
+                           stateVAnchors != QQuickAnchors::BaselineAnchor);
+    bool origSetHeight = (origVAnchors &&
+                          origVAnchors != QQuickAnchors::TopAnchor &&
+                          origVAnchors != QQuickAnchors::BottomAnchor &&
+                          origVAnchors != QQuickAnchors::VCenterAnchor &&
+                          origVAnchors != QQuickAnchors::BaselineAnchor);
+    if (d->origHeight.isValid() && stateSetHeight && !origSetHeight)
+        d->target->setHeight(d->origHeight.value);
+
+    if (stateHAnchors && !origHAnchors)
+        d->target->setX(d->origX);
+
+    if (stateVAnchors && !origVAnchors)
+        d->target->setY(d->origY);
+}
+
+QString QQuickAnchorChanges::typeName() const
+{
+    return QLatin1String("AnchorChanges");
+}
+
+QList<QDeclarativeAction> QQuickAnchorChanges::additionalActions()
+{
+    Q_D(QQuickAnchorChanges);
+    QList<QDeclarativeAction> extra;
+
+    QQuickAnchors::Anchors combined = d->anchorSet->d_func()->usedAnchors | d->anchorSet->d_func()->resetAnchors;
+    bool hChange = combined & QQuickAnchors::Horizontal_Mask;
+    bool vChange = combined & QQuickAnchors::Vertical_Mask;
+
+    if (d->target) {
+        QDeclarativeAction a;
+        if (hChange && d->fromX != d->toX) {
+            a.property = QDeclarativeProperty(d->target, QLatin1String("x"));
+            a.toValue = d->toX;
+            extra << a;
+        }
+        if (vChange && d->fromY != d->toY) {
+            a.property = QDeclarativeProperty(d->target, QLatin1String("y"));
+            a.toValue = d->toY;
+            extra << a;
+        }
+        if (hChange && d->fromWidth != d->toWidth) {
+            a.property = QDeclarativeProperty(d->target, QLatin1String("width"));
+            a.toValue = d->toWidth;
+            extra << a;
+        }
+        if (vChange && d->fromHeight != d->toHeight) {
+            a.property = QDeclarativeProperty(d->target, QLatin1String("height"));
+            a.toValue = d->toHeight;
+            extra << a;
+        }
+    }
+
+    return extra;
+}
+
+bool QQuickAnchorChanges::changesBindings()
+{
+    return true;
+}
+
+void QQuickAnchorChanges::saveOriginals()
+{
+    Q_D(QQuickAnchorChanges);
+    if (!d->target)
+        return;
+
+    d->origLeftBinding = QDeclarativePropertyPrivate::binding(d->leftProp);
+    d->origRightBinding = QDeclarativePropertyPrivate::binding(d->rightProp);
+    d->origHCenterBinding = QDeclarativePropertyPrivate::binding(d->hCenterProp);
+    d->origTopBinding = QDeclarativePropertyPrivate::binding(d->topProp);
+    d->origBottomBinding = QDeclarativePropertyPrivate::binding(d->bottomProp);
+    d->origVCenterBinding = QDeclarativePropertyPrivate::binding(d->vCenterProp);
+    d->origBaselineBinding = QDeclarativePropertyPrivate::binding(d->baselineProp);
+
+    QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
+    if (targetPrivate->widthValid)
+        d->origWidth = d->target->width();
+    if (targetPrivate->heightValid)
+        d->origHeight = d->target->height();
+    d->origX = d->target->x();
+    d->origY = d->target->y();
+
+    d->applyOrigLeft = d->applyOrigRight = d->applyOrigHCenter = d->applyOrigTop
+      = d->applyOrigBottom = d->applyOrigVCenter = d->applyOrigBaseline = false;
+
+    saveCurrentValues();
+}
+
+void QQuickAnchorChanges::copyOriginals(QDeclarativeActionEvent *other)
+{
+    Q_D(QQuickAnchorChanges);
+    QQuickAnchorChanges *ac = static_cast<QQuickAnchorChanges*>(other);
+    QQuickAnchorChangesPrivate *acp = ac->d_func();
+
+    QQuickAnchors::Anchors combined = acp->anchorSet->d_func()->usedAnchors |
+                                            acp->anchorSet->d_func()->resetAnchors;
+
+    //probably also need to revert some things
+    d->applyOrigLeft = (combined & QQuickAnchors::LeftAnchor);
+    d->applyOrigRight = (combined & QQuickAnchors::RightAnchor);
+    d->applyOrigHCenter = (combined & QQuickAnchors::HCenterAnchor);
+    d->applyOrigTop = (combined & QQuickAnchors::TopAnchor);
+    d->applyOrigBottom = (combined & QQuickAnchors::BottomAnchor);
+    d->applyOrigVCenter = (combined & QQuickAnchors::VCenterAnchor);
+    d->applyOrigBaseline = (combined & QQuickAnchors::BaselineAnchor);
+
+    d->origLeftBinding = acp->origLeftBinding;
+    d->origRightBinding = acp->origRightBinding;
+    d->origHCenterBinding = acp->origHCenterBinding;
+    d->origTopBinding = acp->origTopBinding;
+    d->origBottomBinding = acp->origBottomBinding;
+    d->origVCenterBinding = acp->origVCenterBinding;
+    d->origBaselineBinding = acp->origBaselineBinding;
+
+    d->origWidth = acp->origWidth;
+    d->origHeight = acp->origHeight;
+    d->origX = acp->origX;
+    d->origY = acp->origY;
+
+    d->oldBindings.clear();
+    d->oldBindings << acp->leftBinding << acp->rightBinding << acp->hCenterBinding
+                << acp->topBinding << acp->bottomBinding << acp->baselineBinding;
+
+    saveCurrentValues();
+}
+
+void QQuickAnchorChanges::clearBindings()
+{
+    Q_D(QQuickAnchorChanges);
+    if (!d->target)
+        return;
+
+    //### should this (saving "from" values) be moved to saveCurrentValues()?
+    d->fromX = d->target->x();
+    d->fromY = d->target->y();
+    d->fromWidth = d->target->width();
+    d->fromHeight = d->target->height();
+
+    QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
+    //reset any anchors with corresponding reverts
+    //reset any anchors that have been specified as "undefined"
+    //reset any anchors that we'll be setting in the state
+    QQuickAnchors::Anchors combined = d->anchorSet->d_func()->resetAnchors |
+                                            d->anchorSet->d_func()->usedAnchors;
+    if (d->applyOrigLeft || (combined & QQuickAnchors::LeftAnchor)) {
+        targetPrivate->anchors()->resetLeft();
+        QDeclarativePropertyPrivate::setBinding(d->leftProp, 0);
+    }
+    if (d->applyOrigRight || (combined & QQuickAnchors::RightAnchor)) {
+        targetPrivate->anchors()->resetRight();
+        QDeclarativePropertyPrivate::setBinding(d->rightProp, 0);
+    }
+    if (d->applyOrigHCenter || (combined & QQuickAnchors::HCenterAnchor)) {
+        targetPrivate->anchors()->resetHorizontalCenter();
+        QDeclarativePropertyPrivate::setBinding(d->hCenterProp, 0);
+    }
+    if (d->applyOrigTop || (combined & QQuickAnchors::TopAnchor)) {
+        targetPrivate->anchors()->resetTop();
+        QDeclarativePropertyPrivate::setBinding(d->topProp, 0);
+    }
+    if (d->applyOrigBottom || (combined & QQuickAnchors::BottomAnchor)) {
+        targetPrivate->anchors()->resetBottom();
+        QDeclarativePropertyPrivate::setBinding(d->bottomProp, 0);
+    }
+    if (d->applyOrigVCenter || (combined & QQuickAnchors::VCenterAnchor)) {
+        targetPrivate->anchors()->resetVerticalCenter();
+        QDeclarativePropertyPrivate::setBinding(d->vCenterProp, 0);
+    }
+    if (d->applyOrigBaseline || (combined & QQuickAnchors::BaselineAnchor)) {
+        targetPrivate->anchors()->resetBaseline();
+        QDeclarativePropertyPrivate::setBinding(d->baselineProp, 0);
+    }
+}
+
+bool QQuickAnchorChanges::override(QDeclarativeActionEvent*other)
+{
+    if (other->typeName() != QLatin1String("AnchorChanges"))
+        return false;
+    if (static_cast<QDeclarativeActionEvent*>(this) == other)
+        return true;
+    if (static_cast<QQuickAnchorChanges*>(other)->object() == object())
+        return true;
+    return false;
+}
+
+void QQuickAnchorChanges::rewind()
+{
+    Q_D(QQuickAnchorChanges);
+    if (!d->target)
+        return;
+
+    QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
+
+    //restore previous values (but not previous bindings, i.e. anchors)
+    d->target->setX(d->rewindX);
+    d->target->setY(d->rewindY);
+    if (targetPrivate->widthValid) {
+        d->target->setWidth(d->rewindWidth);
+    }
+    if (targetPrivate->heightValid) {
+        d->target->setHeight(d->rewindHeight);
+    }
+}
+
+void QQuickAnchorChanges::saveCurrentValues()
+{
+    Q_D(QQuickAnchorChanges);
+    if (!d->target)
+        return;
+
+    QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
+    d->rewindLeft = targetPrivate->anchors()->left();
+    d->rewindRight = targetPrivate->anchors()->right();
+    d->rewindHCenter = targetPrivate->anchors()->horizontalCenter();
+    d->rewindTop = targetPrivate->anchors()->top();
+    d->rewindBottom = targetPrivate->anchors()->bottom();
+    d->rewindVCenter = targetPrivate->anchors()->verticalCenter();
+    d->rewindBaseline = targetPrivate->anchors()->baseline();
+
+    d->rewindX = d->target->x();
+    d->rewindY = d->target->y();
+    d->rewindWidth = d->target->width();
+    d->rewindHeight = d->target->height();
+}
+
+void QQuickAnchorChanges::saveTargetValues()
+{
+    Q_D(QQuickAnchorChanges);
+    if (!d->target)
+        return;
+
+    d->toX = d->target->x();
+    d->toY = d->target->y();
+    d->toWidth = d->target->width();
+    d->toHeight = d->target->height();
+}
+
+#include <moc_qquickstateoperations_p.cpp>
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/items/qquickstateoperations_p.h b/src/declarative/items/qquickstateoperations_p.h
new file mode 100644 (file)
index 0000000..7844c6d
--- /dev/null
@@ -0,0 +1,275 @@
+// Commit: 84c47bbb133304d7ef35642fa1fbb17619d4a43d
+/****************************************************************************
+**
+** 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 QQUICKSTATEOPERATIONS_P_H
+#define QQUICKSTATEOPERATIONS_P_H
+
+#include "qquickitem.h"
+#include "qquickanchors_p.h"
+
+#include <private/qdeclarativestate_p.h>
+
+#include <QtDeclarative/qdeclarativescriptstring.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickParentChangePrivate;
+class Q_AUTOTEST_EXPORT QQuickParentChange : public QDeclarativeStateOperation, public QDeclarativeActionEvent
+{
+    Q_OBJECT
+    Q_DECLARE_PRIVATE(QQuickParentChange)
+
+    Q_PROPERTY(QQuickItem *target READ object WRITE setObject)
+    Q_PROPERTY(QQuickItem *parent READ parent WRITE setParent)
+    Q_PROPERTY(QDeclarativeScriptString x READ x WRITE setX)
+    Q_PROPERTY(QDeclarativeScriptString y READ y WRITE setY)
+    Q_PROPERTY(QDeclarativeScriptString width READ width WRITE setWidth)
+    Q_PROPERTY(QDeclarativeScriptString height READ height WRITE setHeight)
+    Q_PROPERTY(QDeclarativeScriptString scale READ scale WRITE setScale)
+    Q_PROPERTY(QDeclarativeScriptString rotation READ rotation WRITE setRotation)
+public:
+    QQuickParentChange(QObject *parent=0);
+    ~QQuickParentChange();
+
+    QQuickItem *object() const;
+    void setObject(QQuickItem *);
+
+    QQuickItem *parent() const;
+    void setParent(QQuickItem *);
+
+    QQuickItem *originalParent() const;
+
+    QDeclarativeScriptString x() const;
+    void setX(QDeclarativeScriptString x);
+    bool xIsSet() const;
+
+    QDeclarativeScriptString y() const;
+    void setY(QDeclarativeScriptString y);
+    bool yIsSet() const;
+
+    QDeclarativeScriptString width() const;
+    void setWidth(QDeclarativeScriptString width);
+    bool widthIsSet() const;
+
+    QDeclarativeScriptString height() const;
+    void setHeight(QDeclarativeScriptString height);
+    bool heightIsSet() const;
+
+    QDeclarativeScriptString scale() const;
+    void setScale(QDeclarativeScriptString scale);
+    bool scaleIsSet() const;
+
+    QDeclarativeScriptString rotation() const;
+    void setRotation(QDeclarativeScriptString rotation);
+    bool rotationIsSet() const;
+
+    virtual ActionList actions();
+
+    virtual void saveOriginals();
+    //virtual void copyOriginals(QDeclarativeActionEvent*);
+    virtual void execute(Reason reason = ActualChange);
+    virtual bool isReversable();
+    virtual void reverse(Reason reason = ActualChange);
+    virtual QString typeName() const;
+    virtual bool override(QDeclarativeActionEvent*other);
+    virtual void rewind();
+    virtual void saveCurrentValues();
+};
+
+class QQuickAnchorChanges;
+class QQuickAnchorSetPrivate;
+class Q_AUTOTEST_EXPORT QQuickAnchorSet : public QObject
+{
+    Q_OBJECT
+
+    Q_PROPERTY(QDeclarativeScriptString left READ left WRITE setLeft RESET resetLeft)
+    Q_PROPERTY(QDeclarativeScriptString right READ right WRITE setRight RESET resetRight)
+    Q_PROPERTY(QDeclarativeScriptString horizontalCenter READ horizontalCenter WRITE setHorizontalCenter RESET resetHorizontalCenter)
+    Q_PROPERTY(QDeclarativeScriptString top READ top WRITE setTop RESET resetTop)
+    Q_PROPERTY(QDeclarativeScriptString bottom READ bottom WRITE setBottom RESET resetBottom)
+    Q_PROPERTY(QDeclarativeScriptString verticalCenter READ verticalCenter WRITE setVerticalCenter RESET resetVerticalCenter)
+    Q_PROPERTY(QDeclarativeScriptString baseline READ baseline WRITE setBaseline RESET resetBaseline)
+    //Q_PROPERTY(QQuickItem *fill READ fill WRITE setFill RESET resetFill)
+    //Q_PROPERTY(QQuickItem *centerIn READ centerIn WRITE setCenterIn RESET resetCenterIn)
+
+    /*Q_PROPERTY(qreal margins READ margins WRITE setMargins NOTIFY marginsChanged)
+    Q_PROPERTY(qreal leftMargin READ leftMargin WRITE setLeftMargin NOTIFY leftMarginChanged)
+    Q_PROPERTY(qreal rightMargin READ rightMargin WRITE setRightMargin NOTIFY rightMarginChanged)
+    Q_PROPERTY(qreal horizontalCenterOffset READ horizontalCenterOffset WRITE setHorizontalCenterOffset NOTIFY horizontalCenterOffsetChanged())
+    Q_PROPERTY(qreal topMargin READ topMargin WRITE setTopMargin NOTIFY topMarginChanged)
+    Q_PROPERTY(qreal bottomMargin READ bottomMargin WRITE setBottomMargin NOTIFY bottomMarginChanged)
+    Q_PROPERTY(qreal verticalCenterOffset READ verticalCenterOffset WRITE setVerticalCenterOffset NOTIFY verticalCenterOffsetChanged())
+    Q_PROPERTY(qreal baselineOffset READ baselineOffset WRITE setBaselineOffset NOTIFY baselineOffsetChanged())*/
+
+public:
+    QQuickAnchorSet(QObject *parent=0);
+    virtual ~QQuickAnchorSet();
+
+    QDeclarativeScriptString left() const;
+    void setLeft(const QDeclarativeScriptString &edge);
+    void resetLeft();
+
+    QDeclarativeScriptString right() const;
+    void setRight(const QDeclarativeScriptString &edge);
+    void resetRight();
+
+    QDeclarativeScriptString horizontalCenter() const;
+    void setHorizontalCenter(const QDeclarativeScriptString &edge);
+    void resetHorizontalCenter();
+
+    QDeclarativeScriptString top() const;
+    void setTop(const QDeclarativeScriptString &edge);
+    void resetTop();
+
+    QDeclarativeScriptString bottom() const;
+    void setBottom(const QDeclarativeScriptString &edge);
+    void resetBottom();
+
+    QDeclarativeScriptString verticalCenter() const;
+    void setVerticalCenter(const QDeclarativeScriptString &edge);
+    void resetVerticalCenter();
+
+    QDeclarativeScriptString baseline() const;
+    void setBaseline(const QDeclarativeScriptString &edge);
+    void resetBaseline();
+
+    QQuickItem *fill() const;
+    void setFill(QQuickItem *);
+    void resetFill();
+
+    QQuickItem *centerIn() const;
+    void setCenterIn(QQuickItem *);
+    void resetCenterIn();
+
+    /*qreal leftMargin() const;
+    void setLeftMargin(qreal);
+
+    qreal rightMargin() const;
+    void setRightMargin(qreal);
+
+    qreal horizontalCenterOffset() const;
+    void setHorizontalCenterOffset(qreal);
+
+    qreal topMargin() const;
+    void setTopMargin(qreal);
+
+    qreal bottomMargin() const;
+    void setBottomMargin(qreal);
+
+    qreal margins() const;
+    void setMargins(qreal);
+
+    qreal verticalCenterOffset() const;
+    void setVerticalCenterOffset(qreal);
+
+    qreal baselineOffset() const;
+    void setBaselineOffset(qreal);*/
+
+    QQuickAnchors::Anchors usedAnchors() const;
+
+/*Q_SIGNALS:
+    void leftMarginChanged();
+    void rightMarginChanged();
+    void topMarginChanged();
+    void bottomMarginChanged();
+    void marginsChanged();
+    void verticalCenterOffsetChanged();
+    void horizontalCenterOffsetChanged();
+    void baselineOffsetChanged();*/
+
+private:
+    friend class QQuickAnchorChanges;
+    Q_DISABLE_COPY(QQuickAnchorSet)
+    Q_DECLARE_PRIVATE(QQuickAnchorSet)
+};
+
+class QQuickAnchorChangesPrivate;
+class Q_AUTOTEST_EXPORT QQuickAnchorChanges : public QDeclarativeStateOperation, public QDeclarativeActionEvent
+{
+    Q_OBJECT
+    Q_DECLARE_PRIVATE(QQuickAnchorChanges)
+
+    Q_PROPERTY(QQuickItem *target READ object WRITE setObject)
+    Q_PROPERTY(QQuickAnchorSet *anchors READ anchors CONSTANT)
+
+public:
+    QQuickAnchorChanges(QObject *parent=0);
+    ~QQuickAnchorChanges();
+
+    virtual ActionList actions();
+
+    QQuickAnchorSet *anchors();
+
+    QQuickItem *object() const;
+    void setObject(QQuickItem *);
+
+    virtual void execute(Reason reason = ActualChange);
+    virtual bool isReversable();
+    virtual void reverse(Reason reason = ActualChange);
+    virtual QString typeName() const;
+    virtual bool override(QDeclarativeActionEvent*other);
+    virtual bool changesBindings();
+    virtual void saveOriginals();
+    virtual bool needsCopy() { return true; }
+    virtual void copyOriginals(QDeclarativeActionEvent*);
+    virtual void clearBindings();
+    virtual void rewind();
+    virtual void saveCurrentValues();
+
+    QList<QDeclarativeAction> additionalActions();
+    virtual void saveTargetValues();
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickParentChange)
+QML_DECLARE_TYPE(QQuickAnchorSet)
+QML_DECLARE_TYPE(QQuickAnchorChanges)
+
+QT_END_HEADER
+
+#endif // QQUICKSTATEOPERATIONS_P_H
+
diff --git a/src/declarative/items/qquicktext.cpp b/src/declarative/items/qquicktext.cpp
new file mode 100644 (file)
index 0000000..bf736e6
--- /dev/null
@@ -0,0 +1,1938 @@
+/****************************************************************************
+**
+** 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 "qquicktext_p.h"
+#include "qquicktext_p_p.h"
+
+#include <private/qsgdistancefieldglyphcache_p.h>
+#include <private/qsgcontext_p.h>
+#include <private/qsgadaptationlayer_p.h>
+#include "qquicktextnode_p.h"
+#include "qquickimage_p_p.h"
+#include <private/qsgtexture_p.h>
+
+#include <QtDeclarative/qdeclarativeinfo.h>
+#include <QtGui/qevent.h>
+#include <QtGui/qabstracttextdocumentlayout.h>
+#include <QtGui/qpainter.h>
+#include <QtGui/qtextdocument.h>
+#include <QtGui/qtextobject.h>
+#include <QtGui/qtextcursor.h>
+#include <QtGui/qguiapplication.h>
+
+#include <private/qdeclarativestyledtext_p.h>
+#include <private/qdeclarativepixmapcache_p.h>
+
+#include <qmath.h>
+#include <limits.h>
+
+QT_BEGIN_NAMESPACE
+
+extern Q_GUI_EXPORT bool qt_applefontsmoothing_enabled;
+
+class QQuickTextDocumentWithImageResources : public QTextDocument {
+    Q_OBJECT
+
+public:
+    QQuickTextDocumentWithImageResources(QQuickText *parent);
+    virtual ~QQuickTextDocumentWithImageResources();
+
+    void setText(const QString &);
+    int resourcesLoading() const { return outstanding; }
+
+protected:
+    QVariant loadResource(int type, const QUrl &name);
+
+private slots:
+    void requestFinished();
+
+private:
+    QHash<QUrl, QDeclarativePixmap *> m_resources;
+
+    int outstanding;
+    static QSet<QUrl> errors;
+};
+
+DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
+DEFINE_BOOL_CONFIG_OPTION(enableImageCache, QML_ENABLE_TEXT_IMAGE_CACHE);
+
+QString QQuickTextPrivate::elideChar = QString(0x2026);
+
+QQuickTextPrivate::QQuickTextPrivate()
+: color((QRgb)0), style(QQuickText::Normal), hAlign(QQuickText::AlignLeft),
+  vAlign(QQuickText::AlignTop), elideMode(QQuickText::ElideNone),
+  format(QQuickText::AutoText), wrapMode(QQuickText::NoWrap), lineHeight(1),
+  lineHeightMode(QQuickText::ProportionalHeight), lineCount(1), maximumLineCount(INT_MAX),
+  maximumLineCountValid(false),
+  texture(0),
+  imageCacheDirty(false), updateOnComponentComplete(true),
+  richText(false), styledText(false), singleline(false), cacheAllTextAsImage(true), internalWidthUpdate(false),
+  requireImplicitWidth(false), truncated(false), hAlignImplicit(true), rightToLeftText(false),
+  layoutTextElided(false), richTextAsImage(false), textureImageCacheDirty(false), textHasChanged(true),
+  naturalWidth(0), doc(0), textLine(0), nodeType(NodeIsNull)
+
+#if defined(Q_OS_MAC)
+, layoutThread(0), paintingThread(0)
+#endif
+
+{
+    cacheAllTextAsImage = enableImageCache();
+}
+
+void QQuickTextPrivate::init()
+{
+    Q_Q(QQuickText);
+    q->setAcceptedMouseButtons(Qt::LeftButton);
+    q->setFlag(QQuickItem::ItemHasContents);
+}
+
+QQuickTextDocumentWithImageResources::QQuickTextDocumentWithImageResources(QQuickText *parent)
+: QTextDocument(parent), outstanding(0)
+{
+    setUndoRedoEnabled(false);
+}
+
+QQuickTextDocumentWithImageResources::~QQuickTextDocumentWithImageResources()
+{
+    if (!m_resources.isEmpty())
+        qDeleteAll(m_resources);
+}
+
+QVariant QQuickTextDocumentWithImageResources::loadResource(int type, const QUrl &name)
+{
+    QDeclarativeContext *context = qmlContext(parent());
+    QUrl url = context->resolvedUrl(name);
+
+    if (type == QTextDocument::ImageResource) {
+        QHash<QUrl, QDeclarativePixmap *>::Iterator iter = m_resources.find(url);
+
+        if (iter == m_resources.end()) {
+            QDeclarativePixmap *p = new QDeclarativePixmap(context->engine(), url);
+            iter = m_resources.insert(name, p);
+
+            if (p->isLoading()) {
+                p->connectFinished(this, SLOT(requestFinished()));
+                outstanding++;
+            }
+        }
+
+        QDeclarativePixmap *p = *iter;
+        if (p->isReady()) {
+            return p->pixmap();
+        } else if (p->isError()) {
+            if (!errors.contains(url)) {
+                errors.insert(url);
+                qmlInfo(parent()) << p->error();
+            }
+        }
+    }
+
+    return QTextDocument::loadResource(type,url); // The *resolved* URL
+}
+
+void QQuickTextDocumentWithImageResources::requestFinished()
+{
+    outstanding--;
+    if (outstanding == 0) {
+        QQuickText *textItem = static_cast<QQuickText*>(parent());
+        QString text = textItem->text();
+#ifndef QT_NO_TEXTHTMLPARSER
+        setHtml(text);
+#else
+        setPlainText(text);
+#endif
+        QQuickTextPrivate *d = QQuickTextPrivate::get(textItem);
+        d->updateLayout();
+    }
+}
+
+void QQuickTextDocumentWithImageResources::setText(const QString &text)
+{
+    if (!m_resources.isEmpty()) {
+        qDeleteAll(m_resources);
+        m_resources.clear();
+        outstanding = 0;
+    }
+
+#ifndef QT_NO_TEXTHTMLPARSER
+    setHtml(text);
+#else
+    setPlainText(text);
+#endif
+}
+
+QSet<QUrl> QQuickTextDocumentWithImageResources::errors;
+
+QQuickTextPrivate::~QQuickTextPrivate()
+{
+    delete textLine; textLine = 0;
+}
+
+qreal QQuickTextPrivate::getImplicitWidth() const
+{
+    if (!requireImplicitWidth) {
+        // We don't calculate implicitWidth unless it is required.
+        // We need to force a size update now to ensure implicitWidth is calculated
+        QQuickTextPrivate *me = const_cast<QQuickTextPrivate*>(this);
+        me->requireImplicitWidth = true;
+        me->updateSize();
+    }
+    return implicitWidth;
+}
+
+void QQuickTextPrivate::updateLayout()
+{
+    Q_Q(QQuickText);
+    if (!q->isComponentComplete()) {
+        updateOnComponentComplete = true;
+        return;
+    }
+
+    layoutTextElided = false;
+    // Setup instance of QTextLayout for all cases other than richtext
+    if (!richText) {
+        layout.clearLayout();
+        layout.setFont(font);
+        if (!styledText) {
+            QString tmp = text;
+            tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
+            singleline = !tmp.contains(QChar::LineSeparator);
+            if (singleline && !maximumLineCountValid && elideMode != QQuickText::ElideNone && q->widthValid()) {
+                QFontMetrics fm(font);
+                tmp = fm.elidedText(tmp,(Qt::TextElideMode)elideMode,q->width());
+                if (tmp != text) {
+                    layoutTextElided = true;
+                    if (!truncated) {
+                        truncated = true;
+                        emit q->truncatedChanged();
+                    }
+                }
+            }
+            layout.setText(tmp);
+        } else {
+            singleline = false;
+            if (textHasChanged) {
+                QDeclarativeStyledText::parse(text, layout);
+                textHasChanged = false;
+            }
+        }
+    } else {
+        ensureDoc();
+        QTextBlockFormat::LineHeightTypes type;
+        type = lineHeightMode == QQuickText::FixedHeight ? QTextBlockFormat::FixedHeight : QTextBlockFormat::ProportionalHeight;
+        QTextBlockFormat blockFormat;
+        blockFormat.setLineHeight((lineHeightMode == QQuickText::FixedHeight ? lineHeight : lineHeight * 100), type);
+        for (QTextBlock it = doc->begin(); it != doc->end(); it = it.next()) {
+            QTextCursor cursor(it);
+            cursor.mergeBlockFormat(blockFormat);
+        }
+    }
+
+    updateSize();
+}
+
+void QQuickTextPrivate::updateSize()
+{
+    Q_Q(QQuickText);
+
+    if (!q->isComponentComplete()) {
+        updateOnComponentComplete = true;
+        return;
+    }
+
+    if (!requireImplicitWidth) {
+        emit q->implicitWidthChanged();
+        // if the implicitWidth is used, then updateSize() has already been called (recursively)
+        if (requireImplicitWidth)
+            return;
+    }
+
+    invalidateImageCache();
+
+    QFontMetrics fm(font);
+    if (text.isEmpty()) {
+        q->setImplicitWidth(0);
+        q->setImplicitHeight(fm.height());
+        paintedSize = QSize(0, fm.height());
+        emit q->paintedSizeChanged();
+        q->update();
+        return;
+    }
+
+    int dy = q->height();
+    QSize size(0, 0);
+
+#if defined(Q_OS_MAC)
+    layoutThread = QThread::currentThread();
+#endif
+
+    //setup instance of QTextLayout for all cases other than richtext
+    if (!richText) {
+        QRect textRect = setupTextLayout();
+        layedOutTextRect = textRect;
+        size = textRect.size();
+        dy -= size.height();
+    } else {
+        singleline = false; // richtext can't elide or be optimized for single-line case
+        ensureDoc();
+        doc->setDefaultFont(font);
+        QQuickText::HAlignment horizontalAlignment = q->effectiveHAlign();
+        if (rightToLeftText) {
+            if (horizontalAlignment == QQuickText::AlignLeft)
+                horizontalAlignment = QQuickText::AlignRight;
+            else if (horizontalAlignment == QQuickText::AlignRight)
+                horizontalAlignment = QQuickText::AlignLeft;
+        }
+        QTextOption option;
+        option.setAlignment((Qt::Alignment)int(horizontalAlignment | vAlign));
+        option.setWrapMode(QTextOption::WrapMode(wrapMode));
+        if (!cacheAllTextAsImage && !richTextAsImage && !qmlDisableDistanceField())
+            option.setUseDesignMetrics(true);
+        doc->setDefaultTextOption(option);
+        if (requireImplicitWidth && q->widthValid()) {
+            doc->setTextWidth(-1);
+            naturalWidth = doc->idealWidth();
+        }
+        if (wrapMode != QQuickText::NoWrap && q->widthValid())
+            doc->setTextWidth(q->width());
+        else
+            doc->setTextWidth(doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug)
+        dy -= (int)doc->size().height();
+        QSize dsize = doc->size().toSize();
+        layedOutTextRect = QRect(QPoint(0,0), dsize);
+        size = QSize(int(doc->idealWidth()),dsize.height());
+    }
+    int yoff = 0;
+
+    if (q->heightValid()) {
+        if (vAlign == QQuickText::AlignBottom)
+            yoff = dy;
+        else if (vAlign == QQuickText::AlignVCenter)
+            yoff = dy/2;
+    }
+    q->setBaselineOffset(fm.ascent() + yoff);
+
+    //### need to comfirm cost of always setting these for richText
+    internalWidthUpdate = true;
+    if (!q->widthValid())
+        q->setImplicitWidth(size.width());
+    else if (requireImplicitWidth)
+        q->setImplicitWidth(naturalWidth);
+    internalWidthUpdate = false;
+
+    q->setImplicitHeight(size.height());
+    if (paintedSize != size) {
+        paintedSize = size;
+        emit q->paintedSizeChanged();
+    }
+    q->update();
+}
+
+QQuickTextLine::QQuickTextLine()
+    : QObject(), m_line(0), m_height(0)
+{
+}
+
+void QQuickTextLine::setLine(QTextLine *line)
+{
+    m_line = line;
+}
+
+int QQuickTextLine::number() const
+{
+    if (m_line)
+        return m_line->lineNumber();
+    return 0;
+}
+
+qreal QQuickTextLine::width() const
+{
+    if (m_line)
+        return m_line->width();
+    return 0;
+}
+
+void QQuickTextLine::setWidth(qreal width)
+{
+    if (m_line)
+        m_line->setLineWidth(width);
+}
+
+qreal QQuickTextLine::height() const
+{
+    if (m_height)
+        return m_height;
+    if (m_line)
+        return m_line->height();
+    return 0;
+}
+
+void QQuickTextLine::setHeight(qreal height)
+{
+    if (m_line)
+        m_line->setPosition(QPointF(m_line->x(), m_line->y() - m_line->height() + height));
+    m_height = height;
+}
+
+qreal QQuickTextLine::x() const
+{
+    if (m_line)
+        return m_line->x();
+    return 0;
+}
+
+void QQuickTextLine::setX(qreal x)
+{
+    if (m_line)
+        m_line->setPosition(QPointF(x, m_line->y()));
+}
+
+qreal QQuickTextLine::y() const
+{
+    if (m_line)
+        return m_line->y();
+    return 0;
+}
+
+void QQuickTextLine::setY(qreal y)
+{
+    if (m_line)
+        m_line->setPosition(QPointF(m_line->x(), y));
+}
+
+void QQuickText::doLayout()
+{
+    Q_D(QQuickText);
+    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 QQuickTextPrivate::isLineLaidOutConnected()
+{
+    static int idx = this->signalIndex("lineLaidOut(QQuickTextLine*)");
+    return this->isSignalConnected(idx);
+}
+
+void QQuickTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height, qreal elideWidth = 0)
+{
+    Q_Q(QQuickText);
+
+#if defined(Q_OS_MAC)
+    if (QThread::currentThread() != paintingThread) {
+#endif
+        if (!line.lineNumber())
+            linesRects.clear();
+
+        if (!textLine)
+            textLine = new QQuickTextLine;
+        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() != QQuickText::NoWrap)
+            textLine->setWidth(q->width() - elideWidth);
+        else
+            textLine->setWidth(INT_MAX);
+        if (lineHeight != 1.0)
+            textLine->setHeight((lineHeightMode == QQuickText::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 QQuickTextPrivate::layout QTextLayout in the constraints of the QQuickText.
+
+    Returns the size of the final text.  This can be used to position the text vertically (the text is
+    already absolutely positioned horizontally).
+*/
+QRect QQuickTextPrivate::setupTextLayout()
+{
+    // ### text layout handling should be profiled and optimized as needed
+    // what about QStackTextEngine engine(tmp, d->font.font()); QTextLayout textLayout(&engine);
+    Q_Q(QQuickText);
+    layout.setCacheEnabled(true);
+
+    qreal lineWidth = 0;
+    int visibleCount = 0;
+
+    //set manual width
+    if (q->widthValid())
+        lineWidth = q->width();
+
+    QTextOption textOption = layout.textOption();
+    textOption.setAlignment(Qt::Alignment(q->effectiveHAlign()));
+    textOption.setWrapMode(QTextOption::WrapMode(wrapMode));
+    if (!cacheAllTextAsImage && !richTextAsImage && !qmlDisableDistanceField())
+        textOption.setUseDesignMetrics(true);
+    layout.setTextOption(textOption);
+
+    bool elideText = false;
+    bool truncate = false;
+
+    QFontMetrics fm(layout.font());
+    elidePos = QPointF();
+
+    if (requireImplicitWidth && q->widthValid()) {
+        // requires an extra layout
+        QString elidedText;
+        if (layoutTextElided) {
+            // We have provided elided text to the layout, but we must calculate unelided width.
+            elidedText = layout.text();
+            layout.setText(text);
+        }
+        layout.beginLayout();
+        forever {
+            QTextLine line = layout.createLine();
+            if (!line.isValid())
+                break;
+        }
+        layout.endLayout();
+        QRectF br;
+        for (int i = 0; i < layout.lineCount(); ++i) {
+            QTextLine line = layout.lineAt(i);
+            br = br.united(line.naturalTextRect());
+        }
+        naturalWidth = br.width();
+        if (layoutTextElided)
+            layout.setText(elidedText);
+    }
+
+    qreal height = 0;
+    bool customLayout = isLineLaidOutConnected();
+
+    if (maximumLineCountValid) {
+        layout.beginLayout();
+        if (!lineWidth)
+            lineWidth = INT_MAX;
+        int linesLeft = maximumLineCount;
+        int visibleTextLength = 0;
+        while (linesLeft > 0) {
+            QTextLine line = layout.createLine();
+            if (!line.isValid())
+                break;
+
+            visibleCount++;
+
+            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 == QQuickText::ElideRight && q->widthValid()) {
+                        qreal elideWidth = fm.width(elideChar);
+                        // Need to correct for alignment
+                        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);
+                        } else {
+                            elidePos.setX(line.naturalTextRect().right());
+                        }
+                        elideText = true;
+                    }
+                }
+            }
+        }
+        layout.endLayout();
+
+        //Update truncated
+        if (truncated != truncate) {
+            truncated = truncate;
+            emit q->truncatedChanged();
+        }
+    } else {
+        layout.beginLayout();
+        forever {
+            QTextLine line = layout.createLine();
+            if (!line.isValid())
+                break;
+            visibleCount++;
+            if (customLayout)
+                setupCustomLineGeometry(line, height);
+            else {
+                if (lineWidth)
+                    line.setLineWidth(lineWidth);
+            }
+        }
+        layout.endLayout();
+    }
+
+    height = 0;
+    QRectF br;
+    for (int i = 0; i < layout.lineCount(); ++i) {
+        QTextLine line = layout.lineAt(i);
+        // set line spacing
+        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())));
+        }
+        br = br.united(line.naturalTextRect());
+        height += (lineHeightMode == QQuickText::FixedHeight) ? lineHeight : line.height() * lineHeight;
+    }
+    if (!customLayout)
+        br.setHeight(height);
+
+    if (!q->widthValid())
+        naturalWidth = br.width();
+
+    //Update the number of visible lines
+    if (lineCount != visibleCount) {
+        lineCount = visibleCount;
+        emit q->lineCountChanged();
+    }
+
+    return QRect(qRound(br.x()), qRound(br.y()), qCeil(br.width()), qCeil(br.height()));
+}
+
+/*!
+    Returns a painted version of the QQuickTextPrivate::layout QTextLayout.
+    If \a drawStyle is true, the style color overrides all colors in the document.
+*/
+QPixmap QQuickTextPrivate::textLayoutImage(bool drawStyle)
+{
+    QSize size = layedOutTextRect.size();
+
+    //paint text
+    QPixmap img(size);
+    if (!size.isEmpty()) {
+        img.fill(Qt::transparent);
+#ifdef Q_WS_MAC
+        bool oldSmooth = qt_applefontsmoothing_enabled;
+        qt_applefontsmoothing_enabled = false;
+#endif
+        QPainter p(&img);
+#ifdef Q_WS_MAC
+        qt_applefontsmoothing_enabled = oldSmooth;
+#endif
+        drawTextLayout(&p, QPointF(-layedOutTextRect.x(),0), drawStyle);
+    }
+    return img;
+}
+
+/*!
+    Paints the QQuickTextPrivate::layout QTextLayout into \a painter at \a pos.  If
+    \a drawStyle is true, the style color overrides all colors in the document.
+*/
+void QQuickTextPrivate::drawTextLayout(QPainter *painter, const QPointF &pos, bool drawStyle)
+{
+    if (drawStyle)
+        painter->setPen(styleColor);
+    else
+        painter->setPen(color);
+    painter->setFont(font);
+    layout.draw(painter, pos);
+    if (!elidePos.isNull())
+        painter->drawText(pos + elidePos, elideChar);
+}
+
+/*!
+    Returns a painted version of the QQuickTextPrivate::doc QTextDocument.
+    If \a drawStyle is true, the style color overrides all colors in the document.
+*/
+QPixmap QQuickTextPrivate::textDocumentImage(bool drawStyle)
+{
+    QSize size = doc->size().toSize();
+
+    //paint text
+    QPixmap img(size);
+    img.fill(Qt::transparent);
+#ifdef Q_WS_MAC
+    bool oldSmooth = qt_applefontsmoothing_enabled;
+    qt_applefontsmoothing_enabled = false;
+#endif
+    QPainter p(&img);
+#ifdef Q_WS_MAC
+    qt_applefontsmoothing_enabled = oldSmooth;
+#endif
+
+    QAbstractTextDocumentLayout::PaintContext context;
+
+    QTextOption oldOption(doc->defaultTextOption());
+    if (drawStyle) {
+        context.palette.setColor(QPalette::Text, styleColor);
+        QTextOption colorOption(doc->defaultTextOption());
+        colorOption.setFlags(QTextOption::SuppressColors);
+        doc->setDefaultTextOption(colorOption);
+    } else {
+        context.palette.setColor(QPalette::Text, color);
+    }
+    doc->documentLayout()->draw(&p, context);
+    if (drawStyle)
+        doc->setDefaultTextOption(oldOption);
+    return img;
+}
+
+/*!
+    Mark the image cache as dirty.
+*/
+void QQuickTextPrivate::invalidateImageCache()
+{
+    Q_Q(QQuickText);
+
+    if (richTextAsImage || cacheAllTextAsImage || (qmlDisableDistanceField() && style != QQuickText::Normal)) { // If actually using the image cache
+        if (imageCacheDirty)
+            return;
+
+        imageCacheDirty = true;
+
+        if (q->isComponentComplete())
+            QCoreApplication::postEvent(q, new QEvent(QEvent::User));
+    } else if (q->isComponentComplete())
+        q->update();
+}
+
+/*!
+    Tests if the image cache is dirty, and repaints it if it is.
+*/
+void QQuickTextPrivate::checkImageCache()
+{
+    Q_Q(QQuickText);
+
+    if (!imageCacheDirty)
+        return;
+
+    if (text.isEmpty()) {
+
+        imageCache = QPixmap();
+
+    } else {
+
+        QPixmap textImage;
+        QPixmap styledImage;
+
+        if (richText) {
+            textImage = textDocumentImage(false);
+            if (style != QQuickText::Normal)
+                styledImage = textDocumentImage(true); //### should use styleColor
+        } else {
+            textImage = textLayoutImage(false);
+            if (style != QQuickText::Normal)
+                styledImage = textLayoutImage(true); //### should use styleColor
+        }
+
+        switch (style) {
+        case QQuickText::Outline:
+            imageCache = drawOutline(textImage, styledImage);
+            break;
+        case QQuickText::Sunken:
+            imageCache = drawOutline(textImage, styledImage, -1);
+            break;
+        case QQuickText::Raised:
+            imageCache = drawOutline(textImage, styledImage, 1);
+            break;
+        default:
+            imageCache = textImage;
+            break;
+        }
+
+    }
+
+    imageCacheDirty = false;
+    textureImageCacheDirty = true;
+    q->update();
+}
+
+/*!
+    Ensures the QQuickTextPrivate::doc variable is set to a valid text document
+*/
+void QQuickTextPrivate::ensureDoc()
+{
+    if (!doc) {
+        Q_Q(QQuickText);
+        doc = new QQuickTextDocumentWithImageResources(q);
+        doc->setDocumentMargin(0);
+    }
+}
+
+/*!
+    Draw \a styleSource as an outline around \a source and return the new image.
+*/
+QPixmap QQuickTextPrivate::drawOutline(const QPixmap &source, const QPixmap &styleSource)
+{
+    QPixmap img = QPixmap(styleSource.width() + 2, styleSource.height() + 2);
+    img.fill(Qt::transparent);
+
+    QPainter ppm(&img);
+
+    QPoint pos(0, 0);
+    pos += QPoint(-1, 0);
+    ppm.drawPixmap(pos, styleSource);
+    pos += QPoint(2, 0);
+    ppm.drawPixmap(pos, styleSource);
+    pos += QPoint(-1, -1);
+    ppm.drawPixmap(pos, styleSource);
+    pos += QPoint(0, 2);
+    ppm.drawPixmap(pos, styleSource);
+
+    pos += QPoint(0, -1);
+    ppm.drawPixmap(pos, source);
+    ppm.end();
+
+    return img;
+}
+
+/*!
+    Draw \a styleSource below \a source at \a yOffset and return the new image.
+*/
+QPixmap QQuickTextPrivate::drawOutline(const QPixmap &source, const QPixmap &styleSource, int yOffset)
+{
+    QPixmap img = QPixmap(styleSource.width() + 2, styleSource.height() + 2);
+    img.fill(Qt::transparent);
+
+    QPainter ppm(&img);
+
+    ppm.drawPixmap(QPoint(0, yOffset), styleSource);
+    ppm.drawPixmap(0, 0, source);
+
+    ppm.end();
+
+    return img;
+}
+
+/*!
+    \qmlclass Text QQuickText
+    \inqmlmodule QtQuick 2
+    \ingroup qml-basic-visual-elements
+    \brief The Text item allows you to add formatted text to a scene.
+    \inherits Item
+
+    Text items can display both plain and rich text. For example, red text with
+    a specific font and size can be defined like this:
+
+    \qml
+    Text {
+        text: "Hello World!"
+        font.family: "Helvetica"
+        font.pointSize: 24
+        color: "red"
+    }
+    \endqml
+
+    Rich text is defined using HTML-style markup:
+
+    \qml
+    Text {
+        text: "<b>Hello</b> <i>World!</i>"
+    }
+    \endqml
+
+    \image declarative-text.png
+
+    If height and width are not explicitly set, Text will attempt to determine how
+    much room is needed and set it accordingly. Unless \l wrapMode is set, it will always
+    prefer width to height (all text will be placed on a single line).
+
+    The \l elide property can alternatively be used to fit a single line of
+    plain text to a set width.
+
+    Note that the \l{Supported HTML Subset} is limited. Also, if the text contains
+    HTML img tags that load remote images, the text is reloaded.
+
+    Text provides read-only text. For editable text, see \l TextEdit.
+
+    \sa {declarative/text/fonts}{Fonts example}
+*/
+QQuickText::QQuickText(QQuickItem *parent)
+: QQuickImplicitSizeItem(*(new QQuickTextPrivate), parent)
+{
+    Q_D(QQuickText);
+    d->init();
+}
+
+QQuickText::~QQuickText()
+{
+}
+
+/*!
+  \qmlproperty bool QtQuick2::Text::clip
+  This property holds whether the text is clipped.
+
+  Note that if the text does not fit in the bounding rectangle it will be abruptly chopped.
+
+  If you want to display potentially long text in a limited space, you probably want to use \c elide instead.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::Text::smooth
+
+    This property holds whether the text is smoothly scaled or transformed.
+
+    Smooth filtering gives better visual quality, but is slower.  If
+    the item is displayed at its natural size, this property has no visual or
+    performance effect.
+
+    \note Generally scaling artifacts are only visible if the item is stationary on
+    the screen.  A common pattern when animating an item is to disable smooth
+    filtering at the beginning of the animation and reenable it at the conclusion.
+*/
+
+/*!
+    \qmlsignal QtQuick2::Text::onLinkActivated(string link)
+
+    This handler is called when the user clicks on a link embedded in the text.
+    The link must be in rich text or HTML format and the
+    \a link string provides access to the particular link.
+
+    \snippet doc/src/snippets/declarative/text/onLinkActivated.qml 0
+
+    The example code will display the text
+    "The main website is at \l{http://qt.nokia.com}{Nokia Qt DF}."
+
+    Clicking on the highlighted link will output
+    \tt{http://qt.nokia.com link activated} to the console.
+*/
+
+/*!
+    \qmlproperty string QtQuick2::Text::font.family
+
+    Sets the family name of the font.
+
+    The family name is case insensitive and may optionally include a foundry name, e.g. "Helvetica [Cronyx]".
+    If the family is available from more than one foundry and the foundry isn't specified, an arbitrary foundry is chosen.
+    If the family isn't available a family will be set using the font matching algorithm.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::Text::font.bold
+
+    Sets whether the font weight is bold.
+*/
+
+/*!
+    \qmlproperty enumeration QtQuick2::Text::font.weight
+
+    Sets the font's weight.
+
+    The weight can be one of:
+    \list
+    \o Font.Light
+    \o Font.Normal - the default
+    \o Font.DemiBold
+    \o Font.Bold
+    \o Font.Black
+    \endlist
+
+    \qml
+    Text { text: "Hello"; font.weight: Font.DemiBold }
+    \endqml
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::Text::font.italic
+
+    Sets whether the font has an italic style.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::Text::font.underline
+
+    Sets whether the text is underlined.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::Text::font.strikeout
+
+    Sets whether the font has a strikeout style.
+*/
+
+/*!
+    \qmlproperty real QtQuick2::Text::font.pointSize
+
+    Sets the font size in points. The point size must be greater than zero.
+*/
+
+/*!
+    \qmlproperty int QtQuick2::Text::font.pixelSize
+
+    Sets the font size in pixels.
+
+    Using this function makes the font device dependent.
+    Use \c pointSize to set the size of the font in a device independent manner.
+*/
+
+/*!
+    \qmlproperty real QtQuick2::Text::font.letterSpacing
+
+    Sets the letter spacing for the font.
+
+    Letter spacing changes the default spacing between individual letters in the font.
+    A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing.
+*/
+
+/*!
+    \qmlproperty real QtQuick2::Text::font.wordSpacing
+
+    Sets the word spacing for the font.
+
+    Word spacing changes the default spacing between individual words.
+    A positive value increases the word spacing by a corresponding amount of pixels,
+    while a negative value decreases the inter-word spacing accordingly.
+*/
+
+/*!
+    \qmlproperty enumeration QtQuick2::Text::font.capitalization
+
+    Sets the capitalization for the text.
+
+    \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.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character.
+    \endlist
+
+    \qml
+    Text { text: "Hello"; font.capitalization: Font.AllLowercase }
+    \endqml
+*/
+QFont QQuickText::font() const
+{
+    Q_D(const QQuickText);
+    return d->sourceFont;
+}
+
+void QQuickText::setFont(const QFont &font)
+{
+    Q_D(QQuickText);
+    if (d->sourceFont == font)
+        return;
+
+    d->sourceFont = font;
+    QFont oldFont = d->font;
+    d->font = font;
+
+    if (d->font.pointSizeF() != -1) {
+        // 0.5pt resolution
+        qreal size = qRound(d->font.pointSizeF()*2.0);
+        d->font.setPointSizeF(size/2.0);
+    }
+
+    if (oldFont != d->font)
+        d->updateLayout();
+
+    emit fontChanged(d->sourceFont);
+}
+
+/*!
+    \qmlproperty string QtQuick2::Text::text
+
+    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 styled text. This determination is made using Qt::mightBeRichText().
+*/
+QString QQuickText::text() const
+{
+    Q_D(const QQuickText);
+    return d->text;
+}
+
+void QQuickText::setText(const QString &n)
+{
+    Q_D(QQuickText);
+    if (d->text == n)
+        return;
+
+    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 = enableImageCache();
+        } else {
+            d->rightToLeftText = d->text.isRightToLeft();
+        }
+        d->determineHorizontalAlignment();
+    }
+    d->textHasChanged = true;
+    d->updateLayout();
+    emit textChanged(d->text);
+}
+
+/*!
+    \qmlproperty color QtQuick2::Text::color
+
+    The text color.
+
+    An example of green text defined using hexadecimal notation:
+    \qml
+    Text {
+        color: "#00FF00"
+        text: "green text"
+    }
+    \endqml
+
+    An example of steel blue text defined using an SVG color name:
+    \qml
+    Text {
+        color: "steelblue"
+        text: "blue text"
+    }
+    \endqml
+*/
+QColor QQuickText::color() const
+{
+    Q_D(const QQuickText);
+    return d->color;
+}
+
+void QQuickText::setColor(const QColor &color)
+{
+    Q_D(QQuickText);
+    if (d->color == color)
+        return;
+
+    d->color = color;
+    d->invalidateImageCache();
+    emit colorChanged(d->color);
+}
+/*!
+    \qmlproperty enumeration QtQuick2::Text::style
+
+    Set an additional text style.
+
+    Supported text styles are:
+    \list
+    \o Text.Normal - the default
+    \o Text.Outline
+    \o Text.Raised
+    \o Text.Sunken
+    \endlist
+
+    \qml
+    Row {
+        Text { font.pointSize: 24; text: "Normal" }
+        Text { font.pointSize: 24; text: "Raised"; style: Text.Raised; styleColor: "#AAAAAA" }
+        Text { font.pointSize: 24; text: "Outline";style: Text.Outline; styleColor: "red" }
+        Text { font.pointSize: 24; text: "Sunken"; style: Text.Sunken; styleColor: "#AAAAAA" }
+    }
+    \endqml
+
+    \image declarative-textstyle.png
+*/
+QQuickText::TextStyle QQuickText::style() const
+{
+    Q_D(const QQuickText);
+    return d->style;
+}
+
+void QQuickText::setStyle(QQuickText::TextStyle style)
+{
+    Q_D(QQuickText);
+    if (d->style == style)
+        return;
+
+    // changing to/from Normal requires the boundingRect() to change
+    if (isComponentComplete() && (d->style == Normal || style == Normal))
+        update();
+    d->style = style;
+    d->invalidateImageCache();
+    emit styleChanged(d->style);
+}
+
+/*!
+    \qmlproperty color QtQuick2::Text::styleColor
+
+    Defines the secondary color used by text styles.
+
+    \c styleColor is used as the outline color for outlined text, and as the
+    shadow color for raised or sunken text. If no style has been set, it is not
+    used at all.
+
+    \qml
+    Text { font.pointSize: 18; text: "hello"; style: Text.Raised; styleColor: "gray" }
+    \endqml
+
+    \sa style
+ */
+QColor QQuickText::styleColor() const
+{
+    Q_D(const QQuickText);
+    return d->styleColor;
+}
+
+void QQuickText::setStyleColor(const QColor &color)
+{
+    Q_D(QQuickText);
+    if (d->styleColor == color)
+        return;
+
+    d->styleColor = color;
+    d->invalidateImageCache();
+    emit styleColorChanged(d->styleColor);
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::Text::horizontalAlignment
+    \qmlproperty enumeration QtQuick2::Text::verticalAlignment
+    \qmlproperty enumeration QtQuick2::Text::effectiveHorizontalAlignment
+
+    Sets the horizontal and vertical alignment of the text within the Text items
+    width and height. By default, the text is vertically aligned to the top. Horizontal
+    alignment follows the natural alignment of the text, for example text that is read
+    from left to right will be aligned to the left.
+
+    The valid values for \c horizontalAlignment are \c Text.AlignLeft, \c Text.AlignRight, \c Text.AlignHCenter and
+    \c Text.AlignJustify.  The valid values for \c verticalAlignment are \c Text.AlignTop, \c Text.AlignBottom
+    and \c Text.AlignVCenter.
+
+    Note that for a single line of text, the size of the text is the area of the text. In this common case,
+    all alignments are equivalent. If you want the text to be, say, centered in its parent, then you will
+    need to either modify the Item::anchors, or set horizontalAlignment to Text.AlignHCenter and bind the width to
+    that of the parent.
+
+    When using the attached property LayoutMirroring::enabled to mirror application
+    layouts, the horizontal alignment of text will also be mirrored. However, the property
+    \c horizontalAlignment will remain unchanged. To query the effective horizontal alignment
+    of Text, use the read-only property \c effectiveHorizontalAlignment.
+*/
+QQuickText::HAlignment QQuickText::hAlign() const
+{
+    Q_D(const QQuickText);
+    return d->hAlign;
+}
+
+void QQuickText::setHAlign(HAlignment align)
+{
+    Q_D(QQuickText);
+    bool forceAlign = d->hAlignImplicit && d->effectiveLayoutMirror;
+    d->hAlignImplicit = false;
+    if (d->setHAlign(align, forceAlign) && isComponentComplete())
+        d->updateLayout();
+}
+
+void QQuickText::resetHAlign()
+{
+    Q_D(QQuickText);
+    d->hAlignImplicit = true;
+    if (d->determineHorizontalAlignment() && isComponentComplete())
+        d->updateLayout();
+}
+
+QQuickText::HAlignment QQuickText::effectiveHAlign() const
+{
+    Q_D(const QQuickText);
+    QQuickText::HAlignment effectiveAlignment = d->hAlign;
+    if (!d->hAlignImplicit && d->effectiveLayoutMirror) {
+        switch (d->hAlign) {
+        case QQuickText::AlignLeft:
+            effectiveAlignment = QQuickText::AlignRight;
+            break;
+        case QQuickText::AlignRight:
+            effectiveAlignment = QQuickText::AlignLeft;
+            break;
+        default:
+            break;
+        }
+    }
+    return effectiveAlignment;
+}
+
+bool QQuickTextPrivate::setHAlign(QQuickText::HAlignment alignment, bool forceAlign)
+{
+    Q_Q(QQuickText);
+    if (hAlign != alignment || forceAlign) {
+        QQuickText::HAlignment oldEffectiveHAlign = q->effectiveHAlign();
+        hAlign = alignment;
+
+        emit q->horizontalAlignmentChanged(hAlign);
+        if (oldEffectiveHAlign != q->effectiveHAlign())
+            emit q->effectiveHorizontalAlignmentChanged();
+        return true;
+    }
+    return false;
+}
+
+bool QQuickTextPrivate::determineHorizontalAlignment()
+{
+    Q_Q(QQuickText);
+    if (hAlignImplicit && q->isComponentComplete()) {
+        bool alignToRight = text.isEmpty() ? QGuiApplication::keyboardInputDirection() == Qt::RightToLeft : rightToLeftText;
+        return setHAlign(alignToRight ? QQuickText::AlignRight : QQuickText::AlignLeft);
+    }
+    return false;
+}
+
+void QQuickTextPrivate::mirrorChange()
+{
+    Q_Q(QQuickText);
+    if (q->isComponentComplete()) {
+        if (!hAlignImplicit && (hAlign == QQuickText::AlignRight || hAlign == QQuickText::AlignLeft)) {
+            updateLayout();
+            emit q->effectiveHorizontalAlignmentChanged();
+        }
+    }
+}
+
+QTextDocument *QQuickTextPrivate::textDocument()
+{
+    return doc;
+}
+
+QQuickText::VAlignment QQuickText::vAlign() const
+{
+    Q_D(const QQuickText);
+    return d->vAlign;
+}
+
+void QQuickText::setVAlign(VAlignment align)
+{
+    Q_D(QQuickText);
+    if (d->vAlign == align)
+        return;
+
+    d->vAlign = align;
+    emit verticalAlignmentChanged(align);
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::Text::wrapMode
+
+    Set this property to wrap the text to the Text item's width.  The text will only
+    wrap if an explicit width has been set.  wrapMode can be one of:
+
+    \list
+    \o Text.NoWrap (default) - no wrapping will be performed. If the text contains insufficient newlines, then \l paintedWidth will exceed a set width.
+    \o Text.WordWrap - wrapping is done on word boundaries only. If a word is too long, \l paintedWidth will exceed a set width.
+    \o Text.WrapAnywhere - wrapping is done at any point on a line, even if it occurs in the middle of a word.
+    \o Text.Wrap - if possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word.
+    \endlist
+*/
+QQuickText::WrapMode QQuickText::wrapMode() const
+{
+    Q_D(const QQuickText);
+    return d->wrapMode;
+}
+
+void QQuickText::setWrapMode(WrapMode mode)
+{
+    Q_D(QQuickText);
+    if (mode == d->wrapMode)
+        return;
+
+    d->wrapMode = mode;
+    d->updateLayout();
+
+    emit wrapModeChanged();
+}
+
+/*!
+    \qmlproperty int QtQuick2::Text::lineCount
+
+    Returns the number of lines visible in the text item.
+
+    This property is not supported for rich text.
+
+    \sa maximumLineCount
+*/
+int QQuickText::lineCount() const
+{
+    Q_D(const QQuickText);
+    return d->lineCount;
+}
+
+/*!
+    \qmlproperty bool QtQuick2::Text::truncated
+
+    Returns true if the text has been truncated due to \l maximumLineCount
+    or \l elide.
+
+    This property is not supported for rich text.
+
+    \sa maximumLineCount, elide
+*/
+bool QQuickText::truncated() const
+{
+    Q_D(const QQuickText);
+    return d->truncated;
+}
+
+/*!
+    \qmlproperty int QtQuick2::Text::maximumLineCount
+
+    Set this property to limit the number of lines that the text item will show.
+    If elide is set to Text.ElideRight, the text will be elided appropriately.
+    By default, this is the value of the largest possible integer.
+
+    This property is not supported for rich text.
+
+    \sa lineCount, elide
+*/
+int QQuickText::maximumLineCount() const
+{
+    Q_D(const QQuickText);
+    return d->maximumLineCount;
+}
+
+void QQuickText::setMaximumLineCount(int lines)
+{
+    Q_D(QQuickText);
+
+    d->maximumLineCountValid = lines==INT_MAX ? false : true;
+    if (d->maximumLineCount != lines) {
+        d->maximumLineCount = lines;
+        d->updateLayout();
+        emit maximumLineCountChanged();
+    }
+}
+
+void QQuickText::resetMaximumLineCount()
+{
+    Q_D(QQuickText);
+    setMaximumLineCount(INT_MAX);
+    d->elidePos = QPointF();
+    if (d->truncated != false) {
+        d->truncated = false;
+        emit truncatedChanged();
+    }
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::Text::textFormat
+
+    The way the text property should be displayed.
+
+    Supported text formats are:
+
+    \list
+    \o Text.AutoText (default)
+    \o Text.PlainText
+    \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
+    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:
+
+    \code
+    <b></b> - bold
+    <i></i> - italic
+    <br> - new line
+    <p> - paragraph
+    <u> - underlined text
+    <font color="color_name" size="1-7"></font>
+    <h1> to <h6> - headers
+    <a href=""> - anchor
+    <ol type="">, <ul type=""> and <li> - ordered and unordered lists
+    &gt; &lt; &amp;
+    \endcode
+
+    \c Text.StyledText parser is strict, requiring tags to be correctly nested.
+
+    \table
+    \row
+    \o
+    \qml
+Column {
+    Text {
+        font.pointSize: 24
+        text: "<b>Hello</b> <i>World!</i>"
+    }
+    Text {
+        font.pointSize: 24
+        textFormat: Text.RichText
+        text: "<b>Hello</b> <i>World!</i>"
+    }
+    Text {
+        font.pointSize: 24
+        textFormat: Text.PlainText
+        text: "<b>Hello</b> <i>World!</i>"
+    }
+}
+    \endqml
+    \o \image declarative-textformat.png
+    \endtable
+*/
+QQuickText::TextFormat QQuickText::textFormat() const
+{
+    Q_D(const QQuickText);
+    return d->format;
+}
+
+void QQuickText::setTextFormat(TextFormat format)
+{
+    Q_D(QQuickText);
+    if (format == d->format)
+        return;
+    d->format = format;
+    bool wasRich = d->richText;
+    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->rightToLeftText = d->doc->toPlainText().isRightToLeft();
+        d->richTextAsImage = enableImageCache();
+    } else {
+        d->rightToLeftText = d->text.isRightToLeft();
+    }
+    d->determineHorizontalAlignment();
+    d->updateLayout();
+
+    emit textFormatChanged(d->format);
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::Text::elide
+
+    Set this property to elide parts of the text fit to the Text item's width.
+    The text will only elide if an explicit width has been set.
+
+    This property cannot be used with rich text.
+
+    Eliding can be:
+    \list
+    \o Text.ElideNone  - the default
+    \o Text.ElideLeft
+    \o Text.ElideMiddle
+    \o Text.ElideRight
+    \endlist
+
+    If this property is set to Text.ElideRight, it can be used with multiline
+    text. The text will only elide if maximumLineCount has been set.
+
+    If the text is a multi-length string, and the mode is not \c Text.ElideNone,
+    the first string that fits will be used, otherwise the last will be elided.
+
+    Multi-length strings are ordered from longest to shortest, separated by the
+    Unicode "String Terminator" character \c U009C (write this in QML with \c{"\u009C"} or \c{"\x9C"}).
+*/
+QQuickText::TextElideMode QQuickText::elideMode() const
+{
+    Q_D(const QQuickText);
+    return d->elideMode;
+}
+
+void QQuickText::setElideMode(QQuickText::TextElideMode mode)
+{
+    Q_D(QQuickText);
+    if (mode == d->elideMode)
+        return;
+
+    d->elideMode = mode;
+    d->updateLayout();
+
+    emit elideModeChanged(d->elideMode);
+}
+
+/*! \internal */
+QRectF QQuickText::boundingRect() const
+{
+    Q_D(const QQuickText);
+
+    QRect rect = d->layedOutTextRect;
+    if (d->style != Normal)
+        rect.adjust(-1, 0, 1, 2);
+
+    // Could include font max left/right bearings to either side of rectangle.
+
+    int h = height();
+    switch (d->vAlign) {
+    case AlignTop:
+        break;
+    case AlignBottom:
+        rect.moveTop(h - rect.height());
+        break;
+    case AlignVCenter:
+        rect.moveTop((h - rect.height()) / 2);
+        break;
+    }
+
+    return QRectF(rect);
+}
+
+/*! \internal */
+void QQuickText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+    Q_D(QQuickText);
+    if ((!d->internalWidthUpdate && newGeometry.width() != oldGeometry.width())
+            && (d->wrapMode != QQuickText::NoWrap
+                || d->elideMode != QQuickText::ElideNone
+                || d->hAlign != QQuickText::AlignLeft)) {
+        if ((d->singleline || d->maximumLineCountValid) && d->elideMode != QQuickText::ElideNone && widthValid()) {
+            // We need to re-elide
+            d->updateLayout();
+        } else {
+            // We just need to re-layout
+            d->updateSize();
+        }
+    }
+
+    QQuickItem::geometryChanged(newGeometry, oldGeometry);
+}
+
+QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
+{
+    Q_UNUSED(data);
+    Q_D(QQuickText);
+
+    if (d->text.isEmpty()) {
+        delete oldNode;
+        return 0;
+    }
+
+    QRectF bounds = boundingRect();
+
+    // We need to make sure the layout is done in the current thread
+#if defined(Q_OS_MAC)
+    d->paintingThread = QThread::currentThread();
+    if (d->layoutThread != d->paintingThread)
+        d->updateLayout();
+#endif
+
+    // XXX todo - some styled text can be done by the QQuickTextNode
+    if (d->richTextAsImage || d->cacheAllTextAsImage || (qmlDisableDistanceField() && d->style != Normal)) {
+        bool wasDirty = d->textureImageCacheDirty;
+        d->textureImageCacheDirty = false;
+
+        if (d->imageCache.isNull()) {
+            delete oldNode;
+            return 0;
+        }
+
+        QSGImageNode *node = 0;
+        if (!oldNode || d->nodeType != QQuickTextPrivate::NodeIsTexture) {
+            delete oldNode;
+            node = QQuickItemPrivate::get(this)->sceneGraphContext()->createImageNode();
+            d->texture = new QSGPlainTexture();
+            wasDirty = true;
+            d->nodeType = QQuickTextPrivate::NodeIsTexture;
+        } else {
+            node = static_cast<QSGImageNode *>(oldNode);
+            Q_ASSERT(d->texture);
+        }
+
+        if (wasDirty) {
+            qobject_cast<QSGPlainTexture *>(d->texture)->setImage(d->imageCache.toImage());
+            node->setTexture(0);
+            node->setTexture(d->texture);
+        }
+
+        node->setTargetRect(QRectF(bounds.x(), bounds.y(), d->imageCache.width(), d->imageCache.height()));
+        node->setSourceRect(QRectF(0, 0, 1, 1));
+        node->setHorizontalWrapMode(QSGTexture::ClampToEdge);
+        node->setVerticalWrapMode(QSGTexture::ClampToEdge);
+        node->setFiltering(QSGTexture::Linear); // Nonsmooth text just ugly, so don't do that..
+        node->update();
+
+        return node;
+
+    } else {
+        QQuickTextNode *node = 0;
+        if (!oldNode || d->nodeType != QQuickTextPrivate::NodeIsText) {
+            delete oldNode;
+            node = new QQuickTextNode(QQuickItemPrivate::get(this)->sceneGraphContext());
+            d->nodeType = QQuickTextPrivate::NodeIsText;
+        } else {
+            node = static_cast<QQuickTextNode *>(oldNode);
+        }
+
+        node->deleteContent();
+        node->setMatrix(QMatrix4x4());
+
+        if (d->richText) {
+            d->ensureDoc();
+            node->addTextDocument(bounds.topLeft(), d->doc, QColor(), d->style, d->styleColor);
+
+        } else {
+            node->addTextLayout(QPoint(0, bounds.y()), &d->layout, d->color, d->style, d->styleColor);
+        }
+
+        return node;
+    }
+}
+
+bool QQuickText::event(QEvent *e)
+{
+    Q_D(QQuickText);
+    if (e->type() == QEvent::User) {
+        d->checkImageCache();
+        return true;
+    } else {
+        return QQuickImplicitSizeItem::event(e);
+    }
+}
+
+/*!
+    \qmlproperty real QtQuick2::Text::paintedWidth
+
+    Returns the width of the text, including width past the width
+    which is covered due to insufficient wrapping if WrapMode is set.
+*/
+qreal QQuickText::paintedWidth() const
+{
+    Q_D(const QQuickText);
+    return d->paintedSize.width();
+}
+
+/*!
+    \qmlproperty real QtQuick2::Text::paintedHeight
+
+    Returns the height of the text, including height past the height
+    which is covered due to there being more text than fits in the set height.
+*/
+qreal QQuickText::paintedHeight() const
+{
+    Q_D(const QQuickText);
+    return d->paintedSize.height();
+}
+
+/*!
+    \qmlproperty real QtQuick2::Text::lineHeight
+
+    Sets the line height for the text.
+    The value can be in pixels or a multiplier depending on lineHeightMode.
+
+    The default value is a multiplier of 1.0.
+    The line height must be a positive value.
+*/
+qreal QQuickText::lineHeight() const
+{
+    Q_D(const QQuickText);
+    return d->lineHeight;
+}
+
+void QQuickText::setLineHeight(qreal lineHeight)
+{
+    Q_D(QQuickText);
+
+    if ((d->lineHeight == lineHeight) || (lineHeight < 0.0))
+        return;
+
+    d->lineHeight = lineHeight;
+    d->updateLayout();
+    emit lineHeightChanged(lineHeight);
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::Text::lineHeightMode
+
+    This property determines how the line height is specified.
+    The possible values are:
+
+    \list
+    \o Text.ProportionalHeight (default) - this sets the spacing proportional to the
+       line (as a multiplier). For example, set to 2 for double spacing.
+    \o Text.FixedHeight - this sets the line height to a fixed line height (in pixels).
+    \endlist
+*/
+QQuickText::LineHeightMode QQuickText::lineHeightMode() const
+{
+    Q_D(const QQuickText);
+    return d->lineHeightMode;
+}
+
+void QQuickText::setLineHeightMode(LineHeightMode mode)
+{
+    Q_D(QQuickText);
+    if (mode == d->lineHeightMode)
+        return;
+
+    d->lineHeightMode = mode;
+    d->updateLayout();
+
+    emit lineHeightModeChanged(mode);
+}
+
+/*!
+    Returns the number of resources (images) that are being loaded asynchronously.
+*/
+int QQuickText::resourcesLoading() const
+{
+    Q_D(const QQuickText);
+    return d->doc ? d->doc->resourcesLoading() : 0;
+}
+
+/*! \internal */
+void QQuickText::componentComplete()
+{
+    Q_D(QQuickText);
+    QQuickItem::componentComplete();
+    if (d->updateOnComponentComplete) {
+        d->updateOnComponentComplete = false;
+        if (d->richText) {
+            d->ensureDoc();
+            d->doc->setText(d->text);
+            d->rightToLeftText = d->doc->toPlainText().isRightToLeft();
+            d->richTextAsImage = enableImageCache();
+        } else {
+            d->rightToLeftText = d->text.isRightToLeft();
+        }
+        d->determineHorizontalAlignment();
+        d->updateLayout();
+    }
+}
+
+
+QString QQuickTextPrivate::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 QQuickTextPrivate::isLinkActivatedConnected()
+{
+    static int idx = this->signalIndex("linkActivated(QString)");
+    return this->isSignalConnected(idx);
+}
+
+/*!  \internal */
+void QQuickText::mousePressEvent(QMouseEvent *event)
+{
+    Q_D(QQuickText);
+
+    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())
+        QQuickItem::mousePressEvent(event);
+
+}
+
+/*! \internal */
+void QQuickText::mouseReleaseEvent(QMouseEvent *event)
+{
+    Q_D(QQuickText);
+
+    // ### 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);
+
+    if (!event->isAccepted())
+        QQuickItem::mouseReleaseEvent(event);
+}
+
+QT_END_NAMESPACE
+
+#include "qquicktext.moc"
diff --git a/src/declarative/items/qquicktext_p.h b/src/declarative/items/qquicktext_p.h
new file mode 100644 (file)
index 0000000..be77f2e
--- /dev/null
@@ -0,0 +1,252 @@
+// Commit: 27e4302b7f45f22180693d26747f419177c81e27
+/****************************************************************************
+**
+** 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 QQUICKTEXT_P_H
+#define QQUICKTEXT_P_H
+
+#include "qquickimplicitsizeitem_p.h"
+
+#include <private/qdeclarativeglobal_p.h>
+
+#include <QtGui/qtextoption.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class QQuickTextPrivate;
+class QQuickTextLine;
+class Q_DECLARATIVE_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem
+{
+    Q_OBJECT
+    Q_ENUMS(HAlignment)
+    Q_ENUMS(VAlignment)
+    Q_ENUMS(TextStyle)
+    Q_ENUMS(TextFormat)
+    Q_ENUMS(TextElideMode)
+    Q_ENUMS(WrapMode)
+    Q_ENUMS(LineHeightMode)
+
+    Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
+    Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
+    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
+    Q_PROPERTY(TextStyle style READ style WRITE setStyle NOTIFY styleChanged)
+    Q_PROPERTY(QColor styleColor READ styleColor WRITE setStyleColor NOTIFY styleColorChanged)
+    Q_PROPERTY(HAlignment horizontalAlignment READ hAlign WRITE setHAlign RESET resetHAlign NOTIFY horizontalAlignmentChanged)
+    Q_PROPERTY(HAlignment effectiveHorizontalAlignment READ effectiveHAlign NOTIFY effectiveHorizontalAlignmentChanged)
+    Q_PROPERTY(VAlignment verticalAlignment READ vAlign WRITE setVAlign NOTIFY verticalAlignmentChanged)
+    Q_PROPERTY(WrapMode wrapMode READ wrapMode WRITE setWrapMode NOTIFY wrapModeChanged)
+    Q_PROPERTY(int lineCount READ lineCount NOTIFY lineCountChanged)
+    Q_PROPERTY(bool truncated READ truncated NOTIFY truncatedChanged)
+    Q_PROPERTY(int maximumLineCount READ maximumLineCount WRITE setMaximumLineCount NOTIFY maximumLineCountChanged RESET resetMaximumLineCount)
+
+    Q_PROPERTY(TextFormat textFormat READ textFormat WRITE setTextFormat NOTIFY textFormatChanged)
+    Q_PROPERTY(TextElideMode elide READ elideMode WRITE setElideMode NOTIFY elideModeChanged) //### elideMode?
+    Q_PROPERTY(qreal paintedWidth READ paintedWidth NOTIFY paintedSizeChanged)
+    Q_PROPERTY(qreal paintedHeight READ paintedHeight NOTIFY paintedSizeChanged)
+    Q_PROPERTY(qreal lineHeight READ lineHeight WRITE setLineHeight NOTIFY lineHeightChanged)
+    Q_PROPERTY(LineHeightMode lineHeightMode READ lineHeightMode WRITE setLineHeightMode NOTIFY lineHeightModeChanged)
+
+public:
+    QQuickText(QQuickItem *parent=0);
+    ~QQuickText();
+
+    enum HAlignment { AlignLeft = Qt::AlignLeft,
+                       AlignRight = Qt::AlignRight,
+                       AlignHCenter = Qt::AlignHCenter,
+                       AlignJustify = Qt::AlignJustify };
+    enum VAlignment { AlignTop = Qt::AlignTop,
+                       AlignBottom = Qt::AlignBottom,
+                       AlignVCenter = Qt::AlignVCenter };
+    enum TextStyle { Normal,
+                      Outline,
+                      Raised,
+                      Sunken };
+    enum TextFormat { PlainText = Qt::PlainText,
+                       RichText = Qt::RichText,
+                       AutoText = Qt::AutoText,
+                       StyledText = 4 };
+    enum TextElideMode { ElideLeft = Qt::ElideLeft,
+                          ElideRight = Qt::ElideRight,
+                          ElideMiddle = Qt::ElideMiddle,
+                          ElideNone = Qt::ElideNone };
+
+    enum WrapMode { NoWrap = QTextOption::NoWrap,
+                    WordWrap = QTextOption::WordWrap,
+                    WrapAnywhere = QTextOption::WrapAnywhere,
+                    WrapAtWordBoundaryOrAnywhere = QTextOption::WrapAtWordBoundaryOrAnywhere, // COMPAT
+                    Wrap = QTextOption::WrapAtWordBoundaryOrAnywhere
+                  };
+
+    enum LineHeightMode { ProportionalHeight, FixedHeight };
+
+    QString text() const;
+    void setText(const QString &);
+
+    QFont font() const;
+    void setFont(const QFont &font);
+
+    QColor color() const;
+    void setColor(const QColor &c);
+
+    TextStyle style() const;
+    void setStyle(TextStyle style);
+
+    QColor styleColor() const;
+    void setStyleColor(const QColor &c);
+
+    HAlignment hAlign() const;
+    void setHAlign(HAlignment align);
+    void resetHAlign();
+    HAlignment effectiveHAlign() const;
+
+    VAlignment vAlign() const;
+    void setVAlign(VAlignment align);
+
+    WrapMode wrapMode() const;
+    void setWrapMode(WrapMode w);
+
+    int lineCount() const;
+    bool truncated() const;
+
+    int maximumLineCount() const;
+    void setMaximumLineCount(int lines);
+    void resetMaximumLineCount();
+
+    TextFormat textFormat() const;
+    void setTextFormat(TextFormat format);
+
+    TextElideMode elideMode() const;
+    void setElideMode(TextElideMode);
+
+    qreal lineHeight() const;
+    void setLineHeight(qreal lineHeight);
+
+    LineHeightMode lineHeightMode() const;
+    void setLineHeightMode(LineHeightMode);
+
+    virtual void componentComplete();
+
+    int resourcesLoading() const; // mainly for testing
+
+    qreal paintedWidth() const;
+    qreal paintedHeight() const;
+
+    QRectF boundingRect() const;
+    Q_INVOKABLE void doLayout();
+
+Q_SIGNALS:
+    void textChanged(const QString &text);
+    void linkActivated(const QString &link);
+    void fontChanged(const QFont &font);
+    void colorChanged(const QColor &color);
+    void styleChanged(TextStyle style);
+    void styleColorChanged(const QColor &color);
+    void horizontalAlignmentChanged(HAlignment alignment);
+    void verticalAlignmentChanged(VAlignment alignment);
+    void wrapModeChanged();
+    void lineCountChanged();
+    void truncatedChanged();
+    void maximumLineCountChanged();
+    void textFormatChanged(TextFormat textFormat);
+    void elideModeChanged(TextElideMode mode);
+    void paintedSizeChanged();
+    void lineHeightChanged(qreal lineHeight);
+    void lineHeightModeChanged(LineHeightMode mode);
+    void effectiveHorizontalAlignmentChanged();
+    void lineLaidOut(QQuickTextLine *line);
+
+protected:
+    void mousePressEvent(QMouseEvent *event);
+    void mouseReleaseEvent(QMouseEvent *event);
+    virtual void geometryChanged(const QRectF &newGeometry,
+                                 const QRectF &oldGeometry);
+    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+    virtual bool event(QEvent *);
+
+private:
+    Q_DISABLE_COPY(QQuickText)
+    Q_DECLARE_PRIVATE(QQuickText)
+};
+
+class QTextLine;
+class Q_AUTOTEST_EXPORT QQuickTextLine : 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:
+    QQuickTextLine();
+
+    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(QQuickText)
+QML_DECLARE_TYPE(QQuickTextLine)
+
+QT_END_HEADER
+
+#endif // QQUICKTEXT_P_H
diff --git a/src/declarative/items/qquicktext_p_p.h b/src/declarative/items/qquicktext_p_p.h
new file mode 100644 (file)
index 0000000..16cc29a
--- /dev/null
@@ -0,0 +1,168 @@
+// Commit: 6e5a642c9484536fc173714f560f739944368cf5
+/****************************************************************************
+**
+** 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 QQUICKTEXT_P_P_H
+#define QQUICKTEXT_P_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 "qquickitem.h"
+#include "qquickimplicitsizeitem_p_p.h"
+
+#include <QtDeclarative/qdeclarative.h>
+#include <QtGui/qtextlayout.h>
+
+QT_BEGIN_NAMESPACE
+
+class QTextLayout;
+class QQuickTextDocumentWithImageResources;
+class QSGPlainTexture;
+
+class Q_AUTOTEST_EXPORT QQuickTextPrivate : public QQuickImplicitSizeItemPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickText)
+public:
+    QQuickTextPrivate();
+    ~QQuickTextPrivate();
+    void init();
+
+    void updateSize();
+    void updateLayout();
+    bool determineHorizontalAlignment();
+    bool setHAlign(QQuickText::HAlignment, bool forceAlign = false);
+    void mirrorChange();
+    QTextDocument *textDocument();
+    bool isLineLaidOutConnected();
+
+    QString text;
+    QFont font;
+    QFont sourceFont;
+    QColor  color;
+    QQuickText::TextStyle style;
+    QColor  styleColor;
+    QString activeLink;
+    QQuickText::HAlignment hAlign;
+    QQuickText::VAlignment vAlign;
+    QQuickText::TextElideMode elideMode;
+    QQuickText::TextFormat format;
+    QQuickText::WrapMode wrapMode;
+    qreal lineHeight;
+    QQuickText::LineHeightMode lineHeightMode;
+    int lineCount;
+    int maximumLineCount;
+    int maximumLineCountValid;
+    QPointF elidePos;
+
+    static QString elideChar;
+
+    void invalidateImageCache();
+    void checkImageCache();
+    QPixmap imageCache;
+    QSGTexture *texture;
+
+    bool imageCacheDirty:1;
+    bool updateOnComponentComplete:1;
+    bool richText:1;
+    bool styledText:1;
+    bool singleline:1;
+    bool cacheAllTextAsImage:1;
+    bool internalWidthUpdate:1;
+    bool requireImplicitWidth:1;
+    bool truncated:1;
+    bool hAlignImplicit:1;
+    bool rightToLeftText:1;
+    bool layoutTextElided:1;
+    bool richTextAsImage:1;
+    bool textureImageCacheDirty:1;
+    bool textHasChanged:1;
+
+    QRect layedOutTextRect;
+    QSize paintedSize;
+    qreal naturalWidth;
+    virtual qreal getImplicitWidth() const;
+
+    void ensureDoc();
+    QPixmap textDocumentImage(bool drawStyle);
+    QQuickTextDocumentWithImageResources *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;
+    QQuickTextLine *textLine;
+
+    static QPixmap drawOutline(const QPixmap &source, const QPixmap &styleSource);
+    static QPixmap drawOutline(const QPixmap &source, const QPixmap &styleSource, int yOffset);
+
+    static inline QQuickTextPrivate *get(QQuickText *t) {
+        return t->d_func();
+    }
+
+    enum NodeType {
+        NodeIsNull,
+        NodeIsTexture,
+        NodeIsText
+    };
+    NodeType nodeType;
+
+#if defined(Q_OS_MAC)
+    QThread *layoutThread;
+    QThread *paintingThread;
+#endif
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKTEXT_P_P_H
diff --git a/src/declarative/items/qquicktextedit.cpp b/src/declarative/items/qquicktextedit.cpp
new file mode 100644 (file)
index 0000000..75f60bc
--- /dev/null
@@ -0,0 +1,1976 @@
+/****************************************************************************
+**
+** 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 "qquicktextedit_p.h"
+#include "qquicktextedit_p_p.h"
+#include "qquickevents_p_p.h"
+#include "qquickcanvas.h"
+#include "qquicktextnode_p.h"
+#include "qsgsimplerectnode.h"
+
+#include <QtDeclarative/qdeclarativeinfo.h>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qevent.h>
+#include <QtGui/qpainter.h>
+#include <QtGui/qtextobject.h>
+#include <QtCore/qmath.h>
+
+#include <private/qdeclarativeglobal_p.h>
+#include <private/qtextcontrol_p.h>
+#include <private/qtextengine_p.h>
+#include <private/qsgdistancefieldglyphcache_p.h>
+#include <private/qsgtexture_p.h>
+#include <private/qsgadaptationlayer_p.h>
+
+QT_BEGIN_NAMESPACE
+
+DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
+DEFINE_BOOL_CONFIG_OPTION(qmlEnableImageCache, QML_ENABLE_TEXT_IMAGE_CACHE)
+
+/*!
+    \qmlclass TextEdit QQuickTextEdit
+    \inqmlmodule QtQuick 2
+    \ingroup qml-basic-visual-elements
+    \brief The TextEdit item displays multiple lines of editable formatted text.
+    \inherits Item
+
+    The TextEdit item displays a block of editable, formatted text.
+
+    It can display both plain and rich text. For example:
+
+    \qml
+TextEdit {
+    width: 240
+    text: "<b>Hello</b> <i>World!</i>"
+    font.family: "Helvetica"
+    font.pointSize: 20
+    color: "blue"
+    focus: true
+}
+    \endqml
+
+    \image declarative-textedit.gif
+
+    Setting \l {Item::focus}{focus} to \c true enables the TextEdit item to receive keyboard focus.
+
+    Note that the TextEdit does not implement scrolling, following the cursor, or other behaviors specific
+    to a look-and-feel. For example, to add flickable scrolling that follows the cursor:
+
+    \snippet snippets/declarative/texteditor.qml 0
+
+    A particular look-and-feel might use smooth scrolling (eg. using SmoothedFollow), might have a visible
+    scrollbar, or a scrollbar that fades in to show location, etc.
+
+    Clipboard support is provided by the cut(), copy(), and paste() functions, and the selection can
+    be handled in a traditional "mouse" mechanism by setting selectByMouse, or handled completely
+    from QML by manipulating selectionStart and selectionEnd, or using selectAll() or selectWord().
+
+    You can translate between cursor positions (characters from the start of the document) and pixel
+    points using positionAt() and positionToRectangle().
+
+    \sa Text, TextInput, {declarative/text/textselection}{Text Selection example}
+*/
+
+/*!
+    \qmlsignal QtQuick2::TextEdit::onLinkActivated(string link)
+
+    This handler is called when the user clicks on a link embedded in the text.
+    The link must be in rich text or HTML format and the
+    \a link string provides access to the particular link.
+*/
+QQuickTextEdit::QQuickTextEdit(QQuickItem *parent)
+: QQuickImplicitSizeItem(*(new QQuickTextEditPrivate), parent)
+{
+    Q_D(QQuickTextEdit);
+    d->init();
+}
+
+QString QQuickTextEdit::text() const
+{
+    Q_D(const QQuickTextEdit);
+
+#ifndef QT_NO_TEXTHTMLPARSER
+    if (d->richText)
+        return d->document->toHtml();
+    else
+#endif
+        return d->document->toPlainText();
+}
+
+/*!
+    \qmlproperty string QtQuick2::TextEdit::font.family
+
+    Sets the family name of the font.
+
+    The family name is case insensitive and may optionally include a foundry name, e.g. "Helvetica [Cronyx]".
+    If the family is available from more than one foundry and the foundry isn't specified, an arbitrary foundry is chosen.
+    If the family isn't available a family will be set using the font matching algorithm.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::TextEdit::font.bold
+
+    Sets whether the font weight is bold.
+*/
+
+/*!
+    \qmlproperty enumeration QtQuick2::TextEdit::font.weight
+
+    Sets the font's weight.
+
+    The weight can be one of:
+    \list
+    \o Font.Light
+    \o Font.Normal - the default
+    \o Font.DemiBold
+    \o Font.Bold
+    \o Font.Black
+    \endlist
+
+    \qml
+    TextEdit { text: "Hello"; font.weight: Font.DemiBold }
+    \endqml
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::TextEdit::font.italic
+
+    Sets whether the font has an italic style.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::TextEdit::font.underline
+
+    Sets whether the text is underlined.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::TextEdit::font.strikeout
+
+    Sets whether the font has a strikeout style.
+*/
+
+/*!
+    \qmlproperty real QtQuick2::TextEdit::font.pointSize
+
+    Sets the font size in points. The point size must be greater than zero.
+*/
+
+/*!
+    \qmlproperty int QtQuick2::TextEdit::font.pixelSize
+
+    Sets the font size in pixels.
+
+    Using this function makes the font device dependent.  Use
+    \l{TextEdit::font.pointSize} to set the size of the font in a
+    device independent manner.
+*/
+
+/*!
+    \qmlproperty real QtQuick2::TextEdit::font.letterSpacing
+
+    Sets the letter spacing for the font.
+
+    Letter spacing changes the default spacing between individual letters in the font.
+    A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing.
+*/
+
+/*!
+    \qmlproperty real QtQuick2::TextEdit::font.wordSpacing
+
+    Sets the word spacing for the font.
+
+    Word spacing changes the default spacing between individual words.
+    A positive value increases the word spacing by a corresponding amount of pixels,
+    while a negative value decreases the inter-word spacing accordingly.
+*/
+
+/*!
+    \qmlproperty enumeration QtQuick2::TextEdit::font.capitalization
+
+    Sets the capitalization for the text.
+
+    \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.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character.
+    \endlist
+
+    \qml
+    TextEdit { text: "Hello"; font.capitalization: Font.AllLowercase }
+    \endqml
+*/
+
+/*!
+    \qmlproperty string QtQuick2::TextEdit::text
+
+    The text to display.  If the text format is AutoText the text edit will
+    automatically determine whether the text should be treated as
+    rich text.  This determination is made using Qt::mightBeRichText().
+*/
+void QQuickTextEdit::setText(const QString &text)
+{
+    Q_D(QQuickTextEdit);
+    if (QQuickTextEdit::text() == text)
+        return;
+
+    d->richText = d->format == RichText || (d->format == AutoText && Qt::mightBeRichText(text));
+    if (d->richText) {
+#ifndef QT_NO_TEXTHTMLPARSER
+        d->control->setHtml(text);
+#else
+        d->control->setPlainText(text);
+#endif
+        d->useImageFallback = qmlEnableImageCache();
+    } else {
+        d->control->setPlainText(text);
+    }
+    q_textChanged();
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::TextEdit::textFormat
+
+    The way the text property should be displayed.
+
+    \list
+    \o TextEdit.AutoText
+    \o TextEdit.PlainText
+    \o TextEdit.RichText
+    \endlist
+
+    The default is TextEdit.AutoText.  If the text format is TextEdit.AutoText the text edit
+    will automatically determine whether the text should be treated as
+    rich text.  This determination is made using Qt::mightBeRichText().
+
+    \table
+    \row
+    \o
+    \qml
+Column {
+    TextEdit {
+        font.pointSize: 24
+        text: "<b>Hello</b> <i>World!</i>"
+    }
+    TextEdit {
+        font.pointSize: 24
+        textFormat: TextEdit.RichText
+        text: "<b>Hello</b> <i>World!</i>"
+    }
+    TextEdit {
+        font.pointSize: 24
+        textFormat: TextEdit.PlainText
+        text: "<b>Hello</b> <i>World!</i>"
+    }
+}
+    \endqml
+    \o \image declarative-textformat.png
+    \endtable
+*/
+QQuickTextEdit::TextFormat QQuickTextEdit::textFormat() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->format;
+}
+
+void QQuickTextEdit::setTextFormat(TextFormat format)
+{
+    Q_D(QQuickTextEdit);
+    if (format == d->format)
+        return;
+    bool wasRich = d->richText;
+    d->richText = format == RichText || (format == AutoText && Qt::mightBeRichText(d->text));
+
+    if (wasRich && !d->richText) {
+        d->control->setPlainText(d->text);
+        updateSize();
+    } else if (!wasRich && d->richText) {
+#ifndef QT_NO_TEXTHTMLPARSER
+        d->control->setHtml(d->text);
+#else
+        d->control->setPlainText(d->text);
+#endif
+        updateSize();
+        d->useImageFallback = qmlEnableImageCache();
+    }
+    d->format = format;
+    d->control->setAcceptRichText(d->format != PlainText);
+    emit textFormatChanged(d->format);
+}
+
+QFont QQuickTextEdit::font() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->sourceFont;
+}
+
+void QQuickTextEdit::setFont(const QFont &font)
+{
+    Q_D(QQuickTextEdit);
+    if (d->sourceFont == font)
+        return;
+
+    d->sourceFont = font;
+    QFont oldFont = d->font;
+    d->font = font;
+    if (d->font.pointSizeF() != -1) {
+        // 0.5pt resolution
+        qreal size = qRound(d->font.pointSizeF()*2.0);
+        d->font.setPointSizeF(size/2.0);
+    }
+
+    if (oldFont != d->font) {
+        d->document->setDefaultFont(d->font);
+        if (d->cursor) {
+            d->cursor->setHeight(QFontMetrics(d->font).height());
+            moveCursorDelegate();
+        }
+        updateSize();
+        updateDocument();
+    }
+    emit fontChanged(d->sourceFont);
+}
+
+/*!
+    \qmlproperty color QtQuick2::TextEdit::color
+
+    The text color.
+
+    \qml
+    // green text using hexadecimal notation
+    TextEdit { color: "#00FF00" }
+    \endqml
+
+    \qml
+    // steelblue text using SVG color name
+    TextEdit { color: "steelblue" }
+    \endqml
+*/
+QColor QQuickTextEdit::color() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->color;
+}
+
+void QQuickTextEdit::setColor(const QColor &color)
+{
+    Q_D(QQuickTextEdit);
+    if (d->color == color)
+        return;
+
+    d->color = color;
+    QPalette pal = d->control->palette();
+    pal.setColor(QPalette::Text, color);
+    d->control->setPalette(pal);
+    updateDocument();
+    emit colorChanged(d->color);
+}
+
+/*!
+    \qmlproperty color QtQuick2::TextEdit::selectionColor
+
+    The text highlight color, used behind selections.
+*/
+QColor QQuickTextEdit::selectionColor() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->selectionColor;
+}
+
+void QQuickTextEdit::setSelectionColor(const QColor &color)
+{
+    Q_D(QQuickTextEdit);
+    if (d->selectionColor == color)
+        return;
+
+    d->selectionColor = color;
+    QPalette pal = d->control->palette();
+    pal.setColor(QPalette::Highlight, color);
+    d->control->setPalette(pal);
+    updateDocument();
+    emit selectionColorChanged(d->selectionColor);
+}
+
+/*!
+    \qmlproperty color QtQuick2::TextEdit::selectedTextColor
+
+    The selected text color, used in selections.
+*/
+QColor QQuickTextEdit::selectedTextColor() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->selectedTextColor;
+}
+
+void QQuickTextEdit::setSelectedTextColor(const QColor &color)
+{
+    Q_D(QQuickTextEdit);
+    if (d->selectedTextColor == color)
+        return;
+
+    d->selectedTextColor = color;
+    QPalette pal = d->control->palette();
+    pal.setColor(QPalette::HighlightedText, color);
+    d->control->setPalette(pal);
+    updateDocument();
+    emit selectedTextColorChanged(d->selectedTextColor);
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::TextEdit::horizontalAlignment
+    \qmlproperty enumeration QtQuick2::TextEdit::verticalAlignment
+    \qmlproperty enumeration QtQuick2::TextEdit::effectiveHorizontalAlignment
+
+    Sets the horizontal and vertical alignment of the text within the TextEdit item's
+    width and height. By default, the text alignment follows the natural alignment
+    of the text, for example text that is read from left to right will be aligned to
+    the left.
+
+    Valid values for \c horizontalAlignment are:
+    \list
+    \o TextEdit.AlignLeft (default)
+    \o TextEdit.AlignRight
+    \o TextEdit.AlignHCenter
+    \o TextEdit.AlignJustify
+    \endlist
+
+    Valid values for \c verticalAlignment are:
+    \list
+    \o TextEdit.AlignTop (default)
+    \o TextEdit.AlignBottom
+    \o TextEdit.AlignVCenter
+    \endlist
+
+    When using the attached property LayoutMirroring::enabled to mirror application
+    layouts, the horizontal alignment of text will also be mirrored. However, the property
+    \c horizontalAlignment will remain unchanged. To query the effective horizontal alignment
+    of TextEdit, use the read-only property \c effectiveHorizontalAlignment.
+*/
+QQuickTextEdit::HAlignment QQuickTextEdit::hAlign() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->hAlign;
+}
+
+void QQuickTextEdit::setHAlign(HAlignment align)
+{
+    Q_D(QQuickTextEdit);
+    bool forceAlign = d->hAlignImplicit && d->effectiveLayoutMirror;
+    d->hAlignImplicit = false;
+    if (d->setHAlign(align, forceAlign) && isComponentComplete()) {
+        d->updateDefaultTextOption();
+        updateSize();
+    }
+}
+
+void QQuickTextEdit::resetHAlign()
+{
+    Q_D(QQuickTextEdit);
+    d->hAlignImplicit = true;
+    if (d->determineHorizontalAlignment() && isComponentComplete()) {
+        d->updateDefaultTextOption();
+        updateSize();
+    }
+}
+
+QQuickTextEdit::HAlignment QQuickTextEdit::effectiveHAlign() const
+{
+    Q_D(const QQuickTextEdit);
+    QQuickTextEdit::HAlignment effectiveAlignment = d->hAlign;
+    if (!d->hAlignImplicit && d->effectiveLayoutMirror) {
+        switch (d->hAlign) {
+        case QQuickTextEdit::AlignLeft:
+            effectiveAlignment = QQuickTextEdit::AlignRight;
+            break;
+        case QQuickTextEdit::AlignRight:
+            effectiveAlignment = QQuickTextEdit::AlignLeft;
+            break;
+        default:
+            break;
+        }
+    }
+    return effectiveAlignment;
+}
+
+bool QQuickTextEditPrivate::setHAlign(QQuickTextEdit::HAlignment alignment, bool forceAlign)
+{
+    Q_Q(QQuickTextEdit);
+    if (hAlign != alignment || forceAlign) {
+        QQuickTextEdit::HAlignment oldEffectiveHAlign = q->effectiveHAlign();
+        hAlign = alignment;
+        emit q->horizontalAlignmentChanged(alignment);
+        if (oldEffectiveHAlign != q->effectiveHAlign())
+            emit q->effectiveHorizontalAlignmentChanged();
+        return true;
+    }
+    return false;
+}
+
+bool QQuickTextEditPrivate::determineHorizontalAlignment()
+{
+    Q_Q(QQuickTextEdit);
+    if (hAlignImplicit && q->isComponentComplete()) {
+        bool alignToRight = text.isEmpty() ? QGuiApplication::keyboardInputDirection() == Qt::RightToLeft : rightToLeftText;
+        return setHAlign(alignToRight ? QQuickTextEdit::AlignRight : QQuickTextEdit::AlignLeft);
+    }
+    return false;
+}
+
+void QQuickTextEditPrivate::mirrorChange()
+{
+    Q_Q(QQuickTextEdit);
+    if (q->isComponentComplete()) {
+        if (!hAlignImplicit && (hAlign == QQuickTextEdit::AlignRight || hAlign == QQuickTextEdit::AlignLeft)) {
+            updateDefaultTextOption();
+            q->updateSize();
+            emit q->effectiveHorizontalAlignmentChanged();
+        }
+    }
+}
+
+QQuickTextEdit::VAlignment QQuickTextEdit::vAlign() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->vAlign;
+}
+
+void QQuickTextEdit::setVAlign(QQuickTextEdit::VAlignment alignment)
+{
+    Q_D(QQuickTextEdit);
+    if (alignment == d->vAlign)
+        return;
+    d->vAlign = alignment;
+    d->updateDefaultTextOption();
+    updateSize();
+    moveCursorDelegate();
+    emit verticalAlignmentChanged(d->vAlign);
+}
+/*!
+    \qmlproperty enumeration QtQuick2::TextEdit::wrapMode
+
+    Set this property to wrap the text to the TextEdit item's width.
+    The text will only wrap if an explicit width has been set.
+
+    \list
+    \o TextEdit.NoWrap - no wrapping will be performed. If the text contains insufficient newlines, then implicitWidth will exceed a set width.
+    \o TextEdit.WordWrap - wrapping is done on word boundaries only. If a word is too long, implicitWidth will exceed a set width.
+    \o TextEdit.WrapAnywhere - wrapping is done at any point on a line, even if it occurs in the middle of a word.
+    \o TextEdit.Wrap - if possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word.
+    \endlist
+
+    The default is TextEdit.NoWrap. If you set a width, consider using TextEdit.Wrap.
+*/
+QQuickTextEdit::WrapMode QQuickTextEdit::wrapMode() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->wrapMode;
+}
+
+void QQuickTextEdit::setWrapMode(WrapMode mode)
+{
+    Q_D(QQuickTextEdit);
+    if (mode == d->wrapMode)
+        return;
+    d->wrapMode = mode;
+    d->updateDefaultTextOption();
+    updateSize();
+    emit wrapModeChanged();
+}
+
+/*!
+    \qmlproperty int QtQuick2::TextEdit::lineCount
+
+    Returns the total number of lines in the textEdit item.
+*/
+int QQuickTextEdit::lineCount() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->lineCount;
+}
+
+/*!
+    \qmlproperty real QtQuick2::TextEdit::paintedWidth
+
+    Returns the width of the text, including the width past the width
+    which is covered due to insufficient wrapping if \l wrapMode is set.
+*/
+qreal QQuickTextEdit::paintedWidth() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->paintedSize.width();
+}
+
+/*!
+    \qmlproperty real QtQuick2::TextEdit::paintedHeight
+
+    Returns the height of the text, including the height past the height
+    that is covered if the text does not fit within the set height.
+*/
+qreal QQuickTextEdit::paintedHeight() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->paintedSize.height();
+}
+
+/*!
+    \qmlmethod rectangle QtQuick2::TextEdit::positionToRectangle(position)
+
+    Returns the rectangle at the given \a position in the text. The x, y,
+    and height properties correspond to the cursor that would describe
+    that position.
+*/
+QRectF QQuickTextEdit::positionToRectangle(int pos) const
+{
+    Q_D(const QQuickTextEdit);
+    QTextCursor c(d->document);
+    c.setPosition(pos);
+    return d->control->cursorRect(c);
+
+}
+
+/*!
+    \qmlmethod int QtQuick2::TextEdit::positionAt(int x, int y)
+
+    Returns the text position closest to pixel position (\a x, \a y).
+
+    Position 0 is before the first character, position 1 is after the first character
+    but before the second, and so on until position \l {text}.length, which is after all characters.
+*/
+int QQuickTextEdit::positionAt(int x, int y) const
+{
+    Q_D(const QQuickTextEdit);
+    int r = d->document->documentLayout()->hitTest(QPoint(x,y-d->yoff), Qt::FuzzyHit);
+    QTextCursor cursor = d->control->textCursor();
+    if (r > cursor.position()) {
+        // The cursor position includes positions within the preedit text, but only positions in the
+        // same text block are offset so it is possible to get a position that is either part of the
+        // preedit or the next text block.
+        QTextLayout *layout = cursor.block().layout();
+        const int preeditLength = layout
+                ? layout->preeditAreaText().length()
+                : 0;
+        if (preeditLength > 0
+                && d->document->documentLayout()->blockBoundingRect(cursor.block()).contains(x,y-d->yoff)) {
+            r = r > cursor.position() + preeditLength
+                    ? r - preeditLength
+                    : cursor.position();
+        }
+    }
+    return r;
+}
+
+/*!
+    \qmlmethod void QtQuick2::TextEdit::moveCursorSelection(int position, SelectionMode mode = TextEdit.SelectCharacters)
+
+    Moves the cursor to \a position and updates the selection according to the optional \a mode
+    parameter. (To only move the cursor, set the \l cursorPosition property.)
+
+    When this method is called it additionally sets either the
+    selectionStart or the selectionEnd (whichever was at the previous cursor position)
+    to the specified position. This allows you to easily extend and contract the selected
+    text range.
+
+    The selection mode specifies whether the selection is updated on a per character or a per word
+    basis.  If not specified the selection mode will default to TextEdit.SelectCharacters.
+
+    \list
+    \o TextEdit.SelectCharacters - Sets either the selectionStart or selectionEnd (whichever was at
+    the previous cursor position) to the specified position.
+    \o TextEdit.SelectWords - Sets the selectionStart and selectionEnd to include all
+    words between the specified postion and the previous cursor position.  Words partially in the
+    range are included.
+    \endlist
+
+    For example, take this sequence of calls:
+
+    \code
+        cursorPosition = 5
+        moveCursorSelection(9, TextEdit.SelectCharacters)
+        moveCursorSelection(7, TextEdit.SelectCharacters)
+    \endcode
+
+    This moves the cursor to position 5, extend the selection end from 5 to 9
+    and then retract the selection end from 9 to 7, leaving the text from position 5 to 7
+    selected (the 6th and 7th characters).
+
+    The same sequence with TextEdit.SelectWords will extend the selection start to a word boundary
+    before or on position 5 and extend the selection end to a word boundary on or past position 9.
+*/
+void QQuickTextEdit::moveCursorSelection(int pos)
+{
+    //Note that this is the same as setCursorPosition but with the KeepAnchor flag set
+    Q_D(QQuickTextEdit);
+    QTextCursor cursor = d->control->textCursor();
+    if (cursor.position() == pos)
+        return;
+    cursor.setPosition(pos, QTextCursor::KeepAnchor);
+    d->control->setTextCursor(cursor);
+}
+
+void QQuickTextEdit::moveCursorSelection(int pos, SelectionMode mode)
+{
+    Q_D(QQuickTextEdit);
+    QTextCursor cursor = d->control->textCursor();
+    if (cursor.position() == pos)
+        return;
+    if (mode == SelectCharacters) {
+        cursor.setPosition(pos, QTextCursor::KeepAnchor);
+    } else if (cursor.anchor() < pos || (cursor.anchor() == pos && cursor.position() < pos)) {
+        if (cursor.anchor() > cursor.position()) {
+            cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
+            cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
+            if (cursor.position() == cursor.anchor())
+                cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::MoveAnchor);
+            else
+                cursor.setPosition(cursor.position(), QTextCursor::MoveAnchor);
+        } else {
+            cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
+            cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
+        }
+
+        cursor.setPosition(pos, QTextCursor::KeepAnchor);
+        cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
+        if (cursor.position() != pos)
+            cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
+    } else if (cursor.anchor() > pos || (cursor.anchor() == pos && cursor.position() > pos)) {
+        if (cursor.anchor() < cursor.position()) {
+            cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
+            cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::MoveAnchor);
+        } else {
+            cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
+            cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor);
+            cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
+            if (cursor.position() != cursor.anchor()) {
+                cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
+                cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::MoveAnchor);
+            }
+        }
+
+        cursor.setPosition(pos, QTextCursor::KeepAnchor);
+        cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
+        if (cursor.position() != pos) {
+            cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor);
+            cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
+        }
+    }
+    d->control->setTextCursor(cursor);
+}
+
+/*!
+    \qmlproperty bool QtQuick2::TextEdit::cursorVisible
+    If true the text edit shows a cursor.
+
+    This property is set and unset when the text edit gets active focus, but it can also
+    be set directly (useful, for example, if a KeyProxy might forward keys to it).
+*/
+bool QQuickTextEdit::isCursorVisible() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->cursorVisible;
+}
+
+void QQuickTextEdit::setCursorVisible(bool on)
+{
+    Q_D(QQuickTextEdit);
+    if (d->cursorVisible == on)
+        return;
+    d->cursorVisible = on;
+    QFocusEvent focusEvent(on ? QEvent::FocusIn : QEvent::FocusOut);
+    if (!on && !d->persistentSelection)
+        d->control->setCursorIsFocusIndicator(true);
+    d->control->processEvent(&focusEvent, QPointF(0, -d->yoff));
+    emit cursorVisibleChanged(d->cursorVisible);
+}
+
+/*!
+    \qmlproperty int QtQuick2::TextEdit::cursorPosition
+    The position of the cursor in the TextEdit.
+*/
+int QQuickTextEdit::cursorPosition() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->control->textCursor().position();
+}
+
+void QQuickTextEdit::setCursorPosition(int pos)
+{
+    Q_D(QQuickTextEdit);
+    if (pos < 0 || pos > d->text.length())
+        return;
+    QTextCursor cursor = d->control->textCursor();
+    if (cursor.position() == pos && cursor.anchor() == pos)
+        return;
+    cursor.setPosition(pos);
+    d->control->setTextCursor(cursor);
+}
+
+/*!
+    \qmlproperty Component QtQuick2::TextEdit::cursorDelegate
+    The delegate for the cursor in the TextEdit.
+
+    If you set a cursorDelegate for a TextEdit, this delegate will be used for
+    drawing the cursor instead of the standard cursor. An instance of the
+    delegate will be created and managed by the text edit when a cursor is
+    needed, and the x and y properties of delegate instance will be set so as
+    to be one pixel before the top left of the current character.
+
+    Note that the root item of the delegate component must be a QDeclarativeItem or
+    QDeclarativeItem derived item.
+*/
+QDeclarativeComponent* QQuickTextEdit::cursorDelegate() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->cursorComponent;
+}
+
+void QQuickTextEdit::setCursorDelegate(QDeclarativeComponent* c)
+{
+    Q_D(QQuickTextEdit);
+    if (d->cursorComponent) {
+        if (d->cursor) {
+            d->control->setCursorWidth(-1);
+            updateCursor();
+            delete d->cursor;
+            d->cursor = 0;
+        }
+    }
+    d->cursorComponent = c;
+    if (c && c->isReady()) {
+        loadCursorDelegate();
+    } else {
+        if (c)
+            connect(c, SIGNAL(statusChanged()),
+                    this, SLOT(loadCursorDelegate()));
+    }
+
+    emit cursorDelegateChanged();
+}
+
+void QQuickTextEdit::loadCursorDelegate()
+{
+    Q_D(QQuickTextEdit);
+    if (d->cursorComponent->isLoading())
+        return;
+    QDeclarativeContext *creationContext = d->cursorComponent->creationContext();
+    QObject *object = d->cursorComponent->create(creationContext ? creationContext : qmlContext(this));
+    d->cursor = qobject_cast<QQuickItem*>(object);
+    if (d->cursor) {
+        d->control->setCursorWidth(0);
+        updateCursor();
+        QDeclarative_setParent_noEvent(d->cursor, this);
+        d->cursor->setParentItem(this);
+        d->cursor->setHeight(QFontMetrics(d->font).height());
+        moveCursorDelegate();
+    }else{
+        delete object;
+        qmlInfo(this) << "Error loading cursor delegate.";
+    }
+}
+
+/*!
+    \qmlproperty int QtQuick2::TextEdit::selectionStart
+
+    The cursor position before the first character in the current selection.
+
+    This property is read-only. To change the selection, use select(start,end),
+    selectAll(), or selectWord().
+
+    \sa selectionEnd, cursorPosition, selectedText
+*/
+int QQuickTextEdit::selectionStart() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->control->textCursor().selectionStart();
+}
+
+/*!
+    \qmlproperty int QtQuick2::TextEdit::selectionEnd
+
+    The cursor position after the last character in the current selection.
+
+    This property is read-only. To change the selection, use select(start,end),
+    selectAll(), or selectWord().
+
+    \sa selectionStart, cursorPosition, selectedText
+*/
+int QQuickTextEdit::selectionEnd() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->control->textCursor().selectionEnd();
+}
+
+/*!
+    \qmlproperty string QtQuick2::TextEdit::selectedText
+
+    This read-only property provides the text currently selected in the
+    text edit.
+
+    It is equivalent to the following snippet, but is faster and easier
+    to use.
+    \code
+    //myTextEdit is the id of the TextEdit
+    myTextEdit.text.toString().substring(myTextEdit.selectionStart,
+            myTextEdit.selectionEnd);
+    \endcode
+*/
+QString QQuickTextEdit::selectedText() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->control->textCursor().selectedText();
+}
+
+/*!
+    \qmlproperty bool QtQuick2::TextEdit::activeFocusOnPress
+
+    Whether the TextEdit should gain active focus on a mouse press. By default this is
+    set to true.
+*/
+bool QQuickTextEdit::focusOnPress() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->focusOnPress;
+}
+
+void QQuickTextEdit::setFocusOnPress(bool on)
+{
+    Q_D(QQuickTextEdit);
+    if (d->focusOnPress == on)
+        return;
+    d->focusOnPress = on;
+    emit activeFocusOnPressChanged(d->focusOnPress);
+}
+
+/*!
+    \qmlproperty bool QtQuick2::TextEdit::persistentSelection
+
+    Whether the TextEdit should keep the selection visible when it loses active focus to another
+    item in the scene. By default this is set to true;
+*/
+bool QQuickTextEdit::persistentSelection() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->persistentSelection;
+}
+
+void QQuickTextEdit::setPersistentSelection(bool on)
+{
+    Q_D(QQuickTextEdit);
+    if (d->persistentSelection == on)
+        return;
+    d->persistentSelection = on;
+    emit persistentSelectionChanged(d->persistentSelection);
+}
+
+/*
+   \qmlproperty real QtQuick2::TextEdit::textMargin
+
+   The margin, in pixels, around the text in the TextEdit.
+*/
+qreal QQuickTextEdit::textMargin() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->textMargin;
+}
+
+void QQuickTextEdit::setTextMargin(qreal margin)
+{
+    Q_D(QQuickTextEdit);
+    if (d->textMargin == margin)
+        return;
+    d->textMargin = margin;
+    d->document->setDocumentMargin(d->textMargin);
+    emit textMarginChanged(d->textMargin);
+}
+
+void QQuickTextEdit::geometryChanged(const QRectF &newGeometry,
+                                  const QRectF &oldGeometry)
+{
+    if (newGeometry.width() != oldGeometry.width())
+        updateSize();
+    QQuickImplicitSizeItem::geometryChanged(newGeometry, oldGeometry);
+}
+
+/*!
+    Ensures any delayed caching or data loading the class
+    needs to performed is complete.
+*/
+void QQuickTextEdit::componentComplete()
+{
+    Q_D(QQuickTextEdit);
+    QQuickImplicitSizeItem::componentComplete();
+
+    if (d->richText)
+        d->useImageFallback = qmlEnableImageCache();
+
+    if (d->dirty) {
+        d->determineHorizontalAlignment();
+        d->updateDefaultTextOption();
+        updateSize();
+        d->dirty = false;
+    }
+
+}
+/*!
+    \qmlproperty bool QtQuick2::TextEdit::selectByMouse
+
+    Defaults to false.
+
+    If true, the user can use the mouse to select text in some
+    platform-specific way. Note that for some platforms this may
+    not be an appropriate interaction (eg. may conflict with how
+    the text needs to behave inside a Flickable.
+*/
+bool QQuickTextEdit::selectByMouse() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->selectByMouse;
+}
+
+void QQuickTextEdit::setSelectByMouse(bool on)
+{
+    Q_D(QQuickTextEdit);
+    if (d->selectByMouse != on) {
+        d->selectByMouse = on;
+        setKeepMouseGrab(on);
+        if (on)
+            setTextInteractionFlags(d->control->textInteractionFlags() | Qt::TextSelectableByMouse);
+        else
+            setTextInteractionFlags(d->control->textInteractionFlags() & ~Qt::TextSelectableByMouse);
+        emit selectByMouseChanged(on);
+    }
+}
+
+/*!
+    \qmlproperty enum QtQuick2::TextEdit::mouseSelectionMode
+
+    Specifies how text should be selected using a mouse.
+
+    \list
+    \o TextEdit.SelectCharacters - The selection is updated with individual characters. (Default)
+    \o TextEdit.SelectWords - The selection is updated with whole words.
+    \endlist
+
+    This property only applies when \l selectByMouse is true.
+*/
+QQuickTextEdit::SelectionMode QQuickTextEdit::mouseSelectionMode() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->mouseSelectionMode;
+}
+
+void QQuickTextEdit::setMouseSelectionMode(SelectionMode mode)
+{
+    Q_D(QQuickTextEdit);
+    if (d->mouseSelectionMode != mode) {
+        d->mouseSelectionMode = mode;
+        d->control->setWordSelectionEnabled(mode == SelectWords);
+        emit mouseSelectionModeChanged(mode);
+    }
+}
+
+/*!
+    \qmlproperty bool QtQuick2::TextEdit::readOnly
+
+    Whether the user can interact with the TextEdit item. If this
+    property is set to true the text cannot be edited by user interaction.
+
+    By default this property is false.
+*/
+void QQuickTextEdit::setReadOnly(bool r)
+{
+    Q_D(QQuickTextEdit);
+    if (r == isReadOnly())
+        return;
+
+    setFlag(QQuickItem::ItemAcceptsInputMethod, !r);
+    Qt::TextInteractionFlags flags = Qt::LinksAccessibleByMouse;
+    if (d->selectByMouse)
+        flags = flags | Qt::TextSelectableByMouse;
+    if (!r)
+        flags = flags | Qt::TextSelectableByKeyboard | Qt::TextEditable;
+    d->control->setTextInteractionFlags(flags);
+    if (!r)
+        d->control->moveCursor(QTextCursor::End);
+
+    emit readOnlyChanged(r);
+}
+
+bool QQuickTextEdit::isReadOnly() const
+{
+    Q_D(const QQuickTextEdit);
+    return !(d->control->textInteractionFlags() & Qt::TextEditable);
+}
+
+/*!
+    Sets how the text edit should interact with user input to the given
+    \a flags.
+*/
+void QQuickTextEdit::setTextInteractionFlags(Qt::TextInteractionFlags flags)
+{
+    Q_D(QQuickTextEdit);
+    d->control->setTextInteractionFlags(flags);
+}
+
+/*!
+    Returns the flags specifying how the text edit should interact
+    with user input.
+*/
+Qt::TextInteractionFlags QQuickTextEdit::textInteractionFlags() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->control->textInteractionFlags();
+}
+
+/*!
+    \qmlproperty rectangle QtQuick2::TextEdit::cursorRectangle
+
+    The rectangle where the text cursor is rendered
+    within the text edit. Read-only.
+*/
+QRect QQuickTextEdit::cursorRectangle() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->control->cursorRect().toRect().translated(0,d->yoff);
+}
+
+bool QQuickTextEdit::event(QEvent *event)
+{
+    Q_D(QQuickTextEdit);
+    if (event->type() == QEvent::ShortcutOverride) {
+        d->control->processEvent(event, QPointF(0, -d->yoff));
+        return event->isAccepted();
+    }
+    return QQuickImplicitSizeItem::event(event);
+}
+
+/*!
+\overload
+Handles the given key \a event.
+*/
+void QQuickTextEdit::keyPressEvent(QKeyEvent *event)
+{
+    Q_D(QQuickTextEdit);
+    d->control->processEvent(event, QPointF(0, -d->yoff));
+    if (!event->isAccepted())
+        QQuickImplicitSizeItem::keyPressEvent(event);
+}
+
+/*!
+\overload
+Handles the given key \a event.
+*/
+void QQuickTextEdit::keyReleaseEvent(QKeyEvent *event)
+{
+    Q_D(QQuickTextEdit);
+    d->control->processEvent(event, QPointF(0, -d->yoff));
+    if (!event->isAccepted())
+        QQuickImplicitSizeItem::keyReleaseEvent(event);
+}
+
+/*!
+    \qmlmethod void QtQuick2::TextEdit::deselect()
+
+    Removes active text selection.
+*/
+void QQuickTextEdit::deselect()
+{
+    Q_D(QQuickTextEdit);
+    QTextCursor c = d->control->textCursor();
+    c.clearSelection();
+    d->control->setTextCursor(c);
+}
+
+/*!
+    \qmlmethod void QtQuick2::TextEdit::selectAll()
+
+    Causes all text to be selected.
+*/
+void QQuickTextEdit::selectAll()
+{
+    Q_D(QQuickTextEdit);
+    d->control->selectAll();
+}
+
+/*!
+    \qmlmethod void QtQuick2::TextEdit::selectWord()
+
+    Causes the word closest to the current cursor position to be selected.
+*/
+void QQuickTextEdit::selectWord()
+{
+    Q_D(QQuickTextEdit);
+    QTextCursor c = d->control->textCursor();
+    c.select(QTextCursor::WordUnderCursor);
+    d->control->setTextCursor(c);
+}
+
+/*!
+    \qmlmethod void QtQuick2::TextEdit::select(int start, int end)
+
+    Causes the text from \a start to \a end to be selected.
+
+    If either start or end is out of range, the selection is not changed.
+
+    After calling this, selectionStart will become the lesser
+    and selectionEnd will become the greater (regardless of the order passed
+    to this method).
+
+    \sa selectionStart, selectionEnd
+*/
+void QQuickTextEdit::select(int start, int end)
+{
+    Q_D(QQuickTextEdit);
+    if (start < 0 || end < 0 || start > d->text.length() || end > d->text.length())
+        return;
+    QTextCursor cursor = d->control->textCursor();
+    cursor.beginEditBlock();
+    cursor.setPosition(start, QTextCursor::MoveAnchor);
+    cursor.setPosition(end, QTextCursor::KeepAnchor);
+    cursor.endEditBlock();
+    d->control->setTextCursor(cursor);
+
+    // QTBUG-11100
+    updateSelectionMarkers();
+}
+
+/*!
+    \qmlmethod void QtQuick2::TextEdit::isRightToLeft(int start, int end)
+
+    Returns true if the natural reading direction of the editor text
+    found between positions \a start and \a end is right to left.
+*/
+bool QQuickTextEdit::isRightToLeft(int start, int end)
+{
+    Q_D(QQuickTextEdit);
+    if (start > end) {
+        qmlInfo(this) << "isRightToLeft(start, end) called with the end property being smaller than the start.";
+        return false;
+    } else {
+        return d->text.mid(start, end - start).isRightToLeft();
+    }
+}
+
+#ifndef QT_NO_CLIPBOARD
+/*!
+    \qmlmethod QtQuick2::TextEdit::cut()
+
+    Moves the currently selected text to the system clipboard.
+*/
+void QQuickTextEdit::cut()
+{
+    Q_D(QQuickTextEdit);
+    d->control->cut();
+}
+
+/*!
+    \qmlmethod QtQuick2::TextEdit::copy()
+
+    Copies the currently selected text to the system clipboard.
+*/
+void QQuickTextEdit::copy()
+{
+    Q_D(QQuickTextEdit);
+    d->control->copy();
+}
+
+/*!
+    \qmlmethod QtQuick2::TextEdit::paste()
+
+    Replaces the currently selected text by the contents of the system clipboard.
+*/
+void QQuickTextEdit::paste()
+{
+    Q_D(QQuickTextEdit);
+    d->control->paste();
+}
+#endif // QT_NO_CLIPBOARD
+
+/*!
+\overload
+Handles the given mouse \a event.
+*/
+void QQuickTextEdit::mousePressEvent(QMouseEvent *event)
+{
+    Q_D(QQuickTextEdit);
+    if (d->focusOnPress){
+        bool hadActiveFocus = hasActiveFocus();
+        forceActiveFocus();
+        // 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())
+        QQuickImplicitSizeItem::mousePressEvent(event);
+}
+
+/*!
+\overload
+Handles the given mouse \a event.
+*/
+void QQuickTextEdit::mouseReleaseEvent(QMouseEvent *event)
+{
+    Q_D(QQuickTextEdit);
+    d->control->processEvent(event, QPointF(0, -d->yoff));
+
+    if (!event->isAccepted())
+        QQuickImplicitSizeItem::mouseReleaseEvent(event);
+}
+
+/*!
+\overload
+Handles the given mouse \a event.
+*/
+void QQuickTextEdit::mouseDoubleClickEvent(QMouseEvent *event)
+{
+    Q_D(QQuickTextEdit);
+    d->control->processEvent(event, QPointF(0, -d->yoff));
+    if (!event->isAccepted())
+        QQuickImplicitSizeItem::mouseDoubleClickEvent(event);
+}
+
+/*!
+\overload
+Handles the given mouse \a event.
+*/
+void QQuickTextEdit::mouseMoveEvent(QMouseEvent *event)
+{
+    Q_D(QQuickTextEdit);
+    d->control->processEvent(event, QPointF(0, -d->yoff));
+    if (!event->isAccepted())
+        QQuickImplicitSizeItem::mouseMoveEvent(event);
+}
+
+/*!
+\overload
+Handles the given input method \a event.
+*/
+void QQuickTextEdit::inputMethodEvent(QInputMethodEvent *event)
+{
+    Q_D(QQuickTextEdit);
+    const bool wasComposing = isInputMethodComposing();
+    d->control->processEvent(event, QPointF(0, -d->yoff));
+    if (wasComposing != isInputMethodComposing())
+        emit inputMethodComposingChanged();
+}
+
+void QQuickTextEdit::itemChange(ItemChange change, const ItemChangeData &value)
+{
+    Q_D(QQuickTextEdit);
+    if (change == ItemActiveFocusHasChanged) {
+        setCursorVisible(value.boolValue); // ### refactor: focus handling && d->canvas && d->canvas->hasFocus());
+    }
+    QQuickItem::itemChange(change, value);
+}
+
+/*!
+\overload
+Returns the value of the given \a property.
+*/
+QVariant QQuickTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const
+{
+    Q_D(const QQuickTextEdit);
+
+    QVariant v;
+    switch (property) {
+    case Qt::ImEnabled:
+        v = (bool)(flags() & ItemAcceptsInputMethod);
+        break;
+    case Qt::ImHints:
+        v = (int)inputMethodHints();
+        break;
+    default:
+        v = d->control->inputMethodQuery(property);
+        break;
+    }
+    return v;
+
+}
+
+void QQuickTextEdit::updateImageCache(const QRectF &)
+{
+    Q_D(QQuickTextEdit);
+
+    // Do we really need the image cache?
+    if (!d->richText || !d->useImageFallback) {
+        if (!d->pixmapCache.isNull())
+            d->pixmapCache = QPixmap();
+        return;
+    }
+
+    if (width() != d->pixmapCache.width() || height() != d->pixmapCache.height())
+        d->pixmapCache = QPixmap(width(), height());
+
+    if (d->pixmapCache.isNull())
+        return;
+
+    // ### Use supplied rect, clear area and update only this part (for cursor updates)
+    QRectF bounds = QRectF(0, 0, width(), height());
+    d->pixmapCache.fill(Qt::transparent);
+    {
+        QPainter painter(&d->pixmapCache);
+
+        painter.setRenderHint(QPainter::TextAntialiasing);
+        painter.translate(0, d->yoff);
+
+        d->control->drawContents(&painter, bounds);
+    }
+
+}
+
+QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData)
+{
+    Q_UNUSED(updatePaintNodeData);
+    Q_D(QQuickTextEdit);
+
+    QSGNode *currentNode = oldNode;
+    if (d->richText && d->useImageFallback) {
+        QSGImageNode *node = 0;
+        if (oldNode == 0 || d->nodeType != QQuickTextEditPrivate::NodeIsTexture) {
+            delete oldNode;
+            node = QQuickItemPrivate::get(this)->sceneGraphContext()->createImageNode();
+            d->texture = new QSGPlainTexture();
+            d->nodeType = QQuickTextEditPrivate::NodeIsTexture;
+            currentNode = node;
+        } else {
+            node = static_cast<QSGImageNode *>(oldNode);
+        }
+
+        qobject_cast<QSGPlainTexture *>(d->texture)->setImage(d->pixmapCache.toImage());
+        node->setTexture(0);
+        node->setTexture(d->texture);
+
+        node->setTargetRect(QRectF(0, 0, d->pixmapCache.width(), d->pixmapCache.height()));
+        node->setSourceRect(QRectF(0, 0, 1, 1));
+        node->setHorizontalWrapMode(QSGTexture::ClampToEdge);
+        node->setVerticalWrapMode(QSGTexture::ClampToEdge);
+        node->setFiltering(QSGTexture::Linear); // Nonsmooth text just ugly, so don't do that..
+        node->update();
+
+    } else if (oldNode == 0 || d->documentDirty) {
+        d->documentDirty = false;
+
+#if defined(Q_WS_MAC)
+        // Make sure document is relayouted in the paint node on Mac
+        // to avoid crashes due to the font engines created in the
+        // shaping process
+        d->document->markContentsDirty(0, d->document->characterCount());
+#endif
+
+        QQuickTextNode *node = 0;
+        if (oldNode == 0 || d->nodeType != QQuickTextEditPrivate::NodeIsText) {
+            delete oldNode;
+            node = new QQuickTextNode(QQuickItemPrivate::get(this)->sceneGraphContext());
+            d->nodeType = QQuickTextEditPrivate::NodeIsText;
+            currentNode = node;
+        } else {
+            node = static_cast<QQuickTextNode *>(oldNode);
+        }
+
+        node->deleteContent();
+        node->setMatrix(QMatrix4x4());
+
+        QRectF bounds = boundingRect();
+
+        QColor selectionColor = d->control->palette().color(QPalette::Highlight);
+        QColor selectedTextColor = d->control->palette().color(QPalette::HighlightedText);
+        node->addTextDocument(bounds.topLeft(), d->document, d->color, QQuickText::Normal, QColor(),
+                              selectionColor, selectedTextColor, selectionStart(),
+                              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
+        // control is returned to the main thread, as all the font engines
+        // are now owned by the rendering thread
+        d->document->markContentsDirty(0, d->document->characterCount());
+#endif
+    }
+
+    if (d->nodeType == QQuickTextEditPrivate::NodeIsText && d->cursorComponent == 0 && !isReadOnly()) {
+        QQuickTextNode *node = static_cast<QQuickTextNode *>(currentNode);
+
+        QColor color = (!d->cursorVisible || !d->control->cursorOn())
+                ? QColor(0, 0, 0, 0)
+                : d->color;
+
+        if (node->cursorNode() == 0) {
+            node->setCursor(cursorRectangle(), color);
+        } else {
+            node->cursorNode()->setRect(cursorRectangle());
+            node->cursorNode()->setColor(color);
+        }
+
+    }
+
+    return currentNode;
+}
+
+/*!
+    \qmlproperty bool QtQuick2::TextEdit::smooth
+
+    This property holds whether the text is smoothly scaled or transformed.
+
+    Smooth filtering gives better visual quality, but is slower.  If
+    the item is displayed at its natural size, this property has no visual or
+    performance effect.
+
+    \note Generally scaling artifacts are only visible if the item is stationary on
+    the screen.  A common pattern when animating an item is to disable smooth
+    filtering at the beginning of the animation and reenable it at the conclusion.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::TextEdit::canPaste
+
+    Returns true if the TextEdit is writable and the content of the clipboard is
+    suitable for pasting into the TextEdit.
+*/
+bool QQuickTextEdit::canPaste() const
+{
+    Q_D(const QQuickTextEdit);
+    return d->canPaste;
+}
+
+/*!
+    \qmlproperty bool QtQuick2::TextEdit::inputMethodComposing
+
+
+    This property holds whether the TextEdit has partial text input from an
+    input method.
+
+    While it is composing an input method may rely on mouse or key events from
+    the TextEdit to edit or commit the partial text.  This property can be used
+    to determine when to disable events handlers that may interfere with the
+    correct operation of an input method.
+*/
+bool QQuickTextEdit::isInputMethodComposing() const
+{
+    Q_D(const QQuickTextEdit);
+    if (QTextLayout *layout = d->control->textCursor().block().layout())
+        return layout->preeditAreaText().length() > 0;
+    return false;
+}
+
+void QQuickTextEditPrivate::init()
+{
+    Q_Q(QQuickTextEdit);
+
+    q->setSmooth(smooth);
+    q->setAcceptedMouseButtons(Qt::LeftButton);
+    q->setFlag(QQuickItem::ItemAcceptsInputMethod);
+    q->setFlag(QQuickItem::ItemHasContents);
+
+    control = new QTextControl(q);
+    control->setIgnoreUnusedNavigationEvents(true);
+    control->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard | Qt::TextEditable);
+    control->setDragEnabled(false);
+
+    // By default, QTextControl will issue both a updateCursorRequest() and an updateRequest()
+    // when the cursor needs to be repainted. We need the signals to be separate to be able to
+    // distinguish the cursor updates so that we can avoid updating the whole subtree when the
+    // cursor blinks.
+    if (!QObject::disconnect(control, SIGNAL(updateCursorRequest(QRectF)),
+                             control, SIGNAL(updateRequest(QRectF)))) {
+        qWarning("QQuickTextEditPrivate::init: Failed to disconnect updateCursorRequest and updateRequest");
+    }
+
+    // QTextControl follows the default text color
+    // defined by the platform, declarative text
+    // should be black by default
+    QPalette pal = control->palette();
+    if (pal.color(QPalette::Text) != color) {
+        pal.setColor(QPalette::Text, color);
+        control->setPalette(pal);
+    }
+
+    QObject::connect(control, SIGNAL(updateRequest(QRectF)), q, SLOT(updateDocument()));
+    QObject::connect(control, SIGNAL(updateCursorRequest()), q, SLOT(updateCursor()));
+    QObject::connect(control, SIGNAL(textChanged()), q, SLOT(q_textChanged()));
+    QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
+    QObject::connect(control, SIGNAL(selectionChanged()), q, SLOT(updateSelectionMarkers()));
+    QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(updateSelectionMarkers()));
+    QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
+    QObject::connect(control, SIGNAL(microFocusChanged()), q, SLOT(moveCursorDelegate()));
+    QObject::connect(control, SIGNAL(linkActivated(QString)), q, SIGNAL(linkActivated(QString)));
+#ifndef QT_NO_CLIPBOARD
+    QObject::connect(q, SIGNAL(readOnlyChanged(bool)), q, SLOT(q_canPasteChanged()));
+    QObject::connect(QGuiApplication::clipboard(), SIGNAL(dataChanged()), q, SLOT(q_canPasteChanged()));
+    canPaste = control->canPaste();
+#endif
+
+    document = control->document();
+    document->setDefaultFont(font);
+    document->setDocumentMargin(textMargin);
+    document->setUndoRedoEnabled(false); // flush undo buffer.
+    document->setUndoRedoEnabled(true);
+    updateDefaultTextOption();
+}
+
+void QQuickTextEdit::q_textChanged()
+{
+    Q_D(QQuickTextEdit);
+    d->text = text();
+    d->rightToLeftText = d->document->begin().layout()->engine()->isRightToLeft();
+    d->determineHorizontalAlignment();
+    d->updateDefaultTextOption();
+    updateSize();
+    updateTotalLines();
+    emit textChanged(d->text);
+}
+
+void QQuickTextEdit::moveCursorDelegate()
+{
+    Q_D(QQuickTextEdit);
+    d->determineHorizontalAlignment();
+    updateMicroFocus();
+    emit cursorRectangleChanged();
+    if (!d->cursor)
+        return;
+    QRectF cursorRect = cursorRectangle();
+    d->cursor->setX(cursorRect.x());
+    d->cursor->setY(cursorRect.y());
+}
+
+void QQuickTextEditPrivate::updateSelection()
+{
+    Q_Q(QQuickTextEdit);
+    QTextCursor cursor = control->textCursor();
+    bool startChange = (lastSelectionStart != cursor.selectionStart());
+    bool endChange = (lastSelectionEnd != cursor.selectionEnd());
+    cursor.beginEditBlock();
+    cursor.setPosition(lastSelectionStart, QTextCursor::MoveAnchor);
+    cursor.setPosition(lastSelectionEnd, QTextCursor::KeepAnchor);
+    cursor.endEditBlock();
+    control->setTextCursor(cursor);
+    if (startChange)
+        q->selectionStartChanged();
+    if (endChange)
+        q->selectionEndChanged();
+}
+
+void QQuickTextEdit::updateSelectionMarkers()
+{
+    Q_D(QQuickTextEdit);
+    if (d->lastSelectionStart != d->control->textCursor().selectionStart()) {
+        d->lastSelectionStart = d->control->textCursor().selectionStart();
+        emit selectionStartChanged();
+    }
+    if (d->lastSelectionEnd != d->control->textCursor().selectionEnd()) {
+        d->lastSelectionEnd = d->control->textCursor().selectionEnd();
+        emit selectionEndChanged();
+    }
+}
+
+QRectF QQuickTextEdit::boundingRect() const
+{
+    Q_D(const QQuickTextEdit);
+    QRectF r = QQuickImplicitSizeItem::boundingRect();
+    int cursorWidth = 1;
+    if (d->cursor)
+        cursorWidth = d->cursor->width();
+    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.
+
+    r.setRight(r.right() + cursorWidth);
+    return r.translated(0,d->yoff);
+}
+
+qreal QQuickTextEditPrivate::getImplicitWidth() const
+{
+    Q_Q(const QQuickTextEdit);
+    if (!requireImplicitWidth) {
+        // We don't calculate implicitWidth unless it is required.
+        // We need to force a size update now to ensure implicitWidth is calculated
+        const_cast<QQuickTextEditPrivate*>(this)->requireImplicitWidth = true;
+        const_cast<QQuickTextEdit*>(q)->updateSize();
+    }
+    return implicitWidth;
+}
+
+//### we should perhaps be a bit smarter here -- depending on what has changed, we shouldn't
+//    need to do all the calculations each time
+void QQuickTextEdit::updateSize()
+{
+    Q_D(QQuickTextEdit);
+    if (isComponentComplete()) {
+        qreal naturalWidth = d->implicitWidth;
+        // ### assumes that if the width is set, the text will fill to edges
+        // ### (unless wrap is false, then clipping will occur)
+        if (widthValid()) {
+            if (!d->requireImplicitWidth) {
+                emit implicitWidthChanged();
+                // if the implicitWidth is used, then updateSize() has already been called (recursively)
+                if (d->requireImplicitWidth)
+                    return;
+            }
+            if (d->requireImplicitWidth) {
+                d->document->setTextWidth(-1);
+                naturalWidth = d->document->idealWidth();
+            }
+            if (d->document->textWidth() != width())
+                d->document->setTextWidth(width());
+        } else {
+            d->document->setTextWidth(-1);
+        }
+        QFontMetrics fm = QFontMetrics(d->font);
+        int dy = height();
+        dy -= (int)d->document->size().height();
+
+        int nyoff;
+        if (heightValid()) {
+            if (d->vAlign == AlignBottom)
+                nyoff = dy;
+            else if (d->vAlign == AlignVCenter)
+                nyoff = dy/2;
+            else
+                nyoff = 0;
+        } else {
+            nyoff = 0;
+        }
+        if (nyoff != d->yoff)
+            d->yoff = nyoff;
+        setBaselineOffset(fm.ascent() + d->yoff + d->textMargin);
+
+        //### need to comfirm cost of always setting these
+        int newWidth = qCeil(d->document->idealWidth());
+        if (!widthValid() && d->document->textWidth() != newWidth)
+            d->document->setTextWidth(newWidth); // ### Text does not align if width is not set (QTextDoc bug)
+        // ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed.
+        if (!widthValid())
+            setImplicitWidth(newWidth);
+        else if (d->requireImplicitWidth)
+            setImplicitWidth(naturalWidth);
+        qreal newHeight = d->document->isEmpty() ? fm.height() : (int)d->document->size().height();
+        setImplicitHeight(newHeight);
+
+        d->paintedSize = QSize(newWidth, newHeight);
+        emit paintedSizeChanged();
+    } else {
+        d->dirty = true;
+    }
+    updateDocument();
+}
+
+void QQuickTextEdit::updateDocument()
+{
+    Q_D(QQuickTextEdit);
+    d->documentDirty = true;
+
+    if (isComponentComplete()) {
+        updateImageCache();
+        update();
+    }
+}
+
+void QQuickTextEdit::updateCursor()
+{
+    Q_D(QQuickTextEdit);
+    if (isComponentComplete()) {
+        updateImageCache(d->control->cursorRect());
+        update();
+    }
+}
+
+void QQuickTextEdit::updateTotalLines()
+{
+    Q_D(QQuickTextEdit);
+
+    int subLines = 0;
+
+    for (QTextBlock it = d->document->begin(); it != d->document->end(); it = it.next()) {
+        QTextLayout *layout = it.layout();
+        if (!layout)
+            continue;
+        subLines += layout->lineCount()-1;
+    }
+
+    int newTotalLines = d->document->lineCount() + subLines;
+    if (d->lineCount != newTotalLines) {
+        d->lineCount = newTotalLines;
+        emit lineCountChanged();
+    }
+}
+
+void QQuickTextEditPrivate::updateDefaultTextOption()
+{
+    Q_Q(QQuickTextEdit);
+    QTextOption opt = document->defaultTextOption();
+    int oldAlignment = opt.alignment();
+
+    QQuickTextEdit::HAlignment horizontalAlignment = q->effectiveHAlign();
+    if (rightToLeftText) {
+        if (horizontalAlignment == QQuickTextEdit::AlignLeft)
+            horizontalAlignment = QQuickTextEdit::AlignRight;
+        else if (horizontalAlignment == QQuickTextEdit::AlignRight)
+            horizontalAlignment = QQuickTextEdit::AlignLeft;
+    }
+    opt.setAlignment((Qt::Alignment)(int)(horizontalAlignment | vAlign));
+
+    QTextOption::WrapMode oldWrapMode = opt.wrapMode();
+    opt.setWrapMode(QTextOption::WrapMode(wrapMode));
+
+    bool oldUseDesignMetrics = opt.useDesignMetrics();
+    bool useDesignMetrics = !qmlDisableDistanceField();
+    opt.setUseDesignMetrics(useDesignMetrics);
+
+    if (oldWrapMode == opt.wrapMode()
+            && oldAlignment == opt.alignment()
+            && oldUseDesignMetrics == useDesignMetrics) {
+        return;
+    }
+    document->setDefaultTextOption(opt);
+}
+
+
+
+/*!
+    \qmlmethod void QtQuick2::TextEdit::openSoftwareInputPanel()
+
+    Opens software input panels like virtual keyboards for typing, useful for
+    customizing when you want the input keyboard to be shown and hidden in
+    your application.
+
+    By default the opening of input panels follows the platform style. On Symbian^1 and
+    Symbian^3 -based devices the panels are opened by clicking TextEdit. On other platforms
+    the panels are automatically opened when TextEdit element gains active focus. Input panels are
+    always closed if no editor has active focus.
+
+    You can disable the automatic behavior by setting the property \c activeFocusOnPress to false
+    and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement
+    the behavior you want.
+
+    Only relevant on platforms, which provide virtual keyboards.
+
+    \code
+        import QtQuick 1.0
+        TextEdit {
+            id: textEdit
+            text: "Hello world!"
+            activeFocusOnPress: false
+            MouseArea {
+                anchors.fill: parent
+                onClicked: {
+                    if (!textEdit.activeFocus) {
+                        textEdit.forceActiveFocus();
+                        textEdit.openSoftwareInputPanel();
+                    } else {
+                        textEdit.focus = false;
+                    }
+                }
+                onPressAndHold: textEdit.closeSoftwareInputPanel();
+            }
+        }
+    \endcode
+*/
+void QQuickTextEdit::openSoftwareInputPanel()
+{
+    if (qGuiApp)
+        qGuiApp->inputPanel()->show();
+}
+
+/*!
+    \qmlmethod void QtQuick2::TextEdit::closeSoftwareInputPanel()
+
+    Closes a software input panel like a virtual keyboard shown on the screen, useful
+    for customizing when you want the input keyboard to be shown and hidden in
+    your application.
+
+    By default the opening of input panels follows the platform style. On Symbian^1 and
+    Symbian^3 -based devices the panels are opened by clicking TextEdit. On other platforms
+    the panels are automatically opened when TextEdit element gains active focus. Input panels are
+    always closed if no editor has active focus.
+
+    You can disable the automatic behavior by setting the property \c activeFocusOnPress to false
+    and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement
+    the behavior you want.
+
+    Only relevant on platforms, which provide virtual keyboards.
+
+    \code
+        import QtQuick 1.0
+        TextEdit {
+            id: textEdit
+            text: "Hello world!"
+            activeFocusOnPress: false
+            MouseArea {
+                anchors.fill: parent
+                onClicked: {
+                    if (!textEdit.activeFocus) {
+                        textEdit.forceActiveFocus();
+                        textEdit.openSoftwareInputPanel();
+                    } else {
+                        textEdit.focus = false;
+                    }
+                }
+                onPressAndHold: textEdit.closeSoftwareInputPanel();
+            }
+        }
+    \endcode
+*/
+void QQuickTextEdit::closeSoftwareInputPanel()
+{
+    if (qGuiApp)
+        qGuiApp->inputPanel()->hide();
+}
+
+void QQuickTextEdit::focusInEvent(QFocusEvent *event)
+{
+    Q_D(const QQuickTextEdit);
+    if (d->focusOnPress && !isReadOnly())
+        openSoftwareInputPanel();
+    QQuickImplicitSizeItem::focusInEvent(event);
+}
+
+void QQuickTextEdit::q_canPasteChanged()
+{
+    Q_D(QQuickTextEdit);
+    bool old = d->canPaste;
+    d->canPaste = d->control->canPaste();
+    if (old!=d->canPaste)
+        emit canPasteChanged();
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquicktextedit_p.h b/src/declarative/items/qquicktextedit_p.h
new file mode 100644 (file)
index 0000000..e237e2e
--- /dev/null
@@ -0,0 +1,306 @@
+// Commit: 27e4302b7f45f22180693d26747f419177c81e27
+/****************************************************************************
+**
+** 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 QQUICKTEXTEDIT_P_H
+#define QQUICKTEXTEDIT_P_H
+
+#include "qquickimplicitsizeitem_p.h"
+
+#include <QtGui/qtextoption.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickTextEditPrivate;
+class Q_AUTOTEST_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem
+{
+    Q_OBJECT
+    Q_ENUMS(VAlignment)
+    Q_ENUMS(HAlignment)
+    Q_ENUMS(TextFormat)
+    Q_ENUMS(WrapMode)
+    Q_ENUMS(SelectionMode)
+
+    Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
+    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
+    Q_PROPERTY(QColor selectionColor READ selectionColor WRITE setSelectionColor NOTIFY selectionColorChanged)
+    Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor NOTIFY selectedTextColorChanged)
+    Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
+    Q_PROPERTY(HAlignment horizontalAlignment READ hAlign WRITE setHAlign RESET resetHAlign NOTIFY horizontalAlignmentChanged)
+    Q_PROPERTY(HAlignment effectiveHorizontalAlignment READ effectiveHAlign NOTIFY effectiveHorizontalAlignmentChanged)
+    Q_PROPERTY(VAlignment verticalAlignment READ vAlign WRITE setVAlign NOTIFY verticalAlignmentChanged)
+    Q_PROPERTY(WrapMode wrapMode READ wrapMode WRITE setWrapMode NOTIFY wrapModeChanged)
+    Q_PROPERTY(int lineCount READ lineCount NOTIFY lineCountChanged)
+    Q_PROPERTY(qreal paintedWidth READ paintedWidth NOTIFY paintedSizeChanged)
+    Q_PROPERTY(qreal paintedHeight READ paintedHeight NOTIFY paintedSizeChanged)
+    Q_PROPERTY(TextFormat textFormat READ textFormat WRITE setTextFormat NOTIFY textFormatChanged)
+    Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged)
+    Q_PROPERTY(bool cursorVisible READ isCursorVisible WRITE setCursorVisible NOTIFY cursorVisibleChanged)
+    Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged)
+    Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged)
+    Q_PROPERTY(QDeclarativeComponent* cursorDelegate READ cursorDelegate WRITE setCursorDelegate NOTIFY cursorDelegateChanged)
+    Q_PROPERTY(int selectionStart READ selectionStart NOTIFY selectionStartChanged)
+    Q_PROPERTY(int selectionEnd READ selectionEnd NOTIFY selectionEndChanged)
+    Q_PROPERTY(QString selectedText READ selectedText NOTIFY selectionChanged)
+    Q_PROPERTY(bool activeFocusOnPress READ focusOnPress WRITE setFocusOnPress NOTIFY activeFocusOnPressChanged)
+    Q_PROPERTY(bool persistentSelection READ persistentSelection WRITE setPersistentSelection NOTIFY persistentSelectionChanged)
+    Q_PROPERTY(qreal textMargin READ textMargin WRITE setTextMargin NOTIFY textMarginChanged)
+    Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints)
+    Q_PROPERTY(bool selectByMouse READ selectByMouse WRITE setSelectByMouse NOTIFY selectByMouseChanged)
+    Q_PROPERTY(SelectionMode mouseSelectionMode READ mouseSelectionMode WRITE setMouseSelectionMode NOTIFY mouseSelectionModeChanged)
+    Q_PROPERTY(bool canPaste READ canPaste NOTIFY canPasteChanged)
+    Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged)
+
+public:
+    QQuickTextEdit(QQuickItem *parent=0);
+
+    enum HAlignment {
+        AlignLeft = Qt::AlignLeft,
+        AlignRight = Qt::AlignRight,
+        AlignHCenter = Qt::AlignHCenter,
+        AlignJustify = Qt::AlignJustify
+    };
+
+    enum VAlignment {
+        AlignTop = Qt::AlignTop,
+        AlignBottom = Qt::AlignBottom,
+        AlignVCenter = Qt::AlignVCenter
+    };
+
+    enum TextFormat {
+        PlainText = Qt::PlainText,
+        RichText = Qt::RichText,
+        AutoText = Qt::AutoText
+    };
+
+    enum WrapMode { NoWrap = QTextOption::NoWrap,
+                    WordWrap = QTextOption::WordWrap,
+                    WrapAnywhere = QTextOption::WrapAnywhere,
+                    WrapAtWordBoundaryOrAnywhere = QTextOption::WrapAtWordBoundaryOrAnywhere, // COMPAT
+                    Wrap = QTextOption::WrapAtWordBoundaryOrAnywhere
+                  };
+
+    enum SelectionMode {
+        SelectCharacters,
+        SelectWords
+    };
+
+    Q_INVOKABLE void openSoftwareInputPanel();
+    Q_INVOKABLE void closeSoftwareInputPanel();
+
+    QString text() const;
+    void setText(const QString &);
+
+    TextFormat textFormat() const;
+    void setTextFormat(TextFormat format);
+
+    QFont font() const;
+    void setFont(const QFont &font);
+
+    QColor color() const;
+    void setColor(const QColor &c);
+
+    QColor selectionColor() const;
+    void setSelectionColor(const QColor &c);
+
+    QColor selectedTextColor() const;
+    void setSelectedTextColor(const QColor &c);
+
+    HAlignment hAlign() const;
+    void setHAlign(HAlignment align);
+    void resetHAlign();
+    HAlignment effectiveHAlign() const;
+
+    VAlignment vAlign() const;
+    void setVAlign(VAlignment align);
+
+    WrapMode wrapMode() const;
+    void setWrapMode(WrapMode w);
+
+    int lineCount() const;
+
+    bool isCursorVisible() const;
+    void setCursorVisible(bool on);
+
+    int cursorPosition() const;
+    void setCursorPosition(int pos);
+
+    QDeclarativeComponent* cursorDelegate() const;
+    void setCursorDelegate(QDeclarativeComponent*);
+
+    int selectionStart() const;
+    int selectionEnd() const;
+
+    QString selectedText() const;
+
+    bool focusOnPress() const;
+    void setFocusOnPress(bool on);
+
+    bool persistentSelection() const;
+    void setPersistentSelection(bool on);
+
+    qreal textMargin() const;
+    void setTextMargin(qreal margin);
+
+    bool selectByMouse() const;
+    void setSelectByMouse(bool);
+
+    SelectionMode mouseSelectionMode() const;
+    void setMouseSelectionMode(SelectionMode mode);
+
+    bool canPaste() const;
+
+    virtual void componentComplete();
+
+    /* FROM EDIT */
+    void setReadOnly(bool);
+    bool isReadOnly() const;
+
+    void setTextInteractionFlags(Qt::TextInteractionFlags flags);
+    Qt::TextInteractionFlags textInteractionFlags() const;
+
+    QRect cursorRectangle() const;
+
+    QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
+
+    qreal paintedWidth() const;
+    qreal paintedHeight() const;
+
+    Q_INVOKABLE QRectF positionToRectangle(int) const;
+    Q_INVOKABLE int positionAt(int x, int y) const;
+    Q_INVOKABLE void moveCursorSelection(int pos);
+    Q_INVOKABLE void moveCursorSelection(int pos, SelectionMode mode);
+
+    QRectF boundingRect() const;
+
+    bool isInputMethodComposing() const;
+
+Q_SIGNALS:
+    void textChanged(const QString &);
+    void paintedSizeChanged();
+    void cursorPositionChanged();
+    void cursorRectangleChanged();
+    void selectionStartChanged();
+    void selectionEndChanged();
+    void selectionChanged();
+    void colorChanged(const QColor &color);
+    void selectionColorChanged(const QColor &color);
+    void selectedTextColorChanged(const QColor &color);
+    void fontChanged(const QFont &font);
+    void horizontalAlignmentChanged(HAlignment alignment);
+    void verticalAlignmentChanged(VAlignment alignment);
+    void wrapModeChanged();
+    void lineCountChanged();
+    void textFormatChanged(TextFormat textFormat);
+    void readOnlyChanged(bool isReadOnly);
+    void cursorVisibleChanged(bool isCursorVisible);
+    void cursorDelegateChanged();
+    void activeFocusOnPressChanged(bool activeFocusOnPressed);
+    void persistentSelectionChanged(bool isPersistentSelection);
+    void textMarginChanged(qreal textMargin);
+    void selectByMouseChanged(bool selectByMouse);
+    void mouseSelectionModeChanged(SelectionMode mode);
+    void linkActivated(const QString &link);
+    void canPasteChanged();
+    void inputMethodComposingChanged();
+    void effectiveHorizontalAlignmentChanged();
+
+public Q_SLOTS:
+    void selectAll();
+    void selectWord();
+    void select(int start, int end);
+    void deselect();
+    bool isRightToLeft(int start, int end);
+#ifndef QT_NO_CLIPBOARD
+    void cut();
+    void copy();
+    void paste();
+#endif
+
+private Q_SLOTS:
+    void q_textChanged();
+    void updateSelectionMarkers();
+    void moveCursorDelegate();
+    void loadCursorDelegate();
+    void q_canPasteChanged();
+    void updateDocument();
+    void updateCursor();
+
+private:
+    void updateSize();
+    void updateTotalLines();
+    void updateImageCache(const QRectF &rect = QRectF());
+
+protected:
+    virtual void geometryChanged(const QRectF &newGeometry,
+                                 const QRectF &oldGeometry);
+
+    bool event(QEvent *);
+    void keyPressEvent(QKeyEvent *);
+    void keyReleaseEvent(QKeyEvent *);
+    void focusInEvent(QFocusEvent *event);
+
+    // mouse filter?
+    void mousePressEvent(QMouseEvent *event);
+    void mouseReleaseEvent(QMouseEvent *event);
+    void mouseDoubleClickEvent(QMouseEvent *event);
+    void mouseMoveEvent(QMouseEvent *event);
+    void inputMethodEvent(QInputMethodEvent *e);
+    virtual void itemChange(ItemChange, const ItemChangeData &);
+
+    QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData);
+
+private:
+    Q_DISABLE_COPY(QQuickTextEdit)
+    Q_DECLARE_PRIVATE(QQuickTextEdit)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickTextEdit)
+
+QT_END_HEADER
+
+#endif // QQUICKTEXTEDIT_P_H
diff --git a/src/declarative/items/qquicktextedit_p_p.h b/src/declarative/items/qquicktextedit_p_p.h
new file mode 100644 (file)
index 0000000..7bcbe2a
--- /dev/null
@@ -0,0 +1,144 @@
+// Commit: 27e4302b7f45f22180693d26747f419177c81e27
+/****************************************************************************
+**
+** 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 QQUICKTEXTEDIT_P_P_H
+#define QQUICKTEXTEDIT_P_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 "qquicktextedit_p.h"
+#include "qquickimplicitsizeitem_p_p.h"
+
+#include <QtDeclarative/qdeclarative.h>
+#include <QtGui/qpixmap.h>
+
+QT_BEGIN_NAMESPACE
+class QTextLayout;
+class QTextDocument;
+class QTextControl;
+class QQuickTextEditPrivate : public QQuickImplicitSizeItemPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickTextEdit)
+
+public:
+    QQuickTextEditPrivate()
+      : color("black"), hAlign(QQuickTextEdit::AlignLeft), vAlign(QQuickTextEdit::AlignTop),
+      documentDirty(true), dirty(false), richText(false), cursorVisible(false), focusOnPress(true),
+      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(QQuickTextEdit::AutoText), document(0), wrapMode(QQuickTextEdit::NoWrap),
+      mouseSelectionMode(QQuickTextEdit::SelectCharacters),
+      lineCount(0), yoff(0), nodeType(NodeIsNull), texture(0)
+    {
+    }
+
+    void init();
+
+    void updateDefaultTextOption();
+    void relayoutDocument();
+    void updateSelection();
+    bool determineHorizontalAlignment();
+    bool setHAlign(QQuickTextEdit::HAlignment, bool forceAlign = false);
+    void mirrorChange();
+    qreal getImplicitWidth() const;
+
+    QString text;
+    QFont font;
+    QFont sourceFont;
+    QColor  color;
+    QColor  selectionColor;
+    QColor  selectedTextColor;
+    QString style;
+    QColor  styleColor;
+    QQuickTextEdit::HAlignment hAlign;
+    QQuickTextEdit::VAlignment vAlign;
+
+    bool documentDirty : 1;
+    bool dirty : 1;
+    bool richText : 1;
+    bool cursorVisible : 1;
+    bool focusOnPress : 1;
+    bool persistentSelection : 1;
+    bool requireImplicitWidth:1;
+    bool selectByMouse:1;
+    bool canPaste:1;
+    bool hAlignImplicit:1;
+    bool rightToLeftText:1;
+    bool useImageFallback:1;
+
+    qreal textMargin;
+    int lastSelectionStart;
+    int lastSelectionEnd;
+    QDeclarativeComponent* cursorComponent;
+    QQuickItem* cursor;
+    QQuickTextEdit::TextFormat format;
+    QTextDocument *document;
+    QTextControl *control;
+    QQuickTextEdit::WrapMode wrapMode;
+    QQuickTextEdit::SelectionMode mouseSelectionMode;
+    int lineCount;
+    int yoff;
+    QSize paintedSize;
+
+    enum NodeType {
+        NodeIsNull,
+        NodeIsTexture,
+        NodeIsText
+    };
+    NodeType nodeType;
+    QSGTexture *texture;
+    QPixmap pixmapCache;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKTEXTEDIT_P_P_H
diff --git a/src/declarative/items/qquicktextinput.cpp b/src/declarative/items/qquicktextinput.cpp
new file mode 100644 (file)
index 0000000..e28832e
--- /dev/null
@@ -0,0 +1,2007 @@
+/****************************************************************************
+**
+** 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 "qquicktextinput_p.h"
+#include "qquicktextinput_p_p.h"
+#include "qquickcanvas.h"
+
+#include <private/qdeclarativeglobal_p.h>
+#include <private/qsgdistancefieldglyphcache_p.h>
+
+#include <QtDeclarative/qdeclarativeinfo.h>
+#include <QtGui/qevent.h>
+#include <QTextBoundaryFinder>
+#include "qquicktextnode_p.h"
+#include <qsgsimplerectnode.h>
+
+#include <QtGui/qstylehints.h>
+#include <QtGui/qinputpanel.h>
+
+QT_BEGIN_NAMESPACE
+
+DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
+
+/*!
+    \qmlclass TextInput QQuickTextInput
+    \inqmlmodule QtQuick 2
+    \ingroup qml-basic-visual-elements
+    \brief The TextInput item displays an editable line of text.
+    \inherits Item
+
+    The TextInput element displays a single line of editable plain text.
+
+    TextInput is used to accept a line of text input. Input constraints
+    can be placed on a TextInput item (for example, through a \l validator or \l inputMask),
+    and setting \l echoMode to an appropriate value enables TextInput to be used for
+    a password input field.
+
+    On Mac OS X, the Up/Down key bindings for Home/End are explicitly disabled.
+    If you want such bindings (on any platform), you will need to construct them in QML.
+
+    \sa TextEdit, Text, {declarative/text/textselection}{Text Selection example}
+*/
+QQuickTextInput::QQuickTextInput(QQuickItem* parent)
+: QQuickImplicitSizeItem(*(new QQuickTextInputPrivate), parent)
+{
+    Q_D(QQuickTextInput);
+    d->init();
+}
+
+QQuickTextInput::~QQuickTextInput()
+{
+}
+
+/*!
+    \qmlproperty string QtQuick2::TextInput::text
+
+    The text in the TextInput.
+*/
+QString QQuickTextInput::text() const
+{
+    Q_D(const QQuickTextInput);
+    return d->control->text();
+}
+
+void QQuickTextInput::setText(const QString &s)
+{
+    Q_D(QQuickTextInput);
+    if (s == text())
+        return;
+    d->control->setText(s);
+}
+
+/*!
+    \qmlproperty string QtQuick2::TextInput::font.family
+
+    Sets the family name of the font.
+
+    The family name is case insensitive and may optionally include a foundry name, e.g. "Helvetica [Cronyx]".
+    If the family is available from more than one foundry and the foundry isn't specified, an arbitrary foundry is chosen.
+    If the family isn't available a family will be set using the font matching algorithm.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::TextInput::font.bold
+
+    Sets whether the font weight is bold.
+*/
+
+/*!
+    \qmlproperty enumeration QtQuick2::TextInput::font.weight
+
+    Sets the font's weight.
+
+    The weight can be one of:
+    \list
+    \o Font.Light
+    \o Font.Normal - the default
+    \o Font.DemiBold
+    \o Font.Bold
+    \o Font.Black
+    \endlist
+
+    \qml
+    TextInput { text: "Hello"; font.weight: Font.DemiBold }
+    \endqml
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::TextInput::font.italic
+
+    Sets whether the font has an italic style.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::TextInput::font.underline
+
+    Sets whether the text is underlined.
+*/
+
+/*!
+    \qmlproperty bool QtQuick2::TextInput::font.strikeout
+
+    Sets whether the font has a strikeout style.
+*/
+
+/*!
+    \qmlproperty real QtQuick2::TextInput::font.pointSize
+
+    Sets the font size in points. The point size must be greater than zero.
+*/
+
+/*!
+    \qmlproperty int QtQuick2::TextInput::font.pixelSize
+
+    Sets the font size in pixels.
+
+    Using this function makes the font device dependent.
+    Use \c pointSize to set the size of the font in a device independent manner.
+*/
+
+/*!
+    \qmlproperty real QtQuick2::TextInput::font.letterSpacing
+
+    Sets the letter spacing for the font.
+
+    Letter spacing changes the default spacing between individual letters in the font.
+    A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing.
+*/
+
+/*!
+    \qmlproperty real QtQuick2::TextInput::font.wordSpacing
+
+    Sets the word spacing for the font.
+
+    Word spacing changes the default spacing between individual words.
+    A positive value increases the word spacing by a corresponding amount of pixels,
+    while a negative value decreases the inter-word spacing accordingly.
+*/
+
+/*!
+    \qmlproperty enumeration QtQuick2::TextInput::font.capitalization
+
+    Sets the capitalization for the text.
+
+    \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.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character.
+    \endlist
+
+    \qml
+    TextInput { text: "Hello"; font.capitalization: Font.AllLowercase }
+    \endqml
+*/
+
+QFont QQuickTextInput::font() const
+{
+    Q_D(const QQuickTextInput);
+    return d->sourceFont;
+}
+
+void QQuickTextInput::setFont(const QFont &font)
+{
+    Q_D(QQuickTextInput);
+    if (d->sourceFont == font)
+        return;
+
+    d->sourceFont = font;
+    QFont oldFont = d->font;
+    d->font = font;
+    if (d->font.pointSizeF() != -1) {
+        // 0.5pt resolution
+        qreal size = qRound(d->font.pointSizeF()*2.0);
+        d->font.setPointSizeF(size/2.0);
+    }
+    if (oldFont != d->font) {
+        d->control->setFont(d->font);
+        updateSize();
+        updateCursorRectangle();
+        if (d->cursorItem) {
+            d->cursorItem->setHeight(QFontMetrics(d->font).height());
+        }
+    }
+    emit fontChanged(d->sourceFont);
+}
+
+/*!
+    \qmlproperty color QtQuick2::TextInput::color
+
+    The text color.
+*/
+QColor QQuickTextInput::color() const
+{
+    Q_D(const QQuickTextInput);
+    return d->color;
+}
+
+void QQuickTextInput::setColor(const QColor &c)
+{
+    Q_D(QQuickTextInput);
+    if (c != d->color) {
+        d->color = c;
+        update();
+        emit colorChanged(c);
+    }
+}
+
+
+/*!
+    \qmlproperty color QtQuick2::TextInput::selectionColor
+
+    The text highlight color, used behind selections.
+*/
+QColor QQuickTextInput::selectionColor() const
+{
+    Q_D(const QQuickTextInput);
+    return d->selectionColor;
+}
+
+void QQuickTextInput::setSelectionColor(const QColor &color)
+{
+    Q_D(QQuickTextInput);
+    if (d->selectionColor == color)
+        return;
+
+    d->selectionColor = color;
+    QPalette p = d->control->palette();
+    p.setColor(QPalette::Highlight, d->selectionColor);
+    d->control->setPalette(p);
+    if (d->control->hasSelectedText())
+        update();
+    emit selectionColorChanged(color);
+}
+/*!
+    \qmlproperty color QtQuick2::TextInput::selectedTextColor
+
+    The highlighted text color, used in selections.
+*/
+QColor QQuickTextInput::selectedTextColor() const
+{
+    Q_D(const QQuickTextInput);
+    return d->selectedTextColor;
+}
+
+void QQuickTextInput::setSelectedTextColor(const QColor &color)
+{
+    Q_D(QQuickTextInput);
+    if (d->selectedTextColor == color)
+        return;
+
+    d->selectedTextColor = color;
+    QPalette p = d->control->palette();
+    p.setColor(QPalette::HighlightedText, d->selectedTextColor);
+    d->control->setPalette(p);
+    if (d->control->hasSelectedText())
+        update();
+    emit selectedTextColorChanged(color);
+}
+
+/*!
+    \qmlproperty enumeration QtQuick2::TextInput::horizontalAlignment
+    \qmlproperty enumeration QtQuick2::TextInput::effectiveHorizontalAlignment
+
+    Sets the horizontal alignment of the text within the TextInput item's
+    width and height. By default, the text alignment follows the natural alignment
+    of the text, for example text that is read from left to right will be aligned to
+    the left.
+
+    TextInput does not have vertical alignment, as the natural height is
+    exactly the height of the single line of text. If you set the height
+    manually to something larger, TextInput will always be top aligned
+    vertically. You can use anchors to align it however you want within
+    another item.
+
+    The valid values for \c horizontalAlignment are \c TextInput.AlignLeft, \c TextInput.AlignRight and
+    \c TextInput.AlignHCenter.
+
+    When using the attached property LayoutMirroring::enabled to mirror application
+    layouts, the horizontal alignment of text will also be mirrored. However, the property
+    \c horizontalAlignment will remain unchanged. To query the effective horizontal alignment
+    of TextInput, use the read-only property \c effectiveHorizontalAlignment.
+*/
+QQuickTextInput::HAlignment QQuickTextInput::hAlign() const
+{
+    Q_D(const QQuickTextInput);
+    return d->hAlign;
+}
+
+void QQuickTextInput::setHAlign(HAlignment align)
+{
+    Q_D(QQuickTextInput);
+    bool forceAlign = d->hAlignImplicit && d->effectiveLayoutMirror;
+    d->hAlignImplicit = false;
+    if (d->setHAlign(align, forceAlign) && isComponentComplete()) {
+        updateCursorRectangle();
+    }
+}
+
+void QQuickTextInput::resetHAlign()
+{
+    Q_D(QQuickTextInput);
+    d->hAlignImplicit = true;
+    if (d->determineHorizontalAlignment() && isComponentComplete()) {
+        updateCursorRectangle();
+    }
+}
+
+QQuickTextInput::HAlignment QQuickTextInput::effectiveHAlign() const
+{
+    Q_D(const QQuickTextInput);
+    QQuickTextInput::HAlignment effectiveAlignment = d->hAlign;
+    if (!d->hAlignImplicit && d->effectiveLayoutMirror) {
+        switch (d->hAlign) {
+        case QQuickTextInput::AlignLeft:
+            effectiveAlignment = QQuickTextInput::AlignRight;
+            break;
+        case QQuickTextInput::AlignRight:
+            effectiveAlignment = QQuickTextInput::AlignLeft;
+            break;
+        default:
+            break;
+        }
+    }
+    return effectiveAlignment;
+}
+
+bool QQuickTextInputPrivate::setHAlign(QQuickTextInput::HAlignment alignment, bool forceAlign)
+{
+    Q_Q(QQuickTextInput);
+    if ((hAlign != alignment || forceAlign) && alignment <= QQuickTextInput::AlignHCenter) { // justify not supported
+        QQuickTextInput::HAlignment oldEffectiveHAlign = q->effectiveHAlign();
+        hAlign = alignment;
+        emit q->horizontalAlignmentChanged(alignment);
+        if (oldEffectiveHAlign != q->effectiveHAlign())
+            emit q->effectiveHorizontalAlignmentChanged();
+        return true;
+    }
+    return false;
+}
+
+bool QQuickTextInputPrivate::determineHorizontalAlignment()
+{
+    if (hAlignImplicit) {
+        // if no explicit alignment has been set, follow the natural layout direction of the text
+        QString text = control->text();
+        if (text.isEmpty())
+            text = control->preeditAreaText();
+        bool isRightToLeft = text.isEmpty() ? QGuiApplication::keyboardInputDirection() == Qt::RightToLeft : text.isRightToLeft();
+        return setHAlign(isRightToLeft ? QQuickTextInput::AlignRight : QQuickTextInput::AlignLeft);
+    }
+    return false;
+}
+
+void QQuickTextInputPrivate::mirrorChange()
+{
+    Q_Q(QQuickTextInput);
+    if (q->isComponentComplete()) {
+        if (!hAlignImplicit && (hAlign == QQuickTextInput::AlignRight || hAlign == QQuickTextInput::AlignLeft)) {
+            q->updateCursorRectangle();
+            emit q->effectiveHorizontalAlignmentChanged();
+        }
+    }
+}
+
+/*!
+    \qmlproperty bool QtQuick2::TextInput::readOnly
+
+    Sets whether user input can modify the contents of the TextInput.
+
+    If readOnly is set to true, then user input will not affect the text
+    property. Any bindings or attempts to set the text property will still
+    work.
+*/
+bool QQuickTextInput::isReadOnly() const
+{
+    Q_D(const QQuickTextInput);
+    return d->control->isReadOnly();
+}
+
+void QQuickTextInput::setReadOnly(bool ro)
+{
+    Q_D(QQuickTextInput);
+    if (d->control->isReadOnly() == ro)
+        return;
+
+    setFlag(QQuickItem::ItemAcceptsInputMethod, !ro);
+    d->control->setReadOnly(ro);
+    if (!ro)
+        d->control->setCursorPosition(d->control->end());
+
+    emit readOnlyChanged(ro);
+}
+
+/*!
+    \qmlproperty int QtQuick2::TextInput::maximumLength
+    The maximum permitted length of the text in the TextInput.
+
+    If the text is too long, it is truncated at the limit.
+
+    By default, this property contains a value of 32767.
+*/
+int QQuickTextInput::maxLength() const
+{
+    Q_D(const QQuickTextInput);
+    return d->control->maxLength();
+}
+
+void QQuickTextInput::setMaxLength(int ml)
+{
+    Q_D(QQuickTextInput);
+    if (d->control->maxLength() == ml)
+        return;
+
+    d->control->setMaxLength(ml);
+
+    emit maximumLengthChanged(ml);
+}
+
+/*!
+    \qmlproperty bool QtQuick2::TextInput::cursorVisible
+    Set to true when the TextInput shows a cursor.
+
+    This property is set and unset when the TextInput gets active focus, so that other
+    properties can be bound to whether the cursor is currently showing. As it
+    gets set and unset automatically, when you set the value yourself you must
+    keep in mind that your value may be overwritten.
+
+    It can be set directly in script, for example if a KeyProxy might
+    forward keys to it and you desire it to look active when this happens
+    (but without actually giving it active focus).
+
+    It should not be set directly on the element, like in the below QML,
+    as the specified value will be overridden an lost on focus changes.
+
+    \code
+    TextInput {
+        text: "Text"
+        cursorVisible: false
+    }
+    \endcode
+
+    In the above snippet the cursor will still become visible when the
+    TextInput gains active focus.
+*/
+bool QQuickTextInput::isCursorVisible() const
+{
+    Q_D(const QQuickTextInput);
+    return d->cursorVisible;
+}
+
+void QQuickTextInput::setCursorVisible(bool on)
+{
+    Q_D(QQuickTextInput);
+    if (d->cursorVisible == on)
+        return;
+    d->cursorVisible = on;
+    d->control->setCursorBlinkPeriod(on ? qApp->styleHints()->cursorFlashTime() : 0);
+    QRect r = d->control->cursorRect();
+    if (d->control->inputMask().isEmpty())
+        updateRect(r);
+    else
+        updateRect();
+    emit cursorVisibleChanged(d->cursorVisible);
+}
+
+/*!
+    \qmlproperty int QtQuick2::TextInput::cursorPosition
+    The position of the cursor in the TextInput.
+*/
+int QQuickTextInput::cursorPosition() const
+{
+    Q_D(const QQuickTextInput);
+    return d->control->cursor();
+}
+void QQuickTextInput::setCursorPosition(int cp)
+{
+    Q_D(QQuickTextInput);
+    if (cp < 0 || cp > d->control->text().length())
+        return;
+    d->control->moveCursor(cp);
+}
+
+/*!
+  Returns a Rect which encompasses the cursor, but which may be larger than is
+  required. Ignores custom cursor delegates.
+*/
+QRect QQuickTextInput::cursorRectangle() const
+{
+    Q_D(const QQuickTextInput);
+    QRect r = d->control->cursorRect();
+    // Scroll and make consistent with TextEdit
+    // QLineControl inexplicably adds 1 to the height and horizontal padding
+    // for unicode direction markers.
+    r.adjust(5 - d->hscroll, 0, -4 - d->hscroll, -1);
+    return r;
+}
+/*!
+    \qmlproperty int QtQuick2::TextInput::selectionStart
+
+    The cursor position before the first character in the current selection.
+
+    This property is read-only. To change the selection, use select(start,end),
+    selectAll(), or selectWord().
+
+    \sa selectionEnd, cursorPosition, selectedText
+*/
+int QQuickTextInput::selectionStart() const
+{
+    Q_D(const QQuickTextInput);
+    return d->lastSelectionStart;
+}
+/*!
+    \qmlproperty int QtQuick2::TextInput::selectionEnd
+
+    The cursor position after the last character in the current selection.
+
+    This property is read-only. To change the selection, use select(start,end),
+    selectAll(), or selectWord().
+
+    \sa selectionStart, cursorPosition, selectedText
+*/
+int QQuickTextInput::selectionEnd() const
+{
+    Q_D(const QQuickTextInput);
+    return d->lastSelectionEnd;
+}
+/*!
+    \qmlmethod void QtQuick2::TextInput::select(int start, int end)
+
+    Causes the text from \a start to \a end to be selected.
+
+    If either start or end is out of range, the selection is not changed.
+
+    After calling this, selectionStart will become the lesser
+    and selectionEnd will become the greater (regardless of the order passed
+    to this method).
+
+    \sa selectionStart, selectionEnd
+*/
+void QQuickTextInput::select(int start, int end)
+{
+    Q_D(QQuickTextInput);
+    if (start < 0 || end < 0 || start > d->control->text().length() || end > d->control->text().length())
+        return;
+    d->control->setSelection(start, end-start);
+}
+
+/*!
+    \qmlproperty string QtQuick2::TextInput::selectedText
+
+    This read-only property provides the text currently selected in the
+    text input.
+
+    It is equivalent to the following snippet, but is faster and easier
+    to use.
+
+    \js
+    myTextInput.text.toString().substring(myTextInput.selectionStart,
+        myTextInput.selectionEnd);
+    \endjs
+*/
+QString QQuickTextInput::selectedText() const
+{
+    Q_D(const QQuickTextInput);
+    return d->control->selectedText();
+}
+
+/*!
+    \qmlproperty bool QtQuick2::TextInput::activeFocusOnPress
+
+    Whether the TextInput should gain active focus on a mouse press. By default this is
+    set to true.
+*/
+bool QQuickTextInput::focusOnPress() const
+{
+    Q_D(const QQuickTextInput);
+    return d->focusOnPress;
+}
+
+void QQuickTextInput::setFocusOnPress(bool b)
+{
+    Q_D(QQuickTextInput);
+    if (d->focusOnPress == b)
+        return;
+
+    d->focusOnPress = b;
+
+    emit activeFocusOnPressChanged(d->focusOnPress);
+}
+/*!
+    \qmlproperty bool QtQuick2::TextInput::autoScroll
+
+    Whether the TextInput should scroll when the text is longer than the width. By default this is
+    set to true.
+*/
+bool QQuickTextInput::autoScroll() const
+{
+    Q_D(const QQuickTextInput);
+    return d->autoScroll;
+}
+
+void QQuickTextInput::setAutoScroll(bool b)
+{
+    Q_D(QQuickTextInput);
+    if (d->autoScroll == b)
+        return;
+
+    d->autoScroll = b;
+    //We need to repaint so that the scrolling is taking into account.
+    updateSize(true);
+    updateCursorRectangle();
+    emit autoScrollChanged(d->autoScroll);
+}
+
+#ifndef QT_NO_VALIDATOR
+
+/*!
+    \qmlclass IntValidator QIntValidator
+    \inqmlmodule QtQuick 2
+    \ingroup qml-basic-visual-elements
+
+    This element provides a validator for integer values.
+
+    IntValidator uses the \l {QLocale::setDefault()}{default locale} to interpret the number and
+    will accept locale specific digits, group separators, and positive and negative signs.  In
+    addition, IntValidator is always guaranteed to accept a number formatted according to the "C"
+    locale.
+*/
+/*!
+    \qmlproperty int QtQuick2::IntValidator::top
+
+    This property holds the validator's highest acceptable value.
+    By default, this property's value is derived from the highest signed integer available (typically 2147483647).
+*/
+/*!
+    \qmlproperty int QtQuick2::IntValidator::bottom
+
+    This property holds the validator's lowest acceptable value.
+    By default, this property's value is derived from the lowest signed integer available (typically -2147483647).
+*/
+
+/*!
+    \qmlclass DoubleValidator QDoubleValidator
+    \inqmlmodule QtQuick 2
+    \ingroup qml-basic-visual-elements
+
+    This element provides a validator for non-integer numbers.
+*/
+
+/*!
+    \qmlproperty real QtQuick2::DoubleValidator::top
+
+    This property holds the validator's maximum acceptable value.
+    By default, this property contains a value of infinity.
+*/
+/*!
+    \qmlproperty real QtQuick2::DoubleValidator::bottom
+
+    This property holds the validator's minimum acceptable value.
+    By default, this property contains a value of -infinity.
+*/
+/*!
+    \qmlproperty int QtQuick2::DoubleValidator::decimals
+
+    This property holds the validator's maximum number of digits after the decimal point.
+    By default, this property contains a value of 1000.
+*/
+/*!
+    \qmlproperty enumeration QtQuick2::DoubleValidator::notation
+    This property holds the notation of how a string can describe a number.
+
+    The possible values for this property are:
+
+    \list
+    \o DoubleValidator.StandardNotation
+    \o DoubleValidator.ScientificNotation (default)
+    \endlist
+
+    If this property is set to DoubleValidator.ScientificNotation, the written number may have an exponent part (e.g. 1.5E-2).
+*/
+
+/*!
+    \qmlclass RegExpValidator QRegExpValidator
+    \inqmlmodule QtQuick 2
+    \ingroup qml-basic-visual-elements
+
+    This element provides a validator, which counts as valid any string which
+    matches a specified regular expression.
+*/
+/*!
+   \qmlproperty regExp QtQuick2::RegExpValidator::regExp
+
+   This property holds the regular expression used for validation.
+
+   Note that this property should be a regular expression in JS syntax, e.g /a/ for the regular expression
+   matching "a".
+
+   By default, this property contains a regular expression with the pattern .* that matches any string.
+*/
+
+/*!
+    \qmlproperty Validator QtQuick2::TextInput::validator
+
+    Allows you to set a validator on the TextInput. When a validator is set
+    the TextInput will only accept input which leaves the text property in
+    an acceptable or intermediate state. The accepted signal will only be sent
+    if the text is in an acceptable state when enter is pressed.
+
+    Currently supported validators are IntValidator, DoubleValidator and
+    RegExpValidator. An example of using validators is shown below, which allows
+    input of integers between 11 and 31 into the text input:
+
+    \code
+    import QtQuick 1.0
+    TextInput{
+        validator: IntValidator{bottom: 11; top: 31;}
+        focus: true
+    }
+    \endcode
+
+    \sa acceptableInput, inputMask
+*/
+
+QValidator* QQuickTextInput::validator() const
+{
+    Q_D(const QQuickTextInput);
+    //###const cast isn't good, but needed for property system?
+    return const_cast<QValidator*>(d->control->validator());
+}
+
+void QQuickTextInput::setValidator(QValidator* v)
+{
+    Q_D(QQuickTextInput);
+    if (d->control->validator() == v)
+        return;
+
+    d->control->setValidator(v);
+    if (!d->control->hasAcceptableInput()) {
+        d->oldValidity = false;
+        emit acceptableInputChanged();
+    }
+
+    emit validatorChanged();
+}
+#endif // QT_NO_VALIDATOR
+
+/*!
+    \qmlproperty string QtQuick2::TextInput::inputMask
+
+    Allows you to set an input mask on the TextInput, restricting the allowable
+    text inputs. See QLineEdit::inputMask for further details, as the exact
+    same mask strings are used by TextInput.
+
+    \sa acceptableInput, validator
+*/
+QString QQuickTextInput::inputMask() const
+{
+    Q_D(const QQuickTextInput);
+    return d->control->inputMask();
+}
+
+void QQuickTextInput::setInputMask(const QString &im)
+{
+    Q_D(QQuickTextInput);
+    if (d->control->inputMask() == im)
+        return;
+
+    d->control->setInputMask(im);
+    emit inputMaskChanged(d->control->inputMask());
+}
+
+/*!
+    \qmlproperty bool QtQuick2::TextInput::acceptableInput
+
+    This property is always true unless a validator or input mask has been set.
+    If a validator or input mask has been set, this property will only be true
+    if the current text is acceptable to the validator or input mask as a final
+    string (not as an intermediate string).
+*/
+bool QQuickTextInput::hasAcceptableInput() const
+{
+    Q_D(const QQuickTextInput);
+    return d->control->hasAcceptableInput();
+}
+
+/*!
+    \qmlsignal QtQuick2::TextInput::onAccepted()
+
+    This handler is called when the Return or Enter key is pressed.
+    Note that if there is a \l validator or \l inputMask set on the text
+    input, the handler will only be emitted if the input is in an acceptable
+    state.
+*/
+
+void QQuickTextInputPrivate::updateInputMethodHints()
+{
+    Q_Q(QQuickTextInput);
+    Qt::InputMethodHints hints = inputMethodHints;
+    uint echo = control->echoMode();
+    if (echo == QQuickTextInput::Password || echo == QQuickTextInput::NoEcho)
+        hints |= Qt::ImhHiddenText;
+    else if (echo == QQuickTextInput::PasswordEchoOnEdit)
+        hints &= ~Qt::ImhHiddenText;
+    if (echo != QQuickTextInput::Normal)
+        hints |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText);
+    q->setInputMethodHints(hints);
+}
+/*!
+    \qmlproperty enumeration QtQuick2::TextInput::echoMode
+
+    Specifies how the text should be displayed in the TextInput.
+    \list
+    \o TextInput.Normal - Displays the text as it is. (Default)
+    \o TextInput.Password - Displays asterixes instead of characters.
+    \o TextInput.NoEcho - Displays nothing.
+    \o TextInput.PasswordEchoOnEdit - Displays characters as they are entered
+    while editing, otherwise displays asterisks.
+    \endlist
+*/
+QQuickTextInput::EchoMode QQuickTextInput::echoMode() const
+{
+    Q_D(const QQuickTextInput);
+    return (QQuickTextInput::EchoMode)d->control->echoMode();
+}
+
+void QQuickTextInput::setEchoMode(QQuickTextInput::EchoMode echo)
+{
+    Q_D(QQuickTextInput);
+    if (echoMode() == echo)
+        return;
+    d->control->setEchoMode((QLineControl::EchoMode)echo);
+    d->updateInputMethodHints();
+    q_textChanged();
+    emit echoModeChanged(echoMode());
+}
+
+Qt::InputMethodHints QQuickTextInput::imHints() const
+{
+    Q_D(const QQuickTextInput);
+    return d->inputMethodHints;
+}
+
+void QQuickTextInput::setIMHints(Qt::InputMethodHints hints)
+{
+    Q_D(QQuickTextInput);
+    if (d->inputMethodHints == hints)
+        return;
+    d->inputMethodHints = hints;
+    d->updateInputMethodHints();
+}
+
+/*!
+    \qmlproperty Component QtQuick2::TextInput::cursorDelegate
+    The delegate for the cursor in the TextInput.
+
+    If you set a cursorDelegate for a TextInput, this delegate will be used for
+    drawing the cursor instead of the standard cursor. An instance of the
+    delegate will be created and managed by the TextInput when a cursor is
+    needed, and the x property of delegate instance will be set so as
+    to be one pixel before the top left of the current character.
+
+    Note that the root item of the delegate component must be a QDeclarativeItem or
+    QDeclarativeItem derived item.
+*/
+QDeclarativeComponent* QQuickTextInput::cursorDelegate() const
+{
+    Q_D(const QQuickTextInput);
+    return d->cursorComponent;
+}
+
+void QQuickTextInput::setCursorDelegate(QDeclarativeComponent* c)
+{
+    Q_D(QQuickTextInput);
+    if (d->cursorComponent == c)
+        return;
+
+    d->cursorComponent = c;
+    if (!c) {
+        //note that the components are owned by something else
+        delete d->cursorItem;
+    } else {
+        d->startCreatingCursor();
+    }
+
+    emit cursorDelegateChanged();
+}
+
+void QQuickTextInputPrivate::startCreatingCursor()
+{
+    Q_Q(QQuickTextInput);
+    if (cursorComponent->isReady()) {
+        q->createCursor();
+    } else if (cursorComponent->isLoading()) {
+        q->connect(cursorComponent, SIGNAL(statusChanged(int)),
+                q, SLOT(createCursor()));
+    } else { // isError
+        qmlInfo(q, cursorComponent->errors()) << QQuickTextInput::tr("Could not load cursor delegate");
+    }
+}
+
+void QQuickTextInput::createCursor()
+{
+    Q_D(QQuickTextInput);
+    if (d->cursorComponent->isError()) {
+        qmlInfo(this, d->cursorComponent->errors()) << tr("Could not load cursor delegate");
+        return;
+    }
+
+    if (!d->cursorComponent->isReady())
+        return;
+
+    if (d->cursorItem)
+        delete d->cursorItem;
+    QDeclarativeContext *creationContext = d->cursorComponent->creationContext();
+    QObject *object = d->cursorComponent->create(creationContext ? creationContext : qmlContext(this));
+    d->cursorItem = qobject_cast<QQuickItem*>(object);
+    if (!d->cursorItem) {
+        delete object;
+        qmlInfo(this, d->cursorComponent->errors()) << tr("Could not instantiate cursor delegate");
+        return;
+    }
+
+    QDeclarative_setParent_noEvent(d->cursorItem, this);
+    d->cursorItem->setParentItem(this);
+    d->cursorItem->setX(d->control->cursorToX());
+    d->cursorItem->setHeight(d->control->height()-1); // -1 to counter QLineControl's +1 which is not consistent with Text.
+}
+
+/*!
+    \qmlmethod rect QtQuick2::TextInput::positionToRectangle(int pos)
+
+    This function takes a character position and returns the rectangle that the
+    cursor would occupy, if it was placed at that character position.
+
+    This is similar to setting the cursorPosition, and then querying the cursor
+    rectangle, but the cursorPosition is not changed.
+*/
+QRectF QQuickTextInput::positionToRectangle(int pos) const
+{
+    Q_D(const QQuickTextInput);
+    if (pos > d->control->cursorPosition())
+        pos += d->control->preeditAreaText().length();
+    return QRectF(d->control->cursorToX(pos)-d->hscroll,
+        0.0,
+        d->control->cursorWidth(),
+        cursorRectangle().height());
+}
+
+/*!
+    \qmlmethod int QtQuick2::TextInput::positionAt(int x, CursorPosition position = CursorBetweenCharacters)
+
+    This function returns the character position at
+    x pixels from the left of the textInput. Position 0 is before the
+    first character, position 1 is after the first character but before the second,
+    and so on until position text.length, which is after all characters.
+
+    This means that for all x values before the first character this function returns 0,
+    and for all x values after the last character this function returns text.length.
+
+    The cursor position type specifies how the cursor position should be resolved.
+
+    \list
+    \o TextInput.CursorBetweenCharacters - Returns the position between characters that is nearest x.
+    \o TextInput.CursorOnCharacter - Returns the position before the character that is nearest x.
+    \endlist
+*/
+int QQuickTextInput::positionAt(int x) const
+{
+    return positionAt(x, CursorBetweenCharacters);
+}
+
+int QQuickTextInput::positionAt(int x, CursorPosition position) const
+{
+    Q_D(const QQuickTextInput);
+    int pos = d->control->xToPos(x + d->hscroll, QTextLine::CursorPosition(position));
+    const int cursor = d->control->cursor();
+    if (pos > cursor) {
+        const int preeditLength = d->control->preeditAreaText().length();
+        pos = pos > cursor + preeditLength
+                ? pos - preeditLength
+                : cursor;
+    }
+    return pos;
+}
+
+void QQuickTextInput::keyPressEvent(QKeyEvent* ev)
+{
+    Q_D(QQuickTextInput);
+    // Don't allow MacOSX up/down support, and we don't allow a completer.
+    bool ignore = (ev->key() == Qt::Key_Up || ev->key() == Qt::Key_Down) && ev->modifiers() == Qt::NoModifier;
+    if (!ignore && (d->lastSelectionStart == d->lastSelectionEnd) && (ev->key() == Qt::Key_Right || ev->key() == Qt::Key_Left)) {
+        // Ignore when moving off the end unless there is a selection,
+        // because then moving will do something (deselect).
+        int cursorPosition = d->control->cursor();
+        if (cursorPosition == 0)
+            ignore = ev->key() == (d->control->layoutDirection() == Qt::LeftToRight ? Qt::Key_Left : Qt::Key_Right);
+        if (cursorPosition == d->control->text().length())
+            ignore = ev->key() == (d->control->layoutDirection() == Qt::LeftToRight ? Qt::Key_Right : Qt::Key_Left);
+    }
+    if (ignore) {
+        ev->ignore();
+    } else {
+        d->control->processKeyEvent(ev);
+    }
+    if (!ev->isAccepted())
+        QQuickImplicitSizeItem::keyPressEvent(ev);
+}
+
+void QQuickTextInput::inputMethodEvent(QInputMethodEvent *ev)
+{
+    Q_D(QQuickTextInput);
+    const bool wasComposing = d->control->preeditAreaText().length() > 0;
+    if (d->control->isReadOnly()) {
+        ev->ignore();
+    } else {
+        d->control->processInputMethodEvent(ev);
+    }
+    if (!ev->isAccepted())
+        QQuickImplicitSizeItem::inputMethodEvent(ev);
+
+    if (wasComposing != (d->control->preeditAreaText().length() > 0))
+        emit inputMethodComposingChanged();
+}
+
+void QQuickTextInput::mouseDoubleClickEvent(QMouseEvent *event)
+{
+    Q_D(QQuickTextInput);
+    if (d->sendMouseEventToInputContext(event))
+        return;
+    if (d->selectByMouse) {
+        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 {
+        QQuickImplicitSizeItem::mouseDoubleClickEvent(event);
+    }
+}
+
+void QQuickTextInput::mousePressEvent(QMouseEvent *event)
+{
+    Q_D(QQuickTextInput);
+    if (d->sendMouseEventToInputContext(event))
+        return;
+    if (d->focusOnPress) {
+        bool hadActiveFocus = hasActiveFocus();
+        forceActiveFocus();
+        // 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());
+    d->control->moveCursor(cursor, mark);
+    event->setAccepted(true);
+}
+
+void QQuickTextInput::mouseMoveEvent(QMouseEvent *event)
+{
+    Q_D(QQuickTextInput);
+    if (d->sendMouseEventToInputContext(event))
+        return;
+    if (d->selectPressed) {
+        if (qAbs(int(event->localPos().x() - d->pressPos.x())) > qApp->styleHints()->startDragDistance())
+            setKeepMouseGrab(true);
+        moveCursorSelection(d->xToPos(event->localPos().x()), d->mouseSelectionMode);
+        event->setAccepted(true);
+    } else {
+        QQuickImplicitSizeItem::mouseMoveEvent(event);
+    }
+}
+
+void QQuickTextInput::mouseReleaseEvent(QMouseEvent *event)
+{
+    Q_D(QQuickTextInput);
+    if (d->sendMouseEventToInputContext(event))
+        return;
+    if (d->selectPressed) {
+        d->selectPressed = false;
+        setKeepMouseGrab(false);
+    }
+    d->control->processEvent(event);
+    if (!event->isAccepted())
+        QQuickImplicitSizeItem::mouseReleaseEvent(event);
+}
+
+bool QQuickTextInputPrivate::sendMouseEventToInputContext(QMouseEvent *event)
+{
+#if !defined QT_NO_IM
+    if (control->composeMode() && event->type() == QEvent::KeyRelease) {
+        int tmp_cursor = xToPos(event->localPos().x());
+        int mousePos = tmp_cursor - control->cursor();
+        if (mousePos < 0 || mousePos > control->preeditAreaText().length()) {
+            mousePos = -1;
+            // don't send move events outside the preedit area
+            if (event->type() == QEvent::MouseMove)
+                return true;
+        }
+
+        // may be causing reset() in some input methods
+        qApp->inputPanel()->invokeAction(QInputPanel::Click, mousePos);
+        if (!control->preeditAreaText().isEmpty())
+            return true;
+    }
+#else
+    Q_UNUSED(event);
+    Q_UNUSED(eventType)
+#endif
+
+    return false;
+}
+
+void QQuickTextInput::mouseUngrabEvent()
+{
+    Q_D(QQuickTextInput);
+    d->selectPressed = false;
+    setKeepMouseGrab(false);
+}
+
+bool QQuickTextInput::event(QEvent* ev)
+{
+    Q_D(QQuickTextInput);
+    //Anything we don't deal with ourselves, pass to the control
+    bool handled = false;
+    switch (ev->type()) {
+        case QEvent::KeyPress:
+        case QEvent::KeyRelease://###Should the control be doing anything with release?
+        case QEvent::InputMethod:
+        case QEvent::MouseButtonPress:
+        case QEvent::MouseMove:
+        case QEvent::MouseButtonRelease:
+        case QEvent::MouseButtonDblClick:
+            break;
+        default:
+            handled = d->control->processEvent(ev);
+    }
+    if (!handled)
+        handled = QQuickImplicitSizeItem::event(ev);
+    return handled;
+}
+
+void QQuickTextInput::geometryChanged(const QRectF &newGeometry,
+                                  const QRectF &oldGeometry)
+{
+    if (newGeometry.width() != oldGeometry.width()) {
+        updateSize();
+        updateCursorRectangle();
+    }
+    QQuickImplicitSizeItem::geometryChanged(newGeometry, oldGeometry);
+}
+
+int QQuickTextInputPrivate::calculateTextWidth()
+{
+    return qRound(control->naturalTextWidth());
+}
+
+void QQuickTextInputPrivate::updateHorizontalScroll()
+{
+    Q_Q(QQuickTextInput);
+    const int preeditLength = control->preeditAreaText().length();
+    const int width = q->width();
+    int widthUsed = calculateTextWidth();
+
+    if (!autoScroll || widthUsed <=  width) {
+        QQuickTextInput::HAlignment effectiveHAlign = q->effectiveHAlign();
+        // text fits in br; use hscroll for alignment
+        switch (effectiveHAlign & ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask)) {
+        case Qt::AlignRight:
+            hscroll = widthUsed - width;
+            break;
+        case Qt::AlignHCenter:
+            hscroll = (widthUsed - width) / 2;
+            break;
+        default:
+            // Left
+            hscroll = 0;
+            break;
+        }
+    } else {
+        int cix = qRound(control->cursorToX(control->cursor() + preeditLength));
+        if (cix - hscroll >= width) {
+            // text doesn't fit, cursor is to the right of br (scroll right)
+            hscroll = cix - width;
+        } else if (cix - hscroll < 0 && hscroll < widthUsed) {
+            // text doesn't fit, cursor is to the left of br (scroll left)
+            hscroll = cix;
+        } else if (widthUsed - hscroll < width) {
+            // text doesn't fit, text document is to the left of br; align
+            // right
+            hscroll = widthUsed - width;
+        }
+        if (preeditLength > 0) {
+            // check to ensure long pre-edit text doesn't push the cursor
+            // off to the left
+             cix = qRound(control->cursorToX(
+                     control->cursor() + qMax(0, control->preeditCursor() - 1)));
+             if (cix < hscroll)
+                 hscroll = cix;
+        }
+    }
+}
+
+QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
+{
+    Q_UNUSED(data);
+    Q_D(QQuickTextInput);
+
+    QQuickTextNode *node = static_cast<QQuickTextNode *>(oldNode);
+    if (node == 0)
+        node = new QQuickTextNode(QQuickItemPrivate::get(this)->sceneGraphContext());
+    d->textNode = node;
+
+    if (!d->textLayoutDirty) {
+        QSGSimpleRectNode *cursorNode = node->cursorNode();
+        if (cursorNode != 0 && !isReadOnly()) {
+            QFontMetrics fm = QFontMetrics(d->font);
+            // the y offset is there to keep the baseline constant in case we have script changes in the text.
+            QPoint offset(-d->hscroll, fm.ascent() - d->control->ascent());
+            offset.rx() += d->control->cursorToX();
+
+            QRect br(boundingRect().toRect());
+            cursorNode->setRect(QRectF(offset, QSizeF(d->control->cursorWidth(), br.height())));
+
+            if (!d->cursorVisible
+                    || (!d->control->cursorBlinkStatus() && d->control->cursorBlinkPeriod() > 0)) {
+                d->hideCursor();
+            } else {
+                d->showCursor();
+            }
+        }
+    } else {
+        node->deleteContent();
+        node->setMatrix(QMatrix4x4());
+
+        QPoint offset = QPoint(0,0);
+        QFontMetrics fm = QFontMetrics(d->font);
+        QRect br(boundingRect().toRect());
+        if (d->autoScroll) {
+            // the y offset is there to keep the baseline constant in case we have script changes in the text.
+            offset = br.topLeft() - QPoint(d->hscroll, d->control->ascent() - fm.ascent());
+        } else {
+            offset = QPoint(d->hscroll, 0);
+        }
+
+        QTextLayout *textLayout = d->control->textLayout();
+        if (!textLayout->text().isEmpty()) {
+            node->addTextLayout(offset, textLayout, d->color,
+                                QQuickText::Normal, QColor(),
+                                d->selectionColor, d->selectedTextColor,
+                                d->control->selectionStart(),
+                                d->control->selectionEnd() - 1); // selectionEnd() returns first char after
+                                                                 // selection
+        }
+
+        if (!isReadOnly() && d->cursorItem == 0) {
+            offset.rx() += d->control->cursorToX();
+            node->setCursor(QRectF(offset, QSizeF(d->control->cursorWidth(), br.height())), d->color);
+            if (!d->cursorVisible
+                    || (!d->control->cursorBlinkStatus() && d->control->cursorBlinkPeriod() > 0)) {
+                d->hideCursor();
+            } else {
+                d->showCursor();
+            }
+        }
+
+        d->textLayoutDirty = false;
+    }
+
+    return node;
+}
+
+QVariant QQuickTextInput::inputMethodQuery(Qt::InputMethodQuery property) const
+{
+    Q_D(const QQuickTextInput);
+    switch (property) {
+    case Qt::ImEnabled:
+        return QVariant((bool)(flags() & ItemAcceptsInputMethod));
+    case Qt::ImHints:
+        return QVariant((int)inputMethodHints());
+    case Qt::ImCursorRectangle:
+        return cursorRectangle();
+    case Qt::ImFont:
+        return font();
+    case Qt::ImCursorPosition:
+        return QVariant(d->control->cursor());
+    case Qt::ImSurroundingText:
+        if (d->control->echoMode() == QLineControl::PasswordEchoOnEdit
+            && !d->control->passwordEchoEditing()) {
+            return QVariant(displayText());
+        } else {
+            return QVariant(text());
+        }
+    case Qt::ImCurrentSelection:
+        return QVariant(selectedText());
+    case Qt::ImMaximumTextLength:
+        return QVariant(maxLength());
+    case Qt::ImAnchorPosition:
+        if (d->control->selectionStart() == d->control->selectionEnd())
+            return QVariant(d->control->cursor());
+        else if (d->control->selectionStart() == d->control->cursor())
+            return QVariant(d->control->selectionEnd());
+        else
+            return QVariant(d->control->selectionStart());
+    default:
+        return QVariant();
+    }
+}
+
+/*!
+    \qmlmethod void QtQuick2::TextInput::deselect()
+
+    Removes active text selection.
+*/
+void QQuickTextInput::deselect()
+{
+    Q_D(QQuickTextInput);
+    d->control->deselect();
+}
+
+/*!
+    \qmlmethod void QtQuick2::TextInput::selectAll()
+
+    Causes all text to be selected.
+*/
+void QQuickTextInput::selectAll()
+{
+    Q_D(QQuickTextInput);
+    d->control->setSelection(0, d->control->text().length());
+}
+
+/*!
+    \qmlmethod void QtQuick2::TextInput::isRightToLeft(int start, int end)
+
+    Returns true if the natural reading direction of the editor text
+    found between positions \a start and \a end is right to left.
+*/
+bool QQuickTextInput::isRightToLeft(int start, int end)
+{
+    Q_D(QQuickTextInput);
+    if (start > end) {
+        qmlInfo(this) << "isRightToLeft(start, end) called with the end property being smaller than the start.";
+        return false;
+    } else {
+        return d->control->text().mid(start, end - start).isRightToLeft();
+    }
+}
+
+#ifndef QT_NO_CLIPBOARD
+/*!
+    \qmlmethod QtQuick2::TextInput::cut()
+
+    Moves the currently selected text to the system clipboard.
+*/
+void QQuickTextInput::cut()
+{
+    Q_D(QQuickTextInput);
+    d->control->copy();
+    d->control->del();
+}
+
+/*!
+    \qmlmethod QtQuick2::TextInput::copy()
+
+    Copies the currently selected text to the system clipboard.
+*/
+void QQuickTextInput::copy()
+{
+    Q_D(QQuickTextInput);
+    d->control->copy();
+}
+
+/*!
+    \qmlmethod QtQuick2::TextInput::paste()
+
+    Replaces the currently selected text by the contents of the system clipboard.
+*/
+void QQuickTextInput::paste()
+{
+    Q_D(QQuickTextInput);
+    if (!d->control->isReadOnly())
+        d->control->paste();
+}
+#endif // QT_NO_CLIPBOARD
+
+/*!
+    \qmlmethod void QtQuick2::TextInput::selectWord()
+
+    Causes the word closest to the current cursor position to be selected.
+*/
+void QQuickTextInput::selectWord()
+{
+    Q_D(QQuickTextInput);
+    d->control->selectWordAtPos(d->control->cursor());
+}
+
+/*!
+    \qmlproperty bool QtQuick2::TextInput::smooth
+
+    This property holds whether the text is smoothly scaled or transformed.
+
+    Smooth filtering gives better visual quality, but is slower.  If
+    the item is displayed at its natural size, this property has no visual or
+    performance effect.
+
+    \note Generally scaling artifacts are only visible if the item is stationary on
+    the screen.  A common pattern when animating an item is to disable smooth
+    filtering at the beginning of the animation and reenable it at the conclusion.
+*/
+
+/*!
+   \qmlproperty string QtQuick2::TextInput::passwordCharacter
+
+   This is the character displayed when echoMode is set to Password or
+   PasswordEchoOnEdit. By default it is an asterisk.
+
+   If this property is set to a string with more than one character,
+   the first character is used. If the string is empty, the value
+   is ignored and the property is not set.
+*/
+QString QQuickTextInput::passwordCharacter() const
+{
+    Q_D(const QQuickTextInput);
+    return QString(d->control->passwordCharacter());
+}
+
+void QQuickTextInput::setPasswordCharacter(const QString &str)
+{
+    Q_D(QQuickTextInput);
+    if (str.length() < 1)
+        return;
+    d->control->setPasswordCharacter(str.constData()[0]);
+    EchoMode echoMode_ = echoMode();
+    if (echoMode_ == Password || echoMode_ == PasswordEchoOnEdit) {
+        updateSize();
+    }
+    emit passwordCharacterChanged();
+}
+
+/*!
+   \qmlproperty string QtQuick2::TextInput::displayText
+
+   This is the text displayed in the TextInput.
+
+   If \l echoMode is set to TextInput::Normal, this holds the
+   same value as the TextInput::text property. Otherwise,
+   this property holds the text visible to the user, while
+   the \l text property holds the actual entered text.
+*/
+QString QQuickTextInput::displayText() const
+{
+    Q_D(const QQuickTextInput);
+    return d->control->displayText();
+}
+
+/*!
+    \qmlproperty bool QtQuick2::TextInput::selectByMouse
+
+    Defaults to false.
+
+    If true, the user can use the mouse to select text in some
+    platform-specific way. Note that for some platforms this may
+    not be an appropriate interaction (eg. may conflict with how
+    the text needs to behave inside a Flickable.
+*/
+bool QQuickTextInput::selectByMouse() const
+{
+    Q_D(const QQuickTextInput);
+    return d->selectByMouse;
+}
+
+void QQuickTextInput::setSelectByMouse(bool on)
+{
+    Q_D(QQuickTextInput);
+    if (d->selectByMouse != on) {
+        d->selectByMouse = on;
+        emit selectByMouseChanged(on);
+    }
+}
+
+/*!
+    \qmlproperty enum QtQuick2::TextInput::mouseSelectionMode
+
+    Specifies how text should be selected using a mouse.
+
+    \list
+    \o TextInput.SelectCharacters - The selection is updated with individual characters. (Default)
+    \o TextInput.SelectWords - The selection is updated with whole words.
+    \endlist
+
+    This property only applies when \l selectByMouse is true.
+*/
+
+QQuickTextInput::SelectionMode QQuickTextInput::mouseSelectionMode() const
+{
+    Q_D(const QQuickTextInput);
+    return d->mouseSelectionMode;
+}
+
+void QQuickTextInput::setMouseSelectionMode(SelectionMode mode)
+{
+    Q_D(QQuickTextInput);
+    if (d->mouseSelectionMode != mode) {
+        d->mouseSelectionMode = mode;
+        emit mouseSelectionModeChanged(mode);
+    }
+}
+
+/*!
+    \qmlproperty bool QtQuick2::TextInput::canPaste
+
+    Returns true if the TextInput is writable and the content of the clipboard is
+    suitable for pasting into the TextEdit.
+*/
+bool QQuickTextInput::canPaste() const
+{
+    Q_D(const QQuickTextInput);
+    return d->canPaste;
+}
+
+void QQuickTextInput::moveCursorSelection(int position)
+{
+    Q_D(QQuickTextInput);
+    d->control->moveCursor(position, true);
+}
+
+/*!
+    \qmlmethod void QtQuick2::TextInput::moveCursorSelection(int position, SelectionMode mode = TextInput.SelectCharacters)
+
+    Moves the cursor to \a position and updates the selection according to the optional \a mode
+    parameter.  (To only move the cursor, set the \l cursorPosition property.)
+
+    When this method is called it additionally sets either the
+    selectionStart or the selectionEnd (whichever was at the previous cursor position)
+    to the specified position. This allows you to easily extend and contract the selected
+    text range.
+
+    The selection mode specifies whether the selection is updated on a per character or a per word
+    basis.  If not specified the selection mode will default to TextInput.SelectCharacters.
+
+    \list
+    \o TextEdit.SelectCharacters - Sets either the selectionStart or selectionEnd (whichever was at
+    the previous cursor position) to the specified position.
+    \o TextEdit.SelectWords - Sets the selectionStart and selectionEnd to include all
+    words between the specified postion and the previous cursor position.  Words partially in the
+    range are included.
+    \endlist
+
+    For example, take this sequence of calls:
+
+    \code
+        cursorPosition = 5
+        moveCursorSelection(9, TextInput.SelectCharacters)
+        moveCursorSelection(7, TextInput.SelectCharacters)
+    \endcode
+
+    This moves the cursor to position 5, extend the selection end from 5 to 9
+    and then retract the selection end from 9 to 7, leaving the text from position 5 to 7
+    selected (the 6th and 7th characters).
+
+    The same sequence with TextInput.SelectWords will extend the selection start to a word boundary
+    before or on position 5 and extend the selection end to a word boundary on or past position 9.
+*/
+void QQuickTextInput::moveCursorSelection(int pos, SelectionMode mode)
+{
+    Q_D(QQuickTextInput);
+
+    if (mode == SelectCharacters) {
+        d->control->moveCursor(pos, true);
+    } else if (pos != d->control->cursor()){
+        const int cursor = d->control->cursor();
+        int anchor;
+        if (!d->control->hasSelectedText())
+            anchor = d->control->cursor();
+        else if (d->control->selectionStart() == d->control->cursor())
+            anchor = d->control->selectionEnd();
+        else
+            anchor = d->control->selectionStart();
+
+        if (anchor < pos || (anchor == pos && cursor < pos)) {
+            const QString text = d->control->text();
+            QTextBoundaryFinder finder(QTextBoundaryFinder::Word, text);
+            finder.setPosition(anchor);
+
+            const QTextBoundaryFinder::BoundaryReasons reasons = finder.boundaryReasons();
+            if (anchor < text.length() && (!(reasons & QTextBoundaryFinder::StartWord)
+                    || ((reasons & QTextBoundaryFinder::EndWord) && anchor > cursor))) {
+                finder.toPreviousBoundary();
+            }
+            anchor = finder.position() != -1 ? finder.position() : 0;
+
+            finder.setPosition(pos);
+            if (pos > 0 && !finder.boundaryReasons())
+                finder.toNextBoundary();
+            const int cursor = finder.position() != -1 ? finder.position() : text.length();
+
+            d->control->setSelection(anchor, cursor - anchor);
+        } else if (anchor > pos || (anchor == pos && cursor > pos)) {
+            const QString text = d->control->text();
+            QTextBoundaryFinder finder(QTextBoundaryFinder::Word, text);
+            finder.setPosition(anchor);
+
+            const QTextBoundaryFinder::BoundaryReasons reasons = finder.boundaryReasons();
+            if (anchor > 0 && (!(reasons & QTextBoundaryFinder::EndWord)
+                    || ((reasons & QTextBoundaryFinder::StartWord) && anchor < cursor))) {
+                finder.toNextBoundary();
+            }
+
+            anchor = finder.position() != -1 ? finder.position() : text.length();
+
+            finder.setPosition(pos);
+            if (pos < text.length() && !finder.boundaryReasons())
+                 finder.toPreviousBoundary();
+            const int cursor = finder.position() != -1 ? finder.position() : 0;
+
+            d->control->setSelection(anchor, cursor - anchor);
+        }
+    }
+}
+
+/*!
+    \qmlmethod void QtQuick2::TextInput::openSoftwareInputPanel()
+
+    Opens software input panels like virtual keyboards for typing, useful for
+    customizing when you want the input keyboard to be shown and hidden in
+    your application.
+
+    By default the opening of input panels follows the platform style. On Symbian^1 and
+    Symbian^3 -based devices the panels are opened by clicking TextInput. On other platforms
+    the panels are automatically opened when TextInput element gains active focus. Input panels are
+    always closed if no editor has active focus.
+
+  . You can disable the automatic behavior by setting the property \c activeFocusOnPress to false
+    and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement
+    the behavior you want.
+
+    Only relevant on platforms, which provide virtual keyboards.
+
+    \qml
+        import QtQuick 1.0
+        TextInput {
+            id: textInput
+            text: "Hello world!"
+            activeFocusOnPress: false
+            MouseArea {
+                anchors.fill: parent
+                onClicked: {
+                    if (!textInput.activeFocus) {
+                        textInput.forceActiveFocus()
+                        textInput.openSoftwareInputPanel();
+                    } else {
+                        textInput.focus = false;
+                    }
+                }
+                onPressAndHold: textInput.closeSoftwareInputPanel();
+            }
+        }
+    \endqml
+*/
+void QQuickTextInput::openSoftwareInputPanel()
+{
+    if (qGuiApp)
+        qGuiApp->inputPanel()->show();
+}
+
+/*!
+    \qmlmethod void QtQuick2::TextInput::closeSoftwareInputPanel()
+
+    Closes a software input panel like a virtual keyboard shown on the screen, useful
+    for customizing when you want the input keyboard to be shown and hidden in
+    your application.
+
+    By default the opening of input panels follows the platform style. On Symbian^1 and
+    Symbian^3 -based devices the panels are opened by clicking TextInput. On other platforms
+    the panels are automatically opened when TextInput element gains active focus. Input panels are
+    always closed if no editor has active focus.
+
+  . You can disable the automatic behavior by setting the property \c activeFocusOnPress to false
+    and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement
+    the behavior you want.
+
+    Only relevant on platforms, which provide virtual keyboards.
+
+    \qml
+        import QtQuick 1.0
+        TextInput {
+            id: textInput
+            text: "Hello world!"
+            activeFocusOnPress: false
+            MouseArea {
+                anchors.fill: parent
+                onClicked: {
+                    if (!textInput.activeFocus) {
+                        textInput.forceActiveFocus();
+                        textInput.openSoftwareInputPanel();
+                    } else {
+                        textInput.focus = false;
+                    }
+                }
+                onPressAndHold: textInput.closeSoftwareInputPanel();
+            }
+        }
+    \endqml
+*/
+void QQuickTextInput::closeSoftwareInputPanel()
+{
+    if (qGuiApp)
+        qGuiApp->inputPanel()->hide();
+}
+
+void QQuickTextInput::focusInEvent(QFocusEvent *event)
+{
+    Q_D(const QQuickTextInput);
+    if (d->focusOnPress && !isReadOnly())
+        openSoftwareInputPanel();
+    QQuickImplicitSizeItem::focusInEvent(event);
+}
+
+void QQuickTextInput::itemChange(ItemChange change, const ItemChangeData &value)
+{
+    Q_D(QQuickTextInput);
+    if (change == ItemActiveFocusHasChanged) {
+        bool hasFocus = value.boolValue;
+        d->focused = hasFocus;
+        setCursorVisible(hasFocus); // ### refactor:  && d->canvas && d->canvas->hasFocus()
+        if (echoMode() == QQuickTextInput::PasswordEchoOnEdit && !hasFocus)
+            d->control->updatePasswordEchoEditing(false);//QLineControl sets it on key events, but doesn't deal with focus events
+        if (!hasFocus)
+            d->control->deselect();
+    }
+    QQuickItem::itemChange(change, value);
+}
+
+/*!
+    \qmlproperty bool QtQuick2::TextInput::inputMethodComposing
+
+
+    This property holds whether the TextInput has partial text input from an
+    input method.
+
+    While it is composing an input method may rely on mouse or key events from
+    the TextInput to edit or commit the partial text.  This property can be
+    used to determine when to disable events handlers that may interfere with
+    the correct operation of an input method.
+*/
+bool QQuickTextInput::isInputMethodComposing() const
+{
+    Q_D(const QQuickTextInput);
+    return d->control->preeditAreaText().length() > 0;
+}
+
+void QQuickTextInputPrivate::init()
+{
+    Q_Q(QQuickTextInput);
+#if defined(Q_WS_MAC)
+    control->setThreadChecks(true);
+#endif
+    control->setParent(q);//Now mandatory due to accessibility changes
+    control->setCursorWidth(1);
+    control->setPasswordCharacter(QLatin1Char('*'));
+    q->setSmooth(smooth);
+    q->setAcceptedMouseButtons(Qt::LeftButton);
+    q->setFlag(QQuickItem::ItemAcceptsInputMethod);
+    q->setFlag(QQuickItem::ItemHasContents);
+    q->connect(control, SIGNAL(cursorPositionChanged(int,int)),
+               q, SLOT(cursorPosChanged()));
+    q->connect(control, SIGNAL(selectionChanged()),
+               q, SLOT(selectionChanged()));
+    q->connect(control, SIGNAL(textChanged(QString)),
+               q, SLOT(q_textChanged()));
+    q->connect(control, SIGNAL(accepted()),
+               q, SIGNAL(accepted()));
+    q->connect(control, SIGNAL(updateNeeded(QRect)),
+               q, SLOT(updateRect(QRect)));
+#ifndef QT_NO_CLIPBOARD
+    q->connect(q, SIGNAL(readOnlyChanged(bool)),
+            q, SLOT(q_canPasteChanged()));
+    q->connect(QGuiApplication::clipboard(), SIGNAL(dataChanged()),
+            q, SLOT(q_canPasteChanged()));
+    canPaste = !control->isReadOnly() && QGuiApplication::clipboard()->text().length() != 0;
+#endif // QT_NO_CLIPBOARD
+    q->connect(control, SIGNAL(updateMicroFocus()),
+               q, SLOT(updateCursorRectangle()));
+    q->connect(control, SIGNAL(displayTextChanged(QString)),
+               q, SLOT(updateRect()));
+    q->updateSize();
+    imHints &= ~Qt::ImhMultiLine;
+    oldValidity = control->hasAcceptableInput();
+    lastSelectionStart = 0;
+    lastSelectionEnd = 0;
+    QPalette p = control->palette();
+    selectedTextColor = p.color(QPalette::HighlightedText);
+    selectionColor = p.color(QPalette::Highlight);
+    determineHorizontalAlignment();
+
+    if (!qmlDisableDistanceField()) {
+        QTextOption option = control->textLayout()->textOption();
+        option.setUseDesignMetrics(true);
+        control->textLayout()->setTextOption(option);
+    }
+}
+
+void QQuickTextInput::cursorPosChanged()
+{
+    Q_D(QQuickTextInput);
+    updateCursorRectangle();
+    emit cursorPositionChanged();
+    // XXX todo - not in 4.8?
+#if 0
+    d->control->resetCursorBlinkTimer();
+#endif
+
+    if (!d->control->hasSelectedText()) {
+        if (d->lastSelectionStart != d->control->cursor()) {
+            d->lastSelectionStart = d->control->cursor();
+            emit selectionStartChanged();
+        }
+        if (d->lastSelectionEnd != d->control->cursor()) {
+            d->lastSelectionEnd = d->control->cursor();
+            emit selectionEndChanged();
+        }
+    }
+}
+
+void QQuickTextInput::updateCursorRectangle()
+{
+    Q_D(QQuickTextInput);
+    d->determineHorizontalAlignment();
+    d->updateHorizontalScroll();
+    updateRect();//TODO: Only update rect between pos's
+    updateMicroFocus();
+    emit cursorRectangleChanged();
+    if (d->cursorItem)
+        d->cursorItem->setX(d->control->cursorToX() - d->hscroll);
+}
+
+void QQuickTextInput::selectionChanged()
+{
+    Q_D(QQuickTextInput);
+    updateRect();//TODO: Only update rect in selection
+    emit selectedTextChanged();
+
+    if (d->lastSelectionStart != d->control->selectionStart()) {
+        d->lastSelectionStart = d->control->selectionStart();
+        if (d->lastSelectionStart == -1)
+            d->lastSelectionStart = d->control->cursor();
+        emit selectionStartChanged();
+    }
+    if (d->lastSelectionEnd != d->control->selectionEnd()) {
+        d->lastSelectionEnd = d->control->selectionEnd();
+        if (d->lastSelectionEnd == -1)
+            d->lastSelectionEnd = d->control->cursor();
+        emit selectionEndChanged();
+    }
+}
+
+void QQuickTextInput::q_textChanged()
+{
+    Q_D(QQuickTextInput);
+    emit textChanged();
+    emit displayTextChanged();
+    updateSize();
+    d->determineHorizontalAlignment();
+    d->updateHorizontalScroll();
+    updateMicroFocus();
+    if (hasAcceptableInput() != d->oldValidity) {
+        d->oldValidity = hasAcceptableInput();
+        emit acceptableInputChanged();
+    }
+}
+
+void QQuickTextInputPrivate::showCursor()
+{
+    if (textNode != 0 && textNode->cursorNode() != 0)
+        textNode->cursorNode()->setColor(color);
+}
+
+void QQuickTextInputPrivate::hideCursor()
+{
+    if (textNode != 0 && textNode->cursorNode() != 0)
+        textNode->cursorNode()->setColor(QColor(0, 0, 0, 0));
+}
+
+void QQuickTextInput::updateRect(const QRect &r)
+{
+    Q_D(QQuickTextInput);
+    if (!isComponentComplete())
+        return;
+
+    if (r.isEmpty()) {
+        d->textLayoutDirty = true;
+    }
+
+    update();
+}
+
+QRectF QQuickTextInput::boundingRect() const
+{
+    Q_D(const QQuickTextInput);
+    QRectF r = QQuickImplicitSizeItem::boundingRect();
+
+    int cursorWidth = d->cursorItem ? d->cursorItem->width() : d->control->cursorWidth();
+
+    // Could include font max left/right bearings to either side of rectangle.
+
+    r.setRight(r.right() + cursorWidth);
+    return r;
+}
+
+void QQuickTextInput::updateSize(bool needsRedraw)
+{
+    Q_D(QQuickTextInput);
+    int w = width();
+    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)
+        update();
+}
+
+void QQuickTextInput::q_canPasteChanged()
+{
+    Q_D(QQuickTextInput);
+    bool old = d->canPaste;
+#ifndef QT_NO_CLIPBOARD
+    d->canPaste = !d->control->isReadOnly() && QGuiApplication::clipboard()->text().length() != 0;
+#endif
+    if (d->canPaste != old)
+        emit canPasteChanged();
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/items/qquicktextinput_p.h b/src/declarative/items/qquicktextinput_p.h
new file mode 100644 (file)
index 0000000..a322b8c
--- /dev/null
@@ -0,0 +1,303 @@
+// Commit: 2f173e4945dd8414636c1061acfaf9c2d8b718d8
+/****************************************************************************
+**
+** 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 QQUICKTEXTINPUT_P_H
+#define QQUICKTEXTINPUT_P_H
+
+#include "qquickimplicitsizeitem_p.h"
+#include <QtGui/qvalidator.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickTextInputPrivate;
+class QValidator;
+class Q_AUTOTEST_EXPORT QQuickTextInput : public QQuickImplicitSizeItem
+{
+    Q_OBJECT
+    Q_ENUMS(HAlignment)
+    Q_ENUMS(EchoMode)
+    Q_ENUMS(SelectionMode)
+
+    Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
+    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
+    Q_PROPERTY(QColor selectionColor READ selectionColor WRITE setSelectionColor NOTIFY selectionColorChanged)
+    Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor NOTIFY selectedTextColorChanged)
+    Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
+    Q_PROPERTY(HAlignment horizontalAlignment READ hAlign WRITE setHAlign RESET resetHAlign NOTIFY horizontalAlignmentChanged)
+    Q_PROPERTY(HAlignment effectiveHorizontalAlignment READ effectiveHAlign NOTIFY effectiveHorizontalAlignmentChanged)
+
+    Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged)
+    Q_PROPERTY(bool cursorVisible READ isCursorVisible WRITE setCursorVisible NOTIFY cursorVisibleChanged)
+    Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged)
+    Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged)
+    Q_PROPERTY(QDeclarativeComponent *cursorDelegate READ cursorDelegate WRITE setCursorDelegate NOTIFY cursorDelegateChanged)
+    Q_PROPERTY(int selectionStart READ selectionStart NOTIFY selectionStartChanged)
+    Q_PROPERTY(int selectionEnd READ selectionEnd NOTIFY selectionEndChanged)
+    Q_PROPERTY(QString selectedText READ selectedText NOTIFY selectedTextChanged)
+
+    Q_PROPERTY(int maximumLength READ maxLength WRITE setMaxLength NOTIFY maximumLengthChanged)
+#ifndef QT_NO_VALIDATOR
+    Q_PROPERTY(QValidator* validator READ validator WRITE setValidator NOTIFY validatorChanged)
+#endif
+    Q_PROPERTY(QString inputMask READ inputMask WRITE setInputMask NOTIFY inputMaskChanged)
+    Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ imHints WRITE setIMHints)
+
+    Q_PROPERTY(bool acceptableInput READ hasAcceptableInput NOTIFY acceptableInputChanged)
+    Q_PROPERTY(EchoMode echoMode READ echoMode WRITE setEchoMode NOTIFY echoModeChanged)
+    Q_PROPERTY(bool activeFocusOnPress READ focusOnPress WRITE setFocusOnPress NOTIFY activeFocusOnPressChanged)
+    Q_PROPERTY(QString passwordCharacter READ passwordCharacter WRITE setPasswordCharacter NOTIFY passwordCharacterChanged)
+    Q_PROPERTY(QString displayText READ displayText NOTIFY displayTextChanged)
+    Q_PROPERTY(bool autoScroll READ autoScroll WRITE setAutoScroll NOTIFY autoScrollChanged)
+    Q_PROPERTY(bool selectByMouse READ selectByMouse WRITE setSelectByMouse NOTIFY selectByMouseChanged)
+    Q_PROPERTY(SelectionMode mouseSelectionMode READ mouseSelectionMode WRITE setMouseSelectionMode NOTIFY mouseSelectionModeChanged)
+    Q_PROPERTY(bool canPaste READ canPaste NOTIFY canPasteChanged)
+    Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged)
+
+public:
+    QQuickTextInput(QQuickItem * parent=0);
+    ~QQuickTextInput();
+
+    enum EchoMode {//To match QLineEdit::EchoMode
+        Normal,
+        NoEcho,
+        Password,
+        PasswordEchoOnEdit
+    };
+
+    enum HAlignment {
+        AlignLeft = Qt::AlignLeft,
+        AlignRight = Qt::AlignRight,
+        AlignHCenter = Qt::AlignHCenter
+    };
+
+    enum SelectionMode {
+        SelectCharacters,
+        SelectWords
+    };
+
+    enum CursorPosition {
+        CursorBetweenCharacters,
+        CursorOnCharacter
+    };
+
+    //Auxilliary functions needed to control the TextInput from QML
+    Q_INVOKABLE int positionAt(int x) const;
+    Q_INVOKABLE int positionAt(int x, CursorPosition position) const;
+    Q_INVOKABLE QRectF positionToRectangle(int pos) const;
+    Q_INVOKABLE void moveCursorSelection(int pos);
+    Q_INVOKABLE void moveCursorSelection(int pos, SelectionMode mode);
+
+    Q_INVOKABLE void openSoftwareInputPanel();
+    Q_INVOKABLE void closeSoftwareInputPanel();
+
+    QString text() const;
+    void setText(const QString &);
+
+    QFont font() const;
+    void setFont(const QFont &font);
+
+    QColor color() const;
+    void setColor(const QColor &c);
+
+    QColor selectionColor() const;
+    void setSelectionColor(const QColor &c);
+
+    QColor selectedTextColor() const;
+    void setSelectedTextColor(const QColor &c);
+
+    HAlignment hAlign() const;
+    void setHAlign(HAlignment align);
+    void resetHAlign();
+    HAlignment effectiveHAlign() const;
+
+    bool isReadOnly() const;
+    void setReadOnly(bool);
+
+    bool isCursorVisible() const;
+    void setCursorVisible(bool on);
+
+    int cursorPosition() const;
+    void setCursorPosition(int cp);
+
+    QRect cursorRectangle() const;
+
+    int selectionStart() const;
+    int selectionEnd() const;
+
+    QString selectedText() const;
+
+    int maxLength() const;
+    void setMaxLength(int ml);
+
+#ifndef QT_NO_VALIDATOR
+    QValidator * validator() const;
+    void setValidator(QValidator* v);
+#endif
+    QString inputMask() const;
+    void setInputMask(const QString &im);
+
+    EchoMode echoMode() const;
+    void setEchoMode(EchoMode echo);
+
+    QString passwordCharacter() const;
+    void setPasswordCharacter(const QString &str);
+
+    QString displayText() const;
+
+    QDeclarativeComponent* cursorDelegate() const;
+    void setCursorDelegate(QDeclarativeComponent*);
+
+    bool focusOnPress() const;
+    void setFocusOnPress(bool);
+
+    bool autoScroll() const;
+    void setAutoScroll(bool);
+
+    bool selectByMouse() const;
+    void setSelectByMouse(bool);
+
+    SelectionMode mouseSelectionMode() const;
+    void setMouseSelectionMode(SelectionMode mode);
+
+    bool hasAcceptableInput() const;
+
+    QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
+
+    QRectF boundingRect() const;
+    bool canPaste() const;
+
+    bool isInputMethodComposing() const;
+
+    Qt::InputMethodHints imHints() const;
+    void setIMHints(Qt::InputMethodHints hints);
+
+Q_SIGNALS:
+    void textChanged();
+    void cursorPositionChanged();
+    void cursorRectangleChanged();
+    void selectionStartChanged();
+    void selectionEndChanged();
+    void selectedTextChanged();
+    void accepted();
+    void acceptableInputChanged();
+    void colorChanged(const QColor &color);
+    void selectionColorChanged(const QColor &color);
+    void selectedTextColorChanged(const QColor &color);
+    void fontChanged(const QFont &font);
+    void horizontalAlignmentChanged(HAlignment alignment);
+    void readOnlyChanged(bool isReadOnly);
+    void cursorVisibleChanged(bool isCursorVisible);
+    void cursorDelegateChanged();
+    void maximumLengthChanged(int maximumLength);
+    void validatorChanged();
+    void inputMaskChanged(const QString &inputMask);
+    void echoModeChanged(EchoMode echoMode);
+    void passwordCharacterChanged();
+    void displayTextChanged();
+    void activeFocusOnPressChanged(bool activeFocusOnPress);
+    void autoScrollChanged(bool autoScroll);
+    void selectByMouseChanged(bool selectByMouse);
+    void mouseSelectionModeChanged(SelectionMode mode);
+    void canPasteChanged();
+    void inputMethodComposingChanged();
+    void effectiveHorizontalAlignmentChanged();
+
+protected:
+    virtual void geometryChanged(const QRectF &newGeometry,
+                                 const QRectF &oldGeometry);
+
+    void mousePressEvent(QMouseEvent *event);
+    void mouseMoveEvent(QMouseEvent *event);
+    void mouseReleaseEvent(QMouseEvent *event);
+    void mouseDoubleClickEvent(QMouseEvent *event);
+    bool sceneEvent(QEvent *event);
+    void keyPressEvent(QKeyEvent* ev);
+    void inputMethodEvent(QInputMethodEvent *);
+    void mouseUngrabEvent();
+    bool event(QEvent *e);
+    void focusInEvent(QFocusEvent *event);
+    virtual void itemChange(ItemChange, const ItemChangeData &);
+    QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data);
+
+public Q_SLOTS:
+    void selectAll();
+    void selectWord();
+    void select(int start, int end);
+    void deselect();
+    bool isRightToLeft(int start, int end);
+#ifndef QT_NO_CLIPBOARD
+    void cut();
+    void copy();
+    void paste();
+#endif
+
+private Q_SLOTS:
+    void updateSize(bool needsRedraw = true);
+    void q_textChanged();
+    void selectionChanged();
+    void createCursor();
+    void cursorPosChanged();
+    void updateCursorRectangle();
+    void updateRect(const QRect &r = QRect());
+    void q_canPasteChanged();
+
+private:
+    Q_DECLARE_PRIVATE(QQuickTextInput)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickTextInput)
+#ifndef QT_NO_VALIDATOR
+QML_DECLARE_TYPE(QValidator)
+QML_DECLARE_TYPE(QIntValidator)
+QML_DECLARE_TYPE(QDoubleValidator)
+QML_DECLARE_TYPE(QRegExpValidator)
+#endif
+
+QT_END_HEADER
+
+#endif // QQUICKTEXTINPUT_P_H
diff --git a/src/declarative/items/qquicktextinput_p_p.h b/src/declarative/items/qquicktextinput_p_p.h
new file mode 100644 (file)
index 0000000..900b080
--- /dev/null
@@ -0,0 +1,172 @@
+// Commit: 47712d1f330e4b22ce6dd30e7557288ef7f7fca0
+/****************************************************************************
+**
+** 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 QQUICKTEXTINPUT_P_P_H
+#define QQUICKTEXTINPUT_P_P_H
+
+#include "qquicktextinput_p.h"
+#include "qquicktext_p.h"
+#include "qquickimplicitsizeitem_p_p.h"
+
+#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>
+
+
+//
+//  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 QQuickTextNode;
+
+class Q_AUTOTEST_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeItemPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickTextInput)
+public:
+    QQuickTextInputPrivate()
+                 : control(new QLineControl(QString()))
+                 , color((QRgb)0)
+                 , style(QQuickText::Normal)
+                 , styleColor((QRgb)0)
+                 , hAlign(QQuickTextInput::AlignLeft)
+                 , mouseSelectionMode(QQuickTextInput::SelectCharacters)
+                 , inputMethodHints(Qt::ImhNone)
+                 , textNode(0)
+                 , hscroll(0)
+                 , oldScroll(0)
+                 , oldValidity(false)
+                 , focused(false)
+                 , focusOnPress(true)
+                 , cursorVisible(false)
+                 , autoScroll(true)
+                 , selectByMouse(false)
+                 , canPaste(false)
+                 , hAlignImplicit(true)
+                 , selectPressed(false)
+                 , textLayoutDirty(true)
+    {
+    }
+
+    ~QQuickTextInputPrivate()
+    {
+    }
+
+    int xToPos(int x, QTextLine::CursorPosition betweenOrOn = QTextLine::CursorBetweenCharacters) const
+    {
+        Q_Q(const QQuickTextInput);
+        QRect cr = q->boundingRect().toRect();
+        x-= cr.x() - hscroll;
+        return control->xToPos(x, betweenOrOn);
+    }
+
+    void init();
+    void startCreatingCursor();
+    void updateHorizontalScroll();
+    bool determineHorizontalAlignment();
+    bool setHAlign(QQuickTextInput::HAlignment, bool forceAlign = false);
+    void mirrorChange();
+    int calculateTextWidth();
+    bool sendMouseEventToInputContext(QMouseEvent *event);
+    void updateInputMethodHints();
+    void hideCursor();
+    void showCursor();
+
+    QLineControl* control;
+
+    QFont font;
+    QFont sourceFont;
+    QColor  color;
+    QColor  selectionColor;
+    QColor  selectedTextColor;
+    QQuickText::TextStyle style;
+    QColor  styleColor;
+    QQuickTextInput::HAlignment hAlign;
+    QQuickTextInput::SelectionMode mouseSelectionMode;
+    Qt::InputMethodHints inputMethodHints;
+    QPointer<QDeclarativeComponent> cursorComponent;
+    QPointer<QQuickItem> cursorItem;
+    QPointF pressPos;
+    QQuickTextNode *textNode;
+    QElapsedTimer tripleClickTimer;
+    QPoint tripleClickStartPoint;
+
+    int lastSelectionStart;
+    int lastSelectionEnd;
+    int oldHeight;
+    int oldWidth;
+    int hscroll;
+    int oldScroll;
+
+    bool oldValidity:1;
+    bool focused:1;
+    bool focusOnPress:1;
+    bool cursorVisible:1;
+    bool autoScroll:1;
+    bool selectByMouse:1;
+    bool canPaste:1;
+    bool hAlignImplicit:1;
+    bool selectPressed:1;
+    bool textLayoutDirty:1;
+
+    static inline QQuickTextInputPrivate *get(QQuickTextInput *t) {
+        return t->d_func();
+    }
+    bool hasPendingTripleClick() const {
+        return !tripleClickTimer.hasExpired(qApp->styleHints()->mouseDoubleClickInterval());
+    }
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKTEXTINPUT_P_P_H
diff --git a/src/declarative/items/qquicktextnode.cpp b/src/declarative/items/qquicktextnode.cpp
new file mode 100644 (file)
index 0000000..fab592f
--- /dev/null
@@ -0,0 +1,1343 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qquicktextnode_p.h"
+#include "qsgsimplerectnode.h"
+#include <private/qsgadaptationlayer_p.h>
+#include <private/qsgdistancefieldglyphcache_p.h>
+#include <private/qsgdistancefieldglyphnode_p.h>
+
+#include <private/qsgcontext_p.h>
+
+#include <QtCore/qpoint.h>
+#include <qmath.h>
+#include <qtextdocument.h>
+#include <qtextlayout.h>
+#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
+
+/*!
+  Creates an empty QQuickTextNode
+*/
+QQuickTextNode::QQuickTextNode(QSGContext *context)
+    : m_context(context), m_cursorNode(0)
+{
+#if defined(QML_RUNTIME_TESTING)
+    description = QLatin1String("text");
+#endif
+}
+
+QQuickTextNode::~QQuickTextNode()
+{
+    qDeleteAll(m_textures);
+}
+
+#if 0
+void QQuickTextNode::setColor(const QColor &color)
+{
+    if (m_usePixmapCache) {
+        setUpdateFlag(UpdateNodes);
+    } else {
+        for (QSGNode *childNode = firstChild(); childNode; childNode = childNode->nextSibling()) {
+            if (childNode->subType() == GlyphNodeSubType) {
+                QSGGlyphNode *glyphNode = static_cast<QSGGlyphNode *>(childNode);
+                if (glyphNode->color() == m_color)
+                    glyphNode->setColor(color);
+            } else if (childNode->subType() == SolidRectNodeSubType) {
+                QSGSimpleRectNode *solidRectNode = static_cast<QSGSimpleRectNode *>(childNode);
+                if (solidRectNode->color() == m_color)
+                    solidRectNode->setColor(color);
+            }
+        }
+    }
+    m_color = color;
+}
+
+void QQuickTextNode::setStyleColor(const QColor &styleColor)
+{
+    if (m_textStyle != QQuickTextNode::NormalTextStyle) {
+        if (m_usePixmapCache) {
+            setUpdateFlag(UpdateNodes);
+        } else {
+            for (QSGNode *childNode = firstChild(); childNode; childNode = childNode->nextSibling()) {
+                if (childNode->subType() == GlyphNodeSubType) {
+                    QSGGlyphNode *glyphNode = static_cast<QSGGlyphNode *>(childNode);
+                    if (glyphNode->color() == m_styleColor)
+                        glyphNode->setColor(styleColor);
+                } else if (childNode->subType() == SolidRectNodeSubType) {
+                    QSGSimpleRectNode *solidRectNode = static_cast<QSGSimpleRectNode *>(childNode);
+                    if (solidRectNode->color() == m_styleColor)
+                        solidRectNode->setColor(styleColor);
+                }
+            }
+        }
+    }
+    m_styleColor = styleColor;
+}
+#endif
+
+QSGGlyphNode *QQuickTextNode::addGlyphs(const QPointF &position, const QGlyphRun &glyphs, const QColor &color,
+                                     QQuickText::TextStyle style, const QColor &styleColor,
+                                     QSGNode *parentNode)
+{
+    QSGGlyphNode *node = m_context->createGlyphNode();
+    node->setGlyphs(position + QPointF(0, glyphs.rawFont().ascent()), glyphs);
+    node->setStyle(style);
+    node->setStyleColor(styleColor);
+    node->setColor(color);
+    node->update();
+
+    /* We flag the geometry as static, but we never call markVertexDataDirty
+       or markIndexDataDirty on them. This is because all text nodes are
+       discarded when a change occurs. If we start appending/removing from
+       existing geometry, then we also need to start marking the geometry as
+       dirty.
+     */
+    node->geometry()->setIndexDataPattern(QSGGeometry::StaticPattern);
+    node->geometry()->setVertexDataPattern(QSGGeometry::StaticPattern);
+
+    if (parentNode == 0)
+        parentNode = this;
+    parentNode->appendChildNode(node);
+
+    return node;
+}
+
+void QQuickTextNode::setCursor(const QRectF &rect, const QColor &color)
+{
+    if (m_cursorNode != 0)
+        delete m_cursorNode;
+
+    m_cursorNode = new QSGSimpleRectNode(rect, color);
+    appendChildNode(m_cursorNode);
+}
+
+namespace {
+
+    struct BinaryTreeNode {
+        enum SelectionState {
+            Unselected,
+            Selected
+        };
+
+        BinaryTreeNode()
+            : selectionState(Unselected)
+            , clipNode(0)
+            , decorations(QQuickTextNode::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(QQuickTextNode::NoDecoration)
+            , image(i)
+            , ascent(a)
+            , leftChildIndex(-1)
+            , rightChildIndex(-1)
+        {
+        }
+
+        BinaryTreeNode(const QGlyphRun &g, SelectionState selState, const QRectF &brect,
+                       const QQuickTextNode::Decorations &decs, const QColor &c, const QColor &bc,
+                       const QPointF &pos, qreal a)
+            : glyphRun(g)
+            , boundingRect(brect)
+            , selectionState(selState)
+            , clipNode(0)
+            , decorations(decs)
+            , color(c)
+            , backgroundColor(bc)
+            , position(pos)
+            , ascent(a)
+            , leftChildIndex(-1)
+            , rightChildIndex(-1)
+        {
+        }
+
+        QGlyphRun glyphRun;
+        QRectF boundingRect;
+        SelectionState selectionState;
+        QSGClipNode *clipNode;
+        QQuickTextNode::Decorations decorations;
+        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)
+        {
+            QRectF searchRect = glyphRun.boundingRect();
+            searchRect.translate(position);
+
+            if (qFuzzyIsNull(searchRect.width()) || qFuzzyIsNull(searchRect.height()))
+                return;
+
+            QQuickTextNode::Decorations decorations = QQuickTextNode::NoDecoration;
+            decorations |= (glyphRun.underline() ? QQuickTextNode::Underline : QQuickTextNode::NoDecoration);
+            decorations |= (glyphRun.overline()  ? QQuickTextNode::Overline  : QQuickTextNode::NoDecoration);
+            decorations |= (glyphRun.strikeOut() ? QQuickTextNode::StrikeOut : QQuickTextNode::NoDecoration);
+            decorations |= (backgroundColor.isValid() ? QQuickTextNode::Background : QQuickTextNode::NoDecoration);
+
+            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 (binaryTreeNode.boundingRect.left() < node->boundingRect.left()) {
+                    if (node->leftChildIndex < 0) {
+                        node->leftChildIndex = newIndex;
+                        break;
+                    } else {
+                        searchIndex = node->leftChildIndex;
+                    }
+                } else {
+                    if (node->rightChildIndex < 0) {
+                        node->rightChildIndex = newIndex;
+                        break;
+                    } else {
+                        searchIndex = node->rightChildIndex;
+                    }
+                }
+            }
+        }
+
+        static void inOrder(const QVarLengthArray<BinaryTreeNode> &binaryTree,
+                            QVarLengthArray<int> *sortedIndexes,
+                            int currentIndex = 0)
+        {
+            Q_ASSERT(currentIndex < binaryTree.size());
+
+            const BinaryTreeNode *node = binaryTree.data() + currentIndex;
+            if (node->leftChildIndex >= 0)
+                inOrder(binaryTree, sortedIndexes, node->leftChildIndex);
+
+            sortedIndexes->append(currentIndex);
+
+            if (node->rightChildIndex >= 0)
+                inOrder(binaryTree, sortedIndexes, node->rightChildIndex);
+        }
+    };
+
+    // Engine that takes glyph runs as input, and produces a set of glyph nodes, clip nodes,
+    // and rectangle nodes to represent the text, decorations and selection. Will try to minimize
+    // number of nodes, and join decorations in neighbouring items
+    class SelectionEngine
+    {
+    public:
+        SelectionEngine() : m_hasSelection(false) {}
+
+        QTextLine currentLine() const { return m_currentLine; }
+
+        void setCurrentLine(const QTextLine &currentLine)
+        {
+            if (m_currentLine.isValid())
+                processCurrentLine();
+
+            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,
+                              const QColor &color, const QColor &backgroundColor,
+                              int selectionStart, int selectionEnd);
+        void addGlyphsForRanges(const QVarLengthArray<QTextLayout::FormatRange> &ranges,
+                                int start, int end,
+                                int selectionStart, int selectionEnd);
+
+        void addToSceneGraph(QQuickTextNode *parent,
+                             QQuickText::TextStyle style = QQuickText::Normal,
+                             const QColor &styleColor = QColor());
+
+        void setSelectionColor(const QColor &selectionColor)
+        {
+            m_selectionColor = selectionColor;
+        }
+
+        void setSelectedTextColor(const QColor &selectedTextColor)
+        {
+            m_selectedTextColor = selectedTextColor;
+        }
+
+        void setTextColor(const QColor &textColor)
+        {
+            m_textColor = textColor;
+        }
+
+        void setPosition(const QPointF &position)
+        {
+            m_position = position;
+        }
+
+    private:
+        struct TextDecoration
+        {
+            TextDecoration() : selectionState(BinaryTreeNode::Unselected) {}
+            TextDecoration(const BinaryTreeNode::SelectionState &s,
+                           const QRectF &r,
+                           const QColor &c)
+                : selectionState(s)
+                , rect(r)
+                , color(c)
+            {
+            }
+
+            BinaryTreeNode::SelectionState selectionState;
+            QRectF rect;
+            QColor color;
+        };
+
+        void processCurrentLine();
+        void addTextDecorations(const QVarLengthArray<TextDecoration> &textDecorations,
+                                qreal offset, qreal thickness);
+
+        QColor m_selectionColor;
+        QColor m_textColor;
+        QColor m_backgroundColor;
+        QColor m_selectedTextColor;
+        QPointF m_position;
+
+        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,
+                                             qreal offset, qreal thickness)
+    {
+        for (int i=0; i<textDecorations.size(); ++i) {
+            TextDecoration textDecoration = textDecorations.at(i);
+
+            {
+                QRectF &rect = textDecoration.rect;
+                rect.setY(qRound(rect.y() + m_currentLine.ascent() + offset));
+                rect.setHeight(thickness);
+            }
+
+            m_lines.append(textDecoration);
+        }
+    }
+
+    void SelectionEngine::processCurrentLine()
+    {
+        // No glyphs, do nothing
+        if (m_currentLineTree.isEmpty())
+            return;
+
+        // 1. Go through current line and get correct decoration position for each node based on
+        // neighbouring decorations. Add decoration to global list
+        // 2. Create clip nodes for all selected text. Try to merge as many as possible within
+        // the line.
+        // 3. Add QRects to a list of selection rects.
+        // 4. Add all nodes to a global processed list
+        QVarLengthArray<int> sortedIndexes; // Indexes in tree sorted by x position
+        BinaryTreeNode::inOrder(m_currentLineTree, &sortedIndexes);
+
+        Q_ASSERT(sortedIndexes.size() == m_currentLineTree.size());
+
+        BinaryTreeNode::SelectionState currentSelectionState = BinaryTreeNode::Unselected;
+        QRectF currentRect;
+
+        QQuickTextNode::Decorations currentDecorations = QQuickTextNode::NoDecoration;
+        qreal underlineOffset = 0.0;
+        qreal underlineThickness = 0.0;
+
+        qreal overlineOffset = 0.0;
+        qreal overlineThickness = 0.0;
+
+        qreal strikeOutOffset = 0.0;
+        qreal strikeOutThickness = 0.0;
+
+        QRectF decorationRect = currentRect;
+
+        QColor lastColor;
+        QColor lastBackgroundColor;
+
+        QVarLengthArray<TextDecoration> pendingUnderlines;
+        QVarLengthArray<TextDecoration> pendingOverlines;
+        QVarLengthArray<TextDecoration> pendingStrikeOuts;
+        if (!sortedIndexes.isEmpty()) {
+            QSGClipNode *currentClipNode = m_hasSelection ? new QSGClipNode : 0;
+            bool currentClipNodeUsed = false;
+            for (int i=0; i<=sortedIndexes.size(); ++i) {
+                BinaryTreeNode *node = 0;
+                if (i < sortedIndexes.size()) {
+                    int sortedIndex = sortedIndexes.at(i);
+                    Q_ASSERT(sortedIndex < m_currentLineTree.size());
+
+                    node = m_currentLineTree.data() + sortedIndex;
+                }
+
+                if (i == 0)
+                    currentSelectionState = node->selectionState;
+
+                // Update decorations
+                if (currentDecorations != QQuickTextNode::NoDecoration) {
+                    decorationRect.setY(m_position.y() + m_currentLine.y());
+                    decorationRect.setHeight(m_currentLine.height());
+
+                    if (node != 0)
+                        decorationRect.setRight(node->boundingRect.left());
+
+                    TextDecoration textDecoration(currentSelectionState, decorationRect, lastColor);
+                    if (currentDecorations & QQuickTextNode::Underline)
+                        pendingUnderlines.append(textDecoration);
+
+                    if (currentDecorations & QQuickTextNode::Overline)
+                        pendingOverlines.append(textDecoration);
+
+                    if (currentDecorations & QQuickTextNode::StrikeOut)
+                        pendingStrikeOuts.append(textDecoration);
+
+                    if (currentDecorations & QQuickTextNode::Background)
+                        m_backgrounds.append(qMakePair(decorationRect, lastBackgroundColor));
+                }
+
+                // If we've reached an unselected node from a selected node, we add the
+                // selection rect to the graph, and we add decoration every time the
+                // selection state changes, because that means the text color changes
+                if (node == 0 || node->selectionState != currentSelectionState) {
+                    if (node != 0)
+                        currentRect.setRight(node->boundingRect.left());
+                    currentRect.setY(m_position.y() + m_currentLine.y());
+                    currentRect.setHeight(m_currentLine.height());
+
+                    // Draw selection all the way up to the left edge of the unselected item
+                    if (currentSelectionState == BinaryTreeNode::Selected)
+                        m_selectionRects.append(currentRect);
+
+                    if (currentClipNode != 0) {
+                        if (!currentClipNodeUsed) {
+                            delete currentClipNode;
+                        } else {
+                            currentClipNode->setIsRectangular(true);
+                            currentClipNode->setClipRect(currentRect);
+                        }
+                    }
+
+                    if (node != 0 && m_hasSelection)
+                        currentClipNode = new QSGClipNode;
+                    else
+                        currentClipNode = 0;
+                    currentClipNodeUsed = false;
+
+                    if (node != 0) {
+                        currentSelectionState = node->selectionState;
+                        currentRect = node->boundingRect;
+
+                        // Make sure currentRect is valid, otherwise the unite won't work
+                        if (currentRect.isNull())
+                            currentRect.setSize(QSizeF(1, 1));
+                    }
+                } else {
+                    if (currentRect.isNull())
+                        currentRect = node->boundingRect;
+                    else
+                        currentRect = currentRect.united(node->boundingRect);
+                }
+
+                if (node != 0) {
+                    node->clipNode = currentClipNode;
+                    currentClipNodeUsed = true;
+
+                    decorationRect = node->boundingRect;
+
+                    // 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()
+                      && !(node->decorations & QQuickTextNode::Underline)) {
+                        addTextDecorations(pendingUnderlines, underlineOffset, underlineThickness);
+
+                        pendingUnderlines.clear();
+
+                        underlineOffset = 0.0;
+                        underlineThickness = 0.0;
+                    }
+
+                    // ### Add pending when overlineOffset/thickness changes to minimize number of
+                    // nodes
+                    if (!pendingOverlines.isEmpty()) {
+                        addTextDecorations(pendingOverlines, overlineOffset, overlineThickness);
+
+                        pendingOverlines.clear();
+
+                        overlineOffset = 0.0;
+                        overlineThickness = 0.0;
+                    }
+
+                    // ### Add pending when overlineOffset/thickness changes to minimize number of
+                    // nodes
+                    if (!pendingStrikeOuts.isEmpty()) {
+                        addTextDecorations(pendingStrikeOuts, strikeOutOffset, strikeOutThickness);
+
+                        pendingStrikeOuts.clear();
+
+                        strikeOutOffset = 0.0;
+                        strikeOutThickness = 0.0;
+                    }
+
+                    // Merge current values with previous. Prefer greatest thickness
+                    QRawFont rawFont = node->glyphRun.rawFont();
+                    if (node->decorations & QQuickTextNode::Underline) {
+                        if (rawFont.lineThickness() > underlineThickness) {
+                            underlineThickness = rawFont.lineThickness();
+                            underlineOffset = rawFont.underlinePosition();
+                        }
+                    }
+
+                    if (node->decorations & QQuickTextNode::Overline) {
+                        overlineOffset = -rawFont.ascent();
+                        overlineThickness = rawFont.lineThickness();
+                    }
+
+                    if (node->decorations & QQuickTextNode::StrikeOut) {
+                        strikeOutThickness = rawFont.lineThickness();
+                        strikeOutOffset = rawFont.ascent() / -3.0;
+                    }
+
+                    currentDecorations = node->decorations;
+                    lastColor = node->color;
+                    lastBackgroundColor = node->backgroundColor;
+                    m_processedNodes.append(*node);
+                }
+            }
+
+            if (!pendingUnderlines.isEmpty())
+                addTextDecorations(pendingUnderlines, underlineOffset, underlineThickness);
+
+            if (!pendingOverlines.isEmpty())
+                addTextDecorations(pendingOverlines, overlineOffset, overlineThickness);
+
+            if (!pendingStrikeOuts.isEmpty())
+                addTextDecorations(pendingStrikeOuts, strikeOutOffset, strikeOutThickness);
+        }
+
+        m_currentLineTree.clear();
+        m_currentLine = QTextLine();
+        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,
+                               m_textColor, m_backgroundColor, m_position);
+    }
+
+    void SelectionEngine::addSelectedGlyphs(const QGlyphRun &glyphRun)
+    {
+        int currentSize = m_currentLineTree.size();
+        BinaryTreeNode::insert(&m_currentLineTree, glyphRun, BinaryTreeNode::Selected,
+                               m_textColor, m_backgroundColor, m_position);
+        m_hasSelection = m_hasSelection || m_currentLineTree.size() > currentSize;
+    }
+
+    void SelectionEngine::addGlyphsForRanges(const QVarLengthArray<QTextLayout::FormatRange> &ranges,
+                                             int start, int end,
+                                             int selectionStart, int selectionEnd)
+    {
+        int currentPosition = start;
+        int remainingLength = end - start;
+        for (int j=0; j<ranges.size(); ++j) {
+            const QTextLayout::FormatRange &range = ranges.at(j);
+            if (range.start + range.length >= currentPosition
+                && range.start < currentPosition + remainingLength) {
+
+                if (range.start > currentPosition) {
+                    addGlyphsInRange(currentPosition, range.start - currentPosition,
+                                     QColor(), QColor(), selectionStart, selectionEnd);
+                }
+
+                int rangeEnd = qMin(range.start + range.length, currentPosition + remainingLength);
+                QColor rangeColor = range.format.hasProperty(QTextFormat::ForegroundBrush)
+                        ? range.format.foreground().color()
+                        : QColor();
+                QColor rangeBackgroundColor = range.format.hasProperty(QTextFormat::BackgroundBrush)
+                        ? range.format.background().color()
+                        : QColor();
+
+                addGlyphsInRange(range.start, rangeEnd - range.start,
+                                 rangeColor, rangeBackgroundColor,
+                                 selectionStart, selectionEnd);
+
+                currentPosition = range.start + range.length;
+                remainingLength = end - currentPosition;
+
+            } else if (range.start > currentPosition + remainingLength || remainingLength <= 0) {
+                break;
+            }
+        }
+
+        if (remainingLength > 0) {
+            addGlyphsInRange(currentPosition, remainingLength, QColor(), QColor(),
+                             selectionStart, selectionEnd);
+        }
+
+    }
+
+    void SelectionEngine::addGlyphsInRange(int rangeStart, int rangeLength,
+                                           const QColor &color, const QColor &backgroundColor,
+                                           int selectionStart, int selectionEnd)
+    {
+        QColor oldColor;
+        if (color.isValid()) {
+            oldColor = m_textColor;
+            m_textColor = color;
+        }
+
+        QColor oldBackgroundColor = m_backgroundColor;
+        if (backgroundColor.isValid()) {
+            oldBackgroundColor = m_backgroundColor;
+            m_backgroundColor = backgroundColor;
+        }
+
+        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) {
+                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) {
+                    const QGlyphRun &glyphRun = glyphRuns.at(j);
+                    addUnselectedGlyphs(glyphRun);
+                }
+            }
+
+            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) {
+                    const QGlyphRun &glyphRun = glyphRuns.at(j);
+                    addSelectedGlyphs(glyphRun);
+                }
+            }
+
+            if (selectionEnd >= rangeStart && selectionEnd < rangeEnd) {
+                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);
+                }
+            }
+        }
+
+        if (backgroundColor.isValid())
+            m_backgroundColor = oldBackgroundColor;
+
+        if (oldColor.isValid())
+            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(QQuickTextNode *parentNode,
+                                          QQuickText::TextStyle style,
+                                          const QColor &styleColor)
+    {
+        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);
+
+            parentNode->appendChildNode(new QSGSimpleRectNode(rect, m_selectionColor));
+        }
+
+        // Finally, add decorations for each node to the tree.
+        for (int i=0; i<m_lines.size(); ++i) {
+            const TextDecoration &textDecoration = m_lines.at(i);
+
+            QColor color = textDecoration.selectionState == BinaryTreeNode::Selected
+                    ? m_selectedTextColor
+                    : textDecoration.color;
+
+            parentNode->appendChildNode(new QSGSimpleRectNode(textDecoration.rect, color));
+        }
+
+        // Then, go through all the nodes for all lines and combine all QGlyphRuns with a common
+        // font, selection state and clip node.
+        typedef QPair<QFontEngine *, QPair<QSGClipNode *, QPair<QRgb, int> > > KeyType;
+        QHash<KeyType, BinaryTreeNode *> map;
+        for (int i=0; i<m_processedNodes.size(); ++i) {
+            BinaryTreeNode *node = m_processedNodes.data() + i;
+
+            if (node->image.isNull()) {
+                QGlyphRun glyphRun = node->glyphRun;
+                QRawFont rawFont = glyphRun.rawFont();
+                QRawFontPrivate *rawFontD = QRawFontPrivate::get(rawFont);
+
+                QFontEngine *fontEngine = rawFontD->fontEngine;
+
+                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;
+
+                    QVector<quint32> otherGlyphIndexes = otherGlyphRun.glyphIndexes();
+                    QVector<QPointF> otherGlyphPositions = otherGlyphRun.positions();
+
+                    otherGlyphIndexes += glyphRun.glyphIndexes();
+
+                    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);
+
+                } else {
+                    map.insert(key, node);
+                }
+            } else {
+                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));
+                }
+            }
+        }
+
+        // ...and add clip nodes and glyphs to tree.
+        QHash<KeyType, BinaryTreeNode *>::const_iterator it = map.constBegin();
+        while (it != map.constEnd()) {
+
+            BinaryTreeNode *node = it.value();
+
+            QSGClipNode *clipNode = node->clipNode;
+            if (clipNode != 0 && clipNode->parent() == 0 )
+                parentNode->appendChildNode(clipNode);
+
+            QColor color = node->selectionState == BinaryTreeNode::Selected
+                    ? m_selectedTextColor
+                    : node->color;
+
+            parentNode->addGlyphs(node->position, node->glyphRun, color, style, styleColor, clipNode);
+
+            ++it;
+        }
+    }
+}
+
+void QQuickTextNode::mergeFormats(QTextLayout *textLayout,
+                               QVarLengthArray<QTextLayout::FormatRange> *mergedFormats)
+{
+    Q_ASSERT(mergedFormats != 0);
+    if (textLayout == 0)
+        return;
+
+    QList<QTextLayout::FormatRange> additionalFormats = textLayout->additionalFormats();
+    for (int i=0; i<additionalFormats.size(); ++i) {
+        QTextLayout::FormatRange additionalFormat = additionalFormats.at(i);
+        if (additionalFormat.format.hasProperty(QTextFormat::ForegroundBrush)
+         || additionalFormat.format.hasProperty(QTextFormat::BackgroundBrush)) {
+            // Merge overlapping formats
+            if (!mergedFormats->isEmpty()) {
+                QTextLayout::FormatRange *lastFormat = mergedFormats->data() + mergedFormats->size() - 1;
+
+                if (additionalFormat.start < lastFormat->start + lastFormat->length) {
+                    QTextLayout::FormatRange *mergedRange = 0;
+
+                    int length = additionalFormat.length;
+                    if (additionalFormat.start > lastFormat->start) {
+                        lastFormat->length = additionalFormat.start - lastFormat->start;
+                        length -= lastFormat->length;
+
+                        mergedFormats->append(QTextLayout::FormatRange());
+                        mergedRange = mergedFormats->data() + mergedFormats->size() - 1;
+                        lastFormat = mergedFormats->data() + mergedFormats->size() - 2;
+                    } else {
+                        mergedRange = lastFormat;
+                    }
+
+                    mergedRange->format = lastFormat->format;
+                    mergedRange->format.merge(additionalFormat.format);
+                    mergedRange->start = additionalFormat.start;
+
+                    int end = qMin(additionalFormat.start + additionalFormat.length,
+                                   lastFormat->start + lastFormat->length);
+
+                    mergedRange->length = end - mergedRange->start;
+                    length -= mergedRange->length;
+
+                    additionalFormat.start = end;
+                    additionalFormat.length = length;
+                }
+            }
+
+            if (additionalFormat.length > 0)
+                mergedFormats->append(additionalFormat);
+        }
+    }
+
+}
+
+namespace {
+
+    class ProtectedLayoutAccessor: public QAbstractTextDocumentLayout
+    {
+    public:
+        inline QTextCharFormat formatAccessor(int pos)
+        {
+            return format(pos);
+        }
+    };
+
+}
+
+void QQuickTextNode::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 QQuickTextNode::addTextDocument(const QPointF &, QTextDocument *textDocument,
+                                  const QColor &textColor,
+                                  QQuickText::TextStyle style, const QColor &styleColor,
+                                  const QColor &selectionColor, const QColor &selectedTextColor,
+                                  int selectionStart, int selectionEnd)
+{
+    SelectionEngine engine;
+    engine.setTextColor(textColor);
+    engine.setSelectedTextColor(selectedTextColor);
+    engine.setSelectionColor(selectionColor);
+
+    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));
+                    }
+                }
+
+                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;
+                        }
+
+                        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);
+                            }
+
+                            Q_ASSERT(line.textLength() > 0);
+                            int lineEnd = line.textStart() + block.position() + line.textLength();
+
+                            int len = qMin(lineEnd - textPos, fragmentEnd - textPos);
+                            Q_ASSERT(len > 0);
+
+                            int currentStepEnd = textPos + len;
+
+                            engine.addGlyphsForRanges(colorChanges,
+                                                      textPos - block.position(),
+                                                      currentStepEnd - block.position(),
+                                                      selectionStart - block.position(),
+                                                      selectionEnd - block.position());
+
+                            textPos = currentStepEnd;
+                        }
+                    }
+
+                    ++blockIterator;
+                }
+
+                engine.setCurrentLine(QTextLine()); // Reset current line because the text layout changed
+                ++it;
+            }
+        }
+    }
+
+    engine.addToSceneGraph(this, style, styleColor);
+}
+
+void QQuickTextNode::addTextLayout(const QPointF &position, QTextLayout *textLayout, const QColor &color,
+                                QQuickText::TextStyle style, const QColor &styleColor,
+                                const QColor &selectionColor, const QColor &selectedTextColor,
+                                int selectionStart, int selectionEnd)
+{
+    SelectionEngine engine;
+    engine.setTextColor(color);
+    engine.setSelectedTextColor(selectedTextColor);
+    engine.setSelectionColor(selectionColor);
+    engine.setPosition(position);
+
+    int preeditLength = textLayout->preeditAreaText().length();
+    int preeditPosition = textLayout->preeditAreaPosition();
+
+    QVarLengthArray<QTextLayout::FormatRange> colorChanges;
+    mergeFormats(textLayout, &colorChanges);
+
+    for (int i=0; i<textLayout->lineCount(); ++i) {
+        QTextLine line = textLayout->lineAt(i);
+
+        int start = line.textStart();
+        int length = line.textLength();
+        int end = start + length;
+
+        if (preeditPosition >= 0
+         && preeditPosition >= start
+         && preeditPosition < end) {
+            end += preeditLength;
+        }
+
+        engine.setCurrentLine(line);
+        engine.addGlyphsForRanges(colorChanges, start, end, selectionStart, selectionEnd);
+    }
+
+    engine.addToSceneGraph(this, style, styleColor);
+}
+
+void QQuickTextNode::deleteContent()
+{
+    while (firstChild() != 0)
+        delete firstChild();
+    m_cursorNode = 0;
+}
+
+#if 0
+void QQuickTextNode::updateNodes()
+{
+    return;
+    deleteContent();
+    if (m_text.isEmpty())
+        return;
+
+    if (m_usePixmapCache) {
+        // ### gunnar: port properly
+//        QPixmap pixmap = generatedPixmap();
+//        if (pixmap.isNull())
+//            return;
+
+//        QSGImageNode *pixmapNode = m_context->createImageNode();
+//        pixmapNode->setRect(pixmap.rect());
+//        pixmapNode->setSourceRect(pixmap.rect());
+//        pixmapNode->setOpacity(m_opacity);
+//        pixmapNode->setClampToEdge(true);
+//        pixmapNode->setLinearFiltering(m_linearFiltering);
+
+//        appendChildNode(pixmapNode);
+    } else {
+        if (m_text.isEmpty())
+            return;
+
+        // Implement styling by drawing text several times at slight shifts. shiftForStyle
+        // contains the sequence of shifted positions at which to draw the text. All except
+        // the last will be drawn with styleColor.
+        QList<QPointF> shiftForStyle;
+        switch (m_textStyle) {
+        case OutlineTextStyle:
+            // ### Should be made faster by implementing outline material
+            shiftForStyle << QPointF(-1, 0);
+            shiftForStyle << QPointF(0, -1);
+            shiftForStyle << QPointF(1, 0);
+            shiftForStyle << QPointF(0, 1);
+            break;
+        case SunkenTextStyle:
+            shiftForStyle << QPointF(0, -1);
+            break;
+        case RaisedTextStyle:
+            shiftForStyle << QPointF(0, 1);
+            break;
+        default:
+            break;
+        }
+
+        shiftForStyle << QPointF(0, 0); // Regular position
+        while (!shiftForStyle.isEmpty()) {
+            QPointF shift = shiftForStyle.takeFirst();
+
+            // Use styleColor for all but last shift
+            if (m_richText) {
+                QColor overrideColor = shiftForStyle.isEmpty() ? QColor() : m_styleColor;
+
+                QTextFrame *textFrame = m_textDocument->rootFrame();
+                QPointF p = m_textDocument->documentLayout()->frameBoundingRect(textFrame).topLeft();
+
+                QTextFrame::iterator it = textFrame->begin();
+                while (!it.atEnd()) {
+                    addTextBlock(shift + p, it.currentBlock(), overrideColor);
+                    ++it;
+                }
+            } else {
+                addTextLayout(shift, m_textLayout, shiftForStyle.isEmpty()
+                                                   ? m_color
+                                                   : m_styleColor);
+            }
+        }
+    }
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquicktextnode_p.h b/src/declarative/items/qquicktextnode_p.h
new file mode 100644 (file)
index 0000000..16e92e3
--- /dev/null
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** 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 QQUICKTEXTNODE_P_H
+#define QQUICKTEXTNODE_P_H
+
+#include <qsgnode.h>
+#include "qquicktext_p.h"
+#include <qglyphrun.h>
+
+#include <QtGui/qcolor.h>
+#include <QtGui/qtextlayout.h>
+#include <QtCore/qvarlengtharray.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGGlyphNode;
+class QTextBlock;
+class QColor;
+class QTextDocument;
+class QSGContext;
+class QRawFont;
+class QSGSimpleRectNode;
+class QSGClipNode;
+class QSGTexture;
+
+class QQuickTextNode : public QSGTransformNode
+{
+public:
+    enum Decoration {
+        NoDecoration = 0x0,
+        Underline    = 0x1,
+        Overline     = 0x2,
+        StrikeOut    = 0x4,
+        Background   = 0x8
+    };
+    Q_DECLARE_FLAGS(Decorations, Decoration)
+
+    QQuickTextNode(QSGContext *);
+    ~QQuickTextNode();
+
+    static bool isComplexRichText(QTextDocument *);
+
+    void deleteContent();
+    void addTextLayout(const QPointF &position, QTextLayout *textLayout, const QColor &color = QColor(),
+                       QQuickText::TextStyle style = QQuickText::Normal, const QColor &styleColor = QColor(),
+                       const QColor &selectionColor = QColor(), const QColor &selectedTextColor = QColor(),
+                       int selectionStart = -1, int selectionEnd = -1);
+    void addTextDocument(const QPointF &position, QTextDocument *textDocument, const QColor &color = QColor(),
+                         QQuickText::TextStyle style = QQuickText::Normal, const QColor &styleColor = QColor(),
+                         const QColor &selectionColor = QColor(), const QColor &selectedTextColor = QColor(),
+                         int selectionStart = -1, int selectionEnd = -1);
+
+    void setCursor(const QRectF &rect, const QColor &color);
+    QSGSimpleRectNode *cursorNode() const { return m_cursorNode; }
+
+    QSGGlyphNode *addGlyphs(const QPointF &position, const QGlyphRun &glyphs, const QColor &color,
+                            QQuickText::TextStyle style = QQuickText::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
+
+#endif // QQUICKTEXTNODE_P_H
diff --git a/src/declarative/items/qquicktranslate.cpp b/src/declarative/items/qquicktranslate.cpp
new file mode 100644 (file)
index 0000000..7347cb0
--- /dev/null
@@ -0,0 +1,319 @@
+/****************************************************************************
+**
+** 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 "qquicktranslate_p.h"
+#include "qquickitem_p.h"
+
+#include <QtCore/qmath.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickTranslatePrivate : public QQuickTransformPrivate
+{
+public:
+    QQuickTranslatePrivate()
+    : x(0), y(0) {}
+
+    qreal x;
+    qreal y;
+};
+
+/*!
+    Constructs an empty QQuickTranslate object with the given \a parent.
+*/
+QQuickTranslate::QQuickTranslate(QObject *parent)
+: QQuickTransform(*new QQuickTranslatePrivate, parent)
+{
+}
+
+/*!
+    Destroys the graphics scale.
+*/
+QQuickTranslate::~QQuickTranslate()
+{
+}
+
+/*!
+    \property QQuickTranslate::x
+    \brief the horizontal translation.
+
+    The translation can be any real number; the default value is 0.0.
+
+    \sa y
+*/
+qreal QQuickTranslate::x() const
+{
+    Q_D(const QQuickTranslate);
+    return d->x;
+}
+
+void QQuickTranslate::setX(qreal x)
+{
+    Q_D(QQuickTranslate);
+    if (d->x == x)
+        return;
+    d->x = x;
+    update();
+    emit xChanged();
+}
+
+/*!
+    \property QQuickTranslate::y
+    \brief the vertical translation.
+
+    The translation can be any real number; the default value is 0.0.
+
+    \sa x
+*/
+qreal QQuickTranslate::y() const
+{
+    Q_D(const QQuickTranslate);
+    return d->y;
+}
+void QQuickTranslate::setY(qreal y)
+{
+    Q_D(QQuickTranslate);
+    if (d->y == y)
+        return;
+    d->y = y;
+    update();
+    emit yChanged();
+}
+
+void QQuickTranslate::applyTo(QMatrix4x4 *matrix) const
+{
+    Q_D(const QQuickTranslate);
+    matrix->translate(d->x, d->y, 0);
+}
+
+class QQuickScalePrivate : public QQuickTransformPrivate
+{
+public:
+    QQuickScalePrivate()
+        : xScale(1), yScale(1), zScale(1) {}
+    QVector3D origin;
+    qreal xScale;
+    qreal yScale;
+    qreal zScale;
+};
+
+QQuickScale::QQuickScale(QObject *parent)
+    : QQuickTransform(*new QQuickScalePrivate, parent)
+{
+}
+
+QQuickScale::~QQuickScale()
+{
+}
+
+QVector3D QQuickScale::origin() const
+{
+    Q_D(const QQuickScale);
+    return d->origin;
+}
+void QQuickScale::setOrigin(const QVector3D &point)
+{
+    Q_D(QQuickScale);
+    if (d->origin == point)
+        return;
+    d->origin = point;
+    update();
+    emit originChanged();
+}
+
+qreal QQuickScale::xScale() const
+{
+    Q_D(const QQuickScale);
+    return d->xScale;
+}
+void QQuickScale::setXScale(qreal scale)
+{
+    Q_D(QQuickScale);
+    if (d->xScale == scale)
+        return;
+    d->xScale = scale;
+    update();
+    emit xScaleChanged();
+    emit scaleChanged();
+}
+
+qreal QQuickScale::yScale() const
+{
+    Q_D(const QQuickScale);
+    return d->yScale;
+}
+void QQuickScale::setYScale(qreal scale)
+{
+    Q_D(QQuickScale);
+    if (d->yScale == scale)
+        return;
+    d->yScale = scale;
+    update();
+    emit yScaleChanged();
+    emit scaleChanged();
+}
+
+qreal QQuickScale::zScale() const
+{
+    Q_D(const QQuickScale);
+    return d->zScale;
+}
+void QQuickScale::setZScale(qreal scale)
+{
+    Q_D(QQuickScale);
+    if (d->zScale == scale)
+        return;
+    d->zScale = scale;
+    update();
+    emit zScaleChanged();
+    emit scaleChanged();
+}
+
+void QQuickScale::applyTo(QMatrix4x4 *matrix) const
+{
+    Q_D(const QQuickScale);
+    matrix->translate(d->origin);
+    matrix->scale(d->xScale, d->yScale, d->zScale);
+    matrix->translate(-d->origin);
+}
+
+class QQuickRotationPrivate : public QQuickTransformPrivate
+{
+public:
+    QQuickRotationPrivate()
+        : angle(0), axis(0, 0, 1) {}
+    QVector3D origin;
+    qreal angle;
+    QVector3D axis;
+};
+
+QQuickRotation::QQuickRotation(QObject *parent)
+    : QQuickTransform(*new QQuickRotationPrivate, parent)
+{
+}
+
+QQuickRotation::~QQuickRotation()
+{
+}
+
+QVector3D QQuickRotation::origin() const
+{
+    Q_D(const QQuickRotation);
+    return d->origin;
+}
+
+void QQuickRotation::setOrigin(const QVector3D &point)
+{
+    Q_D(QQuickRotation);
+    if (d->origin == point)
+        return;
+    d->origin = point;
+    update();
+    emit originChanged();
+}
+
+qreal QQuickRotation::angle() const
+{
+    Q_D(const QQuickRotation);
+    return d->angle;
+}
+void QQuickRotation::setAngle(qreal angle)
+{
+    Q_D(QQuickRotation);
+    if (d->angle == angle)
+        return;
+    d->angle = angle;
+    update();
+    emit angleChanged();
+}
+
+QVector3D QQuickRotation::axis() const
+{
+    Q_D(const QQuickRotation);
+    return d->axis;
+}
+void QQuickRotation::setAxis(const QVector3D &axis)
+{
+    Q_D(QQuickRotation);
+    if (d->axis == axis)
+         return;
+    d->axis = axis;
+    update();
+    emit axisChanged();
+}
+
+void QQuickRotation::setAxis(Qt::Axis axis)
+{
+    switch (axis)
+    {
+    case Qt::XAxis:
+        setAxis(QVector3D(1, 0, 0));
+        break;
+    case Qt::YAxis:
+        setAxis(QVector3D(0, 1, 0));
+        break;
+    case Qt::ZAxis:
+        setAxis(QVector3D(0, 0, 1));
+        break;
+    }
+}
+
+class QGraphicsRotation {
+public:
+    static inline void projectedRotate(QMatrix4x4 *matrix, qreal angle, qreal x, qreal y, qreal z)
+    {
+        matrix->projectedRotate(angle, x, y, z);
+    }
+};
+
+void QQuickRotation::applyTo(QMatrix4x4 *matrix) const
+{
+    Q_D(const QQuickRotation);
+
+    if (d->angle == 0. || d->axis.isNull())
+        return;
+
+    matrix->translate(d->origin);
+    QGraphicsRotation::projectedRotate(matrix, d->angle, d->axis.x(), d->axis.y(), d->axis.z());
+    matrix->translate(-d->origin);
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquicktranslate_p.h b/src/declarative/items/qquicktranslate_p.h
new file mode 100644 (file)
index 0000000..6c2333d
--- /dev/null
@@ -0,0 +1,162 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
+/****************************************************************************
+**
+** 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 QQUICKTRANSLATE_P_H
+#define QQUICKTRANSLATE_P_H
+
+#include "qquickitem.h"
+
+#include <QtGui/qmatrix4x4.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickTranslatePrivate;
+class Q_AUTOTEST_EXPORT QQuickTranslate : public QQuickTransform
+{
+    Q_OBJECT
+
+    Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged)
+    Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged)
+
+public:
+    QQuickTranslate(QObject *parent = 0);
+    ~QQuickTranslate();
+
+    qreal x() const;
+    void setX(qreal);
+
+    qreal y() const;
+    void setY(qreal);
+
+    void applyTo(QMatrix4x4 *matrix) const;
+
+Q_SIGNALS:
+    void xChanged();
+    void yChanged();
+
+private:
+    Q_DECLARE_PRIVATE(QQuickTranslate)
+    Q_DISABLE_COPY(QQuickTranslate)
+};
+
+class QQuickScalePrivate;
+class Q_AUTOTEST_EXPORT QQuickScale : public QQuickTransform
+{
+    Q_OBJECT
+
+    Q_PROPERTY(QVector3D origin READ origin WRITE setOrigin NOTIFY originChanged)
+    Q_PROPERTY(qreal xScale READ xScale WRITE setXScale NOTIFY xScaleChanged)
+    Q_PROPERTY(qreal yScale READ yScale WRITE setYScale NOTIFY yScaleChanged)
+    Q_PROPERTY(qreal zScale READ zScale WRITE setZScale NOTIFY zScaleChanged)
+public:
+    QQuickScale(QObject *parent = 0);
+    ~QQuickScale();
+
+    QVector3D origin() const;
+    void setOrigin(const QVector3D &point);
+
+    qreal xScale() const;
+    void setXScale(qreal);
+
+    qreal yScale() const;
+    void setYScale(qreal);
+
+    qreal zScale() const;
+    void setZScale(qreal);
+
+    void applyTo(QMatrix4x4 *matrix) const;
+
+Q_SIGNALS:
+    void originChanged();
+    void xScaleChanged();
+    void yScaleChanged();
+    void zScaleChanged();
+    void scaleChanged();
+
+private:
+    Q_DECLARE_PRIVATE(QQuickScale)
+};
+
+class QQuickRotationPrivate;
+class Q_AUTOTEST_EXPORT QQuickRotation : public QQuickTransform
+{
+    Q_OBJECT
+
+    Q_PROPERTY(QVector3D origin READ origin WRITE setOrigin NOTIFY originChanged)
+    Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged)
+    Q_PROPERTY(QVector3D axis READ axis WRITE setAxis NOTIFY axisChanged)
+public:
+    QQuickRotation(QObject *parent = 0);
+    ~QQuickRotation();
+
+    QVector3D origin() const;
+    void setOrigin(const QVector3D &point);
+
+    qreal angle() const;
+    void setAngle(qreal);
+
+    QVector3D axis() const;
+    void setAxis(const QVector3D &axis);
+    void setAxis(Qt::Axis axis);
+
+    void applyTo(QMatrix4x4 *matrix) const;
+
+Q_SIGNALS:
+    void originChanged();
+    void angleChanged();
+    void axisChanged();
+
+private:
+    Q_DECLARE_PRIVATE(QQuickRotation)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickTranslate)
+
+QT_END_HEADER
+
+#endif
diff --git a/src/declarative/items/qquickview.cpp b/src/declarative/items/qquickview.cpp
new file mode 100644 (file)
index 0000000..cc87b77
--- /dev/null
@@ -0,0 +1,417 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qquickview.h"
+#include "qquickview_p.h"
+
+#include "qquickcanvas_p.h"
+#include "qquickitem_p.h"
+#include "qquickitemchangelistener_p.h"
+
+#include <private/qdeclarativedebugtrace_p.h>
+#include <private/qdeclarativeinspectorservice_p.h>
+
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <private/qdeclarativeengine_p.h>
+#include <QtCore/qbasictimer.h>
+
+
+// XXX todo - This whole class should probably be merged with QDeclarativeView for
+// maximum seamlessness
+QT_BEGIN_NAMESPACE
+
+DEFINE_BOOL_CONFIG_OPTION(frameRateDebug, QML_SHOW_FRAMERATE)
+
+void QQuickViewPrivate::init()
+{
+    Q_Q(QQuickView);
+
+    QDeclarativeEnginePrivate::get(&engine)->sgContext = QQuickCanvasPrivate::context;
+
+    engine.setIncubationController(q->incubationController());
+
+    if (QDeclarativeDebugService::isDebuggingEnabled())
+        QDeclarativeInspectorService::instance()->addView(q);
+}
+
+QQuickViewPrivate::QQuickViewPrivate()
+    : root(0), component(0), resizeMode(QQuickView::SizeViewToRootObject), initialSize(0,0), resized(false)
+{
+}
+
+QQuickViewPrivate::~QQuickViewPrivate()
+{
+    if (QDeclarativeDebugService::isDebuggingEnabled())
+        QDeclarativeInspectorService::instance()->removeView(q_func());
+
+    delete root;
+}
+
+void QQuickViewPrivate::execute()
+{
+    Q_Q(QQuickView);
+    if (root) {
+        delete root;
+        root = 0;
+    }
+    if (component) {
+        delete component;
+        component = 0;
+    }
+    if (!source.isEmpty()) {
+        component = new QDeclarativeComponent(&engine, source, q);
+        if (!component->isLoading()) {
+            q->continueExecute();
+        } else {
+            QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)),
+                             q, SLOT(continueExecute()));
+        }
+    }
+}
+
+void QQuickViewPrivate::itemGeometryChanged(QQuickItem *resizeItem, const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+    Q_Q(QQuickView);
+    if (resizeItem == root && resizeMode == QQuickView::SizeViewToRootObject) {
+        // wait for both width and height to be changed
+        resizetimer.start(0,q);
+    }
+    QQuickItemChangeListener::itemGeometryChanged(resizeItem, newGeometry, oldGeometry);
+}
+
+QQuickView::QQuickView(QWindow *parent, Qt::WindowFlags f)
+: QQuickCanvas(*(new QQuickViewPrivate), parent)
+{
+    setWindowFlags(f);
+    d_func()->init();
+}
+
+QQuickView::QQuickView(const QUrl &source, QWindow *parent, Qt::WindowFlags f)
+: QQuickCanvas(*(new QQuickViewPrivate), parent)
+{
+    setWindowFlags(f);
+    d_func()->init();
+    setSource(source);
+}
+
+QQuickView::~QQuickView()
+{
+}
+
+void QQuickView::setSource(const QUrl& url)
+{
+    Q_D(QQuickView);
+    d->source = url;
+    d->execute();
+}
+
+QUrl QQuickView::source() const
+{
+    Q_D(const QQuickView);
+    return d->source;
+}
+
+QDeclarativeEngine* QQuickView::engine() const
+{
+    Q_D(const QQuickView);
+    return const_cast<QDeclarativeEngine *>(&d->engine);
+}
+
+QDeclarativeContext* QQuickView::rootContext() const
+{
+    Q_D(const QQuickView);
+    return d->engine.rootContext();
+}
+
+QQuickView::Status QQuickView::status() const
+{
+    Q_D(const QQuickView);
+    if (!d->component)
+        return QQuickView::Null;
+
+    return QQuickView::Status(d->component->status());
+}
+
+QList<QDeclarativeError> QQuickView::errors() const
+{
+    Q_D(const QQuickView);
+    if (d->component)
+        return d->component->errors();
+    return QList<QDeclarativeError>();
+}
+
+void QQuickView::setResizeMode(ResizeMode mode)
+{
+    Q_D(QQuickView);
+    if (d->resizeMode == mode)
+        return;
+
+    if (d->root) {
+        if (d->resizeMode == SizeViewToRootObject) {
+            QQuickItemPrivate *p = QQuickItemPrivate::get(d->root);
+            p->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
+        }
+    }
+
+    d->resizeMode = mode;
+    if (d->root) {
+        d->initResize();
+    }
+}
+
+void QQuickViewPrivate::initResize()
+{
+    if (root) {
+        if (resizeMode == QQuickView::SizeViewToRootObject) {
+            QQuickItemPrivate *p = QQuickItemPrivate::get(root);
+            p->addItemChangeListener(this, QQuickItemPrivate::Geometry);
+        }
+    }
+    updateSize();
+}
+
+void QQuickViewPrivate::updateSize()
+{
+    Q_Q(QQuickView);
+    if (!root)
+        return;
+
+    if (resizeMode == QQuickView::SizeViewToRootObject) {
+        QSize newSize = QSize(root->width(), root->height());
+        if (newSize.isValid() && newSize != q->size()) {
+            q->resize(newSize);
+        }
+    } else if (resizeMode == QQuickView::SizeRootObjectToView) {
+        if (!qFuzzyCompare(q->width(), root->width()))
+            root->setWidth(q->width());
+        if (!qFuzzyCompare(q->height(), root->height()))
+            root->setHeight(q->height());
+    }
+}
+
+QSize QQuickViewPrivate::rootObjectSize() const
+{
+    QSize rootObjectSize(0,0);
+    int widthCandidate = -1;
+    int heightCandidate = -1;
+    if (root) {
+        widthCandidate = root->width();
+        heightCandidate = root->height();
+    }
+    if (widthCandidate > 0) {
+        rootObjectSize.setWidth(widthCandidate);
+    }
+    if (heightCandidate > 0) {
+        rootObjectSize.setHeight(heightCandidate);
+    }
+    return rootObjectSize;
+}
+
+QQuickView::ResizeMode QQuickView::resizeMode() const
+{
+    Q_D(const QQuickView);
+    return d->resizeMode;
+}
+
+/*!
+  \internal
+ */
+void QQuickView::continueExecute()
+{
+    Q_D(QQuickView);
+    disconnect(d->component, SIGNAL(statusChanged(QDeclarativeComponent::Status)), this, SLOT(continueExecute()));
+
+    if (d->component->isError()) {
+        QList<QDeclarativeError> errorList = d->component->errors();
+        foreach (const QDeclarativeError &error, errorList) {
+            qWarning() << error;
+        }
+        emit statusChanged(status());
+        return;
+    }
+
+    QObject *obj = d->component->create();
+
+    if (d->component->isError()) {
+        QList<QDeclarativeError> errorList = d->component->errors();
+        foreach (const QDeclarativeError &error, errorList) {
+            qWarning() << error;
+        }
+        emit statusChanged(status());
+        return;
+    }
+
+    d->setRootObject(obj);
+    emit statusChanged(status());
+}
+
+
+/*!
+  \internal
+*/
+void QQuickViewPrivate::setRootObject(QObject *obj)
+{
+    Q_Q(QQuickView);
+    if (root == obj)
+        return;
+    if (QQuickItem *sgItem = qobject_cast<QQuickItem *>(obj)) {
+        root = sgItem;
+        sgItem->setParentItem(q->QQuickCanvas::rootItem());
+    } else {
+        qWarning() << "QQuickView only supports loading of root objects that derive from QQuickItem." << endl
+                   << endl
+                   << "If your example is using QML 2, (such as qmlscene) and the .qml file you" << endl
+                   << "loaded has 'import QtQuick 1.0' or 'import Qt 4.7', this error will occur." << endl
+                   << endl
+                   << "To load files with 'import QtQuick 1.0' with QML 2, specify:" << endl
+                   << "  QMLSCENE_IMPORT_NAME=quick1" << endl
+                   << "on as an environment variable prior to launching the application." << endl
+                   << endl
+                   << "To load files with 'import Qt 4.7' with QML 2, specify:" << endl
+                   << "  QMLSCENE_IMPORT_NAME=qt" << endl
+                   << "on as an environment variable prior to launching the application." << endl;
+        delete obj;
+        root = 0;
+    }
+    if (root) {
+        initialSize = rootObjectSize();
+        if ((resizeMode == QQuickView::SizeViewToRootObject || !resized) // ### refactor:  || !q->testAttribute(Qt::WA_Resized)
+             && initialSize != q->size()) {
+
+            q->resize(initialSize);
+            resized = true;
+        }
+        initResize();
+    }
+}
+
+/*!
+  \internal
+  If the \l {QTimerEvent} {timer event} \a e is this
+  view's resize timer, sceneResized() is emitted.
+ */
+void QQuickView::timerEvent(QTimerEvent* e)
+{
+    Q_D(QQuickView);
+    if (!e || e->timerId() == d->resizetimer.timerId()) {
+        d->updateSize();
+        d->resizetimer.stop();
+    }
+}
+
+/*!
+    \internal
+    Preferred size follows the root object geometry.
+*/
+QSize QQuickView::sizeHint() const
+{
+    Q_D(const QQuickView);
+    QSize rootObjectSize = d->rootObjectSize();
+    if (rootObjectSize.isEmpty()) {
+        return size();
+    } else {
+        return rootObjectSize;
+    }
+}
+
+QSize QQuickView::initialSize() const
+{
+    Q_D(const QQuickView);
+    return d->initialSize;
+}
+
+QQuickItem *QQuickView::rootObject() const
+{
+    Q_D(const QQuickView);
+    return d->root;
+}
+
+/*!
+  \internal
+  This function handles the \l {QResizeEvent} {resize event}
+  \a e.
+ */
+void QQuickView::resizeEvent(QResizeEvent *e)
+{
+    Q_D(QQuickView);
+    if (d->resizeMode == SizeRootObjectToView)
+        d->updateSize();
+
+    QQuickCanvas::resizeEvent(e);
+}
+
+void QQuickView::keyPressEvent(QKeyEvent *e)
+{
+    QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Key);
+
+    QQuickCanvas::keyPressEvent(e);
+}
+
+void QQuickView::keyReleaseEvent(QKeyEvent *e)
+{
+    QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Key);
+
+    QQuickCanvas::keyReleaseEvent(e);
+}
+
+void QQuickView::mouseMoveEvent(QMouseEvent *e)
+{
+    QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
+
+    QQuickCanvas::mouseMoveEvent(e);
+}
+
+void QQuickView::mousePressEvent(QMouseEvent *e)
+{
+    QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
+
+    QQuickCanvas::mousePressEvent(e);
+}
+
+void QQuickView::mouseReleaseEvent(QMouseEvent *e)
+{
+    QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
+
+    QQuickCanvas::mouseReleaseEvent(e);
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickview.h b/src/declarative/items/qquickview.h
new file mode 100644 (file)
index 0000000..8321655
--- /dev/null
@@ -0,0 +1,120 @@
+// Commit: 0b83a2161261be525f01359397ab1c8c34827749
+/****************************************************************************
+**
+** 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 QQUICKVIEW_H
+#define QQUICKVIEW_H
+
+#include <qquickcanvas.h>
+#include <QtCore/qurl.h>
+#include <QtDeclarative/qdeclarativedebug.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeEngine;
+class QDeclarativeContext;
+class QDeclarativeError;
+class QQuickItem;
+
+class QQuickViewPrivate;
+class Q_DECLARATIVE_EXPORT QQuickView : public QQuickCanvas
+{
+    Q_OBJECT
+    Q_PROPERTY(ResizeMode resizeMode READ resizeMode WRITE setResizeMode)
+    Q_PROPERTY(Status status READ status NOTIFY statusChanged)
+    Q_PROPERTY(QUrl source READ source WRITE setSource DESIGNABLE true)
+    Q_ENUMS(ResizeMode Status)
+public:
+    explicit QQuickView(QWindow *parent = 0, Qt::WindowFlags f = 0);
+    QQuickView(const QUrl &source, QWindow *parent = 0, Qt::WindowFlags f = 0);
+    virtual ~QQuickView();
+
+    QUrl source() const;
+
+    QDeclarativeEngine* engine() const;
+    QDeclarativeContext* rootContext() const;
+
+    QQuickItem *rootObject() const;
+
+    enum ResizeMode { SizeViewToRootObject, SizeRootObjectToView };
+    ResizeMode resizeMode() const;
+    void setResizeMode(ResizeMode);
+
+    enum Status { Null, Ready, Loading, Error };
+    Status status() const;
+
+    QList<QDeclarativeError> errors() const;
+
+    QSize sizeHint() const;
+    QSize initialSize() const;
+
+public Q_SLOTS:
+    void setSource(const QUrl&);
+
+Q_SIGNALS:
+    void statusChanged(QQuickView::Status);
+
+private Q_SLOTS:
+    void continueExecute();
+
+protected:
+    virtual void resizeEvent(QResizeEvent *);
+    virtual void timerEvent(QTimerEvent*);
+
+    virtual void keyPressEvent(QKeyEvent *);
+    virtual void keyReleaseEvent(QKeyEvent *);
+    virtual void mousePressEvent(QMouseEvent *);
+    virtual void mouseReleaseEvent(QMouseEvent *);
+    virtual void mouseMoveEvent(QMouseEvent *);
+private:
+    Q_DISABLE_COPY(QQuickView)
+    Q_DECLARE_PRIVATE(QQuickView)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QQUICKVIEW_H
diff --git a/src/declarative/items/qquickview_p.h b/src/declarative/items/qquickview_p.h
new file mode 100644 (file)
index 0000000..12be09b
--- /dev/null
@@ -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 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 QQUICKVIEW_P_H
+#define QQUICKVIEW_P_H
+
+#include "qquickview.h"
+
+#include <QtCore/qurl.h>
+#include <QtCore/qelapsedtimer.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qpointer.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include "qquickcanvas_p.h"
+
+#include "qquickitemchangelistener_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeContext;
+class QDeclarativeError;
+class QQuickItem;
+class QDeclarativeComponent;
+
+class QQuickViewPrivate : public QQuickCanvasPrivate,
+                       public QQuickItemChangeListener
+{
+    Q_DECLARE_PUBLIC(QQuickView)
+public:
+    static QQuickViewPrivate* get(QQuickView *view) { return view->d_func(); }
+    static const QQuickViewPrivate* get(const QQuickView *view) { return view->d_func(); }
+
+    QQuickViewPrivate();
+    ~QQuickViewPrivate();
+
+    void execute();
+    void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
+    void initResize();
+    void updateSize();
+    void setRootObject(QObject *);
+
+    void init();
+
+    QSize rootObjectSize() const;
+
+    QPointer<QQuickItem> root;
+
+    QUrl source;
+
+    QDeclarativeEngine engine;
+    QDeclarativeComponent *component;
+    QBasicTimer resizetimer;
+
+    QQuickView::ResizeMode resizeMode;
+    QSize initialSize;
+    QElapsedTimer frameTimer;
+
+    bool resized;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QQUICKVIEW_P_H
diff --git a/src/declarative/items/qquickvisualadaptormodel.cpp b/src/declarative/items/qquickvisualadaptormodel.cpp
new file mode 100644 (file)
index 0000000..28ea830
--- /dev/null
@@ -0,0 +1,889 @@
+/****************************************************************************
+**
+** 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 "qquickvisualadaptormodel_p.h"
+#include "qquickitem.h"
+
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativeexpression.h>
+#include <QtDeclarative/qdeclarativeinfo.h>
+
+#include <private/qdeclarativecontext_p.h>
+#include <private/qdeclarativepackage_p.h>
+#include <private/qdeclarativeopenmetaobject_p.h>
+#include <private/qdeclarativelistaccessor_p.h>
+#include <private/qdeclarativedata_p.h>
+#include <private/qdeclarativepropertycache_p.h>
+#include <private/qdeclarativeguard_p.h>
+#include <private/qdeclarativeglobal_p.h>
+#include <private/qlistmodelinterface_p.h>
+#include <private/qmetaobjectbuilder_p.h>
+#include <private/qdeclarativeproperty_p.h>
+#include <private/qintrusivelist_p.h>
+#include <private/qobject_p.h>
+
+#include <QtCore/qhash.h>
+#include <QtCore/qlist.h>
+
+Q_DECLARE_METATYPE(QModelIndex)
+
+QT_BEGIN_NAMESPACE
+
+class VDMDelegateDataType : public QDeclarativeRefCount
+{
+public:
+    VDMDelegateDataType()
+        : metaObject(0)
+        , propertyCache(0)
+        , propertyOffset(0)
+        , signalOffset(0)
+        , shared(true)
+    {
+    }
+
+    VDMDelegateDataType(const VDMDelegateDataType &type)
+        : metaObject(0)
+        , propertyCache(0)
+        , propertyOffset(type.propertyOffset)
+        , signalOffset(type.signalOffset)
+        , shared(false)
+        , builder(type.metaObject, QMetaObjectBuilder::Properties
+                | QMetaObjectBuilder::Signals
+                | QMetaObjectBuilder::SuperClass
+                | QMetaObjectBuilder::ClassName)
+    {
+        builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
+    }
+
+    ~VDMDelegateDataType()
+    {
+        if (propertyCache)
+            propertyCache->release();
+        qFree(metaObject);
+    }
+
+    QMetaObject *metaObject;
+    QDeclarativePropertyCache *propertyCache;
+    int propertyOffset;
+    int signalOffset;
+    bool shared : 1;
+    QMetaObjectBuilder builder;
+};
+
+class QQuickVisualAdaptorModelData : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(int index READ index NOTIFY indexChanged)
+public:
+    QQuickVisualAdaptorModelData(int index, QQuickVisualAdaptorModel *model);
+    ~QQuickVisualAdaptorModelData();
+
+    int index() const;
+    void setIndex(int index);
+
+Q_SIGNALS:
+    void indexChanged();
+
+public:
+    int m_index;
+    QDeclarativeGuard<QQuickVisualAdaptorModel> m_model;
+    QIntrusiveListNode m_cacheNode;
+};
+
+typedef QIntrusiveList<QQuickVisualAdaptorModelData, &QQuickVisualAdaptorModelData::m_cacheNode> QQuickVisualAdaptorModelDataCache;
+
+class QQuickVisualAdaptorModelDataMetaObject;
+class QQuickVisualAdaptorModelPrivate : public QObjectPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickVisualAdaptorModel)
+public:
+    QQuickVisualAdaptorModelPrivate()
+        : m_engine(0)
+        , m_listAccessor(0)
+        , m_delegateDataType(0)
+        , createModelData(&initializeModelData)
+        , m_ref(0)
+        , m_count(0)
+        , m_objectList(false)
+    {
+    }
+
+
+    static QQuickVisualAdaptorModelPrivate *get(QQuickVisualAdaptorModel *m) {
+        return static_cast<QQuickVisualAdaptorModelPrivate *>(QObjectPrivate::get(m));
+    }
+
+    void addProperty(int role, int propertyId, const char *propertyName, const char *propertyType, bool isModelData = false);
+    template <typename T> void setModelDataType()
+    {
+        createModelData = &T::create;
+        m_delegateDataType->builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
+        m_delegateDataType->builder.setClassName(T::staticMetaObject.className());
+        m_delegateDataType->builder.setSuperClass(&T::staticMetaObject);
+        m_delegateDataType->propertyOffset = T::staticMetaObject.propertyCount();
+        m_delegateDataType->signalOffset = T::staticMetaObject.methodCount();
+    }
+    QQuickVisualAdaptorModelData *createMetaObject(int index, QQuickVisualAdaptorModel *model);
+
+    static QQuickVisualAdaptorModelData *initializeModelData(int index, QQuickVisualAdaptorModel *model) {
+        return get(model)->createMetaObject(index, model);
+    }
+
+    typedef QQuickVisualAdaptorModelData *(*CreateModelData)(int index, QQuickVisualAdaptorModel *model);
+
+    struct PropertyData {
+        int role;
+        bool isModelData : 1;
+    };
+
+    int modelCount() const {
+        if (m_listModelInterface)
+            return m_listModelInterface->count();
+        if (m_abstractItemModel)
+            return m_abstractItemModel->rowCount(m_root);
+        if (m_listAccessor)
+            return m_listAccessor->count();
+        return 0;
+    }
+
+    QDeclarativeGuard<QDeclarativeEngine> m_engine;
+    QDeclarativeGuard<QListModelInterface> m_listModelInterface;
+    QDeclarativeGuard<QAbstractItemModel> m_abstractItemModel;
+    QDeclarativeListAccessor *m_listAccessor;
+    VDMDelegateDataType *m_delegateDataType;
+    CreateModelData createModelData;
+
+    int m_ref;
+    int m_count;
+    QQuickVisualAdaptorModel::Flags m_flags;
+    bool m_objectList : 1;
+
+    QVariant m_modelVariant;
+    QModelIndex m_root;
+
+    QList<int> m_roles;
+    QList<int> watchedRoleIds;
+    QList<QByteArray> watchedRoles;
+    QHash<QByteArray,int> m_roleNames;
+    QVector<PropertyData> m_propertyData;
+    QQuickVisualAdaptorModelDataCache m_cache;
+};
+
+class QQuickVisualAdaptorModelDataMetaObject : public QAbstractDynamicMetaObject
+{
+public:
+    QQuickVisualAdaptorModelDataMetaObject(QQuickVisualAdaptorModelData *data, VDMDelegateDataType *type)
+        : m_data(data)
+        , m_type(type)
+    {
+        QObjectPrivate *op = QObjectPrivate::get(m_data);
+        *static_cast<QMetaObject *>(this) = *type->metaObject;
+        op->metaObject = this;
+        m_type->addref();
+    }
+
+    ~QQuickVisualAdaptorModelDataMetaObject() { m_type->release(); }
+
+    QQuickVisualAdaptorModelData *m_data;
+    VDMDelegateDataType *m_type;
+};
+
+class QQuickVDMAbstractItemModelDataMetaObject : public QQuickVisualAdaptorModelDataMetaObject
+{
+public:
+    QQuickVDMAbstractItemModelDataMetaObject(QQuickVisualAdaptorModelData *object, VDMDelegateDataType *type)
+        : QQuickVisualAdaptorModelDataMetaObject(object, type) {}
+
+    int metaCall(QMetaObject::Call call, int id, void **arguments)
+    {
+        if (call == QMetaObject::ReadProperty && id >= m_type->propertyOffset) {
+            QQuickVisualAdaptorModelPrivate *model = QQuickVisualAdaptorModelPrivate::get(m_data->m_model);
+            if (m_data->m_index == -1 || !model->m_abstractItemModel)
+                return -1;
+            *static_cast<QVariant *>(arguments[0]) = model->m_abstractItemModel->index(
+                    m_data->m_index, 0, model->m_root).data(model->m_propertyData.at(id - m_type->propertyOffset).role);
+            return -1;
+        } else {
+            return m_data->qt_metacall(call, id, arguments);
+        }
+    }
+};
+
+class QQuickVDMAbstractItemModelData : public QQuickVisualAdaptorModelData
+{
+    Q_OBJECT
+    Q_PROPERTY(bool hasModelChildren READ hasModelChildren CONSTANT)
+public:
+    bool hasModelChildren() const
+    {
+        QQuickVisualAdaptorModelPrivate *model = QQuickVisualAdaptorModelPrivate::get(m_model);
+        return model->m_abstractItemModel->hasChildren(model->m_abstractItemModel->index(m_index, 0, model->m_root));
+    }
+
+    static QQuickVisualAdaptorModelData *create(int index, QQuickVisualAdaptorModel *model) {
+        return new QQuickVDMAbstractItemModelData(index, model); }
+private:
+    QQuickVDMAbstractItemModelData(int index, QQuickVisualAdaptorModel *model)
+        : QQuickVisualAdaptorModelData(index, model)
+    {
+        new QQuickVDMAbstractItemModelDataMetaObject(
+                this, QQuickVisualAdaptorModelPrivate::get(m_model)->m_delegateDataType);
+    }
+};
+
+class QQuickVDMListModelInterfaceDataMetaObject : public QQuickVisualAdaptorModelDataMetaObject
+{
+public:
+    QQuickVDMListModelInterfaceDataMetaObject(QQuickVisualAdaptorModelData *object, VDMDelegateDataType *type)
+        : QQuickVisualAdaptorModelDataMetaObject(object, type) {}
+
+    int metaCall(QMetaObject::Call call, int id, void **arguments)
+    {
+        if (call == QMetaObject::ReadProperty && id >= m_type->propertyOffset) {
+            QQuickVisualAdaptorModelPrivate *model = QQuickVisualAdaptorModelPrivate::get(m_data->m_model);
+            if (m_data->m_index == -1 || !model->m_listModelInterface)
+                return -1;
+            *static_cast<QVariant *>(arguments[0]) = model->m_listModelInterface->data(
+                    m_data->m_index, model->m_propertyData.at(id - m_type->propertyOffset).role);
+            return -1;
+        } else {
+            return m_data->qt_metacall(call, id, arguments);
+        }
+    }
+};
+
+class QQuickVDMListModelInterfaceData : public QQuickVisualAdaptorModelData
+{
+public:
+    static QQuickVisualAdaptorModelData *create(int index, QQuickVisualAdaptorModel *model) {
+        return new QQuickVDMListModelInterfaceData(index, model); }
+private:
+    QQuickVDMListModelInterfaceData(int index, QQuickVisualAdaptorModel *model)
+        : QQuickVisualAdaptorModelData(index, model)
+    {
+        new QQuickVDMListModelInterfaceDataMetaObject(
+                this, QQuickVisualAdaptorModelPrivate::get(m_model)->m_delegateDataType);
+    }
+};
+
+class QQuickVDMListAccessorData : public QQuickVisualAdaptorModelData
+{
+    Q_OBJECT
+    Q_PROPERTY(QVariant modelData READ modelData CONSTANT)
+public:
+    QVariant modelData() const {
+        return QQuickVisualAdaptorModelPrivate::get(m_model)->m_listAccessor->at(m_index); }
+
+    static QQuickVisualAdaptorModelData *create(int index, QQuickVisualAdaptorModel *model) {
+        return new QQuickVDMListAccessorData(index, model); }
+private:
+    QQuickVDMListAccessorData(int index, QQuickVisualAdaptorModel *model)
+        : QQuickVisualAdaptorModelData(index, model)
+    {
+    }
+};
+
+class QQuickVDMObjectDataMetaObject : public QQuickVisualAdaptorModelDataMetaObject
+{
+public:
+    QQuickVDMObjectDataMetaObject(QQuickVisualAdaptorModelData *data, VDMDelegateDataType *type)
+        : QQuickVisualAdaptorModelDataMetaObject(data, type)
+        , m_object(QQuickVisualAdaptorModelPrivate::get(data->m_model)->m_listAccessor->at(data->m_index).value<QObject *>())
+    {}
+
+    int metaCall(QMetaObject::Call call, int id, void **arguments)
+    {
+        if (id >= m_type->propertyOffset
+                && (call == QMetaObject::ReadProperty
+                || call == QMetaObject::WriteProperty
+                || call == QMetaObject::ResetProperty)) {
+            if (m_object)
+                QMetaObject::metacall(m_object, call, id - m_type->propertyOffset + 1, arguments);
+            return -1;
+        } else if (id >= m_type->signalOffset && call == QMetaObject::InvokeMetaMethod) {
+            QMetaObject::activate(m_data, this, id, 0);
+            return -1;
+        } else {
+            return m_data->qt_metacall(call, id, arguments);
+        }
+    }
+
+    int createProperty(const char *name, const char *)
+    {
+        if (!m_object)
+            return -1;
+        const QMetaObject *metaObject = m_object->metaObject();
+
+        const int previousPropertyCount = propertyCount() - propertyOffset();
+        int propertyIndex = metaObject->indexOfProperty(name);
+        if (propertyIndex == -1)
+            return -1;
+        if (previousPropertyCount + 1 == metaObject->propertyCount())
+            return propertyIndex + m_type->propertyOffset - 1;
+
+        if (m_type->shared) {
+            VDMDelegateDataType *type = m_type;
+            m_type = new VDMDelegateDataType(*m_type);
+            type->release();
+        }
+
+        const int previousMethodCount = methodCount();
+        int notifierId = previousMethodCount;
+        for (int propertyId = previousPropertyCount; propertyId < metaObject->propertyCount() - 1; ++propertyId) {
+            QMetaProperty property = metaObject->property(propertyId + 1);
+            QMetaPropertyBuilder propertyBuilder;
+            if (property.hasNotifySignal()) {
+                m_type->builder.addSignal("__" + QByteArray::number(propertyId) + "()");
+                propertyBuilder = m_type->builder.addProperty(property.name(), property.typeName(), notifierId);
+                ++notifierId;
+            } else {
+                propertyBuilder = m_type->builder.addProperty(property.name(), property.typeName());
+            }
+            propertyBuilder.setWritable(property.isWritable());
+            propertyBuilder.setResettable(property.isResettable());
+            propertyBuilder.setConstant(property.isConstant());
+        }
+
+        if (m_type->metaObject)
+            qFree(m_type->metaObject);
+        m_type->metaObject = m_type->builder.toMetaObject();
+        *static_cast<QMetaObject *>(this) = *m_type->metaObject;
+
+        notifierId = previousMethodCount;
+        for (int i = previousPropertyCount; i < metaObject->propertyCount(); ++i) {
+            QMetaProperty property = metaObject->property(i);
+            if (property.hasNotifySignal()) {
+                QDeclarativePropertyPrivate::connect(
+                        m_object, property.notifySignalIndex(), m_data, notifierId);
+                ++notifierId;
+            }
+        }
+        return propertyIndex + m_type->propertyOffset - 1;
+    }
+
+    QDeclarativeGuard<QObject> m_object;
+};
+
+class QQuickVDMObjectData : public QQuickVisualAdaptorModelData, public QQuickVisualAdaptorModelProxyInterface
+{
+    Q_OBJECT
+    Q_PROPERTY(QObject *modelData READ modelData CONSTANT)
+    Q_INTERFACES(QQuickVisualAdaptorModelProxyInterface)
+public:
+    QObject *modelData() const { return m_metaObject->m_object; }
+    QObject *proxiedObject() { return m_metaObject->m_object; }
+
+    static QQuickVisualAdaptorModelData *create(int index, QQuickVisualAdaptorModel *model) {
+        return new QQuickVDMObjectData(index, model); }
+
+private:
+    QQuickVDMObjectData(int index, QQuickVisualAdaptorModel *model)
+        : QQuickVisualAdaptorModelData(index, model)
+        , m_metaObject(new QQuickVDMObjectDataMetaObject(this, QQuickVisualAdaptorModelPrivate::get(m_model)->m_delegateDataType))
+    {
+    }
+
+    QQuickVDMObjectDataMetaObject *m_metaObject;
+};
+
+void QQuickVisualAdaptorModelPrivate::addProperty(
+        int role, int propertyId, const char *propertyName, const char *propertyType, bool isModelData)
+{
+    PropertyData propertyData;
+    propertyData.role = role;
+    propertyData.isModelData = isModelData;
+    m_delegateDataType->builder.addSignal("__" + QByteArray::number(propertyId) + "()");
+    QMetaPropertyBuilder property = m_delegateDataType->builder.addProperty(
+            propertyName, propertyType, propertyId);
+    property.setWritable(false);
+
+    m_propertyData.append(propertyData);
+}
+
+QQuickVisualAdaptorModelData *QQuickVisualAdaptorModelPrivate::createMetaObject(int index, QQuickVisualAdaptorModel *model)
+{
+    Q_ASSERT(!m_delegateDataType);
+
+    m_objectList = false;
+    m_propertyData.clear();
+    if (m_listAccessor
+            && m_listAccessor->type() != QDeclarativeListAccessor::ListProperty
+            && m_listAccessor->type() != QDeclarativeListAccessor::Instance) {
+        createModelData = &QQuickVDMListAccessorData::create;
+        m_flags = QQuickVisualAdaptorModel::MetaObjectCacheable;
+        return QQuickVDMListAccessorData::create(index, model);
+    }
+
+    m_delegateDataType = new VDMDelegateDataType;
+    if (m_listModelInterface) {
+        setModelDataType<QQuickVDMListModelInterfaceData>();
+        QList<int> roles = m_listModelInterface->roles();
+        for (int propertyId = 0; propertyId < roles.count(); ++propertyId) {
+            const int role = roles.at(propertyId);
+            const QByteArray propertyName = m_listModelInterface->toString(role).toUtf8();
+            addProperty(role, propertyId, propertyName, "QVariant");
+            m_roleNames.insert(propertyName, role);
+        }
+        if (m_propertyData.count() == 1)
+            addProperty(roles.first(), 1, "modelData", "QVariant", true);
+        m_flags = QQuickVisualAdaptorModel::MetaObjectCacheable;
+    } else if (m_abstractItemModel) {
+        setModelDataType<QQuickVDMAbstractItemModelData>();
+        QHash<int, QByteArray> roleNames = m_abstractItemModel->roleNames();
+        for (QHash<int, QByteArray>::const_iterator it = roleNames.begin(); it != roleNames.end(); ++it) {
+            addProperty(it.key(), m_propertyData.count(), it.value(), "QVariant");
+            m_roleNames.insert(it.value(), it.key());
+        }
+        if (m_propertyData.count() == 1)
+            addProperty(roleNames.begin().key(), 1, "modelData", "QVariant", true);
+        m_flags = QQuickVisualAdaptorModel::MetaObjectCacheable;
+    } else if (m_listAccessor) {
+        setModelDataType<QQuickVDMObjectData>();
+        m_objectList = true;
+        m_flags = QQuickVisualAdaptorModel::ProxiedObject;
+    } else {
+        Q_ASSERT(!"No model set on VisualDataModel");
+        return 0;
+    }
+    m_delegateDataType->metaObject = m_delegateDataType->builder.toMetaObject();
+    if (!m_objectList) {
+        m_delegateDataType->propertyCache = new QDeclarativePropertyCache(
+                m_engine, m_delegateDataType->metaObject);
+    }
+    return createModelData(index, model);
+}
+
+QQuickVisualAdaptorModelData::QQuickVisualAdaptorModelData(int index, QQuickVisualAdaptorModel *model)
+    : m_index(index)
+    , m_model(model)
+{
+}
+
+QQuickVisualAdaptorModelData::~QQuickVisualAdaptorModelData()
+{
+}
+
+int QQuickVisualAdaptorModelData::index() const
+{
+    return m_index;
+}
+
+// This is internal only - it should not be set from qml
+void QQuickVisualAdaptorModelData::setIndex(int index)
+{
+    m_index = index;
+    emit indexChanged();
+}
+
+//---------------------------------------------------------------------------
+
+QQuickVisualAdaptorModel::QQuickVisualAdaptorModel(QObject *parent)
+    : QObject(*(new QQuickVisualAdaptorModelPrivate), parent)
+{
+}
+
+QQuickVisualAdaptorModel::~QQuickVisualAdaptorModel()
+{
+    Q_D(QQuickVisualAdaptorModel);
+    if (d->m_listAccessor)
+        delete d->m_listAccessor;
+    if (d->m_delegateDataType)
+        d->m_delegateDataType->release();
+}
+
+QQuickVisualAdaptorModel::Flags QQuickVisualAdaptorModel::flags() const
+{
+    Q_D(const QQuickVisualAdaptorModel);
+    return d->m_flags;
+}
+
+QVariant QQuickVisualAdaptorModel::model() const
+{
+    Q_D(const QQuickVisualAdaptorModel);
+    return d->m_modelVariant;
+}
+
+void QQuickVisualAdaptorModel::setModel(const QVariant &model, QDeclarativeEngine *engine)
+{
+    Q_D(QQuickVisualAdaptorModel);
+    delete d->m_listAccessor;
+    d->m_engine = engine;
+    d->m_listAccessor = 0;
+    d->m_modelVariant = model;
+    if (d->m_listModelInterface) {
+        // Assume caller has released all items.
+        QObject::disconnect(d->m_listModelInterface, SIGNAL(itemsChanged(int,int,QList<int>)),
+                this, SLOT(_q_itemsChanged(int,int,QList<int>)));
+        QObject::disconnect(d->m_listModelInterface, SIGNAL(itemsInserted(int,int)),
+                this, SLOT(_q_itemsInserted(int,int)));
+        QObject::disconnect(d->m_listModelInterface, SIGNAL(itemsRemoved(int,int)),
+                this, SLOT(_q_itemsRemoved(int,int)));
+        QObject::disconnect(d->m_listModelInterface, SIGNAL(itemsMoved(int,int,int)),
+                this, SLOT(_q_itemsMoved(int,int,int)));
+        d->m_listModelInterface = 0;
+    } else if (d->m_abstractItemModel) {
+        QObject::disconnect(d->m_abstractItemModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
+                            this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
+        QObject::disconnect(d->m_abstractItemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+                            this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+        QObject::disconnect(d->m_abstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+                            this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
+        QObject::disconnect(d->m_abstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+                            this, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int)));
+        QObject::disconnect(d->m_abstractItemModel, SIGNAL(modelReset()), this, SLOT(_q_modelReset()));
+        QObject::disconnect(d->m_abstractItemModel, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
+        d->m_abstractItemModel = 0;
+    }
+
+    d->m_roles.clear();
+    d->m_roleNames.clear();
+    d->m_flags = QQuickVisualAdaptorModel::Flags();
+    if (d->m_delegateDataType)
+        d->m_delegateDataType->release();
+    d->m_delegateDataType = 0;
+    d->createModelData = &QQuickVisualAdaptorModelPrivate::initializeModelData;
+
+    if (d->m_count)
+        emit itemsRemoved(0, d->m_count);
+
+    QObject *object = qvariant_cast<QObject *>(model);
+    if (object && (d->m_listModelInterface = qobject_cast<QListModelInterface *>(object))) {
+        QObject::connect(d->m_listModelInterface, SIGNAL(itemsChanged(int,int,QList<int>)),
+                         this, SLOT(_q_itemsChanged(int,int,QList<int>)));
+        QObject::connect(d->m_listModelInterface, SIGNAL(itemsInserted(int,int)),
+                         this, SLOT(_q_itemsInserted(int,int)));
+        QObject::connect(d->m_listModelInterface, SIGNAL(itemsRemoved(int,int)),
+                         this, SLOT(_q_itemsRemoved(int,int)));
+        QObject::connect(d->m_listModelInterface, SIGNAL(itemsMoved(int,int,int)),
+                         this, SLOT(_q_itemsMoved(int,int,int)));
+        if ((d->m_count = d->m_listModelInterface->count()))
+            emit itemsInserted(0, d->m_count);
+        return;
+    } else if (object && (d->m_abstractItemModel = qobject_cast<QAbstractItemModel *>(object))) {
+        QObject::connect(d->m_abstractItemModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
+                            this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
+        QObject::connect(d->m_abstractItemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+                            this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+        QObject::connect(d->m_abstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+                            this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
+        QObject::connect(d->m_abstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+                            this, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int)));
+        QObject::connect(d->m_abstractItemModel, SIGNAL(modelReset()), this, SLOT(_q_modelReset()));
+        QObject::connect(d->m_abstractItemModel, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
+
+        if ((d->m_count = d->m_abstractItemModel->rowCount(d->m_root)))
+            emit itemsInserted(0, d->m_count);
+        return;
+    }
+
+    d->m_listAccessor = new QDeclarativeListAccessor;
+    d->m_listAccessor->setList(model, d->m_engine);
+    if ((d->m_count = d->m_listAccessor->count()))
+        emit itemsInserted(0, d->m_count);
+}
+
+QVariant QQuickVisualAdaptorModel::rootIndex() const
+{
+    Q_D(const QQuickVisualAdaptorModel);
+    return QVariant::fromValue(d->m_root);
+}
+
+void QQuickVisualAdaptorModel::setRootIndex(const QVariant &root)
+{
+    Q_D(QQuickVisualAdaptorModel);
+    QModelIndex modelIndex = qvariant_cast<QModelIndex>(root);
+    if (d->m_root != modelIndex) {
+        int oldCount = d->modelCount();
+        d->m_root = modelIndex;
+        if (d->m_abstractItemModel && d->m_abstractItemModel->canFetchMore(modelIndex))
+            d->m_abstractItemModel->fetchMore(modelIndex);
+        int newCount = d->modelCount();
+        if (oldCount)
+            emit itemsRemoved(0, oldCount);
+        if (newCount)
+            emit itemsInserted(0, newCount);
+        emit rootIndexChanged();
+    }
+}
+
+QVariant QQuickVisualAdaptorModel::modelIndex(int idx) const
+{
+    Q_D(const QQuickVisualAdaptorModel);
+    if (d->m_abstractItemModel)
+        return QVariant::fromValue(d->m_abstractItemModel->index(idx, 0, d->m_root));
+    return QVariant::fromValue(QModelIndex());
+}
+
+QVariant QQuickVisualAdaptorModel::parentModelIndex() const
+{
+    Q_D(const QQuickVisualAdaptorModel);
+    if (d->m_abstractItemModel)
+        return QVariant::fromValue(d->m_abstractItemModel->parent(d->m_root));
+    return QVariant::fromValue(QModelIndex());
+}
+
+int QQuickVisualAdaptorModel::count() const
+{
+    Q_D(const QQuickVisualAdaptorModel);
+    return d->modelCount();
+}
+
+QObject *QQuickVisualAdaptorModel::data(int index)
+{
+    Q_D(QQuickVisualAdaptorModel);
+    QQuickVisualAdaptorModelData *data = d->createModelData(index, this);
+    d->m_cache.insert(data);
+    return data;
+}
+
+QString QQuickVisualAdaptorModel::stringValue(int index, const QString &name)
+{
+    Q_D(QQuickVisualAdaptorModel);
+    if ((!d->m_listModelInterface || !d->m_abstractItemModel) && d->m_listAccessor) {
+        if (QObject *object = d->m_listAccessor->at(index).value<QObject*>())
+            return object->property(name.toUtf8()).toString();
+    }
+
+    QString val;
+    QQuickVisualAdaptorModelData *data = d->createModelData(index, this);
+
+    QDeclarativeData *ddata = QDeclarativeData::get(data);
+    if (ddata && ddata->propertyCache) {
+        QDeclarativePropertyCache::Data *prop = ddata->propertyCache->property(name);
+        if (prop) {
+            if (prop->propType == QVariant::String) {
+                void *args[] = { &val, 0 };
+                QMetaObject::metacall(data, QMetaObject::ReadProperty, prop->coreIndex, args);
+            } else if (prop->propType == qMetaTypeId<QVariant>()) {
+                QVariant v;
+                void *args[] = { &v, 0 };
+                QMetaObject::metacall(data, QMetaObject::ReadProperty, prop->coreIndex, args);
+                val = v.toString();
+            }
+        } else {
+            val = data->property(name.toUtf8()).toString();
+        }
+    } else {
+        val = data->property(name.toUtf8()).toString();
+    }
+
+    delete data;
+
+    return val;
+}
+
+int QQuickVisualAdaptorModel::indexOf(QObject *object) const
+{
+    if (QQuickVisualAdaptorModelData *data = qobject_cast<QQuickVisualAdaptorModelData *>(object))
+        return data->index();
+    return -1;
+}
+
+bool QQuickVisualAdaptorModel::canFetchMore() const
+{
+    Q_D(const QQuickVisualAdaptorModel);
+    return d->m_abstractItemModel && d->m_abstractItemModel->canFetchMore(d->m_root);
+}
+
+void QQuickVisualAdaptorModel::fetchMore()
+{
+    Q_D(QQuickVisualAdaptorModel);
+    if (d->m_abstractItemModel)
+        d->m_abstractItemModel->fetchMore(d->m_root);
+}
+
+void QQuickVisualAdaptorModel::replaceWatchedRoles(const QList<QByteArray> &oldRoles, const QList<QByteArray> &newRoles)
+{
+    Q_D(QQuickVisualAdaptorModel);
+    d->watchedRoleIds.clear();
+    foreach (const QByteArray &oldRole, oldRoles)
+        d->watchedRoles.removeOne(oldRole);
+    d->watchedRoles += newRoles;
+}
+
+void QQuickVisualAdaptorModel::_q_itemsChanged(int index, int count, const QList<int> &roles)
+{
+    Q_D(QQuickVisualAdaptorModel);
+    bool changed = roles.isEmpty();
+    if (!d->watchedRoles.isEmpty() && d->watchedRoleIds.isEmpty()) {
+        foreach (QByteArray r, d->watchedRoles) {
+            if (d->m_roleNames.contains(r))
+                d->watchedRoleIds << d->m_roleNames.value(r);
+        }
+    }
+
+    QVector<int> signalIndexes;
+    for (int i = 0; i < roles.count(); ++i) {
+        const int role = roles.at(i);
+        if (!changed && d->watchedRoleIds.contains(role))
+            changed = true;
+        for (int propertyId = 0; propertyId < d->m_propertyData.count(); ++propertyId) {
+            if (d->m_propertyData.at(propertyId).role == role)
+                signalIndexes.append(propertyId + d->m_delegateDataType->signalOffset);
+        }
+    }
+    if (roles.isEmpty()) {
+        for (int propertyId = 0; propertyId < d->m_propertyData.count(); ++propertyId)
+            signalIndexes.append(propertyId + d->m_delegateDataType->signalOffset);
+    }
+
+    typedef QQuickVisualAdaptorModelDataCache::iterator iterator;
+    for (iterator it = d->m_cache.begin(); it != d->m_cache.end(); ++it) {
+        const int idx = it->index();
+        if (idx >= index && idx < index + count) {
+            QQuickVisualAdaptorModelData *data = *it;
+            for (int i = 0; i < signalIndexes.count(); ++i)
+                QMetaObject::activate(data, signalIndexes.at(i), 0);
+        }
+    }
+    if (changed)
+        emit itemsChanged(index, count);
+}
+
+void QQuickVisualAdaptorModel::_q_itemsInserted(int index, int count)
+{
+    Q_D(QQuickVisualAdaptorModel);
+    if (count <= 0)
+        return;
+    d->m_count += count;
+
+    typedef QQuickVisualAdaptorModelDataCache::iterator iterator;
+    for (iterator it = d->m_cache.begin(); it != d->m_cache.end(); ++it) {
+        if (it->index() >= index)
+            it->setIndex(it->index() + count);
+    }
+
+    emit itemsInserted(index, count);
+}
+
+void QQuickVisualAdaptorModel::_q_itemsRemoved(int index, int count)
+{
+    Q_D(QQuickVisualAdaptorModel);
+    if (count <= 0)
+        return;
+    d->m_count -= count;
+
+    typedef QQuickVisualAdaptorModelDataCache::iterator iterator;
+    for (iterator it = d->m_cache.begin(); it != d->m_cache.end(); ++it) {
+        if (it->index() >= index + count)
+            it->setIndex(it->index() - count);
+        else  if (it->index() >= index)
+            it->setIndex(-1);
+    }
+
+    emit itemsRemoved(index, count);
+}
+
+void QQuickVisualAdaptorModel::_q_itemsMoved(int from, int to, int count)
+{
+    Q_D(QQuickVisualAdaptorModel);
+    const int minimum = qMin(from, to);
+    const int maximum = qMax(from, to) + count;
+    const int difference = from > to ? count : -count;
+
+    typedef QQuickVisualAdaptorModelDataCache::iterator iterator;
+    for (iterator it = d->m_cache.begin(); it != d->m_cache.end(); ++it) {
+        if (it->index() >= from && it->index() < from + count)
+            it->setIndex(it->index() - from + to);
+        else if (it->index() >= minimum && it->index() < maximum)
+            it->setIndex(it->index() + difference);
+    }
+    emit itemsMoved(from, to, count);
+}
+
+void QQuickVisualAdaptorModel::_q_rowsInserted(const QModelIndex &parent, int begin, int end)
+{
+    Q_D(QQuickVisualAdaptorModel);
+    if (parent == d->m_root)
+        _q_itemsInserted(begin, end - begin + 1);
+}
+
+void QQuickVisualAdaptorModel::_q_rowsRemoved(const QModelIndex &parent, int begin, int end)
+{
+    Q_D(QQuickVisualAdaptorModel);
+    if (parent == d->m_root)
+        _q_itemsRemoved(begin, end - begin + 1);
+}
+
+void QQuickVisualAdaptorModel::_q_rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
+{
+   Q_D(QQuickVisualAdaptorModel);
+    const int count = sourceEnd - sourceStart + 1;
+    if (destinationParent == d->m_root && sourceParent == d->m_root) {
+        _q_itemsMoved(sourceStart, sourceStart > destinationRow ? destinationRow : destinationRow-count, count);
+    } else if (sourceParent == d->m_root) {
+        _q_itemsRemoved(sourceStart, count);
+    } else if (destinationParent == d->m_root) {
+        _q_itemsInserted(destinationRow, count);
+    }
+}
+
+void QQuickVisualAdaptorModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end)
+{
+    Q_D(QQuickVisualAdaptorModel);
+    if (begin.parent() == d->m_root)
+        _q_itemsChanged(begin.row(), end.row() - begin.row() + 1, d->m_roles);
+}
+
+void QQuickVisualAdaptorModel::_q_layoutChanged()
+{
+    Q_D(QQuickVisualAdaptorModel);
+    _q_itemsChanged(0, count(), d->m_roles);
+}
+
+void QQuickVisualAdaptorModel::_q_modelReset()
+{
+    Q_D(QQuickVisualAdaptorModel);
+    int oldCount = d->m_count;
+    d->m_root = QModelIndex();
+    d->m_count = d->modelCount();
+    emit modelReset(oldCount, d->m_count);
+    emit rootIndexChanged();
+    if (d->m_abstractItemModel && d->m_abstractItemModel->canFetchMore(d->m_root))
+        d->m_abstractItemModel->fetchMore(d->m_root);
+}
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QListModelInterface)
+
+#include <qquickvisualadaptormodel.moc>
diff --git a/src/declarative/items/qquickvisualadaptormodel_p.h b/src/declarative/items/qquickvisualadaptormodel_p.h
new file mode 100644 (file)
index 0000000..31eba50
--- /dev/null
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** 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 QQUICKVISUALADAPTORMODEL_P_H
+#define QQUICKVISUALADAPTORMODEL_P_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qabstractitemmodel.h>
+
+#include <private/qdeclarativerefcount_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeEngine;
+
+class QQuickVisualAdaptorModelPrivate;
+class QQuickVisualAdaptorModel : public QObject
+{
+    Q_OBJECT
+    Q_DECLARE_PRIVATE(QQuickVisualAdaptorModel)
+public:
+    enum Flag
+    {
+        MetaObjectCacheable = 0x01,
+        ProxiedObject       = 0x02
+    };
+    Q_DECLARE_FLAGS(Flags, Flag)
+
+    QQuickVisualAdaptorModel(QObject *parent = 0);
+    virtual ~QQuickVisualAdaptorModel();
+
+    Flags flags() const;
+
+    QVariant model() const;
+    void setModel(const QVariant &, QDeclarativeEngine *);
+
+    QVariant rootIndex() const;
+    void setRootIndex(const QVariant &root);
+
+    QVariant modelIndex(int idx) const;
+    QVariant parentModelIndex() const;
+
+    int count() const;
+    QObject *data(int index);
+    QString stringValue(int index, const QString &role);
+    void replaceWatchedRoles(const QList<QByteArray> &oldRoles, const QList<QByteArray> &newRoles);
+    int indexOf(QObject *object) const;
+
+    bool canFetchMore() const;
+    void fetchMore();
+
+Q_SIGNALS:
+    void rootIndexChanged();
+    void modelReset(int oldCount, int newCount);
+
+    void itemsInserted(int index, int count);
+    void itemsRemoved(int index, int count);
+    void itemsMoved(int from, int to, int count);
+    void itemsChanged(int index, int count);
+
+private Q_SLOTS:
+    void _q_itemsChanged(int, int, const QList<int> &);
+    void _q_itemsInserted(int index, int count);
+    void _q_itemsRemoved(int index, int count);
+    void _q_itemsMoved(int from, int to, int count);
+    void _q_rowsInserted(const QModelIndex &,int,int);
+    void _q_rowsRemoved(const QModelIndex &,int,int);
+    void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
+    void _q_dataChanged(const QModelIndex&,const QModelIndex&);
+    void _q_layoutChanged();
+    void _q_modelReset();
+
+private:
+    Q_DISABLE_COPY(QQuickVisualAdaptorModel)
+};
+
+class QQuickVisualAdaptorModelProxyInterface
+{
+public:
+    virtual ~QQuickVisualAdaptorModelProxyInterface() {}
+
+    virtual QObject *proxiedObject() = 0;
+};
+
+Q_DECLARE_INTERFACE(QQuickVisualAdaptorModelProxyInterface, "com.trolltech.qml.QQuickVisualAdaptorModelProxyInterface")
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/declarative/items/qquickvisualdatamodel.cpp b/src/declarative/items/qquickvisualdatamodel.cpp
new file mode 100644 (file)
index 0000000..1a24e16
--- /dev/null
@@ -0,0 +1,2538 @@
+/****************************************************************************
+**
+** 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 "qquickvisualdatamodel_p.h"
+#include "qquickitem.h"
+
+#include <QtCore/qcoreapplication.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativeexpression.h>
+#include <QtDeclarative/qdeclarativeinfo.h>
+
+#include <private/qdeclarativecontext_p.h>
+#include <private/qdeclarativepackage_p.h>
+#include <private/qdeclarativeopenmetaobject_p.h>
+#include <private/qdeclarativelistaccessor_p.h>
+#include <private/qdeclarativedata_p.h>
+#include <private/qdeclarativepropertycache_p.h>
+#include <private/qdeclarativeguard_p.h>
+#include <private/qdeclarativeglobal_p.h>
+#include <private/qmetaobjectbuilder_p.h>
+#include <private/qdeclarativeproperty_p.h>
+#include <private/qquickvisualadaptormodel_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>
+#include <QtCore/qlist.h>
+
+QT_BEGIN_NAMESPACE
+
+typedef QDeclarativeListCompositor Compositor;
+
+class QQuickVisualDataGroupEmitter
+{
+public:
+    virtual void emitModelUpdated(const QDeclarativeChangeSet &changeSet, bool reset) = 0;
+    virtual void createdPackage(int, QDeclarativePackage *) {}
+    virtual void destroyingPackage(QDeclarativePackage *) {}
+
+    QIntrusiveListNode emitterNode;
+};
+
+typedef QIntrusiveList<QQuickVisualDataGroupEmitter, &QQuickVisualDataGroupEmitter::emitterNode> QQuickVisualDataGroupEmitterList;
+
+//---------------------------------------------------------------------------
+
+class QQuickVisualDataGroupPrivate : public QObjectPrivate
+{
+public:
+    Q_DECLARE_PUBLIC(QQuickVisualDataGroup)
+
+    QQuickVisualDataGroupPrivate() : group(Compositor::Cache), defaultInclude(false) {}
+
+    static QQuickVisualDataGroupPrivate *get(QQuickVisualDataGroup *group) {
+        return static_cast<QQuickVisualDataGroupPrivate *>(QObjectPrivate::get(group)); }
+
+    void setModel(QQuickVisualDataModel *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<QQuickVisualDataModel> model;
+    QQuickVisualDataGroupEmitterList emitters;
+    QDeclarativeChangeSet changeSet;
+    QString name;
+    bool defaultInclude;
+};
+
+//---------------------------------------------------------------------------
+
+class QQuickVisualDataModelCacheItem;
+class QQuickVisualDataModelCacheMetaType;
+class QQuickVisualDataModelParts;
+
+class QQuickVisualDataModelPrivate : public QObjectPrivate, public QQuickVisualDataGroupEmitter
+{
+    Q_DECLARE_PUBLIC(QQuickVisualDataModel)
+public:
+    QQuickVisualDataModelPrivate(QDeclarativeContext *);
+
+    static QQuickVisualDataModelPrivate *get(QQuickVisualDataModel *m) {
+        return static_cast<QQuickVisualDataModelPrivate *>(QObjectPrivate::get(m));
+    }
+
+    void init();
+    void connectModel(QQuickVisualAdaptorModel *model);
+
+    QObject *object(Compositor::Group group, int index, bool complete, bool reference);
+    void destroy(QObject *object);
+    QQuickVisualDataModel::ReleaseFlags release(QObject *object);
+    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, QQuickItem *item) {
+        emit q_func()->createdItem(at.index[m_compositorGroup], item); }
+    void emitDestroyingPackage(QDeclarativePackage *package);
+    void emitDestroyingItem(QQuickItem *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<QQuickVisualDataModelCacheItem *> > *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<QQuickVisualDataModelCacheItem *> > *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<QQuickVisualDataGroup> *property, QQuickVisualDataGroup *group);
+    static int group_count(QDeclarativeListProperty<QQuickVisualDataGroup> *property);
+    static QQuickVisualDataGroup *group_at(QDeclarativeListProperty<QQuickVisualDataGroup> *property, int index);
+
+    QQuickVisualAdaptorModel *m_adaptorModel;
+    QDeclarativeComponent *m_delegate;
+    QQuickVisualDataModelCacheMetaType *m_cacheMetaType;
+    QDeclarativeGuard<QDeclarativeContext> m_context;
+
+    QList<QQuickVisualDataModelCacheItem *> m_cache;
+    QQuickVisualDataModelParts *m_parts;
+    QQuickVisualDataGroupEmitterList m_pendingParts;
+
+    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;
+
+    QString m_filterGroup;
+    QList<QByteArray> watchedRoles;
+
+    union {
+        struct {
+            QQuickVisualDataGroup *m_cacheItems;
+            QQuickVisualDataGroup *m_items;
+            QQuickVisualDataGroup *m_persistedItems;
+        };
+        QQuickVisualDataGroup *m_groups[Compositor::MaximumGroupCount];
+    };
+    int m_groupCount;
+};
+
+//---------------------------------------------------------------------------
+
+class QQuickVisualPartsModel : public QQuickVisualModel, public QQuickVisualDataGroupEmitter
+{
+    Q_OBJECT
+    Q_PROPERTY(QString filterOnGroup READ filterGroup WRITE setFilterGroup NOTIFY filterGroupChanged RESET resetFilterGroup)
+public:
+    QQuickVisualPartsModel(QQuickVisualDataModel *model, const QString &part, QObject *parent = 0);
+    ~QQuickVisualPartsModel();
+
+    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;
+    QQuickItem *item(int index, bool complete=true);
+    ReleaseFlags release(QQuickItem *item);
+    bool completePending() const;
+    void completeItem();
+    QString stringValue(int index, const QString &role);
+    void setWatchedRoles(QList<QByteArray> roles);
+
+    int indexOf(QQuickItem *item, QObject *objectContext) const;
+
+    void emitModelUpdated(const QDeclarativeChangeSet &changeSet, bool reset);
+
+    void createdPackage(int index, QDeclarativePackage *package);
+    void destroyingPackage(QDeclarativePackage *package);
+
+Q_SIGNALS:
+    void filterGroupChanged();
+
+private:
+    QQuickVisualDataModel *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 QQuickVisualDataModelPartsMetaObject : public QDeclarativeOpenMetaObject
+{
+public:
+    QQuickVisualDataModelPartsMetaObject(QObject *parent)
+    : QDeclarativeOpenMetaObject(parent) {}
+
+    virtual void propertyCreated(int, QMetaPropertyBuilder &);
+    virtual QVariant initialValue(int);
+};
+
+class QQuickVisualDataModelParts : public QObject
+{
+Q_OBJECT
+public:
+    QQuickVisualDataModelParts(QQuickVisualDataModel *parent);
+
+    QQuickVisualDataModel *model;
+    QList<QQuickVisualPartsModel *> models;
+};
+
+void QQuickVisualDataModelPartsMetaObject::propertyCreated(int, QMetaPropertyBuilder &prop)
+{
+    prop.setWritable(false);
+}
+
+QVariant QQuickVisualDataModelPartsMetaObject::initialValue(int id)
+{
+    QQuickVisualDataModelParts *parts = static_cast<QQuickVisualDataModelParts *>(object());
+    QQuickVisualPartsModel *m = new QQuickVisualPartsModel(
+            parts->model, QString::fromUtf8(name(id)), parts);
+    parts->models.append(m);
+    return QVariant::fromValue(static_cast<QObject *>(m));
+}
+
+QQuickVisualDataModelParts::QQuickVisualDataModelParts(QQuickVisualDataModel *parent)
+: QObject(parent), model(parent)
+{
+    new QQuickVisualDataModelPartsMetaObject(this);
+}
+
+//---------------------------------------------------------------------------
+
+class QQuickVisualDataModelCacheMetaType : public QDeclarativeRefCount
+{
+public:
+    QQuickVisualDataModelCacheMetaType(QV8Engine *engine, QQuickVisualDataModel *model, const QStringList &groupNames);
+    ~QQuickVisualDataModelCacheMetaType();
+
+    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<QQuickVisualDataModel> model;
+    const int groupCount;
+    const int memberPropertyOffset;
+    const int indexPropertyOffset;
+    QV8Engine * const v8Engine;
+    QMetaObject *metaObject;
+    const QStringList groupNames;
+    v8::Persistent<v8::Function> constructor;
+};
+
+class QQuickVisualDataModelCacheItem : public QV8ObjectResource
+{
+    V8_RESOURCE_TYPE(VisualDataItemType)
+public:
+    QQuickVisualDataModelCacheItem(QQuickVisualDataModelCacheMetaType *metaType)
+        : QV8ObjectResource(metaType->v8Engine)
+        , metaType(metaType)
+        , object(0)
+        , attached(0)
+        , objectRef(0)
+        , scriptRef(0)
+        , groups(0)
+    {
+        metaType->addref();
+    }
+
+    ~QQuickVisualDataModelCacheItem()
+    {
+        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();
+
+    QQuickVisualDataModelCacheMetaType * const metaType;
+    QDeclarativeGuard<QObject> object;
+    QQuickVisualDataModelAttached *attached;
+    int objectRef;
+    int scriptRef;
+    int groups;
+    int index[Compositor::MaximumGroupCount];
+};
+
+class QQuickVisualDataModelAttachedMetaObject : public QAbstractDynamicMetaObject
+{
+public:
+    QQuickVisualDataModelAttachedMetaObject(
+            QQuickVisualDataModelAttached *attached, QQuickVisualDataModelCacheMetaType *metaType);
+    ~QQuickVisualDataModelAttachedMetaObject();
+
+    int metaCall(QMetaObject::Call, int _id, void **);
+
+private:
+    QQuickVisualDataModelAttached *attached;
+    QQuickVisualDataModelCacheMetaType *metaType;
+};
+
+//---------------------------------------------------------------------------
+
+QHash<QObject*, QQuickVisualDataModelAttached*> QQuickVisualDataModelAttached::attachedProperties;
+
+/*!
+    \qmlclass VisualDataModel QQuickVisualDataModel
+    \inqmlmodule QtQuick 2
+    \ingroup qml-working-with-data
+    \brief The VisualDataModel encapsulates a model and delegate
+
+    A VisualDataModel encapsulates a model and the delegate that will
+    be instantiated for items in the model.
+
+    It is usually not necessary to create VisualDataModel elements.
+    However, it can be useful for manipulating and accessing the \l modelIndex
+    when a QAbstractItemModel subclass is used as the
+    model. Also, VisualDataModel is used together with \l Package to
+    provide delegates to multiple views.
+
+    The example below illustrates using a VisualDataModel with a ListView.
+
+    \snippet doc/src/snippets/declarative/visualdatamodel.qml 0
+*/
+
+QQuickVisualDataModelPrivate::QQuickVisualDataModelPrivate(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 QQuickVisualDataModelPrivate::connectModel(QQuickVisualAdaptorModel *model)
+{
+    Q_Q(QQuickVisualDataModel);
+
+    QObject::connect(model, SIGNAL(itemsInserted(int,int)), q, SLOT(_q_itemsInserted(int,int)));
+    QObject::connect(model, SIGNAL(itemsRemoved(int,int)), q, SLOT(_q_itemsRemoved(int,int)));
+    QObject::connect(model, SIGNAL(itemsMoved(int,int,int)), q, SLOT(_q_itemsMoved(int,int,int)));
+    QObject::connect(model, SIGNAL(itemsChanged(int,int)), q, SLOT(_q_itemsChanged(int,int)));
+    QObject::connect(model, SIGNAL(modelReset(int,int)), q, SLOT(_q_modelReset(int,int)));
+}
+
+void QQuickVisualDataModelPrivate::init()
+{
+    Q_Q(QQuickVisualDataModel);
+    m_compositor.setRemoveGroups(Compositor::GroupMask & ~Compositor::PersistedFlag);
+
+    m_adaptorModel = new QQuickVisualAdaptorModel;
+    QObject::connect(m_adaptorModel, SIGNAL(rootIndexChanged()), q, SIGNAL(rootIndexChanged()));
+
+    m_items = new QQuickVisualDataGroup(QStringLiteral("items"), q, Compositor::Default, q);
+    m_items->setDefaultInclude(true);
+    m_persistedItems = new QQuickVisualDataGroup(QStringLiteral("persistedItems"), q, Compositor::Persisted, q);
+    QQuickVisualDataGroupPrivate::get(m_items)->emitters.insert(this);
+}
+
+QQuickVisualDataModel::QQuickVisualDataModel()
+: QQuickVisualModel(*(new QQuickVisualDataModelPrivate(0)))
+{
+    Q_D(QQuickVisualDataModel);
+    d->init();
+}
+
+QQuickVisualDataModel::QQuickVisualDataModel(QDeclarativeContext *ctxt, QObject *parent)
+: QQuickVisualModel(*(new QQuickVisualDataModelPrivate(ctxt)), parent)
+{
+    Q_D(QQuickVisualDataModel);
+    d->init();
+}
+
+QQuickVisualDataModel::~QQuickVisualDataModel()
+{
+    Q_D(QQuickVisualDataModel);
+    foreach (QQuickVisualDataModelCacheItem *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 QQuickVisualDataModel::classBegin()
+{
+}
+
+void QQuickVisualDataModel::componentComplete()
+{
+    Q_D(QQuickVisualDataModel);
+    d->m_complete = true;
+
+    int defaultGroups = 0;
+    QStringList groupNames;
+    groupNames.append(QStringLiteral("items"));
+    groupNames.append(QStringLiteral("persistedItems"));
+    if (QQuickVisualDataGroupPrivate::get(d->m_items)->defaultInclude)
+        defaultGroups |= Compositor::DefaultFlag;
+    if (QQuickVisualDataGroupPrivate::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]) << QQuickVisualDataGroup::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);
+
+            QQuickVisualDataGroupPrivate *group = QQuickVisualDataGroupPrivate::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 QQuickVisualDataModelCacheMetaType(
+            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<QQuickVisualPartsModel *>(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));
+}
+
+/*!
+    \qmlproperty model QtQuick2::VisualDataModel::model
+    This property holds the model providing data for the VisualDataModel.
+
+    The model provides a set of data that is used to create the items
+    for a view.  For large or dynamic datasets the model is usually
+    provided by a C++ model object.  The C++ model object must be a \l
+    {QAbstractItemModel} subclass or a simple list.
+
+    Models can also be created directly in QML, using a \l{ListModel} or
+    \l{XmlListModel}.
+
+    \sa {qmlmodels}{Data Models}
+*/
+QVariant QQuickVisualDataModel::model() const
+{
+    Q_D(const QQuickVisualDataModel);
+    return d->m_adaptorModel->model();
+}
+
+void QQuickVisualDataModel::setModel(const QVariant &model)
+{
+    Q_D(QQuickVisualDataModel);
+    d->m_adaptorModel->setModel(model, d->m_context ? d->m_context->engine() : qmlEngine(this));
+    if (d->m_complete && d->m_adaptorModel->canFetchMore())
+        QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
+}
+
+/*!
+    \qmlproperty Component QtQuick2::VisualDataModel::delegate
+
+    The delegate provides a template defining each item instantiated by a view.
+    The index is exposed as an accessible \c index property.  Properties of the
+    model are also available depending upon the type of \l {qmlmodels}{Data Model}.
+*/
+QDeclarativeComponent *QQuickVisualDataModel::delegate() const
+{
+    Q_D(const QQuickVisualDataModel);
+    return d->m_delegate;
+}
+
+void QQuickVisualDataModel::setDelegate(QDeclarativeComponent *delegate)
+{
+    Q_D(QQuickVisualDataModel);
+    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_complete) {
+        for (int i = 1; i < d->m_groupCount; ++i) {
+            QQuickVisualDataGroupPrivate::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) {
+            QQuickVisualDataGroupPrivate::get(d->m_groups[i])->changeSet.insert(
+                    0, d->m_compositor.count(Compositor::Group(i)));
+        }
+    }
+    d->emitChanges();
+}
+
+/*!
+    \qmlproperty QModelIndex QtQuick2::VisualDataModel::rootIndex
+
+    QAbstractItemModel provides a hierarchical tree of data, whereas
+    QML only operates on list data.  \c rootIndex allows the children of
+    any node in a QAbstractItemModel to be provided by this model.
+
+    This property only affects models of type QAbstractItemModel that
+    are hierarchical (e.g, a tree model).
+
+    For example, here is a simple interactive file system browser.
+    When a directory name is clicked, the view's \c rootIndex is set to the
+    QModelIndex node of the clicked directory, thus updating the view to show
+    the new directory's contents.
+
+    \c main.cpp:
+    \snippet doc/src/snippets/declarative/visualdatamodel_rootindex/main.cpp 0
+
+    \c view.qml:
+    \snippet doc/src/snippets/declarative/visualdatamodel_rootindex/view.qml 0
+
+    If the \l model is a QAbstractItemModel subclass, the delegate can also
+    reference a \c hasModelChildren property (optionally qualified by a
+    \e model. prefix) that indicates whether the delegate's model item has
+    any child nodes.
+
+
+    \sa modelIndex(), parentModelIndex()
+*/
+QVariant QQuickVisualDataModel::rootIndex() const
+{
+    Q_D(const QQuickVisualDataModel);
+    return d->m_adaptorModel->rootIndex();
+}
+
+void QQuickVisualDataModel::setRootIndex(const QVariant &root)
+{
+    Q_D(QQuickVisualDataModel);
+    d->m_adaptorModel->setRootIndex(root);
+}
+
+/*!
+    \qmlmethod QModelIndex QtQuick2::VisualDataModel::modelIndex(int index)
+
+    QAbstractItemModel provides a hierarchical tree of data, whereas
+    QML only operates on list data.  This function assists in using
+    tree models in QML.
+
+    Returns a QModelIndex for the specified index.
+    This value can be assigned to rootIndex.
+
+    \sa rootIndex
+*/
+QVariant QQuickVisualDataModel::modelIndex(int idx) const
+{
+    Q_D(const QQuickVisualDataModel);
+    return d->m_adaptorModel->modelIndex(idx);
+}
+
+/*!
+    \qmlmethod QModelIndex QtQuick2::VisualDataModel::parentModelIndex()
+
+    QAbstractItemModel provides a hierarchical tree of data, whereas
+    QML only operates on list data.  This function assists in using
+    tree models in QML.
+
+    Returns a QModelIndex for the parent of the current rootIndex.
+    This value can be assigned to rootIndex.
+
+    \sa rootIndex
+*/
+QVariant QQuickVisualDataModel::parentModelIndex() const
+{
+    Q_D(const QQuickVisualDataModel);
+    return d->m_adaptorModel->parentModelIndex();
+}
+
+/*!
+    \qmlproperty int QtQuick2::VisualDataModel::count
+*/
+
+int QQuickVisualDataModel::count() const
+{
+    Q_D(const QQuickVisualDataModel);
+    if (!d->m_delegate)
+        return 0;
+    return d->m_compositor.count(d->m_compositorGroup);
+}
+
+void QQuickVisualDataModelPrivate::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();
+}
+
+QQuickVisualDataModel::ReleaseFlags QQuickVisualDataModelPrivate::release(QObject *object)
+{
+    QQuickVisualDataModel::ReleaseFlags stat = 0;
+    if (!object)
+        return stat;
+
+    int cacheIndex = cacheIndexOf(object);
+    if (cacheIndex != -1) {
+        QQuickVisualDataModelCacheItem *cacheItem = m_cache.at(cacheIndex);
+        if (cacheItem->releaseObject()) {
+            destroy(object);
+            cacheItem->object = 0;
+            stat |= QQuickVisualModel::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 |= QQuickVisualDataModel::Referenced;
+        }
+    }
+    return stat;
+}
+
+/*
+  Returns ReleaseStatus flags.
+*/
+
+QQuickVisualDataModel::ReleaseFlags QQuickVisualDataModel::release(QQuickItem *item)
+{
+    Q_D(QQuickVisualDataModel);
+    QQuickVisualModel::ReleaseFlags stat = d->release(item);
+    if (stat & Destroyed)
+        item->setParentItem(0);
+    return stat;
+}
+
+void QQuickVisualDataModelPrivate::group_append(
+        QDeclarativeListProperty<QQuickVisualDataGroup> *property, QQuickVisualDataGroup *group)
+{
+    QQuickVisualDataModelPrivate *d = static_cast<QQuickVisualDataModelPrivate *>(property->data);
+    if (d->m_complete)
+        return;
+    if (d->m_groupCount == 11) {
+        qmlInfo(d->q_func()) << QQuickVisualDataModel::tr("The maximum number of supported VisualDataGroups is 8");
+        return;
+    }
+    d->m_groups[d->m_groupCount] = group;
+    d->m_groupCount += 1;
+}
+
+int QQuickVisualDataModelPrivate::group_count(
+        QDeclarativeListProperty<QQuickVisualDataGroup> *property)
+{
+    QQuickVisualDataModelPrivate *d = static_cast<QQuickVisualDataModelPrivate *>(property->data);
+    return d->m_groupCount - 1;
+}
+
+QQuickVisualDataGroup *QQuickVisualDataModelPrivate::group_at(
+        QDeclarativeListProperty<QQuickVisualDataGroup> *property, int index)
+{
+    QQuickVisualDataModelPrivate *d = static_cast<QQuickVisualDataModelPrivate *>(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<QQuickVisualDataGroup> QQuickVisualDataModel::groups()
+{
+    Q_D(QQuickVisualDataModel);
+    return QDeclarativeListProperty<QQuickVisualDataGroup>(
+            this,
+            d,
+            QQuickVisualDataModelPrivate::group_append,
+            QQuickVisualDataModelPrivate::group_count,
+            QQuickVisualDataModelPrivate::group_at);
+}
+
+/*!
+    \qmlproperty VisualDataGroup QtQuick2::VisualDataModel::items
+
+    This property holds visual data model's default group to which all new items are added.
+*/
+
+QQuickVisualDataGroup *QQuickVisualDataModel::items()
+{
+    Q_D(QQuickVisualDataModel);
+    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.
+*/
+
+QQuickVisualDataGroup *QQuickVisualDataModel::persistedItems()
+{
+    Q_D(QQuickVisualDataModel);
+    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 QQuickVisualDataModel::filterGroup() const
+{
+    Q_D(const QQuickVisualDataModel);
+    return d->m_filterGroup;
+}
+
+void QQuickVisualDataModel::setFilterGroup(const QString &group)
+{
+    Q_D(QQuickVisualDataModel);
+
+    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 QQuickVisualDataModel::resetFilterGroup()
+{
+    setFilterGroup(QStringLiteral("items"));
+}
+
+void QQuickVisualDataModelPrivate::updateFilterGroup()
+{
+    Q_Q(QQuickVisualDataModel);
+    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;
+        }
+    }
+
+    QQuickVisualDataGroupPrivate::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 (QQuickVisualPartsModel *model, m_parts->models)
+                model->updateFilterGroup(m_compositorGroup, changeSet);
+        }
+    }
+}
+
+/*!
+    \qmlproperty object QtQuick2::VisualDataModel::parts
+
+    The \a parts property selects a VisualDataModel which creates
+    delegates from the part named.  This is used in conjunction with
+    the \l Package element.
+
+    For example, the code below selects a model which creates
+    delegates named \e list from a \l Package:
+
+    \code
+    VisualDataModel {
+        id: visualModel
+        delegate: Package {
+            Item { Package.name: "list" }
+        }
+        model: myModel
+    }
+
+    ListView {
+        width: 200; height:200
+        model: visualModel.parts.list
+    }
+    \endcode
+
+    \sa Package
+*/
+
+QObject *QQuickVisualDataModel::parts()
+{
+    Q_D(QQuickVisualDataModel);
+    if (!d->m_parts)
+        d->m_parts = new QQuickVisualDataModelParts(this);
+    return d->m_parts;
+}
+
+void QQuickVisualDataModelPrivate::emitCreatedPackage(Compositor::iterator at, QDeclarativePackage *package)
+{
+    for (int i = 1; i < m_groupCount; ++i)
+        QQuickVisualDataGroupPrivate::get(m_groups[i])->createdPackage(at.index[i], package);
+}
+
+void QQuickVisualDataModelPrivate::emitDestroyingPackage(QDeclarativePackage *package)
+{
+    for (int i = 1; i < m_groupCount; ++i)
+        QQuickVisualDataGroupPrivate::get(m_groups[i])->destroyingPackage(package);
+}
+
+QObject *QQuickVisualDataModelPrivate::object(Compositor::Group group, int index, bool complete, bool reference)
+{
+    Q_Q(QQuickVisualDataModel);
+
+    Compositor::iterator it = m_compositor.find(group, index);
+    QQuickVisualDataModelCacheItem *cacheItem = it->inCache() ? m_cache.at(it.cacheIndex) : 0;
+
+    if (!cacheItem) {
+        cacheItem = new QQuickVisualDataModelCacheItem(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(
+                creationContext ? creationContext : m_context.data());
+        QDeclarativeContext *ctxt = rootContext;
+        if (m_adaptorModel->flags() & QQuickVisualAdaptorModel::ProxiedObject) {
+            if (QQuickVisualAdaptorModelProxyInterface *proxy = qobject_cast<QQuickVisualAdaptorModelProxyInterface *>(data)) {
+                ctxt->setContextObject(proxy->proxiedObject());
+                ctxt = new QDeclarativeContext(ctxt, ctxt);
+            }
+        }
+
+        QDeclarative_setParent_noEvent(data, ctxt);
+        ctxt->setContextProperty(QLatin1String("model"), data);
+        ctxt->setContextObject(data);
+
+        m_completePending = false;
+        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 = QQuickVisualDataModelAttached::properties(cacheItem->object);
+            cacheItem->attached->m_cacheItem = cacheItem;
+            new QQuickVisualDataModelAttachedMetaObject(cacheItem->attached, m_cacheMetaType);
+            cacheItem->attached->emitChanges();
+
+            if (QDeclarativePackage *package = qobject_cast<QDeclarativePackage *>(cacheItem->object)) {
+                emitCreatedPackage(it, package);
+            } else if (!reference) {
+                if (QQuickItem *item = qobject_cast<QQuickItem *>(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_compositor.count(group) - 1 && m_adaptorModel->canFetchMore())
+        QCoreApplication::postEvent(q, new QEvent(QEvent::UpdateRequest));
+    if (reference)
+        cacheItem->referenceObject();
+    return cacheItem->object;
+}
+
+QQuickItem *QQuickVisualDataModel::item(int index, bool complete)
+{
+    Q_D(QQuickVisualDataModel);
+    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 (QQuickItem *item = qobject_cast<QQuickItem *>(object))
+        return item;
+    if (d->m_completePending)
+        completeItem();
+    d->release(object);
+    if (!d->m_delegateValidated) {
+        if (object)
+            qmlInfo(d->m_delegate) << QQuickVisualDataModel::tr("Delegate component must be Item type.");
+        d->m_delegateValidated = true;
+    }
+    return 0;
+}
+
+bool QQuickVisualDataModel::completePending() const
+{
+    Q_D(const QQuickVisualDataModel);
+    return d->m_completePending;
+}
+
+void QQuickVisualDataModel::completeItem()
+{
+    Q_D(QQuickVisualDataModel);
+    d->m_delegate->completeCreate();
+    d->m_completePending = false;
+}
+
+QString QQuickVisualDataModelPrivate::stringValue(Compositor::Group group, int index, const QString &name)
+{
+    Compositor::iterator it = m_compositor.find(group, index);
+    if (QQuickVisualAdaptorModel *model = it.list<QQuickVisualAdaptorModel>()) {
+        return model->stringValue(it.modelIndex(), name);
+    }
+    return QString();
+}
+
+QString QQuickVisualDataModel::stringValue(int index, const QString &name)
+{
+    Q_D(QQuickVisualDataModel);
+    return d->stringValue(d->m_compositorGroup, index, name);
+}
+
+int QQuickVisualDataModelPrivate::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 QQuickVisualDataModel::indexOf(QQuickItem *item, QObject *) const
+{
+    Q_D(const QQuickVisualDataModel);
+    const int cacheIndex = d->cacheIndexOf(item);
+    return cacheIndex != -1
+            ? d->m_cache.at(cacheIndex)->index[d->m_compositorGroup]
+            : -1;
+}
+
+void QQuickVisualDataModel::setWatchedRoles(QList<QByteArray> roles)
+{
+    Q_D(QQuickVisualDataModel);
+    d->m_adaptorModel->replaceWatchedRoles(d->watchedRoles, roles);
+    d->watchedRoles = roles;
+}
+
+void QQuickVisualDataModelPrivate::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 QQuickVisualDataModelPrivate::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 QQuickVisualDataModelPrivate::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 QQuickVisualDataModel::event(QEvent *e)
+{
+    Q_D(QQuickVisualDataModel);
+    if (e->type() == QEvent::UpdateRequest)
+        d->m_adaptorModel->fetchMore();
+    return QQuickVisualModel::event(e);
+}
+
+void QQuickVisualDataModelPrivate::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)
+        QQuickVisualDataGroupPrivate::get(m_groups[i])->changeSet.apply(translatedChanges.at(i));
+}
+
+void QQuickVisualDataModel::_q_itemsChanged(int index, int count)
+{
+    Q_D(QQuickVisualDataModel);
+    if (count <= 0)
+        return;
+    QVector<Compositor::Change> changes;
+    d->m_compositor.listItemsChanged(d->m_adaptorModel, index, count, &changes);
+    d->itemsChanged(changes);
+    d->emitChanges();
+}
+
+void QQuickVisualDataModelPrivate::itemsInserted(
+        const QVector<Compositor::Insert> &inserts,
+        QVarLengthArray<QVector<QDeclarativeChangeSet::Insert>, Compositor::MaximumGroupCount> *translatedInserts,
+        QHash<int, QList<QQuickVisualDataModelCacheItem *> > *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) {
+            QQuickVisualDataModelCacheItem *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<QQuickVisualDataModelCacheItem *> 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) {
+                QQuickVisualDataModelCacheItem *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) {
+        QQuickVisualDataModelCacheItem *cacheItem = m_cache.at(cacheIndex);
+        if (!cacheItem->groups)
+            continue;
+        for (int i = 1; i < m_groupCount; ++i)
+            cacheItem->index[i] += inserted[i];
+    }
+}
+
+void QQuickVisualDataModelPrivate::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)
+        QQuickVisualDataGroupPrivate::get(m_groups[i])->changeSet.apply(translatedInserts.at(i));
+}
+
+void QQuickVisualDataModel::_q_itemsInserted(int index, int count)
+{
+
+    Q_D(QQuickVisualDataModel);
+    if (count <= 0)
+        return;
+    QVector<Compositor::Insert> inserts;
+    d->m_compositor.listItemsInserted(d->m_adaptorModel, index, count, &inserts);
+    d->itemsInserted(inserts);
+    d->emitChanges();
+}
+
+void QQuickVisualDataModelPrivate::itemsRemoved(
+        const QVector<Compositor::Remove> &removes,
+        QVarLengthArray<QVector<QDeclarativeChangeSet::Remove>, Compositor::MaximumGroupCount> *translatedRemoves,
+        QHash<int, QList<QQuickVisualDataModelCacheItem *> > *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) {
+            QQuickVisualDataModelCacheItem *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 (!remove.inCache())
+            continue;
+
+        if (movedItems && remove.isMove()) {
+            movedItems->insert(remove.moveId, m_cache.mid(remove.cacheIndex, remove.count));
+            QList<QQuickVisualDataModelCacheItem *>::iterator begin = m_cache.begin() + remove.cacheIndex;
+            QList<QQuickVisualDataModelCacheItem *>::iterator end = begin + remove.count;
+            m_cache.erase(begin, end);
+        } else {
+            for (; cacheIndex < remove.cacheIndex + remove.count - removedCache; ++cacheIndex) {
+                QQuickVisualDataModelCacheItem *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 (QQuickItem *item = qobject_cast<QQuickItem *>(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;
+                }
+            }
+        }
+    }
+
+    for (; cacheIndex < m_cache.count(); ++cacheIndex) {
+        QQuickVisualDataModelCacheItem *cacheItem = m_cache.at(cacheIndex);
+        if (!cacheItem->groups)
+            continue;
+        for (int i = 1; i < m_groupCount; ++i)
+            cacheItem->index[i] -= removed[i];
+    }
+}
+
+void QQuickVisualDataModelPrivate::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)
+       QQuickVisualDataGroupPrivate::get(m_groups[i])->changeSet.apply(translatedRemoves.at(i));
+}
+
+void QQuickVisualDataModel::_q_itemsRemoved(int index, int count)
+{
+    Q_D(QQuickVisualDataModel);
+    if (count <= 0)
+        return;
+
+    QVector<Compositor::Remove> removes;
+    d->m_compositor.listItemsRemoved(d->m_adaptorModel, index, count, &removes);
+    d->itemsRemoved(removes);
+    d->emitChanges();
+}
+
+void QQuickVisualDataModelPrivate::itemsMoved(
+        const QVector<Compositor::Remove> &removes, const QVector<Compositor::Insert> &inserts)
+{
+    QHash<int, QList<QQuickVisualDataModelCacheItem *> > 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) {
+        QQuickVisualDataGroupPrivate::get(m_groups[i])->changeSet.apply(
+                    translatedRemoves.at(i),
+                    translatedInserts.at(i));
+    }
+}
+
+void QQuickVisualDataModel::_q_itemsMoved(int from, int to, int count)
+{
+    Q_D(QQuickVisualDataModel);
+    if (count <= 0)
+        return;
+
+    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();
+}
+
+template <typename T> v8::Local<v8::Array>
+QQuickVisualDataModelPrivate::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 QQuickVisualDataModelPrivate::emitModelUpdated(const QDeclarativeChangeSet &changeSet, bool reset)
+{
+    Q_Q(QQuickVisualDataModel);
+    emit q->modelUpdated(changeSet, reset);
+    if (changeSet.difference() != 0)
+        emit q->countChanged();
+}
+
+void QQuickVisualDataModelPrivate::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)
+        QQuickVisualDataGroupPrivate::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)
+        QQuickVisualDataGroupPrivate::get(m_groups[i])->emitModelUpdated(reset);
+
+    foreach (QQuickVisualDataModelCacheItem *cacheItem, m_cache) {
+        if (cacheItem->object)
+            cacheItem->attached->emitChanges();
+    }
+}
+
+void QQuickVisualDataModel::_q_modelReset(int oldCount, int newCount)
+{
+    Q_D(QQuickVisualDataModel);
+    if (!d->m_delegate)
+        return;
+
+    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();
+}
+
+QQuickVisualDataModelAttached *QQuickVisualDataModel::qmlAttachedProperties(QObject *obj)
+{
+    return QQuickVisualDataModelAttached::properties(obj);
+}
+
+//============================================================================
+
+QQuickVisualDataModelCacheMetaType::QQuickVisualDataModelCacheMetaType(
+        QV8Engine *engine, QQuickVisualDataModel *model, const QStringList &groupNames)
+    : model(model)
+    , groupCount(groupNames.count() + 1)
+    , memberPropertyOffset(QQuickVisualDataModelAttached::staticMetaObject.propertyCount())
+    , indexPropertyOffset(QQuickVisualDataModelAttached::staticMetaObject.propertyCount() + groupNames.count())
+    , v8Engine(engine)
+    , metaObject(0)
+    , groupNames(groupNames)
+{
+    QMetaObjectBuilder builder;
+    builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
+    builder.setClassName(QQuickVisualDataModelAttached::staticMetaObject.className());
+    builder.setSuperClass(&QQuickVisualDataModelAttached::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());
+}
+
+QQuickVisualDataModelCacheMetaType::~QQuickVisualDataModelCacheMetaType()
+{
+    qFree(metaObject);
+    qPersistentDispose(constructor);
+}
+
+int QQuickVisualDataModelCacheMetaType::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 QQuickVisualDataModelCacheMetaType::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> QQuickVisualDataModelCacheMetaType::get_model(
+        v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QQuickVisualDataModelCacheItem *cacheItem = v8_resource_cast<QQuickVisualDataModelCacheItem>(info.This());
+    if (!cacheItem)
+        V8THROW_ERROR("Not a valid VisualData object");
+    if (!cacheItem->metaType->model)
+        return v8::Undefined();
+    QObject *data = 0;
+
+    QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::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 (QQuickVisualAdaptorModel *list = it.list<QQuickVisualAdaptorModel>())
+                data = list->data(it.modelIndex());
+            break;
+        }
+    }
+    if (!data)
+        return v8::Undefined();
+    return cacheItem->engine->newQObject(data);
+}
+
+v8::Handle<v8::Value> QQuickVisualDataModelCacheMetaType::get_groups(
+        v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QQuickVisualDataModelCacheItem *cacheItem = v8_resource_cast<QQuickVisualDataModelCacheItem>(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 QQuickVisualDataModelCacheMetaType::set_groups(
+        v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+    QQuickVisualDataModelCacheItem *cacheItem = v8_resource_cast<QQuickVisualDataModelCacheItem>(info.This());
+    if (!cacheItem)
+        V8THROW_ERROR_SETTER("Not a valid VisualData object");
+
+    if (!cacheItem->metaType->model)
+        return;
+    QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::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> QQuickVisualDataModelCacheMetaType::get_member(
+        v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QQuickVisualDataModelCacheItem *cacheItem = v8_resource_cast<QQuickVisualDataModelCacheItem>(info.This());
+    if (!cacheItem)
+        V8THROW_ERROR("Not a valid VisualData object");
+
+    return v8::Boolean::New(cacheItem->groups & (1 << info.Data()->Int32Value()));
+}
+
+void QQuickVisualDataModelCacheMetaType::set_member(
+        v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
+{
+    QQuickVisualDataModelCacheItem *cacheItem = v8_resource_cast<QQuickVisualDataModelCacheItem>(info.This());
+    if (!cacheItem)
+        V8THROW_ERROR_SETTER("Not a valid VisualData object");
+
+    if (!cacheItem->metaType->model)
+        return;
+    QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::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> QQuickVisualDataModelCacheMetaType::get_index(
+        v8::Local<v8::String>, const v8::AccessorInfo &info)
+{
+    QQuickVisualDataModelCacheItem *cacheItem = v8_resource_cast<QQuickVisualDataModelCacheItem>(info.This());
+    if (!cacheItem)
+        V8THROW_ERROR("Not a valid VisualData object");
+
+    return v8::Integer::New(cacheItem->index[info.Data()->Int32Value()]);
+}
+
+
+//---------------------------------------------------------------------------
+
+void QQuickVisualDataModelCacheItem::Dispose()
+{
+    --scriptRef;
+    if (isReferenced())
+        return;
+
+    if (metaType->model) {
+        QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::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;
+}
+
+//---------------------------------------------------------------------------
+
+QQuickVisualDataModelAttachedMetaObject::QQuickVisualDataModelAttachedMetaObject(
+        QQuickVisualDataModelAttached *attached, QQuickVisualDataModelCacheMetaType *metaType)
+    : attached(attached)
+    , metaType(metaType)
+{
+    metaType->addref();
+    *static_cast<QMetaObject *>(this) = *metaType->metaObject;
+    QObjectPrivate::get(attached)->metaObject = this;
+}
+
+QQuickVisualDataModelAttachedMetaObject::~QQuickVisualDataModelAttachedMetaObject()
+{
+    metaType->release();
+}
+
+int QQuickVisualDataModelAttachedMetaObject::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])) {
+                QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::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.
+*/
+
+QQuickVisualDataModel *QQuickVisualDataModelAttached::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 QQuickVisualDataModelAttached::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 QQuickVisualDataModelAttached::setGroups(const QStringList &groups)
+{
+    if (!m_cacheItem)
+        return;
+
+    QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::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 QQuickVisualDataModelAttached::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 QQuickVisualDataGroupPrivate::setModel(QQuickVisualDataModel *m, Compositor::Group g)
+{
+    Q_ASSERT(!model);
+    model = m;
+    group = g;
+}
+
+void QQuickVisualDataGroupPrivate::emitChanges(QV8Engine *engine)
+{
+    Q_Q(QQuickVisualDataGroup);
+    static int idx = signalIndex("changed(QDeclarativeV8Handle,QDeclarativeV8Handle)");
+    if (isSignalConnected(idx)) {
+        v8::HandleScope handleScope;
+        v8::Context::Scope contextScope(engine->context());
+        v8::Local<v8::Array> removed  = QQuickVisualDataModelPrivate::buildChangeList(changeSet.removes());
+        v8::Local<v8::Array> inserted = QQuickVisualDataModelPrivate::buildChangeList(changeSet.inserts());
+        emit q->changed(
+                QDeclarativeV8Handle::fromHandle(removed), QDeclarativeV8Handle::fromHandle(inserted));
+    }
+    if (changeSet.difference() != 0)
+        emit q->countChanged();
+}
+
+void QQuickVisualDataGroupPrivate::emitModelUpdated(bool reset)
+{
+    for (QQuickVisualDataGroupEmitterList::iterator it = emitters.begin(); it != emitters.end(); ++it)
+        it->emitModelUpdated(changeSet, reset);
+    changeSet.clear();
+}
+
+void QQuickVisualDataGroupPrivate::createdPackage(int index, QDeclarativePackage *package)
+{
+    for (QQuickVisualDataGroupEmitterList::iterator it = emitters.begin(); it != emitters.end(); ++it)
+        it->createdPackage(index, package);
+}
+
+void QQuickVisualDataGroupPrivate::destroyingPackage(QDeclarativePackage *package)
+{
+    for (QQuickVisualDataGroupEmitterList::iterator it = emitters.begin(); it != emitters.end(); ++it)
+        it->destroyingPackage(package);
+}
+
+/*!
+    \qmlclass VisualDataGroup QQuickVisualDataGroup
+    \inqmlmodule QtQuick 2
+    \ingroup qml-working-with-data
+    \brief The VisualDataGroup encapsulates a filtered set of visual data items.
+
+*/
+
+QQuickVisualDataGroup::QQuickVisualDataGroup(QObject *parent)
+    : QObject(*new QQuickVisualDataGroupPrivate, parent)
+{
+}
+
+QQuickVisualDataGroup::QQuickVisualDataGroup(
+        const QString &name, QQuickVisualDataModel *model, int index, QObject *parent)
+    : QObject(*new QQuickVisualDataGroupPrivate, parent)
+{
+    Q_D(QQuickVisualDataGroup);
+    d->name = name;
+    d->setModel(model, Compositor::Group(index));
+}
+
+QQuickVisualDataGroup::~QQuickVisualDataGroup()
+{
+}
+
+/*!
+    \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 QQuickVisualDataGroup::name() const
+{
+    Q_D(const QQuickVisualDataGroup);
+    return d->name;
+}
+
+void QQuickVisualDataGroup::setName(const QString &name)
+{
+    Q_D(QQuickVisualDataGroup);
+    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 QQuickVisualDataGroup::count() const
+{
+    Q_D(const QQuickVisualDataGroup);
+    if (!d->model)
+        return 0;
+    return QQuickVisualDataModelPrivate::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 QQuickVisualDataGroup::defaultInclude() const
+{
+    Q_D(const QQuickVisualDataGroup);
+    return d->defaultInclude;
+}
+
+void QQuickVisualDataGroup::setDefaultInclude(bool include)
+{
+    Q_D(QQuickVisualDataGroup);
+    if (d->defaultInclude != include) {
+        d->defaultInclude = include;
+
+        if (d->model) {
+            if (include)
+                QQuickVisualDataModelPrivate::get(d->model)->m_compositor.setDefaultGroup(d->group);
+            else
+                QQuickVisualDataModelPrivate::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 QQuickVisualDataGroup::get(int index)
+{
+    Q_D(QQuickVisualDataGroup);
+    if (!d->model)
+        return QDeclarativeV8Handle::fromHandle(v8::Undefined());;
+
+    QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::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);
+    QQuickVisualDataModelCacheItem *cacheItem = it->inCache()
+            ? model->m_cache.at(it.cacheIndex)
+            : 0;
+
+    if (!cacheItem) {
+        cacheItem = new QQuickVisualDataModelCacheItem(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 *QQuickVisualDataGroup::create(int index)
+{
+    Q_D(QQuickVisualDataGroup);
+    if (!d->model)
+        return 0;
+
+    QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::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 QQuickVisualDataGroup::remove(QDeclarativeV8Function *args)
+{
+    Q_D(QQuickVisualDataGroup);
+    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();
+    }
+
+    QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::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 QQuickVisualDataGroupPrivate::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 = QQuickVisualDataModelPrivate::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 QQuickVisualDataGroup::addGroups(QDeclarativeV8Function *args)
+{
+    Q_D(QQuickVisualDataGroup);
+    int index = -1;
+    int count = 1;
+    int groups = 0;
+
+    if (!d->parseGroupArgs(args, &index, &count, &groups))
+        return;
+
+    QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::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 QQuickVisualDataGroup::removeGroups(QDeclarativeV8Function *args)
+{
+    Q_D(QQuickVisualDataGroup);
+    int index = -1;
+    int count = 1;
+    int groups = 0;
+
+    if (!d->parseGroupArgs(args, &index, &count, &groups))
+        return;
+
+    QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::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 QQuickVisualDataGroup::setGroups(QDeclarativeV8Function *args)
+{
+    Q_D(QQuickVisualDataGroup);
+    int index = -1;
+    int count = 1;
+    int groups = 0;
+
+    if (!d->parseGroupArgs(args, &index, &count, &groups))
+        return;
+
+    QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::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 QQuickVisualDataGroup::move(QDeclarativeV8Function *args)
+{
+    Q_D(QQuickVisualDataGroup);
+
+    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 (QQuickVisualDataGroup *group = qobject_cast<QQuickVisualDataGroup *>(args->engine()->toQObject(v))) {
+        QQuickVisualDataGroupPrivate *g_d = QQuickVisualDataGroupPrivate::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 (QQuickVisualDataGroup *group = qobject_cast<QQuickVisualDataGroup *>(args->engine()->toQObject(v))) {
+        QQuickVisualDataGroupPrivate *g_d = QQuickVisualDataGroupPrivate::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();
+    }
+
+    QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::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.
+*/
+
+//============================================================================
+
+QQuickVisualPartsModel::QQuickVisualPartsModel(QQuickVisualDataModel *model, const QString &part, QObject *parent)
+    : QQuickVisualModel(*new QObjectPrivate, parent)
+    , m_model(model)
+    , m_part(part)
+    , m_compositorGroup(Compositor::Cache)
+    , m_inheritGroup(true)
+{
+    QQuickVisualDataModelPrivate *d = QQuickVisualDataModelPrivate::get(m_model);
+    if (d->m_cacheMetaType) {
+        QQuickVisualDataGroupPrivate::get(d->m_groups[1])->emitters.insert(this);
+        m_compositorGroup = Compositor::Default;
+    } else {
+        d->m_pendingParts.insert(this);
+    }
+}
+
+QQuickVisualPartsModel::~QQuickVisualPartsModel()
+{
+}
+
+QString QQuickVisualPartsModel::filterGroup() const
+{
+    if (m_inheritGroup)
+        return m_model->filterGroup();
+    return m_filterGroup;
+}
+
+void QQuickVisualPartsModel::setFilterGroup(const QString &group)
+{
+    if (QQuickVisualDataModelPrivate::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 QQuickVisualPartsModel::resetFilterGroup()
+{
+    if (!m_inheritGroup) {
+        m_inheritGroup = true;
+        updateFilterGroup();
+        emit filterGroupChanged();
+    }
+}
+
+void QQuickVisualPartsModel::updateFilterGroup()
+{
+    QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(m_model);
+    if (!model->m_cacheMetaType)
+        return;
+
+    if (m_inheritGroup)
+        return;
+
+    QDeclarativeListCompositor::Group previousGroup = model->m_compositorGroup;
+    m_compositorGroup = Compositor::Default;
+    QQuickVisualDataGroupPrivate::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;
+        }
+    }
+
+    QQuickVisualDataGroupPrivate::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 QQuickVisualPartsModel::updateFilterGroup(
+        Compositor::Group group, const QDeclarativeChangeSet &changeSet)
+{
+    if (!m_inheritGroup)
+        return;
+
+    m_compositorGroup = group;
+    QQuickVisualDataGroupPrivate::get(QQuickVisualDataModelPrivate::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 QQuickVisualPartsModel::count() const
+{
+    QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(m_model);
+    return model->m_delegate
+            ? model->m_compositor.count(m_compositorGroup)
+            : 0;
+}
+
+bool QQuickVisualPartsModel::isValid() const
+{
+    return m_model->isValid();
+}
+
+QQuickItem *QQuickVisualPartsModel::item(int index, bool complete)
+{
+    QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(m_model);
+
+    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);
+        if (!part)
+            return 0;
+        if (QQuickItem *item = qobject_cast<QQuickItem *>(part)) {
+            m_packaged.insertMulti(item, package);
+            return item;
+        }
+    }
+
+    if (m_model->completePending())
+        m_model->completeItem();
+    model->release(object);
+    if (!model->m_delegateValidated) {
+        if (object)
+            qmlInfo(model->m_delegate) << tr("Delegate component must be Package type.");
+        model->m_delegateValidated = true;
+    }
+
+    return 0;
+}
+
+QQuickVisualModel::ReleaseFlags QQuickVisualPartsModel::release(QQuickItem *item)
+{
+    QQuickVisualModel::ReleaseFlags flags = 0;
+
+    QHash<QObject *, QDeclarativePackage *>::iterator it = m_packaged.find(item);
+    if (it != m_packaged.end()) {
+        QDeclarativePackage *package = *it;
+        QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(m_model);
+        flags = model->release(package);
+        m_packaged.erase(it);
+        if (!m_packaged.contains(item))
+            flags &= ~Referenced;
+        if (flags & Destroyed)
+            QQuickVisualDataModelPrivate::get(m_model)->emitDestroyingPackage(package);
+    }
+    return flags;
+}
+
+bool QQuickVisualPartsModel::completePending() const
+{
+    return m_model->completePending();
+}
+
+void QQuickVisualPartsModel::completeItem()
+{
+    m_model->completeItem();
+}
+
+QString QQuickVisualPartsModel::stringValue(int index, const QString &role)
+{
+    return QQuickVisualDataModelPrivate::get(m_model)->stringValue(m_compositorGroup, index, role);
+}
+
+void QQuickVisualPartsModel::setWatchedRoles(QList<QByteArray> roles)
+{
+    QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(m_model);
+    model->m_adaptorModel->replaceWatchedRoles(m_watchedRoles, roles);
+    m_watchedRoles = roles;
+}
+
+int QQuickVisualPartsModel::indexOf(QQuickItem *item, QObject *) const
+{
+    QHash<QObject *, QDeclarativePackage *>::const_iterator it = m_packaged.find(item);
+    if (it != m_packaged.end()) {
+        const QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(m_model);
+        const int cacheIndex = model->cacheIndexOf(*it);
+        return cacheIndex != -1
+                ? model->m_cache.at(cacheIndex)->index[m_compositorGroup]
+                : -1;
+    }
+    return -1;
+}
+
+void QQuickVisualPartsModel::createdPackage(int index, QDeclarativePackage *package)
+{
+    if (QQuickItem *item = qobject_cast<QQuickItem *>(package->part(m_part)))
+        emit createdItem(index, item);
+}
+
+void QQuickVisualPartsModel::destroyingPackage(QDeclarativePackage *package)
+{
+    if (QQuickItem *item = qobject_cast<QQuickItem *>(package->part(m_part))) {
+        Q_ASSERT(!m_packaged.contains(item));
+        emit destroyingItem(item);
+    }
+}
+
+void QQuickVisualPartsModel::emitModelUpdated(const QDeclarativeChangeSet &changeSet, bool reset)
+{
+    emit modelUpdated(changeSet, reset);
+    if (changeSet.difference() != 0)
+        emit countChanged();
+}
+
+
+QT_END_NAMESPACE
+
+#include <qquickvisualdatamodel.moc>
diff --git a/src/declarative/items/qquickvisualdatamodel_p.h b/src/declarative/items/qquickvisualdatamodel_p.h
new file mode 100644 (file)
index 0000000..3312551
--- /dev/null
@@ -0,0 +1,242 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
+/****************************************************************************
+**
+** 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 QQUICKVISUALDATAMODEL_P_H
+#define QQUICKVISUALDATAMODEL_P_H
+
+#include <private/qdeclarativelistcompositor_p.h>
+#include <private/qquickvisualitemmodel_p.h>
+
+
+#include <QtCore/qabstractitemmodel.h>
+#include <QtCore/qstringlist.h>
+
+#include <private/qv8engine_p.h>
+
+QT_BEGIN_HEADER
+
+Q_DECLARE_METATYPE(QModelIndex)
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+
+class QDeclarativeChangeSet;
+class QDeclarativeComponent;
+class QDeclarativePackage;
+class QDeclarativeV8Function;
+class QQuickVisualDataGroup;
+class QQuickVisualDataModelAttached;
+class QQuickVisualDataModelPrivate;
+
+
+class Q_DECLARATIVE_EXPORT QQuickVisualDataModel : public QQuickVisualModel, public QDeclarativeParserStatus
+{
+    Q_OBJECT
+    Q_DECLARE_PRIVATE(QQuickVisualDataModel)
+
+    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(QQuickVisualDataGroup *items READ items CONSTANT)
+    Q_PROPERTY(QQuickVisualDataGroup *persistedItems READ persistedItems CONSTANT)
+    Q_PROPERTY(QDeclarativeListProperty<QQuickVisualDataGroup> 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:
+    QQuickVisualDataModel();
+    QQuickVisualDataModel(QDeclarativeContext *, QObject *parent=0);
+    virtual ~QQuickVisualDataModel();
+
+    void classBegin();
+    void componentComplete();
+
+    QVariant model() const;
+    void setModel(const QVariant &);
+
+    QDeclarativeComponent *delegate() const;
+    void setDelegate(QDeclarativeComponent *);
+
+    QVariant rootIndex() const;
+    void setRootIndex(const QVariant &root);
+
+    Q_INVOKABLE QVariant modelIndex(int idx) const;
+    Q_INVOKABLE QVariant parentModelIndex() const;
+
+    int count() const;
+    bool isValid() const { return delegate() != 0; }
+    QQuickItem *item(int index, bool complete=true);
+    ReleaseFlags release(QQuickItem *item);
+    bool completePending() const;
+    void completeItem();
+    virtual QString stringValue(int index, const QString &role);
+    virtual void setWatchedRoles(QList<QByteArray> roles);
+
+    int indexOf(QQuickItem *item, QObject *objectContext) const;
+
+    QString filterGroup() const;
+    void setFilterGroup(const QString &group);
+    void resetFilterGroup();
+
+    QQuickVisualDataGroup *items();
+    QQuickVisualDataGroup *persistedItems();
+    QDeclarativeListProperty<QQuickVisualDataGroup> groups();
+    QObject *parts();
+
+    bool event(QEvent *);
+
+    static QQuickVisualDataModelAttached *qmlAttachedProperties(QObject *obj);
+
+Q_SIGNALS:
+    void filterGroupChanged();
+    void defaultGroupsChanged();
+    void rootIndexChanged();
+
+private Q_SLOTS:
+    void _q_itemsChanged(int index, int count);
+    void _q_itemsInserted(int index, int count);
+    void _q_itemsRemoved(int index, int count);
+    void _q_itemsMoved(int from, int to, int count);
+    void _q_modelReset(int oldCount, int newCount);
+private:
+    Q_DISABLE_COPY(QQuickVisualDataModel)
+};
+
+class QQuickVisualDataGroupPrivate;
+class Q_AUTOTEST_EXPORT QQuickVisualDataGroup : 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:
+    QQuickVisualDataGroup(QObject *parent = 0);
+    QQuickVisualDataGroup(const QString &name, QQuickVisualDataModel *model, int compositorType, QObject *parent = 0);
+    ~QQuickVisualDataGroup();
+
+    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(QQuickVisualDataGroup)
+};
+
+class QQuickVisualDataModelCacheItem;
+class QQuickVisualDataModelAttachedMetaObject;
+class QQuickVisualDataModelAttached : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(QQuickVisualDataModel *model READ model NOTIFY modelChanged)
+    Q_PROPERTY(QStringList groups READ groups WRITE setGroups NOTIFY groupsChanged)
+public:
+    QQuickVisualDataModelAttached(QObject *parent)
+        : QObject(parent)
+        , m_cacheItem(0)
+        , m_previousGroups(0)
+        , m_modelChanged(false)
+    {}
+    ~QQuickVisualDataModelAttached() { attachedProperties.remove(parent()); }
+
+    QQuickVisualDataModel *model() const;
+
+    QStringList groups() const;
+    void setGroups(const QStringList &groups);
+
+    void emitChanges();
+
+    static QQuickVisualDataModelAttached *properties(QObject *obj)
+    {
+        QQuickVisualDataModelAttached *rv = attachedProperties.value(obj);
+        if (!rv) {
+            rv = new QQuickVisualDataModelAttached(obj);
+            attachedProperties.insert(obj, rv);
+        }
+        return rv;
+    }
+
+Q_SIGNALS:
+    void modelChanged();
+    void groupsChanged();
+
+public:
+    QQuickVisualDataModelCacheItem *m_cacheItem;
+    int m_previousGroups;
+    int m_previousIndex[QDeclarativeListCompositor::MaximumGroupCount];
+    bool m_modelChanged;
+
+    static QHash<QObject*, QQuickVisualDataModelAttached*> attachedProperties;
+
+    friend class QQuickVisualDataModelAttachedMetaObject;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickVisualDataModel)
+QML_DECLARE_TYPEINFO(QQuickVisualDataModel, QML_HAS_ATTACHED_PROPERTIES)
+QML_DECLARE_TYPE(QQuickVisualDataGroup)
+
+QT_END_HEADER
+
+#endif // QQUICKVISUALDATAMODEL_P_H
diff --git a/src/declarative/items/qquickvisualitemmodel.cpp b/src/declarative/items/qquickvisualitemmodel.cpp
new file mode 100644 (file)
index 0000000..31d06f6
--- /dev/null
@@ -0,0 +1,243 @@
+/****************************************************************************
+**
+** 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 "qquickvisualitemmodel_p.h"
+#include "qquickitem.h"
+
+#include <QtCore/qcoreapplication.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+
+#include <private/qdeclarativechangeset_p.h>
+#include <private/qdeclarativeglobal_p.h>
+#include <private/qobject_p.h>
+
+#include <QtCore/qhash.h>
+#include <QtCore/qlist.h>
+
+QT_BEGIN_NAMESPACE
+
+QHash<QObject*, QQuickVisualItemModelAttached*> QQuickVisualItemModelAttached::attachedProperties;
+
+
+class QQuickVisualItemModelPrivate : public QObjectPrivate
+{
+    Q_DECLARE_PUBLIC(QQuickVisualItemModel)
+public:
+    QQuickVisualItemModelPrivate() : QObjectPrivate() {}
+
+    static void children_append(QDeclarativeListProperty<QQuickItem> *prop, QQuickItem *item) {
+        QDeclarative_setParent_noEvent(item, prop->object);
+        static_cast<QQuickVisualItemModelPrivate *>(prop->data)->children.append(Item(item));
+        static_cast<QQuickVisualItemModelPrivate *>(prop->data)->itemAppended();
+        static_cast<QQuickVisualItemModelPrivate *>(prop->data)->emitChildrenChanged();
+    }
+
+    static int children_count(QDeclarativeListProperty<QQuickItem> *prop) {
+        return static_cast<QQuickVisualItemModelPrivate *>(prop->data)->children.count();
+    }
+
+    static QQuickItem *children_at(QDeclarativeListProperty<QQuickItem> *prop, int index) {
+        return static_cast<QQuickVisualItemModelPrivate *>(prop->data)->children.at(index).item;
+    }
+
+    void itemAppended() {
+        Q_Q(QQuickVisualItemModel);
+        QQuickVisualItemModelAttached *attached = QQuickVisualItemModelAttached::properties(children.last().item);
+        attached->setIndex(children.count()-1);
+        QDeclarativeChangeSet changeSet;
+        changeSet.insert(children.count() - 1, 1);
+        emit q->modelUpdated(changeSet, false);
+        emit q->countChanged();
+    }
+
+    void emitChildrenChanged() {
+        Q_Q(QQuickVisualItemModel);
+        emit q->childrenChanged();
+    }
+
+    int indexOf(QQuickItem *item) const {
+        for (int i = 0; i < children.count(); ++i)
+            if (children.at(i).item == item)
+                return i;
+        return -1;
+    }
+
+    class Item {
+    public:
+        Item(QQuickItem *i) : item(i), ref(0) {}
+
+        void addRef() { ++ref; }
+        bool deref() { return --ref == 0; }
+
+        QQuickItem *item;
+        int ref;
+    };
+
+    QList<Item> children;
+};
+
+
+/*!
+    \qmlclass VisualItemModel QQuickVisualItemModel
+    \inqmlmodule QtQuick 2
+    \ingroup qml-working-with-data
+    \brief The VisualItemModel allows items to be provided to a view.
+
+    A VisualItemModel contains the visual items to be used in a view.
+    When a VisualItemModel is used in a view, the view does not require
+    a delegate since the VisualItemModel already contains the visual
+    delegate (items).
+
+    An item can determine its index within the
+    model via the \l{VisualItemModel::index}{index} attached property.
+
+    The example below places three colored rectangles in a ListView.
+    \code
+    import QtQuick 1.0
+
+    Rectangle {
+        VisualItemModel {
+            id: itemModel
+            Rectangle { height: 30; width: 80; color: "red" }
+            Rectangle { height: 30; width: 80; color: "green" }
+            Rectangle { height: 30; width: 80; color: "blue" }
+        }
+
+        ListView {
+            anchors.fill: parent
+            model: itemModel
+        }
+    }
+    \endcode
+
+    \image visualitemmodel.png
+
+    \sa {declarative/modelviews/visualitemmodel}{VisualItemModel example}
+*/
+QQuickVisualItemModel::QQuickVisualItemModel(QObject *parent)
+    : QQuickVisualModel(*(new QQuickVisualItemModelPrivate), parent)
+{
+}
+
+/*!
+    \qmlattachedproperty int QtQuick2::VisualItemModel::index
+    This attached property holds the index of this delegate's item within the model.
+
+    It is attached to each instance of the delegate.
+*/
+
+QDeclarativeListProperty<QQuickItem> QQuickVisualItemModel::children()
+{
+    Q_D(QQuickVisualItemModel);
+    return QDeclarativeListProperty<QQuickItem>(this, d, d->children_append,
+                                                      d->children_count, d->children_at);
+}
+
+/*!
+    \qmlproperty int QtQuick2::VisualItemModel::count
+
+    The number of items in the model.  This property is readonly.
+*/
+int QQuickVisualItemModel::count() const
+{
+    Q_D(const QQuickVisualItemModel);
+    return d->children.count();
+}
+
+bool QQuickVisualItemModel::isValid() const
+{
+    return true;
+}
+
+QQuickItem *QQuickVisualItemModel::item(int index, bool)
+{
+    Q_D(QQuickVisualItemModel);
+    QQuickVisualItemModelPrivate::Item &item = d->children[index];
+    item.addRef();
+    return item.item;
+}
+
+QQuickVisualModel::ReleaseFlags QQuickVisualItemModel::release(QQuickItem *item)
+{
+    Q_D(QQuickVisualItemModel);
+    int idx = d->indexOf(item);
+    if (idx >= 0) {
+        if (d->children[idx].deref()) {
+            // XXX todo - the original did item->scene()->removeItem().  Why?
+            item->setParentItem(0);
+            QDeclarative_setParent_noEvent(item, this);
+        }
+    }
+    return 0;
+}
+
+bool QQuickVisualItemModel::completePending() const
+{
+    return false;
+}
+
+void QQuickVisualItemModel::completeItem()
+{
+    // Nothing to do
+}
+
+QString QQuickVisualItemModel::stringValue(int index, const QString &name)
+{
+    Q_D(QQuickVisualItemModel);
+    if (index < 0 || index >= d->children.count())
+        return QString();
+    return QDeclarativeEngine::contextForObject(d->children.at(index).item)->contextProperty(name).toString();
+}
+
+int QQuickVisualItemModel::indexOf(QQuickItem *item, QObject *) const
+{
+    Q_D(const QQuickVisualItemModel);
+    return d->indexOf(item);
+}
+
+QQuickVisualItemModelAttached *QQuickVisualItemModel::qmlAttachedProperties(QObject *obj)
+{
+    return QQuickVisualItemModelAttached::properties(obj);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/items/qquickvisualitemmodel_p.h b/src/declarative/items/qquickvisualitemmodel_p.h
new file mode 100644 (file)
index 0000000..9fc3d57
--- /dev/null
@@ -0,0 +1,178 @@
+// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
+/****************************************************************************
+**
+** 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 QQUICKVISUALITEMMODEL_P_H
+#define QQUICKVISUALITEMMODEL_P_H
+
+#include <QtDeclarative/qdeclarative.h>
+#include <QtCore/qobject.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickItem;
+class QDeclarativeChangeSet;
+
+class Q_DECLARATIVE_EXPORT QQuickVisualModel : public QObject
+{
+    Q_OBJECT
+
+    Q_PROPERTY(int count READ count NOTIFY countChanged)
+
+public:
+    virtual ~QQuickVisualModel() {}
+
+    enum ReleaseFlag { Referenced = 0x01, Destroyed = 0x02 };
+    Q_DECLARE_FLAGS(ReleaseFlags, ReleaseFlag)
+
+    virtual int count() const = 0;
+    virtual bool isValid() const = 0;
+    virtual QQuickItem *item(int index, bool complete=true) = 0;
+    virtual ReleaseFlags release(QQuickItem *item) = 0;
+    virtual bool completePending() const = 0;
+    virtual void completeItem() = 0;
+    virtual QString stringValue(int, const QString &) = 0;
+    virtual void setWatchedRoles(QList<QByteArray> roles) = 0;
+
+    virtual int indexOf(QQuickItem *item, QObject *objectContext) const = 0;
+
+Q_SIGNALS:
+    void countChanged();
+    void modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset);
+    void createdItem(int index, QQuickItem *item);
+    void destroyingItem(QQuickItem *item);
+
+protected:
+    QQuickVisualModel(QObjectPrivate &dd, QObject *parent = 0)
+        : QObject(dd, parent) {}
+
+private:
+    Q_DISABLE_COPY(QQuickVisualModel)
+};
+
+class QQuickVisualItemModelAttached;
+class QQuickVisualItemModelPrivate;
+class Q_DECLARATIVE_EXPORT QQuickVisualItemModel : public QQuickVisualModel
+{
+    Q_OBJECT
+    Q_DECLARE_PRIVATE(QQuickVisualItemModel)
+
+    Q_PROPERTY(QDeclarativeListProperty<QQuickItem> children READ children NOTIFY childrenChanged DESIGNABLE false)
+    Q_CLASSINFO("DefaultProperty", "children")
+
+public:
+    QQuickVisualItemModel(QObject *parent=0);
+    virtual ~QQuickVisualItemModel() {}
+
+    virtual int count() const;
+    virtual bool isValid() const;
+    virtual QQuickItem *item(int index, bool complete=true);
+    virtual ReleaseFlags release(QQuickItem *item);
+    virtual bool completePending() const;
+    virtual void completeItem();
+    virtual QString stringValue(int index, const QString &role);
+    virtual void setWatchedRoles(QList<QByteArray>) {}
+
+    virtual int indexOf(QQuickItem *item, QObject *objectContext) const;
+
+    QDeclarativeListProperty<QQuickItem> children();
+
+    static QQuickVisualItemModelAttached *qmlAttachedProperties(QObject *obj);
+
+Q_SIGNALS:
+    void childrenChanged();
+
+private:
+    Q_DISABLE_COPY(QQuickVisualItemModel)
+};
+
+class QQuickVisualItemModelAttached : public QObject
+{
+    Q_OBJECT
+
+public:
+    QQuickVisualItemModelAttached(QObject *parent)
+        : QObject(parent), m_index(0) {}
+    ~QQuickVisualItemModelAttached() {
+        attachedProperties.remove(parent());
+    }
+
+    Q_PROPERTY(int index READ index NOTIFY indexChanged)
+    int index() const { return m_index; }
+    void setIndex(int idx) {
+        if (m_index != idx) {
+            m_index = idx;
+            emit indexChanged();
+        }
+    }
+
+    static QQuickVisualItemModelAttached *properties(QObject *obj) {
+        QQuickVisualItemModelAttached *rv = attachedProperties.value(obj);
+        if (!rv) {
+            rv = new QQuickVisualItemModelAttached(obj);
+            attachedProperties.insert(obj, rv);
+        }
+        return rv;
+    }
+
+Q_SIGNALS:
+    void indexChanged();
+
+public:
+    int m_index;
+
+    static QHash<QObject*, QQuickVisualItemModelAttached*> attachedProperties;
+};
+
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickVisualModel)
+QML_DECLARE_TYPE(QQuickVisualItemModel)
+QML_DECLARE_TYPEINFO(QQuickVisualItemModel, QML_HAS_ATTACHED_PROPERTIES)
+
+QT_END_HEADER
+
+#endif // QQUICKVISUALITEMMODEL_P_H
diff --git a/src/declarative/items/qsganchors.cpp b/src/declarative/items/qsganchors.cpp
deleted file mode 100644 (file)
index 67ca031..0000000
+++ /dev/null
@@ -1,1110 +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 "qsganchors_p_p.h"
-
-#include "qsgitem.h"
-#include "qsgitem_p.h"
-
-#include <qdeclarativeinfo.h>
-
-QT_BEGIN_NAMESPACE
-
-//TODO: should we cache relationships, so we don't have to check each time (parent-child or sibling)?
-//TODO: support non-parent, non-sibling (need to find lowest common ancestor)
-
-static qreal hcenter(QSGItem *item)
-{
-    qreal width = item->width();
-    int iw = width;
-    if (iw % 2)
-        return (width + 1) / 2;
-    else
-        return width / 2;
-}
-
-static qreal vcenter(QSGItem *item)
-{
-    qreal height = item->height();
-    int ih = height;
-    if (ih % 2)
-        return (height + 1) / 2;
-    else
-        return height / 2;
-}
-
-//### const item?
-//local position
-static qreal position(QSGItem *item, QSGAnchorLine::AnchorLine anchorLine)
-{
-    qreal ret = 0.0;
-    switch (anchorLine) {
-    case QSGAnchorLine::Left:
-        ret = item->x();
-        break;
-    case QSGAnchorLine::Right:
-        ret = item->x() + item->width();
-        break;
-    case QSGAnchorLine::Top:
-        ret = item->y();
-        break;
-    case QSGAnchorLine::Bottom:
-        ret = item->y() + item->height();
-        break;
-    case QSGAnchorLine::HCenter:
-        ret = item->x() + hcenter(item);
-        break;
-    case QSGAnchorLine::VCenter:
-        ret = item->y() + vcenter(item);
-        break;
-    case QSGAnchorLine::Baseline:
-        ret = item->y() + item->baselineOffset();
-        break;
-    default:
-        break;
-    }
-
-    return ret;
-}
-
-//position when origin is 0,0
-static qreal adjustedPosition(QSGItem *item, QSGAnchorLine::AnchorLine anchorLine)
-{
-    qreal ret = 0.0;
-    switch (anchorLine) {
-    case QSGAnchorLine::Left:
-        ret = 0.0;
-        break;
-    case QSGAnchorLine::Right:
-        ret = item->width();
-        break;
-    case QSGAnchorLine::Top:
-        ret = 0.0;
-        break;
-    case QSGAnchorLine::Bottom:
-        ret = item->height();
-        break;
-    case QSGAnchorLine::HCenter:
-        ret = hcenter(item);
-        break;
-    case QSGAnchorLine::VCenter:
-        ret = vcenter(item);
-        break;
-    case QSGAnchorLine::Baseline:
-        ret = item->baselineOffset();
-        break;
-    default:
-        break;
-    }
-
-    return ret;
-}
-
-QSGAnchors::QSGAnchors(QSGItem *item, QObject *parent)
-: QObject(*new QSGAnchorsPrivate(item), parent)
-{
-}
-
-QSGAnchors::~QSGAnchors()
-{
-    Q_D(QSGAnchors);
-    d->remDepend(d->fill);
-    d->remDepend(d->centerIn);
-    d->remDepend(d->left.item);
-    d->remDepend(d->right.item);
-    d->remDepend(d->top.item);
-    d->remDepend(d->bottom.item);
-    d->remDepend(d->vCenter.item);
-    d->remDepend(d->hCenter.item);
-    d->remDepend(d->baseline.item);
-}
-
-void QSGAnchorsPrivate::fillChanged()
-{
-    Q_Q(QSGAnchors);
-    if (!fill || !isItemComplete())
-        return;
-
-    if (updatingFill < 2) {
-        ++updatingFill;
-
-        qreal horizontalMargin = q->mirrored() ? rightMargin : leftMargin;
-
-        if (fill == item->parentItem()) {                         //child-parent
-            setItemPos(QPointF(horizontalMargin, topMargin));
-        } else if (fill->parentItem() == item->parentItem()) {   //siblings
-            setItemPos(QPointF(fill->x()+horizontalMargin, fill->y()+topMargin));
-        }
-        setItemSize(QSizeF(fill->width()-leftMargin-rightMargin, fill->height()-topMargin-bottomMargin));
-
-        --updatingFill;
-    } else {
-        // ### Make this certain :)
-        qmlInfo(item) << QSGAnchors::tr("Possible anchor loop detected on fill.");
-    }
-
-}
-
-void QSGAnchorsPrivate::centerInChanged()
-{
-    Q_Q(QSGAnchors);
-    if (!centerIn || fill || !isItemComplete())
-        return;
-
-    if (updatingCenterIn < 2) {
-        ++updatingCenterIn;
-
-        qreal effectiveHCenterOffset = q->mirrored() ? -hCenterOffset : hCenterOffset;
-        if (centerIn == item->parentItem()) {
-            QPointF p(hcenter(item->parentItem()) - hcenter(item) + effectiveHCenterOffset,
-                      vcenter(item->parentItem()) - vcenter(item) + vCenterOffset);
-            setItemPos(p);
-
-        } else if (centerIn->parentItem() == item->parentItem()) {
-            QPointF p(centerIn->x() + hcenter(centerIn) - hcenter(item) + effectiveHCenterOffset,
-                      centerIn->y() + vcenter(centerIn) - vcenter(item) + vCenterOffset);
-            setItemPos(p);
-        }
-
-        --updatingCenterIn;
-    } else {
-        // ### Make this certain :)
-        qmlInfo(item) << QSGAnchors::tr("Possible anchor loop detected on centerIn.");
-    }
-}
-
-void QSGAnchorsPrivate::clearItem(QSGItem *item)
-{
-    if (!item)
-        return;
-    if (fill == item)
-        fill = 0;
-    if (centerIn == item)
-        centerIn = 0;
-    if (left.item == item) {
-        left.item = 0;
-        usedAnchors &= ~QSGAnchors::LeftAnchor;
-    }
-    if (right.item == item) {
-        right.item = 0;
-        usedAnchors &= ~QSGAnchors::RightAnchor;
-    }
-    if (top.item == item) {
-        top.item = 0;
-        usedAnchors &= ~QSGAnchors::TopAnchor;
-    }
-    if (bottom.item == item) {
-        bottom.item = 0;
-        usedAnchors &= ~QSGAnchors::BottomAnchor;
-    }
-    if (vCenter.item == item) {
-        vCenter.item = 0;
-        usedAnchors &= ~QSGAnchors::VCenterAnchor;
-    }
-    if (hCenter.item == item) {
-        hCenter.item = 0;
-        usedAnchors &= ~QSGAnchors::HCenterAnchor;
-    }
-    if (baseline.item == item) {
-        baseline.item = 0;
-        usedAnchors &= ~QSGAnchors::BaselineAnchor;
-    }
-}
-
-void QSGAnchorsPrivate::addDepend(QSGItem *item)
-{
-    if (!item)
-        return;
-
-    QSGItemPrivate *p = QSGItemPrivate::get(item);
-    p->addItemChangeListener(this, QSGItemPrivate::Geometry);
-}
-
-void QSGAnchorsPrivate::remDepend(QSGItem *item)
-{
-    if (!item)
-        return;
-
-    QSGItemPrivate *p = QSGItemPrivate::get(item);
-    p->removeItemChangeListener(this, QSGItemPrivate::Geometry);
-}
-
-bool QSGAnchors::mirrored()
-{
-    Q_D(QSGAnchors);
-    return QSGItemPrivate::get(d->item)->effectiveLayoutMirror;
-}
-
-bool QSGAnchorsPrivate::isItemComplete() const
-{
-    return componentComplete;
-}
-
-void QSGAnchors::classBegin()
-{
-    Q_D(QSGAnchors);
-    d->componentComplete = false;
-}
-
-void QSGAnchors::componentComplete()
-{
-    Q_D(QSGAnchors);
-    d->componentComplete = true;
-}
-
-void QSGAnchorsPrivate::setItemHeight(qreal v)
-{
-    updatingMe = true;
-    item->setHeight(v);
-    updatingMe = false;
-}
-
-void QSGAnchorsPrivate::setItemWidth(qreal v)
-{
-    updatingMe = true;
-    item->setWidth(v);
-    updatingMe = false;
-}
-
-void QSGAnchorsPrivate::setItemX(qreal v)
-{
-    updatingMe = true;
-    item->setX(v);
-    updatingMe = false;
-}
-
-void QSGAnchorsPrivate::setItemY(qreal v)
-{
-    updatingMe = true;
-    item->setY(v);
-    updatingMe = false;
-}
-
-void QSGAnchorsPrivate::setItemPos(const QPointF &v)
-{
-    updatingMe = true;
-    item->setPos(v);
-    updatingMe = false;
-}
-
-void QSGAnchorsPrivate::setItemSize(const QSizeF &v)
-{
-    updatingMe = true;
-    item->setSize(v);
-    updatingMe = false;
-}
-
-void QSGAnchorsPrivate::updateMe()
-{
-    if (updatingMe) {
-        updatingMe = false;
-        return;
-    }
-
-    fillChanged();
-    centerInChanged();
-    updateHorizontalAnchors();
-    updateVerticalAnchors();
-}
-
-void QSGAnchorsPrivate::updateOnComplete()
-{
-    fillChanged();
-    centerInChanged();
-    updateHorizontalAnchors();
-    updateVerticalAnchors();
-}
-
-void QSGAnchorsPrivate::itemGeometryChanged(QSGItem *, const QRectF &newG, const QRectF &oldG)
-{
-    fillChanged();
-    centerInChanged();
-    if (newG.x() != oldG.x() || newG.width() != oldG.width())
-        updateHorizontalAnchors();
-    if (newG.y() != oldG.y() || newG.height() != oldG.height())
-        updateVerticalAnchors();
-}
-
-QSGItem *QSGAnchors::fill() const
-{
-    Q_D(const QSGAnchors);
-    return d->fill;
-}
-
-void QSGAnchors::setFill(QSGItem *f)
-{
-    Q_D(QSGAnchors);
-    if (d->fill == f)
-        return;
-
-    if (!f) {
-        d->remDepend(d->fill);
-        d->fill = f;
-        emit fillChanged();
-        return;
-    }
-    if (f != d->item->parentItem() && f->parentItem() != d->item->parentItem()){
-        qmlInfo(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling.");
-        return;
-    }
-    d->remDepend(d->fill);
-    d->fill = f;
-    d->addDepend(d->fill);
-    emit fillChanged();
-    d->fillChanged();
-}
-
-void QSGAnchors::resetFill()
-{
-    setFill(0);
-}
-
-QSGItem *QSGAnchors::centerIn() const
-{
-    Q_D(const QSGAnchors);
-    return d->centerIn;
-}
-
-void QSGAnchors::setCenterIn(QSGItem* c)
-{
-    Q_D(QSGAnchors);
-    if (d->centerIn == c)
-        return;
-
-    if (!c) {
-        d->remDepend(d->centerIn);
-        d->centerIn = c;
-        emit centerInChanged();
-        return;
-    }
-    if (c != d->item->parentItem() && c->parentItem() != d->item->parentItem()){
-        qmlInfo(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling.");
-        return;
-    }
-
-    d->remDepend(d->centerIn);
-    d->centerIn = c;
-    d->addDepend(d->centerIn);
-    emit centerInChanged();
-    d->centerInChanged();
-}
-
-void QSGAnchors::resetCenterIn()
-{
-    setCenterIn(0);
-}
-
-bool QSGAnchorsPrivate::calcStretch(const QSGAnchorLine &edge1,
-                                    const QSGAnchorLine &edge2,
-                                    qreal offset1,
-                                    qreal offset2,
-                                    QSGAnchorLine::AnchorLine line,
-                                    qreal &stretch)
-{
-    bool edge1IsParent = (edge1.item == item->parentItem());
-    bool edge2IsParent = (edge2.item == item->parentItem());
-    bool edge1IsSibling = (edge1.item->parentItem() == item->parentItem());
-    bool edge2IsSibling = (edge2.item->parentItem() == item->parentItem());
-
-    bool invalid = false;
-    if ((edge2IsParent && edge1IsParent) || (edge2IsSibling && edge1IsSibling)) {
-        stretch = (position(edge2.item, edge2.anchorLine) + offset2)
-                    - (position(edge1.item, edge1.anchorLine) + offset1);
-    } else if (edge2IsParent && edge1IsSibling) {
-        stretch = (position(edge2.item, edge2.anchorLine) + offset2)
-                    - (position(item->parentItem(), line)
-                    + position(edge1.item, edge1.anchorLine) + offset1);
-    } else if (edge2IsSibling && edge1IsParent) {
-        stretch = (position(item->parentItem(), line) + position(edge2.item, edge2.anchorLine) + offset2)
-                    - (position(edge1.item, edge1.anchorLine) + offset1);
-    } else
-        invalid = true;
-
-    return invalid;
-}
-
-void QSGAnchorsPrivate::updateVerticalAnchors()
-{
-    if (fill || centerIn || !isItemComplete())
-        return;
-
-    if (updatingVerticalAnchor < 2) {
-        ++updatingVerticalAnchor;
-        if (usedAnchors & QSGAnchors::TopAnchor) {
-            //Handle stretching
-            bool invalid = true;
-            qreal height = 0.0;
-            if (usedAnchors & QSGAnchors::BottomAnchor) {
-                invalid = calcStretch(top, bottom, topMargin, -bottomMargin, QSGAnchorLine::Top, height);
-            } else if (usedAnchors & QSGAnchors::VCenterAnchor) {
-                invalid = calcStretch(top, vCenter, topMargin, vCenterOffset, QSGAnchorLine::Top, height);
-                height *= 2;
-            }
-            if (!invalid)
-                setItemHeight(height);
-
-            //Handle top
-            if (top.item == item->parentItem()) {
-                setItemY(adjustedPosition(top.item, top.anchorLine) + topMargin);
-            } else if (top.item->parentItem() == item->parentItem()) {
-                setItemY(position(top.item, top.anchorLine) + topMargin);
-            }
-        } else if (usedAnchors & QSGAnchors::BottomAnchor) {
-            //Handle stretching (top + bottom case is handled above)
-            if (usedAnchors & QSGAnchors::VCenterAnchor) {
-                qreal height = 0.0;
-                bool invalid = calcStretch(vCenter, bottom, vCenterOffset, -bottomMargin,
-                                              QSGAnchorLine::Top, height);
-                if (!invalid)
-                    setItemHeight(height*2);
-            }
-
-            //Handle bottom
-            if (bottom.item == item->parentItem()) {
-                setItemY(adjustedPosition(bottom.item, bottom.anchorLine) - item->height() - bottomMargin);
-            } else if (bottom.item->parentItem() == item->parentItem()) {
-                setItemY(position(bottom.item, bottom.anchorLine) - item->height() - bottomMargin);
-            }
-        } else if (usedAnchors & QSGAnchors::VCenterAnchor) {
-            //(stetching handled above)
-
-            //Handle vCenter
-            if (vCenter.item == item->parentItem()) {
-                setItemY(adjustedPosition(vCenter.item, vCenter.anchorLine)
-                              - vcenter(item) + vCenterOffset);
-            } else if (vCenter.item->parentItem() == item->parentItem()) {
-                setItemY(position(vCenter.item, vCenter.anchorLine) - vcenter(item) + vCenterOffset);
-            }
-        } else if (usedAnchors & QSGAnchors::BaselineAnchor) {
-            //Handle baseline
-            if (baseline.item == item->parentItem()) {
-                setItemY(adjustedPosition(baseline.item, baseline.anchorLine) - item->baselineOffset() + baselineOffset);
-            } else if (baseline.item->parentItem() == item->parentItem()) {
-                setItemY(position(baseline.item, baseline.anchorLine) - item->baselineOffset() + baselineOffset);
-            }
-        }
-        --updatingVerticalAnchor;
-    } else {
-        // ### Make this certain :)
-        qmlInfo(item) << QSGAnchors::tr("Possible anchor loop detected on vertical anchor.");
-    }
-}
-
-inline QSGAnchorLine::AnchorLine reverseAnchorLine(QSGAnchorLine::AnchorLine anchorLine)
-{
-    if (anchorLine == QSGAnchorLine::Left) {
-        return QSGAnchorLine::Right;
-    } else if (anchorLine == QSGAnchorLine::Right) {
-        return QSGAnchorLine::Left;
-    } else {
-        return anchorLine;
-    }
-}
-
-void QSGAnchorsPrivate::updateHorizontalAnchors()
-{
-    Q_Q(QSGAnchors);
-    if (fill || centerIn || !isItemComplete())
-        return;
-
-    if (updatingHorizontalAnchor < 3) {
-        ++updatingHorizontalAnchor;
-        qreal effectiveRightMargin, effectiveLeftMargin, effectiveHorizontalCenterOffset;
-        QSGAnchorLine effectiveLeft, effectiveRight, effectiveHorizontalCenter;
-        QSGAnchors::Anchor effectiveLeftAnchor, effectiveRightAnchor;
-        if (q->mirrored()) {
-            effectiveLeftAnchor = QSGAnchors::RightAnchor;
-            effectiveRightAnchor = QSGAnchors::LeftAnchor;
-            effectiveLeft.item = right.item;
-            effectiveLeft.anchorLine = reverseAnchorLine(right.anchorLine);
-            effectiveRight.item = left.item;
-            effectiveRight.anchorLine = reverseAnchorLine(left.anchorLine);
-            effectiveHorizontalCenter.item = hCenter.item;
-            effectiveHorizontalCenter.anchorLine = reverseAnchorLine(hCenter.anchorLine);
-            effectiveLeftMargin = rightMargin;
-            effectiveRightMargin = leftMargin;
-            effectiveHorizontalCenterOffset = -hCenterOffset;
-        } else {
-            effectiveLeftAnchor = QSGAnchors::LeftAnchor;
-            effectiveRightAnchor = QSGAnchors::RightAnchor;
-            effectiveLeft = left;
-            effectiveRight = right;
-            effectiveHorizontalCenter = hCenter;
-            effectiveLeftMargin = leftMargin;
-            effectiveRightMargin = rightMargin;
-            effectiveHorizontalCenterOffset = hCenterOffset;
-        }
-
-        if (usedAnchors & effectiveLeftAnchor) {
-            //Handle stretching
-            bool invalid = true;
-            qreal width = 0.0;
-            if (usedAnchors & effectiveRightAnchor) {
-                invalid = calcStretch(effectiveLeft, effectiveRight, effectiveLeftMargin, -effectiveRightMargin, QSGAnchorLine::Left, width);
-            } else if (usedAnchors & QSGAnchors::HCenterAnchor) {
-                invalid = calcStretch(effectiveLeft, effectiveHorizontalCenter, effectiveLeftMargin, effectiveHorizontalCenterOffset, QSGAnchorLine::Left, width);
-                width *= 2;
-            }
-            if (!invalid)
-                setItemWidth(width);
-
-            //Handle left
-            if (effectiveLeft.item == item->parentItem()) {
-                setItemX(adjustedPosition(effectiveLeft.item, effectiveLeft.anchorLine) + effectiveLeftMargin);
-            } else if (effectiveLeft.item->parentItem() == item->parentItem()) {
-                setItemX(position(effectiveLeft.item, effectiveLeft.anchorLine) + effectiveLeftMargin);
-            }
-        } else if (usedAnchors & effectiveRightAnchor) {
-            //Handle stretching (left + right case is handled in updateLeftAnchor)
-            if (usedAnchors & QSGAnchors::HCenterAnchor) {
-                qreal width = 0.0;
-                bool invalid = calcStretch(effectiveHorizontalCenter, effectiveRight, effectiveHorizontalCenterOffset, -effectiveRightMargin,
-                                              QSGAnchorLine::Left, width);
-                if (!invalid)
-                    setItemWidth(width*2);
-            }
-
-            //Handle right
-            if (effectiveRight.item == item->parentItem()) {
-                setItemX(adjustedPosition(effectiveRight.item, effectiveRight.anchorLine) - item->width() - effectiveRightMargin);
-            } else if (effectiveRight.item->parentItem() == item->parentItem()) {
-                setItemX(position(effectiveRight.item, effectiveRight.anchorLine) - item->width() - effectiveRightMargin);
-            }
-        } else if (usedAnchors & QSGAnchors::HCenterAnchor) {
-            //Handle hCenter
-            if (effectiveHorizontalCenter.item == item->parentItem()) {
-                setItemX(adjustedPosition(effectiveHorizontalCenter.item, effectiveHorizontalCenter.anchorLine) - hcenter(item) + effectiveHorizontalCenterOffset);
-            } else if (effectiveHorizontalCenter.item->parentItem() == item->parentItem()) {
-                setItemX(position(effectiveHorizontalCenter.item, effectiveHorizontalCenter.anchorLine) - hcenter(item) + effectiveHorizontalCenterOffset);
-            }
-        }
-        --updatingHorizontalAnchor;
-    } else {
-        // ### Make this certain :)
-        qmlInfo(item) << QSGAnchors::tr("Possible anchor loop detected on horizontal anchor.");
-    }
-}
-
-QSGAnchorLine QSGAnchors::top() const
-{
-    Q_D(const QSGAnchors);
-    return d->top;
-}
-
-void QSGAnchors::setTop(const QSGAnchorLine &edge)
-{
-    Q_D(QSGAnchors);
-    if (!d->checkVAnchorValid(edge) || d->top == edge)
-        return;
-
-    d->usedAnchors |= TopAnchor;
-
-    if (!d->checkVValid()) {
-        d->usedAnchors &= ~TopAnchor;
-        return;
-    }
-
-    d->remDepend(d->top.item);
-    d->top = edge;
-    d->addDepend(d->top.item);
-    emit topChanged();
-    d->updateVerticalAnchors();
-}
-
-void QSGAnchors::resetTop()
-{
-    Q_D(QSGAnchors);
-    d->usedAnchors &= ~TopAnchor;
-    d->remDepend(d->top.item);
-    d->top = QSGAnchorLine();
-    emit topChanged();
-    d->updateVerticalAnchors();
-}
-
-QSGAnchorLine QSGAnchors::bottom() const
-{
-    Q_D(const QSGAnchors);
-    return d->bottom;
-}
-
-void QSGAnchors::setBottom(const QSGAnchorLine &edge)
-{
-    Q_D(QSGAnchors);
-    if (!d->checkVAnchorValid(edge) || d->bottom == edge)
-        return;
-
-    d->usedAnchors |= BottomAnchor;
-
-    if (!d->checkVValid()) {
-        d->usedAnchors &= ~BottomAnchor;
-        return;
-    }
-
-    d->remDepend(d->bottom.item);
-    d->bottom = edge;
-    d->addDepend(d->bottom.item);
-    emit bottomChanged();
-    d->updateVerticalAnchors();
-}
-
-void QSGAnchors::resetBottom()
-{
-    Q_D(QSGAnchors);
-    d->usedAnchors &= ~BottomAnchor;
-    d->remDepend(d->bottom.item);
-    d->bottom = QSGAnchorLine();
-    emit bottomChanged();
-    d->updateVerticalAnchors();
-}
-
-QSGAnchorLine QSGAnchors::verticalCenter() const
-{
-    Q_D(const QSGAnchors);
-    return d->vCenter;
-}
-
-void QSGAnchors::setVerticalCenter(const QSGAnchorLine &edge)
-{
-    Q_D(QSGAnchors);
-    if (!d->checkVAnchorValid(edge) || d->vCenter == edge)
-        return;
-
-    d->usedAnchors |= VCenterAnchor;
-
-    if (!d->checkVValid()) {
-        d->usedAnchors &= ~VCenterAnchor;
-        return;
-    }
-
-    d->remDepend(d->vCenter.item);
-    d->vCenter = edge;
-    d->addDepend(d->vCenter.item);
-    emit verticalCenterChanged();
-    d->updateVerticalAnchors();
-}
-
-void QSGAnchors::resetVerticalCenter()
-{
-    Q_D(QSGAnchors);
-    d->usedAnchors &= ~VCenterAnchor;
-    d->remDepend(d->vCenter.item);
-    d->vCenter = QSGAnchorLine();
-    emit verticalCenterChanged();
-    d->updateVerticalAnchors();
-}
-
-QSGAnchorLine QSGAnchors::baseline() const
-{
-    Q_D(const QSGAnchors);
-    return d->baseline;
-}
-
-void QSGAnchors::setBaseline(const QSGAnchorLine &edge)
-{
-    Q_D(QSGAnchors);
-    if (!d->checkVAnchorValid(edge) || d->baseline == edge)
-        return;
-
-    d->usedAnchors |= BaselineAnchor;
-
-    if (!d->checkVValid()) {
-        d->usedAnchors &= ~BaselineAnchor;
-        return;
-    }
-
-    d->remDepend(d->baseline.item);
-    d->baseline = edge;
-    d->addDepend(d->baseline.item);
-    emit baselineChanged();
-    d->updateVerticalAnchors();
-}
-
-void QSGAnchors::resetBaseline()
-{
-    Q_D(QSGAnchors);
-    d->usedAnchors &= ~BaselineAnchor;
-    d->remDepend(d->baseline.item);
-    d->baseline = QSGAnchorLine();
-    emit baselineChanged();
-    d->updateVerticalAnchors();
-}
-
-QSGAnchorLine QSGAnchors::left() const
-{
-    Q_D(const QSGAnchors);
-    return d->left;
-}
-
-void QSGAnchors::setLeft(const QSGAnchorLine &edge)
-{
-    Q_D(QSGAnchors);
-    if (!d->checkHAnchorValid(edge) || d->left == edge)
-        return;
-
-    d->usedAnchors |= LeftAnchor;
-
-    if (!d->checkHValid()) {
-        d->usedAnchors &= ~LeftAnchor;
-        return;
-    }
-
-    d->remDepend(d->left.item);
-    d->left = edge;
-    d->addDepend(d->left.item);
-    emit leftChanged();
-    d->updateHorizontalAnchors();
-}
-
-void QSGAnchors::resetLeft()
-{
-    Q_D(QSGAnchors);
-    d->usedAnchors &= ~LeftAnchor;
-    d->remDepend(d->left.item);
-    d->left = QSGAnchorLine();
-    emit leftChanged();
-    d->updateHorizontalAnchors();
-}
-
-QSGAnchorLine QSGAnchors::right() const
-{
-    Q_D(const QSGAnchors);
-    return d->right;
-}
-
-void QSGAnchors::setRight(const QSGAnchorLine &edge)
-{
-    Q_D(QSGAnchors);
-    if (!d->checkHAnchorValid(edge) || d->right == edge)
-        return;
-
-    d->usedAnchors |= RightAnchor;
-
-    if (!d->checkHValid()) {
-        d->usedAnchors &= ~RightAnchor;
-        return;
-    }
-
-    d->remDepend(d->right.item);
-    d->right = edge;
-    d->addDepend(d->right.item);
-    emit rightChanged();
-    d->updateHorizontalAnchors();
-}
-
-void QSGAnchors::resetRight()
-{
-    Q_D(QSGAnchors);
-    d->usedAnchors &= ~RightAnchor;
-    d->remDepend(d->right.item);
-    d->right = QSGAnchorLine();
-    emit rightChanged();
-    d->updateHorizontalAnchors();
-}
-
-QSGAnchorLine QSGAnchors::horizontalCenter() const
-{
-    Q_D(const QSGAnchors);
-    return d->hCenter;
-}
-
-void QSGAnchors::setHorizontalCenter(const QSGAnchorLine &edge)
-{
-    Q_D(QSGAnchors);
-    if (!d->checkHAnchorValid(edge) || d->hCenter == edge)
-        return;
-
-    d->usedAnchors |= HCenterAnchor;
-
-    if (!d->checkHValid()) {
-        d->usedAnchors &= ~HCenterAnchor;
-        return;
-    }
-
-    d->remDepend(d->hCenter.item);
-    d->hCenter = edge;
-    d->addDepend(d->hCenter.item);
-    emit horizontalCenterChanged();
-    d->updateHorizontalAnchors();
-}
-
-void QSGAnchors::resetHorizontalCenter()
-{
-    Q_D(QSGAnchors);
-    d->usedAnchors &= ~HCenterAnchor;
-    d->remDepend(d->hCenter.item);
-    d->hCenter = QSGAnchorLine();
-    emit horizontalCenterChanged();
-    d->updateHorizontalAnchors();
-}
-
-qreal QSGAnchors::leftMargin() const
-{
-    Q_D(const QSGAnchors);
-    return d->leftMargin;
-}
-
-void QSGAnchors::setLeftMargin(qreal offset)
-{
-    Q_D(QSGAnchors);
-    if (d->leftMargin == offset)
-        return;
-    d->leftMargin = offset;
-    if (d->fill)
-        d->fillChanged();
-    else
-        d->updateHorizontalAnchors();
-    emit leftMarginChanged();
-}
-
-qreal QSGAnchors::rightMargin() const
-{
-    Q_D(const QSGAnchors);
-    return d->rightMargin;
-}
-
-void QSGAnchors::setRightMargin(qreal offset)
-{
-    Q_D(QSGAnchors);
-    if (d->rightMargin == offset)
-        return;
-    d->rightMargin = offset;
-    if (d->fill)
-        d->fillChanged();
-    else
-        d->updateHorizontalAnchors();
-    emit rightMarginChanged();
-}
-
-qreal QSGAnchors::margins() const
-{
-    Q_D(const QSGAnchors);
-    return d->margins;
-}
-
-void QSGAnchors::setMargins(qreal offset)
-{
-    Q_D(QSGAnchors);
-    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)
-        setRightMargin(offset);
-    if (!d->leftMargin || d->leftMargin == d->margins)
-        setLeftMargin(offset);
-    if (!d->topMargin || d->topMargin == d->margins)
-        setTopMargin(offset);
-    if (!d->bottomMargin || d->bottomMargin == d->margins)
-        setBottomMargin(offset);
-    d->margins = offset;
-    emit marginsChanged();
-
-}
-
-qreal QSGAnchors::horizontalCenterOffset() const
-{
-    Q_D(const QSGAnchors);
-    return d->hCenterOffset;
-}
-
-void QSGAnchors::setHorizontalCenterOffset(qreal offset)
-{
-    Q_D(QSGAnchors);
-    if (d->hCenterOffset == offset)
-        return;
-    d->hCenterOffset = offset;
-    if (d->centerIn)
-        d->centerInChanged();
-    else
-        d->updateHorizontalAnchors();
-    emit horizontalCenterOffsetChanged();
-}
-
-qreal QSGAnchors::topMargin() const
-{
-    Q_D(const QSGAnchors);
-    return d->topMargin;
-}
-
-void QSGAnchors::setTopMargin(qreal offset)
-{
-    Q_D(QSGAnchors);
-    if (d->topMargin == offset)
-        return;
-    d->topMargin = offset;
-    if (d->fill)
-        d->fillChanged();
-    else
-        d->updateVerticalAnchors();
-    emit topMarginChanged();
-}
-
-qreal QSGAnchors::bottomMargin() const
-{
-    Q_D(const QSGAnchors);
-    return d->bottomMargin;
-}
-
-void QSGAnchors::setBottomMargin(qreal offset)
-{
-    Q_D(QSGAnchors);
-    if (d->bottomMargin == offset)
-        return;
-    d->bottomMargin = offset;
-    if (d->fill)
-        d->fillChanged();
-    else
-        d->updateVerticalAnchors();
-    emit bottomMarginChanged();
-}
-
-qreal QSGAnchors::verticalCenterOffset() const
-{
-    Q_D(const QSGAnchors);
-    return d->vCenterOffset;
-}
-
-void QSGAnchors::setVerticalCenterOffset(qreal offset)
-{
-    Q_D(QSGAnchors);
-    if (d->vCenterOffset == offset)
-        return;
-    d->vCenterOffset = offset;
-    if (d->centerIn)
-        d->centerInChanged();
-    else
-        d->updateVerticalAnchors();
-    emit verticalCenterOffsetChanged();
-}
-
-qreal QSGAnchors::baselineOffset() const
-{
-    Q_D(const QSGAnchors);
-    return d->baselineOffset;
-}
-
-void QSGAnchors::setBaselineOffset(qreal offset)
-{
-    Q_D(QSGAnchors);
-    if (d->baselineOffset == offset)
-        return;
-    d->baselineOffset = offset;
-    d->updateVerticalAnchors();
-    emit baselineOffsetChanged();
-}
-
-QSGAnchors::Anchors QSGAnchors::usedAnchors() const
-{
-    Q_D(const QSGAnchors);
-    return d->usedAnchors;
-}
-
-bool QSGAnchorsPrivate::checkHValid() const
-{
-    if (usedAnchors & QSGAnchors::LeftAnchor &&
-        usedAnchors & QSGAnchors::RightAnchor &&
-        usedAnchors & QSGAnchors::HCenterAnchor) {
-        qmlInfo(item) << QSGAnchors::tr("Cannot specify left, right, and hcenter anchors.");
-        return false;
-    }
-
-    return true;
-}
-
-bool QSGAnchorsPrivate::checkHAnchorValid(QSGAnchorLine anchor) const
-{
-    if (!anchor.item) {
-        qmlInfo(item) << QSGAnchors::tr("Cannot anchor to a null item.");
-        return false;
-    } else if (anchor.anchorLine & QSGAnchorLine::Vertical_Mask) {
-        qmlInfo(item) << QSGAnchors::tr("Cannot anchor a horizontal edge to a vertical edge.");
-        return false;
-    } else if (anchor.item != item->parentItem() && anchor.item->parentItem() != item->parentItem()){
-        qmlInfo(item) << QSGAnchors::tr("Cannot anchor to an item that isn't a parent or sibling.");
-        return false;
-    } else if (anchor.item == item) {
-        qmlInfo(item) << QSGAnchors::tr("Cannot anchor item to self.");
-        return false;
-    }
-
-    return true;
-}
-
-bool QSGAnchorsPrivate::checkVValid() const
-{
-    if (usedAnchors & QSGAnchors::TopAnchor &&
-        usedAnchors & QSGAnchors::BottomAnchor &&
-        usedAnchors & QSGAnchors::VCenterAnchor) {
-        qmlInfo(item) << QSGAnchors::tr("Cannot specify top, bottom, and vcenter anchors.");
-        return false;
-    } else if (usedAnchors & QSGAnchors::BaselineAnchor &&
-               (usedAnchors & QSGAnchors::TopAnchor ||
-                usedAnchors & QSGAnchors::BottomAnchor ||
-                usedAnchors & QSGAnchors::VCenterAnchor)) {
-        qmlInfo(item) << QSGAnchors::tr("Baseline anchor cannot be used in conjunction with top, bottom, or vcenter anchors.");
-        return false;
-    }
-
-    return true;
-}
-
-bool QSGAnchorsPrivate::checkVAnchorValid(QSGAnchorLine anchor) const
-{
-    if (!anchor.item) {
-        qmlInfo(item) << QSGAnchors::tr("Cannot anchor to a null item.");
-        return false;
-    } else if (anchor.anchorLine & QSGAnchorLine::Horizontal_Mask) {
-        qmlInfo(item) << QSGAnchors::tr("Cannot anchor a vertical edge to a horizontal edge.");
-        return false;
-    } else if (anchor.item != item->parentItem() && anchor.item->parentItem() != item->parentItem()){
-        qmlInfo(item) << QSGAnchors::tr("Cannot anchor to an item that isn't a parent or sibling.");
-        return false;
-    } else if (anchor.item == item){
-        qmlInfo(item) << QSGAnchors::tr("Cannot anchor item to self.");
-        return false;
-    }
-
-    return true;
-}
-
-QT_END_NAMESPACE
-
-#include <moc_qsganchors_p.cpp>
-
diff --git a/src/declarative/items/qsganchors_p.h b/src/declarative/items/qsganchors_p.h
deleted file mode 100644 (file)
index a80c279..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-// Commit: 2c7cab4172f1acc86fd49345a2847417e162f2c3
-/****************************************************************************
-**
-** 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 QSGANCHORS_P_H
-#define QSGANCHORS_P_H
-
-#include <qdeclarative.h>
-
-#include <QtCore/QObject>
-
-#include <private/qdeclarativeglobal_p.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGItem;
-class QSGAnchorsPrivate;
-class QSGAnchorLine;
-class Q_DECLARATIVE_PRIVATE_EXPORT QSGAnchors : public QObject
-{
-    Q_OBJECT
-
-    Q_PROPERTY(QSGAnchorLine left READ left WRITE setLeft RESET resetLeft NOTIFY leftChanged)
-    Q_PROPERTY(QSGAnchorLine right READ right WRITE setRight RESET resetRight NOTIFY rightChanged)
-    Q_PROPERTY(QSGAnchorLine horizontalCenter READ horizontalCenter WRITE setHorizontalCenter RESET resetHorizontalCenter NOTIFY horizontalCenterChanged)
-    Q_PROPERTY(QSGAnchorLine top READ top WRITE setTop RESET resetTop NOTIFY topChanged)
-    Q_PROPERTY(QSGAnchorLine bottom READ bottom WRITE setBottom RESET resetBottom NOTIFY bottomChanged)
-    Q_PROPERTY(QSGAnchorLine verticalCenter READ verticalCenter WRITE setVerticalCenter RESET resetVerticalCenter NOTIFY verticalCenterChanged)
-    Q_PROPERTY(QSGAnchorLine baseline READ baseline WRITE setBaseline RESET resetBaseline NOTIFY baselineChanged)
-    Q_PROPERTY(qreal margins READ margins WRITE setMargins NOTIFY marginsChanged)
-    Q_PROPERTY(qreal leftMargin READ leftMargin WRITE setLeftMargin NOTIFY leftMarginChanged)
-    Q_PROPERTY(qreal rightMargin READ rightMargin WRITE setRightMargin NOTIFY rightMarginChanged)
-    Q_PROPERTY(qreal horizontalCenterOffset READ horizontalCenterOffset WRITE setHorizontalCenterOffset NOTIFY horizontalCenterOffsetChanged)
-    Q_PROPERTY(qreal topMargin READ topMargin WRITE setTopMargin NOTIFY topMarginChanged)
-    Q_PROPERTY(qreal bottomMargin READ bottomMargin WRITE setBottomMargin NOTIFY bottomMarginChanged)
-    Q_PROPERTY(qreal verticalCenterOffset READ verticalCenterOffset WRITE setVerticalCenterOffset NOTIFY verticalCenterOffsetChanged)
-    Q_PROPERTY(qreal baselineOffset READ baselineOffset WRITE setBaselineOffset NOTIFY baselineOffsetChanged)
-    Q_PROPERTY(QSGItem *fill READ fill WRITE setFill RESET resetFill NOTIFY fillChanged)
-    Q_PROPERTY(QSGItem *centerIn READ centerIn WRITE setCenterIn RESET resetCenterIn NOTIFY centerInChanged)
-    Q_PROPERTY(bool mirrored READ mirrored NOTIFY mirroredChanged)
-
-public:
-    QSGAnchors(QSGItem *item, QObject *parent=0);
-    virtual ~QSGAnchors();
-
-    enum Anchor {
-        LeftAnchor = 0x01,
-        RightAnchor = 0x02,
-        TopAnchor = 0x04,
-        BottomAnchor = 0x08,
-        HCenterAnchor = 0x10,
-        VCenterAnchor = 0x20,
-        BaselineAnchor = 0x40,
-        Horizontal_Mask = LeftAnchor | RightAnchor | HCenterAnchor,
-        Vertical_Mask = TopAnchor | BottomAnchor | VCenterAnchor | BaselineAnchor
-    };
-    Q_DECLARE_FLAGS(Anchors, Anchor)
-
-    QSGAnchorLine left() const;
-    void setLeft(const QSGAnchorLine &edge);
-    void resetLeft();
-
-    QSGAnchorLine right() const;
-    void setRight(const QSGAnchorLine &edge);
-    void resetRight();
-
-    QSGAnchorLine horizontalCenter() const;
-    void setHorizontalCenter(const QSGAnchorLine &edge);
-    void resetHorizontalCenter();
-
-    QSGAnchorLine top() const;
-    void setTop(const QSGAnchorLine &edge);
-    void resetTop();
-
-    QSGAnchorLine bottom() const;
-    void setBottom(const QSGAnchorLine &edge);
-    void resetBottom();
-
-    QSGAnchorLine verticalCenter() const;
-    void setVerticalCenter(const QSGAnchorLine &edge);
-    void resetVerticalCenter();
-
-    QSGAnchorLine baseline() const;
-    void setBaseline(const QSGAnchorLine &edge);
-    void resetBaseline();
-
-    qreal leftMargin() const;
-    void setLeftMargin(qreal);
-
-    qreal rightMargin() const;
-    void setRightMargin(qreal);
-
-    qreal horizontalCenterOffset() const;
-    void setHorizontalCenterOffset(qreal);
-
-    qreal topMargin() const;
-    void setTopMargin(qreal);
-
-    qreal bottomMargin() const;
-    void setBottomMargin(qreal);
-
-    qreal margins() const;
-    void setMargins(qreal);
-
-    qreal verticalCenterOffset() const;
-    void setVerticalCenterOffset(qreal);
-
-    qreal baselineOffset() const;
-    void setBaselineOffset(qreal);
-
-    QSGItem *fill() const;
-    void setFill(QSGItem *);
-    void resetFill();
-
-    QSGItem *centerIn() const;
-    void setCenterIn(QSGItem *);
-    void resetCenterIn();
-
-    Anchors usedAnchors() const;
-
-    bool mirrored();
-
-    void classBegin();
-    void componentComplete();
-
-Q_SIGNALS:
-    void leftChanged();
-    void rightChanged();
-    void topChanged();
-    void bottomChanged();
-    void verticalCenterChanged();
-    void horizontalCenterChanged();
-    void baselineChanged();
-    void fillChanged();
-    void centerInChanged();
-    void leftMarginChanged();
-    void rightMarginChanged();
-    void topMarginChanged();
-    void bottomMarginChanged();
-    void marginsChanged();
-    void verticalCenterOffsetChanged();
-    void horizontalCenterOffsetChanged();
-    void baselineOffsetChanged();
-    void mirroredChanged();
-
-private:
-    friend class QSGItemPrivate;
-    Q_DISABLE_COPY(QSGAnchors)
-    Q_DECLARE_PRIVATE(QSGAnchors)
-};
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSGAnchors::Anchors)
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGAnchors)
-
-QT_END_HEADER
-
-#endif // QSGANCHORS_P_H
diff --git a/src/declarative/items/qsganchors_p_p.h b/src/declarative/items/qsganchors_p_p.h
deleted file mode 100644 (file)
index 0417761..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-// Commit: 2c7cab4172f1acc86fd49345a2847417e162f2c3
-/****************************************************************************
-**
-** 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 QSGANCHORS_P_P_H
-#define QSGANCHORS_P_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 "qsganchors_p.h"
-#include "qsgitemchangelistener_p.h"
-#include <private/qobject_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGAnchorLine
-{
-public:
-    QSGAnchorLine() : item(0), anchorLine(Invalid) {}
-
-    enum AnchorLine {
-        Invalid = 0x0,
-        Left = 0x01,
-        Right = 0x02,
-        Top = 0x04,
-        Bottom = 0x08,
-        HCenter = 0x10,
-        VCenter = 0x20,
-        Baseline = 0x40,
-        Horizontal_Mask = Left | Right | HCenter,
-        Vertical_Mask = Top | Bottom | VCenter | Baseline
-    };
-
-    QSGItem *item;
-    AnchorLine anchorLine;
-};
-
-inline bool operator==(const QSGAnchorLine& a, const QSGAnchorLine& b)
-{
-    return a.item == b.item && a.anchorLine == b.anchorLine;
-}
-
-class QSGAnchorsPrivate : public QObjectPrivate, public QSGItemChangeListener
-{
-    Q_DECLARE_PUBLIC(QSGAnchors)
-public:
-    QSGAnchorsPrivate(QSGItem *i)
-      : componentComplete(true), updatingMe(false), updatingHorizontalAnchor(0),
-        updatingVerticalAnchor(0), updatingFill(0), updatingCenterIn(0), item(i), usedAnchors(0), fill(0),
-        centerIn(0), leftMargin(0), rightMargin(0), topMargin(0), bottomMargin(0),
-        margins(0), vCenterOffset(0), hCenterOffset(0), baselineOffset(0)
-    {
-    }
-
-    void clearItem(QSGItem *);
-
-    void addDepend(QSGItem *);
-    void remDepend(QSGItem *);
-    bool isItemComplete() const;
-
-    bool componentComplete:1;
-    bool updatingMe:1;
-    uint updatingHorizontalAnchor:2;
-    uint updatingVerticalAnchor:2;
-    uint updatingFill:2;
-    uint updatingCenterIn:2;
-
-    void setItemHeight(qreal);
-    void setItemWidth(qreal);
-    void setItemX(qreal);
-    void setItemY(qreal);
-    void setItemPos(const QPointF &);
-    void setItemSize(const QSizeF &);
-
-    void updateOnComplete();
-    void updateMe();
-
-    // QSGItemGeometryListener interface
-    void itemGeometryChanged(QSGItem *, const QRectF &, const QRectF &);
-    QSGAnchorsPrivate *anchorPrivate() { return this; }
-
-    bool checkHValid() const;
-    bool checkVValid() const;
-    bool checkHAnchorValid(QSGAnchorLine anchor) const;
-    bool checkVAnchorValid(QSGAnchorLine anchor) const;
-    bool calcStretch(const QSGAnchorLine &edge1, const QSGAnchorLine &edge2, qreal offset1, qreal offset2, QSGAnchorLine::AnchorLine line, qreal &stretch);
-
-    bool isMirrored() const;
-    void updateHorizontalAnchors();
-    void updateVerticalAnchors();
-    void fillChanged();
-    void centerInChanged();
-
-    QSGItem *item;
-    QSGAnchors::Anchors usedAnchors;
-
-    QSGItem *fill;
-    QSGItem *centerIn;
-
-    QSGAnchorLine left;
-    QSGAnchorLine right;
-    QSGAnchorLine top;
-    QSGAnchorLine bottom;
-    QSGAnchorLine vCenter;
-    QSGAnchorLine hCenter;
-    QSGAnchorLine baseline;
-
-    qreal leftMargin;
-    qreal rightMargin;
-    qreal topMargin;
-    qreal bottomMargin;
-    qreal margins;
-    qreal vCenterOffset;
-    qreal hCenterOffset;
-    qreal baselineOffset;
-
-    static inline QSGAnchorsPrivate *get(QSGAnchors *o) {
-        return static_cast<QSGAnchorsPrivate *>(QObjectPrivate::get(o));
-    }
-};
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QSGAnchorLine)
-
-#endif
diff --git a/src/declarative/items/qsganimatedimage.cpp b/src/declarative/items/qsganimatedimage.cpp
deleted file mode 100644 (file)
index 93e0284..0000000
+++ /dev/null
@@ -1,397 +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 "qsganimatedimage_p.h"
-#include "qsganimatedimage_p_p.h"
-
-#ifndef QT_NO_MOVIE
-
-#include <QtDeclarative/qdeclarativeinfo.h>
-#include <QtGui/qmovie.h>
-#include <QtNetwork/qnetworkrequest.h>
-#include <QtNetwork/qnetworkreply.h>
-
-#include <private/qdeclarativeengine_p.h>
-
-QT_BEGIN_NAMESPACE
-/*!
-    \qmlclass AnimatedImage QSGAnimatedImage
-    \inqmlmodule QtQuick 2
-    \inherits Image
-    \ingroup basic-visual-elements
-
-    The AnimatedImage element extends the features of the \l Image element, providing
-    a way to play animations stored as images containing a series of frames,
-    such as those stored in GIF files.
-
-    Information about the current frame and totla length of the animation can be
-    obtained using the \l currentFrame and \l frameCount properties. You can
-    start, pause and stop the animation by changing the values of the \l playing
-    and \l paused properties.
-
-    The full list of supported formats can be determined with QMovie::supportedFormats().
-
-    \section1 Example Usage
-
-    \beginfloatleft
-    \image animatedimageitem.gif
-    \endfloat
-
-    The following QML shows how to display an animated image and obtain information
-    about its state, such as the current frame and total number of frames.
-    The result is an animated image with a simple progress indicator underneath it.
-
-    \bold Note: Unlike images, animated images are not cached or shared internally.
-
-    \clearfloat
-    \snippet doc/src/snippets/declarative/animatedimage.qml document
-
-    \sa BorderImage, Image
-*/
-
-/*!
-    \qmlproperty url QtQuick2::AnimatedImage::source
-
-    This property holds the URL that refers to the source image.
-
-    AnimatedImage can handle any image format supported by Qt, loaded from any
-    URL scheme supported by Qt.
-
-    \sa QDeclarativeImageProvider
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::AnimatedImage::asynchronous
-
-    Specifies that images on the local filesystem should be loaded
-    asynchronously in a separate thread.  The default value is
-    false, causing the user interface thread to block while the
-    image is loaded.  Setting \a asynchronous to true is useful where
-    maintaining a responsive user interface is more desirable
-    than having images immediately visible.
-
-    Note that this property is only valid for images read from the
-    local filesystem.  Images loaded via a network resource (e.g. HTTP)
-    are always loaded asynchonously.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::AnimatedImage::mirror
-
-    This property holds whether the image should be horizontally inverted
-    (effectively displaying a mirrored image).
-
-    The default value is false.
-*/
-
-QSGAnimatedImage::QSGAnimatedImage(QSGItem *parent)
-    : QSGImage(*(new QSGAnimatedImagePrivate), parent)
-{
-}
-
-QSGAnimatedImage::~QSGAnimatedImage()
-{
-    Q_D(QSGAnimatedImage);
-    delete d->_movie;
-}
-
-/*!
-  \qmlproperty bool QtQuick2::AnimatedImage::paused
-  This property holds whether the animated image is paused.
-
-  By default, this property is false. Set it to true when you want to pause
-  the animation.
-*/
-
-bool QSGAnimatedImage::isPaused() const
-{
-    Q_D(const QSGAnimatedImage);
-    if (!d->_movie)
-        return false;
-    return d->_movie->state()==QMovie::Paused;
-}
-
-void QSGAnimatedImage::setPaused(bool pause)
-{
-    Q_D(QSGAnimatedImage);
-    if (pause == d->paused)
-        return;
-    d->paused = pause;
-    if (!d->_movie)
-        return;
-    d->_movie->setPaused(pause);
-}
-
-/*!
-  \qmlproperty bool QtQuick2::AnimatedImage::playing
-  This property holds whether the animated image is playing.
-
-  By default, this property is true, meaning that the animation
-  will start playing immediately.
-*/
-
-bool QSGAnimatedImage::isPlaying() const
-{
-    Q_D(const QSGAnimatedImage);
-    if (!d->_movie)
-        return false;
-    return d->_movie->state()!=QMovie::NotRunning;
-}
-
-void QSGAnimatedImage::setPlaying(bool play)
-{
-    Q_D(QSGAnimatedImage);
-    if (play == d->playing)
-        return;
-    d->playing = play;
-    if (!d->_movie)
-        return;
-    if (play)
-        d->_movie->start();
-    else
-        d->_movie->stop();
-}
-
-/*!
-  \qmlproperty int QtQuick2::AnimatedImage::currentFrame
-  \qmlproperty int QtQuick2::AnimatedImage::frameCount
-
-  currentFrame is the frame that is currently visible. By monitoring this property
-  for changes, you can animate other items at the same time as the image.
-
-  frameCount is the number of frames in the animation. For some animation formats,
-  frameCount is unknown and has a value of zero.
-*/
-int QSGAnimatedImage::currentFrame() const
-{
-    Q_D(const QSGAnimatedImage);
-    if (!d->_movie)
-        return d->preset_currentframe;
-    return d->_movie->currentFrameNumber();
-}
-
-void QSGAnimatedImage::setCurrentFrame(int frame)
-{
-    Q_D(QSGAnimatedImage);
-    if (!d->_movie) {
-        d->preset_currentframe = frame;
-        return;
-    }
-    d->_movie->jumpToFrame(frame);
-}
-
-int QSGAnimatedImage::frameCount() const
-{
-    Q_D(const QSGAnimatedImage);
-    if (!d->_movie)
-        return 0;
-    return d->_movie->frameCount();
-}
-
-void QSGAnimatedImage::setSource(const QUrl &url)
-{
-    Q_D(QSGAnimatedImage);
-    if (url == d->url)
-        return;
-
-    delete d->_movie;
-    d->_movie = 0;
-
-    if (d->reply) {
-        d->reply->deleteLater();
-        d->reply = 0;
-    }
-
-    d->url = url;
-    emit sourceChanged(d->url);
-
-    if (isComponentComplete())
-        load();
-}
-
-void QSGAnimatedImage::load()
-{
-    Q_D(QSGAnimatedImage);
-
-    QSGImageBase::Status oldStatus = d->status;
-    qreal oldProgress = d->progress;
-
-    if (d->url.isEmpty()) {
-        delete d->_movie;
-        d->setPixmap(QPixmap());
-        d->progress = 0;
-        d->status = Null;
-        if (d->status != oldStatus)
-            emit statusChanged(d->status);
-        if (d->progress != oldProgress)
-            emit progressChanged(d->progress);
-    } else {
-        QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(d->url);
-        if (!lf.isEmpty()) {
-            //### should be unified with movieRequestFinished
-            d->_movie = new QMovie(lf);
-            if (!d->_movie->isValid()){
-                qmlInfo(this) << "Error Reading Animated Image File " << d->url.toString();
-                delete d->_movie;
-                d->_movie = 0;
-                d->status = Error;
-                if (d->status != oldStatus)
-                    emit statusChanged(d->status);
-                return;
-            }
-            connect(d->_movie, SIGNAL(stateChanged(QMovie::MovieState)),
-                    this, SLOT(playingStatusChanged()));
-            connect(d->_movie, SIGNAL(frameChanged(int)),
-                    this, SLOT(movieUpdate()));
-            d->_movie->setCacheMode(QMovie::CacheAll);
-            if (d->playing)
-                d->_movie->start();
-            else
-                d->_movie->jumpToFrame(0);
-            if (d->paused)
-                d->_movie->setPaused(true);
-            d->setPixmap(d->_movie->currentPixmap());
-            d->status = Ready;
-            d->progress = 1.0;
-            if (d->status != oldStatus)
-                emit statusChanged(d->status);
-            if (d->progress != oldProgress)
-                emit progressChanged(d->progress);
-            return;
-        }
-
-        d->status = Loading;
-        d->progress = 0;
-        emit statusChanged(d->status);
-        emit progressChanged(d->progress);
-        QNetworkRequest req(d->url);
-        req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
-        d->reply = qmlEngine(this)->networkAccessManager()->get(req);
-        QObject::connect(d->reply, SIGNAL(finished()),
-                         this, SLOT(movieRequestFinished()));
-        QObject::connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)),
-                         this, SLOT(requestProgress(qint64,qint64)));
-    }
-}
-
-#define ANIMATEDIMAGE_MAXIMUM_REDIRECT_RECURSION 16
-
-void QSGAnimatedImage::movieRequestFinished()
-{
-    Q_D(QSGAnimatedImage);
-
-    d->redirectCount++;
-    if (d->redirectCount < ANIMATEDIMAGE_MAXIMUM_REDIRECT_RECURSION) {
-        QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
-        if (redirect.isValid()) {
-            QUrl url = d->reply->url().resolved(redirect.toUrl());
-            d->reply->deleteLater();
-            d->reply = 0;
-            setSource(url);
-            return;
-        }
-    }
-    d->redirectCount=0;
-
-    d->_movie = new QMovie(d->reply);
-    if (!d->_movie->isValid()){
-#ifndef QT_NO_DEBUG_STREAM
-        qmlInfo(this) << "Error Reading Animated Image File " << d->url;
-#endif
-        delete d->_movie;
-        d->_movie = 0;
-        d->status = Error;
-        emit statusChanged(d->status);
-        return;
-    }
-    connect(d->_movie, SIGNAL(stateChanged(QMovie::MovieState)),
-            this, SLOT(playingStatusChanged()));
-    connect(d->_movie, SIGNAL(frameChanged(int)),
-            this, SLOT(movieUpdate()));
-    d->_movie->setCacheMode(QMovie::CacheAll);
-    if (d->playing)
-        d->_movie->start();
-    if (d->paused || !d->playing) {
-        d->_movie->jumpToFrame(d->preset_currentframe);
-        d->preset_currentframe = 0;
-    }
-    if (d->paused)
-        d->_movie->setPaused(true);
-    d->setPixmap(d->_movie->currentPixmap());
-    d->status = Ready;
-    emit statusChanged(d->status);
-}
-
-void QSGAnimatedImage::movieUpdate()
-{
-    Q_D(QSGAnimatedImage);
-    d->setPixmap(d->_movie->currentPixmap());
-    emit frameChanged();
-}
-
-void QSGAnimatedImage::playingStatusChanged()
-{
-    Q_D(QSGAnimatedImage);
-    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) {
-        d->playing = (d->_movie->state() == QMovie::Paused);
-        emit pausedChanged();
-    }
-}
-
-void QSGAnimatedImage::componentComplete()
-{
-    Q_D(QSGAnimatedImage);
-    QSGItem::componentComplete(); // NOT QSGImage
-    if (d->url.isValid())
-        load();
-    if (!d->reply) {
-        setCurrentFrame(d->preset_currentframe);
-        d->preset_currentframe = 0;
-    }
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_MOVIE
diff --git a/src/declarative/items/qsganimatedimage_p.h b/src/declarative/items/qsganimatedimage_p.h
deleted file mode 100644 (file)
index efbe01d..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-// Commit: 80d0fe9cbd92288a08d5ced8767f1edb651dae37
-/****************************************************************************
-**
-** 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 QSGANIMATEDIMAGE_P_H
-#define QSGANIMATEDIMAGE_P_H
-
-#include "qsgimage_p.h"
-
-#ifndef QT_NO_MOVIE
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QMovie;
-class QSGAnimatedImagePrivate;
-
-class Q_AUTOTEST_EXPORT QSGAnimatedImage : public QSGImage
-{
-    Q_OBJECT
-
-    Q_PROPERTY(bool playing READ isPlaying WRITE setPlaying NOTIFY playingChanged)
-    Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged)
-    Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY frameChanged)
-    Q_PROPERTY(int frameCount READ frameCount)
-
-    // read-only for AnimatedImage
-    Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged)
-
-public:
-    QSGAnimatedImage(QSGItem *parent=0);
-    ~QSGAnimatedImage();
-
-    bool isPlaying() const;
-    void setPlaying(bool play);
-
-    bool isPaused() const;
-    void setPaused(bool pause);
-
-    int currentFrame() const;
-    void setCurrentFrame(int frame);
-
-    int frameCount() const;
-
-    // Extends QSGImage's src property*/
-    virtual void setSource(const QUrl&);
-
-Q_SIGNALS:
-    void playingChanged();
-    void pausedChanged();
-    void frameChanged();
-    void sourceSizeChanged();
-
-private Q_SLOTS:
-    void movieUpdate();
-    void movieRequestFinished();
-    void playingStatusChanged();
-
-protected:
-    virtual void load();
-    void componentComplete();
-
-private:
-    Q_DISABLE_COPY(QSGAnimatedImage)
-    Q_DECLARE_PRIVATE(QSGAnimatedImage)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGAnimatedImage)
-
-QT_END_HEADER
-
-#endif // QT_NO_MOVIE
-
-#endif // QSGANIMATEDIMAGE_P_H
diff --git a/src/declarative/items/qsganimatedimage_p_p.h b/src/declarative/items/qsganimatedimage_p_p.h
deleted file mode 100644 (file)
index f216df2..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
-/****************************************************************************
-**
-** 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 QSGANIMATEDIMAGE_P_P_H
-#define QSGANIMATEDIMAGE_P_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 "qsgimage_p_p.h"
-
-#ifndef QT_NO_MOVIE
-
-QT_BEGIN_NAMESPACE
-
-class QMovie;
-class QNetworkReply;
-
-class QSGAnimatedImagePrivate : public QSGImagePrivate
-{
-    Q_DECLARE_PUBLIC(QSGAnimatedImage)
-
-public:
-    QSGAnimatedImagePrivate()
-      : playing(true), paused(false), preset_currentframe(0), _movie(0), reply(0), redirectCount(0)
-    {
-    }
-
-    bool playing;
-    bool paused;
-    int preset_currentframe;
-    QMovie *_movie;
-    QNetworkReply *reply;
-    int redirectCount;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_MOVIE
-
-#endif // QSGANIMATEDIMAGE_P_P_H
diff --git a/src/declarative/items/qsganimation.cpp b/src/declarative/items/qsganimation.cpp
deleted file mode 100644 (file)
index 81c8391..0000000
+++ /dev/null
@@ -1,792 +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$
-**
-****************************************************************************/
-
-#include "qsganimation_p.h"
-#include "qsganimation_p_p.h"
-#include "qsgstateoperations_p.h"
-
-#include <private/qdeclarativeproperty_p.h>
-#include <private/qdeclarativepath_p.h>
-
-#include <QtDeclarative/qdeclarativeinfo.h>
-#include <QtCore/qmath.h>
-#include <QtCore/qsequentialanimationgroup.h>
-#include <QtCore/qparallelanimationgroup.h>
-#include <QtGui/qtransform.h>
-
-QT_BEGIN_NAMESPACE
-
-QSGParentAnimation::QSGParentAnimation(QObject *parent)
-    : QDeclarativeAnimationGroup(*(new QSGParentAnimationPrivate), parent)
-{
-    Q_D(QSGParentAnimation);
-    d->topLevelGroup = new QSequentialAnimationGroup;
-    QDeclarative_setParent_noEvent(d->topLevelGroup, this);
-
-    d->startAction = new QActionAnimation;
-    QDeclarative_setParent_noEvent(d->startAction, d->topLevelGroup);
-    d->topLevelGroup->addAnimation(d->startAction);
-
-    d->ag = new QParallelAnimationGroup;
-    QDeclarative_setParent_noEvent(d->ag, d->topLevelGroup);
-    d->topLevelGroup->addAnimation(d->ag);
-
-    d->endAction = new QActionAnimation;
-    QDeclarative_setParent_noEvent(d->endAction, d->topLevelGroup);
-    d->topLevelGroup->addAnimation(d->endAction);
-}
-
-QSGParentAnimation::~QSGParentAnimation()
-{
-}
-
-QSGItem *QSGParentAnimation::target() const
-{
-    Q_D(const QSGParentAnimation);
-    return d->target;
-}
-
-void QSGParentAnimation::setTarget(QSGItem *target)
-{
-    Q_D(QSGParentAnimation);
-    if (target == d->target)
-        return;
-
-    d->target = target;
-    emit targetChanged();
-}
-
-QSGItem *QSGParentAnimation::newParent() const
-{
-    Q_D(const QSGParentAnimation);
-    return d->newParent;
-}
-
-void QSGParentAnimation::setNewParent(QSGItem *newParent)
-{
-    Q_D(QSGParentAnimation);
-    if (newParent == d->newParent)
-        return;
-
-    d->newParent = newParent;
-    emit newParentChanged();
-}
-
-QSGItem *QSGParentAnimation::via() const
-{
-    Q_D(const QSGParentAnimation);
-    return d->via;
-}
-
-void QSGParentAnimation::setVia(QSGItem *via)
-{
-    Q_D(QSGParentAnimation);
-    if (via == d->via)
-        return;
-
-    d->via = via;
-    emit viaChanged();
-}
-
-//### mirrors same-named function in QSGItem
-QPointF QSGParentAnimationPrivate::computeTransformOrigin(QSGItem::TransformOrigin origin, qreal width, qreal height) const
-{
-    switch (origin) {
-    default:
-    case QSGItem::TopLeft:
-        return QPointF(0, 0);
-    case QSGItem::Top:
-        return QPointF(width / 2., 0);
-    case QSGItem::TopRight:
-        return QPointF(width, 0);
-    case QSGItem::Left:
-        return QPointF(0, height / 2.);
-    case QSGItem::Center:
-        return QPointF(width / 2., height / 2.);
-    case QSGItem::Right:
-        return QPointF(width, height / 2.);
-    case QSGItem::BottomLeft:
-        return QPointF(0, height);
-    case QSGItem::Bottom:
-        return QPointF(width / 2., height);
-    case QSGItem::BottomRight:
-        return QPointF(width, height);
-    }
-}
-
-void QSGParentAnimation::transition(QDeclarativeStateActions &actions,
-                        QDeclarativeProperties &modified,
-                        TransitionDirection direction)
-{
-    Q_D(QSGParentAnimation);
-
-    struct QSGParentAnimationData : public QAbstractAnimationAction
-    {
-        QSGParentAnimationData() {}
-        ~QSGParentAnimationData() { qDeleteAll(pc); }
-
-        QDeclarativeStateActions actions;
-        //### reverse should probably apply on a per-action basis
-        bool reverse;
-        QList<QSGParentChange *> pc;
-        virtual void doAction()
-        {
-            for (int ii = 0; ii < actions.count(); ++ii) {
-                const QDeclarativeAction &action = actions.at(ii);
-                if (reverse)
-                    action.event->reverse();
-                else
-                    action.event->execute();
-            }
-        }
-    };
-
-    QSGParentAnimationData *data = new QSGParentAnimationData;
-    QSGParentAnimationData *viaData = new QSGParentAnimationData;
-
-    bool hasExplicit = false;
-    if (d->target && d->newParent) {
-        data->reverse = false;
-        QDeclarativeAction myAction;
-        QSGParentChange *pc = new QSGParentChange;
-        pc->setObject(d->target);
-        pc->setParent(d->newParent);
-        myAction.event = pc;
-        data->pc << pc;
-        data->actions << myAction;
-        hasExplicit = true;
-        if (d->via) {
-            viaData->reverse = false;
-            QDeclarativeAction myVAction;
-            QSGParentChange *vpc = new QSGParentChange;
-            vpc->setObject(d->target);
-            vpc->setParent(d->via);
-            myVAction.event = vpc;
-            viaData->pc << vpc;
-            viaData->actions << myVAction;
-        }
-        //### once actions have concept of modified,
-        //    loop to match appropriate ParentChanges and mark as modified
-    }
-
-    if (!hasExplicit)
-    for (int i = 0; i < actions.size(); ++i) {
-        QDeclarativeAction &action = actions[i];
-        if (action.event && action.event->typeName() == QLatin1String("ParentChange")
-            && (!d->target || static_cast<QSGParentChange*>(action.event)->object() == d->target)) {
-
-            QSGParentChange *pc = static_cast<QSGParentChange*>(action.event);
-            QDeclarativeAction myAction = action;
-            data->reverse = action.reverseEvent;
-
-            //### this logic differs from PropertyAnimation
-            //    (probably a result of modified vs. done)
-            if (d->newParent) {
-                QSGParentChange *epc = new QSGParentChange;
-                epc->setObject(static_cast<QSGParentChange*>(action.event)->object());
-                epc->setParent(d->newParent);
-                myAction.event = epc;
-                data->pc << epc;
-                data->actions << myAction;
-                pc = epc;
-            } else {
-                action.actionDone = true;
-                data->actions << myAction;
-            }
-
-            if (d->via) {
-                viaData->reverse = false;
-                QDeclarativeAction myAction;
-                QSGParentChange *vpc = new QSGParentChange;
-                vpc->setObject(pc->object());
-                vpc->setParent(d->via);
-                myAction.event = vpc;
-                viaData->pc << vpc;
-                viaData->actions << myAction;
-                QDeclarativeAction dummyAction;
-                QDeclarativeAction &xAction = pc->xIsSet() && i < actions.size()-1 ? actions[++i] : dummyAction;
-                QDeclarativeAction &yAction = pc->yIsSet() && i < actions.size()-1 ? actions[++i] : dummyAction;
-                QDeclarativeAction &sAction = pc->scaleIsSet() && i < actions.size()-1 ? actions[++i] : dummyAction;
-                QDeclarativeAction &rAction = pc->rotationIsSet() && i < actions.size()-1 ? actions[++i] : dummyAction;
-                QSGItem *target = pc->object();
-                QSGItem *targetParent = action.reverseEvent ? pc->originalParent() : pc->parent();
-
-                //### this mirrors the logic in QSGParentChange.
-                bool ok;
-                const QTransform &transform = targetParent->itemTransform(d->via, &ok);
-                if (transform.type() >= QTransform::TxShear || !ok) {
-                    qmlInfo(this) << QSGParentAnimation::tr("Unable to preserve appearance under complex transform");
-                    ok = false;
-                }
-
-                qreal scale = 1;
-                qreal rotation = 0;
-                bool isRotate = (transform.type() == QTransform::TxRotate) || (transform.m11() < 0);
-                if (ok && !isRotate) {
-                    if (transform.m11() == transform.m22())
-                        scale = transform.m11();
-                    else {
-                        qmlInfo(this) << QSGParentAnimation::tr("Unable to preserve appearance under non-uniform scale");
-                        ok = false;
-                    }
-                } else if (ok && isRotate) {
-                    if (transform.m11() == transform.m22())
-                        scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12());
-                    else {
-                        qmlInfo(this) << QSGParentAnimation::tr("Unable to preserve appearance under non-uniform scale");
-                        ok = false;
-                    }
-
-                    if (scale != 0)
-                        rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
-                    else {
-                        qmlInfo(this) << QSGParentAnimation::tr("Unable to preserve appearance under scale of 0");
-                        ok = false;
-                    }
-                }
-
-                const QPointF &point = transform.map(QPointF(xAction.toValue.toReal(),yAction.toValue.toReal()));
-                qreal x = point.x();
-                qreal y = point.y();
-                if (ok && target->transformOrigin() != QSGItem::TopLeft) {
-                    qreal w = target->width();
-                    qreal h = target->height();
-                    if (pc->widthIsSet() && i < actions.size() - 1)
-                        w = actions[++i].toValue.toReal();
-                    if (pc->heightIsSet() && i < actions.size() - 1)
-                        h = actions[++i].toValue.toReal();
-                    const QPointF &transformOrigin
-                            = d->computeTransformOrigin(target->transformOrigin(), w,h);
-                    qreal tempxt = transformOrigin.x();
-                    qreal tempyt = transformOrigin.y();
-                    QTransform t;
-                    t.translate(-tempxt, -tempyt);
-                    t.rotate(rotation);
-                    t.scale(scale, scale);
-                    t.translate(tempxt, tempyt);
-                    const QPointF &offset = t.map(QPointF(0,0));
-                    x += offset.x();
-                    y += offset.y();
-                }
-
-                if (ok) {
-                    //qDebug() << x << y << rotation << scale;
-                    xAction.toValue = x;
-                    yAction.toValue = y;
-                    sAction.toValue = sAction.toValue.toReal() * scale;
-                    rAction.toValue = rAction.toValue.toReal() + rotation;
-                }
-            }
-        }
-    }
-
-    if (data->actions.count()) {
-        if (direction == QDeclarativeAbstractAnimation::Forward) {
-            d->startAction->setAnimAction(d->via ? viaData : data, QActionAnimation::DeleteWhenStopped);
-            d->endAction->setAnimAction(d->via ? data : 0, QActionAnimation::DeleteWhenStopped);
-        } else {
-            d->endAction->setAnimAction(d->via ? viaData : data, QActionAnimation::DeleteWhenStopped);
-            d->startAction->setAnimAction(d->via ? data : 0, QActionAnimation::DeleteWhenStopped);
-        }
-    } else {
-        delete data;
-        delete viaData;
-    }
-
-    //take care of any child animations
-    bool valid = d->defaultProperty.isValid();
-    for (int ii = 0; ii < d->animations.count(); ++ii) {
-        if (valid)
-            d->animations.at(ii)->setDefaultTarget(d->defaultProperty);
-        d->animations.at(ii)->transition(actions, modified, direction);
-    }
-
-}
-
-QAbstractAnimation *QSGParentAnimation::qtAnimation()
-{
-    Q_D(QSGParentAnimation);
-    return d->topLevelGroup;
-}
-
-QSGAnchorAnimation::QSGAnchorAnimation(QObject *parent)
-: QDeclarativeAbstractAnimation(*(new QSGAnchorAnimationPrivate), parent)
-{
-    Q_D(QSGAnchorAnimation);
-    d->va = new QDeclarativeBulkValueAnimator;
-    QDeclarative_setParent_noEvent(d->va, this);
-}
-
-QSGAnchorAnimation::~QSGAnchorAnimation()
-{
-}
-
-QAbstractAnimation *QSGAnchorAnimation::qtAnimation()
-{
-    Q_D(QSGAnchorAnimation);
-    return d->va;
-}
-
-QDeclarativeListProperty<QSGItem> QSGAnchorAnimation::targets()
-{
-    Q_D(QSGAnchorAnimation);
-    return QDeclarativeListProperty<QSGItem>(this, d->targets);
-}
-
-int QSGAnchorAnimation::duration() const
-{
-    Q_D(const QSGAnchorAnimation);
-    return d->va->duration();
-}
-
-void QSGAnchorAnimation::setDuration(int duration)
-{
-    if (duration < 0) {
-        qmlInfo(this) << tr("Cannot set a duration of < 0");
-        return;
-    }
-
-    Q_D(QSGAnchorAnimation);
-    if (d->va->duration() == duration)
-        return;
-    d->va->setDuration(duration);
-    emit durationChanged(duration);
-}
-
-QEasingCurve QSGAnchorAnimation::easing() const
-{
-    Q_D(const QSGAnchorAnimation);
-    return d->va->easingCurve();
-}
-
-void QSGAnchorAnimation::setEasing(const QEasingCurve &e)
-{
-    Q_D(QSGAnchorAnimation);
-    if (d->va->easingCurve() == e)
-        return;
-
-    d->va->setEasingCurve(e);
-    emit easingChanged(e);
-}
-
-void QSGAnchorAnimation::transition(QDeclarativeStateActions &actions,
-                        QDeclarativeProperties &modified,
-                        TransitionDirection direction)
-{
-    Q_UNUSED(modified);
-    Q_D(QSGAnchorAnimation);
-    QDeclarativeAnimationPropertyUpdater *data = new QDeclarativeAnimationPropertyUpdater;
-    data->interpolatorType = QMetaType::QReal;
-    data->interpolator = d->interpolator;
-
-    data->reverse = direction == Backward ? true : false;
-    data->fromSourced = false;
-    data->fromDefined = false;
-
-    for (int ii = 0; ii < actions.count(); ++ii) {
-        QDeclarativeAction &action = actions[ii];
-        if (action.event && action.event->typeName() == QLatin1String("AnchorChanges")
-            && (d->targets.isEmpty() || d->targets.contains(static_cast<QSGAnchorChanges*>(action.event)->object()))) {
-            data->actions << static_cast<QSGAnchorChanges*>(action.event)->additionalActions();
-        }
-    }
-
-    if (data->actions.count()) {
-        if (!d->rangeIsSet) {
-            d->va->setStartValue(qreal(0));
-            d->va->setEndValue(qreal(1));
-            d->rangeIsSet = true;
-        }
-        d->va->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped);
-        d->va->setFromSourcedValue(&data->fromSourced);
-    } else {
-        delete data;
-    }
-}
-
-QSGPathAnimation::QSGPathAnimation(QObject *parent)
-: QDeclarativeAbstractAnimation(*(new QSGPathAnimationPrivate), parent)
-{
-    Q_D(QSGPathAnimation);
-    d->pa = new QDeclarativeBulkValueAnimator;
-    QDeclarative_setParent_noEvent(d->pa, this);
-}
-
-QSGPathAnimation::~QSGPathAnimation()
-{
-}
-
-int QSGPathAnimation::duration() const
-{
-    Q_D(const QSGPathAnimation);
-    return d->pa->duration();
-}
-
-void QSGPathAnimation::setDuration(int duration)
-{
-    if (duration < 0) {
-        qmlInfo(this) << tr("Cannot set a duration of < 0");
-        return;
-    }
-
-    Q_D(QSGPathAnimation);
-    if (d->pa->duration() == duration)
-        return;
-    d->pa->setDuration(duration);
-    emit durationChanged(duration);
-}
-
-QEasingCurve QSGPathAnimation::easing() const
-{
-    Q_D(const QSGPathAnimation);
-    return d->pa->easingCurve();
-}
-
-void QSGPathAnimation::setEasing(const QEasingCurve &e)
-{
-    Q_D(QSGPathAnimation);
-    if (d->pa->easingCurve() == e)
-        return;
-
-    d->pa->setEasingCurve(e);
-    emit easingChanged(e);
-}
-
-QDeclarativePath *QSGPathAnimation::path() const
-{
-    Q_D(const QSGPathAnimation);
-    return d->path;
-}
-
-void QSGPathAnimation::setPath(QDeclarativePath *path)
-{
-    Q_D(QSGPathAnimation);
-    if (d->path == path)
-        return;
-
-    d->path = path;
-    emit pathChanged();
-}
-
-QSGItem *QSGPathAnimation::target() const
-{
-    Q_D(const QSGPathAnimation);
-    return d->target;
-}
-
-void QSGPathAnimation::setTarget(QSGItem *target)
-{
-    Q_D(QSGPathAnimation);
-    if (d->target == target)
-        return;
-
-    d->target = target;
-    emit targetChanged();
-}
-
-QSGPathAnimation::Orientation QSGPathAnimation::orientation() const
-{
-    Q_D(const QSGPathAnimation);
-    return d->orientation;
-}
-
-void QSGPathAnimation::setOrientation(Orientation orientation)
-{
-    Q_D(QSGPathAnimation);
-    if (d->orientation == orientation)
-        return;
-
-    d->orientation = orientation;
-    emit orientationChanged(d->orientation);
-}
-
-QPointF QSGPathAnimation::anchorPoint() const
-{
-    Q_D(const QSGPathAnimation);
-    return d->anchorPoint;
-}
-
-void QSGPathAnimation::setAnchorPoint(const QPointF &point)
-{
-    Q_D(QSGPathAnimation);
-    if (d->anchorPoint == point)
-        return;
-
-    d->anchorPoint = point;
-    emit anchorPointChanged(point);
-}
-
-qreal QSGPathAnimation::orientationEntryInterval() const
-{
-    Q_D(const QSGPathAnimation);
-    return d->entryInterval;
-}
-
-void QSGPathAnimation::setOrientationEntryInterval(qreal interval)
-{
-    Q_D(QSGPathAnimation);
-    if (d->entryInterval == interval)
-        return;
-    d->entryInterval = interval;
-    emit orientationEntryIntervalChanged(interval);
-}
-
-qreal QSGPathAnimation::orientationExitInterval() const
-{
-    Q_D(const QSGPathAnimation);
-    return d->exitInterval;
-}
-
-void QSGPathAnimation::setOrientationExitInterval(qreal interval)
-{
-    Q_D(QSGPathAnimation);
-    if (d->exitInterval == interval)
-        return;
-    d->exitInterval = interval;
-    emit orientationExitIntervalChanged(interval);
-}
-
-qreal QSGPathAnimation::endRotation() const
-{
-    Q_D(const QSGPathAnimation);
-    return d->endRotation.isNull ? qreal(0) : d->endRotation.value;
-}
-
-void QSGPathAnimation::setEndRotation(qreal rotation)
-{
-    Q_D(QSGPathAnimation);
-    if (!d->endRotation.isNull && d->endRotation == rotation)
-        return;
-
-    d->endRotation = rotation;
-    emit endRotationChanged(d->endRotation);
-}
-
-
-QAbstractAnimation *QSGPathAnimation::qtAnimation()
-{
-    Q_D(QSGPathAnimation);
-    return d->pa;
-}
-
-void QSGPathAnimation::transition(QDeclarativeStateActions &actions,
-                                           QDeclarativeProperties &modified,
-                                           TransitionDirection direction)
-{
-    Q_D(QSGPathAnimation);
-    QSGPathAnimationUpdater *data = new QSGPathAnimationUpdater;
-
-    data->orientation = d->orientation;
-    data->anchorPoint = d->anchorPoint;
-    data->entryInterval = d->entryInterval;
-    data->exitInterval = d->exitInterval;
-    data->endRotation = d->endRotation;
-    data->reverse = direction == Backward ? true : false;
-    data->fromSourced = false;
-    data->fromDefined = (d->path && d->path->hasStartX() && d->path->hasStartY()) ? true : false;
-    data->toDefined = d->path ? d->path->hasEnd() : false;
-    int origModifiedSize = modified.count();
-
-    for (int i = 0; i < actions.count(); ++i) {
-        QDeclarativeAction &action = actions[i];
-        if (action.event)
-            continue;
-        if (action.specifiedObject == d->target && action.property.name() == QLatin1String("x")) {
-            data->toX = action.toValue.toReal();
-            modified << action.property;
-            action.fromValue = action.toValue;
-        }
-        if (action.specifiedObject == d->target && action.property.name() == QLatin1String("y")) {
-            data->toY = action.toValue.toReal();
-            modified << action.property;
-            action.fromValue = action.toValue;
-        }
-    }
-
-    if (d->target && d->path &&
-        (modified.count() > origModifiedSize || data->toDefined)) {
-        data->target = d->target;
-        data->path = d->path;
-        if (!d->rangeIsSet) {
-            d->pa->setStartValue(qreal(0));
-            d->pa->setEndValue(qreal(1));
-            d->rangeIsSet = true;
-        }
-        /*
-            NOTE: The following block relies on the fact that the previous value hasn't
-            yet been deleted, and has the same target, etc, which may be a bit fragile.
-         */
-        if (d->pa->getAnimValue()) {
-            QSGPathAnimationUpdater *prevData = static_cast<QSGPathAnimationUpdater*>(d->pa->getAnimValue());
-
-            // get the original start angle that was used (so we can exactly reverse).
-            data->startRotation = prevData->startRotation;
-
-            // treat interruptions specially, otherwise we end up with strange paths
-            if ((data->reverse || prevData->reverse) && prevData->currentV > 0 && prevData->currentV < 1) {
-                if (!data->fromDefined && !data->toDefined && !prevData->painterPath.isEmpty()) {
-                    QPointF pathPos = QDeclarativePath::sequentialPointAt(prevData->painterPath, prevData->pathLength, prevData->attributePoints, prevData->prevBez, prevData->currentV);
-                    if (!prevData->anchorPoint.isNull())
-                        pathPos -= prevData->anchorPoint;
-                    if (pathPos == data->target->pos()) {   //only treat as interruption if we interrupted ourself
-                        data->painterPath = prevData->painterPath;
-                        data->toDefined = data->fromDefined = data->fromSourced = true;
-                        data->prevBez.isValid = false;
-                        data->interruptStart = prevData->currentV;
-                        data->startRotation = prevData->startRotation;
-                        data->pathLength = prevData->pathLength;
-                        data->attributePoints = prevData->attributePoints;
-                    }
-                }
-            }
-        }
-        d->pa->setFromSourcedValue(&data->fromSourced);
-        d->pa->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped);
-    } else {
-        d->pa->setFromSourcedValue(0);
-        d->pa->setAnimValue(0, QAbstractAnimation::DeleteWhenStopped);
-        delete data;
-    }
-}
-
-void QSGPathAnimationUpdater::setValue(qreal v)
-{
-    if (interruptStart.isValid()) {
-        if (reverse)
-            v = 1 - v;
-        qreal end = reverse ? 0.0 : 1.0;
-        v = interruptStart + v * (end-interruptStart);
-    }
-    currentV = v;
-    bool atStart = ((reverse && v == 1.0) || (!reverse && v == 0.0));
-    if (!fromSourced && (!fromDefined || !toDefined)) {
-        qreal startX = reverse ? toX + anchorPoint.x() : target->x() + anchorPoint.x();
-        qreal startY = reverse ? toY + anchorPoint.y() : target->y() + anchorPoint.y();
-        qreal endX = reverse ? target->x() + anchorPoint.x() : toX + anchorPoint.x();
-        qreal endY = reverse ? target->y() + anchorPoint.y() : toY + anchorPoint.y();
-
-        prevBez.isValid = false;
-        painterPath = path->createPath(QPointF(startX, startY), QPointF(endX, endY), QStringList(), pathLength, attributePoints);
-        fromSourced = true;
-    }
-
-    qreal angle;
-    bool fixed = orientation == QSGPathAnimation::Fixed;
-    QPointF currentPos = !painterPath.isEmpty() ? path->sequentialPointAt(painterPath, pathLength, attributePoints, prevBez, v, fixed ? 0 : &angle) : path->sequentialPointAt(v, fixed ? 0 : &angle);
-
-    //adjust position according to anchor point
-    if (!anchorPoint.isNull()) {
-        currentPos -= anchorPoint;
-        if (atStart) {
-            if (!anchorPoint.isNull() && !fixed)
-                target->setTransformOriginPoint(anchorPoint);
-        }
-    }
-
-    //### could cache properties rather than reconstructing each time
-    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) {
-        switch (orientation) {
-            case QSGPathAnimation::RightFirst:
-                angle = -angle;
-                break;
-            case QSGPathAnimation::TopFirst:
-                angle = -angle + 90;
-                break;
-            case QSGPathAnimation::LeftFirst:
-                angle = -angle + 180;
-                break;
-            case QSGPathAnimation::BottomFirst:
-                angle = -angle + 270;
-                break;
-            default:
-                angle = 0;
-                break;
-        }
-
-        if (atStart && !reverse) {
-            startRotation = target->rotation();
-
-            //shortest distance to correct orientation
-            qreal diff = angle - startRotation;
-            while (diff > 180.0) {
-                startRotation.value += 360.0;
-                diff -= 360.0;
-            }
-            while (diff < -180.0) {
-                startRotation.value -= 360.0;
-                diff += 360.0;
-            }
-        }
-
-        //smoothly transition to the desired orientation
-        if (startRotation.isValid()) {
-            if (reverse && v == 0.0)
-                angle = startRotation;
-            else if (v < entryInterval)
-                angle = angle * v / entryInterval + startRotation * (entryInterval - v) / entryInterval;
-        }
-        if (endRotation.isValid()) {
-            qreal exitStart = 1 - exitInterval;
-            if (!reverse && v == 1.0)
-                angle = endRotation;
-            else if (v > exitStart)
-                angle = endRotation * (v - exitStart) / exitInterval + angle * (exitInterval - (v - exitStart)) / exitInterval;
-        }
-        QDeclarativePropertyPrivate::write(QDeclarativeProperty(target, QStringLiteral("rotation")), angle, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding);
-    }
-
-    /*
-        NOTE: we don't always reset the transform origin, as it can cause a
-        visual jump if ending on an angle. This means that in some cases
-        (anchor point and orientation both specified, and ending at an angle)
-        the transform origin will always be set after running the path animation.
-     */
-    if ((reverse && v == 0.0) || (!reverse && v == 1.0)) {
-        if (!anchorPoint.isNull() && !fixed && qFuzzyIsNull(angle))
-            target->setTransformOriginPoint(QPointF());
-    }
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsganimation_p.h b/src/declarative/items/qsganimation_p.h
deleted file mode 100644 (file)
index af6279a..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-// Commit: e39a2e39451bf106a9845f8a60fc571faaa4dde5
-/****************************************************************************
-**
-** 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 QSGANIMATION_H
-#define QSGANIMATION_H
-
-#include "qsgitem.h"
-
-#include <private/qdeclarativeanimation_p.h>
-
-#include <QtCore/qabstractanimation.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGParentAnimationPrivate;
-class QSGParentAnimation : public QDeclarativeAnimationGroup
-{
-    Q_OBJECT
-    Q_DECLARE_PRIVATE(QSGParentAnimation)
-
-    Q_PROPERTY(QSGItem *target READ target WRITE setTarget NOTIFY targetChanged)
-    Q_PROPERTY(QSGItem *newParent READ newParent WRITE setNewParent NOTIFY newParentChanged)
-    Q_PROPERTY(QSGItem *via READ via WRITE setVia NOTIFY viaChanged)
-
-public:
-    QSGParentAnimation(QObject *parent=0);
-    virtual ~QSGParentAnimation();
-
-    QSGItem *target() const;
-    void setTarget(QSGItem *);
-
-    QSGItem *newParent() const;
-    void setNewParent(QSGItem *);
-
-    QSGItem *via() const;
-    void setVia(QSGItem *);
-
-Q_SIGNALS:
-    void targetChanged();
-    void newParentChanged();
-    void viaChanged();
-
-protected:
-    virtual void transition(QDeclarativeStateActions &actions,
-                            QDeclarativeProperties &modified,
-                            TransitionDirection direction);
-    virtual QAbstractAnimation *qtAnimation();
-};
-
-class QSGAnchorAnimationPrivate;
-class QSGAnchorAnimation : public QDeclarativeAbstractAnimation
-{
-    Q_OBJECT
-    Q_DECLARE_PRIVATE(QSGAnchorAnimation)
-    Q_PROPERTY(QDeclarativeListProperty<QSGItem> targets READ targets)
-    Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
-    Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged)
-
-public:
-    QSGAnchorAnimation(QObject *parent=0);
-    virtual ~QSGAnchorAnimation();
-
-    QDeclarativeListProperty<QSGItem> targets();
-
-    int duration() const;
-    void setDuration(int);
-
-    QEasingCurve easing() const;
-    void setEasing(const QEasingCurve &);
-
-Q_SIGNALS:
-    void durationChanged(int);
-    void easingChanged(const QEasingCurve&);
-
-protected:
-    virtual void transition(QDeclarativeStateActions &actions,
-                            QDeclarativeProperties &modified,
-                            TransitionDirection direction);
-    virtual QAbstractAnimation *qtAnimation();
-};
-
-class QSGItem;
-class QDeclarativePath;
-class QSGPathAnimationPrivate;
-class Q_AUTOTEST_EXPORT QSGPathAnimation : public QDeclarativeAbstractAnimation
-{
-    Q_OBJECT
-    Q_DECLARE_PRIVATE(QSGPathAnimation)
-
-    Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
-    Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged)
-    Q_PROPERTY(QDeclarativePath *path READ path WRITE setPath NOTIFY pathChanged)
-    Q_PROPERTY(QSGItem *target READ target WRITE setTarget NOTIFY targetChanged)
-    Q_PROPERTY(Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged)
-    Q_PROPERTY(QPointF anchorPoint READ anchorPoint WRITE setAnchorPoint NOTIFY anchorPointChanged)
-    Q_PROPERTY(qreal orientationEntryInterval READ orientationEntryInterval WRITE setOrientationEntryInterval NOTIFY orientationEntryIntervalChanged)
-    Q_PROPERTY(qreal orientationExitInterval READ orientationExitInterval WRITE setOrientationExitInterval NOTIFY orientationExitIntervalChanged)
-    Q_PROPERTY(qreal endRotation READ endRotation WRITE setEndRotation NOTIFY endRotationChanged)
-
-public:
-    QSGPathAnimation(QObject *parent=0);
-    virtual ~QSGPathAnimation();
-
-    enum Orientation {
-        Fixed,
-        RightFirst,
-        LeftFirst,
-        BottomFirst,
-        TopFirst
-    };
-    Q_ENUMS(Orientation)
-
-    int duration() const;
-    void setDuration(int);
-
-    QEasingCurve easing() const;
-    void setEasing(const QEasingCurve &);
-
-    QDeclarativePath *path() const;
-    void setPath(QDeclarativePath *);
-
-    QSGItem *target() const;
-    void setTarget(QSGItem *);
-
-    Orientation orientation() const;
-    void setOrientation(Orientation orientation);
-
-    QPointF anchorPoint() const;
-    void setAnchorPoint(const QPointF &point);
-
-    qreal orientationEntryInterval() const;
-    void setOrientationEntryInterval(qreal);
-
-    qreal orientationExitInterval() const;
-    void setOrientationExitInterval(qreal);
-
-    qreal endRotation() const;
-    void setEndRotation(qreal);
-
-protected:
-    virtual void transition(QDeclarativeStateActions &actions,
-                            QDeclarativeProperties &modified,
-                            TransitionDirection direction);
-    virtual QAbstractAnimation *qtAnimation();
-
-Q_SIGNALS:
-    void durationChanged(int);
-    void easingChanged(const QEasingCurve &);
-    void pathChanged();
-    void targetChanged();
-    void orientationChanged(Orientation);
-    void anchorPointChanged(const QPointF &);
-    void orientationEntryIntervalChanged(qreal);
-    void orientationExitIntervalChanged(qreal);
-    void endRotationChanged(qreal);
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGParentAnimation)
-QML_DECLARE_TYPE(QSGAnchorAnimation)
-QML_DECLARE_TYPE(QSGPathAnimation)
-
-QT_END_HEADER
-
-#endif // QSGANIMATION_H
diff --git a/src/declarative/items/qsganimation_p_p.h b/src/declarative/items/qsganimation_p_p.h
deleted file mode 100644 (file)
index 276efc5..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-// Commit: 0ade09152067324f74678f2de4d447b6e0280600
-/****************************************************************************
-**
-** 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 QSGANIMATION_P_H
-#define QSGANIMATION_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 "qsganimation_p.h"
-
-#include <private/qdeclarativepath_p.h>
-#include <private/qdeclarativeanimation_p_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGParentAnimationPrivate : public QDeclarativeAnimationGroupPrivate
-{
-    Q_DECLARE_PUBLIC(QSGParentAnimation)
-public:
-    QSGParentAnimationPrivate()
-    : QDeclarativeAnimationGroupPrivate(), target(0), newParent(0),
-       via(0), topLevelGroup(0), startAction(0), endAction(0) {}
-
-    QSGItem *target;
-    QSGItem *newParent;
-    QSGItem *via;
-
-    QSequentialAnimationGroup *topLevelGroup;
-    QActionAnimation *startAction;
-    QActionAnimation *endAction;
-
-    QPointF computeTransformOrigin(QSGItem::TransformOrigin origin, qreal width, qreal height) const;
-};
-
-class QSGAnchorAnimationPrivate : public QDeclarativeAbstractAnimationPrivate
-{
-    Q_DECLARE_PUBLIC(QSGAnchorAnimation)
-public:
-    QSGAnchorAnimationPrivate() : rangeIsSet(false), va(0),
-        interpolator(QVariantAnimationPrivate::getInterpolator(QMetaType::QReal)) {}
-
-    bool rangeIsSet;
-    QDeclarativeBulkValueAnimator *va;
-    QVariantAnimation::Interpolator interpolator;
-    QList<QSGItem*> targets;
-};
-
-class QSGPathAnimationUpdater : public QDeclarativeBulkValueUpdater
-{
-public:
-    QSGPathAnimationUpdater() : path(0), target(0), reverse(false),
-        fromSourced(false), fromDefined(false), toDefined(false),
-        toX(0), toY(0), currentV(0), orientation(QSGPathAnimation::Fixed),
-        entryInterval(0), exitInterval(0) {}
-    ~QSGPathAnimationUpdater() {}
-
-        void setValue(qreal v);
-
-    QDeclarativePath *path;
-
-    QPainterPath painterPath;
-    QDeclarativeCachedBezier prevBez;
-    qreal pathLength;
-    QList<QDeclarativePath::AttributePoint> attributePoints;
-
-    QSGItem *target;
-    bool reverse;
-    bool fromSourced;
-    bool fromDefined;
-    bool toDefined;
-    qreal toX;
-    qreal toY;
-    qreal currentV;
-    QDeclarativeNullableValue<qreal> interruptStart;
-    //TODO: bundle below into common struct
-    QSGPathAnimation::Orientation orientation;
-    QPointF anchorPoint;
-    qreal entryInterval;
-    qreal exitInterval;
-    QDeclarativeNullableValue<qreal> endRotation;
-    QDeclarativeNullableValue<qreal> startRotation;
-};
-
-class QSGPathAnimationPrivate : public QDeclarativeAbstractAnimationPrivate
-{
-    Q_DECLARE_PUBLIC(QSGPathAnimation)
-public:
-    QSGPathAnimationPrivate() : path(0), target(0),
-        rangeIsSet(false), orientation(QSGPathAnimation::Fixed), entryInterval(0), exitInterval(0), pa(0) {}
-
-    QDeclarativePath *path;
-    QSGItem *target;
-    bool rangeIsSet;
-    QSGPathAnimation::Orientation orientation;
-    QPointF anchorPoint;
-    qreal entryInterval;
-    qreal exitInterval;
-    QDeclarativeNullableValue<qreal> endRotation;
-    QDeclarativeBulkValueAnimator *pa;
-};
-
-
-QT_END_NAMESPACE
-
-#endif // QSGANIMATION_P_H
diff --git a/src/declarative/items/qsgborderimage.cpp b/src/declarative/items/qsgborderimage.cpp
deleted file mode 100644 (file)
index fb407d7..0000000
+++ /dev/null
@@ -1,601 +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 "qsgborderimage_p.h"
-#include "qsgborderimage_p_p.h"
-#include "qsgninepatchnode_p.h"
-
-#include <QtDeclarative/qdeclarativeinfo.h>
-#include <QtCore/qfile.h>
-
-#include <private/qdeclarativeengine_p.h>
-
-QT_BEGIN_NAMESPACE
-
-
-/*!
-    \qmlclass BorderImage QSGBorderImage
-    \inqmlmodule QtQuick 2
-    \brief The BorderImage element provides an image that can be used as a border.
-    \inherits Item
-    \ingroup qml-basic-visual-elements
-
-    The BorderImage element is used to create borders out of images by scaling or tiling
-    parts of each image.
-
-    A BorderImage element breaks a source image, specified using the \l url property,
-    into 9 regions, as shown below:
-
-    \image declarative-scalegrid.png
-
-    When the image is scaled, regions of the source image are scaled or tiled to
-    create the displayed border image in the following way:
-
-    \list
-    \i The corners (regions 1, 3, 7, and 9) are not scaled at all.
-    \i Regions 2 and 8 are scaled according to
-       \l{BorderImage::horizontalTileMode}{horizontalTileMode}.
-    \i Regions 4 and 6 are scaled according to
-       \l{BorderImage::verticalTileMode}{verticalTileMode}.
-    \i The middle (region 5) is scaled according to both
-       \l{BorderImage::horizontalTileMode}{horizontalTileMode} and
-       \l{BorderImage::verticalTileMode}{verticalTileMode}.
-    \endlist
-
-    The regions of the image are defined using the \l border property group, which
-    describes the distance from each edge of the source image to use as a border.
-
-    \section1 Example Usage
-
-    The following examples show the effects of the different modes on an image.
-    Guide lines are overlaid onto the image to show the different regions of the
-    image as described above.
-
-    \beginfloatleft
-    \image qml-borderimage-normal-image.png
-    \endfloat
-
-    An unscaled image is displayed using an Image element. The \l border property is
-    used to determine the parts of the image that will lie inside the unscaled corner
-    areas and the parts that will be stretched horizontally and vertically.
-
-    \snippet doc/src/snippets/declarative/borderimage/normal-image.qml normal image
-
-    \clearfloat
-    \beginfloatleft
-    \image qml-borderimage-scaled.png
-    \endfloat
-
-    A BorderImage element is used to display the image, and it is given a size that is
-    larger than the original image. Since the \l horizontalTileMode property is set to
-    \l{BorderImage::horizontalTileMode}{BorderImage.Stretch}, the parts of image in
-    regions 2 and 8 are stretched horizontally. Since the \l verticalTileMode property
-    is set to \l{BorderImage::verticalTileMode}{BorderImage.Stretch}, the parts of image
-    in regions 4 and 6 are stretched vertically.
-
-    \snippet doc/src/snippets/declarative/borderimage/borderimage-scaled.qml scaled border image
-
-    \clearfloat
-    \beginfloatleft
-    \image qml-borderimage-tiled.png
-    \endfloat
-
-    Again, a large BorderImage element is used to display the image. With the
-    \l horizontalTileMode property set to \l{BorderImage::horizontalTileMode}{BorderImage.Repeat},
-    the parts of image in regions 2 and 8 are tiled so that they fill the space at the
-    top and bottom of the element. Similarly, the \l verticalTileMode property is set to
-    \l{BorderImage::verticalTileMode}{BorderImage.Repeat}, the parts of image in regions
-    4 and 6 are tiled so that they fill the space at the left and right of the element.
-
-    \snippet doc/src/snippets/declarative/borderimage/borderimage-tiled.qml tiled border image
-
-    \clearfloat
-    In some situations, the width of regions 2 and 8 may not be an exact multiple of the width
-    of the corresponding regions in the source image. Similarly, the height of regions 4 and 6
-    may not be an exact multiple of the height of the corresponding regions. It can be useful
-    to use \l{BorderImage::horizontalTileMode}{BorderImage.Round} instead of
-    \l{BorderImage::horizontalTileMode}{BorderImage.Repeat} in cases like these.
-
-    The \l{declarative/imageelements/borderimage}{BorderImage example} shows how a BorderImage
-    can be used to simulate a shadow effect on a rectangular item.
-
-    \section1 Quality and Performance
-
-    By default, any scaled regions of the image are rendered without smoothing to improve
-    rendering speed. Setting the \l smooth property improves rendering quality of scaled
-    regions, but may slow down rendering.
-
-    The source image may not be loaded instantaneously, depending on its original location.
-    Loading progress can be monitored with the \l progress property.
-
-    \sa Image, AnimatedImage
- */
-
-/*!
-    \qmlproperty bool QtQuick2::BorderImage::asynchronous
-
-    Specifies that images on the local filesystem should be loaded
-    asynchronously in a separate thread.  The default value is
-    false, causing the user interface thread to block while the
-    image is loaded.  Setting \a asynchronous to true is useful where
-    maintaining a responsive user interface is more desirable
-    than having images immediately visible.
-
-    Note that this property is only valid for images read from the
-    local filesystem.  Images loaded via a network resource (e.g. HTTP)
-    are always loaded asynchonously.
-*/
-QSGBorderImage::QSGBorderImage(QSGItem *parent)
-: QSGImageBase(*(new QSGBorderImagePrivate), parent)
-{
-}
-
-QSGBorderImage::~QSGBorderImage()
-{
-    Q_D(QSGBorderImage);
-    if (d->sciReply)
-        d->sciReply->deleteLater();
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::BorderImage::status
-
-    This property describes the status of image loading.  It can be one of:
-
-    \list
-    \o BorderImage.Null - no image has been set
-    \o BorderImage.Ready - the image has been loaded
-    \o BorderImage.Loading - the image is currently being loaded
-    \o BorderImage.Error - an error occurred while loading the image
-    \endlist
-
-    \sa progress
-*/
-
-/*!
-    \qmlproperty real QtQuick2::BorderImage::progress
-
-    This property holds the progress of image loading, from 0.0 (nothing loaded)
-    to 1.0 (finished).
-
-    \sa status
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::BorderImage::smooth
-
-    Set this property if you want the image to be smoothly filtered when scaled or
-    transformed.  Smooth filtering gives better visual quality, but is slower.  If
-    the image is displayed at its natural size, this property has no visual or
-    performance effect.
-
-    By default, this property is set to false.
-
-    \note Generally scaling artifacts are only visible if the image is stationary on
-    the screen.  A common pattern when animating an image is to disable smooth
-    filtering at the beginning of the animation and enable it at the conclusion.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::BorderImage::cache
-
-    Specifies whether the image should be cached. The default value is
-    true. Setting \a cache to false is useful when dealing with large images,
-    to make sure that they aren't cached at the expense of small 'ui element' images.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::BorderImage::mirror
-
-    This property holds whether the image should be horizontally inverted
-    (effectively displaying a mirrored image).
-
-    The default value is false.
-*/
-
-/*!
-    \qmlproperty url QtQuick2::BorderImage::source
-
-    This property holds the URL that refers to the source image.
-
-    BorderImage can handle any image format supported by Qt, loaded from any
-    URL scheme supported by Qt.
-
-    This property can also be used to refer to .sci files, which are
-    written in a QML-specific, text-based format that specifies the
-    borders, the image file and the tile rules for a given border image.
-
-    The following .sci file sets the borders to 10 on each side for the
-    image \c picture.png:
-
-    \code
-    border.left: 10
-    border.top: 10
-    border.bottom: 10
-    border.right: 10
-    source: "picture.png"
-    \endcode
-
-    The URL may be absolute, or relative to the URL of the component.
-
-    \sa QDeclarativeImageProvider
-*/
-
-/*!
-    \qmlproperty QSize QtQuick2::BorderImage::sourceSize
-
-    This property holds the actual width and height of the loaded image.
-
-    In BorderImage, this property is read-only.
-
-    \sa Image::sourceSize
-*/
-void QSGBorderImage::setSource(const QUrl &url)
-{
-    Q_D(QSGBorderImage);
-    //equality is fairly expensive, so we bypass for simple, common case
-    if ((d->url.isEmpty() == url.isEmpty()) && url == d->url)
-        return;
-
-    if (d->sciReply) {
-        d->sciReply->deleteLater();
-        d->sciReply = 0;
-    }
-
-    d->url = url;
-    d->sciurl = QUrl();
-    emit sourceChanged(d->url);
-
-    if (isComponentComplete())
-        load();
-}
-
-void QSGBorderImage::load()
-{
-    Q_D(QSGBorderImage);
-    if (d->progress != 0.0) {
-        d->progress = 0.0;
-        emit progressChanged(d->progress);
-    }
-
-    if (d->url.isEmpty()) {
-        d->pix.clear(this);
-        d->status = Null;
-        setImplicitWidth(0);
-        setImplicitHeight(0);
-        emit statusChanged(d->status);
-        update();
-    } else {
-        d->status = Loading;
-        if (d->url.path().endsWith(QLatin1String("sci"))) {
-            QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(d->url);
-            if (!lf.isEmpty()) {
-                QFile file(lf);
-                file.open(QIODevice::ReadOnly);
-                setGridScaledImage(QSGGridScaledImage(&file));
-            } else {
-                QNetworkRequest req(d->url);
-                d->sciReply = qmlEngine(this)->networkAccessManager()->get(req);
-                FAST_CONNECT(d->sciReply, SIGNAL(finished()), this, SLOT(sciRequestFinished()))
-            }
-        } else {
-
-            QDeclarativePixmap::Options options;
-            if (d->async)
-                options |= QDeclarativePixmap::Asynchronous;
-            if (d->cache)
-                options |= QDeclarativePixmap::Cache;
-            d->pix.clear(this);
-            d->pix.load(qmlEngine(this), d->url, options);
-
-            if (d->pix.isLoading()) {
-                d->pix.connectFinished(this, SLOT(requestFinished()));
-                d->pix.connectDownloadProgress(this, SLOT(requestProgress(qint64,qint64)));
-            } else {
-                QSize impsize = d->pix.implicitSize();
-                setImplicitWidth(impsize.width());
-                setImplicitHeight(impsize.height());
-
-                if (d->pix.isReady()) {
-                    d->status = Ready;
-                } else {
-                    d->status = Error;
-                    qmlInfo(this) << d->pix.error();
-                }
-
-                d->progress = 1.0;
-                emit statusChanged(d->status);
-                emit progressChanged(d->progress);
-                update();
-            }
-        }
-    }
-
-    emit statusChanged(d->status);
-}
-
-/*!
-    \qmlproperty int QtQuick2::BorderImage::border.left
-    \qmlproperty int QtQuick2::BorderImage::border.right
-    \qmlproperty int QtQuick2::BorderImage::border.top
-    \qmlproperty int QtQuick2::BorderImage::border.bottom
-
-    The 4 border lines (2 horizontal and 2 vertical) break the image into 9 sections,
-    as shown below:
-
-    \image declarative-scalegrid.png
-
-    Each border line (left, right, top, and bottom) specifies an offset in pixels
-    from the respective edge of the source image. By default, each border line has
-    a value of 0.
-
-    For example, the following definition sets the bottom line 10 pixels up from
-    the bottom of the image:
-
-    \qml
-    BorderImage {
-        border.bottom: 10
-        // ...
-    }
-    \endqml
-
-    The border lines can also be specified using a
-    \l {BorderImage::source}{.sci file}.
-*/
-
-QSGScaleGrid *QSGBorderImage::border()
-{
-    Q_D(QSGBorderImage);
-    return d->getScaleGrid();
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::BorderImage::horizontalTileMode
-    \qmlproperty enumeration QtQuick2::BorderImage::verticalTileMode
-
-    This property describes how to repeat or stretch the middle parts of the border image.
-
-    \list
-    \o BorderImage.Stretch - Scales the image to fit to the available area.
-    \o BorderImage.Repeat - Tile the image until there is no more space. May crop the last image.
-    \o BorderImage.Round - Like Repeat, but scales the images down to ensure that the last image is not cropped.
-    \endlist
-
-    The default tile mode for each property is BorderImage.Stretch.
-*/
-QSGBorderImage::TileMode QSGBorderImage::horizontalTileMode() const
-{
-    Q_D(const QSGBorderImage);
-    return d->horizontalTileMode;
-}
-
-void QSGBorderImage::setHorizontalTileMode(TileMode t)
-{
-    Q_D(QSGBorderImage);
-    if (t != d->horizontalTileMode) {
-        d->horizontalTileMode = t;
-        emit horizontalTileModeChanged();
-        update();
-    }
-}
-
-QSGBorderImage::TileMode QSGBorderImage::verticalTileMode() const
-{
-    Q_D(const QSGBorderImage);
-    return d->verticalTileMode;
-}
-
-void QSGBorderImage::setVerticalTileMode(TileMode t)
-{
-    Q_D(QSGBorderImage);
-    if (t != d->verticalTileMode) {
-        d->verticalTileMode = t;
-        emit verticalTileModeChanged();
-        update();
-    }
-}
-
-void QSGBorderImage::setGridScaledImage(const QSGGridScaledImage& sci)
-{
-    Q_D(QSGBorderImage);
-    if (!sci.isValid()) {
-        d->status = Error;
-        emit statusChanged(d->status);
-    } else {
-        QSGScaleGrid *sg = border();
-        sg->setTop(sci.gridTop());
-        sg->setBottom(sci.gridBottom());
-        sg->setLeft(sci.gridLeft());
-        sg->setRight(sci.gridRight());
-        d->horizontalTileMode = sci.horizontalTileRule();
-        d->verticalTileMode = sci.verticalTileRule();
-
-        d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl()));
-
-        QDeclarativePixmap::Options options;
-        if (d->async)
-            options |= QDeclarativePixmap::Asynchronous;
-        if (d->cache)
-            options |= QDeclarativePixmap::Cache;
-        d->pix.clear(this);
-        d->pix.load(qmlEngine(this), d->sciurl, options);
-
-        if (d->pix.isLoading()) {
-            static int thisRequestProgress = -1;
-            static int thisRequestFinished = -1;
-            if (thisRequestProgress == -1) {
-                thisRequestProgress =
-                    QSGBorderImage::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
-                thisRequestFinished =
-                    QSGBorderImage::staticMetaObject.indexOfSlot("requestFinished()");
-            }
-
-            d->pix.connectFinished(this, thisRequestFinished);
-            d->pix.connectDownloadProgress(this, thisRequestProgress);
-
-        } else {
-
-            QSize impsize = d->pix.implicitSize();
-            setImplicitWidth(impsize.width());
-            setImplicitHeight(impsize.height());
-
-            if (d->pix.isReady()) {
-                d->status = Ready;
-            } else {
-                d->status = Error;
-                qmlInfo(this) << d->pix.error();
-            }
-
-            d->progress = 1.0;
-            emit statusChanged(d->status);
-            emit progressChanged(1.0);
-            update();
-
-        }
-    }
-}
-
-void QSGBorderImage::requestFinished()
-{
-    Q_D(QSGBorderImage);
-
-    QSize impsize = d->pix.implicitSize();
-    if (d->pix.isError()) {
-        d->status = Error;
-        qmlInfo(this) << d->pix.error();
-    } else {
-        d->status = Ready;
-    }
-
-    setImplicitWidth(impsize.width());
-    setImplicitHeight(impsize.height());
-
-    if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height())
-        emit sourceSizeChanged();
-
-    d->progress = 1.0;
-    emit statusChanged(d->status);
-    emit progressChanged(1.0);
-    update();
-}
-
-#define BORDERIMAGE_MAX_REDIRECT 16
-
-void QSGBorderImage::sciRequestFinished()
-{
-    Q_D(QSGBorderImage);
-
-    d->redirectCount++;
-    if (d->redirectCount < BORDERIMAGE_MAX_REDIRECT) {
-        QVariant redirect = d->sciReply->attribute(QNetworkRequest::RedirectionTargetAttribute);
-        if (redirect.isValid()) {
-            QUrl url = d->sciReply->url().resolved(redirect.toUrl());
-            setSource(url);
-            return;
-        }
-    }
-    d->redirectCount=0;
-
-    if (d->sciReply->error() != QNetworkReply::NoError) {
-        d->status = Error;
-        d->sciReply->deleteLater();
-        d->sciReply = 0;
-        emit statusChanged(d->status);
-    } else {
-        QSGGridScaledImage sci(d->sciReply);
-        d->sciReply->deleteLater();
-        d->sciReply = 0;
-        setGridScaledImage(sci);
-    }
-}
-
-void QSGBorderImage::doUpdate()
-{
-    update();
-}
-
-QSGNode *QSGBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
-{
-    Q_D(QSGBorderImage);
-
-    QSGTexture *texture = d->pix.texture(d->sceneGraphContext());
-
-    if (!texture || width() <= 0 || height() <= 0) {
-        delete oldNode;
-        return 0;
-    }
-
-    QSGNinePatchNode *node = static_cast<QSGNinePatchNode *>(oldNode);
-
-    if (!node) {
-        node = new QSGNinePatchNode();
-    }
-
-    node->setTexture(texture);
-
-    // Don't implicitly create the scalegrid in the rendering thread...
-    if (d->border) {
-        const QSGScaleGrid *border = d->getScaleGrid();
-        node->setInnerRect(QRectF(border->left(),
-                                  border->top(),
-                                  qMax(1, d->pix.width() - border->right() - border->left()),
-                                  qMax(1, d->pix.height() - border->bottom() - border->top())));
-    } else {
-        node->setInnerRect(QRectF(0, 0, width(), height()));
-    }
-    node->setRect(QRectF(0, 0, width(), height()));
-    node->setFiltering(d->smooth ? QSGTexture::Linear : QSGTexture::Nearest);
-    node->setHorzontalTileMode(d->horizontalTileMode);
-    node->setVerticalTileMode(d->verticalTileMode);
-    node->setMirror(d->mirror);
-    node->update();
-
-    return node;
-}
-
-void QSGBorderImage::pixmapChange()
-{
-    Q_D(QSGBorderImage);
-
-    d->pixmapChanged = true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgborderimage_p.h b/src/declarative/items/qsgborderimage_p.h
deleted file mode 100644 (file)
index c88a61b..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-// Commit: ebd4bc73c46c2962742a682b6a391fb68c482aec
-/****************************************************************************
-**
-** 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 QSGBORDERIMAGE_P_H
-#define QSGBORDERIMAGE_P_H
-
-#include "qsgimagebase_p.h"
-
-QT_BEGIN_HEADER
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGScaleGrid;
-class QSGGridScaledImage;
-class QSGBorderImagePrivate;
-class Q_AUTOTEST_EXPORT QSGBorderImage : public QSGImageBase
-{
-    Q_OBJECT
-    Q_ENUMS(TileMode)
-
-    Q_PROPERTY(QSGScaleGrid *border READ border CONSTANT)
-    Q_PROPERTY(TileMode horizontalTileMode READ horizontalTileMode WRITE setHorizontalTileMode NOTIFY horizontalTileModeChanged)
-    Q_PROPERTY(TileMode verticalTileMode READ verticalTileMode WRITE setVerticalTileMode NOTIFY verticalTileModeChanged)
-    // read-only for BorderImage
-    Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged)
-
-public:
-    QSGBorderImage(QSGItem *parent=0);
-    ~QSGBorderImage();
-
-    QSGScaleGrid *border();
-
-    enum TileMode { Stretch = Qt::StretchTile, Repeat = Qt::RepeatTile, Round = Qt::RoundTile };
-
-    TileMode horizontalTileMode() const;
-    void setHorizontalTileMode(TileMode);
-
-    TileMode verticalTileMode() const;
-    void setVerticalTileMode(TileMode);
-
-    void setSource(const QUrl &url);
-
-Q_SIGNALS:
-    void horizontalTileModeChanged();
-    void verticalTileModeChanged();
-    void sourceSizeChanged();
-
-protected:
-    virtual void load();
-    virtual void pixmapChange();
-    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
-
-private:
-    void setGridScaledImage(const QSGGridScaledImage& sci);
-
-private Q_SLOTS:
-    void doUpdate();
-    void requestFinished();
-    void sciRequestFinished();
-
-private:
-    Q_DISABLE_COPY(QSGBorderImage)
-    Q_DECLARE_PRIVATE(QSGBorderImage)
-};
-
-QT_END_NAMESPACE
-QML_DECLARE_TYPE(QSGBorderImage)
-QT_END_HEADER
-
-#endif // QSGBORDERIMAGE_P_H
diff --git a/src/declarative/items/qsgborderimage_p_p.h b/src/declarative/items/qsgborderimage_p_p.h
deleted file mode 100644 (file)
index 2781669..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
-/****************************************************************************
-**
-** 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 QSGBORDERIMAGE_P_P_H
-#define QSGBORDERIMAGE_P_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 "qsgimagebase_p_p.h"
-#include "qsgscalegrid_p_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QNetworkReply;
-class QSGBorderImagePrivate : public QSGImageBasePrivate
-{
-    Q_DECLARE_PUBLIC(QSGBorderImage)
-
-public:
-    QSGBorderImagePrivate()
-      : border(0), sciReply(0),
-        horizontalTileMode(QSGBorderImage::Stretch),
-        verticalTileMode(QSGBorderImage::Stretch),
-        redirectCount(0), pixmapChanged(false)
-    {
-    }
-
-    ~QSGBorderImagePrivate()
-    {
-    }
-
-
-    QSGScaleGrid *getScaleGrid()
-    {
-        Q_Q(QSGBorderImage);
-        if (!border) {
-            border = new QSGScaleGrid(q);
-            FAST_CONNECT(border, SIGNAL(borderChanged()), q, SLOT(doUpdate()))
-        }
-        return border;
-    }
-
-    QSGScaleGrid *border;
-    QUrl sciurl;
-    QNetworkReply *sciReply;
-    QSGBorderImage::TileMode horizontalTileMode;
-    QSGBorderImage::TileMode verticalTileMode;
-    int redirectCount;
-
-    bool pixmapChanged : 1;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGBORDERIMAGE_P_P_H
diff --git a/src/declarative/items/qsgcanvas.cpp b/src/declarative/items/qsgcanvas.cpp
deleted file mode 100644 (file)
index 1e35627..0000000
+++ /dev/null
@@ -1,2399 +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$
-**
-****************************************************************************/
-
-#include "qsgcanvas.h"
-#include "qsgcanvas_p.h"
-
-#include "qsgitem.h"
-#include "qsgitem_p.h"
-
-#include <private/qsgrenderer_p.h>
-#include <private/qsgflashnode_p.h>
-
-#include <private/qguiapplication_p.h>
-#include <QtGui/QInputPanel>
-
-#include <private/qabstractanimation_p.h>
-
-#include <QtGui/qpainter.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qmatrix4x4.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qabstractanimation.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)
-
-extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha);
-
-void QSGCanvasPrivate::updateFocusItemTransform()
-{
-    Q_Q(QSGCanvas);
-    QSGItem *focus = q->activeFocusItem();
-    if (focus && qApp->inputPanel()->inputItem() == focus)
-        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:
-    QSGCanvasPlainRenderLoop()
-        : updatePending(false)
-        , animationRunning(false)
-    {
-        qWarning("QSGCanvas: using non-threaded render loop. Be very sure to not access scene graph "
-                 "objects outside the QSGItem::updatePaintNode() call. Failing to do so will cause "
-                 "your code to crash on other platforms!");
-    }
-
-    virtual void paint() {
-        updatePending = false;
-        if (animationRunning && animationDriver())
-            animationDriver()->advance();
-        polishItems();
-        syncSceneGraph();
-        makeCurrent();
-        glViewport(0, 0, size.width(), size.height());
-        renderSceneGraph(size);
-        swapBuffers();
-
-        if (animationRunning)
-            maybeUpdate();
-    }
-
-    virtual QImage grab() {
-        return qt_gl_read_framebuffer(size, false, false);
-    }
-
-    virtual void startRendering() {
-        if (!glContext()) {
-            createGLContext();
-            makeCurrent();
-            initializeSceneGraph();
-        } else {
-            makeCurrent();
-        }
-        maybeUpdate();
-    }
-
-    virtual void stopRendering() { }
-
-    virtual void maybeUpdate() {
-        if (!updatePending) {
-            QCoreApplication::postEvent(this, new QEvent(QEvent::User));
-            updatePending = true;
-        }
-    }
-
-    virtual void animationStarted() {
-        animationRunning = true;
-        maybeUpdate();
-    }
-
-    virtual void animationStopped() {
-        animationRunning = false;
-    }
-
-    virtual bool isRunning() const { return glContext(); } // Event loop is always running...
-    virtual void resize(const QSize &s) { size = s; }
-    virtual void setWindowSize(const QSize &s) { size = s; }
-
-    bool event(QEvent *e) {
-        if (e->type() == QEvent::User) {
-            paint();
-            return true;
-        }
-        return QObject::event(e);
-    }
-
-    QSize size;
-
-    uint updatePending : 1;
-    uint animationRunning : 1;
-};
-
-
-
-/*
-Focus behavior
-==============
-
-Prior to being added to a valid canvas items can set and clear focus with no
-effect.  Only once items are added to a canvas (by way of having a parent set that
-already belongs to a canvas) do the focus rules apply.  Focus goes back to
-having no effect if an item is removed from a canvas.
-
-When an item is moved into a new focus scope (either being added to a canvas
-for the first time, or having its parent changed), if the focus scope already has
-a scope focused item that takes precedence over the item being added.  Otherwise,
-the focus of the added tree is used.  In the case of of a tree of items being
-added to a canvas for the first time, which may have a conflicted focus state (two
-or more items in one scope having focus set), the same rule is applied item by item -
-thus the first item that has focus will get it (assuming the scope doesn't already
-have a scope focused item), and the other items will have their focus cleared.
-*/
-
-/*
-  Threaded Rendering
-  ==================
-
-  The threaded rendering uses a number of different variables to track potential
-  states used to handle resizing, initial paint, grabbing and driving animations
-  while ALWAYS keeping the GL context in the rendering thread and keeping the
-  overhead of normal one-shot paints and vblank driven animations at a minimum.
-
-  Resize, initial show and grab suffer slightly in this model as they are locked
-  to the rendering in the rendering thread, but this is a necessary evil for
-  the system to work.
-
-  Variables that are used:
-
-  Private::animationRunning: This is true while the animations are running, and only
-  written to inside locks.
-
-  RenderThread::isGuiBlocked: This is used to indicate that the GUI thread owns the
-  lock. This variable is an integer to allow for recursive calls to lockInGui()
-  without using a recursive mutex. See isGuiBlockPending.
-
-  RenderThread::isPaintComplete: This variable is cleared when rendering starts and
-  set once rendering is complete. It is monitored in the paintEvent(),
-  resizeEvent() and grab() functions to force them to wait for rendering to
-  complete.
-
-  RenderThread::isGuiBlockPending: This variable is set in the render thread just
-  before the sync event is sent to the GUI thread. It is used to avoid deadlocks
-  in the case where render thread waits while waiting for GUI to pick up the sync
-  event and GUI thread gets a resizeEvent, the initial paintEvent or a grab.
-  When this happens, we use the
-  exhaustSyncEvent() function to do the sync right there and mark the coming
-  sync event to be discarded. There can only ever be one sync incoming.
-
-  RenderThread::isRenderBlock: This variable is true when animations are not
-  running and the render thread has gone to sleep, waiting for more to do.
-
-  RenderThread::isExternalUpdatePending: This variable is set to false during
-  the sync phase in the GUI thread and to true in maybeUpdate(). It is an
-  indication to the render thread that another render pass needs to take
-  place, rather than the render thread going to sleep after completing its swap.
-
-  RenderThread::doGrab: This variable is set by the grab() function and
-  tells the renderer to do a grab after rendering is complete and before
-  swapping happens.
-
-  RenderThread::shouldExit: This variable is used to determine if the render
-  thread should do a nother pass. It is typically set as a result of show()
-  and unset as a result of hide() or during shutdown()
-
-  RenderThread::hasExited: Used by the GUI thread to synchronize the shutdown
-  after shouldExit has been set to true.
- */
-
-// #define FOCUS_DEBUG
-// #define MOUSE_DEBUG
-// #define TOUCH_DEBUG
-// #define DIRTY_DEBUG
-// #define THREAD_DEBUG
-
-// #define FRAME_TIMING
-
-#ifdef FRAME_TIMING
-static QTime frameTimer;
-int sceneGraphRenderTime;
-int readbackTime;
-#endif
-
-QSGItem::UpdatePaintNodeData::UpdatePaintNodeData()
-: transformNode(0)
-{
-}
-
-QSGRootItem::QSGRootItem()
-{
-}
-
-void QSGCanvas::exposeEvent(QExposeEvent *)
-{
-    Q_D(QSGCanvas);
-    d->thread->paint();
-}
-
-void QSGCanvas::resizeEvent(QResizeEvent *)
-{
-    Q_D(QSGCanvas);
-    d->thread->resize(size());
-}
-
-void QSGCanvas::animationStarted()
-{
-    d_func()->thread->animationStarted();
-}
-
-void QSGCanvas::animationStopped()
-{
-    d_func()->thread->animationStopped();
-}
-
-void QSGCanvas::showEvent(QShowEvent *)
-{
-    Q_D(QSGCanvas);
-    if (d->vsyncAnimations) {
-        if (!d->animationDriver) {
-            d->animationDriver = d->context->createAnimationDriver(this);
-            connect(d->animationDriver, SIGNAL(started()), this, SLOT(animationStarted()), Qt::DirectConnection);
-            connect(d->animationDriver, SIGNAL(stopped()), this, SLOT(animationStopped()), Qt::DirectConnection);
-        }
-        d->animationDriver->install();
-    }
-
-    if (!d->thread->isRunning()) {
-        d->thread->setWindowSize(size());
-        d->thread->startRendering();
-    }
-}
-
-void QSGCanvas::hideEvent(QHideEvent *)
-{
-    Q_D(QSGCanvas);
-    d->thread->stopRendering();
-}
-
-
-
-/*!
-    Sets weither this canvas should use vsync driven animations.
-
-    This option can only be set on one single QSGCanvas, and that it's
-    vsync signal will then be used to drive all animations in the
-    process.
-
-    This feature is primarily useful for single QSGCanvas, QML-only
-    applications.
-
-    \warning Enabling vsync on multiple QSGCanvas instances has
-    undefined behavior.
- */
-void QSGCanvas::setVSyncAnimations(bool enabled)
-{
-    Q_D(QSGCanvas);
-    if (visible()) {
-        qWarning("QSGCanvas::setVSyncAnimations: Cannot be changed when widget is shown");
-        return;
-    }
-    d->vsyncAnimations = enabled;
-}
-
-
-
-/*!
-    Returns true if this canvas should use vsync driven animations;
-    otherwise returns false.
- */
-bool QSGCanvas::vsyncAnimations() const
-{
-    Q_D(const QSGCanvas);
-    return d->vsyncAnimations;
-}
-
-void QSGCanvasPrivate::initializeSceneGraph()
-{
-    if (!context)
-        context = QSGContext::createDefaultContext();
-
-    if (context->isReady())
-        return;
-
-    QOpenGLContext *glctx = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
-    context->initialize(glctx);
-
-    Q_Q(QSGCanvas);
-    QObject::connect(context->renderer(), SIGNAL(sceneGraphChanged()), q, SLOT(maybeUpdate()),
-                     Qt::DirectConnection);
-
-    if (!QSGItemPrivate::get(rootItem)->itemNode()->parent()) {
-        context->rootNode()->appendChildNode(QSGItemPrivate::get(rootItem)->itemNode());
-    }
-
-    emit q_func()->sceneGraphInitialized();
-}
-
-void QSGCanvasPrivate::polishItems()
-{
-    while (!itemsToPolish.isEmpty()) {
-        QSet<QSGItem *>::Iterator iter = itemsToPolish.begin();
-        QSGItem *item = *iter;
-        itemsToPolish.erase(iter);
-        QSGItemPrivate::get(item)->polishScheduled = false;
-        item->updatePolish();
-    }
-    updateFocusItemTransform();
-}
-
-
-void QSGCanvasPrivate::syncSceneGraph()
-{
-    updateDirtyNodes();
-}
-
-
-void QSGCanvasPrivate::renderSceneGraph(const QSize &size)
-{
-    context->renderer()->setDeviceRect(QRect(QPoint(0, 0), size));
-    context->renderer()->setViewportRect(QRect(QPoint(0, 0), renderTarget ? renderTarget->size() : size));
-    context->renderer()->setProjectionMatrixToDeviceRect();
-
-    context->renderNextFrame(renderTarget);
-
-#ifdef FRAME_TIMING
-    sceneGraphRenderTime = frameTimer.elapsed();
-#endif
-
-#ifdef FRAME_TIMING
-//    int pixel;
-//    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
-    readbackTime = frameTimer.elapsed();
-#endif
-}
-
-
-// ### Do we need this?
-void QSGCanvas::sceneGraphChanged()
-{
-//    Q_D(QSGCanvas);
-//    d->needsRepaint = true;
-}
-
-QSGCanvasPrivate::QSGCanvasPrivate()
-    : rootItem(0)
-    , activeFocusItem(0)
-    , mouseGrabberItem(0)
-    , dirtyItemList(0)
-    , context(0)
-    , vsyncAnimations(false)
-    , thread(0)
-    , animationDriver(0)
-    , renderTarget(0)
-    , incubationController(0)
-{
-}
-
-QSGCanvasPrivate::~QSGCanvasPrivate()
-{
-}
-
-void QSGCanvasPrivate::init(QSGCanvas *c)
-{
-    QUnifiedTimer::instance(true)->setConsistentTiming(qmlFixedAnimationStep());
-
-    q_ptr = c;
-
-    Q_Q(QSGCanvas);
-
-    rootItem = new QSGRootItem;
-    QSGItemPrivate *rootItemPrivate = QSGItemPrivate::get(rootItem);
-    rootItemPrivate->canvas = q;
-    rootItemPrivate->flags |= QSGItem::ItemIsFocusScope;
-
-    // QML always has focus. It is important that this call happens after the rootItem
-    // has a canvas..
-    rootItem->setFocus(true);
-
-    bool threaded = !qmlNoThreadedRenderer();
-
-    if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL)) {
-        qWarning("QSGCanvas: platform does not support threaded rendering!");
-        threaded = false;
-    }
-
-    if (threaded)
-        thread = new QSGCanvasRenderThread();
-    else
-        thread = new QSGCanvasPlainRenderLoop();
-
-    thread->renderer = q;
-    thread->d = this;
-
-    context = QSGContext::createDefaultContext();
-    thread->moveContextToThread(context);
-
-    q->setSurfaceType(QWindow::OpenGLSurface);
-    q->setFormat(context->defaultSurfaceFormat());
-}
-
-void QSGCanvasPrivate::transformTouchPoints(QList<QTouchEvent::TouchPoint> &touchPoints, const QTransform &transform)
-{
-    for (int i=0; i<touchPoints.count(); i++) {
-        QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
-        touchPoint.setRect(transform.mapRect(touchPoint.sceneRect()));
-        touchPoint.setStartPos(transform.map(touchPoint.startScenePos()));
-        touchPoint.setLastPos(transform.map(touchPoint.lastScenePos()));
-    }
-}
-
-
-/*!
-Translates the data in \a touchEvent to this canvas.  This method leaves the item local positions in
-\a touchEvent untouched (these are filled in later).
-*/
-void QSGCanvasPrivate::translateTouchEvent(QTouchEvent *touchEvent)
-{
-//    Q_Q(QSGCanvas);
-
-//    touchEvent->setWidget(q); // ### refactor...
-
-    QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
-    for (int i = 0; i < touchPoints.count(); ++i) {
-        QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
-
-        touchPoint.setScreenRect(touchPoint.sceneRect());
-        touchPoint.setStartScreenPos(touchPoint.startScenePos());
-        touchPoint.setLastScreenPos(touchPoint.lastScenePos());
-
-        touchPoint.setSceneRect(touchPoint.rect());
-        touchPoint.setStartScenePos(touchPoint.startPos());
-        touchPoint.setLastScenePos(touchPoint.lastPos());
-
-        if (touchPoint.isPrimary())
-            lastMousePosition = touchPoint.pos().toPoint();
-    }
-    touchEvent->setTouchPoints(touchPoints);
-}
-
-void QSGCanvasPrivate::setFocusInScope(QSGItem *scope, QSGItem *item, FocusOptions options)
-{
-    Q_Q(QSGCanvas);
-
-    Q_ASSERT(item);
-    Q_ASSERT(scope || item == rootItem);
-
-#ifdef FOCUS_DEBUG
-    qWarning() << "QSGCanvasPrivate::setFocusInScope():";
-    qWarning() << "    scope:" << (QObject *)scope;
-    if (scope)
-        qWarning() << "    scopeSubFocusItem:" << (QObject *)QSGItemPrivate::get(scope)->subFocusItem;
-    qWarning() << "    item:" << (QObject *)item;
-    qWarning() << "    activeFocusItem:" << (QObject *)activeFocusItem;
-#endif
-
-    QSGItemPrivate *scopePrivate = scope ? QSGItemPrivate::get(scope) : 0;
-    QSGItemPrivate *itemPrivate = QSGItemPrivate::get(item);
-
-    QSGItem *oldActiveFocusItem = 0;
-    QSGItem *newActiveFocusItem = 0;
-
-    QVarLengthArray<QSGItem *, 20> changed;
-
-    // Does this change the active focus?
-    if (item == rootItem || scopePrivate->activeFocus) {
-        oldActiveFocusItem = activeFocusItem;
-        newActiveFocusItem = item;
-        while (newActiveFocusItem->isFocusScope() && newActiveFocusItem->scopedFocusItem())
-            newActiveFocusItem = newActiveFocusItem->scopedFocusItem();
-
-        if (oldActiveFocusItem) {
-#ifndef QT_NO_IM
-            qApp->inputPanel()->commit();
-#endif
-
-            activeFocusItem = 0;
-            QFocusEvent event(QEvent::FocusOut, Qt::OtherFocusReason);
-            q->sendEvent(oldActiveFocusItem, &event);
-
-            QSGItem *afi = oldActiveFocusItem;
-            while (afi != scope) {
-                if (QSGItemPrivate::get(afi)->activeFocus) {
-                    QSGItemPrivate::get(afi)->activeFocus = false;
-                    changed << afi;
-                }
-                afi = afi->parentItem();
-            }
-        }
-    }
-
-    if (item != rootItem) {
-        QSGItem *oldSubFocusItem = scopePrivate->subFocusItem;
-        // Correct focus chain in scope
-        if (oldSubFocusItem) {
-            QSGItem *sfi = scopePrivate->subFocusItem->parentItem();
-            while (sfi != scope) {
-                QSGItemPrivate::get(sfi)->subFocusItem = 0;
-                sfi = sfi->parentItem();
-            }
-        }
-        {
-            scopePrivate->subFocusItem = item;
-            QSGItem *sfi = scopePrivate->subFocusItem->parentItem();
-            while (sfi != scope) {
-                QSGItemPrivate::get(sfi)->subFocusItem = item;
-                sfi = sfi->parentItem();
-            }
-        }
-
-        if (oldSubFocusItem) {
-            QSGItemPrivate::get(oldSubFocusItem)->focus = false;
-            changed << oldSubFocusItem;
-        }
-    }
-
-    if (!(options & DontChangeFocusProperty)) {
-        // if (item != rootItem || q->hasFocus()) { // ### refactor: focus handling...
-            itemPrivate->focus = true;
-            changed << item;
-        // }
-    }
-
-    if (newActiveFocusItem) { // ### refactor:  && q->hasFocus()) {
-        activeFocusItem = newActiveFocusItem;
-
-        QSGItemPrivate::get(newActiveFocusItem)->activeFocus = true;
-        changed << newActiveFocusItem;
-
-        QSGItem *afi = newActiveFocusItem->parentItem();
-        while (afi && afi != scope) {
-            if (afi->isFocusScope()) {
-                QSGItemPrivate::get(afi)->activeFocus = true;
-                changed << afi;
-            }
-            afi = afi->parentItem();
-        }
-
-        updateInputMethodData();
-
-        QFocusEvent event(QEvent::FocusIn, Qt::OtherFocusReason);
-        q->sendEvent(newActiveFocusItem, &event);
-    } else {
-        updateInputMethodData();
-    }
-
-    if (!changed.isEmpty())
-        notifyFocusChangesRecur(changed.data(), changed.count() - 1);
-}
-
-void QSGCanvasPrivate::clearFocusInScope(QSGItem *scope, QSGItem *item, FocusOptions options)
-{
-    Q_Q(QSGCanvas);
-
-    Q_UNUSED(item);
-    Q_ASSERT(item);
-    Q_ASSERT(scope || item == rootItem);
-
-#ifdef FOCUS_DEBUG
-    qWarning() << "QSGCanvasPrivate::clearFocusInScope():";
-    qWarning() << "    scope:" << (QObject *)scope;
-    qWarning() << "    item:" << (QObject *)item;
-    qWarning() << "    activeFocusItem:" << (QObject *)activeFocusItem;
-#endif
-
-    QSGItemPrivate *scopePrivate = scope ? QSGItemPrivate::get(scope) : 0;
-
-    QSGItem *oldActiveFocusItem = 0;
-    QSGItem *newActiveFocusItem = 0;
-
-    QVarLengthArray<QSGItem *, 20> changed;
-
-    Q_ASSERT(item == rootItem || item == scopePrivate->subFocusItem);
-
-    // Does this change the active focus?
-    if (item == rootItem || scopePrivate->activeFocus) {
-        oldActiveFocusItem = activeFocusItem;
-        newActiveFocusItem = scope;
-
-        Q_ASSERT(oldActiveFocusItem);
-
-#ifndef QT_NO_IM
-        qApp->inputPanel()->commit();
-#endif
-
-        activeFocusItem = 0;
-        QFocusEvent event(QEvent::FocusOut, Qt::OtherFocusReason);
-        q->sendEvent(oldActiveFocusItem, &event);
-
-        QSGItem *afi = oldActiveFocusItem;
-        while (afi != scope) {
-            if (QSGItemPrivate::get(afi)->activeFocus) {
-                QSGItemPrivate::get(afi)->activeFocus = false;
-                changed << afi;
-            }
-            afi = afi->parentItem();
-        }
-    }
-
-    if (item != rootItem) {
-        QSGItem *oldSubFocusItem = scopePrivate->subFocusItem;
-        // Correct focus chain in scope
-        if (oldSubFocusItem) {
-            QSGItem *sfi = scopePrivate->subFocusItem->parentItem();
-            while (sfi != scope) {
-                QSGItemPrivate::get(sfi)->subFocusItem = 0;
-                sfi = sfi->parentItem();
-            }
-        }
-        scopePrivate->subFocusItem = 0;
-
-        if (oldSubFocusItem && !(options & DontChangeFocusProperty)) {
-            QSGItemPrivate::get(oldSubFocusItem)->focus = false;
-            changed << oldSubFocusItem;
-        }
-    } else if (!(options & DontChangeFocusProperty)) {
-        QSGItemPrivate::get(item)->focus = false;
-        changed << item;
-    }
-
-    if (newActiveFocusItem) {
-        Q_ASSERT(newActiveFocusItem == scope);
-        activeFocusItem = scope;
-
-        updateInputMethodData();
-
-        QFocusEvent event(QEvent::FocusIn, Qt::OtherFocusReason);
-        q->sendEvent(newActiveFocusItem, &event);
-    } else {
-        updateInputMethodData();
-    }
-
-    if (!changed.isEmpty())
-        notifyFocusChangesRecur(changed.data(), changed.count() - 1);
-}
-
-void QSGCanvasPrivate::notifyFocusChangesRecur(QSGItem **items, int remaining)
-{
-    QDeclarativeGuard<QSGItem> item(*items);
-
-    if (remaining)
-        notifyFocusChangesRecur(items + 1, remaining - 1);
-
-    if (item) {
-        QSGItemPrivate *itemPrivate = QSGItemPrivate::get(item);
-
-        if (itemPrivate->notifiedFocus != itemPrivate->focus) {
-            itemPrivate->notifiedFocus = itemPrivate->focus;
-            emit item->focusChanged(itemPrivate->focus);
-        }
-
-        if (item && itemPrivate->notifiedActiveFocus != itemPrivate->activeFocus) {
-            itemPrivate->notifiedActiveFocus = itemPrivate->activeFocus;
-            itemPrivate->itemChange(QSGItem::ItemActiveFocusHasChanged, itemPrivate->activeFocus);
-            emit item->activeFocusChanged(itemPrivate->activeFocus);
-        }
-    }
-}
-
-void QSGCanvasPrivate::updateInputMethodData()
-{
-    QSGItem *inputItem = 0;
-    if (activeFocusItem && activeFocusItem->flags() & QSGItem::ItemAcceptsInputMethod)
-        inputItem = activeFocusItem;
-    qApp->inputPanel()->setInputItem(inputItem);
-}
-
-QVariant QSGCanvas::inputMethodQuery(Qt::InputMethodQuery query) const
-{
-    Q_D(const QSGCanvas);
-    if (!d->activeFocusItem || !(QSGItemPrivate::get(d->activeFocusItem)->flags & QSGItem::ItemAcceptsInputMethod))
-        return QVariant();
-    QVariant value = d->activeFocusItem->inputMethodQuery(query);
-
-    //map geometry types
-    QVariant::Type type = value.type();
-    if (type == QVariant::RectF || type == QVariant::Rect) {
-        const QTransform transform = QSGItemPrivate::get(d->activeFocusItem)->itemToCanvasTransform();
-        value = transform.mapRect(value.toRectF());
-    } else if (type == QVariant::PointF || type == QVariant::Point) {
-        const QTransform transform = QSGItemPrivate::get(d->activeFocusItem)->itemToCanvasTransform();
-        value = transform.map(value.toPointF());
-    }
-    return value;
-}
-
-void QSGCanvasPrivate::dirtyItem(QSGItem *)
-{
-    Q_Q(QSGCanvas);
-    q->maybeUpdate();
-}
-
-void QSGCanvasPrivate::cleanup(QSGNode *n)
-{
-    Q_Q(QSGCanvas);
-
-    Q_ASSERT(!cleanupNodeList.contains(n));
-    cleanupNodeList.append(n);
-    q->maybeUpdate();
-}
-
-
-QSGCanvas::QSGCanvas(QWindow *parent)
-    : QWindow(*(new QSGCanvasPrivate), parent)
-{
-    Q_D(QSGCanvas);
-    d->init(this);
-}
-
-QSGCanvas::QSGCanvas(QSGCanvasPrivate &dd, QWindow *parent)
-    : QWindow(dd, parent)
-{
-    Q_D(QSGCanvas);
-    d->init(this);
-}
-
-QSGCanvas::~QSGCanvas()
-{
-    Q_D(QSGCanvas);
-
-    if (d->thread->isRunning()) {
-        d->thread->stopRendering();
-        delete d->thread;
-        d->thread = 0;
-    }
-
-    // ### should we change ~QSGItem to handle this better?
-    // manually cleanup for the root item (item destructor only handles these when an item is parented)
-    QSGItemPrivate *rootItemPrivate = QSGItemPrivate::get(d->rootItem);
-    rootItemPrivate->removeFromDirtyList();
-
-    delete d->incubationController; d->incubationController = 0;
-
-    delete d->rootItem; d->rootItem = 0;
-    d->cleanupNodes();
-}
-
-QSGItem *QSGCanvas::rootItem() const
-{
-    Q_D(const QSGCanvas);
-
-    return d->rootItem;
-}
-
-QSGItem *QSGCanvas::activeFocusItem() const
-{
-    Q_D(const QSGCanvas);
-
-    return d->activeFocusItem;
-}
-
-QSGItem *QSGCanvas::mouseGrabberItem() const
-{
-    Q_D(const QSGCanvas);
-
-    return d->mouseGrabberItem;
-}
-
-
-bool QSGCanvasPrivate::clearHover()
-{
-    if (hoverItems.isEmpty())
-        return false;
-
-    QPointF pos = QCursor::pos(); // ### refactor: q->mapFromGlobal(QCursor::pos());
-
-    bool accepted = false;
-    foreach (QSGItem* item, hoverItems)
-        accepted = sendHoverEvent(QEvent::HoverLeave, item, pos, pos, QGuiApplication::keyboardModifiers(), true) || accepted;
-    hoverItems.clear();
-    return accepted;
-}
-
-
-bool QSGCanvas::event(QEvent *e)
-{
-    Q_D(QSGCanvas);
-
-    switch (e->type()) {
-
-    case QEvent::TouchBegin:
-    case QEvent::TouchUpdate:
-    case QEvent::TouchEnd:
-    {
-        QTouchEvent *touch = static_cast<QTouchEvent *>(e);
-        d->translateTouchEvent(touch);
-        d->deliverTouchEvent(touch);
-        if (!touch->isAccepted())
-            return false;
-        break;
-    }
-    case QEvent::Leave:
-        d->clearHover();
-        d->lastMousePosition = QPoint();
-        break;
-    case QEvent::DragEnter:
-    case QEvent::DragLeave:
-    case QEvent::DragMove:
-    case QEvent::Drop:
-        d->deliverDragEvent(&d->dragGrabber, e);
-        break;
-    case QEvent::WindowDeactivate:
-        rootItem()->windowDeactivateEvent();
-        break;
-    default:
-        break;
-    }
-
-    return QWindow::event(e);
-}
-
-void QSGCanvas::keyPressEvent(QKeyEvent *e)
-{
-    Q_D(QSGCanvas);
-
-    if (d->activeFocusItem)
-        sendEvent(d->activeFocusItem, e);
-}
-
-void QSGCanvas::keyReleaseEvent(QKeyEvent *e)
-{
-    Q_D(QSGCanvas);
-
-    if (d->activeFocusItem)
-        sendEvent(d->activeFocusItem, e);
-}
-
-void QSGCanvas::inputMethodEvent(QInputMethodEvent *e)
-{
-    Q_D(QSGCanvas);
-
-    if (d->activeFocusItem)
-        sendEvent(d->activeFocusItem, e);
-}
-
-bool QSGCanvasPrivate::deliverInitialMousePressEvent(QSGItem *item, QMouseEvent *event)
-{
-    Q_Q(QSGCanvas);
-
-    QSGItemPrivate *itemPrivate = QSGItemPrivate::get(item);
-    if (itemPrivate->opacity == 0.0)
-        return false;
-
-    if (itemPrivate->flags & QSGItem::ItemClipsChildrenToShape) {
-        QPointF p = item->mapFromScene(event->windowPos());
-        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 (deliverInitialMousePressEvent(child, event))
-            return true;
-    }
-
-    if (itemPrivate->acceptedMouseButtons & event->button()) {
-        QPointF p = item->mapFromScene(event->windowPos());
-        if (QRectF(0, 0, item->width(), item->height()).contains(p)) {
-            QMouseEvent me(event->type(), p, event->windowPos(), event->screenPos(),
-                           event->button(), event->buttons(), event->modifiers());
-            me.accept();
-            mouseGrabberItem = item;
-            q->sendEvent(item, &me);
-            event->setAccepted(me.isAccepted());
-            if (me.isAccepted())
-                return true;
-            mouseGrabberItem->ungrabMouse();
-            mouseGrabberItem = 0;
-        }
-    }
-
-    return false;
-}
-
-bool QSGCanvasPrivate::deliverMouseEvent(QMouseEvent *event)
-{
-    Q_Q(QSGCanvas);
-
-    lastMousePosition = event->windowPos();
-
-    if (!mouseGrabberItem &&
-         event->type() == QEvent::MouseButtonPress &&
-         (event->button() & event->buttons()) == event->buttons()) {
-        return deliverInitialMousePressEvent(rootItem, event);
-    }
-
-    if (mouseGrabberItem) {
-        QSGItemPrivate *mgPrivate = QSGItemPrivate::get(mouseGrabberItem);
-        const QTransform &transform = mgPrivate->canvasToItemTransform();
-        QMouseEvent me(event->type(), transform.map(event->windowPos()), event->windowPos(), event->screenPos(),
-                       event->button(), event->buttons(), event->modifiers());
-        me.accept();
-        q->sendEvent(mouseGrabberItem, &me);
-        event->setAccepted(me.isAccepted());
-        if (me.isAccepted())
-            return true;
-    }
-
-    return false;
-}
-
-void QSGCanvas::mousePressEvent(QMouseEvent *event)
-{
-    Q_D(QSGCanvas);
-
-#ifdef MOUSE_DEBUG
-    qWarning() << "QSGCanvas::mousePressEvent()" << event->pos() << event->button() << event->buttons();
-#endif
-
-    d->deliverMouseEvent(event);
-}
-
-void QSGCanvas::mouseReleaseEvent(QMouseEvent *event)
-{
-    Q_D(QSGCanvas);
-
-#ifdef MOUSE_DEBUG
-    qWarning() << "QSGCanvas::mouseReleaseEvent()" << event->pos() << event->button() << event->buttons();
-#endif
-
-    if (!d->mouseGrabberItem) {
-        QWindow::mouseReleaseEvent(event);
-        return;
-    }
-
-    d->deliverMouseEvent(event);
-    d->mouseGrabberItem = 0;
-}
-
-void QSGCanvas::mouseDoubleClickEvent(QMouseEvent *event)
-{
-    Q_D(QSGCanvas);
-
-#ifdef MOUSE_DEBUG
-    qWarning() << "QSGCanvas::mouseDoubleClickEvent()" << event->pos() << event->button() << event->buttons();
-#endif
-
-    if (!d->mouseGrabberItem && (event->button() & event->buttons()) == event->buttons()) {
-        if (d->deliverInitialMousePressEvent(d->rootItem, event))
-            event->accept();
-        else
-            event->ignore();
-        return;
-    }
-
-    d->deliverMouseEvent(event);
-}
-
-bool QSGCanvasPrivate::sendHoverEvent(QEvent::Type type, QSGItem *item,
-                                      const QPointF &scenePos, const QPointF &lastScenePos,
-                                      Qt::KeyboardModifiers modifiers, bool accepted)
-{
-    Q_Q(QSGCanvas);
-    const QTransform transform = QSGItemPrivate::get(item)->canvasToItemTransform();
-
-    //create copy of event
-    QHoverEvent hoverEvent(type, transform.map(scenePos), transform.map(lastScenePos), modifiers);
-    hoverEvent.setAccepted(accepted);
-
-    q->sendEvent(item, &hoverEvent);
-
-    return hoverEvent.isAccepted();
-}
-
-void QSGCanvas::mouseMoveEvent(QMouseEvent *event)
-{
-    Q_D(QSGCanvas);
-
-#ifdef MOUSE_DEBUG
-    qWarning() << "QSGCanvas::mouseMoveEvent()" << event->pos() << event->button() << event->buttons();
-#endif
-
-    if (!d->mouseGrabberItem) {
-        if (d->lastMousePosition.isNull())
-            d->lastMousePosition = event->windowPos();
-        QPointF last = d->lastMousePosition;
-        d->lastMousePosition = event->windowPos();
-
-        bool accepted = event->isAccepted();
-        bool delivered = d->deliverHoverEvent(d->rootItem, event->windowPos(), last, event->modifiers(), accepted);
-        if (!delivered) {
-            //take care of any exits
-            accepted = d->clearHover();
-        }
-        event->setAccepted(accepted);
-        return;
-    }
-
-    d->deliverMouseEvent(event);
-}
-
-bool QSGCanvasPrivate::deliverHoverEvent(QSGItem *item, const QPointF &scenePos, const QPointF &lastScenePos,
-                                         Qt::KeyboardModifiers modifiers, bool &accepted)
-{
-    QSGItemPrivate *itemPrivate = QSGItemPrivate::get(item);
-    if (itemPrivate->opacity == 0.0)
-        return false;
-
-    if (itemPrivate->flags & QSGItem::ItemClipsChildrenToShape) {
-        QPointF p = item->mapFromScene(scenePos);
-        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 (deliverHoverEvent(child, scenePos, lastScenePos, modifiers, accepted))
-            return true;
-    }
-
-    if (itemPrivate->hoverEnabled) {
-        QPointF p = item->mapFromScene(scenePos);
-        if (QRectF(0, 0, item->width(), item->height()).contains(p)) {
-            if (!hoverItems.isEmpty() && hoverItems[0] == item) {
-                //move
-                accepted = sendHoverEvent(QEvent::HoverMove, item, scenePos, lastScenePos, modifiers, accepted);
-            } else {
-                QList<QSGItem *> itemsToHover;
-                QSGItem* parent = item;
-                itemsToHover << item;
-                while ((parent = parent->parentItem()))
-                    itemsToHover << parent;
-
-                // Leaving from previous hovered items until we reach the item or one of its ancestors.
-                while (!hoverItems.isEmpty() && !itemsToHover.contains(hoverItems[0])) {
-                    sendHoverEvent(QEvent::HoverLeave, hoverItems[0], scenePos, lastScenePos, modifiers, accepted);
-                    hoverItems.removeFirst();
-                }
-
-                if (!hoverItems.isEmpty() && hoverItems[0] == item){//Not entering a new Item
-                    // ### Shouldn't we send moves for the parent items as well?
-                    accepted = sendHoverEvent(QEvent::HoverMove, item, scenePos, lastScenePos, modifiers, accepted);
-                } else {
-                    // Enter items that are not entered yet.
-                    int startIdx = -1;
-                    if (!hoverItems.isEmpty())
-                        startIdx = itemsToHover.indexOf(hoverItems[0]) - 1;
-                    if (startIdx == -1)
-                        startIdx = itemsToHover.count() - 1;
-
-                    for (int i = startIdx; i >= 0; i--) {
-                        QSGItem *itemToHover = itemsToHover[i];
-                        if (QSGItemPrivate::get(itemToHover)->hoverEnabled) {
-                            hoverItems.prepend(itemToHover);
-                            sendHoverEvent(QEvent::HoverEnter, itemToHover, scenePos, lastScenePos, modifiers, accepted);
-                        }
-                    }
-                }
-            }
-            return true;
-        }
-    }
-
-    return false;
-}
-
-bool QSGCanvasPrivate::deliverWheelEvent(QSGItem *item, QWheelEvent *event)
-{
-    Q_Q(QSGCanvas);
-    QSGItemPrivate *itemPrivate = QSGItemPrivate::get(item);
-    if (itemPrivate->opacity == 0.0)
-        return false;
-
-    if (itemPrivate->flags & QSGItem::ItemClipsChildrenToShape) {
-        QPointF p = item->mapFromScene(event->posF());
-        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 (deliverWheelEvent(child, event))
-            return true;
-    }
-
-    QPointF p = item->mapFromScene(event->posF());
-    if (QRectF(0, 0, item->width(), item->height()).contains(p)) {
-        QWheelEvent wheel(p, event->delta(), event->buttons(), event->modifiers(), event->orientation());
-        wheel.accept();
-        q->sendEvent(item, &wheel);
-        if (wheel.isAccepted()) {
-            event->accept();
-            return true;
-        }
-    }
-
-    return false;
-}
-
-#ifndef QT_NO_WHEELEVENT
-void QSGCanvas::wheelEvent(QWheelEvent *event)
-{
-    Q_D(QSGCanvas);
-#ifdef MOUSE_DEBUG
-    qWarning() << "QSGCanvas::wheelEvent()" << event->pos() << event->delta() << event->orientation();
-#endif
-    event->ignore();
-    d->deliverWheelEvent(d->rootItem, event);
-}
-#endif // QT_NO_WHEELEVENT
-
-bool QSGCanvasPrivate::deliverTouchEvent(QTouchEvent *event)
-{
-#ifdef TOUCH_DEBUG
-    if (event->type() == QEvent::TouchBegin)
-        qWarning("touchBeginEvent");
-    else if (event->type() == QEvent::TouchUpdate)
-        qWarning("touchUpdateEvent");
-    else if (event->type() == QEvent::TouchEnd)
-        qWarning("touchEndEvent");
-#endif
-
-    QHash<QSGItem *, QList<QTouchEvent::TouchPoint> > updatedPoints;
-
-    if (event->type() == QTouchEvent::TouchBegin) {     // all points are new touch points
-        QSet<int> acceptedNewPoints;
-        deliverTouchPoints(rootItem, event, event->touchPoints(), &acceptedNewPoints, &updatedPoints);
-        if (acceptedNewPoints.count() > 0)
-            event->accept();
-        return event->isAccepted();
-    }
-
-    const QList<QTouchEvent::TouchPoint> &touchPoints = event->touchPoints();
-    QList<QTouchEvent::TouchPoint> newPoints;
-    QSGItem *item = 0;
-    for (int i=0; i<touchPoints.count(); i++) {
-        const QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
-        switch (touchPoint.state()) {
-            case Qt::TouchPointPressed:
-                newPoints << touchPoint;
-                break;
-            case Qt::TouchPointMoved:
-            case Qt::TouchPointStationary:
-            case Qt::TouchPointReleased:
-                if (itemForTouchPointId.contains(touchPoint.id())) {
-                    item = itemForTouchPointId[touchPoint.id()];
-                    if (item)
-                        updatedPoints[item].append(touchPoint);
-                }
-                break;
-            default:
-                break;
-        }
-    }
-
-    if (newPoints.count() > 0 || updatedPoints.count() > 0) {
-        QSet<int> acceptedNewPoints;
-        int prevCount = updatedPoints.count();
-        deliverTouchPoints(rootItem, event, newPoints, &acceptedNewPoints, &updatedPoints);
-        if (acceptedNewPoints.count() > 0 || updatedPoints.count() != prevCount)
-            event->accept();
-    }
-
-    if (event->touchPointStates() & Qt::TouchPointReleased) {
-        for (int i=0; i<touchPoints.count(); i++) {
-            if (touchPoints[i].state() == Qt::TouchPointReleased)
-                itemForTouchPointId.remove(touchPoints[i].id());
-        }
-    }
-
-    return event->isAccepted();
-}
-
-bool QSGCanvasPrivate::deliverTouchPoints(QSGItem *item, QTouchEvent *event, const QList<QTouchEvent::TouchPoint> &newPoints, QSet<int> *acceptedNewPoints, QHash<QSGItem *, QList<QTouchEvent::TouchPoint> > *updatedPoints)
-{
-    Q_Q(QSGCanvas);
-    QSGItemPrivate *itemPrivate = QSGItemPrivate::get(item);
-
-    if (itemPrivate->opacity == 0.0)
-        return false;
-
-    if (itemPrivate->flags & QSGItem::ItemClipsChildrenToShape) {
-        QRectF bounds(0, 0, item->width(), item->height());
-        for (int i=0; i<newPoints.count(); i++) {
-            QPointF p = item->mapFromScene(newPoints[i].scenePos());
-            if (!bounds.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->isEnabled())
-            continue;
-        if (deliverTouchPoints(child, event, newPoints, acceptedNewPoints, updatedPoints))
-            return true;
-    }
-
-    QList<QTouchEvent::TouchPoint> matchingPoints;
-    if (newPoints.count() > 0 && acceptedNewPoints->count() < newPoints.count()) {
-        QRectF bounds(0, 0, item->width(), item->height());
-        for (int i=0; i<newPoints.count(); i++) {
-            if (acceptedNewPoints->contains(newPoints[i].id()))
-                continue;
-            QPointF p = item->mapFromScene(newPoints[i].scenePos());
-            if (bounds.contains(p))
-                matchingPoints << newPoints[i];
-        }
-    }
-
-    if (matchingPoints.count() > 0 || (*updatedPoints)[item].count() > 0) {
-        QList<QTouchEvent::TouchPoint> &eventPoints = (*updatedPoints)[item];
-        eventPoints.append(matchingPoints);
-        transformTouchPoints(eventPoints, itemPrivate->canvasToItemTransform());
-
-        Qt::TouchPointStates eventStates;
-        for (int i=0; i<eventPoints.count(); i++)
-            eventStates |= eventPoints[i].state();
-        // if all points have the same state, set the event type accordingly
-        QEvent::Type eventType;
-        switch (eventStates) {
-            case Qt::TouchPointPressed:
-                eventType = QEvent::TouchBegin;
-                break;
-            case Qt::TouchPointReleased:
-                eventType = QEvent::TouchEnd;
-                break;
-            default:
-                eventType = QEvent::TouchUpdate;
-                break;
-        }
-
-        if (eventStates != Qt::TouchPointStationary) {
-            QTouchEvent touchEvent(eventType);
-            // touchEvent.setWidget(q); // ### refactor: what is the consequence of not setting the widget?
-            touchEvent.setDeviceType(event->deviceType());
-            touchEvent.setModifiers(event->modifiers());
-            touchEvent.setTouchPointStates(eventStates);
-            touchEvent.setTouchPoints(eventPoints);
-            touchEvent.setTimestamp(event->timestamp());
-
-            touchEvent.accept();
-            q->sendEvent(item, &touchEvent);
-
-            if (touchEvent.isAccepted()) {
-                for (int i=0; i<matchingPoints.count(); i++) {
-                    itemForTouchPointId[matchingPoints[i].id()] = item;
-                    acceptedNewPoints->insert(matchingPoints[i].id());
-                }
-            }
-        }
-    }
-
-    updatedPoints->remove(item);
-    if (acceptedNewPoints->count() == newPoints.count() && updatedPoints->isEmpty())
-        return true;
-
-    return false;
-}
-
-void QSGCanvasPrivate::deliverDragEvent(QSGDragGrabber *grabber, QEvent *event)
-{
-    Q_Q(QSGCanvas);
-    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);
-            }
-        }
-        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);
-            }
-        }
-    }
-    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(QSGDragGrabber *grabber, QSGItem *item, QDragMoveEvent *event)
-{
-    Q_Q(QSGCanvas);
-    bool accepted = false;
-    QSGItemPrivate *itemPrivate = QSGItemPrivate::get(item);
-    if (itemPrivate->opacity == 0.0 || !item->isVisible() || !item->isEnabled())
-        return false;
-
-    QPointF p = item->mapFromScene(event->pos());
-    if (QRectF(0, 0, item->width(), item->height()).contains(p)) {
-        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;
-                }
-            } else {
-                accepted = true;
-            }
-        }
-    } else if (itemPrivate->flags & QSGItem::ItemClipsChildrenToShape) {
-        return false;
-    }
-
-    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;
-    }
-
-    return accepted;
-}
-
-bool QSGCanvasPrivate::sendFilteredMouseEvent(QSGItem *target, QSGItem *item, QMouseEvent *event)
-{
-    if (!target)
-        return false;
-
-    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;
-}
-
-bool QSGCanvas::sendEvent(QSGItem *item, QEvent *e)
-{
-    Q_D(QSGCanvas);
-
-    if (!item) {
-        qWarning("QSGCanvas::sendEvent: Cannot send event to a null item");
-        return false;
-    }
-
-    Q_ASSERT(e);
-
-    switch (e->type()) {
-    case QEvent::KeyPress:
-    case QEvent::KeyRelease:
-        e->accept();
-        QSGItemPrivate::get(item)->deliverKeyEvent(static_cast<QKeyEvent *>(e));
-        while (!e->isAccepted() && (item = item->parentItem())) {
-            e->accept();
-            QSGItemPrivate::get(item)->deliverKeyEvent(static_cast<QKeyEvent *>(e));
-        }
-        break;
-    case QEvent::InputMethod:
-        e->accept();
-        QSGItemPrivate::get(item)->deliverInputMethodEvent(static_cast<QInputMethodEvent *>(e));
-        while (!e->isAccepted() && (item = item->parentItem())) {
-            e->accept();
-            QSGItemPrivate::get(item)->deliverInputMethodEvent(static_cast<QInputMethodEvent *>(e));
-        }
-        break;
-    case QEvent::FocusIn:
-    case QEvent::FocusOut:
-        QSGItemPrivate::get(item)->deliverFocusEvent(static_cast<QFocusEvent *>(e));
-        break;
-    case QEvent::MouseButtonPress:
-    case QEvent::MouseButtonRelease:
-    case QEvent::MouseButtonDblClick:
-    case QEvent::MouseMove:
-        // 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)) {
-                se->accept();
-                QSGItemPrivate::get(item)->deliverMouseEvent(se);
-            }
-        }
-        break;
-    case QEvent::Wheel:
-        QSGItemPrivate::get(item)->deliverWheelEvent(static_cast<QWheelEvent *>(e));
-        break;
-    case QEvent::HoverEnter:
-    case QEvent::HoverLeave:
-    case QEvent::HoverMove:
-        QSGItemPrivate::get(item)->deliverHoverEvent(static_cast<QHoverEvent *>(e));
-        break;
-    case QEvent::TouchBegin:
-    case QEvent::TouchUpdate:
-    case QEvent::TouchEnd:
-        QSGItemPrivate::get(item)->deliverTouchEvent(static_cast<QTouchEvent *>(e));
-        break;
-    case QEvent::DragEnter:
-    case QEvent::DragMove:
-    case QEvent::DragLeave:
-    case QEvent::Drop:
-        QSGItemPrivate::get(item)->deliverDragEvent(e);
-        break;
-    default:
-        break;
-    }
-
-    return false;
-}
-
-void QSGCanvasPrivate::cleanupNodes()
-{
-    for (int ii = 0; ii < cleanupNodeList.count(); ++ii)
-        delete cleanupNodeList.at(ii);
-    cleanupNodeList.clear();
-}
-
-void QSGCanvasPrivate::updateDirtyNodes()
-{
-#ifdef DIRTY_DEBUG
-    qWarning() << "QSGCanvasPrivate::updateDirtyNodes():";
-#endif
-
-    cleanupNodes();
-
-    QSGItem *updateList = dirtyItemList;
-    dirtyItemList = 0;
-    if (updateList) QSGItemPrivate::get(updateList)->prevDirtyItem = &updateList;
-
-    while (updateList) {
-        QSGItem *item = updateList;
-        QSGItemPrivate *itemPriv = QSGItemPrivate::get(item);
-        itemPriv->removeFromDirtyList();
-
-#ifdef DIRTY_DEBUG
-        qWarning() << "   QSGNode:" << item << qPrintable(itemPriv->dirtyToString());
-#endif
-        updateDirtyNode(item);
-    }
-}
-
-void QSGCanvasPrivate::updateDirtyNode(QSGItem *item)
-{
-#ifdef QML_RUNTIME_TESTING
-    bool didFlash = false;
-#endif
-
-    QSGItemPrivate *itemPriv = QSGItemPrivate::get(item);
-    quint32 dirty = itemPriv->dirtyAttributes;
-    itemPriv->dirtyAttributes = 0;
-
-    if ((dirty & QSGItemPrivate::TransformUpdateMask) ||
-        (dirty & QSGItemPrivate::Size && itemPriv->origin != QSGItem::TopLeft &&
-         (itemPriv->scale != 1. || itemPriv->rotation != 0.))) {
-
-        QMatrix4x4 matrix;
-
-        if (itemPriv->x != 0. || itemPriv->y != 0.)
-            matrix.translate(itemPriv->x, itemPriv->y);
-
-        for (int ii = itemPriv->transforms.count() - 1; ii >= 0; --ii)
-            itemPriv->transforms.at(ii)->applyTo(&matrix);
-
-        if (itemPriv->scale != 1. || itemPriv->rotation != 0.) {
-            QPointF origin = item->transformOriginPoint();
-            matrix.translate(origin.x(), origin.y());
-            if (itemPriv->scale != 1.)
-                matrix.scale(itemPriv->scale, itemPriv->scale);
-            if (itemPriv->rotation != 0.)
-                matrix.rotate(itemPriv->rotation, 0, 0, 1);
-            matrix.translate(-origin.x(), -origin.y());
-        }
-
-        itemPriv->itemNode()->setMatrix(matrix);
-    }
-
-    bool clipEffectivelyChanged = dirty & QSGItemPrivate::Clip &&
-                                  ((item->clip() == false) != (itemPriv->clipNode == 0));
-    bool effectRefEffectivelyChanged = dirty & QSGItemPrivate::EffectReference &&
-                                  ((itemPriv->effectRefCount == 0) != (itemPriv->rootNode == 0));
-
-    if (clipEffectivelyChanged) {
-        QSGNode *parent = itemPriv->opacityNode ? (QSGNode *) itemPriv->opacityNode : (QSGNode *)itemPriv->itemNode();
-        QSGNode *child = itemPriv->rootNode ? (QSGNode *)itemPriv->rootNode : (QSGNode *)itemPriv->groupNode;
-
-        if (item->clip()) {
-            Q_ASSERT(itemPriv->clipNode == 0);
-            itemPriv->clipNode = new QSGDefaultClipNode(item->boundingRect());
-            itemPriv->clipNode->update();
-
-            if (child)
-                parent->removeChildNode(child);
-            parent->appendChildNode(itemPriv->clipNode);
-            if (child)
-                itemPriv->clipNode->appendChildNode(child);
-
-        } else {
-            Q_ASSERT(itemPriv->clipNode != 0);
-            parent->removeChildNode(itemPriv->clipNode);
-            if (child)
-                itemPriv->clipNode->removeChildNode(child);
-            delete itemPriv->clipNode;
-            itemPriv->clipNode = 0;
-            if (child)
-                parent->appendChildNode(child);
-        }
-    }
-
-    if (dirty & QSGItemPrivate::ChildrenUpdateMask)
-        itemPriv->childContainerNode()->removeAllChildNodes();
-
-    if (effectRefEffectivelyChanged) {
-        QSGNode *parent = itemPriv->clipNode;
-        if (!parent)
-            parent = itemPriv->opacityNode;
-        if (!parent)
-            parent = itemPriv->itemNode();
-        QSGNode *child = itemPriv->groupNode;
-
-        if (itemPriv->effectRefCount) {
-            Q_ASSERT(itemPriv->rootNode == 0);
-            itemPriv->rootNode = new QSGRootNode;
-
-            if (child)
-                parent->removeChildNode(child);
-            parent->appendChildNode(itemPriv->rootNode);
-            if (child)
-                itemPriv->rootNode->appendChildNode(child);
-        } else {
-            Q_ASSERT(itemPriv->rootNode != 0);
-            parent->removeChildNode(itemPriv->rootNode);
-            if (child)
-                itemPriv->rootNode->removeChildNode(child);
-            delete itemPriv->rootNode;
-            itemPriv->rootNode = 0;
-            if (child)
-                parent->appendChildNode(child);
-        }
-    }
-
-    if (dirty & QSGItemPrivate::ChildrenUpdateMask) {
-        QSGNode *groupNode = itemPriv->groupNode;
-        if (groupNode)
-            groupNode->removeAllChildNodes();
-
-        QList<QSGItem *> orderedChildren = itemPriv->paintOrderChildItems();
-        int ii = 0;
-
-        for (; ii < orderedChildren.count() && orderedChildren.at(ii)->z() < 0; ++ii) {
-            QSGItemPrivate *childPrivate = QSGItemPrivate::get(orderedChildren.at(ii));
-            if (!childPrivate->explicitVisible && !childPrivate->effectRefCount)
-                continue;
-            if (childPrivate->itemNode()->parent())
-                childPrivate->itemNode()->parent()->removeChildNode(childPrivate->itemNode());
-
-            itemPriv->childContainerNode()->appendChildNode(childPrivate->itemNode());
-        }
-        itemPriv->beforePaintNode = itemPriv->groupNode ? itemPriv->groupNode->lastChild() : 0;
-
-        if (itemPriv->paintNode)
-            itemPriv->childContainerNode()->appendChildNode(itemPriv->paintNode);
-
-        for (; ii < orderedChildren.count(); ++ii) {
-            QSGItemPrivate *childPrivate = QSGItemPrivate::get(orderedChildren.at(ii));
-            if (!childPrivate->explicitVisible && !childPrivate->effectRefCount)
-                continue;
-            if (childPrivate->itemNode()->parent())
-                childPrivate->itemNode()->parent()->removeChildNode(childPrivate->itemNode());
-
-            itemPriv->childContainerNode()->appendChildNode(childPrivate->itemNode());
-        }
-    }
-
-    if ((dirty & QSGItemPrivate::Size) && itemPriv->clipNode) {
-        itemPriv->clipNode->setRect(item->boundingRect());
-        itemPriv->clipNode->update();
-    }
-
-    if (dirty & (QSGItemPrivate::OpacityValue | QSGItemPrivate::Visible | QSGItemPrivate::HideReference)) {
-        qreal opacity = itemPriv->explicitVisible && itemPriv->hideRefCount == 0
-                      ? itemPriv->opacity : qreal(0);
-
-        if (opacity != 1 && !itemPriv->opacityNode) {
-            itemPriv->opacityNode = new QSGOpacityNode;
-
-            QSGNode *parent = itemPriv->itemNode();
-            QSGNode *child = itemPriv->clipNode;
-            if (!child)
-                child = itemPriv->rootNode;
-            if (!child)
-                child = itemPriv->groupNode;
-
-            if (child)
-                parent->removeChildNode(child);
-            parent->appendChildNode(itemPriv->opacityNode);
-            if (child)
-                itemPriv->opacityNode->appendChildNode(child);
-        }
-        if (itemPriv->opacityNode)
-            itemPriv->opacityNode->setOpacity(opacity);
-    }
-
-    if (dirty & QSGItemPrivate::ContentUpdateMask) {
-
-        if (itemPriv->flags & QSGItem::ItemHasContents) {
-            updatePaintNodeData.transformNode = itemPriv->itemNode();
-            itemPriv->paintNode = item->updatePaintNode(itemPriv->paintNode, &updatePaintNodeData);
-
-            Q_ASSERT(itemPriv->paintNode == 0 ||
-                     itemPriv->paintNode->parent() == 0 ||
-                     itemPriv->paintNode->parent() == itemPriv->childContainerNode());
-
-            if (itemPriv->paintNode && itemPriv->paintNode->parent() == 0) {
-                if (itemPriv->beforePaintNode)
-                    itemPriv->childContainerNode()->insertChildNodeAfter(itemPriv->paintNode, itemPriv->beforePaintNode);
-                else
-                    itemPriv->childContainerNode()->prependChildNode(itemPriv->paintNode);
-            }
-        } else if (itemPriv->paintNode) {
-            delete itemPriv->paintNode;
-            itemPriv->paintNode = 0;
-        }
-    }
-
-#ifndef QT_NO_DEBUG
-    // Check consistency.
-    const QSGNode *nodeChain[] = {
-        itemPriv->itemNodeInstance,
-        itemPriv->opacityNode,
-        itemPriv->clipNode,
-        itemPriv->rootNode,
-        itemPriv->groupNode,
-        itemPriv->paintNode,
-    };
-
-    int ip = 0;
-    for (;;) {
-        while (ip < 5 && nodeChain[ip] == 0)
-            ++ip;
-        if (ip == 5)
-            break;
-        int ic = ip + 1;
-        while (ic < 5 && nodeChain[ic] == 0)
-            ++ic;
-        const QSGNode *parent = nodeChain[ip];
-        const QSGNode *child = nodeChain[ic];
-        if (child == 0) {
-            Q_ASSERT(parent == itemPriv->groupNode || parent->childCount() == 0);
-        } else {
-            Q_ASSERT(parent == itemPriv->groupNode || parent->childCount() == 1);
-            Q_ASSERT(child->parent() == parent);
-            bool containsChild = false;
-            for (QSGNode *n = parent->firstChild(); n; n = n->nextSibling())
-                containsChild |= (n == child);
-            Q_ASSERT(containsChild);
-        }
-        ip = ic;
-    }
-#endif
-
-#ifdef QML_RUNTIME_TESTING
-    if (itemPriv->sceneGraphContext()->isFlashModeEnabled()) {
-        QSGFlashNode *flash = new QSGFlashNode();
-        flash->setRect(item->boundingRect());
-        itemPriv->childContainerNode()->appendChildNode(flash);
-        didFlash = true;
-    }
-    Q_Q(QSGCanvas);
-    if (didFlash) {
-        q->maybeUpdate();
-    }
-#endif
-
-}
-
-void QSGCanvas::maybeUpdate()
-{
-    Q_D(QSGCanvas);
-
-    if (d->thread && d->thread->isRunning())
-        d->thread->maybeUpdate();
-}
-
-/*!
-    \fn void QSGEngine::sceneGraphInitialized();
-
-    This signal is emitted when the scene graph has been initialized.
-
-    This signal will be emitted from the scene graph rendering thread.
- */
-
-/*!
-    Returns the QSGEngine used for this scene.
-
-    The engine will only be available once the scene graph has been
-    initialized. Register for the sceneGraphEngine() signal to get
-    notification about this.
- */
-
-QSGEngine *QSGCanvas::sceneGraphEngine() const
-{
-    Q_D(const QSGCanvas);
-    if (d->context && d->context->isReady())
-        return d->context->engine();
-    return 0;
-}
-
-
-
-/*!
-    Sets the render target for this canvas to be \a fbo.
-
-    The specified fbo must be created in the context of the canvas
-    or one that shares with it.
-
-    \warning
-    This function can only be called from the thread doing
-    the rendering.
- */
-
-void QSGCanvas::setRenderTarget(QOpenGLFramebufferObject *fbo)
-{
-    Q_D(QSGCanvas);
-    if (d->context && d->context && QThread::currentThread() != d->context->thread()) {
-        qWarning("QSGCanvas::setRenderThread: Cannot set render target from outside the rendering thread");
-        return;
-    }
-
-    d->renderTarget = fbo;
-}
-
-
-
-/*!
-    Returns the render target for this canvas.
-
-    The default is to render to the surface of the canvas, in which
-    case the render target is 0.
- */
-QOpenGLFramebufferObject *QSGCanvas::renderTarget() const
-{
-    Q_D(const QSGCanvas);
-    return d->renderTarget;
-}
-
-
-/*!
-    Grabs the contents of the framebuffer and returns it as an image.
-
-    This function might not work if the view is not visible.
-
-    \warning Calling this function will cause performance problems.
-
-    \warning This function can only be called from the GUI thread.
- */
-QImage QSGCanvas::grabFrameBuffer()
-{
-    Q_D(QSGCanvas);
-    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->requestedFormat());
-    gl->create();
-}
-
-void QSGCanvasRenderThread::run()
-{
-#ifdef THREAD_DEBUG
-    qDebug("QML Rendering Thread Started");
-#endif
-
-    if (!glContext()) {
-        createGLContext();
-        makeCurrent();
-        initializeSceneGraph();
-    } else {
-        makeCurrent();
-    }
-
-    while (!shouldExit) {
-        lock();
-
-        bool sizeChanged = false;
-        isExternalUpdatePending = false;
-
-        if (renderedSize != windowSize) {
-#ifdef THREAD_DEBUG
-            printf("                RenderThread: window has changed size...\n");
-#endif
-            glViewport(0, 0, windowSize.width(), windowSize.height());
-            sizeChanged = true;
-        }
-
-#ifdef THREAD_DEBUG
-        printf("                RenderThread: preparing to sync...\n");
-#endif
-
-        if (!isGuiBlocked) {
-            isGuiBlockPending = true;
-
-#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");
-#endif
-            wait();
-
-            isGuiBlockPending = false;
-        }
-
-#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();
-        if (doGrab) {
-#ifdef THREAD_DEBUG
-            printf("                RenderThread: doing a grab...\n");
-#endif
-            grabContent = qt_gl_read_framebuffer(windowSize, false, false);
-            doGrab = false;
-        }
-
-#ifdef THREAD_DEBUG
-        printf("                RenderThread: wait for swap...\n");
-#endif
-
-        swapBuffers();
-#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;
-        if (sizeChanged)
-            renderedSize = windowSize;
-
-        // Wake the GUI thread now that rendering is complete, to signal that painting
-        // is done, resizing is done or grabbing is completed. For grabbing, we're
-        // signalling this much later than needed (we could have done it before swap)
-        // but we don't want to lock an extra time.
-        wake();
-
-        if (!animationRunning && !isExternalUpdatePending && !shouldExit && !doGrab) {
-#ifdef THREAD_DEBUG
-            printf("                RenderThread: nothing to do, going to sleep...\n");
-#endif
-            isRenderBlocked = true;
-            wait();
-            isRenderBlocked = false;
-        }
-
-        unlock();
-
-        // Process any "deleteLater" objects...
-        QCoreApplication::processEvents();
-    }
-
-#ifdef THREAD_DEBUG
-    printf("                RenderThread: render loop exited... Good Night!\n");
-#endif
-
-    doneCurrent();
-
-    lock();
-    hasExited = true;
-#ifdef THREAD_DEBUG
-    printf("                RenderThread: waking GUI for final sleep..\n");
-#endif
-    wake();
-    unlock();
-
-#ifdef THREAD_DEBUG
-    printf("                RenderThread: All done...\n");
-#endif
-}
-
-
-
-bool QSGCanvasRenderThread::event(QEvent *e)
-{
-    Q_ASSERT(QThread::currentThread() == qApp->thread());
-
-    if (e->type() == QEvent::User) {
-        if (!syncAlreadyHappened)
-            sync(false);
-
-        syncAlreadyHappened = false;
-
-        if (animationRunning && animationDriver()) {
-#ifdef THREAD_DEBUG
-            qDebug("GUI: Advancing animations...\n");
-#endif
-
-            animationDriver()->advance();
-
-#ifdef THREAD_DEBUG
-            qDebug("GUI: Animations advanced...\n");
-#endif
-        }
-
-        return true;
-    }
-
-    return QThread::event(e);
-}
-
-
-
-void QSGCanvasRenderThread::exhaustSyncEvent()
-{
-    if (isGuiBlockPending) {
-        sync(true);
-        syncAlreadyHappened = true;
-    }
-}
-
-
-
-void QSGCanvasRenderThread::sync(bool guiAlreadyLocked)
-{
-#ifdef THREAD_DEBUG
-    printf("GUI: sync - %s\n", guiAlreadyLocked ? "outside event" : "inside event");
-#endif
-    if (!guiAlreadyLocked)
-        lockInGui();
-
-    renderThreadAwakened = false;
-
-    polishItems();
-
-    wake();
-    wait();
-
-    if (!guiAlreadyLocked)
-        unlockInGui();
-}
-
-
-
-
-/*!
-    Acquires the mutex for the GUI thread. The function uses the isGuiBlocked
-    variable to keep track of how many recursion levels the gui is locket with.
-    We only actually acquire the mutex for the first level to avoid deadlocking
-    ourselves.
- */
-
-void QSGCanvasRenderThread::lockInGui()
-{
-    // We must avoid recursive locking in the GUI thread, hence we
-    // only lock when we are the first one to try to block.
-    if (!isGuiBlocked)
-        lock();
-
-    isGuiBlocked++;
-
-#ifdef THREAD_DEBUG
-    printf("GUI: aquired lock... %d\n", isGuiBlocked);
-#endif
-}
-
-
-
-void QSGCanvasRenderThread::unlockInGui()
-{
-#ifdef THREAD_DEBUG
-    printf("GUI: releasing lock... %d\n", isGuiBlocked);
-#endif
-    --isGuiBlocked;
-    if (!isGuiBlocked)
-        unlock();
-}
-
-
-
-
-void QSGCanvasRenderThread::animationStarted()
-{
-#ifdef THREAD_DEBUG
-    printf("GUI: animationStarted()\n");
-#endif
-
-    lockInGui();
-
-    animationRunning = true;
-
-    if (isRenderBlocked)
-        wake();
-
-    unlockInGui();
-}
-
-
-
-void QSGCanvasRenderThread::animationStopped()
-{
-#ifdef THREAD_DEBUG
-    printf("GUI: animationStopped()...\n");
-#endif
-
-    lockInGui();
-    animationRunning = false;
-    unlockInGui();
-}
-
-
-void QSGCanvasRenderThread::paint()
-{
-#ifdef THREAD_DEBUG
-    printf("GUI: paint called..\n");
-#endif
-
-    lockInGui();
-    exhaustSyncEvent();
-
-    isPaintCompleted = false;
-    while (isRunning() && !isPaintCompleted) {
-        if (isRenderBlocked)
-            wake();
-        wait();
-    }
-    unlockInGui();
-}
-
-
-
-void QSGCanvasRenderThread::resize(const QSize &size)
-{
-#ifdef THREAD_DEBUG
-    printf("GUI: Resize Event: %dx%d\n", size.width(), size.height());
-#endif
-
-    if (!isRunning()) {
-        windowSize = size;
-        return;
-    }
-
-    lockInGui();
-    exhaustSyncEvent();
-
-    windowSize = size;
-
-    while (isRunning() && renderedSize != windowSize) {
-        if (isRenderBlocked)
-            wake();
-        wait();
-    }
-    unlockInGui();
-}
-
-
-
-void QSGCanvasRenderThread::startRendering()
-{
-#ifdef THREAD_DEBUG
-    printf("GUI: Starting Render Thread\n");
-#endif
-    hasExited = false;
-    shouldExit = false;
-    isGuiBlocked = 0;
-    isGuiBlockPending = false;
-    start();
-}
-
-
-
-void QSGCanvasRenderThread::stopRendering()
-{
-#ifdef THREAD_DEBUG
-    printf("GUI: stopping render thread\n");
-#endif
-
-    lockInGui();
-    exhaustSyncEvent();
-    shouldExit = true;
-
-    if (isRenderBlocked) {
-#ifdef THREAD_DEBUG
-        printf("GUI: waking up render thread\n");
-#endif
-        wake();
-    }
-
-    while (!hasExited) {
-#ifdef THREAD_DEBUG
-        printf("GUI: waiting for render thread to have exited..\n");
-#endif
-        wait();
-    }
-
-    unlockInGui();
-
-#ifdef THREAD_DEBUG
-    printf("GUI: waiting for render thread to terminate..\n");
-#endif
-    // Actually wait for the thread to terminate.  Otherwise we can delete it
-    // too early and crash.
-    QThread::wait();
-
-#ifdef THREAD_DEBUG
-    printf("GUI: thread has terminated and we're all good..\n");
-#endif
-
-}
-
-
-
-QImage QSGCanvasRenderThread::grab()
-{
-    if (!isRunning())
-        return QImage();
-
-    if (QThread::currentThread() != qApp->thread()) {
-        qWarning("QSGCanvas::grabFrameBuffer: can only be called from the GUI thread");
-        return QImage();
-    }
-
-#ifdef THREAD_DEBUG
-    printf("GUI: doing a pixelwise grab..\n");
-#endif
-
-    lockInGui();
-    exhaustSyncEvent();
-
-    doGrab = true;
-    isPaintCompleted = false;
-    while (isRunning() && !isPaintCompleted) {
-        if (isRenderBlocked)
-            wake();
-        wait();
-    }
-
-    QImage grabbed = grabContent;
-    grabContent = QImage();
-
-    unlockInGui();
-
-    return grabbed;
-}
-
-
-
-void QSGCanvasRenderThread::maybeUpdate()
-{
-    Q_ASSERT_X(QThread::currentThread() == QCoreApplication::instance()->thread() || inSync,
-               "QSGCanvas::update",
-               "Function can only be called from GUI thread or during QSGItem::updatePaintNode()");
-
-    if (inSync) {
-        isExternalUpdatePending = true;
-
-    } else if (!renderThreadAwakened) {
-#ifdef THREAD_DEBUG
-        printf("GUI: doing update...\n");
-#endif
-        renderThreadAwakened = true;
-        lockInGui();
-        isExternalUpdatePending = true;
-        if (isRenderBlocked)
-            wake();
-        unlockInGui();
-    }
-}
-
-
-#include "moc_qsgcanvas.cpp"
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgcanvas.h b/src/declarative/items/qsgcanvas.h
deleted file mode 100644 (file)
index 094fe40..0000000
+++ /dev/null
@@ -1,135 +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 QSGCANVAS_H
-#define QSGCANVAS_H
-
-#include <QtCore/qmetatype.h>
-#include <QtGui/qopengl.h>
-#include <QtGui/qwindow.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGItem;
-class QSGEngine;
-class QSGCanvasPrivate;
-class QOpenGLFramebufferObject;
-class QDeclarativeIncubationController;
-
-class Q_DECLARATIVE_EXPORT QSGCanvas : public QWindow
-{
-Q_OBJECT
-Q_DECLARE_PRIVATE(QSGCanvas)
-public:
-    QSGCanvas(QWindow *parent = 0);
-
-    virtual ~QSGCanvas();
-
-    QSGItem *rootItem() const;
-    QSGItem *activeFocusItem() const;
-
-    QSGItem *mouseGrabberItem() const;
-
-    bool sendEvent(QSGItem *, QEvent *);
-
-    QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
-
-    QSGEngine *sceneGraphEngine() const;
-
-    void setVSyncAnimations(bool enabled);
-    bool vsyncAnimations() const;
-
-    QImage grabFrameBuffer();
-
-    void setRenderTarget(QOpenGLFramebufferObject *fbo);
-    QOpenGLFramebufferObject *renderTarget() const;
-
-    QDeclarativeIncubationController *incubationController() const;
-
-Q_SIGNALS:
-    void frameSwapped();
-    void sceneGraphInitialized();
-
-protected:
-    QSGCanvas(QSGCanvasPrivate &dd, QWindow *parent = 0);
-
-    virtual void exposeEvent(QExposeEvent *);
-    virtual void resizeEvent(QResizeEvent *);
-
-    virtual void showEvent(QShowEvent *);
-    virtual void hideEvent(QHideEvent *);
-
-    virtual bool event(QEvent *);
-    virtual void keyPressEvent(QKeyEvent *);
-    virtual void keyReleaseEvent(QKeyEvent *);
-    virtual void inputMethodEvent(QInputMethodEvent *);
-    virtual void mousePressEvent(QMouseEvent *);
-    virtual void mouseReleaseEvent(QMouseEvent *);
-    virtual void mouseDoubleClickEvent(QMouseEvent *);
-    virtual void mouseMoveEvent(QMouseEvent *);
-#ifndef QT_NO_WHEELEVENT
-    virtual void wheelEvent(QWheelEvent *);
-#endif
-
-private Q_SLOTS:
-    void sceneGraphChanged();
-    void maybeUpdate();
-    void animationStarted();
-    void animationStopped();
-
-private:
-    friend class QSGItem;
-    friend class QSGCanvasRenderLoop;
-    Q_DISABLE_COPY(QSGCanvas)
-};
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QSGCanvas *)
-
-QT_END_HEADER
-
-#endif // QSGCANVAS_H
-
diff --git a/src/declarative/items/qsgcanvas_p.h b/src/declarative/items/qsgcanvas_p.h
deleted file mode 100644 (file)
index e2ec7a1..0000000
+++ /dev/null
@@ -1,308 +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 QSGCANVAS_P_H
-#define QSGCANVAS_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 "qsgitem.h"
-#include "qsgcanvas.h"
-#include <private/qdeclarativeguard_p.h>
-
-#include <private/qsgcontext_p.h>
-#include <private/qsgdrag_p.h>
-
-#include <QtCore/qthread.h>
-#include <QtCore/qmutex.h>
-#include <QtCore/qwaitcondition.h>
-#include <private/qwindow_p.h>
-#include <private/qopengl_p.h>
-#include <qopenglcontext.h>
-#include <QtGui/qopenglframebufferobject.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qinputpanel.h>
-
-QT_BEGIN_NAMESPACE
-
-//Make it easy to identify and customize the root item if needed
-class QSGRootItem : public QSGItem
-{
-    Q_OBJECT
-public:
-    QSGRootItem();
-};
-
-class QSGCanvasPrivate;
-
-class QTouchEvent;
-class QSGCanvasRenderLoop;
-class QSGCanvasIncubationController;
-
-class QSGCanvasPrivate : public QWindowPrivate
-{
-public:
-    Q_DECLARE_PUBLIC(QSGCanvas)
-
-    static inline QSGCanvasPrivate *get(QSGCanvas *c) { return c->d_func(); }
-
-    QSGCanvasPrivate();
-    virtual ~QSGCanvasPrivate();
-
-    void init(QSGCanvas *);
-
-    QSGRootItem *rootItem;
-
-    QSGItem *activeFocusItem;
-    QSGItem *mouseGrabberItem;
-    QSGDragGrabber dragGrabber;
-
-    // Mouse positions are saved in widget coordinates
-    QPointF lastMousePosition;
-    void translateTouchEvent(QTouchEvent *touchEvent);
-    static void transformTouchPoints(QList<QTouchEvent::TouchPoint> &touchPoints, const QTransform &transform);
-    bool deliverInitialMousePressEvent(QSGItem *, QMouseEvent *);
-    bool deliverMouseEvent(QMouseEvent *);
-    bool sendFilteredMouseEvent(QSGItem *, QSGItem *, QMouseEvent *);
-    bool deliverWheelEvent(QSGItem *, QWheelEvent *);
-    bool deliverTouchPoints(QSGItem *, QTouchEvent *, const QList<QTouchEvent::TouchPoint> &, QSet<int> *,
-            QHash<QSGItem *, QList<QTouchEvent::TouchPoint> > *);
-    bool deliverTouchEvent(QTouchEvent *);
-    bool deliverHoverEvent(QSGItem *, const QPointF &scenePos, const QPointF &lastScenePos, Qt::KeyboardModifiers modifiers, bool &accepted);
-    bool sendHoverEvent(QEvent::Type, QSGItem *, const QPointF &scenePos, const QPointF &lastScenePos,
-                        Qt::KeyboardModifiers modifiers, bool accepted);
-    bool clearHover();
-    void deliverDragEvent(QSGDragGrabber *, QEvent *);
-    bool deliverDragEvent(QSGDragGrabber *, QSGItem *, QDragMoveEvent *);
-
-    QList<QSGItem*> hoverItems;
-    enum FocusOption {
-        DontChangeFocusProperty = 0x01,
-    };
-    Q_DECLARE_FLAGS(FocusOptions, FocusOption)
-
-    void setFocusInScope(QSGItem *scope, QSGItem *item, FocusOptions = 0);
-    void clearFocusInScope(QSGItem *scope, QSGItem *item, FocusOptions = 0);
-    void notifyFocusChangesRecur(QSGItem **item, int remaining);
-
-    void updateInputMethodData();
-    void updateFocusItemTransform();
-
-    void dirtyItem(QSGItem *);
-    void cleanup(QSGNode *);
-
-    void initializeSceneGraph();
-    void polishItems();
-    void syncSceneGraph();
-    void renderSceneGraph(const QSize &size);
-
-    QSGItem::UpdatePaintNodeData updatePaintNodeData;
-
-    QSGItem *dirtyItemList;
-    QList<QSGNode *> cleanupNodeList;
-
-    QSet<QSGItem *> itemsToPolish;
-
-    void updateDirtyNodes();
-    void cleanupNodes();
-    bool updateEffectiveOpacity(QSGItem *);
-    void updateEffectiveOpacityRoot(QSGItem *, qreal);
-    void updateDirtyNode(QSGItem *);
-
-    QSGContext *context;
-
-    uint vsyncAnimations : 1;
-
-    QSGCanvasRenderLoop *thread;
-    QSize widgetSize;
-    QSize viewportSize;
-
-    QAnimationDriver *animationDriver;
-
-    QOpenGLFramebufferObject *renderTarget;
-
-    QHash<int, QSGItem *> itemForTouchPointId;
-
-    mutable QSGCanvasIncubationController *incubationController;
-};
-
-class QSGCanvasRenderLoop
-{
-public:
-    QSGCanvasRenderLoop()
-        : d(0)
-        , renderer(0)
-        , gl(0)
-    {
-    }
-    virtual ~QSGCanvasRenderLoop()
-    {
-        delete gl;
-    }
-
-    friend class QSGCanvasPrivate;
-
-    virtual void paint() = 0;
-    virtual void resize(const QSize &size) = 0;
-    virtual void startRendering() = 0;
-    virtual void stopRendering() = 0;
-    virtual QImage grab() = 0;
-    virtual void setWindowSize(const QSize &size) = 0;
-    virtual void maybeUpdate() = 0;
-    virtual bool isRunning() const = 0;
-    virtual void animationStarted() = 0;
-    virtual void animationStopped() = 0;
-    virtual void moveContextToThread(QSGContext *) { }
-    virtual bool *allowMainThreadProcessing() { return 0; }
-
-protected:
-    void initializeSceneGraph() { d->initializeSceneGraph(); }
-    void syncSceneGraph() { d->syncSceneGraph(); }
-    void renderSceneGraph(const QSize &size) { d->renderSceneGraph(size); }
-    void polishItems() { d->polishItems(); }
-    QAnimationDriver *animationDriver() const { return d->animationDriver; }
-
-    inline QOpenGLContext *glContext() const { return gl; }
-    void createGLContext();
-    void makeCurrent() { gl->makeCurrent(renderer); }
-    void doneCurrent() { gl->doneCurrent(); }
-    void swapBuffers() {
-        gl->swapBuffers(renderer);
-        emit renderer->frameSwapped();
-    }
-
-private:
-    QSGCanvasPrivate *d;
-    QSGCanvas *renderer;
-
-    QOpenGLContext *gl;
-};
-
-class QSGCanvasRenderThread : public QThread, public QSGCanvasRenderLoop
-{
-    Q_OBJECT
-public:
-    QSGCanvasRenderThread()
-        : mutex(QMutex::NonRecursive)
-        , allowMainThreadProcessingFlag(true)
-        , animationRunning(false)
-        , isGuiBlocked(0)
-        , isPaintCompleted(false)
-        , isGuiBlockPending(false)
-        , isRenderBlocked(false)
-        , isExternalUpdatePending(false)
-        , syncAlreadyHappened(false)
-        , inSync(false)
-        , doGrab(false)
-        , shouldExit(false)
-        , hasExited(false)
-        , renderThreadAwakened(false)
-    {}
-
-    inline void lock() { mutex.lock(); }
-    inline void unlock() { mutex.unlock(); }
-    inline void wait() { condition.wait(&mutex); }
-    inline void wake() { condition.wakeOne(); }
-
-    void lockInGui();
-    void unlockInGui();
-
-    void paint();
-    void resize(const QSize &size);
-    void startRendering();
-    void stopRendering();
-    void exhaustSyncEvent();
-    void sync(bool guiAlreadyLocked);
-    bool isRunning() const { return QThread::isRunning(); }
-    void setWindowSize(const QSize &size) { windowSize = size; }
-    void maybeUpdate();
-    void moveContextToThread(QSGContext *c) { c->moveToThread(this); }
-    bool *allowMainThreadProcessing() { return &allowMainThreadProcessingFlag; }
-
-    bool event(QEvent *);
-
-    QImage grab();
-
-public slots:
-    void animationStarted();
-    void animationStopped();
-
-public:
-    QMutex mutex;
-    QWaitCondition condition;
-
-    bool allowMainThreadProcessingFlag;
-
-    QSize windowSize;
-    QSize renderedSize;
-
-    uint animationRunning: 1;
-    int isGuiBlocked;
-    uint isPaintCompleted : 1;
-    uint isGuiBlockPending : 1;
-    uint isRenderBlocked : 1;
-    uint isExternalUpdatePending : 1;
-    uint syncAlreadyHappened : 1;
-    uint inSync : 1;
-    uint doGrab : 1;
-    uint shouldExit : 1;
-    uint hasExited : 1;
-    uint renderThreadAwakened : 1;
-
-    QImage grabContent;
-
-    void run();
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSGCanvasPrivate::FocusOptions)
-
-QT_END_NAMESPACE
-
-#endif // QSGCANVAS_P_H
diff --git a/src/declarative/items/qsgclipnode.cpp b/src/declarative/items/qsgclipnode.cpp
deleted file mode 100644 (file)
index 1147636..0000000
+++ /dev/null
@@ -1,120 +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$
-**
-****************************************************************************/
-
-
-#include "qsgclipnode_p.h"
-
-#include <QtGui/qvector2d.h>
-#include <QtCore/qmath.h>
-
-QSGDefaultClipNode::QSGDefaultClipNode(const QRectF &rect)
-    : m_rect(rect)
-    , m_radius(0)
-    , m_dirty_geometry(true)
-    , m_geometry(QSGGeometry::defaultAttributes_Point2D(), 0)
-{
-    setGeometry(&m_geometry);
-    setIsRectangular(true);
-}
-
-void QSGDefaultClipNode::setRect(const QRectF &rect)
-{
-    m_rect = rect;
-    m_dirty_geometry = true;
-}
-
-void QSGDefaultClipNode::setRadius(qreal radius)
-{
-    m_radius = radius;
-    m_dirty_geometry = true;
-    setIsRectangular(radius == 0);
-}
-
-void QSGDefaultClipNode::update()
-{
-    if (m_dirty_geometry) {
-        updateGeometry();
-        m_dirty_geometry = false;
-    }
-}
-
-void QSGDefaultClipNode::updateGeometry()
-{
-    QSGGeometry *g = geometry();
-
-    if (qFuzzyIsNull(m_radius)) {
-        g->allocate(4);
-        QSGGeometry::updateRectGeometry(g, m_rect);
-
-    } else {
-        int vertexCount = 0;
-
-        // Radius should never exceeds half of the width or half of the height
-        qreal radius = qMin(qMin(m_rect.width() / 2, m_rect.height() / 2), m_radius);
-        QRectF rect = m_rect;
-        rect.adjust(radius, radius, -radius, -radius);
-
-        int segments = qMin(30, qCeil(radius)); // Number of segments per corner.
-
-        g->allocate((segments + 1) * 2);
-
-        QVector2D *vertices = (QVector2D *)g->vertexData();
-
-        for (int part = 0; part < 2; ++part) {
-            for (int i = 0; i <= segments; ++i) {
-                //### Should change to calculate sin/cos only once.
-                qreal angle = qreal(0.5 * M_PI) * (part + i / qreal(segments));
-                qreal s = qFastSin(angle);
-                qreal c = qFastCos(angle);
-                qreal y = (part ? rect.bottom() : rect.top()) - radius * c; // current inner y-coordinate.
-                qreal lx = rect.left() - radius * s; // current inner left x-coordinate.
-                qreal rx = rect.right() + radius * s; // current inner right x-coordinate.
-
-                vertices[vertexCount++] = QVector2D(rx, y);
-                vertices[vertexCount++] = QVector2D(lx, y);
-            }
-        }
-
-        markDirty(DirtyGeometry);
-    }
-    setClipRect(m_rect);
-}
-
diff --git a/src/declarative/items/qsgclipnode_p.h b/src/declarative/items/qsgclipnode_p.h
deleted file mode 100644 (file)
index 0e6d057..0000000
+++ /dev/null
@@ -1,71 +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 QSGCLIPNODE_P_H
-#define QSGCLIPNODE_P_H
-
-#include <qsgnode.h>
-
-class QSGDefaultClipNode : public QSGClipNode
-{
-public:
-    QSGDefaultClipNode(const QRectF &);
-
-    void setRect(const QRectF &);
-    QRectF rect() const { return m_rect; }
-
-    void setRadius(qreal radius);
-    qreal radius() const { return m_radius; }
-
-    virtual void update();
-
-private:
-    void updateGeometry();
-    QRectF m_rect;
-    qreal m_radius;
-
-    uint m_dirty_geometry : 1;
-    uint m_reserved : 31;
-
-    QSGGeometry m_geometry;
-};
-
-#endif // QSGCLIPNODE_P_H
diff --git a/src/declarative/items/qsgdrag.cpp b/src/declarative/items/qsgdrag.cpp
deleted file mode 100644 (file)
index b95e495..0000000
+++ /dev/null
@@ -1,462 +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 "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
deleted file mode 100644 (file)
index 246c6e6..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-// 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/qsgdroparea.cpp b/src/declarative/items/qsgdroparea.cpp
deleted file mode 100644 (file)
index a1b81be..0000000
+++ /dev/null
@@ -1,426 +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 "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/qsgdroparea_p.h b/src/declarative/items/qsgdroparea_p.h
deleted file mode 100644 (file)
index cd51f57..0000000
+++ /dev/null
@@ -1,167 +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 QSGDROPAREA_P_H
-#define QSGDROPAREA_P_H
-
-#include "qsgitem.h"
-
-#include <private/qdeclarativeguard_p.h>
-#include <private/qv8engine_p.h>
-
-#include <QtGui/qevent.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGDropAreaPrivate;
-class QSGDropEvent : public QObject
-{
-    Q_OBJECT
-    Q_PROPERTY(qreal x READ x)
-    Q_PROPERTY(qreal y READ y)
-    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:
-    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 *);
-
-private:
-    QSGDropAreaPrivate *d;
-    QDropEvent *event;
-};
-
-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();
-
-    qreal x() const;
-    qreal y() const;
-    QObject *source() const;
-
-Q_SIGNALS:
-    void positionChanged();
-    void sourceChanged();
-
-private:
-    QSGDropAreaPrivate *d;
-
-    friend class QSGDropArea;
-    friend class QSGDropAreaPrivate;
-};
-
-class QSGDropAreaPrivate;
-class Q_AUTOTEST_EXPORT QSGDropArea : public QSGItem
-{
-    Q_OBJECT
-    Q_PROPERTY(bool containsDrag READ containsDrag NOTIFY containsDragChanged)
-    Q_PROPERTY(QStringList keys READ keys WRITE setKeys NOTIFY keysChanged)
-    Q_PROPERTY(QSGDropAreaDrag *drag READ drag CONSTANT)
-
-public:
-    QSGDropArea(QSGItem *parent=0);
-    ~QSGDropArea();
-
-    bool containsDrag() const;
-    void setContainsDrag(bool drag);
-
-    QStringList keys() const;
-    void setKeys(const QStringList &keys);
-
-    QSGDropAreaDrag *drag();
-
-Q_SIGNALS:
-    void containsDragChanged();
-    void keysChanged();
-    void sourceChanged();
-
-    void entered(QSGDropEvent *drag);
-    void exited();
-    void positionChanged(QSGDropEvent *drag);
-    void dropped(QSGDropEvent *drop);
-
-protected:
-    void dragMoveEvent(QDragMoveEvent *event);
-    void dragEnterEvent(QDragEnterEvent *event);
-    void dragLeaveEvent(QDragLeaveEvent *event);
-    void dropEvent(QDropEvent *event);
-
-private:
-    Q_DISABLE_COPY(QSGDropArea)
-    Q_DECLARE_PRIVATE(QSGDropArea)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGDropEvent)
-QML_DECLARE_TYPE(QSGDropArea)
-
-QT_END_HEADER
-
-#endif // QSGDRAGTARGET_P_H
diff --git a/src/declarative/items/qsgevents.cpp b/src/declarative/items/qsgevents.cpp
deleted file mode 100644 (file)
index 2173b4a..0000000
+++ /dev/null
@@ -1,239 +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 "qsgevents_p_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
-    \qmlclass KeyEvent QSGKeyEvent
-    \inqmlmodule QtQuick 2
-    \ingroup qml-event-elements
-
-    \brief The KeyEvent object provides information about a key event.
-
-    For example, the following changes the Item's state property when the Enter
-    key is pressed:
-    \qml
-Item {
-    focus: true
-    Keys.onPressed: { if (event.key == Qt.Key_Enter) state = 'ShowDetails'; }
-}
-    \endqml
-*/
-
-/*!
-    \qmlproperty int QtQuick2::KeyEvent::key
-
-    This property holds the code of the key that was pressed or released.
-
-    See \l {Qt::Key}{Qt.Key} for the list of keyboard codes. These codes are
-    independent of the underlying window system. Note that this
-    function does not distinguish between capital and non-capital
-    letters, use the text() function (returning the Unicode text the
-    key generated) for this purpose.
-
-    A value of either 0 or \l {Qt::Key_unknown}{Qt.Key_Unknown} means that the event is not
-    the result of a known key; for example, it may be the result of
-    a compose sequence, a keyboard macro, or due to key event
-    compression.
-*/
-
-/*!
-    \qmlproperty string QtQuick2::KeyEvent::text
-
-    This property holds the Unicode text that the key generated.
-    The text returned can be an empty string in cases where modifier keys,
-    such as Shift, Control, Alt, and Meta, are being pressed or released.
-    In such cases \c key will contain a valid value
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::KeyEvent::isAutoRepeat
-
-    This property holds whether this event comes from an auto-repeating key.
-*/
-
-/*!
-    \qmlproperty int QtQuick2::KeyEvent::count
-
-    This property holds the number of keys involved in this event. If \l KeyEvent::text
-    is not empty, this is simply the length of the string.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::KeyEvent::accepted
-
-    Setting \a accepted to true prevents the key event from being
-    propagated to the item's parent.
-
-    Generally, if the item acts on the key event then it should be accepted
-    so that ancestor items do not also respond to the same event.
-*/
-
-/*!
-    \qmlproperty int QtQuick2::KeyEvent::modifiers
-
-    This property holds the keyboard modifier flags that existed immediately
-    before the event occurred.
-
-    It contains a bitwise combination of:
-    \list
-    \o Qt.NoModifier - No modifier key is pressed.
-    \o Qt.ShiftModifier - A Shift key on the keyboard is pressed.
-    \o Qt.ControlModifier - A Ctrl key on the keyboard is pressed.
-    \o Qt.AltModifier - An Alt key on the keyboard is pressed.
-    \o Qt.MetaModifier - A Meta key on the keyboard is pressed.
-    \o Qt.KeypadModifier - A keypad button is pressed.
-    \endlist
-
-    For example, to react to a Shift key + Enter key combination:
-    \qml
-    Item {
-        focus: true
-        Keys.onPressed: {
-            if ((event.key == Qt.Key_Enter) && (event.modifiers & Qt.ShiftModifier))
-                doSomething();
-        }
-    }
-    \endqml
-*/
-
-
-/*!
-    \qmlclass MouseEvent QSGMouseEvent
-    \inqmlmodule QtQuick 2
-    \ingroup qml-event-elements
-
-    \brief The MouseEvent object provides information about a mouse event.
-
-    The position of the mouse can be found via the \l x and \l y properties.
-    The button that caused the event is available via the \l button property.
-
-    \sa MouseArea
-*/
-
-/*!
-    \internal
-    \class QSGMouseEvent
-*/
-
-/*!
-    \qmlproperty int QtQuick2::MouseEvent::x
-    \qmlproperty int QtQuick2::MouseEvent::y
-
-    These properties hold the coordinates of the position supplied by the mouse event.
-*/
-
-
-/*!
-    \qmlproperty bool QtQuick2::MouseEvent::accepted
-
-    Setting \a accepted to true prevents the mouse event from being
-    propagated to items below this item.
-
-    Generally, if the item acts on the mouse event then it should be accepted
-    so that items lower in the stacking order do not also respond to the same event.
-*/
-
-/*!
-    \qmlproperty enumeration QtQuick2::MouseEvent::button
-
-    This property holds the button that caused the event.  It can be one of:
-    \list
-    \o Qt.LeftButton
-    \o Qt.RightButton
-    \o Qt.MiddleButton
-    \endlist
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::MouseEvent::wasHeld
-
-    This property is true if the mouse button has been held pressed longer the
-    threshold (800ms).
-*/
-
-/*!
-    \qmlproperty int QtQuick2::MouseEvent::buttons
-
-    This property holds the mouse buttons pressed when the event was generated.
-    For mouse move events, this is all buttons that are pressed down. For mouse
-    press and double click events this includes the button that caused the event.
-    For mouse release events this excludes the button that caused the event.
-
-    It contains a bitwise combination of:
-    \list
-    \o Qt.LeftButton
-    \o Qt.RightButton
-    \o Qt.MiddleButton
-    \endlist
-*/
-
-/*!
-    \qmlproperty int QtQuick2::MouseEvent::modifiers
-
-    This property holds the keyboard modifier flags that existed immediately
-    before the event occurred.
-
-    It contains a bitwise combination of:
-    \list
-    \o Qt.NoModifier - No modifier key is pressed.
-    \o Qt.ShiftModifier - A Shift key on the keyboard is pressed.
-    \o Qt.ControlModifier - A Ctrl key on the keyboard is pressed.
-    \o Qt.AltModifier - An Alt key on the keyboard is pressed.
-    \o Qt.MetaModifier - A Meta key on the keyboard is pressed.
-    \o Qt.KeypadModifier - A keypad button is pressed.
-    \endlist
-
-    For example, to react to a Shift key + Left mouse button click:
-    \qml
-    MouseArea {
-        onClicked: {
-            if ((mouse.button == Qt.LeftButton) && (mouse.modifiers & Qt.ShiftModifier))
-                doSomething();
-        }
-    }
-    \endqml
-*/
-
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgevents_p_p.h b/src/declarative/items/qsgevents_p_p.h
deleted file mode 100644 (file)
index 1d2b6a9..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
-/****************************************************************************
-**
-** 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 QSGEVENTS_P_P_H
-#define QSGEVENTS_P_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 <qdeclarative.h>
-
-#include <QtCore/qobject.h>
-#include <QtGui/qevent.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGKeyEvent : 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:
-    QSGKeyEvent(QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, const QString &text=QString(), bool autorep=false, ushort count=1)
-        : event(type, key, modifiers, text, autorep, count) { event.setAccepted(false); }
-    QSGKeyEvent(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;
-};
-
-// used in QtLocation
-class Q_DECLARATIVE_EXPORT QSGMouseEvent : 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 wasHeld READ wasHeld)
-    Q_PROPERTY(bool isClick READ isClick)
-    Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
-
-public:
-    QSGMouseEvent(int x, int y, Qt::MouseButton button, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers
-                  , bool isClick=false, bool wasHeld=false)
-        : _x(x), _y(y), _button(button), _buttons(buttons), _modifiers(modifiers)
-          , _wasHeld(wasHeld), _isClick(isClick), _accepted(true) {}
-
-    int x() const { return _x; }
-    int y() const { return _y; }
-    int button() const { return _button; }
-    int buttons() const { return _buttons; }
-    int modifiers() const { return _modifiers; }
-    bool wasHeld() const { return _wasHeld; }
-    bool isClick() const { return _isClick; }
-
-    // only for internal usage
-    void setX(int x) { _x = x; }
-    void setY(int y) { _y = y; }
-    void setPosition(const QPointF &point) { _x = point.x(); _y = point.y(); }
-
-    bool isAccepted() { return _accepted; }
-    void setAccepted(bool accepted) { _accepted = accepted; }
-
-private:
-    int _x;
-    int _y;
-    Qt::MouseButton _button;
-    Qt::MouseButtons _buttons;
-    Qt::KeyboardModifiers _modifiers;
-    bool _wasHeld;
-    bool _isClick;
-    bool _accepted;
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGKeyEvent)
-QML_DECLARE_TYPE(QSGMouseEvent)
-
-#endif // QSGEVENTS_P_P_H
diff --git a/src/declarative/items/qsgflickable.cpp b/src/declarative/items/qsgflickable.cpp
deleted file mode 100644 (file)
index 4871a43..0000000
+++ /dev/null
@@ -1,1997 +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 "qsgflickable_p.h"
-#include "qsgflickable_p_p.h"
-#include "qsgcanvas.h"
-#include "qsgcanvas_p.h"
-
-#include <QtDeclarative/qdeclarativeinfo.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qguiapplication.h>
-#include <QtGui/qstylehints.h>
-#include "qplatformdefs.h"
-
-QT_BEGIN_NAMESPACE
-
-// The maximum number of pixels a flick can overshoot
-#ifndef QML_FLICK_OVERSHOOT
-#define QML_FLICK_OVERSHOOT 200
-#endif
-
-// The number of samples to use in calculating the velocity of a flick
-#ifndef QML_FLICK_SAMPLEBUFFER
-#define QML_FLICK_SAMPLEBUFFER 3
-#endif
-
-// The number of samples to discard when calculating the flick velocity.
-// Touch panels often produce inaccurate results as the finger is lifted.
-#ifndef QML_FLICK_DISCARDSAMPLES
-#define QML_FLICK_DISCARDSAMPLES 1
-#endif
-
-// The default maximum velocity of a flick.
-#ifndef QML_FLICK_DEFAULTMAXVELOCITY
-#define QML_FLICK_DEFAULTMAXVELOCITY 2500
-#endif
-
-// The default deceleration of a flick.
-#ifndef QML_FLICK_DEFAULTDECELERATION
-#define QML_FLICK_DEFAULTDECELERATION 1500
-#endif
-
-// How much faster to decelerate when overshooting
-#ifndef QML_FLICK_OVERSHOOTFRICTION
-#define QML_FLICK_OVERSHOOTFRICTION 8
-#endif
-
-// FlickThreshold determines how far the "mouse" must have moved
-// before we perform a flick.
-static const int FlickThreshold = 20;
-
-// RetainGrabVelocity is the maxmimum instantaneous velocity that
-// will ensure the Flickable retains the grab on consecutive flicks.
-static const int RetainGrabVelocity = 15;
-
-QSGFlickableVisibleArea::QSGFlickableVisibleArea(QSGFlickable *parent)
-    : QObject(parent), flickable(parent), m_xPosition(0.), m_widthRatio(0.)
-    , m_yPosition(0.), m_heightRatio(0.)
-{
-}
-
-qreal QSGFlickableVisibleArea::widthRatio() const
-{
-    return m_widthRatio;
-}
-
-qreal QSGFlickableVisibleArea::xPosition() const
-{
-    return m_xPosition;
-}
-
-qreal QSGFlickableVisibleArea::heightRatio() const
-{
-    return m_heightRatio;
-}
-
-qreal QSGFlickableVisibleArea::yPosition() const
-{
-    return m_yPosition;
-}
-
-void QSGFlickableVisibleArea::updateVisible()
-{
-    QSGFlickablePrivate *p = QSGFlickablePrivate::get(flickable);
-
-    bool changeX = false;
-    bool changeY = false;
-    bool changeWidth = false;
-    bool changeHeight = false;
-
-    // Vertical
-    const qreal viewheight = flickable->height();
-    const qreal maxyextent = -flickable->maxYExtent() + flickable->minYExtent();
-    qreal pagePos = (-p->vData.move.value() + flickable->minYExtent()) / (maxyextent + viewheight);
-    qreal pageSize = viewheight / (maxyextent + viewheight);
-
-    if (pageSize != m_heightRatio) {
-        m_heightRatio = pageSize;
-        changeHeight = true;
-    }
-    if (pagePos != m_yPosition) {
-        m_yPosition = pagePos;
-        changeY = true;
-    }
-
-    // Horizontal
-    const qreal viewwidth = flickable->width();
-    const qreal maxxextent = -flickable->maxXExtent() + flickable->minXExtent();
-    pagePos = (-p->hData.move.value() + flickable->minXExtent()) / (maxxextent + viewwidth);
-    pageSize = viewwidth / (maxxextent + viewwidth);
-
-    if (pageSize != m_widthRatio) {
-        m_widthRatio = pageSize;
-        changeWidth = true;
-    }
-    if (pagePos != m_xPosition) {
-        m_xPosition = pagePos;
-        changeX = true;
-    }
-
-    if (changeX)
-        emit xPositionChanged(m_xPosition);
-    if (changeY)
-        emit yPositionChanged(m_yPosition);
-    if (changeWidth)
-        emit widthRatioChanged(m_widthRatio);
-    if (changeHeight)
-        emit heightRatioChanged(m_heightRatio);
-}
-
-
-QSGFlickablePrivate::QSGFlickablePrivate()
-  : contentItem(new QSGItem)
-    , hData(this, &QSGFlickablePrivate::setViewportX)
-    , vData(this, &QSGFlickablePrivate::setViewportY)
-    , hMoved(false), vMoved(false)
-    , stealMouse(false), pressed(false), interactive(true), calcVelocity(false)
-    , pixelAligned(false)
-    , deceleration(QML_FLICK_DEFAULTDECELERATION)
-    , maxVelocity(QML_FLICK_DEFAULTMAXVELOCITY), reportedVelocitySmoothing(100)
-    , delayedPressEvent(0), delayedPressTarget(0), pressDelay(0), fixupDuration(400)
-    , fixupMode(Normal), vTime(0), visibleArea(0)
-    , flickableDirection(QSGFlickable::AutoFlickDirection)
-    , boundsBehavior(QSGFlickable::DragAndOvershootBounds)
-{
-}
-
-void QSGFlickablePrivate::init()
-{
-    Q_Q(QSGFlickable);
-    QDeclarative_setParent_noEvent(contentItem, q);
-    contentItem->setParentItem(q);
-    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);
-    viewportPrivate->addItemChangeListener(this, QSGItemPrivate::Geometry);
-    lastPosTime.invalidate();
-}
-
-/*
-    Returns the amount to overshoot by given a velocity.
-    Will be roughly in range 0 - size/4
-*/
-qreal QSGFlickablePrivate::overShootDistance(qreal size)
-{
-    if (maxVelocity <= 0)
-        return 0.0;
-
-    return qMin(qreal(QML_FLICK_OVERSHOOT), size/3);
-}
-
-void QSGFlickablePrivate::AxisData::addVelocitySample(qreal v, qreal maxVelocity)
-{
-    if (v > maxVelocity)
-        v = maxVelocity;
-    else if (v < -maxVelocity)
-        v = -maxVelocity;
-    velocityBuffer.append(v);
-    if (velocityBuffer.count() > QML_FLICK_SAMPLEBUFFER)
-        velocityBuffer.remove(0);
-}
-
-void QSGFlickablePrivate::AxisData::updateVelocity()
-{
-    velocity = 0;
-    if (velocityBuffer.count() > QML_FLICK_DISCARDSAMPLES) {
-        int count = velocityBuffer.count()-QML_FLICK_DISCARDSAMPLES;
-        for (int i = 0; i < count; ++i) {
-            qreal v = velocityBuffer.at(i);
-            velocity += v;
-        }
-        velocity /= count;
-    }
-}
-
-void QSGFlickablePrivate::itemGeometryChanged(QSGItem *item, const QRectF &newGeom, const QRectF &oldGeom)
-{
-    Q_Q(QSGFlickable);
-    if (item == contentItem) {
-        if (newGeom.x() != oldGeom.x())
-            emit q->contentXChanged();
-        if (newGeom.y() != oldGeom.y())
-            emit q->contentYChanged();
-    }
-}
-
-void QSGFlickablePrivate::flickX(qreal velocity)
-{
-    Q_Q(QSGFlickable);
-    flick(hData, q->minXExtent(), q->maxXExtent(), q->width(), fixupX_callback, velocity);
-}
-
-void QSGFlickablePrivate::flickY(qreal velocity)
-{
-    Q_Q(QSGFlickable);
-    flick(vData, q->minYExtent(), q->maxYExtent(), q->height(), fixupY_callback, velocity);
-}
-
-void QSGFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal,
-                                         QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity)
-{
-    Q_Q(QSGFlickable);
-    qreal maxDistance = -1;
-    data.fixingUp = false;
-    // -ve velocity means list is moving up
-    if (velocity > 0) {
-        maxDistance = qAbs(minExtent - data.move.value());
-        data.flickTarget = minExtent;
-    } else {
-        maxDistance = qAbs(maxExtent - data.move.value());
-        data.flickTarget = maxExtent;
-    }
-    if (maxDistance > 0) {
-        qreal v = velocity;
-        if (maxVelocity != -1 && maxVelocity < qAbs(v)) {
-            if (v < 0)
-                v = -maxVelocity;
-            else
-                v = maxVelocity;
-        }
-        timeline.reset(data.move);
-        if (boundsBehavior == QSGFlickable::DragAndOvershootBounds)
-            timeline.accel(data.move, v, deceleration);
-        else
-            timeline.accel(data.move, v, deceleration, maxDistance);
-        timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this));
-        if (!hData.flicking && q->xflick()) {
-            hData.flicking = true;
-            emit q->flickingChanged();
-            emit q->flickingHorizontallyChanged();
-            if (!vData.flicking)
-                emit q->flickStarted();
-        }
-        if (!vData.flicking && q->yflick()) {
-            vData.flicking = true;
-            emit q->flickingChanged();
-            emit q->flickingVerticallyChanged();
-            if (!hData.flicking)
-                emit q->flickStarted();
-        }
-    } else {
-        timeline.reset(data.move);
-        fixup(data, minExtent, maxExtent);
-    }
-}
-
-void QSGFlickablePrivate::fixupY_callback(void *data)
-{
-    ((QSGFlickablePrivate *)data)->fixupY();
-}
-
-void QSGFlickablePrivate::fixupX_callback(void *data)
-{
-    ((QSGFlickablePrivate *)data)->fixupX();
-}
-
-void QSGFlickablePrivate::fixupX()
-{
-    Q_Q(QSGFlickable);
-    fixup(hData, q->minXExtent(), q->maxXExtent());
-}
-
-void QSGFlickablePrivate::fixupY()
-{
-    Q_Q(QSGFlickable);
-    fixup(vData, q->minYExtent(), q->maxYExtent());
-}
-
-void QSGFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
-{
-    if (data.move.value() > minExtent || maxExtent > minExtent) {
-        timeline.reset(data.move);
-        if (data.move.value() != minExtent) {
-            switch (fixupMode) {
-            case Immediate:
-                timeline.set(data.move, minExtent);
-                break;
-            case ExtentChanged:
-                // The target has changed. Don't start from the beginning; just complete the
-                // second half of the animation using the new extent.
-                timeline.move(data.move, minExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
-                data.fixingUp = true;
-                break;
-            default: {
-                    qreal dist = minExtent - data.move;
-                    timeline.move(data.move, minExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
-                    timeline.move(data.move, minExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
-                    data.fixingUp = true;
-                }
-            }
-        }
-    } else if (data.move.value() < maxExtent) {
-        timeline.reset(data.move);
-        switch (fixupMode) {
-        case Immediate:
-            timeline.set(data.move, maxExtent);
-            break;
-        case ExtentChanged:
-            // The target has changed. Don't start from the beginning; just complete the
-            // second half of the animation using the new extent.
-            timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
-            data.fixingUp = true;
-            break;
-        default: {
-                qreal dist = maxExtent - data.move;
-                timeline.move(data.move, maxExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
-                timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
-                data.fixingUp = true;
-            }
-        }
-    }
-    data.inOvershoot = false;
-    fixupMode = Normal;
-    vTime = timeline.time();
-}
-
-void QSGFlickablePrivate::updateBeginningEnd()
-{
-    Q_Q(QSGFlickable);
-    bool atBoundaryChange = false;
-
-    // Vertical
-    const int maxyextent = int(-q->maxYExtent());
-    const qreal ypos = -vData.move.value();
-    bool atBeginning = (ypos <= -q->minYExtent());
-    bool atEnd = (maxyextent <= ypos);
-
-    if (atBeginning != vData.atBeginning) {
-        vData.atBeginning = atBeginning;
-        atBoundaryChange = true;
-    }
-    if (atEnd != vData.atEnd) {
-        vData.atEnd = atEnd;
-        atBoundaryChange = true;
-    }
-
-    // Horizontal
-    const int maxxextent = int(-q->maxXExtent());
-    const qreal xpos = -hData.move.value();
-    atBeginning = (xpos <= -q->minXExtent());
-    atEnd = (maxxextent <= xpos);
-
-    if (atBeginning != hData.atBeginning) {
-        hData.atBeginning = atBeginning;
-        atBoundaryChange = true;
-    }
-    if (atEnd != hData.atEnd) {
-        hData.atEnd = atEnd;
-        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();
-
-    if (visibleArea)
-        visibleArea->updateVisible();
-}
-
-/*
-XXXTODO add docs describing moving, dragging, flicking properties, e.g.
-
-When the user starts dragging the Flickable, the dragging and moving properties
-will be true.
-
-If the velocity is sufficient when the drag is ended, flicking may begin.
-
-The moving properties will remain true until all dragging and flicking
-is finished.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Flickable::onDragStarted()
-
-    This handler is called when the view starts to be dragged due to user
-    interaction.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Flickable::onDragEnded()
-
-    This handler is called when the user stops dragging the view.
-
-    If the velocity of the drag is suffient at the time the
-    touch/mouse button is released then a flick will start.
-*/
-
-/*!
-    \qmlclass Flickable QSGFlickable
-    \inqmlmodule QtQuick 2
-    \ingroup qml-basic-interaction-elements
-
-    \brief The Flickable item provides a surface that can be "flicked".
-    \inherits Item
-
-    The Flickable item places its children on a surface that can be dragged
-    and flicked, causing the view onto the child items to scroll. This
-    behavior forms the basis of Items that are designed to show large numbers
-    of child items, such as \l ListView and \l GridView.
-
-    In traditional user interfaces, views can be scrolled using standard
-    controls, such as scroll bars and arrow buttons. In some situations, it
-    is also possible to drag the view directly by pressing and holding a
-    mouse button while moving the cursor. In touch-based user interfaces,
-    this dragging action is often complemented with a flicking action, where
-    scrolling continues after the user has stopped touching the view.
-
-    Flickable does not automatically clip its contents. If it is not used as
-    a full-screen item, you should consider setting the \l{Item::}{clip} property
-    to true.
-
-    \section1 Example Usage
-
-    \div {class="float-right"}
-    \inlineimage flickable.gif
-    \enddiv
-
-    The following example shows a small view onto a large image in which the
-    user can drag or flick the image in order to view different parts of it.
-
-    \snippet doc/src/snippets/declarative/flickable.qml document
-
-    \clearfloat
-
-    Items declared as children of a Flickable are automatically parented to the
-    Flickable's \l contentItem.  This should be taken into account when
-    operating on the children of the Flickable; it is usually the children of
-    \c contentItem that are relevant.  For example, the bound of Items added
-    to the Flickable will be available by \c contentItem.childrenRect
-
-    \section1 Limitations
-
-    \note Due to an implementation detail, items placed inside a Flickable cannot anchor to it by
-    \c id. Use \c parent instead.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Flickable::onMovementStarted()
-
-    This handler is called when the view begins moving due to user
-    interaction.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Flickable::onMovementEnded()
-
-    This handler is called when the view stops moving due to user
-    interaction.  If a flick was generated, this handler will
-    be triggered once the flick stops.  If a flick was not
-    generated, the handler will be triggered when the
-    user stops dragging - i.e. a mouse or touch release.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Flickable::onFlickStarted()
-
-    This handler is called when the view is flicked.  A flick
-    starts from the point that the mouse or touch is released,
-    while still in motion.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Flickable::onFlickEnded()
-
-    This handler is called when the view stops moving due to a flick.
-*/
-
-/*!
-    \qmlproperty real QtQuick2::Flickable::visibleArea.xPosition
-    \qmlproperty real QtQuick2::Flickable::visibleArea.widthRatio
-    \qmlproperty real QtQuick2::Flickable::visibleArea.yPosition
-    \qmlproperty real QtQuick2::Flickable::visibleArea.heightRatio
-
-    These properties describe the position and size of the currently viewed area.
-    The size is defined as the percentage of the full view currently visible,
-    scaled to 0.0 - 1.0.  The page position is usually in the range 0.0 (beginning) to
-    1.0 minus size ratio (end), i.e. \c yPosition is in the range 0.0 to 1.0-\c heightRatio.
-    However, it is possible for the contents to be dragged outside of the normal
-    range, resulting in the page positions also being outside the normal range.
-
-    These properties are typically used to draw a scrollbar. For example:
-
-    \snippet doc/src/snippets/declarative/flickableScrollbar.qml 0
-    \dots 8
-    \snippet doc/src/snippets/declarative/flickableScrollbar.qml 1
-
-    \sa {declarative/ui-components/scrollbar}{scrollbar example}
-*/
-QSGFlickable::QSGFlickable(QSGItem *parent)
-  : QSGItem(*(new QSGFlickablePrivate), parent)
-{
-    Q_D(QSGFlickable);
-    d->init();
-}
-
-QSGFlickable::QSGFlickable(QSGFlickablePrivate &dd, QSGItem *parent)
-  : QSGItem(dd, parent)
-{
-    Q_D(QSGFlickable);
-    d->init();
-}
-
-QSGFlickable::~QSGFlickable()
-{
-}
-
-/*!
-    \qmlproperty real QtQuick2::Flickable::contentX
-    \qmlproperty real QtQuick2::Flickable::contentY
-
-    These properties hold the surface coordinate currently at the top-left
-    corner of the Flickable. For example, if you flick an image up 100 pixels,
-    \c contentY will be 100.
-*/
-qreal QSGFlickable::contentX() const
-{
-    Q_D(const QSGFlickable);
-    return -d->contentItem->x();
-}
-
-void QSGFlickable::setContentX(qreal pos)
-{
-    Q_D(QSGFlickable);
-    d->hData.explicitValue = true;
-    d->timeline.reset(d->hData.move);
-    d->vTime = d->timeline.time();
-    movementXEnding();
-    if (-pos != d->hData.move.value()) {
-        d->hData.move.setValue(-pos);
-        viewportMoved();
-    }
-}
-
-qreal QSGFlickable::contentY() const
-{
-    Q_D(const QSGFlickable);
-    return -d->contentItem->y();
-}
-
-void QSGFlickable::setContentY(qreal pos)
-{
-    Q_D(QSGFlickable);
-    d->vData.explicitValue = true;
-    d->timeline.reset(d->vData.move);
-    d->vTime = d->timeline.time();
-    movementYEnding();
-    if (-pos != d->vData.move.value()) {
-        d->vData.move.setValue(-pos);
-        viewportMoved();
-    }
-}
-
-/*!
-    \qmlproperty bool QtQuick2::Flickable::interactive
-
-    This property describes whether the user can interact with the Flickable.
-    A user cannot drag or flick a Flickable that is not interactive.
-
-    By default, this property is true.
-
-    This property is useful for temporarily disabling flicking. This allows
-    special interaction with Flickable's children; for example, you might want
-    to freeze a flickable map while scrolling through a pop-up dialog that
-    is a child of the Flickable.
-*/
-bool QSGFlickable::isInteractive() const
-{
-    Q_D(const QSGFlickable);
-    return d->interactive;
-}
-
-void QSGFlickable::setInteractive(bool interactive)
-{
-    Q_D(QSGFlickable);
-    if (interactive != d->interactive) {
-        d->interactive = interactive;
-        if (!interactive && (d->hData.flicking || d->vData.flicking)) {
-            d->timeline.clear();
-            d->vTime = d->timeline.time();
-            d->hData.flicking = false;
-            d->vData.flicking = false;
-            emit flickingChanged();
-            emit flickingHorizontallyChanged();
-            emit flickingVerticallyChanged();
-            emit flickEnded();
-        }
-        emit interactiveChanged();
-    }
-}
-
-/*!
-    \qmlproperty real QtQuick2::Flickable::horizontalVelocity
-    \qmlproperty real QtQuick2::Flickable::verticalVelocity
-
-    The instantaneous velocity of movement along the x and y axes, in pixels/sec.
-
-    The reported velocity is smoothed to avoid erratic output.
-*/
-qreal QSGFlickable::horizontalVelocity() const
-{
-    Q_D(const QSGFlickable);
-    return d->hData.smoothVelocity.value();
-}
-
-qreal QSGFlickable::verticalVelocity() const
-{
-    Q_D(const QSGFlickable);
-    return d->vData.smoothVelocity.value();
-}
-
-/*!
-    \qmlproperty bool QtQuick2::Flickable::atXBeginning
-    \qmlproperty bool QtQuick2::Flickable::atXEnd
-    \qmlproperty bool QtQuick2::Flickable::atYBeginning
-    \qmlproperty bool QtQuick2::Flickable::atYEnd
-
-    These properties are true if the flickable view is positioned at the beginning,
-    or end respecively.
-*/
-bool QSGFlickable::isAtXEnd() const
-{
-    Q_D(const QSGFlickable);
-    return d->hData.atEnd;
-}
-
-bool QSGFlickable::isAtXBeginning() const
-{
-    Q_D(const QSGFlickable);
-    return d->hData.atBeginning;
-}
-
-bool QSGFlickable::isAtYEnd() const
-{
-    Q_D(const QSGFlickable);
-    return d->vData.atEnd;
-}
-
-bool QSGFlickable::isAtYBeginning() const
-{
-    Q_D(const QSGFlickable);
-    return d->vData.atBeginning;
-}
-
-void QSGFlickable::ticked()
-{
-    viewportMoved();
-}
-
-/*!
-    \qmlproperty Item QtQuick2::Flickable::contentItem
-
-    The internal item that contains the Items to be moved in the Flickable.
-
-    Items declared as children of a Flickable are automatically parented to the Flickable's contentItem.
-
-    Items created dynamically need to be explicitly parented to the \e contentItem:
-    \code
-    Flickable {
-        id: myFlickable
-        function addItem(file) {
-            var component = Qt.createComponent(file)
-            component.createObject(myFlickable.contentItem);
-        }
-    }
-    \endcode
-*/
-QSGItem *QSGFlickable::contentItem()
-{
-    Q_D(QSGFlickable);
-    return d->contentItem;
-}
-
-QSGFlickableVisibleArea *QSGFlickable::visibleArea()
-{
-    Q_D(QSGFlickable);
-    if (!d->visibleArea)
-        d->visibleArea = new QSGFlickableVisibleArea(this);
-    return d->visibleArea;
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::Flickable::flickableDirection
-
-    This property determines which directions the view can be flicked.
-
-    \list
-    \o Flickable.AutoFlickDirection (default) - allows flicking vertically if the
-    \e contentHeight is not equal to the \e height of the Flickable.
-    Allows flicking horizontally if the \e contentWidth is not equal
-    to the \e width of the Flickable.
-    \o Flickable.HorizontalFlick - allows flicking horizontally.
-    \o Flickable.VerticalFlick - allows flicking vertically.
-    \o Flickable.HorizontalAndVerticalFlick - allows flicking in both directions.
-    \endlist
-*/
-QSGFlickable::FlickableDirection QSGFlickable::flickableDirection() const
-{
-    Q_D(const QSGFlickable);
-    return d->flickableDirection;
-}
-
-void QSGFlickable::setFlickableDirection(FlickableDirection direction)
-{
-    Q_D(QSGFlickable);
-    if (direction != d->flickableDirection) {
-        d->flickableDirection = direction;
-        emit flickableDirectionChanged();
-    }
-}
-
-bool QSGFlickable::pixelAligned() const
-{
-    Q_D(const QSGFlickable);
-    return d->pixelAligned;
-}
-
-void QSGFlickable::setPixelAligned(bool align)
-{
-    Q_D(QSGFlickable);
-    if (align != d->pixelAligned) {
-        d->pixelAligned = align;
-        emit pixelAlignedChanged();
-    }
-}
-
-void QSGFlickablePrivate::handleMousePressEvent(QMouseEvent *event)
-{
-    Q_Q(QSGFlickable);
-    if (interactive && timeline.isActive()
-        && (qAbs(hData.smoothVelocity.value()) > RetainGrabVelocity
-            || qAbs(vData.smoothVelocity.value()) > RetainGrabVelocity)) {
-        stealMouse = true; // If we've been flicked then steal the click.
-    } else {
-        stealMouse = false;
-    }
-    q->setKeepMouseGrab(stealMouse);
-    pressed = true;
-    timeline.clear();
-    hData.reset();
-    vData.reset();
-    hData.dragMinBound = q->minXExtent();
-    vData.dragMinBound = q->minYExtent();
-    hData.dragMaxBound = q->maxXExtent();
-    vData.dragMaxBound = q->maxYExtent();
-    fixupMode = Normal;
-    lastPos = QPoint();
-    QSGItemPrivate::start(lastPosTime);
-    pressPos = event->localPos();
-    hData.pressPos = hData.move.value();
-    vData.pressPos = vData.move.value();
-    hData.flicking = false;
-    vData.flicking = false;
-    QSGItemPrivate::start(pressTime);
-    QSGItemPrivate::start(velocityTime);
-}
-
-void QSGFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event)
-{
-    Q_Q(QSGFlickable);
-    if (!interactive || !lastPosTime.isValid())
-        return;
-    bool rejectY = false;
-    bool rejectX = false;
-
-    bool stealY = stealMouse;
-    bool stealX = stealMouse;
-
-    if (q->yflick()) {
-        int dy = int(event->localPos().y() - pressPos.y());
-        if (qAbs(dy) > qApp->styleHints()->startDragDistance() || QSGItemPrivate::elapsed(pressTime) > 200) {
-            if (!vMoved)
-                vData.dragStartOffset = dy;
-            qreal newY = dy + vData.pressPos - vData.dragStartOffset;
-            const qreal minY = vData.dragMinBound;
-            const qreal maxY = vData.dragMaxBound;
-            if (newY > minY)
-                newY = minY + (newY - minY) / 2;
-            if (newY < maxY && maxY - minY <= 0)
-                newY = maxY + (newY - maxY) / 2;
-            if (boundsBehavior == QSGFlickable::StopAtBounds && (newY > minY || newY < maxY)) {
-                rejectY = true;
-                if (newY < maxY) {
-                    newY = maxY;
-                    rejectY = false;
-                }
-                if (newY > minY) {
-                    newY = minY;
-                    rejectY = false;
-                }
-            }
-            if (!rejectY && stealMouse) {
-                vData.move.setValue(qRound(newY));
-                vMoved = true;
-            }
-            if (qAbs(dy) > qApp->styleHints()->startDragDistance())
-                stealY = true;
-        }
-    }
-
-    if (q->xflick()) {
-        int dx = int(event->localPos().x() - pressPos.x());
-        if (qAbs(dx) > qApp->styleHints()->startDragDistance() || QSGItemPrivate::elapsed(pressTime) > 200) {
-            if (!hMoved)
-                hData.dragStartOffset = dx;
-            qreal newX = dx + hData.pressPos - hData.dragStartOffset;
-            const qreal minX = hData.dragMinBound;
-            const qreal maxX = hData.dragMaxBound;
-            if (newX > minX)
-                newX = minX + (newX - minX) / 2;
-            if (newX < maxX && maxX - minX <= 0)
-                newX = maxX + (newX - maxX) / 2;
-            if (boundsBehavior == QSGFlickable::StopAtBounds && (newX > minX || newX < maxX)) {
-                rejectX = true;
-                if (newX < maxX) {
-                    newX = maxX;
-                    rejectX = false;
-                }
-                if (newX > minX) {
-                    newX = minX;
-                    rejectX = false;
-                }
-            }
-            if (!rejectX && stealMouse) {
-                hData.move.setValue(qRound(newX));
-                hMoved = true;
-            }
-
-            if (qAbs(dx) > qApp->styleHints()->startDragDistance())
-                stealX = true;
-        }
-    }
-
-    stealMouse = stealX || stealY;
-    if (stealMouse)
-        q->setKeepMouseGrab(true);
-
-    if (rejectY) {
-        vData.velocityBuffer.clear();
-        vData.velocity = 0;
-    }
-    if (rejectX) {
-        hData.velocityBuffer.clear();
-        hData.velocity = 0;
-    }
-
-    if (hMoved || vMoved) {
-        draggingStarting();
-        q->movementStarting();
-        q->viewportMoved();
-    }
-
-    if (!lastPos.isNull()) {
-        qreal elapsed = qreal(QSGItemPrivate::elapsed(lastPosTime)) / 1000.;
-        if (elapsed <= 0)
-            return;
-        QSGItemPrivate::restart(lastPosTime);
-        qreal dy = event->localPos().y()-lastPos.y();
-        if (q->yflick() && !rejectY)
-            vData.addVelocitySample(dy/elapsed, maxVelocity);
-        qreal dx = event->localPos().x()-lastPos.x();
-        if (q->xflick() && !rejectX)
-            hData.addVelocitySample(dx/elapsed, maxVelocity);
-    }
-
-    lastPos = event->localPos();
-}
-
-void QSGFlickablePrivate::handleMouseReleaseEvent(QMouseEvent *event)
-{
-    Q_Q(QSGFlickable);
-    stealMouse = false;
-    q->setKeepMouseGrab(false);
-    pressed = false;
-
-    // if we drag then pause before release we should not cause a flick.
-    qint64 elapsed = QSGItemPrivate::elapsed(lastPosTime);
-
-    vData.updateVelocity();
-    hData.updateVelocity();
-
-    draggingEnding();
-
-    if (!lastPosTime.isValid())
-        return;
-
-    vTime = timeline.time();
-
-    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) {
-        velocityTimeline.reset(vData.smoothVelocity);
-        vData.smoothVelocity.setValue(-velocity);
-        flickY(velocity);
-    } else {
-        fixupY();
-    }
-
-    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) {
-        velocityTimeline.reset(hData.smoothVelocity);
-        hData.smoothVelocity.setValue(-velocity);
-        flickX(velocity);
-    } else {
-        fixupX();
-    }
-
-    if (!timeline.isActive())
-        q->movementEnding();
-}
-
-void QSGFlickable::mousePressEvent(QMouseEvent *event)
-{
-    Q_D(QSGFlickable);
-    if (d->interactive) {
-        if (!d->pressed)
-            d->handleMousePressEvent(event);
-        event->accept();
-    } else {
-        QSGItem::mousePressEvent(event);
-    }
-}
-
-void QSGFlickable::mouseMoveEvent(QMouseEvent *event)
-{
-    Q_D(QSGFlickable);
-    if (d->interactive) {
-        d->handleMouseMoveEvent(event);
-        event->accept();
-    } else {
-        QSGItem::mouseMoveEvent(event);
-    }
-}
-
-void QSGFlickable::mouseReleaseEvent(QMouseEvent *event)
-{
-    Q_D(QSGFlickable);
-    if (d->interactive) {
-        d->clearDelayedPress();
-        d->handleMouseReleaseEvent(event);
-        event->accept();
-        ungrabMouse();
-    } else {
-        QSGItem::mouseReleaseEvent(event);
-    }
-}
-
-void QSGFlickable::wheelEvent(QWheelEvent *event)
-{
-    Q_D(QSGFlickable);
-    if (!d->interactive) {
-        QSGItem::wheelEvent(event);
-    } else if (yflick() && event->orientation() == Qt::Vertical) {
-        bool valid = false;
-        if (event->delta() > 0 && contentY() > -minYExtent()) {
-            d->vData.velocity = qMax(event->delta()*2 - d->vData.smoothVelocity.value(), qreal(d->maxVelocity/4));
-            valid = true;
-        } else if (event->delta() < 0 && contentY() < -maxYExtent()) {
-            d->vData.velocity = qMin(event->delta()*2 - d->vData.smoothVelocity.value(), qreal(-d->maxVelocity/4));
-            valid = true;
-        }
-        if (valid) {
-            d->vData.flicking = false;
-            d->flickY(d->vData.velocity);
-            if (d->vData.flicking) {
-                d->vMoved = true;
-                movementStarting();
-            }
-            event->accept();
-        }
-    } else if (xflick() && event->orientation() == Qt::Horizontal) {
-        bool valid = false;
-        if (event->delta() > 0 && contentX() > -minXExtent()) {
-            d->hData.velocity = qMax(event->delta()*2 - d->hData.smoothVelocity.value(), qreal(d->maxVelocity/4));
-            valid = true;
-        } else if (event->delta() < 0 && contentX() < -maxXExtent()) {
-            d->hData.velocity = qMin(event->delta()*2 - d->hData.smoothVelocity.value(), qreal(-d->maxVelocity/4));
-            valid = true;
-        }
-        if (valid) {
-            d->hData.flicking = false;
-            d->flickX(d->hData.velocity);
-            if (d->hData.flicking) {
-                d->hMoved = true;
-                movementStarting();
-            }
-            event->accept();
-        }
-    } else {
-        QSGItem::wheelEvent(event);
-    }
-}
-
-bool QSGFlickablePrivate::isOutermostPressDelay() const
-{
-    Q_Q(const QSGFlickable);
-    QSGItem *item = q->parentItem();
-    while (item) {
-        QSGFlickable *flick = qobject_cast<QSGFlickable*>(item);
-        if (flick && flick->pressDelay() > 0 && flick->isInteractive())
-            return false;
-        item = item->parentItem();
-    }
-
-    return true;
-}
-
-void QSGFlickablePrivate::captureDelayedPress(QMouseEvent *event)
-{
-    Q_Q(QSGFlickable);
-    if (!q->canvas() || pressDelay <= 0)
-        return;
-    if (!isOutermostPressDelay())
-        return;
-    delayedPressTarget = q->canvas()->mouseGrabberItem();
-    delayedPressEvent = new QMouseEvent(*event);
-    delayedPressEvent->setAccepted(false);
-    delayedPressTimer.start(pressDelay, q);
-}
-
-void QSGFlickablePrivate::clearDelayedPress()
-{
-    if (delayedPressEvent) {
-        delayedPressTimer.stop();
-        delete delayedPressEvent;
-        delayedPressEvent = 0;
-    }
-}
-
-//XXX pixelAligned ignores the global position of the Flickable, i.e. assumes Flickable itself is pixel aligned.
-void QSGFlickablePrivate::setViewportX(qreal x)
-{
-    contentItem->setX(pixelAligned ? qRound(x) : x);
-}
-
-void QSGFlickablePrivate::setViewportY(qreal y)
-{
-    contentItem->setY(pixelAligned ? qRound(y) : y);
-}
-
-void QSGFlickable::timerEvent(QTimerEvent *event)
-{
-    Q_D(QSGFlickable);
-    if (event->timerId() == d->delayedPressTimer.timerId()) {
-        d->delayedPressTimer.stop();
-        if (d->delayedPressEvent) {
-            QSGItem *grabber = canvas() ? canvas()->mouseGrabberItem() : 0;
-            if (!grabber || grabber != this) {
-                // We replay the mouse press but the grabber we had might not be interessted by the event (e.g. overlay)
-                // so we reset the grabber
-                if (canvas()->mouseGrabberItem() == d->delayedPressTarget)
-                    d->delayedPressTarget->ungrabMouse();
-                // Use the event handler that will take care of finding the proper item to propagate the event
-                QSGCanvasPrivate::get(canvas())->deliverMouseEvent(d->delayedPressEvent);
-            }
-            delete d->delayedPressEvent;
-            d->delayedPressEvent = 0;
-        }
-    }
-}
-
-qreal QSGFlickable::minYExtent() const
-{
-    Q_D(const QSGFlickable);
-    return d->vData.startMargin;
-}
-
-qreal QSGFlickable::minXExtent() const
-{
-    Q_D(const QSGFlickable);
-    return d->hData.startMargin;
-}
-
-/* returns -ve */
-qreal QSGFlickable::maxXExtent() const
-{
-    Q_D(const QSGFlickable);
-    return width() - vWidth() - d->hData.endMargin;
-}
-/* returns -ve */
-qreal QSGFlickable::maxYExtent() const
-{
-    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()
-{
-    Q_D(QSGFlickable);
-
-    qreal prevX = d->lastFlickablePosition.x();
-    qreal prevY = d->lastFlickablePosition.y();
-    if (d->pressed || d->calcVelocity) {
-        int elapsed = QSGItemPrivate::restart(d->velocityTime);
-        if (elapsed > 0) {
-            qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / elapsed;
-            if (qAbs(horizontalVelocity) > 0) {
-                d->velocityTimeline.reset(d->hData.smoothVelocity);
-                d->velocityTimeline.move(d->hData.smoothVelocity, horizontalVelocity, d->reportedVelocitySmoothing);
-                d->velocityTimeline.move(d->hData.smoothVelocity, 0, d->reportedVelocitySmoothing);
-            }
-            qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / elapsed;
-            if (qAbs(verticalVelocity) > 0) {
-                d->velocityTimeline.reset(d->vData.smoothVelocity);
-                d->velocityTimeline.move(d->vData.smoothVelocity, verticalVelocity, d->reportedVelocitySmoothing);
-                d->velocityTimeline.move(d->vData.smoothVelocity, 0, d->reportedVelocitySmoothing);
-            }
-        }
-    } else {
-        if (d->timeline.time() > d->vTime) {
-            d->velocityTimeline.clear();
-            qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / (d->timeline.time() - d->vTime);
-            qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / (d->timeline.time() - d->vTime);
-            d->hData.smoothVelocity.setValue(horizontalVelocity);
-            d->vData.smoothVelocity.setValue(verticalVelocity);
-        }
-    }
-
-    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
-        d->vData.inOvershoot = true;
-        qreal maxDistance = d->overShootDistance(height());
-        d->timeline.reset(d->vData.move);
-        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->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
-        d->hData.inOvershoot = true;
-        qreal maxDistance = d->overShootDistance(width());
-        d->timeline.reset(d->hData.move);
-        d->timeline.accel(d->hData.move, -d->hData.smoothVelocity.value(), d->deceleration*QML_FLICK_OVERSHOOTFRICTION, maxDistance);
-        d->timeline.callback(QDeclarativeTimeLineCallback(&d->hData.move, d->fixupX_callback, d));
-    }
-
-    d->lastFlickablePosition = QPointF(d->hData.move.value(), d->vData.move.value());
-
-    d->vTime = d->timeline.time();
-    d->updateBeginningEnd();
-}
-
-void QSGFlickable::geometryChanged(const QRectF &newGeometry,
-                             const QRectF &oldGeometry)
-{
-    Q_D(QSGFlickable);
-    QSGItem::geometryChanged(newGeometry, oldGeometry);
-
-    bool changed = false;
-    if (newGeometry.width() != oldGeometry.width()) {
-        if (xflick())
-            changed = true;
-        if (d->hData.viewSize < 0) {
-            d->contentItem->setWidth(width());
-            emit contentWidthChanged();
-        }
-        // Make sure that we're entirely in view.
-        if (!d->pressed && !d->hData.moving && !d->vData.moving) {
-            d->fixupMode = QSGFlickablePrivate::Immediate;
-            d->fixupX();
-        }
-    }
-    if (newGeometry.height() != oldGeometry.height()) {
-        if (yflick())
-            changed = true;
-        if (d->vData.viewSize < 0) {
-            d->contentItem->setHeight(height());
-            emit contentHeightChanged();
-        }
-        // Make sure that we're entirely in view.
-        if (!d->pressed && !d->hData.moving && !d->vData.moving) {
-            d->fixupMode = QSGFlickablePrivate::Immediate;
-            d->fixupY();
-        }
-    }
-
-    if (changed)
-        d->updateBeginningEnd();
-}
-
-void QSGFlickable::cancelFlick()
-{
-    Q_D(QSGFlickable);
-    d->timeline.reset(d->hData.move);
-    d->timeline.reset(d->vData.move);
-    movementEnding();
-}
-
-void QSGFlickablePrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
-{
-    QSGItem *i = qobject_cast<QSGItem *>(o);
-    if (i) {
-        i->setParentItem(static_cast<QSGFlickablePrivate*>(prop->data)->contentItem);
-    } else {
-        o->setParent(prop->object); // XXX todo - do we want this?
-    }
-}
-
-int QSGFlickablePrivate::data_count(QDeclarativeListProperty<QObject> *)
-{
-    // XXX todo
-    return 0;
-}
-
-QObject *QSGFlickablePrivate::data_at(QDeclarativeListProperty<QObject> *, int)
-{
-    // XXX todo
-    return 0;
-}
-
-void QSGFlickablePrivate::data_clear(QDeclarativeListProperty<QObject> *)
-{
-    // XXX todo
-}
-
-QDeclarativeListProperty<QObject> QSGFlickable::flickableData()
-{
-    Q_D(QSGFlickable);
-    return QDeclarativeListProperty<QObject>(this, (void *)d, QSGFlickablePrivate::data_append,
-                                             QSGFlickablePrivate::data_count,
-                                             QSGFlickablePrivate::data_at,
-                                             QSGFlickablePrivate::data_clear);
-}
-
-QDeclarativeListProperty<QSGItem> QSGFlickable::flickableChildren()
-{
-    Q_D(QSGFlickable);
-    return QSGItemPrivate::get(d->contentItem)->children();
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::Flickable::boundsBehavior
-    This property holds whether the surface may be dragged
-    beyond the Fickable's boundaries, or overshoot the
-    Flickable's boundaries when flicked.
-
-    This enables the feeling that the edges of the view are soft,
-    rather than a hard physical boundary.
-
-    The \c boundsBehavior can be one of:
-
-    \list
-    \o Flickable.StopAtBounds - the contents can not be dragged beyond the boundary
-    of the flickable, and flicks will not overshoot.
-    \o Flickable.DragOverBounds - the contents can be dragged beyond the boundary
-    of the Flickable, but flicks will not overshoot.
-    \o Flickable.DragAndOvershootBounds (default) - the contents can be dragged
-    beyond the boundary of the Flickable, and can overshoot the
-    boundary when flicked.
-    \endlist
-*/
-QSGFlickable::BoundsBehavior QSGFlickable::boundsBehavior() const
-{
-    Q_D(const QSGFlickable);
-    return d->boundsBehavior;
-}
-
-void QSGFlickable::setBoundsBehavior(BoundsBehavior b)
-{
-    Q_D(QSGFlickable);
-    if (b == d->boundsBehavior)
-        return;
-    d->boundsBehavior = b;
-    emit boundsBehaviorChanged();
-}
-
-/*!
-    \qmlproperty real QtQuick2::Flickable::contentWidth
-    \qmlproperty real QtQuick2::Flickable::contentHeight
-
-    The dimensions of the content (the surface controlled by Flickable).
-    This should typically be set to the combined size of the items placed in the
-    Flickable.
-
-    The following snippet shows how these properties are used to display
-    an image that is larger than the Flickable item itself:
-
-    \snippet doc/src/snippets/declarative/flickable.qml document
-
-    In some cases, the the content dimensions can be automatically set
-    using the \l {Item::childrenRect.width}{childrenRect.width}
-    and \l {Item::childrenRect.height}{childrenRect.height} properties.
-*/
-qreal QSGFlickable::contentWidth() const
-{
-    Q_D(const QSGFlickable);
-    return d->hData.viewSize;
-}
-
-void QSGFlickable::setContentWidth(qreal w)
-{
-    Q_D(QSGFlickable);
-    if (d->hData.viewSize == w)
-        return;
-    d->hData.viewSize = w;
-    if (w < 0)
-        d->contentItem->setWidth(width());
-    else
-        d->contentItem->setWidth(w);
-    d->hData.markExtentsDirty();
-    // Make sure that we're entirely in view.
-    if (!d->pressed && !d->hData.moving && !d->vData.moving) {
-        d->fixupMode = QSGFlickablePrivate::Immediate;
-        d->fixupX();
-    } else if (!d->pressed && d->hData.fixingUp) {
-        d->fixupMode = QSGFlickablePrivate::ExtentChanged;
-        d->fixupX();
-    }
-    emit contentWidthChanged();
-    d->updateBeginningEnd();
-}
-
-qreal QSGFlickable::contentHeight() const
-{
-    Q_D(const QSGFlickable);
-    return d->vData.viewSize;
-}
-
-void QSGFlickable::setContentHeight(qreal h)
-{
-    Q_D(QSGFlickable);
-    if (d->vData.viewSize == h)
-        return;
-    d->vData.viewSize = h;
-    if (h < 0)
-        d->contentItem->setHeight(height());
-    else
-        d->contentItem->setHeight(h);
-    d->vData.markExtentsDirty();
-    // Make sure that we're entirely in view.
-    if (!d->pressed && !d->hData.moving && !d->vData.moving) {
-        d->fixupMode = QSGFlickablePrivate::Immediate;
-        d->fixupY();
-    } else if (!d->pressed && d->vData.fixingUp) {
-        d->fixupMode = QSGFlickablePrivate::ExtentChanged;
-        d->fixupY();
-    }
-    emit contentHeightChanged();
-    d->updateBeginningEnd();
-}
-
-/*!
-    \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)
-
-    Resizes the content to \a width x \a height about \a center.
-
-    This does not scale the contents of the Flickable - it only resizes the \l contentWidth
-    and \l contentHeight.
-
-    Resizing the content may result in the content being positioned outside
-    the bounds of the Flickable.  Calling \l returnToBounds() will
-    move the content back within legal bounds.
-*/
-void QSGFlickable::resizeContent(qreal w, qreal h, QPointF center)
-{
-    Q_D(QSGFlickable);
-    if (w != d->hData.viewSize) {
-        qreal oldSize = d->hData.viewSize;
-        d->hData.viewSize = w;
-        d->contentItem->setWidth(w);
-        emit contentWidthChanged();
-        if (center.x() != 0) {
-            qreal pos = center.x() * w / oldSize;
-            setContentX(contentX() + pos - center.x());
-        }
-    }
-    if (h != d->vData.viewSize) {
-        qreal oldSize = d->vData.viewSize;
-        d->vData.viewSize = h;
-        d->contentItem->setHeight(h);
-        emit contentHeightChanged();
-        if (center.y() != 0) {
-            qreal pos = center.y() * h / oldSize;
-            setContentY(contentY() + pos - center.y());
-        }
-    }
-    d->updateBeginningEnd();
-}
-
-/*!
-    \qmlmethod QtQuick2::Flickable::returnToBounds()
-
-    Ensures the content is within legal bounds.
-
-    This may be called to ensure that the content is within legal bounds
-    after manually positioning the content.
-*/
-void QSGFlickable::returnToBounds()
-{
-    Q_D(QSGFlickable);
-    d->fixupX();
-    d->fixupY();
-}
-
-qreal QSGFlickable::vWidth() const
-{
-    Q_D(const QSGFlickable);
-    if (d->hData.viewSize < 0)
-        return width();
-    else
-        return d->hData.viewSize;
-}
-
-qreal QSGFlickable::vHeight() const
-{
-    Q_D(const QSGFlickable);
-    if (d->vData.viewSize < 0)
-        return height();
-    else
-        return d->vData.viewSize;
-}
-
-bool QSGFlickable::xflick() const
-{
-    Q_D(const QSGFlickable);
-    if (d->flickableDirection == QSGFlickable::AutoFlickDirection)
-        return vWidth() != width();
-    return d->flickableDirection & QSGFlickable::HorizontalFlick;
-}
-
-bool QSGFlickable::yflick() const
-{
-    Q_D(const QSGFlickable);
-    if (d->flickableDirection == QSGFlickable::AutoFlickDirection)
-        return vHeight() !=  height();
-    return d->flickableDirection & QSGFlickable::VerticalFlick;
-}
-
-void QSGFlickable::mouseUngrabEvent()
-{
-    Q_D(QSGFlickable);
-    if (d->pressed) {
-        // if our mouse grab has been removed (probably by another Flickable),
-        // fix our state
-        d->pressed = false;
-        d->draggingEnding();
-        d->stealMouse = false;
-        setKeepMouseGrab(false);
-    }
-}
-
-bool QSGFlickable::sendMouseEvent(QMouseEvent *event)
-{
-    Q_D(QSGFlickable);
-    QRectF myRect = mapRectToScene(QRectF(0, 0, width(), height()));
-
-    QSGCanvas *c = canvas();
-    QSGItem *grabber = c ? c->mouseGrabberItem() : 0;
-    bool disabledItem = grabber && !grabber->isEnabled();
-    bool stealThisEvent = d->stealMouse;
-    if ((stealThisEvent || myRect.contains(event->windowPos())) && (!grabber || !grabber->keepMouseGrab() || disabledItem)) {
-        QMouseEvent mouseEvent(event->type(), mapFromScene(event->windowPos()), event->windowPos(), event->screenPos(),
-                               event->button(), event->buttons(), event->modifiers());
-
-        mouseEvent.setAccepted(false);
-
-        switch (mouseEvent.type()) {
-        case QEvent::MouseMove:
-            d->handleMouseMoveEvent(&mouseEvent);
-            break;
-        case QEvent::MouseButtonPress:
-            if (d->pressed) // we are already pressed - this is a delayed replay
-                return false;
-
-            d->handleMousePressEvent(&mouseEvent);
-            d->captureDelayedPress(event);
-            stealThisEvent = d->stealMouse;   // Update stealThisEvent in case changed by function call above
-            break;
-        case QEvent::MouseButtonRelease:
-            if (d->delayedPressEvent) {
-                // We replay the mouse press but the grabber we had might not be interessted by the event (e.g. overlay)
-                // so we reset the grabber
-                if (c->mouseGrabberItem() == d->delayedPressTarget)
-                    d->delayedPressTarget->ungrabMouse();
-                //Use the event handler that will take care of finding the proper item to propagate the event
-                QSGCanvasPrivate::get(canvas())->deliverMouseEvent(d->delayedPressEvent);
-                d->clearDelayedPress();
-                // We send the release
-                canvas()->sendEvent(c->mouseGrabberItem(), event);
-                // And the event has been consumed
-                d->stealMouse = false;
-                d->pressed = false;
-                return true;
-            }
-            d->handleMouseReleaseEvent(&mouseEvent);
-            break;
-        default:
-            break;
-        }
-        grabber = qobject_cast<QSGItem*>(c->mouseGrabberItem());
-        if ((grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) || disabledItem) {
-            d->clearDelayedPress();
-            grabMouse();
-        }
-
-        return stealThisEvent || d->delayedPressEvent || disabledItem;
-    } else if (d->lastPosTime.isValid()) {
-        d->lastPosTime.invalidate();
-        returnToBounds();
-    }
-    if (event->type() == QEvent::MouseButtonRelease) {
-        d->lastPosTime.invalidate();
-        d->clearDelayedPress();
-        d->stealMouse = false;
-        d->pressed = false;
-    }
-    return false;
-}
-
-
-bool QSGFlickable::childMouseEventFilter(QSGItem *i, QEvent *e)
-{
-    Q_D(QSGFlickable);
-    if (!isVisible() || !d->interactive || !isEnabled())
-        return QSGItem::childMouseEventFilter(i, e);
-    switch (e->type()) {
-    case QEvent::MouseButtonPress:
-    case QEvent::MouseMove:
-    case QEvent::MouseButtonRelease:
-        return sendMouseEvent(static_cast<QMouseEvent *>(e));
-    default:
-        break;
-    }
-
-    return QSGItem::childMouseEventFilter(i, e);
-}
-
-/*!
-    \qmlproperty real QtQuick2::Flickable::maximumFlickVelocity
-    This property holds the maximum velocity that the user can flick the view in pixels/second.
-
-    The default value is platform dependent.
-*/
-qreal QSGFlickable::maximumFlickVelocity() const
-{
-    Q_D(const QSGFlickable);
-    return d->maxVelocity;
-}
-
-void QSGFlickable::setMaximumFlickVelocity(qreal v)
-{
-    Q_D(QSGFlickable);
-    if (v == d->maxVelocity)
-        return;
-    d->maxVelocity = v;
-    emit maximumFlickVelocityChanged();
-}
-
-/*!
-    \qmlproperty real QtQuick2::Flickable::flickDeceleration
-    This property holds the rate at which a flick will decelerate.
-
-    The default value is platform dependent.
-*/
-qreal QSGFlickable::flickDeceleration() const
-{
-    Q_D(const QSGFlickable);
-    return d->deceleration;
-}
-
-void QSGFlickable::setFlickDeceleration(qreal deceleration)
-{
-    Q_D(QSGFlickable);
-    if (deceleration == d->deceleration)
-        return;
-    d->deceleration = deceleration;
-    emit flickDecelerationChanged();
-}
-
-bool QSGFlickable::isFlicking() const
-{
-    Q_D(const QSGFlickable);
-    return d->hData.flicking ||  d->vData.flicking;
-}
-
-/*!
-    \qmlproperty bool QtQuick2::Flickable::flicking
-    \qmlproperty bool QtQuick2::Flickable::flickingHorizontally
-    \qmlproperty bool QtQuick2::Flickable::flickingVertically
-
-    These properties describe whether the view is currently moving horizontally,
-    vertically or in either direction, due to the user flicking the view.
-*/
-bool QSGFlickable::isFlickingHorizontally() const
-{
-    Q_D(const QSGFlickable);
-    return d->hData.flicking;
-}
-
-bool QSGFlickable::isFlickingVertically() const
-{
-    Q_D(const QSGFlickable);
-    return d->vData.flicking;
-}
-
-/*!
-    \qmlproperty bool QtQuick2::Flickable::dragging
-    \qmlproperty bool QtQuick2::Flickable::draggingHorizontally
-    \qmlproperty bool QtQuick2::Flickable::draggingVertically
-
-    These properties describe whether the view is currently moving horizontally,
-    vertically or in either direction, due to the user dragging the view.
-*/
-bool QSGFlickable::isDragging() const
-{
-    Q_D(const QSGFlickable);
-    return d->hData.dragging ||  d->vData.dragging;
-}
-
-bool QSGFlickable::isDraggingHorizontally() const
-{
-    Q_D(const QSGFlickable);
-    return d->hData.dragging;
-}
-
-bool QSGFlickable::isDraggingVertically() const
-{
-    Q_D(const QSGFlickable);
-    return d->vData.dragging;
-}
-
-void QSGFlickablePrivate::draggingStarting()
-{
-    Q_Q(QSGFlickable);
-    bool wasDragging = hData.dragging || vData.dragging;
-    if (hMoved && !hData.dragging) {
-        hData.dragging = true;
-        emit q->draggingHorizontallyChanged();
-    }
-    if (vMoved && !vData.dragging) {
-        vData.dragging = true;
-        emit q->draggingVerticallyChanged();
-    }
-    if (!wasDragging && (hData.dragging || vData.dragging)) {
-        emit q->draggingChanged();
-        emit q->dragStarted();
-    }
-}
-
-void QSGFlickablePrivate::draggingEnding()
-{
-    Q_Q(QSGFlickable);
-    bool wasDragging = hData.dragging || vData.dragging;
-    if (hData.dragging) {
-        hData.dragging = false;
-        emit q->draggingHorizontallyChanged();
-    }
-    if (vData.dragging) {
-        vData.dragging = false;
-        emit q->draggingVerticallyChanged();
-    }
-    if (wasDragging && !hData.dragging && !vData.dragging) {
-        emit q->draggingChanged();
-        emit q->dragEnded();
-    }
-}
-
-/*!
-    \qmlproperty int QtQuick2::Flickable::pressDelay
-
-    This property holds the time to delay (ms) delivering a press to
-    children of the Flickable.  This can be useful where reacting
-    to a press before a flicking action has undesirable effects.
-
-    If the flickable is dragged/flicked before the delay times out
-    the press event will not be delivered.  If the button is released
-    within the timeout, both the press and release will be delivered.
-
-    Note that for nested Flickables with pressDelay set, the pressDelay of
-    inner Flickables is overridden by the outermost Flickable.
-*/
-int QSGFlickable::pressDelay() const
-{
-    Q_D(const QSGFlickable);
-    return d->pressDelay;
-}
-
-void QSGFlickable::setPressDelay(int delay)
-{
-    Q_D(QSGFlickable);
-    if (d->pressDelay == delay)
-        return;
-    d->pressDelay = delay;
-    emit pressDelayChanged();
-}
-
-/*!
-    \qmlproperty bool QtQuick2::Flickable::moving
-    \qmlproperty bool QtQuick2::Flickable::movingHorizontally
-    \qmlproperty bool QtQuick2::Flickable::movingVertically
-
-    These properties describe whether the view is currently moving horizontally,
-    vertically or in either direction, due to the user either dragging or
-    flicking the view.
-*/
-
-bool QSGFlickable::isMoving() const
-{
-    Q_D(const QSGFlickable);
-    return d->hData.moving || d->vData.moving;
-}
-
-bool QSGFlickable::isMovingHorizontally() const
-{
-    Q_D(const QSGFlickable);
-    return d->hData.moving;
-}
-
-bool QSGFlickable::isMovingVertically() const
-{
-    Q_D(const QSGFlickable);
-    return d->vData.moving;
-}
-
-void QSGFlickable::movementStarting()
-{
-    Q_D(QSGFlickable);
-    if (d->hMoved && !d->hData.moving) {
-        d->hData.moving = true;
-        emit movingChanged();
-        emit movingHorizontallyChanged();
-        if (!d->vData.moving)
-            emit movementStarted();
-    }
-    else if (d->vMoved && !d->vData.moving) {
-        d->vData.moving = true;
-        emit movingChanged();
-        emit movingVerticallyChanged();
-        if (!d->hData.moving)
-            emit movementStarted();
-    }
-}
-
-void QSGFlickable::movementEnding()
-{
-    Q_D(QSGFlickable);
-    movementXEnding();
-    movementYEnding();
-    d->hData.smoothVelocity.setValue(0);
-    d->vData.smoothVelocity.setValue(0);
-}
-
-void QSGFlickable::movementXEnding()
-{
-    Q_D(QSGFlickable);
-    if (d->hData.flicking) {
-        d->hData.flicking = false;
-        emit flickingChanged();
-        emit flickingHorizontallyChanged();
-        if (!d->vData.flicking)
-           emit flickEnded();
-    }
-    if (!d->pressed && !d->stealMouse) {
-        if (d->hData.moving) {
-            d->hData.moving = false;
-            d->hMoved = false;
-            emit movingChanged();
-            emit movingHorizontallyChanged();
-            if (!d->vData.moving)
-                emit movementEnded();
-        }
-    }
-    d->hData.fixingUp = false;
-}
-
-void QSGFlickable::movementYEnding()
-{
-    Q_D(QSGFlickable);
-    if (d->vData.flicking) {
-        d->vData.flicking = false;
-        emit flickingChanged();
-        emit flickingVerticallyChanged();
-        if (!d->hData.flicking)
-           emit flickEnded();
-    }
-    if (!d->pressed && !d->stealMouse) {
-        if (d->vData.moving) {
-            d->vData.moving = false;
-            d->vMoved = false;
-            emit movingChanged();
-            emit movingVerticallyChanged();
-            if (!d->hData.moving)
-                emit movementEnded();
-        }
-    }
-    d->vData.fixingUp = false;
-}
-
-void QSGFlickablePrivate::updateVelocity()
-{
-    Q_Q(QSGFlickable);
-    emit q->horizontalVelocityChanged();
-    emit q->verticalVelocityChanged();
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgflickable_p.h b/src/declarative/items/qsgflickable_p.h
deleted file mode 100644 (file)
index 54581a5..0000000
+++ /dev/null
@@ -1,277 +0,0 @@
-// Commit: 1bcddaaf318fc37c71c5191913f3487c49444ec6
-/****************************************************************************
-**
-** 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 QSGFLICKABLE_P_H
-#define QSGFLICKABLE_P_H
-
-#include "qsgitem.h"
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGFlickablePrivate;
-class QSGFlickableVisibleArea;
-class Q_AUTOTEST_EXPORT QSGFlickable : public QSGItem
-{
-    Q_OBJECT
-
-    Q_PROPERTY(qreal contentWidth READ contentWidth WRITE setContentWidth NOTIFY contentWidthChanged)
-    Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight NOTIFY contentHeightChanged)
-    Q_PROPERTY(qreal contentX READ contentX WRITE setContentX NOTIFY contentXChanged)
-    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)
-
-    Q_PROPERTY(BoundsBehavior boundsBehavior READ boundsBehavior WRITE setBoundsBehavior NOTIFY boundsBehaviorChanged)
-    Q_PROPERTY(qreal maximumFlickVelocity READ maximumFlickVelocity WRITE setMaximumFlickVelocity NOTIFY maximumFlickVelocityChanged)
-    Q_PROPERTY(qreal flickDeceleration READ flickDeceleration WRITE setFlickDeceleration NOTIFY flickDecelerationChanged)
-    Q_PROPERTY(bool moving READ isMoving NOTIFY movingChanged)
-    Q_PROPERTY(bool movingHorizontally READ isMovingHorizontally NOTIFY movingHorizontallyChanged)
-    Q_PROPERTY(bool movingVertically READ isMovingVertically NOTIFY movingVerticallyChanged)
-    Q_PROPERTY(bool flicking READ isFlicking NOTIFY flickingChanged)
-    Q_PROPERTY(bool flickingHorizontally READ isFlickingHorizontally NOTIFY flickingHorizontallyChanged)
-    Q_PROPERTY(bool flickingVertically READ isFlickingVertically NOTIFY flickingVerticallyChanged)
-    Q_PROPERTY(bool dragging READ isDragging NOTIFY draggingChanged)
-    Q_PROPERTY(bool draggingHorizontally READ isDraggingHorizontally NOTIFY draggingHorizontallyChanged)
-    Q_PROPERTY(bool draggingVertically READ isDraggingVertically NOTIFY draggingVerticallyChanged)
-    Q_PROPERTY(FlickableDirection flickableDirection READ flickableDirection WRITE setFlickableDirection NOTIFY flickableDirectionChanged)
-
-    Q_PROPERTY(bool interactive READ isInteractive WRITE setInteractive NOTIFY interactiveChanged)
-    Q_PROPERTY(int pressDelay READ pressDelay WRITE setPressDelay NOTIFY pressDelayChanged)
-
-    Q_PROPERTY(bool atXEnd READ isAtXEnd NOTIFY isAtBoundaryChanged)
-    Q_PROPERTY(bool atYEnd READ isAtYEnd NOTIFY isAtBoundaryChanged)
-    Q_PROPERTY(bool atXBeginning READ isAtXBeginning NOTIFY isAtBoundaryChanged)
-    Q_PROPERTY(bool atYBeginning READ isAtYBeginning NOTIFY isAtBoundaryChanged)
-
-    Q_PROPERTY(QSGFlickableVisibleArea *visibleArea READ visibleArea CONSTANT)
-
-    Q_PROPERTY(bool pixelAligned READ pixelAligned WRITE setPixelAligned NOTIFY pixelAlignedChanged)
-
-    Q_PROPERTY(QDeclarativeListProperty<QObject> flickableData READ flickableData)
-    Q_PROPERTY(QDeclarativeListProperty<QSGItem> flickableChildren READ flickableChildren)
-    Q_CLASSINFO("DefaultProperty", "flickableData")
-
-    Q_ENUMS(FlickableDirection)
-    Q_ENUMS(BoundsBehavior)
-
-public:
-    QSGFlickable(QSGItem *parent=0);
-    ~QSGFlickable();
-
-    QDeclarativeListProperty<QObject> flickableData();
-    QDeclarativeListProperty<QSGItem> flickableChildren();
-
-    enum BoundsBehavior { StopAtBounds, DragOverBounds, DragAndOvershootBounds };
-    BoundsBehavior boundsBehavior() const;
-    void setBoundsBehavior(BoundsBehavior);
-
-    qreal contentWidth() const;
-    void setContentWidth(qreal);
-
-    qreal contentHeight() const;
-    void setContentHeight(qreal);
-
-    qreal contentX() const;
-    virtual void setContentX(qreal pos);
-
-    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;
-    bool isFlicking() const;
-    bool isFlickingHorizontally() const;
-    bool isFlickingVertically() const;
-    bool isDragging() const;
-    bool isDraggingHorizontally() const;
-    bool isDraggingVertically() const;
-
-    int pressDelay() const;
-    void setPressDelay(int delay);
-
-    qreal maximumFlickVelocity() const;
-    void setMaximumFlickVelocity(qreal);
-
-    qreal flickDeceleration() const;
-    void setFlickDeceleration(qreal);
-
-    bool isInteractive() const;
-    void setInteractive(bool);
-
-    qreal horizontalVelocity() const;
-    qreal verticalVelocity() const;
-
-    bool isAtXEnd() const;
-    bool isAtXBeginning() const;
-    bool isAtYEnd() const;
-    bool isAtYBeginning() const;
-
-    QSGItem *contentItem();
-
-    enum FlickableDirection { AutoFlickDirection=0x00, HorizontalFlick=0x01, VerticalFlick=0x02, HorizontalAndVerticalFlick=0x03 };
-    FlickableDirection flickableDirection() const;
-    void setFlickableDirection(FlickableDirection);
-
-    bool pixelAligned() const;
-    void setPixelAligned(bool align);
-
-    Q_INVOKABLE void resizeContent(qreal w, qreal h, QPointF center);
-    Q_INVOKABLE void returnToBounds();
-
-Q_SIGNALS:
-    void contentWidthChanged();
-    void contentHeightChanged();
-    void contentXChanged();
-    void contentYChanged();
-    void topMarginChanged();
-    void bottomMarginChanged();
-    void leftMarginChanged();
-    void rightMarginChanged();
-    void yOriginChanged();
-    void xOriginChanged();
-    void movingChanged();
-    void movingHorizontallyChanged();
-    void movingVerticallyChanged();
-    void flickingChanged();
-    void flickingHorizontallyChanged();
-    void flickingVerticallyChanged();
-    void draggingChanged();
-    void draggingHorizontallyChanged();
-    void draggingVerticallyChanged();
-    void horizontalVelocityChanged();
-    void verticalVelocityChanged();
-    void isAtBoundaryChanged();
-    void flickableDirectionChanged();
-    void interactiveChanged();
-    void boundsBehaviorChanged();
-    void maximumFlickVelocityChanged();
-    void flickDecelerationChanged();
-    void pressDelayChanged();
-    void movementStarted();
-    void movementEnded();
-    void flickStarted();
-    void flickEnded();
-    void dragStarted();
-    void dragEnded();
-    void pixelAlignedChanged();
-
-protected:
-    virtual bool childMouseEventFilter(QSGItem *, QEvent *);
-    virtual void mousePressEvent(QMouseEvent *event);
-    virtual void mouseMoveEvent(QMouseEvent *event);
-    virtual void mouseReleaseEvent(QMouseEvent *event);
-    virtual void wheelEvent(QWheelEvent *event);
-    virtual void timerEvent(QTimerEvent *event);
-
-    QSGFlickableVisibleArea *visibleArea();
-
-protected Q_SLOTS:
-    virtual void ticked();
-    void movementStarting();
-    void movementEnding();
-
-protected:
-    void movementXEnding();
-    void movementYEnding();
-    virtual qreal minXExtent() const;
-    virtual qreal minYExtent() const;
-    virtual qreal maxXExtent() const;
-    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);
-    void mouseUngrabEvent();
-    bool sendMouseEvent(QMouseEvent *event);
-
-    bool xflick() const;
-    bool yflick() const;
-    void cancelFlick();
-
-protected:
-    QSGFlickable(QSGFlickablePrivate &dd, QSGItem *parent);
-
-private:
-    Q_DISABLE_COPY(QSGFlickable)
-    Q_DECLARE_PRIVATE(QSGFlickable)
-    friend class QSGFlickableVisibleArea;
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGFlickable)
-
-QT_END_HEADER
-
-#endif // QSGFLICKABLE_P_H
diff --git a/src/declarative/items/qsgflickable_p_p.h b/src/declarative/items/qsgflickable_p_p.h
deleted file mode 100644 (file)
index b7a91a0..0000000
+++ /dev/null
@@ -1,262 +0,0 @@
-// Commit: 160f1867868cdea916923652b00484ed11f90aaa
-/****************************************************************************
-**
-** 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 QSGFLICKABLE_P_P_H
-#define QSGFLICKABLE_P_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 "qsgflickable_p.h"
-#include "qsgitem_p.h"
-#include "qsgitemchangelistener_p.h"
-
-#include <QtDeclarative/qdeclarative.h>
-#include <QtCore/qdatetime.h>
-#include "qplatformdefs.h"
-
-#include <private/qdeclarativetimeline_p_p.h>
-#include <private/qdeclarativeanimation_p_p.h>
-
-QT_BEGIN_NAMESPACE
-
-// Really slow flicks can be annoying.
-const qreal MinimumFlickVelocity = 75.0;
-
-class QSGFlickableVisibleArea;
-class QSGFlickablePrivate : public QSGItemPrivate, public QSGItemChangeListener
-{
-    Q_DECLARE_PUBLIC(QSGFlickable)
-
-public:
-    static inline QSGFlickablePrivate *get(QSGFlickable *o) { return o->d_func(); }
-
-    QSGFlickablePrivate();
-    void init();
-
-    struct Velocity : public QDeclarativeTimeLineValue
-    {
-        Velocity(QSGFlickablePrivate *p)
-            : parent(p) {}
-        virtual void setValue(qreal v) {
-            if (v != value()) {
-                QDeclarativeTimeLineValue::setValue(v);
-                parent->updateVelocity();
-            }
-        }
-        QSGFlickablePrivate *parent;
-    };
-
-    struct AxisData {
-        AxisData(QSGFlickablePrivate *fp, void (QSGFlickablePrivate::*func)(qreal))
-            : 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() {
-            velocityBuffer.clear();
-            dragStartOffset = 0;
-            fixingUp = false;
-            inOvershoot = false;
-        }
-
-        void markExtentsDirty() {
-            minExtentDirty = true;
-            maxExtentDirty = true;
-            extentsChanged = true;
-        }
-
-        void addVelocitySample(qreal v, qreal maxVelocity);
-        void updateVelocity();
-
-        QDeclarativeTimeLineValueProxy<QSGFlickablePrivate> move;
-        qreal viewSize;
-        qreal pressPos;
-        qreal dragStartOffset;
-        qreal dragMinBound;
-        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);
-    void flickY(qreal velocity);
-    virtual void flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
-                        QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity);
-
-    void fixupX();
-    void fixupY();
-    virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent);
-
-    void updateBeginningEnd();
-
-    bool isOutermostPressDelay() const;
-    void captureDelayedPress(QMouseEvent *event);
-    void clearDelayedPress();
-
-    void setViewportX(qreal x);
-    void setViewportY(qreal y);
-
-    qreal overShootDistance(qreal size);
-
-    void itemGeometryChanged(QSGItem *, const QRectF &, const QRectF &);
-
-    void draggingStarting();
-    void draggingEnding();
-
-public:
-    QSGItem *contentItem;
-
-    AxisData hData;
-    AxisData vData;
-
-    QDeclarativeTimeLine timeline;
-    bool hMoved : 1;
-    bool vMoved : 1;
-    bool stealMouse : 1;
-    bool pressed : 1;
-    bool interactive : 1;
-    bool calcVelocity : 1;
-    bool pixelAligned : 1;
-    QElapsedTimer lastPosTime;
-    QPointF lastPos;
-    QPointF pressPos;
-    QElapsedTimer pressTime;
-    qreal deceleration;
-    qreal maxVelocity;
-    QElapsedTimer velocityTime;
-    QPointF lastFlickablePosition;
-    qreal reportedVelocitySmoothing;
-    QMouseEvent *delayedPressEvent;
-    QSGItem *delayedPressTarget;
-    QBasicTimer delayedPressTimer;
-    int pressDelay;
-    int fixupDuration;
-
-    enum FixupMode { Normal, Immediate, ExtentChanged };
-    FixupMode fixupMode;
-
-    static void fixupY_callback(void *);
-    static void fixupX_callback(void *);
-
-    void updateVelocity();
-    int vTime;
-    QDeclarativeTimeLine velocityTimeline;
-    QSGFlickableVisibleArea *visibleArea;
-    QSGFlickable::FlickableDirection flickableDirection;
-    QSGFlickable::BoundsBehavior boundsBehavior;
-
-    void handleMousePressEvent(QMouseEvent *);
-    void handleMouseMoveEvent(QMouseEvent *);
-    void handleMouseReleaseEvent(QMouseEvent *);
-
-    // flickableData property
-    static void data_append(QDeclarativeListProperty<QObject> *, QObject *);
-    static int data_count(QDeclarativeListProperty<QObject> *);
-    static QObject *data_at(QDeclarativeListProperty<QObject> *, int);
-    static void data_clear(QDeclarativeListProperty<QObject> *);
-};
-
-class QSGFlickableVisibleArea : public QObject
-{
-    Q_OBJECT
-
-    Q_PROPERTY(qreal xPosition READ xPosition NOTIFY xPositionChanged)
-    Q_PROPERTY(qreal yPosition READ yPosition NOTIFY yPositionChanged)
-    Q_PROPERTY(qreal widthRatio READ widthRatio NOTIFY widthRatioChanged)
-    Q_PROPERTY(qreal heightRatio READ heightRatio NOTIFY heightRatioChanged)
-
-public:
-    QSGFlickableVisibleArea(QSGFlickable *parent=0);
-
-    qreal xPosition() const;
-    qreal widthRatio() const;
-    qreal yPosition() const;
-    qreal heightRatio() const;
-
-    void updateVisible();
-
-signals:
-    void xPositionChanged(qreal xPosition);
-    void yPositionChanged(qreal yPosition);
-    void widthRatioChanged(qreal widthRatio);
-    void heightRatioChanged(qreal heightRatio);
-
-private:
-    QSGFlickable *flickable;
-    qreal m_xPosition;
-    qreal m_widthRatio;
-    qreal m_yPosition;
-    qreal m_heightRatio;
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGFlickableVisibleArea)
-
-#endif // QSGFLICKABLE_P_P_H
diff --git a/src/declarative/items/qsgflipable.cpp b/src/declarative/items/qsgflipable.cpp
deleted file mode 100644 (file)
index ac68b31..0000000
+++ /dev/null
@@ -1,308 +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 "qsgflipable_p.h"
-#include "qsgitem_p.h"
-
-#include <private/qdeclarativeguard_p.h>
-
-#include <QtDeclarative/qdeclarativeinfo.h>
-
-QT_BEGIN_NAMESPACE
-
-// XXX todo - i think this needs work and a bit of a re-think
-
-class QSGLocalTransform : public QSGTransform
-{
-    Q_OBJECT
-public:
-    QSGLocalTransform(QObject *parent) : QSGTransform(parent) {}
-
-    void setTransform(const QTransform &t) {
-        transform = t;
-        update();
-    }
-    virtual void applyTo(QMatrix4x4 *matrix) const {
-        *matrix *= transform;
-    }
-private:
-    QTransform transform;
-};
-
-class QSGFlipablePrivate : public QSGItemPrivate
-{
-    Q_DECLARE_PUBLIC(QSGFlipable)
-public:
-    QSGFlipablePrivate() : current(QSGFlipable::Front), front(0), back(0), sideDirty(false) {}
-
-    virtual void transformChanged();
-    void updateSide();
-    void setBackTransform();
-
-    QSGFlipable::Side current;
-    QDeclarativeGuard<QSGLocalTransform> backTransform;
-    QDeclarativeGuard<QSGItem> front;
-    QDeclarativeGuard<QSGItem> back;
-
-    bool sideDirty;
-    bool wantBackXFlipped;
-    bool wantBackYFlipped;
-};
-
-/*!
-    \qmlclass Flipable QSGFlipable
-    \inqmlmodule QtQuick 2
-    \ingroup qml-basic-interaction-elements
-    \brief The Flipable item provides a surface that can be flipped.
-    \inherits Item
-
-    Flipable is an item that can be visibly "flipped" between its front and
-    back sides, like a card. It is used together with \l Rotation, \l State
-    and \l Transition elements to produce a flipping effect.
-
-    The \l front and \l back properties are used to hold the items that are
-    shown respectively on the front and back sides of the flipable item.
-
-    \section1 Example Usage
-
-    The following example shows a Flipable item that flips whenever it is
-    clicked, rotating about the y-axis.
-
-    This flipable item has a \c flipped boolean property that is toggled
-    whenever the MouseArea within the flipable is clicked. When
-    \c flipped is true, the item changes to the "back" state; in this
-    state, the \c angle of the \l Rotation item is changed to 180
-    degrees to produce the flipping effect. When \c flipped is false, the
-    item reverts to the default state, in which the \c angle value is 0.
-
-    \snippet doc/src/snippets/declarative/flipable/flipable.qml 0
-
-    \image flipable.gif
-
-    The \l Transition creates the animation that changes the angle over
-    four seconds. When the item changes between its "back" and
-    default states, the NumberAnimation animates the angle between
-    its old and new values.
-
-    See \l {QML States} for details on state changes and the default
-    state, and \l {QML Animation and Transitions} for more information on how
-    animations work within transitions.
-
-    \sa {declarative/ui-components/flipable}{Flipable example}
-*/
-QSGFlipable::QSGFlipable(QSGItem *parent)
-: QSGItem(*(new QSGFlipablePrivate), parent)
-{
-}
-
-QSGFlipable::~QSGFlipable()
-{
-}
-
-/*!
-  \qmlproperty Item QtQuick2::Flipable::front
-  \qmlproperty Item QtQuick2::Flipable::back
-
-  The front and back sides of the flipable.
-*/
-
-QSGItem *QSGFlipable::front()
-{
-    Q_D(const QSGFlipable);
-    return d->front;
-}
-
-void QSGFlipable::setFront(QSGItem *front)
-{
-    Q_D(QSGFlipable);
-    if (d->front) {
-        qmlInfo(this) << tr("front is a write-once property");
-        return;
-    }
-    d->front = front;
-    d->front->setParentItem(this);
-    if (Back == d->current)
-        d->front->setOpacity(0.);
-    emit frontChanged();
-}
-
-QSGItem *QSGFlipable::back()
-{
-    Q_D(const QSGFlipable);
-    return d->back;
-}
-
-void QSGFlipable::setBack(QSGItem *back)
-{
-    Q_D(QSGFlipable);
-    if (d->back) {
-        qmlInfo(this) << tr("back is a write-once property");
-        return;
-    }
-    if (back == 0)
-        return;
-    d->back = back;
-    d->back->setParentItem(this);
-
-    d->backTransform = new QSGLocalTransform(d->back);
-    d->backTransform->prependToItem(d->back);
-
-    if (Front == d->current)
-        d->back->setOpacity(0.);
-    connect(back, SIGNAL(widthChanged()),
-            this, SLOT(retransformBack()));
-    connect(back, SIGNAL(heightChanged()),
-            this, SLOT(retransformBack()));
-    emit backChanged();
-}
-
-void QSGFlipable::retransformBack()
-{
-    Q_D(QSGFlipable);
-    if (d->current == QSGFlipable::Back && d->back)
-        d->setBackTransform();
-}
-
-/*!
-  \qmlproperty enumeration QtQuick2::Flipable::side
-
-  The side of the Flipable currently visible. Possible values are \c
-  Flipable.Front and \c Flipable.Back.
-*/
-QSGFlipable::Side QSGFlipable::side() const
-{
-    Q_D(const QSGFlipable);
-
-    const_cast<QSGFlipablePrivate *>(d)->updateSide();
-    return d->current;
-}
-
-void QSGFlipablePrivate::transformChanged()
-{
-    Q_Q(QSGFlipable);
-
-    if (!sideDirty) {
-        sideDirty = true;
-        q->polish();
-    }
-
-    QSGItemPrivate::transformChanged();
-}
-
-void QSGFlipable::updatePolish()
-{
-    Q_D(QSGFlipable);
-    d->updateSide();
-}
-
-// determination on the currently visible side of the flipable
-// has to be done on the complete scene transform to give
-// correct results.
-void QSGFlipablePrivate::updateSide()
-{
-    Q_Q(QSGFlipable);
-
-    if (!sideDirty)
-        return;
-
-    sideDirty = false;
-
-    QTransform sceneTransform;
-    itemToParentTransform(sceneTransform);
-
-    QPointF p1(0, 0);
-    QPointF p2(1, 0);
-    QPointF p3(1, 1);
-
-    QPointF scenep1 = sceneTransform.map(p1);
-    QPointF scenep2 = sceneTransform.map(p2);
-    QPointF scenep3 = sceneTransform.map(p3);
-#if 0
-    p1 = q->mapToParent(p1);
-    p2 = q->mapToParent(p2);
-    p3 = q->mapToParent(p3);
-#endif
-
-    qreal cross = (scenep1.x() - scenep2.x()) * (scenep3.y() - scenep2.y()) -
-                  (scenep1.y() - scenep2.y()) * (scenep3.x() - scenep2.x());
-
-    wantBackYFlipped = scenep1.x() >= scenep2.x();
-    wantBackXFlipped = scenep2.y() >= scenep3.y();
-
-    QSGFlipable::Side newSide;
-    if (cross > 0) {
-        newSide = QSGFlipable::Back;
-    } else {
-        newSide = QSGFlipable::Front;
-    }
-
-    if (newSide != current) {
-        current = newSide;
-        if (current == QSGFlipable::Back && back)
-            setBackTransform();
-        if (front)
-            front->setOpacity((current==QSGFlipable::Front)?1.:0.);
-        if (back)
-            back->setOpacity((current==QSGFlipable::Back)?1.:0.);
-        emit q->sideChanged();
-    }
-}
-
-/* Depends on the width/height of the back item, and so needs reevaulating
-   if those change.
-*/
-void QSGFlipablePrivate::setBackTransform()
-{
-    QTransform mat;
-    mat.translate(back->width()/2,back->height()/2);
-    if (back->width() && wantBackYFlipped)
-        mat.rotate(180, Qt::YAxis);
-    if (back->height() && wantBackXFlipped)
-        mat.rotate(180, Qt::XAxis);
-    mat.translate(-back->width()/2,-back->height()/2);
-
-    if (backTransform)
-        backTransform->setTransform(mat);
-}
-
-QT_END_NAMESPACE
-
-#include "qsgflipable.moc"
diff --git a/src/declarative/items/qsgflipable_p.h b/src/declarative/items/qsgflipable_p.h
deleted file mode 100644 (file)
index 4c83932..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-// Commit: ebd4bc73c46c2962742a682b6a391fb68c482aec
-/****************************************************************************
-**
-** 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 QSGFLIPABLE_P_H
-#define QSGFLIPABLE_P_H
-
-#include "qsgitem.h"
-
-#include <QtGui/qtransform.h>
-#include <QtGui/qvector3d.h>
-#include <QtCore/qobject.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGFlipablePrivate;
-class Q_AUTOTEST_EXPORT QSGFlipable : public QSGItem
-{
-    Q_OBJECT
-
-    Q_ENUMS(Side)
-    Q_PROPERTY(QSGItem *front READ front WRITE setFront NOTIFY frontChanged)
-    Q_PROPERTY(QSGItem *back READ back WRITE setBack NOTIFY backChanged)
-    Q_PROPERTY(Side side READ side NOTIFY sideChanged)
-    //### flipAxis
-    //### flipRotation
-public:
-    QSGFlipable(QSGItem *parent=0);
-    ~QSGFlipable();
-
-    QSGItem *front();
-    void setFront(QSGItem *);
-
-    QSGItem *back();
-    void setBack(QSGItem *);
-
-    enum Side { Front, Back };
-    Side side() const;
-
-Q_SIGNALS:
-    void frontChanged();
-    void backChanged();
-    void sideChanged();
-
-protected:
-    virtual void updatePolish();
-
-private Q_SLOTS:
-    void retransformBack();
-
-private:
-    Q_DISABLE_COPY(QSGFlipable)
-    Q_DECLARE_PRIVATE(QSGFlipable)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGFlipable)
-
-QT_END_HEADER
-
-#endif // QSGFLIPABLE_P_H
diff --git a/src/declarative/items/qsgfocusscope.cpp b/src/declarative/items/qsgfocusscope.cpp
deleted file mode 100644 (file)
index 2018d5c..0000000
+++ /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 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 "qsgfocusscope_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
-    \qmlclass FocusScope QSGFocusScope
-    \inqmlmodule QtQuick 2
-    \ingroup qml-basic-interaction-elements
-
-    \brief The FocusScope object explicitly creates a focus scope.
-    \inherits Item
-
-    Focus scopes assist in keyboard focus handling when building reusable QML
-    components.  All the details are covered in the
-    \l {qmlfocus}{keyboard focus documentation}.
-
-    \sa {declarative/keyinteraction/focus}{Keyboard focus example}
-*/
-QSGFocusScope::QSGFocusScope(QSGItem *parent)
-: QSGItem(parent)
-{
-    setFlag(ItemIsFocusScope);
-}
-
-QSGFocusScope::~QSGFocusScope()
-{
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgfocusscope_p.h b/src/declarative/items/qsgfocusscope_p.h
deleted file mode 100644 (file)
index 222269b..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
-/****************************************************************************
-**
-** 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 QSGFOCUSSCOPE_P_H
-#define QSGFOCUSSCOPE_P_H
-
-#include "qsgitem.h"
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class Q_AUTOTEST_EXPORT QSGFocusScope : public QSGItem
-{
-    Q_OBJECT
-public:
-    QSGFocusScope(QSGItem *parent=0);
-    virtual ~QSGFocusScope();
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGFocusScope)
-
-QT_END_HEADER
-
-#endif // QSGFOCUSSCOPE_P_H
diff --git a/src/declarative/items/qsggridview.cpp b/src/declarative/items/qsggridview.cpp
deleted file mode 100644 (file)
index 2507a29..0000000
+++ /dev/null
@@ -1,1930 +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 "qsggridview_p.h"
-#include "qsgvisualitemmodel_p.h"
-#include "qsgflickable_p_p.h"
-#include "qsgitemview_p_p.h"
-
-#include <private/qdeclarativesmoothedanimation_p_p.h>
-#include <private/qlistmodelinterface_p.h>
-
-#include <QtGui/qevent.h>
-#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
-{
-public:
-    FxGridItemSG(QSGItem *i, QSGGridView *v, bool own) : FxViewItem(i, own), view(v) {
-        attached = static_cast<QSGGridViewAttached*>(qmlAttachedPropertiesObject<QSGGridView>(item));
-        if (attached)
-            static_cast<QSGGridViewAttached*>(attached)->setView(view);
-    }
-
-    ~FxGridItemSG() {}
-
-    qreal position() const {
-        return rowPos();
-    }
-
-    qreal endPosition() const {
-        return endRowPos();
-    }
-
-    qreal size() const {
-        return view->flow() == QSGGridView::LeftToRight ? view->cellHeight() : view->cellWidth();
-    }
-
-    qreal sectionSize() const {
-        return 0.0;
-    }
-
-    qreal rowPos() const {
-        if (view->flow() == QSGGridView::LeftToRight)
-            return item->y();
-        else
-            return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -view->cellWidth()-item->x() : item->x());
-    }
-
-    qreal colPos() const {
-        if (view->flow() == QSGGridView::LeftToRight) {
-            if (view->effectiveLayoutDirection() == Qt::RightToLeft) {
-                qreal colSize = view->cellWidth();
-                int columns = view->width()/colSize;
-                return colSize * (columns-1) - item->x();
-            } else {
-                return item->x();
-            }
-        } else {
-            return item->y();
-        }
-    }
-    qreal endRowPos() const {
-        if (view->flow() == QSGGridView::LeftToRight) {
-            return item->y() + view->cellHeight();
-        } else {
-            if (view->effectiveLayoutDirection() == Qt::RightToLeft)
-                return -item->x();
-            else
-                return item->x() + view->cellWidth();
-        }
-    }
-    void setPosition(qreal col, qreal row) {
-        if (view->effectiveLayoutDirection() == Qt::RightToLeft) {
-            if (view->flow() == QSGGridView::LeftToRight) {
-                int columns = view->width()/view->cellWidth();
-                item->setPos(QPointF((view->cellWidth() * (columns-1) - col), row));
-            } else {
-                item->setPos(QPointF(-view->cellWidth()-row, col));
-            }
-        } else {
-            if (view->flow() == QSGGridView::LeftToRight)
-                item->setPos(QPointF(col, row));
-            else
-                item->setPos(QPointF(row, col));
-        }
-    }
-    bool contains(qreal x, qreal y) const {
-        return (x >= item->x() && x < item->x() + view->cellWidth() &&
-                y >= item->y() && y < item->y() + view->cellHeight());
-    }
-
-    QSGGridView *view;
-};
-
-//----------------------------------------------------------------------------
-
-class QSGGridViewPrivate : public QSGItemViewPrivate
-{
-    Q_DECLARE_PUBLIC(QSGGridView)
-
-public:
-    virtual Qt::Orientation layoutOrientation() const;
-    virtual bool isContentFlowReversed() const;
-    bool isRightToLeftTopToBottom() const;
-
-    virtual qreal positionAt(int index) const;
-    virtual qreal endPositionAt(int index) const;
-    virtual qreal originPosition() const;
-    virtual qreal lastPosition() const;
-
-    qreal rowSize() const;
-    qreal colSize() const;
-    qreal colPosAt(int modelIndex) const;
-    qreal rowPosAt(int modelIndex) const;
-    qreal snapPosAt(qreal pos) const;
-    FxViewItem *snapItemAt(qreal pos) const;
-    int snapIndex() const;
-
-    virtual bool addVisibleItems(qreal fillFrom, qreal fillTo, bool doBuffer);
-    virtual bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo);
-    virtual void visibleItemsChanged();
-
-    virtual FxViewItem *newViewItem(int index, QSGItem *item);
-    virtual void repositionPackageItemAt(QSGItem *item, int index);
-    virtual void resetItemPosition(FxViewItem *item, FxViewItem *toItem);
-    virtual void resetFirstItemPosition();
-    virtual void moveItemBy(FxViewItem *item, qreal forwards, qreal backwards);
-
-    virtual void createHighlight();
-    virtual void updateHighlight();
-    virtual void resetHighlightPosition();
-
-    virtual void setPosition(qreal pos);
-    virtual void layoutVisibleItems();
-    bool applyInsertionChange(const QDeclarativeChangeSet::Insert &, FxViewItem *, InsertionsResult *);
-
-    virtual qreal headerSize() const;
-    virtual qreal footerSize() const;
-    virtual bool showHeaderForIndex(int index) const;
-    virtual bool showFooterForIndex(int index) const;
-    virtual void updateHeader();
-    virtual void updateFooter();
-
-    virtual void changedVisibleIndex(int newIndex);
-    virtual void initializeCurrentItem();
-
-    virtual void updateViewport();
-    virtual void itemGeometryChanged(QSGItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
-    virtual void fixupPosition();
-    virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent);
-    virtual void flick(QSGItemViewPrivate::AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
-                        QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity);
-
-    QSGGridView::Flow flow;
-    qreal cellWidth;
-    qreal cellHeight;
-    int columns;
-    QSGGridView::SnapMode snapMode;
-
-    QSmoothedAnimation *highlightXAnimator;
-    QSmoothedAnimation *highlightYAnimator;
-
-    QSGGridViewPrivate()
-        : flow(QSGGridView::LeftToRight)
-        , cellWidth(100), cellHeight(100), columns(1)
-        , snapMode(QSGGridView::NoSnap)
-        , highlightXAnimator(0), highlightYAnimator(0)
-    {}
-};
-
-Qt::Orientation QSGGridViewPrivate::layoutOrientation() const
-{
-    return flow == QSGGridView::LeftToRight ? Qt::Vertical : Qt::Horizontal;
-}
-
-bool QSGGridViewPrivate::isContentFlowReversed() const
-{
-    return isRightToLeftTopToBottom();
-}
-
-bool QSGGridViewPrivate::isRightToLeftTopToBottom() const
-{
-    Q_Q(const QSGGridView);
-    return flow == QSGGridView::TopToBottom && q->effectiveLayoutDirection() == Qt::RightToLeft;
-}
-
-void QSGGridViewPrivate::changedVisibleIndex(int newIndex)
-{
-    visibleIndex = newIndex / columns * columns;
-}
-
-void QSGGridViewPrivate::setPosition(qreal pos)
-{
-    Q_Q(QSGGridView);
-    if (flow == QSGGridView::LeftToRight) {
-        q->QSGFlickable::setContentY(pos);
-        q->QSGFlickable::setContentX(0);
-    } else {
-        if (q->effectiveLayoutDirection() == Qt::LeftToRight)
-            q->QSGFlickable::setContentX(pos);
-        else
-            q->QSGFlickable::setContentX(-pos-size());
-        q->QSGFlickable::setContentY(0);
-    }
-}
-
-qreal QSGGridViewPrivate::originPosition() const
-{
-    qreal pos = 0;
-    if (!visibleItems.isEmpty())
-        pos = static_cast<FxGridItemSG*>(visibleItems.first())->rowPos() - visibleIndex / columns * rowSize();
-    return pos;
-}
-
-qreal QSGGridViewPrivate::lastPosition() const
-{
-    qreal pos = 0;
-    if (model && model->count()) {
-        // get end position of last item
-        pos = (rowPosAt(model->count() - 1) + rowSize());
-    }
-    return pos;
-}
-
-qreal QSGGridViewPrivate::positionAt(int index) const
-{
-    return rowPosAt(index);
-}
-
-qreal QSGGridViewPrivate::endPositionAt(int index) const
-{
-    return rowPosAt(index) + rowSize();
-}
-
-qreal QSGGridViewPrivate::rowSize() const {
-    return flow == QSGGridView::LeftToRight ? cellHeight : cellWidth;
-}
-qreal QSGGridViewPrivate::colSize() const {
-    return flow == QSGGridView::LeftToRight ? cellWidth : cellHeight;
-}
-
-qreal QSGGridViewPrivate::colPosAt(int modelIndex) const
-{
-    if (FxViewItem *item = visibleItem(modelIndex))
-        return static_cast<FxGridItemSG*>(item)->colPos();
-    if (!visibleItems.isEmpty()) {
-        if (modelIndex < visibleIndex) {
-            int count = (visibleIndex - modelIndex) % columns;
-            int col = static_cast<FxGridItemSG*>(visibleItems.first())->colPos() / colSize();
-            col = (columns - count + col) % columns;
-            return col * colSize();
-        } else {
-            int count = columns - 1 - (modelIndex - visibleItems.last()->index - 1) % columns;
-            return static_cast<FxGridItemSG*>(visibleItems.last())->colPos() - count * colSize();
-        }
-    }
-    return (modelIndex % columns) * colSize();
-}
-
-qreal QSGGridViewPrivate::rowPosAt(int modelIndex) const
-{
-    if (FxViewItem *item = visibleItem(modelIndex))
-        return static_cast<FxGridItemSG*>(item)->rowPos();
-    if (!visibleItems.isEmpty()) {
-        if (modelIndex < visibleIndex) {
-            FxGridItemSG *firstItem = static_cast<FxGridItemSG*>(visibleItems.first());
-            int firstCol = firstItem->colPos() / colSize();
-            int col = visibleIndex - modelIndex + (columns - firstCol - 1);
-            int rows = col / columns;
-            return firstItem->rowPos() - rows * rowSize();
-        } else {
-            FxGridItemSG *lastItem = static_cast<FxGridItemSG*>(visibleItems.last());
-            int count = modelIndex - lastItem->index;
-            int col = lastItem->colPos() + count * colSize();
-            int rows = col / (columns * colSize());
-            return lastItem->rowPos() + rows * rowSize();
-        }
-    }
-    return (modelIndex / columns) * rowSize();
-}
-
-
-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()) {
-            maxExtent = q->minXExtent();
-            minExtent = q->maxXExtent();
-        } else {
-            maxExtent = flow == QSGGridView::LeftToRight ? -q->maxYExtent() : -q->maxXExtent();
-            minExtent = flow == QSGGridView::LeftToRight ? -q->minYExtent() : -q->minXExtent();
-        }
-        if (snapPos > maxExtent)
-            snapPos = maxExtent;
-        if (snapPos < minExtent)
-            snapPos = minExtent;
-    }
-    return snapPos;
-}
-
-FxViewItem *QSGGridViewPrivate::snapItemAt(qreal pos) const
-{
-    for (int i = 0; i < visibleItems.count(); ++i) {
-        FxViewItem *item = visibleItems.at(i);
-        if (item->index == -1)
-            continue;
-        qreal itemTop = item->position();
-        if (itemTop+rowSize()/2 >= pos && itemTop - rowSize()/2 <= pos)
-            return item;
-    }
-    return 0;
-}
-
-int QSGGridViewPrivate::snapIndex() const
-{
-    int index = currentIndex;
-    for (int i = 0; i < visibleItems.count(); ++i) {
-        FxGridItemSG *item = static_cast<FxGridItemSG*>(visibleItems.at(i));
-        if (item->index == -1)
-            continue;
-        qreal itemTop = item->position();
-        FxGridItemSG *hItem = static_cast<FxGridItemSG*>(highlight);
-        if (itemTop >= hItem->rowPos()-rowSize()/2 && itemTop < hItem->rowPos()+rowSize()/2) {
-            index = item->index;
-            if (item->colPos() >= hItem->colPos()-colSize()/2 && item->colPos() < hItem->colPos()+colSize()/2)
-                return item->index;
-        }
-    }
-    return index;
-}
-
-FxViewItem *QSGGridViewPrivate::newViewItem(int modelIndex, QSGItem *item)
-{
-    Q_Q(QSGGridView);
-    Q_UNUSED(modelIndex);
-    return new FxGridItemSG(item, q, false);
-}
-
-bool QSGGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool doBuffer)
-{
-    int colPos = colPosAt(visibleIndex);
-    int rowPos = rowPosAt(visibleIndex);
-    if (visibleItems.count()) {
-        FxGridItemSG *lastItem = static_cast<FxGridItemSG*>(visibleItems.last());
-        rowPos = lastItem->rowPos();
-        colPos = lastItem->colPos() + colSize();
-        if (colPos > colSize() * (columns-1)) {
-            colPos = 0;
-            rowPos += rowSize();
-        }
-    }
-
-    int modelIndex = findLastVisibleIndex();
-    modelIndex = modelIndex < 0 ? visibleIndex : modelIndex + 1;
-
-    if (visibleItems.count() && (fillFrom > rowPos + rowSize()*2
-        || fillTo < rowPosAt(visibleIndex) - rowSize())) {
-        // We've jumped more than a page.  Estimate which items are now
-        // visible and fill from there.
-        int count = (fillFrom - (rowPos + rowSize())) / (rowSize()) * columns;
-        for (int i = 0; i < visibleItems.count(); ++i)
-            releaseItem(visibleItems.at(i));
-        visibleItems.clear();
-        modelIndex += count;
-        if (modelIndex >= model->count())
-            modelIndex = model->count() - 1;
-        else if (modelIndex < 0)
-            modelIndex = 0;
-        modelIndex = modelIndex / columns * columns;
-        visibleIndex = modelIndex;
-        colPos = colPosAt(visibleIndex);
-        rowPos = rowPosAt(visibleIndex);
-    }
-
-    int colNum = colPos / colSize();
-    FxGridItemSG *item = 0;
-    bool changed = false;
-
-    while (modelIndex < model->count() && rowPos <= fillTo + rowSize()*(columns - colNum)/(columns+1)) {
-//        qDebug() << "refill: append item" << modelIndex;
-        if (!(item = static_cast<FxGridItemSG*>(createItem(modelIndex))))
-            break;
-        item->setPosition(colPos, rowPos);
-        visibleItems.append(item);
-        colPos += colSize();
-        colNum++;
-        if (colPos > colSize() * (columns-1)) {
-            colPos = 0;
-            colNum = 0;
-            rowPos += rowSize();
-        }
-        ++modelIndex;
-        changed = true;
-        if (doBuffer) // never buffer more than one item per frame
-            break;
-    }
-
-    if (visibleItems.count()) {
-        FxGridItemSG *firstItem = static_cast<FxGridItemSG*>(visibleItems.first());
-        rowPos = firstItem->rowPos();
-        colPos = firstItem->colPos() - colSize();
-        if (colPos < 0) {
-            colPos = colSize() * (columns - 1);
-            rowPos -= rowSize();
-        }
-    }
-
-    colNum = colPos / colSize();
-    while (visibleIndex > 0 && rowPos + rowSize() - 1 >= fillFrom - rowSize()*(colNum+1)/(columns+1)){
-//        qDebug() << "refill: prepend item" << visibleIndex-1 << "top pos" << rowPos << colPos;
-        if (!(item = static_cast<FxGridItemSG*>(createItem(visibleIndex-1))))
-            break;
-        --visibleIndex;
-        item->setPosition(colPos, rowPos);
-        visibleItems.prepend(item);
-        colPos -= colSize();
-        colNum--;
-        if (colPos < 0) {
-            colPos = colSize() * (columns - 1);
-            colNum = columns-1;
-            rowPos -= rowSize();
-        }
-        changed = true;
-        if (doBuffer) // never buffer more than one item per frame
-            break;
-    }
-
-    return changed;
-}
-
-bool QSGGridViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal bufferTo)
-{
-    FxGridItemSG *item = 0;
-    bool changed = false;
-
-    while (visibleItems.count() > 1
-           && (item = static_cast<FxGridItemSG*>(visibleItems.first()))
-                && item->rowPos()+rowSize()-1 < bufferFrom - rowSize()*(item->colPos()/colSize()+1)/(columns+1)) {
-        if (item->attached->delayRemove())
-            break;
-//            qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endRowPos();
-        if (item->index != -1)
-            visibleIndex++;
-        visibleItems.removeFirst();
-        releaseItem(item);
-        changed = true;
-    }
-    while (visibleItems.count() > 1
-           && (item = static_cast<FxGridItemSG*>(visibleItems.last()))
-                && item->rowPos() > bufferTo + rowSize()*(columns - item->colPos()/colSize())/(columns+1)) {
-        if (item->attached->delayRemove())
-            break;
-//            qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1;
-        visibleItems.removeLast();
-        releaseItem(item);
-        changed = true;
-    }
-
-    return changed;
-}
-
-void QSGGridViewPrivate::visibleItemsChanged()
-{
-    updateHeader();
-    updateFooter();
-    updateViewport();
-}
-
-void QSGGridViewPrivate::updateViewport()
-{
-    Q_Q(QSGGridView);
-    columns = (int)qMax((flow == QSGGridView::LeftToRight ? q->width() : q->height()) / colSize(), qreal(1.));
-    QSGItemViewPrivate::updateViewport();
-}
-
-void QSGGridViewPrivate::layoutVisibleItems()
-{
-    if (visibleItems.count()) {
-        FxGridItemSG *firstItem = static_cast<FxGridItemSG*>(visibleItems.first());
-        qreal rowPos = firstItem->rowPos();
-        qreal colPos = firstItem->colPos();
-        int col = visibleIndex % columns;
-        if (colPos != col * colSize()) {
-            colPos = col * colSize();
-            firstItem->setPosition(colPos, rowPos);
-        }
-        for (int i = 1; i < visibleItems.count(); ++i) {
-            FxGridItemSG *item = static_cast<FxGridItemSG*>(visibleItems.at(i));
-            colPos += colSize();
-            if (colPos > colSize() * (columns-1)) {
-                colPos = 0;
-                rowPos += rowSize();
-            }
-            item->setPosition(colPos, rowPos);
-        }
-    }
-}
-
-void QSGGridViewPrivate::repositionPackageItemAt(QSGItem *item, int index)
-{
-    Q_Q(QSGGridView);
-    qreal pos = position();
-    if (flow == QSGGridView::LeftToRight) {
-        if (item->y() + item->height() > pos && item->y() < pos + q->height())
-            item->setPos(QPointF(colPosAt(index), rowPosAt(index)));
-    } else {
-        if (item->x() + item->width() > pos && item->x() < pos + q->width()) {
-            if (isRightToLeftTopToBottom())
-                item->setPos(QPointF(-rowPosAt(index)-item->width(), colPosAt(index)));
-            else
-                item->setPos(QPointF(rowPosAt(index), colPosAt(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());
-}
-
-void QSGGridViewPrivate::resetFirstItemPosition()
-{
-    FxGridItemSG *item = static_cast<FxGridItemSG*>(visibleItems.first());
-    item->setPosition(0, 0);
-}
-
-void QSGGridViewPrivate::moveItemBy(FxViewItem *item, qreal forwards, qreal backwards)
-{
-    int moveCount = (forwards / rowSize()) - (backwards / rowSize());
-
-    FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(item);
-    gridItem->setPosition(gridItem->colPos(), gridItem->rowPos() + ((moveCount / columns) * rowSize()));
-}
-
-void QSGGridViewPrivate::createHighlight()
-{
-    Q_Q(QSGGridView);
-    bool changed = false;
-    if (highlight) {
-        if (trackedItem == highlight)
-            trackedItem = 0;
-        delete highlight;
-        highlight = 0;
-
-        delete highlightXAnimator;
-        delete highlightYAnimator;
-        highlightXAnimator = 0;
-        highlightYAnimator = 0;
-
-        changed = true;
-    }
-
-    if (currentItem) {
-        QSGItem *item = createHighlightItem();
-        if (item) {
-            FxGridItemSG *newHighlight = new FxGridItemSG(item, q, true);
-            if (autoHighlight)
-                resetHighlightPosition();
-            highlightXAnimator = new QSmoothedAnimation(q);
-            highlightXAnimator->target = QDeclarativeProperty(item, QLatin1String("x"));
-            highlightXAnimator->userDuration = highlightMoveDuration;
-            highlightYAnimator = new QSmoothedAnimation(q);
-            highlightYAnimator->target = QDeclarativeProperty(item, QLatin1String("y"));
-            highlightYAnimator->userDuration = highlightMoveDuration;
-
-            highlight = newHighlight;
-            changed = true;
-        }
-    }
-    if (changed)
-        emit q->highlightItemChanged();
-}
-
-void QSGGridViewPrivate::updateHighlight()
-{
-    applyPendingChanges();
-
-    if ((!currentItem && highlight) || (currentItem && !highlight))
-        createHighlight();
-    bool strictHighlight = haveHighlightRange && highlightRange == QSGGridView::StrictlyEnforceRange;
-    if (currentItem && autoHighlight && highlight && (!strictHighlight || !pressed)) {
-        // auto-update highlight
-        highlightXAnimator->to = currentItem->item->x();
-        highlightYAnimator->to = currentItem->item->y();
-        highlight->item->setWidth(currentItem->item->width());
-        highlight->item->setHeight(currentItem->item->height());
-
-        highlightXAnimator->restart();
-        highlightYAnimator->restart();
-    }
-    updateTrackedItem();
-}
-
-void QSGGridViewPrivate::resetHighlightPosition()
-{
-    if (highlight && currentItem) {
-        FxGridItemSG *cItem = static_cast<FxGridItemSG*>(currentItem);
-        static_cast<FxGridItemSG*>(highlight)->setPosition(cItem->colPos(), cItem->rowPos());
-    }
-}
-
-qreal QSGGridViewPrivate::headerSize() const
-{
-    if (!header)
-        return 0.0;
-    return flow == QSGGridView::LeftToRight ? header->item->height() : header->item->width();
-}
-
-qreal QSGGridViewPrivate::footerSize() const
-{
-    if (!footer)
-        return 0.0;
-    return flow == QSGGridView::LeftToRight? footer->item->height() : footer->item->width();
-}
-
-bool QSGGridViewPrivate::showHeaderForIndex(int index) const
-{
-    return index / columns == 0;
-}
-
-bool QSGGridViewPrivate::showFooterForIndex(int index) const
-{
-    return index / columns == (model->count()-1) / columns;
-}
-
-void QSGGridViewPrivate::updateFooter()
-{
-    Q_Q(QSGGridView);
-    bool created = false;
-    if (!footer) {
-        QSGItem *item = createComponentItem(footerComponent, true);
-        if (!item)
-            return;
-        item->setZ(1);
-        footer = new FxGridItemSG(item, q, true);
-        created = true;
-    }
-
-    FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(footer);
-    qreal colOffset = 0;
-    qreal rowOffset = 0;
-    if (q->effectiveLayoutDirection() == Qt::RightToLeft) {
-        if (flow == QSGGridView::TopToBottom)
-            rowOffset = gridItem->item->width() - cellWidth;
-        else
-            colOffset = gridItem->item->width() - cellWidth;
-    }
-    if (visibleItems.count()) {
-        qreal endPos = lastPosition();
-        if (findLastVisibleIndex() == model->count()-1) {
-            gridItem->setPosition(colOffset, endPos + rowOffset);
-        } else {
-            qreal visiblePos = isRightToLeftTopToBottom() ? -position() : position() + size();
-            if (endPos <= visiblePos || gridItem->endPosition() <= endPos + rowOffset)
-                gridItem->setPosition(colOffset, endPos + rowOffset);
-        }
-    } else {
-        gridItem->setPosition(colOffset, rowOffset);
-    }
-
-    if (created)
-        emit q->footerItemChanged();
-}
-
-void QSGGridViewPrivate::updateHeader()
-{
-    Q_Q(QSGGridView);
-    bool created = false;
-    if (!header) {
-        QSGItem *item = createComponentItem(headerComponent, true);
-        if (!item)
-            return;
-        item->setZ(1);
-        header = new FxGridItemSG(item, q, true);
-        created = true;
-    }
-
-    FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(header);
-    qreal colOffset = 0;
-    qreal rowOffset = -headerSize();
-    if (q->effectiveLayoutDirection() == Qt::RightToLeft) {
-        if (flow == QSGGridView::TopToBottom)
-            rowOffset += gridItem->item->width()-cellWidth;
-        else
-            colOffset = gridItem->item->width()-cellWidth;
-    }
-    if (visibleItems.count()) {
-        qreal startPos = originPosition();
-        if (visibleIndex == 0) {
-            gridItem->setPosition(colOffset, startPos + rowOffset);
-        } else {
-            qreal tempPos = isRightToLeftTopToBottom() ? -position()-size() : position();
-            qreal headerPos = isRightToLeftTopToBottom() ? gridItem->rowPos() + cellWidth - headerSize() : gridItem->rowPos();
-            if (tempPos <= startPos || headerPos > startPos + rowOffset)
-                gridItem->setPosition(colOffset, startPos + rowOffset);
-        }
-    } else {
-        if (isRightToLeftTopToBottom())
-            gridItem->setPosition(colOffset, rowOffset);
-        else
-            gridItem->setPosition(colOffset, -headerSize());
-    }
-
-    if (created)
-        emit q->headerItemChanged();
-}
-
-void QSGGridViewPrivate::initializeCurrentItem()
-{
-    if (currentItem && currentIndex >= 0) {
-        FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(currentItem);
-        if (gridItem)
-            gridItem->setPosition(colPosAt(currentIndex), rowPosAt(currentIndex));
-    }
-}
-
-void QSGGridViewPrivate::itemGeometryChanged(QSGItem *item, const QRectF &newGeometry, const QRectF &oldGeometry)
-{
-    Q_Q(QSGGridView);
-    QSGItemViewPrivate::itemGeometryChanged(item, newGeometry, oldGeometry);
-    if (!q->isComponentComplete())
-        return;
-    if (item == q) {
-        if (newGeometry.height() != oldGeometry.height() || newGeometry.width() != oldGeometry.width()) {
-            updateViewport();
-            forceLayout = true;
-            q->polish();
-        }
-    }
-}
-
-void QSGGridViewPrivate::fixupPosition()
-{
-    moveReason = Other;
-    if (flow == QSGGridView::LeftToRight)
-        fixupY();
-    else
-        fixupX();
-}
-
-void QSGGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
-{
-    if ((flow == QSGGridView::TopToBottom && &data == &vData)
-        || (flow == QSGGridView::LeftToRight && &data == &hData))
-        return;
-
-    fixupMode = moveReason == Mouse ? fixupMode : Immediate;
-
-    qreal viewPos = isRightToLeftTopToBottom() ? -position()-size() : position();
-
-    bool strictHighlightRange = haveHighlightRange && highlightRange == QSGGridView::StrictlyEnforceRange;
-    if (snapMode != QSGGridView::NoSnap) {
-        qreal tempPosition = isRightToLeftTopToBottom() ? -position()-size() : position();
-        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;
-        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() + highlightRangeStart - size(), -maxExtent), -minExtent);
-                else
-                    pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent);
-            }
-        } else if (bottomItem && isInBounds) {
-            if (isRightToLeftTopToBottom())
-                pos = qMax(qMin(-bottomItem->position() + highlightRangeEnd - size(), -maxExtent), -minExtent);
-            else
-                pos = qMax(qMin(bottomItem->position() - highlightRangeEnd, -maxExtent), -minExtent);
-        } else {
-            QSGItemViewPrivate::fixup(data, minExtent, maxExtent);
-            return;
-        }
-
-        qreal dist = qAbs(data.move + pos);
-        if (dist > 0) {
-            timeline.reset(data.move);
-            if (fixupMode != Immediate) {
-                timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
-                data.fixingUp = true;
-            } else {
-                timeline.set(data.move, -pos);
-            }
-            vTime = timeline.time();
-        }
-    } else if (haveHighlightRange && highlightRange == QSGGridView::StrictlyEnforceRange) {
-        if (currentItem) {
-            updateHighlight();
-            qreal pos = static_cast<FxGridItemSG*>(currentItem)->rowPos();
-            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);
-            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);
-    }
-    data.inOvershoot = false;
-    fixupMode = Normal;
-}
-
-void QSGGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
-                                        QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity)
-{
-    Q_Q(QSGGridView);
-    data.fixingUp = false;
-    moveReason = Mouse;
-    if ((!haveHighlightRange || highlightRange != QSGGridView::StrictlyEnforceRange)
-        && snapMode == QSGGridView::NoSnap) {
-        QSGItemViewPrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, velocity);
-        return;
-    }
-    qreal maxDistance = 0;
-    qreal dataValue = isRightToLeftTopToBottom() ? -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 == QSGGridView::SnapOneRow) {
-                // 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());
-            }
-        }
-        if (snapMode == QSGGridView::NoSnap && highlightRange != QSGGridView::StrictlyEnforceRange)
-            data.flickTarget = minExtent;
-    } else {
-        if (data.move.value() > maxExtent) {
-            if (snapMode == QSGGridView::SnapOneRow) {
-                // 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());
-            }
-        }
-        if (snapMode == QSGGridView::NoSnap && highlightRange != QSGGridView::StrictlyEnforceRange)
-            data.flickTarget = maxExtent;
-    }
-    bool overShoot = boundsBehavior == QSGFlickable::DragAndOvershootBounds;
-    if (maxDistance > 0 || overShoot) {
-        // This mode requires the grid to stop exactly on a row boundary.
-        qreal v = velocity;
-        if (maxVelocity != -1 && maxVelocity < qAbs(v)) {
-            if (v < 0)
-                v = -maxVelocity;
-            else
-                v = maxVelocity;
-        }
-        qreal accel = deceleration;
-        qreal v2 = v * v;
-        qreal overshootDist = 0.0;
-        if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QSGGridView::SnapOneRow) {
-            // + rowSize()/4 to encourage moving at least one item in the flick direction
-            qreal dist = v2 / (accel * 2.0) + rowSize()/4;
-            dist = qMin(dist, maxDistance);
-            if (v > 0)
-                dist = -dist;
-            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
-                qreal adjv2 = accel * 2.0f * qAbs(adjDist);
-                if (adjv2 > v2) {
-                    v2 = adjv2;
-                    v = qSqrt(v2);
-                    if (dist > 0)
-                        v = -v;
-                }
-            }
-            dist = adjDist;
-            accel = v2 / (2.0f * qAbs(dist));
-        } else {
-            data.flickTarget = velocity > 0 ? minExtent : maxExtent;
-            overshootDist = overShoot ? overShootDistance(vSize) : 0;
-        }
-        timeline.reset(data.move);
-        timeline.accel(data.move, v, accel, maxDistance + overshootDist);
-        timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this));
-        if (!hData.flicking && q->xflick()) {
-            hData.flicking = true;
-            emit q->flickingChanged();
-            emit q->flickingHorizontallyChanged();
-            emit q->flickStarted();
-        }
-        if (!vData.flicking && q->yflick()) {
-            vData.flicking = true;
-            emit q->flickingChanged();
-            emit q->flickingVerticallyChanged();
-            emit q->flickStarted();
-        }
-    } else {
-        timeline.reset(data.move);
-        fixup(data, minExtent, maxExtent);
-    }
-}
-
-
-//----------------------------------------------------------------------------
-/*!
-    \qmlclass GridView QSGGridView
-    \inqmlmodule QtQuick 2
-    \ingroup qml-view-elements
-
-    \inherits Flickable
-    \brief The GridView item provides a grid view of items provided by a model.
-
-    A GridView displays data from models created from built-in QML elements like ListModel
-    and XmlListModel, or custom model classes defined in C++ that inherit from
-    QAbstractListModel.
-
-    A GridView has a \l model, which defines the data to be displayed, and
-    a \l delegate, which defines how the data should be displayed. Items in a
-    GridView are laid out horizontally or vertically. Grid views are inherently flickable
-    as GridView inherits from \l Flickable.
-
-    \section1 Example Usage
-
-    The following example shows the definition of a simple list model defined
-    in a file called \c ContactModel.qml:
-
-    \snippet doc/src/snippets/declarative/gridview/ContactModel.qml 0
-
-    \div {class="float-right"}
-    \inlineimage gridview-simple.png
-    \enddiv
-
-    This model can be referenced as \c ContactModel in other QML files. See \l{QML Modules}
-    for more information about creating reusable components like this.
-
-    Another component can display this model data in a GridView, as in the following
-    example, which creates a \c ContactModel component for its model, and a \l Column element
-    (containing \l Image and \l Text elements) for its delegate.
-
-    \clearfloat
-    \snippet doc/src/snippets/declarative/gridview/gridview.qml import
-    \codeline
-    \snippet doc/src/snippets/declarative/gridview/gridview.qml classdocs simple
-
-    \div {class="float-right"}
-    \inlineimage gridview-highlight.png
-    \enddiv
-
-    The view will create a new delegate for each item in the model. Note that the delegate
-    is able to access the model's \c name and \c portrait data directly.
-
-    An improved grid view is shown below. The delegate is visually improved and is moved
-    into a separate \c contactDelegate component.
-
-    \clearfloat
-    \snippet doc/src/snippets/declarative/gridview/gridview.qml classdocs advanced
-
-    The currently selected item is highlighted with a blue \l Rectangle using the \l highlight property,
-    and \c focus is set to \c true to enable keyboard navigation for the grid view.
-    The grid view itself is a focus scope (see \l{qmlfocus#Acquiring Focus and Focus Scopes}{the focus documentation page} for more details).
-
-    Delegates are instantiated as needed and may be destroyed at any time.
-    State should \e never be stored in a delegate.
-
-    GridView attaches a number of properties to the root item of the delegate, for example
-    \c {GridView.isCurrentItem}.  In the following example, the root delegate item can access
-    this attached property directly as \c GridView.isCurrentItem, while the child
-    \c contactInfo object must refer to this property as \c wrapper.GridView.isCurrentItem.
-
-    \snippet doc/src/snippets/declarative/gridview/gridview.qml isCurrentItem
-
-    \note Views do not set the \l{Item::}{clip} property automatically.
-    If the view is not clipped by another item or the screen, it will be necessary
-    to set this property to true in order to clip the items that are partially or
-    fully outside the view.
-
-    \sa {declarative/modelviews/gridview}{GridView example}
-*/
-
-QSGGridView::QSGGridView(QSGItem *parent)
-    : QSGItemView(*(new QSGGridViewPrivate), parent)
-{
-}
-
-QSGGridView::~QSGGridView()
-{
-}
-
-void QSGGridView::setHighlightFollowsCurrentItem(bool autoHighlight)
-{
-    Q_D(QSGGridView);
-    if (d->autoHighlight != autoHighlight) {
-        if (!autoHighlight && d->highlightXAnimator) {
-            d->highlightXAnimator->stop();
-            d->highlightYAnimator->stop();
-        }
-        QSGItemView::setHighlightFollowsCurrentItem(autoHighlight);
-    }
-}
-
-/*!
-    \qmlattachedproperty bool QtQuick2::GridView::isCurrentItem
-    This attached property is true if this delegate is the current item; otherwise false.
-
-    It is attached to each instance of the delegate.
-*/
-
-/*!
-    \qmlattachedproperty GridView QtQuick2::GridView::view
-    This attached property holds the view that manages this delegate instance.
-
-    It is attached to each instance of the delegate.
-
-    \snippet doc/src/snippets/declarative/gridview/gridview.qml isCurrentItem
-*/
-
-/*!
-    \qmlattachedproperty bool QtQuick2::GridView::delayRemove
-    This attached property holds whether the delegate may be destroyed.
-
-    It is attached to each instance of the delegate.
-
-    It is sometimes necessary to delay the destruction of an item
-    until an animation completes.
-
-    The example below ensures that the animation completes before
-    the item is removed from the grid.
-
-    \snippet doc/src/snippets/declarative/gridview/gridview.qml delayRemove
-*/
-
-/*!
-    \qmlattachedsignal QtQuick2::GridView::onAdd()
-    This attached handler is called immediately after an item is added to the view.
-*/
-
-/*!
-    \qmlattachedsignal QtQuick2::GridView::onRemove()
-    This attached handler is called immediately before an item is removed from the view.
-*/
-
-
-/*!
-  \qmlproperty model QtQuick2::GridView::model
-  This property holds the model providing data for the grid.
-
-    The model provides the set of data that is used to create the items
-    in the view. Models can be created directly in QML using \l ListModel, \l XmlListModel
-    or \l VisualItemModel, or provided by C++ model classes. If a C++ model class is
-    used, it must be a subclass of \l QAbstractItemModel or a simple list.
-
-  \sa {qmlmodels}{Data Models}
-*/
-
-/*!
-    \qmlproperty Component QtQuick2::GridView::delegate
-
-    The delegate provides a template defining each item instantiated by the view.
-    The index is exposed as an accessible \c index property.  Properties of the
-    model are also available depending upon the type of \l {qmlmodels}{Data Model}.
-
-    The number of elements in the delegate has a direct effect on the
-    flicking performance of the view.  If at all possible, place functionality
-    that is not needed for the normal display of the delegate in a \l Loader which
-    can load additional elements when needed.
-
-    The GridView will layout the items based on the size of the root item
-    in the delegate.
-
-    \note Delegates are instantiated as needed and may be destroyed at any time.
-    State should \e never be stored in a delegate.
-*/
-
-/*!
-  \qmlproperty int QtQuick2::GridView::currentIndex
-  \qmlproperty Item QtQuick2::GridView::currentItem
-
-    The \c currentIndex property holds the index of the current item, and
-    \c currentItem holds the current item.  Setting the currentIndex to -1
-    will clear the highlight and set currentItem to null.
-
-    If highlightFollowsCurrentItem is \c true, setting either of these
-    properties will smoothly scroll the GridView so that the current
-    item becomes visible.
-
-    Note that the position of the current item
-    may only be approximate until it becomes visible in the view.
-*/
-
-
-/*!
-  \qmlproperty Item QtQuick2::GridView::highlightItem
-
-  This holds the highlight item created from the \l highlight component.
-
-  The highlightItem is managed by the view unless
-  \l highlightFollowsCurrentItem is set to false.
-
-  \sa highlight, highlightFollowsCurrentItem
-*/
-
-
-/*!
-  \qmlproperty int QtQuick2::GridView::count
-  This property holds the number of items in the view.
-*/
-
-
-/*!
-  \qmlproperty Component QtQuick2::GridView::highlight
-  This property holds the component to use as the highlight.
-
-  An instance of the highlight component is created for each view.
-  The geometry of the resulting component instance will be managed by the view
-  so as to stay with the current item, unless the highlightFollowsCurrentItem property is false.
-
-  \sa highlightItem, highlightFollowsCurrentItem
-*/
-
-/*!
-  \qmlproperty bool QtQuick2::GridView::highlightFollowsCurrentItem
-  This property sets whether the highlight is managed by the view.
-
-    If this property is true (the default value), the highlight is moved smoothly
-    to follow the current item.  Otherwise, the
-    highlight is not moved by the view, and any movement must be implemented
-    by the highlight.
-
-    Here is a highlight with its motion defined by a \l {SpringAnimation} item:
-
-    \snippet doc/src/snippets/declarative/gridview/gridview.qml highlightFollowsCurrentItem
-*/
-
-
-/*!
-    \qmlproperty int QtQuick2::GridView::highlightMoveDuration
-    This property holds the move animation duration of the highlight delegate.
-
-    highlightFollowsCurrentItem must be true for this property
-    to have effect.
-
-    The default value for the duration is 150ms.
-
-    \sa highlightFollowsCurrentItem
-*/
-
-/*!
-    \qmlproperty real QtQuick2::GridView::preferredHighlightBegin
-    \qmlproperty real QtQuick2::GridView::preferredHighlightEnd
-    \qmlproperty enumeration QtQuick2::GridView::highlightRangeMode
-
-    These properties define the preferred range of the highlight (for the current item)
-    within the view. The \c preferredHighlightBegin value must be less than the
-    \c preferredHighlightEnd value.
-
-    These properties affect the position of the current item when the view is scrolled.
-    For example, if the currently selected item should stay in the middle of the
-    view when it is scrolled, set the \c preferredHighlightBegin and
-    \c preferredHighlightEnd values to the top and bottom coordinates of where the middle
-    item would be. If the \c currentItem is changed programmatically, the view will
-    automatically scroll so that the current item is in the middle of the view.
-    Furthermore, the behavior of the current item index will occur whether or not a
-    highlight exists.
-
-    Valid values for \c highlightRangeMode are:
-
-    \list
-    \o GridView.ApplyRange - the view attempts to maintain the highlight within the range.
-       However, the highlight can move outside of the range at the ends of the view or due
-       to mouse interaction.
-    \o GridView.StrictlyEnforceRange - the highlight never moves outside of the range.
-       The current item changes if a keyboard or mouse action would cause the highlight to move
-       outside of the range.
-    \o GridView.NoHighlightRange - this is the default value.
-    \endlist
-*/
-
-
-/*!
-  \qmlproperty enumeration QtQuick2::GridView::layoutDirection
-  This property holds the layout direction of the grid.
-
-    Possible values:
-
-  \list
-  \o Qt.LeftToRight (default) - Items will be laid out starting in the top, left corner. The flow is
-  dependent on the \l GridView::flow property.
-  \o Qt.RightToLeft - Items will be laid out starting in the top, right corner. The flow is dependent
-  on the \l GridView::flow property.
-  \endlist
-
-  \bold Note: If GridView::flow is set to GridView.LeftToRight, this is not to be confused if
-  GridView::layoutDirection is set to Qt.RightToLeft. The GridView.LeftToRight flow value simply
-  indicates that the flow is horizontal.
-*/
-
-
-/*!
-    \qmlproperty enumeration QtQuick2::GridView::effectiveLayoutDirection
-    This property holds the effective layout direction of the grid.
-
-    When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} for locale layouts,
-    the visual layout direction of the grid will be mirrored. However, the
-    property \l {GridView::layoutDirection}{layoutDirection} will remain unchanged.
-
-    \sa GridView::layoutDirection, {LayoutMirroring}{LayoutMirroring}
-*/
-/*!
-  \qmlproperty bool QtQuick2::GridView::keyNavigationWraps
-  This property holds whether the grid wraps key navigation
-
-    If this is true, key navigation that would move the current item selection
-    past one end of the view instead wraps around and moves the selection to
-    the other end of the view.
-
-    By default, key navigation is not wrapped.
-*/
-/*!
-    \qmlproperty int QtQuick2::GridView::cacheBuffer
-    This property determines whether delegates are retained outside the
-    visible area of the view.
-
-    If non-zero the view will keep as many delegates
-    instantiated as will fit within the buffer specified.  For example,
-    if in a vertical view the delegate is 20 pixels high and \c cacheBuffer is
-    set to 40, then up to 2 delegates above and 2 delegates below the visible
-    area may be retained.
-
-    Note that cacheBuffer is not a pixel buffer - it only maintains additional
-    instantiated delegates.
-
-    Setting this value can make scrolling the list smoother at the expense
-    of additional memory usage.  It is not a substitute for creating efficient
-    delegates; the fewer elements in a delegate, the faster a view may be
-    scrolled.
-*/
-void QSGGridView::setHighlightMoveDuration(int duration)
-{
-    Q_D(QSGGridView);
-    if (d->highlightMoveDuration != duration) {
-        if (d->highlightYAnimator) {
-            d->highlightXAnimator->userDuration = duration;
-            d->highlightYAnimator->userDuration = duration;
-        }
-        QSGItemView::setHighlightMoveDuration(duration);
-    }
-}
-
-/*!
-  \qmlproperty enumeration QtQuick2::GridView::flow
-  This property holds the flow of the grid.
-
-    Possible values:
-
-    \list
-    \o GridView.LeftToRight (default) - Items are laid out from left to right, and the view scrolls vertically
-    \o GridView.TopToBottom - Items are laid out from top to bottom, and the view scrolls horizontally
-    \endlist
-*/
-QSGGridView::Flow QSGGridView::flow() const
-{
-    Q_D(const QSGGridView);
-    return d->flow;
-}
-
-void QSGGridView::setFlow(Flow flow)
-{
-    Q_D(QSGGridView);
-    if (d->flow != flow) {
-        d->flow = flow;
-        if (d->flow == LeftToRight) {
-            setContentWidth(-1);
-            setFlickableDirection(VerticalFlick);
-        } else {
-            setContentHeight(-1);
-            setFlickableDirection(HorizontalFlick);
-        }
-        setContentX(0);
-        setContentY(0);
-        d->regenerate();
-        emit flowChanged();
-    }
-}
-
-
-/*!
-  \qmlproperty real QtQuick2::GridView::cellWidth
-  \qmlproperty real QtQuick2::GridView::cellHeight
-
-  These properties holds the width and height of each cell in the grid.
-
-  The default cell size is 100x100.
-*/
-qreal QSGGridView::cellWidth() const
-{
-    Q_D(const QSGGridView);
-    return d->cellWidth;
-}
-
-void QSGGridView::setCellWidth(qreal cellWidth)
-{
-    Q_D(QSGGridView);
-    if (cellWidth != d->cellWidth && cellWidth > 0) {
-        d->cellWidth = qMax(qreal(1), cellWidth);
-        d->updateViewport();
-        emit cellWidthChanged();
-        d->forceLayout = true;
-        d->layout();
-    }
-}
-
-qreal QSGGridView::cellHeight() const
-{
-    Q_D(const QSGGridView);
-    return d->cellHeight;
-}
-
-void QSGGridView::setCellHeight(qreal cellHeight)
-{
-    Q_D(QSGGridView);
-    if (cellHeight != d->cellHeight && cellHeight > 0) {
-        d->cellHeight = qMax(qreal(1), cellHeight);
-        d->updateViewport();
-        emit cellHeightChanged();
-        d->forceLayout = true;
-        d->layout();
-    }
-}
-/*!
-    \qmlproperty enumeration QtQuick2::GridView::snapMode
-
-    This property determines how the view scrolling will settle following a drag or flick.
-    The possible values are:
-
-    \list
-    \o GridView.NoSnap (default) - the view stops anywhere within the visible area.
-    \o GridView.SnapToRow - the view settles with a row (or column for \c GridView.TopToBottom flow)
-    aligned with the start of the view.
-    \o GridView.SnapOneRow - the view will settle no more than one row (or column for \c GridView.TopToBottom flow)
-    away from the first visible row at the time the mouse button is released.
-    This mode is particularly useful for moving one page at a time.
-    \endlist
-
-*/
-QSGGridView::SnapMode QSGGridView::snapMode() const
-{
-    Q_D(const QSGGridView);
-    return d->snapMode;
-}
-
-void QSGGridView::setSnapMode(SnapMode mode)
-{
-    Q_D(QSGGridView);
-    if (d->snapMode != mode) {
-        d->snapMode = mode;
-        emit snapModeChanged();
-    }
-}
-
-
-/*!
-    \qmlproperty Component QtQuick2::GridView::footer
-    This property holds the component to use as the footer.
-
-    An instance of the footer component is created for each view.  The
-    footer is positioned at the end of the view, after any items.
-
-    \sa header
-*/
-/*!
-    \qmlproperty Component QtQuick2::GridView::header
-    This property holds the component to use as the header.
-
-    An instance of the header component is created for each view.  The
-    header is positioned at the beginning of the view, before any items.
-
-    \sa footer
-*/
-void QSGGridView::viewportMoved()
-{
-    Q_D(QSGGridView);
-    QSGItemView::viewportMoved();
-    if (!d->itemCount)
-        return;
-    if (d->inViewportMoved)
-        return;
-    d->inViewportMoved = true;
-
-    d->lazyRelease = true;
-    if (d->hData.flicking || d->vData.flicking) {
-        if (yflick()) {
-            if (d->vData.velocity > 0)
-                d->bufferMode = QSGGridViewPrivate::BufferBefore;
-            else if (d->vData.velocity < 0)
-                d->bufferMode = QSGGridViewPrivate::BufferAfter;
-        }
-
-        if (xflick()) {
-            if (d->hData.velocity > 0)
-                d->bufferMode = QSGGridViewPrivate::BufferBefore;
-            else if (d->hData.velocity < 0)
-                d->bufferMode = QSGGridViewPrivate::BufferAfter;
-        }
-    }
-    d->refill();
-    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 = 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();
-                d->highlightYAnimator->stop();
-                static_cast<FxGridItemSG*>(d->highlight)->setPosition(static_cast<FxGridItemSG*>(d->highlight)->colPos(), pos);
-            } else {
-                d->updateHighlight();
-            }
-
-            // update current index
-            int idx = d->snapIndex();
-            if (idx >= 0 && idx != d->currentIndex) {
-                d->updateCurrent(idx);
-                if (d->currentItem && static_cast<FxGridItemSG*>(d->currentItem)->colPos() != static_cast<FxGridItemSG*>(d->highlight)->colPos() && d->autoHighlight) {
-                    if (d->flow == LeftToRight)
-                        d->highlightXAnimator->to = d->currentItem->item->x();
-                    else
-                        d->highlightYAnimator->to = d->currentItem->item->y();
-                }
-            }
-        }
-    }
-
-    d->inViewportMoved = false;
-}
-
-void QSGGridView::keyPressEvent(QKeyEvent *event)
-{
-    Q_D(QSGGridView);
-    if (d->model && d->model->count() && d->interactive) {
-        d->moveReason = QSGGridViewPrivate::SetIndex;
-        int oldCurrent = currentIndex();
-        switch (event->key()) {
-        case Qt::Key_Up:
-            moveCurrentIndexUp();
-            break;
-        case Qt::Key_Down:
-            moveCurrentIndexDown();
-            break;
-        case Qt::Key_Left:
-            moveCurrentIndexLeft();
-            break;
-        case Qt::Key_Right:
-            moveCurrentIndexRight();
-            break;
-        default:
-            break;
-        }
-        if (oldCurrent != currentIndex()) {
-            event->accept();
-            return;
-        }
-    }
-    event->ignore();
-    QSGItemView::keyPressEvent(event);
-}
-/*!
-    \qmlmethod QtQuick2::GridView::moveCurrentIndexUp()
-
-    Move the currentIndex up one item in the view.
-    The current index will wrap if keyNavigationWraps is true and it
-    is currently at the end. This method has no effect if the \l count is zero.
-
-    \bold Note: methods should only be called after the Component has completed.
-*/
-
-
-void QSGGridView::moveCurrentIndexUp()
-{
-    Q_D(QSGGridView);
-    const int count = d->model ? d->model->count() : 0;
-    if (!count)
-        return;
-    if (d->flow == QSGGridView::LeftToRight) {
-        if (currentIndex() >= d->columns || d->wrap) {
-            int index = currentIndex() - d->columns;
-            setCurrentIndex((index >= 0 && index < count) ? index : count-1);
-        }
-    } else {
-        if (currentIndex() > 0 || d->wrap) {
-            int index = currentIndex() - 1;
-            setCurrentIndex((index >= 0 && index < count) ? index : count-1);
-        }
-    }
-}
-
-/*!
-    \qmlmethod QtQuick2::GridView::moveCurrentIndexDown()
-
-    Move the currentIndex down one item in the view.
-    The current index will wrap if keyNavigationWraps is true and it
-    is currently at the end. This method has no effect if the \l count is zero.
-
-    \bold Note: methods should only be called after the Component has completed.
-*/
-void QSGGridView::moveCurrentIndexDown()
-{
-    Q_D(QSGGridView);
-    const int count = d->model ? d->model->count() : 0;
-    if (!count)
-        return;
-    if (d->flow == QSGGridView::LeftToRight) {
-        if (currentIndex() < count - d->columns || d->wrap) {
-            int index = currentIndex()+d->columns;
-            setCurrentIndex((index >= 0 && index < count) ? index : 0);
-        }
-    } else {
-        if (currentIndex() < count - 1 || d->wrap) {
-            int index = currentIndex() + 1;
-            setCurrentIndex((index >= 0 && index < count) ? index : 0);
-        }
-    }
-}
-
-/*!
-    \qmlmethod QtQuick2::GridView::moveCurrentIndexLeft()
-
-    Move the currentIndex left one item in the view.
-    The current index will wrap if keyNavigationWraps is true and it
-    is currently at the end. This method has no effect if the \l count is zero.
-
-    \bold Note: methods should only be called after the Component has completed.
-*/
-void QSGGridView::moveCurrentIndexLeft()
-{
-    Q_D(QSGGridView);
-    const int count = d->model ? d->model->count() : 0;
-    if (!count)
-        return;
-    if (effectiveLayoutDirection() == Qt::LeftToRight) {
-        if (d->flow == QSGGridView::LeftToRight) {
-            if (currentIndex() > 0 || d->wrap) {
-                int index = currentIndex() - 1;
-                setCurrentIndex((index >= 0 && index < count) ? index : count-1);
-            }
-        } else {
-            if (currentIndex() >= d->columns || d->wrap) {
-                int index = currentIndex() - d->columns;
-                setCurrentIndex((index >= 0 && index < count) ? index : count-1);
-            }
-        }
-    } else {
-        if (d->flow == QSGGridView::LeftToRight) {
-            if (currentIndex() < count - 1 || d->wrap) {
-                int index = currentIndex() + 1;
-                setCurrentIndex((index >= 0 && index < count) ? index : 0);
-            }
-        } else {
-            if (currentIndex() < count - d->columns || d->wrap) {
-                int index = currentIndex() + d->columns;
-                setCurrentIndex((index >= 0 && index < count) ? index : 0);
-            }
-        }
-    }
-}
-
-
-/*!
-    \qmlmethod QtQuick2::GridView::moveCurrentIndexRight()
-
-    Move the currentIndex right one item in the view.
-    The current index will wrap if keyNavigationWraps is true and it
-    is currently at the end. This method has no effect if the \l count is zero.
-
-    \bold Note: methods should only be called after the Component has completed.
-*/
-void QSGGridView::moveCurrentIndexRight()
-{
-    Q_D(QSGGridView);
-    const int count = d->model ? d->model->count() : 0;
-    if (!count)
-        return;
-    if (effectiveLayoutDirection() == Qt::LeftToRight) {
-        if (d->flow == QSGGridView::LeftToRight) {
-            if (currentIndex() < count - 1 || d->wrap) {
-                int index = currentIndex() + 1;
-                setCurrentIndex((index >= 0 && index < count) ? index : 0);
-            }
-        } else {
-            if (currentIndex() < count - d->columns || d->wrap) {
-                int index = currentIndex()+d->columns;
-                setCurrentIndex((index >= 0 && index < count) ? index : 0);
-            }
-        }
-    } else {
-        if (d->flow == QSGGridView::LeftToRight) {
-            if (currentIndex() > 0 || d->wrap) {
-                int index = currentIndex() - 1;
-                setCurrentIndex((index >= 0 && index < count) ? index : count-1);
-            }
-        } else {
-            if (currentIndex() >= d->columns || d->wrap) {
-                int index = currentIndex() - d->columns;
-                setCurrentIndex((index >= 0 && index < count) ? index : count-1);
-            }
-        }
-    }
-}
-
-bool QSGGridViewPrivate::applyInsertionChange(const QDeclarativeChangeSet::Insert &change, FxViewItem *firstVisible, InsertionsResult *insertResult)
-{
-    Q_Q(QSGGridView);
-
-    int modelIndex = change.index;
-    int count = change.count;
-
-    int index = visibleItems.count() ? mapFromModel(modelIndex) : 0;
-
-    if (index < 0) {
-        int i = visibleItems.count() - 1;
-        while (i > 0 && visibleItems.at(i)->index == -1)
-            --i;
-        if (visibleItems.at(i)->index + 1 == modelIndex) {
-            // Special case of appending an item to the model.
-            index = visibleItems.count();
-        } else {
-            if (modelIndex <= visibleIndex) {
-                // Insert before visible items
-                visibleIndex += count;
-                for (int i = 0; i < visibleItems.count(); ++i) {
-                    FxViewItem *item = visibleItems.at(i);
-                    if (item->index != -1 && item->index >= modelIndex)
-                        item->index += count;
-                }
-            }
-            return true;
-        }
-    }
-
-    qreal tempPos = isRightToLeftTopToBottom() ? -position()-size()+q->width()+1 : position();
-    int colPos = 0;
-    int rowPos = 0;
-    if (visibleItems.count()) {
-        if (index < visibleItems.count()) {
-            FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(visibleItems.at(index));
-            colPos = gridItem->colPos();
-            rowPos = gridItem->rowPos();
-        } else {
-            // appending items to visible list
-            FxGridItemSG *gridItem = static_cast<FxGridItemSG*>(visibleItems.at(index-1));
-            colPos = gridItem->colPos() + colSize();
-            rowPos = gridItem->rowPos();
-            if (colPos > colSize() * (columns-1)) {
-                colPos = 0;
-                rowPos += rowSize();
-            }
-        }
-    }
-
-    // Update the indexes of the following visible items.
-    for (int i = 0; i < visibleItems.count(); ++i) {
-        FxViewItem *item = visibleItems.at(i);
-        if (item->index != -1 && item->index >= modelIndex)
-            item->index += count;
-    }
-
-    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--;
-        }
-    } 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;
-        }
-    }
-
-    updateVisibleIndex();
-
-    return insertResult->addedItems.count() > prevAddedCount;
-}
-
-/*!
-    \qmlmethod QtQuick2::GridView::positionViewAtIndex(int index, PositionMode mode)
-
-    Positions the view such that the \a index is at the position specified by
-    \a mode:
-
-    \list
-    \o GridView.Beginning - position item at the top (or left for \c GridView.TopToBottom flow) of the view.
-    \o GridView.Center - position item in the center of the view.
-    \o GridView.End - position item at bottom (or right for horizontal orientation) of the view.
-    \o GridView.Visible - if any part of the item is visible then take no action, otherwise
-    bring the item into view.
-    \o GridView.Contain - ensure the entire item is visible.  If the item is larger than
-    the view the item is positioned at the top (or left for \c GridView.TopToBottom flow) of the view.
-    \endlist
-
-    If positioning the view at the index would cause empty space to be displayed at
-    the beginning or end of the view, the view will be positioned at the boundary.
-
-    It is not recommended to use \l {Flickable::}{contentX} or \l {Flickable::}{contentY} to position the view
-    at a particular index.  This is unreliable since removing items from the start
-    of the view does not cause all other items to be repositioned.
-    The correct way to bring an item into view is with \c positionViewAtIndex.
-
-    \bold Note: methods should only be called after the Component has completed.  To position
-    the view at startup, this method should be called by Component.onCompleted.  For
-    example, to position the view at the end:
-
-    \code
-    Component.onCompleted: positionViewAtIndex(count - 1, GridView.Beginning)
-    \endcode
-*/
-
-/*!
-    \qmlmethod QtQuick2::GridView::positionViewAtBeginning()
-    \qmlmethod QtQuick2::GridView::positionViewAtEnd()
-
-    Positions the view at the beginning or end, taking into account any header or footer.
-
-    It is not recommended to use \l {Flickable::}{contentX} or \l {Flickable::}{contentY} to position the view
-    at a particular index.  This is unreliable since removing items from the start
-    of the list does not cause all other items to be repositioned, and because
-    the actual start of the view can vary based on the size of the delegates.
-
-    \bold Note: methods should only be called after the Component has completed.  To position
-    the view at startup, this method should be called by Component.onCompleted.  For
-    example, to position the view at the end on startup:
-
-    \code
-    Component.onCompleted: positionViewAtEnd()
-    \endcode
-*/
-
-/*!
-    \qmlmethod int QtQuick2::GridView::indexAt(int x, int y)
-
-    Returns the index of the visible item containing the point \a x, \a y in content
-    coordinates.  If there is no item at the point specified, or the item is
-    not visible -1 is returned.
-
-    If the item is outside the visible area, -1 is returned, regardless of
-    whether an item will exist at that point when scrolled into view.
-
-    \bold Note: methods should only be called after the Component has completed.
-*/
-
-QSGGridViewAttached *QSGGridView::qmlAttachedProperties(QObject *obj)
-{
-    return new QSGGridViewAttached(obj);
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsggridview_p.h b/src/declarative/items/qsggridview_p.h
deleted file mode 100644 (file)
index c3b92d0..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-// Commit: 95814418f9d6adeba365c795462e8afb00138211
-/****************************************************************************
-**
-** 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 QSGGRIDVIEW_P_H
-#define QSGGRIDVIEW_P_H
-
-#include "qsgitemview_p.h"
-
-#include <private/qdeclarativeguard_p.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-class QSGVisualModel;
-class QSGGridViewAttached;
-class QSGGridViewPrivate;
-class Q_AUTOTEST_EXPORT QSGGridView : public QSGItemView
-{
-    Q_OBJECT
-    Q_DECLARE_PRIVATE(QSGGridView)
-
-    Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged)
-    Q_PROPERTY(qreal cellWidth READ cellWidth WRITE setCellWidth NOTIFY cellWidthChanged)
-    Q_PROPERTY(qreal cellHeight READ cellHeight WRITE setCellHeight NOTIFY cellHeightChanged)
-
-    Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged)
-
-    Q_ENUMS(SnapMode)
-    Q_ENUMS(Flow)
-    Q_CLASSINFO("DefaultProperty", "data")
-
-public:
-    QSGGridView(QSGItem *parent=0);
-    ~QSGGridView();
-
-    virtual void setHighlightFollowsCurrentItem(bool);
-    virtual void setHighlightMoveDuration(int);
-
-    enum Flow { LeftToRight, TopToBottom };
-    Flow flow() const;
-    void setFlow(Flow);
-
-    qreal cellWidth() const;
-    void setCellWidth(qreal);
-
-    qreal cellHeight() const;
-    void setCellHeight(qreal);
-
-    enum SnapMode { NoSnap, SnapToRow, SnapOneRow };
-    SnapMode snapMode() const;
-    void setSnapMode(SnapMode mode);
-
-    static QSGGridViewAttached *qmlAttachedProperties(QObject *);
-
-public Q_SLOTS:
-    void moveCurrentIndexUp();
-    void moveCurrentIndexDown();
-    void moveCurrentIndexLeft();
-    void moveCurrentIndexRight();
-
-Q_SIGNALS:
-    void cellWidthChanged();
-    void cellHeightChanged();
-    void highlightMoveDurationChanged();
-    void flowChanged();
-    void snapModeChanged();
-
-protected:
-    virtual void viewportMoved();
-    virtual void keyPressEvent(QKeyEvent *);
-};
-
-class QSGGridViewAttached : public QSGItemViewAttached
-{
-    Q_OBJECT
-public:
-    QSGGridViewAttached(QObject *parent)
-        : QSGItemViewAttached(parent), m_view(0) {}
-    ~QSGGridViewAttached() {}
-
-    Q_PROPERTY(QSGGridView *view READ view NOTIFY viewChanged)
-    QSGGridView *view() { return m_view; }
-    void setView(QSGGridView *view) {
-        if (view != m_view) {
-            m_view = view;
-            emit viewChanged();
-        }
-    }
-
-Q_SIGNALS:
-    void viewChanged();
-
-public:
-    QDeclarativeGuard<QSGGridView> m_view;
-};
-
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGGridView)
-QML_DECLARE_TYPEINFO(QSGGridView, QML_HAS_ATTACHED_PROPERTIES)
-
-QT_END_HEADER
-
-#endif // QSGGRIDVIEW_P_H
diff --git a/src/declarative/items/qsgimage.cpp b/src/declarative/items/qsgimage.cpp
deleted file mode 100644 (file)
index 9461de4..0000000
+++ /dev/null
@@ -1,753 +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 "qsgimage_p.h"
-#include "qsgimage_p_p.h"
-
-#include <private/qsgtextureprovider_p.h>
-
-#include <private/qsgcontext_p.h>
-#include <private/qsgadaptationlayer_p.h>
-
-#include <QtGui/qpainter.h>
-#include <qmath.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGImageTextureProvider : public QSGTextureProvider
-{
-    Q_OBJECT
-public:
-    QSGImageTextureProvider()
-        : m_texture(0)
-        , m_smooth(false)
-    {
-    }
-
-    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);
-            m_texture->setHorizontalWrapMode(QSGTexture::ClampToEdge);
-            m_texture->setVerticalWrapMode(QSGTexture::ClampToEdge);
-        }
-        return m_texture;
-    }
-
-    friend class QSGImage;
-
-    QSGTexture *m_texture;
-    bool m_smooth;
-};
-
-#include "qsgimage.moc"
-
-QSGImagePrivate::QSGImagePrivate()
-    : fillMode(QSGImage::Stretch)
-    , paintedWidth(0)
-    , paintedHeight(0)
-    , pixmapChanged(false)
-    , hAlign(QSGImage::AlignHCenter)
-    , vAlign(QSGImage::AlignVCenter)
-    , provider(0)
-{
-}
-
-/*!
-    \qmlclass Image QSGImage
-    \inqmlmodule QtQuick 2
-    \ingroup qml-basic-visual-elements
-    \brief The Image element displays an image in a declarative user interface
-    \inherits Item
-
-    The Image element is used to display images in a declarative user interface.
-
-    The source of the image is specified as a URL using the \l source property.
-    Images can be supplied in any of the standard image formats supported by Qt,
-    including bitmap formats such as PNG and JPEG, and vector graphics formats
-    such as SVG. If you need to display animated images, use the \l AnimatedImage
-    element.
-
-    If the \l{Item::width}{width} and \l{Item::height}{height} properties are not
-    specified, the Image element automatically uses the size of the loaded image.
-    By default, specifying the width and height of the element causes the image
-    to be scaled to that size. This behavior can be changed by setting the
-    \l fillMode property, allowing the image to be stretched and tiled instead.
-
-    \section1 Example Usage
-
-    The following example shows the simplest usage of the Image element.
-
-    \snippet doc/src/snippets/declarative/image.qml document
-
-    \beginfloatleft
-    \image declarative-qtlogo.png
-    \endfloat
-
-    \clearfloat
-
-    \section1 Performance
-
-    By default, locally available images are loaded immediately, and the user interface
-    is blocked until loading is complete. If a large image is to be loaded, it may be
-    preferable to load the image in a low priority thread, by enabling the \l asynchronous
-    property.
-
-    If the image is obtained from a network rather than a local resource, it is
-    automatically loaded asynchronously, and the \l progress and \l status properties
-    are updated as appropriate.
-
-    Images are cached and shared internally, so if several Image elements have the same \l source,
-    only one copy of the image will be loaded.
-
-    \bold Note: Images are often the greatest user of memory in QML user interfaces.  It is recommended
-    that images which do not form part of the user interface have their
-    size bounded via the \l sourceSize property. This is especially important for content
-    that is loaded from external sources or provided by the user.
-
-    \sa {declarative/imageelements/image}{Image example}, QDeclarativeImageProvider
-*/
-
-QSGImage::QSGImage(QSGItem *parent)
-    : QSGImageBase(*(new QSGImagePrivate), parent)
-{
-}
-
-QSGImage::QSGImage(QSGImagePrivate &dd, QSGItem *parent)
-    : QSGImageBase(dd, parent)
-{
-}
-
-QSGImage::~QSGImage()
-{
-    Q_D(QSGImage);
-    if (d->provider)
-        d->provider->deleteLater();
-}
-
-void QSGImagePrivate::setPixmap(const QPixmap &pixmap)
-{
-    Q_Q(QSGImage);
-    pix.setPixmap(pixmap);
-
-    q->pixmapChange();
-    status = pix.isNull() ? QSGImageBase::Null : QSGImageBase::Ready;
-
-    q->update();
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::Image::fillMode
-
-    Set this property to define what happens when the source image has a different size
-    than the item.
-
-    \list
-    \o Image.Stretch - the image is scaled to fit
-    \o Image.PreserveAspectFit - the image is scaled uniformly to fit without cropping
-    \o Image.PreserveAspectCrop - the image is scaled uniformly to fill, cropping if necessary
-    \o Image.Tile - the image is duplicated horizontally and vertically
-    \o Image.TileVertically - the image is stretched horizontally and tiled vertically
-    \o Image.TileHorizontally - the image is stretched vertically and tiled horizontally
-    \o Image.Pad - the image is not transformed
-    \endlist
-
-    \table
-
-    \row
-    \o \image declarative-qtlogo-stretch.png
-    \o Stretch (default)
-    \qml
-    Image {
-        width: 130; height: 100
-        smooth: true
-        source: "qtlogo.png"
-    }
-    \endqml
-
-    \row
-    \o \image declarative-qtlogo-preserveaspectfit.png
-    \o PreserveAspectFit
-    \qml
-    Image {
-        width: 130; height: 100
-        fillMode: Image.PreserveAspectFit
-        smooth: true
-        source: "qtlogo.png"
-    }
-    \endqml
-
-    \row
-    \o \image declarative-qtlogo-preserveaspectcrop.png
-    \o PreserveAspectCrop
-    \qml
-    Image {
-        width: 130; height: 100
-        fillMode: Image.PreserveAspectCrop
-        smooth: true
-        source: "qtlogo.png"
-        clip: true
-    }
-    \endqml
-
-    \row
-    \o \image declarative-qtlogo-tile.png
-    \o Tile
-    \qml
-    Image {
-        width: 120; height: 120
-        fillMode: Image.Tile
-        source: "qtlogo.png"
-    }
-    \endqml
-
-    \row
-    \o \image declarative-qtlogo-tilevertically.png
-    \o TileVertically
-    \qml
-    Image {
-        width: 120; height: 120
-        fillMode: Image.TileVertically
-        smooth: true
-        source: "qtlogo.png"
-    }
-    \endqml
-
-    \row
-    \o \image declarative-qtlogo-tilehorizontally.png
-    \o TileHorizontally
-    \qml
-    Image {
-        width: 120; height: 120
-        fillMode: Image.TileHorizontally
-        smooth: true
-        source: "qtlogo.png"
-    }
-    \endqml
-
-    \endtable
-
-    Note that \c clip is \c false by default which means that the element might
-    paint outside its bounding rectangle even if the fillMode is set to \c PreserveAspectCrop.
-
-    \sa {declarative/imageelements/image}{Image example}
-*/
-QSGImage::FillMode QSGImage::fillMode() const
-{
-    Q_D(const QSGImage);
-    return d->fillMode;
-}
-
-void QSGImage::setFillMode(FillMode mode)
-{
-    Q_D(QSGImage);
-    if (d->fillMode == mode)
-        return;
-    d->fillMode = mode;
-    update();
-    updatePaintedGeometry();
-    emit fillModeChanged();
-}
-
-/*!
-
-    \qmlproperty real QtQuick2::Image::paintedWidth
-    \qmlproperty real QtQuick2::Image::paintedHeight
-
-    These properties hold the size of the image that is actually painted.
-    In most cases it is the same as \c width and \c height, but when using a
-    \c fillMode \c PreserveAspectFit or \c fillMode \c PreserveAspectCrop
-    \c paintedWidth or \c paintedHeight can be smaller or larger than
-    \c width and \c height of the Image element.
-*/
-qreal QSGImage::paintedWidth() const
-{
-    Q_D(const QSGImage);
-    return d->paintedWidth;
-}
-
-qreal QSGImage::paintedHeight() const
-{
-    Q_D(const QSGImage);
-    return d->paintedHeight;
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::Image::status
-
-    This property holds the status of image loading.  It can be one of:
-    \list
-    \o Image.Null - no image has been set
-    \o Image.Ready - the image has been loaded
-    \o Image.Loading - the image is currently being loaded
-    \o Image.Error - an error occurred while loading the image
-    \endlist
-
-    Use this status to provide an update or respond to the status change in some way.
-    For example, you could:
-
-    \list
-    \o Trigger a state change:
-    \qml
-        State { name: 'loaded'; when: image.status == Image.Ready }
-    \endqml
-
-    \o Implement an \c onStatusChanged signal handler:
-    \qml
-        Image {
-            id: image
-            onStatusChanged: if (image.status == Image.Ready) console.log('Loaded')
-        }
-    \endqml
-
-    \o Bind to the status value:
-    \qml
-        Text { text: image.status == Image.Ready ? 'Loaded' : 'Not loaded' }
-    \endqml
-    \endlist
-
-    \sa progress
-*/
-
-/*!
-    \qmlproperty real QtQuick2::Image::progress
-
-    This property holds the progress of image loading, from 0.0 (nothing loaded)
-    to 1.0 (finished).
-
-    \sa status
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::Image::smooth
-
-    Set this property if you want the image to be smoothly filtered when scaled or
-    transformed.  Smooth filtering gives better visual quality, but is slower.  If
-    the image is displayed at its natural size, this property has no visual or
-    performance effect.
-
-    \note Generally scaling artifacts are only visible if the image is stationary on
-    the screen.  A common pattern when animating an image is to disable smooth
-    filtering at the beginning of the animation and reenable it at the conclusion.
-*/
-
-/*!
-    \qmlproperty QSize QtQuick2::Image::sourceSize
-
-    This property holds the actual width and height of the loaded image.
-
-    Unlike the \l {Item::}{width} and \l {Item::}{height} properties, which scale
-    the painting of the image, this property sets the actual number of pixels
-    stored for the loaded image so that large images do not use more
-    memory than necessary. For example, this ensures the image in memory is no
-    larger than 1024x1024 pixels, regardless of the Image's \l {Item::}{width} and
-    \l {Item::}{height} values:
-
-    \code
-    Rectangle {
-        width: ...
-        height: ...
-
-        Image {
-           anchors.fill: parent
-           source: "reallyBigImage.jpg"
-           sourceSize.width: 1024
-           sourceSize.height: 1024
-        }
-    }
-    \endcode
-
-    If the image's actual size is larger than the sourceSize, the image is scaled down.
-    If only one dimension of the size is set to greater than 0, the
-    other dimension is set in proportion to preserve the source image's aspect ratio.
-    (The \l fillMode is independent of this.)
-
-    If the source is an instrinsically scalable image (eg. SVG), this property
-    determines the size of the loaded image regardless of intrinsic size.
-    Avoid changing this property dynamically; rendering an SVG is \e slow compared
-    to an image.
-
-    If the source is a non-scalable image (eg. JPEG), the loaded image will
-    be no greater than this property specifies. For some formats (currently only JPEG),
-    the whole image will never actually be loaded into memory.
-
-    Since QtQuick 1.1 the sourceSize can be cleared to the natural size of the image
-    by setting sourceSize to \c undefined.
-
-    \note \e {Changing this property dynamically causes the image source to be reloaded,
-    potentially even from the network, if it is not in the disk cache.}
-*/
-
-/*!
-    \qmlproperty url QtQuick2::Image::source
-
-    Image can handle any image format supported by Qt, loaded from any URL scheme supported by Qt.
-
-    The URL may be absolute, or relative to the URL of the component.
-
-    \sa QDeclarativeImageProvider
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::Image::asynchronous
-
-    Specifies that images on the local filesystem should be loaded
-    asynchronously in a separate thread.  The default value is
-    false, causing the user interface thread to block while the
-    image is loaded.  Setting \a asynchronous to true is useful where
-    maintaining a responsive user interface is more desirable
-    than having images immediately visible.
-
-    Note that this property is only valid for images read from the
-    local filesystem.  Images loaded via a network resource (e.g. HTTP)
-    are always loaded asynchonously.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::Image::cache
-
-    Specifies whether the image should be cached. The default value is
-    true. Setting \a cache to false is useful when dealing with large images,
-    to make sure that they aren't cached at the expense of small 'ui element' images.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::Image::mirror
-
-    This property holds whether the image should be horizontally inverted
-    (effectively displaying a mirrored image).
-
-    The default value is false.
-*/
-
-/*!
-    \qmlproperty enumeration QtQuick2::Image::horizontalAlignment
-    \qmlproperty enumeration QtQuick2::Image::verticalAlignment
-
-    Sets the horizontal and vertical alignment of the image. By default, the image is top-left aligned.
-
-    The valid values for \c horizontalAlignment are \c Image.AlignLeft, \c Image.AlignRight and \c Image.AlignHCenter.
-    The valid values for \c verticalAlignment are \c Image.AlignTop, \c Image.AlignBottom
-    and \c Image.AlignVCenter.
-*/
-void QSGImage::updatePaintedGeometry()
-{
-    Q_D(QSGImage);
-
-    if (d->fillMode == PreserveAspectFit) {
-        if (!d->pix.width() || !d->pix.height()) {
-            setImplicitWidth(0);
-            setImplicitHeight(0);
-            return;
-        }
-        qreal w = widthValid() ? width() : d->pix.width();
-        qreal widthScale = w / qreal(d->pix.width());
-        qreal h = heightValid() ? height() : d->pix.height();
-        qreal heightScale = h / qreal(d->pix.height());
-        if (widthScale <= heightScale) {
-            d->paintedWidth = w;
-            d->paintedHeight = widthScale * qreal(d->pix.height());
-        } else if (heightScale < widthScale) {
-            d->paintedWidth = heightScale * qreal(d->pix.width());
-            d->paintedHeight = h;
-        }
-        if (widthValid() && !heightValid()) {
-            setImplicitHeight(d->paintedHeight);
-        } else {
-            setImplicitHeight(d->pix.height());
-        }
-        if (heightValid() && !widthValid()) {
-            setImplicitWidth(d->paintedWidth);
-        } else {
-            setImplicitWidth(d->pix.width());
-        }
-    } else if (d->fillMode == PreserveAspectCrop) {
-        if (!d->pix.width() || !d->pix.height())
-            return;
-        qreal widthScale = width() / qreal(d->pix.width());
-        qreal heightScale = height() / qreal(d->pix.height());
-        if (widthScale < heightScale) {
-            widthScale = heightScale;
-        } else if (heightScale < widthScale) {
-            heightScale = widthScale;
-        }
-
-        d->paintedHeight = heightScale * qreal(d->pix.height());
-        d->paintedWidth = widthScale * qreal(d->pix.width());
-    } else if (d->fillMode == Pad) {
-        d->paintedWidth = d->pix.width();
-        d->paintedHeight = d->pix.height();
-    } else {
-        d->paintedWidth = width();
-        d->paintedHeight = height();
-    }
-    emit paintedGeometryChanged();
-}
-
-void QSGImage::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
-{
-    QSGImageBase::geometryChanged(newGeometry, oldGeometry);
-    updatePaintedGeometry();
-}
-
-QRectF QSGImage::boundingRect() const
-{
-    Q_D(const QSGImage);
-    return QRectF(0, 0, qMax(width(), d->paintedWidth), qMax(height(), d->paintedHeight));
-}
-
-QSGTextureProvider *QSGImage::textureProvider() const
-{
-    Q_D(const QSGImage);
-    if (!d->provider) {
-        // Make sure it gets thread affinity on the rendering thread so deletion works properly..
-        Q_ASSERT_X(d->canvas
-                   && d->sceneGraphContext()
-                   && QThread::currentThread() == d->sceneGraphContext()->thread(),
-                   "QSGImage::textureProvider",
-                   "Cannot be used outside the GUI thread");
-        QSGImagePrivate *dd = const_cast<QSGImagePrivate *>(d);
-        dd->provider = new QSGImageTextureProvider;
-        dd->provider->m_texture = d->pix.texture(d->sceneGraphContext());
-    }
-
-    return d->provider;
-}
-
-QSGNode *QSGImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
-{
-    Q_D(QSGImage);
-
-    QSGTexture *texture = d->pix.texture(d->sceneGraphContext());
-
-    // Copy over the current texture state into the texture provider...
-    if (d->provider) {
-        d->provider->m_smooth = d->smooth;
-        d->provider->m_texture = texture;
-    }
-
-    if (!texture || width() <= 0 || height() <= 0) {
-        delete oldNode;
-        return 0;
-    }
-
-    QSGImageNode *node = static_cast<QSGImageNode *>(oldNode);
-    if (!node) {
-        d->pixmapChanged = true;
-        node = d->sceneGraphContext()->createImageNode();
-        node->setTexture(texture);
-    }
-
-    if (d->pixmapChanged) {
-        // force update the texture in the node to trigger reconstruction of
-        // geometry and the likes when a atlas segment has changed.
-        node->setTexture(0);
-        node->setTexture(texture);
-        d->pixmapChanged = false;
-    }
-
-    QRectF targetRect;
-    QRectF sourceRect;
-    QSGTexture::WrapMode hWrap = QSGTexture::ClampToEdge;
-    QSGTexture::WrapMode vWrap = QSGTexture::ClampToEdge;
-
-    qreal pixWidth = (d->fillMode == PreserveAspectFit) ? d->paintedWidth : d->pix.width();
-    qreal pixHeight = (d->fillMode == PreserveAspectFit) ? d->paintedHeight : d->pix.height();
-
-    int xOffset = 0;
-    if (d->hAlign == QSGImage::AlignHCenter)
-        xOffset = qCeil((width() - pixWidth) / 2.);
-    else if (d->hAlign == QSGImage::AlignRight)
-        xOffset = qCeil(width() - pixWidth);
-
-    int yOffset = 0;
-    if (d->vAlign == QSGImage::AlignVCenter)
-        yOffset = qCeil((height() - pixHeight) / 2.);
-    else if (d->vAlign == QSGImage::AlignBottom)
-        yOffset = qCeil(height() - pixHeight);
-
-    switch (d->fillMode) {
-    default:
-    case Stretch:
-        targetRect = QRectF(0, 0, width(), height());
-        sourceRect = d->pix.rect();
-        break;
-
-    case PreserveAspectFit:
-        targetRect = QRectF(xOffset, yOffset, d->paintedWidth, d->paintedHeight);
-        sourceRect = d->pix.rect();
-        break;
-
-    case PreserveAspectCrop: {
-        targetRect = QRect(0, 0, width(), height());
-        qreal wscale = width() / qreal(d->pix.width());
-        qreal hscale = height() / qreal(d->pix.height());
-
-        if (wscale > hscale) {
-            int src = (hscale / wscale) * qreal(d->pix.height());
-            int y = 0;
-            if (d->vAlign == QSGImage::AlignVCenter)
-                y = qCeil((d->pix.height() - src) / 2.);
-            else if (d->vAlign == QSGImage::AlignBottom)
-                y = qCeil(d->pix.height() - src);
-            sourceRect = QRectF(0, y, d->pix.width(), src);
-
-        } else {
-            int src = (wscale / hscale) * qreal(d->pix.width());
-            int x = 0;
-            if (d->hAlign == QSGImage::AlignHCenter)
-                x = qCeil((d->pix.width() - src) / 2.);
-            else if (d->hAlign == QSGImage::AlignRight)
-                x = qCeil(d->pix.width() - src);
-            sourceRect = QRectF(x, 0, src, d->pix.height());
-        }
-        }
-        break;
-
-    case Tile:
-        targetRect = QRectF(0, 0, width(), height());
-        sourceRect = QRectF(-xOffset, -yOffset, width(), height());
-        hWrap = QSGTexture::Repeat;
-        vWrap = QSGTexture::Repeat;
-        break;
-
-    case TileHorizontally:
-        targetRect = QRectF(0, 0, width(), height());
-        sourceRect = QRectF(-xOffset, 0, width(), d->pix.height());
-        hWrap = QSGTexture::Repeat;
-        break;
-
-    case TileVertically:
-        targetRect = QRectF(0, 0, width(), height());
-        sourceRect = QRectF(0, -yOffset, d->pix.width(), height());
-        vWrap = QSGTexture::Repeat;
-        break;
-
-    case Pad:
-        qreal w = qMin(qreal(d->pix.width()), width());
-        qreal h = qMin(qreal(d->pix.height()), height());
-        qreal x = (d->pix.width() > width()) ? -xOffset : 0;
-        qreal y = (d->pix.height() > height()) ? -yOffset : 0;
-        targetRect = QRectF(x + xOffset, y + yOffset, w, h);
-        sourceRect = QRectF(x, y, w, h);
-        break;
-    };
-
-    QRectF nsrect(sourceRect.x() / d->pix.width(),
-                  sourceRect.y() / d->pix.height(),
-                  sourceRect.width() / d->pix.width(),
-                  sourceRect.height() / d->pix.height());
-
-    if (d->mirror) {
-        qreal oldLeft = nsrect.left();
-        nsrect.setLeft(nsrect.right());
-        nsrect.setRight(oldLeft);
-    }
-
-    node->setHorizontalWrapMode(hWrap);
-    node->setVerticalWrapMode(vWrap);
-    node->setFiltering(d->smooth ? QSGTexture::Linear : QSGTexture::Nearest);
-
-    node->setTargetRect(targetRect);
-    node->setSourceRect(nsrect);
-    node->update();
-
-    return node;
-}
-
-void QSGImage::pixmapChange()
-{
-    Q_D(QSGImage);
-    // PreserveAspectFit calculates the implicit size differently so we
-    // don't call our superclass pixmapChange(), since that would
-    // result in the implicit size being set incorrectly, then updated
-    // in updatePaintedGeometry()
-    if (d->fillMode != PreserveAspectFit)
-        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
-{
-    Q_D(const QSGImage);
-    return d->vAlign;
-}
-
-void QSGImage::setVerticalAlignment(VAlignment align)
-{
-    Q_D(QSGImage);
-    if (d->vAlign == align)
-        return;
-
-    d->vAlign = align;
-    update();
-    updatePaintedGeometry();
-    emit verticalAlignmentChanged(align);
-}
-
-QSGImage::HAlignment QSGImage::horizontalAlignment() const
-{
-    Q_D(const QSGImage);
-    return d->hAlign;
-}
-
-void QSGImage::setHorizontalAlignment(HAlignment align)
-{
-    Q_D(QSGImage);
-    if (d->hAlign == align)
-        return;
-
-    d->hAlign = align;
-    update();
-    updatePaintedGeometry();
-    emit horizontalAlignmentChanged(align);
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgimage_p.h b/src/declarative/items/qsgimage_p.h
deleted file mode 100644 (file)
index 9bf1d91..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
-/****************************************************************************
-**
-** 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 QSGIMAGE_P_H
-#define QSGIMAGE_P_H
-
-#include "qsgimagebase_p.h"
-#include <private/qsgtextureprovider_p.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGImagePrivate;
-class Q_AUTOTEST_EXPORT QSGImage : public QSGImageBase
-{
-    Q_OBJECT
-    Q_ENUMS(FillMode)
-    Q_ENUMS(HAlignment)
-    Q_ENUMS(VAlignment)
-
-    Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged)
-    Q_PROPERTY(qreal paintedWidth READ paintedWidth NOTIFY paintedGeometryChanged)
-    Q_PROPERTY(qreal paintedHeight READ paintedHeight NOTIFY paintedGeometryChanged)
-    Q_PROPERTY(HAlignment horizontalAlignment READ horizontalAlignment WRITE setHorizontalAlignment NOTIFY horizontalAlignmentChanged)
-    Q_PROPERTY(VAlignment verticalAlignment READ verticalAlignment WRITE setVerticalAlignment NOTIFY verticalAlignmentChanged)
-
-public:
-    QSGImage(QSGItem *parent=0);
-    ~QSGImage();
-
-    enum HAlignment { AlignLeft = Qt::AlignLeft,
-                       AlignRight = Qt::AlignRight,
-                       AlignHCenter = Qt::AlignHCenter };
-    enum VAlignment { AlignTop = Qt::AlignTop,
-                       AlignBottom = Qt::AlignBottom,
-                       AlignVCenter = Qt::AlignVCenter };
-
-    enum FillMode { Stretch, PreserveAspectFit, PreserveAspectCrop, Tile, TileVertically, TileHorizontally, Pad };
-
-    FillMode fillMode() const;
-    void setFillMode(FillMode);
-
-    qreal paintedWidth() const;
-    qreal paintedHeight() const;
-
-    QRectF boundingRect() const;
-
-    HAlignment horizontalAlignment() const;
-    void setHorizontalAlignment(HAlignment align);
-
-    VAlignment verticalAlignment() const;
-    void setVerticalAlignment(VAlignment align);
-
-    bool isTextureProvider() const { return true; }
-    QSGTextureProvider *textureProvider() const;
-
-Q_SIGNALS:
-    void fillModeChanged();
-    void paintedGeometryChanged();
-    void horizontalAlignmentChanged(HAlignment alignment);
-    void verticalAlignmentChanged(VAlignment alignment);
-
-protected:
-    QSGImage(QSGImagePrivate &dd, QSGItem *parent);
-    void pixmapChange();
-    void updatePaintedGeometry();
-
-    virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
-    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
-
-private:
-    Q_DISABLE_COPY(QSGImage)
-    Q_DECLARE_PRIVATE(QSGImage)
-};
-
-QT_END_NAMESPACE
-QML_DECLARE_TYPE(QSGImage)
-QT_END_HEADER
-
-#endif // QSGIMAGE_P_H
diff --git a/src/declarative/items/qsgimage_p_p.h b/src/declarative/items/qsgimage_p_p.h
deleted file mode 100644 (file)
index 9f8b971..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
-/****************************************************************************
-**
-** 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 QSGIMAGE_P_P_H
-#define QSGIMAGE_P_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 "qsgimagebase_p_p.h"
-#include "qsgimage_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QSGImageTextureProvider;
-
-class QSGImagePrivate : public QSGImageBasePrivate
-{
-    Q_DECLARE_PUBLIC(QSGImage)
-
-public:
-    QSGImagePrivate();
-
-    QSGImage::FillMode fillMode;
-    qreal paintedWidth;
-    qreal paintedHeight;
-    void setPixmap(const QPixmap &pix);
-
-    bool pixmapChanged : 1;
-    QSGImage::HAlignment hAlign;
-    QSGImage::VAlignment vAlign;
-
-    QSGImageTextureProvider *provider;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGIMAGE_P_P_H
diff --git a/src/declarative/items/qsgimagebase.cpp b/src/declarative/items/qsgimagebase.cpp
deleted file mode 100644 (file)
index 0c08010..0000000
+++ /dev/null
@@ -1,291 +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 "qsgimagebase_p.h"
-#include "qsgimagebase_p_p.h"
-
-#include <QtDeclarative/qdeclarativeinfo.h>
-
-QT_BEGIN_NAMESPACE
-
-QSGImageBase::QSGImageBase(QSGItem *parent)
-: QSGImplicitSizeItem(*(new QSGImageBasePrivate), parent)
-{
-    setFlag(ItemHasContents);
-}
-
-QSGImageBase::QSGImageBase(QSGImageBasePrivate &dd, QSGItem *parent)
-: QSGImplicitSizeItem(dd, parent)
-{
-    setFlag(ItemHasContents);
-}
-
-QSGImageBase::~QSGImageBase()
-{
-}
-
-QSGImageBase::Status QSGImageBase::status() const
-{
-    Q_D(const QSGImageBase);
-    return d->status;
-}
-
-
-qreal QSGImageBase::progress() const
-{
-    Q_D(const QSGImageBase);
-    return d->progress;
-}
-
-
-bool QSGImageBase::asynchronous() const
-{
-    Q_D(const QSGImageBase);
-    return d->async;
-}
-
-void QSGImageBase::setAsynchronous(bool async)
-{
-    Q_D(QSGImageBase);
-    if (d->async != async) {
-        d->async = async;
-        emit asynchronousChanged();
-    }
-}
-
-QUrl QSGImageBase::source() const
-{
-    Q_D(const QSGImageBase);
-    return d->url;
-}
-
-void QSGImageBase::setSource(const QUrl &url)
-{
-    Q_D(QSGImageBase);
-    //equality is fairly expensive, so we bypass for simple, common case
-    if ((d->url.isEmpty() == url.isEmpty()) && url == d->url)
-        return;
-
-    d->url = url;
-    emit sourceChanged(d->url);
-
-    if (isComponentComplete())
-        load();
-}
-
-void QSGImageBase::setSourceSize(const QSize& size)
-{
-    Q_D(QSGImageBase);
-    if (d->sourcesize == size)
-        return;
-
-    d->sourcesize = size;
-    d->explicitSourceSize = true;
-    emit sourceSizeChanged();
-    if (isComponentComplete())
-        load();
-}
-
-QSize QSGImageBase::sourceSize() const
-{
-    Q_D(const QSGImageBase);
-
-    int width = d->sourcesize.width();
-    int height = d->sourcesize.height();
-    return QSize(width != -1 ? width : d->pix.width(), height != -1 ? height : d->pix.height());
-}
-
-void QSGImageBase::resetSourceSize()
-{
-    Q_D(QSGImageBase);
-    if (!d->explicitSourceSize)
-        return;
-    d->explicitSourceSize = false;
-    d->sourcesize = QSize();
-    emit sourceSizeChanged();
-    if (isComponentComplete())
-        load();
-}
-
-bool QSGImageBase::cache() const
-{
-    Q_D(const QSGImageBase);
-    return d->cache;
-}
-
-void QSGImageBase::setCache(bool cache)
-{
-    Q_D(QSGImageBase);
-    if (d->cache == cache)
-        return;
-
-    d->cache = cache;
-    emit cacheChanged();
-    if (isComponentComplete())
-        load();
-}
-
-QPixmap QSGImageBase::pixmap() const
-{
-    Q_D(const QSGImageBase);
-    return d->pix.pixmap();
-}
-
-void QSGImageBase::setMirror(bool mirror)
-{
-    Q_D(QSGImageBase);
-    if (mirror == d->mirror)
-        return;
-
-    d->mirror = mirror;
-
-    if (isComponentComplete())
-        update();
-
-    emit mirrorChanged();
-}
-
-bool QSGImageBase::mirror() const
-{
-    Q_D(const QSGImageBase);
-    return d->mirror;
-}
-
-void QSGImageBase::load()
-{
-    Q_D(QSGImageBase);
-
-    if (d->url.isEmpty()) {
-        d->pix.clear(this);
-        d->status = Null;
-        d->progress = 0.0;
-        pixmapChange();
-        emit progressChanged(d->progress);
-        emit statusChanged(d->status);
-        update();
-    } else {
-        QDeclarativePixmap::Options options;
-        if (d->async)
-            options |= QDeclarativePixmap::Asynchronous;
-        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()) {
-            d->progress = 0.0;
-            d->status = Loading;
-            emit progressChanged(d->progress);
-            emit statusChanged(d->status);
-
-            static int thisRequestProgress = -1;
-            static int thisRequestFinished = -1;
-            if (thisRequestProgress == -1) {
-                thisRequestProgress =
-                    QSGImageBase::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
-                thisRequestFinished =
-                    QSGImageBase::staticMetaObject.indexOfSlot("requestFinished()");
-            }
-
-            d->pix.connectFinished(this, thisRequestFinished);
-            d->pix.connectDownloadProgress(this, thisRequestProgress);
-
-        } else {
-            requestFinished();
-        }
-    }
-}
-
-void QSGImageBase::requestFinished()
-{
-    Q_D(QSGImageBase);
-
-    QSGImageBase::Status oldStatus = d->status;
-    qreal oldProgress = d->progress;
-
-    if (d->pix.isError()) {
-        d->status = Error;
-        qmlInfo(this) << d->pix.error();
-    } else {
-        d->status = Ready;
-    }
-
-    d->progress = 1.0;
-
-    pixmapChange();
-
-    if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height())
-        emit sourceSizeChanged();
-
-    if (d->status != oldStatus)
-        emit statusChanged(d->status);
-    if (d->progress != oldProgress)
-        emit progressChanged(d->progress);
-
-    update();
-}
-
-void QSGImageBase::requestProgress(qint64 received, qint64 total)
-{
-    Q_D(QSGImageBase);
-    if (d->status == Loading && total > 0) {
-        d->progress = qreal(received)/total;
-        emit progressChanged(d->progress);
-    }
-}
-
-void QSGImageBase::componentComplete()
-{
-    Q_D(QSGImageBase);
-    QSGItem::componentComplete();
-    if (d->url.isValid())
-        load();
-}
-
-void QSGImageBase::pixmapChange()
-{
-    Q_D(QSGImageBase);
-    setImplicitWidth(d->pix.width());
-    setImplicitHeight(d->pix.height());
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgimagebase_p.h b/src/declarative/items/qsgimagebase_p.h
deleted file mode 100644 (file)
index e17ca3b..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-// Commit: af05f64d3edc860c3cf79c7f0bdf2377faae5f40
-/****************************************************************************
-**
-** 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 QSGIMAGEBASE_P_H
-#define QSGIMAGEBASE_P_H
-
-#include "qsgimplicitsizeitem_p.h"
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-class QSGImageBasePrivate;
-class Q_AUTOTEST_EXPORT QSGImageBase : public QSGImplicitSizeItem
-{
-    Q_OBJECT
-    Q_ENUMS(Status)
-
-    Q_PROPERTY(Status status READ status NOTIFY statusChanged)
-    Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
-    Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
-    Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged)
-    Q_PROPERTY(bool cache READ cache WRITE setCache NOTIFY cacheChanged)
-    Q_PROPERTY(QSize sourceSize READ sourceSize WRITE setSourceSize RESET resetSourceSize NOTIFY sourceSizeChanged)
-    Q_PROPERTY(bool mirror READ mirror WRITE setMirror NOTIFY mirrorChanged)
-
-public:
-    QSGImageBase(QSGItem *parent=0);
-    ~QSGImageBase();
-    enum Status { Null, Ready, Loading, Error };
-    Status status() const;
-    qreal progress() const;
-
-    QUrl source() const;
-    virtual void setSource(const QUrl &url);
-
-    bool asynchronous() const;
-    void setAsynchronous(bool);
-
-    bool cache() const;
-    void setCache(bool);
-
-    QPixmap pixmap() const;
-
-    virtual void setSourceSize(const QSize&);
-    QSize sourceSize() const;
-    void resetSourceSize();
-
-    virtual void setMirror(bool mirror);
-    bool mirror() const;
-
-Q_SIGNALS:
-    void sourceChanged(const QUrl &);
-    void sourceSizeChanged();
-    void statusChanged(QSGImageBase::Status);
-    void progressChanged(qreal progress);
-    void asynchronousChanged();
-    void cacheChanged();
-    void mirrorChanged();
-
-protected:
-    virtual void load();
-    virtual void componentComplete();
-    virtual void pixmapChange();
-    QSGImageBase(QSGImageBasePrivate &dd, QSGItem *parent);
-
-private Q_SLOTS:
-    virtual void requestFinished();
-    void requestProgress(qint64,qint64);
-
-private:
-    Q_DISABLE_COPY(QSGImageBase)
-    Q_DECLARE_PRIVATE(QSGImageBase)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSGIMAGEBASE_P_H
diff --git a/src/declarative/items/qsgimagebase_p_p.h b/src/declarative/items/qsgimagebase_p_p.h
deleted file mode 100644 (file)
index dd1a00f..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-// Commit: 6f78a6080b84cc3ef96b73a4ff58d1b5a72f08f4
-/****************************************************************************
-**
-** 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 QSGIMAGEBASE_P_P_H
-#define QSGIMAGEBASE_P_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 "qsgimplicitsizeitem_p_p.h"
-#include "qsgimagebase_p.h"
-
-#include <private/qdeclarativepixmapcache_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QNetworkReply;
-class QSGImageBasePrivate : public QSGImplicitSizeItemPrivate
-{
-    Q_DECLARE_PUBLIC(QSGImageBase)
-
-public:
-    QSGImageBasePrivate()
-      : status(QSGImageBase::Null),
-        progress(0.0),
-        explicitSourceSize(false),
-        async(false),
-        cache(true),
-        mirror(false)
-    {
-    }
-
-    QDeclarativePixmap pix;
-    QSGImageBase::Status status;
-    QUrl url;
-    qreal progress;
-    QSize sourcesize;
-    bool explicitSourceSize : 1;
-    bool async : 1;
-    bool cache : 1;
-    bool mirror: 1;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGIMAGEBASE_P_P_H
diff --git a/src/declarative/items/qsgimplicitsizeitem.cpp b/src/declarative/items/qsgimplicitsizeitem.cpp
deleted file mode 100644 (file)
index 163b73b..0000000
+++ /dev/null
@@ -1,92 +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 "qsgimplicitsizeitem_p.h"
-#include "qsgimplicitsizeitem_p_p.h"
-
-QT_BEGIN_NAMESPACE
-
-void QSGImplicitSizeItemPrivate::implicitWidthChanged()
-{
-    Q_Q(QSGImplicitSizeItem);
-    emit q->implicitWidthChanged();
-}
-
-void QSGImplicitSizeItemPrivate::implicitHeightChanged()
-{
-    Q_Q(QSGImplicitSizeItem);
-    emit q->implicitHeightChanged();
-}
-
-QSGImplicitSizeItem::QSGImplicitSizeItem(QSGItem *parent)
-    : QSGItem(*(new QSGImplicitSizeItemPrivate), parent)
-{
-}
-
-QSGImplicitSizeItem::QSGImplicitSizeItem(QSGImplicitSizeItemPrivate &dd, QSGItem *parent)
-    : QSGItem(dd, parent)
-{
-}
-
-
-void QSGImplicitSizePaintedItemPrivate::implicitWidthChanged()
-{
-    Q_Q(QSGImplicitSizePaintedItem);
-    emit q->implicitWidthChanged();
-}
-
-void QSGImplicitSizePaintedItemPrivate::implicitHeightChanged()
-{
-    Q_Q(QSGImplicitSizePaintedItem);
-    emit q->implicitHeightChanged();
-}
-
-QSGImplicitSizePaintedItem::QSGImplicitSizePaintedItem(QSGItem *parent)
-    : QSGPaintedItem(*(new QSGImplicitSizePaintedItemPrivate), parent)
-{
-}
-
-QSGImplicitSizePaintedItem::QSGImplicitSizePaintedItem(QSGImplicitSizePaintedItemPrivate &dd, QSGItem *parent)
-    : QSGPaintedItem(dd, parent)
-{
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgimplicitsizeitem_p.h b/src/declarative/items/qsgimplicitsizeitem_p.h
deleted file mode 100644 (file)
index b839fc2..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-// Commit: 6f78a6080b84cc3ef96b73a4ff58d1b5a72f08f4
-/****************************************************************************
-**
-** 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 QSGIMPLICITSIZEITEM_H
-#define QSGIMPLICITSIZEITEM_H
-
-#include "qsgpainteditem.h"
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-class QSGImplicitSizeItemPrivate;
-class Q_AUTOTEST_EXPORT QSGImplicitSizeItem : public QSGItem
-{
-    Q_OBJECT
-    Q_PROPERTY(qreal implicitWidth READ implicitWidth NOTIFY implicitWidthChanged)
-    Q_PROPERTY(qreal implicitHeight READ implicitHeight NOTIFY implicitHeightChanged)
-
-public:
-    QSGImplicitSizeItem(QSGItem *parent = 0);
-
-protected:
-    QSGImplicitSizeItem(QSGImplicitSizeItemPrivate &dd, QSGItem *parent);
-
-Q_SIGNALS:
-    void implicitWidthChanged();
-    void implicitHeightChanged();
-
-private:
-    Q_DISABLE_COPY(QSGImplicitSizeItem)
-    Q_DECLARE_PRIVATE(QSGImplicitSizeItem)
-};
-
-class QSGImplicitSizePaintedItemPrivate;
-class Q_AUTOTEST_EXPORT QSGImplicitSizePaintedItem : public QSGPaintedItem
-{
-    Q_OBJECT
-    Q_PROPERTY(qreal implicitWidth READ implicitWidth NOTIFY implicitWidthChanged)
-    Q_PROPERTY(qreal implicitHeight READ implicitHeight NOTIFY implicitHeightChanged)
-
-public:
-    QSGImplicitSizePaintedItem(QSGItem *parent = 0);
-
-protected:
-    QSGImplicitSizePaintedItem(QSGImplicitSizePaintedItemPrivate &dd, QSGItem *parent);
-    virtual void drawContents(QPainter *, const QRect &) {};
-
-Q_SIGNALS:
-    void implicitWidthChanged();
-    void implicitHeightChanged();
-
-private:
-    Q_DISABLE_COPY(QSGImplicitSizePaintedItem)
-    Q_DECLARE_PRIVATE(QSGImplicitSizePaintedItem)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSGIMPLICITSIZEITEM_H
diff --git a/src/declarative/items/qsgimplicitsizeitem_p_p.h b/src/declarative/items/qsgimplicitsizeitem_p_p.h
deleted file mode 100644 (file)
index 3ddd69d..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-// Commit: 6f78a6080b84cc3ef96b73a4ff58d1b5a72f08f4
-/****************************************************************************
-**
-** 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 QSGIMPLICITSIZEITEM_P_H
-#define QSGIMPLICITSIZEITEM_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 "qsgitem_p.h"
-#include "qsgpainteditem_p.h"
-#include "qsgimplicitsizeitem_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QSGImplicitSizeItemPrivate : public QSGItemPrivate
-{
-    Q_DECLARE_PUBLIC(QSGImplicitSizeItem)
-
-public:
-    QSGImplicitSizeItemPrivate()
-    {
-    }
-
-    virtual void implicitWidthChanged();
-    virtual void implicitHeightChanged();
-};
-
-
-class QSGImplicitSizePaintedItemPrivate : public QSGPaintedItemPrivate
-{
-    Q_DECLARE_PUBLIC(QSGImplicitSizePaintedItem)
-
-public:
-    QSGImplicitSizePaintedItemPrivate()
-    {
-    }
-
-    virtual void implicitWidthChanged();
-    virtual void implicitHeightChanged();
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGIMPLICITSIZEITEM_P_H
diff --git a/src/declarative/items/qsgitem.cpp b/src/declarative/items/qsgitem.cpp
deleted file mode 100644 (file)
index bdea19b..0000000
+++ /dev/null
@@ -1,5038 +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 "qsgitem.h"
-
-#include "qsgcanvas.h"
-#include <QtDeclarative/qjsengine.h>
-#include "qsgcanvas_p.h"
-
-#include "qsgevents_p_p.h"
-
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtDeclarative/qdeclarativeinfo.h>
-#include <QtGui/qpen.h>
-#include <QtGui/qcursor.h>
-#include <QtGui/qguiapplication.h>
-#include <QtGui/qinputpanel.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qcoreevent.h>
-#include <QtCore/qnumeric.h>
-
-#include <private/qdeclarativeengine_p.h>
-#include <private/qdeclarativestategroup_p.h>
-#include <private/qdeclarativeopenmetaobject_p.h>
-#include <private/qdeclarativestate_p.h>
-#include <private/qlistmodelinterface_p.h>
-#include <private/qsgitem_p.h>
-
-#include <float.h>
-
-// XXX todo Readd parentNotifier for faster parent bindings
-// XXX todo Check that elements that create items handle memory correctly after visual ownership change
-
-QT_BEGIN_NAMESPACE
-
-/*!
-    \qmlclass Transform QSGTransform
-    \inqmlmodule QtQuick 2
-    \ingroup qml-transform-elements
-    \brief The Transform elements provide a way of building advanced transformations on Items.
-
-    The Transform element is a base type which cannot be instantiated directly.
-    The following concrete Transform types are available:
-
-    \list
-    \o \l Rotation
-    \o \l Scale
-    \o \l Translate
-    \endlist
-
-    The Transform elements let you create and control advanced transformations that can be configured
-    independently using specialized properties.
-
-    You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
-    one at a time.
-*/
-
-/*!
-    \qmlclass Translate QSGTranslate
-    \inqmlmodule QtQuick 2
-    \ingroup qml-transform-elements
-    \brief The Translate object provides a way to move an Item without changing its x or y properties.
-
-    The Translate object provides independent control over position in addition to the Item's x and y properties.
-
-    The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
-    to lay the items out as if they had not been transformed:
-    \qml
-    import QtQuick 1.0
-
-    Row {
-        Rectangle {
-            width: 100; height: 100
-            color: "blue"
-            transform: Translate { y: 20 }
-        }
-        Rectangle {
-            width: 100; height: 100
-            color: "red"
-            transform: Translate { y: -20 }
-        }
-    }
-    \endqml
-
-    \image translate.png
-*/
-
-/*!
-    \qmlproperty real QtQuick2::Translate::x
-
-    The translation along the X axis.
-*/
-
-/*!
-    \qmlproperty real QtQuick2::Translate::y
-
-    The translation along the Y axis.
-*/
-
-/*!
-    \qmlclass Scale QSGScale
-    \inqmlmodule QtQuick 2
-    \ingroup qml-transform-elements
-    \brief The Scale element provides a way to scale an Item.
-
-    The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
-    it allows a different scale for the x and y axes, and allows the scale to be relative to an
-    arbitrary point.
-
-    The following example scales the X axis of the Rectangle, relative to its interior point 25, 25:
-    \qml
-    Rectangle {
-        width: 100; height: 100
-        color: "blue"
-        transform: Scale { origin.x: 25; origin.y: 25; xScale: 3}
-    }
-    \endqml
-
-    \sa Rotation, Translate
-*/
-
-/*!
-    \qmlproperty real QtQuick2::Scale::origin.x
-    \qmlproperty real QtQuick2::Scale::origin.y
-
-    The point that the item is scaled from (i.e., the point that stays fixed relative to the parent as
-    the rest of the item grows). By default the origin is 0, 0.
-*/
-
-/*!
-    \qmlproperty real QtQuick2::Scale::xScale
-
-    The scaling factor for the X axis.
-*/
-
-/*!
-    \qmlproperty real QtQuick2::Scale::yScale
-
-    The scaling factor for the Y axis.
-*/
-
-/*!
-    \qmlclass Rotation QSGRotation
-    \inqmlmodule QtQuick 2
-    \ingroup qml-transform-elements
-    \brief The Rotation object provides a way to rotate an Item.
-
-    The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
-    Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
-
-    The following example rotates a Rectangle around its interior point 25, 25:
-    \qml
-    Rectangle {
-        width: 100; height: 100
-        color: "blue"
-        transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
-    }
-    \endqml
-
-    Rotation also provides a way to specify 3D-like rotations for Items. For these types of
-    rotations you must specify the axis to rotate around in addition to the origin point.
-
-    The following example shows various 3D-like rotations applied to an \l Image.
-    \snippet doc/src/snippets/declarative/rotation.qml 0
-
-    \image axisrotation.png
-
-    \sa {declarative/ui-components/dialcontrol}{Dial Control example}, {declarative/toys/clocks}{Clocks example}
-*/
-
-/*!
-    \qmlproperty real QtQuick2::Rotation::origin.x
-    \qmlproperty real QtQuick2::Rotation::origin.y
-
-    The origin point of the rotation (i.e., the point that stays fixed relative to the parent as
-    the rest of the item rotates). By default the origin is 0, 0.
-*/
-
-/*!
-    \qmlproperty real QtQuick2::Rotation::axis.x
-    \qmlproperty real QtQuick2::Rotation::axis.y
-    \qmlproperty real QtQuick2::Rotation::axis.z
-
-    The axis to rotate around. For simple (2D) rotation around a point, you do not need to specify an axis,
-    as the default axis is the z axis (\c{ axis { x: 0; y: 0; z: 1 } }).
-
-    For a typical 3D-like rotation you will usually specify both the origin and the axis.
-
-    \image 3d-rotation-axis.png
-*/
-
-/*!
-    \qmlproperty real QtQuick2::Rotation::angle
-
-    The angle to rotate, in degrees clockwise.
-*/
-
-QSGTransformPrivate::QSGTransformPrivate()
-{
-}
-
-QSGTransform::QSGTransform(QObject *parent)
-: QObject(*(new QSGTransformPrivate), parent)
-{
-}
-
-QSGTransform::QSGTransform(QSGTransformPrivate &dd, QObject *parent)
-: QObject(dd, parent)
-{
-}
-
-QSGTransform::~QSGTransform()
-{
-    Q_D(QSGTransform);
-    for (int ii = 0; ii < d->items.count(); ++ii) {
-        QSGItemPrivate *p = QSGItemPrivate::get(d->items.at(ii));
-        p->transforms.removeOne(this);
-        p->dirty(QSGItemPrivate::Transform);
-    }
-}
-
-void QSGTransform::update()
-{
-    Q_D(QSGTransform);
-    for (int ii = 0; ii < d->items.count(); ++ii) {
-        QSGItemPrivate *p = QSGItemPrivate::get(d->items.at(ii));
-        p->dirty(QSGItemPrivate::Transform);
-    }
-}
-
-QSGContents::QSGContents(QSGItem *item)
-: m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
-{
-    //### optimize
-    connect(this, SIGNAL(rectChanged(QRectF)), m_item, SIGNAL(childrenRectChanged(QRectF)));
-}
-
-QSGContents::~QSGContents()
-{
-    QList<QSGItem *> children = m_item->childItems();
-    for (int i = 0; i < children.count(); ++i) {
-        QSGItem *child = children.at(i);
-        QSGItemPrivate::get(child)->removeItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
-    }
-}
-
-QRectF QSGContents::rectF() const
-{
-    return QRectF(m_x, m_y, m_width, m_height);
-}
-
-void QSGContents::calcHeight(QSGItem *changed)
-{
-    qreal oldy = m_y;
-    qreal oldheight = m_height;
-
-    if (changed) {
-        qreal top = oldy;
-        qreal bottom = oldy + oldheight;
-        qreal y = changed->y();
-        if (y + changed->height() > bottom)
-            bottom = y + changed->height();
-        if (y < top)
-            top = y;
-        m_y = top;
-        m_height = bottom - top;
-    } else {
-        qreal top = FLT_MAX;
-        qreal bottom = 0;
-        QList<QSGItem *> children = m_item->childItems();
-        for (int i = 0; i < children.count(); ++i) {
-            QSGItem *child = children.at(i);
-            qreal y = child->y();
-            if (y + child->height() > bottom)
-                bottom = y + child->height();
-            if (y < top)
-                top = y;
-        }
-        if (!children.isEmpty())
-            m_y = top;
-        m_height = qMax(bottom - top, qreal(0.0));
-    }
-
-    if (m_height != oldheight || m_y != oldy)
-        emit rectChanged(rectF());
-}
-
-void QSGContents::calcWidth(QSGItem *changed)
-{
-    qreal oldx = m_x;
-    qreal oldwidth = m_width;
-
-    if (changed) {
-        qreal left = oldx;
-        qreal right = oldx + oldwidth;
-        qreal x = changed->x();
-        if (x + changed->width() > right)
-            right = x + changed->width();
-        if (x < left)
-            left = x;
-        m_x = left;
-        m_width = right - left;
-    } else {
-        qreal left = FLT_MAX;
-        qreal right = 0;
-        QList<QSGItem *> children = m_item->childItems();
-        for (int i = 0; i < children.count(); ++i) {
-            QSGItem *child = children.at(i);
-            qreal x = child->x();
-            if (x + child->width() > right)
-                right = x + child->width();
-            if (x < left)
-                left = x;
-        }
-        if (!children.isEmpty())
-            m_x = left;
-        m_width = qMax(right - left, qreal(0.0));
-    }
-
-    if (m_width != oldwidth || m_x != oldx)
-        emit rectChanged(rectF());
-}
-
-void QSGContents::complete()
-{
-    QList<QSGItem *> children = m_item->childItems();
-    for (int i = 0; i < children.count(); ++i) {
-        QSGItem *child = children.at(i);
-        QSGItemPrivate::get(child)->addItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
-        //###what about changes to visibility?
-    }
-
-    calcGeometry();
-}
-
-void QSGContents::itemGeometryChanged(QSGItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
-{
-    Q_UNUSED(changed)
-    //### we can only pass changed if the left edge has moved left, or the right edge has moved right
-    if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
-        calcWidth(/*changed*/);
-    if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
-        calcHeight(/*changed*/);
-}
-
-void QSGContents::itemDestroyed(QSGItem *item)
-{
-    if (item)
-        QSGItemPrivate::get(item)->removeItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
-    calcGeometry();
-}
-
-void QSGContents::childRemoved(QSGItem *item)
-{
-    if (item)
-        QSGItemPrivate::get(item)->removeItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
-    calcGeometry();
-}
-
-void QSGContents::childAdded(QSGItem *item)
-{
-    if (item)
-        QSGItemPrivate::get(item)->addItemChangeListener(this, QSGItemPrivate::Geometry | QSGItemPrivate::Destroyed);
-    calcWidth(item);
-    calcHeight(item);
-}
-
-QSGItemKeyFilter::QSGItemKeyFilter(QSGItem *item)
-: m_processPost(false), m_next(0)
-{
-    QSGItemPrivate *p = item?QSGItemPrivate::get(item):0;
-    if (p) {
-        m_next = p->keyHandler;
-        p->keyHandler = this;
-    }
-}
-
-QSGItemKeyFilter::~QSGItemKeyFilter()
-{
-}
-
-void QSGItemKeyFilter::keyPressed(QKeyEvent *event, bool post)
-{
-    if (m_next) m_next->keyPressed(event, post);
-}
-
-void QSGItemKeyFilter::keyReleased(QKeyEvent *event, bool post)
-{
-    if (m_next) m_next->keyReleased(event, post);
-}
-
-void QSGItemKeyFilter::inputMethodEvent(QInputMethodEvent *event, bool post)
-{
-    if (m_next)
-        m_next->inputMethodEvent(event, post);
-    else
-        event->ignore();
-}
-
-QVariant QSGItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const
-{
-    if (m_next) return m_next->inputMethodQuery(query);
-    return QVariant();
-}
-
-void QSGItemKeyFilter::componentComplete()
-{
-    if (m_next) m_next->componentComplete();
-}
-/*!
-    \qmlclass KeyNavigation QSGKeyNavigationAttached
-    \inqmlmodule QtQuick 2
-    \ingroup qml-basic-interaction-elements
-    \brief The KeyNavigation attached property supports key navigation by arrow keys.
-
-    Key-based user interfaces commonly allow the use of arrow keys to navigate between
-    focusable items.  The KeyNavigation attached property enables this behavior by providing a
-    convenient way to specify the item that should gain focus when an arrow or tab key is pressed.
-
-    The following example provides key navigation for a 2x2 grid of items:
-
-    \snippet doc/src/snippets/declarative/keynavigation.qml 0
-
-    The top-left item initially receives focus by setting \l {Item::}{focus} to
-    \c true. When an arrow key is pressed, the focus will move to the
-    appropriate item, as defined by the value that has been set for
-    the KeyNavigation \l left, \l right, \l up or \l down properties.
-
-    Note that if a KeyNavigation attached property receives the key press and release
-    events for a requested arrow or tab key, the event is accepted and does not
-    propagate any further.
-
-    By default, KeyNavigation receives key events after the item to which it is attached.
-    If the item accepts the key event, the KeyNavigation attached property will not
-    receive an event for that key.  Setting the \l priority property to
-    \c KeyNavigation.BeforeItem allows the event to be used for key navigation
-    before the item, rather than after.
-
-    If item to which the focus is switching is not enabled or visible, an attempt will
-    be made to skip this item and focus on the next. This is possible if there are
-    a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
-    or visible, they will also be skipped.
-
-    KeyNavigation will implicitly set the other direction to return focus to this item. So if you set
-    \l left to another item, \l right will be set on that item's KeyNavigation to set focus back to this
-    item. However, if that item's KeyNavigation has had right explicitly set then no change will occur.
-    This means that the above example could have been written, with the same behaviour, without specifing
-    KeyNavigation.right or KeyNavigation.down for any of the items.
-
-    \sa {Keys}{Keys attached property}
-*/
-
-/*!
-    \qmlproperty Item QtQuick2::KeyNavigation::left
-    \qmlproperty Item QtQuick2::KeyNavigation::right
-    \qmlproperty Item QtQuick2::KeyNavigation::up
-    \qmlproperty Item QtQuick2::KeyNavigation::down
-    \qmlproperty Item QtQuick2::KeyNavigation::tab
-    \qmlproperty Item QtQuick2::KeyNavigation::backtab
-
-    These properties hold the item to assign focus to
-    when the left, right, up or down cursor keys, or the
-    tab key are pressed.
-*/
-
-/*!
-    \qmlproperty Item QtQuick2::KeyNavigation::tab
-    \qmlproperty Item QtQuick2::KeyNavigation::backtab
-
-    These properties hold the item to assign focus to
-    when the Tab key or Shift+Tab key combination (Backtab) are pressed.
-*/
-
-QSGKeyNavigationAttached::QSGKeyNavigationAttached(QObject *parent)
-: QObject(*(new QSGKeyNavigationAttachedPrivate), parent),
-  QSGItemKeyFilter(qobject_cast<QSGItem*>(parent))
-{
-    m_processPost = true;
-}
-
-QSGKeyNavigationAttached *
-QSGKeyNavigationAttached::qmlAttachedProperties(QObject *obj)
-{
-    return new QSGKeyNavigationAttached(obj);
-}
-
-QSGItem *QSGKeyNavigationAttached::left() const
-{
-    Q_D(const QSGKeyNavigationAttached);
-    return d->left;
-}
-
-void QSGKeyNavigationAttached::setLeft(QSGItem *i)
-{
-    Q_D(QSGKeyNavigationAttached);
-    if (d->left == i)
-        return;
-    d->left = i;
-    d->leftSet = true;
-    QSGKeyNavigationAttached* other =
-            qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
-    if (other && !other->d_func()->rightSet){
-        other->d_func()->right = qobject_cast<QSGItem*>(parent());
-        emit other->rightChanged();
-    }
-    emit leftChanged();
-}
-
-QSGItem *QSGKeyNavigationAttached::right() const
-{
-    Q_D(const QSGKeyNavigationAttached);
-    return d->right;
-}
-
-void QSGKeyNavigationAttached::setRight(QSGItem *i)
-{
-    Q_D(QSGKeyNavigationAttached);
-    if (d->right == i)
-        return;
-    d->right = i;
-    d->rightSet = true;
-    QSGKeyNavigationAttached* other =
-            qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
-    if (other && !other->d_func()->leftSet){
-        other->d_func()->left = qobject_cast<QSGItem*>(parent());
-        emit other->leftChanged();
-    }
-    emit rightChanged();
-}
-
-QSGItem *QSGKeyNavigationAttached::up() const
-{
-    Q_D(const QSGKeyNavigationAttached);
-    return d->up;
-}
-
-void QSGKeyNavigationAttached::setUp(QSGItem *i)
-{
-    Q_D(QSGKeyNavigationAttached);
-    if (d->up == i)
-        return;
-    d->up = i;
-    d->upSet = true;
-    QSGKeyNavigationAttached* other =
-            qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
-    if (other && !other->d_func()->downSet){
-        other->d_func()->down = qobject_cast<QSGItem*>(parent());
-        emit other->downChanged();
-    }
-    emit upChanged();
-}
-
-QSGItem *QSGKeyNavigationAttached::down() const
-{
-    Q_D(const QSGKeyNavigationAttached);
-    return d->down;
-}
-
-void QSGKeyNavigationAttached::setDown(QSGItem *i)
-{
-    Q_D(QSGKeyNavigationAttached);
-    if (d->down == i)
-        return;
-    d->down = i;
-    d->downSet = true;
-    QSGKeyNavigationAttached* other =
-            qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
-    if (other && !other->d_func()->upSet) {
-        other->d_func()->up = qobject_cast<QSGItem*>(parent());
-        emit other->upChanged();
-    }
-    emit downChanged();
-}
-
-QSGItem *QSGKeyNavigationAttached::tab() const
-{
-    Q_D(const QSGKeyNavigationAttached);
-    return d->tab;
-}
-
-void QSGKeyNavigationAttached::setTab(QSGItem *i)
-{
-    Q_D(QSGKeyNavigationAttached);
-    if (d->tab == i)
-        return;
-    d->tab = i;
-    d->tabSet = true;
-    QSGKeyNavigationAttached* other =
-            qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
-    if (other && !other->d_func()->backtabSet) {
-        other->d_func()->backtab = qobject_cast<QSGItem*>(parent());
-        emit other->backtabChanged();
-    }
-    emit tabChanged();
-}
-
-QSGItem *QSGKeyNavigationAttached::backtab() const
-{
-    Q_D(const QSGKeyNavigationAttached);
-    return d->backtab;
-}
-
-void QSGKeyNavigationAttached::setBacktab(QSGItem *i)
-{
-    Q_D(QSGKeyNavigationAttached);
-    if (d->backtab == i)
-        return;
-    d->backtab = i;
-    d->backtabSet = true;
-    QSGKeyNavigationAttached* other =
-            qobject_cast<QSGKeyNavigationAttached*>(qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(i));
-    if (other && !other->d_func()->tabSet) {
-        other->d_func()->tab = qobject_cast<QSGItem*>(parent());
-        emit other->tabChanged();
-    }
-    emit backtabChanged();
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::KeyNavigation::priority
-
-    This property determines whether the keys are processed before
-    or after the attached item's own key handling.
-
-    \list
-    \o KeyNavigation.BeforeItem - process the key events before normal
-    item key processing.  If the event is used for key navigation, it will be accepted and will not
-    be passed on to the item.
-    \o KeyNavigation.AfterItem (default) - process the key events after normal item key
-    handling.  If the item accepts the key event it will not be
-    handled by the KeyNavigation attached property handler.
-    \endlist
-*/
-QSGKeyNavigationAttached::Priority QSGKeyNavigationAttached::priority() const
-{
-    return m_processPost ? AfterItem : BeforeItem;
-}
-
-void QSGKeyNavigationAttached::setPriority(Priority order)
-{
-    bool processPost = order == AfterItem;
-    if (processPost != m_processPost) {
-        m_processPost = processPost;
-        emit priorityChanged();
-    }
-}
-
-void QSGKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
-{
-    Q_D(QSGKeyNavigationAttached);
-    event->ignore();
-
-    if (post != m_processPost) {
-        QSGItemKeyFilter::keyPressed(event, post);
-        return;
-    }
-
-    bool mirror = false;
-    switch (event->key()) {
-    case Qt::Key_Left: {
-        if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
-            mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
-        QSGItem* leftItem = mirror ? d->right : d->left;
-        if (leftItem) {
-            setFocusNavigation(leftItem, mirror ? "right" : "left");
-            event->accept();
-        }
-        break;
-    }
-    case Qt::Key_Right: {
-        if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
-            mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
-        QSGItem* rightItem = mirror ? d->left : d->right;
-        if (rightItem) {
-            setFocusNavigation(rightItem, mirror ? "left" : "right");
-            event->accept();
-        }
-        break;
-    }
-    case Qt::Key_Up:
-        if (d->up) {
-            setFocusNavigation(d->up, "up");
-            event->accept();
-        }
-        break;
-    case Qt::Key_Down:
-        if (d->down) {
-            setFocusNavigation(d->down, "down");
-            event->accept();
-        }
-        break;
-    case Qt::Key_Tab:
-        if (d->tab) {
-            setFocusNavigation(d->tab, "tab");
-            event->accept();
-        }
-        break;
-    case Qt::Key_Backtab:
-        if (d->backtab) {
-            setFocusNavigation(d->backtab, "backtab");
-            event->accept();
-        }
-        break;
-    default:
-        break;
-    }
-
-    if (!event->isAccepted()) QSGItemKeyFilter::keyPressed(event, post);
-}
-
-void QSGKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
-{
-    Q_D(QSGKeyNavigationAttached);
-    event->ignore();
-
-    if (post != m_processPost) {
-        QSGItemKeyFilter::keyReleased(event, post);
-        return;
-    }
-
-    bool mirror = false;
-    switch (event->key()) {
-    case Qt::Key_Left:
-        if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
-            mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
-        if (mirror ? d->right : d->left)
-            event->accept();
-        break;
-    case Qt::Key_Right:
-        if (QSGItem *parentItem = qobject_cast<QSGItem*>(parent()))
-            mirror = QSGItemPrivate::get(parentItem)->effectiveLayoutMirror;
-        if (mirror ? d->left : d->right)
-            event->accept();
-        break;
-    case Qt::Key_Up:
-        if (d->up) {
-            event->accept();
-        }
-        break;
-    case Qt::Key_Down:
-        if (d->down) {
-            event->accept();
-        }
-        break;
-    case Qt::Key_Tab:
-        if (d->tab) {
-            event->accept();
-        }
-        break;
-    case Qt::Key_Backtab:
-        if (d->backtab) {
-            event->accept();
-        }
-        break;
-    default:
-        break;
-    }
-
-    if (!event->isAccepted()) QSGItemKeyFilter::keyReleased(event, post);
-}
-
-void QSGKeyNavigationAttached::setFocusNavigation(QSGItem *currentItem, const char *dir)
-{
-    QSGItem *initialItem = currentItem;
-    bool isNextItem = false;
-    do {
-        isNextItem = false;
-        if (currentItem->isVisible() && currentItem->isEnabled()) {
-            currentItem->setFocus(true);
-        } else {
-            QObject *attached =
-                qmlAttachedPropertiesObject<QSGKeyNavigationAttached>(currentItem, false);
-            if (attached) {
-                QSGItem *tempItem = qvariant_cast<QSGItem*>(attached->property(dir));
-                if (tempItem) {
-                    currentItem = tempItem;
-                    isNextItem = true;
-                }
-            }
-        }
-    }
-    while (currentItem != initialItem && isNextItem);
-}
-
-const QSGKeysAttached::SigMap QSGKeysAttached::sigMap[] = {
-    { Qt::Key_Left, "leftPressed" },
-    { Qt::Key_Right, "rightPressed" },
-    { Qt::Key_Up, "upPressed" },
-    { Qt::Key_Down, "downPressed" },
-    { Qt::Key_Tab, "tabPressed" },
-    { Qt::Key_Backtab, "backtabPressed" },
-    { Qt::Key_Asterisk, "asteriskPressed" },
-    { Qt::Key_NumberSign, "numberSignPressed" },
-    { Qt::Key_Escape, "escapePressed" },
-    { Qt::Key_Return, "returnPressed" },
-    { Qt::Key_Enter, "enterPressed" },
-    { Qt::Key_Delete, "deletePressed" },
-    { Qt::Key_Space, "spacePressed" },
-    { Qt::Key_Back, "backPressed" },
-    { Qt::Key_Cancel, "cancelPressed" },
-    { Qt::Key_Select, "selectPressed" },
-    { Qt::Key_Yes, "yesPressed" },
-    { Qt::Key_No, "noPressed" },
-    { Qt::Key_Context1, "context1Pressed" },
-    { Qt::Key_Context2, "context2Pressed" },
-    { Qt::Key_Context3, "context3Pressed" },
-    { Qt::Key_Context4, "context4Pressed" },
-    { Qt::Key_Call, "callPressed" },
-    { Qt::Key_Hangup, "hangupPressed" },
-    { Qt::Key_Flip, "flipPressed" },
-    { Qt::Key_Menu, "menuPressed" },
-    { Qt::Key_VolumeUp, "volumeUpPressed" },
-    { Qt::Key_VolumeDown, "volumeDownPressed" },
-    { 0, 0 }
-};
-
-bool QSGKeysAttachedPrivate::isConnected(const char *signalName)
-{
-    return isSignalConnected(signalIndex(signalName));
-}
-
-/*!
-    \qmlclass Keys QSGKeysAttached
-    \inqmlmodule QtQuick 2
-    \ingroup qml-basic-interaction-elements
-    \brief The Keys attached property provides key handling to Items.
-
-    All visual primitives support key handling via the Keys
-    attached property.  Keys can be handled via the onPressed
-    and onReleased signal properties.
-
-    The signal properties have a \l KeyEvent parameter, named
-    \e event which contains details of the event.  If a key is
-    handled \e event.accepted should be set to true to prevent the
-    event from propagating up the item hierarchy.
-
-    \section1 Example Usage
-
-    The following example shows how the general onPressed handler can
-    be used to test for a certain key; in this case, the left cursor
-    key:
-
-    \snippet doc/src/snippets/declarative/keys/keys-pressed.qml key item
-
-    Some keys may alternatively be handled via specific signal properties,
-    for example \e onSelectPressed.  These handlers automatically set
-    \e event.accepted to true.
-
-    \snippet doc/src/snippets/declarative/keys/keys-handler.qml key item
-
-    See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
-
-    \section1 Key Handling Priorities
-
-    The Keys attached property can be configured to handle key events
-    before or after the item it is attached to. This makes it possible
-    to intercept events in order to override an item's default behavior,
-    or act as a fallback for keys not handled by the item.
-
-    If \l priority is Keys.BeforeItem (default) the order of key event processing is:
-
-    \list 1
-    \o Items specified in \c forwardTo
-    \o specific key handlers, e.g. onReturnPressed
-    \o onKeyPress, onKeyRelease handlers
-    \o Item specific key handling, e.g. TextInput key handling
-    \o parent item
-    \endlist
-
-    If priority is Keys.AfterItem the order of key event processing is:
-
-    \list 1
-    \o Item specific key handling, e.g. TextInput key handling
-    \o Items specified in \c forwardTo
-    \o specific key handlers, e.g. onReturnPressed
-    \o onKeyPress, onKeyRelease handlers
-    \o parent item
-    \endlist
-
-    If the event is accepted during any of the above steps, key
-    propagation stops.
-
-    \sa KeyEvent, {KeyNavigation}{KeyNavigation attached property}
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::Keys::enabled
-
-    This flags enables key handling if true (default); otherwise
-    no key handlers will be called.
-*/
-
-/*!
-    \qmlproperty enumeration QtQuick2::Keys::priority
-
-    This property determines whether the keys are processed before
-    or after the attached item's own key handling.
-
-    \list
-    \o Keys.BeforeItem (default) - process the key events before normal
-    item key processing.  If the event is accepted it will not
-    be passed on to the item.
-    \o Keys.AfterItem - process the key events after normal item key
-    handling.  If the item accepts the key event it will not be
-    handled by the Keys attached property handler.
-    \endlist
-*/
-
-/*!
-    \qmlproperty list<Object> QtQuick2::Keys::forwardTo
-
-    This property provides a way to forward key presses, key releases, and keyboard input
-    coming from input methods to other items. This can be useful when you want
-    one item to handle some keys (e.g. the up and down arrow keys), and another item to
-    handle other keys (e.g. the left and right arrow keys).  Once an item that has been
-    forwarded keys accepts the event it is no longer forwarded to items later in the
-    list.
-
-    This example forwards key events to two lists:
-    \qml
-    Item {
-        ListView {
-            id: list1
-            // ...
-        }
-        ListView {
-            id: list2
-            // ...
-        }
-        Keys.forwardTo: [list1, list2]
-        focus: true
-    }
-    \endqml
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onPressed(KeyEvent event)
-
-    This handler is called when a key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onReleased(KeyEvent event)
-
-    This handler is called when a key has been released. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onDigit0Pressed(KeyEvent event)
-
-    This handler is called when the digit '0' has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onDigit1Pressed(KeyEvent event)
-
-    This handler is called when the digit '1' has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onDigit2Pressed(KeyEvent event)
-
-    This handler is called when the digit '2' has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onDigit3Pressed(KeyEvent event)
-
-    This handler is called when the digit '3' has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onDigit4Pressed(KeyEvent event)
-
-    This handler is called when the digit '4' has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onDigit5Pressed(KeyEvent event)
-
-    This handler is called when the digit '5' has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onDigit6Pressed(KeyEvent event)
-
-    This handler is called when the digit '6' has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onDigit7Pressed(KeyEvent event)
-
-    This handler is called when the digit '7' has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onDigit8Pressed(KeyEvent event)
-
-    This handler is called when the digit '8' has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onDigit9Pressed(KeyEvent event)
-
-    This handler is called when the digit '9' has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onLeftPressed(KeyEvent event)
-
-    This handler is called when the Left arrow has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onRightPressed(KeyEvent event)
-
-    This handler is called when the Right arrow has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onUpPressed(KeyEvent event)
-
-    This handler is called when the Up arrow has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onDownPressed(KeyEvent event)
-
-    This handler is called when the Down arrow has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onTabPressed(KeyEvent event)
-
-    This handler is called when the Tab key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onBacktabPressed(KeyEvent event)
-
-    This handler is called when the Shift+Tab key combination (Backtab) has
-    been pressed. The \a event parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onAsteriskPressed(KeyEvent event)
-
-    This handler is called when the Asterisk '*' has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onEscapePressed(KeyEvent event)
-
-    This handler is called when the Escape key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onReturnPressed(KeyEvent event)
-
-    This handler is called when the Return key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onEnterPressed(KeyEvent event)
-
-    This handler is called when the Enter key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onDeletePressed(KeyEvent event)
-
-    This handler is called when the Delete key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onSpacePressed(KeyEvent event)
-
-    This handler is called when the Space key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onBackPressed(KeyEvent event)
-
-    This handler is called when the Back key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onCancelPressed(KeyEvent event)
-
-    This handler is called when the Cancel key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onSelectPressed(KeyEvent event)
-
-    This handler is called when the Select key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onYesPressed(KeyEvent event)
-
-    This handler is called when the Yes key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onNoPressed(KeyEvent event)
-
-    This handler is called when the No key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onContext1Pressed(KeyEvent event)
-
-    This handler is called when the Context1 key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onContext2Pressed(KeyEvent event)
-
-    This handler is called when the Context2 key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onContext3Pressed(KeyEvent event)
-
-    This handler is called when the Context3 key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onContext4Pressed(KeyEvent event)
-
-    This handler is called when the Context4 key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onCallPressed(KeyEvent event)
-
-    This handler is called when the Call key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onHangupPressed(KeyEvent event)
-
-    This handler is called when the Hangup key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onFlipPressed(KeyEvent event)
-
-    This handler is called when the Flip key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onMenuPressed(KeyEvent event)
-
-    This handler is called when the Menu key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onVolumeUpPressed(KeyEvent event)
-
-    This handler is called when the VolumeUp key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Keys::onVolumeDownPressed(KeyEvent event)
-
-    This handler is called when the VolumeDown key has been pressed. The \a event
-    parameter provides information about the event.
-*/
-
-QSGKeysAttached::QSGKeysAttached(QObject *parent)
-: QObject(*(new QSGKeysAttachedPrivate), parent),
-  QSGItemKeyFilter(qobject_cast<QSGItem*>(parent))
-{
-    Q_D(QSGKeysAttached);
-    m_processPost = false;
-    d->item = qobject_cast<QSGItem*>(parent);
-}
-
-QSGKeysAttached::~QSGKeysAttached()
-{
-}
-
-QSGKeysAttached::Priority QSGKeysAttached::priority() const
-{
-    return m_processPost ? AfterItem : BeforeItem;
-}
-
-void QSGKeysAttached::setPriority(Priority order)
-{
-    bool processPost = order == AfterItem;
-    if (processPost != m_processPost) {
-        m_processPost = processPost;
-        emit priorityChanged();
-    }
-}
-
-void QSGKeysAttached::componentComplete()
-{
-    Q_D(QSGKeysAttached);
-    if (d->item) {
-        for (int ii = 0; ii < d->targets.count(); ++ii) {
-            QSGItem *targetItem = d->targets.at(ii);
-            if (targetItem && (targetItem->flags() & QSGItem::ItemAcceptsInputMethod)) {
-                d->item->setFlag(QSGItem::ItemAcceptsInputMethod);
-                break;
-            }
-        }
-    }
-}
-
-void QSGKeysAttached::keyPressed(QKeyEvent *event, bool post)
-{
-    Q_D(QSGKeysAttached);
-    if (post != m_processPost || !d->enabled || d->inPress) {
-        event->ignore();
-        QSGItemKeyFilter::keyPressed(event, post);
-        return;
-    }
-
-    // first process forwards
-    if (d->item && d->item->canvas()) {
-        d->inPress = true;
-        for (int ii = 0; ii < d->targets.count(); ++ii) {
-            QSGItem *i = d->targets.at(ii);
-            if (i && i->isVisible()) {
-                d->item->canvas()->sendEvent(i, event);
-                if (event->isAccepted()) {
-                    d->inPress = false;
-                    return;
-                }
-            }
-        }
-        d->inPress = false;
-    }
-
-    QSGKeyEvent ke(*event);
-    QByteArray keySignal = keyToSignal(event->key());
-    if (!keySignal.isEmpty()) {
-        keySignal += "(QSGKeyEvent*)";
-        if (d->isConnected(keySignal)) {
-            // If we specifically handle a key then default to accepted
-            ke.setAccepted(true);
-            int idx = QSGKeysAttached::staticMetaObject.indexOfSignal(keySignal);
-            metaObject()->method(idx).invoke(this, Qt::DirectConnection, Q_ARG(QSGKeyEvent*, &ke));
-        }
-    }
-    if (!ke.isAccepted())
-        emit pressed(&ke);
-    event->setAccepted(ke.isAccepted());
-
-    if (!event->isAccepted()) QSGItemKeyFilter::keyPressed(event, post);
-}
-
-void QSGKeysAttached::keyReleased(QKeyEvent *event, bool post)
-{
-    Q_D(QSGKeysAttached);
-    if (post != m_processPost || !d->enabled || d->inRelease) {
-        event->ignore();
-        QSGItemKeyFilter::keyReleased(event, post);
-        return;
-    }
-
-    if (d->item && d->item->canvas()) {
-        d->inRelease = true;
-        for (int ii = 0; ii < d->targets.count(); ++ii) {
-            QSGItem *i = d->targets.at(ii);
-            if (i && i->isVisible()) {
-                d->item->canvas()->sendEvent(i, event);
-                if (event->isAccepted()) {
-                    d->inRelease = false;
-                    return;
-                }
-            }
-        }
-        d->inRelease = false;
-    }
-
-    QSGKeyEvent ke(*event);
-    emit released(&ke);
-    event->setAccepted(ke.isAccepted());
-
-    if (!event->isAccepted()) QSGItemKeyFilter::keyReleased(event, post);
-}
-
-void QSGKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
-{
-    Q_D(QSGKeysAttached);
-    if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
-        d->inIM = true;
-        for (int ii = 0; ii < d->targets.count(); ++ii) {
-            QSGItem *i = d->targets.at(ii);
-            if (i && i->isVisible() && (i->flags() & QSGItem::ItemAcceptsInputMethod)) {
-                d->item->canvas()->sendEvent(i, event);
-                if (event->isAccepted()) {
-                    d->imeItem = i;
-                    d->inIM = false;
-                    return;
-                }
-            }
-        }
-        d->inIM = false;
-    }
-    QSGItemKeyFilter::inputMethodEvent(event, post);
-}
-
-QVariant QSGKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const
-{
-    Q_D(const QSGKeysAttached);
-    if (d->item) {
-        for (int ii = 0; ii < d->targets.count(); ++ii) {
-            QSGItem *i = d->targets.at(ii);
-            if (i && i->isVisible() && (i->flags() & QSGItem::ItemAcceptsInputMethod) && i == d->imeItem) {
-                //### how robust is i == d->imeItem check?
-                QVariant v = i->inputMethodQuery(query);
-                if (v.userType() == QVariant::RectF)
-                    v = d->item->mapRectFromItem(i, v.toRectF());  //### cost?
-                return v;
-            }
-        }
-    }
-    return QSGItemKeyFilter::inputMethodQuery(query);
-}
-
-QSGKeysAttached *QSGKeysAttached::qmlAttachedProperties(QObject *obj)
-{
-    return new QSGKeysAttached(obj);
-}
-
-/*!
-    \qmlclass LayoutMirroring QSGLayoutMirroringAttached
-    \inqmlmodule QtQuick 2
-    \ingroup qml-utility-elements
-    \brief The LayoutMirroring attached property is used to mirror layout behavior.
-
-    The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
-    \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
-    and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
-    anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
-    horizontal layout of child items.
-
-    Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
-    only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
-    behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
-    for an item, mirroring is not enabled.
-
-    The following example shows mirroring in action. The \l Row below is specified as being anchored
-    to the left of its parent. However, since mirroring has been enabled, the anchor is horizontally
-    reversed and it is now anchored to the right. Also, since items in a \l Row are positioned
-    from left to right by default, they are now positioned from right to left instead, as demonstrated
-    by the numbering and opacity of the items:
-
-    \snippet doc/src/snippets/declarative/layoutmirroring.qml 0
-
-    \image layoutmirroring.png
-
-    Layout mirroring is useful when it is necessary to support both left-to-right and right-to-left
-    layout versions of an application to target different language areas. The \l childrenInherit
-    property allows layout mirroring to be applied without manually setting layout configurations
-    for every item in an application. Keep in mind, however, that mirroring does not affect any
-    positioning that is defined by the \l Item \l {Item::}{x} coordinate value, so even with
-    mirroring enabled, it will often be necessary to apply some layout fixes to support the
-    desired layout direction. Also, it may be necessary to disable the mirroring of individual
-    child items (by setting \l {enabled}{LayoutMirroring.enabled} to false for such items) if
-    mirroring is not the desired behavior, or if the child item already implements mirroring in
-    some custom way.
-
-    See \l {QML Right-to-left User Interfaces} for further details on using \c LayoutMirroring and
-    other related features to implement right-to-left support for an application.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::LayoutMirroring::enabled
-
-    This property holds whether the item's layout is mirrored horizontally. Setting this to true
-    horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
-    and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
-    (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
-    this also mirrors the horizontal layout direction of the item.
-
-    The default value is false.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::LayoutMirroring::childrenInherit
-
-    This property holds whether the \l {enabled}{LayoutMirroring.enabled} value for this item
-    is inherited by its children.
-
-    The default value is false.
-*/
-
-
-QSGLayoutMirroringAttached::QSGLayoutMirroringAttached(QObject *parent) : QObject(parent), itemPrivate(0)
-{
-    if (QSGItem *item = qobject_cast<QSGItem*>(parent)) {
-        itemPrivate = QSGItemPrivate::get(item);
-        itemPrivate->attachedLayoutDirection = this;
-    } else
-        qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
-}
-
-QSGLayoutMirroringAttached * QSGLayoutMirroringAttached::qmlAttachedProperties(QObject *object)
-{
-    return new QSGLayoutMirroringAttached(object);
-}
-
-bool QSGLayoutMirroringAttached::enabled() const
-{
-    return itemPrivate ? itemPrivate->effectiveLayoutMirror : false;
-}
-
-void QSGLayoutMirroringAttached::setEnabled(bool enabled)
-{
-    if (!itemPrivate)
-        return;
-
-    itemPrivate->isMirrorImplicit = false;
-    if (enabled != itemPrivate->effectiveLayoutMirror) {
-        itemPrivate->setLayoutMirror(enabled);
-        if (itemPrivate->inheritMirrorFromItem)
-             itemPrivate->resolveLayoutMirror();
-    }
-}
-
-void QSGLayoutMirroringAttached::resetEnabled()
-{
-    if (itemPrivate && !itemPrivate->isMirrorImplicit) {
-        itemPrivate->isMirrorImplicit = true;
-        itemPrivate->resolveLayoutMirror();
-    }
-}
-
-bool QSGLayoutMirroringAttached::childrenInherit() const
-{
-    return itemPrivate ? itemPrivate->inheritMirrorFromItem : false;
-}
-
-void QSGLayoutMirroringAttached::setChildrenInherit(bool childrenInherit) {
-    if (itemPrivate && childrenInherit != itemPrivate->inheritMirrorFromItem) {
-        itemPrivate->inheritMirrorFromItem = childrenInherit;
-        itemPrivate->resolveLayoutMirror();
-        childrenInheritChanged();
-    }
-}
-
-void QSGItemPrivate::resolveLayoutMirror()
-{
-    Q_Q(QSGItem);
-    if (QSGItem *parentItem = q->parentItem()) {
-        QSGItemPrivate *parentPrivate = QSGItemPrivate::get(parentItem);
-        setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
-    } else {
-        setImplicitLayoutMirror(isMirrorImplicit ? false : effectiveLayoutMirror, inheritMirrorFromItem);
-    }
-}
-
-void QSGItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
-{
-    inherit = inherit || inheritMirrorFromItem;
-    if (!isMirrorImplicit && inheritMirrorFromItem)
-        mirror = effectiveLayoutMirror;
-    if (mirror == inheritedLayoutMirror && inherit == inheritMirrorFromParent)
-        return;
-
-    inheritMirrorFromParent = inherit;
-    inheritedLayoutMirror = inheritMirrorFromParent ? mirror : false;
-
-    if (isMirrorImplicit)
-        setLayoutMirror(inherit ? inheritedLayoutMirror : false);
-    for (int i = 0; i < childItems.count(); ++i) {
-        if (QSGItem *child = qobject_cast<QSGItem *>(childItems.at(i))) {
-            QSGItemPrivate *childPrivate = QSGItemPrivate::get(child);
-            childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
-        }
-    }
-}
-
-void QSGItemPrivate::setLayoutMirror(bool mirror)
-{
-    if (mirror != effectiveLayoutMirror) {
-        effectiveLayoutMirror = mirror;
-        if (_anchors) {
-            QSGAnchorsPrivate *anchor_d = QSGAnchorsPrivate::get(_anchors);
-            anchor_d->fillChanged();
-            anchor_d->centerInChanged();
-            anchor_d->updateHorizontalAnchors();
-            emit _anchors->mirroredChanged();
-        }
-        mirrorChange();
-        if (attachedLayoutDirection) {
-            emit attachedLayoutDirection->enabledChanged();
-        }
-    }
-}
-
-/*!
-    \class QSGItem
-    \brief The QSGItem class provides the most basic of all visual items in QML.
-
-    All visual items in Qt Declarative inherit from QSGItem.  Although QSGItem
-    has no visual appearance, it defines all the properties that are
-    common across visual items - such as the x and y position, the
-    width and height, \l {anchor-layout}{anchoring} and key handling.
-
-    You can subclass QSGItem to provide your own custom visual item that inherits
-    these features. Note that, because it does not draw anything, QSGItem sets the
-    QGraphicsItem::ItemHasNoContents flag. If you subclass QSGItem to create a visual
-    item, you will need to unset this flag.
-
-*/
-
-/*!
-    \qmlclass Item QSGItem
-    \inqmlmodule QtQuick 2
-    \ingroup qml-basic-visual-elements
-    \brief The Item is the most basic of all visual items in QML.
-
-    All visual items in Qt Declarative inherit from Item.  Although Item
-    has no visual appearance, it defines all the properties that are
-    common across visual items - such as the x and y position, the
-    width and height, \l {anchor-layout}{anchoring} and key handling.
-
-    Item is also useful for grouping items together.
-
-    \qml
-    Item {
-        Image {
-            source: "tile.png"
-        }
-        Image {
-            x: 80
-            width: 100
-            height: 100
-            source: "tile.png"
-        }
-        Image {
-            x: 190
-            width: 100
-            height: 100
-            fillMode: Image.Tile
-            source: "tile.png"
-        }
-    }
-    \endqml
-
-
-    \section1 Key Handling
-
-    Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
-    attached property.  The \e Keys attached property provides basic handlers such
-    as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
-    as well as handlers for specific keys, such as
-    \l {Keys::onCancelPressed}{onCancelPressed}.  The example below
-    assigns \l {qmlfocus}{focus} to the item and handles
-    the Left key via the general \e onPressed handler and the Select key via the
-    onSelectPressed handler:
-
-    \qml
-    Item {
-        focus: true
-        Keys.onPressed: {
-            if (event.key == Qt.Key_Left) {
-                console.log("move left");
-                event.accepted = true;
-            }
-        }
-        Keys.onSelectPressed: console.log("Selected");
-    }
-    \endqml
-
-    See the \l {Keys}{Keys} attached property for detailed documentation.
-
-    \section1 Layout Mirroring
-
-    Item layouts can be mirrored using the \l {LayoutMirroring}{LayoutMirroring} attached property.
-
-*/
-
-/*!
-    \fn void QSGItem::childrenRectChanged(const QRectF &)
-    \internal
-*/
-
-/*!
-    \fn void QSGItem::baselineOffsetChanged(qreal)
-    \internal
-*/
-
-/*!
-    \fn void QSGItem::stateChanged(const QString &state)
-    \internal
-*/
-
-/*!
-    \fn void QSGItem::parentChanged(QSGItem *)
-    \internal
-*/
-
-/*!
-    \fn void QSGItem::smoothChanged(bool)
-    \internal
-*/
-
-/*!
-    \fn void QSGItem::clipChanged(bool)
-    \internal
-*/
-
-/*! \fn void QSGItem::transformOriginChanged(TransformOrigin)
-  \internal
-*/
-
-/*!
-    \fn void QSGItem::focusChanged(bool)
-    \internal
-*/
-
-/*!
-    \fn void QSGItem::activeFocusChanged(bool)
-    \internal
-*/
-/*!
-    \fn QSGItem::QSGItem(QSGItem *parent)
-
-    Constructs a QSGItem with the given \a parent.
-*/
-QSGItem::QSGItem(QSGItem* parent)
-: QObject(*(new QSGItemPrivate), parent)
-{
-    Q_D(QSGItem);
-    d->init(parent);
-}
-
-/*! \internal
-*/
-QSGItem::QSGItem(QSGItemPrivate &dd, QSGItem *parent)
-: QObject(dd, parent)
-{
-    Q_D(QSGItem);
-    d->init(parent);
-}
-
-#ifndef QT_NO_DEBUG
-static int qt_item_count = 0;
-
-static void qt_print_item_count()
-{
-    qDebug("Number of leaked items: %i", qt_item_count);
-    qt_item_count = -1;
-}
-#endif
-
-/*!
-    Destroys the QSGItem.
-*/
-QSGItem::~QSGItem()
-{
-#ifndef QT_NO_DEBUG
-    --qt_item_count;
-    if (qt_item_count < 0)
-        qDebug("Item destroyed after qt_print_item_count() was called.");
-#endif
-
-    Q_D(QSGItem);
-
-    if (d->parentItem)
-        setParentItem(0);
-    else if (d->canvas && d->itemNodeInstance)
-        QSGCanvasPrivate::get(d->canvas)->cleanup(d->itemNodeInstance); // cleanup root
-    // XXX todo - optimize
-    while (!d->childItems.isEmpty())
-        d->childItems.first()->setParentItem(0);
-
-    for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
-        QSGAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
-        if (anchor)
-            anchor->clearItem(this);
-    }
-
-    // XXX todo - the original checks if the parent is being destroyed
-    for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
-        QSGAnchorsPrivate *anchor = d->changeListeners.at(ii).listener->anchorPrivate();
-        if (anchor && anchor->item && anchor->item->parent() != this) //child will be deleted anyway
-            anchor->updateOnComplete();
-    }
-
-    for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
-        const QSGItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
-        if (change.types & QSGItemPrivate::Destroyed)
-            change.listener->itemDestroyed(this);
-    }
-    d->changeListeners.clear();
-    delete d->_anchorLines; d->_anchorLines = 0;
-    delete d->_anchors; d->_anchors = 0;
-    delete d->_stateGroup; d->_stateGroup = 0;
-    delete d->_contents; d->_contents = 0;
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::Item::transformOrigin
-    This property holds the origin point around which scale and rotation transform.
-
-    Nine transform origins are available, as shown in the image below.
-
-    \image declarative-transformorigin.png
-
-    This example rotates an image around its bottom-right corner.
-    \qml
-    Image {
-        source: "myimage.png"
-        transformOrigin: Item.BottomRight
-        rotation: 45
-    }
-    \endqml
-
-    The default transform origin is \c Item.Center.
-
-    To set an arbitrary transform origin point use the \l Scale or \l Rotation
-    transform elements.
-*/
-
-/*!
-    \qmlproperty Item QtQuick2::Item::parent
-    This property holds the parent of the item.
-*/
-
-/*!
-    \property QSGItem::parent
-    This property holds the parent of the item.
-*/
-void QSGItem::setParentItem(QSGItem *parentItem)
-{
-    Q_D(QSGItem);
-    if (parentItem == d->parentItem)
-        return;
-
-    d->removeFromDirtyList();
-
-    QSGItem *oldParentItem = d->parentItem;
-    QSGItem *scopeFocusedItem = 0;
-
-    if (oldParentItem) {
-        QSGItemPrivate *op = QSGItemPrivate::get(oldParentItem);
-
-        QSGItem *scopeItem = 0;
-
-        if (d->canvas && hasFocus()) {
-            scopeItem = oldParentItem;
-            while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
-            scopeFocusedItem = this;
-        } else if (d->canvas && !isFocusScope() && d->subFocusItem) {
-            scopeItem = oldParentItem;
-            while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
-            scopeFocusedItem = d->subFocusItem;
-        }
-
-        if (scopeFocusedItem)
-            QSGCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
-                                                                QSGCanvasPrivate::DontChangeFocusProperty);
-
-        op->removeChild(this);
-    }
-
-    d->parentItem = parentItem;
-
-    QSGCanvas *parentCanvas = parentItem?QSGItemPrivate::get(parentItem)->canvas:0;
-    if (d->canvas != parentCanvas) {
-        QSGItemPrivate::InitializationState initState;
-        initState.clear();
-        d->initCanvas(&initState, parentCanvas);
-    }
-
-    d->dirty(QSGItemPrivate::ParentChanged);
-
-    if (d->parentItem)
-        QSGItemPrivate::get(d->parentItem)->addChild(this);
-
-    d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
-    d->setEffectiveEnableRecur(d->calcEffectiveEnable());
-
-    if (scopeFocusedItem && d->parentItem && d->canvas) {
-        // We need to test whether this item becomes scope focused
-        QSGItem *scopeItem = 0;
-        scopeItem = d->parentItem;
-        while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
-
-        if (scopeItem->scopedFocusItem()) {
-            QSGItemPrivate::get(scopeFocusedItem)->focus = false;
-            emit scopeFocusedItem->focusChanged(false);
-        } else {
-            QSGCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
-                                                              QSGCanvasPrivate::DontChangeFocusProperty);
-        }
-    }
-
-    d->resolveLayoutMirror();
-
-    d->itemChange(ItemParentHasChanged, d->parentItem);
-
-    emit parentChanged(d->parentItem);
-}
-
-void QSGItem::stackBefore(const QSGItem *sibling)
-{
-    Q_D(QSGItem);
-    if (!sibling || sibling == this || !d->parentItem || d->parentItem != QSGItemPrivate::get(sibling)->parentItem) {
-        qWarning("QSGItem::stackBefore: Cannot stack before %p, which must be a sibling", sibling);
-        return;
-    }
-
-    QSGItemPrivate *parentPrivate = QSGItemPrivate::get(d->parentItem);
-
-    int myIndex = parentPrivate->childItems.indexOf(this);
-    int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QSGItem *>(sibling));
-
-    Q_ASSERT(myIndex != -1 && siblingIndex != -1);
-
-    if (myIndex == siblingIndex - 1)
-        return;
-
-    parentPrivate->childItems.removeAt(myIndex);
-
-    if (myIndex < siblingIndex) --siblingIndex;
-
-    parentPrivate->childItems.insert(siblingIndex, this);
-
-    parentPrivate->dirty(QSGItemPrivate::ChildrenStackingChanged);
-
-    for (int ii = qMin(siblingIndex, myIndex); ii < parentPrivate->childItems.count(); ++ii)
-        QSGItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
-}
-
-void QSGItem::stackAfter(const QSGItem *sibling)
-{
-    Q_D(QSGItem);
-    if (!sibling || sibling == this || !d->parentItem || d->parentItem != QSGItemPrivate::get(sibling)->parentItem) {
-        qWarning("QSGItem::stackAfter: Cannot stack after %p, which must be a sibling", sibling);
-        return;
-    }
-
-    QSGItemPrivate *parentPrivate = QSGItemPrivate::get(d->parentItem);
-
-    int myIndex = parentPrivate->childItems.indexOf(this);
-    int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QSGItem *>(sibling));
-
-    Q_ASSERT(myIndex != -1 && siblingIndex != -1);
-
-    if (myIndex == siblingIndex + 1)
-        return;
-
-    parentPrivate->childItems.removeAt(myIndex);
-
-    if (myIndex < siblingIndex) --siblingIndex;
-
-    parentPrivate->childItems.insert(siblingIndex + 1, this);
-
-    parentPrivate->dirty(QSGItemPrivate::ChildrenStackingChanged);
-
-    for (int ii = qMin(myIndex, siblingIndex + 1); ii < parentPrivate->childItems.count(); ++ii)
-        QSGItemPrivate::get(parentPrivate->childItems.at(ii))->siblingOrderChanged();
-}
-
-/*!
-    Returns the QSGItem parent of this item.
-*/
-QSGItem *QSGItem::parentItem() const
-{
-    Q_D(const QSGItem);
-    return d->parentItem;
-}
-
-QSGEngine *QSGItem::sceneGraphEngine() const
-{
-    return canvas()->sceneGraphEngine();
-}
-
-QSGCanvas *QSGItem::canvas() const
-{
-    Q_D(const QSGItem);
-    return d->canvas;
-}
-
-static bool itemZOrder_sort(QSGItem *lhs, QSGItem *rhs)
-{
-    return lhs->z() < rhs->z();
-}
-
-QList<QSGItem *> QSGItemPrivate::paintOrderChildItems() const
-{
-    // XXX todo - optimize, don't sort and return items that are
-    // ignored anyway, like invisible or disabled items.
-    QList<QSGItem *> items = childItems;
-    qStableSort(items.begin(), items.end(), itemZOrder_sort);
-    return items;
-}
-
-void QSGItemPrivate::addChild(QSGItem *child)
-{
-    Q_Q(QSGItem);
-
-    Q_ASSERT(!childItems.contains(child));
-
-    childItems.append(child);
-
-    dirty(QSGItemPrivate::ChildrenChanged);
-
-    itemChange(QSGItem::ItemChildAddedChange, child);
-
-    emit q->childrenChanged();
-}
-
-void QSGItemPrivate::removeChild(QSGItem *child)
-{
-    Q_Q(QSGItem);
-
-    Q_ASSERT(child);
-    Q_ASSERT(childItems.contains(child));
-    childItems.removeOne(child);
-    Q_ASSERT(!childItems.contains(child));
-
-    dirty(QSGItemPrivate::ChildrenChanged);
-
-    itemChange(QSGItem::ItemChildRemovedChange, child);
-
-    emit q->childrenChanged();
-}
-
-void QSGItemPrivate::InitializationState::clear()
-{
-    focusScope = 0;
-}
-
-void QSGItemPrivate::InitializationState::clear(QSGItem *fs)
-{
-    focusScope = fs;
-}
-
-QSGItem *QSGItemPrivate::InitializationState::getFocusScope(QSGItem *item)
-{
-    if (!focusScope) {
-        QSGItem *fs = item->parentItem();
-        while (!fs->isFocusScope())
-            fs = fs->parentItem();
-        focusScope = fs;
-    }
-    return focusScope;
-}
-
-void QSGItemPrivate::initCanvas(InitializationState *state, QSGCanvas *c)
-{
-    Q_Q(QSGItem);
-
-    if (canvas) {
-        removeFromDirtyList();
-        QSGCanvasPrivate *c = QSGCanvasPrivate::get(canvas);
-        if (polishScheduled)
-            c->itemsToPolish.remove(q);
-        if (c->mouseGrabberItem == q)
-            c->mouseGrabberItem = 0;
-        if ( hoverEnabled )
-            c->hoverItems.removeAll(q);
-        if (itemNodeInstance)
-            c->cleanup(itemNodeInstance);
-    }
-
-    canvas = c;
-
-    if (canvas && polishScheduled)
-        QSGCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
-
-    itemNodeInstance = 0;
-    opacityNode = 0;
-    clipNode = 0;
-    rootNode = 0;
-    groupNode = 0;
-    paintNode = 0;
-    beforePaintNode = 0;
-
-    InitializationState _dummy;
-    InitializationState *childState = state;
-
-    if (c && q->isFocusScope()) {
-        _dummy.clear(q);
-        childState = &_dummy;
-    }
-
-    for (int ii = 0; ii < childItems.count(); ++ii) {
-        QSGItem *child = childItems.at(ii);
-        QSGItemPrivate::get(child)->initCanvas(childState, c);
-    }
-
-    if (c && focus) {
-        // Fixup
-        if (state->getFocusScope(q)->scopedFocusItem()) {
-            focus = false;
-            emit q->focusChanged(false);
-        } else {
-            QSGCanvasPrivate::get(canvas)->setFocusInScope(state->getFocusScope(q), q);
-        }
-    }
-
-    dirty(Canvas);
-
-    itemChange(QSGItem::ItemSceneChange, c);
-}
-
-/*!
-Returns a transform that maps points from canvas space into item space.
-*/
-QTransform QSGItemPrivate::canvasToItemTransform() const
-{
-    // XXX todo - optimize
-    return itemToCanvasTransform().inverted();
-}
-
-/*!
-Returns a transform that maps points from item space into canvas space.
-*/
-QTransform QSGItemPrivate::itemToCanvasTransform() const
-{
-    // XXX todo
-    QTransform rv = parentItem?QSGItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
-    itemToParentTransform(rv);
-    return rv;
-}
-
-/*!
-Motifies \a t with this items local transform relative to its parent.
-*/
-void QSGItemPrivate::itemToParentTransform(QTransform &t) const
-{
-    if (x || y)
-        t.translate(x, y);
-
-    if (!transforms.isEmpty()) {
-        QMatrix4x4 m(t);
-        for (int ii = transforms.count() - 1; ii >= 0; --ii)
-            transforms.at(ii)->applyTo(&m);
-        t = m.toTransform();
-    }
-
-    if (scale != 1. || rotation != 0.) {
-        QPointF tp = computeTransformOrigin();
-        t.translate(tp.x(), tp.y());
-        t.scale(scale, scale);
-        t.rotate(rotation);
-        t.translate(-tp.x(), -tp.y());
-    }
-}
-
-
-/*!
-    \qmlproperty real QtQuick2::Item::childrenRect.x
-    \qmlproperty real QtQuick2::Item::childrenRect.y
-    \qmlproperty real QtQuick2::Item::childrenRect.width
-    \qmlproperty real QtQuick2::Item::childrenRect.height
-
-    The childrenRect properties allow an item access to the geometry of its
-    children. This property is useful if you have an item that needs to be
-    sized to fit its children.
-*/
-
-
-/*!
-    \qmlproperty list<Item> QtQuick2::Item::children
-    \qmlproperty list<Object> QtQuick2::Item::resources
-
-    The children property contains the list of visual children of this item.
-    The resources property contains non-visual resources that you want to
-    reference by name.
-
-    Generally you can rely on Item's default property to handle all this for
-    you, but it can come in handy in some cases.
-
-    \qml
-    Item {
-        children: [
-            Text {},
-            Rectangle {}
-        ]
-        resources: [
-            Component {
-                id: myComponent
-                Text {}
-            }
-        ]
-    }
-    \endqml
-*/
-
-/*!
-    Returns true if construction of the QML component is complete; otherwise
-    returns false.
-
-    It is often desirable to delay some processing until the component is
-    completed.
-
-    \sa componentComplete()
-*/
-bool QSGItem::isComponentComplete() const
-{
-    Q_D(const QSGItem);
-    return d->componentComplete;
-}
-
-QSGItemPrivate::QSGItemPrivate()
-: _anchors(0), _contents(0), baselineOffset(0), _anchorLines(0), _stateGroup(0), origin(QSGItem::Center),
-
-  flags(0), widthValid(false), heightValid(false), componentComplete(true),
-  keepMouse(false), hoverEnabled(false), smooth(false), focus(false), activeFocus(false), notifiedFocus(false),
-  notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
-  effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
-  inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
-  inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
-
-  canvas(0), parentItem(0),
-
-  subFocusItem(0),
-
-  x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
-  z(0), scale(1), rotation(0), opacity(1),
-
-  attachedLayoutDirection(0), acceptedMouseButtons(0),
-  imHints(Qt::ImhMultiLine),
-
-  keyHandler(0),
-
-  dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
-
-  itemNodeInstance(0), opacityNode(0), clipNode(0), rootNode(0), groupNode(0), paintNode(0)
-  , beforePaintNode(0), effectRefCount(0), hideRefCount(0)
-{
-}
-
-void QSGItemPrivate::init(QSGItem *parent)
-{
-#ifndef QT_NO_DEBUG
-    ++qt_item_count;
-    static bool atexit_registered = false;
-    if (!atexit_registered) {
-        atexit(qt_print_item_count);
-        atexit_registered = true;
-    }
-#endif
-
-    Q_Q(QSGItem);
-    baselineOffset.invalidate();
-
-    if (parent) {
-        q->setParentItem(parent);
-        QSGItemPrivate *parentPrivate = QSGItemPrivate::get(parent);
-        setImplicitLayoutMirror(parentPrivate->inheritedLayoutMirror, parentPrivate->inheritMirrorFromParent);
-    }
-}
-
-void QSGItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
-{
-    if (!o)
-        return;
-
-    QSGItem *that = static_cast<QSGItem *>(prop->object);
-
-    // This test is measurably (albeit only slightly) faster than qobject_cast<>()
-    const QMetaObject *mo = o->metaObject();
-    while (mo && mo != &QSGItem::staticMetaObject) {
-        mo = mo->d.superdata;
-    }
-
-    if (mo) {
-        QSGItem *item = static_cast<QSGItem *>(o);
-        item->setParentItem(that);
-    } else {
-        if (o->inherits("QGraphicsItem"))
-            qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
-
-        // XXX todo - do we really want this behavior?
-        o->setParent(that);
-    }
-}
-
-/*!
-    \qmlproperty list<Object> QtQuick2::Item::data
-    \default
-
-    The data property allows you to freely mix visual children and resources
-    in an item.  If you assign a visual item to the data list it becomes
-    a child and if you assign any other object type, it is added as a resource.
-
-    So you can write:
-    \qml
-    Item {
-        Text {}
-        Rectangle {}
-        Timer {}
-    }
-    \endqml
-
-    instead of:
-    \qml
-    Item {
-        children: [
-            Text {},
-            Rectangle {}
-        ]
-        resources: [
-            Timer {}
-        ]
-    }
-    \endqml
-
-    data is a behind-the-scenes property: you should never need to explicitly
-    specify it.
- */
-
-int QSGItemPrivate::data_count(QDeclarativeListProperty<QObject> *prop)
-{
-    Q_UNUSED(prop);
-    // XXX todo
-    return 0;
-}
-
-QObject *QSGItemPrivate::data_at(QDeclarativeListProperty<QObject> *prop, int i)
-{
-    Q_UNUSED(prop);
-    Q_UNUSED(i);
-    // XXX todo
-    return 0;
-}
-
-void QSGItemPrivate::data_clear(QDeclarativeListProperty<QObject> *prop)
-{
-    Q_UNUSED(prop);
-    // XXX todo
-}
-
-QObject *QSGItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index)
-{
-    const QObjectList children = prop->object->children();
-    if (index < children.count())
-        return children.at(index);
-    else
-        return 0;
-}
-
-void QSGItemPrivate::resources_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
-{
-    // XXX todo - do we really want this behavior?
-    o->setParent(prop->object);
-}
-
-int QSGItemPrivate::resources_count(QDeclarativeListProperty<QObject> *prop)
-{
-    return prop->object->children().count();
-}
-
-void QSGItemPrivate::resources_clear(QDeclarativeListProperty<QObject> *prop)
-{
-    // XXX todo - do we really want this behavior?
-    const QObjectList children = prop->object->children();
-    for (int index = 0; index < children.count(); index++)
-        children.at(index)->setParent(0);
-}
-
-QSGItem *QSGItemPrivate::children_at(QDeclarativeListProperty<QSGItem> *prop, int index)
-{
-    QSGItemPrivate *p = QSGItemPrivate::get(static_cast<QSGItem *>(prop->object));
-    if (index >= p->childItems.count() || index < 0)
-        return 0;
-    else
-        return p->childItems.at(index);
-}
-
-void QSGItemPrivate::children_append(QDeclarativeListProperty<QSGItem> *prop, QSGItem *o)
-{
-    if (!o)
-        return;
-
-    QSGItem *that = static_cast<QSGItem *>(prop->object);
-    if (o->parentItem() == that)
-        o->setParentItem(0);
-
-    o->setParentItem(that);
-}
-
-int QSGItemPrivate::children_count(QDeclarativeListProperty<QSGItem> *prop)
-{
-    QSGItemPrivate *p = QSGItemPrivate::get(static_cast<QSGItem *>(prop->object));
-    return p->childItems.count();
-}
-
-void QSGItemPrivate::children_clear(QDeclarativeListProperty<QSGItem> *prop)
-{
-    QSGItem *that = static_cast<QSGItem *>(prop->object);
-    QSGItemPrivate *p = QSGItemPrivate::get(that);
-    while (!p->childItems.isEmpty())
-        p->childItems.at(0)->setParentItem(0);
-}
-
-int QSGItemPrivate::transform_count(QDeclarativeListProperty<QSGTransform> *prop)
-{
-    QSGItem *that = static_cast<QSGItem *>(prop->object);
-    return QSGItemPrivate::get(that)->transforms.count();
-}
-
-void QSGTransform::appendToItem(QSGItem *item)
-{
-    Q_D(QSGTransform);
-    if (!item)
-        return;
-
-    QSGItemPrivate *p = QSGItemPrivate::get(item);
-
-    if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
-        p->transforms.removeOne(this);
-        p->transforms.append(this);
-    } else {
-        p->transforms.append(this);
-        d->items.append(item);
-    }
-
-    p->dirty(QSGItemPrivate::Transform);
-}
-
-void QSGTransform::prependToItem(QSGItem *item)
-{
-    Q_D(QSGTransform);
-    if (!item)
-        return;
-
-    QSGItemPrivate *p = QSGItemPrivate::get(item);
-
-    if (!d->items.isEmpty() && !p->transforms.isEmpty() && p->transforms.contains(this)) {
-        p->transforms.removeOne(this);
-        p->transforms.prepend(this);
-    } else {
-        p->transforms.prepend(this);
-        d->items.append(item);
-    }
-
-    p->dirty(QSGItemPrivate::Transform);
-}
-
-void QSGItemPrivate::transform_append(QDeclarativeListProperty<QSGTransform> *prop, QSGTransform *transform)
-{
-    if (!transform)
-        return;
-
-    QSGItem *that = static_cast<QSGItem *>(prop->object);
-    transform->appendToItem(that);
-}
-
-QSGTransform *QSGItemPrivate::transform_at(QDeclarativeListProperty<QSGTransform> *prop, int idx)
-{
-    QSGItem *that = static_cast<QSGItem *>(prop->object);
-    QSGItemPrivate *p = QSGItemPrivate::get(that);
-
-    if (idx < 0 || idx >= p->transforms.count())
-        return 0;
-    else
-        return p->transforms.at(idx);
-}
-
-void QSGItemPrivate::transform_clear(QDeclarativeListProperty<QSGTransform> *prop)
-{
-    QSGItem *that = static_cast<QSGItem *>(prop->object);
-    QSGItemPrivate *p = QSGItemPrivate::get(that);
-
-    for (int ii = 0; ii < p->transforms.count(); ++ii) {
-        QSGTransform *t = p->transforms.at(ii);
-        QSGTransformPrivate *tp = QSGTransformPrivate::get(t);
-        tp->items.removeOne(that);
-    }
-
-    p->transforms.clear();
-
-    p->dirty(QSGItemPrivate::Transform);
-}
-
-/*!
-    \property QSGItem::childrenRect
-    \brief The geometry of an item's children.
-
-    This property holds the (collective) position and size of the item's children.
-*/
-
-/*!
-  \qmlproperty real QtQuick2::Item::x
-  \qmlproperty real QtQuick2::Item::y
-  \qmlproperty real QtQuick2::Item::width
-  \qmlproperty real QtQuick2::Item::height
-
-  Defines the item's position and size relative to its parent.
-
-  \qml
-  Item { x: 100; y: 100; width: 100; height: 100 }
-  \endqml
- */
-
-/*!
-  \qmlproperty real QtQuick2::Item::z
-
-  Sets the stacking order of sibling items.  By default the stacking order is 0.
-
-  Items with a higher stacking value are drawn on top of siblings with a
-  lower stacking order.  Items with the same stacking value are drawn
-  bottom up in the order they appear.  Items with a negative stacking
-  value are drawn under their parent's content.
-
-  The following example shows the various effects of stacking order.
-
-  \table
-  \row
-  \o \image declarative-item_stacking1.png
-  \o Same \c z - later children above earlier children:
-  \qml
-  Item {
-      Rectangle {
-          color: "red"
-          width: 100; height: 100
-      }
-      Rectangle {
-          color: "blue"
-          x: 50; y: 50; width: 100; height: 100
-      }
-  }
-  \endqml
-  \row
-  \o \image declarative-item_stacking2.png
-  \o Higher \c z on top:
-  \qml
-  Item {
-      Rectangle {
-          z: 1
-          color: "red"
-          width: 100; height: 100
-      }
-      Rectangle {
-          color: "blue"
-          x: 50; y: 50; width: 100; height: 100
-      }
-  }
-  \endqml
-  \row
-  \o \image declarative-item_stacking3.png
-  \o Same \c z - children above parents:
-  \qml
-  Item {
-      Rectangle {
-          color: "red"
-          width: 100; height: 100
-          Rectangle {
-              color: "blue"
-              x: 50; y: 50; width: 100; height: 100
-          }
-      }
-  }
-  \endqml
-  \row
-  \o \image declarative-item_stacking4.png
-  \o Lower \c z below:
-  \qml
-  Item {
-      Rectangle {
-          color: "red"
-          width: 100; height: 100
-          Rectangle {
-              z: -1
-              color: "blue"
-              x: 50; y: 50; width: 100; height: 100
-          }
-      }
-  }
-  \endqml
-  \endtable
- */
-
-/*!
-    \qmlproperty bool QtQuick2::Item::visible
-
-    This property holds whether the item is visible. By default this is true.
-
-    Setting this property directly affects the \c visible value of child
-    items. When set to \c false, the \c visible values of all child items also
-    become \c false. When set to \c true, the \c visible values of child items
-    are returned to \c true, unless they have explicitly been set to \c false.
-
-    (Because of this flow-on behavior, using the \c visible property may not
-    have the intended effect if a property binding should only respond to
-    explicit property changes. In such cases it may be better to use the
-    \l opacity property instead.)
-
-    Setting this property to \c false automatically causes \l focus to be set
-    to \c false, and this item will longer receive mouse and keyboard events.
-    (In contrast, setting the \l opacity to 0 does not affect the \l focus
-    property and the receiving of key events.)
-
-    \note This property's value is only affected by changes to this property or
-    the parent's \c visible property. It does not change, for example, if this
-    item moves off-screen, or if the \l opacity changes to 0.
-*/
-
-
-/*!
-  \qmlproperty AnchorLine QtQuick2::Item::anchors.top
-  \qmlproperty AnchorLine QtQuick2::Item::anchors.bottom
-  \qmlproperty AnchorLine QtQuick2::Item::anchors.left
-  \qmlproperty AnchorLine QtQuick2::Item::anchors.right
-  \qmlproperty AnchorLine QtQuick2::Item::anchors.horizontalCenter
-  \qmlproperty AnchorLine QtQuick2::Item::anchors.verticalCenter
-  \qmlproperty AnchorLine QtQuick2::Item::anchors.baseline
-
-  \qmlproperty Item QtQuick2::Item::anchors.fill
-  \qmlproperty Item QtQuick2::Item::anchors.centerIn
-
-  \qmlproperty real QtQuick2::Item::anchors.margins
-  \qmlproperty real QtQuick2::Item::anchors.topMargin
-  \qmlproperty real QtQuick2::Item::anchors.bottomMargin
-  \qmlproperty real QtQuick2::Item::anchors.leftMargin
-  \qmlproperty real QtQuick2::Item::anchors.rightMargin
-  \qmlproperty real QtQuick2::Item::anchors.horizontalCenterOffset
-  \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
-  \qmlproperty real QtQuick2::Item::anchors.baselineOffset
-
-  \qmlproperty bool QtQuick2::Item::anchors.mirrored
-
-  Anchors provide a way to position an item by specifying its
-  relationship with other items.
-
-  Margins apply to top, bottom, left, right, and fill anchors.
-  The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
-  Note that margins are anchor-specific and are not applied if an item does not
-  use anchors.
-
-  Offsets apply for horizontal center, vertical center, and baseline anchors.
-
-  \table
-  \row
-  \o \image declarative-anchors_example.png
-  \o Text anchored to Image, horizontally centered and vertically below, with a margin.
-  \qml
-  Item {
-      Image {
-          id: pic
-          // ...
-      }
-      Text {
-          id: label
-          anchors.horizontalCenter: pic.horizontalCenter
-          anchors.top: pic.bottom
-          anchors.topMargin: 5
-          // ...
-      }
-  }
-  \endqml
-  \row
-  \o \image declarative-anchors_example2.png
-  \o
-  Left of Text anchored to right of Image, with a margin. The y
-  property of both defaults to 0.
-
-  \qml
-  Item {
-      Image {
-          id: pic
-          // ...
-      }
-      Text {
-          id: label
-          anchors.left: pic.right
-          anchors.leftMargin: 5
-          // ...
-      }
-  }
-  \endqml
-  \endtable
-
-  \c anchors.fill provides a convenient way for one item to have the
-  same geometry as another item, and is equivalent to connecting all
-  four directional anchors.
-
-  To clear an anchor value, set it to \c undefined.
-
-  \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
-
-  \note You can only anchor an item to siblings or a parent.
-
-  For more information see \l {anchor-layout}{Anchor Layouts}.
-*/
-
-/*!
-  \property QSGItem::baselineOffset
-  \brief The position of the item's baseline in local coordinates.
-
-  The baseline of a \l Text item is the imaginary line on which the text
-  sits. Controls containing text usually set their baseline to the
-  baseline of their text.
-
-  For non-text items, a default baseline offset of 0 is used.
-*/
-QSGAnchors *QSGItemPrivate::anchors() const
-{
-    if (!_anchors) {
-        Q_Q(const QSGItem);
-        _anchors = new QSGAnchors(const_cast<QSGItem *>(q));
-        if (!componentComplete)
-            _anchors->classBegin();
-    }
-    return _anchors;
-}
-
-QSGItemPrivate::AnchorLines *QSGItemPrivate::anchorLines() const
-{
-    Q_Q(const QSGItem);
-    if (!_anchorLines) _anchorLines =
-        new AnchorLines(const_cast<QSGItem *>(q));
-    return _anchorLines;
-}
-
-void QSGItemPrivate::siblingOrderChanged()
-{
-    Q_Q(QSGItem);
-    for (int ii = 0; ii < changeListeners.count(); ++ii) {
-        const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
-        if (change.types & QSGItemPrivate::SiblingOrder) {
-            change.listener->itemSiblingOrderChanged(q);
-        }
-    }
-}
-
-QDeclarativeListProperty<QObject> QSGItemPrivate::data()
-{
-    return QDeclarativeListProperty<QObject>(q_func(), 0, QSGItemPrivate::data_append,
-                                             QSGItemPrivate::data_count,
-                                             QSGItemPrivate::data_at,
-                                             QSGItemPrivate::data_clear);
-}
-
-QRectF QSGItem::childrenRect()
-{
-    Q_D(QSGItem);
-    if (!d->_contents) {
-        d->_contents = new QSGContents(this);
-        if (d->componentComplete)
-            d->_contents->complete();
-    }
-    return d->_contents->rectF();
-}
-
-QList<QSGItem *> QSGItem::childItems() const
-{
-    Q_D(const QSGItem);
-    return d->childItems;
-}
-
-bool QSGItem::clip() const
-{
-    return flags() & ItemClipsChildrenToShape;
-}
-
-void QSGItem::setClip(bool c)
-{
-    if (clip() == c)
-        return;
-
-    setFlag(ItemClipsChildrenToShape, c);
-
-    emit clipChanged(c);
-}
-
-
-/*!
-  This function is called to handle this item's changes in
-  geometry from \a oldGeometry to \a newGeometry. If the two
-  geometries are the same, it doesn't do anything.
- */
-void QSGItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
-{
-    Q_D(QSGItem);
-
-    if (d->_anchors)
-        QSGAnchorsPrivate::get(d->_anchors)->updateMe();
-
-    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);
-    }
-
-    if (newGeometry.x() != oldGeometry.x())
-        emit xChanged();
-    if (newGeometry.y() != oldGeometry.y())
-        emit yChanged();
-    if (newGeometry.width() != oldGeometry.width())
-        emit widthChanged();
-    if (newGeometry.height() != oldGeometry.height())
-        emit heightChanged();
-}
-
-/*!
-    Called by the rendering thread when it is time to sync the state of the QML objects with the
-    scene graph objects. The function should return the root of the scene graph subtree for
-    this item. \a oldNode is the node that was returned the last time the function was called.
-
-    The main thread is blocked while this function is executed so it is safe to read
-    values from the QSGItem instance and other objects in the main thread.
-
-    \warning This is the only function in which it is allowed to make use of scene graph
-    objects from the main thread. Use of scene graph objects outside this function will
-    result in race conditions and potential crashes.
- */
-
-QSGNode *QSGItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
-{
-    delete oldNode;
-    return 0;
-}
-
-QSGTransformNode *QSGItemPrivate::createTransformNode()
-{
-    return new QSGTransformNode;
-}
-
-void QSGItem::updatePolish()
-{
-}
-
-void QSGItemPrivate::removeItemChangeListener(QSGItemChangeListener *listener, ChangeTypes types)
-{
-    ChangeListener change(listener, types);
-    changeListeners.removeOne(change);
-}
-
-void QSGItem::keyPressEvent(QKeyEvent *event)
-{
-    event->ignore();
-}
-
-void QSGItem::keyReleaseEvent(QKeyEvent *event)
-{
-    event->ignore();
-}
-
-void QSGItem::inputMethodEvent(QInputMethodEvent *event)
-{
-    event->ignore();
-}
-
-void QSGItem::focusInEvent(QFocusEvent *)
-{
-}
-
-void QSGItem::focusOutEvent(QFocusEvent *)
-{
-}
-
-void QSGItem::mousePressEvent(QMouseEvent *event)
-{
-    event->ignore();
-}
-
-void QSGItem::mouseMoveEvent(QMouseEvent *event)
-{
-    event->ignore();
-}
-
-void QSGItem::mouseReleaseEvent(QMouseEvent *event)
-{
-    event->ignore();
-}
-
-void QSGItem::mouseDoubleClickEvent(QMouseEvent *event)
-{
-    mousePressEvent(event);
-}
-
-void QSGItem::mouseUngrabEvent()
-{
-    // XXX todo
-}
-
-void QSGItem::wheelEvent(QWheelEvent *event)
-{
-    event->ignore();
-}
-
-void QSGItem::touchEvent(QTouchEvent *event)
-{
-    event->ignore();
-}
-
-void QSGItem::hoverEnterEvent(QHoverEvent *event)
-{
-    Q_UNUSED(event);
-}
-
-void QSGItem::hoverMoveEvent(QHoverEvent *event)
-{
-    Q_UNUSED(event);
-}
-
-void QSGItem::hoverLeaveEvent(QHoverEvent *event)
-{
-    Q_UNUSED(event);
-}
-
-void QSGItem::dragEnterEvent(QDragEnterEvent *event)
-{
-    Q_UNUSED(event);
-}
-
-void QSGItem::dragMoveEvent(QDragMoveEvent *event)
-{
-
-    Q_UNUSED(event);
-}
-
-void QSGItem::dragLeaveEvent(QDragLeaveEvent *event)
-{
-
-    Q_UNUSED(event);
-}
-
-void QSGItem::dropEvent(QDropEvent *event)
-{
-    Q_UNUSED(event);
-}
-
-bool QSGItem::childMouseEventFilter(QSGItem *, QEvent *)
-{
-    return false;
-}
-
-void QSGItem::windowDeactivateEvent()
-{
-    foreach (QSGItem* item, childItems()) {
-        item->windowDeactivateEvent();
-    }
-}
-
-Qt::InputMethodHints QSGItem::inputMethodHints() const
-{
-    Q_D(const QSGItem);
-    return d->imHints;
-}
-
-void QSGItem::setInputMethodHints(Qt::InputMethodHints hints)
-{
-    Q_D(QSGItem);
-    d->imHints = hints;
-
-    if (!d->canvas || d->canvas->activeFocusItem() != this)
-        return;
-
-    QInputPanel *p = qApp->inputPanel();
-    if (p->inputItem() == this)
-        qApp->inputPanel()->update(Qt::ImHints);
-}
-
-void QSGItem::updateMicroFocus()
-{
-    QInputPanel *p = qApp->inputPanel();
-    if (p->inputItem() == this)
-        qApp->inputPanel()->update(Qt::ImQueryInput);
-}
-
-QVariant QSGItem::inputMethodQuery(Qt::InputMethodQuery query) const
-{
-    Q_D(const QSGItem);
-    QVariant v;
-
-    switch (query) {
-    case Qt::ImEnabled:
-        v = (bool)(flags() & ItemAcceptsInputMethod);
-        break;
-    case Qt::ImHints:
-        v = (int)inputMethodHints();
-        break;
-    case Qt::ImCursorRectangle:
-    case Qt::ImFont:
-    case Qt::ImCursorPosition:
-    case Qt::ImSurroundingText:
-    case Qt::ImCurrentSelection:
-    case Qt::ImMaximumTextLength:
-    case Qt::ImAnchorPosition:
-    case Qt::ImPreferredLanguage:
-        if (d->keyHandler)
-            v = d->keyHandler->inputMethodQuery(query);
-    default:
-        break;
-    }
-
-    return v;
-}
-
-QSGAnchorLine QSGItemPrivate::left() const
-{
-    return anchorLines()->left;
-}
-
-QSGAnchorLine QSGItemPrivate::right() const
-{
-    return anchorLines()->right;
-}
-
-QSGAnchorLine QSGItemPrivate::horizontalCenter() const
-{
-    return anchorLines()->hCenter;
-}
-
-QSGAnchorLine QSGItemPrivate::top() const
-{
-    return anchorLines()->top;
-}
-
-QSGAnchorLine QSGItemPrivate::bottom() const
-{
-    return anchorLines()->bottom;
-}
-
-QSGAnchorLine QSGItemPrivate::verticalCenter() const
-{
-    return anchorLines()->vCenter;
-}
-
-QSGAnchorLine QSGItemPrivate::baseline() const
-{
-    return anchorLines()->baseline;
-}
-
-qreal QSGItem::baselineOffset() const
-{
-    Q_D(const QSGItem);
-    if (!d->baselineOffset.isValid()) {
-        return 0.0;
-    } else
-        return d->baselineOffset;
-}
-
-void QSGItem::setBaselineOffset(qreal offset)
-{
-    Q_D(QSGItem);
-    if (offset == d->baselineOffset)
-        return;
-
-    d->baselineOffset = offset;
-
-    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();
-            if (anchor)
-                anchor->updateVerticalAnchors();
-        }
-    }
-    emit baselineOffsetChanged(offset);
-}
-
-void QSGItem::update()
-{
-    Q_D(QSGItem);
-    Q_ASSERT(flags() & ItemHasContents);
-    d->dirty(QSGItemPrivate::Content);
-}
-
-void QSGItem::polish()
-{
-    Q_D(QSGItem);
-    if (!d->polishScheduled) {
-        d->polishScheduled = true;
-        if (d->canvas) {
-            QSGCanvasPrivate *p = QSGCanvasPrivate::get(d->canvas);
-            bool maybeupdate = p->itemsToPolish.isEmpty();
-            p->itemsToPolish.insert(this);
-            if (maybeupdate) d->canvas->maybeUpdate();
-        }
-    }
-}
-
-void QSGItem::mapFromItem(QDeclarativeV8Function *args) const
-{
-    if (args->Length() != 0) {
-        v8::Local<v8::Value> item = (*args)[0];
-        QV8Engine *engine = args->engine();
-
-        QSGItem *itemObj = 0;
-        if (!item->IsNull())
-            itemObj = qobject_cast<QSGItem*>(engine->toQObject(item));
-
-        if (!itemObj && !item->IsNull()) {
-            qmlInfo(this) << "mapFromItem() given argument \"" << engine->toString(item->ToString())
-                          << "\" which is neither null nor an Item";
-            return;
-        }
-
-        v8::Local<v8::Object> rv = v8::Object::New();
-        args->returnValue(rv);
-
-        qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
-        qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
-
-        QPointF p = mapFromItem(itemObj, QPointF(x, y));
-
-        rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
-        rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
-    }
-}
-
-QTransform QSGItem::itemTransform(QSGItem *other, bool *ok) const
-{
-    Q_D(const QSGItem);
-
-    // XXX todo - we need to be able to handle common parents better and detect
-    // invalid cases
-    if (ok) *ok = true;
-
-    QTransform t = d->itemToCanvasTransform();
-    if (other) t *= QSGItemPrivate::get(other)->canvasToItemTransform();
-
-    return t;
-}
-
-void QSGItem::mapToItem(QDeclarativeV8Function *args) const
-{
-    if (args->Length() != 0) {
-        v8::Local<v8::Value> item = (*args)[0];
-        QV8Engine *engine = args->engine();
-
-        QSGItem *itemObj = 0;
-        if (!item->IsNull())
-            itemObj = qobject_cast<QSGItem*>(engine->toQObject(item));
-
-        if (!itemObj && !item->IsNull()) {
-            qmlInfo(this) << "mapToItem() given argument \"" << engine->toString(item->ToString())
-                          << "\" which is neither null nor an Item";
-            return;
-        }
-
-        v8::Local<v8::Object> rv = v8::Object::New();
-        args->returnValue(rv);
-
-        qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
-        qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
-
-        QPointF p = mapToItem(itemObj, QPointF(x, y));
-
-        rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
-        rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
-    }
-}
-
-void QSGItem::forceActiveFocus()
-{
-    setFocus(true);
-    QSGItem *parent = parentItem();
-    while (parent) {
-        if (parent->flags() & QSGItem::ItemIsFocusScope) {
-            parent->setFocus(true);
-        }
-        parent = parent->parentItem();
-    }
-}
-
-QSGItem *QSGItem::childAt(qreal x, qreal y) const
-{
-    // XXX todo - should this include transform etc.?
-    const QList<QSGItem *> children = childItems();
-    for (int i = children.count()-1; i >= 0; --i) {
-        QSGItem *child = children.at(i);
-        if (child->isVisible() && child->x() <= x
-                && child->x() + child->width() >= x
-                && child->y() <= y
-                && child->y() + child->height() >= y)
-            return child;
-    }
-    return 0;
-}
-
-QDeclarativeListProperty<QObject> QSGItemPrivate::resources()
-{
-    return QDeclarativeListProperty<QObject>(q_func(), 0, QSGItemPrivate::resources_append,
-                                             QSGItemPrivate::resources_count,
-                                             QSGItemPrivate::resources_at,
-                                             QSGItemPrivate::resources_clear);
-}
-
-QDeclarativeListProperty<QSGItem> QSGItemPrivate::children()
-{
-    return QDeclarativeListProperty<QSGItem>(q_func(), 0, QSGItemPrivate::children_append,
-                                             QSGItemPrivate::children_count,
-                                             QSGItemPrivate::children_at,
-                                             QSGItemPrivate::children_clear);
-
-}
-
-QDeclarativeListProperty<QDeclarativeState> QSGItemPrivate::states()
-{
-    return _states()->statesProperty();
-}
-
-QDeclarativeListProperty<QDeclarativeTransition> QSGItemPrivate::transitions()
-{
-    return _states()->transitionsProperty();
-}
-
-QString QSGItemPrivate::state() const
-{
-    if (!_stateGroup)
-        return QString();
-    else
-        return _stateGroup->state();
-}
-
-void QSGItemPrivate::setState(const QString &state)
-{
-    _states()->setState(state);
-}
-
-QString QSGItem::state() const
-{
-    Q_D(const QSGItem);
-    return d->state();
-}
-
-void QSGItem::setState(const QString &state)
-{
-    Q_D(QSGItem);
-    d->setState(state);
-}
-
-QDeclarativeListProperty<QSGTransform> QSGItem::transform()
-{
-    Q_D(QSGItem);
-    return QDeclarativeListProperty<QSGTransform>(this, 0, d->transform_append, d->transform_count,
-                                                  d->transform_at, d->transform_clear);
-}
-
-void QSGItem::classBegin()
-{
-    Q_D(QSGItem);
-    d->componentComplete = false;
-    if (d->_stateGroup)
-        d->_stateGroup->classBegin();
-    if (d->_anchors)
-        d->_anchors->classBegin();
-}
-
-void QSGItem::componentComplete()
-{
-    Q_D(QSGItem);
-    d->componentComplete = true;
-    if (d->_stateGroup)
-        d->_stateGroup->componentComplete();
-    if (d->_anchors) {
-        d->_anchors->componentComplete();
-        QSGAnchorsPrivate::get(d->_anchors)->updateOnComplete();
-    }
-    if (d->keyHandler)
-        d->keyHandler->componentComplete();
-    if (d->_contents)
-        d->_contents->complete();
-}
-
-QDeclarativeStateGroup *QSGItemPrivate::_states()
-{
-    Q_Q(QSGItem);
-    if (!_stateGroup) {
-        _stateGroup = new QDeclarativeStateGroup;
-        if (!componentComplete)
-            _stateGroup->classBegin();
-        FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
-                     q, SIGNAL(stateChanged(QString)))
-    }
-
-    return _stateGroup;
-}
-
-QSGItemPrivate::AnchorLines::AnchorLines(QSGItem *q)
-{
-    left.item = q;
-    left.anchorLine = QSGAnchorLine::Left;
-    right.item = q;
-    right.anchorLine = QSGAnchorLine::Right;
-    hCenter.item = q;
-    hCenter.anchorLine = QSGAnchorLine::HCenter;
-    top.item = q;
-    top.anchorLine = QSGAnchorLine::Top;
-    bottom.item = q;
-    bottom.anchorLine = QSGAnchorLine::Bottom;
-    vCenter.item = q;
-    vCenter.anchorLine = QSGAnchorLine::VCenter;
-    baseline.item = q;
-    baseline.anchorLine = QSGAnchorLine::Baseline;
-}
-
-QPointF QSGItemPrivate::computeTransformOrigin() const
-{
-    switch (origin) {
-    default:
-    case QSGItem::TopLeft:
-        return QPointF(0, 0);
-    case QSGItem::Top:
-        return QPointF(width / 2., 0);
-    case QSGItem::TopRight:
-        return QPointF(width, 0);
-    case QSGItem::Left:
-        return QPointF(0, height / 2.);
-    case QSGItem::Center:
-        return QPointF(width / 2., height / 2.);
-    case QSGItem::Right:
-        return QPointF(width, height / 2.);
-    case QSGItem::BottomLeft:
-        return QPointF(0, height);
-    case QSGItem::Bottom:
-        return QPointF(width / 2., height);
-    case QSGItem::BottomRight:
-        return QPointF(width, height);
-    }
-}
-
-void QSGItemPrivate::transformChanged()
-{
-}
-
-void QSGItemPrivate::deliverKeyEvent(QKeyEvent *e)
-{
-    Q_Q(QSGItem);
-
-    Q_ASSERT(e->isAccepted());
-    if (keyHandler) {
-        if (e->type() == QEvent::KeyPress)
-            keyHandler->keyPressed(e, false);
-        else
-            keyHandler->keyReleased(e, false);
-
-        if (e->isAccepted())
-            return;
-        else
-            e->accept();
-    }
-
-    if (e->type() == QEvent::KeyPress)
-        q->keyPressEvent(e);
-    else
-        q->keyReleaseEvent(e);
-
-    if (e->isAccepted())
-        return;
-
-    if (keyHandler) {
-        e->accept();
-
-        if (e->type() == QEvent::KeyPress)
-            keyHandler->keyPressed(e, true);
-        else
-            keyHandler->keyReleased(e, true);
-    }
-}
-
-void QSGItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
-{
-    Q_Q(QSGItem);
-
-    Q_ASSERT(e->isAccepted());
-    if (keyHandler) {
-        keyHandler->inputMethodEvent(e, false);
-
-        if (e->isAccepted())
-            return;
-        else
-            e->accept();
-    }
-
-    q->inputMethodEvent(e);
-
-    if (e->isAccepted())
-        return;
-
-    if (keyHandler) {
-        e->accept();
-
-        keyHandler->inputMethodEvent(e, true);
-    }
-}
-
-void QSGItemPrivate::deliverFocusEvent(QFocusEvent *e)
-{
-    Q_Q(QSGItem);
-
-    if (e->type() == QEvent::FocusIn) {
-        q->focusInEvent(e);
-    } else {
-        q->focusOutEvent(e);
-    }
-}
-
-void QSGItemPrivate::deliverMouseEvent(QMouseEvent *e)
-{
-    Q_Q(QSGItem);
-
-    Q_ASSERT(e->isAccepted());
-
-    switch (e->type()) {
-    default:
-        Q_ASSERT(!"Unknown event type");
-    case QEvent::MouseMove:
-        q->mouseMoveEvent(e);
-        break;
-    case QEvent::MouseButtonPress:
-        q->mousePressEvent(e);
-        break;
-    case QEvent::MouseButtonRelease:
-        q->mouseReleaseEvent(e);
-        break;
-    case QEvent::MouseButtonDblClick:
-        q->mouseDoubleClickEvent(e);
-        break;
-    }
-}
-
-void QSGItemPrivate::deliverWheelEvent(QWheelEvent *e)
-{
-    Q_Q(QSGItem);
-    q->wheelEvent(e);
-}
-
-void QSGItemPrivate::deliverTouchEvent(QTouchEvent *e)
-{
-    Q_Q(QSGItem);
-    q->touchEvent(e);
-}
-
-void QSGItemPrivate::deliverHoverEvent(QHoverEvent *e)
-{
-    Q_Q(QSGItem);
-    switch (e->type()) {
-    default:
-        Q_ASSERT(!"Unknown event type");
-    case QEvent::HoverEnter:
-        q->hoverEnterEvent(e);
-        break;
-    case QEvent::HoverLeave:
-        q->hoverLeaveEvent(e);
-        break;
-    case QEvent::HoverMove:
-        q->hoverMoveEvent(e);
-        break;
-    }
-}
-
-void QSGItemPrivate::deliverDragEvent(QEvent *e)
-{
-    Q_Q(QSGItem);
-    switch (e->type()) {
-    default:
-        Q_ASSERT(!"Unknown event type");
-    case QEvent::DragEnter:
-        q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
-        break;
-    case QEvent::DragLeave:
-        q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
-        break;
-    case QEvent::DragMove:
-        q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
-        break;
-    case QEvent::Drop:
-        q->dropEvent(static_cast<QDropEvent *>(e));
-        break;
-    }
-}
-
-void QSGItem::itemChange(ItemChange change, const ItemChangeData &value)
-{
-    Q_UNUSED(change);
-    Q_UNUSED(value);
-}
-
-/*! \internal */
-// XXX todo - do we want/need this anymore?
-// Note that it's now used for varying clip rect
-QRectF QSGItem::boundingRect() const
-{
-    Q_D(const QSGItem);
-    return QRectF(0, 0, d->width, d->height);
-}
-
-QSGItem::TransformOrigin QSGItem::transformOrigin() const
-{
-    Q_D(const QSGItem);
-    return d->origin;
-}
-
-void QSGItem::setTransformOrigin(TransformOrigin origin)
-{
-    Q_D(QSGItem);
-    if (origin == d->origin)
-        return;
-
-    d->origin = origin;
-    d->dirty(QSGItemPrivate::TransformOrigin);
-
-    emit transformOriginChanged(d->origin);
-}
-
-QPointF QSGItem::transformOriginPoint() const
-{
-    Q_D(const QSGItem);
-    if (!d->transformOriginPoint.isNull())
-        return d->transformOriginPoint;
-    return d->computeTransformOrigin();
-}
-
-void QSGItem::setTransformOriginPoint(const QPointF &point)
-{
-    Q_D(QSGItem);
-    if (d->transformOriginPoint == point)
-        return;
-
-    d->transformOriginPoint = point;
-    d->dirty(QSGItemPrivate::TransformOrigin);
-}
-
-qreal QSGItem::z() const
-{
-    Q_D(const QSGItem);
-    return d->z;
-}
-
-void QSGItem::setZ(qreal v)
-{
-    Q_D(QSGItem);
-    if (d->z == v)
-        return;
-
-    d->z = v;
-
-    d->dirty(QSGItemPrivate::ZValue);
-    if (d->parentItem)
-        QSGItemPrivate::get(d->parentItem)->dirty(QSGItemPrivate::ChildrenStackingChanged);
-
-    emit zChanged();
-}
-
-
-/*!
-  \qmlproperty real QtQuick2::Item::rotation
-  This property holds the rotation of the item in degrees clockwise.
-
-  This specifies how many degrees to rotate the item around its transformOrigin.
-  The default rotation is 0 degrees (i.e. not rotated at all).
-
-  \table
-  \row
-  \o \image declarative-rotation.png
-  \o
-  \qml
-  Rectangle {
-      color: "blue"
-      width: 100; height: 100
-      Rectangle {
-          color: "red"
-          x: 25; y: 25; width: 50; height: 50
-          rotation: 30
-      }
-  }
-  \endqml
-  \endtable
-
-  \sa transform, Rotation
-*/
-
-/*!
-  \qmlproperty real QtQuick2::Item::scale
-  This property holds the scale of the item.
-
-  A scale of less than 1 means the item will be displayed smaller than
-  normal, and a scale of greater than 1 means the item will be
-  displayed larger than normal.  A negative scale means the item will
-  be mirrored.
-
-  By default, items are displayed at a scale of 1 (i.e. at their
-  normal size).
-
-  Scaling is from the item's transformOrigin.
-
-  \table
-  \row
-  \o \image declarative-scale.png
-  \o
-  \qml
-  Rectangle {
-      color: "blue"
-      width: 100; height: 100
-      Rectangle {
-          color: "green"
-          width: 25; height: 25
-      }
-      Rectangle {
-          color: "red"
-          x: 25; y: 25; width: 50; height: 50
-          scale: 1.4
-      }
-  }
-  \endqml
-  \endtable
-
-  \sa transform, Scale
-*/
-
-/*!
-  \qmlproperty real QtQuick2::Item::opacity
-
-  This property holds the opacity of the item.  Opacity is specified as a
-  number between 0 (fully transparent) and 1 (fully opaque).  The default is 1.
-
-  When this property is set, the specified opacity is also applied
-  individually to child items.  In almost all cases this is what you want,
-  but in some cases it may produce undesired results. For example in the
-  second set of rectangles below, the red rectangle has specified an opacity
-  of 0.5, which affects the opacity of its blue child rectangle even though
-  the child has not specified an opacity.
-
-  \table
-  \row
-  \o \image declarative-item_opacity1.png
-  \o
-  \qml
-    Item {
-        Rectangle {
-            color: "red"
-            width: 100; height: 100
-            Rectangle {
-                color: "blue"
-                x: 50; y: 50; width: 100; height: 100
-            }
-        }
-    }
-  \endqml
-  \row
-  \o \image declarative-item_opacity2.png
-  \o
-  \qml
-    Item {
-        Rectangle {
-            opacity: 0.5
-            color: "red"
-            width: 100; height: 100
-            Rectangle {
-                color: "blue"
-                x: 50; y: 50; width: 100; height: 100
-            }
-        }
-    }
-  \endqml
-  \endtable
-
-  If an item's opacity is set to 0, the item will no longer receive mouse
-  events, but will continue to receive key events and will retain the keyboard
-  \l focus if it has been set. (In contrast, setting the \l visible property
-  to \c false stops both mouse and keyboard events, and also removes focus
-  from the item.)
-*/
-
-/*!
-  Returns a value indicating whether mouse input should
-  remain with this item exclusively.
-
-  \sa setKeepMouseGrab()
- */
-
-qreal QSGItem::rotation() const
-{
-    Q_D(const QSGItem);
-    return d->rotation;
-}
-
-void QSGItem::setRotation(qreal r)
-{
-    Q_D(QSGItem);
-    if (d->rotation == r)
-        return;
-
-    d->rotation = r;
-
-    d->dirty(QSGItemPrivate::BasicTransform);
-
-    d->itemChange(ItemRotationHasChanged, r);
-
-    emit rotationChanged();
-}
-
-qreal QSGItem::scale() const
-{
-    Q_D(const QSGItem);
-    return d->scale;
-}
-
-void QSGItem::setScale(qreal s)
-{
-    Q_D(QSGItem);
-    if (d->scale == s)
-        return;
-
-    d->scale = s;
-
-    d->dirty(QSGItemPrivate::BasicTransform);
-
-    emit scaleChanged();
-}
-
-qreal QSGItem::opacity() const
-{
-    Q_D(const QSGItem);
-    return d->opacity;
-}
-
-void QSGItem::setOpacity(qreal o)
-{
-    Q_D(QSGItem);
-    if (d->opacity == o)
-        return;
-
-    d->opacity = o;
-
-    d->dirty(QSGItemPrivate::OpacityValue);
-
-    d->itemChange(ItemOpacityHasChanged, o);
-
-    emit opacityChanged();
-}
-
-bool QSGItem::isVisible() const
-{
-    Q_D(const QSGItem);
-    return d->effectiveVisible;
-}
-
-void QSGItem::setVisible(bool v)
-{
-    Q_D(QSGItem);
-    if (v == d->explicitVisible)
-        return;
-
-    d->explicitVisible = v;
-
-    d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
-}
-
-bool QSGItem::isEnabled() const
-{
-    Q_D(const QSGItem);
-    return d->effectiveEnable;
-}
-
-void QSGItem::setEnabled(bool e)
-{
-    Q_D(QSGItem);
-    if (e == d->explicitEnable)
-        return;
-
-    d->explicitEnable = e;
-
-    d->setEffectiveEnableRecur(d->calcEffectiveEnable());
-}
-
-bool QSGItemPrivate::calcEffectiveVisible() const
-{
-    // XXX todo - Should the effective visible of an element with no parent just be the current
-    // effective visible?  This would prevent pointless re-processing in the case of an element
-    // moving to/from a no-parent situation, but it is different from what graphics view does.
-    return explicitVisible && (!parentItem || QSGItemPrivate::get(parentItem)->effectiveVisible);
-}
-
-void QSGItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
-{
-    Q_Q(QSGItem);
-
-    if (newEffectiveVisible && !explicitVisible) {
-        // This item locally overrides visibility
-        return;
-    }
-
-    if (newEffectiveVisible == effectiveVisible) {
-        // No change necessary
-        return;
-    }
-
-    effectiveVisible = newEffectiveVisible;
-    dirty(Visible);
-    if (parentItem) QSGItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
-
-    if (canvas) {
-        QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(canvas);
-        if (canvasPriv->mouseGrabberItem == q)
-            q->ungrabMouse();
-    }
-
-    for (int ii = 0; ii < childItems.count(); ++ii)
-        QSGItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
-
-    for (int ii = 0; ii < changeListeners.count(); ++ii) {
-        const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
-        if (change.types & QSGItemPrivate::Visibility)
-            change.listener->itemVisibilityChanged(q);
-    }
-
-    emit q->visibleChanged();
-}
-
-bool QSGItemPrivate::calcEffectiveEnable() const
-{
-    // XXX todo - Should the effective enable of an element with no parent just be the current
-    // effective enable?  This would prevent pointless re-processing in the case of an element
-    // moving to/from a no-parent situation, but it is different from what graphics view does.
-    return explicitEnable && (!parentItem || QSGItemPrivate::get(parentItem)->effectiveEnable);
-}
-
-void QSGItemPrivate::setEffectiveEnableRecur(bool newEffectiveEnable)
-{
-    Q_Q(QSGItem);
-
-    // XXX todo - need to fixup focus
-
-    if (newEffectiveEnable && !explicitEnable) {
-        // This item locally overrides enable
-        return;
-    }
-
-    if (newEffectiveEnable == effectiveEnable) {
-        // No change necessary
-        return;
-    }
-
-    effectiveEnable = newEffectiveEnable;
-
-    if (canvas) {
-        QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(canvas);
-        if (canvasPriv->mouseGrabberItem == q)
-            q->ungrabMouse();
-    }
-
-    for (int ii = 0; ii < childItems.count(); ++ii)
-        QSGItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(newEffectiveEnable);
-
-    emit q->enabledChanged();
-}
-
-QString QSGItemPrivate::dirtyToString() const
-{
-#define DIRTY_TO_STRING(value) if (dirtyAttributes & value) { \
-    if (!rv.isEmpty()) \
-        rv.append(QLatin1String("|")); \
-    rv.append(QLatin1String(#value)); \
-}
-
-//    QString rv = QLatin1String("0x") + QString::number(dirtyAttributes, 16);
-    QString rv;
-
-    DIRTY_TO_STRING(TransformOrigin);
-    DIRTY_TO_STRING(Transform);
-    DIRTY_TO_STRING(BasicTransform);
-    DIRTY_TO_STRING(Position);
-    DIRTY_TO_STRING(Size);
-    DIRTY_TO_STRING(ZValue);
-    DIRTY_TO_STRING(Content);
-    DIRTY_TO_STRING(Smooth);
-    DIRTY_TO_STRING(OpacityValue);
-    DIRTY_TO_STRING(ChildrenChanged);
-    DIRTY_TO_STRING(ChildrenStackingChanged);
-    DIRTY_TO_STRING(ParentChanged);
-    DIRTY_TO_STRING(Clip);
-    DIRTY_TO_STRING(Canvas);
-    DIRTY_TO_STRING(EffectReference);
-    DIRTY_TO_STRING(Visible);
-    DIRTY_TO_STRING(HideReference);
-
-    return rv;
-}
-
-void QSGItemPrivate::dirty(DirtyType type)
-{
-    Q_Q(QSGItem);
-    if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
-        transformChanged();
-
-    if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
-        dirtyAttributes |= type;
-        if (canvas) {
-            addToDirtyList();
-            QSGCanvasPrivate::get(canvas)->dirtyItem(q);
-        }
-    }
-}
-
-void QSGItemPrivate::addToDirtyList()
-{
-    Q_Q(QSGItem);
-
-    Q_ASSERT(canvas);
-    if (!prevDirtyItem) {
-        Q_ASSERT(!nextDirtyItem);
-
-        QSGCanvasPrivate *p = QSGCanvasPrivate::get(canvas);
-        nextDirtyItem = p->dirtyItemList;
-        if (nextDirtyItem) QSGItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
-        prevDirtyItem = &p->dirtyItemList;
-        p->dirtyItemList = q;
-        p->dirtyItem(q);
-    }
-    Q_ASSERT(prevDirtyItem);
-}
-
-void QSGItemPrivate::removeFromDirtyList()
-{
-    if (prevDirtyItem) {
-        if (nextDirtyItem) QSGItemPrivate::get(nextDirtyItem)->prevDirtyItem = prevDirtyItem;
-        *prevDirtyItem = nextDirtyItem;
-        prevDirtyItem = 0;
-        nextDirtyItem = 0;
-    }
-    Q_ASSERT(!prevDirtyItem);
-    Q_ASSERT(!nextDirtyItem);
-}
-
-void QSGItemPrivate::refFromEffectItem(bool hide)
-{
-    ++effectRefCount;
-    if (1 == effectRefCount) {
-        dirty(EffectReference);
-        if (parentItem) QSGItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
-    }
-    if (hide) {
-        if (++hideRefCount == 1)
-            dirty(HideReference);
-    }
-}
-
-void QSGItemPrivate::derefFromEffectItem(bool unhide)
-{
-    Q_ASSERT(effectRefCount);
-    --effectRefCount;
-    if (0 == effectRefCount) {
-        dirty(EffectReference);
-        if (parentItem) QSGItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
-    }
-    if (unhide) {
-        if (--hideRefCount == 0)
-            dirty(HideReference);
-    }
-}
-
-void QSGItemPrivate::itemChange(QSGItem::ItemChange change, const QSGItem::ItemChangeData &data)
-{
-    Q_Q(QSGItem);
-    switch (change) {
-    case QSGItem::ItemChildAddedChange:
-        q->itemChange(change, data);
-        if (_contents && componentComplete)
-            _contents->childAdded(data.item);
-        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);
-            }
-        }
-        break;
-    case QSGItem::ItemChildRemovedChange:
-        q->itemChange(change, data);
-        if (_contents && componentComplete)
-            _contents->childRemoved(data.item);
-        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);
-            }
-        }
-        break;
-    case QSGItem::ItemSceneChange:
-        q->itemChange(change, data);
-        break;
-    case QSGItem::ItemVisibleHasChanged:
-        q->itemChange(change, data);
-        for (int ii = 0; ii < changeListeners.count(); ++ii) {
-            const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
-            if (change.types & QSGItemPrivate::Visibility) {
-                change.listener->itemVisibilityChanged(q);
-            }
-        }
-        break;
-    case QSGItem::ItemParentHasChanged:
-        q->itemChange(change, data);
-        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);
-            }
-        }
-        break;
-    case QSGItem::ItemOpacityHasChanged:
-        q->itemChange(change, data);
-        for (int ii = 0; ii < changeListeners.count(); ++ii) {
-            const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
-            if (change.types & QSGItemPrivate::Opacity) {
-                change.listener->itemOpacityChanged(q);
-            }
-        }
-        break;
-    case QSGItem::ItemActiveFocusHasChanged:
-        q->itemChange(change, data);
-        break;
-    case QSGItem::ItemRotationHasChanged:
-        q->itemChange(change, data);
-        for (int ii = 0; ii < changeListeners.count(); ++ii) {
-            const QSGItemPrivate::ChangeListener &change = changeListeners.at(ii);
-            if (change.types & QSGItemPrivate::Rotation) {
-                change.listener->itemRotationChanged(q);
-            }
-        }
-        break;
-    }
-}
-
-/*!
-    \property QSGItem::smooth
-    \brief whether the item is smoothly transformed.
-
-    This property is provided purely for the purpose of optimization. Turning
-    smooth transforms off is faster, but looks worse; turning smooth
-    transformations on is slower, but looks better.
-
-    By default smooth transformations are off.
-*/
-
-/*!
-    Returns true if the item should be drawn with antialiasing and
-    smooth pixmap filtering, false otherwise.
-
-    The default is false.
-
-    \sa setSmooth()
-*/
-bool QSGItem::smooth() const
-{
-    Q_D(const QSGItem);
-    return d->smooth;
-}
-
-/*!
-    Sets whether the item should be drawn with antialiasing and
-    smooth pixmap filtering to \a smooth.
-
-    \sa smooth()
-*/
-void QSGItem::setSmooth(bool smooth)
-{
-    Q_D(QSGItem);
-    if (d->smooth == smooth)
-        return;
-
-    d->smooth = smooth;
-    d->dirty(QSGItemPrivate::Smooth);
-
-    emit smoothChanged(smooth);
-}
-
-QSGItem::Flags QSGItem::flags() const
-{
-    Q_D(const QSGItem);
-    return (QSGItem::Flags)d->flags;
-}
-
-void QSGItem::setFlag(Flag flag, bool enabled)
-{
-    Q_D(QSGItem);
-    if (enabled)
-        setFlags((Flags)(d->flags | (quint32)flag));
-    else
-        setFlags((Flags)(d->flags & ~(quint32)flag));
-}
-
-void QSGItem::setFlags(Flags flags)
-{
-    Q_D(QSGItem);
-
-    if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
-        if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
-            qWarning("QSGItem: Cannot set FocusScope once item has children and is in a canvas.");
-            flags &= ~ItemIsFocusScope;
-        } else if (d->flags & ItemIsFocusScope) {
-            qWarning("QSGItem: Cannot unset FocusScope flag.");
-            flags |= ItemIsFocusScope;
-        }
-    }
-
-    if ((flags & ItemClipsChildrenToShape ) != (d->flags & ItemClipsChildrenToShape))
-        d->dirty(QSGItemPrivate::Clip);
-
-    d->flags = flags;
-}
-
-qreal QSGItem::x() const
-{
-    Q_D(const QSGItem);
-    return d->x;
-}
-
-qreal QSGItem::y() const
-{
-    Q_D(const QSGItem);
-    return d->y;
-}
-
-QPointF QSGItem::pos() const
-{
-    Q_D(const QSGItem);
-    return QPointF(d->x, d->y);
-}
-
-void QSGItem::setX(qreal v)
-{
-    Q_D(QSGItem);
-    if (d->x == v)
-        return;
-
-    qreal oldx = d->x;
-    d->x = v;
-
-    d->dirty(QSGItemPrivate::Position);
-
-    geometryChanged(QRectF(x(), y(), width(), height()),
-                    QRectF(oldx, y(), width(), height()));
-}
-
-void QSGItem::setY(qreal v)
-{
-    Q_D(QSGItem);
-    if (d->y == v)
-        return;
-
-    qreal oldy = d->y;
-    d->y = v;
-
-    d->dirty(QSGItemPrivate::Position);
-
-    geometryChanged(QRectF(x(), y(), width(), height()),
-                    QRectF(x(), oldy, width(), height()));
-}
-
-void QSGItem::setPos(const QPointF &pos)
-{
-    Q_D(QSGItem);
-    if (QPointF(d->x, d->y) == pos)
-        return;
-
-    qreal oldx = d->x;
-    qreal oldy = d->y;
-
-    d->x = pos.x();
-    d->y = pos.y();
-
-    d->dirty(QSGItemPrivate::Position);
-
-    geometryChanged(QRectF(x(), y(), width(), height()),
-                    QRectF(oldx, oldy, width(), height()));
-}
-
-qreal QSGItem::width() const
-{
-    Q_D(const QSGItem);
-    return d->width;
-}
-
-void QSGItem::setWidth(qreal w)
-{
-    Q_D(QSGItem);
-    if (qIsNaN(w))
-        return;
-
-    d->widthValid = true;
-    if (d->width == w)
-        return;
-
-    qreal oldWidth = d->width;
-    d->width = w;
-
-    d->dirty(QSGItemPrivate::Size);
-
-    geometryChanged(QRectF(x(), y(), width(), height()),
-                    QRectF(x(), y(), oldWidth, height()));
-}
-
-void QSGItem::resetWidth()
-{
-    Q_D(QSGItem);
-    d->widthValid = false;
-    setImplicitWidth(implicitWidth());
-}
-
-void QSGItemPrivate::implicitWidthChanged()
-{
-    Q_Q(QSGItem);
-    emit q->implicitWidthChanged();
-}
-
-qreal QSGItemPrivate::getImplicitWidth() const
-{
-    return implicitWidth;
-}
-/*!
-    Returns the width of the item that is implied by other properties that determine the content.
-*/
-qreal QSGItem::implicitWidth() const
-{
-    Q_D(const QSGItem);
-    return d->getImplicitWidth();
-}
-
-/*!
-    \qmlproperty real QtQuick2::Item::implicitWidth
-    \qmlproperty real QtQuick2::Item::implicitHeight
-
-    Defines the natural width or height of the Item if no \l width or \l height is specified.
-
-    The default implicit size for most items is 0x0, however some elements have an inherent
-    implicit size which cannot be overridden, e.g. Image, Text.
-
-    Setting the implicit size is useful for defining components that have a preferred size
-    based on their content, for example:
-
-    \qml
-    // Label.qml
-    import QtQuick 1.1
-
-    Item {
-        property alias icon: image.source
-        property alias label: text.text
-        implicitWidth: text.implicitWidth + image.implicitWidth
-        implicitHeight: Math.max(text.implicitHeight, image.implicitHeight)
-        Image { id: image }
-        Text {
-            id: text
-            wrapMode: Text.Wrap
-            anchors.left: image.right; anchors.right: parent.right
-            anchors.verticalCenter: parent.verticalCenter
-        }
-    }
-    \endqml
-
-    \bold Note: using implicitWidth of Text or TextEdit and setting the width explicitly
-    incurs a performance penalty as the text must be laid out twice.
-*/
-
-/*!
-    Sets the implied width of the item to \a w.
-    This is the width implied by other properties that determine the content.
-*/
-void QSGItem::setImplicitWidth(qreal w)
-{
-    Q_D(QSGItem);
-    bool changed = w != d->implicitWidth;
-    d->implicitWidth = w;
-    if (d->width == w || widthValid()) {
-        if (changed)
-            d->implicitWidthChanged();
-        return;
-    }
-
-    qreal oldWidth = d->width;
-    d->width = w;
-
-    d->dirty(QSGItemPrivate::Size);
-
-    geometryChanged(QRectF(x(), y(), width(), height()),
-                    QRectF(x(), y(), oldWidth, height()));
-
-    if (changed)
-        d->implicitWidthChanged();
-}
-
-/*!
-    Returns whether the width property has been set explicitly.
-*/
-bool QSGItem::widthValid() const
-{
-    Q_D(const QSGItem);
-    return d->widthValid;
-}
-
-qreal QSGItem::height() const
-{
-    Q_D(const QSGItem);
-    return d->height;
-}
-
-void QSGItem::setHeight(qreal h)
-{
-    Q_D(QSGItem);
-    if (qIsNaN(h))
-        return;
-
-    d->heightValid = true;
-    if (d->height == h)
-        return;
-
-    qreal oldHeight = d->height;
-    d->height = h;
-
-    d->dirty(QSGItemPrivate::Size);
-
-    geometryChanged(QRectF(x(), y(), width(), height()),
-                    QRectF(x(), y(), width(), oldHeight));
-}
-
-void QSGItem::resetHeight()
-{
-    Q_D(QSGItem);
-    d->heightValid = false;
-    setImplicitHeight(implicitHeight());
-}
-
-void QSGItemPrivate::implicitHeightChanged()
-{
-    Q_Q(QSGItem);
-    emit q->implicitHeightChanged();
-}
-
-qreal QSGItemPrivate::getImplicitHeight() const
-{
-    return implicitHeight;
-}
-
-/*!
-    Returns the height of the item that is implied by other properties that determine the content.
-*/
-qreal QSGItem::implicitHeight() const
-{
-    Q_D(const QSGItem);
-    return d->getImplicitHeight();
-}
-
-
-/*!
-    Sets the implied height of the item to \a h.
-    This is the height implied by other properties that determine the content.
-*/
-void QSGItem::setImplicitHeight(qreal h)
-{
-    Q_D(QSGItem);
-    bool changed = h != d->implicitHeight;
-    d->implicitHeight = h;
-    if (d->height == h || heightValid()) {
-        if (changed)
-            d->implicitHeightChanged();
-        return;
-    }
-
-    qreal oldHeight = d->height;
-    d->height = h;
-
-    d->dirty(QSGItemPrivate::Size);
-
-    geometryChanged(QRectF(x(), y(), width(), height()),
-                    QRectF(x(), y(), width(), oldHeight));
-
-    if (changed)
-        d->implicitHeightChanged();
-}
-
-/*!
-    Returns whether the height property has been set explicitly.
-*/
-bool QSGItem::heightValid() const
-{
-    Q_D(const QSGItem);
-    return d->heightValid;
-}
-
-void QSGItem::setSize(const QSizeF &size)
-{
-    Q_D(QSGItem);
-    d->heightValid = true;
-    d->widthValid = true;
-
-    if (QSizeF(d->width, d->height) == size)
-        return;
-
-    qreal oldHeight = d->height;
-    qreal oldWidth = d->width;
-    d->height = size.height();
-    d->width = size.width();
-
-    d->dirty(QSGItemPrivate::Size);
-
-    geometryChanged(QRectF(x(), y(), width(), height()),
-                    QRectF(x(), y(), oldWidth, oldHeight));
-}
-
-bool QSGItem::hasActiveFocus() const
-{
-    Q_D(const QSGItem);
-    return d->activeFocus;
-}
-
-bool QSGItem::hasFocus() const
-{
-    Q_D(const QSGItem);
-    return d->focus;
-}
-
-void QSGItem::setFocus(bool focus)
-{
-    Q_D(QSGItem);
-    if (d->focus == focus)
-        return;
-
-    if (d->canvas) {
-        // Need to find our nearest focus scope
-        QSGItem *scope = parentItem();
-        while (scope && !scope->isFocusScope())
-            scope = scope->parentItem();
-        if (focus)
-            QSGCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
-        else
-            QSGCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
-    } else {
-        d->focus = focus;
-        emit focusChanged(focus);
-    }
-}
-
-bool QSGItem::isFocusScope() const
-{
-    return flags() & ItemIsFocusScope;
-}
-
-QSGItem *QSGItem::scopedFocusItem() const
-{
-    Q_D(const QSGItem);
-    if (!isFocusScope())
-        return 0;
-    else
-        return d->subFocusItem;
-}
-
-
-Qt::MouseButtons QSGItem::acceptedMouseButtons() const
-{
-    Q_D(const QSGItem);
-    return d->acceptedMouseButtons;
-}
-
-void QSGItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
-{
-    Q_D(QSGItem);
-    d->acceptedMouseButtons = buttons;
-}
-
-bool QSGItem::filtersChildMouseEvents() const
-{
-    Q_D(const QSGItem);
-    return d->filtersChildMouseEvents;
-}
-
-void QSGItem::setFiltersChildMouseEvents(bool filter)
-{
-    Q_D(QSGItem);
-    d->filtersChildMouseEvents = filter;
-}
-
-bool QSGItem::isUnderMouse() const
-{
-    Q_D(const QSGItem);
-    if (!d->canvas)
-        return false;
-
-    QPoint cursorPos = QCursor::pos();
-    if (QRectF(0, 0, width(), height()).contains(mapFromScene(cursorPos))) // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
-        return true;
-    return false;
-}
-
-bool QSGItem::acceptHoverEvents() const
-{
-    Q_D(const QSGItem);
-    return d->hoverEnabled;
-}
-
-void QSGItem::setAcceptHoverEvents(bool enabled)
-{
-    Q_D(QSGItem);
-    d->hoverEnabled = enabled;
-}
-
-void QSGItem::grabMouse()
-{
-    Q_D(QSGItem);
-    if (!d->canvas)
-        return;
-    QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(d->canvas);
-    if (canvasPriv->mouseGrabberItem == this)
-        return;
-
-    QSGItem *oldGrabber = canvasPriv->mouseGrabberItem;
-    canvasPriv->mouseGrabberItem = this;
-    if (oldGrabber)
-        oldGrabber->mouseUngrabEvent();
-}
-
-void QSGItem::ungrabMouse()
-{
-    Q_D(QSGItem);
-    if (!d->canvas)
-        return;
-    QSGCanvasPrivate *canvasPriv = QSGCanvasPrivate::get(d->canvas);
-    if (canvasPriv->mouseGrabberItem != this) {
-        qWarning("QSGItem::ungrabMouse(): Item is not the mouse grabber.");
-        return;
-    }
-
-    canvasPriv->mouseGrabberItem = 0;
-    mouseUngrabEvent();
-}
-
-bool QSGItem::keepMouseGrab() const
-{
-    Q_D(const QSGItem);
-    return d->keepMouse;
-}
-
-/*!
-  The flag indicating whether the mouse should remain
-  with this item is set to \a keep.
-
-  This is useful for items that wish to grab and keep mouse
-  interaction following a predefined gesture.  For example,
-  an item that is interested in horizontal mouse movement
-  may set keepMouseGrab to true once a threshold has been
-  exceeded.  Once keepMouseGrab has been set to true, filtering
-  items will not react to mouse events.
-
-  If the item does not indicate that it wishes to retain mouse grab,
-  a filtering item may steal the grab. For example, Flickable may attempt
-  to steal a mouse grab if it detects that the user has begun to
-  move the viewport.
-
-  \sa keepMouseGrab()
- */
-void QSGItem::setKeepMouseGrab(bool keep)
-{
-    Q_D(QSGItem);
-    d->keepMouse = keep;
-}
-
-/*!
-    \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
-
-    Maps the point (\a x, \a y), which is in \a item's coordinate system, to
-    this item's coordinate system, and returns an object with \c x and \c y
-    properties matching the mapped cooordinate.
-
-    If \a item is a \c null value, this maps the point from the coordinate
-    system of the root QML view.
-*/
-/*!
-    \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
-
-    Maps the point (\a x, \a y), which is in this item's coordinate system, to
-    \a item's coordinate system, and returns an object with \c x and \c y
-    properties matching the mapped cooordinate.
-
-    If \a item is a \c null value, this maps \a x and \a y to the coordinate
-    system of the root QML view.
-*/
-QPointF QSGItem::mapToItem(const QSGItem *item, const QPointF &point) const
-{
-    QPointF p = mapToScene(point);
-    if (item)
-        p = item->mapFromScene(p);
-    return p;
-}
-
-QPointF QSGItem::mapToScene(const QPointF &point) const
-{
-    Q_D(const QSGItem);
-    return d->itemToCanvasTransform().map(point);
-}
-
-QRectF QSGItem::mapRectToItem(const QSGItem *item, const QRectF &rect) const
-{
-    Q_D(const QSGItem);
-    QTransform t = d->itemToCanvasTransform();
-    if (item)
-        t *= QSGItemPrivate::get(item)->canvasToItemTransform();
-    return t.mapRect(rect);
-}
-
-QRectF QSGItem::mapRectToScene(const QRectF &rect) const
-{
-    Q_D(const QSGItem);
-    return d->itemToCanvasTransform().mapRect(rect);
-}
-
-QPointF QSGItem::mapFromItem(const QSGItem *item, const QPointF &point) const
-{
-    QPointF p = item?item->mapToScene(point):point;
-    return mapFromScene(p);
-}
-
-QPointF QSGItem::mapFromScene(const QPointF &point) const
-{
-    Q_D(const QSGItem);
-    return d->canvasToItemTransform().map(point);
-}
-
-QRectF QSGItem::mapRectFromItem(const QSGItem *item, const QRectF &rect) const
-{
-    Q_D(const QSGItem);
-    QTransform t = item?QSGItemPrivate::get(item)->itemToCanvasTransform():QTransform();
-    t *= d->canvasToItemTransform();
-    return t.mapRect(rect);
-}
-
-QRectF QSGItem::mapRectFromScene(const QRectF &rect) const
-{
-    Q_D(const QSGItem);
-    return d->canvasToItemTransform().mapRect(rect);
-}
-
-
-/*!
-    \qmlmethod QtQuick2::Item::forceActiveFocus()
-
-    Forces active focus on the item.
-
-    This method sets focus on the item and makes sure that all the focus scopes
-    higher in the object hierarchy are also given the focus.
-*/
-
-/*!
-    Forces active focus on the item.
-
-    This method sets focus on the item and makes sure that all the focus scopes
-    higher in the object hierarchy are also given the focus.
-*/
-
-/*!
-  \qmlmethod QtQuick2::Item::childAt(real x, real y)
-
-  Returns the visible child item at point (\a x, \a y), which is in this
-  item's coordinate system, or \c null if there is no such item.
-*/
-
-/*!
-  Returns the visible child item at point (\a x, \a y), which is in this
-  item's coordinate system, or 0 if there is no such item.
-*/
-
-/*!
-  \qmlproperty list<State> QtQuick2::Item::states
-  This property holds a list of states defined by the item.
-
-  \qml
-  Item {
-      states: [
-          State {
-              // ...
-          },
-          State {
-              // ...
-          }
-          // ...
-      ]
-  }
-  \endqml
-
-  \sa {qmlstate}{States}
-*/
-/*!
-  \qmlproperty list<Transition> QtQuick2::Item::transitions
-  This property holds a list of transitions defined by the item.
-
-  \qml
-  Item {
-      transitions: [
-          Transition {
-              // ...
-          },
-          Transition {
-              // ...
-          }
-          // ...
-      ]
-  }
-  \endqml
-
-  \sa {QML Animation and Transitions}{Transitions}
-*/
-/*
-  \qmlproperty list<Filter> QtQuick2::Item::filter
-  This property holds a list of graphical filters to be applied to the item.
-
-  \l {Filter}{Filters} include things like \l {Blur}{blurring}
-  the item, or giving it a \l Reflection.  Some
-  filters may not be available on all canvases; if a filter is not
-  available on a certain canvas, it will simply not be applied for
-  that canvas (but the QML will still be considered valid).
-
-  \qml
-  Item {
-      filter: [
-          Blur {
-              // ...
-          },
-          Reflection {
-              // ...
-          }
-          // ...
-      ]
-  }
-  \endqml
-*/
-
-/*!
-  \qmlproperty bool QtQuick2::Item::clip
-  This property holds whether clipping is enabled. The default clip value is \c false.
-
-  If clipping is enabled, an item will clip its own painting, as well
-  as the painting of its children, to its bounding rectangle.
-
-  Non-rectangular clipping regions are not supported for performance reasons.
-*/
-
-/*!
-  \property QSGItem::clip
-  This property holds whether clipping is enabled. The default clip value is \c false.
-
-  If clipping is enabled, an item will clip its own painting, as well
-  as the painting of its children, to its bounding rectangle. If you set
-  clipping during an item's paint operation, remember to re-set it to
-  prevent clipping the rest of your scene.
-
-  Non-rectangular clipping regions are not supported for performance reasons.
-*/
-
-/*!
-  \qmlproperty string QtQuick2::Item::state
-
-  This property holds the name of the current state of the item.
-
-  This property is often used in scripts to change between states. For
-  example:
-
-  \js
-  function toggle() {
-      if (button.state == 'On')
-          button.state = 'Off';
-      else
-          button.state = 'On';
-  }
-  \endjs
-
-  If the item is in its base state (i.e. no explicit state has been
-  set), \c state will be a blank string. Likewise, you can return an
-  item to its base state by setting its current state to \c ''.
-
-  \sa {qmlstates}{States}
-*/
-
-/*!
-  \qmlproperty list<Transform> QtQuick2::Item::transform
-  This property holds the list of transformations to apply.
-
-  For more information see \l Transform.
-*/
-
-/*!
-    \enum QSGItem::TransformOrigin
-
-    Controls the point about which simple transforms like scale apply.
-
-    \value TopLeft The top-left corner of the item.
-    \value Top The center point of the top of the item.
-    \value TopRight The top-right corner of the item.
-    \value Left The left most point of the vertical middle.
-    \value Center The center of the item.
-    \value Right The right most point of the vertical middle.
-    \value BottomLeft The bottom-left corner of the item.
-    \value Bottom The center point of the bottom of the item.
-    \value BottomRight The bottom-right corner of the item.
-*/
-
-
-/*!
-  \qmlproperty bool QtQuick2::Item::activeFocus
-
-  This property indicates whether the item has active focus.
-
-  An item with active focus will receive keyboard input,
-  or is a FocusScope ancestor of the item that will receive keyboard input.
-
-  Usually, activeFocus is gained by setting focus on an item and its enclosing
-  FocusScopes. In the following example \c input will have activeFocus.
-  \qml
-  Rectangle {
-      FocusScope {
-          focus: true
-          TextInput {
-              id: input
-              focus: true
-          }
-      }
-  }
-  \endqml
-
-  \sa focus, {qmlfocus}{Keyboard Focus}
-*/
-
-/*!
-  \qmlproperty bool QtQuick2::Item::focus
-  This property indicates whether the item has focus within the enclosing focus scope. If true, this item
-  will gain active focus when the enclosing focus scope gains active focus.
-  In the following example, \c input will be given active focus when \c scope gains active focus.
-  \qml
-  Rectangle {
-      FocusScope {
-          id: scope
-          TextInput {
-              id: input
-              focus: true
-          }
-      }
-  }
-  \endqml
-
-  For the purposes of this property, the scene as a whole is assumed to act like a focus scope.
-  On a practical level, that means the following QML will give active focus to \c input on startup.
-
-  \qml
-  Rectangle {
-      TextInput {
-          id: input
-          focus: true
-      }
-  }
-  \endqml
-
-  \sa activeFocus, {qmlfocus}{Keyboard Focus}
-*/
-
-
-/*!
-  \property QSGItem::anchors
-  \internal
-*/
-
-/*!
-  \property QSGItem::left
-  \internal
-*/
-
-/*!
-  \property QSGItem::right
-  \internal
-*/
-
-/*!
-  \property QSGItem::horizontalCenter
-  \internal
-*/
-
-/*!
-  \property QSGItem::top
-  \internal
-*/
-
-/*!
-  \property QSGItem::bottom
-  \internal
-*/
-
-/*!
-  \property QSGItem::verticalCenter
-  \internal
-*/
-
-/*!
-  \property QSGItem::focus
-  \internal
-*/
-
-/*!
-  \property QSGItem::transform
-  \internal
-*/
-
-/*!
-  \property QSGItem::transformOrigin
-  \internal
-*/
-
-/*!
-  \property QSGItem::activeFocus
-  \internal
-*/
-
-/*!
-  \property QSGItem::baseline
-  \internal
-*/
-
-/*!
-  \property QSGItem::data
-  \internal
-*/
-
-/*!
-  \property QSGItem::resources
-  \internal
-*/
-
-/*!
-  \property QSGItem::state
-  \internal
-*/
-
-/*!
-  \property QSGItem::states
-  \internal
-*/
-
-/*!
-  \property QSGItem::transformOriginPoint
-  \internal
-*/
-
-/*!
-  \property QSGItem::transitions
-  \internal
-*/
-
-bool QSGItem::event(QEvent *ev)
-{
-#if 0
-    if (ev->type() == QEvent::PolishRequest) {
-        Q_D(QSGItem);
-        d->polishScheduled = false;
-        updatePolish();
-        return true;
-    } else {
-        return QObject::event(ev);
-    }
-#endif
-    if (ev->type() == QEvent::InputMethodQuery) {
-        QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
-        Qt::InputMethodQueries queries = query->queries();
-        for (uint i = 0; i < 32; ++i) {
-            Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i));
-            if (q) {
-                QVariant v = inputMethodQuery(q);
-                query->setValue(q, v);
-            }
-        }
-        query->accept();
-        return true;
-    } else if (ev->type() == QEvent::InputMethod) {
-        inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
-        return true;
-    }
-    return QObject::event(ev);
-}
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug debug, QSGItem *item)
-{
-    if (!item) {
-        debug << "QSGItem(0)";
-        return debug;
-    }
-
-    debug << item->metaObject()->className() << "(this =" << ((void*)item)
-          << ", name=" << item->objectName()
-          << ", parent =" << ((void*)item->parentItem())
-          << ", geometry =" << QRectF(item->pos(), QSizeF(item->width(), item->height()))
-          << ", z =" << item->z() << ')';
-    return debug;
-}
-#endif
-
-qint64 QSGItemPrivate::consistentTime = -1;
-void QSGItemPrivate::setConsistentTime(qint64 t)
-{
-    consistentTime = t;
-}
-
-class QElapsedTimerConsistentTimeHack
-{
-public:
-    void start() {
-        t1 = QSGItemPrivate::consistentTime;
-        t2 = 0;
-    }
-    qint64 elapsed() {
-        return QSGItemPrivate::consistentTime - t1;
-    }
-    qint64 restart() {
-        qint64 val = QSGItemPrivate::consistentTime - t1;
-        t1 = QSGItemPrivate::consistentTime;
-        t2 = 0;
-        return val;
-    }
-
-private:
-    qint64 t1;
-    qint64 t2;
-};
-
-void QSGItemPrivate::start(QElapsedTimer &t)
-{
-    if (QSGItemPrivate::consistentTime == -1)
-        t.start();
-    else
-        ((QElapsedTimerConsistentTimeHack*)&t)->start();
-}
-
-qint64 QSGItemPrivate::elapsed(QElapsedTimer &t)
-{
-    if (QSGItemPrivate::consistentTime == -1)
-        return t.elapsed();
-    else
-        return ((QElapsedTimerConsistentTimeHack*)&t)->elapsed();
-}
-
-qint64 QSGItemPrivate::restart(QElapsedTimer &t)
-{
-    if (QSGItemPrivate::consistentTime == -1)
-        return t.restart();
-    else
-        return ((QElapsedTimerConsistentTimeHack*)&t)->restart();
-}
-
-/*!
-    \fn bool QSGItem::isTextureProvider() const
-
-    Returns true if this item is a texture provider. The default
-    implementation returns false.
-
-    This function can be called from any thread.
- */
-
-/*!
-    \fn QSGTextureProvider *QSGItem::textureProvider() const
-
-    Returns the texture provider for an item. The default implementation
-    returns 0.
-
-    This function may only be called on the rendering thread.
- */
-
-QT_END_NAMESPACE
-
-#include <moc_qsgitem.cpp>
diff --git a/src/declarative/items/qsgitem.h b/src/declarative/items/qsgitem.h
deleted file mode 100644 (file)
index 018453f..0000000
+++ /dev/null
@@ -1,415 +0,0 @@
-// Commit: 6f78a6080b84cc3ef96b73a4ff58d1b5a72f08f4
-/****************************************************************************
-**
-** 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 QSGITEM_H
-#define QSGITEM_H
-
-#include <QtDeclarative/qdeclarative.h>
-#include <QtDeclarative/qdeclarativecomponent.h>
-
-#include <QtCore/QObject>
-#include <QtCore/QList>
-#include <QtGui/qevent.h>
-#include <QtGui/qfont.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGItem;
-class QSGTransformPrivate;
-class QSGTransform : public QObject
-{
-    Q_OBJECT
-public:
-    QSGTransform(QObject *parent = 0);
-    ~QSGTransform();
-
-    void appendToItem(QSGItem *);
-    void prependToItem(QSGItem *);
-
-    virtual void applyTo(QMatrix4x4 *matrix) const = 0;
-
-protected Q_SLOTS:
-    void update();
-
-protected:
-    QSGTransform(QSGTransformPrivate &dd, QObject *parent);
-
-private:
-    Q_DECLARE_PRIVATE(QSGTransform)
-};
-
-class QDeclarativeV8Function;
-class QDeclarativeState;
-class QSGAnchorLine;
-class QDeclarativeTransition;
-class QSGKeyEvent;
-class QSGAnchors;
-class QSGItemPrivate;
-class QSGCanvas;
-class QSGDragEvent;
-class QSGEngine;
-class QTouchEvent;
-class QSGNode;
-class QSGTransformNode;
-class QSGTextureProvider;
-
-class Q_DECLARATIVE_EXPORT QSGItem : public QObject, public QDeclarativeParserStatus
-{
-    Q_OBJECT
-    Q_INTERFACES(QDeclarativeParserStatus)
-
-    Q_PROPERTY(QSGItem *parent READ parentItem WRITE setParentItem NOTIFY parentChanged DESIGNABLE false FINAL)
-    Q_PRIVATE_PROPERTY(QSGItem::d_func(), QDeclarativeListProperty<QObject> data READ data DESIGNABLE false)
-    Q_PRIVATE_PROPERTY(QSGItem::d_func(), QDeclarativeListProperty<QObject> resources READ resources DESIGNABLE false)
-    Q_PRIVATE_PROPERTY(QSGItem::d_func(), QDeclarativeListProperty<QSGItem> children READ children NOTIFY childrenChanged DESIGNABLE false)
-
-    Q_PROPERTY(QPointF pos READ pos FINAL)
-    Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged FINAL)
-    Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged FINAL)
-    Q_PROPERTY(qreal z READ z WRITE setZ NOTIFY zChanged FINAL)
-    Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY widthChanged RESET resetWidth FINAL)
-    Q_PROPERTY(qreal height READ height WRITE setHeight NOTIFY heightChanged RESET resetHeight FINAL)
-
-    Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged FINAL)
-    Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
-    Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL)
-
-    Q_PRIVATE_PROPERTY(QSGItem::d_func(), QDeclarativeListProperty<QDeclarativeState> states READ states DESIGNABLE false)
-    Q_PRIVATE_PROPERTY(QSGItem::d_func(), QDeclarativeListProperty<QDeclarativeTransition> transitions READ transitions DESIGNABLE false)
-    Q_PROPERTY(QString state READ state WRITE setState NOTIFY stateChanged)
-    Q_PROPERTY(QRectF childrenRect READ childrenRect NOTIFY childrenRectChanged DESIGNABLE false FINAL)
-    Q_PRIVATE_PROPERTY(QSGItem::d_func(), QSGAnchors * anchors READ anchors DESIGNABLE false CONSTANT FINAL)
-    Q_PRIVATE_PROPERTY(QSGItem::d_func(), QSGAnchorLine left READ left CONSTANT FINAL)
-    Q_PRIVATE_PROPERTY(QSGItem::d_func(), QSGAnchorLine right READ right CONSTANT FINAL)
-    Q_PRIVATE_PROPERTY(QSGItem::d_func(), QSGAnchorLine horizontalCenter READ horizontalCenter CONSTANT FINAL)
-    Q_PRIVATE_PROPERTY(QSGItem::d_func(), QSGAnchorLine top READ top CONSTANT FINAL)
-    Q_PRIVATE_PROPERTY(QSGItem::d_func(), QSGAnchorLine bottom READ bottom CONSTANT FINAL)
-    Q_PRIVATE_PROPERTY(QSGItem::d_func(), QSGAnchorLine verticalCenter READ verticalCenter CONSTANT FINAL)
-    Q_PRIVATE_PROPERTY(QSGItem::d_func(), QSGAnchorLine baseline READ baseline CONSTANT FINAL)
-    Q_PROPERTY(qreal baselineOffset READ baselineOffset WRITE setBaselineOffset NOTIFY baselineOffsetChanged)
-
-    Q_PROPERTY(bool clip READ clip WRITE setClip NOTIFY clipChanged)
-
-    Q_PROPERTY(bool focus READ hasFocus WRITE setFocus NOTIFY focusChanged FINAL)
-    Q_PROPERTY(bool activeFocus READ hasActiveFocus NOTIFY activeFocusChanged FINAL)
-
-    Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged)
-    Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged)
-    Q_PROPERTY(TransformOrigin transformOrigin READ transformOrigin WRITE setTransformOrigin NOTIFY transformOriginChanged)
-    Q_PROPERTY(QPointF transformOriginPoint READ transformOriginPoint)  // XXX todo - notify?
-    Q_PROPERTY(QDeclarativeListProperty<QSGTransform> transform READ transform DESIGNABLE false FINAL)
-
-    Q_PROPERTY(bool smooth READ smooth WRITE setSmooth NOTIFY smoothChanged)
-    Q_PROPERTY(qreal implicitWidth READ implicitWidth WRITE setImplicitWidth NOTIFY implicitWidthChanged)
-    Q_PROPERTY(qreal implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged)
-
-    Q_ENUMS(TransformOrigin)
-    Q_CLASSINFO("DefaultProperty", "data")
-
-public:
-    enum Flag {
-        ItemClipsChildrenToShape  = 0x01,
-        ItemAcceptsInputMethod    = 0x02,
-        ItemIsFocusScope          = 0x04,
-        ItemHasContents           = 0x08,
-        ItemAcceptsDrops          = 0x10
-        // Remember to increment the size of QSGItemPrivate::flags
-    };
-    Q_DECLARE_FLAGS(Flags, Flag)
-
-    enum ItemChange {
-        ItemChildAddedChange,      // value.item
-        ItemChildRemovedChange,    // value.item
-        ItemSceneChange,           // value.canvas
-        ItemVisibleHasChanged,     // value.realValue
-        ItemParentHasChanged,      // value.item
-        ItemOpacityHasChanged,     // value.realValue
-        ItemActiveFocusHasChanged, // value.boolValue
-        ItemRotationHasChanged     // value.realValue
-    };
-
-    union ItemChangeData {
-        ItemChangeData(QSGItem *v) : item(v) {}
-        ItemChangeData(QSGCanvas *v) : canvas(v) {}
-        ItemChangeData(qreal v) : realValue(v) {}
-        ItemChangeData(bool v) : boolValue(v) {}
-
-        QSGItem *item;
-        QSGCanvas *canvas;
-        qreal realValue;
-        bool boolValue;
-    };
-
-    enum TransformOrigin {
-        TopLeft, Top, TopRight,
-        Left, Center, Right,
-        BottomLeft, Bottom, BottomRight
-    };
-
-    QSGItem(QSGItem *parent = 0);
-    virtual ~QSGItem();
-
-    QSGEngine *sceneGraphEngine() const;
-
-    QSGCanvas *canvas() const;
-    QSGItem *parentItem() const;
-    void setParentItem(QSGItem *parent);
-    void stackBefore(const QSGItem *);
-    void stackAfter(const QSGItem *);
-
-    QRectF childrenRect();
-    QList<QSGItem *> childItems() const;
-
-    bool clip() const;
-    void setClip(bool);
-
-    QString state() const;
-    void setState(const QString &);
-
-    qreal baselineOffset() const;
-    void setBaselineOffset(qreal);
-
-    QDeclarativeListProperty<QSGTransform> transform();
-
-    qreal x() const;
-    qreal y() const;
-    QPointF pos() const;
-    void setX(qreal);
-    void setY(qreal);
-    void setPos(const QPointF &);
-
-    qreal width() const;
-    void setWidth(qreal);
-    void resetWidth();
-    qreal implicitWidth() const;
-
-    qreal height() const;
-    void setHeight(qreal);
-    void resetHeight();
-    qreal implicitHeight() const;
-
-    void setSize(const QSizeF &size);
-
-    TransformOrigin transformOrigin() const;
-    void setTransformOrigin(TransformOrigin);
-    QPointF transformOriginPoint() const;
-    void setTransformOriginPoint(const QPointF &);
-
-    qreal z() const;
-    void setZ(qreal);
-
-    qreal rotation() const;
-    void setRotation(qreal);
-    qreal scale() const;
-    void setScale(qreal);
-
-    qreal opacity() const;
-    void setOpacity(qreal);
-
-    bool isVisible() const;
-    void setVisible(bool);
-
-    bool isEnabled() const;
-    void setEnabled(bool);
-
-    bool smooth() const;
-    void setSmooth(bool);
-
-    Flags flags() const;
-    void setFlag(Flag flag, bool enabled = true);
-    void setFlags(Flags flags);
-
-    virtual QRectF boundingRect() const;
-
-    bool hasActiveFocus() const;
-    bool hasFocus() const;
-    void setFocus(bool);
-    bool isFocusScope() const;
-    QSGItem *scopedFocusItem() const;
-
-    Qt::MouseButtons acceptedMouseButtons() const;
-    void setAcceptedMouseButtons(Qt::MouseButtons buttons);
-    bool acceptHoverEvents() const;
-    void setAcceptHoverEvents(bool enabled);
-
-    bool isUnderMouse() const;
-    void grabMouse();
-    void ungrabMouse();
-    bool keepMouseGrab() const;
-    void setKeepMouseGrab(bool);
-    bool filtersChildMouseEvents() const;
-    void setFiltersChildMouseEvents(bool filter);
-
-    QTransform itemTransform(QSGItem *, bool *) const;
-    QPointF mapToItem(const QSGItem *item, const QPointF &point) const;
-    QPointF mapToScene(const QPointF &point) const;
-    QRectF mapRectToItem(const QSGItem *item, const QRectF &rect) const;
-    QRectF mapRectToScene(const QRectF &rect) const;
-    QPointF mapFromItem(const QSGItem *item, const QPointF &point) const;
-    QPointF mapFromScene(const QPointF &point) const;
-    QRectF mapRectFromItem(const QSGItem *item, const QRectF &rect) const;
-    QRectF mapRectFromScene(const QRectF &rect) const;
-
-    void polish();
-
-    Q_INVOKABLE void mapFromItem(QDeclarativeV8Function*) const;
-    Q_INVOKABLE void mapToItem(QDeclarativeV8Function*) const;
-    Q_INVOKABLE void forceActiveFocus();
-    Q_INVOKABLE QSGItem *childAt(qreal x, qreal y) const;
-
-    Qt::InputMethodHints inputMethodHints() const;
-    void setInputMethodHints(Qt::InputMethodHints hints);
-    virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
-
-    struct UpdatePaintNodeData {
-       QSGTransformNode *transformNode;
-    private:
-       friend class QSGCanvasPrivate;
-       UpdatePaintNodeData();
-    };
-
-    virtual bool isTextureProvider() const { return false; }
-    virtual QSGTextureProvider *textureProvider() const { return 0; }
-
-public Q_SLOTS:
-    void update();
-    void updateMicroFocus();
-
-Q_SIGNALS:
-    void childrenRectChanged(const QRectF &);
-    void baselineOffsetChanged(qreal);
-    void stateChanged(const QString &);
-    void focusChanged(bool);
-    void activeFocusChanged(bool);
-    void parentChanged(QSGItem *);
-    void transformOriginChanged(TransformOrigin);
-    void smoothChanged(bool);
-    void clipChanged(bool);
-
-    // XXX todo
-    void childrenChanged();
-    void opacityChanged();
-    void enabledChanged();
-    void visibleChanged();
-    void rotationChanged();
-    void scaleChanged();
-
-    void xChanged();
-    void yChanged();
-    void widthChanged();
-    void heightChanged();
-    void zChanged();
-    void implicitWidthChanged();
-    void implicitHeightChanged();
-
-protected:
-    virtual bool event(QEvent *);
-
-    bool isComponentComplete() const;
-    virtual void itemChange(ItemChange, const ItemChangeData &);
-
-    void setImplicitWidth(qreal);
-    bool widthValid() const; // ### better name?
-    void setImplicitHeight(qreal);
-    bool heightValid() const; // ### better name?
-
-    virtual void classBegin();
-    virtual void componentComplete();
-
-    virtual void keyPressEvent(QKeyEvent *event);
-    virtual void keyReleaseEvent(QKeyEvent *event);
-    virtual void inputMethodEvent(QInputMethodEvent *);
-    virtual void focusInEvent(QFocusEvent *);
-    virtual void focusOutEvent(QFocusEvent *);
-    virtual void mousePressEvent(QMouseEvent *event);
-    virtual void mouseMoveEvent(QMouseEvent *event);
-    virtual void mouseReleaseEvent(QMouseEvent *event);
-    virtual void mouseDoubleClickEvent(QMouseEvent *event);
-    virtual void mouseUngrabEvent(); // XXX todo - params?
-    virtual void wheelEvent(QWheelEvent *event);
-    virtual void touchEvent(QTouchEvent *event);
-    virtual void hoverEnterEvent(QHoverEvent *event);
-    virtual void hoverMoveEvent(QHoverEvent *event);
-    virtual void hoverLeaveEvent(QHoverEvent *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();
-
-    virtual void geometryChanged(const QRectF &newGeometry,
-                                 const QRectF &oldGeometry);
-
-    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
-    virtual void updatePolish();
-
-protected:
-    QSGItem(QSGItemPrivate &dd, QSGItem *parent = 0);
-
-private:
-    friend class QSGCanvas;
-    friend class QSGCanvasPrivate;
-    friend class QSGRenderer;
-    Q_DISABLE_COPY(QSGItem)
-    Q_DECLARE_PRIVATE(QSGItem)
-};
-
-// XXX todo
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSGItem::Flags)
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug Q_DECLARATIVE_EXPORT operator<<(QDebug debug, QSGItem *item);
-#endif
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGItem)
-QML_DECLARE_TYPE(QSGTransform)
-
-QT_END_HEADER
-
-#endif // QSGITEM_H
diff --git a/src/declarative/items/qsgitem_p.h b/src/declarative/items/qsgitem_p.h
deleted file mode 100644 (file)
index c0ed1db..0000000
+++ /dev/null
@@ -1,716 +0,0 @@
-// Commit: 5c783d0a9a912816813945387903857a314040b5
-/****************************************************************************
-**
-** 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 QSGITEM_P_H
-#define QSGITEM_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 "qsgitem.h"
-
-#include "qsganchors_p.h"
-#include "qsganchors_p_p.h"
-#include "qsgitemchangelistener_p.h"
-
-#include "qsgcanvas_p.h"
-
-#include "qsgnode.h"
-#include "qsgclipnode_p.h"
-
-#include <private/qpodvector_p.h>
-#include <private/qdeclarativestate_p.h>
-#include <private/qdeclarativenullablevalue_p_p.h>
-#include <private/qdeclarativenotifier_p.h>
-#include <private/qdeclarativeglobal_p.h>
-
-#include <qdeclarative.h>
-#include <qdeclarativecontext.h>
-
-#include <QtCore/qlist.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qelapsedtimer.h>
-
-QT_BEGIN_NAMESPACE
-
-class QNetworkReply;
-class QSGItemKeyFilter;
-class QSGLayoutMirroringAttached;
-
-//### merge into private?
-class QSGContents : public QObject, public QSGItemChangeListener
-{
-    Q_OBJECT
-public:
-    QSGContents(QSGItem *item);
-    ~QSGContents();
-
-    QRectF rectF() const;
-
-    void childRemoved(QSGItem *item);
-    void childAdded(QSGItem *item);
-
-    void calcGeometry() { calcWidth(); calcHeight(); }
-    void complete();
-
-Q_SIGNALS:
-    void rectChanged(QRectF);
-
-protected:
-    void itemGeometryChanged(QSGItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
-    void itemDestroyed(QSGItem *item);
-    //void itemVisibilityChanged(QSGItem *item)
-
-private:
-    void calcHeight(QSGItem *changed = 0);
-    void calcWidth(QSGItem *changed = 0);
-
-    QSGItem *m_item;
-    qreal m_x;
-    qreal m_y;
-    qreal m_width;
-    qreal m_height;
-};
-
-class QSGTransformPrivate : public QObjectPrivate
-{
-    Q_DECLARE_PUBLIC(QSGTransform);
-public:
-    static QSGTransformPrivate* get(QSGTransform *transform) { return transform->d_func(); }
-
-    QSGTransformPrivate();
-
-    QList<QSGItem *> items;
-};
-
-class Q_DECLARATIVE_EXPORT QSGItemPrivate : public QObjectPrivate
-{
-    Q_DECLARE_PUBLIC(QSGItem)
-
-public:
-    static QSGItemPrivate* get(QSGItem *item) { return item->d_func(); }
-    static const QSGItemPrivate* get(const QSGItem *item) { return item->d_func(); }
-
-    QSGItemPrivate();
-    void init(QSGItem *parent);
-
-    QDeclarativeListProperty<QObject> data();
-    QDeclarativeListProperty<QObject> resources();
-    QDeclarativeListProperty<QSGItem> children();
-
-    QDeclarativeListProperty<QDeclarativeState> states();
-    QDeclarativeListProperty<QDeclarativeTransition> transitions();
-
-    QString state() const;
-    void setState(const QString &);
-
-    QSGAnchorLine left() const;
-    QSGAnchorLine right() const;
-    QSGAnchorLine horizontalCenter() const;
-    QSGAnchorLine top() const;
-    QSGAnchorLine bottom() const;
-    QSGAnchorLine verticalCenter() const;
-    QSGAnchorLine baseline() const;
-
-    // data property
-    static void data_append(QDeclarativeListProperty<QObject> *, QObject *);
-    static int data_count(QDeclarativeListProperty<QObject> *);
-    static QObject *data_at(QDeclarativeListProperty<QObject> *, int);
-    static void data_clear(QDeclarativeListProperty<QObject> *);
-
-    // resources property
-    static QObject *resources_at(QDeclarativeListProperty<QObject> *, int);
-    static void resources_append(QDeclarativeListProperty<QObject> *, QObject *);
-    static int resources_count(QDeclarativeListProperty<QObject> *);
-    static void resources_clear(QDeclarativeListProperty<QObject> *);
-
-    // children property
-    static void children_append(QDeclarativeListProperty<QSGItem> *, QSGItem *);
-    static int children_count(QDeclarativeListProperty<QSGItem> *);
-    static QSGItem *children_at(QDeclarativeListProperty<QSGItem> *, int);
-    static void children_clear(QDeclarativeListProperty<QSGItem> *);
-
-    // transform property
-    static int transform_count(QDeclarativeListProperty<QSGTransform> *list);
-    static void transform_append(QDeclarativeListProperty<QSGTransform> *list, QSGTransform *);
-    static QSGTransform *transform_at(QDeclarativeListProperty<QSGTransform> *list, int);
-    static void transform_clear(QDeclarativeListProperty<QSGTransform> *list);
-
-    QSGAnchors *anchors() const;
-    mutable QSGAnchors *_anchors;
-    QSGContents *_contents;
-
-    QDeclarativeNullableValue<qreal> baselineOffset;
-
-    struct AnchorLines {
-        AnchorLines(QSGItem *);
-        QSGAnchorLine left;
-        QSGAnchorLine right;
-        QSGAnchorLine hCenter;
-        QSGAnchorLine top;
-        QSGAnchorLine bottom;
-        QSGAnchorLine vCenter;
-        QSGAnchorLine baseline;
-    };
-    mutable AnchorLines *_anchorLines;
-    AnchorLines *anchorLines() const;
-
-    enum ChangeType {
-        Geometry = 0x01,
-        SiblingOrder = 0x02,
-        Visibility = 0x04,
-        Opacity = 0x08,
-        Destroyed = 0x10,
-        Parent = 0x20,
-        Children = 0x40,
-        Rotation = 0x80,
-    };
-
-    Q_DECLARE_FLAGS(ChangeTypes, ChangeType)
-
-    struct ChangeListener {
-        ChangeListener(QSGItemChangeListener *l, QSGItemPrivate::ChangeTypes t) : listener(l), types(t) {}
-        QSGItemChangeListener *listener;
-        QSGItemPrivate::ChangeTypes types;
-        bool operator==(const ChangeListener &other) const { return listener == other.listener && types == other.types; }
-    };
-
-    void addItemChangeListener(QSGItemChangeListener *listener, ChangeTypes types) {
-        changeListeners.append(ChangeListener(listener, types));
-    }
-    void removeItemChangeListener(QSGItemChangeListener *, ChangeTypes types);
-    QPODVector<ChangeListener,4> changeListeners;
-
-    QDeclarativeStateGroup *_states();
-    QDeclarativeStateGroup *_stateGroup;
-
-    QSGItem::TransformOrigin origin:5;
-    quint32 flags:5;
-    bool widthValid:1;
-    bool heightValid:1;
-    bool componentComplete:1;
-    bool keepMouse:1;
-    bool hoverEnabled:1;
-    bool smooth:1;
-    bool focus:1;
-    bool activeFocus:1;
-    bool notifiedFocus:1;
-    bool notifiedActiveFocus:1;
-    bool filtersChildMouseEvents:1;
-    bool explicitVisible:1;
-    bool effectiveVisible:1;
-    bool explicitEnable:1;
-    bool effectiveEnable:1;
-    bool polishScheduled:1;
-    bool inheritedLayoutMirror:1;
-    bool effectiveLayoutMirror:1;
-    bool isMirrorImplicit:1;
-    bool inheritMirrorFromParent:1;
-    bool inheritMirrorFromItem:1;
-    bool childrenDoNotOverlap:1;
-    quint32 dummy:1;
-
-    QSGCanvas *canvas;
-    QSGContext *sceneGraphContext() const { Q_ASSERT(canvas); return static_cast<QSGCanvasPrivate *>(QObjectPrivate::get(canvas))->context; }
-
-    QSGItem *parentItem;
-    QList<QSGItem *> childItems;
-    QList<QSGItem *> paintOrderChildItems() const;
-    void addChild(QSGItem *);
-    void removeChild(QSGItem *);
-    void siblingOrderChanged();
-
-    class InitializationState {
-    public:
-        QSGItem *getFocusScope(QSGItem *item);
-        void clear();
-        void clear(QSGItem *focusScope);
-    private:
-        QSGItem *focusScope;
-    };
-    void initCanvas(InitializationState *, QSGCanvas *);
-
-    QSGItem *subFocusItem;
-
-    QTransform canvasToItemTransform() const;
-    QTransform itemToCanvasTransform() const;
-    void itemToParentTransform(QTransform &) const;
-
-    qreal x;
-    qreal y;
-    qreal width;
-    qreal height;
-    qreal implicitWidth;
-    qreal implicitHeight;
-
-    qreal z;
-    qreal scale;
-    qreal rotation;
-    qreal opacity;
-
-    QSGLayoutMirroringAttached* attachedLayoutDirection;
-
-    Qt::MouseButtons acceptedMouseButtons;
-    Qt::InputMethodHints imHints;
-
-    QPointF transformOriginPoint;
-
-    virtual qreal getImplicitWidth() const;
-    virtual qreal getImplicitHeight() const;
-    virtual void implicitWidthChanged();
-    virtual void implicitHeightChanged();
-
-    void resolveLayoutMirror();
-    void setImplicitLayoutMirror(bool mirror, bool inherit);
-    void setLayoutMirror(bool mirror);
-    bool isMirrored() const {
-        return effectiveLayoutMirror;
-    }
-
-    QPointF computeTransformOrigin() const;
-    QList<QSGTransform *> transforms;
-    virtual void transformChanged();
-
-    QSGItemKeyFilter *keyHandler;
-    void deliverKeyEvent(QKeyEvent *);
-    void deliverInputMethodEvent(QInputMethodEvent *);
-    void deliverFocusEvent(QFocusEvent *);
-    void deliverMouseEvent(QMouseEvent *);
-    void deliverWheelEvent(QWheelEvent *);
-    void deliverTouchEvent(QTouchEvent *);
-    void deliverHoverEvent(QHoverEvent *);
-    void deliverDragEvent(QEvent *);
-
-    bool calcEffectiveVisible() const;
-    void setEffectiveVisibleRecur(bool);
-    bool calcEffectiveEnable() const;
-    void setEffectiveEnableRecur(bool);
-
-    // XXX todo
-    enum DirtyType {
-        TransformOrigin         = 0x00000001,
-        Transform               = 0x00000002,
-        BasicTransform          = 0x00000004,
-        Position                = 0x00000008,
-        Size                    = 0x00000010,
-
-        ZValue                  = 0x00000020,
-        Content                 = 0x00000040,
-        Smooth                  = 0x00000080,
-        OpacityValue            = 0x00000100,
-        ChildrenChanged         = 0x00000200,
-        ChildrenStackingChanged = 0x00000400,
-        ParentChanged           = 0x00000800,
-
-        Clip                    = 0x00001000,
-        Canvas                  = 0x00002000,
-
-        EffectReference         = 0x00008000,
-        Visible                 = 0x00010000,
-        HideReference           = 0x00020000,
-        // When you add an attribute here, don't forget to update
-        // dirtyToString()
-
-        TransformUpdateMask     = TransformOrigin | Transform | BasicTransform | Position | Size | Canvas,
-        ComplexTransformUpdateMask     = Transform | Canvas,
-        ContentUpdateMask       = Size | Content | Smooth | Canvas,
-        ChildrenUpdateMask      = ChildrenChanged | ChildrenStackingChanged | EffectReference | Canvas,
-
-    };
-    quint32 dirtyAttributes;
-    QString dirtyToString() const;
-    void dirty(DirtyType);
-    void addToDirtyList();
-    void removeFromDirtyList();
-    QSGItem *nextDirtyItem;
-    QSGItem**prevDirtyItem;
-
-    inline QSGTransformNode *itemNode();
-    inline QSGNode *childContainerNode();
-
-    /*
-      QSGNode order is:
-         - itemNode
-         - (opacityNode)
-         - (clipNode)
-         - (effectNode)
-         - groupNode
-     */
-
-    QSGTransformNode *itemNodeInstance;
-    QSGOpacityNode *opacityNode;
-    QSGDefaultClipNode *clipNode;
-    QSGRootNode *rootNode;
-    QSGNode *groupNode;
-    QSGNode *paintNode;
-    QSGNode *beforePaintNode;
-
-    virtual QSGTransformNode *createTransformNode();
-
-    // A reference from an effect item means that this item is used by the effect, so
-    // it should insert a root node.
-    void refFromEffectItem(bool hide);
-    void derefFromEffectItem(bool unhide);
-    int effectRefCount;
-    int hideRefCount;
-
-    void itemChange(QSGItem::ItemChange, const QSGItem::ItemChangeData &);
-
-    virtual void mirrorChange() {}
-
-    static qint64 consistentTime;
-    static void setConsistentTime(qint64 t);
-    static void start(QElapsedTimer &);
-    static qint64 elapsed(QElapsedTimer &);
-    static qint64 restart(QElapsedTimer &);
-};
-
-/*
-    Key filters can be installed on a QSGItem, but not removed.  Currently they
-    are only used by attached objects (which are only destroyed on Item
-    destruction), so this isn't a problem.  If in future this becomes any form
-    of public API, they will have to support removal too.
-*/
-class QSGItemKeyFilter
-{
-public:
-    QSGItemKeyFilter(QSGItem * = 0);
-    virtual ~QSGItemKeyFilter();
-
-    virtual void keyPressed(QKeyEvent *event, bool post);
-    virtual void keyReleased(QKeyEvent *event, bool post);
-    virtual void inputMethodEvent(QInputMethodEvent *event, bool post);
-    virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
-    virtual void componentComplete();
-
-    bool m_processPost;
-
-private:
-    QSGItemKeyFilter *m_next;
-};
-
-class QSGKeyNavigationAttachedPrivate : public QObjectPrivate
-{
-public:
-    QSGKeyNavigationAttachedPrivate()
-        : QObjectPrivate(),
-          left(0), right(0), up(0), down(0), tab(0), backtab(0),
-          leftSet(false), rightSet(false), upSet(false), downSet(false),
-          tabSet(false), backtabSet(false) {}
-
-    QSGItem *left;
-    QSGItem *right;
-    QSGItem *up;
-    QSGItem *down;
-    QSGItem *tab;
-    QSGItem *backtab;
-    bool leftSet : 1;
-    bool rightSet : 1;
-    bool upSet : 1;
-    bool downSet : 1;
-    bool tabSet : 1;
-    bool backtabSet : 1;
-};
-
-class QSGKeyNavigationAttached : public QObject, public QSGItemKeyFilter
-{
-    Q_OBJECT
-    Q_DECLARE_PRIVATE(QSGKeyNavigationAttached)
-
-    Q_PROPERTY(QSGItem *left READ left WRITE setLeft NOTIFY leftChanged)
-    Q_PROPERTY(QSGItem *right READ right WRITE setRight NOTIFY rightChanged)
-    Q_PROPERTY(QSGItem *up READ up WRITE setUp NOTIFY upChanged)
-    Q_PROPERTY(QSGItem *down READ down WRITE setDown NOTIFY downChanged)
-    Q_PROPERTY(QSGItem *tab READ tab WRITE setTab NOTIFY tabChanged)
-    Q_PROPERTY(QSGItem *backtab READ backtab WRITE setBacktab NOTIFY backtabChanged)
-    Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
-
-    Q_ENUMS(Priority)
-
-public:
-    QSGKeyNavigationAttached(QObject * = 0);
-
-    QSGItem *left() const;
-    void setLeft(QSGItem *);
-    QSGItem *right() const;
-    void setRight(QSGItem *);
-    QSGItem *up() const;
-    void setUp(QSGItem *);
-    QSGItem *down() const;
-    void setDown(QSGItem *);
-    QSGItem *tab() const;
-    void setTab(QSGItem *);
-    QSGItem *backtab() const;
-    void setBacktab(QSGItem *);
-
-    enum Priority { BeforeItem, AfterItem };
-    Priority priority() const;
-    void setPriority(Priority);
-
-    static QSGKeyNavigationAttached *qmlAttachedProperties(QObject *);
-
-Q_SIGNALS:
-    void leftChanged();
-    void rightChanged();
-    void upChanged();
-    void downChanged();
-    void tabChanged();
-    void backtabChanged();
-    void priorityChanged();
-
-private:
-    virtual void keyPressed(QKeyEvent *event, bool post);
-    virtual void keyReleased(QKeyEvent *event, bool post);
-    void setFocusNavigation(QSGItem *currentItem, const char *dir);
-};
-
-class QSGLayoutMirroringAttached : public QObject
-{
-    Q_OBJECT
-    Q_PROPERTY(bool enabled READ enabled WRITE setEnabled RESET resetEnabled NOTIFY enabledChanged)
-    Q_PROPERTY(bool childrenInherit READ childrenInherit WRITE setChildrenInherit NOTIFY childrenInheritChanged)
-
-public:
-    explicit QSGLayoutMirroringAttached(QObject *parent = 0);
-
-    bool enabled() const;
-    void setEnabled(bool);
-    void resetEnabled();
-
-    bool childrenInherit() const;
-    void setChildrenInherit(bool);
-
-    static QSGLayoutMirroringAttached *qmlAttachedProperties(QObject *);
-Q_SIGNALS:
-    void enabledChanged();
-    void childrenInheritChanged();
-private:
-    friend class QSGItemPrivate;
-    QSGItemPrivate *itemPrivate;
-};
-
-class QSGKeysAttachedPrivate : public QObjectPrivate
-{
-public:
-    QSGKeysAttachedPrivate()
-        : QObjectPrivate(), inPress(false), inRelease(false)
-        , inIM(false), enabled(true), imeItem(0), item(0)
-    {}
-
-    bool isConnected(const char *signalName);
-
-    //loop detection
-    bool inPress:1;
-    bool inRelease:1;
-    bool inIM:1;
-
-    bool enabled : 1;
-
-    QSGItem *imeItem;
-    QList<QSGItem *> targets;
-    QSGItem *item;
-};
-
-class QSGKeysAttached : public QObject, public QSGItemKeyFilter
-{
-    Q_OBJECT
-    Q_DECLARE_PRIVATE(QSGKeysAttached)
-
-    Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
-    Q_PROPERTY(QDeclarativeListProperty<QSGItem> forwardTo READ forwardTo)
-    Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged)
-
-    Q_ENUMS(Priority)
-
-public:
-    QSGKeysAttached(QObject *parent=0);
-    ~QSGKeysAttached();
-
-    bool enabled() const { Q_D(const QSGKeysAttached); return d->enabled; }
-    void setEnabled(bool enabled) {
-        Q_D(QSGKeysAttached);
-        if (enabled != d->enabled) {
-            d->enabled = enabled;
-            emit enabledChanged();
-        }
-    }
-
-    enum Priority { BeforeItem, AfterItem};
-    Priority priority() const;
-    void setPriority(Priority);
-
-    QDeclarativeListProperty<QSGItem> forwardTo() {
-        Q_D(QSGKeysAttached);
-        return QDeclarativeListProperty<QSGItem>(this, d->targets);
-    }
-
-    virtual void componentComplete();
-
-    static QSGKeysAttached *qmlAttachedProperties(QObject *);
-
-Q_SIGNALS:
-    void enabledChanged();
-    void priorityChanged();
-    void pressed(QSGKeyEvent *event);
-    void released(QSGKeyEvent *event);
-    void digit0Pressed(QSGKeyEvent *event);
-    void digit1Pressed(QSGKeyEvent *event);
-    void digit2Pressed(QSGKeyEvent *event);
-    void digit3Pressed(QSGKeyEvent *event);
-    void digit4Pressed(QSGKeyEvent *event);
-    void digit5Pressed(QSGKeyEvent *event);
-    void digit6Pressed(QSGKeyEvent *event);
-    void digit7Pressed(QSGKeyEvent *event);
-    void digit8Pressed(QSGKeyEvent *event);
-    void digit9Pressed(QSGKeyEvent *event);
-
-    void leftPressed(QSGKeyEvent *event);
-    void rightPressed(QSGKeyEvent *event);
-    void upPressed(QSGKeyEvent *event);
-    void downPressed(QSGKeyEvent *event);
-    void tabPressed(QSGKeyEvent *event);
-    void backtabPressed(QSGKeyEvent *event);
-
-    void asteriskPressed(QSGKeyEvent *event);
-    void numberSignPressed(QSGKeyEvent *event);
-    void escapePressed(QSGKeyEvent *event);
-    void returnPressed(QSGKeyEvent *event);
-    void enterPressed(QSGKeyEvent *event);
-    void deletePressed(QSGKeyEvent *event);
-    void spacePressed(QSGKeyEvent *event);
-    void backPressed(QSGKeyEvent *event);
-    void cancelPressed(QSGKeyEvent *event);
-    void selectPressed(QSGKeyEvent *event);
-    void yesPressed(QSGKeyEvent *event);
-    void noPressed(QSGKeyEvent *event);
-    void context1Pressed(QSGKeyEvent *event);
-    void context2Pressed(QSGKeyEvent *event);
-    void context3Pressed(QSGKeyEvent *event);
-    void context4Pressed(QSGKeyEvent *event);
-    void callPressed(QSGKeyEvent *event);
-    void hangupPressed(QSGKeyEvent *event);
-    void flipPressed(QSGKeyEvent *event);
-    void menuPressed(QSGKeyEvent *event);
-    void volumeUpPressed(QSGKeyEvent *event);
-    void volumeDownPressed(QSGKeyEvent *event);
-
-private:
-    virtual void keyPressed(QKeyEvent *event, bool post);
-    virtual void keyReleased(QKeyEvent *event, bool post);
-    virtual void inputMethodEvent(QInputMethodEvent *, bool post);
-    virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
-
-    const QByteArray keyToSignal(int key) {
-        QByteArray keySignal;
-        if (key >= Qt::Key_0 && key <= Qt::Key_9) {
-            keySignal = "digit0Pressed";
-            keySignal[5] = '0' + (key - Qt::Key_0);
-        } else {
-            int i = 0;
-            while (sigMap[i].key && sigMap[i].key != key)
-                ++i;
-            keySignal = sigMap[i].sig;
-        }
-        return keySignal;
-    }
-
-    struct SigMap {
-        int key;
-        const char *sig;
-    };
-
-    static const SigMap sigMap[];
-};
-
-QSGTransformNode *QSGItemPrivate::itemNode()
-{
-    if (!itemNodeInstance) {
-        itemNodeInstance = createTransformNode();
-        itemNodeInstance->setFlag(QSGNode::OwnedByParent, false);
-#ifdef QML_RUNTIME_TESTING
-        Q_Q(QSGItem);
-        itemNodeInstance->description = QString::fromLatin1("QSGItem(%1)").arg(QString::fromLatin1(q->metaObject()->className()));
-#endif
-    }
-    return itemNodeInstance;
-}
-
-QSGNode *QSGItemPrivate::childContainerNode()
-{
-    if (!groupNode) {
-        groupNode = new QSGNode();
-        if (rootNode)
-            rootNode->appendChildNode(groupNode);
-        else if (clipNode)
-            clipNode->appendChildNode(groupNode);
-        else if (opacityNode)
-            opacityNode->appendChildNode(groupNode);
-        else
-            itemNode()->appendChildNode(groupNode);
-        groupNode->setFlag(QSGNode::ChildrenDoNotOverlap, childrenDoNotOverlap);
-#ifdef QML_RUNTIME_TESTING
-        groupNode->description = QLatin1String("group");
-#endif
-    }
-    return groupNode;
-}
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSGItemPrivate::ChangeTypes);
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGKeysAttached)
-QML_DECLARE_TYPEINFO(QSGKeysAttached, QML_HAS_ATTACHED_PROPERTIES)
-QML_DECLARE_TYPE(QSGKeyNavigationAttached)
-QML_DECLARE_TYPEINFO(QSGKeyNavigationAttached, QML_HAS_ATTACHED_PROPERTIES)
-QML_DECLARE_TYPE(QSGLayoutMirroringAttached)
-QML_DECLARE_TYPEINFO(QSGLayoutMirroringAttached, QML_HAS_ATTACHED_PROPERTIES)
-
-#endif // QSGITEM_P_H
diff --git a/src/declarative/items/qsgitemchangelistener_p.h b/src/declarative/items/qsgitemchangelistener_p.h
deleted file mode 100644 (file)
index 3ea0c9c..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
-/****************************************************************************
-**
-** 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 QSGITEMCHANGELISTENER_P_H
-#define QSGITEMCHANGELISTENER_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
-
-class QRectF;
-class QSGItem;
-class QSGAnchorsPrivate;
-class QSGItemChangeListener
-{
-public:
-    virtual void itemGeometryChanged(QSGItem *, const QRectF &, const QRectF &) {}
-    virtual void itemSiblingOrderChanged(QSGItem *) {}
-    virtual void itemVisibilityChanged(QSGItem *) {}
-    virtual void itemOpacityChanged(QSGItem *) {}
-    virtual void itemDestroyed(QSGItem *) {}
-    virtual void itemChildAdded(QSGItem *, QSGItem *) {}
-    virtual void itemChildRemoved(QSGItem *, QSGItem *) {}
-    virtual void itemParentChanged(QSGItem *, QSGItem *) {}
-    virtual void itemRotationChanged(QSGItem *) {}
-
-    virtual QSGAnchorsPrivate *anchorPrivate() { return 0; }
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGITEMCHANGELISTENER_P_H
diff --git a/src/declarative/items/qsgitemsmodule.cpp b/src/declarative/items/qsgitemsmodule.cpp
deleted file mode 100644 (file)
index bb471dd..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-/****************************************************************************
-**
-** 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 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 "qsgitemsmodule_p.h"
-
-#include "qsgitem.h"
-#include "qsgitem_p.h"
-#include "qsgevents_p_p.h"
-#include "qsgrectangle_p.h"
-#include "qsgfocusscope_p.h"
-#include "qsgtext_p.h"
-#include "qsgtextinput_p.h"
-#include "qsgtextedit_p.h"
-#include "qsgimage_p.h"
-#include "qsgborderimage_p.h"
-#include "qsgscalegrid_p_p.h"
-#include "qsgmousearea_p.h"
-#include "qsgpincharea_p.h"
-#include "qsgflickable_p.h"
-#include "qsgflickable_p_p.h"
-#include "qsglistview_p.h"
-#include "qsgvisualitemmodel_p.h"
-#include "qsgvisualdatamodel_p.h"
-#include "qsggridview_p.h"
-#include "qsgpathview_p.h"
-#include <private/qdeclarativepath_p.h>
-#include <private/qdeclarativepathinterpolator_p.h>
-#include "qsgpositioners_p.h"
-#include "qsgrepeater_p.h"
-#include "qsgloader_p.h"
-#include "qsganimatedimage_p.h"
-#include "qsgflipable_p.h"
-#include "qsgtranslate_p.h"
-#include "qsgstateoperations_p.h"
-#include "qsganimation_p.h"
-#include <private/qsgshadereffect_p.h>
-#include <private/qsgshadereffectsource_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 "qsgdrag_p.h"
-#include "qsgdroparea_p.h"
-
-static QDeclarativePrivate::AutoParentResult qsgitem_autoParent(QObject *obj, QObject *parent)
-{
-    QSGItem *item = qobject_cast<QSGItem *>(obj);
-    if (!item)
-        return QDeclarativePrivate::IncompatibleObject;
-
-    QSGItem *parentItem = qobject_cast<QSGItem *>(parent);
-    if (!parentItem)
-        return QDeclarativePrivate::IncompatibleParent;
-
-    item->setParentItem(parentItem);
-    return QDeclarativePrivate::Parented;
-}
-
-static void qt_sgitems_defineModule(const char *uri, int major, int minor)
-{
-    QDeclarativePrivate::RegisterAutoParent autoparent = { 0, &qsgitem_autoParent };
-    QDeclarativePrivate::qmlregister(QDeclarativePrivate::AutoParentRegistration, &autoparent);
-
-#ifdef QT_NO_MOVIE
-    qmlRegisterTypeNotAvailable(uri,major,minor,"AnimatedImage", qApp->translate("QSGAnimatedImage","Qt was built without support for QMovie"));
-#else
-    qmlRegisterType<QSGAnimatedImage>(uri,major,minor,"AnimatedImage");
-#endif
-    qmlRegisterType<QSGBorderImage>(uri,major,minor,"BorderImage");
-    qmlRegisterType<QSGColumn>(uri,major,minor,"Column");
-    qmlRegisterType<QSGFlickable>(uri,major,minor,"Flickable");
-    qmlRegisterType<QSGFlipable>(uri,major,minor,"Flipable");
-    qmlRegisterType<QSGFlow>(uri,major,minor,"Flow");
-//    qmlRegisterType<QDeclarativeFocusPanel>(uri,major,minor,"FocusPanel");
-    qmlRegisterType<QSGFocusScope>(uri,major,minor,"FocusScope");
-    qmlRegisterType<QSGGradient>(uri,major,minor,"Gradient");
-    qmlRegisterType<QSGGradientStop>(uri,major,minor,"GradientStop");
-    qmlRegisterType<QSGGrid>(uri,major,minor,"Grid");
-    qmlRegisterType<QSGGridView>(uri,major,minor,"GridView");
-    qmlRegisterType<QSGImage>(uri,major,minor,"Image");
-    qmlRegisterType<QSGItem>(uri,major,minor,"Item");
-    qmlRegisterType<QSGListView>(uri,major,minor,"ListView");
-    qmlRegisterType<QSGLoader>(uri,major,minor,"Loader");
-    qmlRegisterType<QSGMouseArea>(uri,major,minor,"MouseArea");
-    qmlRegisterType<QDeclarativePath>(uri,major,minor,"Path");
-    qmlRegisterType<QDeclarativePathAttribute>(uri,major,minor,"PathAttribute");
-    qmlRegisterType<QDeclarativePathCubic>(uri,major,minor,"PathCubic");
-    qmlRegisterType<QDeclarativePathLine>(uri,major,minor,"PathLine");
-    qmlRegisterType<QDeclarativePathPercent>(uri,major,minor,"PathPercent");
-    qmlRegisterType<QDeclarativePathQuad>(uri,major,minor,"PathQuad");
-    qmlRegisterType<QDeclarativePathCatmullRomCurve>("QtQuick",2,0,"PathCurve");
-    qmlRegisterType<QDeclarativePathArc>("QtQuick",2,0,"PathArc");
-    qmlRegisterType<QDeclarativePathSvg>("QtQuick",2,0,"PathSvg");
-    qmlRegisterType<QSGPathView>(uri,major,minor,"PathView");
-    qmlRegisterUncreatableType<QSGBasePositioner>(uri,major,minor,"Positioner",
-                                                  QStringLiteral("Positioner is an abstract type that is only available as an attached property."));
-#ifndef QT_NO_VALIDATOR
-    qmlRegisterType<QIntValidator>(uri,major,minor,"IntValidator");
-    qmlRegisterType<QDoubleValidator>(uri,major,minor,"DoubleValidator");
-    qmlRegisterType<QRegExpValidator>(uri,major,minor,"RegExpValidator");
-#endif
-    qmlRegisterType<QSGRectangle>(uri,major,minor,"Rectangle");
-    qmlRegisterType<QSGRepeater>(uri,major,minor,"Repeater");
-    qmlRegisterType<QSGRow>(uri,major,minor,"Row");
-    qmlRegisterType<QSGTranslate>(uri,major,minor,"Translate");
-    qmlRegisterType<QSGRotation>(uri,major,minor,"Rotation");
-    qmlRegisterType<QSGScale>(uri,major,minor,"Scale");
-    qmlRegisterType<QSGText>(uri,major,minor,"Text");
-    qmlRegisterType<QSGTextEdit>(uri,major,minor,"TextEdit");
-    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>();
-    qmlRegisterType<QSGKeyEvent>();
-    qmlRegisterType<QSGMouseEvent>();
-    qmlRegisterType<QSGTransform>();
-    qmlRegisterType<QDeclarativePathElement>();
-    qmlRegisterType<QDeclarativeCurve>();
-    qmlRegisterType<QSGScaleGrid>();
-    qmlRegisterType<QSGTextLine>();
-#ifndef QT_NO_VALIDATOR
-    qmlRegisterType<QValidator>();
-#endif
-    qmlRegisterType<QSGVisualModel>();
-    qmlRegisterType<QSGPen>();
-    qmlRegisterType<QSGFlickableVisibleArea>();
-    qRegisterMetaType<QSGAnchorLine>("QSGAnchorLine");
-
-    qmlRegisterUncreatableType<QSGKeyNavigationAttached>(uri,major,minor,"KeyNavigation",QSGKeyNavigationAttached::tr("KeyNavigation is only available via attached properties"));
-    qmlRegisterUncreatableType<QSGKeysAttached>(uri,major,minor,"Keys",QSGKeysAttached::tr("Keys is only available via attached properties"));
-    qmlRegisterUncreatableType<QSGLayoutMirroringAttached>(uri,major,minor,"LayoutMirroring", QSGLayoutMirroringAttached::tr("LayoutMirroring is only available via attached properties"));
-
-    qmlRegisterType<QSGPinchArea>(uri,major,minor,"PinchArea");
-    qmlRegisterType<QSGPinch>(uri,major,minor,"Pinch");
-    qmlRegisterType<QSGPinchEvent>();
-
-    qmlRegisterType<QSGShaderEffectItem>("QtQuick", 2, 0, "ShaderEffectItem"); // TODO: Remove after grace period.
-    qmlRegisterType<QSGShaderEffect>("QtQuick", 2, 0, "ShaderEffect");
-    qmlRegisterType<QSGShaderEffectSource>("QtQuick", 2, 0, "ShaderEffectSource");
-    qmlRegisterUncreatableType<QSGShaderEffectMesh>("QtQuick", 2, 0, "ShaderEffectMesh", QSGShaderEffectMesh::tr("Cannot create instance of abstract class ShaderEffectMesh."));
-    qmlRegisterType<QSGGridMesh>("QtQuick", 2, 0, "GridMesh");
-
-    qmlRegisterUncreatableType<QSGPaintedItem>("QtQuick", 2, 0, "PaintedItem", QSGPaintedItem::tr("Cannot create instance of abstract class PaintedItem"));
-
-    qmlRegisterType<QSGCanvasItem>("QtQuick", 2, 0, "Canvas");
-
-    qmlRegisterType<QSGSprite>("QtQuick", 2, 0, "Sprite");
-    qmlRegisterType<QSGSpriteImage>("QtQuick", 2, 0, "SpriteImage");
-
-    qmlRegisterType<QSGParentChange>(uri, major, minor,"ParentChange");
-    qmlRegisterType<QSGAnchorChanges>(uri, major, minor,"AnchorChanges");
-    qmlRegisterType<QSGAnchorSet>();
-    qmlRegisterType<QSGAnchorAnimation>(uri, major, minor,"AnchorAnimation");
-    qmlRegisterType<QSGParentAnimation>(uri, major, minor,"ParentAnimation");
-    qmlRegisterType<QSGPathAnimation>("QtQuick",2,0,"PathAnimation");
-    qmlRegisterType<QDeclarativePathInterpolator>("QtQuick",2,0,"PathInterpolator");
-
-    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()
-{
-    static bool initialized = false;
-    if (initialized)
-        return;
-    initialized = true;
-
-    // XXX todo -  Remove before final integration...
-    QByteArray mode = qgetenv("QMLSCENE_IMPORT_NAME");
-    QByteArray name = "QtQuick";
-    int majorVersion = 2;
-    int minorVersion = 0;
-    if (mode == "quick1") {
-        majorVersion = 1;
-    } else if (mode == "qt") {
-        name = "Qt";
-        majorVersion = 4;
-        minorVersion = 7;
-    }
-
-    qt_sgitems_defineModule(name, majorVersion, minorVersion);
-}
-
diff --git a/src/declarative/items/qsgitemsmodule_p.h b/src/declarative/items/qsgitemsmodule_p.h
deleted file mode 100644 (file)
index b030669..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
-/****************************************************************************
-**
-** 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 QSGITEMSMODULE_P_H
-#define QSGITEMSMODULE_P_H
-
-#include <qdeclarative.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGItemsModule
-{
-public:
-    static void defineModule();
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSGITEMSMODULE_P_H
-
diff --git a/src/declarative/items/qsgitemview.cpp b/src/declarative/items/qsgitemview.cpp
deleted file mode 100644 (file)
index 5b95097..0000000
+++ /dev/null
@@ -1,1676 +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 "qsgitemview_p_p.h"
-
-QT_BEGIN_NAMESPACE
-
-
-FxViewItem::FxViewItem(QSGItem *i, bool own)
-    : item(i), ownItem(own), index(-1)
-{
-}
-
-FxViewItem::~FxViewItem()
-{
-    if (ownItem && item) {
-        item->setParentItem(0);
-        item->deleteLater();
-        item = 0;
-    }
-}
-
-
-QSGItemViewChangeSet::QSGItemViewChangeSet()
-    : active(false)
-{
-    reset();
-}
-
-bool QSGItemViewChangeSet::hasPendingChanges() const
-{
-    return !pendingChanges.isEmpty();
-}
-
-void QSGItemViewChangeSet::applyChanges(const QDeclarativeChangeSet &changeSet)
-{
-    pendingChanges.apply(changeSet);
-
-    int moveId = -1;
-    int moveOffset;
-
-    foreach (const QDeclarativeChangeSet::Remove &r, changeSet.removes()) {
-        itemCount -= r.count;
-        if (moveId == -1 && newCurrentIndex >= r.index + r.count) {
-            newCurrentIndex -= r.count;
-            currentChanged = true;
-        } else if (moveId == -1 && newCurrentIndex >= r.index && newCurrentIndex < r.index + r.count) {
-            // current item has been removed.
-            if (r.isMove()) {
-                moveId = r.moveId;
-                moveOffset = newCurrentIndex - r.index;
-            } else {
-                currentRemoved = true;
-                newCurrentIndex = -1;
-                if (itemCount)
-                    newCurrentIndex = qMin(r.index, itemCount - 1);
-            }
-            currentChanged = true;
-        }
-    }
-    foreach (const QDeclarativeChangeSet::Insert &i, changeSet.inserts()) {
-        if (moveId == -1) {
-            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;
-    }
-}
-
-void QSGItemViewChangeSet::prepare(int currentIndex, int count)
-{
-    if (active)
-        return;
-    reset();
-    active = true;
-    itemCount = count;
-    newCurrentIndex = currentIndex;
-}
-
-void QSGItemViewChangeSet::reset()
-{
-    itemCount = 0;
-    newCurrentIndex = -1;
-    pendingChanges.clear();
-    removedItems.clear();
-    active = false;
-    currentChanged = false;
-    currentRemoved = false;
-}
-
-
-QSGItemView::QSGItemView(QSGFlickablePrivate &dd, QSGItem *parent)
-    : QSGFlickable(dd, parent)
-{
-    Q_D(QSGItemView);
-    d->init();
-}
-
-QSGItemView::~QSGItemView()
-{
-    Q_D(QSGItemView);
-    d->clear();
-    if (d->ownModel)
-        delete d->model;
-    delete d->header;
-    delete d->footer;
-}
-
-
-QSGItem *QSGItemView::currentItem() const
-{
-    Q_D(const QSGItemView);
-    if (!d->currentItem)
-        return 0;
-    const_cast<QSGItemViewPrivate*>(d)->applyPendingChanges();
-    return d->currentItem->item;
-}
-
-QVariant QSGItemView::model() const
-{
-    Q_D(const QSGItemView);
-    return d->modelVariant;
-}
-
-void QSGItemView::setModel(const QVariant &model)
-{
-    Q_D(QSGItemView);
-    if (d->modelVariant == model)
-        return;
-    if (d->model) {
-        disconnect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
-                this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
-        disconnect(d->model, SIGNAL(createdItem(int,QSGItem*)), this, SLOT(createdItem(int,QSGItem*)));
-        disconnect(d->model, SIGNAL(destroyingItem(QSGItem*)), this, SLOT(destroyingItem(QSGItem*)));
-    }
-
-    QSGVisualModel *oldModel = d->model;
-
-    d->clear();
-    d->setPosition(d->contentStartPosition());
-    d->model = 0;
-    d->modelVariant = model;
-
-    QObject *object = qvariant_cast<QObject*>(model);
-    QSGVisualModel *vim = 0;
-    if (object && (vim = qobject_cast<QSGVisualModel *>(object))) {
-        if (d->ownModel) {
-            delete oldModel;
-            d->ownModel = false;
-        }
-        d->model = vim;
-    } else {
-        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;
-        }
-        if (QSGVisualDataModel *dataModel = qobject_cast<QSGVisualDataModel*>(d->model))
-            dataModel->setModel(model);
-    }
-
-    if (d->model) {
-        d->bufferMode = QSGItemViewPrivate::BufferBefore | QSGItemViewPrivate::BufferAfter;
-        if (isComponentComplete()) {
-            updateSections();
-            d->refill();
-            if ((d->currentIndex >= d->model->count() || d->currentIndex < 0) && !d->currentIndexCleared) {
-                setCurrentIndex(0);
-            } else {
-                d->moveReason = QSGItemViewPrivate::SetIndex;
-                d->updateCurrent(d->currentIndex);
-                if (d->highlight && d->currentItem) {
-                    if (d->autoHighlight)
-                        d->resetHighlightPosition();
-                    d->updateTrackedItem();
-                }
-                d->moveReason = QSGItemViewPrivate::Other;
-            }
-            d->updateViewport();
-        }
-        connect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
-                this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
-        connect(d->model, SIGNAL(createdItem(int,QSGItem*)), this, SLOT(createdItem(int,QSGItem*)));
-        connect(d->model, SIGNAL(destroyingItem(QSGItem*)), this, SLOT(destroyingItem(QSGItem*)));
-        emit countChanged();
-    }
-    emit modelChanged();
-}
-
-QDeclarativeComponent *QSGItemView::delegate() const
-{
-    Q_D(const QSGItemView);
-    if (d->model) {
-        if (QSGVisualDataModel *dataModel = qobject_cast<QSGVisualDataModel*>(d->model))
-            return dataModel->delegate();
-    }
-
-    return 0;
-}
-
-void QSGItemView::setDelegate(QDeclarativeComponent *delegate)
-{
-    Q_D(QSGItemView);
-    if (delegate == this->delegate())
-        return;
-    if (!d->ownModel) {
-        d->model = new QSGVisualDataModel(qmlContext(this));
-        d->ownModel = true;
-    }
-    if (QSGVisualDataModel *dataModel = qobject_cast<QSGVisualDataModel*>(d->model)) {
-        int oldCount = dataModel->count();
-        dataModel->setDelegate(delegate);
-        if (isComponentComplete()) {
-            for (int i = 0; i < d->visibleItems.count(); ++i)
-                d->releaseItem(d->visibleItems.at(i));
-            d->visibleItems.clear();
-            d->releaseItem(d->currentItem);
-            d->currentItem = 0;
-            updateSections();
-            d->refill();
-            d->moveReason = QSGItemViewPrivate::SetIndex;
-            d->updateCurrent(d->currentIndex);
-            if (d->highlight && d->currentItem) {
-                if (d->autoHighlight)
-                    d->resetHighlightPosition();
-                d->updateTrackedItem();
-            }
-            d->moveReason = QSGItemViewPrivate::Other;
-            d->updateViewport();
-        }
-        if (oldCount != dataModel->count())
-            emit countChanged();
-    }
-    emit delegateChanged();
-}
-
-
-int QSGItemView::count() const
-{
-    Q_D(const QSGItemView);
-    if (!d->model)
-        return 0;
-    const_cast<QSGItemViewPrivate*>(d)->applyPendingChanges();
-    return d->model->count();
-}
-
-int QSGItemView::currentIndex() const
-{
-    Q_D(const QSGItemView);
-    const_cast<QSGItemViewPrivate*>(d)->applyPendingChanges();
-    return d->currentIndex;
-}
-
-void QSGItemView::setCurrentIndex(int index)
-{
-    Q_D(QSGItemView);
-    if (d->requestedIndex >= 0)  // currently creating item
-        return;
-    d->currentIndexCleared = (index == -1);
-
-    d->applyPendingChanges();
-    if (index == d->currentIndex)
-        return;
-    if (isComponentComplete() && d->isValid()) {
-        d->moveReason = QSGItemViewPrivate::SetIndex;
-        d->updateCurrent(index);
-    } else if (d->currentIndex != index) {
-        d->currentIndex = index;
-        emit currentIndexChanged();
-    }
-}
-
-
-bool QSGItemView::isWrapEnabled() const
-{
-    Q_D(const QSGItemView);
-    return d->wrap;
-}
-
-void QSGItemView::setWrapEnabled(bool wrap)
-{
-    Q_D(QSGItemView);
-    if (d->wrap == wrap)
-        return;
-    d->wrap = wrap;
-    emit keyNavigationWrapsChanged();
-}
-
-int QSGItemView::cacheBuffer() const
-{
-    Q_D(const QSGItemView);
-    return d->buffer;
-}
-
-void QSGItemView::setCacheBuffer(int b)
-{
-    Q_D(QSGItemView);
-    if (d->buffer != b) {
-        d->buffer = b;
-        if (isComponentComplete()) {
-            d->bufferMode = QSGItemViewPrivate::BufferBefore | QSGItemViewPrivate::BufferAfter;
-            d->refill();
-        }
-        emit cacheBufferChanged();
-    }
-}
-
-
-Qt::LayoutDirection QSGItemView::layoutDirection() const
-{
-    Q_D(const QSGItemView);
-    return d->layoutDirection;
-}
-
-void QSGItemView::setLayoutDirection(Qt::LayoutDirection layoutDirection)
-{
-    Q_D(QSGItemView);
-    if (d->layoutDirection != layoutDirection) {
-        d->layoutDirection = layoutDirection;
-        d->regenerate();
-        emit layoutDirectionChanged();
-        emit effectiveLayoutDirectionChanged();
-    }
-}
-
-Qt::LayoutDirection QSGItemView::effectiveLayoutDirection() const
-{
-    Q_D(const QSGItemView);
-    if (d->effectiveLayoutMirror)
-        return d->layoutDirection == Qt::RightToLeft ? Qt::LeftToRight : Qt::RightToLeft;
-    else
-        return d->layoutDirection;
-}
-
-
-QDeclarativeComponent *QSGItemView::header() const
-{
-    Q_D(const QSGItemView);
-    return d->headerComponent;
-}
-
-QSGItem *QSGItemView::headerItem() const
-{
-    Q_D(const QSGItemView);
-    const_cast<QSGItemViewPrivate*>(d)->applyPendingChanges();
-    return d->header ? d->header->item : 0;
-}
-
-void QSGItemView::setHeader(QDeclarativeComponent *headerComponent)
-{
-    Q_D(QSGItemView);
-    if (d->headerComponent != headerComponent) {
-        d->applyPendingChanges();
-        delete d->header;
-        d->header = 0;
-        d->headerComponent = headerComponent;
-
-        d->markExtentsDirty();
-
-        if (isComponentComplete()) {
-            d->updateHeader();
-            d->updateFooter();
-            d->updateViewport();
-            d->fixupPosition();
-        } else {
-            emit headerItemChanged();
-        }
-        emit headerChanged();
-    }
-}
-
-QDeclarativeComponent *QSGItemView::footer() const
-{
-    Q_D(const QSGItemView);
-    return d->footerComponent;
-}
-
-QSGItem *QSGItemView::footerItem() const
-{
-    Q_D(const QSGItemView);
-    const_cast<QSGItemViewPrivate*>(d)->applyPendingChanges();
-    return d->footer ? d->footer->item : 0;
-}
-
-void QSGItemView::setFooter(QDeclarativeComponent *footerComponent)
-{
-    Q_D(QSGItemView);
-    if (d->footerComponent != footerComponent) {
-        d->applyPendingChanges();
-        delete d->footer;
-        d->footer = 0;
-        d->footerComponent = footerComponent;
-
-        if (isComponentComplete()) {
-            d->updateFooter();
-            d->updateViewport();
-            d->fixupPosition();
-        } else {
-            emit footerItemChanged();
-        }
-        emit footerChanged();
-    }
-}
-
-QDeclarativeComponent *QSGItemView::highlight() const
-{
-    Q_D(const QSGItemView);
-    const_cast<QSGItemViewPrivate*>(d)->applyPendingChanges();
-    return d->highlightComponent;
-}
-
-void QSGItemView::setHighlight(QDeclarativeComponent *highlightComponent)
-{
-    Q_D(QSGItemView);
-    if (highlightComponent != d->highlightComponent) {
-        d->applyPendingChanges();
-        d->highlightComponent = highlightComponent;
-        d->createHighlight();
-        if (d->currentItem)
-            d->updateHighlight();
-        emit highlightChanged();
-    }
-}
-
-QSGItem *QSGItemView::highlightItem() const
-{
-    Q_D(const QSGItemView);
-    const_cast<QSGItemViewPrivate*>(d)->applyPendingChanges();
-    return d->highlight ? d->highlight->item : 0;
-}
-
-bool QSGItemView::highlightFollowsCurrentItem() const
-{
-    Q_D(const QSGItemView);
-    return d->autoHighlight;
-}
-
-void QSGItemView::setHighlightFollowsCurrentItem(bool autoHighlight)
-{
-    Q_D(QSGItemView);
-    if (d->autoHighlight != autoHighlight) {
-        d->autoHighlight = autoHighlight;
-        if (autoHighlight)
-            d->updateHighlight();
-        emit highlightFollowsCurrentItemChanged();
-    }
-}
-
-QSGItemView::HighlightRangeMode QSGItemView::highlightRangeMode() const
-{
-    Q_D(const QSGItemView);
-    return static_cast<QSGItemView::HighlightRangeMode>(d->highlightRange);
-}
-
-void QSGItemView::setHighlightRangeMode(HighlightRangeMode mode)
-{
-    Q_D(QSGItemView);
-    if (d->highlightRange == mode)
-        return;
-    d->highlightRange = mode;
-    d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
-    emit highlightRangeModeChanged();
-}
-
-//###Possibly rename these properties, since they are very useful even without a highlight?
-qreal QSGItemView::preferredHighlightBegin() const
-{
-    Q_D(const QSGItemView);
-    return d->highlightRangeStart;
-}
-
-void QSGItemView::setPreferredHighlightBegin(qreal start)
-{
-    Q_D(QSGItemView);
-    d->highlightRangeStartValid = true;
-    if (d->highlightRangeStart == start)
-        return;
-    d->highlightRangeStart = start;
-    d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
-    emit preferredHighlightBeginChanged();
-}
-
-void QSGItemView::resetPreferredHighlightBegin()
-{
-    Q_D(QSGItemView);
-    d->highlightRangeStartValid = false;
-    if (d->highlightRangeStart == 0)
-        return;
-    d->highlightRangeStart = 0;
-    emit preferredHighlightBeginChanged();
-}
-
-qreal QSGItemView::preferredHighlightEnd() const
-{
-    Q_D(const QSGItemView);
-    return d->highlightRangeEnd;
-}
-
-void QSGItemView::setPreferredHighlightEnd(qreal end)
-{
-    Q_D(QSGItemView);
-    d->highlightRangeEndValid = true;
-    if (d->highlightRangeEnd == end)
-        return;
-    d->highlightRangeEnd = end;
-    d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
-    emit preferredHighlightEndChanged();
-}
-
-void QSGItemView::resetPreferredHighlightEnd()
-{
-    Q_D(QSGItemView);
-    d->highlightRangeEndValid = false;
-    if (d->highlightRangeEnd == 0)
-        return;
-    d->highlightRangeEnd = 0;
-    emit preferredHighlightEndChanged();
-}
-
-int QSGItemView::highlightMoveDuration() const
-{
-    Q_D(const QSGItemView);
-    return d->highlightMoveDuration;
-}
-
-void QSGItemView::setHighlightMoveDuration(int duration)
-{
-    Q_D(QSGItemView);
-    if (d->highlightMoveDuration != duration) {
-        d->highlightMoveDuration = duration;
-        emit highlightMoveDurationChanged();
-    }
-}
-
-void QSGItemViewPrivate::positionViewAtIndex(int index, int mode)
-{
-    Q_Q(QSGItemView);
-    if (!isValid())
-        return;
-    if (mode < QSGItemView::Beginning || mode > QSGItemView::Contain)
-        return;
-
-    applyPendingChanges();
-    int idx = qMax(qMin(index, model->count()-1), 0);
-
-    qreal pos = isContentFlowReversed() ? -position() - size() : position();
-    FxViewItem *item = visibleItem(idx);
-    qreal maxExtent;
-    if (layoutOrientation() == Qt::Vertical)
-        maxExtent = -q->maxYExtent();
-    else
-        maxExtent = isContentFlowReversed() ? q->minXExtent()-size(): -q->maxXExtent();
-    if (!item) {
-        int itemPos = positionAt(idx);
-        changedVisibleIndex(idx);
-        // save the currently visible items in case any of them end up visible again
-        QList<FxViewItem *> oldVisible = visibleItems;
-        visibleItems.clear();
-        setPosition(qMin(qreal(itemPos), maxExtent));
-        // now release the reference to all the old visible items.
-        for (int i = 0; i < oldVisible.count(); ++i)
-            releaseItem(oldVisible.at(i));
-        item = visibleItem(idx);
-    }
-    if (item) {
-        const qreal itemPos = item->position();
-        switch (mode) {
-        case QSGItemView::Beginning:
-            pos = itemPos;
-            if (index < 0 && header)
-                pos -= headerSize();
-            break;
-        case QSGItemView::Center:
-            pos = itemPos - (size() - item->size())/2;
-            break;
-        case QSGItemView::End:
-            pos = itemPos - size() + item->size();
-            if (index >= model->count() && footer)
-                pos += footerSize();
-            break;
-        case QSGItemView::Visible:
-            if (itemPos > pos + size())
-                pos = itemPos - size() + item->size();
-            else if (item->endPosition() <= pos)
-                pos = itemPos;
-            break;
-        case QSGItemView::Contain:
-            if (item->endPosition() >= pos + size())
-                pos = itemPos - size() + item->size();
-            if (itemPos < pos)
-                pos = itemPos;
-        }
-        pos = qMin(pos, maxExtent);
-        qreal minExtent;
-        if (layoutOrientation() == Qt::Vertical)
-            minExtent = -q->minYExtent();
-        else
-            minExtent = isContentFlowReversed() ? q->maxXExtent()-size(): -q->minXExtent();
-        pos = qMax(pos, minExtent);
-        moveReason = QSGItemViewPrivate::Other;
-        q->cancelFlick();
-        setPosition(pos);
-
-        if (highlight) {
-            if (autoHighlight)
-                resetHighlightPosition();
-            updateHighlight();
-        }
-    }
-    fixupPosition();
-}
-
-void QSGItemView::positionViewAtIndex(int index, int mode)
-{
-    Q_D(QSGItemView);
-    if (!d->isValid() || index < 0 || index >= d->model->count())
-        return;
-    d->positionViewAtIndex(index, mode);
-}
-
-
-void QSGItemView::positionViewAtBeginning()
-{
-    Q_D(QSGItemView);
-    if (!d->isValid())
-        return;
-    d->positionViewAtIndex(-1, Beginning);
-}
-
-void QSGItemView::positionViewAtEnd()
-{
-    Q_D(QSGItemView);
-    if (!d->isValid())
-        return;
-    d->positionViewAtIndex(d->model->count(), End);
-}
-
-int QSGItemView::indexAt(qreal x, qreal y) const
-{
-    Q_D(const QSGItemView);
-    for (int i = 0; i < d->visibleItems.count(); ++i) {
-        const FxViewItem *item = d->visibleItems.at(i);
-        if (item->contains(x, y))
-            return item->index;
-    }
-
-    return -1;
-}
-
-void QSGItemViewPrivate::applyPendingChanges()
-{
-    Q_Q(QSGItemView);
-    if (q->isComponentComplete() && currentChanges.hasPendingChanges())
-        layout();
-}
-
-// for debugging only
-void QSGItemViewPrivate::checkVisible() const
-{
-    int skip = 0;
-    for (int i = 0; i < visibleItems.count(); ++i) {
-        FxViewItem *item = visibleItems.at(i);
-        if (item->index == -1) {
-            ++skip;
-        } else if (item->index != visibleIndex + i - skip) {
-            qFatal("index %d %d %d", visibleIndex, i, item->index);
-        }
-    }
-}
-
-void QSGItemViewPrivate::itemGeometryChanged(QSGItem *item, const QRectF &newGeometry, const QRectF &oldGeometry)
-{
-    Q_Q(QSGItemView);
-    QSGFlickablePrivate::itemGeometryChanged(item, newGeometry, oldGeometry);
-    if (!q->isComponentComplete())
-        return;
-
-    if (header && header->item == item) {
-        updateHeader();
-        markExtentsDirty();
-        if (!q->isMoving() && !q->isFlicking())
-            fixupPosition();
-    } else if (footer && footer->item == item) {
-        updateFooter();
-        markExtentsDirty();
-        if (!q->isMoving() && !q->isFlicking())
-            fixupPosition();
-    }
-
-    if (currentItem && currentItem->item == item)
-        updateHighlight();
-    if (trackedItem && trackedItem->item == item)
-        q->trackedPositionChanged();
-}
-
-void QSGItemView::destroyRemoved()
-{
-    Q_D(QSGItemView);
-    for (QList<FxViewItem*>::Iterator it = d->visibleItems.begin();
-            it != d->visibleItems.end();) {
-        FxViewItem *item = *it;
-        if (item->index == -1 && item->attached->delayRemove() == false) {
-            d->releaseItem(item);
-            it = d->visibleItems.erase(it);
-        } else {
-            ++it;
-        }
-    }
-
-    // Correct the positioning of the items
-    d->updateSections();
-    d->forceLayout = true;
-    d->layout();
-}
-
-void QSGItemView::modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset)
-{
-    Q_D(QSGItemView);
-    if (reset) {
-        d->moveReason = QSGItemViewPrivate::SetIndex;
-        d->regenerate();
-        if (d->highlight && d->currentItem) {
-            if (d->autoHighlight)
-                d->resetHighlightPosition();
-            d->updateTrackedItem();
-        }
-        d->moveReason = QSGItemViewPrivate::Other;
-
-        emit countChanged();
-    } else {
-        d->currentChanges.prepare(d->currentIndex, d->itemCount);
-        d->currentChanges.applyChanges(changeSet);
-        polish();
-    }
-}
-
-void QSGItemView::createdItem(int index, QSGItem *item)
-{
-    Q_D(QSGItemView);
-    if (d->requestedIndex != index) {
-        item->setParentItem(contentItem());
-        d->unrequestedItems.insert(item, index);
-        d->repositionPackageItemAt(item, index);
-    }
-}
-
-void QSGItemView::destroyingItem(QSGItem *item)
-{
-    Q_D(QSGItemView);
-    d->unrequestedItems.remove(item);
-}
-
-void QSGItemView::animStopped()
-{
-    Q_D(QSGItemView);
-    d->bufferMode = QSGItemViewPrivate::NoBuffer;
-    if (d->haveHighlightRange && d->highlightRange == QSGItemView::StrictlyEnforceRange)
-        d->updateHighlight();
-}
-
-
-void QSGItemView::trackedPositionChanged()
-{
-    Q_D(QSGItemView);
-    if (!d->trackedItem || !d->currentItem)
-        return;
-    if (d->moveReason == QSGItemViewPrivate::SetIndex) {
-        qreal trackedPos = d->trackedItem->position();
-        qreal trackedSize = d->trackedItem->size();
-        if (d->trackedItem != d->currentItem) {
-            trackedSize += d->currentItem->sectionSize();
-        }
-        qreal viewPos = d->isContentFlowReversed() ? -d->position()-d->size() : d->position();
-        qreal pos = viewPos;
-        if (d->haveHighlightRange) {
-            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())
-                    pos = d->startPosition();
-            }
-        } else {
-            qreal trackedEndPos = d->trackedItem->endPosition();
-            qreal toItemPos = d->currentItem->position();
-            qreal toItemEndPos = d->currentItem->endPosition();
-
-            if (d->header && d->showHeaderForIndex(d->currentIndex)) {
-                trackedPos -= d->headerSize();
-                trackedEndPos -= d->headerSize();
-                toItemPos -= d->headerSize();
-                toItemEndPos -= d->headerSize();
-            } else if (d->footer && d->showFooterForIndex(d->currentIndex)) {
-                trackedPos += d->footerSize();
-                trackedEndPos += d->footerSize();
-                toItemPos += d->footerSize();
-                toItemEndPos += d->footerSize();
-            }
-
-            if (trackedPos < viewPos && toItemPos < viewPos) {
-                pos = qMax(trackedPos, toItemPos);
-            } else if (trackedEndPos >= viewPos + d->size()
-                && toItemEndPos >= viewPos + d->size()) {
-                if (trackedEndPos <= toItemEndPos) {
-                    pos = trackedEndPos - d->size();
-                    if (trackedSize > d->size())
-                        pos = trackedPos;
-                } else {
-                    pos = toItemEndPos - d->size();
-                    if (d->currentItem->size() > d->size())
-                        pos = d->currentItem->position();
-                }
-            }
-        }
-        if (viewPos != pos) {
-            cancelFlick();
-            d->calcVelocity = true;
-            d->setPosition(pos);
-            d->calcVelocity = false;
-        }
-    }
-}
-
-void QSGItemView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
-{
-    Q_D(QSGItemView);
-    d->markExtentsDirty();
-    QSGFlickable::geometryChanged(newGeometry, oldGeometry);
-}
-
-
-qreal QSGItemView::minYExtent() const
-{
-    Q_D(const QSGItemView);
-    if (d->layoutOrientation() == Qt::Horizontal)
-        return QSGFlickable::minYExtent();
-
-    if (d->vData.minExtentDirty) {
-        d->minExtent = d->vData.startMargin-d->startPosition();
-        if (d->header)
-            d->minExtent += d->headerSize();
-        if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
-            d->minExtent += d->highlightRangeStart;
-            if (d->visibleItem(0))
-                d->minExtent -= d->visibleItem(0)->sectionSize();
-            d->minExtent = qMax(d->minExtent, -(d->endPositionAt(0) - d->highlightRangeEnd));
-        }
-        d->vData.minExtentDirty = false;
-    }
-
-    return d->minExtent;
-}
-
-qreal QSGItemView::maxYExtent() const
-{
-    Q_D(const QSGItemView);
-    if (d->layoutOrientation() == Qt::Horizontal)
-        return height();
-
-    if (d->vData.maxExtentDirty) {
-        if (!d->model || !d->model->count()) {
-            d->maxExtent = d->header ? -d->headerSize() : 0;
-            d->maxExtent += height();
-        } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
-            d->maxExtent = -(d->positionAt(d->model->count()-1) - d->highlightRangeStart);
-            if (d->highlightRangeEnd != d->highlightRangeStart)
-                d->maxExtent = qMin(d->maxExtent, -(d->endPosition() - d->highlightRangeEnd));
-        } else {
-            d->maxExtent = -(d->endPosition() - height());
-        }
-
-        if (d->footer)
-            d->maxExtent -= d->footerSize();
-        d->maxExtent -= d->vData.endMargin;
-        qreal minY = minYExtent();
-        if (d->maxExtent > minY)
-            d->maxExtent = minY;
-        d->vData.maxExtentDirty = false;
-    }
-    return d->maxExtent;
-}
-
-qreal QSGItemView::minXExtent() const
-{
-    Q_D(const QSGItemView);
-    if (d->layoutOrientation() == Qt::Vertical)
-        return QSGFlickable::minXExtent();
-
-    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->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;
-            if (d->header)
-                d->minExtent += d->headerSize();
-        }
-        if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
-            d->minExtent += highlightStart;
-            d->minExtent = d->isContentFlowReversed()
-                                ? qMin(d->minExtent, endPositionFirstItem + highlightEnd)
-                                : qMax(d->minExtent, -(endPositionFirstItem - highlightEnd));
-        }
-        d->hData.minExtentDirty = false;
-    }
-
-    return d->minExtent;
-}
-
-qreal QSGItemView::maxXExtent() const
-{
-    Q_D(const QSGItemView);
-    if (d->layoutOrientation() == Qt::Vertical)
-        return width();
-
-    if (d->hData.maxExtentDirty) {
-        qreal highlightStart;
-        qreal highlightEnd;
-        qreal lastItemPosition = 0;
-        d->maxExtent = 0;
-        if (d->isContentFlowReversed()) {
-            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;
-            highlightEnd = d->highlightRangeEnd;
-            if (d->model && d->model->count())
-                lastItemPosition = d->positionAt(d->model->count()-1);
-        }
-        if (!d->model || !d->model->count()) {
-            if (!d->isContentFlowReversed())
-                d->maxExtent = d->header ? -d->headerSize() : 0;
-            d->maxExtent += width();
-        } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
-            d->maxExtent = -(lastItemPosition - highlightStart);
-            if (highlightEnd != highlightStart) {
-                d->maxExtent = d->isContentFlowReversed()
-                        ? qMax(d->maxExtent, -(d->endPosition() - highlightEnd))
-                        : qMin(d->maxExtent, -(d->endPosition() - highlightEnd));
-            }
-        } else {
-            d->maxExtent = -(d->endPosition() - width());
-        }
-        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->hData.maxExtentDirty = false;
-    }
-
-    return d->maxExtent;
-}
-
-void QSGItemView::setContentX(qreal pos)
-{
-    Q_D(QSGItemView);
-    // Positioning the view manually should override any current movement state
-    d->moveReason = QSGItemViewPrivate::Other;
-    QSGFlickable::setContentX(pos);
-}
-
-void QSGItemView::setContentY(qreal pos)
-{
-    Q_D(QSGItemView);
-    // Positioning the view manually should override any current movement state
-    d->moveReason = QSGItemViewPrivate::Other;
-    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()
-{
-    Q_D(QSGItemView);
-    QSGFlickable::updatePolish();
-    d->layout();
-}
-
-void QSGItemView::componentComplete()
-{
-    Q_D(QSGItemView);
-    if (d->model && d->ownModel)
-        static_cast<QSGVisualDataModel *>(d->model.data())->componentComplete();
-
-    QSGFlickable::componentComplete();
-
-    updateSections();
-    d->updateHeader();
-    d->updateFooter();
-    d->updateViewport();
-    d->setPosition(d->contentStartPosition());
-    if (d->isValid()) {
-        d->refill();
-        d->moveReason = QSGItemViewPrivate::SetIndex;
-        if (d->currentIndex < 0 && !d->currentIndexCleared)
-            d->updateCurrent(0);
-        else
-            d->updateCurrent(d->currentIndex);
-        if (d->highlight && d->currentItem) {
-            if (d->autoHighlight)
-                d->resetHighlightPosition();
-            d->updateTrackedItem();
-        }
-        d->moveReason = QSGItemViewPrivate::Other;
-        d->fixupPosition();
-    }
-    if (d->model && d->model->count())
-        emit countChanged();
-}
-
-
-
-QSGItemViewPrivate::QSGItemViewPrivate()
-    : itemCount(0)
-    , buffer(0), bufferMode(BufferBefore | BufferAfter)
-    , layoutDirection(Qt::LeftToRight)
-    , moveReason(Other)
-    , visibleIndex(0)
-    , currentIndex(-1), currentItem(0)
-    , trackedItem(0), requestedIndex(-1)
-    , highlightComponent(0), highlight(0)
-    , highlightRange(QSGItemView::NoHighlightRange)
-    , highlightRangeStart(0), highlightRangeEnd(0)
-    , highlightMoveDuration(150)
-    , headerComponent(0), header(0), footerComponent(0), footer(0)
-    , minExtent(0), maxExtent(0)
-    , ownModel(false), wrap(false), lazyRelease(false), deferredRelease(false)
-    , inApplyModelChanges(false), inViewportMoved(false), forceLayout(false), currentIndexCleared(false)
-    , haveHighlightRange(false), autoHighlight(true), highlightRangeStartValid(false), highlightRangeEndValid(false)
-{
-}
-
-bool QSGItemViewPrivate::isValid() const
-{
-    return model && model->count() && model->isValid();
-}
-
-qreal QSGItemViewPrivate::position() const
-{
-    Q_Q(const QSGItemView);
-    return layoutOrientation() == Qt::Vertical ? q->contentY() : q->contentX();
-}
-
-qreal QSGItemViewPrivate::size() const
-{
-    Q_Q(const QSGItemView);
-    return layoutOrientation() == Qt::Vertical ? q->height() : q->width();
-}
-
-qreal QSGItemViewPrivate::startPosition() const
-{
-    return isContentFlowReversed() ? -lastPosition() : originPosition();
-}
-
-qreal QSGItemViewPrivate::endPosition() const
-{
-    return isContentFlowReversed() ? -originPosition() : lastPosition();
-}
-
-qreal QSGItemViewPrivate::contentStartPosition() const
-{
-    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
-{
-    if (visibleItems.count()) {
-        int i = visibleItems.count() - 1;
-        while (i > 0 && visibleItems.at(i)->index == -1)
-            --i;
-        if (visibleItems.at(i)->index != -1)
-            return visibleItems.at(i)->index;
-    }
-    return defaultValue;
-}
-
-FxViewItem *QSGItemViewPrivate::visibleItem(int modelIndex) const {
-    if (modelIndex >= visibleIndex && modelIndex < visibleIndex + visibleItems.count()) {
-        for (int i = modelIndex - visibleIndex; i < visibleItems.count(); ++i) {
-            FxViewItem *item = visibleItems.at(i);
-            if (item->index == modelIndex)
-                return item;
-        }
-    }
-    return 0;
-}
-
-FxViewItem *QSGItemViewPrivate::firstVisibleItem() const {
-    const qreal pos = isContentFlowReversed() ? -position()-size() : position();
-    for (int i = 0; i < visibleItems.count(); ++i) {
-        FxViewItem *item = visibleItems.at(i);
-        if (item->index != -1 && item->endPosition() > pos)
-            return item;
-    }
-    return visibleItems.count() ? visibleItems.first() : 0;
-}
-
-// Map a model index to visibleItems list index.
-// These may differ if removed items are still present in the visible list,
-// e.g. doing a removal animation
-int QSGItemViewPrivate::mapFromModel(int modelIndex) const
-{
-    if (modelIndex < visibleIndex || modelIndex >= visibleIndex + visibleItems.count())
-        return -1;
-    for (int i = 0; i < visibleItems.count(); ++i) {
-        FxViewItem *item = visibleItems.at(i);
-        if (item->index == modelIndex)
-            return i;
-        if (item->index > modelIndex)
-            return -1;
-    }
-    return -1; // Not in visibleList
-}
-
-void QSGItemViewPrivate::init()
-{
-    Q_Q(QSGItemView);
-    QSGItemPrivate::get(contentItem)->childrenDoNotOverlap = true;
-    q->setFlag(QSGItem::ItemIsFocusScope);
-    addItemChangeListener(this, Geometry);
-    QObject::connect(q, SIGNAL(movementEnded()), q, SLOT(animStopped()));
-    q->setFlickableDirection(QSGFlickable::VerticalFlick);
-}
-
-void QSGItemViewPrivate::updateCurrent(int modelIndex)
-{
-    Q_Q(QSGItemView);
-    applyPendingChanges();
-
-    if (!q->isComponentComplete() || !isValid() || modelIndex < 0 || modelIndex >= model->count()) {
-        if (currentItem) {
-            currentItem->attached->setIsCurrentItem(false);
-            releaseItem(currentItem);
-            currentItem = 0;
-            currentIndex = modelIndex;
-            emit q->currentIndexChanged();
-            updateHighlight();
-        } else if (currentIndex != modelIndex) {
-            currentIndex = modelIndex;
-            emit q->currentIndexChanged();
-        }
-        return;
-    }
-
-    if (currentItem && currentIndex == modelIndex) {
-        updateHighlight();
-        return;
-    }
-
-    FxViewItem *oldCurrentItem = currentItem;
-    currentIndex = modelIndex;
-    currentItem = createItem(modelIndex);
-    if (oldCurrentItem && (!currentItem || oldCurrentItem->item != currentItem->item))
-        oldCurrentItem->attached->setIsCurrentItem(false);
-    if (currentItem) {
-        currentItem->item->setFocus(true);
-        currentItem->attached->setIsCurrentItem(true);
-        initializeCurrentItem();
-    }
-
-    updateHighlight();
-    emit q->currentIndexChanged();
-    releaseItem(oldCurrentItem);
-}
-
-void QSGItemViewPrivate::clear()
-{
-    currentChanges.reset();
-    timeline.clear();
-
-    for (int i = 0; i < visibleItems.count(); ++i)
-        releaseItem(visibleItems.at(i));
-    visibleItems.clear();
-    visibleIndex = 0;
-
-    releaseItem(currentItem);
-    currentItem = 0;
-    createHighlight();
-    trackedItem = 0;
-
-    markExtentsDirty();
-    itemCount = 0;
-}
-
-
-void QSGItemViewPrivate::mirrorChange()
-{
-    Q_Q(QSGItemView);
-    regenerate();
-    emit q->effectiveLayoutDirectionChanged();
-}
-
-void QSGItemViewPrivate::refill()
-{
-    if (isContentFlowReversed())
-        refill(-position()-size(), -position());
-    else
-        refill(position(), position()+size());
-}
-
-void QSGItemViewPrivate::refill(qreal from, qreal to, bool doBuffer)
-{
-    Q_Q(QSGItemView);
-    if (!isValid() || !q->isComponentComplete())
-        return;
-
-    currentChanges.reset();
-
-    int prevCount = itemCount;
-    itemCount = model->count();
-    qreal bufferFrom = from - buffer;
-    qreal bufferTo = to + buffer;
-    qreal fillFrom = from;
-    qreal fillTo = to;
-    if (doBuffer && (bufferMode & BufferAfter))
-        fillTo = bufferTo;
-    if (doBuffer && (bufferMode & BufferBefore))
-        fillFrom = bufferFrom;
-
-    // Item creation and release is staggered in order to avoid
-    // creating/releasing multiple items in one frame
-    // while flicking (as much as possible).
-
-    bool changed = addVisibleItems(fillFrom, fillTo, doBuffer);
-
-    if (!lazyRelease || !changed || deferredRelease) { // avoid destroying items in the same frame that we create
-        if (removeNonVisibleItems(bufferFrom, bufferTo))
-            changed = true;
-        deferredRelease = false;
-    } else {
-        deferredRelease = true;
-    }
-
-    if (changed) {
-        markExtentsDirty();
-        visibleItemsChanged();
-    } else if (!doBuffer && buffer && bufferMode != NoBuffer) {
-        refill(from, to, true);
-    }
-
-    lazyRelease = false;
-    if (prevCount != itemCount)
-        emit q->countChanged();
-}
-
-void QSGItemViewPrivate::regenerate()
-{
-    Q_Q(QSGItemView);
-    if (q->isComponentComplete()) {
-        currentChanges.reset();
-        delete header;
-        header = 0;
-        delete footer;
-        footer = 0;
-        updateHeader();
-        updateFooter();
-        clear();
-        updateViewport();
-        setPosition(contentStartPosition());
-        refill();
-        updateCurrent(currentIndex);
-    }
-}
-
-void QSGItemViewPrivate::updateViewport()
-{
-    Q_Q(QSGItemView);
-    if (isValid()) {
-        if (layoutOrientation() == Qt::Vertical)
-            q->setContentHeight(endPosition() - startPosition());
-        else
-            q->setContentWidth(endPosition() - startPosition());
-    }
-}
-
-void QSGItemViewPrivate::layout()
-{
-    Q_Q(QSGItemView);
-    if (inApplyModelChanges)
-        return;
-
-    if (!isValid() && !visibleItems.count()) {
-        clear();
-        setPosition(contentStartPosition());
-        return;
-    }
-
-    if (!applyModelChanges() && !forceLayout)
-        return;
-    forceLayout = false;
-
-    layoutVisibleItems();
-    refill();
-
-    markExtentsDirty();
-
-    updateHighlight();
-
-    if (!q->isMoving() && !q->isFlicking()) {
-        fixupPosition();
-        refill();
-    }
-
-    updateHeader();
-    updateFooter();
-    updateViewport();
-    updateUnrequestedPositions();
-}
-
-bool QSGItemViewPrivate::applyModelChanges()
-{
-    Q_Q(QSGItemView);
-    if (!q->isComponentComplete() || !currentChanges.hasPendingChanges() || inApplyModelChanges)
-        return false;
-    inApplyModelChanges = true;
-
-    updateUnrequestedIndexes();
-    moveReason = QSGItemViewPrivate::Other;
-
-    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;
-    qreal removedBeforeFirstVisibleBy = 0;
-
-    const QVector<QDeclarativeChangeSet::Remove> &removals = currentChanges.pendingChanges.removes();
-    for (int i=0; i<removals.count(); i++) {
-        itemCount -= removals[i].count;
-
-        // Remove the items from the visible list, skipping anything already marked for removal
-        QList<FxViewItem*>::Iterator it = visibleItems.begin();
-        while (it != visibleItems.end()) {
-            FxViewItem *item = *it;
-            if (item->index == -1 || item->index < removals[i].index) {
-                // already removed, or before removed items
-                if (item->index < removals[i].index && !removedVisible)
-                    removedVisible = true;
-                ++it;
-            } else if (item->index >= removals[i].index + removals[i].count) {
-                // after removed items
-                item->index -= removals[i].count;
-                ++it;
-            } else {
-                // removed item
-                removedVisible = true;
-                if (!removals[i].isMove())
-                    item->attached->emitRemove();
-
-                if (item->attached->delayRemove() && !removals[i].isMove()) {
-                    item->index = -1;
-                    QObject::connect(item->attached, SIGNAL(delayRemoveChanged()), q, SLOT(destroyRemoved()), Qt::QueuedConnection);
-                    ++it;
-                } else {
-                    if (firstVisible && item->position() < firstVisible->position() && item != visibleItems.first())
-                        removedBeforeFirstVisibleBy += item->size();
-                    if (removals[i].isMove()) {
-                        currentChanges.removedItems.insert(removals[i].moveKey(item->index), item);
-                    } else {
-                        if (item == firstVisible)
-                            firstVisible = 0;
-                        currentChanges.removedItems.insertMulti(QDeclarativeChangeSet::MoveKey(), item);
-                    }
-                    it = visibleItems.erase(it);
-                }
-            }
-        }
-
-    }
-    if (!removals.isEmpty())
-        updateVisibleIndex();
-
-    const QVector<QDeclarativeChangeSet::Insert> &insertions = currentChanges.pendingChanges.inserts();
-    bool addedVisible = false;
-    InsertionsResult insertResult;
-    bool allInsertionsBeforeVisible = true;
-
-    for (int i=0; i<insertions.count(); i++) {
-        bool wasEmpty = visibleItems.isEmpty();
-        if (applyInsertionChange(insertions[i], firstVisible, &insertResult))
-            addedVisible = true;
-        if (insertions[i].index >= visibleIndex)
-            allInsertionsBeforeVisible = false;
-        if (wasEmpty && !visibleItems.isEmpty())
-            resetFirstItemPosition();
-        itemCount += insertions[i].count;
-    }
-    for (int i=0; i<insertResult.addedItems.count(); ++i)
-        insertResult.addedItems.at(i)->attached->emitAdd();
-
-    // 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) {
-        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 (insertResult.movedBackwards.count() && origVisibleItemsFirst)
-            resetItemPosition(visibleItems.first(), origVisibleItemsFirst);
-        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.
-    for (QHash<QDeclarativeChangeSet::MoveKey, FxViewItem *>::Iterator it = currentChanges.removedItems.begin();
-         it != currentChanges.removedItems.end(); ++it) {
-        releaseItem(it.value());
-    }
-    currentChanges.removedItems.clear();
-
-    if (currentChanges.currentChanged) {
-        if (currentChanges.currentRemoved && currentItem) {
-            currentItem->attached->setIsCurrentItem(false);
-            releaseItem(currentItem);
-            currentItem = 0;
-        }
-        if (!currentIndexCleared)
-            updateCurrent(currentChanges.newCurrentIndex);
-    }
-    currentChanges.reset();
-
-    updateSections();
-    if (prevCount != itemCount)
-        emit q->countChanged();
-
-    bool visibleAffected = removedVisible || addedVisible || !currentChanges.pendingChanges.changes().isEmpty();
-    if (!visibleAffected && viewportChanged)
-        updateViewport();
-
-    inApplyModelChanges = false;
-    return visibleAffected;
-}
-
-FxViewItem *QSGItemViewPrivate::createItem(int modelIndex)
-{
-    Q_Q(QSGItemView);
-
-    requestedIndex = modelIndex;
-    FxViewItem *viewItem = 0;
-
-    if (QSGItem *item = model->item(modelIndex, false)) {
-        viewItem = newViewItem(modelIndex, item);
-        if (viewItem) {
-            viewItem->index = 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
-            // until after bindings are evaluated
-            initializeViewItem(viewItem);
-
-            unrequestedItems.remove(viewItem->item);
-        }
-    }
-    requestedIndex = -1;
-    return viewItem;
-}
-
-
-void QSGItemViewPrivate::releaseItem(FxViewItem *item)
-{
-    Q_Q(QSGItemView);
-    if (!item || !model)
-        return;
-    if (trackedItem == item)
-        trackedItem = 0;
-    QSGItemPrivate *itemPrivate = QSGItemPrivate::get(item->item);
-    itemPrivate->removeItemChangeListener(this, QSGItemPrivate::Geometry);
-    if (model->release(item->item) == 0) {
-        // item was not destroyed, and we no longer reference it.
-        unrequestedItems.insert(item->item, model->indexOf(item->item, q));
-    }
-    delete item;
-}
-
-QSGItem *QSGItemViewPrivate::createHighlightItem()
-{
-    return createComponentItem(highlightComponent, true, true);
-}
-
-QSGItem *QSGItemViewPrivate::createComponentItem(QDeclarativeComponent *component, bool receiveItemGeometryChanges, bool createDefault)
-{
-    Q_Q(QSGItemView);
-
-    QSGItem *item = 0;
-    if (component) {
-        QDeclarativeContext *creationContext = component->creationContext();
-        QDeclarativeContext *context = new QDeclarativeContext(
-                creationContext ? creationContext : qmlContext(q));
-        QObject *nobj = component->create(context);
-        if (nobj) {
-            QDeclarative_setParent_noEvent(context, nobj);
-            item = qobject_cast<QSGItem *>(nobj);
-            if (!item)
-                delete nobj;
-        } else {
-            delete context;
-        }
-    } else if (createDefault) {
-        item = new QSGItem;
-    }
-    if (item) {
-        QDeclarative_setParent_noEvent(item, q->contentItem());
-        item->setParentItem(q->contentItem());
-        if (receiveItemGeometryChanges) {
-            QSGItemPrivate *itemPrivate = QSGItemPrivate::get(item);
-            itemPrivate->addItemChangeListener(this, QSGItemPrivate::Geometry);
-        }
-    }
-    return item;
-}
-
-void QSGItemViewPrivate::updateTrackedItem()
-{
-    Q_Q(QSGItemView);
-    FxViewItem *item = currentItem;
-    if (highlight)
-        item = highlight;
-    trackedItem = item;
-
-    if (trackedItem)
-        q->trackedPositionChanged();
-}
-
-void QSGItemViewPrivate::updateUnrequestedIndexes()
-{
-    Q_Q(QSGItemView);
-    for (QHash<QSGItem*,int>::iterator it = unrequestedItems.begin(); it != unrequestedItems.end(); ++it)
-        *it = model->indexOf(it.key(), q);
-}
-
-void QSGItemViewPrivate::updateUnrequestedPositions()
-{
-    for (QHash<QSGItem*,int>::const_iterator it = unrequestedItems.begin(); it != unrequestedItems.end(); ++it)
-        repositionPackageItemAt(it.key(), it.value());
-}
-
-void QSGItemViewPrivate::updateVisibleIndex()
-{
-    visibleIndex = 0;
-    for (QList<FxViewItem*>::Iterator it = visibleItems.begin(); it != visibleItems.end(); ++it) {
-        if ((*it)->index != -1) {
-            visibleIndex = (*it)->index;
-            break;
-        }
-    }
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgitemview_p.h b/src/declarative/items/qsgitemview_p.h
deleted file mode 100644 (file)
index 7b8efbb..0000000
+++ /dev/null
@@ -1,294 +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 QSGITEMVIEW_P_H
-#define QSGITEMVIEW_P_H
-
-#include "qsgflickable_p.h"
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QDeclarativeChangeSet;
-
-class QSGItemViewPrivate;
-
-class Q_AUTOTEST_EXPORT QSGItemView : public QSGFlickable
-{
-    Q_OBJECT
-
-    Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged)
-    Q_PROPERTY(QDeclarativeComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
-    Q_PROPERTY(int count READ count NOTIFY countChanged)
-
-    Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
-    Q_PROPERTY(QSGItem *currentItem READ currentItem NOTIFY currentIndexChanged)
-
-    Q_PROPERTY(bool keyNavigationWraps READ isWrapEnabled WRITE setWrapEnabled NOTIFY keyNavigationWrapsChanged)
-    Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)
-
-    Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
-    Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
-
-    Q_PROPERTY(QDeclarativeComponent *header READ header WRITE setHeader NOTIFY headerChanged)
-    Q_PROPERTY(QSGItem *headerItem READ headerItem NOTIFY headerItemChanged)
-    Q_PROPERTY(QDeclarativeComponent *footer READ footer WRITE setFooter NOTIFY footerChanged)
-    Q_PROPERTY(QSGItem *footerItem READ footerItem NOTIFY footerItemChanged)
-
-    Q_PROPERTY(QDeclarativeComponent *highlight READ highlight WRITE setHighlight NOTIFY highlightChanged)
-    Q_PROPERTY(QSGItem *highlightItem READ highlightItem NOTIFY highlightItemChanged)
-    Q_PROPERTY(bool highlightFollowsCurrentItem READ highlightFollowsCurrentItem WRITE setHighlightFollowsCurrentItem NOTIFY highlightFollowsCurrentItemChanged)
-    Q_PROPERTY(HighlightRangeMode highlightRangeMode READ highlightRangeMode WRITE setHighlightRangeMode NOTIFY highlightRangeModeChanged)
-    Q_PROPERTY(qreal preferredHighlightBegin READ preferredHighlightBegin WRITE setPreferredHighlightBegin NOTIFY preferredHighlightBeginChanged RESET resetPreferredHighlightBegin)
-    Q_PROPERTY(qreal preferredHighlightEnd READ preferredHighlightEnd WRITE setPreferredHighlightEnd NOTIFY preferredHighlightEndChanged RESET resetPreferredHighlightEnd)
-    Q_PROPERTY(int highlightMoveDuration READ highlightMoveDuration WRITE setHighlightMoveDuration NOTIFY highlightMoveDurationChanged)
-
-    Q_ENUMS(HighlightRangeMode)
-    Q_ENUMS(PositionMode)
-
-public:
-    QSGItemView(QSGFlickablePrivate &dd, QSGItem *parent = 0);
-    ~QSGItemView();
-
-    QVariant model() const;
-    void setModel(const QVariant &);
-
-    QDeclarativeComponent *delegate() const;
-    void setDelegate(QDeclarativeComponent *);
-
-    int count() const;
-
-    int currentIndex() const;
-    void setCurrentIndex(int idx);
-
-    QSGItem *currentItem() const;
-
-    bool isWrapEnabled() const;
-    void setWrapEnabled(bool);
-
-    int cacheBuffer() const;
-    void setCacheBuffer(int);
-
-    Qt::LayoutDirection layoutDirection() const;
-    void setLayoutDirection(Qt::LayoutDirection);
-    Qt::LayoutDirection effectiveLayoutDirection() const;
-
-    QDeclarativeComponent *footer() const;
-    void setFooter(QDeclarativeComponent *);
-    QSGItem *footerItem() const;
-
-    QDeclarativeComponent *header() const;
-    void setHeader(QDeclarativeComponent *);
-    QSGItem *headerItem() const;
-
-    QDeclarativeComponent *highlight() const;
-    void setHighlight(QDeclarativeComponent *);
-
-    QSGItem *highlightItem() const;
-
-    bool highlightFollowsCurrentItem() const;
-    virtual void setHighlightFollowsCurrentItem(bool);
-
-    enum HighlightRangeMode { NoHighlightRange, ApplyRange, StrictlyEnforceRange };
-    HighlightRangeMode highlightRangeMode() const;
-    void setHighlightRangeMode(HighlightRangeMode mode);
-
-    qreal preferredHighlightBegin() const;
-    void setPreferredHighlightBegin(qreal);
-    void resetPreferredHighlightBegin();
-
-    qreal preferredHighlightEnd() const;
-    void setPreferredHighlightEnd(qreal);
-    void resetPreferredHighlightEnd();
-
-    int highlightMoveDuration() const;
-    virtual void setHighlightMoveDuration(int);
-
-    enum PositionMode { Beginning, Center, End, Visible, Contain };
-
-    Q_INVOKABLE void positionViewAtIndex(int index, int mode);
-    Q_INVOKABLE int indexAt(qreal x, qreal y) const;
-    Q_INVOKABLE void positionViewAtBeginning();
-    Q_INVOKABLE void positionViewAtEnd();
-
-    virtual void setContentX(qreal pos);
-    virtual void setContentY(qreal pos);
-    virtual qreal xOrigin() const;
-
-signals:
-    void modelChanged();
-    void delegateChanged();
-    void countChanged();
-    void currentIndexChanged();
-
-    void keyNavigationWrapsChanged();
-    void cacheBufferChanged();
-
-    void layoutDirectionChanged();
-    void effectiveLayoutDirectionChanged();
-
-    void headerChanged();
-    void footerChanged();
-    void headerItemChanged();
-    void footerItemChanged();
-
-    void highlightChanged();
-    void highlightItemChanged();
-    void highlightFollowsCurrentItemChanged();
-    void highlightRangeModeChanged();
-    void preferredHighlightBeginChanged();
-    void preferredHighlightEndChanged();
-    void highlightMoveDurationChanged();
-
-protected:
-    virtual void updatePolish();
-    virtual void componentComplete();
-    virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
-    virtual qreal minYExtent() const;
-    virtual qreal maxYExtent() const;
-    virtual qreal minXExtent() const;
-    virtual qreal maxXExtent() const;
-
-protected slots:
-    virtual void updateSections() {}
-    void destroyRemoved();
-    void createdItem(int index, QSGItem *item);
-    void modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset);
-    void destroyingItem(QSGItem *item);
-    void animStopped();
-    void trackedPositionChanged();
-
-
-
-private:
-    Q_DECLARE_PRIVATE(QSGItemView)
-};
-
-
-class Q_AUTOTEST_EXPORT QSGItemViewAttached : public QObject
-{
-    Q_OBJECT
-
-    Q_PROPERTY(bool isCurrentItem READ isCurrentItem NOTIFY currentItemChanged)
-    Q_PROPERTY(bool delayRemove READ delayRemove WRITE setDelayRemove NOTIFY delayRemoveChanged)
-
-    Q_PROPERTY(QString section READ section NOTIFY sectionChanged)
-    Q_PROPERTY(QString previousSection READ prevSection NOTIFY prevSectionChanged)
-    Q_PROPERTY(QString nextSection READ nextSection NOTIFY nextSectionChanged)
-
-public:
-    QSGItemViewAttached(QObject *parent)
-        : QObject(parent), m_isCurrent(false), m_delayRemove(false) {}
-    ~QSGItemViewAttached() {}
-
-    bool isCurrentItem() const { return m_isCurrent; }
-    void setIsCurrentItem(bool c) {
-        if (m_isCurrent != c) {
-            m_isCurrent = c;
-            emit currentItemChanged();
-        }
-    }
-
-    bool delayRemove() const { return m_delayRemove; }
-    void setDelayRemove(bool delay) {
-        if (m_delayRemove != delay) {
-            m_delayRemove = delay;
-            emit delayRemoveChanged();
-        }
-    }
-
-    QString section() const { return m_section; }
-    void setSection(const QString &sect) {
-        if (m_section != sect) {
-            m_section = sect;
-            emit sectionChanged();
-        }
-    }
-
-    QString prevSection() const { return m_prevSection; }
-    void setPrevSection(const QString &sect) {
-        if (m_prevSection != sect) {
-            m_prevSection = sect;
-            emit prevSectionChanged();
-        }
-    }
-
-    QString nextSection() const { return m_nextSection; }
-    void setNextSection(const QString &sect) {
-        if (m_nextSection != sect) {
-            m_nextSection = sect;
-            emit nextSectionChanged();
-        }
-    }
-
-    void emitAdd() { emit add(); }
-    void emitRemove() { emit remove(); }
-
-signals:
-    void currentItemChanged();
-    void delayRemoveChanged();
-
-    void add();
-    void remove();
-
-    void sectionChanged();
-    void prevSectionChanged();
-    void nextSectionChanged();
-
-public:
-    bool m_isCurrent : 1;
-    bool m_delayRemove : 1;
-
-    // current only used by list view
-    mutable QString m_section;
-    QString m_prevSection;
-    QString m_nextSection;
-};
-
-
-QT_END_NAMESPACE
-QT_END_HEADER
-
-#endif // QSGITEMVIEW_P_H
-
diff --git a/src/declarative/items/qsgitemview_p_p.h b/src/declarative/items/qsgitemview_p_p.h
deleted file mode 100644 (file)
index 5eaa84c..0000000
+++ /dev/null
@@ -1,256 +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 QSGITEMVIEW_P_P_H
-#define QSGITEMVIEW_P_P_H
-
-#include "qsgitemview_p.h"
-#include "qsgflickable_p_p.h"
-#include "qsgvisualdatamodel_p.h"
-#include <private/qdeclarativechangeset_p.h>
-
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class FxViewItem
-{
-public:
-    FxViewItem(QSGItem *, bool own);
-    ~FxViewItem();
-
-    // these are positions and sizes along the current direction of scrolling/flicking
-    virtual qreal position() const = 0;
-    virtual qreal endPosition() const = 0;
-    virtual qreal size() const = 0;
-    virtual qreal sectionSize() const = 0;
-
-    virtual bool contains(qreal x, qreal y) const = 0;
-
-    QSGItem *item;
-    bool ownItem;
-    int index;
-    QSGItemViewAttached *attached;
-};
-
-class QSGItemViewChangeSet
-{
-public:
-    QSGItemViewChangeSet();
-
-    bool hasPendingChanges() const;
-    void prepare(int currentIndex, int count);
-    void reset();
-
-    void applyChanges(const QDeclarativeChangeSet &changeSet);
-
-    int itemCount;
-    int newCurrentIndex;
-    QDeclarativeChangeSet pendingChanges;
-    QHash<QDeclarativeChangeSet::MoveKey, FxViewItem *> removedItems;
-
-    bool active : 1;
-    bool currentChanged : 1;
-    bool currentRemoved : 1;
-};
-
-class QSGItemViewPrivate : public QSGFlickablePrivate
-{
-    Q_DECLARE_PUBLIC(QSGItemView)
-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 };
-
-    bool isValid() const;
-    qreal position() const;
-    qreal size() const;
-    qreal startPosition() const;
-    qreal endPosition() const;
-    qreal contentStartPosition() const;
-    int findLastVisibleIndex(int defaultValue = -1) const;
-    FxViewItem *visibleItem(int modelIndex) const;
-    FxViewItem *firstVisibleItem() const;
-    int mapFromModel(int modelIndex) const;
-
-    virtual void init();
-    virtual void clear();
-    virtual void updateViewport();
-
-    void regenerate();
-    void layout();
-    void refill();
-    void refill(qreal from, qreal to, bool doBuffer = false);
-    void mirrorChange();
-
-    FxViewItem *createItem(int modelIndex);
-    virtual void releaseItem(FxViewItem *item);
-
-    QSGItem *createHighlightItem();
-    QSGItem *createComponentItem(QDeclarativeComponent *component, bool receiveItemGeometryChanges, bool createDefault = false);
-
-    void updateCurrent(int modelIndex);
-    void updateTrackedItem();
-    void updateUnrequestedIndexes();
-    void updateUnrequestedPositions();
-    void updateVisibleIndex();
-    void positionViewAtIndex(int index, int mode);
-    void applyPendingChanges();
-    bool applyModelChanges();
-
-    void checkVisible() const;
-
-    void markExtentsDirty() {
-        if (layoutOrientation() == Qt::Vertical)
-            vData.markExtentsDirty();
-        else
-            hData.markExtentsDirty();
-    }
-
-    QDeclarativeGuard<QSGVisualModel> model;
-    QVariant modelVariant;
-    int itemCount;
-    int buffer;
-    int bufferMode;
-    Qt::LayoutDirection layoutDirection;
-
-    MovementReason moveReason;
-
-    QList<FxViewItem *> visibleItems;
-    int visibleIndex;
-    int currentIndex;
-    FxViewItem *currentItem;
-    FxViewItem *trackedItem;
-    QHash<QSGItem*,int> unrequestedItems;
-    int requestedIndex;
-    QSGItemViewChangeSet currentChanges;
-
-    // XXX split into struct
-    QDeclarativeComponent *highlightComponent;
-    FxViewItem *highlight;
-    int highlightRange;     // enum value
-    qreal highlightRangeStart;
-    qreal highlightRangeEnd;
-    int highlightMoveDuration;
-
-    QDeclarativeComponent *headerComponent;
-    FxViewItem *header;
-    QDeclarativeComponent *footerComponent;
-    FxViewItem *footer;
-
-    mutable qreal minExtent;
-    mutable qreal maxExtent;
-
-    bool ownModel : 1;
-    bool wrap : 1;
-    bool lazyRelease : 1;
-    bool deferredRelease : 1;
-    bool inApplyModelChanges : 1;
-    bool inViewportMoved : 1;
-    bool forceLayout : 1;
-    bool currentIndexCleared : 1;
-    bool haveHighlightRange : 1;
-    bool autoHighlight : 1;
-    bool highlightRangeStartValid : 1;
-    bool highlightRangeEndValid : 1;
-
-protected:
-    virtual Qt::Orientation layoutOrientation() const = 0;
-    virtual bool isContentFlowReversed() const = 0;
-
-    virtual qreal positionAt(int index) const = 0;
-    virtual qreal endPositionAt(int index) const = 0;
-    virtual qreal originPosition() const = 0;
-    virtual qreal lastPosition() const = 0;
-
-    virtual qreal headerSize() const = 0;
-    virtual qreal footerSize() const = 0;
-    virtual bool showHeaderForIndex(int index) const = 0;
-    virtual bool showFooterForIndex(int index) const = 0;
-    virtual void updateHeader() = 0;
-    virtual void updateFooter() = 0;
-
-    virtual void createHighlight() = 0;
-    virtual void updateHighlight() = 0;
-    virtual void resetHighlightPosition() = 0;
-
-    virtual void setPosition(qreal pos) = 0;
-    virtual void fixupPosition() = 0;
-
-    virtual bool addVisibleItems(qreal fillFrom, qreal fillTo, bool doBuffer) = 0;
-    virtual bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo) = 0;
-    virtual void visibleItemsChanged() = 0;
-
-    virtual FxViewItem *newViewItem(int index, QSGItem *item) = 0;
-    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, qreal forwards, qreal backwards) = 0;
-
-    virtual void layoutVisibleItems() = 0;
-    virtual void changedVisibleIndex(int newIndex) = 0;
-    virtual bool applyInsertionChange(const QDeclarativeChangeSet::Insert &, FxViewItem *, InsertionsResult *) = 0;
-
-    virtual void initializeViewItem(FxViewItem *) {}
-    virtual void initializeCurrentItem() {}
-    virtual void updateSections() {}
-
-    virtual void itemGeometryChanged(QSGItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
-};
-
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSGITEMVIEW_P_P_H
diff --git a/src/declarative/items/qsglistview.cpp b/src/declarative/items/qsglistview.cpp
deleted file mode 100644 (file)
index 5ea9efe..0000000
+++ /dev/null
@@ -1,2500 +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 "qsglistview_p.h"
-#include "qsgitemview_p_p.h"
-#include "qsgvisualitemmodel_p.h"
-
-#include <QtDeclarative/qdeclarativeexpression.h>
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativeinfo.h>
-#include <QtGui/qevent.h>
-#include <QtCore/qmath.h>
-#include <QtCore/qcoreapplication.h>
-
-#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
-{
-    Q_DECLARE_PUBLIC(QSGListView)
-public:
-    static QSGListViewPrivate* get(QSGListView *item) { return item->d_func(); }
-
-    virtual Qt::Orientation layoutOrientation() const;
-    virtual bool isContentFlowReversed() const;
-    bool isRightToLeft() const;
-
-    virtual qreal positionAt(int index) const;
-    virtual qreal endPositionAt(int index) const;
-    virtual qreal originPosition() const;
-    virtual qreal lastPosition() const;
-
-    FxViewItem *itemBefore(int modelIndex) const;
-    QString sectionAt(int modelIndex);
-    qreal snapPosAt(qreal pos);
-    FxViewItem *snapItemAt(qreal pos);
-
-    virtual void init();
-    virtual void clear();
-
-    virtual bool addVisibleItems(qreal fillFrom, qreal fillTo, bool doBuffer);
-    virtual bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo);
-    virtual void visibleItemsChanged();
-
-    virtual FxViewItem *newViewItem(int index, QSGItem *item);
-    virtual void initializeViewItem(FxViewItem *item);
-    virtual void releaseItem(FxViewItem *item);
-    virtual void repositionPackageItemAt(QSGItem *item, int index);
-    virtual void resetItemPosition(FxViewItem *item, FxViewItem *toItem);
-    virtual void resetFirstItemPosition();
-    virtual void moveItemBy(FxViewItem *item, qreal forwards, qreal backwards);
-
-    virtual void createHighlight();
-    virtual void updateHighlight();
-    virtual void resetHighlightPosition();
-
-    virtual void setPosition(qreal pos);
-    virtual void layoutVisibleItems();
-    bool applyInsertionChange(const QDeclarativeChangeSet::Insert &, FxViewItem *firstVisible, InsertionsResult *);
-
-    virtual void updateSections();
-    QSGItem *getSectionItem(const QString &section);
-    void releaseSectionItem(QSGItem *item);
-    void updateInlineSection(FxListItemSG *);
-    void updateCurrentSection();
-    void updateStickySections();
-
-    virtual qreal headerSize() const;
-    virtual qreal footerSize() const;
-    virtual bool showHeaderForIndex(int index) const;
-    virtual bool showFooterForIndex(int index) const;
-    virtual void updateHeader();
-    virtual void updateFooter();
-
-    virtual void changedVisibleIndex(int newIndex);
-    virtual void initializeCurrentItem();
-
-    void updateAverage();
-
-    void itemGeometryChanged(QSGItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
-    virtual void fixupPosition();
-    virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent);
-    virtual void flick(QSGItemViewPrivate::AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
-                        QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity);
-
-    QSGListView::Orientation orient;
-    qreal visiblePos;
-    qreal averageSize;
-    qreal spacing;
-    QSGListView::SnapMode snapMode;
-
-    QSmoothedAnimation *highlightPosAnimator;
-    QSmoothedAnimation *highlightSizeAnimator;
-    qreal highlightMoveSpeed;
-    qreal highlightResizeSpeed;
-    int highlightResizeDuration;
-
-    QSGViewSection *sectionCriteria;
-    QString currentSection;
-    static const int sectionCacheSize = 5;
-    QSGItem *sectionCache[sectionCacheSize];
-    QSGItem *currentSectionItem;
-    QString currentStickySection;
-    QSGItem *nextSectionItem;
-    QString nextStickySection;
-    QString lastVisibleSection;
-    QString nextSection;
-
-    qreal overshootDist;
-    bool correctFlick : 1;
-    bool inFlickCorrection : 1;
-
-    QSGListViewPrivate()
-        : orient(QSGListView::Vertical)
-        , visiblePos(0)
-        , averageSize(100.0), spacing(0.0)
-        , snapMode(QSGListView::NoSnap)
-        , highlightPosAnimator(0), highlightSizeAnimator(0)
-        , highlightMoveSpeed(400), highlightResizeSpeed(400), highlightResizeDuration(-1)
-        , sectionCriteria(0), currentSectionItem(0), nextSectionItem(0)
-        , overshootDist(0.0), correctFlick(false), inFlickCorrection(false)
-    {}
-
-    friend class QSGViewSection;
-};
-
-//----------------------------------------------------------------------------
-
-QSGViewSection::QSGViewSection(QSGListView *parent)
-    : QObject(parent), m_criteria(FullString), m_delegate(0), m_labelPositioning(InlineLabels)
-    , m_view(parent ? QSGListViewPrivate::get(parent) : 0)
-{
-}
-
-void QSGViewSection::setProperty(const QString &property)
-{
-    if (property != m_property) {
-        m_property = property;
-        emit propertyChanged();
-        m_view->updateSections();
-    }
-}
-
-void QSGViewSection::setCriteria(QSGViewSection::SectionCriteria criteria)
-{
-    if (criteria != m_criteria) {
-        m_criteria = criteria;
-        emit criteriaChanged();
-        m_view->updateSections();
-    }
-}
-
-void QSGViewSection::setDelegate(QDeclarativeComponent *delegate)
-{
-    if (delegate != m_delegate) {
-        m_delegate = delegate;
-        emit delegateChanged();
-        m_view->updateSections();
-    }
-}
-
-QString QSGViewSection::sectionString(const QString &value)
-{
-    if (m_criteria == FirstCharacter)
-        return value.isEmpty() ? QString() : value.at(0);
-    else
-        return value;
-}
-
-void QSGViewSection::setLabelPositioning(int l)
-{
-    if (m_labelPositioning != l) {
-        m_labelPositioning = l;
-        emit labelPositioningChanged();
-        m_view->updateSections();
-    }
-}
-
-//----------------------------------------------------------------------------
-
-class FxListItemSG : public FxViewItem
-{
-public:
-    FxListItemSG(QSGItem *i, QSGListView *v, bool own) : FxViewItem(i, own), section(0), view(v) {
-        attached = static_cast<QSGListViewAttached*>(qmlAttachedPropertiesObject<QSGListView>(item));
-        if (attached)
-            static_cast<QSGListViewAttached*>(attached)->setView(view);
-    }
-
-    ~FxListItemSG() {}
-
-    qreal position() const {
-        if (section) {
-            if (view->orientation() == QSGListView::Vertical)
-                return section->y();
-            else
-                return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -section->width()-section->x() : section->x());
-        } else {
-            return itemPosition();
-        }
-    }
-    qreal itemPosition() const {
-        if (view->orientation() == QSGListView::Vertical)
-            return item->y();
-        else
-            return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -item->width()-item->x() : item->x());
-    }
-    qreal size() const {
-        if (section)
-            return (view->orientation() == QSGListView::Vertical ? item->height()+section->height() : item->width()+section->width());
-        else
-            return (view->orientation() == QSGListView::Vertical ? item->height() : item->width());
-    }
-    qreal itemSize() const {
-        return (view->orientation() == QSGListView::Vertical ? item->height() : item->width());
-    }
-    qreal sectionSize() const {
-        if (section)
-            return (view->orientation() == QSGListView::Vertical ? section->height() : section->width());
-        return 0.0;
-    }
-    qreal endPosition() const {
-        if (view->orientation() == QSGListView::Vertical) {
-            return item->y() + item->height();
-        } else {
-            return (view->effectiveLayoutDirection() == Qt::RightToLeft
-                    ? -item->x()
-                    : item->x() + item->width());
-        }
-    }
-    void setPosition(qreal pos) {
-        if (view->orientation() == QSGListView::Vertical) {
-            if (section) {
-                section->setY(pos);
-                pos += section->height();
-            }
-            item->setY(pos);
-        } else {
-            if (view->effectiveLayoutDirection() == Qt::RightToLeft) {
-                if (section) {
-                    section->setX(-section->width()-pos);
-                    pos += section->width();
-                }
-                item->setX(-item->width()-pos);
-            } else {
-                if (section) {
-                    section->setX(pos);
-                    pos += section->width();
-                }
-                item->setX(pos);
-            }
-        }
-    }
-    void setSize(qreal size) {
-        if (view->orientation() == QSGListView::Vertical)
-            item->setHeight(size);
-        else
-            item->setWidth(size);
-    }
-    bool contains(qreal x, qreal y) const {
-        return (x >= item->x() && x < item->x() + item->width() &&
-                y >= item->y() && y < item->y() + item->height());
-    }
-
-    QSGItem *section;
-    QSGListView *view;
-};
-
-//----------------------------------------------------------------------------
-
-bool QSGListViewPrivate::isContentFlowReversed() const
-{
-    return isRightToLeft();
-}
-
-Qt::Orientation QSGListViewPrivate::layoutOrientation() const
-{
-    return static_cast<Qt::Orientation>(orient);
-}
-
-bool QSGListViewPrivate::isRightToLeft() const
-{
-    Q_Q(const QSGListView);
-    return orient == QSGListView::Horizontal && q->effectiveLayoutDirection() == Qt::RightToLeft;
-}
-
-// Returns the item before modelIndex, if created.
-// May return an item marked for removal.
-FxViewItem *QSGListViewPrivate::itemBefore(int modelIndex) const
-{
-    if (modelIndex < visibleIndex)
-        return 0;
-    int idx = 1;
-    int lastIndex = -1;
-    while (idx < visibleItems.count()) {
-        FxViewItem *item = visibleItems.at(idx);
-        if (item->index != -1)
-            lastIndex = item->index;
-        if (item->index == modelIndex)
-            return visibleItems.at(idx-1);
-        ++idx;
-    }
-    if (lastIndex == modelIndex-1)
-        return visibleItems.last();
-    return 0;
-}
-
-void QSGListViewPrivate::setPosition(qreal pos)
-{
-    Q_Q(QSGListView);
-    if (orient == QSGListView::Vertical) {
-        q->QSGFlickable::setContentY(pos);
-    } else {
-        if (isRightToLeft())
-            q->QSGFlickable::setContentX(-pos-size());
-        else
-            q->QSGFlickable::setContentX(pos);
-    }
-}
-
-qreal QSGListViewPrivate::originPosition() const
-{
-    qreal pos = 0;
-    if (!visibleItems.isEmpty()) {
-        pos = (*visibleItems.constBegin())->position();
-        if (visibleIndex > 0)
-            pos -= visibleIndex * (averageSize + spacing);
-    }
-    return pos;
-}
-
-qreal QSGListViewPrivate::lastPosition() const
-{
-    qreal pos = 0;
-    if (!visibleItems.isEmpty()) {
-        int invisibleCount = visibleItems.count() - visibleIndex;
-        for (int i = visibleItems.count()-1; i >= 0; --i) {
-            if (visibleItems.at(i)->index != -1) {
-                invisibleCount = model->count() - visibleItems.at(i)->index - 1;
-                break;
-            }
-        }
-        pos = (*(--visibleItems.constEnd()))->endPosition() + invisibleCount * (averageSize + spacing);
-    } else if (model && model->count()) {
-        pos = (model->count() * averageSize + (model->count()-1) * spacing);
-    }
-    return pos;
-}
-
-qreal QSGListViewPrivate::positionAt(int modelIndex) const
-{
-    if (FxViewItem *item = visibleItem(modelIndex))
-        return item->position();
-    if (!visibleItems.isEmpty()) {
-        if (modelIndex < visibleIndex) {
-            int count = visibleIndex - modelIndex;
-            qreal cs = 0;
-            if (modelIndex == currentIndex && currentItem) {
-                cs = currentItem->size() + spacing;
-                --count;
-            }
-            return (*visibleItems.constBegin())->position() - count * (averageSize + spacing) - cs;
-        } else {
-            int count = modelIndex - findLastVisibleIndex(visibleIndex) - 1;
-            return (*(--visibleItems.constEnd()))->endPosition() + spacing + count * (averageSize + spacing);
-        }
-    }
-    return 0;
-}
-
-qreal QSGListViewPrivate::endPositionAt(int modelIndex) const
-{
-    if (FxViewItem *item = visibleItem(modelIndex))
-        return item->endPosition();
-    if (!visibleItems.isEmpty()) {
-        if (modelIndex < visibleIndex) {
-            int count = visibleIndex - modelIndex;
-            return (*visibleItems.constBegin())->position() - (count - 1) * (averageSize + spacing) - spacing;
-        } else {
-            int count = modelIndex - findLastVisibleIndex(visibleIndex) - 1;
-            return (*(--visibleItems.constEnd()))->endPosition() + count * (averageSize + spacing);
-        }
-    }
-    return 0;
-}
-
-QString QSGListViewPrivate::sectionAt(int modelIndex)
-{
-    if (FxViewItem *item = visibleItem(modelIndex))
-        return item->attached->section();
-
-    QString section;
-    if (sectionCriteria) {
-        QString propValue = model->stringValue(modelIndex, sectionCriteria->property());
-        section = sectionCriteria->sectionString(propValue);
-    }
-
-    return section;
-}
-
-qreal QSGListViewPrivate::snapPosAt(qreal pos)
-{
-    if (FxViewItem *snapItem = snapItemAt(pos))
-        return snapItem->position();
-    if (visibleItems.count()) {
-        qreal firstPos = (*visibleItems.constBegin())->position();
-        qreal endPos = (*(--visibleItems.constEnd()))->position();
-        if (pos < firstPos) {
-            return firstPos - qRound((firstPos - pos) / averageSize) * averageSize;
-        } else if (pos > endPos)
-            return endPos + qRound((pos - endPos) / averageSize) * averageSize;
-    }
-    return qRound((pos - originPosition()) / averageSize) * averageSize + originPosition();
-}
-
-FxViewItem *QSGListViewPrivate::snapItemAt(qreal pos)
-{
-    FxViewItem *snapItem = 0;
-    qreal prevItemSize = 0;
-    for (int i = 0; i < visibleItems.count(); ++i) {
-        FxViewItem *item = visibleItems.at(i);
-        if (item->index == -1)
-            continue;
-        qreal itemTop = item->position();
-        if (highlight && itemTop >= pos && item->endPosition() <= pos + highlight->size())
-            return item;
-        if (itemTop+item->size()/2 >= pos && itemTop-prevItemSize/2 < pos)
-            snapItem = item;
-        prevItemSize = item->size();
-    }
-    return snapItem;
-}
-
-void QSGListViewPrivate::changedVisibleIndex(int newIndex)
-{
-    visiblePos = positionAt(newIndex);
-    visibleIndex = newIndex;
-}
-
-void QSGListViewPrivate::init()
-{
-    QSGItemViewPrivate::init();
-    ::memset(sectionCache, 0, sizeof(QSGItem*) * sectionCacheSize);
-}
-
-void QSGListViewPrivate::clear()
-{
-    for (int i = 0; i < sectionCacheSize; ++i) {
-        delete sectionCache[i];
-        sectionCache[i] = 0;
-    }
-    visiblePos = 0;
-    currentSectionItem = 0;
-    nextSectionItem = 0;
-    lastVisibleSection = QString();
-    QSGItemViewPrivate::clear();
-}
-
-FxViewItem *QSGListViewPrivate::newViewItem(int modelIndex, QSGItem *item)
-{
-    Q_Q(QSGListView);
-
-    FxListItemSG *listItem = new FxListItemSG(item, q, false);
-    listItem->index = modelIndex;
-
-    // initialise attached properties
-    if (sectionCriteria) {
-        QString propValue = model->stringValue(modelIndex, sectionCriteria->property());
-        listItem->attached->m_section = sectionCriteria->sectionString(propValue);
-        if (modelIndex > 0) {
-            if (FxViewItem *item = itemBefore(modelIndex))
-                listItem->attached->m_prevSection = item->attached->section();
-            else
-                listItem->attached->m_prevSection = sectionAt(modelIndex-1);
-        }
-        if (modelIndex < model->count()-1) {
-            if (FxViewItem *item = visibleItem(modelIndex+1))
-                listItem->attached->m_nextSection = static_cast<QSGListViewAttached*>(item->attached)->section();
-            else
-                listItem->attached->m_nextSection = sectionAt(modelIndex+1);
-        }
-    }
-
-    return listItem;
-}
-
-void QSGListViewPrivate::initializeViewItem(FxViewItem *item)
-{
-    QSGItemViewPrivate::initializeViewItem(item);
-
-    QSGItemPrivate *itemPrivate = QSGItemPrivate::get(item->item);
-    itemPrivate->addItemChangeListener(this, QSGItemPrivate::Geometry);
-
-    if (sectionCriteria && sectionCriteria->delegate()) {
-        if (item->attached->m_prevSection != item->attached->m_section)
-            updateInlineSection(static_cast<FxListItemSG*>(item));
-    }
-}
-
-void QSGListViewPrivate::releaseItem(FxViewItem *item)
-{
-    if (item) {
-        FxListItemSG* listItem = static_cast<FxListItemSG*>(item);
-        if (listItem->section) {
-            int i = 0;
-            do {
-                if (!sectionCache[i]) {
-                    sectionCache[i] = listItem->section;
-                    sectionCache[i]->setVisible(false);
-                    listItem->section = 0;
-                    break;
-                }
-                ++i;
-            } while (i < sectionCacheSize);
-            delete listItem->section;
-        }
-    }
-    QSGItemViewPrivate::releaseItem(item);
-}
-
-bool QSGListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool doBuffer)
-{
-    qreal itemEnd = visiblePos;
-    if (visibleItems.count()) {
-        visiblePos = (*visibleItems.constBegin())->position();
-        itemEnd = (*(--visibleItems.constEnd()))->endPosition() + spacing;
-    }
-
-    int modelIndex = findLastVisibleIndex();
-    bool haveValidItems = modelIndex >= 0;
-    modelIndex = modelIndex < 0 ? visibleIndex : modelIndex + 1;
-
-    if (haveValidItems && (fillFrom > itemEnd+averageSize+spacing
-        || fillTo < visiblePos - averageSize - spacing)) {
-        // We've jumped more than a page.  Estimate which items are now
-        // visible and fill from there.
-        int count = (fillFrom - itemEnd) / (averageSize + spacing);
-        for (int i = 0; i < visibleItems.count(); ++i)
-            releaseItem(visibleItems.at(i));
-        visibleItems.clear();
-        modelIndex += count;
-        if (modelIndex >= model->count()) {
-            count -= modelIndex - model->count() + 1;
-            modelIndex = model->count() - 1;
-        } else if (modelIndex < 0) {
-            count -= modelIndex;
-            modelIndex = 0;
-        }
-        visibleIndex = modelIndex;
-        visiblePos = itemEnd + count * (averageSize + spacing);
-        itemEnd = visiblePos;
-    }
-
-    bool changed = false;
-    FxListItemSG *item = 0;
-    qreal pos = itemEnd;
-    while (modelIndex < model->count() && pos <= fillTo) {
-//        qDebug() << "refill: append item" << modelIndex << "pos" << pos;
-        if (!(item = static_cast<FxListItemSG*>(createItem(modelIndex))))
-            break;
-        item->setPosition(pos);
-        pos += item->size() + spacing;
-        visibleItems.append(item);
-        ++modelIndex;
-        changed = true;
-        if (doBuffer) // never buffer more than one item per frame
-            break;
-    }
-    while (visibleIndex > 0 && visibleIndex <= model->count() && visiblePos >= fillFrom) {
-//        qDebug() << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos;
-        if (!(item = static_cast<FxListItemSG*>(createItem(visibleIndex-1))))
-            break;
-        --visibleIndex;
-        visiblePos -= item->size() + spacing;
-        item->setPosition(visiblePos);
-        visibleItems.prepend(item);
-        changed = true;
-        if (doBuffer) // never buffer more than one item per frame
-            break;
-    }
-
-    return changed;
-}
-
-bool QSGListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal bufferTo)
-{
-    FxViewItem *item = 0;
-    bool changed = false;
-
-    while (visibleItems.count() > 1 && (item = visibleItems.first()) && item->endPosition() <= bufferFrom) {
-        if (item->attached->delayRemove())
-            break;
-        if (item->size() == 0)
-            break;
-//            qDebug() << "refill: remove first" << visibleIndex << "top end pos" << item->endPosition();
-        if (item->index != -1)
-            visibleIndex++;
-        visibleItems.removeFirst();
-        releaseItem(item);
-        changed = true;
-    }
-    while (visibleItems.count() > 1 && (item = visibleItems.last()) && item->position() > bufferTo) {
-        if (item->attached->delayRemove())
-            break;
-//            qDebug() << "refill: remove last" << visibleIndex+visibleItems.count()-1 << item->position();
-        visibleItems.removeLast();
-        releaseItem(item);
-        changed = true;
-    }
-
-    return changed;
-}
-
-void QSGListViewPrivate::visibleItemsChanged()
-{
-    if (visibleItems.count())
-        visiblePos = (*visibleItems.constBegin())->position();
-    updateAverage();
-    if (currentIndex >= 0 && currentItem && !visibleItem(currentIndex)) {
-        static_cast<FxListItemSG*>(currentItem)->setPosition(positionAt(currentIndex));
-        updateHighlight();
-    }
-    if (sectionCriteria)
-        updateCurrentSection();
-    updateHeader();
-    updateFooter();
-    updateViewport();
-    updateUnrequestedPositions();
-}
-
-void QSGListViewPrivate::layoutVisibleItems()
-{
-    if (!visibleItems.isEmpty()) {
-        bool fixedCurrent = currentItem && (*visibleItems.constBegin())->item == currentItem->item;
-        qreal sum = (*visibleItems.constBegin())->size();
-        qreal pos = (*visibleItems.constBegin())->position() + (*visibleItems.constBegin())->size() + spacing;
-        for (int i=1; i < visibleItems.count(); ++i) {
-            FxListItemSG *item = static_cast<FxListItemSG*>(visibleItems.at(i));
-            item->setPosition(pos);
-            pos += item->size() + spacing;
-            sum += item->size();
-            fixedCurrent = fixedCurrent || (currentItem && item->item == currentItem->item);
-        }
-        averageSize = qRound(sum / visibleItems.count());
-
-        // move current item if it is not a visible item.
-        if (currentIndex >= 0 && currentItem && !fixedCurrent) {
-            static_cast<FxListItemSG*>(currentItem)->setPosition(positionAt(currentIndex));
-        }
-    }
-}
-
-void QSGListViewPrivate::repositionPackageItemAt(QSGItem *item, int index)
-{
-    Q_Q(QSGListView);
-    qreal pos = position();
-    if (orient == QSGListView::Vertical) {
-        if (item->y() + item->height() > pos && item->y() < pos + q->height())
-            item->setY(positionAt(index));
-    } else {
-        if (item->x() + item->width() > pos && item->x() < pos + q->width()) {
-            if (isRightToLeft())
-                item->setX(-positionAt(index)-item->width());
-            else
-                item->setX(positionAt(index));
-        }
-    }
-}
-
-void QSGListViewPrivate::resetItemPosition(FxViewItem *item, FxViewItem *toItem)
-{
-    if (item == toItem)
-        return;
-    static_cast<FxListItemSG*>(item)->setPosition(toItem->position());
-}
-
-void QSGListViewPrivate::resetFirstItemPosition()
-{
-    FxListItemSG *item = static_cast<FxListItemSG*>(visibleItems.first());
-    item->setPosition(0);
-}
-
-void QSGListViewPrivate::moveItemBy(FxViewItem *item, qreal forwards, qreal backwards)
-{
-    qreal diff = forwards - backwards;
-    static_cast<FxListItemSG*>(item)->setPosition(item->position() + diff);
-}
-
-void QSGListViewPrivate::createHighlight()
-{
-    Q_Q(QSGListView);
-    bool changed = false;
-    if (highlight) {
-        if (trackedItem == highlight)
-            trackedItem = 0;
-        delete highlight;
-        highlight = 0;
-
-        delete highlightPosAnimator;
-        delete highlightSizeAnimator;
-        highlightPosAnimator = 0;
-        highlightSizeAnimator = 0;
-
-        changed = true;
-    }
-
-    if (currentItem) {
-        QSGItem *item = createHighlightItem();
-        if (item) {
-            FxListItemSG *newHighlight = new FxListItemSG(item, q, true);
-
-            if (autoHighlight) {
-                newHighlight->setSize(static_cast<FxListItemSG*>(currentItem)->itemSize());
-                newHighlight->setPosition(static_cast<FxListItemSG*>(currentItem)->itemPosition());
-            }
-            const QLatin1String posProp(orient == QSGListView::Vertical ? "y" : "x");
-            highlightPosAnimator = new QSmoothedAnimation(q);
-            highlightPosAnimator->target = QDeclarativeProperty(item, posProp);
-            highlightPosAnimator->velocity = highlightMoveSpeed;
-            highlightPosAnimator->userDuration = highlightMoveDuration;
-
-            const QLatin1String sizeProp(orient == QSGListView::Vertical ? "height" : "width");
-            highlightSizeAnimator = new QSmoothedAnimation(q);
-            highlightSizeAnimator->velocity = highlightResizeSpeed;
-            highlightSizeAnimator->userDuration = highlightResizeDuration;
-            highlightSizeAnimator->target = QDeclarativeProperty(item, sizeProp);
-
-            highlight = newHighlight;
-            changed = true;
-        }
-    }
-    if (changed)
-        emit q->highlightItemChanged();
-}
-
-void QSGListViewPrivate::updateHighlight()
-{
-    applyPendingChanges();
-
-    if ((!currentItem && highlight) || (currentItem && !highlight))
-        createHighlight();
-    bool strictHighlight = haveHighlightRange && highlightRange == QSGListView::StrictlyEnforceRange;
-    if (currentItem && autoHighlight && highlight && (!strictHighlight || !pressed)) {
-        // auto-update highlight
-        FxListItemSG *listItem = static_cast<FxListItemSG*>(currentItem);
-        highlightPosAnimator->to = isRightToLeft()
-                ? -listItem->itemPosition()-listItem->itemSize()
-                : listItem->itemPosition();
-        highlightSizeAnimator->to = listItem->itemSize();
-        if (orient == QSGListView::Vertical) {
-            if (highlight->item->width() == 0)
-                highlight->item->setWidth(currentItem->item->width());
-        } else {
-            if (highlight->item->height() == 0)
-                highlight->item->setHeight(currentItem->item->height());
-        }
-
-        highlightPosAnimator->restart();
-        highlightSizeAnimator->restart();
-    }
-    updateTrackedItem();
-}
-
-void QSGListViewPrivate::resetHighlightPosition()
-{
-    if (highlight && currentItem)
-        static_cast<FxListItemSG*>(highlight)->setPosition(static_cast<FxListItemSG*>(currentItem)->itemPosition());
-}
-
-QSGItem * QSGListViewPrivate::getSectionItem(const QString &section)
-{
-    Q_Q(QSGListView);
-    QSGItem *sectionItem = 0;
-    int i = sectionCacheSize-1;
-    while (i >= 0 && !sectionCache[i])
-        --i;
-    if (i >= 0) {
-        sectionItem = sectionCache[i];
-        sectionCache[i] = 0;
-        sectionItem->setVisible(true);
-        QDeclarativeContext *context = QDeclarativeEngine::contextForObject(sectionItem)->parentContext();
-        context->setContextProperty(QLatin1String("section"), section);
-    } else {
-        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) {
-            QDeclarative_setParent_noEvent(context, nobj);
-            sectionItem = qobject_cast<QSGItem *>(nobj);
-            if (!sectionItem) {
-                delete nobj;
-            } else {
-                sectionItem->setZ(2);
-                QDeclarative_setParent_noEvent(sectionItem, contentItem);
-                sectionItem->setParentItem(contentItem);
-            }
-        } else {
-            delete context;
-        }
-        sectionCriteria->delegate()->completeCreate();
-    }
-
-    return sectionItem;
-}
-
-void QSGListViewPrivate::releaseSectionItem(QSGItem *item)
-{
-    int i = 0;
-    do {
-        if (!sectionCache[i]) {
-            sectionCache[i] = item;
-            sectionCache[i]->setVisible(false);
-            return;
-        }
-        ++i;
-    } while (i < sectionCacheSize);
-    delete item;
-}
-
-void QSGListViewPrivate::updateInlineSection(FxListItemSG *listItem)
-{
-    if (!sectionCriteria || !sectionCriteria->delegate())
-        return;
-    if (listItem->attached->m_prevSection != listItem->attached->m_section
-            && (sectionCriteria->labelPositioning() & QSGViewSection::InlineLabels
-                || (listItem->index == 0 && sectionCriteria->labelPositioning() & QSGViewSection::CurrentLabelAtStart))) {
-        if (!listItem->section) {
-            qreal pos = listItem->position();
-            listItem->section = getSectionItem(listItem->attached->m_section);
-            listItem->setPosition(pos);
-        } else {
-            QDeclarativeContext *context = QDeclarativeEngine::contextForObject(listItem->section)->parentContext();
-            context->setContextProperty(QLatin1String("section"), listItem->attached->m_section);
-        }
-    } else if (listItem->section) {
-        qreal pos = listItem->position();
-        releaseSectionItem(listItem->section);
-        listItem->section = 0;
-        listItem->setPosition(pos);
-    }
-}
-
-void QSGListViewPrivate::updateStickySections()
-{
-    if (!sectionCriteria || visibleItems.isEmpty()
-            || (!sectionCriteria->labelPositioning() && !currentSectionItem && !nextSectionItem))
-        return;
-
-    bool isRtl = isRightToLeft();
-    qreal viewPos = isRightToLeft() ? -position()-size() : position();
-    QSGItem *sectionItem = 0;
-    QSGItem *lastSectionItem = 0;
-    int index = 0;
-    while (index < visibleItems.count()) {
-        if (QSGItem *section = static_cast<FxListItemSG *>(visibleItems.at(index))->section) {
-            // Find the current section header and last visible section header
-            // and hide them if they will overlap a static section header.
-            qreal sectionPos = orient == QSGListView::Vertical ? section->y() : section->x();
-            qreal sectionSize = orient == QSGListView::Vertical ? section->height() : section->width();
-            bool visTop = true;
-            if (sectionCriteria->labelPositioning() & QSGViewSection::CurrentLabelAtStart)
-                visTop = isRtl ? -sectionPos-sectionSize >= viewPos : sectionPos >= viewPos;
-            bool visBot = true;
-            if (sectionCriteria->labelPositioning() & QSGViewSection::NextLabelAtEnd)
-                visBot = isRtl ? -sectionPos <= viewPos + size() : sectionPos + sectionSize < viewPos + size();
-            section->setVisible(visBot && visTop);
-            if (visTop && !sectionItem)
-                sectionItem = section;
-            if (isRtl) {
-               if (-sectionPos <= viewPos + size())
-                    lastSectionItem = section;
-            } else {
-                if (sectionPos + sectionSize < viewPos + size())
-                    lastSectionItem = section;
-            }
-        }
-        ++index;
-    }
-
-    // Current section header
-    if (sectionCriteria->labelPositioning() & QSGViewSection::CurrentLabelAtStart) {
-        if (!currentSectionItem) {
-            currentSectionItem = getSectionItem(currentSection);
-        } else if (currentStickySection != currentSection) {
-            QDeclarativeContext *context = QDeclarativeEngine::contextForObject(currentSectionItem)->parentContext();
-            context->setContextProperty(QLatin1String("section"), currentSection);
-        }
-        currentStickySection = currentSection;
-        if (!currentSectionItem)
-            return;
-
-        qreal sectionSize = orient == QSGListView::Vertical ? currentSectionItem->height() : currentSectionItem->width();
-        bool atBeginning = orient == QSGListView::Vertical ? vData.atBeginning : (isRightToLeft() ? hData.atEnd : hData.atBeginning);
-        currentSectionItem->setVisible(!atBeginning && (!header || header->endPosition() < viewPos));
-        qreal pos = isRtl ? position() + size() - sectionSize : viewPos;
-        if (sectionItem) {
-            qreal sectionPos = orient == QSGListView::Vertical ? sectionItem->y() : sectionItem->x();
-            pos = isRtl ? qMax(pos, sectionPos + sectionSize) : qMin(pos, sectionPos - sectionSize);
-        }
-        if (header)
-            pos = isRtl ? qMin(header->endPosition(), pos) : qMax(header->endPosition(), pos);
-        if (footer)
-            pos = isRtl ? qMax(-footer->position(), pos) : qMin(footer->position() - sectionSize, pos);
-        if (orient == QSGListView::Vertical)
-            currentSectionItem->setY(pos);
-        else
-            currentSectionItem->setX(pos);
-    } else if (currentSectionItem) {
-        releaseSectionItem(currentSectionItem);
-        currentSectionItem = 0;
-    }
-
-    // Next section footer
-    if (sectionCriteria->labelPositioning() & QSGViewSection::NextLabelAtEnd) {
-        if (!nextSectionItem) {
-            nextSectionItem = getSectionItem(nextSection);
-        } else if (nextStickySection != nextSection) {
-            QDeclarativeContext *context = QDeclarativeEngine::contextForObject(nextSectionItem)->parentContext();
-            context->setContextProperty(QLatin1String("section"), nextSection);
-        }
-        nextStickySection = nextSection;
-        if (!nextSectionItem)
-            return;
-
-        qreal sectionSize = orient == QSGListView::Vertical ? nextSectionItem->height() : nextSectionItem->width();
-        nextSectionItem->setVisible(!nextSection.isEmpty());
-        qreal pos = isRtl ? position() : viewPos + size() - sectionSize;
-        if (lastSectionItem) {
-            qreal sectionPos = orient == QSGListView::Vertical ? lastSectionItem->y() : lastSectionItem->x();
-            pos = isRtl ? qMin(pos, sectionPos - sectionSize) : qMax(pos, sectionPos + sectionSize);
-        }
-        if (header)
-            pos = isRtl ? qMin(header->endPosition() - sectionSize, pos) : qMax(header->endPosition(), pos);
-        if (orient == QSGListView::Vertical)
-            nextSectionItem->setY(pos);
-        else
-            nextSectionItem->setX(pos);
-    } else if (nextSectionItem) {
-        releaseSectionItem(nextSectionItem);
-        nextSectionItem = 0;
-    }
-}
-
-void QSGListViewPrivate::updateSections()
-{
-    Q_Q(QSGListView);
-    if (!q->isComponentComplete())
-        return;
-
-    QSGItemViewPrivate::updateSections();
-
-    if (sectionCriteria && !visibleItems.isEmpty()) {
-        QString prevSection;
-        if (visibleIndex > 0)
-            prevSection = sectionAt(visibleIndex-1);
-        QSGListViewAttached *prevAtt = 0;
-        int idx = -1;
-        for (int i = 0; i < visibleItems.count(); ++i) {
-            QSGListViewAttached *attached = static_cast<QSGListViewAttached*>(visibleItems.at(i)->attached);
-            attached->setPrevSection(prevSection);
-            if (visibleItems.at(i)->index != -1) {
-                QString propValue = model->stringValue(visibleItems.at(i)->index, sectionCriteria->property());
-                attached->setSection(sectionCriteria->sectionString(propValue));
-                idx = visibleItems.at(i)->index;
-            }
-            updateInlineSection(static_cast<FxListItemSG*>(visibleItems.at(i)));
-            if (prevAtt)
-                prevAtt->setNextSection(attached->section());
-            prevSection = attached->section();
-            prevAtt = attached;
-        }
-        if (prevAtt) {
-            if (idx > 0 && idx < model->count()-1)
-                prevAtt->setNextSection(sectionAt(idx+1));
-            else
-                prevAtt->setNextSection(QString());
-        }
-    }
-
-    lastVisibleSection = QString();
-    updateCurrentSection();
-    updateStickySections();
-}
-
-void QSGListViewPrivate::updateCurrentSection()
-{
-    Q_Q(QSGListView);
-    if (!sectionCriteria || visibleItems.isEmpty()) {
-        if (!currentSection.isEmpty()) {
-            currentSection.clear();
-            emit q->currentSectionChanged();
-        }
-        return;
-    }
-    bool inlineSections = sectionCriteria->labelPositioning() & QSGViewSection::InlineLabels;
-    qreal sectionThreshold = position();
-    if (currentSectionItem && !inlineSections)
-        sectionThreshold += orient == QSGListView::Vertical ? currentSectionItem->height() : currentSectionItem->width();
-    int index = 0;
-    int modelIndex = visibleIndex;
-    while (index < visibleItems.count() && visibleItems.at(index)->endPosition() <= sectionThreshold) {
-        if (visibleItems.at(index)->index != -1)
-            modelIndex = visibleItems.at(index)->index;
-        ++index;
-    }
-
-    QString newSection = currentSection;
-    if (index < visibleItems.count())
-        newSection = visibleItems.at(index)->attached->section();
-    else
-        newSection = (*visibleItems.constBegin())->attached->section();
-    if (newSection != currentSection) {
-        currentSection = newSection;
-        updateStickySections();
-        emit q->currentSectionChanged();
-    }
-
-    if (sectionCriteria->labelPositioning() & QSGViewSection::NextLabelAtEnd) {
-        // Don't want to scan for next section on every movement, so remember
-        // the last section in the visible area and only scan for the next
-        // section when that changes.  Clearing lastVisibleSection will also
-        // force searching.
-        QString lastSection = currentSection;
-        qreal endPos = isRightToLeft() ? -position() : position() + size();
-        if (nextSectionItem && !inlineSections)
-            endPos -= orient == QSGListView::Vertical ? nextSectionItem->height() : nextSectionItem->width();
-        while (index < visibleItems.count() && static_cast<FxListItemSG*>(visibleItems.at(index))->itemPosition() < endPos) {
-            if (visibleItems.at(index)->index != -1)
-                modelIndex = visibleItems.at(index)->index;
-            lastSection = visibleItems.at(index)->attached->section();
-            ++index;
-        }
-
-        if (lastVisibleSection != lastSection) {
-            nextSection = QString();
-            lastVisibleSection = lastSection;
-            for (int i = modelIndex; i < itemCount; ++i) {
-                QString section = sectionAt(i);
-                if (section != lastSection) {
-                    nextSection = section;
-                    updateStickySections();
-                    break;
-                }
-            }
-        }
-    }
-}
-
-void QSGListViewPrivate::initializeCurrentItem()
-{
-    QSGItemViewPrivate::initializeCurrentItem();
-
-    if (currentItem) {
-        FxListItemSG *listItem = static_cast<FxListItemSG *>(currentItem);
-
-        if (currentIndex == visibleIndex - 1 && visibleItems.count()) {
-            // We can calculate exact postion in this case
-            listItem->setPosition(visibleItems.first()->position() - currentItem->size() - spacing);
-        } else {
-            // Create current item now and position as best we can.
-            // Its position will be corrected when it becomes visible.
-            listItem->setPosition(positionAt(currentIndex));
-        }
-
-        // Avoid showing section delegate twice.  We still need the section heading so that
-        // currentItem positioning works correctly.
-        // This is slightly sub-optimal, but section heading caching minimizes the impact.
-        if (listItem->section)
-            listItem->section->setVisible(false);
-
-        if (visibleItems.isEmpty())
-            averageSize = listItem->size();
-    }
-}
-
-void QSGListViewPrivate::updateAverage()
-{
-    if (!visibleItems.count())
-        return;
-    qreal sum = 0.0;
-    for (int i = 0; i < visibleItems.count(); ++i)
-        sum += visibleItems.at(i)->size();
-    averageSize = qRound(sum / visibleItems.count());
-}
-
-qreal QSGListViewPrivate::headerSize() const
-{
-    return header ? header->size() : 0.0;
-}
-
-qreal QSGListViewPrivate::footerSize() const
-{
-    return footer ? footer->size() : 0.0;
-}
-
-bool QSGListViewPrivate::showHeaderForIndex(int index) const
-{
-    return index == 0;
-}
-
-bool QSGListViewPrivate::showFooterForIndex(int index) const
-{
-    return index == model->count()-1;
-}
-
-void QSGListViewPrivate::updateFooter()
-{
-    Q_Q(QSGListView);
-    bool created = false;
-    if (!footer) {
-        QSGItem *item = createComponentItem(footerComponent, true);
-        if (!item)
-            return;
-        item->setZ(1);
-        footer = new FxListItemSG(item, q, true);
-        created = true;
-    }
-
-    FxListItemSG *listItem = static_cast<FxListItemSG*>(footer);
-    if (visibleItems.count()) {
-        qreal endPos = lastPosition();
-        if (findLastVisibleIndex() == model->count()-1) {
-            listItem->setPosition(endPos);
-        } else {
-            qreal visiblePos = position() + q->height();
-            if (endPos <= visiblePos || listItem->position() < endPos)
-                listItem->setPosition(endPos);
-        }
-    } else {
-        listItem->setPosition(visiblePos);
-    }
-
-    if (created)
-        emit q->footerItemChanged();
-}
-
-void QSGListViewPrivate::updateHeader()
-{
-    Q_Q(QSGListView);
-    bool created = false;
-    if (!header) {
-        QSGItem *item = createComponentItem(headerComponent, true);
-        if (!item)
-            return;
-        item->setZ(1);
-        header = new FxListItemSG(item, q, true);
-        created = true;
-    }
-
-    FxListItemSG *listItem = static_cast<FxListItemSG*>(header);
-    if (listItem) {
-        if (visibleItems.count()) {
-            qreal startPos = originPosition();
-            if (visibleIndex == 0) {
-                listItem->setPosition(startPos - headerSize());
-            } else {
-                if (position() <= startPos || listItem->position() > startPos - headerSize())
-                    listItem->setPosition(startPos - headerSize());
-            }
-        } else {
-            listItem->setPosition(-headerSize());
-        }
-    }
-
-    if (created)
-        emit q->headerItemChanged();
-}
-
-void QSGListViewPrivate::itemGeometryChanged(QSGItem *item, const QRectF &newGeometry, const QRectF &oldGeometry)
-{
-    Q_Q(QSGListView);
-    QSGItemViewPrivate::itemGeometryChanged(item, newGeometry, oldGeometry);
-    if (!q->isComponentComplete())
-        return;
-    if (item != contentItem && (!highlight || item != highlight->item)) {
-        if ((orient == QSGListView::Vertical && newGeometry.height() != oldGeometry.height())
-            || (orient == QSGListView::Horizontal && newGeometry.width() != oldGeometry.width())) {
-            forceLayout = true;
-            q->polish();
-        }
-    }
-}
-
-void QSGListViewPrivate::fixupPosition()
-{
-    if ((haveHighlightRange && highlightRange == QSGListView::StrictlyEnforceRange)
-        || snapMode != QSGListView::NoSnap)
-        moveReason = Other;
-    if (orient == QSGListView::Vertical)
-        fixupY();
-    else
-        fixupX();
-}
-
-void QSGListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
-{
-    if ((orient == QSGListView::Horizontal && &data == &vData)
-        || (orient == QSGListView::Vertical && &data == &hData))
-        return;
-
-    correctFlick = false;
-    fixupMode = moveReason == Mouse ? fixupMode : Immediate;
-    bool strictHighlightRange = haveHighlightRange && highlightRange == QSGListView::StrictlyEnforceRange;
-
-    qreal viewPos = isRightToLeft() ? -position()-size() : position();
-
-    if (snapMode != QSGListView::NoSnap && moveReason != QSGListViewPrivate::SetIndex) {
-        qreal tempPosition = isRightToLeft() ? -position()-size() : position();
-        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 || 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() + highlightRangeStart - size(), -maxExtent), -minExtent);
-                else
-                    pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent);
-            }
-        } else if (bottomItem && isInBounds) {
-            if (isRightToLeft())
-                pos = qMax(qMin(-bottomItem->position() + highlightRangeEnd - size(), -maxExtent), -minExtent);
-            else
-                pos = qMax(qMin(bottomItem->position() - highlightRangeEnd, -maxExtent), -minExtent);
-        } else {
-            QSGItemViewPrivate::fixup(data, minExtent, maxExtent);
-            return;
-        }
-
-        qreal dist = qAbs(data.move + pos);
-        if (dist > 0) {
-            timeline.reset(data.move);
-            if (fixupMode != Immediate) {
-                timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
-                data.fixingUp = true;
-            } else {
-                timeline.set(data.move, -pos);
-            }
-            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);
-    }
-    data.inOvershoot = false;
-    fixupMode = Normal;
-}
-
-void QSGListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
-                                        QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity)
-{
-    Q_Q(QSGListView);
-
-    data.fixingUp = false;
-    moveReason = Mouse;
-    if ((!haveHighlightRange || highlightRange != QSGListView::StrictlyEnforceRange) && snapMode == QSGListView::NoSnap) {
-        correctFlick = true;
-        QSGItemViewPrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, velocity);
-        return;
-    }
-    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 && !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());
-            }
-        }
-        if (snapMode == QSGListView::NoSnap && highlightRange != QSGListView::StrictlyEnforceRange)
-            data.flickTarget = minExtent;
-    } else {
-        if (data.move.value() > maxExtent) {
-            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());
-            }
-        }
-        if (snapMode == QSGListView::NoSnap && highlightRange != QSGListView::StrictlyEnforceRange)
-            data.flickTarget = maxExtent;
-    }
-    bool overShoot = boundsBehavior == QSGFlickable::DragAndOvershootBounds;
-    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.
-        // Since list items can have variable sizes, the boundary will be
-        // reevaluated and adjusted as we approach the boundary.
-        qreal v = velocity;
-        if (maxVelocity != -1 && maxVelocity < qAbs(v)) {
-            if (v < 0)
-                v = -maxVelocity;
-            else
-                v = maxVelocity;
-        }
-        if (!hData.flicking && !vData.flicking) {
-            // the initial flick - estimate boundary
-            qreal accel = deceleration;
-            qreal v2 = v * v;
-            overshootDist = 0.0;
-            // + averageSize/4 to encourage moving at least one item in the flick direction
-            qreal dist = v2 / (accel * 2.0) + averageSize/4;
-            if (maxDistance > 0)
-                dist = qMin(dist, maxDistance);
-            if (v > 0)
-                dist = -dist;
-            if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QSGListView::SnapOneItem) {
-                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) {
-                        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
-                    qreal adjv2 = accel * 2.0f * qAbs(adjDist);
-                    if (adjv2 > v2) {
-                        v2 = adjv2;
-                        v = qSqrt(v2);
-                        if (dist > 0)
-                            v = -v;
-                    }
-                }
-                dist = adjDist;
-                accel = v2 / (2.0f * qAbs(dist));
-            } else if (overShoot) {
-                data.flickTarget = data.move.value() - dist;
-                if (data.flickTarget >= minExtent) {
-                    overshootDist = overShootDistance(vSize);
-                    data.flickTarget += overshootDist;
-                } else if (data.flickTarget <= maxExtent) {
-                    overshootDist = overShootDistance(vSize);
-                    data.flickTarget -= overshootDist;
-                }
-            }
-            timeline.reset(data.move);
-            timeline.accel(data.move, v, accel, maxDistance + overshootDist);
-            timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this));
-            if (!hData.flicking && q->xflick()) {
-                hData.flicking = true;
-                emit q->flickingChanged();
-                emit q->flickingHorizontallyChanged();
-                emit q->flickStarted();
-            }
-            if (!vData.flicking && q->yflick()) {
-                vData.flicking = true;
-                emit q->flickingChanged();
-                emit q->flickingVerticallyChanged();
-                emit q->flickStarted();
-            }
-            correctFlick = true;
-        } else {
-            // reevaluate the target boundary.
-            qreal newtarget = data.flickTarget;
-            if (snapMode != QSGListView::NoSnap || highlightRange == QSGListView::StrictlyEnforceRange) {
-                qreal tempFlickTarget = isRightToLeft() ? -data.flickTarget+size() : data.flickTarget;
-                newtarget = -snapPosAt(-(tempFlickTarget - highlightRangeStart)) + highlightRangeStart;
-                newtarget = isRightToLeft() ? -newtarget+size() : newtarget;
-            }
-            if (velocity < 0 && newtarget <= maxExtent)
-                newtarget = maxExtent - overshootDist;
-            else if (velocity > 0 && newtarget >= minExtent)
-                newtarget = minExtent + overshootDist;
-            if (newtarget == data.flickTarget) { // boundary unchanged - nothing to do
-                if (qAbs(velocity) < MinimumFlickVelocity)
-                    correctFlick = false;
-                return;
-            }
-            data.flickTarget = newtarget;
-            qreal dist = -newtarget + data.move.value();
-            if ((v < 0 && dist < 0) || (v > 0 && dist > 0)) {
-                correctFlick = false;
-                timeline.reset(data.move);
-                fixup(data, minExtent, maxExtent);
-                return;
-            }
-            timeline.reset(data.move);
-            timeline.accelDistance(data.move, v, -dist);
-            timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this));
-        }
-    } else {
-        correctFlick = false;
-        timeline.reset(data.move);
-        fixup(data, minExtent, maxExtent);
-    }
-}
-
-//----------------------------------------------------------------------------
-
-/*!
-    \qmlclass ListView QSGListView
-    \inqmlmodule QtQuick 2
-    \ingroup qml-view-elements
-    \inherits Flickable
-    \brief The ListView item provides a list view of items provided by a model.
-
-    A ListView displays data from models created from built-in QML elements like ListModel
-    and XmlListModel, or custom model classes defined in C++ that inherit from
-    QAbstractListModel.
-
-    A ListView has a \l model, which defines the data to be displayed, and
-    a \l delegate, which defines how the data should be displayed. Items in a
-    ListView are laid out horizontally or vertically. List views are inherently
-    flickable because ListView inherits from \l Flickable.
-
-    \section1 Example Usage
-
-    The following example shows the definition of a simple list model defined
-    in a file called \c ContactModel.qml:
-
-    \snippet doc/src/snippets/declarative/listview/ContactModel.qml 0
-
-    Another component can display this model data in a ListView, like this:
-
-    \snippet doc/src/snippets/declarative/listview/listview.qml import
-    \codeline
-    \snippet doc/src/snippets/declarative/listview/listview.qml classdocs simple
-
-    \image listview-simple.png
-
-    Here, the ListView creates a \c ContactModel component for its model, and a \l Text element
-    for its delegate. The view will create a new \l Text component for each item in the model. Notice
-    the delegate is able to access the model's \c name and \c number data directly.
-
-    An improved list view is shown below. The delegate is visually improved and is moved
-    into a separate \c contactDelegate component.
-
-    \snippet doc/src/snippets/declarative/listview/listview.qml classdocs advanced
-    \image listview-highlight.png
-
-    The currently selected item is highlighted with a blue \l Rectangle using the \l highlight property,
-    and \c focus is set to \c true to enable keyboard navigation for the list view.
-    The list view itself is a focus scope (see \l{qmlfocus#Acquiring Focus and Focus Scopes}{the focus documentation page} for more details).
-
-    Delegates are instantiated as needed and may be destroyed at any time.
-    State should \e never be stored in a delegate.
-
-    ListView attaches a number of properties to the root item of the delegate, for example
-    \c {ListView.isCurrentItem}.  In the following example, the root delegate item can access
-    this attached property directly as \c ListView.isCurrentItem, while the child
-    \c contactInfo object must refer to this property as \c wrapper.ListView.isCurrentItem.
-
-    \snippet doc/src/snippets/declarative/listview/listview.qml isCurrentItem
-
-    \note Views do not enable \e clip automatically.  If the view
-    is not clipped by another item or the screen, it will be necessary
-    to set \e {clip: true} in order to have the out of view items clipped
-    nicely.
-
-    \sa {QML Data Models}, GridView, {declarative/modelviews/listview}{ListView examples}
-*/
-QSGListView::QSGListView(QSGItem *parent)
-    : QSGItemView(*(new QSGListViewPrivate), parent)
-{
-}
-
-QSGListView::~QSGListView()
-{
-}
-
-/*!
-    \qmlattachedproperty bool QtQuick2::ListView::isCurrentItem
-    This attached property is true if this delegate is the current item; otherwise false.
-
-    It is attached to each instance of the delegate.
-
-    This property may be used to adjust the appearance of the current item, for example:
-
-    \snippet doc/src/snippets/declarative/listview/listview.qml isCurrentItem
-*/
-
-/*!
-    \qmlattachedproperty ListView QtQuick2::ListView::view
-    This attached property holds the view that manages this delegate instance.
-
-    It is attached to each instance of the delegate.
-*/
-
-/*!
-    \qmlattachedproperty string QtQuick2::ListView::previousSection
-    This attached property holds the section of the previous element.
-
-    It is attached to each instance of the delegate.
-
-    The section is evaluated using the \l {ListView::section.property}{section} properties.
-*/
-
-/*!
-    \qmlattachedproperty string QtQuick2::ListView::nextSection
-    This attached property holds the section of the next element.
-
-    It is attached to each instance of the delegate.
-
-    The section is evaluated using the \l {ListView::section.property}{section} properties.
-*/
-
-/*!
-    \qmlattachedproperty string QtQuick2::ListView::section
-    This attached property holds the section of this element.
-
-    It is attached to each instance of the delegate.
-
-    The section is evaluated using the \l {ListView::section.property}{section} properties.
-*/
-
-/*!
-    \qmlattachedproperty bool QtQuick2::ListView::delayRemove
-    This attached property holds whether the delegate may be destroyed.
-
-    It is attached to each instance of the delegate.
-
-    It is sometimes necessary to delay the destruction of an item
-    until an animation completes.
-
-    The example delegate below ensures that the animation completes before
-    the item is removed from the list.
-
-    \snippet doc/src/snippets/declarative/listview/listview.qml delayRemove
-*/
-
-/*!
-    \qmlattachedsignal QtQuick2::ListView::onAdd()
-    This attached handler is called immediately after an item is added to the view.
-*/
-
-/*!
-    \qmlattachedsignal QtQuick2::ListView::onRemove()
-    This attached handler is called immediately before an item is removed from the view.
-*/
-
-/*!
-    \qmlproperty model QtQuick2::ListView::model
-    This property holds the model providing data for the list.
-
-    The model provides the set of data that is used to create the items
-    in the view. Models can be created directly in QML using \l ListModel, \l XmlListModel
-    or \l VisualItemModel, or provided by C++ model classes. If a C++ model class is
-    used, it must be a subclass of \l QAbstractItemModel or a simple list.
-
-    \sa {qmlmodels}{Data Models}
-*/
-
-/*!
-    \qmlproperty Component QtQuick2::ListView::delegate
-
-    The delegate provides a template defining each item instantiated by the view.
-    The index is exposed as an accessible \c index property.  Properties of the
-    model are also available depending upon the type of \l {qmlmodels}{Data Model}.
-
-    The number of elements in the delegate has a direct effect on the
-    flicking performance of the view.  If at all possible, place functionality
-    that is not needed for the normal display of the delegate in a \l Loader which
-    can load additional elements when needed.
-
-    The ListView will lay out the items based on the size of the root item
-    in the delegate.
-
-    It is recommended that the delagate's size be a whole number to avoid sub-pixel
-    alignment of items.
-
-    \note Delegates are instantiated as needed and may be destroyed at any time.
-    State should \e never be stored in a delegate.
-*/
-/*!
-    \qmlproperty int QtQuick2::ListView::currentIndex
-    \qmlproperty Item QtQuick2::ListView::currentItem
-
-    The \c currentIndex property holds the index of the current item, and
-    \c currentItem holds the current item.   Setting the currentIndex to -1
-    will clear the highlight and set currentItem to null.
-
-    If highlightFollowsCurrentItem is \c true, setting either of these
-    properties will smoothly scroll the ListView so that the current
-    item becomes visible.
-
-    Note that the position of the current item
-    may only be approximate until it becomes visible in the view.
-*/
-
-/*!
-  \qmlproperty Item QtQuick2::ListView::highlightItem
-
-    This holds the highlight item created from the \l highlight component.
-
-  The \c highlightItem is managed by the view unless
-  \l highlightFollowsCurrentItem is set to false.
-
-  \sa highlight, highlightFollowsCurrentItem
-*/
-
-/*!
-  \qmlproperty int QtQuick2::ListView::count
-  This property holds the number of items in the view.
-*/
-
-/*!
-    \qmlproperty Component QtQuick2::ListView::highlight
-    This property holds the component to use as the highlight.
-
-    An instance of the highlight component is created for each list.
-    The geometry of the resulting component instance is managed by the list
-    so as to stay with the current item, unless the highlightFollowsCurrentItem
-    property is false.
-
-    \sa highlightItem, highlightFollowsCurrentItem, {declarative/modelviews/listview}{ListView examples}
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::ListView::highlightFollowsCurrentItem
-    This property holds whether the highlight is managed by the view.
-
-    If this property is true (the default value), the highlight is moved smoothly
-    to follow the current item.  Otherwise, the
-    highlight is not moved by the view, and any movement must be implemented
-    by the highlight.
-
-    Here is a highlight with its motion defined by a \l {SpringAnimation} item:
-
-    \snippet doc/src/snippets/declarative/listview/listview.qml highlightFollowsCurrentItem
-
-    Note that the highlight animation also affects the way that the view
-    is scrolled.  This is because the view moves to maintain the
-    highlight within the preferred highlight range (or visible viewport).
-
-    \sa highlight, highlightMoveSpeed
-*/
-//###Possibly rename these properties, since they are very useful even without a highlight?
-/*!
-    \qmlproperty real QtQuick2::ListView::preferredHighlightBegin
-    \qmlproperty real QtQuick2::ListView::preferredHighlightEnd
-    \qmlproperty enumeration QtQuick2::ListView::highlightRangeMode
-
-    These properties define the preferred range of the highlight (for the current item)
-    within the view. The \c preferredHighlightBegin value must be less than the
-    \c preferredHighlightEnd value.
-
-    These properties affect the position of the current item when the list is scrolled.
-    For example, if the currently selected item should stay in the middle of the
-    list when the view is scrolled, set the \c preferredHighlightBegin and
-    \c preferredHighlightEnd values to the top and bottom coordinates of where the middle
-    item would be. If the \c currentItem is changed programmatically, the list will
-    automatically scroll so that the current item is in the middle of the view.
-    Furthermore, the behavior of the current item index will occur whether or not a
-    highlight exists.
-
-    Valid values for \c highlightRangeMode are:
-
-    \list
-    \o ListView.ApplyRange - the view attempts to maintain the highlight within the range.
-       However, the highlight can move outside of the range at the ends of the list or due
-       to mouse interaction.
-    \o ListView.StrictlyEnforceRange - the highlight never moves outside of the range.
-       The current item changes if a keyboard or mouse action would cause the highlight to move
-       outside of the range.
-    \o ListView.NoHighlightRange - this is the default value.
-    \endlist
-*/
-void QSGListView::setHighlightFollowsCurrentItem(bool autoHighlight)
-{
-    Q_D(QSGListView);
-    if (d->autoHighlight != autoHighlight) {
-        if (!autoHighlight) {
-            if (d->highlightPosAnimator)
-                d->highlightPosAnimator->stop();
-            if (d->highlightSizeAnimator)
-                d->highlightSizeAnimator->stop();
-        }
-        QSGItemView::setHighlightFollowsCurrentItem(autoHighlight);
-    }
-}
-
-/*!
-    \qmlproperty real QtQuick2::ListView::spacing
-
-    This property holds the spacing between items.
-
-    The default value is 0.
-*/
-qreal QSGListView::spacing() const
-{
-    Q_D(const QSGListView);
-    return d->spacing;
-}
-
-void QSGListView::setSpacing(qreal spacing)
-{
-    Q_D(QSGListView);
-    if (spacing != d->spacing) {
-        d->spacing = spacing;
-        d->forceLayout = true;
-        d->layout();
-        emit spacingChanged();
-    }
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::ListView::orientation
-    This property holds the orientation of the list.
-
-    Possible values:
-
-    \list
-    \o ListView.Horizontal - Items are laid out horizontally
-    \o ListView.Vertical (default) - Items are laid out vertically
-    \endlist
-
-    \table
-    \row
-    \o Horizontal orientation:
-    \image ListViewHorizontal.png
-
-    \row
-    \o Vertical orientation:
-    \image listview-highlight.png
-    \endtable
-*/
-QSGListView::Orientation QSGListView::orientation() const
-{
-    Q_D(const QSGListView);
-    return d->orient;
-}
-
-void QSGListView::setOrientation(QSGListView::Orientation orientation)
-{
-    Q_D(QSGListView);
-    if (d->orient != orientation) {
-        d->orient = orientation;
-        if (d->orient == Vertical) {
-            setContentWidth(-1);
-            setFlickableDirection(VerticalFlick);
-            setContentX(0);
-        } else {
-            setContentHeight(-1);
-            setFlickableDirection(HorizontalFlick);
-            setContentY(0);
-        }
-        d->regenerate();
-        emit orientationChanged();
-    }
-}
-
-/*!
-  \qmlproperty enumeration QtQuick2::ListView::layoutDirection
-  This property holds the layout direction of the horizontal list.
-
-  Possible values:
-
-  \list
-  \o Qt.LeftToRight (default) - Items will be laid out from left to right.
-  \o Qt.RightToLeft - Items will be laid out from right to let.
-  \endlist
-
-  \sa ListView::effectiveLayoutDirection
-*/
-
-
-/*!
-    \qmlproperty enumeration QtQuick2::ListView::effectiveLayoutDirection
-    This property holds the effective layout direction of the horizontal list.
-
-    When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} for locale layouts,
-    the visual layout direction of the horizontal list will be mirrored. However, the
-    property \l {ListView::layoutDirection}{layoutDirection} will remain unchanged.
-
-    \sa ListView::layoutDirection, {LayoutMirroring}{LayoutMirroring}
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::ListView::keyNavigationWraps
-    This property holds whether the list wraps key navigation.
-
-    If this is true, key navigation that would move the current item selection
-    past the end of the list instead wraps around and moves the selection to
-    the start of the list, and vice-versa.
-
-    By default, key navigation is not wrapped.
-*/
-
-
-/*!
-    \qmlproperty int QtQuick2::ListView::cacheBuffer
-    This property determines whether delegates are retained outside the
-    visible area of the view.
-
-    If this value is non-zero, the view keeps as many delegates
-    instantiated as it can fit within the buffer specified.  For example,
-    if in a vertical view the delegate is 20 pixels high and \c cacheBuffer is
-    set to 40, then up to 2 delegates above and 2 delegates below the visible
-    area may be retained.
-
-    Note that cacheBuffer is not a pixel buffer - it only maintains additional
-    instantiated delegates.
-
-    Setting this value can improve the smoothness of scrolling behavior at the expense
-    of additional memory usage.  It is not a substitute for creating efficient
-    delegates; the fewer elements in a delegate, the faster a view can be
-    scrolled.
-*/
-
-
-/*!
-    \qmlproperty string QtQuick2::ListView::section.property
-    \qmlproperty enumeration QtQuick2::ListView::section.criteria
-    \qmlproperty Component QtQuick2::ListView::section.delegate
-    \qmlproperty enumeration QtQuick2::ListView::section.labelPositioning
-
-    These properties determine the expression to be evaluated and appearance
-    of the section labels.
-
-    \c section.property holds the name of the property that is the basis
-    of each section.
-
-    \c section.criteria holds the criteria for forming each section based on
-    \c section.property. This value can be one of:
-
-    \list
-    \o ViewSection.FullString (default) - sections are created based on the
-    \c section.property value.
-    \o ViewSection.FirstCharacter - sections are created based on the first
-    character of the \c section.property value (for example, 'A', 'B', 'C'
-    sections, etc. for an address book)
-    \endlist
-
-    \c section.delegate holds the delegate component for each section.
-
-    \c section.labelPositioning determines whether the current and/or
-    next section labels stick to the start/end of the view, and whether
-    the labels are shown inline.  This value can be a combination of:
-
-    \list
-    \o ViewSection.InlineLabels - section labels are shown inline between
-    the item delegates separating sections (default).
-    \o ViewSection.CurrentLabelAtStart - the current section label sticks to the
-    start of the view as it is moved.
-    \o ViewSection.NextLabelAtEnd - the next section label (beyond all visible
-    sections) sticks to the end of the view as it is moved. \note Enabling
-    \c ViewSection.NextLabelAtEnd requires the view to scan ahead for the next
-    section, which has performance implications, especially for slower models.
-    \endlist
-
-    Each item in the list has attached properties named \c ListView.section,
-    \c ListView.previousSection and \c ListView.nextSection.
-
-    For example, here is a ListView that displays a list of animals, separated
-    into sections. Each item in the ListView is placed in a different section
-    depending on the "size" property of the model item. The \c sectionHeading
-    delegate component provides the light blue bar that marks the beginning of
-    each section.
-
-
-    \snippet examples/declarative/modelviews/listview/sections.qml 0
-
-    \image qml-listview-sections-example.png
-
-    \note Adding sections to a ListView does not automatically re-order the
-    list items by the section criteria.
-    If the model is not ordered by section, then it is possible that
-    the sections created will not be unique; each boundary between
-    differing sections will result in a section header being created
-    even if that section exists elsewhere.
-
-    \sa {declarative/modelviews/listview}{ListView examples}
-*/
-QSGViewSection *QSGListView::sectionCriteria()
-{
-    Q_D(QSGListView);
-    if (!d->sectionCriteria) {
-        d->sectionCriteria = new QSGViewSection(this);
-        connect(d->sectionCriteria, SIGNAL(propertyChanged()), this, SLOT(updateSections()));
-    }
-    return d->sectionCriteria;
-}
-
-/*!
-    \qmlproperty string QtQuick2::ListView::currentSection
-    This property holds the section that is currently at the beginning of the view.
-*/
-QString QSGListView::currentSection() const
-{
-    Q_D(const QSGListView);
-    return d->currentSection;
-}
-
-/*!
-    \qmlproperty real QtQuick2::ListView::highlightMoveSpeed
-    \qmlproperty int QtQuick2::ListView::highlightMoveDuration
-    \qmlproperty real QtQuick2::ListView::highlightResizeSpeed
-    \qmlproperty int QtQuick2::ListView::highlightResizeDuration
-
-    These properties hold the move and resize animation speed of the highlight delegate.
-
-    \l highlightFollowsCurrentItem must be true for these properties
-    to have effect.
-
-    The default value for the speed properties is 400 pixels/second.
-    The default value for the duration properties is -1, i.e. the
-    highlight will take as much time as necessary to move at the set speed.
-
-    These properties have the same characteristics as a SmoothedAnimation.
-
-    \sa highlightFollowsCurrentItem
-*/
-qreal QSGListView::highlightMoveSpeed() const
-{
-    Q_D(const QSGListView);
-    return d->highlightMoveSpeed;
-}
-
-void QSGListView::setHighlightMoveSpeed(qreal speed)
-{
-    Q_D(QSGListView);
-    if (d->highlightMoveSpeed != speed) {
-        d->highlightMoveSpeed = speed;
-        if (d->highlightPosAnimator)
-            d->highlightPosAnimator->velocity = d->highlightMoveSpeed;
-        emit highlightMoveSpeedChanged();
-    }
-}
-
-void QSGListView::setHighlightMoveDuration(int duration)
-{
-    Q_D(QSGListView);
-    if (d->highlightMoveDuration != duration) {
-        if (d->highlightPosAnimator)
-            d->highlightPosAnimator->userDuration = duration;
-        QSGItemView::setHighlightMoveDuration(duration);
-    }
-}
-
-qreal QSGListView::highlightResizeSpeed() const
-{
-    Q_D(const QSGListView);
-    return d->highlightResizeSpeed;
-}
-
-void QSGListView::setHighlightResizeSpeed(qreal speed)
-{
-    Q_D(QSGListView);
-    if (d->highlightResizeSpeed != speed) {
-        d->highlightResizeSpeed = speed;
-        if (d->highlightSizeAnimator)
-            d->highlightSizeAnimator->velocity = d->highlightResizeSpeed;
-        emit highlightResizeSpeedChanged();
-    }
-}
-
-int QSGListView::highlightResizeDuration() const
-{
-    Q_D(const QSGListView);
-    return d->highlightResizeDuration;
-}
-
-void QSGListView::setHighlightResizeDuration(int duration)
-{
-    Q_D(QSGListView);
-    if (d->highlightResizeDuration != duration) {
-        d->highlightResizeDuration = duration;
-        if (d->highlightSizeAnimator)
-            d->highlightSizeAnimator->userDuration = d->highlightResizeDuration;
-        emit highlightResizeDurationChanged();
-    }
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::ListView::snapMode
-
-    This property determines how the view scrolling will settle following a drag or flick.
-    The possible values are:
-
-    \list
-    \o ListView.NoSnap (default) - the view stops anywhere within the visible area.
-    \o ListView.SnapToItem - the view settles with an item aligned with the start of
-    the view.
-    \o ListView.SnapOneItem - the view settles no more than one item away from the first
-    visible item at the time the mouse button is released.  This mode is particularly
-    useful for moving one page at a time.
-    \endlist
-
-    \c snapMode does not affect the \l currentIndex.  To update the
-    \l currentIndex as the list is moved, set \l highlightRangeMode
-    to \c ListView.StrictlyEnforceRange.
-
-    \sa highlightRangeMode
-*/
-QSGListView::SnapMode QSGListView::snapMode() const
-{
-    Q_D(const QSGListView);
-    return d->snapMode;
-}
-
-void QSGListView::setSnapMode(SnapMode mode)
-{
-    Q_D(QSGListView);
-    if (d->snapMode != mode) {
-        d->snapMode = mode;
-        emit snapModeChanged();
-    }
-}
-
-
-/*!
-    \qmlproperty Component QtQuick2::ListView::footer
-    This property holds the component to use as the footer.
-
-    An instance of the footer component is created for each view.  The
-    footer is positioned at the end of the view, after any items.
-
-    \sa header
-*/
-
-
-/*!
-    \qmlproperty Component QtQuick2::ListView::header
-    This property holds the component to use as the header.
-
-    An instance of the header component is created for each view.  The
-    header is positioned at the beginning of the view, before any items.
-
-    \sa footer
-*/
-
-void QSGListView::viewportMoved()
-{
-    Q_D(QSGListView);
-    QSGItemView::viewportMoved();
-    if (!d->itemCount)
-        return;
-    // Recursion can occur due to refill changing the content size.
-    if (d->inViewportMoved)
-        return;
-    d->inViewportMoved = true;
-    d->lazyRelease = true;
-    d->refill();
-    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 = 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);
-            } else {
-                d->updateHighlight();
-            }
-
-            // update current index
-            if (FxViewItem *snapItem = d->snapItemAt(d->highlight->position())) {
-                if (snapItem->index >= 0 && snapItem->index != d->currentIndex)
-                    d->updateCurrent(snapItem->index);
-            }
-        }
-    }
-
-    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.
-        if (yflick() && !d->vData.inOvershoot) {
-            if (d->vData.velocity > 0) {
-                const qreal minY = minYExtent();
-                if ((minY - d->vData.move.value() < height()/2 || d->vData.flickTarget - d->vData.move.value() < height()/2)
-                    && minY != d->vData.flickTarget)
-                    d->flickY(-d->vData.smoothVelocity.value());
-                d->bufferMode = QSGListViewPrivate::BufferBefore;
-            } else if (d->vData.velocity < 0) {
-                const qreal maxY = maxYExtent();
-                if ((d->vData.move.value() - maxY < height()/2 || d->vData.move.value() - d->vData.flickTarget < height()/2)
-                    && maxY != d->vData.flickTarget)
-                    d->flickY(-d->vData.smoothVelocity.value());
-                d->bufferMode = QSGListViewPrivate::BufferAfter;
-            }
-        }
-
-        if (xflick() && !d->hData.inOvershoot) {
-            if (d->hData.velocity > 0) {
-                const qreal minX = minXExtent();
-                if ((minX - d->hData.move.value() < width()/2 || d->hData.flickTarget - d->hData.move.value() < width()/2)
-                    && minX != d->hData.flickTarget)
-                    d->flickX(-d->hData.smoothVelocity.value());
-                d->bufferMode = d->isRightToLeft() ? QSGListViewPrivate::BufferAfter : QSGListViewPrivate::BufferBefore;
-            } else if (d->hData.velocity < 0) {
-                const qreal maxX = maxXExtent();
-                if ((d->hData.move.value() - maxX < width()/2 || d->hData.move.value() - d->hData.flickTarget < width()/2)
-                    && maxX != d->hData.flickTarget)
-                    d->flickX(-d->hData.smoothVelocity.value());
-                d->bufferMode = d->isRightToLeft() ? QSGListViewPrivate::BufferBefore : QSGListViewPrivate::BufferAfter;
-            }
-        }
-        d->inFlickCorrection = false;
-    }
-    if (d->sectionCriteria) {
-        d->updateCurrentSection();
-        d->updateStickySections();
-    }
-    d->inViewportMoved = false;
-}
-
-void QSGListView::keyPressEvent(QKeyEvent *event)
-{
-    Q_D(QSGListView);
-    if (d->model && d->model->count() && d->interactive) {
-        if ((d->orient == QSGListView::Horizontal && !d->isRightToLeft() && event->key() == Qt::Key_Left)
-                    || (d->orient == QSGListView::Horizontal && d->isRightToLeft() && event->key() == Qt::Key_Right)
-                    || (d->orient == QSGListView::Vertical && event->key() == Qt::Key_Up)) {
-            if (currentIndex() > 0 || (d->wrap && !event->isAutoRepeat())) {
-                decrementCurrentIndex();
-                event->accept();
-                return;
-            } else if (d->wrap) {
-                event->accept();
-                return;
-            }
-        } else if ((d->orient == QSGListView::Horizontal && !d->isRightToLeft() && event->key() == Qt::Key_Right)
-                    || (d->orient == QSGListView::Horizontal && d->isRightToLeft() && event->key() == Qt::Key_Left)
-                    || (d->orient == QSGListView::Vertical && event->key() == Qt::Key_Down)) {
-            if (currentIndex() < d->model->count() - 1 || (d->wrap && !event->isAutoRepeat())) {
-                incrementCurrentIndex();
-                event->accept();
-                return;
-            } else if (d->wrap) {
-                event->accept();
-                return;
-            }
-        }
-    }
-    event->ignore();
-    QSGItemView::keyPressEvent(event);
-}
-
-void QSGListView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
-{
-    Q_D(QSGListView);
-    if (d->isRightToLeft() && d->orient == QSGListView::Horizontal) {
-        // maintain position relative to the right edge
-        int dx = newGeometry.width() - oldGeometry.width();
-        setContentX(contentX() - dx);
-    }
-    QSGItemView::geometryChanged(newGeometry, oldGeometry);
-}
-
-
-/*!
-    \qmlmethod QtQuick2::ListView::incrementCurrentIndex()
-
-    Increments the current index.  The current index will wrap
-    if keyNavigationWraps is true and it is currently at the end.
-    This method has no effect if the \l count is zero.
-
-    \bold Note: methods should only be called after the Component has completed.
-*/
-void QSGListView::incrementCurrentIndex()
-{
-    Q_D(QSGListView);
-    int count = d->model ? d->model->count() : 0;
-    if (count && (currentIndex() < count - 1 || d->wrap)) {
-        d->moveReason = QSGListViewPrivate::SetIndex;
-        int index = currentIndex()+1;
-        setCurrentIndex((index >= 0 && index < count) ? index : 0);
-    }
-}
-
-/*!
-    \qmlmethod QtQuick2::ListView::decrementCurrentIndex()
-
-    Decrements the current index.  The current index will wrap
-    if keyNavigationWraps is true and it is currently at the beginning.
-    This method has no effect if the \l count is zero.
-
-    \bold Note: methods should only be called after the Component has completed.
-*/
-void QSGListView::decrementCurrentIndex()
-{
-    Q_D(QSGListView);
-    int count = d->model ? d->model->count() : 0;
-    if (count && (currentIndex() > 0 || d->wrap)) {
-        d->moveReason = QSGListViewPrivate::SetIndex;
-        int index = currentIndex()-1;
-        setCurrentIndex((index >= 0 && index < count) ? index : count-1);
-    }
-}
-
-void QSGListView::updateSections()
-{
-    Q_D(QSGListView);
-    if (isComponentComplete() && d->model) {
-        QList<QByteArray> roles;
-        if (d->sectionCriteria && !d->sectionCriteria->property().isEmpty())
-            roles << d->sectionCriteria->property().toUtf8();
-        d->model->setWatchedRoles(roles);
-        d->updateSections();
-        if (d->itemCount) {
-            d->forceLayout = true;
-            d->layout();
-        }
-    }
-}
-
-bool QSGListViewPrivate::applyInsertionChange(const QDeclarativeChangeSet::Insert &change, FxViewItem *firstVisible, InsertionsResult *insertResult)
-{
-    Q_Q(QSGListView);
-
-    int modelIndex = change.index;
-    int count = change.count;
-
-
-    qreal tempPos = isRightToLeft() ? -position()-size() : position();
-    int index = visibleItems.count() ? mapFromModel(modelIndex) : 0;
-
-    if (index < 0) {
-        int i = visibleItems.count() - 1;
-        while (i > 0 && visibleItems.at(i)->index == -1)
-            --i;
-        if (i == 0 && visibleItems.first()->index == -1) {
-            // there are no visible items except items marked for removal
-            index = visibleItems.count();
-        } else if (visibleItems.at(i)->index + 1 == modelIndex
-            && visibleItems.at(i)->endPosition() <= buffer+tempPos+size()) {
-            // Special case of appending an item to the model.
-            index = visibleItems.count();
-        } else {
-            if (modelIndex < visibleIndex) {
-                // Insert before visible items
-                visibleIndex += count;
-                for (int i = 0; i < visibleItems.count(); ++i) {
-                    FxViewItem *item = visibleItems.at(i);
-                    if (item->index != -1 && item->index >= modelIndex)
-                        item->index += count;
-                }
-            }
-            return true;
-        }
-    }
-
-    // index can be the next item past the end of the visible items list (i.e. appended)
-    int pos = 0;
-    if (visibleItems.count()) {
-        pos = index < visibleItems.count() ? visibleItems.at(index)->position()
-                                                : visibleItems.last()->endPosition()+spacing;
-    }
-
-    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; --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()) {
-                    insertResult->addedItems.append(item);
-                    insertResult->sizeAddedBeforeVisible += item->size();
-                }
-                pos -= item->size() + spacing;
-            }
-            index++;
-        }
-    } else {
-        int i = 0;
-        int to = buffer+tempPos+size();
-        for (i = 0; i < count && pos <= to; ++i) {
-            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);
-            pos += item->size() + spacing;
-            ++index;
-        }
-    }
-
-    for (; index < visibleItems.count(); ++index) {
-        FxViewItem *item = visibleItems.at(index);
-        if (item->index != -1)
-            item->index += count;
-    }
-
-    updateVisibleIndex();
-
-    return insertResult->addedItems.count() > prevAddedCount;
-}
-
-
-/*!
-    \qmlmethod QtQuick2::ListView::positionViewAtIndex(int index, PositionMode mode)
-
-    Positions the view such that the \a index is at the position specified by
-    \a mode:
-
-    \list
-    \o ListView.Beginning - position item at the top (or left for horizontal orientation) of the view.
-    \o ListView.Center - position item in the center of the view.
-    \o ListView.End - position item at bottom (or right for horizontal orientation) of the view.
-    \o ListView.Visible - if any part of the item is visible then take no action, otherwise
-    bring the item into view.
-    \o ListView.Contain - ensure the entire item is visible.  If the item is larger than
-    the view the item is positioned at the top (or left for horizontal orientation) of the view.
-    \endlist
-
-    If positioning the view at \a index would cause empty space to be displayed at
-    the beginning or end of the view, the view will be positioned at the boundary.
-
-    It is not recommended to use \l {Flickable::}{contentX} or \l {Flickable::}{contentY} to position the view
-    at a particular index.  This is unreliable since removing items from the start
-    of the list does not cause all other items to be repositioned, and because
-    the actual start of the view can vary based on the size of the delegates.
-    The correct way to bring an item into view is with \c positionViewAtIndex.
-
-    \bold Note: methods should only be called after the Component has completed.  To position
-    the view at startup, this method should be called by Component.onCompleted.  For
-    example, to position the view at the end:
-
-    \code
-    Component.onCompleted: positionViewAtIndex(count - 1, ListView.Beginning)
-    \endcode
-*/
-
-/*!
-    \qmlmethod QtQuick2::ListView::positionViewAtBeginning()
-    \qmlmethod QtQuick2::ListView::positionViewAtEnd()
-
-    Positions the view at the beginning or end, taking into account any header or footer.
-
-    It is not recommended to use \l {Flickable::}{contentX} or \l {Flickable::}{contentY} to position the view
-    at a particular index.  This is unreliable since removing items from the start
-    of the list does not cause all other items to be repositioned, and because
-    the actual start of the view can vary based on the size of the delegates.
-
-    \bold Note: methods should only be called after the Component has completed.  To position
-    the view at startup, this method should be called by Component.onCompleted.  For
-    example, to position the view at the end on startup:
-
-    \code
-    Component.onCompleted: positionViewAtEnd()
-    \endcode
-*/
-
-/*!
-    \qmlmethod int QtQuick2::ListView::indexAt(int x, int y)
-
-    Returns the index of the visible item containing the point \a x, \a y in content
-    coordinates.  If there is no item at the point specified, or the item is
-    not visible -1 is returned.
-
-    If the item is outside the visible area, -1 is returned, regardless of
-    whether an item will exist at that point when scrolled into view.
-
-    \bold Note: methods should only be called after the Component has completed.
-*/
-
-QSGListViewAttached *QSGListView::qmlAttachedProperties(QObject *obj)
-{
-    return new QSGListViewAttached(obj);
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsglistview_p.h b/src/declarative/items/qsglistview_p.h
deleted file mode 100644 (file)
index a3c31df..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-// Commit: 95814418f9d6adeba365c795462e8afb00138211
-/****************************************************************************
-**
-** 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 QSGLISTVIEW_P_H
-#define QSGLISTVIEW_P_H
-
-#include "qsgitemview_p.h"
-
-#include <private/qdeclarativeguard_p.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGListView;
-class QSGListViewPrivate;
-class Q_AUTOTEST_EXPORT QSGViewSection : public QObject
-{
-    Q_OBJECT
-    Q_PROPERTY(QString property READ property WRITE setProperty NOTIFY propertyChanged)
-    Q_PROPERTY(SectionCriteria criteria READ criteria WRITE setCriteria NOTIFY criteriaChanged)
-    Q_PROPERTY(QDeclarativeComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
-    Q_PROPERTY(int labelPositioning READ labelPositioning WRITE setLabelPositioning NOTIFY labelPositioningChanged)
-    Q_ENUMS(SectionCriteria)
-    Q_ENUMS(LabelPositioning)
-public:
-    QSGViewSection(QSGListView *parent=0);
-
-    QString property() const { return m_property; }
-    void setProperty(const QString &);
-
-    enum SectionCriteria { FullString, FirstCharacter };
-    SectionCriteria criteria() const { return m_criteria; }
-    void setCriteria(SectionCriteria);
-
-    QDeclarativeComponent *delegate() const { return m_delegate; }
-    void setDelegate(QDeclarativeComponent *delegate);
-
-    QString sectionString(const QString &value);
-
-    enum LabelPositioning { InlineLabels = 0x01, CurrentLabelAtStart = 0x02, NextLabelAtEnd = 0x04 };
-    int labelPositioning() { return m_labelPositioning; }
-    void setLabelPositioning(int pos);
-
-Q_SIGNALS:
-    void propertyChanged();
-    void criteriaChanged();
-    void delegateChanged();
-    void labelPositioningChanged();
-
-private:
-    QString m_property;
-    SectionCriteria m_criteria;
-    QDeclarativeComponent *m_delegate;
-    int m_labelPositioning;
-    QSGListViewPrivate *m_view;
-};
-
-
-class QSGVisualModel;
-class QSGListViewAttached;
-class Q_AUTOTEST_EXPORT QSGListView : public QSGItemView
-{
-    Q_OBJECT
-    Q_DECLARE_PRIVATE(QSGListView)
-
-    // XXX deprecate these two properties (only duration should be necessary)
-    Q_PROPERTY(qreal highlightMoveSpeed READ highlightMoveSpeed WRITE setHighlightMoveSpeed NOTIFY highlightMoveSpeedChanged)
-    Q_PROPERTY(qreal highlightResizeSpeed READ highlightResizeSpeed WRITE setHighlightResizeSpeed NOTIFY highlightResizeSpeedChanged)
-
-    Q_PROPERTY(int highlightResizeDuration READ highlightResizeDuration WRITE setHighlightResizeDuration NOTIFY highlightResizeDurationChanged)
-
-    Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing NOTIFY spacingChanged)
-    Q_PROPERTY(Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged)
-
-    Q_PROPERTY(QSGViewSection *section READ sectionCriteria CONSTANT)
-    Q_PROPERTY(QString currentSection READ currentSection NOTIFY currentSectionChanged)
-
-    Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged)
-
-    Q_ENUMS(Orientation)
-    Q_ENUMS(SnapMode)
-    Q_CLASSINFO("DefaultProperty", "data")
-
-public:
-    QSGListView(QSGItem *parent=0);
-    ~QSGListView();
-
-    qreal spacing() const;
-    void setSpacing(qreal spacing);
-
-    enum Orientation { Horizontal = Qt::Horizontal, Vertical = Qt::Vertical };
-    Orientation orientation() const;
-    void setOrientation(Orientation);
-
-    QSGViewSection *sectionCriteria();
-    QString currentSection() const;
-
-    virtual void setHighlightFollowsCurrentItem(bool);
-
-    qreal highlightMoveSpeed() const;
-    void setHighlightMoveSpeed(qreal);
-
-    qreal highlightResizeSpeed() const;
-    void setHighlightResizeSpeed(qreal);
-
-    int highlightResizeDuration() const;
-    void setHighlightResizeDuration(int);
-
-    virtual void setHighlightMoveDuration(int);
-
-    enum SnapMode { NoSnap, SnapToItem, SnapOneItem };
-    SnapMode snapMode() const;
-    void setSnapMode(SnapMode mode);
-
-    static QSGListViewAttached *qmlAttachedProperties(QObject *);
-
-public Q_SLOTS:
-    void incrementCurrentIndex();
-    void decrementCurrentIndex();
-
-Q_SIGNALS:
-    void spacingChanged();
-    void orientationChanged();
-    void currentSectionChanged();
-    void highlightMoveSpeedChanged();
-    void highlightResizeSpeedChanged();
-    void highlightResizeDurationChanged();
-    void snapModeChanged();
-
-protected:
-    virtual void viewportMoved();
-    virtual void keyPressEvent(QKeyEvent *);
-    virtual void geometryChanged(const QRectF &newGeometry,const QRectF &oldGeometry);
-
-protected Q_SLOTS:
-    void updateSections();
-};
-
-class QSGListViewAttached : public QSGItemViewAttached
-{
-    Q_OBJECT
-
-public:
-    QSGListViewAttached(QObject *parent)
-        : QSGItemViewAttached(parent), m_view(0) {}
-    ~QSGListViewAttached() {}
-
-    Q_PROPERTY(QSGListView *view READ view NOTIFY viewChanged)
-    QSGListView *view() { return m_view; }
-    void setView(QSGListView *view) {
-        if (view != m_view) {
-            m_view = view;
-            emit viewChanged();
-        }
-    }
-
-Q_SIGNALS:
-    void viewChanged();
-
-public:
-    QDeclarativeGuard<QSGListView> m_view;
-};
-
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPEINFO(QSGListView, QML_HAS_ATTACHED_PROPERTIES)
-QML_DECLARE_TYPE(QSGListView)
-QML_DECLARE_TYPE(QSGViewSection)
-
-QT_END_HEADER
-
-#endif // QSGLISTVIEW_P_H
diff --git a/src/declarative/items/qsgloader.cpp b/src/declarative/items/qsgloader.cpp
deleted file mode 100644 (file)
index e655e17..0000000
+++ /dev/null
@@ -1,853 +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 "qsgloader_p_p.h"
-
-#include <QtDeclarative/qdeclarativeinfo.h>
-
-#include <private/qdeclarativeengine_p.h>
-#include <private/qdeclarativeglobal_p.h>
-
-#include <private/qdeclarativecomponent_p.h>
-
-#include <private/qv8_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QSGLoaderPrivate::QSGLoaderPrivate()
-    : 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();
-}
-
-void QSGLoaderPrivate::itemGeometryChanged(QSGItem *resizeItem, const QRectF &newGeometry, const QRectF &oldGeometry)
-{
-    if (resizeItem == item) {
-        if (!updatingSize && newGeometry.width() != oldGeometry.width())
-            itemWidthValid = true;
-        if (!updatingSize && newGeometry.height() != oldGeometry.height())
-            itemHeightValid = true;
-        _q_updateSize(false);
-    }
-    QSGItemChangeListener::itemGeometryChanged(resizeItem, newGeometry, oldGeometry);
-}
-
-void QSGLoaderPrivate::clear()
-{
-    disposeInitialPropertyValues();
-
-    if (incubator)
-        incubator->clear();
-
-    if (loadingFromSource && component) {
-        component->deleteLater();
-        component = 0;
-    }
-    source = QUrl();
-
-    if (item) {
-        QSGItemPrivate *p = QSGItemPrivate::get(item);
-        p->removeItemChangeListener(this, QSGItemPrivate::Geometry);
-
-        // We can't delete immediately because our item may have triggered
-        // the Loader to load a different item.
-        item->setParentItem(0);
-        item->setVisible(false);
-        item->deleteLater();
-        item = 0;
-    }
-}
-
-void QSGLoaderPrivate::initResize()
-{
-    QSGItemPrivate *p = QSGItemPrivate::get(item);
-    p->addItemChangeListener(this, QSGItemPrivate::Geometry);
-    // We may override the item's size, so we need to remember
-    // whether the item provided its own valid size.
-    itemWidthValid = p->widthValid;
-    itemHeightValid = p->heightValid;
-    _q_updateSize();
-}
-
-/*!
-    \qmlclass Loader QSGLoader
-    \inqmlmodule QtQuick 2
-    \ingroup qml-utility-elements
-    \inherits Item
-
-    \brief The Loader item allows dynamically loading an Item-based
-    subtree from a URL or Component.
-
-    Loader is used to dynamically load visual QML components. It can load a
-    QML file (using the \l source property) or a \l Component object (using
-    the \l sourceComponent property). It is useful for delaying the creation
-    of a component until it is required: for example, when a component should
-    be created on demand, or when a component should not be created
-    unnecessarily for performance reasons.
-
-    Here is a Loader that loads "Page1.qml" as a component when the
-    \l MouseArea is clicked:
-
-    \snippet doc/src/snippets/declarative/loader/simple.qml 0
-
-    The loaded item can be accessed using the \l item property.
-
-    If the \l source or \l sourceComponent changes, any previously instantiated
-    items are destroyed. Setting \l source to an empty string or setting
-    \l sourceComponent to \c undefined destroys the currently loaded item,
-    freeing resources and leaving the Loader empty.
-
-    \section2 Loader sizing behavior
-
-    Loader is like any other visual item and must be positioned and sized
-    accordingly to become visible.
-
-    \list
-    \o If an explicit size is not specified for the Loader, the Loader
-    is automatically resized to the size of the loaded item once the
-    component is loaded.
-    \o If the size of the Loader is specified explicitly by setting
-    the width, height or by anchoring, the loaded item will be resized
-    to the size of the Loader.
-    \endlist
-
-    In both scenarios the size of the item and the Loader are identical.
-    This ensures that anchoring to the Loader is equivalent to anchoring
-    to the loaded item.
-
-    \table
-    \row
-    \o sizeloader.qml
-    \o sizeitem.qml
-    \row
-    \o \snippet doc/src/snippets/declarative/loader/sizeloader.qml 0
-    \o \snippet doc/src/snippets/declarative/loader/sizeitem.qml 0
-    \row
-    \o The red rectangle will be sized to the size of the root item.
-    \o The red rectangle will be 50x50, centered in the root item.
-    \endtable
-
-
-    \section2 Receiving signals from loaded items
-
-    Any signals emitted from the loaded item can be received using the
-    \l Connections element. For example, the following \c application.qml
-    loads \c MyItem.qml, and is able to receive the \c message signal from
-    the loaded item through a \l Connections object:
-
-    \table
-    \row
-    \o application.qml
-    \o MyItem.qml
-    \row
-    \o \snippet doc/src/snippets/declarative/loader/connections.qml 0
-    \o \snippet doc/src/snippets/declarative/loader/MyItem.qml 0
-    \endtable
-
-    Alternatively, since \c MyItem.qml is loaded within the scope of the
-    Loader, it could also directly call any function defined in the Loader or
-    its parent \l Item.
-
-
-    \section2 Focus and key events
-
-    Loader is a focus scope. Its \l {Item::}{focus} property must be set to
-    \c true for any of its children to get the \e {active focus}. (See
-    \l{qmlfocus#Acquiring Focus and Focus Scopes}{the focus documentation page}
-    for more details.) Any key events received in the loaded item should likely
-    also be \l {KeyEvent::}{accepted} so they are not propagated to the Loader.
-
-    For example, the following \c application.qml loads \c KeyReader.qml when
-    the \l MouseArea is clicked.  Notice the \l {Item::}{focus} property is
-    set to \c true for the Loader as well as the \l Item in the dynamically
-    loaded object:
-
-    \table
-    \row
-    \o application.qml
-    \o KeyReader.qml
-    \row
-    \o \snippet doc/src/snippets/declarative/loader/focus.qml 0
-    \o \snippet doc/src/snippets/declarative/loader/KeyReader.qml 0
-    \endtable
-
-    Once \c KeyReader.qml is loaded, it accepts key events and sets
-    \c event.accepted to \c true so that the event is not propagated to the
-    parent \l Rectangle.
-
-    \sa {dynamic-object-creation}{Dynamic Object Creation}
-*/
-
-QSGLoader::QSGLoader(QSGItem *parent)
-  : QSGImplicitSizeItem(*(new QSGLoaderPrivate), parent)
-{
-    setFlag(ItemIsFocusScope);
-}
-
-QSGLoader::~QSGLoader()
-{
-    Q_D(QSGLoader);
-    if (d->item) {
-        QSGItemPrivate *p = QSGItemPrivate::get(d->item);
-        p->removeItemChangeListener(d, QSGItemPrivate::Geometry);
-    }
-}
-
-/*!
-    \qmlproperty bool QtQuick2::Loader::active
-    This property is \c true if the Loader is currently active.
-    The default value for the \l active property is \c true.
-
-    If the Loader is inactive, changing the \l source or \l sourceComponent
-    will not cause the item to be instantiated until the Loader is made active.
-
-    Setting the value to inactive will cause any \l item loaded by the loader
-    to be released, but will not affect the \l source or \l sourceComponent.
-
-    The \l status of an inactive loader is always \c Null.
-
-    \sa source, sourceComponent
- */
-bool QSGLoader::active() const
-{
-    Q_D(const QSGLoader);
-    return d->active;
-}
-
-void QSGLoader::setActive(bool newVal)
-{
-    Q_D(QSGLoader);
-    if (d->active != newVal) {
-        d->active = newVal;
-        if (newVal == true) {
-            if (d->loadingFromSource) {
-                loadFromSource();
-            } else {
-                loadFromSourceComponent();
-            }
-        } else {
-            if (d->item) {
-                QSGItemPrivate *p = QSGItemPrivate::get(d->item);
-                p->removeItemChangeListener(d, QSGItemPrivate::Geometry);
-
-                // We can't delete immediately because our item may have triggered
-                // the Loader to load a different item.
-                d->item->setParentItem(0);
-                d->item->setVisible(false);
-                d->item->deleteLater();
-                d->item = 0;
-                emit itemChanged();
-            }
-            emit statusChanged();
-        }
-        emit activeChanged();
-    }
-}
-
-
-/*!
-    \qmlproperty url QtQuick2::Loader::source
-    This property holds the URL of the QML component to instantiate.
-
-    Note the QML component must be an \l{Item}-based component. The loader
-    cannot load non-visual components.
-
-    To unload the currently loaded item, set this property to an empty string,
-    or set \l sourceComponent to \c undefined. Setting \c source to a
-    new URL will also cause the item created by the previous URL to be unloaded.
-
-    \sa sourceComponent, status, progress
-*/
-QUrl QSGLoader::source() const
-{
-    Q_D(const QSGLoader);
-    return d->source;
-}
-
-void QSGLoader::setSource(const QUrl &url)
-{
-    setSource(url, true); // clear previous values
-}
-
-void QSGLoader::setSource(const QUrl &url, bool needsClear)
-{
-    Q_D(QSGLoader);
-    if (d->source == url)
-        return;
-
-    if (needsClear)
-        d->clear();
-
-    d->source = url;
-    d->loadingFromSource = true;
-
-    if (d->active)
-        loadFromSource();
-    else
-        emit sourceChanged();
-}
-
-void QSGLoader::loadFromSource()
-{
-    Q_D(QSGLoader);
-    if (d->source.isEmpty()) {
-        emit sourceChanged();
-        emit statusChanged();
-        emit progressChanged();
-        emit itemChanged();
-        return;
-    }
-
-    if (isComponentComplete()) {
-        d->component = new QDeclarativeComponent(qmlEngine(this), d->source, this);
-        d->load();
-    }
-}
-
-/*!
-    \qmlproperty Component QtQuick2::Loader::sourceComponent
-    This property holds the \l{Component} to instantiate.
-
-    \qml
-    Item {
-        Component {
-            id: redSquare
-            Rectangle { color: "red"; width: 10; height: 10 }
-        }
-
-        Loader { sourceComponent: redSquare }
-        Loader { sourceComponent: redSquare; x: 10 }
-    }
-    \endqml
-
-    To unload the currently loaded item, set this property to an empty string
-    or \c undefined.
-
-    \sa source, progress
-*/
-
-QDeclarativeComponent *QSGLoader::sourceComponent() const
-{
-    Q_D(const QSGLoader);
-    return d->component;
-}
-
-void QSGLoader::setSourceComponent(QDeclarativeComponent *comp)
-{
-    Q_D(QSGLoader);
-    if (comp == d->component)
-        return;
-
-    d->clear();
-
-    d->component = comp;
-    d->loadingFromSource = false;
-
-    if (d->active)
-        loadFromSourceComponent();
-    else
-        emit sourceComponentChanged();
-}
-
-void QSGLoader::resetSourceComponent()
-{
-    setSourceComponent(0);
-}
-
-void QSGLoader::loadFromSourceComponent()
-{
-    Q_D(QSGLoader);
-    if (!d->component) {
-        emit sourceComponentChanged();
-        emit statusChanged();
-        emit progressChanged();
-        emit itemChanged();
-        return;
-    }
-
-    if (isComponentComplete())
-        d->load();
-}
-
-/*!
-    \qmlmethod object QtQuick2::Loader::setSource(url source, object properties)
-
-    Creates an object instance of the given \a source component that will have
-    the given \a properties. The \a properties argument is optional.  The instance
-    will be accessible via the \l item property once loading and instantiation
-    is complete.
-
-    If the \l active property is \c false at the time when this function is called,
-    the given \a source component will not be loaded but the \a source and initial
-    \a properties will be cached.  When the loader is made \l active, an instance of
-    the \a source component will be created with the initial \a properties set.
-
-    Setting the initial property values of an instance of a component in this manner
-    will \e not trigger any associated \l{Behavior}s.
-
-    Note that the cached \a properties will be cleared if the \l source or \l sourceComponent
-    is changed after calling this function but prior to setting the loader \l active.
-
-    Example:
-    \table
-    \row
-    \o
-    \qml
-    // ExampleComponent.qml
-    import QtQuick 2.0
-    Rectangle {
-        id: rect
-        color: "red"
-        width: 10
-        height: 10
-
-        Behavior on color {
-            NumberAnimation {
-                target: rect
-                property: "width"
-                to: (rect.width + 20)
-                duration: 0
-            }
-        }
-    }
-    \endqml
-    \o
-    \qml
-    // example.qml
-    import QtQuick 2.0
-    Item {
-        Loader {
-            id: squareLoader
-            onLoaded: console.log(squareLoader.item.width); // prints [10], not [30]
-        }
-
-        Component.onCompleted: {
-            squareLoader.setSource("ExampleComponent.qml", { "color": "blue" });
-            // will trigger the onLoaded code when complete.
-        }
-    }
-    \endqml
-    \endtable
-
-    \sa source, active
-*/
-void QSGLoader::setSource(QDeclarativeV8Function *args)
-{
-    Q_ASSERT(args);
-    Q_D(QSGLoader);
-
-    bool ipvError = false;
-    args->returnValue(v8::Undefined());
-    v8::Handle<v8::Object> ipv = d->extractInitialPropertyValues(args, this, &ipvError);
-    if (ipvError)
-        return;
-
-    d->clear();
-    QUrl sourceUrl = d->resolveSourceUrl(args);
-    if (!ipv.IsEmpty()) {
-        d->disposeInitialPropertyValues();
-        d->initialPropertyValues = qPersistentNew(ipv);
-        d->qmlGlobalForIpv = qPersistentNew(args->qmlGlobal());
-    }
-
-    setSource(sourceUrl, false); // already cleared and set ipv above.
-}
-
-void QSGLoaderPrivate::disposeInitialPropertyValues()
-{
-    if (!initialPropertyValues.IsEmpty())
-        qPersistentDispose(initialPropertyValues);
-    if (!qmlGlobalForIpv.IsEmpty())
-        qPersistentDispose(qmlGlobalForIpv);
-}
-
-void QSGLoaderPrivate::load()
-{
-    Q_Q(QSGLoader);
-
-    if (!q->isComponentComplete() || !component)
-        return;
-
-    if (!component->isLoading()) {
-        _q_sourceLoaded();
-    } else {
-        QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)),
-                q, SLOT(_q_sourceLoaded()));
-        QObject::connect(component, SIGNAL(progressChanged(qreal)),
-                q, SIGNAL(progressChanged()));
-        emit q->statusChanged();
-        emit q->progressChanged();
-        if (loadingFromSource)
-            emit q->sourceChanged();
-        else
-            emit q->sourceComponentChanged();
-        emit q->itemChanged();
-    }
-}
-
-void QSGLoaderIncubator::setInitialState(QObject *o)
-{
-    loader->setInitialState(o);
-}
-
-void QSGLoaderPrivate::setInitialState(QObject *obj)
-{
-    Q_Q(QSGLoader);
-
-    QSGItem *item = qobject_cast<QSGItem*>(obj);
-    if (item) {
-        QDeclarative_setParent_noEvent(itemContext, obj);
-        QDeclarative_setParent_noEvent(item, q);
-        item->setParentItem(q);
-    }
-
-    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 {
-            qmlInfo(q) << QSGLoader::tr("Loader does not support loading non-visual elements.");
-            delete itemContext;
-            itemContext = 0;
-            delete obj;
-        }
-    } 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();
-        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();
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::Loader::status
-
-    This property holds the status of QML loading.  It can be one of:
-    \list
-    \o Loader.Null - the loader is inactive or no QML source has been set
-    \o Loader.Ready - the QML source has been loaded
-    \o Loader.Loading - the QML source is currently being loaded
-    \o Loader.Error - an error occurred while loading the QML source
-    \endlist
-
-    Use this status to provide an update or respond to the status change in some way.
-    For example, you could:
-
-    \list
-    \o Trigger a state change:
-    \qml
-        State { name: 'loaded'; when: loader.status == Loader.Ready }
-    \endqml
-
-    \o Implement an \c onStatusChanged signal handler:
-    \qml
-        Loader {
-            id: loader
-            onStatusChanged: if (loader.status == Loader.Ready) console.log('Loaded')
-        }
-    \endqml
-
-    \o Bind to the status value:
-    \qml
-        Text { text: loader.status == Loader.Ready ? 'Loaded' : 'Not loaded' }
-    \endqml
-    \endlist
-
-    Note that if the source is a local file, the status will initially be Ready (or Error). While
-    there will be no onStatusChanged signal in that case, the onLoaded will still be invoked.
-
-    \sa progress
-*/
-
-QSGLoader::Status QSGLoader::status() const
-{
-    Q_D(const QSGLoader);
-
-    if (!d->active)
-        return Null;
-
-    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;
-
-    return d->source.isEmpty() ? Null : Error;
-}
-
-void QSGLoader::componentComplete()
-{
-    Q_D(QSGLoader);
-    QSGItem::componentComplete();
-    if (active()) {
-        if (d->loadingFromSource) {
-            d->component = new QDeclarativeComponent(qmlEngine(this), d->source, this);
-        }
-        d->load();
-    }
-}
-
-/*!
-    \qmlsignal QtQuick2::Loader::onLoaded()
-
-    This handler is called when the \l status becomes \c Loader.Ready, or on successful
-    initial load.
-*/
-
-
-/*!
-\qmlproperty real QtQuick2::Loader::progress
-
-This property holds the progress of loading QML data from the network, from
-0.0 (nothing loaded) to 1.0 (finished).  Most QML files are quite small, so
-this value will rapidly change from 0 to 1.
-
-\sa status
-*/
-qreal QSGLoader::progress() const
-{
-    Q_D(const QSGLoader);
-
-    if (d->item)
-        return 1.0;
-
-    if (d->component)
-        return d->component->progress();
-
-    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);
-    if (!item || updatingSize)
-        return;
-
-    updatingSize = true;
-
-    if (!itemWidthValid)
-        q->setImplicitWidth(item->implicitWidth());
-    else
-        q->setImplicitWidth(item->width());
-    if (loaderGeometryChanged && q->widthValid())
-        item->setWidth(q->width());
-
-    if (!itemHeightValid)
-        q->setImplicitHeight(item->implicitHeight());
-    else
-        q->setImplicitHeight(item->height());
-    if (loaderGeometryChanged && q->heightValid())
-        item->setHeight(q->height());
-
-    updatingSize = false;
-}
-
-/*!
-    \qmlproperty Item QtQuick2::Loader::item
-    This property holds the top-level item that is currently loaded.
-*/
-QSGItem *QSGLoader::item() const
-{
-    Q_D(const QSGLoader);
-    return d->item;
-}
-
-void QSGLoader::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
-{
-    Q_D(QSGLoader);
-    if (newGeometry != oldGeometry) {
-        d->_q_updateSize();
-    }
-    QSGItem::geometryChanged(newGeometry, oldGeometry);
-}
-
-QUrl QSGLoaderPrivate::resolveSourceUrl(QDeclarativeV8Function *args)
-{
-    QV8Engine *v8engine = args->engine();
-    QString arg = v8engine->toString((*args)[0]->ToString());
-    if (arg.isEmpty())
-        return QUrl();
-
-    QDeclarativeContextData *context = args->context();
-    Q_ASSERT(context);
-    return context->resolvedUrl(QUrl(arg));
-}
-
-v8::Handle<v8::Object> QSGLoaderPrivate::extractInitialPropertyValues(QDeclarativeV8Function *args, QObject *loader, bool *error)
-{
-    v8::Local<v8::Object> valuemap;
-    if (args->Length() >= 2) {
-        v8::Local<v8::Value> v = (*args)[1];
-        if (!v->IsObject() || v->IsArray()) {
-            *error = true;
-            qmlInfo(loader) << loader->tr("setSource: value is not an object");
-        } else {
-            *error = false;
-            valuemap = v8::Local<v8::Object>::Cast(v);
-        }
-    }
-
-    return valuemap;
-}
-
-#include <moc_qsgloader_p.cpp>
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgloader_p.h b/src/declarative/items/qsgloader_p.h
deleted file mode 100644 (file)
index 3a41e79..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-// Commit: 6f78a6080b84cc3ef96b73a4ff58d1b5a72f08f4
-/****************************************************************************
-**
-** 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 QSGLOADER_P_H
-#define QSGLOADER_P_H
-
-#include "qsgimplicitsizeitem_p.h"
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGLoaderPrivate;
-class Q_AUTOTEST_EXPORT QSGLoader : public QSGImplicitSizeItem
-{
-    Q_OBJECT
-    Q_ENUMS(Status)
-
-    Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
-    Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
-    Q_PROPERTY(QDeclarativeComponent *sourceComponent READ sourceComponent WRITE setSourceComponent RESET resetSourceComponent NOTIFY sourceComponentChanged)
-    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);
-    virtual ~QSGLoader();
-
-    bool active() const;
-    void setActive(bool newVal);
-
-    Q_INVOKABLE void setSource(QDeclarativeV8Function *);
-
-    QUrl source() const;
-    void setSource(const QUrl &);
-
-    QDeclarativeComponent *sourceComponent() const;
-    void setSourceComponent(QDeclarativeComponent *);
-    void resetSourceComponent();
-
-    enum Status { Null, Ready, Loading, Error };
-    Status status() const;
-    qreal progress() const;
-
-    bool asynchronous() const;
-    void setAsynchronous(bool a);
-
-    QSGItem *item() const;
-
-Q_SIGNALS:
-    void itemChanged();
-    void activeChanged();
-    void sourceChanged();
-    void sourceComponentChanged();
-    void statusChanged();
-    void progressChanged();
-    void loaded();
-    void asynchronousChanged();
-
-protected:
-    void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
-    void componentComplete();
-
-private:
-    void setSource(const QUrl &sourceUrl, bool needsClear);
-    void loadFromSource();
-    void loadFromSourceComponent();
-    Q_DISABLE_COPY(QSGLoader)
-    Q_DECLARE_PRIVATE(QSGLoader)
-    Q_PRIVATE_SLOT(d_func(), void _q_sourceLoaded())
-    Q_PRIVATE_SLOT(d_func(), void _q_updateSize())
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGLoader)
-
-QT_END_HEADER
-
-#endif // QSGLOADER_P_H
diff --git a/src/declarative/items/qsgloader_p_p.h b/src/declarative/items/qsgloader_p_p.h
deleted file mode 100644 (file)
index 36059ca..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-// Commit: 5d2817cd668a705729df1727de49adf00713ac97
-/****************************************************************************
-**
-** 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 QSGLOADER_P_P_H
-#define QSGLOADER_P_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 "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
-{
-    Q_DECLARE_PUBLIC(QSGLoader)
-
-public:
-    QSGLoaderPrivate();
-    ~QSGLoaderPrivate();
-
-    void itemGeometryChanged(QSGItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
-    void clear();
-    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);
-
-    QUrl source;
-    QSGItem *item;
-    QDeclarativeComponent *component;
-    QDeclarativeContext *itemContext;
-    QSGLoaderIncubator *incubator;
-    v8::Persistent<v8::Object> initialPropertyValues;
-    v8::Persistent<v8::Object> qmlGlobalForIpv;
-    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);
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGLOADER_P_P_H
diff --git a/src/declarative/items/qsgmousearea.cpp b/src/declarative/items/qsgmousearea.cpp
deleted file mode 100644 (file)
index a401b52..0000000
+++ /dev/null
@@ -1,1131 +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 "qsgmousearea_p.h"
-#include "qsgmousearea_p_p.h"
-#include "qsgcanvas.h"
-#include "qsgevents_p_p.h"
-#include "qsgdrag_p.h"
-
-#include <QtGui/qevent.h>
-#include <QtGui/qguiapplication.h>
-#include <QtGui/qstylehints.h>
-
-#include <float.h>
-
-QT_BEGIN_NAMESPACE
-static const int PressAndHoldDelay = 800;
-
-QSGDrag::QSGDrag(QObject *parent)
-: QObject(parent), _target(0), _axis(XandYAxis), _xmin(-FLT_MAX),
-_xmax(FLT_MAX), _ymin(-FLT_MAX), _ymax(FLT_MAX), _active(false), _filterChildren(false)
-{
-}
-
-QSGDrag::~QSGDrag()
-{
-}
-
-QSGItem *QSGDrag::target() const
-{
-    return _target;
-}
-
-void QSGDrag::setTarget(QSGItem *t)
-{
-    if (_target == t)
-        return;
-    _target = t;
-    emit targetChanged();
-}
-
-void QSGDrag::resetTarget()
-{
-    if (_target == 0)
-        return;
-    _target = 0;
-    emit targetChanged();
-}
-
-QSGDrag::Axis QSGDrag::axis() const
-{
-    return _axis;
-}
-
-void QSGDrag::setAxis(QSGDrag::Axis a)
-{
-    if (_axis == a)
-        return;
-    _axis = a;
-    emit axisChanged();
-}
-
-qreal QSGDrag::xmin() const
-{
-    return _xmin;
-}
-
-void QSGDrag::setXmin(qreal m)
-{
-    if (_xmin == m)
-        return;
-    _xmin = m;
-    emit minimumXChanged();
-}
-
-qreal QSGDrag::xmax() const
-{
-    return _xmax;
-}
-
-void QSGDrag::setXmax(qreal m)
-{
-    if (_xmax == m)
-        return;
-    _xmax = m;
-    emit maximumXChanged();
-}
-
-qreal QSGDrag::ymin() const
-{
-    return _ymin;
-}
-
-void QSGDrag::setYmin(qreal m)
-{
-    if (_ymin == m)
-        return;
-    _ymin = m;
-    emit minimumYChanged();
-}
-
-qreal QSGDrag::ymax() const
-{
-    return _ymax;
-}
-
-void QSGDrag::setYmax(qreal m)
-{
-    if (_ymax == m)
-        return;
-    _ymax = m;
-    emit maximumYChanged();
-}
-
-bool QSGDrag::active() const
-{
-    return _active;
-}
-
-void QSGDrag::setActive(bool drag)
-{
-    if (_active == drag)
-        return;
-    _active = drag;
-    emit activeChanged();
-}
-
-bool QSGDrag::filterChildren() const
-{
-    return _filterChildren;
-}
-
-void QSGDrag::setFilterChildren(bool filter)
-{
-    if (_filterChildren == filter)
-        return;
-    _filterChildren = filter;
-    emit filterChildrenChanged();
-}
-
-QSGDragAttached *QSGDrag::qmlAttachedProperties(QObject *obj)
-{
-    return new QSGDragAttached(obj);
-}
-
-QSGMouseAreaPrivate::QSGMouseAreaPrivate()
-: absorb(true), hovered(false), pressed(false), longPress(false),
-  moved(false), stealMouse(false), doubleClick(false), preventStealing(false),
-  drag(0)
-{
-}
-
-QSGMouseAreaPrivate::~QSGMouseAreaPrivate()
-{
-    delete drag;
-}
-
-void QSGMouseAreaPrivate::init()
-{
-    Q_Q(QSGMouseArea);
-    q->setAcceptedMouseButtons(Qt::LeftButton);
-    q->setFiltersChildMouseEvents(true);
-}
-
-void QSGMouseAreaPrivate::saveEvent(QMouseEvent *event)
-{
-    lastPos = event->localPos();
-    lastScenePos = event->windowPos();
-    lastButton = event->button();
-    lastButtons = event->buttons();
-    lastModifiers = event->modifiers();
-}
-
-bool QSGMouseAreaPrivate::isPressAndHoldConnected()
-{
-    Q_Q(QSGMouseArea);
-    static int idx = QObjectPrivate::get(q)->signalIndex("pressAndHold(QSGMouseEvent*)");
-    return QObjectPrivate::get(q)->isSignalConnected(idx);
-}
-
-bool QSGMouseAreaPrivate::isDoubleClickConnected()
-{
-    Q_Q(QSGMouseArea);
-    static int idx = QObjectPrivate::get(q)->signalIndex("doubleClicked(QSGMouseEvent*)");
-    return QObjectPrivate::get(q)->isSignalConnected(idx);
-}
-
-bool QSGMouseAreaPrivate::isClickConnected()
-{
-    Q_Q(QSGMouseArea);
-    static int idx = QObjectPrivate::get(q)->signalIndex("clicked(QSGMouseEvent*)");
-    return QObjectPrivate::get(q)->isSignalConnected(idx);
-}
-
-void QSGMouseAreaPrivate::propagate(QSGMouseEvent* event, PropagateType t)
-{
-    Q_Q(QSGMouseArea);
-    QPointF scenePos = q->mapToScene(QPointF(event->x(), event->y()));
-    propagateHelper(event, canvas->rootItem(), scenePos, t);
-}
-
-bool QSGMouseAreaPrivate::propagateHelper(QSGMouseEvent *ev, QSGItem *item,const QPointF &sp, PropagateType sig)
-{
-    //Based off of QSGCanvas::deliverInitialMousePressEvent
-    //But specific to MouseArea, so doesn't belong in canvas
-    Q_Q(const QSGMouseArea);
-    QSGItemPrivate *itemPrivate = QSGItemPrivate::get(item);
-    if (itemPrivate->opacity == 0.0)
-        return false;
-
-    if (itemPrivate->flags & QSGItem::ItemClipsChildrenToShape) {
-        QPointF p = item->mapFromScene(sp);
-        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 (propagateHelper(ev, child, sp, sig))
-            return true;
-    }
-
-    QSGMouseArea* ma = qobject_cast<QSGMouseArea*>(item);
-    if (ma && ma != q && itemPrivate->acceptedMouseButtons & ev->button()) {
-        switch (sig) {
-        case Click:
-            if (!ma->d_func()->isClickConnected())
-                return false;
-            break;
-        case DoubleClick:
-            if (!ma->d_func()->isDoubleClickConnected())
-                return false;
-            break;
-        case PressAndHold:
-            if (!ma->d_func()->isPressAndHoldConnected())
-                return false;
-            break;
-        }
-        QPointF p = item->mapFromScene(sp);
-        if (QRectF(0, 0, item->width(), item->height()).contains(p)) {
-            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) {
-            case Click: emit ma->clicked(ev); break;
-            case DoubleClick: emit ma->doubleClicked(ev); break;
-            case PressAndHold: emit ma->pressAndHold(ev); break;
-            }
-            if (ev->isAccepted())
-                return true;
-        }
-    }
-    return false;
-
-}
-
-/*!
-    \qmlclass MouseArea QSGMouseArea
-    \inqmlmodule QtQuick 2
-    \ingroup qml-basic-interaction-elements
-    \brief The MouseArea item enables simple mouse handling.
-    \inherits Item
-
-    A MouseArea is an invisible item that is typically used in conjunction with
-    a visible item in order to provide mouse handling for that item.
-    By effectively acting as a proxy, the logic for mouse handling can be
-    contained within a MouseArea item.
-
-    For basic key handling, see the \l{Keys}{Keys attached property}.
-
-    The \l enabled property is used to enable and disable mouse handling for
-    the proxied item. When disabled, the mouse area becomes transparent to
-    mouse events.
-
-    The \l pressed read-only property indicates whether or not the user is
-    holding down a mouse button over the mouse area. This property is often
-    used in bindings between properties in a user interface. The containsMouse
-    read-only property indicates the presence of the mouse cursor over the
-    mouse area but, by default, only when a mouse button is held down; see below
-    for further details.
-
-    Information about the mouse position and button clicks are provided via
-    signals for which event handler properties are defined. The most commonly
-    used involved handling mouse presses and clicks: onClicked, onDoubleClicked,
-    onPressed, onReleased and onPressAndHold.
-
-    By default, MouseArea items only report mouse clicks and not changes to the
-    position of the mouse cursor. Setting the hoverEnabled property ensures that
-    handlers defined for onPositionChanged, onEntered and onExited are used and
-    that the containsMouse property is updated even when no mouse buttons are
-    pressed.
-
-    \section1 Example Usage
-
-    \div {class="float-right"}
-    \inlineimage qml-mousearea-snippet.png
-    \enddiv
-
-    The following example uses a MouseArea in a \l Rectangle that changes
-    the \l Rectangle color to red when clicked:
-
-    \snippet doc/src/snippets/declarative/mousearea/mousearea.qml import
-    \codeline
-    \snippet doc/src/snippets/declarative/mousearea/mousearea.qml intro
-
-    \clearfloat
-    Many MouseArea signals pass a \l{MouseEvent}{mouse} parameter that contains
-    additional information about the mouse event, such as the position, button,
-    and any key modifiers.
-
-    Here is an extension of the previous example that produces a different
-    color when the area is right clicked:
-
-    \snippet doc/src/snippets/declarative/mousearea/mousearea.qml intro-extended
-
-  Behavioral Change in QtQuick 2.0
-
-  From QtQuick 2.0, the signals clicked, doubleClicked and pressAndHold have a different interaction
-  model with regards to the delivery of events to multiple overlapping MouseAreas. These signals will now propagate
-  to all MouseAreas in the area, in painting order, until accepted by one of them. A signal is accepted by
-  default if there is a signal handler for it, use mouse.accepted = false; to ignore. This propagation
-  can send the signal to MouseAreas other than the one which accepted the press event, although that MouseArea
-  will receive the signal first.
-
-  Note that to get the same behavior as a QtQuick 1.0 MouseArea{} with regard to absorbing all mouse events, you will
-  now need to add empty signal handlers for these three signals.
-
-    \sa MouseEvent, {declarative/touchinteraction/mousearea}{MouseArea example}
-*/
-
-/*!
-    \qmlsignal QtQuick2::MouseArea::onEntered()
-
-    This handler is called when the mouse enters the mouse area.
-
-    By default the onEntered handler is only called while a button is
-    pressed. Setting hoverEnabled to true enables handling of
-    onEntered when no mouse button is pressed.
-
-    \sa hoverEnabled
-*/
-
-/*!
-    \qmlsignal QtQuick2::MouseArea::onExited()
-
-    This handler is called when the mouse exits the mouse area.
-
-    By default the onExited handler is only called while a button is
-    pressed. Setting hoverEnabled to true enables handling of
-    onExited when no mouse button is pressed.
-
-    The example below shows a fairly typical relationship between
-    two MouseAreas, with \c mouseArea2 on top of \c mouseArea1. Moving the
-    mouse into \c mouseArea2 from \c mouseArea1 will cause \c onExited
-    to be called for \c mouseArea1.
-    \qml
-    Rectangle {
-        width: 400; height: 400
-        MouseArea {
-            id: mouseArea1
-            anchors.fill: parent
-            hoverEnabled: true
-        }
-        MouseArea {
-            id: mouseArea2
-            width: 100; height: 100
-            anchors.centerIn: parent
-            hoverEnabled: true
-        }
-    }
-    \endqml
-
-    If instead you give the two mouseAreas a parent-child relationship,
-    moving the mouse into \c mouseArea2 from \c mouseArea1 will \b not
-    cause \c onExited to be called for \c mouseArea1. Instead, they will
-    both be considered to be simultaneously hovered.
-
-    \sa hoverEnabled
-*/
-
-/*!
-    \qmlsignal QtQuick2::MouseArea::onPositionChanged(MouseEvent mouse)
-
-    This handler is called when the mouse position changes.
-
-    The \l {MouseEvent}{mouse} parameter provides information about the mouse, including the x and y
-    position, and any buttons currently pressed.
-
-    The \e accepted property of the MouseEvent parameter is ignored in this handler.
-
-    By default the onPositionChanged handler is only called while a button is
-    pressed.  Setting hoverEnabled to true enables handling of
-    onPositionChanged when no mouse button is pressed.
-*/
-
-/*!
-    \qmlsignal QtQuick2::MouseArea::onClicked(MouseEvent mouse)
-
-    This handler is called when there is a click. A click is defined as a press followed by a release,
-    both inside the MouseArea (pressing, moving outside the MouseArea, and then moving back inside and
-    releasing is also considered a click).
-
-    The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y
-    position of the release of the click, and whether the click was held.
-
-    The \e accepted property of the MouseEvent parameter is ignored in this handler.
-*/
-
-/*!
-    \qmlsignal QtQuick2::MouseArea::onPressed(MouseEvent mouse)
-
-    This handler is called when there is a press.
-    The \l {MouseEvent}{mouse} parameter provides information about the press, including the x and y
-    position and which button was pressed.
-
-    The \e accepted property of the MouseEvent parameter determines whether this MouseArea
-    will handle the press and all future mouse events until release.  The default is to accept
-    the event and not allow other MouseArea beneath this one to handle the event.  If \e accepted
-    is set to false, no further events will be sent to this MouseArea until the button is next
-    pressed.
-*/
-
-/*!
-    \qmlsignal QtQuick2::MouseArea::onReleased(MouseEvent mouse)
-
-    This handler is called when there is a release.
-    The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y
-    position of the release of the click, and whether the click was held.
-
-    The \e accepted property of the MouseEvent parameter is ignored in this handler.
-
-    \sa onCanceled
-*/
-
-/*!
-    \qmlsignal QtQuick2::MouseArea::onPressAndHold(MouseEvent mouse)
-
-    This handler is called when there is a long press (currently 800ms).
-    The \l {MouseEvent}{mouse} parameter provides information about the press, including the x and y
-    position of the press, and which button is pressed.
-
-    The \e accepted property of the MouseEvent parameter is ignored in this handler.
-*/
-
-/*!
-    \qmlsignal QtQuick2::MouseArea::onDoubleClicked(MouseEvent mouse)
-
-    This handler is called when there is a double-click (a press followed by a release followed by a press).
-    The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y
-    position of the release of the click, and whether the click was held.
-
-    If the \e accepted property of the \l {MouseEvent}{mouse} parameter is set to false
-    in the handler, the onPressed/onReleased/onClicked handlers will be called for the second
-    click; otherwise they are suppressed.  The accepted property defaults to true.
-*/
-
-/*!
-    \qmlsignal QtQuick2::MouseArea::onCanceled()
-
-    This handler is called when mouse events have been canceled, either because an event was not accepted, or
-    because another element stole the mouse event handling.
-
-    This signal is for advanced use: it is useful when there is more than one MouseArea
-    that is handling input, or when there is a MouseArea inside a \l Flickable. In the latter
-    case, if you execute some logic on the pressed signal and then start dragging, the
-    \l Flickable will steal the mouse handling from the MouseArea. In these cases, to reset
-    the logic when the MouseArea has lost the mouse handling to the \l Flickable,
-    \c onCanceled should be used in addition to onReleased.
-*/
-QSGMouseArea::QSGMouseArea(QSGItem *parent)
-  : QSGItem(*(new QSGMouseAreaPrivate), parent)
-{
-    Q_D(QSGMouseArea);
-    d->init();
-}
-
-QSGMouseArea::~QSGMouseArea()
-{
-}
-
-/*!
-    \qmlproperty real QtQuick2::MouseArea::mouseX
-    \qmlproperty real QtQuick2::MouseArea::mouseY
-    These properties hold the coordinates of the mouse cursor.
-
-    If the hoverEnabled property is false then these properties will only be valid
-    while a button is pressed, and will remain valid as long as the button is held
-    down even if the mouse is moved outside the area.
-
-    By default, this property is false.
-
-    If hoverEnabled is true then these properties will be valid when:
-    \list
-        \i no button is pressed, but the mouse is within the MouseArea (containsMouse is true).
-        \i a button is pressed and held, even if it has since moved out of the area.
-    \endlist
-
-    The coordinates are relative to the MouseArea.
-*/
-qreal QSGMouseArea::mouseX() const
-{
-    Q_D(const QSGMouseArea);
-    return d->lastPos.x();
-}
-
-qreal QSGMouseArea::mouseY() const
-{
-    Q_D(const QSGMouseArea);
-    return d->lastPos.y();
-}
-
-/*!
-    \qmlproperty bool QtQuick2::MouseArea::enabled
-    This property holds whether the item accepts mouse events.
-
-    By default, this property is true.
-*/
-bool QSGMouseArea::isEnabled() const
-{
-    Q_D(const QSGMouseArea);
-    return d->absorb;
-}
-
-void QSGMouseArea::setEnabled(bool a)
-{
-    Q_D(QSGMouseArea);
-    if (a != d->absorb) {
-        d->absorb = a;
-        emit enabledChanged();
-    }
-}
-
-/*!
-    \qmlproperty bool QtQuick2::MouseArea::preventStealing
-    This property holds whether the mouse events may be stolen from this
-    MouseArea.
-
-    If a MouseArea is placed within an item that filters child mouse
-    events, such as Flickable, the mouse
-    events may be stolen from the MouseArea if a gesture is recognized
-    by the parent element, e.g. a flick gesture.  If preventStealing is
-    set to true, no element will steal the mouse events.
-
-    Note that setting preventStealing to true once an element has started
-    stealing events will have no effect until the next press event.
-
-    By default this property is false.
-*/
-bool QSGMouseArea::preventStealing() const
-{
-    Q_D(const QSGMouseArea);
-    return d->preventStealing;
-}
-
-void QSGMouseArea::setPreventStealing(bool prevent)
-{
-    Q_D(QSGMouseArea);
-    if (prevent != d->preventStealing) {
-        d->preventStealing = prevent;
-        setKeepMouseGrab(d->preventStealing && d->absorb);
-        emit preventStealingChanged();
-    }
-}
-
-/*!
-    \qmlproperty MouseButtons QtQuick2::MouseArea::pressedButtons
-    This property holds the mouse buttons currently pressed.
-
-    It contains a bitwise combination of:
-    \list
-    \o Qt.LeftButton
-    \o Qt.RightButton
-    \o Qt.MiddleButton
-    \endlist
-
-    The code below displays "right" when the right mouse buttons is pressed:
-
-    \snippet doc/src/snippets/declarative/mousearea/mousearea.qml mousebuttons
-
-    \sa acceptedButtons
-*/
-Qt::MouseButtons QSGMouseArea::pressedButtons() const
-{
-    Q_D(const QSGMouseArea);
-    return d->lastButtons;
-}
-
-void QSGMouseArea::mousePressEvent(QMouseEvent *event)
-{
-    Q_D(QSGMouseArea);
-    d->moved = false;
-    d->stealMouse = d->preventStealing;
-    if (!d->absorb)
-        QSGItem::mousePressEvent(event);
-    else {
-        d->longPress = false;
-        d->saveEvent(event);
-        if (d->drag) {
-            d->dragX = drag()->axis() & QSGDrag::XAxis;
-            d->dragY = drag()->axis() & QSGDrag::YAxis;
-        }
-        if (d->drag)
-            d->drag->setActive(false);
-        setHovered(true);
-        d->startScene = event->windowPos();
-        d->pressAndHoldTimer.start(PressAndHoldDelay, this);
-        setKeepMouseGrab(d->stealMouse);
-        event->setAccepted(setPressed(true));
-
-    }
-}
-
-void QSGMouseArea::mouseMoveEvent(QMouseEvent *event)
-{
-    Q_D(QSGMouseArea);
-    if (!d->absorb) {
-        QSGItem::mouseMoveEvent(event);
-        return;
-    }
-
-    d->saveEvent(event);
-
-    // ### we should skip this if these signals aren't used
-    // ### can GV handle this for us?
-    bool contains = boundingRect().contains(d->lastPos);
-    if (d->hovered && !contains)
-        setHovered(false);
-    else if (!d->hovered && contains)
-        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())
-                    : d->drag->target()->pos();
-        }
-
-        QPointF startLocalPos;
-        QPointF curLocalPos;
-        if (drag()->target()->parentItem()) {
-            startLocalPos = drag()->target()->parentItem()->mapFromScene(d->startScene);
-            curLocalPos = drag()->target()->parentItem()->mapFromScene(event->windowPos());
-        } else {
-            startLocalPos = d->startScene;
-            curLocalPos = event->windowPos();
-        }
-
-        const int dragThreshold = qApp->styleHints()->startDragDistance();
-        qreal dx = qAbs(curLocalPos.x() - startLocalPos.x());
-        qreal dy = qAbs(curLocalPos.y() - startLocalPos.y());
-
-        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();
-            dragPos.setX(x);
-        }
-        if (d->dragY && d->drag->active()) {
-            qreal y = (curLocalPos.y() - startLocalPos.y()) + startPos.y();
-            if (y < drag()->ymin())
-                y = drag()->ymin();
-            else if (y > drag()->ymax())
-                y = drag()->ymax();
-            dragPos.setY(y);
-        }
-        d->drag->target()->setPos(dragPos);
-
-        if (!keepMouseGrab()) {
-            if ((!d->dragY && dy < dragThreshold && d->dragX && dx > dragThreshold)
-                || (!d->dragX && dx < dragThreshold && d->dragY && dy > dragThreshold)
-                || (d->dragX && d->dragY && (dx > dragThreshold || dy > dragThreshold))) {
-                setKeepMouseGrab(true);
-                d->stealMouse = true;
-            }
-        }
-
-        d->moved = true;
-    }
-    QSGMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress);
-    emit mouseXChanged(&me);
-    me.setPosition(d->lastPos);
-    emit mouseYChanged(&me);
-    me.setPosition(d->lastPos);
-    emit positionChanged(&me);
-}
-
-void QSGMouseArea::mouseReleaseEvent(QMouseEvent *event)
-{
-    Q_D(QSGMouseArea);
-    d->stealMouse = false;
-    if (!d->absorb) {
-        QSGItem::mouseReleaseEvent(event);
-    } else {
-        d->saveEvent(event);
-        setPressed(false);
-        if (d->drag)
-            d->drag->setActive(false);
-        // If we don't accept hover, we need to reset containsMouse.
-        if (!acceptHoverEvents())
-            setHovered(false);
-        QSGCanvas *c = canvas();
-        if (c && c->mouseGrabberItem() == this)
-            ungrabMouse();
-        setKeepMouseGrab(false);
-
-    }
-    d->doubleClick = false;
-}
-
-void QSGMouseArea::mouseDoubleClickEvent(QMouseEvent *event)
-{
-    Q_D(QSGMouseArea);
-    if (d->absorb) {
-        d->saveEvent(event);
-        QSGMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, true, false);
-        me.setAccepted(d->isDoubleClickConnected());
-        emit this->doubleClicked(&me);
-        if (!me.isAccepted())
-            d->propagate(&me, QSGMouseAreaPrivate::DoubleClick);
-        d->doubleClick = d->isDoubleClickConnected() || me.isAccepted();
-    }
-    QSGItem::mouseDoubleClickEvent(event);
-}
-
-void QSGMouseArea::hoverEnterEvent(QHoverEvent *event)
-{
-    Q_D(QSGMouseArea);
-    if (!d->absorb) {
-        QSGItem::hoverEnterEvent(event);
-    } else {
-        d->lastPos = event->posF();
-        d->lastModifiers = event->modifiers();
-        setHovered(true);
-        QSGMouseEvent me(d->lastPos.x(), d->lastPos.y(), Qt::NoButton, Qt::NoButton, d->lastModifiers, false, false);
-        emit mouseXChanged(&me);
-        me.setPosition(d->lastPos);
-        emit mouseYChanged(&me);
-        me.setPosition(d->lastPos);
-    }
-}
-
-void QSGMouseArea::hoverMoveEvent(QHoverEvent *event)
-{
-    Q_D(QSGMouseArea);
-    if (!d->absorb) {
-        QSGItem::hoverMoveEvent(event);
-    } else {
-        d->lastPos = event->posF();
-        d->lastModifiers = event->modifiers();
-        QSGMouseEvent me(d->lastPos.x(), d->lastPos.y(), Qt::NoButton, Qt::NoButton, d->lastModifiers, false, false);
-        emit mouseXChanged(&me);
-        me.setPosition(d->lastPos);
-        emit mouseYChanged(&me);
-        me.setPosition(d->lastPos);
-        emit positionChanged(&me);
-    }
-}
-
-void QSGMouseArea::hoverLeaveEvent(QHoverEvent *event)
-{
-    Q_D(QSGMouseArea);
-    if (!d->absorb)
-        QSGItem::hoverLeaveEvent(event);
-    else
-        setHovered(false);
-}
-
-void QSGMouseArea::ungrabMouse()
-{
-    Q_D(QSGMouseArea);
-    if (d->pressed) {
-        // if our mouse grab has been removed (probably by Flickable), fix our
-        // state
-        d->pressed = false;
-        d->stealMouse = false;
-        setKeepMouseGrab(false);
-        emit canceled();
-        emit pressedChanged();
-        if (d->hovered) {
-            d->hovered = false;
-            emit hoveredChanged();
-        }
-    }
-}
-
-void QSGMouseArea::mouseUngrabEvent()
-{
-    ungrabMouse();
-}
-
-bool QSGMouseArea::sendMouseEvent(QMouseEvent *event)
-{
-    Q_D(QSGMouseArea);
-    QRectF myRect = mapRectToScene(QRectF(0, 0, width(), height()));
-
-    QSGCanvas *c = canvas();
-    QSGItem *grabber = c ? c->mouseGrabberItem() : 0;
-    bool stealThisEvent = d->stealMouse;
-    if ((stealThisEvent || myRect.contains(event->windowPos())) && (!grabber || !grabber->keepMouseGrab())) {
-        QMouseEvent mouseEvent(event->type(), mapFromScene(event->windowPos()), event->windowPos(), event->screenPos(),
-                               event->button(), event->buttons(), event->modifiers());
-        mouseEvent.setAccepted(false);
-
-        switch (event->type()) {
-        case QEvent::MouseMove:
-            mouseMoveEvent(&mouseEvent);
-            break;
-        case QEvent::MouseButtonPress:
-            mousePressEvent(&mouseEvent);
-            break;
-        case QEvent::MouseButtonRelease:
-            mouseReleaseEvent(&mouseEvent);
-            break;
-        default:
-            break;
-        }
-        grabber = c->mouseGrabberItem();
-        if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this)
-            grabMouse();
-
-        return stealThisEvent;
-    }
-    if (event->type() == QEvent::MouseButtonRelease) {
-        if (d->pressed) {
-            d->pressed = false;
-            d->stealMouse = false;
-            if (c && c->mouseGrabberItem() == this)
-                ungrabMouse();
-            emit canceled();
-            emit pressedChanged();
-            if (d->hovered) {
-                d->hovered = false;
-                emit hoveredChanged();
-            }
-        }
-    }
-    return false;
-}
-
-bool QSGMouseArea::childMouseEventFilter(QSGItem *i, QEvent *e)
-{
-    Q_D(QSGMouseArea);
-    if (!d->absorb || !isVisible() || !d->drag || !d->drag->filterChildren())
-        return QSGItem::childMouseEventFilter(i, e);
-    switch (e->type()) {
-    case QEvent::MouseButtonPress:
-    case QEvent::MouseMove:
-    case QEvent::MouseButtonRelease:
-        return sendMouseEvent(static_cast<QMouseEvent *>(e));
-    default:
-        break;
-    }
-
-    return QSGItem::childMouseEventFilter(i, e);
-}
-
-void QSGMouseArea::timerEvent(QTimerEvent *event)
-{
-    Q_D(QSGMouseArea);
-    if (event->timerId() == d->pressAndHoldTimer.timerId()) {
-        d->pressAndHoldTimer.stop();
-        bool dragged = d->drag && d->drag->active();
-        if (d->pressed && dragged == false && d->hovered == true) {
-            d->longPress = true;
-            QSGMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress);
-            me.setAccepted(d->isPressAndHoldConnected());
-            emit pressAndHold(&me);
-            if (!me.isAccepted())
-                d->propagate(&me, QSGMouseAreaPrivate::PressAndHold);
-            if (!me.isAccepted()) // no one handled the long press - allow click
-                d->longPress = false;
-        }
-    }
-}
-
-void QSGMouseArea::windowDeactivateEvent()
-{
-    ungrabMouse();
-    QSGItem::windowDeactivateEvent();
-}
-
-void QSGMouseArea::geometryChanged(const QRectF &newGeometry,
-                                            const QRectF &oldGeometry)
-{
-    Q_D(QSGMouseArea);
-    QSGItem::geometryChanged(newGeometry, oldGeometry);
-
-    if (d->lastScenePos.isNull)
-        d->lastScenePos = mapToScene(d->lastPos);
-    else if (newGeometry.x() != oldGeometry.x() || newGeometry.y() != oldGeometry.y())
-        d->lastPos = mapFromScene(d->lastScenePos);
-}
-
-void QSGMouseArea::itemChange(ItemChange change, const ItemChangeData &value)
-{
-    Q_D(QSGMouseArea);
-    switch (change) {
-    case ItemVisibleHasChanged:
-        if (acceptHoverEvents() && d->hovered != (isVisible() && isUnderMouse()))
-            setHovered(!d->hovered);
-        break;
-    default:
-        break;
-    }
-
-    QSGItem::itemChange(change, value);
-}
-
-/*!
-    \qmlproperty bool QtQuick2::MouseArea::hoverEnabled
-    This property holds whether hover events are handled.
-
-    By default, mouse events are only handled in response to a button event, or when a button is
-    pressed.  Hover enables handling of all mouse events even when no mouse button is
-    pressed.
-
-    This property affects the containsMouse property and the onEntered, onExited and
-    onPositionChanged signals.
-*/
-bool QSGMouseArea::hoverEnabled() const
-{
-    return acceptHoverEvents();
-}
-
-void QSGMouseArea::setHoverEnabled(bool h)
-{
-    if (h == acceptHoverEvents())
-        return;
-
-    setAcceptHoverEvents(h);
-    emit hoverEnabledChanged();
-}
-
-
-/*!
-    \qmlproperty bool QtQuick2::MouseArea::containsMouse
-    This property holds whether the mouse is currently inside the mouse area.
-
-    \warning This property is not updated if the area moves under the mouse: \e containsMouse will not change.
-    In addition, if hoverEnabled is false, containsMouse will only be valid when the mouse is pressed.
-*/
-bool QSGMouseArea::hovered() const
-{
-    Q_D(const QSGMouseArea);
-    return d->hovered;
-}
-
-/*!
-    \qmlproperty bool QtQuick2::MouseArea::pressed
-    This property holds whether the mouse area is currently pressed.
-*/
-bool QSGMouseArea::pressed() const
-{
-    Q_D(const QSGMouseArea);
-    return d->pressed;
-}
-
-void QSGMouseArea::setHovered(bool h)
-{
-    Q_D(QSGMouseArea);
-    if (d->hovered != h) {
-        d->hovered = h;
-        emit hoveredChanged();
-        d->hovered ? emit entered() : emit exited();
-    }
-}
-/*!
-    \qmlproperty QtQuick2::Qt::MouseButtons MouseArea::acceptedButtons
-    This property holds the mouse buttons that the mouse area reacts to.
-
-    The available buttons are:
-    \list
-    \o Qt.LeftButton
-    \o Qt.RightButton
-    \o Qt.MiddleButton
-    \endlist
-
-    To accept more than one button the flags can be combined with the
-    "|" (or) operator:
-
-    \code
-    MouseArea { acceptedButtons: Qt.LeftButton | Qt.RightButton }
-    \endcode
-
-    The default value is \c Qt.LeftButton.
-*/
-Qt::MouseButtons QSGMouseArea::acceptedButtons() const
-{
-    return acceptedMouseButtons();
-}
-
-void QSGMouseArea::setAcceptedButtons(Qt::MouseButtons buttons)
-{
-    if (buttons != acceptedMouseButtons()) {
-        setAcceptedMouseButtons(buttons);
-        emit acceptedButtonsChanged();
-    }
-}
-
-bool QSGMouseArea::setPressed(bool p)
-{
-    Q_D(QSGMouseArea);
-    bool dragged = d->drag && d->drag->active();
-    bool isclick = d->pressed == true && p == false && dragged == false && d->hovered == true;
-
-    if (d->pressed != p) {
-        d->pressed = p;
-        QSGMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, isclick, d->longPress);
-        if (d->pressed) {
-            if (!d->doubleClick)
-                emit pressed(&me);
-            me.setPosition(d->lastPos);
-            emit mouseXChanged(&me);
-            me.setPosition(d->lastPos);
-            emit mouseYChanged(&me);
-            emit pressedChanged();
-        } else {
-            emit released(&me);
-            me.setPosition(d->lastPos);
-            emit pressedChanged();
-            if (isclick && !d->longPress && !d->doubleClick){
-                me.setAccepted(d->isClickConnected());
-                emit clicked(&me);
-                if (!me.isAccepted())
-                    d->propagate(&me, QSGMouseAreaPrivate::Click);
-            }
-        }
-
-        return me.isAccepted();
-    }
-    return false;
-}
-
-/*!
-    \qmlproperty Item QtQuick2::MouseArea::drag.target
-    \qmlproperty bool QtQuick2::MouseArea::drag.active
-    \qmlproperty enumeration QtQuick2::MouseArea::drag.axis
-    \qmlproperty real QtQuick2::MouseArea::drag.minimumX
-    \qmlproperty real QtQuick2::MouseArea::drag.maximumX
-    \qmlproperty real QtQuick2::MouseArea::drag.minimumY
-    \qmlproperty real QtQuick2::MouseArea::drag.maximumY
-    \qmlproperty bool QtQuick2::MouseArea::drag.filterChildren
-
-    \c drag provides a convenient way to make an item draggable.
-
-    \list
-    \i \c drag.target specifies the id of the item to drag.
-    \i \c drag.active specifies if the target item is currently being dragged.
-    \i \c drag.axis specifies whether dragging can be done horizontally (\c Drag.XAxis), vertically (\c Drag.YAxis), or both (\c Drag.XandYAxis)
-    \i \c drag.minimum and \c drag.maximum limit how far the target can be dragged along the corresponding axes.
-    \endlist
-
-    The following example displays a \l Rectangle that can be dragged along the X-axis. The opacity
-    of the rectangle is reduced when it is dragged to the right.
-
-    \snippet doc/src/snippets/declarative/mousearea/mousearea.qml drag
-
-    \note Items cannot be dragged if they are anchored for the requested
-    \c drag.axis. For example, if \c anchors.left or \c anchors.right was set
-    for \c rect in the above example, it cannot be dragged along the X-axis.
-    This can be avoided by settng the anchor value to \c undefined in
-    an \l onPressed handler.
-
-    If \c drag.filterChildren is set to true, a drag can override descendant MouseAreas.  This
-    enables a parent MouseArea to handle drags, for example, while descendants handle clicks:
-
-    \snippet doc/src/snippets/declarative/mousearea/mouseareadragfilter.qml dragfilter
-
-*/
-
-QSGDrag *QSGMouseArea::drag()
-{
-    Q_D(QSGMouseArea);
-    if (!d->drag)
-        d->drag = new QSGDrag;
-    return d->drag;
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgmousearea_p.h b/src/declarative/items/qsgmousearea_p.h
deleted file mode 100644 (file)
index f0edf41..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-// 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 QSGMOUSEAREA_P_H
-#define QSGMOUSEAREA_P_H
-
-#include "qsgitem.h"
-
-#include <QtCore/qstringlist.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGDragAttached;
-class QSGMouseEvent;
-class Q_AUTOTEST_EXPORT QSGDrag : public QObject
-{
-    Q_OBJECT
-
-    Q_ENUMS(Axis)
-    Q_PROPERTY(QSGItem *target READ target WRITE setTarget NOTIFY targetChanged RESET resetTarget)
-    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)
-    Q_PROPERTY(qreal minimumY READ ymin WRITE setYmin NOTIFY minimumYChanged)
-    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)
-    //### consider drag and drop
-
-public:
-    QSGDrag(QObject *parent=0);
-    ~QSGDrag();
-
-    QSGItem *target() const;
-    void setTarget(QSGItem *target);
-    void resetTarget();
-
-    enum Axis { XAxis=0x01, YAxis=0x02, XandYAxis=0x03 };
-    Axis axis() const;
-    void setAxis(Axis);
-
-    qreal xmin() const;
-    void setXmin(qreal);
-    qreal xmax() const;
-    void setXmax(qreal);
-    qreal ymin() const;
-    void setYmin(qreal);
-    qreal ymax() const;
-    void setYmax(qreal);
-
-    bool active() const;
-    void setActive(bool);
-
-    bool filterChildren() const;
-    void setFilterChildren(bool);
-
-    static QSGDragAttached *qmlAttachedProperties(QObject *obj);
-
-Q_SIGNALS:
-    void targetChanged();
-    void axisChanged();
-    void minimumXChanged();
-    void maximumXChanged();
-    void minimumYChanged();
-    void maximumYChanged();
-    void activeChanged();
-    void filterChildrenChanged();
-
-private:
-    QSGItem *_target;
-    Axis _axis;
-    qreal _xmin;
-    qreal _xmax;
-    qreal _ymin;
-    qreal _ymax;
-    bool _active : 1;
-    bool _filterChildren: 1;
-    Q_DISABLE_COPY(QSGDrag)
-};
-
-class QSGMouseAreaPrivate;
-// used in QtLocation
-class Q_DECLARATIVE_EXPORT QSGMouseArea : public QSGItem
-{
-    Q_OBJECT
-
-    Q_PROPERTY(qreal mouseX READ mouseX NOTIFY mouseXChanged)
-    Q_PROPERTY(qreal mouseY READ mouseY NOTIFY mouseYChanged)
-    Q_PROPERTY(bool containsMouse READ hovered NOTIFY hoveredChanged)
-    Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged)
-    Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
-    Q_PROPERTY(Qt::MouseButtons pressedButtons READ pressedButtons NOTIFY pressedChanged)
-    Q_PROPERTY(Qt::MouseButtons acceptedButtons READ acceptedButtons WRITE setAcceptedButtons NOTIFY acceptedButtonsChanged)
-    Q_PROPERTY(bool hoverEnabled READ hoverEnabled WRITE setHoverEnabled NOTIFY hoverEnabledChanged)
-    Q_PROPERTY(QSGDrag *drag READ drag CONSTANT) //### add flicking to QSGDrag or add a QDeclarativeFlick ???
-    Q_PROPERTY(bool preventStealing READ preventStealing WRITE setPreventStealing NOTIFY preventStealingChanged)
-
-public:
-    QSGMouseArea(QSGItem *parent=0);
-    ~QSGMouseArea();
-
-    qreal mouseX() const;
-    qreal mouseY() const;
-
-    bool isEnabled() const;
-    void setEnabled(bool);
-
-    bool hovered() const;
-    bool pressed() const;
-
-    Qt::MouseButtons pressedButtons() const;
-
-    Qt::MouseButtons acceptedButtons() const;
-    void setAcceptedButtons(Qt::MouseButtons buttons);
-
-    bool hoverEnabled() const;
-    void setHoverEnabled(bool h);
-
-    QSGDrag *drag();
-
-    bool preventStealing() const;
-    void setPreventStealing(bool prevent);
-
-Q_SIGNALS:
-    void hoveredChanged();
-    void pressedChanged();
-    void enabledChanged();
-    void acceptedButtonsChanged();
-    void hoverEnabledChanged();
-    void positionChanged(QSGMouseEvent *mouse);
-    void mouseXChanged(QSGMouseEvent *mouse);
-    void mouseYChanged(QSGMouseEvent *mouse);
-    void preventStealingChanged();
-
-    void pressed(QSGMouseEvent *mouse);
-    void pressAndHold(QSGMouseEvent *mouse);
-    void released(QSGMouseEvent *mouse);
-    void clicked(QSGMouseEvent *mouse);
-    void doubleClicked(QSGMouseEvent *mouse);
-    void entered();
-    void exited();
-    void canceled();
-
-protected:
-    void setHovered(bool);
-    bool setPressed(bool);
-    bool sendMouseEvent(QMouseEvent *event);
-
-    virtual void mousePressEvent(QMouseEvent *event);
-    virtual void mouseReleaseEvent(QMouseEvent *event);
-    virtual void mouseDoubleClickEvent(QMouseEvent *event);
-    virtual void mouseMoveEvent(QMouseEvent *event);
-    virtual void mouseUngrabEvent();
-    virtual void hoverEnterEvent(QHoverEvent *event);
-    virtual void hoverMoveEvent(QHoverEvent *event);
-    virtual void hoverLeaveEvent(QHoverEvent *event);
-    virtual bool childMouseEventFilter(QSGItem *i, QEvent *e);
-    virtual void timerEvent(QTimerEvent *event);
-    virtual void windowDeactivateEvent();
-
-    virtual void geometryChanged(const QRectF &newGeometry,
-                                 const QRectF &oldGeometry);
-    virtual void itemChange(ItemChange change, const ItemChangeData& value);
-
-private:
-    void handlePress();
-    void handleRelease();
-    void ungrabMouse();
-
-private:
-    Q_DISABLE_COPY(QSGMouseArea)
-    Q_DECLARE_PRIVATE(QSGMouseArea)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGDrag)
-QML_DECLARE_TYPEINFO(QSGDrag, QML_HAS_ATTACHED_PROPERTIES)
-QML_DECLARE_TYPE(QSGMouseArea)
-
-QT_END_HEADER
-
-#endif // QSGMOUSEAREA_P_H
diff --git a/src/declarative/items/qsgmousearea_p_p.h b/src/declarative/items/qsgmousearea_p_p.h
deleted file mode 100644 (file)
index 6cf663a..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-// 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 QSGMOUSEAREA_P_P_H
-#define QSGMOUSEAREA_P_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 "qsgitem_p.h"
-
-#include <QtGui/qevent.h>
-#include <QtCore/qbasictimer.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGMouseEvent;
-class QSGMouseArea;
-class QSGMouseAreaPrivate : public QSGItemPrivate
-{
-    Q_DECLARE_PUBLIC(QSGMouseArea)
-
-public:
-    QSGMouseAreaPrivate();
-    ~QSGMouseAreaPrivate();
-    void init();
-
-    void saveEvent(QMouseEvent *event);
-    enum PropagateType{
-        Click,
-        DoubleClick,
-        PressAndHold
-    };
-    void propagate(QSGMouseEvent* event, PropagateType);
-    bool propagateHelper(QSGMouseEvent*, QSGItem*,const QPointF &, PropagateType);
-
-    bool isPressAndHoldConnected();
-    bool isDoubleClickConnected();
-    bool isClickConnected();
-
-    bool absorb : 1;
-    bool hovered : 1;
-    bool pressed : 1;
-    bool longPress : 1;
-    bool moved : 1;
-    bool dragX : 1;
-    bool dragY : 1;
-    bool stealMouse : 1;
-    bool doubleClick : 1;
-    bool preventStealing : 1;
-    QSGDrag *drag;
-    QPointF startScene;
-    QPointF targetStartPos;
-    QPointF lastPos;
-    QDeclarativeNullableValue<QPointF> lastScenePos;
-    Qt::MouseButton lastButton;
-    Qt::MouseButtons lastButtons;
-    Qt::KeyboardModifiers lastModifiers;
-    QBasicTimer pressAndHoldTimer;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGMOUSEAREA_P_P_H
diff --git a/src/declarative/items/qsgninepatchnode.cpp b/src/declarative/items/qsgninepatchnode.cpp
deleted file mode 100644 (file)
index 3658b3c..0000000
+++ /dev/null
@@ -1,302 +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$
-**
-****************************************************************************/
-
-#include "qsgninepatchnode_p.h"
-#include <private/qsgadaptationlayer_p.h>
-#include <private/qmath_p.h>
-
-QSGNinePatchNode::QSGNinePatchNode()
-    : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0)
-    , m_horizontalTileMode(QSGBorderImage::Stretch)
-    , m_verticalTileMode(QSGBorderImage::Stretch)
-    , m_dirtyGeometry(false)
-    , m_mirror(false)
-{
-    setOpaqueMaterial(&m_material);
-    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)
-{
-    if (m_innerRect == rect)
-        return;
-    m_innerRect = rect;
-    m_dirtyGeometry = true;
-}
-
-void QSGNinePatchNode::setRect(const QRectF &rect)
-{
-    if (m_targetRect == rect)
-        return;
-    m_targetRect = rect;
-    m_dirtyGeometry = true;
-}
-
-void QSGNinePatchNode::setHorzontalTileMode(QSGBorderImage::TileMode mode)
-{
-    if (mode == QSGBorderImage::TileMode(m_horizontalTileMode))
-        return;
-    m_horizontalTileMode = mode;
-    m_dirtyGeometry = true;
-}
-
-
-void QSGNinePatchNode::setVerticalTileMode(QSGBorderImage::TileMode mode)
-{
-    if (mode == QSGBorderImage::TileMode(m_verticalTileMode))
-        return;
-    m_verticalTileMode = mode;
-    m_dirtyGeometry = true;
-}
-
-
-void QSGNinePatchNode::setFiltering(QSGTexture::Filtering filtering)
-{
-    if (m_material.filtering() == filtering)
-        return;
-
-    m_material.setFiltering(filtering);
-    m_materialO.setFiltering(filtering);
-    markDirty(DirtyMaterial);
-}
-
-QSGTexture::Filtering QSGNinePatchNode::filtering() const
-{
-    return m_material.filtering();
-}
-
-void QSGNinePatchNode::setTexture(QSGTexture *texture)
-{
-    if (texture == m_material.texture())
-        return;
-    m_material.setTexture(texture);
-    m_materialO.setTexture(texture);
-    markDirty(DirtyMaterial);
-}
-
-QSGTexture *QSGNinePatchNode::texture() const
-{
-    return m_material.texture();
-}
-
-void QSGNinePatchNode::setMirror(bool m)
-{
-    if (m_mirror == m)
-        return;
-    m_mirror = m;
-    m_dirtyGeometry = true;
-}
-
-
-void QSGNinePatchNode::update()
-{
-    if (!m_dirtyGeometry)
-        return;
-
-    // For stretch this algorithm could be simplified to use less vertices
-    // as more vertices could be reused then, but I doubt its where our main
-    // problem will lie. This way, we at least share the algorithm between all
-
-    Q_ASSERT(m_material.texture());
-
-    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();
-
-//    qDebug() << m_innerRect << m_targetRect << m_horizontalTileMode << m_verticalTileMode;
-
-    int xChunkCount = 0; // Number of chunks
-    float xChunkSize = 0; // Size of chunk in pixels
-    float xTexSize = m_innerRect.width(); // Size of the texture to stretch/tile
-    float xSize = m_targetRect.width() - m_innerRect.left() - rightBorder; // Size of area to fill with chunks
-
-    if (m_horizontalTileMode == QSGBorderImage::Repeat) {
-        xChunkCount = qCeil(xSize / xTexSize);
-        xChunkSize = xTexSize;
-    } else if (m_horizontalTileMode == QSGBorderImage::Round) {
-        xChunkCount = qCeil(xSize / xTexSize);
-        qreal fullWidth = xChunkCount * xTexSize;
-        xChunkSize = xTexSize * xSize / fullWidth;
-    } else {
-        xChunkCount = 1;
-        xChunkSize = xSize;
-    }
-
-    int yChunkCount = 0;
-    float yChunkSize = 0; // Relative to target rect.
-    float yTexSize = m_innerRect.height(); // Size of the texture to stretch/tile
-    float ySize = m_targetRect.height() - m_innerRect.top() - bottomBorder;
-
-    if (m_verticalTileMode == QSGBorderImage::Repeat) {
-        yChunkCount = qCeil(ySize / yTexSize);
-        yChunkSize = yTexSize;
-    } else if (m_verticalTileMode == QSGBorderImage::Round) {
-        yChunkCount = qCeil(ySize / yTexSize);
-        qreal fullHeight = yChunkCount * yTexSize;
-        yChunkSize = yTexSize * ySize / fullHeight;
-    } else {
-        yChunkCount = 1;
-        yChunkSize = ySize;
-    }
-
-    int xTotalChunkCount = xChunkCount + 2;
-    int yTotalChunkCount = yChunkCount + 2;
-
-    int totalChunkCount = xTotalChunkCount * yTotalChunkCount;
-    int vertexCount = totalChunkCount * 4;
-    int indexCount = totalChunkCount * 6;
-
-    if (vertexCount != m_geometry.vertexCount() || indexCount != m_geometry.indexCount())
-        m_geometry.allocate(vertexCount, indexCount);
-
-    QSGGeometry::TexturedPoint2D *v = m_geometry.vertexDataAsTexturedPoint2D();
-
-
-    // Fill in the vertices.. The loop below is pretty much an exact replica
-    // of the one inside fillRow.
-    float yTexChunk1 = m_innerRect.top() / th;
-    float yTexChunk2 = m_innerRect.bottom() / th;
-
-    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, 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, textureSubRect, textureSize);
-        } else {
-            fillRow(v, yy + yChunkSize, yTexChunk2, xChunkCount, xChunkSize, textureSubRect, textureSize);
-        }
-    }
-
-    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();
-        for (int i=0; i<m_geometry.vertexCount(); ++i) {
-            v->x = m_targetRect.width() - v->x;
-            ++v;
-        }
-    }
-
-//    v = m_geometry.vertexDataAsTexturedPoint2D();
-//    for (int i=0; i<m_geometry.vertexCount(); ++i) {
-//        printf("Vertex: %d:  (%.3f, %.3f) - (%.3f, %.3f)\n",
-//               i,
-//               v->x, v->y, v->tx, v->ty);
-//        ++v;
-//    }
-
-    quint16 *i = m_geometry.indexDataAsUShort();
-    int row = xTotalChunkCount * 2;
-    for (int r=0; r<yTotalChunkCount; ++r) {
-        int offset = r * row * 2;
-        for (int c=0; c<xTotalChunkCount; ++c) {
-            *i++ = offset + c * 2;
-            *i++ = offset + c * 2 + 1;
-            *i++ = offset + c * 2 + row;
-            *i++ = offset + c * 2 + 1;
-            *i++ = offset + c * 2 + row + 1;
-            *i++ = offset + c * 2 + row;
-        }
-    }
-
-//    i = m_geometry.indexDataAsUShort();
-//    for (int idx=0; idx<m_geometry.indexCount(); idx+=6) {
-//        printf("%2d: ", idx / 6);
-//        for (int s=0; s<6; ++s)
-//            printf(" %d", i[idx + s]);
-//        printf("\n");
-//    }
-
-    markDirty(QSGNode::DirtyGeometry);
-}
-
-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
-{
-    ty = tsr.y() + ty * tsr.width();
-
-    float tw = ts.width();
-    float rightBorder = tw - m_innerRect.right();
-    float xTexChunk1 = tsr.left() + tsr.width() * m_innerRect.left() / tw;
-    float xTexChunk2 = tsr.left() + tsr.width() * m_innerRect.right() / tw;
-
-    v++->set(0, y, tsr.left(), ty);
-    v++->set(m_innerRect.x(), y, xTexChunk1, ty);
-
-    for (int xc=0; xc<xChunkCount; ++xc) {
-        float xx = m_innerRect.x() + xChunkSize * xc;
-        v++->set(xx, y, xTexChunk1, ty);
-
-        // Special case the last one
-        if (xc == xChunkCount - 1) {
-            float t = m_horizontalTileMode == QSGBorderImage::Repeat
-                    ? xTexChunk1 + (xTexChunk2 - xTexChunk1) * (m_targetRect.width() - rightBorder - xx) / xChunkSize
-                    : xTexChunk2;
-            v->set(m_targetRect.width() - rightBorder, y, t, ty);
-        } else {
-            v->set(xx + xChunkSize, y, xTexChunk2, ty);
-        }
-        ++v;
-    }
-
-    v++->set(m_targetRect.width() - rightBorder, y, xTexChunk2, 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
deleted file mode 100644 (file)
index fd0a0c5..0000000
+++ /dev/null
@@ -1,98 +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 QSGNINEPATCHNODE_H
-#define QSGNINEPATCHNODE_H
-
-#include "qsgnode.h"
-#include "qsgtexturematerial.h"
-#include "qsgborderimage_p.h"
-
-class TextureReference;
-
-class QSGNinePatchNode : public QSGGeometryNode
-{
-public:
-    QSGNinePatchNode();
-
-    void setTexture(QSGTexture *texture);
-    QSGTexture *texture() const;
-
-    void setRect(const QRectF &rect);
-    QRectF rect() const { return m_targetRect; }
-
-    void setInnerRect(const QRectF &rect);
-    QRectF innerRect() const { return m_innerRect; }
-
-    void setFiltering(QSGTexture::Filtering filtering);
-    QSGTexture::Filtering filtering() const;
-
-    void setHorzontalTileMode(QSGBorderImage::TileMode mode);
-    QSGBorderImage::TileMode horizontalTileMode() const {
-        return (QSGBorderImage::TileMode) m_horizontalTileMode;
-    }
-
-    void setVerticalTileMode(QSGBorderImage::TileMode mode);
-    QSGBorderImage::TileMode verticalTileMode() const {
-        return (QSGBorderImage::TileMode) m_verticalTileMode;
-    }
-
-    void setMirror(bool m);
-    bool mirror() const { return m_mirror; }
-
-    void update();
-
-private:
-    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;
-    QSGTextureMaterial m_materialO;
-    QSGGeometry m_geometry;
-
-    uint m_horizontalTileMode : 2;
-    uint m_verticalTileMode : 2;
-
-    uint m_dirtyGeometry : 1;
-    uint m_mirror : 1;
-};
-
-#endif // QSGNINEPATCHNODE_H
diff --git a/src/declarative/items/qsgpainteditem.cpp b/src/declarative/items/qsgpainteditem.cpp
deleted file mode 100644 (file)
index 16c3b3d..0000000
+++ /dev/null
@@ -1,536 +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 "qsgpainteditem.h"
-#include <private/qsgpainteditem_p.h>
-#include <private/qsgpainternode_p.h>
-
-#include <private/qsgcontext_p.h>
-#include <private/qsgadaptationlayer_p.h>
-#include <qmath.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
-    \class QSGPaintedItem
-    \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.
-    When the render target is a QImage, QPainter first renders into the image then
-    the content is uploaded to the texture.
-    When a QOpenGLFramebufferObject is used, QPainter paints directly onto the texture.
-    Call update() to trigger a repaint.
-
-    To enable QPainter to do anti-aliased rendering, use setAntialiasing().
-
-    QSGPaintedItem is meant to make it easier to port old code that is using the
-    QPainter API to the QML Scene Graph API and it should be used only for that purpose.
-
-    To write your own painted item, you first create a subclass of QSGPaintedItem, and then
-    start by implementing its only pure virtual public function: paint(), which implements
-    the actual painting. To get the size of the area painted by the item, use
-    contentsBoundingRect().
-*/
-
-/*!
-    \enum QSGPaintedItem::RenderTarget
-
-    This enum describes QSGPaintedItem's render targets. The render target is the
-    surface QPainter paints onto before the item is rendered on screen.
-
-    \value Image The default; QPainter paints into a QImage using the raster paint engine.
-    The image's content needs to be uploaded to graphics memory afterward, this operation
-    can potentially be slow if the item is large. This render target allows high quality
-    anti-aliasing and fast item resizing.
-
-    \value FramebufferObject QPainter paints into a QOpenGLFramebufferObject using the GL
-    paint engine. Painting can be faster as no texture upload is required, but anti-aliasing
-    quality is not as good as if using an image. This render target allows faster rendering
-    in some cases, but you should avoid using it if the item is resized often.
-
-    \sa setRenderTarget()
-*/
-
-/*!
-    \enum QSGPaintedItem::PerformanceHint
-
-    This enum describes flags that you can enable to improve rendering
-    performance in QSGPaintedItem. By default, none of these flags are set.
-
-    \value FastFBOResizing If your item gets resized often and you are using the
-    QSGPaintedItem::FramebufferObject render target, set this flag to true to reduce the
-    item resizing time at the cost of using more graphics memory. Resizing a Framebuffer object
-    is a costly operation, by enabling this property the Framebuffer Object will use a texture
-    larger than the actual size of the item to avoid as much as possible resizing it.
-*/
-
-/*!
-    \internal
-*/
-QSGPaintedItemPrivate::QSGPaintedItemPrivate()
-    : QSGItemPrivate()
-    , contentsScale(1.0)
-    , fillColor(Qt::transparent)
-    , renderTarget(QSGPaintedItem::Image)
-    , performanceHints(0)
-    , geometryDirty(false)
-    , contentsDirty(false)
-    , opaquePainting(false)
-    , antialiasing(false)
-    , mipmap(false)
-{
-}
-
-/*!
-    Constructs a QSGPaintedItem with the given \a parent item.
- */
-QSGPaintedItem::QSGPaintedItem(QSGItem *parent)
-    : QSGItem(*(new QSGPaintedItemPrivate), parent)
-{
-    setFlag(ItemHasContents);
-}
-
-/*!
-    \internal
-*/
-QSGPaintedItem::QSGPaintedItem(QSGPaintedItemPrivate &dd, QSGItem *parent)
-    : QSGItem(dd, parent)
-{
-    setFlag(ItemHasContents);
-}
-
-/*!
-    Destroys the QSGPaintedItem.
-*/
-QSGPaintedItem::~QSGPaintedItem()
-{
-}
-
-/*!
-    Schedules a redraw of the area covered by \a rect in this item. You can call this function
-    whenever your item needs to be redrawn, such as if it changes appearance or size.
-
-    This function does not cause an immediate paint; instead it schedules a paint request that
-    is processed by the QML Scene Graph when the next frame is rendered. The item will only be
-    redrawn if it is visible.
-
-    Note that calling this function will trigger a repaint of the whole scene.
-
-    \sa paint()
-*/
-void QSGPaintedItem::update(const QRect &rect)
-{
-    Q_D(QSGPaintedItem);
-    d->contentsDirty = true;
-
-    if (rect.isNull() && !d->dirtyRect.isNull())
-        d->dirtyRect = contentsBoundingRect().toAlignedRect();
-    else
-        d->dirtyRect |= (contentsBoundingRect() & rect).toAlignedRect();
-    QSGItem::update();
-}
-
-/*!
-    Returns true if this item is opaque; otherwise, false is returned.
-
-    By default, painted items are not opaque.
-
-    \sa setOpaquePainting()
-*/
-bool QSGPaintedItem::opaquePainting() const
-{
-    Q_D(const QSGPaintedItem);
-    return d->opaquePainting;
-}
-
-/*!
-    If \a opaque is true, the item is opaque; otherwise, it is considered as translucent.
-
-    Opaque items are not blended with the rest of the scene, you should set this to true
-    if the content of the item is opaque to speed up rendering.
-
-    By default, painted items are not opaque.
-
-    \sa opaquePainting()
-*/
-void QSGPaintedItem::setOpaquePainting(bool opaque)
-{
-    Q_D(QSGPaintedItem);
-
-    if (d->opaquePainting == opaque)
-        return;
-
-    d->opaquePainting = opaque;
-    QSGItem::update();
-}
-
-/*!
-    Returns true if antialiased painting is enabled; otherwise, false is returned.
-
-    By default, antialiasing is not enabled.
-
-    \sa setAntialiasing()
-*/
-bool QSGPaintedItem::antialiasing() const
-{
-    Q_D(const QSGPaintedItem);
-    return d->antialiasing;
-}
-
-/*!
-    If \a enable is true, antialiased painting is enabled.
-
-    By default, antialiasing is not enabled.
-
-    \sa antialiasing()
-*/
-void QSGPaintedItem::setAntialiasing(bool enable)
-{
-    Q_D(QSGPaintedItem);
-
-    if (d->antialiasing == enable)
-        return;
-
-    d->antialiasing = enable;
-    update();
-}
-
-/*!
-    Returns true if mipmaps are enabled; otherwise, false is returned.
-
-    By default, mipmapping is not enabled.
-
-    \sa setMipmap()
-*/
-bool QSGPaintedItem::mipmap() const
-{
-    Q_D(const QSGPaintedItem);
-    return d->mipmap;
-}
-
-/*!
-    If \a enable is true, mipmapping is enabled on the associated texture.
-
-    Mipmapping increases rendering speed and reduces aliasing artifacts when the item is
-    scaled down.
-
-    By default, mipmapping is not enabled.
-
-    \sa mipmap()
-*/
-void QSGPaintedItem::setMipmap(bool enable)
-{
-    Q_D(QSGPaintedItem);
-
-    if (d->mipmap == enable)
-        return;
-
-    d->mipmap = enable;
-    update();
-}
-
-/*!
-    Returns the performance hints.
-
-    By default, no performance hint is enabled/
-
-    \sa setPerformanceHint(), setPerformanceHints()
-*/
-QSGPaintedItem::PerformanceHints QSGPaintedItem::performanceHints() const
-{
-    Q_D(const QSGPaintedItem);
-    return d->performanceHints;
-}
-
-/*!
-    Sets the given performance \a hint on the item if \a enabled is true;
-    otherwise clears the performance hint.
-
-    By default, no performance hint is enabled/
-
-    \sa setPerformanceHints(), performanceHints()
-*/
-void QSGPaintedItem::setPerformanceHint(QSGPaintedItem::PerformanceHint hint, bool enabled)
-{
-    Q_D(QSGPaintedItem);
-    PerformanceHints oldHints = d->performanceHints;
-    if (enabled)
-        d->performanceHints |= hint;
-    else
-        d->performanceHints &= ~hint;
-    if (oldHints != d->performanceHints)
-       update();
-}
-
-/*!
-    Sets the performance hints to \a hints
-
-    By default, no performance hint is enabled/
-
-    \sa setPerformanceHint(), performanceHints()
-*/
-void QSGPaintedItem::setPerformanceHints(QSGPaintedItem::PerformanceHints hints)
-{
-    Q_D(QSGPaintedItem);
-    if (d->performanceHints == hints)
-        return;
-    d->performanceHints = hints;
-    update();
-}
-
-/*!
-    This function returns the outer bounds of the item as a rectangle; all painting must be
-    restricted to inside an item's bounding rect.
-
-    If the contents size has not been set it reflects the size of the item; otherwise
-    it reflects the contents size scaled by the contents scale.
-
-    Use this function to know the area painted by the item.
-
-    \sa QSGItem::width(), QSGItem::height(), contentsSize(), contentsScale()
-*/
-QRectF QSGPaintedItem::contentsBoundingRect() const
-{
-    Q_D(const QSGPaintedItem);
-
-    qreal w = d->width;
-    QSizeF sz = d->contentsSize * d->contentsScale;
-    if (w < sz.width())
-        w = sz.width();
-    qreal h = d->height;
-    if (h < sz.height())
-        h = sz.height();
-
-    return QRectF(0, 0, w, h);
-}
-
-/*!
-    \property QSGPaintedItem::contentsSize
-    \brief The size of the contents
-
-    The contents size is the size of the item in regards to how it is painted
-    using the paint() function.  This is distinct from the size of the
-    item in regards to height() and width().
-*/
-QSize QSGPaintedItem::contentsSize() const
-{
-    Q_D(const QSGPaintedItem);
-    return d->contentsSize;
-}
-
-void QSGPaintedItem::setContentsSize(const QSize &size)
-{
-    Q_D(QSGPaintedItem);
-
-    if (d->contentsSize == size)
-        return;
-
-    d->contentsSize = size;
-    update();
-}
-
-/*!
-    This convenience function is equivalent to calling setContentsSize(QSize()).
-*/
-void QSGPaintedItem::resetContentsSize()
-{
-    setContentsSize(QSize());
-}
-
-/*!
-    \property QSGPaintedItem::contentsScale
-    \brief The scale of the contents
-
-    All painting happening in paint() is scaled by the contents scale. This is distinct
-    from the scale of the item in regards to scale().
-
-    The default value is 1.
-*/
-qreal QSGPaintedItem::contentsScale() const
-{
-    Q_D(const QSGPaintedItem);
-    return d->contentsScale;
-}
-
-void QSGPaintedItem::setContentsScale(qreal scale)
-{
-    Q_D(QSGPaintedItem);
-
-    if (d->contentsScale == scale)
-        return;
-
-    d->contentsScale = scale;
-    update();
-}
-
-/*!
-    \property QSGPaintedItem::fillColor
-    \brief The item's background fill color.
-
-    By default, the fill color is set to Qt::transparent.
-*/
-QColor QSGPaintedItem::fillColor() const
-{
-    Q_D(const QSGPaintedItem);
-    return d->fillColor;
-}
-
-void QSGPaintedItem::setFillColor(const QColor &c)
-{
-    Q_D(QSGPaintedItem);
-
-    if (d->fillColor == c)
-        return;
-
-    d->fillColor = c;
-    update();
-
-    emit fillColorChanged();
-}
-
-/*!
-    \property QSGPaintedItem::renderTarget
-    \brief The item's render target.
-
-    This property defines which render target the QPainter renders into, it can be either
-    QSGPaintedItem::Image or QSGPaintedItem::FramebufferObject. Both have certains benefits,
-    typically performance versus quality. Using a framebuffer object avoids a costly upload
-    of the image contents to the texture in graphics memory, while using an image enables
-    high quality anti-aliasing.
-
-    \warning Resizing a framebuffer object is a costly operation, avoid using
-    the QSGPaintedItem::FramebufferObject render target if the item gets resized often.
-
-    By default, the render target is QSGPaintedItem::Image.
-*/
-QSGPaintedItem::RenderTarget QSGPaintedItem::renderTarget() const
-{
-    Q_D(const QSGPaintedItem);
-    return d->renderTarget;
-}
-
-void QSGPaintedItem::setRenderTarget(RenderTarget target)
-{
-    Q_D(QSGPaintedItem);
-
-    if (d->renderTarget == target)
-        return;
-
-    d->renderTarget = target;
-    update();
-
-    emit renderTargetChanged();
-}
-
-/*!
-    \fn virtual void QSGPaintedItem::paint(QPainter *painter) = 0
-
-    This function, which is usually called by the QML Scene Graph, paints the
-    contents of an item in local coordinates.
-
-    The function is called after the item has been filled with the fillColor.
-
-    Reimplement this function in a QSGPaintedItem subclass to provide the
-    item's painting implementation, using \a painter.
-
-    \note The QML Scene Graph uses two separate threads, the main thread does things such as
-    processing events or updating animations while a second thread does the actual OpenGL rendering.
-    As a consequence, paint() is not called from the main GUI thread but from the GL enabled
-    renderer thread. At the moment paint() is called, the GUI thread is blocked and this is
-    therefore thread-safe.
-*/
-
-/*!
-    This function is called after the item's geometry has changed.
-*/
-void QSGPaintedItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
-{
-    Q_D(QSGPaintedItem);
-    d->geometryDirty = true;
-    QSGItem::geometryChanged(newGeometry, oldGeometry);
-}
-
-
-/*!
-    This function is called when the Scene Graph node associated to the item needs to
-    be updated.
-*/
-QSGNode *QSGPaintedItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
-{
-    Q_UNUSED(data);
-    Q_D(QSGPaintedItem);
-
-    if (width() <= 0 || height() <= 0) {
-        delete oldNode;
-        return 0;
-    }
-
-    QSGPainterNode *node = static_cast<QSGPainterNode *>(oldNode);
-    if (!node)
-        node = new QSGPainterNode(this);
-
-    QRectF br = contentsBoundingRect();
-
-    node->setPreferredRenderTarget(d->renderTarget);
-    node->setFastFBOResizing(d->performanceHints & FastFBOResizing);
-    node->setSize(QSize(qRound(br.width()), qRound(br.height())));
-    node->setSmoothPainting(d->antialiasing);
-    node->setLinearFiltering(d->smooth);
-    node->setMipmapping(d->mipmap);
-    node->setOpaquePainting(d->opaquePainting);
-    node->setFillColor(d->fillColor);
-    node->setContentsScale(d->contentsScale);
-    node->setDirty(d->contentsDirty || d->geometryDirty, d->dirtyRect);
-    node->update();
-
-    d->contentsDirty = false;
-    d->geometryDirty = false;
-    d->dirtyRect = QRect();
-
-    return node;
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgpainteditem.h b/src/declarative/items/qsgpainteditem.h
deleted file mode 100644 (file)
index eaae3be..0000000
+++ /dev/null
@@ -1,130 +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 QSGPAINTEDITEM_P_H
-#define QSGPAINTEDITEM_P_H
-
-#include <qsgitem.h>
-#include <QtGui/qcolor.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-class QSGPaintedItemPrivate;
-class Q_DECLARATIVE_EXPORT QSGPaintedItem : public QSGItem
-{
-    Q_OBJECT
-    Q_ENUMS(RenderTarget)
-
-    Q_PROPERTY(QSize contentsSize READ contentsSize WRITE setContentsSize NOTIFY contentsSizeChanged)
-    Q_PROPERTY(QColor fillColor READ fillColor WRITE setFillColor NOTIFY fillColorChanged)
-    Q_PROPERTY(qreal contentsScale READ contentsScale WRITE setContentsScale NOTIFY contentsScaleChanged)
-    Q_PROPERTY(RenderTarget renderTarget READ renderTarget WRITE setRenderTarget NOTIFY renderTargetChanged)
-public:
-    QSGPaintedItem(QSGItem *parent = 0);
-    virtual ~QSGPaintedItem();
-
-    enum RenderTarget {
-        Image,
-        FramebufferObject
-    };
-
-    enum PerformanceHint {
-        FastFBOResizing = 0x1
-    };
-    Q_DECLARE_FLAGS(PerformanceHints, PerformanceHint)
-
-    void update(const QRect &rect = QRect());
-
-    bool opaquePainting() const;
-    void setOpaquePainting(bool opaque);
-
-    bool antialiasing() const;
-    void setAntialiasing(bool enable);
-
-    bool mipmap() const;
-    void setMipmap(bool enable);
-
-    PerformanceHints performanceHints() const;
-    void setPerformanceHint(PerformanceHint hint, bool enabled = true);
-    void setPerformanceHints(PerformanceHints hints);
-
-    QRectF contentsBoundingRect() const;
-
-    QSize contentsSize() const;
-    void setContentsSize(const QSize &);
-    void resetContentsSize();
-
-    qreal contentsScale() const;
-    void setContentsScale(qreal);
-
-    QColor fillColor() const;
-    void setFillColor(const QColor&);
-
-    RenderTarget renderTarget() const;
-    void setRenderTarget(RenderTarget target);
-
-    virtual void paint(QPainter *painter) = 0;
-
-Q_SIGNALS:
-    void fillColorChanged();
-    void contentsSizeChanged();
-    void contentsScaleChanged();
-    void renderTargetChanged();
-
-protected:
-    QSGPaintedItem(QSGPaintedItemPrivate &dd, QSGItem *parent = 0);
-    virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
-    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
-
-private:
-    Q_DISABLE_COPY(QSGPaintedItem)
-    Q_DECLARE_PRIVATE(QSGPaintedItem)
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QSGPaintedItem::PerformanceHints)
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSGPAINTEDITEM_P_H
diff --git a/src/declarative/items/qsgpainteditem_p.h b/src/declarative/items/qsgpainteditem_p.h
deleted file mode 100644 (file)
index f698e18..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
-/****************************************************************************
-**
-** 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 QSGPAINTEDITEM_P_P_H
-#define QSGPAINTEDITEM_P_P_H
-
-#include "qsgitem_p.h"
-#include <QtGui/qcolor.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGPaintedItemPrivate : public QSGItemPrivate
-{
-public:
-    QSGPaintedItemPrivate();
-
-    QSize contentsSize;
-    qreal contentsScale;
-    QColor fillColor;
-    QSGPaintedItem::RenderTarget renderTarget;
-    QSGPaintedItem::PerformanceHints performanceHints;
-
-    QRect dirtyRect;
-
-    bool geometryDirty : 1;
-    bool contentsDirty : 1;
-    bool opaquePainting: 1;
-    bool antialiasing: 1;
-    bool mipmap: 1;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGPAINTEDITEM_P_P_H
diff --git a/src/declarative/items/qsgpathview.cpp b/src/declarative/items/qsgpathview.cpp
deleted file mode 100644 (file)
index 5e2ad84..0000000
+++ /dev/null
@@ -1,1738 +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 "qsgpathview_p.h"
-#include "qsgpathview_p_p.h"
-#include "qsgcanvas.h"
-
-#include <private/qdeclarativestate_p.h>
-#include <private/qdeclarativeopenmetaobject_p.h>
-#include <private/qlistmodelinterface_p.h>
-#include <private/qdeclarativechangeset_p.h>
-
-#include <QtGui/qevent.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qguiapplication.h>
-#include <QtGui/qstylehints.h>
-#include <QtCore/qmath.h>
-#include <math.h>
-
-QT_BEGIN_NAMESPACE
-
-inline qreal qmlMod(qreal x, qreal y)
-{
-#ifdef QT_USE_MATH_H_FLOATS
-    if (sizeof(qreal) == sizeof(float))
-        return fmodf(float(x), float(y));
-    else
-#endif
-        return fmod(x, y);
-}
-
-static QDeclarativeOpenMetaObjectType *qPathViewAttachedType = 0;
-
-QSGPathViewAttached::QSGPathViewAttached(QObject *parent)
-: QObject(parent), m_percent(-1), m_view(0), m_onPath(false), m_isCurrent(false)
-{
-    if (qPathViewAttachedType) {
-        m_metaobject = new QDeclarativeOpenMetaObject(this, qPathViewAttachedType);
-        m_metaobject->setCached(true);
-    } else {
-        m_metaobject = new QDeclarativeOpenMetaObject(this);
-    }
-}
-
-QSGPathViewAttached::~QSGPathViewAttached()
-{
-}
-
-QVariant QSGPathViewAttached::value(const QByteArray &name) const
-{
-    return m_metaobject->value(name);
-}
-void QSGPathViewAttached::setValue(const QByteArray &name, const QVariant &val)
-{
-    m_metaobject->setValue(name, val);
-}
-
-
-void QSGPathViewPrivate::init()
-{
-    Q_Q(QSGPathView);
-    offset = 0;
-    q->setAcceptedMouseButtons(Qt::LeftButton);
-    q->setFlag(QSGItem::ItemIsFocusScope);
-    q->setFiltersChildMouseEvents(true);
-    FAST_CONNECT(&tl, SIGNAL(updated()), q, SLOT(ticked()))
-    lastPosTime.invalidate();
-    FAST_CONNECT(&tl, SIGNAL(completed()), q, SLOT(movementEnding()))
-}
-
-QSGItem *QSGPathViewPrivate::getItem(int modelIndex, bool onPath)
-{
-    Q_Q(QSGPathView);
-    requestedIndex = modelIndex;
-    QSGItem *item = model->item(modelIndex, false);
-    if (item) {
-        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())
-                attType->createProperty(attr.toUtf8());
-        }
-        qPathViewAttachedType = attType;
-        QSGPathViewAttached *att = static_cast<QSGPathViewAttached *>(qmlAttachedPropertiesObject<QSGPathView>(item));
-        qPathViewAttachedType = 0;
-        if (att) {
-            att->m_view = q;
-            att->setOnPath(onPath);
-        }
-        item->setParentItem(q);
-        QSGItemPrivate *itemPrivate = QSGItemPrivate::get(item);
-        itemPrivate->addItemChangeListener(this, QSGItemPrivate::Geometry);
-    }
-    requestedIndex = -1;
-    return item;
-}
-
-void QSGPathViewPrivate::releaseItem(QSGItem *item)
-{
-    if (!item || !model)
-        return;
-    QSGItemPrivate *itemPrivate = QSGItemPrivate::get(item);
-    itemPrivate->removeItemChangeListener(this, QSGItemPrivate::Geometry);
-    if (model->release(item) == 0) {
-        // item was not destroyed, and we no longer reference it.
-        if (QSGPathViewAttached *att = attached(item))
-            att->setOnPath(false);
-    }
-}
-
-QSGPathViewAttached *QSGPathViewPrivate::attached(QSGItem *item)
-{
-    return static_cast<QSGPathViewAttached *>(qmlAttachedPropertiesObject<QSGPathView>(item, false));
-}
-
-void QSGPathViewPrivate::clear()
-{
-    if (currentItem) {
-        releaseItem(currentItem);
-        currentItem = 0;
-    }
-    for (int i=0; i<items.count(); i++){
-        QSGItem *p = items[i];
-        releaseItem(p);
-    }
-    items.clear();
-}
-
-void QSGPathViewPrivate::updateMappedRange()
-{
-    if (model && pathItems != -1 && pathItems < modelCount)
-        mappedRange = qreal(pathItems)/modelCount;
-    else
-        mappedRange = 1.0;
-}
-
-qreal QSGPathViewPrivate::positionOfIndex(qreal index) const
-{
-    qreal pos = -1.0;
-
-    if (model && index >= 0 && index < modelCount) {
-        qreal start = 0.0;
-        if (haveHighlightRange && highlightRangeMode != QSGPathView::NoHighlightRange)
-            start = highlightRangeStart;
-        qreal globalPos = index + offset;
-        globalPos = qmlMod(globalPos, qreal(modelCount)) / modelCount;
-        if (pathItems != -1 && pathItems < modelCount) {
-            globalPos += start * mappedRange;
-            globalPos = qmlMod(globalPos, 1.0);
-            if (globalPos < mappedRange)
-                pos = globalPos / mappedRange;
-        } else {
-            pos = qmlMod(globalPos + start, 1.0);
-        }
-    }
-
-    return pos;
-}
-
-void QSGPathViewPrivate::createHighlight()
-{
-    Q_Q(QSGPathView);
-    if (!q->isComponentComplete())
-        return;
-
-    bool changed = false;
-    if (highlightItem) {
-        highlightItem->setParentItem(0);
-        highlightItem->deleteLater();
-        highlightItem = 0;
-        changed = true;
-    }
-
-    QSGItem *item = 0;
-    if (highlightComponent) {
-        QDeclarativeContext *creationContext = highlightComponent->creationContext();
-        QDeclarativeContext *highlightContext = new QDeclarativeContext(
-                creationContext ? creationContext : qmlContext(q));
-        QObject *nobj = highlightComponent->create(highlightContext);
-        if (nobj) {
-            QDeclarative_setParent_noEvent(highlightContext, nobj);
-            item = qobject_cast<QSGItem *>(nobj);
-            if (!item)
-                delete nobj;
-        } else {
-            delete highlightContext;
-        }
-    } else {
-        item = new QSGItem;
-    }
-    if (item) {
-        QDeclarative_setParent_noEvent(item, q);
-        item->setParentItem(q);
-        highlightItem = item;
-        changed = true;
-    }
-    if (changed)
-        emit q->highlightItemChanged();
-}
-
-void QSGPathViewPrivate::updateHighlight()
-{
-    Q_Q(QSGPathView);
-    if (!q->isComponentComplete() || !isValid())
-        return;
-    if (highlightItem) {
-        if (haveHighlightRange && highlightRangeMode == QSGPathView::StrictlyEnforceRange) {
-            updateItem(highlightItem, highlightRangeStart);
-        } else {
-            qreal target = currentIndex;
-
-            offsetAdj = 0.0;
-            tl.reset(moveHighlight);
-            moveHighlight.setValue(highlightPosition);
-
-            const int duration = highlightMoveDuration;
-
-            if (target - highlightPosition > modelCount/2) {
-                highlightUp = false;
-                qreal distance = modelCount - target + highlightPosition;
-                tl.move(moveHighlight, 0.0, QEasingCurve(QEasingCurve::InQuad), int(duration * highlightPosition / distance));
-                tl.set(moveHighlight, modelCount-0.01);
-                tl.move(moveHighlight, target, QEasingCurve(QEasingCurve::OutQuad), int(duration * (modelCount-target) / distance));
-            } else if (target - highlightPosition <= -modelCount/2) {
-                highlightUp = true;
-                qreal distance = modelCount - highlightPosition + target;
-                tl.move(moveHighlight, modelCount-0.01, QEasingCurve(QEasingCurve::InQuad), int(duration * (modelCount-highlightPosition) / distance));
-                tl.set(moveHighlight, 0.0);
-                tl.move(moveHighlight, target, QEasingCurve(QEasingCurve::OutQuad), int(duration * target / distance));
-            } else {
-                highlightUp = highlightPosition - target < 0;
-                tl.move(moveHighlight, target, QEasingCurve(QEasingCurve::InOutQuad), duration);
-            }
-        }
-    }
-}
-
-void QSGPathViewPrivate::setHighlightPosition(qreal pos)
-{
-    if (pos != highlightPosition) {
-        qreal start = 0.0;
-        qreal end = 1.0;
-        if (haveHighlightRange && highlightRangeMode != QSGPathView::NoHighlightRange) {
-            start = highlightRangeStart;
-            end = highlightRangeEnd;
-        }
-
-        qreal range = qreal(modelCount);
-        // calc normalized position of highlight relative to offset
-        qreal relativeHighlight = qmlMod(pos + offset, range) / range;
-
-        if (!highlightUp && relativeHighlight > end * mappedRange) {
-            qreal diff = 1.0 - relativeHighlight;
-            setOffset(offset + diff * range);
-        } else if (highlightUp && relativeHighlight >= (end - start) * mappedRange) {
-            qreal diff = relativeHighlight - (end - start) * mappedRange;
-            setOffset(offset - diff * range - 0.00001);
-        }
-
-        highlightPosition = pos;
-        qreal pathPos = positionOfIndex(pos);
-        updateItem(highlightItem, pathPos);
-        if (QSGPathViewAttached *att = attached(highlightItem))
-            att->setOnPath(pathPos != -1.0);
-    }
-}
-
-void QSGPathView::pathUpdated()
-{
-    Q_D(QSGPathView);
-    QList<QSGItem*>::iterator it = d->items.begin();
-    while (it != d->items.end()) {
-        QSGItem *item = *it;
-        if (QSGPathViewAttached *att = d->attached(item))
-            att->m_percent = -1;
-        ++it;
-    }
-    refill();
-}
-
-void QSGPathViewPrivate::updateItem(QSGItem *item, qreal percent)
-{
-    if (QSGPathViewAttached *att = attached(item)) {
-        if (qFuzzyCompare(att->m_percent, percent))
-            return;
-        att->m_percent = percent;
-        foreach (const QString &attr, path->attributes())
-            att->setValue(attr.toUtf8(), path->attributeAt(attr, percent));
-    }
-    QPointF pf = path->pointAt(percent);
-    item->setX(qRound(pf.x() - item->width()/2));
-    item->setY(qRound(pf.y() - item->height()/2));
-}
-
-void QSGPathViewPrivate::regenerate()
-{
-    Q_Q(QSGPathView);
-    if (!q->isComponentComplete())
-        return;
-
-    clear();
-
-    if (!isValid())
-        return;
-
-    firstIndex = -1;
-    updateMappedRange();
-    q->refill();
-}
-
-/*!
-    \qmlclass PathView QSGPathView
-    \inqmlmodule QtQuick 2
-    \ingroup qml-view-elements
-    \brief The PathView element lays out model-provided items on a path.
-    \inherits Item
-
-    A PathView displays data from models created from built-in QML elements like ListModel
-    and XmlListModel, or custom model classes defined in C++ that inherit from
-    QAbstractListModel.
-
-    The view has a \l model, which defines the data to be displayed, and
-    a \l delegate, which defines how the data should be displayed.
-    The \l delegate is instantiated for each item on the \l path.
-    The items may be flicked to move them along the path.
-
-    For example, if there is a simple list model defined in a file \c ContactModel.qml like this:
-
-    \snippet doc/src/snippets/declarative/pathview/ContactModel.qml 0
-
-    This data can be represented as a PathView, like this:
-
-    \snippet doc/src/snippets/declarative/pathview/pathview.qml 0
-
-    \image pathview.gif
-
-    (Note the above example uses PathAttribute to scale and modify the
-    opacity of the items as they rotate. This additional code can be seen in the
-    PathAttribute documentation.)
-
-    PathView does not automatically handle keyboard navigation.  This is because
-    the keys to use for navigation will depend upon the shape of the path.  Navigation
-    can be added quite simply by setting \c focus to \c true and calling
-    \l decrementCurrentIndex() or \l incrementCurrentIndex(), for example to navigate
-    using the left and right arrow keys:
-
-    \qml
-    PathView {
-        // ...
-        focus: true
-        Keys.onLeftPressed: decrementCurrentIndex()
-        Keys.onRightPressed: incrementCurrentIndex()
-    }
-    \endqml
-
-    The path view itself is a focus scope (see \l{qmlfocus#Acquiring Focus and Focus Scopes}{the focus documentation page} for more details).
-
-    Delegates are instantiated as needed and may be destroyed at any time.
-    State should \e never be stored in a delegate.
-
-    PathView attaches a number of properties to the root item of the delegate, for example
-    \c {PathView.isCurrentItem}.  In the following example, the root delegate item can access
-    this attached property directly as \c PathView.isCurrentItem, while the child
-    \c nameText object must refer to this property as \c wrapper.PathView.isCurrentItem.
-
-    \snippet doc/src/snippets/declarative/pathview/pathview.qml 1
-
-    \bold Note that views do not enable \e clip automatically.  If the view
-    is not clipped by another item or the screen, it will be necessary
-    to set \e {clip: true} in order to have the out of view items clipped
-    nicely.
-
-    \sa Path, {declarative/modelviews/pathview}{PathView example}
-*/
-
-QSGPathView::QSGPathView(QSGItem *parent)
-  : QSGItem(*(new QSGPathViewPrivate), parent)
-{
-    Q_D(QSGPathView);
-    d->init();
-}
-
-QSGPathView::~QSGPathView()
-{
-    Q_D(QSGPathView);
-    d->clear();
-    if (d->attType)
-        d->attType->release();
-    if (d->ownModel)
-        delete d->model;
-}
-
-/*!
-    \qmlattachedproperty PathView QtQuick2::PathView::view
-    This attached property holds the view that manages this delegate instance.
-
-    It is attached to each instance of the delegate.
-*/
-
-/*!
-    \qmlattachedproperty bool QtQuick2::PathView::onPath
-    This attached property holds whether the item is currently on the path.
-
-    If a pathItemCount has been set, it is possible that some items may
-    be instantiated, but not considered to be currently on the path.
-    Usually, these items would be set invisible, for example:
-
-    \qml
-    Component {
-        Rectangle {
-            visible: PathView.onPath
-            // ...
-        }
-    }
-    \endqml
-
-    It is attached to each instance of the delegate.
-*/
-
-/*!
-    \qmlattachedproperty bool QtQuick2::PathView::isCurrentItem
-    This attached property is true if this delegate is the current item; otherwise false.
-
-    It is attached to each instance of the delegate.
-
-    This property may be used to adjust the appearance of the current item.
-
-    \snippet doc/src/snippets/declarative/pathview/pathview.qml 1
-*/
-
-/*!
-    \qmlproperty model QtQuick2::PathView::model
-    This property holds the model providing data for the view.
-
-    The model provides a set of data that is used to create the items for the view.
-    For large or dynamic datasets the model is usually provided by a C++ model object.
-    Models can also be created directly in QML, using the ListModel element.
-
-    \sa {qmlmodels}{Data Models}
-*/
-QVariant QSGPathView::model() const
-{
-    Q_D(const QSGPathView);
-    return d->modelVariant;
-}
-
-void QSGPathView::setModel(const QVariant &model)
-{
-    Q_D(QSGPathView);
-    if (d->modelVariant == model)
-        return;
-
-    if (d->model) {
-        disconnect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
-                this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
-        disconnect(d->model, SIGNAL(createdItem(int,QSGItem*)), this, SLOT(createdItem(int,QSGItem*)));
-        for (int i=0; i<d->items.count(); i++){
-            QSGItem *p = d->items[i];
-            d->model->release(p);
-        }
-        d->items.clear();
-    }
-
-    d->modelVariant = model;
-    QObject *object = qvariant_cast<QObject*>(model);
-    QSGVisualModel *vim = 0;
-    if (object && (vim = qobject_cast<QSGVisualModel *>(object))) {
-        if (d->ownModel) {
-            delete d->model;
-            d->ownModel = false;
-        }
-        d->model = vim;
-    } else {
-        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);
-    }
-    d->modelCount = 0;
-    if (d->model) {
-        connect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
-                this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
-        connect(d->model, SIGNAL(createdItem(int,QSGItem*)), this, SLOT(createdItem(int,QSGItem*)));
-        d->modelCount = d->model->count();
-        if (d->model->count())
-            d->offset = qmlMod(d->offset, qreal(d->model->count()));
-        if (d->offset < 0)
-            d->offset = d->model->count() + d->offset;
-}
-    d->regenerate();
-    if (d->currentIndex < d->modelCount)
-        setOffset(qmlMod(d->modelCount - d->currentIndex, d->modelCount));
-    else
-        d->fixOffset();
-    emit countChanged();
-    emit modelChanged();
-}
-
-/*!
-    \qmlproperty int QtQuick2::PathView::count
-    This property holds the number of items in the model.
-*/
-int QSGPathView::count() const
-{
-    Q_D(const QSGPathView);
-    return d->model ? d->modelCount : 0;
-}
-
-/*!
-    \qmlproperty Path QtQuick2::PathView::path
-    This property holds the path used to lay out the items.
-    For more information see the \l Path documentation.
-*/
-QDeclarativePath *QSGPathView::path() const
-{
-    Q_D(const QSGPathView);
-    return d->path;
-}
-
-void QSGPathView::setPath(QDeclarativePath *path)
-{
-    Q_D(QSGPathView);
-    if (d->path == path)
-        return;
-    if (d->path)
-        disconnect(d->path, SIGNAL(changed()), this, SLOT(pathUpdated()));
-    d->path = path;
-    connect(d->path, SIGNAL(changed()), this, SLOT(pathUpdated()));
-    if (d->isValid() && isComponentComplete()) {
-        d->clear();
-        if (d->attType) {
-            d->attType->release();
-            d->attType = 0;
-        }
-        d->regenerate();
-    }
-    emit pathChanged();
-}
-
-/*!
-    \qmlproperty int QtQuick2::PathView::currentIndex
-    This property holds the index of the current item.
-*/
-int QSGPathView::currentIndex() const
-{
-    Q_D(const QSGPathView);
-    return d->currentIndex;
-}
-
-void QSGPathView::setCurrentIndex(int idx)
-{
-    Q_D(QSGPathView);
-    if (d->model && d->modelCount)
-        idx = qAbs(idx % d->modelCount);
-    if (d->model && idx != d->currentIndex) {
-        if (d->currentItem) {
-            if (QSGPathViewAttached *att = d->attached(d->currentItem))
-                att->setIsCurrentItem(false);
-            d->releaseItem(d->currentItem);
-        }
-        d->currentItem = 0;
-        d->moveReason = QSGPathViewPrivate::SetIndex;
-        d->currentIndex = idx;
-        if (d->modelCount) {
-            int itemIndex = (idx - d->firstIndex + d->modelCount) % d->modelCount;
-            if (itemIndex < d->items.count()) {
-                d->currentItem = d->model->item(d->currentIndex, true);
-                d->currentItem->setFocus(true);
-                if (QSGPathViewAttached *att = d->attached(d->currentItem))
-                    att->setIsCurrentItem(true);
-            } else {
-                d->currentItem = d->getItem(d->currentIndex, false);
-                d->updateItem(d->currentItem, d->currentIndex < d->firstIndex ? 0.0 : 1.0);
-                if (QSGPathViewAttached *att = d->attached(d->currentItem))
-                    att->setIsCurrentItem(true);
-                if (d->model->completePending())
-                    d->model->completeItem();
-            }
-            if (d->haveHighlightRange && d->highlightRangeMode == QSGPathView::StrictlyEnforceRange)
-                d->snapToCurrent();
-            d->currentItemOffset = d->positionOfIndex(d->currentIndex);
-            d->updateHighlight();
-        }
-        emit currentIndexChanged();
-    }
-}
-
-QSGItem *QSGPathView::currentItem() const
-{
-    Q_D(const QSGPathView);
-    return d->currentItem;
-}
-
-/*!
-    \qmlmethod QtQuick2::PathView::incrementCurrentIndex()
-
-    Increments the current index.
-
-    \bold Note: methods should only be called after the Component has completed.
-*/
-void QSGPathView::incrementCurrentIndex()
-{
-    Q_D(QSGPathView);
-    d->moveDirection = QSGPathViewPrivate::Positive;
-    setCurrentIndex(currentIndex()+1);
-}
-
-/*!
-    \qmlmethod QtQuick2::PathView::decrementCurrentIndex()
-
-    Decrements the current index.
-
-    \bold Note: methods should only be called after the Component has completed.
-*/
-void QSGPathView::decrementCurrentIndex()
-{
-    Q_D(QSGPathView);
-    if (d->model && d->modelCount) {
-        int idx = currentIndex()-1;
-        if (idx < 0)
-            idx = d->modelCount - 1;
-        d->moveDirection = QSGPathViewPrivate::Negative;
-        setCurrentIndex(idx);
-    }
-}
-
-/*!
-    \qmlproperty real QtQuick2::PathView::offset
-
-    The offset specifies how far along the path the items are from their initial positions.
-    This is a real number that ranges from 0.0 to the count of items in the model.
-*/
-qreal QSGPathView::offset() const
-{
-    Q_D(const QSGPathView);
-    return d->offset;
-}
-
-void QSGPathView::setOffset(qreal offset)
-{
-    Q_D(QSGPathView);
-    d->setOffset(offset);
-    d->updateCurrent();
-}
-
-void QSGPathViewPrivate::setOffset(qreal o)
-{
-    Q_Q(QSGPathView);
-    if (offset != o) {
-        if (isValid() && q->isComponentComplete()) {
-            offset = qmlMod(o, qreal(modelCount));
-            if (offset < 0)
-                offset += qreal(modelCount);
-            q->refill();
-        } else {
-            offset = o;
-        }
-        emit q->offsetChanged();
-    }
-}
-
-void QSGPathViewPrivate::setAdjustedOffset(qreal o)
-{
-    setOffset(o+offsetAdj);
-}
-
-/*!
-    \qmlproperty Component QtQuick2::PathView::highlight
-    This property holds the component to use as the highlight.
-
-    An instance of the highlight component will be created for each view.
-    The geometry of the resultant component instance will be managed by the view
-    so as to stay with the current item.
-
-    The below example demonstrates how to make a simple highlight.  Note the use
-    of the \l{PathView::onPath}{PathView.onPath} attached property to ensure that
-    the highlight is hidden when flicked away from the path.
-
-    \qml
-    Component {
-        Rectangle {
-            visible: PathView.onPath
-            // ...
-        }
-    }
-    \endqml
-
-    \sa highlightItem, highlightRangeMode
-*/
-
-QDeclarativeComponent *QSGPathView::highlight() const
-{
-    Q_D(const QSGPathView);
-    return d->highlightComponent;
-}
-
-void QSGPathView::setHighlight(QDeclarativeComponent *highlight)
-{
-    Q_D(QSGPathView);
-    if (highlight != d->highlightComponent) {
-        d->highlightComponent = highlight;
-        d->createHighlight();
-        d->updateHighlight();
-        emit highlightChanged();
-    }
-}
-
-/*!
-  \qmlproperty Item QtQuick2::PathView::highlightItem
-
-  \c highlightItem holds the highlight item, which was created
-  from the \l highlight component.
-
-  \sa highlight
-*/
-QSGItem *QSGPathView::highlightItem()
-{
-    Q_D(const QSGPathView);
-    return d->highlightItem;
-}
-/*!
-    \qmlproperty real QtQuick2::PathView::preferredHighlightBegin
-    \qmlproperty real QtQuick2::PathView::preferredHighlightEnd
-    \qmlproperty enumeration QtQuick2::PathView::highlightRangeMode
-
-    These properties set the preferred range of the highlight (current item)
-    within the view.  The preferred values must be in the range 0.0-1.0.
-
-    If highlightRangeMode is set to \e PathView.NoHighlightRange
-
-    If highlightRangeMode is set to \e PathView.ApplyRange the view will
-    attempt to maintain the highlight within the range, however
-    the highlight can move outside of the range at the ends of the path
-    or due to a mouse interaction.
-
-    If highlightRangeMode is set to \e PathView.StrictlyEnforceRange the highlight will never
-    move outside of the range.  This means that the current item will change
-    if a keyboard or mouse action would cause the highlight to move
-    outside of the range.
-
-    Note that this is the correct way to influence where the
-    current item ends up when the view moves. For example, if you want the
-    currently selected item to be in the middle of the path, then set the
-    highlight range to be 0.5,0.5 and highlightRangeMode to PathView.StrictlyEnforceRange.
-    Then, when the path scrolls,
-    the currently selected item will be the item at that position. This also applies to
-    when the currently selected item changes - it will scroll to within the preferred
-    highlight range. Furthermore, the behaviour of the current item index will occur
-    whether or not a highlight exists.
-
-    The default value is \e PathView.StrictlyEnforceRange.
-
-    Note that a valid range requires preferredHighlightEnd to be greater
-    than or equal to preferredHighlightBegin.
-*/
-qreal QSGPathView::preferredHighlightBegin() const
-{
-    Q_D(const QSGPathView);
-    return d->highlightRangeStart;
-}
-
-void QSGPathView::setPreferredHighlightBegin(qreal start)
-{
-    Q_D(QSGPathView);
-    if (d->highlightRangeStart == start || start < 0 || start > 1.0)
-        return;
-    d->highlightRangeStart = start;
-    d->haveHighlightRange = d->highlightRangeMode != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
-    refill();
-    emit preferredHighlightBeginChanged();
-}
-
-qreal QSGPathView::preferredHighlightEnd() const
-{
-    Q_D(const QSGPathView);
-    return d->highlightRangeEnd;
-}
-
-void QSGPathView::setPreferredHighlightEnd(qreal end)
-{
-    Q_D(QSGPathView);
-    if (d->highlightRangeEnd == end || end < 0 || end > 1.0)
-        return;
-    d->highlightRangeEnd = end;
-    d->haveHighlightRange = d->highlightRangeMode != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
-    refill();
-    emit preferredHighlightEndChanged();
-}
-
-QSGPathView::HighlightRangeMode QSGPathView::highlightRangeMode() const
-{
-    Q_D(const QSGPathView);
-    return d->highlightRangeMode;
-}
-
-void QSGPathView::setHighlightRangeMode(HighlightRangeMode mode)
-{
-    Q_D(QSGPathView);
-    if (d->highlightRangeMode == mode)
-        return;
-    d->highlightRangeMode = mode;
-    d->haveHighlightRange = d->highlightRangeMode != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
-    emit highlightRangeModeChanged();
-}
-
-/*!
-    \qmlproperty int QtQuick2::PathView::highlightMoveDuration
-    This property holds the move animation duration of the highlight delegate.
-
-    If the highlightRangeMode is StrictlyEnforceRange then this property
-    determines the speed that the items move along the path.
-
-    The default value for the duration is 300ms.
-*/
-int QSGPathView::highlightMoveDuration() const
-{
-    Q_D(const QSGPathView);
-    return d->highlightMoveDuration;
-}
-
-void QSGPathView::setHighlightMoveDuration(int duration)
-{
-    Q_D(QSGPathView);
-    if (d->highlightMoveDuration == duration)
-        return;
-    d->highlightMoveDuration = duration;
-    emit highlightMoveDurationChanged();
-}
-
-/*!
-    \qmlproperty real QtQuick2::PathView::dragMargin
-    This property holds the maximum distance from the path that initiate mouse dragging.
-
-    By default the path can only be dragged by clicking on an item.  If
-    dragMargin is greater than zero, a drag can be initiated by clicking
-    within dragMargin pixels of the path.
-*/
-qreal QSGPathView::dragMargin() const
-{
-    Q_D(const QSGPathView);
-    return d->dragMargin;
-}
-
-void QSGPathView::setDragMargin(qreal dragMargin)
-{
-    Q_D(QSGPathView);
-    if (d->dragMargin == dragMargin)
-        return;
-    d->dragMargin = dragMargin;
-    emit dragMarginChanged();
-}
-
-/*!
-    \qmlproperty real QtQuick2::PathView::flickDeceleration
-    This property holds the rate at which a flick will decelerate.
-
-    The default is 100.
-*/
-qreal QSGPathView::flickDeceleration() const
-{
-    Q_D(const QSGPathView);
-    return d->deceleration;
-}
-
-void QSGPathView::setFlickDeceleration(qreal dec)
-{
-    Q_D(QSGPathView);
-    if (d->deceleration == dec)
-        return;
-    d->deceleration = dec;
-    emit flickDecelerationChanged();
-}
-
-/*!
-    \qmlproperty bool QtQuick2::PathView::interactive
-
-    A user cannot drag or flick a PathView that is not interactive.
-
-    This property is useful for temporarily disabling flicking. This allows
-    special interaction with PathView's children.
-*/
-bool QSGPathView::isInteractive() const
-{
-    Q_D(const QSGPathView);
-    return d->interactive;
-}
-
-void QSGPathView::setInteractive(bool interactive)
-{
-    Q_D(QSGPathView);
-    if (interactive != d->interactive) {
-        d->interactive = interactive;
-        if (!interactive)
-            d->tl.clear();
-        emit interactiveChanged();
-    }
-}
-
-/*!
-    \qmlproperty bool QtQuick2::PathView::moving
-
-    This property holds whether the view is currently moving
-    due to the user either dragging or flicking the view.
-*/
-bool QSGPathView::isMoving() const
-{
-    Q_D(const QSGPathView);
-    return d->moving;
-}
-
-/*!
-    \qmlproperty bool QtQuick2::PathView::flicking
-
-    This property holds whether the view is currently moving
-    due to the user flicking the view.
-*/
-bool QSGPathView::isFlicking() const
-{
-    Q_D(const QSGPathView);
-    return d->flicking;
-}
-
-/*!
-    \qmlsignal QtQuick2::PathView::onMovementStarted()
-
-    This handler is called when the view begins moving due to user
-    interaction.
-*/
-
-/*!
-    \qmlsignal QtQuick2::PathView::onMovementEnded()
-
-    This handler is called when the view stops moving due to user
-    interaction.  If a flick was generated, this handler will
-    be triggered once the flick stops.  If a flick was not
-    generated, the handler will be triggered when the
-    user stops dragging - i.e. a mouse or touch release.
-*/
-
-/*!
-    \qmlsignal QtQuick2::PathView::onFlickStarted()
-
-    This handler is called when the view is flicked.  A flick
-    starts from the point that the mouse or touch is released,
-    while still in motion.
-*/
-
-/*!
-    \qmlsignal QtQuick2::PathView::onFlickEnded()
-
-    This handler is called when the view stops moving due to a flick.
-*/
-
-/*!
-    \qmlproperty Component QtQuick2::PathView::delegate
-
-    The delegate provides a template defining each item instantiated by the view.
-    The index is exposed as an accessible \c index property.  Properties of the
-    model are also available depending upon the type of \l {qmlmodels}{Data Model}.
-
-    The number of elements in the delegate has a direct effect on the
-    flicking performance of the view when pathItemCount is specified.  If at all possible, place functionality
-    that is not needed for the normal display of the delegate in a \l Loader which
-    can load additional elements when needed.
-
-    Note that the PathView will layout the items based on the size of the root
-    item in the delegate.
-
-    Here is an example delegate:
-    \snippet doc/src/snippets/declarative/pathview/pathview.qml 1
-*/
-QDeclarativeComponent *QSGPathView::delegate() const
-{
-    Q_D(const QSGPathView);
-     if (d->model) {
-        if (QSGVisualDataModel *dataModel = qobject_cast<QSGVisualDataModel*>(d->model))
-            return dataModel->delegate();
-    }
-
-    return 0;
-}
-
-void QSGPathView::setDelegate(QDeclarativeComponent *delegate)
-{
-    Q_D(QSGPathView);
-    if (delegate == this->delegate())
-        return;
-    if (!d->ownModel) {
-        d->model = new QSGVisualDataModel(qmlContext(this));
-        d->ownModel = true;
-    }
-    if (QSGVisualDataModel *dataModel = qobject_cast<QSGVisualDataModel*>(d->model)) {
-        int oldCount = dataModel->count();
-        dataModel->setDelegate(delegate);
-        d->modelCount = dataModel->count();
-        d->regenerate();
-        if (oldCount != dataModel->count())
-            emit countChanged();
-        emit delegateChanged();
-    }
-}
-
-/*!
-  \qmlproperty int QtQuick2::PathView::pathItemCount
-  This property holds the number of items visible on the path at any one time.
-*/
-int QSGPathView::pathItemCount() const
-{
-    Q_D(const QSGPathView);
-    return d->pathItems;
-}
-
-void QSGPathView::setPathItemCount(int i)
-{
-    Q_D(QSGPathView);
-    if (i == d->pathItems)
-        return;
-    if (i < 1)
-        i = 1;
-    d->pathItems = i;
-    d->updateMappedRange();
-    if (d->isValid() && isComponentComplete()) {
-        d->regenerate();
-    }
-    emit pathItemCountChanged();
-}
-
-QPointF QSGPathViewPrivate::pointNear(const QPointF &point, qreal *nearPercent) const
-{
-    //XXX maybe do recursively at increasing resolution.
-    qreal mindist = 1e10; // big number
-    QPointF nearPoint = path->pointAt(0);
-    qreal nearPc = 0;
-    for (qreal i=1; i < 1000; i++) {
-        QPointF pt = path->pointAt(i/1000.0);
-        QPointF diff = pt - point;
-        qreal dist = diff.x()*diff.x() + diff.y()*diff.y();
-        if (dist < mindist) {
-            nearPoint = pt;
-            nearPc = i;
-            mindist = dist;
-        }
-    }
-
-    if (nearPercent)
-        *nearPercent = nearPc / 1000.0;
-
-    return nearPoint;
-}
-
-void QSGPathView::mousePressEvent(QMouseEvent *event)
-{
-    Q_D(QSGPathView);
-    if (d->interactive) {
-        d->handleMousePressEvent(event);
-        event->accept();
-    } else {
-        QSGItem::mousePressEvent(event);
-    }
-}
-
-void QSGPathViewPrivate::handleMousePressEvent(QMouseEvent *event)
-{
-    Q_Q(QSGPathView);
-    if (!interactive || !items.count())
-        return;
-    QPointF scenePoint = q->mapToScene(event->localPos());
-    int idx = 0;
-    for (; idx < items.count(); ++idx) {
-        QRectF rect = items.at(idx)->boundingRect();
-        rect = items.at(idx)->mapRectToScene(rect);
-        if (rect.contains(scenePoint))
-            break;
-    }
-    if (idx == items.count() && dragMargin == 0.)  // didn't click on an item
-        return;
-
-    startPoint = pointNear(event->localPos(), &startPc);
-    if (idx == items.count()) {
-        qreal distance = qAbs(event->localPos().x() - startPoint.x()) + qAbs(event->localPos().y() - startPoint.y());
-        if (distance > dragMargin)
-            return;
-    }
-
-    if (tl.isActive() && flicking)
-        stealMouse = true; // If we've been flicked then steal the click.
-    else
-        stealMouse = false;
-
-    lastElapsed = 0;
-    lastDist = 0;
-    QSGItemPrivate::start(lastPosTime);
-    tl.clear();
-}
-
-void QSGPathView::mouseMoveEvent(QMouseEvent *event)
-{
-    Q_D(QSGPathView);
-    if (d->interactive) {
-        d->handleMouseMoveEvent(event);
-        if (d->stealMouse)
-            setKeepMouseGrab(true);
-        event->accept();
-    } else {
-        QSGItem::mouseMoveEvent(event);
-    }
-}
-
-void QSGPathViewPrivate::handleMouseMoveEvent(QMouseEvent *event)
-{
-    Q_Q(QSGPathView);
-    if (!interactive || !lastPosTime.isValid())
-        return;
-
-    qreal newPc;
-    QPointF pathPoint = pointNear(event->localPos(), &newPc);
-    if (!stealMouse) {
-        QPointF delta = pathPoint - startPoint;
-        if (qAbs(delta.x()) > qApp->styleHints()->startDragDistance() || qAbs(delta.y()) > qApp->styleHints()->startDragDistance()) {
-            stealMouse = true;
-            startPc = newPc;
-        }
-    }
-
-    if (stealMouse) {
-        moveReason = QSGPathViewPrivate::Mouse;
-        qreal diff = (newPc - startPc)*modelCount*mappedRange;
-        if (diff) {
-            q->setOffset(offset + diff);
-
-            if (diff > modelCount/2)
-                diff -= modelCount;
-            else if (diff < -modelCount/2)
-                diff += modelCount;
-
-            lastElapsed = QSGItemPrivate::restart(lastPosTime);
-            lastDist = diff;
-            startPc = newPc;
-        }
-        if (!moving) {
-            moving = true;
-            emit q->movingChanged();
-            emit q->movementStarted();
-        }
-    }
-}
-
-void QSGPathView::mouseReleaseEvent(QMouseEvent *event)
-{
-    Q_D(QSGPathView);
-    if (d->interactive) {
-        d->handleMouseReleaseEvent(event);
-        event->accept();
-        ungrabMouse();
-    } else {
-        QSGItem::mouseReleaseEvent(event);
-    }
-}
-
-void QSGPathViewPrivate::handleMouseReleaseEvent(QMouseEvent *)
-{
-    Q_Q(QSGPathView);
-    stealMouse = false;
-    q->setKeepMouseGrab(false);
-    if (!interactive || !lastPosTime.isValid())
-        return;
-
-    qreal elapsed = qreal(lastElapsed + QSGItemPrivate::elapsed(lastPosTime)) / 1000.;
-    qreal velocity = elapsed > 0. ? lastDist / elapsed : 0;
-    if (model && modelCount && qAbs(velocity) > 1.) {
-        qreal count = pathItems == -1 ? modelCount : pathItems;
-        if (qAbs(velocity) > count * 2) // limit velocity
-            velocity = (velocity > 0 ? count : -count) * 2;
-        // Calculate the distance to be travelled
-        qreal v2 = velocity*velocity;
-        qreal accel = deceleration/10;
-        // + 0.25 to encourage moving at least one item in the flick direction
-        qreal dist = qMin(qreal(modelCount-1), qreal(v2 / (accel * 2.0) + 0.25));
-        if (haveHighlightRange && highlightRangeMode == QSGPathView::StrictlyEnforceRange) {
-            // round to nearest item.
-            if (velocity > 0.)
-                dist = qRound(dist + offset) - offset;
-            else
-                dist = qRound(dist - offset) + offset;
-            // Calculate accel required to stop on item boundary
-            if (dist <= 0.) {
-                dist = 0.;
-                accel = 0.;
-            } else {
-                accel = v2 / (2.0f * qAbs(dist));
-            }
-        }
-        offsetAdj = 0.0;
-        moveOffset.setValue(offset);
-        tl.accel(moveOffset, velocity, accel, dist);
-        tl.callback(QDeclarativeTimeLineCallback(&moveOffset, fixOffsetCallback, this));
-        if (!flicking) {
-            flicking = true;
-            emit q->flickingChanged();
-            emit q->flickStarted();
-        }
-    } else {
-        fixOffset();
-    }
-
-    lastPosTime.invalidate();
-    if (!tl.isActive())
-        q->movementEnding();
-}
-
-bool QSGPathView::sendMouseEvent(QMouseEvent *event)
-{
-    Q_D(QSGPathView);
-    QRectF myRect = mapRectToScene(QRectF(0, 0, width(), height()));
-    QSGCanvas *c = canvas();
-    QSGItem *grabber = c ? c->mouseGrabberItem() : 0;
-    bool stealThisEvent = d->stealMouse;
-    if ((stealThisEvent || myRect.contains(event->windowPos())) && (!grabber || !grabber->keepMouseGrab())) {
-        QMouseEvent mouseEvent(event->type(), mapFromScene(event->windowPos()), event->windowPos(), event->screenPos(),
-                               event->button(), event->buttons(), event->modifiers());
-        mouseEvent.setAccepted(false);
-
-        switch (mouseEvent.type()) {
-        case QEvent::MouseMove:
-            d->handleMouseMoveEvent(&mouseEvent);
-            break;
-        case QEvent::MouseButtonPress:
-            d->handleMousePressEvent(&mouseEvent);
-            stealThisEvent = d->stealMouse;   // Update stealThisEvent in case changed by function call above
-            break;
-        case QEvent::MouseButtonRelease:
-            d->handleMouseReleaseEvent(&mouseEvent);
-            break;
-        default:
-            break;
-        }
-        grabber = c->mouseGrabberItem();
-        if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this)
-            grabMouse();
-
-        return d->stealMouse;
-    } else if (d->lastPosTime.isValid()) {
-        d->lastPosTime.invalidate();
-        d->fixOffset();
-    }
-    if (event->type() == QEvent::MouseButtonRelease)
-        d->stealMouse = false;
-    return false;
-}
-
-bool QSGPathView::childMouseEventFilter(QSGItem *i, QEvent *e)
-{
-    Q_D(QSGPathView);
-    if (!isVisible() || !d->interactive)
-        return QSGItem::childMouseEventFilter(i, e);
-
-    switch (e->type()) {
-    case QEvent::MouseButtonPress:
-    case QEvent::MouseMove:
-    case QEvent::MouseButtonRelease:
-        return sendMouseEvent(static_cast<QMouseEvent *>(e));
-    default:
-        break;
-    }
-
-    return QSGItem::childMouseEventFilter(i, e);
-}
-
-void QSGPathView::mouseUngrabEvent()
-{
-    Q_D(QSGPathView);
-    if (d->stealMouse) {
-        // if our mouse grab has been removed (probably by a Flickable),
-        // fix our state
-        d->stealMouse = false;
-        setKeepMouseGrab(false);
-        d->lastPosTime.invalidate();
-    }
-}
-
-void QSGPathView::updatePolish()
-{
-    QSGItem::updatePolish();
-    refill();
-}
-
-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
-    // don't do it again.
-    if (d->items.count() == 0 && d->model) {
-        d->modelCount = d->model->count();
-        d->regenerate();
-    }
-    d->updateHighlight();
-
-    if (d->modelCount)
-        emit countChanged();
-}
-
-void QSGPathView::refill()
-{
-    Q_D(QSGPathView);
-    if (!d->isValid() || !isComponentComplete())
-        return;
-
-    d->layoutScheduled = false;
-    bool currentVisible = false;
-
-    // first move existing items and remove items off path
-    int idx = d->firstIndex;
-    QList<QSGItem*>::iterator it = d->items.begin();
-    while (it != d->items.end()) {
-        qreal pos = d->positionOfIndex(idx);
-        QSGItem *item = *it;
-        if (pos >= 0.0) {
-            d->updateItem(item, pos);
-            if (idx == d->currentIndex) {
-                currentVisible = true;
-                d->currentItemOffset = pos;
-            }
-            ++it;
-        } else {
-            // qDebug() << "release";
-            d->updateItem(item, 1.0);
-            d->releaseItem(item);
-            if (it == d->items.begin()) {
-                if (++d->firstIndex >= d->modelCount)
-                    d->firstIndex = 0;
-            }
-            it = d->items.erase(it);
-        }
-        ++idx;
-        if (idx >= d->modelCount)
-            idx = 0;
-    }
-    if (!d->items.count())
-        d->firstIndex = -1;
-
-    if (d->modelCount) {
-        // add items to beginning and end
-        int count = d->pathItems == -1 ? d->modelCount : qMin(d->pathItems, d->modelCount);
-        if (d->items.count() < count) {
-            int idx = qRound(d->modelCount - d->offset) % d->modelCount;
-            qreal startPos = 0.0;
-            if (d->haveHighlightRange && d->highlightRangeMode != QSGPathView::NoHighlightRange)
-                startPos = d->highlightRangeStart;
-            if (d->firstIndex >= 0) {
-                startPos = d->positionOfIndex(d->firstIndex);
-                idx = (d->firstIndex + d->items.count()) % d->modelCount;
-            }
-            qreal pos = d->positionOfIndex(idx);
-            while ((pos > startPos || !d->items.count()) && d->items.count() < count) {
-                // qDebug() << "append" << idx;
-                QSGItem *item = d->getItem(idx);
-                if (d->model->completePending())
-                    item->setZ(idx+1);
-                if (d->currentIndex == idx) {
-                    currentVisible = true;
-                    d->currentItemOffset = pos;
-                }
-                if (d->items.count() == 0)
-                    d->firstIndex = idx;
-                d->items.append(item);
-                d->updateItem(item, pos);
-                if (d->model->completePending())
-                    d->model->completeItem();
-                ++idx;
-                if (idx >= d->modelCount)
-                    idx = 0;
-                pos = d->positionOfIndex(idx);
-            }
-
-            idx = d->firstIndex - 1;
-            if (idx < 0)
-                idx = d->modelCount - 1;
-            pos = d->positionOfIndex(idx);
-            while ((pos >= 0.0 && pos < startPos) && d->items.count() < count) {
-                // qDebug() << "prepend" << idx;
-                QSGItem *item = d->getItem(idx);
-                if (d->model->completePending())
-                    item->setZ(idx+1);
-                if (d->currentIndex == idx) {
-                    currentVisible = true;
-                    d->currentItemOffset = pos;
-                }
-                d->items.prepend(item);
-                d->updateItem(item, pos);
-                if (d->model->completePending())
-                    d->model->completeItem();
-                d->firstIndex = idx;
-                idx = d->firstIndex - 1;
-                if (idx < 0)
-                    idx = d->modelCount - 1;
-                pos = d->positionOfIndex(idx);
-            }
-        }
-    }
-
-    if (!currentVisible) {
-        d->currentItemOffset = 1.0;
-        if (d->currentItem) {
-            if (QSGPathViewAttached *att = d->attached(d->currentItem))
-                att->setOnPath(false);
-        } else if (d->currentIndex >= 0 && d->currentIndex < d->modelCount) {
-            d->currentItem = d->getItem(d->currentIndex, false);
-            d->updateItem(d->currentItem, d->currentIndex < d->firstIndex ? 0.0 : 1.0);
-            if (QSGPathViewAttached *att = d->attached(d->currentItem))
-                att->setIsCurrentItem(true);
-            if (d->model->completePending())
-                d->model->completeItem();
-        }
-    } else if (!d->currentItem) {
-        d->currentItem = d->model->item(d->currentIndex, true);
-        d->currentItem->setFocus(true);
-        if (QSGPathViewAttached *att = d->attached(d->currentItem))
-            att->setIsCurrentItem(true);
-    }
-
-    if (d->highlightItem && d->haveHighlightRange && d->highlightRangeMode == QSGPathView::StrictlyEnforceRange) {
-        d->updateItem(d->highlightItem, d->highlightRangeStart);
-        if (QSGPathViewAttached *att = d->attached(d->highlightItem))
-            att->setOnPath(true);
-    } else if (d->highlightItem && d->moveReason != QSGPathViewPrivate::SetIndex) {
-        d->updateItem(d->highlightItem, d->currentItemOffset);
-        if (QSGPathViewAttached *att = d->attached(d->highlightItem))
-            att->setOnPath(currentVisible);
-    }
-    while (d->itemCache.count())
-        d->releaseItem(d->itemCache.takeLast());
-}
-
-void QSGPathView::modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset)
-{
-    Q_D(QSGPathView);
-    if (!d->model || !d->model->isValid() || !d->path || !isComponentComplete())
-        return;
-
-    if (reset) {
-        d->modelCount = d->model->count();
-        d->regenerate();
-        emit countChanged();
-        return;
-    }
-
-    if (changeSet.removes().isEmpty() && changeSet.inserts().isEmpty())
-        return;
-
-    const int modelCount = d->modelCount;
-    int moveId = -1;
-    int moveOffset;
-    bool currentChanged = false;
-    bool changedOffset = false;
-    bool removed = false;
-    bool inserted = false;
-    foreach (const QDeclarativeChangeSet::Remove &r, changeSet.removes()) {
-        removed = true;
-        if (moveId == -1 && d->currentIndex >= r.index + r.count) {
-            d->currentIndex -= r.count;
-            currentChanged = true;
-        } else if (moveId == -1 && d->currentIndex >= r.index && d->currentIndex < r.index + r.count) {
-            // current item has been removed.
-            d->currentIndex = qMin(r.index, d->modelCount - r.count - 1);
-            if (r.isMove()) {
-                moveId = r.moveId;
-                moveOffset = d->currentIndex - r.index;
-            } else if (d->currentItem) {
-                if (QSGPathViewAttached *att = d->attached(d->currentItem))
-                    att->setIsCurrentItem(true);
-                d->releaseItem(d->currentItem);
-                d->currentItem = 0;
-            }
-            currentChanged = true;
-        }
-
-        if (r.index > d->currentIndex) {
-            if (d->offset >= r.count) {
-                changedOffset = true;
-                d->offset -= r.count;
-                d->offsetAdj -= r.count;
-            }
-        }
-        d->modelCount -= r.count;
-    }
-    foreach (const QDeclarativeChangeSet::Insert &i, changeSet.inserts()) {
-        inserted = true;
-        if (d->modelCount) {
-            if (moveId == -1 && i.index <= d->currentIndex) {
-                d->currentIndex += i.count;
-            } else if (d->offset != 0) {
-                if (moveId != -1 && moveId == i.moveId)
-                    d->currentIndex = i.index + moveOffset;
-                d->offset += i.count;
-                d->offsetAdj += i.count;
-            }
-        }
-        d->modelCount += i.count;
-    }
-
-    d->itemCache += d->items;
-    d->items.clear();
-
-    if (!d->modelCount) {
-        while (d->itemCache.count())
-            d->releaseItem(d->itemCache.takeLast());
-        d->offset = 0;
-        changedOffset = true;
-        d->tl.reset(d->moveOffset);
-    } else if (removed) {
-        d->regenerate();
-        d->updateCurrent();
-        if (!d->flicking && !d->moving && d->haveHighlightRange && d->highlightRangeMode == QSGPathView::StrictlyEnforceRange)
-            d->snapToCurrent();
-    } else if (inserted) {
-        d->firstIndex = -1;
-        d->updateMappedRange();
-        d->scheduleLayout();
-    }
-    if (changedOffset)
-        emit offsetChanged();
-    if (currentChanged)
-        emit currentIndexChanged();
-    if (d->modelCount != modelCount)
-        emit countChanged();
-}
-
-void QSGPathView::createdItem(int index, QSGItem *item)
-{
-    Q_D(QSGPathView);
-    if (d->requestedIndex != index) {
-        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())
-                d->attType->createProperty(attr.toUtf8());
-        }
-        qPathViewAttachedType = d->attType;
-        QSGPathViewAttached *att = static_cast<QSGPathViewAttached *>(qmlAttachedPropertiesObject<QSGPathView>(item));
-        qPathViewAttachedType = 0;
-        if (att) {
-            att->m_view = this;
-            att->setOnPath(false);
-        }
-        item->setParentItem(this);
-        d->updateItem(item, index < d->firstIndex ? 0.0 : 1.0);
-    }
-}
-
-void QSGPathView::destroyingItem(QSGItem *item)
-{
-    Q_UNUSED(item);
-}
-
-void QSGPathView::ticked()
-{
-    Q_D(QSGPathView);
-    d->updateCurrent();
-}
-
-void QSGPathView::movementEnding()
-{
-    Q_D(QSGPathView);
-    if (d->flicking) {
-        d->flicking = false;
-        emit flickingChanged();
-        emit flickEnded();
-    }
-    if (d->moving && !d->stealMouse) {
-        d->moving = false;
-        emit movingChanged();
-        emit movementEnded();
-    }
-}
-
-// find the item closest to the snap position
-int QSGPathViewPrivate::calcCurrentIndex()
-{
-    int current = -1;
-    if (modelCount && model && items.count()) {
-        offset = qmlMod(offset, modelCount);
-        if (offset < 0)
-            offset += modelCount;
-        current = qRound(qAbs(qmlMod(modelCount - offset, modelCount)));
-        current = current % modelCount;
-    }
-
-    return current;
-}
-
-void QSGPathViewPrivate::updateCurrent()
-{
-    Q_Q(QSGPathView);
-    if (moveReason != Mouse)
-        return;
-    if (!modelCount || !haveHighlightRange || highlightRangeMode != QSGPathView::StrictlyEnforceRange)
-        return;
-
-    int idx = calcCurrentIndex();
-    if (model && idx != currentIndex) {
-        if (currentItem) {
-            if (QSGPathViewAttached *att = attached(currentItem))
-                att->setIsCurrentItem(false);
-            releaseItem(currentItem);
-        }
-        currentIndex = idx;
-        currentItem = 0;
-        int itemIndex = (idx - firstIndex + modelCount) % modelCount;
-        if (itemIndex < items.count()) {
-            currentItem = model->item(currentIndex, true);
-            currentItem->setFocus(true);
-            if (QSGPathViewAttached *att = attached(currentItem))
-                att->setIsCurrentItem(true);
-        } else if (currentIndex >= 0 && currentIndex < modelCount) {
-            currentItem = getItem(currentIndex, false);
-            updateItem(currentItem, currentIndex < firstIndex ? 0.0 : 1.0);
-            if (QSGPathViewAttached *att = attached(currentItem))
-                att->setIsCurrentItem(true);
-            if (model->completePending())
-                model->completeItem();
-        }
-        emit q->currentIndexChanged();
-    }
-}
-
-void QSGPathViewPrivate::fixOffsetCallback(void *d)
-{
-    ((QSGPathViewPrivate *)d)->fixOffset();
-}
-
-void QSGPathViewPrivate::fixOffset()
-{
-    Q_Q(QSGPathView);
-    if (model && items.count()) {
-        if (haveHighlightRange && highlightRangeMode == QSGPathView::StrictlyEnforceRange) {
-            int curr = calcCurrentIndex();
-            if (curr != currentIndex)
-                q->setCurrentIndex(curr);
-            else
-                snapToCurrent();
-        }
-    }
-}
-
-void QSGPathViewPrivate::snapToCurrent()
-{
-    if (!model || modelCount <= 0)
-        return;
-
-    qreal targetOffset = qmlMod(modelCount - currentIndex, modelCount);
-
-    moveReason = Other;
-    offsetAdj = 0.0;
-    tl.reset(moveOffset);
-    moveOffset.setValue(offset);
-
-    const int duration = highlightMoveDuration;
-
-    if (moveDirection == Positive || (moveDirection == Shortest && targetOffset - offset > modelCount/2)) {
-        qreal distance = modelCount - targetOffset + offset;
-        if (targetOffset > moveOffset) {
-            tl.move(moveOffset, 0.0, QEasingCurve(QEasingCurve::InQuad), int(duration * offset / distance));
-            tl.set(moveOffset, modelCount);
-            tl.move(moveOffset, targetOffset, QEasingCurve(offset == 0.0 ? QEasingCurve::InOutQuad : QEasingCurve::OutQuad), int(duration * (modelCount-targetOffset) / distance));
-        } else {
-            tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InOutQuad), duration);
-        }
-    } else if (moveDirection == Negative || targetOffset - offset <= -modelCount/2) {
-        qreal distance = modelCount - offset + targetOffset;
-        if (targetOffset < moveOffset) {
-            tl.move(moveOffset, modelCount, QEasingCurve(targetOffset == 0 ? QEasingCurve::InOutQuad : QEasingCurve::InQuad), int(duration * (modelCount-offset) / distance));
-            tl.set(moveOffset, 0.0);
-            tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::OutQuad), int(duration * targetOffset / distance));
-        } else {
-            tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InOutQuad), duration);
-        }
-    } else {
-        tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InOutQuad), duration);
-    }
-    moveDirection = Shortest;
-}
-
-QSGPathViewAttached *QSGPathView::qmlAttachedProperties(QObject *obj)
-{
-    return new QSGPathViewAttached(obj);
-}
-
-QT_END_NAMESPACE
-
diff --git a/src/declarative/items/qsgpathview_p.h b/src/declarative/items/qsgpathview_p.h
deleted file mode 100644 (file)
index b70745e..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
-/****************************************************************************
-**
-** 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 QSGPATHVIEW_P_H
-#define QSGPATHVIEW_P_H
-
-#include "qsgitem.h"
-
-#include <private/qdeclarativepath_p.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QDeclarativeChangeSet;
-
-class QSGPathViewPrivate;
-class QSGPathViewAttached;
-class Q_AUTOTEST_EXPORT QSGPathView : public QSGItem
-{
-    Q_OBJECT
-
-    Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged)
-    Q_PROPERTY(QDeclarativePath *path READ path WRITE setPath NOTIFY pathChanged)
-    Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
-    Q_PROPERTY(QSGItem *currentItem READ currentItem NOTIFY currentIndexChanged)
-    Q_PROPERTY(qreal offset READ offset WRITE setOffset NOTIFY offsetChanged)
-
-    Q_PROPERTY(QDeclarativeComponent *highlight READ highlight WRITE setHighlight NOTIFY highlightChanged)
-    Q_PROPERTY(QSGItem *highlightItem READ highlightItem NOTIFY highlightItemChanged)
-
-    Q_PROPERTY(qreal preferredHighlightBegin READ preferredHighlightBegin WRITE setPreferredHighlightBegin NOTIFY preferredHighlightBeginChanged)
-    Q_PROPERTY(qreal preferredHighlightEnd READ preferredHighlightEnd WRITE setPreferredHighlightEnd NOTIFY preferredHighlightEndChanged)
-    Q_PROPERTY(HighlightRangeMode highlightRangeMode READ highlightRangeMode WRITE setHighlightRangeMode NOTIFY highlightRangeModeChanged)
-    Q_PROPERTY(int highlightMoveDuration READ highlightMoveDuration WRITE setHighlightMoveDuration NOTIFY highlightMoveDurationChanged)
-
-    Q_PROPERTY(qreal dragMargin READ dragMargin WRITE setDragMargin NOTIFY dragMarginChanged)
-    Q_PROPERTY(qreal flickDeceleration READ flickDeceleration WRITE setFlickDeceleration NOTIFY flickDecelerationChanged)
-    Q_PROPERTY(bool interactive READ isInteractive WRITE setInteractive NOTIFY interactiveChanged)
-
-    Q_PROPERTY(bool moving READ isMoving NOTIFY movingChanged)
-    Q_PROPERTY(bool flicking READ isFlicking NOTIFY flickingChanged)
-
-    Q_PROPERTY(int count READ count NOTIFY countChanged)
-    Q_PROPERTY(QDeclarativeComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
-    Q_PROPERTY(int pathItemCount READ pathItemCount WRITE setPathItemCount NOTIFY pathItemCountChanged)
-
-    Q_ENUMS(HighlightRangeMode)
-
-public:
-    QSGPathView(QSGItem *parent=0);
-    virtual ~QSGPathView();
-
-    QVariant model() const;
-    void setModel(const QVariant &);
-
-    QDeclarativePath *path() const;
-    void setPath(QDeclarativePath *);
-
-    int currentIndex() const;
-    void setCurrentIndex(int idx);
-
-    QSGItem *currentItem() const;
-
-    qreal offset() const;
-    void setOffset(qreal offset);
-
-    QDeclarativeComponent *highlight() const;
-    void setHighlight(QDeclarativeComponent *highlight);
-    QSGItem *highlightItem();
-
-    enum HighlightRangeMode { NoHighlightRange, ApplyRange, StrictlyEnforceRange };
-    HighlightRangeMode highlightRangeMode() const;
-    void setHighlightRangeMode(HighlightRangeMode mode);
-
-    qreal preferredHighlightBegin() const;
-    void setPreferredHighlightBegin(qreal);
-
-    qreal preferredHighlightEnd() const;
-    void setPreferredHighlightEnd(qreal);
-
-    int highlightMoveDuration() const;
-    void setHighlightMoveDuration(int);
-
-    qreal dragMargin() const;
-    void setDragMargin(qreal margin);
-
-    qreal flickDeceleration() const;
-    void setFlickDeceleration(qreal dec);
-
-    bool isInteractive() const;
-    void setInteractive(bool);
-
-    bool isMoving() const;
-    bool isFlicking() const;
-
-    int count() const;
-
-    QDeclarativeComponent *delegate() const;
-    void setDelegate(QDeclarativeComponent *);
-
-    int pathItemCount() const;
-    void setPathItemCount(int);
-
-    static QSGPathViewAttached *qmlAttachedProperties(QObject *);
-
-public Q_SLOTS:
-    void incrementCurrentIndex();
-    void decrementCurrentIndex();
-
-Q_SIGNALS:
-    void currentIndexChanged();
-    void offsetChanged();
-    void modelChanged();
-    void countChanged();
-    void pathChanged();
-    void preferredHighlightBeginChanged();
-    void preferredHighlightEndChanged();
-    void highlightRangeModeChanged();
-    void dragMarginChanged();
-    void snapPositionChanged();
-    void delegateChanged();
-    void pathItemCountChanged();
-    void flickDecelerationChanged();
-    void interactiveChanged();
-    void movingChanged();
-    void flickingChanged();
-    void highlightChanged();
-    void highlightItemChanged();
-    void highlightMoveDurationChanged();
-    void movementStarted();
-    void movementEnded();
-    void flickStarted();
-    void flickEnded();
-
-protected:
-    virtual void updatePolish();
-    void mousePressEvent(QMouseEvent *event);
-    void mouseMoveEvent(QMouseEvent *event);
-    void mouseReleaseEvent(QMouseEvent *);
-    bool sendMouseEvent(QMouseEvent *event);
-    bool childMouseEventFilter(QSGItem *, QEvent *);
-    void mouseUngrabEvent();
-    void componentComplete();
-
-private Q_SLOTS:
-    void refill();
-    void ticked();
-    void movementEnding();
-    void modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset);
-    void createdItem(int index, QSGItem *item);
-    void destroyingItem(QSGItem *item);
-    void pathUpdated();
-
-private:
-    friend class QSGPathViewAttached;
-    Q_DISABLE_COPY(QSGPathView)
-    Q_DECLARE_PRIVATE(QSGPathView)
-};
-
-class QDeclarativeOpenMetaObject;
-class QSGPathViewAttached : public QObject
-{
-    Q_OBJECT
-
-    Q_PROPERTY(QSGPathView *view READ view CONSTANT)
-    Q_PROPERTY(bool isCurrentItem READ isCurrentItem NOTIFY currentItemChanged)
-    Q_PROPERTY(bool onPath READ isOnPath NOTIFY pathChanged)
-
-public:
-    QSGPathViewAttached(QObject *parent);
-    ~QSGPathViewAttached();
-
-    QSGPathView *view() { return m_view; }
-
-    bool isCurrentItem() const { return m_isCurrent; }
-    void setIsCurrentItem(bool c) {
-        if (m_isCurrent != c) {
-            m_isCurrent = c;
-            emit currentItemChanged();
-        }
-    }
-
-    QVariant value(const QByteArray &name) const;
-    void setValue(const QByteArray &name, const QVariant &val);
-
-    bool isOnPath() const { return m_onPath; }
-    void setOnPath(bool on) {
-        if (on != m_onPath) {
-            m_onPath = on;
-            emit pathChanged();
-        }
-    }
-    qreal m_percent;
-
-Q_SIGNALS:
-    void currentItemChanged();
-    void pathChanged();
-
-private:
-    friend class QSGPathViewPrivate;
-    friend class QSGPathView;
-    QSGPathView *m_view;
-    QDeclarativeOpenMetaObject *m_metaobject;
-    bool m_onPath : 1;
-    bool m_isCurrent : 1;
-};
-
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGPathView)
-QML_DECLARE_TYPEINFO(QSGPathView, QML_HAS_ATTACHED_PROPERTIES)
-QT_END_HEADER
-
-#endif // QSGPATHVIEW_P_H
diff --git a/src/declarative/items/qsgpathview_p_p.h b/src/declarative/items/qsgpathview_p_p.h
deleted file mode 100644 (file)
index 10549d9..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
-/****************************************************************************
-**
-** 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 QDECLARATIVEPATHVIEW_P_H
-#define QDECLARATIVEPATHVIEW_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 "qsgpathview_p.h"
-#include "qsgitem_p.h"
-#include "qsgvisualdatamodel_p.h"
-
-#include <QtDeclarative/qdeclarative.h>
-#include <QtCore/qdatetime.h>
-#include <QtCore/qcoreapplication.h>
-
-#include <private/qdeclarativeanimation_p_p.h>
-#include <private/qdeclarativeguard_p.h>
-#include <private/qdeclarativetimeline_p_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QDeclarativeOpenMetaObjectType;
-class QSGPathViewAttached;
-class QSGPathViewPrivate : public QSGItemPrivate, public QSGItemChangeListener
-{
-    Q_DECLARE_PUBLIC(QSGPathView)
-
-public:
-    QSGPathViewPrivate()
-      : path(0), currentIndex(0), currentItemOffset(0.0), startPc(0), lastDist(0)
-        , lastElapsed(0), offset(0.0), offsetAdj(0.0), mappedRange(1.0)
-        , stealMouse(false), ownModel(false), interactive(true), haveHighlightRange(true)
-        , autoHighlight(true), highlightUp(false), layoutScheduled(false)
-        , moving(false), flicking(false)
-        , dragMargin(0), deceleration(100)
-        , moveOffset(this, &QSGPathViewPrivate::setAdjustedOffset)
-        , firstIndex(-1), pathItems(-1), requestedIndex(-1)
-        , moveReason(Other), moveDirection(Shortest), attType(0), highlightComponent(0), highlightItem(0)
-        , moveHighlight(this, &QSGPathViewPrivate::setHighlightPosition)
-        , highlightPosition(0)
-        , highlightRangeStart(0), highlightRangeEnd(0)
-        , highlightRangeMode(QSGPathView::StrictlyEnforceRange)
-        , highlightMoveDuration(300), modelCount(0)
-    {
-    }
-
-    void init();
-
-    void itemGeometryChanged(QSGItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) {
-        if ((newGeometry.size() != oldGeometry.size())
-            && (!highlightItem || item != highlightItem)) {
-            if (QSGPathViewAttached *att = attached(item))
-                att->m_percent = -1;
-            scheduleLayout();
-        }
-    }
-
-    void scheduleLayout() {
-        Q_Q(QSGPathView);
-        if (!layoutScheduled) {
-            layoutScheduled = true;
-            q->polish();
-        }
-    }
-
-    QSGItem *getItem(int modelIndex, bool onPath = true);
-    void releaseItem(QSGItem *item);
-    QSGPathViewAttached *attached(QSGItem *item);
-    void clear();
-    void updateMappedRange();
-    qreal positionOfIndex(qreal index) const;
-    void createHighlight();
-    void updateHighlight();
-    void setHighlightPosition(qreal pos);
-    bool isValid() const {
-        return model && model->count() > 0 && model->isValid() && path;
-    }
-
-    void handleMousePressEvent(QMouseEvent *event);
-    void handleMouseMoveEvent(QMouseEvent *event);
-    void handleMouseReleaseEvent(QMouseEvent *);
-
-    int calcCurrentIndex();
-    void updateCurrent();
-    static void fixOffsetCallback(void*);
-    void fixOffset();
-    void setOffset(qreal offset);
-    void setAdjustedOffset(qreal offset);
-    void regenerate();
-    void updateItem(QSGItem *, qreal);
-    void snapToCurrent();
-    QPointF pointNear(const QPointF &point, qreal *nearPercent=0) const;
-
-    QDeclarativePath *path;
-    int currentIndex;
-    QDeclarativeGuard<QSGItem> currentItem;
-    qreal currentItemOffset;
-    qreal startPc;
-    QPointF startPoint;
-    qreal lastDist;
-    int lastElapsed;
-    qreal offset;
-    qreal offsetAdj;
-    qreal mappedRange;
-    bool stealMouse : 1;
-    bool ownModel : 1;
-    bool interactive : 1;
-    bool haveHighlightRange : 1;
-    bool autoHighlight : 1;
-    bool highlightUp : 1;
-    bool layoutScheduled : 1;
-    bool moving : 1;
-    bool flicking : 1;
-    QElapsedTimer lastPosTime;
-    QPointF lastPos;
-    qreal dragMargin;
-    qreal deceleration;
-    QDeclarativeTimeLine tl;
-    QDeclarativeTimeLineValueProxy<QSGPathViewPrivate> moveOffset;
-    int firstIndex;
-    int pathItems;
-    int requestedIndex;
-    QList<QSGItem *> items;
-    QList<QSGItem *> itemCache;
-    QDeclarativeGuard<QSGVisualModel> model;
-    QVariant modelVariant;
-    enum MovementReason { Other, SetIndex, Mouse };
-    MovementReason moveReason;
-    enum MovementDirection { Shortest, Negative, Positive };
-    MovementDirection moveDirection;
-    QDeclarativeOpenMetaObjectType *attType;
-    QDeclarativeComponent *highlightComponent;
-    QSGItem *highlightItem;
-    QDeclarativeTimeLineValueProxy<QSGPathViewPrivate> moveHighlight;
-    qreal highlightPosition;
-    qreal highlightRangeStart;
-    qreal highlightRangeEnd;
-    QSGPathView::HighlightRangeMode highlightRangeMode;
-    int highlightMoveDuration;
-    int modelCount;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/declarative/items/qsgpincharea.cpp b/src/declarative/items/qsgpincharea.cpp
deleted file mode 100644 (file)
index 2dbe683..0000000
+++ /dev/null
@@ -1,600 +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 QtSG 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 "qsgpincharea_p_p.h"
-#include "qsgcanvas.h"
-
-#include <QtGui/qevent.h>
-#include <QtGui/qguiapplication.h>
-#include <QtGui/qstylehints.h>
-
-#include <float.h>
-#include <math.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
-    \qmlclass PinchEvent QSGPinchEvent
-    \inqmlmodule QtQuick 2
-    \ingroup qml-event-elements
-    \brief The PinchEvent object provides information about a pinch event.
-
-    \bold {The PinchEvent element was added in QtQuick 1.1}
-
-    The \c center, \c startCenter, \c previousCenter properties provide the center position between the two touch points.
-
-    The \c scale and \c previousScale properties provide the scale factor.
-
-    The \c angle, \c previousAngle and \c rotation properties provide the angle between the two points and the amount of rotation.
-
-    The \c point1, \c point2, \c startPoint1, \c startPoint2 properties provide the positions of the touch points.
-
-    The \c accepted property may be set to false in the \c onPinchStarted handler if the gesture should not
-    be handled.
-
-    \sa PinchArea
-*/
-
-/*!
-    \qmlproperty QPointF QtQuick2::PinchEvent::center
-    \qmlproperty QPointF QtQuick2::PinchEvent::startCenter
-    \qmlproperty QPointF QtQuick2::PinchEvent::previousCenter
-
-    These properties hold the position of the center point between the two touch points.
-
-    \list
-    \o \c center is the current center point
-    \o \c previousCenter is the center point of the previous event.
-    \o \c startCenter is the center point when the gesture began
-    \endlist
-*/
-
-/*!
-    \qmlproperty real QtQuick2::PinchEvent::scale
-    \qmlproperty real QtQuick2::PinchEvent::previousScale
-
-    These properties hold the scale factor determined by the change in distance between the two touch points.
-
-    \list
-    \o \c scale is the current scale factor.
-    \o \c previousScale is the scale factor of the previous event.
-    \endlist
-
-    When a pinch gesture is started, the scale is 1.0.
-*/
-
-/*!
-    \qmlproperty real QtQuick2::PinchEvent::angle
-    \qmlproperty real QtQuick2::PinchEvent::previousAngle
-    \qmlproperty real QtQuick2::PinchEvent::rotation
-
-    These properties hold the angle between the two touch points.
-
-    \list
-    \o \c angle is the current angle between the two points in the range -180 to 180.
-    \o \c previousAngle is the angle of the previous event.
-    \o \c rotation is the total rotation since the pinch gesture started.
-    \endlist
-
-    When a pinch gesture is started, the rotation is 0.0.
-*/
-
-/*!
-    \qmlproperty QPointF QtQuick2::PinchEvent::point1
-    \qmlproperty QPointF QtQuick2::PinchEvent::startPoint1
-    \qmlproperty QPointF QtQuick2::PinchEvent::point2
-    \qmlproperty QPointF QtQuick2::PinchEvent::startPoint2
-
-    These properties provide the actual touch points generating the pinch.
-
-    \list
-    \o \c point1 and \c point2 hold the current positions of the points.
-    \o \c startPoint1 and \c startPoint2 hold the positions of the points when the second point was touched.
-    \endlist
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::PinchEvent::accepted
-
-    Setting this property to false in the \c PinchArea::onPinchStarted handler
-    will result in no further pinch events being generated, and the gesture
-    ignored.
-*/
-
-/*!
-    \qmlproperty int QtQuick2::PinchEvent::pointCount
-
-    Holds the number of points currently touched.  The PinchArea will not react
-    until two touch points have initited a gesture, but will remain active until
-    all touch points have been released.
-*/
-
-QSGPinch::QSGPinch()
-    : m_target(0), m_minScale(1.0), m_maxScale(1.0)
-    , m_minRotation(0.0), m_maxRotation(0.0)
-    , m_axis(NoDrag), m_xmin(-FLT_MAX), m_xmax(FLT_MAX)
-    , m_ymin(-FLT_MAX), m_ymax(FLT_MAX), m_active(false)
-{
-}
-
-QSGPinchAreaPrivate::~QSGPinchAreaPrivate()
-{
-    delete pinch;
-}
-
-/*!
-    \qmlclass PinchArea QSGPinchArea
-    \inqmlmodule QtQuick 2
-    \brief The PinchArea item enables simple pinch gesture handling.
-    \inherits Item
-
-    \bold {The PinchArea element was added in QtQuick 1.1}
-
-    A PinchArea is an invisible item that is typically used in conjunction with
-    a visible item in order to provide pinch gesture handling for that item.
-
-    The \l enabled property is used to enable and disable pinch handling for
-    the proxied item. When disabled, the pinch area becomes transparent to
-    mouse/touch events.
-
-    PinchArea can be used in two ways:
-
-    \list
-    \o setting a \c pinch.target to provide automatic interaction with an element
-    \o using the onPinchStarted, onPinchUpdated and onPinchFinished handlers
-    \endlist
-
-    \sa PinchEvent
-*/
-
-/*!
-    \qmlsignal QtQuick2::PinchArea::onPinchStarted()
-
-    This handler is called when the pinch area detects that a pinch gesture has started.
-
-    The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
-    including the scale, center and angle of the pinch.
-
-    To ignore this gesture set the \c pinch.accepted property to false.  The gesture
-    will be cancelled and no further events will be sent.
-*/
-
-/*!
-    \qmlsignal QtQuick2::PinchArea::onPinchUpdated()
-
-    This handler is called when the pinch area detects that a pinch gesture has changed.
-
-    The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
-    including the scale, center and angle of the pinch.
-*/
-
-/*!
-    \qmlsignal QtQuick2::PinchArea::onPinchFinished()
-
-    This handler is called when the pinch area detects that a pinch gesture has finished.
-
-    The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
-    including the scale, center and angle of the pinch.
-*/
-
-
-/*!
-    \qmlproperty Item QtQuick2::PinchArea::pinch.target
-    \qmlproperty bool QtQuick2::PinchArea::pinch.active
-    \qmlproperty real QtQuick2::PinchArea::pinch.minimumScale
-    \qmlproperty real QtQuick2::PinchArea::pinch.maximumScale
-    \qmlproperty real QtQuick2::PinchArea::pinch.minimumRotation
-    \qmlproperty real QtQuick2::PinchArea::pinch.maximumRotation
-    \qmlproperty enumeration QtQuick2::PinchArea::pinch.dragAxis
-    \qmlproperty real QtQuick2::PinchArea::pinch.minimumX
-    \qmlproperty real QtQuick2::PinchArea::pinch.maximumX
-    \qmlproperty real QtQuick2::PinchArea::pinch.minimumY
-    \qmlproperty real QtQuick2::PinchArea::pinch.maximumY
-
-    \c pinch provides a convenient way to make an item react to pinch gestures.
-
-    \list
-    \i \c pinch.target specifies the id of the item to drag.
-    \i \c pinch.active specifies if the target item is currently being dragged.
-    \i \c pinch.minimumScale and \c pinch.maximumScale limit the range of the Item::scale property.
-    \i \c pinch.minimumRotation and \c pinch.maximumRotation limit the range of the Item::rotation property.
-    \i \c pinch.dragAxis specifies whether dragging in not allowed (\c Pinch.NoDrag), can be done horizontally (\c Pinch.XAxis), vertically (\c Pinch.YAxis), or both (\c Pinch.XandYAxis)
-    \i \c pinch.minimum and \c pinch.maximum limit how far the target can be dragged along the corresponding axes.
-    \endlist
-*/
-
-QSGPinchArea::QSGPinchArea(QSGItem *parent)
-  : QSGItem(*(new QSGPinchAreaPrivate), parent)
-{
-    Q_D(QSGPinchArea);
-    d->init();
-}
-
-QSGPinchArea::~QSGPinchArea()
-{
-}
-/*!
-    \qmlproperty bool QtQuick2::PinchArea::enabled
-    This property holds whether the item accepts pinch gestures.
-
-    This property defaults to true.
-*/
-bool QSGPinchArea::isEnabled() const
-{
-    Q_D(const QSGPinchArea);
-    return d->absorb;
-}
-
-void QSGPinchArea::setEnabled(bool a)
-{
-    Q_D(QSGPinchArea);
-    if (a != d->absorb) {
-        d->absorb = a;
-        emit enabledChanged();
-    }
-}
-
-void QSGPinchArea::touchEvent(QTouchEvent *event)
-{
-    Q_D(QSGPinchArea);
-    if (!d->absorb || !isVisible()) {
-        QSGItem::event(event);
-        return;
-    }
-
-    switch (event->type()) {
-    case QEvent::TouchBegin:
-    case QEvent::TouchUpdate:
-        d->touchPoints.clear();
-        for (int i = 0; i < event->touchPoints().count(); ++i) {
-            if (!(event->touchPoints().at(i).state() & Qt::TouchPointReleased)) {
-                d->touchPoints << event->touchPoints().at(i);
-            }
-        }
-        updatePinch();
-        break;
-    case QEvent::TouchEnd:
-        d->touchPoints.clear();
-        updatePinch();
-        break;
-    default:
-        QSGItem::event(event);
-    }
-}
-
-void QSGPinchArea::updatePinch()
-{
-    Q_D(QSGPinchArea);
-    if (d->touchPoints.count() == 0) {
-        if (d->inPinch) {
-            d->inPinch = false;
-            QPointF pinchCenter = mapFromScene(d->sceneLastCenter);
-            QSGPinchEvent pe(pinchCenter, d->pinchLastScale, d->pinchLastAngle, d->pinchRotation);
-            pe.setStartCenter(d->pinchStartCenter);
-            pe.setPreviousCenter(pinchCenter);
-            pe.setPreviousAngle(d->pinchLastAngle);
-            pe.setPreviousScale(d->pinchLastScale);
-            pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
-            pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
-            pe.setPoint1(mapFromScene(d->lastPoint1));
-            pe.setPoint2(mapFromScene(d->lastPoint2));
-            emit pinchFinished(&pe);
-            d->pinchStartDist = 0;
-            d->pinchActivated = false;
-            if (d->pinch && d->pinch->target())
-                d->pinch->setActive(false);
-        }
-        d->initPinch = false;
-        d->pinchRejected = false;
-        d->stealMouse = false;
-        setKeepMouseGrab(false);
-        QSGCanvas *c = canvas();
-        if (c && c->mouseGrabberItem() == this)
-            ungrabMouse();
-        return;
-    }
-    QTouchEvent::TouchPoint touchPoint1 = d->touchPoints.at(0);
-    QTouchEvent::TouchPoint touchPoint2 = d->touchPoints.at(d->touchPoints. count() >= 2 ? 1 : 0);
-    if (d->touchPoints.count() == 2
-        && (touchPoint1.state() & Qt::TouchPointPressed || touchPoint2.state() & Qt::TouchPointPressed)) {
-        d->id1 = touchPoint1.id();
-        d->sceneStartPoint1 = touchPoint1.scenePos();
-        d->sceneStartPoint2 = touchPoint2.scenePos();
-        d->pinchActivated = true;
-        d->initPinch = true;
-    }
-    if (d->pinchActivated && !d->pinchRejected){
-        const int dragThreshold = qApp->styleHints()->startDragDistance();
-        QPointF p1 = touchPoint1.scenePos();
-        QPointF p2 = touchPoint2.scenePos();
-        qreal dx = p1.x() - p2.x();
-        qreal dy = p1.y() - p2.y();
-        qreal dist = sqrt(dx*dx + dy*dy);
-        QPointF sceneCenter = (p1 + p2)/2;
-        qreal angle = QLineF(p1, p2).angle();
-        if (d->touchPoints.count() == 1) {
-            // If we only have one point then just move the center
-            if (d->id1 == touchPoint1.id())
-                sceneCenter = d->sceneLastCenter + touchPoint1.scenePos() - d->lastPoint1;
-            else
-                sceneCenter = d->sceneLastCenter + touchPoint2.scenePos() - d->lastPoint2;
-            angle = d->pinchLastAngle;
-        }
-        d->id1 = touchPoint1.id();
-        if (angle > 180)
-            angle -= 360;
-        if (!d->inPinch || d->initPinch) {
-            if (d->touchPoints.count() >= 2
-                    && (qAbs(p1.x()-d->sceneStartPoint1.x()) > dragThreshold
-                    || qAbs(p1.y()-d->sceneStartPoint1.y()) > dragThreshold
-                    || qAbs(p2.x()-d->sceneStartPoint2.x()) > dragThreshold
-                    || qAbs(p2.y()-d->sceneStartPoint2.y()) > dragThreshold)) {
-                d->initPinch = false;
-                d->sceneStartCenter = sceneCenter;
-                d->sceneLastCenter = sceneCenter;
-                d->pinchStartCenter = mapFromScene(sceneCenter);
-                d->pinchStartDist = dist;
-                d->pinchStartAngle = angle;
-                d->pinchLastScale = 1.0;
-                d->pinchLastAngle = angle;
-                d->pinchRotation = 0.0;
-                d->lastPoint1 = p1;
-                d->lastPoint2 = p2;
-                QSGPinchEvent pe(d->pinchStartCenter, 1.0, angle, 0.0);
-                pe.setStartCenter(d->pinchStartCenter);
-                pe.setPreviousCenter(d->pinchStartCenter);
-                pe.setPreviousAngle(d->pinchLastAngle);
-                pe.setPreviousScale(d->pinchLastScale);
-                pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
-                pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
-                pe.setPoint1(mapFromScene(d->lastPoint1));
-                pe.setPoint2(mapFromScene(d->lastPoint2));
-                pe.setPointCount(d->touchPoints.count());
-                emit pinchStarted(&pe);
-                if (pe.accepted()) {
-                    d->inPinch = true;
-                    d->stealMouse = true;
-                    QSGCanvas *c = canvas();
-                    if (c && c->mouseGrabberItem() != this)
-                        grabMouse();
-                    setKeepMouseGrab(true);
-                    if (d->pinch && d->pinch->target()) {
-                        d->pinchStartPos = pinch()->target()->pos();
-                        d->pinchStartScale = d->pinch->target()->scale();
-                        d->pinchStartRotation = d->pinch->target()->rotation();
-                        d->pinch->setActive(true);
-                    }
-                } else {
-                    d->pinchRejected = true;
-                }
-            }
-        } else if (d->pinchStartDist > 0) {
-            qreal scale = dist ? dist / d->pinchStartDist : d->pinchLastScale;
-            qreal da = d->pinchLastAngle - angle;
-            if (da > 180)
-                da -= 360;
-            else if (da < -180)
-                da += 360;
-            d->pinchRotation += da;
-            QPointF pinchCenter = mapFromScene(sceneCenter);
-            QSGPinchEvent pe(pinchCenter, scale, angle, d->pinchRotation);
-            pe.setStartCenter(d->pinchStartCenter);
-            pe.setPreviousCenter(mapFromScene(d->sceneLastCenter));
-            pe.setPreviousAngle(d->pinchLastAngle);
-            pe.setPreviousScale(d->pinchLastScale);
-            pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
-            pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
-            pe.setPoint1(touchPoint1.pos());
-            pe.setPoint2(touchPoint2.pos());
-            pe.setPointCount(d->touchPoints.count());
-            d->pinchLastScale = scale;
-            d->sceneLastCenter = sceneCenter;
-            d->pinchLastAngle = angle;
-            d->lastPoint1 = touchPoint1.scenePos();
-            d->lastPoint2 = touchPoint2.scenePos();
-            emit pinchUpdated(&pe);
-            if (d->pinch && d->pinch->target()) {
-                qreal s = d->pinchStartScale * scale;
-                s = qMin(qMax(pinch()->minimumScale(),s), pinch()->maximumScale());
-                pinch()->target()->setScale(s);
-                QPointF pos = sceneCenter - d->sceneStartCenter + d->pinchStartPos;
-                if (pinch()->axis() & QSGPinch::XAxis) {
-                    qreal x = pos.x();
-                    if (x < pinch()->xmin())
-                        x = pinch()->xmin();
-                    else if (x > pinch()->xmax())
-                        x = pinch()->xmax();
-                    pinch()->target()->setX(x);
-                }
-                if (pinch()->axis() & QSGPinch::YAxis) {
-                    qreal y = pos.y();
-                    if (y < pinch()->ymin())
-                        y = pinch()->ymin();
-                    else if (y > pinch()->ymax())
-                        y = pinch()->ymax();
-                    pinch()->target()->setY(y);
-                }
-                if (d->pinchStartRotation >= pinch()->minimumRotation()
-                        && d->pinchStartRotation <= pinch()->maximumRotation()) {
-                    qreal r = d->pinchRotation + d->pinchStartRotation;
-                    r = qMin(qMax(pinch()->minimumRotation(),r), pinch()->maximumRotation());
-                    pinch()->target()->setRotation(r);
-                }
-            }
-        }
-    }
-}
-
-void QSGPinchArea::mousePressEvent(QMouseEvent *event)
-{
-    Q_D(QSGPinchArea);
-    d->stealMouse = false;
-    if (!d->absorb)
-        QSGItem::mousePressEvent(event);
-    else {
-        setKeepMouseGrab(false);
-        event->setAccepted(true);
-    }
-}
-
-void QSGPinchArea::mouseMoveEvent(QMouseEvent *event)
-{
-    Q_D(QSGPinchArea);
-    if (!d->absorb) {
-        QSGItem::mouseMoveEvent(event);
-        return;
-    }
-}
-
-void QSGPinchArea::mouseReleaseEvent(QMouseEvent *event)
-{
-    Q_D(QSGPinchArea);
-    d->stealMouse = false;
-    if (!d->absorb) {
-        QSGItem::mouseReleaseEvent(event);
-    } else {
-        QSGCanvas *c = canvas();
-        if (c && c->mouseGrabberItem() == this)
-            ungrabMouse();
-        setKeepMouseGrab(false);
-    }
-}
-
-void QSGPinchArea::mouseUngrabEvent()
-{
-    setKeepMouseGrab(false);
-}
-
-bool QSGPinchArea::sendMouseEvent(QMouseEvent *event)
-{
-    Q_D(QSGPinchArea);
-    QRectF myRect = mapRectToScene(QRectF(0, 0, width(), height()));
-
-    QSGCanvas *c = canvas();
-    QSGItem *grabber = c ? c->mouseGrabberItem() : 0;
-    bool stealThisEvent = d->stealMouse;
-    if ((stealThisEvent || myRect.contains(event->windowPos())) && (!grabber || !grabber->keepMouseGrab())) {
-        QMouseEvent mouseEvent(event->type(), mapFromScene(event->windowPos()), event->windowPos(), event->screenPos(),
-                               event->button(), event->buttons(), event->modifiers());
-        mouseEvent.setAccepted(false);
-
-        switch (mouseEvent.type()) {
-        case QEvent::MouseMove:
-            mouseMoveEvent(&mouseEvent);
-            break;
-        case QEvent::MouseButtonPress:
-            mousePressEvent(&mouseEvent);
-            break;
-        case QEvent::MouseButtonRelease:
-            mouseReleaseEvent(&mouseEvent);
-            break;
-        default:
-            break;
-        }
-        grabber = c->mouseGrabberItem();
-        if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this)
-            grabMouse();
-
-        return stealThisEvent;
-    }
-    if (event->type() == QEvent::MouseButtonRelease) {
-        d->stealMouse = false;
-        if (c && c->mouseGrabberItem() == this)
-            ungrabMouse();
-        setKeepMouseGrab(false);
-    }
-    return false;
-}
-
-bool QSGPinchArea::childMouseEventFilter(QSGItem *i, QEvent *e)
-{
-    Q_D(QSGPinchArea);
-    if (!d->absorb || !isVisible())
-        return QSGItem::childMouseEventFilter(i, e);
-    switch (e->type()) {
-    case QEvent::MouseButtonPress:
-    case QEvent::MouseMove:
-    case QEvent::MouseButtonRelease:
-        return sendMouseEvent(static_cast<QMouseEvent *>(e));
-        break;
-    case QEvent::TouchBegin:
-    case QEvent::TouchUpdate: {
-            QTouchEvent *touch = static_cast<QTouchEvent*>(e);
-            d->touchPoints.clear();
-            for (int i = 0; i < touch->touchPoints().count(); ++i)
-                if (!(touch->touchPoints().at(i).state() & Qt::TouchPointReleased))
-                    d->touchPoints << touch->touchPoints().at(i);
-            updatePinch();
-        }
-        return d->inPinch;
-    case QEvent::TouchEnd:
-        d->touchPoints.clear();
-        updatePinch();
-        break;
-    default:
-        break;
-    }
-
-    return QSGItem::childMouseEventFilter(i, e);
-}
-
-void QSGPinchArea::geometryChanged(const QRectF &newGeometry,
-                                            const QRectF &oldGeometry)
-{
-    QSGItem::geometryChanged(newGeometry, oldGeometry);
-}
-
-void QSGPinchArea::itemChange(ItemChange change, const ItemChangeData &value)
-{
-    QSGItem::itemChange(change, value);
-}
-
-QSGPinch *QSGPinchArea::pinch()
-{
-    Q_D(QSGPinchArea);
-    if (!d->pinch)
-        d->pinch = new QSGPinch;
-    return d->pinch;
-}
-
-
-QT_END_NAMESPACE
-
diff --git a/src/declarative/items/qsgpincharea_p.h b/src/declarative/items/qsgpincharea_p.h
deleted file mode 100644 (file)
index f27bddb..0000000
+++ /dev/null
@@ -1,315 +0,0 @@
-// Commit: f707672eb4c51ea82fbd98e1da16ece61a74c690
-/****************************************************************************
-**
-** 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 QtSG 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 QSGPINCHAREA_H
-#define QSGPINCHAREA_H
-
-#include "qsgitem.h"
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class Q_AUTOTEST_EXPORT QSGPinch : public QObject
-{
-    Q_OBJECT
-
-    Q_ENUMS(Axis)
-    Q_PROPERTY(QSGItem *target READ target WRITE setTarget RESET resetTarget)
-    Q_PROPERTY(qreal minimumScale READ minimumScale WRITE setMinimumScale NOTIFY minimumScaleChanged)
-    Q_PROPERTY(qreal maximumScale READ maximumScale WRITE setMaximumScale NOTIFY maximumScaleChanged)
-    Q_PROPERTY(qreal minimumRotation READ minimumRotation WRITE setMinimumRotation NOTIFY minimumRotationChanged)
-    Q_PROPERTY(qreal maximumRotation READ maximumRotation WRITE setMaximumRotation NOTIFY maximumRotationChanged)
-    Q_PROPERTY(Axis dragAxis READ axis WRITE setAxis NOTIFY dragAxisChanged)
-    Q_PROPERTY(qreal minimumX READ xmin WRITE setXmin NOTIFY minimumXChanged)
-    Q_PROPERTY(qreal maximumX READ xmax WRITE setXmax NOTIFY maximumXChanged)
-    Q_PROPERTY(qreal minimumY READ ymin WRITE setYmin NOTIFY minimumYChanged)
-    Q_PROPERTY(qreal maximumY READ ymax WRITE setYmax NOTIFY maximumYChanged)
-    Q_PROPERTY(bool active READ active NOTIFY activeChanged)
-
-public:
-    QSGPinch();
-
-    QSGItem *target() const { return m_target; }
-    void setTarget(QSGItem *target) {
-        if (target == m_target)
-            return;
-        m_target = target;
-        emit targetChanged();
-    }
-    void resetTarget() {
-        if (!m_target)
-            return;
-        m_target = 0;
-        emit targetChanged();
-    }
-
-    qreal minimumScale() const { return m_minScale; }
-    void setMinimumScale(qreal s) {
-        if (s == m_minScale)
-            return;
-        m_minScale = s;
-        emit minimumScaleChanged();
-    }
-    qreal maximumScale() const { return m_maxScale; }
-    void setMaximumScale(qreal s) {
-        if (s == m_maxScale)
-            return;
-        m_maxScale = s;
-        emit maximumScaleChanged();
-    }
-
-    qreal minimumRotation() const { return m_minRotation; }
-    void setMinimumRotation(qreal r) {
-        if (r == m_minRotation)
-            return;
-        m_minRotation = r;
-        emit minimumRotationChanged();
-    }
-    qreal maximumRotation() const { return m_maxRotation; }
-    void setMaximumRotation(qreal r) {
-        if (r == m_maxRotation)
-            return;
-        m_maxRotation = r;
-        emit maximumRotationChanged();
-    }
-
-    enum Axis { NoDrag=0x00, XAxis=0x01, YAxis=0x02, XandYAxis=0x03 };
-    Axis axis() const { return m_axis; }
-    void setAxis(Axis a) {
-        if (a == m_axis)
-            return;
-        m_axis = a;
-        emit dragAxisChanged();
-    }
-
-    qreal xmin() const { return m_xmin; }
-    void setXmin(qreal x) {
-        if (x == m_xmin)
-            return;
-        m_xmin = x;
-        emit minimumXChanged();
-    }
-    qreal xmax() const { return m_xmax; }
-    void setXmax(qreal x) {
-        if (x == m_xmax)
-            return;
-        m_xmax = x;
-        emit maximumXChanged();
-    }
-    qreal ymin() const { return m_ymin; }
-    void setYmin(qreal y) {
-        if (y == m_ymin)
-            return;
-        m_ymin = y;
-        emit minimumYChanged();
-    }
-    qreal ymax() const { return m_ymax; }
-    void setYmax(qreal y) {
-        if (y == m_ymax)
-            return;
-        m_ymax = y;
-        emit maximumYChanged();
-    }
-
-    bool active() const { return m_active; }
-    void setActive(bool a) {
-        if (a == m_active)
-            return;
-        m_active = a;
-        emit activeChanged();
-    }
-
-signals:
-    void targetChanged();
-    void minimumScaleChanged();
-    void maximumScaleChanged();
-    void minimumRotationChanged();
-    void maximumRotationChanged();
-    void dragAxisChanged();
-    void minimumXChanged();
-    void maximumXChanged();
-    void minimumYChanged();
-    void maximumYChanged();
-    void activeChanged();
-
-private:
-    QSGItem *m_target;
-    qreal m_minScale;
-    qreal m_maxScale;
-    qreal m_minRotation;
-    qreal m_maxRotation;
-    Axis m_axis;
-    qreal m_xmin;
-    qreal m_xmax;
-    qreal m_ymin;
-    qreal m_ymax;
-    bool m_active;
-};
-
-class Q_AUTOTEST_EXPORT QSGPinchEvent : public QObject
-{
-    Q_OBJECT
-
-    Q_PROPERTY(QPointF center READ center)
-    Q_PROPERTY(QPointF startCenter READ startCenter)
-    Q_PROPERTY(QPointF previousCenter READ previousCenter)
-    Q_PROPERTY(qreal scale READ scale)
-    Q_PROPERTY(qreal previousScale READ previousScale)
-    Q_PROPERTY(qreal angle READ angle)
-    Q_PROPERTY(qreal previousAngle READ previousAngle)
-    Q_PROPERTY(qreal rotation READ rotation)
-    Q_PROPERTY(QPointF point1 READ point1)
-    Q_PROPERTY(QPointF startPoint1 READ startPoint1)
-    Q_PROPERTY(QPointF point2 READ point2)
-    Q_PROPERTY(QPointF startPoint2 READ startPoint2)
-    Q_PROPERTY(int pointCount READ pointCount)
-    Q_PROPERTY(bool accepted READ accepted WRITE setAccepted)
-
-public:
-    QSGPinchEvent(QPointF c, qreal s, qreal a, qreal r)
-        : QObject(), m_center(c), m_scale(s), m_angle(a), m_rotation(r)
-        , m_pointCount(0), m_accepted(true) {}
-
-    QPointF center() const { return m_center; }
-    QPointF startCenter() const { return m_startCenter; }
-    void setStartCenter(QPointF c) { m_startCenter = c; }
-    QPointF previousCenter() const { return m_lastCenter; }
-    void setPreviousCenter(QPointF c) { m_lastCenter = c; }
-    qreal scale() const { return m_scale; }
-    qreal previousScale() const { return m_lastScale; }
-    void setPreviousScale(qreal s) { m_lastScale = s; }
-    qreal angle() const { return m_angle; }
-    qreal previousAngle() const { return m_lastAngle; }
-    void setPreviousAngle(qreal a) { m_lastAngle = a; }
-    qreal rotation() const { return m_rotation; }
-    QPointF point1() const { return m_point1; }
-    void setPoint1(QPointF p) { m_point1 = p; }
-    QPointF startPoint1() const { return m_startPoint1; }
-    void setStartPoint1(QPointF p) { m_startPoint1 = p; }
-    QPointF point2() const { return m_point2; }
-    void setPoint2(QPointF p) { m_point2 = p; }
-    QPointF startPoint2() const { return m_startPoint2; }
-    void setStartPoint2(QPointF p) { m_startPoint2 = p; }
-    int pointCount() const { return m_pointCount; }
-    void setPointCount(int count) { m_pointCount = count; }
-
-    bool accepted() const { return m_accepted; }
-    void setAccepted(bool a) { m_accepted = a; }
-
-private:
-    QPointF m_center;
-    QPointF m_startCenter;
-    QPointF m_lastCenter;
-    qreal m_scale;
-    qreal m_lastScale;
-    qreal m_angle;
-    qreal m_lastAngle;
-    qreal m_rotation;
-    QPointF m_point1;
-    QPointF m_point2;
-    QPointF m_startPoint1;
-    QPointF m_startPoint2;
-    int m_pointCount;
-    bool m_accepted;
-};
-
-
-class QSGMouseEvent;
-class QSGPinchAreaPrivate;
-class Q_AUTOTEST_EXPORT QSGPinchArea : public QSGItem
-{
-    Q_OBJECT
-
-    Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
-    Q_PROPERTY(QSGPinch *pinch READ pinch CONSTANT)
-
-public:
-    QSGPinchArea(QSGItem *parent=0);
-    ~QSGPinchArea();
-
-    bool isEnabled() const;
-    void setEnabled(bool);
-
-    QSGPinch *pinch();
-
-Q_SIGNALS:
-    void enabledChanged();
-    void pinchStarted(QSGPinchEvent *pinch);
-    void pinchUpdated(QSGPinchEvent *pinch);
-    void pinchFinished(QSGPinchEvent *pinch);
-
-protected:
-    virtual void mousePressEvent(QMouseEvent *event);
-    virtual void mouseReleaseEvent(QMouseEvent *event);
-    virtual void mouseMoveEvent(QMouseEvent *event);
-    virtual void mouseUngrabEvent();
-    virtual bool sendMouseEvent(QMouseEvent *event);
-    virtual bool childMouseEventFilter(QSGItem *i, QEvent *e);
-    virtual void touchEvent(QTouchEvent *event);
-
-    virtual void geometryChanged(const QRectF &newGeometry,
-                                 const QRectF &oldGeometry);
-    virtual void itemChange(ItemChange change, const ItemChangeData& value);
-
-private:
-    void updatePinch();
-    void handlePress();
-    void handleRelease();
-
-private:
-    Q_DISABLE_COPY(QSGPinchArea)
-    Q_DECLARE_PRIVATE(QSGPinchArea)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGPinch)
-QML_DECLARE_TYPE(QSGPinchEvent)
-QML_DECLARE_TYPE(QSGPinchArea)
-
-QT_END_HEADER
-
-#endif // QSGPINCHAREA_H
-
diff --git a/src/declarative/items/qsgpincharea_p_p.h b/src/declarative/items/qsgpincharea_p_p.h
deleted file mode 100644 (file)
index 9cf928b..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-// Commit: f707672eb4c51ea82fbd98e1da16ece61a74c690
-/****************************************************************************
-**
-** 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 QtSG 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 QSGPINCHAREA_P_H
-#define QSGPINCHAREA_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 <qevent.h>
-
-#include "qsgitem_p.h"
-#include "qsgpincharea_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QSGPinch;
-class QSGPinchAreaPrivate : public QSGItemPrivate
-{
-    Q_DECLARE_PUBLIC(QSGPinchArea)
-public:
-    QSGPinchAreaPrivate()
-      : absorb(true), stealMouse(false), inPinch(false)
-      , pinchRejected(false), pinchActivated(false), initPinch(false)
-      , pinch(0), pinchStartDist(0), pinchStartScale(1.0)
-      , pinchLastScale(1.0), pinchStartRotation(0.0), pinchStartAngle(0.0)
-      , pinchLastAngle(0.0), pinchRotation(0.0)
-    {
-    }
-
-    ~QSGPinchAreaPrivate();
-
-    void init()
-    {
-        Q_Q(QSGPinchArea);
-        q->setAcceptedMouseButtons(Qt::LeftButton);
-        q->setFiltersChildMouseEvents(true);
-    }
-
-    bool absorb : 1;
-    bool stealMouse : 1;
-    bool inPinch : 1;
-    bool pinchRejected : 1;
-    bool pinchActivated : 1;
-    bool initPinch : 1;
-    QSGPinch *pinch;
-    QPointF sceneStartPoint1;
-    QPointF sceneStartPoint2;
-    QPointF lastPoint1;
-    QPointF lastPoint2;
-    qreal pinchStartDist;
-    qreal pinchStartScale;
-    qreal pinchLastScale;
-    qreal pinchStartRotation;
-    qreal pinchStartAngle;
-    qreal pinchLastAngle;
-    qreal pinchRotation;
-    QPointF sceneStartCenter;
-    QPointF pinchStartCenter;
-    QPointF sceneLastCenter;
-    QPointF pinchStartPos;
-    QList<QTouchEvent::TouchPoint> touchPoints;
-    int id1;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGPINCHAREA_P_H
-
diff --git a/src/declarative/items/qsgpositioners.cpp b/src/declarative/items/qsgpositioners.cpp
deleted file mode 100644 (file)
index eaca210..0000000
+++ /dev/null
@@ -1,1533 +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 "qsgpositioners_p.h"
-#include "qsgpositioners_p_p.h"
-
-#include <QtDeclarative/qdeclarative.h>
-#include <QtDeclarative/qdeclarativeinfo.h>
-#include <QtCore/qmath.h>
-#include <QtCore/qcoreapplication.h>
-
-#include <private/qdeclarativestate_p.h>
-#include <private/qdeclarativestategroup_p.h>
-#include <private/qdeclarativestateoperations_p.h>
-#include <private/qdeclarativetransition_p.h>
-
-QT_BEGIN_NAMESPACE
-
-static const QSGItemPrivate::ChangeTypes watchedChanges
-    = QSGItemPrivate::Geometry
-    | QSGItemPrivate::SiblingOrder
-    | QSGItemPrivate::Visibility
-    | QSGItemPrivate::Destroyed;
-
-void QSGBasePositionerPrivate::watchChanges(QSGItem *other)
-{
-    QSGItemPrivate *otherPrivate = QSGItemPrivate::get(other);
-    otherPrivate->addItemChangeListener(this, watchedChanges);
-}
-
-void QSGBasePositionerPrivate::unwatchChanges(QSGItem* other)
-{
-    QSGItemPrivate *otherPrivate = QSGItemPrivate::get(other);
-    otherPrivate->removeItemChangeListener(this, watchedChanges);
-}
-
-QSGBasePositioner::QSGBasePositioner(PositionerType at, QSGItem *parent)
-    : QSGImplicitSizeItem(*(new QSGBasePositionerPrivate), parent)
-{
-    Q_D(QSGBasePositioner);
-    d->init(at);
-}
-/*!
-    \internal
-    \class QSGBasePositioner
-    \brief The QSGBasePositioner class provides a base for QSGGraphics layouts.
-
-    To create a QSGGraphics Positioner, simply subclass QSGBasePositioner and implement
-    doLayout(), which is automatically called when the layout might need
-    updating. In doLayout() use the setX and setY functions from QSGBasePositioner, and the
-    base class will apply the positions along with the appropriate transitions. The items to
-    position are provided in order as the protected member positionedItems.
-
-    You also need to set a PositionerType, to declare whether you are positioning the x, y or both
-    for the child items. Depending on the chosen type, only x or y changes will be applied.
-
-    Note that the subclass is responsible for adding the spacing in between items.
-
-    Positioning is usually delayed until before a frame is rendered, to batch multiple repositioning
-    changes into one calculation.
-*/
-
-QSGBasePositioner::QSGBasePositioner(QSGBasePositionerPrivate &dd, PositionerType at, QSGItem *parent)
-    : QSGImplicitSizeItem(dd, parent)
-{
-    Q_D(QSGBasePositioner);
-    d->init(at);
-}
-
-QSGBasePositioner::~QSGBasePositioner()
-{
-    Q_D(QSGBasePositioner);
-    for (int i = 0; i < positionedItems.count(); ++i)
-        d->unwatchChanges(positionedItems.at(i).item);
-    positionedItems.clear();
-}
-
-void QSGBasePositioner::updatePolish()
-{
-    Q_D(QSGBasePositioner);
-    if (d->positioningDirty)
-        prePositioning();
-}
-
-int QSGBasePositioner::spacing() const
-{
-    Q_D(const QSGBasePositioner);
-    return d->spacing;
-}
-
-void QSGBasePositioner::setSpacing(int s)
-{
-    Q_D(QSGBasePositioner);
-    if (s==d->spacing)
-        return;
-    d->spacing = s;
-    d->setPositioningDirty();
-    emit spacingChanged();
-}
-
-QDeclarativeTransition *QSGBasePositioner::move() const
-{
-    Q_D(const QSGBasePositioner);
-    return d->moveTransition;
-}
-
-void QSGBasePositioner::setMove(QDeclarativeTransition *mt)
-{
-    Q_D(QSGBasePositioner);
-    if (mt == d->moveTransition)
-        return;
-    d->moveTransition = mt;
-    emit moveChanged();
-}
-
-QDeclarativeTransition *QSGBasePositioner::add() const
-{
-    Q_D(const QSGBasePositioner);
-    return d->addTransition;
-}
-
-void QSGBasePositioner::setAdd(QDeclarativeTransition *add)
-{
-    Q_D(QSGBasePositioner);
-    if (add == d->addTransition)
-        return;
-
-    d->addTransition = add;
-    emit addChanged();
-}
-
-void QSGBasePositioner::componentComplete()
-{
-    QSGItem::componentComplete();
-    positionedItems.reserve(childItems().count());
-    prePositioning();
-    reportConflictingAnchors();
-}
-
-void QSGBasePositioner::itemChange(ItemChange change, const ItemChangeData &value)
-{
-    Q_D(QSGBasePositioner);
-    if (change == ItemChildAddedChange){
-        d->setPositioningDirty();
-    } else if (change == ItemChildRemovedChange) {
-        QSGItem *child = value.item;
-        QSGBasePositioner::PositionedItem posItem(child);
-        int idx = positionedItems.find(posItem);
-        if (idx >= 0) {
-            d->unwatchChanges(child);
-            positionedItems.remove(idx);
-        }
-        d->setPositioningDirty();
-    }
-
-    QSGItem::itemChange(change, value);
-}
-
-void QSGBasePositioner::prePositioning()
-{
-    Q_D(QSGBasePositioner);
-    if (!isComponentComplete())
-        return;
-
-    if (d->doingPositioning)
-        return;
-
-    d->positioningDirty = false;
-    d->doingPositioning = true;
-    //Need to order children by creation order modified by stacking order
-    QList<QSGItem *> children = childItems();
-
-    QPODVector<PositionedItem,8> oldItems;
-    positionedItems.copyAndClear(oldItems);
-    for (int ii = 0; ii < children.count(); ++ii) {
-        QSGItem *child = children.at(ii);
-        QSGItemPrivate *childPrivate = QSGItemPrivate::get(child);
-        PositionedItem *item = 0;
-        PositionedItem posItem(child);
-        int wIdx = oldItems.find(posItem);
-        if (wIdx < 0) {
-            d->watchChanges(child);
-            positionedItems.append(posItem);
-            item = &positionedItems[positionedItems.count()-1];
-            item->isNew = true;
-            if (!childPrivate->explicitVisible || !child->width() || !child->height())
-                item->isVisible = false;
-        } else {
-            item = &oldItems[wIdx];
-            // Items are only omitted from positioning if they are explicitly hidden
-            // i.e. their positioning is not affected if an ancestor is hidden.
-            if (!childPrivate->explicitVisible || !child->width() || !child->height()) {
-                item->isVisible = false;
-            } else if (!item->isVisible) {
-                item->isVisible = true;
-                item->isNew = true;
-            } else {
-                item->isNew = false;
-            }
-            positionedItems.append(*item);
-        }
-    }
-    QSizeF contentSize(0,0);
-    doPositioning(&contentSize);
-    updateAttachedProperties();
-    if (!d->addActions.isEmpty() || !d->moveActions.isEmpty())
-        finishApplyTransitions();
-    d->doingPositioning = false;
-    //Set implicit size to the size of its children
-    setImplicitHeight(contentSize.height());
-    setImplicitWidth(contentSize.width());
-}
-
-void QSGBasePositioner::positionX(int x, const PositionedItem &target)
-{
-    Q_D(QSGBasePositioner);
-    if (d->type == Horizontal || d->type == Both) {
-        if (target.isNew) {
-            if (!d->addTransition || !d->addTransition->enabled())
-                target.item->setX(x);
-            else
-                d->addActions << QDeclarativeAction(target.item, QLatin1String("x"), QVariant(x));
-        } else if (x != target.item->x()) {
-            if (!d->moveTransition || !d->moveTransition->enabled())
-                target.item->setX(x);
-            else
-                d->moveActions << QDeclarativeAction(target.item, QLatin1String("x"), QVariant(x));
-        }
-    }
-}
-
-void QSGBasePositioner::positionY(int y, const PositionedItem &target)
-{
-    Q_D(QSGBasePositioner);
-    if (d->type == Vertical || d->type == Both) {
-        if (target.isNew) {
-            if (!d->addTransition || !d->addTransition->enabled())
-                target.item->setY(y);
-            else
-                d->addActions << QDeclarativeAction(target.item, QLatin1String("y"), QVariant(y));
-        } else if (y != target.item->y()) {
-            if (!d->moveTransition || !d->moveTransition->enabled())
-                target.item->setY(y);
-            else
-                d->moveActions << QDeclarativeAction(target.item, QLatin1String("y"), QVariant(y));
-        }
-    }
-}
-
-void QSGBasePositioner::finishApplyTransitions()
-{
-    Q_D(QSGBasePositioner);
-    // Note that if a transition is not set the transition manager will
-    // apply the changes directly, in the case add/move aren't set
-    d->addTransitionManager.transition(d->addActions, d->addTransition);
-    d->moveTransitionManager.transition(d->moveActions, d->moveTransition);
-    d->addActions.clear();
-    d->moveActions.clear();
-}
-
-QSGPositionerAttached *QSGBasePositioner::qmlAttachedProperties(QObject *obj)
-{
-    return new QSGPositionerAttached(obj);
-}
-
-void QSGBasePositioner::updateAttachedProperties(QSGPositionerAttached *specificProperty, QSGItem *specificPropertyOwner) const
-{
-    // If this function is deemed too expensive or shows up in profiles, it could
-    // be changed to run only when there are attached properties present. This
-    // could be a flag in the positioner that is set by the attached property
-    // constructor.
-    QSGPositionerAttached *prevLastProperty = 0;
-    QSGPositionerAttached *lastProperty = 0;
-
-    int visibleItemIndex = 0;
-    for (int ii = 0; ii < positionedItems.count(); ++ii) {
-        const PositionedItem &child = positionedItems.at(ii);
-        if (!child.item)
-            continue;
-
-        QSGPositionerAttached *property = 0;
-
-        if (specificProperty) {
-            if (specificPropertyOwner == child.item) {
-                property = specificProperty;
-            }
-        } else {
-            property = static_cast<QSGPositionerAttached *>(qmlAttachedPropertiesObject<QSGBasePositioner>(child.item, false));
-        }
-
-        if (child.isVisible) {
-            if (property) {
-              property->setIndex(visibleItemIndex);
-              property->setIsFirstItem(visibleItemIndex == 0);
-
-              if (property->isLastItem())
-                prevLastProperty = property;
-            }
-
-            lastProperty = property;
-            ++visibleItemIndex;
-        } else if (property) {
-            property->setIndex(-1);
-            property->setIsFirstItem(false);
-            property->setIsLastItem(false);
-        }
-    }
-
-    if (prevLastProperty && prevLastProperty != lastProperty)
-        prevLastProperty->setIsLastItem(false);
-    if (lastProperty)
-      lastProperty->setIsLastItem(true);
-}
-
-/*!
-    \qmlclass Positioner QSGPositionerAttached
-    \inqmlmodule QtQuick 2
-    \ingroup qml-positioning-elements
-    \brief The Positioner type provides attached properties that contain details on where an item exists in a positioner.
-
-    Positioner items (such as Column, Row, Flow and Grid) provide automatic layout
-    for child items. Attaching this property allows a child item to determine
-    where it exists within the positioner.
-*/
-
-QSGPositionerAttached::QSGPositionerAttached(QObject *parent) : QObject(parent), m_index(-1), m_isFirstItem(false), m_isLastItem(false)
-{
-    QSGItem *attachedItem = qobject_cast<QSGItem *>(parent);
-    if (attachedItem) {
-        QSGBasePositioner *positioner = qobject_cast<QSGBasePositioner *>(attachedItem->parent());
-        if (positioner) {
-            positioner->updateAttachedProperties(this, attachedItem);
-        }
-    }
-}
-
-/*!
-    \qmlattachedproperty Item QtQuick2::Positioner::index
-
-    This property allows the item to determine
-    its index within the positioner.
-*/
-void QSGPositionerAttached::setIndex(int index)
-{
-    if (m_index == index)
-        return;
-    m_index = index;
-    emit indexChanged();
-}
-
-/*!
-    \qmlattachedproperty Item QtQuick2::Positioner::isFirstItem
-    \qmlattachedproperty Item QtQuick2::Positioner::isLastItem
-
-    These properties allow the item to determine if it
-    is the first or last item in the positioner, respectively.
-*/
-void QSGPositionerAttached::setIsFirstItem(bool isFirstItem)
-{
-    if (m_isFirstItem == isFirstItem)
-        return;
-    m_isFirstItem = isFirstItem;
-    emit isFirstItemChanged();
-}
-
-void QSGPositionerAttached::setIsLastItem(bool isLastItem)
-{
-    if (m_isLastItem == isLastItem)
-        return;
-    m_isLastItem = isLastItem;
-    emit isLastItemChanged();
-}
-
-/*!
-  \qmlclass Column QSGColumn
-    \inqmlmodule QtQuick 2
-  \ingroup qml-positioning-elements
-  \brief The Column item arranges its children vertically.
-  \inherits Item
-
-  The Column item positions its child items so that they are vertically
-  aligned and not overlapping.
-
-  Spacing between items can be added using the \l spacing property.
-  Transitions can be used for cases where items managed by a Column are
-  added or moved. These are stored in the \l add and \l move properties
-  respectively.
-
-  See \l{Using QML Positioner and Repeater Items} for more details about this item and other
-  related items.
-
-  \section1 Example Usage
-
-  The following example positions differently shaped rectangles using a Column
-  item.
-
-  \image verticalpositioner_example.png
-
-  \snippet doc/src/snippets/declarative/column/vertical-positioner.qml document
-
-  \section1 Using Transitions
-
-  Transitions can be used to animate items that are added to, moved within,
-  or removed from a Column item. The \l add and \l move properties can be set to
-  the transitions that will be applied when items are added to, removed from,
-  or re-positioned within a Column item.
-
-  The use of transitions with positioners is described in more detail in the
-  \l{Using QML Positioner and Repeater Items#Using Transitions}{Using QML
-  Positioner and Repeater Items} document.
-
-  \image verticalpositioner_transition.gif
-
-  \qml
-  Column {
-      spacing: 2
-      add: Transition {
-          // Define an animation for adding a new item...
-      }
-      move: Transition {
-          // Define an animation for moving items within the column...
-      }
-      // ...
-  }
-  \endqml
-
-  \section1 Limitations
-
-  Note that the positioner assumes that the x and y positions of its children
-  will not change. If you manually change the x or y properties in script, bind
-  the x or y properties, use anchors on a child of a positioner, or have the
-  height of a child depend on the position of a child, then the
-  positioner may exhibit strange behavior. If you need to perform any of these
-  actions, consider positioning the items without the use of a Column.
-
-  Items with a width or height of 0 will not be positioned.
-
-  Positioning is batched and syncronized with painting to reduce the number of
-  calculations needed. This means that positioners may not reposition items immediately
-  when changes occur, but it will have moved by the next frame.
-
-  \sa Row, Grid, Flow, Positioner, {declarative/positioners}{Positioners example}
-*/
-/*!
-    \qmlproperty Transition QtQuick2::Column::add
-
-    This property holds the transition to be applied when adding an
-    item to the positioner. The transition will only be applied to the
-    added item(s).  Positioner transitions will only affect the
-    position (x, y) of items.
-
-    For a positioner, adding an item can mean that either the object
-    has been created or reparented, and thus is now a child or the
-    positioner, or that the object has had its opacity increased from
-    zero, and thus is now visible.
-
-    \sa move
-*/
-/*!
-    \qmlproperty Transition QtQuick2::Column::move
-
-    This property holds the transition to apply when moving an item
-    within the positioner.  Positioner transitions will only affect
-    the position (x, y) of items.
-
-    This transition can be performed when other items are added or removed
-    from the positioner, or when items resize themselves.
-
-    \image positioner-move.gif
-
-    \qml
-    Column {
-        move: Transition {
-            NumberAnimation {
-                properties: "y"
-                duration: 1000
-            }
-        }
-    }
-    \endqml
-
-    \sa add, {declarative/positioners}{Positioners example}
-*/
-/*!
-  \qmlproperty int QtQuick2::Column::spacing
-
-  The spacing is the amount in pixels left empty between adjacent
-  items. The default spacing is 0.
-
-  \sa Grid::spacing
-*/
-QSGColumn::QSGColumn(QSGItem *parent)
-: QSGBasePositioner(Vertical, parent)
-{
-}
-
-void QSGColumn::doPositioning(QSizeF *contentSize)
-{
-    int voffset = 0;
-
-    for (int ii = 0; ii < positionedItems.count(); ++ii) {
-        const PositionedItem &child = positionedItems.at(ii);
-        if (!child.item || !child.isVisible)
-            continue;
-
-        if (child.item->y() != voffset)
-            positionY(voffset, child);
-
-        contentSize->setWidth(qMax(contentSize->width(), child.item->width()));
-
-        voffset += child.item->height();
-        voffset += spacing();
-    }
-
-    if (voffset != 0)//If we positioned any items, undo the spacing from the last item
-        voffset -= spacing();
-    contentSize->setHeight(voffset);
-}
-
-void QSGColumn::reportConflictingAnchors()
-{
-    QSGBasePositionerPrivate *d = static_cast<QSGBasePositionerPrivate*>(QSGBasePositionerPrivate::get(this));
-    for (int ii = 0; ii < positionedItems.count(); ++ii) {
-        const PositionedItem &child = positionedItems.at(ii);
-        if (child.item) {
-            QSGAnchors *anchors = QSGItemPrivate::get(static_cast<QSGItem *>(child.item))->_anchors;
-            if (anchors) {
-                QSGAnchors::Anchors usedAnchors = anchors->usedAnchors();
-                if (usedAnchors & QSGAnchors::TopAnchor ||
-                    usedAnchors & QSGAnchors::BottomAnchor ||
-                    usedAnchors & QSGAnchors::VCenterAnchor ||
-                    anchors->fill() || anchors->centerIn()) {
-                    d->anchorConflict = true;
-                    break;
-                }
-            }
-        }
-    }
-    if (d->anchorConflict) {
-        qmlInfo(this) << "Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column";
-    }
-}
-/*!
-  \qmlclass Row QSGRow
-    \inqmlmodule QtQuick 2
-  \ingroup qml-positioning-elements
-  \brief The Row item arranges its children horizontally.
-  \inherits Item
-
-  The Row item positions its child items so that they are horizontally
-  aligned and not overlapping.
-
-  Use \l spacing to set the spacing between items in a Row, and use the
-  \l add and \l move properties to set the transitions that should be applied
-  when items are added to, removed from, or re-positioned within the Row.
-
-  See \l{Using QML Positioner and Repeater Items} for more details about this item and other
-  related items.
-
-  \section1 Example Usage
-
-  The following example lays out differently shaped rectangles using a Row.
-
-  \image horizontalpositioner_example.png
-
-  \snippet doc/src/snippets/declarative/row/row.qml document
-
-  \section1 Using Transitions
-
-  Transitions can be used to animate items that are added to, moved within,
-  or removed from a Grid item. The \l add and \l move properties can be set to
-  the transitions that will be applied when items are added to, removed from,
-  or re-positioned within a Row item.
-
-  \section1 Limitations
-
-  Note that the positioner assumes that the x and y positions of its children
-  will not change. If you manually change the x or y properties in script, bind
-  the x or y properties, use anchors on a child of a positioner, or have the
-  width of a child depend on the position of a child, then the
-  positioner may exhibit strange behaviour. If you need to perform any of these
-  actions, consider positioning the items without the use of a Row.
-
-  Items with a width or height of 0 will not be positioned.
-
-  Positioning is batched and syncronized with painting to reduce the number of
-  calculations needed. This means that positioners may not reposition items immediately
-  when changes occur, but it will have moved by the next frame.
-
-  \sa Column, Grid, Flow, Positioner, {declarative/positioners}{Positioners example}
-*/
-/*!
-    \qmlproperty Transition QtQuick2::Row::add
-
-    This property holds the transition to be applied when adding an
-    item to the positioner. The transition will only be applied to the
-    added item(s).  Positioner transitions will only affect the
-    position (x, y) of items.
-
-    For a positioner, adding an item can mean that either the object
-    has been created or reparented, and thus is now a child or the
-    positioner, or that the object has had its opacity increased from
-    zero, and thus is now visible.
-
-    \sa move
-*/
-/*!
-    \qmlproperty Transition QtQuick2::Row::move
-
-    This property holds the transition to be applied when moving an
-    item within the positioner. Positioner transitions will only affect
-    the position (x, y) of items.
-
-    This transition can be performed when other items are added or removed
-    from the positioner, or when items resize themselves.
-
-    \qml
-    Row {
-        id: positioner
-        move: Transition {
-            NumberAnimation {
-                properties: "x"
-                duration: 1000
-            }
-        }
-    }
-    \endqml
-
-    \sa add, {declarative/positioners}{Positioners example}
-*/
-/*!
-  \qmlproperty int QtQuick2::Row::spacing
-
-  The spacing is the amount in pixels left empty between adjacent
-  items. The default spacing is 0.
-
-  \sa Grid::spacing
-*/
-
-QSGRow::QSGRow(QSGItem *parent)
-: QSGBasePositioner(Horizontal, parent)
-{
-}
-/*!
-    \qmlproperty enumeration QtQuick2::Row::layoutDirection
-
-    This property holds the layoutDirection of the row.
-
-    Possible values:
-
-    \list
-    \o Qt.LeftToRight (default) - Items are laid out from left to right. If the width of the row is explicitly set,
-    the left anchor remains to the left of the row.
-    \o Qt.RightToLeft - Items are laid out from right to left. If the width of the row is explicitly set,
-    the right anchor remains to the right of the row.
-    \endlist
-
-    \sa Grid::layoutDirection, Flow::layoutDirection, {declarative/righttoleft/layoutdirection}{Layout directions example}
-*/
-
-Qt::LayoutDirection QSGRow::layoutDirection() const
-{
-    return QSGBasePositionerPrivate::getLayoutDirection(this);
-}
-
-void QSGRow::setLayoutDirection(Qt::LayoutDirection layoutDirection)
-{
-    QSGBasePositionerPrivate *d = static_cast<QSGBasePositionerPrivate* >(QSGBasePositionerPrivate::get(this));
-    if (d->layoutDirection != layoutDirection) {
-        d->layoutDirection = layoutDirection;
-        // For RTL layout the positioning changes when the width changes.
-        if (d->layoutDirection == Qt::RightToLeft)
-            d->addItemChangeListener(d, QSGItemPrivate::Geometry);
-        else
-            d->removeItemChangeListener(d, QSGItemPrivate::Geometry);
-        prePositioning();
-        emit layoutDirectionChanged();
-        emit effectiveLayoutDirectionChanged();
-    }
-}
-/*!
-    \qmlproperty enumeration QtQuick2::Row::effectiveLayoutDirection
-    This property holds the effective layout direction of the row positioner.
-
-    When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} for locale layouts,
-    the visual layout direction of the row positioner will be mirrored. However, the
-    property \l {Row::layoutDirection}{layoutDirection} will remain unchanged.
-
-    \sa Row::layoutDirection, {LayoutMirroring}{LayoutMirroring}
-*/
-
-Qt::LayoutDirection QSGRow::effectiveLayoutDirection() const
-{
-    return QSGBasePositionerPrivate::getEffectiveLayoutDirection(this);
-}
-
-void QSGRow::doPositioning(QSizeF *contentSize)
-{
-    QSGBasePositionerPrivate *d = static_cast<QSGBasePositionerPrivate* >(QSGBasePositionerPrivate::get(this));
-    int hoffset = 0;
-
-    QList<int> hoffsets;
-    for (int ii = 0; ii < positionedItems.count(); ++ii) {
-        const PositionedItem &child = positionedItems.at(ii);
-        if (!child.item || !child.isVisible)
-            continue;
-
-        if (d->isLeftToRight()) {
-            if (child.item->x() != hoffset)
-                positionX(hoffset, child);
-        } else {
-            hoffsets << hoffset;
-        }
-
-        contentSize->setHeight(qMax(contentSize->height(), child.item->height()));
-
-        hoffset += child.item->width();
-        hoffset += spacing();
-    }
-
-    if (hoffset != 0)//If we positioned any items, undo the extra spacing from the last item
-        hoffset -= spacing();
-    contentSize->setWidth(hoffset);
-
-    if (d->isLeftToRight())
-        return;
-
-    //Right to Left layout
-    int end = 0;
-    if (!widthValid())
-        end = contentSize->width();
-    else
-        end = width();
-
-    int acc = 0;
-    for (int ii = 0; ii < positionedItems.count(); ++ii) {
-        const PositionedItem &child = positionedItems.at(ii);
-        if (!child.item || !child.isVisible)
-            continue;
-        hoffset = end - hoffsets[acc++] - child.item->width();
-        if (child.item->x() != hoffset)
-            positionX(hoffset, child);
-    }
-}
-
-void QSGRow::reportConflictingAnchors()
-{
-    QSGBasePositionerPrivate *d = static_cast<QSGBasePositionerPrivate*>(QSGBasePositionerPrivate::get(this));
-    for (int ii = 0; ii < positionedItems.count(); ++ii) {
-        const PositionedItem &child = positionedItems.at(ii);
-        if (child.item) {
-            QSGAnchors *anchors = QSGItemPrivate::get(static_cast<QSGItem *>(child.item))->_anchors;
-            if (anchors) {
-                QSGAnchors::Anchors usedAnchors = anchors->usedAnchors();
-                if (usedAnchors & QSGAnchors::LeftAnchor ||
-                    usedAnchors & QSGAnchors::RightAnchor ||
-                    usedAnchors & QSGAnchors::HCenterAnchor ||
-                    anchors->fill() || anchors->centerIn()) {
-                    d->anchorConflict = true;
-                    break;
-                }
-            }
-        }
-    }
-    if (d->anchorConflict)
-        qmlInfo(this) << "Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row";
-}
-
-/*!
-  \qmlclass Grid QSGGrid
-    \inqmlmodule QtQuick 2
-  \ingroup qml-positioning-elements
-  \brief The Grid item positions its children in a grid.
-  \inherits Item
-
-  The Grid item positions its child items so that they are
-  aligned in a grid and are not overlapping.
-
-  The grid positioner calculates a grid of rectangular cells of sufficient
-  size to hold all items, placing the items in the cells, from left to right
-  and top to bottom. Each item is positioned in the top-left corner of its
-  cell with position (0, 0).
-
-  A Grid defaults to four columns, and as many rows as are necessary to
-  fit all child items. The number of rows and columns can be constrained
-  by setting the \l rows and \l columns properties.
-
-  Spacing can be added between child items by setting the \l spacing
-  property. The amount of spacing applied will be the same in the
-  horizontal and vertical directions.
-
-  See \l{Using QML Positioner and Repeater Items} for more details about this item and other
-  related items.
-
-  \section1 Example Usage
-
-  The following example demonstrates this.
-
-  \image gridLayout_example.png
-
-  \snippet doc/src/snippets/declarative/grid/grid.qml document
-
-  \section1 Using Transitions
-
-  Transitions can be used to animate items that are added to, moved within,
-  or removed from a Grid item. The \l add and \l move properties can be set to
-  the transitions that will be applied when items are added to, removed from,
-  or re-positioned within a Grid item.
-
-  \section1 Limitations
-
-  Note that the positioner assumes that the x and y positions of its children
-  will not change. If you manually change the x or y properties in script, bind
-  the x or y properties, use anchors on a child of a positioner, or have the
-  width or height of a child depend on the position of a child, then the
-  positioner may exhibit strange behaviour. If you need to perform any of these
-  actions, consider positioning the items without the use of a Grid.
-
-  Items with a width or height of 0 will not be positioned.
-
-  Positioning is batched and syncronized with painting to reduce the number of
-  calculations needed. This means that positioners may not reposition items immediately
-  when changes occur, but it will have moved by the next frame.
-
-  \sa Flow, Row, Column, Positioner, {declarative/positioners}{Positioners example}
-*/
-/*!
-    \qmlproperty Transition QtQuick2::Grid::add
-
-    This property holds the transition to be applied when adding an
-    item to the positioner. The transition will only be applied to the
-    added item(s).  Positioner transitions will only affect the
-    position (x, y) of items.
-
-    For a positioner, adding an item can mean that either the object
-    has been created or reparented, and thus is now a child or the
-    positioner, or that the object has had its opacity increased from
-    zero, and thus is now visible.
-
-    \sa move
-*/
-/*!
-    \qmlproperty Transition QtQuick2::Grid::move
-
-    This property holds the transition to be applied when moving an
-    item within the positioner. Positioner transitions will only affect
-    the position (x, y) of items.
-
-    This transition can be performed when other items are added or removed
-    from the positioner, or when items resize themselves.
-
-    \qml
-    Grid {
-        move: Transition {
-            NumberAnimation {
-                properties: "x,y"
-                duration: 1000
-            }
-        }
-    }
-    \endqml
-
-    \sa add, {declarative/positioners}{Positioners example}
-*/
-/*!
-  \qmlproperty int QtQuick2::Grid::spacing
-
-  The spacing is the amount in pixels left empty between adjacent
-  items. The default spacing is 0.
-
-  The below example places a Grid containing a red, a blue and a
-  green rectangle on a gray background. The area the grid positioner
-  occupies is colored white. The positioner on the left has the
-  no spacing (the default), and the positioner on the right has
-  a spacing of 6.
-
-  \inlineimage qml-grid-no-spacing.png
-  \inlineimage qml-grid-spacing.png
-
-  \sa rows, columns
-*/
-QSGGrid::QSGGrid(QSGItem *parent) :
-    QSGBasePositioner(Both, parent), m_rows(-1), m_columns(-1), m_rowSpacing(-1), m_columnSpacing(-1), m_flow(LeftToRight)
-{
-}
-
-/*!
-    \qmlproperty int QtQuick2::Grid::columns
-
-    This property holds the number of columns in the grid. The default
-    number of columns is 4.
-
-    If the grid does not have enough items to fill the specified
-    number of columns, some columns will be of zero width.
-*/
-
-/*!
-    \qmlproperty int QtQuick2::Grid::rows
-    This property holds the number of rows in the grid.
-
-    If the grid does not have enough items to fill the specified
-    number of rows, some rows will be of zero width.
-*/
-
-void QSGGrid::setColumns(const int columns)
-{
-    if (columns == m_columns)
-        return;
-    m_columns = columns;
-    prePositioning();
-    emit columnsChanged();
-}
-
-void QSGGrid::setRows(const int rows)
-{
-    if (rows == m_rows)
-        return;
-    m_rows = rows;
-    prePositioning();
-    emit rowsChanged();
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::Grid::flow
-    This property holds the flow of the layout.
-
-    Possible values are:
-
-    \list
-    \o Grid.LeftToRight (default) - Items are positioned next to
-       each other in the \l layoutDirection, then wrapped to the next line.
-    \o Grid.TopToBottom - Items are positioned next to each
-       other from top to bottom, then wrapped to the next column.
-    \endlist
-*/
-QSGGrid::Flow QSGGrid::flow() const
-{
-    return m_flow;
-}
-
-void QSGGrid::setFlow(Flow flow)
-{
-    if (m_flow != flow) {
-        m_flow = flow;
-        prePositioning();
-        emit flowChanged();
-    }
-}
-
-/*!
-    \qmlproperty int QtQuick2::Grid::rowSpacing
-
-    This property holds the spacing in pixels between rows.
-
-    \sa columnSpacing
-    \since QtQuick2.0
-*/
-void QSGGrid::setRowSpacing(const int rowSpacing)
-{
-    if (rowSpacing == m_rowSpacing)
-        return;
-    m_rowSpacing = rowSpacing;
-    prePositioning();
-    emit rowSpacingChanged();
-}
-
-/*!
-    \qmlproperty int QtQuick2::Grid::columnSpacing
-
-    This property holds the spacing in pixels between columns.
-
-    \sa rowSpacing
-    \since QtQuick2.0
-*/
-void QSGGrid::setColumnSpacing(const int columnSpacing)
-{
-    if (columnSpacing == m_columnSpacing)
-        return;
-    m_columnSpacing = columnSpacing;
-    prePositioning();
-    emit columnSpacingChanged();
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::Grid::layoutDirection
-
-    This property holds the layout direction of the layout.
-
-    Possible values are:
-
-    \list
-    \o Qt.LeftToRight (default) - Items are positioned from the top to bottom,
-    and left to right. The flow direction is dependent on the
-    \l Grid::flow property.
-    \o Qt.RightToLeft - Items are positioned from the top to bottom,
-    and right to left. The flow direction is dependent on the
-    \l Grid::flow property.
-    \endlist
-
-    \sa Flow::layoutDirection, Row::layoutDirection, {declarative/righttoleft/layoutdirection}{Layout directions example}
-*/
-Qt::LayoutDirection QSGGrid::layoutDirection() const
-{
-    return QSGBasePositionerPrivate::getLayoutDirection(this);
-}
-
-void QSGGrid::setLayoutDirection(Qt::LayoutDirection layoutDirection)
-{
-    QSGBasePositionerPrivate *d = static_cast<QSGBasePositionerPrivate*>(QSGBasePositionerPrivate::get(this));
-    if (d->layoutDirection != layoutDirection) {
-        d->layoutDirection = layoutDirection;
-        // For RTL layout the positioning changes when the width changes.
-        if (d->layoutDirection == Qt::RightToLeft)
-            d->addItemChangeListener(d, QSGItemPrivate::Geometry);
-        else
-            d->removeItemChangeListener(d, QSGItemPrivate::Geometry);
-        prePositioning();
-        emit layoutDirectionChanged();
-        emit effectiveLayoutDirectionChanged();
-    }
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::Grid::effectiveLayoutDirection
-    This property holds the effective layout direction of the grid positioner.
-
-    When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} for locale layouts,
-    the visual layout direction of the grid positioner will be mirrored. However, the
-    property \l {Grid::layoutDirection}{layoutDirection} will remain unchanged.
-
-    \sa Grid::layoutDirection, {LayoutMirroring}{LayoutMirroring}
-*/
-Qt::LayoutDirection QSGGrid::effectiveLayoutDirection() const
-{
-    return QSGBasePositionerPrivate::getEffectiveLayoutDirection(this);
-}
-
-void QSGGrid::doPositioning(QSizeF *contentSize)
-{
-    QSGBasePositionerPrivate *d = static_cast<QSGBasePositionerPrivate*>(QSGBasePositionerPrivate::get(this));
-    int c = m_columns;
-    int r = m_rows;
-    //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)
-            visibleItems.append(positionedItems[i]);
-
-    int numVisible = visibleItems.count();
-    if (m_columns <= 0 && m_rows <= 0){
-        c = 4;
-        r = (numVisible+3)/4;
-    } else if (m_rows <= 0){
-        r = (numVisible+(m_columns-1))/m_columns;
-    } else if (m_columns <= 0){
-        c = (numVisible+(m_rows-1))/m_rows;
-    }
-
-    if (r==0 || c==0)
-        return; //Nothing to do
-
-    QList<int> maxColWidth;
-    QList<int> maxRowHeight;
-    int childIndex =0;
-    if (m_flow == LeftToRight) {
-        for (int i=0; i < r; i++){
-            for (int j=0; j < c; j++){
-                if (j==0)
-                    maxRowHeight << 0;
-                if (i==0)
-                    maxColWidth << 0;
-
-                if (childIndex == visibleItems.count())
-                    break;
-
-                const PositionedItem &child = visibleItems.at(childIndex++);
-                if (child.item->width() > maxColWidth[j])
-                    maxColWidth[j] = child.item->width();
-                if (child.item->height() > maxRowHeight[i])
-                    maxRowHeight[i] = child.item->height();
-            }
-        }
-    } else {
-        for (int j=0; j < c; j++){
-            for (int i=0; i < r; i++){
-                if (j==0)
-                    maxRowHeight << 0;
-                if (i==0)
-                    maxColWidth << 0;
-
-                if (childIndex == visibleItems.count())
-                    break;
-
-                const PositionedItem &child = visibleItems.at(childIndex++);
-                if (child.item->width() > maxColWidth[j])
-                    maxColWidth[j] = child.item->width();
-                if (child.item->height() > maxRowHeight[i])
-                    maxRowHeight[i] = child.item->height();
-            }
-        }
-    }
-
-    int columnSpacing = m_columnSpacing;
-    if (columnSpacing == -1)
-        columnSpacing = spacing();
-
-    int rowSpacing = m_rowSpacing;
-    if (rowSpacing == -1)
-        rowSpacing = spacing();
-
-    int widthSum = 0;
-    for (int j=0; j < maxColWidth.size(); j++){
-        if (j)
-            widthSum += columnSpacing;
-        widthSum += maxColWidth[j];
-    }
-
-    int heightSum = 0;
-    for (int i=0; i < maxRowHeight.size(); i++){
-        if (i)
-            heightSum += rowSpacing;
-        heightSum += maxRowHeight[i];
-    }
-
-    contentSize->setHeight(heightSum);
-    contentSize->setWidth(widthSum);
-
-    int end = 0;
-    if (widthValid())
-        end = width();
-    else
-        end = widthSum;
-
-    int xoffset=0;
-    if (!d->isLeftToRight())
-        xoffset = end;
-    int yoffset=0;
-    int curRow =0;
-    int curCol =0;
-    for (int i = 0; i < visibleItems.count(); ++i) {
-        const PositionedItem &child = visibleItems.at(i);
-        int childXOffset = xoffset;
-        if (!d->isLeftToRight())
-            childXOffset -= child.item->width();
-        if ((child.item->x() != childXOffset) || (child.item->y() != yoffset)){
-            positionX(childXOffset, child);
-            positionY(yoffset, child);
-        }
-
-        if (m_flow == LeftToRight) {
-            if (d->isLeftToRight())
-                xoffset += maxColWidth[curCol]+columnSpacing;
-            else
-                xoffset -= maxColWidth[curCol]+columnSpacing;
-            curCol++;
-            curCol%=c;
-            if (!curCol){
-                yoffset += maxRowHeight[curRow]+rowSpacing;
-                if (d->isLeftToRight())
-                    xoffset = 0;
-                else
-                    xoffset = end;
-                curRow++;
-                if (curRow>=r)
-                    break;
-            }
-        } else {
-            yoffset+=maxRowHeight[curRow]+rowSpacing;
-            curRow++;
-            curRow%=r;
-            if (!curRow){
-                if (d->isLeftToRight())
-                    xoffset += maxColWidth[curCol]+columnSpacing;
-                else
-                    xoffset -= maxColWidth[curCol]+columnSpacing;
-                yoffset=0;
-                curCol++;
-                if (curCol>=c)
-                    break;
-            }
-        }
-    }
-}
-
-void QSGGrid::reportConflictingAnchors()
-{
-    QSGBasePositionerPrivate *d = static_cast<QSGBasePositionerPrivate*>(QSGBasePositionerPrivate::get(this));
-    for (int ii = 0; ii < positionedItems.count(); ++ii) {
-        const PositionedItem &child = positionedItems.at(ii);
-        if (child.item) {
-            QSGAnchors *anchors = QSGItemPrivate::get(static_cast<QSGItem *>(child.item))->_anchors;
-            if (anchors && (anchors->usedAnchors() || anchors->fill() || anchors->centerIn())) {
-                d->anchorConflict = true;
-                break;
-            }
-        }
-    }
-    if (d->anchorConflict)
-        qmlInfo(this) << "Cannot specify anchors for items inside Grid";
-}
-
-/*!
-  \qmlclass Flow QSGFlow
-    \inqmlmodule QtQuick 2
-  \ingroup qml-positioning-elements
-  \brief The Flow item arranges its children side by side, wrapping as necessary.
-  \inherits Item
-
-  The Flow item positions its child items like words on a page, wrapping them
-  to create rows or columns of items that do not overlap.
-
-  Spacing between items can be added using the \l spacing property.
-  Transitions can be used for cases where items managed by a Column are
-  added or moved. These are stored in the \l add and \l move properties
-  respectively.
-
-  See \l{Using QML Positioner and Repeater Items} for more details about this item and other
-  related items.
-
-  \section1 Example Usage
-
-  The following example positions \l Text items within a parent item using
-  a Flow item.
-
-  \image qml-flow-snippet.png
-
-  \snippet doc/src/snippets/declarative/flow.qml flow item
-
-  \section1 Using Transitions
-
-  Transitions can be used to animate items that are added to, moved within,
-  or removed from a Flow item. The \l add and \l move properties can be set to
-  the transitions that will be applied when items are added to, removed from,
-  or re-positioned within a Flow item.
-
-  The use of transitions with positioners is described in more detail in the
-  \l{Using QML Positioner and Repeater Items#Using Transitions}{Using QML
-  Positioner and Repeater Items} document.
-
-  \section1 Limitations
-
-  Note that the positioner assumes that the x and y positions of its children
-  will not change. If you manually change the x or y properties in script, bind
-  the x or y properties, use anchors on a child of a positioner, or have the
-  width or height of a child depend on the position of a child, then the
-  positioner may exhibit strange behaviour.  If you need to perform any of these
-  actions, consider positioning the items without the use of a Flow.
-
-  Items with a width or height of 0 will not be positioned.
-
-  Positioning is batched and syncronized with painting to reduce the number of
-  calculations needed. This means that positioners may not reposition items immediately
-  when changes occur, but it will have moved by the next frame.
-
-  \sa Column, Row, Grid, Positioner, {declarative/positioners}{Positioners example}
-*/
-/*!
-    \qmlproperty Transition QtQuick2::Flow::add
-
-    This property holds the transition to be applied when adding an
-    item to the positioner. The transition will only be applied to the
-    added item(s).  Positioner transitions will only affect the
-    position (x, y) of items.
-
-    For a positioner, adding an item can mean that either the object
-    has been created or reparented, and thus is now a child or the
-    positioner, or that the object has had its opacity increased from
-    zero, and thus is now visible.
-
-    \sa move
-*/
-/*!
-    \qmlproperty Transition QtQuick2::Flow::move
-
-    This property holds the transition to be applied when moving an
-    item within the positioner. Positioner transitions will only affect
-    the position (x, y) of items.
-
-    This transition can be performed when other items are added or removed
-    from the positioner, or when items resize themselves.
-
-    \qml
-    Flow {
-        id: positioner
-        move: Transition {
-            NumberAnimation {
-                properties: "x,y"
-                ease: "easeOutBounce"
-            }
-        }
-    }
-    \endqml
-
-    \sa add, {declarative/positioners}{Positioners example}
-*/
-/*!
-  \qmlproperty int QtQuick2::Flow::spacing
-
-  spacing is the amount in pixels left empty between each adjacent
-  item, and defaults to 0.
-
-  \sa Grid::spacing
-*/
-
-class QSGFlowPrivate : public QSGBasePositionerPrivate
-{
-    Q_DECLARE_PUBLIC(QSGFlow)
-
-public:
-    QSGFlowPrivate()
-        : QSGBasePositionerPrivate(), flow(QSGFlow::LeftToRight)
-    {}
-
-    QSGFlow::Flow flow;
-};
-
-QSGFlow::QSGFlow(QSGItem *parent)
-: QSGBasePositioner(*(new QSGFlowPrivate), Both, parent)
-{
-    Q_D(QSGFlow);
-    // Flow layout requires relayout if its own size changes too.
-    d->addItemChangeListener(d, QSGItemPrivate::Geometry);
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::Flow::flow
-    This property holds the flow of the layout.
-
-    Possible values are:
-
-    \list
-    \o Flow.LeftToRight (default) - Items are positioned next to
-    to each other according to the \l layoutDirection until the width of the Flow
-    is exceeded, then wrapped to the next line.
-    \o Flow.TopToBottom - Items are positioned next to each
-    other from top to bottom until the height of the Flow is exceeded,
-    then wrapped to the next column.
-    \endlist
-*/
-QSGFlow::Flow QSGFlow::flow() const
-{
-    Q_D(const QSGFlow);
-    return d->flow;
-}
-
-void QSGFlow::setFlow(Flow flow)
-{
-    Q_D(QSGFlow);
-    if (d->flow != flow) {
-        d->flow = flow;
-        prePositioning();
-        emit flowChanged();
-    }
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::Flow::layoutDirection
-
-    This property holds the layout direction of the layout.
-
-    Possible values are:
-
-    \list
-    \o Qt.LeftToRight (default) - Items are positioned from the top to bottom,
-    and left to right. The flow direction is dependent on the
-    \l Flow::flow property.
-    \o Qt.RightToLeft - Items are positioned from the top to bottom,
-    and right to left. The flow direction is dependent on the
-    \l Flow::flow property.
-    \endlist
-
-    \sa Grid::layoutDirection, Row::layoutDirection, {declarative/righttoleft/layoutdirection}{Layout directions example}
-*/
-
-Qt::LayoutDirection QSGFlow::layoutDirection() const
-{
-    Q_D(const QSGFlow);
-    return d->layoutDirection;
-}
-
-void QSGFlow::setLayoutDirection(Qt::LayoutDirection layoutDirection)
-{
-    Q_D(QSGFlow);
-    if (d->layoutDirection != layoutDirection) {
-        d->layoutDirection = layoutDirection;
-        prePositioning();
-        emit layoutDirectionChanged();
-        emit effectiveLayoutDirectionChanged();
-    }
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::Flow::effectiveLayoutDirection
-    This property holds the effective layout direction of the flow positioner.
-
-    When using the attached property \l {LayoutMirroring::enabled}{LayoutMirroring::enabled} for locale layouts,
-    the visual layout direction of the grid positioner will be mirrored. However, the
-    property \l {Flow::layoutDirection}{layoutDirection} will remain unchanged.
-
-    \sa Flow::layoutDirection, {LayoutMirroring}{LayoutMirroring}
-*/
-
-Qt::LayoutDirection QSGFlow::effectiveLayoutDirection() const
-{
-    return QSGBasePositionerPrivate::getEffectiveLayoutDirection(this);
-}
-
-void QSGFlow::doPositioning(QSizeF *contentSize)
-{
-    Q_D(QSGFlow);
-
-    int hoffset = 0;
-    int voffset = 0;
-    int linemax = 0;
-    QList<int> hoffsets;
-
-    for (int i = 0; i < positionedItems.count(); ++i) {
-        const PositionedItem &child = positionedItems.at(i);
-        if (!child.item || !child.isVisible)
-            continue;
-
-        if (d->flow == LeftToRight)  {
-            if (widthValid() && hoffset && hoffset + child.item->width() > width()) {
-                hoffset = 0;
-                voffset += linemax + spacing();
-                linemax = 0;
-            }
-        } else {
-            if (heightValid() && voffset && voffset + child.item->height() > height()) {
-                voffset = 0;
-                hoffset += linemax + spacing();
-                linemax = 0;
-            }
-        }
-
-        if (d->isLeftToRight()) {
-            if (child.item->x() != hoffset)
-                positionX(hoffset, child);
-        } else {
-            hoffsets << hoffset;
-        }
-        if (child.item->y() != voffset)
-            positionY(voffset, child);
-
-        contentSize->setWidth(qMax(contentSize->width(), hoffset + child.item->width()));
-        contentSize->setHeight(qMax(contentSize->height(), voffset + child.item->height()));
-
-        if (d->flow == LeftToRight)  {
-            hoffset += child.item->width();
-            hoffset += spacing();
-            linemax = qMax(linemax, qCeil(child.item->height()));
-        } else {
-            voffset += child.item->height();
-            voffset += spacing();
-            linemax = qMax(linemax, qCeil(child.item->width()));
-        }
-    }
-    if (d->isLeftToRight())
-        return;
-
-    int end;
-    if (widthValid())
-        end = width();
-    else
-        end = contentSize->width();
-    int acc = 0;
-    for (int i = 0; i < positionedItems.count(); ++i) {
-        const PositionedItem &child = positionedItems.at(i);
-        if (!child.item || !child.isVisible)
-            continue;
-        hoffset = end - hoffsets[acc++] - child.item->width();
-        if (child.item->x() != hoffset)
-            positionX(hoffset, child);
-    }
-}
-
-void QSGFlow::reportConflictingAnchors()
-{
-    Q_D(QSGFlow);
-    for (int ii = 0; ii < positionedItems.count(); ++ii) {
-        const PositionedItem &child = positionedItems.at(ii);
-        if (child.item) {
-            QSGAnchors *anchors = QSGItemPrivate::get(static_cast<QSGItem *>(child.item))->_anchors;
-            if (anchors && (anchors->usedAnchors() || anchors->fill() || anchors->centerIn())) {
-                d->anchorConflict = true;
-                break;
-            }
-        }
-    }
-    if (d->anchorConflict)
-        qmlInfo(this) << "Cannot specify anchors for items inside Flow";
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgpositioners_p.h b/src/declarative/items/qsgpositioners_p.h
deleted file mode 100644 (file)
index f871125..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-// Commit: 2c7cab4172f1acc86fd49345a2847417e162f2c3
-/****************************************************************************
-**
-** 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 QSGPOSITIONERS_P_H
-#define QSGPOSITIONERS_P_H
-
-#include "qsgimplicitsizeitem_p.h"
-
-#include <private/qdeclarativestate_p.h>
-#include <private/qpodvector_p.h>
-
-#include <QtCore/qobject.h>
-#include <QtCore/qstring.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGBasePositionerPrivate;
-
-class QSGPositionerAttached : public QObject
-{
-    Q_OBJECT
-
-public:
-    QSGPositionerAttached(QObject *parent);
-
-    Q_PROPERTY(int index READ index NOTIFY indexChanged)
-    Q_PROPERTY(bool isFirstItem READ isFirstItem NOTIFY isFirstItemChanged)
-    Q_PROPERTY(bool isLastItem READ isLastItem NOTIFY isLastItemChanged)
-
-    int index() const { return m_index; }
-    void setIndex(int index);
-
-    bool isFirstItem() const { return m_isFirstItem; }
-    void setIsFirstItem(bool isFirstItem);
-
-    bool isLastItem() const { return m_isLastItem; }
-    void setIsLastItem(bool isLastItem);
-
-Q_SIGNALS:
-    void indexChanged();
-    void isFirstItemChanged();
-    void isLastItemChanged();
-
-private:
-    int m_index;
-    bool m_isFirstItem;
-    bool m_isLastItem;
-};
-
-class Q_DECLARATIVE_PRIVATE_EXPORT QSGBasePositioner : public QSGImplicitSizeItem
-{
-    Q_OBJECT
-
-    Q_PROPERTY(int spacing READ spacing WRITE setSpacing NOTIFY spacingChanged)
-    Q_PROPERTY(QDeclarativeTransition *move READ move WRITE setMove NOTIFY moveChanged)
-    Q_PROPERTY(QDeclarativeTransition *add READ add WRITE setAdd NOTIFY addChanged)
-public:
-    enum PositionerType { None = 0x0, Horizontal = 0x1, Vertical = 0x2, Both = 0x3 };
-    QSGBasePositioner(PositionerType, QSGItem *parent);
-    ~QSGBasePositioner();
-
-    int spacing() const;
-    void setSpacing(int);
-
-    QDeclarativeTransition *move() const;
-    void setMove(QDeclarativeTransition *);
-
-    QDeclarativeTransition *add() const;
-    void setAdd(QDeclarativeTransition *);
-
-    static QSGPositionerAttached *qmlAttachedProperties(QObject *obj);
-
-    void updateAttachedProperties(QSGPositionerAttached *specificProperty = 0, QSGItem *specificPropertyOwner = 0) const;
-
-protected:
-    QSGBasePositioner(QSGBasePositionerPrivate &dd, PositionerType at, QSGItem *parent);
-    virtual void componentComplete();
-    virtual void itemChange(ItemChange, const ItemChangeData &);
-    void finishApplyTransitions();
-
-    virtual void updatePolish();
-
-Q_SIGNALS:
-    void spacingChanged();
-    void moveChanged();
-    void addChanged();
-
-protected Q_SLOTS:
-    void prePositioning();
-
-protected:
-    virtual void doPositioning(QSizeF *contentSize)=0;
-    virtual void reportConflictingAnchors()=0;
-    class PositionedItem {
-    public :
-        PositionedItem(QSGItem *i) : item(i), isNew(false), isVisible(true) {}
-        bool operator==(const PositionedItem &other) const { return other.item == item; }
-        QSGItem *item;
-        bool isNew;
-        bool isVisible;
-    };
-
-    QPODVector<PositionedItem,8> positionedItems;
-    void positionX(int,const PositionedItem &target);
-    void positionY(int,const PositionedItem &target);
-
-private:
-    Q_DISABLE_COPY(QSGBasePositioner)
-    Q_DECLARE_PRIVATE(QSGBasePositioner)
-};
-
-class Q_AUTOTEST_EXPORT QSGColumn : public QSGBasePositioner
-{
-    Q_OBJECT
-public:
-    QSGColumn(QSGItem *parent=0);
-
-protected:
-    virtual void doPositioning(QSizeF *contentSize);
-    virtual void reportConflictingAnchors();
-private:
-    Q_DISABLE_COPY(QSGColumn)
-};
-
-class Q_AUTOTEST_EXPORT QSGRow: public QSGBasePositioner
-{
-    Q_OBJECT
-    Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
-    Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
-public:
-    QSGRow(QSGItem *parent=0);
-
-    Qt::LayoutDirection layoutDirection() const;
-    void setLayoutDirection (Qt::LayoutDirection);
-    Qt::LayoutDirection effectiveLayoutDirection() const;
-
-Q_SIGNALS:
-    void layoutDirectionChanged();
-    void effectiveLayoutDirectionChanged();
-
-protected:
-    virtual void doPositioning(QSizeF *contentSize);
-    virtual void reportConflictingAnchors();
-private:
-    Q_DISABLE_COPY(QSGRow)
-};
-
-class Q_AUTOTEST_EXPORT QSGGrid : public QSGBasePositioner
-{
-    Q_OBJECT
-    Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged)
-    Q_PROPERTY(int columns READ columns WRITE setColumns NOTIFY columnsChanged)
-    Q_PROPERTY(int rowSpacing READ rowSpacing WRITE setRowSpacing NOTIFY rowSpacingChanged)
-    Q_PROPERTY(int columnSpacing READ columnSpacing WRITE setColumnSpacing NOTIFY columnSpacingChanged)
-    Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged)
-    Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
-    Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
-
-public:
-    QSGGrid(QSGItem *parent=0);
-
-    int rows() const {return m_rows;}
-    void setRows(const int rows);
-
-    int columns() const {return m_columns;}
-    void setColumns(const int columns);
-
-    int rowSpacing() const { return m_rowSpacing; }
-    void setRowSpacing(int);
-
-    int columnSpacing() const { return m_columnSpacing; }
-    void setColumnSpacing(int);
-
-    Q_ENUMS(Flow)
-    enum Flow { LeftToRight, TopToBottom };
-    Flow flow() const;
-    void setFlow(Flow);
-
-    Qt::LayoutDirection layoutDirection() const;
-    void setLayoutDirection (Qt::LayoutDirection);
-    Qt::LayoutDirection effectiveLayoutDirection() const;
-
-Q_SIGNALS:
-    void rowsChanged();
-    void columnsChanged();
-    void flowChanged();
-    void layoutDirectionChanged();
-    void effectiveLayoutDirectionChanged();
-    void rowSpacingChanged();
-    void columnSpacingChanged();
-
-protected:
-    virtual void doPositioning(QSizeF *contentSize);
-    virtual void reportConflictingAnchors();
-
-private:
-    int m_rows;
-    int m_columns;
-    int m_rowSpacing;
-    int m_columnSpacing;
-    Flow m_flow;
-    Q_DISABLE_COPY(QSGGrid)
-};
-
-class QSGFlowPrivate;
-class Q_AUTOTEST_EXPORT QSGFlow: public QSGBasePositioner
-{
-    Q_OBJECT
-    Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged)
-    Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
-    Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
-public:
-    QSGFlow(QSGItem *parent=0);
-
-    Q_ENUMS(Flow)
-    enum Flow { LeftToRight, TopToBottom };
-    Flow flow() const;
-    void setFlow(Flow);
-
-    Qt::LayoutDirection layoutDirection() const;
-    void setLayoutDirection (Qt::LayoutDirection);
-    Qt::LayoutDirection effectiveLayoutDirection() const;
-
-Q_SIGNALS:
-    void flowChanged();
-    void layoutDirectionChanged();
-    void effectiveLayoutDirectionChanged();
-
-protected:
-    virtual void doPositioning(QSizeF *contentSize);
-    virtual void reportConflictingAnchors();
-protected:
-    QSGFlow(QSGFlowPrivate &dd, QSGItem *parent);
-private:
-    Q_DISABLE_COPY(QSGFlow)
-    Q_DECLARE_PRIVATE(QSGFlow)
-};
-
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGColumn)
-QML_DECLARE_TYPE(QSGRow)
-QML_DECLARE_TYPE(QSGGrid)
-QML_DECLARE_TYPE(QSGFlow)
-
-QML_DECLARE_TYPE(QSGBasePositioner)
-QML_DECLARE_TYPEINFO(QSGBasePositioner, QML_HAS_ATTACHED_PROPERTIES)
-
-QT_END_HEADER
-
-#endif // QSGPOSITIONERS_P_H
diff --git a/src/declarative/items/qsgpositioners_p_p.h b/src/declarative/items/qsgpositioners_p_p.h
deleted file mode 100644 (file)
index 3c11853..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-// Commit: 2c7cab4172f1acc86fd49345a2847417e162f2c3
-/****************************************************************************
-**
-** 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 QSGPOSITIONERS_P_P_H
-#define QSGPOSITIONERS_P_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 "qsgpositioners_p.h"
-#include "qsgimplicitsizeitem_p_p.h"
-
-#include <private/qdeclarativestate_p.h>
-#include <private/qdeclarativetransitionmanager_p_p.h>
-#include <private/qdeclarativestateoperations_p.h>
-
-#include <QtCore/qobject.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qtimer.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGBasePositionerPrivate : public QSGImplicitSizeItemPrivate, public QSGItemChangeListener
-{
-    Q_DECLARE_PUBLIC(QSGBasePositioner)
-
-public:
-    QSGBasePositionerPrivate()
-        : spacing(0), type(QSGBasePositioner::None)
-        , moveTransition(0), addTransition(0), positioningDirty(false)
-        , doingPositioning(false), anchorConflict(false), layoutDirection(Qt::LeftToRight)
-    {
-    }
-
-    void init(QSGBasePositioner::PositionerType at)
-    {
-        type = at;
-        childrenDoNotOverlap = true;
-    }
-
-    int spacing;
-
-    QSGBasePositioner::PositionerType type;
-    QDeclarativeTransition *moveTransition;
-    QDeclarativeTransition *addTransition;
-    QDeclarativeStateOperation::ActionList addActions;
-    QDeclarativeStateOperation::ActionList moveActions;
-    QDeclarativeTransitionManager addTransitionManager;
-    QDeclarativeTransitionManager moveTransitionManager;
-
-    void watchChanges(QSGItem *other);
-    void unwatchChanges(QSGItem* other);
-    void setPositioningDirty() {
-        Q_Q(QSGBasePositioner);
-        if (!positioningDirty) {
-            positioningDirty = true;
-            q->polish();
-        }
-    }
-
-    bool positioningDirty : 1;
-    bool doingPositioning : 1;
-    bool anchorConflict : 1;
-
-    Qt::LayoutDirection layoutDirection;
-
-    void mirrorChange() {
-        if (type != QSGBasePositioner::Vertical)
-            setPositioningDirty();
-    }
-    bool isLeftToRight() const {
-        if (type == QSGBasePositioner::Vertical)
-            return true;
-        else
-            return effectiveLayoutMirror ? layoutDirection == Qt::RightToLeft : layoutDirection == Qt::LeftToRight;
-    }
-
-    virtual void itemSiblingOrderChanged(QSGItem* other)
-    {
-        Q_UNUSED(other);
-        setPositioningDirty();
-    }
-
-    void itemGeometryChanged(QSGItem *, const QRectF &newGeometry, const QRectF &oldGeometry)
-    {
-        if (newGeometry.size() != oldGeometry.size())
-            setPositioningDirty();
-    }
-
-    virtual void itemVisibilityChanged(QSGItem *)
-    {
-        setPositioningDirty();
-    }
-
-    void itemDestroyed(QSGItem *item)
-    {
-        Q_Q(QSGBasePositioner);
-        q->positionedItems.removeOne(QSGBasePositioner::PositionedItem(item));
-    }
-
-    static Qt::LayoutDirection getLayoutDirection(const QSGBasePositioner *positioner)
-    {
-        return positioner->d_func()->layoutDirection;
-    }
-
-    static Qt::LayoutDirection getEffectiveLayoutDirection(const QSGBasePositioner *positioner)
-    {
-        if (positioner->d_func()->effectiveLayoutMirror)
-            return positioner->d_func()->layoutDirection == Qt::RightToLeft ? Qt::LeftToRight : Qt::RightToLeft;
-        else
-            return positioner->d_func()->layoutDirection;
-    }
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGPOSITIONERS_P_P_H
diff --git a/src/declarative/items/qsgrectangle.cpp b/src/declarative/items/qsgrectangle.cpp
deleted file mode 100644 (file)
index 25f0eda..0000000
+++ /dev/null
@@ -1,555 +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 "qsgrectangle_p.h"
-#include "qsgrectangle_p_p.h"
-
-#include <private/qsgcontext_p.h>
-#include <private/qsgadaptationlayer_p.h>
-
-#include <QtGui/qpixmapcache.h>
-#include <QtCore/qstringbuilder.h>
-#include <QtCore/qmath.h>
-
-QT_BEGIN_NAMESPACE
-
-// XXX todo - should we change rectangle to draw entirely within its width/height?
-/*!
-    \internal
-    \class QSGPen
-    \brief The QSGPen class provides a pen used for drawing rectangle borders on a QSGView.
-
-    By default, the pen is invalid and nothing is drawn. You must either set a color (then the default
-    width is 1) or a width (then the default color is black).
-
-    A width of 1 indicates is a single-pixel line on the border of the item being painted.
-
-    Example:
-    \qml
-    Rectangle {
-        border.width: 2
-        border.color: "red"
-    }
-    \endqml
-*/
-
-QSGPen::QSGPen(QObject *parent)
-    : QObject(parent)
-    , m_width(1)
-    , m_color("#000000")
-    , m_aligned(true)
-    , m_valid(false)
-{
-}
-
-qreal QSGPen::width() const
-{
-    return m_width;
-}
-
-void QSGPen::setWidth(qreal w)
-{
-    if (m_width == w && m_valid)
-        return;
-
-    m_width = w;
-    m_valid = m_color.alpha() && (qRound(m_width) >= 1 || (!m_aligned && m_width > 0));
-    emit penChanged();
-}
-
-QColor QSGPen::color() const
-{
-    return m_color;
-}
-
-void QSGPen::setColor(const QColor &c)
-{
-    m_color = c;
-    m_valid = m_color.alpha() && (qRound(m_width) >= 1 || (!m_aligned && m_width > 0));
-    emit penChanged();
-}
-
-bool QSGPen::aligned() const
-{
-    return m_aligned;
-}
-
-void QSGPen::setAligned(bool aligned)
-{
-    if (aligned == m_aligned)
-        return;
-    m_aligned = aligned;
-    m_valid = m_color.alpha() && (qRound(m_width) >= 1 || (!m_aligned && m_width > 0));
-    emit penChanged();
-}
-
-bool QSGPen::isValid() const
-{
-    return m_valid;
-}
-
-/*!
-    \qmlclass GradientStop QSGGradientStop
-    \inqmlmodule QtQuick 2
-    \ingroup qml-basic-visual-elements
-    \brief The GradientStop item defines the color at a position in a Gradient.
-
-    \sa Gradient
-*/
-
-/*!
-    \qmlproperty real QtQuick2::GradientStop::position
-    \qmlproperty color QtQuick2::GradientStop::color
-
-    The position and color properties describe the color used at a given
-    position in a gradient, as represented by a gradient stop.
-
-    The default position is 0.0; the default color is black.
-
-    \sa Gradient
-*/
-QSGGradientStop::QSGGradientStop(QObject *parent)
-    : QObject(parent)
-{
-}
-
-qreal QSGGradientStop::position() const
-{
-    return m_position;
-}
-
-void QSGGradientStop::setPosition(qreal position)
-{
-    m_position = position; updateGradient();
-}
-
-QColor QSGGradientStop::color() const
-{
-    return m_color;
-}
-
-void QSGGradientStop::setColor(const QColor &color)
-{
-    m_color = color; updateGradient();
-}
-
-void QSGGradientStop::updateGradient()
-{
-    if (QSGGradient *grad = qobject_cast<QSGGradient*>(parent()))
-        grad->doUpdate();
-}
-
-/*!
-    \qmlclass Gradient QSGGradient
-    \inqmlmodule QtQuick 2
-    \ingroup qml-basic-visual-elements
-    \brief The Gradient item defines a gradient fill.
-
-    A gradient is defined by two or more colors, which will be blended seamlessly.
-
-    The colors are specified as a set of GradientStop child items, each of
-    which defines a position on the gradient from 0.0 to 1.0 and a color.
-    The position of each GradientStop is defined by setting its
-    \l{GradientStop::}{position} property; its color is defined using its
-    \l{GradientStop::}{color} property.
-
-    A gradient without any gradient stops is rendered as a solid white fill.
-
-    Note that this item is not a visual representation of a gradient. To display a
-    gradient, use a visual element (like \l Rectangle) which supports the use
-    of gradients.
-
-    \section1 Example Usage
-
-    \div {class="float-right"}
-    \inlineimage qml-gradient.png
-    \enddiv
-
-    The following example declares a \l Rectangle item with a gradient starting
-    with red, blending to yellow at one third of the height of the rectangle,
-    and ending with green:
-
-    \snippet doc/src/snippets/declarative/gradient.qml code
-
-    \clearfloat
-    \section1 Performance and Limitations
-
-    Calculating gradients can be computationally expensive compared to the use
-    of solid color fills or images. Consider using gradients for static items
-    in a user interface.
-
-    In Qt 4.7, only vertical, linear gradients can be applied to items. If you
-    need to apply different orientations of gradients, a combination of rotation
-    and clipping will need to be applied to the relevant items. This can
-    introduce additional performance requirements for your application.
-
-    The use of animations involving gradient stops may not give the desired
-    result. An alternative way to animate gradients is to use pre-generated
-    images or SVG drawings containing gradients.
-
-    \sa GradientStop
-*/
-
-/*!
-    \qmlproperty list<GradientStop> QtQuick2::Gradient::stops
-    \default
-
-    This property holds the gradient stops describing the gradient.
-
-    By default, this property contains an empty list.
-
-    To set the gradient stops, define them as children of the Gradient element.
-*/
-QSGGradient::QSGGradient(QObject *parent)
-: QObject(parent), m_gradient(0)
-{
-}
-
-QSGGradient::~QSGGradient()
-{
-    delete m_gradient;
-}
-
-QDeclarativeListProperty<QSGGradientStop> QSGGradient::stops()
-{
-    return QDeclarativeListProperty<QSGGradientStop>(this, m_stops);
-}
-
-const QGradient *QSGGradient::gradient() const
-{
-    if (!m_gradient && !m_stops.isEmpty()) {
-        m_gradient = new QLinearGradient(0,0,0,1.0);
-        for (int i = 0; i < m_stops.count(); ++i) {
-            const QSGGradientStop *stop = m_stops.at(i);
-            m_gradient->setCoordinateMode(QGradient::ObjectBoundingMode);
-            m_gradient->setColorAt(stop->position(), stop->color());
-        }
-    }
-
-    return m_gradient;
-}
-
-void QSGGradient::doUpdate()
-{
-    delete m_gradient;
-    m_gradient = 0;
-    emit updated();
-}
-
-int QSGRectanglePrivate::doUpdateSlotIdx = -1;
-
-/*!
-    \qmlclass Rectangle QSGRectangle
-    \inqmlmodule QtQuick 2
-    \ingroup qml-basic-visual-elements
-    \brief The Rectangle item provides a filled rectangle with an optional border.
-    \inherits Item
-
-    Rectangle items are used to fill areas with solid color or gradients, and are
-    often used to hold other items.
-
-    \section1 Appearance
-
-    Each Rectangle item is painted using either a solid fill color, specified using
-    the \l color property, or a gradient, defined using a Gradient element and set
-    using the \l gradient property. If both a color and a gradient are specified,
-    the gradient is used.
-
-    You can add an optional border to a rectangle with its own color and thickness
-    by settting the \l border.color and \l border.width properties.
-
-    You can also create rounded rectangles using the \l radius property. Since this
-    introduces curved edges to the corners of a rectangle, it may be appropriate to
-    set the \l smooth property to improve its appearance.
-
-    \section1 Example Usage
-
-    \div {class="float-right"}
-    \inlineimage declarative-rect.png
-    \enddiv
-
-    The following example shows the effects of some of the common properties on a
-    Rectangle item, which in this case is used to create a square:
-
-    \snippet doc/src/snippets/declarative/rectangle/rectangle.qml document
-
-    \clearfloat
-    \section1 Performance
-
-    Using the \l smooth property improves the appearance of a rounded rectangle at
-    the cost of rendering performance. You should consider unsetting this property
-    for rectangles in motion, and only set it when they are stationary.
-
-    \sa Image
-*/
-
-QSGRectangle::QSGRectangle(QSGItem *parent)
-: QSGItem(*(new QSGRectanglePrivate), parent)
-{
-    setFlag(ItemHasContents);
-}
-
-void QSGRectangle::doUpdate()
-{
-    Q_D(QSGRectangle);
-    qreal penMargin = 0;
-    qreal penOffset = 0;
-    if (d->pen && d->pen->isValid()) {
-        if (d->pen->aligned()) {
-            const int pw = qRound(d->pen->width());
-            penMargin = qreal(0.5) * pw;
-            penOffset = (pw & 1) * qreal(0.5);
-        } else {
-            penMargin = qreal(0.5) * d->pen->width();
-        }
-    }
-    if (penMargin != d->penMargin || penOffset != d->penOffset) {
-        d->penMargin = penMargin;
-        d->penOffset = penOffset;
-        d->dirty(QSGItemPrivate::Size); // update clip
-    }
-    update();
-}
-
-/*!
-    \qmlproperty int QtQuick2::Rectangle::border.width
-    \qmlproperty color QtQuick2::Rectangle::border.color
-
-    The width and color used to draw the border of the rectangle.
-
-    A width of 1 creates a thin line. For no line, use a width of 0 or a transparent color.
-
-    \note The width of the rectangle's border does not affect the geometry of the
-    rectangle itself or its position relative to other items if anchors are used.
-
-    If \c border.width is an odd number, the rectangle is painted at a half-pixel offset to retain
-    border smoothness. Also, the border is rendered evenly on either side of the
-    rectangle's boundaries, and the spare pixel is rendered to the right and below the
-    rectangle (as documented for QRect rendering). This can cause unintended effects if
-    \c border.width is 1 and the rectangle is \l{Item::clip}{clipped} by a parent item:
-
-    \div {class="float-right"}
-    \inlineimage rect-border-width.png
-    \enddiv
-
-    \snippet doc/src/snippets/declarative/rectangle/rect-border-width.qml 0
-
-    \clearfloat
-    Here, the innermost rectangle's border is clipped on the bottom and right edges by its
-    parent. To avoid this, the border width can be set to two instead of one.
-*/
-QSGPen *QSGRectangle::border()
-{
-    Q_D(QSGRectangle);
-    return d->getPen();
-}
-
-/*!
-    \qmlproperty Gradient QtQuick2::Rectangle::gradient
-
-    The gradient to use to fill the rectangle.
-
-    This property allows for the construction of simple vertical gradients.
-    Other gradients may by formed by adding rotation to the rectangle.
-
-    \div {class="float-left"}
-    \inlineimage declarative-rect_gradient.png
-    \enddiv
-
-    \snippet doc/src/snippets/declarative/rectangle/rectangle-gradient.qml rectangles
-    \clearfloat
-
-    If both a gradient and a color are specified, the gradient will be used.
-
-    \sa Gradient, color
-*/
-QSGGradient *QSGRectangle::gradient() const
-{
-    Q_D(const QSGRectangle);
-    return d->gradient;
-}
-
-void QSGRectangle::setGradient(QSGGradient *gradient)
-{
-    Q_D(QSGRectangle);
-    if (d->gradient == gradient)
-        return;
-    static int updatedSignalIdx = -1;
-    if (updatedSignalIdx < 0)
-        updatedSignalIdx = QSGGradient::staticMetaObject.indexOfSignal("updated()");
-    if (d->doUpdateSlotIdx < 0)
-        d->doUpdateSlotIdx = QSGRectangle::staticMetaObject.indexOfSlot("doUpdate()");
-    if (d->gradient)
-        QMetaObject::disconnect(d->gradient, updatedSignalIdx, this, d->doUpdateSlotIdx);
-    d->gradient = gradient;
-    if (d->gradient)
-        QMetaObject::connect(d->gradient, updatedSignalIdx, this, d->doUpdateSlotIdx);
-    update();
-}
-
-/*!
-    \qmlproperty real QtQuick2::Rectangle::radius
-    This property holds the corner radius used to draw a rounded rectangle.
-
-    If radius is non-zero, the rectangle will be painted as a rounded rectangle, otherwise it will be
-    painted as a normal rectangle. The same radius is used by all 4 corners; there is currently
-    no way to specify different radii for different corners.
-*/
-qreal QSGRectangle::radius() const
-{
-    Q_D(const QSGRectangle);
-    return d->radius;
-}
-
-void QSGRectangle::setRadius(qreal radius)
-{
-    Q_D(QSGRectangle);
-    if (d->radius == radius)
-        return;
-
-    d->radius = radius;
-    update();
-    emit radiusChanged();
-}
-
-/*!
-    \qmlproperty color QtQuick2::Rectangle::color
-    This property holds the color used to fill the rectangle.
-
-    The default color is white.
-
-    \div {class="float-right"}
-    \inlineimage rect-color.png
-    \enddiv
-
-    The following example shows rectangles with colors specified
-    using hexadecimal and named color notation:
-
-    \snippet doc/src/snippets/declarative/rectangle/rectangle-colors.qml rectangles
-
-    \clearfloat
-    If both a gradient and a color are specified, the gradient will be used.
-
-    \sa gradient
-*/
-QColor QSGRectangle::color() const
-{
-    Q_D(const QSGRectangle);
-    return d->color;
-}
-
-void QSGRectangle::setColor(const QColor &c)
-{
-    Q_D(QSGRectangle);
-    if (d->color == c)
-        return;
-
-    d->color = c;
-    update();
-    emit colorChanged();
-}
-
-QSGNode *QSGRectangle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
-{
-    Q_UNUSED(data);
-    Q_D(QSGRectangle);
-
-    if (width() <= 0 || height() <= 0) {
-        delete oldNode;
-        return 0;
-    }
-
-    QSGRectangleNode *rectangle = static_cast<QSGRectangleNode *>(oldNode);
-    if (!rectangle) rectangle = d->sceneGraphContext()->createRectangleNode();
-
-    rectangle->setRect(QRectF(0, 0, width(), height()));
-    rectangle->setColor(d->color);
-
-    if (d->pen && d->pen->isValid()) {
-        rectangle->setPenColor(d->pen->color());
-        rectangle->setPenWidth(d->pen->width());
-        rectangle->setAligned(d->pen->aligned());
-    } else {
-        rectangle->setPenWidth(0);
-    }
-
-    rectangle->setRadius(d->radius);
-
-    QGradientStops stops;
-    if (d->gradient) {
-        QList<QSGGradientStop *> qxstops = d->gradient->m_stops;
-        for (int i = 0; i < qxstops.size(); ++i){
-            int j = 0;
-            while (j < stops.size() && stops.at(j).first < qxstops[i]->position())
-                j++;
-            stops.insert(j, QGradientStop(qxstops.at(i)->position(), qxstops.at(i)->color()));
-        }
-    }
-    rectangle->setGradientStops(stops);
-
-    rectangle->update();
-
-    return rectangle;
-}
-/*!
-    \qmlproperty bool QtQuick2::Rectangle::smooth
-
-    Set this property if you want the item to be smoothly scaled or
-    transformed.  Smooth filtering gives better visual quality, but is slower.  If
-    the item is displayed at its natural size, this property has no visual or
-    performance effect.
-
-    \note Generally scaling artifacts are only visible if the item is stationary on
-    the screen.  A common pattern when animating an item is to disable smooth
-    filtering at the beginning of the animation and reenable it at the conclusion.
-
-    \image rect-smooth.png
-    On this image, smooth is turned off on the top half and on on the bottom half.
-*/
-
-QRectF QSGRectangle::boundingRect() const
-{
-    Q_D(const QSGRectangle);
-    return QRectF(d->penOffset - d->penMargin, d->penOffset - d->penMargin,
-                  d->width + 2 * d->penMargin, d->height + 2 * d->penMargin);
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgrectangle_p.h b/src/declarative/items/qsgrectangle_p.h
deleted file mode 100644 (file)
index 4d93e66..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
-/****************************************************************************
-**
-** 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 QSGRECTANGLE_P_H
-#define QSGRECTANGLE_P_H
-
-#include "qsgitem.h"
-
-#include <QtGui/qbrush.h>
-
-#include <private/qdeclarativeglobal_p.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-class Q_DECLARATIVE_PRIVATE_EXPORT QSGPen : public QObject
-{
-    Q_OBJECT
-
-    Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY penChanged)
-    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY penChanged)
-    Q_PROPERTY(bool aligned READ aligned WRITE setAligned NOTIFY penChanged)
-public:
-    QSGPen(QObject *parent=0);
-
-    qreal width() const;
-    void setWidth(qreal w);
-
-    QColor color() const;
-    void setColor(const QColor &c);
-
-    bool aligned() const;
-    void setAligned(bool aligned);
-
-    bool isValid() const;
-
-Q_SIGNALS:
-    void penChanged();
-
-private:
-    qreal m_width;
-    QColor m_color;
-    bool m_aligned : 1;
-    bool m_valid : 1;
-};
-
-class Q_AUTOTEST_EXPORT QSGGradientStop : public QObject
-{
-    Q_OBJECT
-
-    Q_PROPERTY(qreal position READ position WRITE setPosition)
-    Q_PROPERTY(QColor color READ color WRITE setColor)
-
-public:
-    QSGGradientStop(QObject *parent=0);
-
-    qreal position() const;
-    void setPosition(qreal position);
-
-    QColor color() const;
-    void setColor(const QColor &color);
-
-private:
-    void updateGradient();
-
-private:
-    qreal m_position;
-    QColor m_color;
-};
-
-class Q_AUTOTEST_EXPORT QSGGradient : public QObject
-{
-    Q_OBJECT
-
-    Q_PROPERTY(QDeclarativeListProperty<QSGGradientStop> stops READ stops)
-    Q_CLASSINFO("DefaultProperty", "stops")
-
-public:
-    QSGGradient(QObject *parent=0);
-    ~QSGGradient();
-
-    QDeclarativeListProperty<QSGGradientStop> stops();
-
-    const QGradient *gradient() const;
-
-Q_SIGNALS:
-    void updated();
-
-private:
-    void doUpdate();
-
-private:
-    QList<QSGGradientStop *> m_stops;
-    mutable QGradient *m_gradient;
-    friend class QSGRectangle;
-    friend class QSGGradientStop;
-};
-
-class QSGRectanglePrivate;
-class Q_DECLARATIVE_PRIVATE_EXPORT QSGRectangle : public QSGItem
-{
-    Q_OBJECT
-
-    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
-    Q_PROPERTY(QSGGradient *gradient READ gradient WRITE setGradient)
-    Q_PROPERTY(QSGPen * border READ border CONSTANT)
-    Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged)
-public:
-    QSGRectangle(QSGItem *parent=0);
-
-    QColor color() const;
-    void setColor(const QColor &);
-
-    QSGPen *border();
-
-    QSGGradient *gradient() const;
-    void setGradient(QSGGradient *gradient);
-
-    qreal radius() const;
-    void setRadius(qreal radius);
-
-    virtual QRectF boundingRect() const;
-
-Q_SIGNALS:
-    void colorChanged();
-    void radiusChanged();
-
-protected:
-    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
-
-private Q_SLOTS:
-    void doUpdate();
-
-private:
-    Q_DISABLE_COPY(QSGRectangle)
-    Q_DECLARE_PRIVATE(QSGRectangle)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGPen)
-QML_DECLARE_TYPE(QSGGradientStop)
-QML_DECLARE_TYPE(QSGGradient)
-QML_DECLARE_TYPE(QSGRectangle)
-
-QT_END_HEADER
-
-#endif // QSGRECTANGLE_P_H
diff --git a/src/declarative/items/qsgrectangle_p_p.h b/src/declarative/items/qsgrectangle_p_p.h
deleted file mode 100644 (file)
index 234a029..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
-/****************************************************************************
-**
-** 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 QSGRECTANGLE_P_P_H
-#define QSGRECTANGLE_P_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 "qsgitem_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QSGGradient;
-class QSGRectangle;
-class QSGRectanglePrivate : public QSGItemPrivate
-{
-    Q_DECLARE_PUBLIC(QSGRectangle)
-
-public:
-    QSGRectanglePrivate() :
-    color(Qt::white), gradient(0), pen(0), radius(0), penMargin(0), penOffset(0)
-    {
-    }
-
-    ~QSGRectanglePrivate()
-    {
-        delete pen;
-    }
-
-    QColor color;
-    QSGGradient *gradient;
-    QSGPen *pen;
-    qreal radius;
-    qreal penMargin;
-    qreal penOffset;
-    static int doUpdateSlotIdx;
-
-    QSGPen *getPen() {
-        if (!pen) {
-            Q_Q(QSGRectangle);
-            pen = new QSGPen;
-            static int penChangedSignalIdx = -1;
-            if (penChangedSignalIdx < 0)
-                penChangedSignalIdx = QSGPen::staticMetaObject.indexOfSignal("penChanged()");
-            if (doUpdateSlotIdx < 0)
-                doUpdateSlotIdx = QSGRectangle::staticMetaObject.indexOfSlot("doUpdate()");
-            QMetaObject::connect(pen, penChangedSignalIdx, q, doUpdateSlotIdx);
-        }
-        return pen;
-    }
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGRECTANGLE_P_P_H
diff --git a/src/declarative/items/qsgrepeater.cpp b/src/declarative/items/qsgrepeater.cpp
deleted file mode 100644 (file)
index 10adb75..0000000
+++ /dev/null
@@ -1,438 +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 "qsgrepeater_p.h"
-#include "qsgrepeater_p_p.h"
-#include "qsgvisualdatamodel_p.h"
-
-#include <private/qdeclarativeglobal_p.h>
-#include <private/qdeclarativelistaccessor_p.h>
-#include <private/qlistmodelinterface_p.h>
-#include <private/qdeclarativechangeset_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QSGRepeaterPrivate::QSGRepeaterPrivate()
-: model(0), ownModel(false)
-{
-}
-
-QSGRepeaterPrivate::~QSGRepeaterPrivate()
-{
-    if (ownModel)
-        delete model;
-}
-
-/*!
-    \qmlclass Repeater QSGRepeater
-    \inqmlmodule QtQuick 2
-    \ingroup qml-utility-elements
-    \inherits Item
-
-    \brief The Repeater element allows you to repeat an Item-based component using a model.
-
-    The Repeater element is used to create a large number of
-    similar items. Like other view elements, a Repeater has a \l model and a \l delegate:
-    for each entry in the model, the delegate is instantiated
-    in a context seeded with data from the model. A Repeater item is usually
-    enclosed in a positioner element such as \l Row or \l Column to visually
-    position the multiple delegate items created by the Repeater.
-
-    The following Repeater creates three instances of a \l Rectangle item within
-    a \l Row:
-
-    \snippet doc/src/snippets/declarative/repeaters/repeater.qml import
-    \codeline
-    \snippet doc/src/snippets/declarative/repeaters/repeater.qml simple
-
-    \image repeater-simple.png
-
-    A Repeater's \l model can be any of the supported \l {qmlmodels}{data models}.
-    Additionally, like delegates for other views, a Repeater delegate can access
-    its index within the repeater, as well as the model data relevant to the
-    delegate. See the \l delegate property documentation for details.
-
-    Items instantiated by the Repeater are inserted, in order, as
-    children of the Repeater's parent.  The insertion starts immediately after
-    the repeater's position in its parent stacking list.  This allows
-    a Repeater to be used inside a layout. For example, the following Repeater's
-    items are stacked between a red rectangle and a blue rectangle:
-
-    \snippet doc/src/snippets/declarative/repeaters/repeater.qml layout
-
-    \image repeater.png
-
-
-    \note A Repeater item owns all items it instantiates. Removing or dynamically destroying
-    an item created by a Repeater results in unpredictable behavior.
-
-
-    \section2 Considerations when using Repeater
-
-    The Repeater element creates all of its delegate items when the repeater is first
-    created. This can be inefficient if there are a large number of delegate items and
-    not all of the items are required to be visible at the same time. If this is the case,
-    consider using other view elements like ListView (which only creates delegate items
-    when they are scrolled into view) or use the \l {Dynamic Object Creation} methods to
-    create items as they are required.
-
-    Also, note that Repeater is \l {Item}-based, and can only repeat \l {Item}-derived objects.
-    For example, it cannot be used to repeat QtObjects:
-    \badcode
-    Item {
-        //XXX does not work! Can't repeat QtObject as it doesn't derive from Item.
-        Repeater {
-            model: 10
-            QtObject {}
-        }
-    }
-    \endcode
- */
-
-/*!
-    \qmlsignal QtQuick2::Repeater::onItemAdded(int index, Item item)
-
-    This handler is called when an item is added to the repeater. The \a index
-    parameter holds the index at which the item has been inserted within the
-    repeater, and the \a item parameter holds the \l Item that has been added.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Repeater::onItemRemoved(int index, Item item)
-
-    This handler is called when an item is removed from the repeater. The \a index
-    parameter holds the index at which the item was removed from the repeater,
-    and the \a item parameter holds the \l Item that was removed.
-
-    Do not keep a reference to \a item if it was created by this repeater, as
-    in these cases it will be deleted shortly after the handler is called.
-*/
-QSGRepeater::QSGRepeater(QSGItem *parent)
-  : QSGItem(*(new QSGRepeaterPrivate), parent)
-{
-}
-
-QSGRepeater::~QSGRepeater()
-{
-}
-
-/*!
-    \qmlproperty any QtQuick2::Repeater::model
-
-    The model providing data for the repeater.
-
-    This property can be set to any of the supported \l {qmlmodels}{data models}:
-
-    \list
-    \o A number that indicates the number of delegates to be created by the repeater
-    \o A model (e.g. a ListModel item, or a QAbstractItemModel subclass)
-    \o A string list
-    \o An object list
-    \endlist
-
-    The type of model affects the properties that are exposed to the \l delegate.
-
-    \sa {qmlmodels}{Data Models}
-*/
-QVariant QSGRepeater::model() const
-{
-    Q_D(const QSGRepeater);
-    return d->dataSource;
-}
-
-void QSGRepeater::setModel(const QVariant &model)
-{
-    Q_D(QSGRepeater);
-    if (d->dataSource == model)
-        return;
-
-    clear();
-    if (d->model) {
-        disconnect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
-                this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
-        /*
-        disconnect(d->model, SIGNAL(createdItem(int,QSGItem*)), this, SLOT(createdItem(int,QSGItem*)));
-        disconnect(d->model, SIGNAL(destroyingItem(QSGItem*)), this, SLOT(destroyingItem(QSGItem*)));
-    */
-    }
-    d->dataSource = model;
-    QObject *object = qvariant_cast<QObject*>(model);
-    QSGVisualModel *vim = 0;
-    if (object && (vim = qobject_cast<QSGVisualModel *>(object))) {
-        if (d->ownModel) {
-            delete d->model;
-            d->ownModel = false;
-        }
-        d->model = vim;
-    } else {
-        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);
-    }
-    if (d->model) {
-        connect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
-                this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
-        /*
-        connect(d->model, SIGNAL(createdItem(int,QSGItem*)), this, SLOT(createdItem(int,QSGItem*)));
-        connect(d->model, SIGNAL(destroyingItem(QSGItem*)), this, SLOT(destroyingItem(QSGItem*)));
-        */
-        regenerate();
-    }
-    emit modelChanged();
-    emit countChanged();
-}
-
-/*!
-    \qmlproperty Component QtQuick2::Repeater::delegate
-    \default
-
-    The delegate provides a template defining each item instantiated by the repeater.
-
-    Delegates are exposed to a read-only \c index property that indicates the index
-    of the delegate within the repeater. For example, the following \l Text delegate
-    displays the index of each repeated item:
-
-    \table
-    \row
-    \o \snippet doc/src/snippets/declarative/repeaters/repeater.qml index
-    \o \image repeater-index.png
-    \endtable
-
-    If the \l model is a \l{QStringList-based model}{string list} or
-    \l{QObjectList-based model}{object list}, the delegate is also exposed to
-    a read-only \c modelData property that holds the string or object data. For
-    example:
-
-    \table
-    \row
-    \o \snippet doc/src/snippets/declarative/repeaters/repeater.qml modeldata
-    \o \image repeater-modeldata.png
-    \endtable
-
-    If the \l model is a model object (such as a \l ListModel) the delegate
-    can access all model roles as named properties, in the same way that delegates
-    do for view classes like ListView.
-
-    \sa {QML Data Models}
- */
-QDeclarativeComponent *QSGRepeater::delegate() const
-{
-    Q_D(const QSGRepeater);
-    if (d->model) {
-        if (QSGVisualDataModel *dataModel = qobject_cast<QSGVisualDataModel*>(d->model))
-            return dataModel->delegate();
-    }
-
-    return 0;
-}
-
-void QSGRepeater::setDelegate(QDeclarativeComponent *delegate)
-{
-    Q_D(QSGRepeater);
-    if (QSGVisualDataModel *dataModel = qobject_cast<QSGVisualDataModel*>(d->model))
-       if (delegate == dataModel->delegate())
-           return;
-
-    if (!d->ownModel) {
-        d->model = new QSGVisualDataModel(qmlContext(this));
-        d->ownModel = true;
-    }
-    if (QSGVisualDataModel *dataModel = qobject_cast<QSGVisualDataModel*>(d->model)) {
-        dataModel->setDelegate(delegate);
-        regenerate();
-        emit delegateChanged();
-    }
-}
-
-/*!
-    \qmlproperty int QtQuick2::Repeater::count
-
-    This property holds the number of items in the repeater.
-*/
-int QSGRepeater::count() const
-{
-    Q_D(const QSGRepeater);
-    if (d->model)
-        return d->model->count();
-    return 0;
-}
-
-/*!
-    \qmlmethod Item QtQuick2::Repeater::itemAt(index)
-
-    Returns the \l Item that has been created at the given \a index, or \c null
-    if no item exists at \a index.
-*/
-QSGItem *QSGRepeater::itemAt(int index) const
-{
-    Q_D(const QSGRepeater);
-    if (index >= 0 && index < d->deletables.count())
-        return d->deletables[index];
-    return 0;
-}
-
-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)
-{
-    QSGItem::itemChange(change, value);
-    if (change == ItemParentHasChanged) {
-        regenerate();
-    }
-}
-
-void QSGRepeater::clear()
-{
-    Q_D(QSGRepeater);
-    bool complete = isComponentComplete();
-
-    if (d->model) {
-        while (d->deletables.count() > 0) {
-            QSGItem *item = d->deletables.takeLast();
-            if (complete)
-                emit itemRemoved(d->deletables.count()-1, item);
-            d->model->release(item);
-        }
-    }
-    d->deletables.clear();
-}
-
-void QSGRepeater::regenerate()
-{
-    Q_D(QSGRepeater);
-    if (!isComponentComplete())
-        return;
-
-    clear();
-
-    if (!d->model || !d->model->count() || !d->model->isValid() || !parentItem() || !isComponentComplete())
-        return;
-
-    for (int ii = 0; ii < count(); ++ii) {
-        QSGItem *item = d->model->item(ii);
-        if (item) {
-            QDeclarative_setParent_noEvent(item, parentItem());
-            item->setParentItem(parentItem());
-            item->stackBefore(this);
-            d->deletables << item;
-            emit itemAdded(ii, item);
-        }
-    }
-}
-
-void QSGRepeater::modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset)
-{
-    Q_D(QSGRepeater);
-
-    if (!isComponentComplete())
-        return;
-
-    if (reset) {
-        regenerate();
-        emit countChanged();
-    }
-
-    int difference = 0;
-    QHash<int, QList<QPointer<QSGItem> > > moved;
-    foreach (const QDeclarativeChangeSet::Remove &remove, changeSet.removes()) {
-        int index = qMin(remove.index, d->deletables.count());
-        int count = qMin(remove.index + remove.count, d->deletables.count()) - index;
-        if (remove.isMove()) {
-            moved.insert(remove.moveId, d->deletables.mid(index, count));
-            d->deletables.erase(
-                    d->deletables.begin() + index,
-                    d->deletables.begin() + index + count);
-        } else while (count--) {
-            QSGItem *item = d->deletables.takeAt(index);
-            emit itemRemoved(index, item);
-            if (item)
-                d->model->release(item);
-        }
-
-        difference -= remove.count;
-    }
-
-    foreach (const QDeclarativeChangeSet::Insert &insert, changeSet.inserts()) {
-        int index = qMin(insert.index, d->deletables.count());
-        if (insert.isMove()) {
-            QList<QPointer<QSGItem> > items = moved.value(insert.moveId);
-            d->deletables = d->deletables.mid(0, index) + items + d->deletables.mid(index);
-            QSGItem *stackBefore = index + items.count() < d->deletables.count()
-                    ? d->deletables.at(index + items.count())
-                    : this;
-            for (int i = index; i < index + items.count(); ++i)
-                d->deletables.at(i)->stackBefore(stackBefore);
-        } else for (int i = 0; i < insert.count; ++i) {
-            int modelIndex = index + i;
-            QSGItem *item = d->model->item(modelIndex);
-            if (item) {
-                QDeclarative_setParent_noEvent(item, parentItem());
-                item->setParentItem(parentItem());
-                if (modelIndex < d->deletables.count())
-                    item->stackBefore(d->deletables.at(modelIndex));
-                else
-                    item->stackBefore(this);
-                d->deletables.insert(modelIndex, item);
-                emit itemAdded(modelIndex, item);
-            }
-        }
-        difference += insert.count;
-    }
-
-    if (difference != 0)
-        emit countChanged();
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgrepeater_p.h b/src/declarative/items/qsgrepeater_p.h
deleted file mode 100644 (file)
index 2094d94..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-// Commit: ebd4bc73c46c2962742a682b6a391fb68c482aec
-/****************************************************************************
-**
-** 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 QSGREPEATER_P_H
-#define QSGREPEATER_P_H
-
-#include "qsgitem.h"
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QDeclarativeChangeSet;
-
-class QSGRepeaterPrivate;
-class Q_AUTOTEST_EXPORT QSGRepeater : public QSGItem
-{
-    Q_OBJECT
-
-    Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged)
-    Q_PROPERTY(QDeclarativeComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
-    Q_PROPERTY(int count READ count NOTIFY countChanged)
-    Q_CLASSINFO("DefaultProperty", "delegate")
-
-public:
-    QSGRepeater(QSGItem *parent=0);
-    virtual ~QSGRepeater();
-
-    QVariant model() const;
-    void setModel(const QVariant &);
-
-    QDeclarativeComponent *delegate() const;
-    void setDelegate(QDeclarativeComponent *);
-
-    int count() const;
-
-    Q_INVOKABLE QSGItem *itemAt(int index) const;
-
-Q_SIGNALS:
-    void modelChanged();
-    void delegateChanged();
-    void countChanged();
-
-    void itemAdded(int index, QSGItem *item);
-    void itemRemoved(int index, QSGItem *item);
-
-private:
-    void clear();
-    void regenerate();
-
-protected:
-    virtual void componentComplete();
-    void itemChange(ItemChange change, const ItemChangeData &value);
-
-private Q_SLOTS:
-    void modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset);
-
-private:
-    Q_DISABLE_COPY(QSGRepeater)
-    Q_DECLARE_PRIVATE(QSGRepeater)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGRepeater)
-
-QT_END_HEADER
-
-#endif // QSGREPEATER_P_H
diff --git a/src/declarative/items/qsgrepeater_p_p.h b/src/declarative/items/qsgrepeater_p_p.h
deleted file mode 100644 (file)
index ae4c78e..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
-/****************************************************************************
-**
-** 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 QSGREPEATER_P_P_H
-#define QSGREPEATER_P_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 "qsgrepeater_p.h"
-#include "qsgitem_p.h"
-
-#include <QtCore/qpointer.h>
-
-QT_BEGIN_NAMESPACE
-
-class QDeclarativeContext;
-class QSGVisualModel;
-class QSGRepeaterPrivate : public QSGItemPrivate
-{
-    Q_DECLARE_PUBLIC(QSGRepeater)
-
-public:
-    QSGRepeaterPrivate();
-    ~QSGRepeaterPrivate();
-
-    QSGVisualModel *model;
-    QVariant dataSource;
-    bool ownModel;
-
-    QList<QPointer<QSGItem> > deletables;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGREPEATER_P_P_H
diff --git a/src/declarative/items/qsgscalegrid.cpp b/src/declarative/items/qsgscalegrid.cpp
deleted file mode 100644 (file)
index 1c4ce8d..0000000
+++ /dev/null
@@ -1,214 +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 "qsgscalegrid_p_p.h"
-
-#include <QtDeclarative/qdeclarative.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
-    \internal
-    \class QSGScaleGrid
-    \brief The QSGScaleGrid class allows you to specify a 3x3 grid to use in scaling an image.
-*/
-
-QSGScaleGrid::QSGScaleGrid(QObject *parent) : QObject(parent), _left(0), _top(0), _right(0), _bottom(0)
-{
-}
-
-QSGScaleGrid::~QSGScaleGrid()
-{
-}
-
-bool QSGScaleGrid::isNull() const
-{
-    return !_left && !_top && !_right && !_bottom;
-}
-
-void QSGScaleGrid::setLeft(int pos)
-{
-    if (_left != pos) {
-        _left = pos;
-        emit borderChanged();
-    }
-}
-
-void QSGScaleGrid::setTop(int pos)
-{
-    if (_top != pos) {
-        _top = pos;
-        emit borderChanged();
-    }
-}
-
-void QSGScaleGrid::setRight(int pos)
-{
-    if (_right != pos) {
-        _right = pos;
-        emit borderChanged();
-    }
-}
-
-void QSGScaleGrid::setBottom(int pos)
-{
-    if (_bottom != pos) {
-        _bottom = pos;
-        emit borderChanged();
-    }
-}
-
-QSGGridScaledImage::QSGGridScaledImage()
-: _l(-1), _r(-1), _t(-1), _b(-1),
-  _h(QSGBorderImage::Stretch), _v(QSGBorderImage::Stretch)
-{
-}
-
-QSGGridScaledImage::QSGGridScaledImage(const QSGGridScaledImage &o)
-: _l(o._l), _r(o._r), _t(o._t), _b(o._b), _h(o._h), _v(o._v), _pix(o._pix)
-{
-}
-
-QSGGridScaledImage &QSGGridScaledImage::operator=(const QSGGridScaledImage &o)
-{
-    _l = o._l;
-    _r = o._r;
-    _t = o._t;
-    _b = o._b;
-    _h = o._h;
-    _v = o._v;
-    _pix = o._pix;
-    return *this;
-}
-
-QSGGridScaledImage::QSGGridScaledImage(QIODevice *data)
-: _l(-1), _r(-1), _t(-1), _b(-1), _h(QSGBorderImage::Stretch), _v(QSGBorderImage::Stretch)
-{
-    int l = -1;
-    int r = -1;
-    int t = -1;
-    int b = -1;
-    QString imgFile;
-
-    QByteArray raw;
-    while (raw = data->readLine(), !raw.isEmpty()) {
-        QString line = QString::fromUtf8(raw.trimmed());
-        if (line.isEmpty() || line.startsWith(QLatin1Char('#')))
-            continue;
-
-        int colonId = line.indexOf(QLatin1Char(':'));
-        if (colonId <= 0)
-            return;
-
-        QStringList list;
-        list.append(line.left(colonId).trimmed());
-        list.append(line.mid(colonId+1).trimmed());
-
-        if (list[0] == QLatin1String("border.left"))
-            l = list[1].toInt();
-        else if (list[0] == QLatin1String("border.right"))
-            r = list[1].toInt();
-        else if (list[0] == QLatin1String("border.top"))
-            t = list[1].toInt();
-        else if (list[0] == QLatin1String("border.bottom"))
-            b = list[1].toInt();
-        else if (list[0] == QLatin1String("source"))
-            imgFile = list[1];
-        else if (list[0] == QLatin1String("horizontalTileRule"))
-            _h = stringToRule(list[1]);
-        else if (list[0] == QLatin1String("verticalTileRule"))
-            _v = stringToRule(list[1]);
-    }
-
-    if (l < 0 || r < 0 || t < 0 || b < 0 || imgFile.isEmpty())
-        return;
-
-    _l = l; _r = r; _t = t; _b = b;
-
-    _pix = imgFile;
-    if (_pix.startsWith(QLatin1Char('"')) && _pix.endsWith(QLatin1Char('"')))
-        _pix = _pix.mid(1, _pix.size() - 2); // remove leading/trailing quotes.
-}
-
-QSGBorderImage::TileMode QSGGridScaledImage::stringToRule(const QString &s)
-{
-    if (s == QLatin1String("Stretch"))
-        return QSGBorderImage::Stretch;
-    if (s == QLatin1String("Repeat"))
-        return QSGBorderImage::Repeat;
-    if (s == QLatin1String("Round"))
-        return QSGBorderImage::Round;
-
-    qWarning("QSGGridScaledImage: Invalid tile rule specified. Using Stretch.");
-    return QSGBorderImage::Stretch;
-}
-
-bool QSGGridScaledImage::isValid() const
-{
-    return _l >= 0;
-}
-
-int QSGGridScaledImage::gridLeft() const
-{
-    return _l;
-}
-
-int QSGGridScaledImage::gridRight() const
-{
-    return _r;
-}
-
-int QSGGridScaledImage::gridTop() const
-{
-    return _t;
-}
-
-int QSGGridScaledImage::gridBottom() const
-{
-    return _b;
-}
-
-QString QSGGridScaledImage::pixmapUrl() const
-{
-    return _pix;
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgscalegrid_p_p.h b/src/declarative/items/qsgscalegrid_p_p.h
deleted file mode 100644 (file)
index 03d68c4..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
-/****************************************************************************
-**
-** 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 QSGSCALEGRID_P_P_H
-#define QSGSCALEGRID_P_P_H
-
-#include "qsgborderimage_p.h"
-
-#include <QtDeclarative/qdeclarative.h>
-#include <QtCore/qobject.h>
-
-#include <private/qdeclarativepixmapcache_p.h>
-#include <private/qdeclarativeglobal_p.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class Q_DECLARATIVE_PRIVATE_EXPORT QSGScaleGrid : public QObject
-{
-    Q_OBJECT
-    Q_ENUMS(TileRule)
-
-    Q_PROPERTY(int left READ left WRITE setLeft NOTIFY borderChanged)
-    Q_PROPERTY(int top READ top WRITE setTop NOTIFY borderChanged)
-    Q_PROPERTY(int right READ right WRITE setRight NOTIFY borderChanged)
-    Q_PROPERTY(int bottom READ bottom WRITE setBottom NOTIFY borderChanged)
-
-public:
-    QSGScaleGrid(QObject *parent=0);
-    ~QSGScaleGrid();
-
-    bool isNull() const;
-
-    int left() const { return _left; }
-    void setLeft(int);
-
-    int top() const { return _top; }
-    void setTop(int);
-
-    int right() const { return _right; }
-    void setRight(int);
-
-    int  bottom() const { return _bottom; }
-    void setBottom(int);
-
-Q_SIGNALS:
-    void borderChanged();
-
-private:
-    int _left;
-    int _top;
-    int _right;
-    int _bottom;
-};
-
-class Q_DECLARATIVE_PRIVATE_EXPORT QSGGridScaledImage
-{
-public:
-    QSGGridScaledImage();
-    QSGGridScaledImage(const QSGGridScaledImage &);
-    QSGGridScaledImage(QIODevice*);
-    QSGGridScaledImage &operator=(const QSGGridScaledImage &);
-    bool isValid() const;
-    int gridLeft() const;
-    int gridRight() const;
-    int gridTop() const;
-    int gridBottom() const;
-    QSGBorderImage::TileMode horizontalTileRule() const { return _h; }
-    QSGBorderImage::TileMode verticalTileRule() const { return _v; }
-
-    QString pixmapUrl() const;
-
-private:
-    static QSGBorderImage::TileMode stringToRule(const QString &);
-
-private:
-    int _l;
-    int _r;
-    int _t;
-    int _b;
-    QSGBorderImage::TileMode _h;
-    QSGBorderImage::TileMode _v;
-    QString _pix;
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGScaleGrid)
-
-QT_END_HEADER
-
-#endif // QSGSCALEGRID_P_P_H
diff --git a/src/declarative/items/qsgshadereffect.cpp b/src/declarative/items/qsgshadereffect.cpp
deleted file mode 100644 (file)
index f84d023..0000000
+++ /dev/null
@@ -1,649 +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$
-**
-****************************************************************************/
-
-#include <private/qsgshadereffect_p.h>
-#include <private/qsgshadereffectnode_p.h>
-
-#include "qsgmaterial.h"
-#include "qsgitem_p.h"
-
-#include <private/qsgcontext_p.h>
-#include <private/qsgtextureprovider_p.h>
-#include "qsgcanvas.h"
-
-#include "qsgimage_p.h"
-#include "qsgshadereffectsource_p.h"
-
-#include <QtCore/qsignalmapper.h>
-#include <QtGui/qopenglframebufferobject.h>
-
-QT_BEGIN_NAMESPACE
-
-static const char qt_default_vertex_code[] =
-    "uniform highp mat4 qt_Matrix;                                  \n"
-    "attribute highp vec4 qt_Vertex;                                \n"
-    "attribute highp vec2 qt_MultiTexCoord0;                        \n"
-    "varying highp vec2 qt_TexCoord0;                               \n"
-    "void main() {                                                  \n"
-    "    qt_TexCoord0 = qt_MultiTexCoord0;                          \n"
-    "    gl_Position = qt_Matrix * qt_Vertex;                       \n"
-    "}";
-
-static const char qt_default_fragment_code[] =
-    "varying highp vec2 qt_TexCoord0;                                   \n"
-    "uniform sampler2D source;                                          \n"
-    "uniform lowp float qt_Opacity;                                     \n"
-    "void main() {                                                      \n"
-    "    gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;   \n"
-    "}";
-
-static const char qt_position_attribute_name[] = "qt_Vertex";
-static const char qt_texcoord_attribute_name[] = "qt_MultiTexCoord0";
-
-const char *qtPositionAttributeName()
-{
-    return qt_position_attribute_name;
-}
-
-const char *qtTexCoordAttributeName()
-{
-    return qt_texcoord_attribute_name;
-}
-
-// TODO: Remove after grace period.
-QSGShaderEffectItem::QSGShaderEffectItem(QSGItem *parent)
-    : QSGShaderEffect(parent)
-{
-    qWarning("ShaderEffectItem has been deprecated. Use ShaderEffect instead.");
-}
-
-
-/*!
-    \qmlclass ShaderEffect QSGShaderEffect
-    \inqmlmodule QtQuick 2
-    \ingroup qml-basic-visual-elements
-    \brief The ShaderEffect element applies custom shaders to a rectangle.
-    \inherits Item
-
-    The ShaderEffect element applies a custom OpenGL
-    \l{vertexShader}{vertex} and \l{fragmentShader}{fragment} shader to a
-    rectangle. It allows you to write effects such as drop shadow, blur,
-    colorize and page curl directly in QML.
-
-    There are two types of input to the \l vertexShader:
-    uniform variables and attributes. Some are predefined:
-    \list
-    \o uniform mat4 qt_Matrix - combined transformation
-       matrix, the product of the matrices from the root item to this
-       ShaderEffect, and an orthogonal projection.
-    \o uniform float qt_Opacity - combined opacity, the product of the
-       opacities from the root item to this ShaderEffect.
-    \o attribute vec4 qt_Vertex - vertex position, the top-left vertex has
-       position (0, 0), the bottom-right (\l{Item::width}{width},
-       \l{Item::height}{height}).
-    \o attribute vec2 qt_MultiTexCoord0 - texture coordinate, the top-left
-       coordinate is (0, 0), the bottom-right (1, 1).
-    \endlist
-
-    In addition, any property that can be mapped to an OpenGL Shading Language
-    (GLSL) type is available as a uniform variable. The following list shows
-    how properties are mapped to GLSL uniform variables:
-    \list
-    \o bool, int, qreal -> bool, int, float - If the type in the shader is not
-       the same as in QML, the value is converted automatically.
-    \o QColor -> vec4 - When colors are passed to the shader, they are first
-       premultiplied. Thus Qt.rgba(0.2, 0.6, 1.0, 0.5) becomes
-       vec4(0.1, 0.3, 0.5, 0.5) in the shader, for example.
-    \o QRect, QRectF -> vec4 - Qt.rect(x, y, w, h) becomes vec4(x, y, w, h) in
-       the shader.
-    \o QPoint, QPointF, QSize, QSizeF -> vec2
-    \o QVector3D -> vec3
-    \o QTransform -> mat4
-    \o \l Image, \l ShaderEffectSource -> sampler2D - Origin is in the top-left
-       corner, and the color values are premultiplied.
-    \endlist
-
-    The output from the \l fragmentShader should be premultiplied. If
-    \l blending is enabled, source-over blending is used. However, additive
-    blending can be achieved by outputting zero in the alpha channel.
-
-    \row
-    \o \image declarative-shadereffectitem.png
-    \o \qml
-        import QtQuick 2.0
-
-        Rectangle {
-            width: 200; height: 100
-            Row {
-                Image { id: img; sourceSize { width: 100; height: 100 } source: "qt-logo.png" }
-                ShaderEffect {
-                    width: 100; height: 100
-                    property variant src: img
-                    vertexShader: "
-                        uniform highp mat4 qt_Matrix;
-                        attribute highp vec4 qt_Vertex;
-                        attribute highp vec2 qt_MultiTexCoord0;
-                        varying highp vec2 coord;
-                        void main() {
-                            coord = qt_MultiTexCoord0;
-                            gl_Position = qt_Matrix * qt_Vertex;
-                        }"
-                    fragmentShader: "
-                        varying highp vec2 coord;
-                        uniform sampler2D src;
-                        uniform lowp float qt_Opacity;
-                        void main() {
-                            lowp vec4 tex = texture2D(src, coord);
-                            gl_FragColor = vec4(vec3(dot(tex.rgb, vec3(0.344, 0.5, 0.156))), tex.a) * qt_Opacity;
-                        }"
-                }
-            }
-        }
-        \endqml
-    \endrow
-
-    By default, the ShaderEffect consists of four vertices, one for each
-    corner. For non-linear vertex transformations, like page curl, you can
-    specify a fine grid of vertices by specifying a \l mesh resolution.
-
-    \note Scene Graph textures have origin in the top-left corner rather than
-    bottom-left which is common in OpenGL.
-*/
-
-QSGShaderEffect::QSGShaderEffect(QSGItem *parent)
-    : QSGItem(parent)
-    , m_meshResolution(1, 1)
-    , m_mesh(0)
-    , m_cullMode(NoCulling)
-    , m_blending(true)
-    , m_dirtyData(true)
-    , m_programDirty(true)
-    , m_dirtyMesh(true)
-    , m_dirtyGeometry(true)
-{
-    setFlag(QSGItem::ItemHasContents);
-}
-
-QSGShaderEffect::~QSGShaderEffect()
-{
-    reset();
-}
-
-void QSGShaderEffect::componentComplete()
-{
-    updateProperties();
-    QSGItem::componentComplete();
-}
-
-/*!
-    \qmlproperty string QtQuick2::ShaderEffect::fragmentShader
-
-    This property holds the fragment shader's GLSL source code.
-    The default shader passes the texture coordinate along to the fragment
-    shader as "varying highp vec2 qt_TexCoord0".
-*/
-
-void QSGShaderEffect::setFragmentShader(const QByteArray &code)
-{
-    if (m_source.fragmentCode.constData() == code.constData())
-        return;
-    m_source.fragmentCode = code;
-    if (isComponentComplete()) {
-        reset();
-        updateProperties();
-    }
-    emit fragmentShaderChanged();
-}
-
-/*!
-    \qmlproperty string QtQuick2::ShaderEffect::vertexShader
-
-    This property holds the vertex shader's GLSL source code.
-    The default shader expects the texture coordinate to be passed from the
-    vertex shader as "varying highp vec2 qt_TexCoord0", and it samples from a
-    sampler2D named "source".
-*/
-
-void QSGShaderEffect::setVertexShader(const QByteArray &code)
-{
-    if (m_source.vertexCode.constData() == code.constData())
-        return;
-    m_source.vertexCode = code;
-    if (isComponentComplete()) {
-        reset();
-        updateProperties();
-    }
-    emit vertexShaderChanged();
-}
-
-/*!
-    \qmlproperty bool QtQuick2::ShaderEffect::blending
-
-    If this property is true, the output from the \l fragmentShader is blended
-    with the background using source-over blend mode. If false, the background
-    is disregarded. Blending decreases the performance, so you should set this
-    property to false when blending is not needed. The default value is true.
-*/
-
-void QSGShaderEffect::setBlending(bool enable)
-{
-    if (blending() == enable)
-        return;
-
-    m_blending = enable;
-    update();
-
-    emit blendingChanged();
-}
-
-/*!
-    \qmlproperty variant QtQuick2::ShaderEffect::mesh
-
-    This property defines the mesh used to draw the ShaderEffect. It can hold
-    any mesh object deriving from \l QSGShaderEffectMesh, such as \l GridMesh.
-    If a size value is assigned to this property, the ShaderEffect implicitly
-    uses a \l GridMesh with the value as
-    \l{GridMesh::resolution}{mesh resolution}. By default, this property is
-    the size 1x1.
-
-    \sa GridMesh
-*/
-
-QVariant QSGShaderEffect::mesh() const
-{
-    return m_mesh ? qVariantFromValue(static_cast<QObject *>(m_mesh))
-                  : qVariantFromValue(m_meshResolution);
-}
-
-void QSGShaderEffect::setMesh(const QVariant &mesh)
-{
-    QSGShaderEffectMesh *newMesh = qobject_cast<QSGShaderEffectMesh *>(qVariantValue<QObject *>(mesh));
-    if (newMesh && newMesh == m_mesh)
-        return;
-    if (m_mesh)
-        disconnect(m_mesh, SIGNAL(geometryChanged()), this, 0);
-    m_mesh = newMesh;
-    if (m_mesh) {
-        connect(m_mesh, SIGNAL(geometryChanged()), this, SLOT(updateGeometry()));
-    } else {
-        if (qVariantCanConvert<QSize>(mesh)) {
-            m_meshResolution = mesh.toSize();
-        } else {
-            QList<QByteArray> res = mesh.toByteArray().split('x');
-            bool ok = res.size() == 2;
-            if (ok) {
-                int w = res.at(0).toInt(&ok);
-                if (ok) {
-                    int h = res.at(1).toInt(&ok);
-                    if (ok)
-                        m_meshResolution = QSize(w, h);
-                }
-            }
-            if (!ok)
-                qWarning("ShaderEffect: mesh property must be size or object deriving from QSGShaderEffectMesh.");
-        }
-        m_defaultMesh.setResolution(m_meshResolution);
-    }
-
-    m_dirtyMesh = true;
-    update();
-    emit meshChanged();
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::ShaderEffect::cullMode
-
-    This property defines which sides of the element should be visible.
-
-    \list
-    \o ShaderEffect.NoCulling - Both sides are visible
-    \o ShaderEffect.BackFaceCulling - only front side is visible
-    \o ShaderEffect.FrontFaceCulling - only back side is visible
-    \endlist
-
-    The default is NoCulling.
-*/
-
-void QSGShaderEffect::setCullMode(CullMode face)
-{
-    if (face == m_cullMode)
-        return;
-    m_cullMode = face;
-    update();
-    emit cullModeChanged();
-}
-
-void QSGShaderEffect::changeSource(int index)
-{
-    Q_ASSERT(index >= 0 && index < m_sources.size());
-    QVariant v = property(m_sources.at(index).name.constData());
-    setSource(v, index);
-}
-
-void QSGShaderEffect::updateData()
-{
-    m_dirtyData = true;
-    update();
-}
-
-void QSGShaderEffect::updateGeometry()
-{
-    m_dirtyGeometry = true;
-    update();
-}
-
-void QSGShaderEffect::setSource(const QVariant &var, int index)
-{
-    Q_ASSERT(index >= 0 && index < m_sources.size());
-
-    SourceData &source = m_sources[index];
-
-    source.sourceObject = 0;
-    if (var.isNull()) {
-        return;
-    } else if (!qVariantCanConvert<QObject *>(var)) {
-        qWarning("Could not assign source of type '%s' to property '%s'.", var.typeName(), source.name.constData());
-        return;
-    }
-
-    QObject *obj = qVariantValue<QObject *>(var);
-    QSGItem *item = qobject_cast<QSGItem *>(obj);
-    if (!item || !item->isTextureProvider()) {
-        qWarning("ShaderEffect: source uniform [%s] is not assigned a valid texture provider: %s [%s]",
-                 source.name.constData(), qPrintable(obj->objectName()), obj->metaObject()->className());
-        return;
-    }
-
-    source.sourceObject = item;
-
-
-    // TODO: Find better solution.
-    // 'item' needs a canvas to get a scenegraph node.
-    // The easiest way to make sure it gets a canvas is to
-    // make it a part of the same item tree as 'this'.
-    if (item && item->parentItem() == 0) {
-        item->setParentItem(this);
-        item->setVisible(false);
-    }
-}
-
-void QSGShaderEffect::disconnectPropertySignals()
-{
-    disconnect(this, 0, this, SLOT(updateData()));
-    for (int i = 0; i < m_sources.size(); ++i) {
-        SourceData &source = m_sources[i];
-        disconnect(this, 0, source.mapper, 0);
-        disconnect(source.mapper, 0, this, 0);
-    }
-}
-
-void QSGShaderEffect::connectPropertySignals()
-{
-    QSet<QByteArray>::const_iterator it;
-    for (it = m_source.uniformNames.begin(); it != m_source.uniformNames.end(); ++it) {
-        int pi = metaObject()->indexOfProperty(it->constData());
-        if (pi >= 0) {
-            QMetaProperty mp = metaObject()->property(pi);
-            if (!mp.hasNotifySignal())
-                qWarning("QSGShaderEffect: property '%s' does not have notification method!", it->constData());
-            QByteArray signalName("2");
-            signalName.append(mp.notifySignal().signature());
-            connect(this, signalName, this, SLOT(updateData()));
-        } else {
-            qWarning("QSGShaderEffect: '%s' does not have a matching property!", it->constData());
-        }
-    }
-    for (int i = 0; i < m_sources.size(); ++i) {
-        SourceData &source = m_sources[i];
-        int pi = metaObject()->indexOfProperty(source.name.constData());
-        if (pi >= 0) {
-            QMetaProperty mp = metaObject()->property(pi);
-            QByteArray signalName("2");
-            signalName.append(mp.notifySignal().signature());
-            connect(this, signalName, source.mapper, SLOT(map()));
-            source.mapper->setMapping(this, i);
-            connect(source.mapper, SIGNAL(mapped(int)), this, SLOT(changeSource(int)));
-        } else {
-            qWarning("QSGShaderEffect: '%s' does not have a matching source!", source.name.constData());
-        }
-    }
-}
-
-void QSGShaderEffect::reset()
-{
-    disconnectPropertySignals();
-
-    m_source.attributeNames.clear();
-    m_source.uniformNames.clear();
-    m_source.respectsOpacity = false;
-    m_source.respectsMatrix = false;
-    m_source.className = metaObject()->className();
-
-    for (int i = 0; i < m_sources.size(); ++i) {
-        const SourceData &source = m_sources.at(i);
-        delete source.mapper;
-        QSGItem *item = qobject_cast<QSGItem *>(source.sourceObject);
-        if (item && item->parentItem() == this)
-            item->setParentItem(0);
-    }
-    m_sources.clear();
-
-    m_programDirty = true;
-    m_dirtyMesh = true;
-}
-
-void QSGShaderEffect::updateProperties()
-{
-    QByteArray vertexCode = m_source.vertexCode;
-    QByteArray fragmentCode = m_source.fragmentCode;
-    if (vertexCode.isEmpty())
-        vertexCode = qt_default_vertex_code;
-    if (fragmentCode.isEmpty())
-        fragmentCode = qt_default_fragment_code;
-
-    lookThroughShaderCode(vertexCode);
-    lookThroughShaderCode(fragmentCode);
-
-    if (!m_mesh && !m_source.attributeNames.contains(qt_position_attribute_name))
-        qWarning("QSGShaderEffect: Missing reference to \'%s\'.", qt_position_attribute_name);
-    if (!m_mesh && !m_source.attributeNames.contains(qt_texcoord_attribute_name))
-        qWarning("QSGShaderEffect: Missing reference to \'%s\'.", qt_texcoord_attribute_name);
-    if (!m_source.respectsMatrix)
-        qWarning("QSGShaderEffect: Missing reference to \'qt_Matrix\'.");
-    if (!m_source.respectsOpacity)
-        qWarning("QSGShaderEffect: Missing reference to \'qt_Opacity\'.");
-
-    for (int i = 0; i < m_sources.size(); ++i) {
-        QVariant v = property(m_sources.at(i).name);
-        setSource(v, i);
-    }
-
-    connectPropertySignals();
-}
-
-void QSGShaderEffect::lookThroughShaderCode(const QByteArray &code)
-{
-    // Regexp for matching attributes and uniforms.
-    // In human readable form: attribute|uniform [lowp|mediump|highp] <type> <name>
-    static QRegExp re(QLatin1String("\\b(attribute|uniform)\\b\\s*\\b(?:lowp|mediump|highp)?\\b\\s*\\b(\\w+)\\b\\s*\\b(\\w+)"));
-    Q_ASSERT(re.isValid());
-
-    int pos = -1;
-
-    QString wideCode = QString::fromLatin1(code.constData(), code.size());
-
-    while ((pos = re.indexIn(wideCode, pos + 1)) != -1) {
-        QByteArray decl = re.cap(1).toLatin1(); // uniform or attribute
-        QByteArray type = re.cap(2).toLatin1(); // type
-        QByteArray name = re.cap(3).toLatin1(); // variable name
-
-        if (decl == "attribute") {
-            m_source.attributeNames.append(name);
-        } else {
-            Q_ASSERT(decl == "uniform");
-
-            if (name == "qt_Matrix") {
-                m_source.respectsMatrix = true;
-            } else if (name == "qt_ModelViewProjectionMatrix") {
-                // TODO: Remove after grace period.
-                qWarning("ShaderEffect: qt_ModelViewProjectionMatrix is deprecated. Use qt_Matrix instead.");
-                m_source.respectsMatrix = true;
-            } else if (name == "qt_Opacity") {
-                m_source.respectsOpacity = true;
-            } else {
-                m_source.uniformNames.insert(name);
-                if (type == "sampler2D") {
-                    SourceData d;
-                    d.mapper = new QSignalMapper;
-                    d.name = name;
-                    d.sourceObject = 0;
-                    m_sources.append(d);
-                }
-            }
-        }
-    }
-}
-
-void QSGShaderEffect::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
-{
-    m_dirtyGeometry = true;
-    QSGItem::geometryChanged(newGeometry, oldGeometry);
-}
-
-QSGNode *QSGShaderEffect::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
-{
-    QSGShaderEffectNode *node = static_cast<QSGShaderEffectNode *>(oldNode);
-
-    // In the case of a bad vertex shader, don't try to create a node...
-    if (m_source.attributeNames.isEmpty()) {
-        if (node)
-            delete node;
-        return 0;
-    }
-
-    if (!node) {
-        node = new QSGShaderEffectNode;
-        m_programDirty = true;
-        m_dirtyData = true;
-        m_dirtyGeometry = true;
-    }
-
-    QSGShaderEffectMaterial *material = node->shaderMaterial();
-
-    if (m_dirtyMesh) {
-        node->setGeometry(0);
-        m_dirtyMesh = false;
-        m_dirtyGeometry = true;
-    }
-
-    if (m_dirtyGeometry) {
-        node->setFlag(QSGNode::OwnsGeometry, false);
-        QSGGeometry *geometry = node->geometry();
-        QRectF rect(0, 0, width(), height());
-        QSGShaderEffectMesh *mesh = m_mesh ? m_mesh : &m_defaultMesh;
-
-        geometry = mesh->updateGeometry(geometry, m_source.attributeNames, rect);
-        if (!geometry) {
-            delete node;
-            return 0;
-        }
-
-        node->setGeometry(geometry);
-        node->setFlag(QSGNode::OwnsGeometry, true);
-
-        m_dirtyGeometry = false;
-    }
-
-    if (m_programDirty) {
-        QSGShaderEffectProgram s = m_source;
-        if (s.fragmentCode.isEmpty())
-            s.fragmentCode = qt_default_fragment_code;
-        if (s.vertexCode.isEmpty())
-            s.vertexCode = qt_default_vertex_code;
-        s.className = metaObject()->className();
-
-        material->setProgramSource(s);
-        node->markDirty(QSGNode::DirtyMaterial);
-        m_programDirty = false;
-    }
-
-    // Update blending
-    if (bool(material->flags() & QSGMaterial::Blending) != m_blending) {
-        material->setFlag(QSGMaterial::Blending, m_blending);
-        node->markDirty(QSGNode::DirtyMaterial);
-    }
-
-    if (int(material->cullMode()) != int(m_cullMode)) {
-        material->setCullMode(QSGShaderEffectMaterial::CullMode(m_cullMode));
-        node->markDirty(QSGNode::DirtyMaterial);
-    }
-
-    if (m_dirtyData) {
-        QVector<QPair<QByteArray, QVariant> > values;
-        QVector<QPair<QByteArray, QSGTextureProvider *> > textures;
-        const QVector<QPair<QByteArray, QSGTextureProvider *> > &oldTextures = material->textureProviders();
-
-        for (QSet<QByteArray>::const_iterator it = m_source.uniformNames.begin();
-             it != m_source.uniformNames.end(); ++it) {
-            values.append(qMakePair(*it, property(*it)));
-        }
-        for (int i = 0; i < oldTextures.size(); ++i) {
-            QSGTextureProvider *t = oldTextures.at(i).second;
-            if (t)
-                disconnect(t, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture()));
-        }
-        for (int i = 0; i < m_sources.size(); ++i) {
-            const SourceData &source = m_sources.at(i);
-            QSGTextureProvider *t = source.sourceObject->textureProvider();
-            textures.append(qMakePair(source.name, t));
-            if (t)
-                connect(t, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture()), Qt::DirectConnection);
-        }
-        material->setUniforms(values);
-        material->setTextureProviders(textures);
-        node->markDirty(QSGNode::DirtyMaterial);
-        m_dirtyData = false;
-    }
-
-    return node;
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgshadereffect_p.h b/src/declarative/items/qsgshadereffect_p.h
deleted file mode 100644 (file)
index 08af5f6..0000000
+++ /dev/null
@@ -1,165 +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 SHADEREFFECTITEM_H
-#define SHADEREFFECTITEM_H
-
-#include "qsgitem.h"
-
-#include "qsgmaterial.h"
-#include <private/qsgadaptationlayer_p.h>
-#include <private/qsgshadereffectnode_p.h>
-#include "qsgshadereffectmesh_p.h"
-
-#include <QtCore/qpointer.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-const char *qtPositionAttributeName();
-const char *qtTexCoordAttributeName();
-
-class QSGContext;
-class QSignalMapper;
-class QSGCustomMaterialShader;
-
-class QSGShaderEffect : public QSGItem
-{
-    Q_OBJECT
-    Q_PROPERTY(QByteArray fragmentShader READ fragmentShader WRITE setFragmentShader NOTIFY fragmentShaderChanged)
-    Q_PROPERTY(QByteArray vertexShader READ vertexShader WRITE setVertexShader NOTIFY vertexShaderChanged)
-    Q_PROPERTY(bool blending READ blending WRITE setBlending NOTIFY blendingChanged)
-    Q_PROPERTY(QVariant mesh READ mesh WRITE setMesh NOTIFY meshChanged)
-    Q_PROPERTY(CullMode culling READ cullMode WRITE setCullMode NOTIFY cullModeChanged)
-    Q_ENUMS(CullMode)
-
-public:
-    enum CullMode
-    {
-        NoCulling = QSGShaderEffectMaterial::NoCulling,
-        BackFaceCulling = QSGShaderEffectMaterial::BackFaceCulling,
-        FrontFaceCulling = QSGShaderEffectMaterial::FrontFaceCulling
-    };
-
-    QSGShaderEffect(QSGItem *parent = 0);
-    ~QSGShaderEffect();
-
-    virtual void componentComplete();
-
-    QByteArray fragmentShader() const { return m_source.fragmentCode; }
-    void setFragmentShader(const QByteArray &code);
-
-    QByteArray vertexShader() const { return m_source.vertexCode; }
-    void setVertexShader(const QByteArray &code);
-
-    bool blending() const { return m_blending; }
-    void setBlending(bool enable);
-
-    QVariant mesh() const;
-    void setMesh(const QVariant &mesh);
-
-    CullMode cullMode() const { return m_cullMode; }
-    void setCullMode(CullMode face);
-
-Q_SIGNALS:
-    void fragmentShaderChanged();
-    void vertexShaderChanged();
-    void blendingChanged();
-    void meshChanged();
-    void cullModeChanged();
-
-protected:
-    virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
-    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
-
-private Q_SLOTS:
-    void changeSource(int index);
-    void updateData();
-    void updateGeometry();
-
-private:
-    friend class QSGCustomMaterialShader;
-    friend class QSGShaderEffectNode;
-
-    void setSource(const QVariant &var, int index);
-    void disconnectPropertySignals();
-    void connectPropertySignals();
-    void reset();
-    void updateProperties();
-    void lookThroughShaderCode(const QByteArray &code);
-
-    QSGShaderEffectProgram m_source;
-    QSize m_meshResolution;
-    QSGShaderEffectMesh *m_mesh;
-    QSGGridMesh m_defaultMesh;
-    CullMode m_cullMode;
-
-    struct SourceData
-    {
-        QSignalMapper *mapper;
-        QPointer<QSGItem> sourceObject;
-        QByteArray name;
-    };
-    QVector<SourceData> m_sources;
-
-    uint m_blending : 1;
-    uint m_dirtyData : 1;
-
-    uint m_programDirty : 1;
-    uint m_dirtyMesh : 1;
-    uint m_dirtyGeometry : 1;
-};
-
-// TODO: Remove after grace period.
-class QSGShaderEffectItem : public QSGShaderEffect
-{
-public:
-    QSGShaderEffectItem(QSGItem *parent = 0);
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // SHADEREFFECTITEM_H
diff --git a/src/declarative/items/qsgshadereffectmesh.cpp b/src/declarative/items/qsgshadereffectmesh.cpp
deleted file mode 100644 (file)
index 53fd917..0000000
+++ /dev/null
@@ -1,215 +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$
-**
-****************************************************************************/
-
-#include "qsgshadereffectmesh_p.h"
-#include "qsggeometry.h"
-#include "qsgshadereffect_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QSGShaderEffectMesh::QSGShaderEffectMesh(QObject *parent)
-    : QObject(parent)
-{
-}
-
-/*!
-    \qmlclass GridMesh QSGGridMesh
-    \inqmlmodule QtQuick 2
-    \ingroup qml-utility-elements
-    \brief GridMesh defines a mesh with vertices arranged in a grid.
-
-    GridMesh defines a rectangular mesh consisting of vertices arranged in an
-    evenly spaced grid. It is used to generate \l{QSGGeometry}{geometry}.
-    The grid resolution is specified with the \l resolution property.
-*/
-
-QSGGridMesh::QSGGridMesh(QObject *parent)
-    : QSGShaderEffectMesh(parent)
-    , m_resolution(1, 1)
-{
-    connect(this, SIGNAL(resolutionChanged()), this, SIGNAL(geometryChanged()));
-}
-
-QSGGeometry *QSGGridMesh::updateGeometry(QSGGeometry *geometry, const QVector<QByteArray> &attributes, const QRectF &dstRect) const
-{
-    int vmesh = m_resolution.height();
-    int hmesh = m_resolution.width();
-    int attrCount = attributes.count();
-
-    if (!geometry) {
-        bool error = true;
-        switch (attrCount) {
-        case 0:
-            qWarning("QSGGridMesh:: No attributes specified.");
-            break;
-        case 1:
-            if (attributes.at(0) == qtPositionAttributeName()) {
-                error = false;
-                break;
-            }
-            qWarning("QSGGridMesh:: Missing \'%s\' attribute.",
-                     qtPositionAttributeName());
-            break;
-        case 2:
-            if (attributes.contains(qtPositionAttributeName())
-                && attributes.contains(qtTexCoordAttributeName()))
-            {
-                error = false;
-                break;
-            }
-            qWarning("QSGGridMesh:: Missing \'%s\' or \'%s\' attribute.",
-                     qtPositionAttributeName(), qtTexCoordAttributeName());
-            break;
-        default:
-            qWarning("QSGGridMesh:: Too many attributes specified.");
-            break;
-        }
-
-        geometry = new QSGGeometry(attrCount == 1
-                                   ? QSGGeometry::defaultAttributes_Point2D()
-                                   : QSGGeometry::defaultAttributes_TexturedPoint2D(),
-                                   (vmesh + 1) * (hmesh + 1), vmesh * 2 * (hmesh + 2),
-                                   GL_UNSIGNED_SHORT);
-
-    } else {
-        geometry->allocate((vmesh + 1) * (hmesh + 1), vmesh * 2 * (hmesh + 2));
-    }
-
-    QSGGeometry::Point2D *vdata = static_cast<QSGGeometry::Point2D *>(geometry->vertexData());
-
-    bool positionFirst = attributes.at(0) == qtPositionAttributeName();
-
-    QRectF srcRect(0, 0, 1, 1);
-    for (int iy = 0; iy <= vmesh; ++iy) {
-        float fy = iy / float(vmesh);
-        float y = float(dstRect.top()) + fy * float(dstRect.height());
-        float ty = float(srcRect.top()) + fy * float(srcRect.height());
-        for (int ix = 0; ix <= hmesh; ++ix) {
-            float fx = ix / float(hmesh);
-            for (int ia = 0; ia < attrCount; ++ia) {
-                if (positionFirst == (ia == 0)) {
-                    vdata->x = float(dstRect.left()) + fx * float(dstRect.width());
-                    vdata->y = y;
-                    ++vdata;
-                } else {
-                    vdata->x = float(srcRect.left()) + fx * float(srcRect.width());
-                    vdata->y = ty;
-                    ++vdata;
-                }
-            }
-        }
-    }
-
-    quint16 *indices = (quint16 *)geometry->indexDataAsUShort();
-    int i = 0;
-    for (int iy = 0; iy < vmesh; ++iy) {
-        *(indices++) = i + hmesh + 1;
-        for (int ix = 0; ix <= hmesh; ++ix, ++i) {
-            *(indices++) = i + hmesh + 1;
-            *(indices++) = i;
-        }
-        *(indices++) = i - 1;
-    }
-
-    return geometry;
-}
-
-/*!
-    \qmlproperty size QtQuick2::GridMesh::resolution
-
-    This property holds the grid resolution. The resolution's width and height
-    specify the number of cells or spacings between vertices horizontally and
-    vertically respectively. The minimum and default is 1x1, which corresponds
-    to four vertices in total, one in each corner.
-    For non-linear vertex transformations, you probably want to set the
-    resolution higher.
-
-    \row
-    \o \image declarative-gridmesh.png
-    \o \qml
-        import QtQuick 2.0
-
-        ShaderEffect {
-            width: 200
-            height: 200
-            mesh: GridMesh {
-                resolution: Qt.size(20, 20)
-            }
-            property variant source: Image {
-                source: "qt-logo.png"
-                sourceSize { width: 200; height: 200 }
-                smooth: true
-            }
-            vertexShader: "
-                uniform highp mat4 qt_Matrix;
-                attribute highp vec4 qt_Vertex;
-                attribute highp vec2 qt_MultiTexCoord0;
-                varying highp vec2 qt_TexCoord0;
-                uniform highp float width;
-                void main() {
-                    highp vec4 pos = qt_Vertex;
-                    highp float d = .5 * smoothstep(0., 1., qt_MultiTexCoord0.y);
-                    pos.x = width * mix(d, 1.0 - d, qt_MultiTexCoord0.x);
-                    gl_Position = qt_Matrix * pos;
-                    qt_TexCoord0 = qt_MultiTexCoord0;
-                }"
-        }
-        \endqml
-    \endrow
-*/
-
-void QSGGridMesh::setResolution(const QSize &res)
-{
-    if (res == m_resolution)
-        return;
-    if (res.width() < 1 || res.height() < 1) {
-        return;
-    }
-    m_resolution = res;
-    emit resolutionChanged();
-}
-
-QSize QSGGridMesh::resolution() const
-{
-    return m_resolution;
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgshadereffectmesh_p.h b/src/declarative/items/qsgshadereffectmesh_p.h
deleted file mode 100644 (file)
index 428674f..0000000
+++ /dev/null
@@ -1,103 +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$
-**
-****************************************************************************/
-
-#include "qdeclarativeparserstatus.h"
-
-#include <QtGui/qcolor.h>
-#include <QtCore/qobject.h>
-#include <QtCore/qsize.h>
-#include <QtCore/qvariant.h>
-#include <QtGui/qopenglfunctions.h>
-
-#ifndef SHADEREFFECTMESH_H
-#define SHADEREFFECTMESH_H
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGGeometry;
-class QRectF;
-
-class Q_DECLARATIVE_EXPORT QSGShaderEffectMesh : public QObject
-{
-    Q_OBJECT
-public:
-    QSGShaderEffectMesh(QObject *parent = 0);
-    // If 'geometry' != 0, 'attributes' is the same as last time the function was called.
-    virtual QSGGeometry *updateGeometry(QSGGeometry *geometry, const QVector<QByteArray> &attributes, const QRectF &rect) const = 0;
-
-Q_SIGNALS:
-    // Emitted when the geometry needs to be updated.
-    void geometryChanged();
-};
-
-class QSGGridMesh : public QSGShaderEffectMesh
-{
-    Q_OBJECT
-    Q_PROPERTY(QSize resolution READ resolution WRITE setResolution NOTIFY resolutionChanged)
-public:
-    QSGGridMesh(QObject *parent = 0);
-    virtual QSGGeometry *updateGeometry(QSGGeometry *geometry, const QVector<QByteArray> &attributes, const QRectF &rect) const;
-
-    void setResolution(const QSize &res);
-    QSize resolution() const;
-
-Q_SIGNALS:
-    void resolutionChanged();
-
-private:
-    QSize m_resolution;
-};
-
-inline QColor qt_premultiply_color(const QColor &c)
-{
-    return QColor::fromRgbF(c.redF() * c.alphaF(), c.greenF() * c.alphaF(), c.blueF() * c.alphaF(), c.alphaF());
-}
-
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // SHADEREFFECTITEM_H
diff --git a/src/declarative/items/qsgshadereffectnode.cpp b/src/declarative/items/qsgshadereffectnode.cpp
deleted file mode 100644 (file)
index c5d2083..0000000
+++ /dev/null
@@ -1,316 +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$
-**
-****************************************************************************/
-
-#include <private/qsgshadereffectnode_p.h>
-
-#include "qsgshadereffectmesh_p.h"
-#include <private/qsgtextureprovider_p.h>
-#include <private/qsgrenderer_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGCustomMaterialShader : public QSGMaterialShader
-{
-public:
-    QSGCustomMaterialShader(const QSGShaderEffectMaterialKey &key, const QVector<QByteArray> &attributes);
-    virtual void deactivate();
-    virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
-    virtual char const *const *attributeNames() const;
-
-protected:
-    friend class QSGShaderEffectNode;
-
-    virtual void initialize();
-    virtual const char *vertexShader() const;
-    virtual const char *fragmentShader() const;
-
-    const QSGShaderEffectMaterialKey m_key;
-    QVector<const char *> m_attributeNames;
-    const QVector<QByteArray> m_attributes;
-
-    QVector<int> m_uniformLocs;
-    int m_opacityLoc;
-    int m_matrixLoc;
-    uint m_textureIndicesSet;
-};
-
-QSGCustomMaterialShader::QSGCustomMaterialShader(const QSGShaderEffectMaterialKey &key, const QVector<QByteArray> &attributes)
-    : m_key(key)
-    , m_attributes(attributes)
-    , m_textureIndicesSet(false)
-{
-    for (int i = 0; i < attributes.count(); ++i)
-        m_attributeNames.append(attributes.at(i).constData());
-    m_attributeNames.append(0);
-}
-
-void QSGCustomMaterialShader::deactivate()
-{
-    QSGMaterialShader::deactivate();
-    glDisable(GL_CULL_FACE);
-}
-
-void QSGCustomMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
-{
-    Q_ASSERT(newEffect != 0);
-
-    const QSGShaderEffectMaterial *material = static_cast<const QSGShaderEffectMaterial *>(newEffect);
-
-    if (!m_textureIndicesSet) {
-        for (int i = 0; i < material->m_textures.size(); ++i)
-            program()->setUniformValue(material->m_textures.at(i).first.constData(), i);
-        m_textureIndicesSet = true;
-    }
-
-    if (m_uniformLocs.size() != material->m_uniformValues.size()) {
-        m_uniformLocs.reserve(material->m_uniformValues.size());
-        for (int i = 0; i < material->m_uniformValues.size(); ++i) {
-            const QByteArray &name = material->m_uniformValues.at(i).first;
-            m_uniformLocs.append(program()->uniformLocation(name.constData()));
-        }
-    }
-
-    QOpenGLFunctions *functions = state.context()->functions();
-    for (int i = material->m_textures.size() - 1; i >= 0; --i) {
-        functions->glActiveTexture(GL_TEXTURE0 + i);
-        if (QSGTextureProvider *provider = material->m_textures.at(i).second) {
-            if (QSGTexture *texture = provider->texture()) {
-                texture->bind();
-                continue;
-            }
-        }
-        qWarning("ShaderEffectItem: source or provider missing when binding textures");
-        glBindTexture(GL_TEXTURE_2D, 0);
-    }
-
-    if (material->m_source.respectsOpacity)
-        program()->setUniformValue(m_opacityLoc, state.opacity());
-
-    for (int i = 0; i < material->m_uniformValues.count(); ++i) {
-        const QVariant &v = material->m_uniformValues.at(i).second;
-
-        switch (v.type()) {
-        case QVariant::Color:
-            program()->setUniformValue(m_uniformLocs.at(i), qt_premultiply_color(qvariant_cast<QColor>(v)));
-            break;
-        case QVariant::Double:
-            program()->setUniformValue(m_uniformLocs.at(i), (float) qvariant_cast<double>(v));
-            break;
-        case QVariant::Transform:
-            program()->setUniformValue(m_uniformLocs.at(i), qvariant_cast<QTransform>(v));
-            break;
-        case QVariant::Int:
-            program()->setUniformValue(m_uniformLocs.at(i), v.toInt());
-            break;
-        case QVariant::Bool:
-            program()->setUniformValue(m_uniformLocs.at(i), GLint(v.toBool()));
-            break;
-        case QVariant::Size:
-        case QVariant::SizeF:
-            program()->setUniformValue(m_uniformLocs.at(i), v.toSizeF());
-            break;
-        case QVariant::Point:
-        case QVariant::PointF:
-            program()->setUniformValue(m_uniformLocs.at(i), v.toPointF());
-            break;
-        case QVariant::Rect:
-        case QVariant::RectF:
-            {
-                QRectF r = v.toRectF();
-                program()->setUniformValue(m_uniformLocs.at(i), r.x(), r.y(), r.width(), r.height());
-            }
-            break;
-        case QVariant::Vector3D:
-            program()->setUniformValue(m_uniformLocs.at(i), qvariant_cast<QVector3D>(v));
-            break;
-        default:
-            break;
-        }
-    }
-
-    const QSGShaderEffectMaterial *oldMaterial = static_cast<const QSGShaderEffectMaterial *>(oldEffect);
-    if (oldEffect == 0 || material->cullMode() != oldMaterial->cullMode()) {
-        switch (material->cullMode()) {
-        case QSGShaderEffectMaterial::FrontFaceCulling:
-            glEnable(GL_CULL_FACE);
-            glCullFace(GL_FRONT);
-            break;
-        case QSGShaderEffectMaterial::BackFaceCulling:
-            glEnable(GL_CULL_FACE);
-            glCullFace(GL_BACK);
-            break;
-        default:
-            glDisable(GL_CULL_FACE);
-            break;
-        }
-    }
-
-    if ((state.isMatrixDirty()) && material->m_source.respectsMatrix)
-        program()->setUniformValue(m_matrixLoc, state.combinedMatrix());
-}
-
-char const *const *QSGCustomMaterialShader::attributeNames() const
-{
-    return m_attributeNames.constData();
-}
-
-void QSGCustomMaterialShader::initialize()
-{
-    m_opacityLoc = program()->uniformLocation("qt_Opacity");
-    m_matrixLoc = program()->uniformLocation("qt_Matrix");
-    // TODO: Remove after grace period.
-    if (m_matrixLoc == -1)
-        m_matrixLoc = program()->uniformLocation("qt_ModelViewProjectionMatrix");
-}
-
-const char *QSGCustomMaterialShader::vertexShader() const
-{
-    return m_key.vertexCode.constData();
-}
-
-const char *QSGCustomMaterialShader::fragmentShader() const
-{
-    return m_key.fragmentCode.constData();
-}
-
-
-bool QSGShaderEffectMaterialKey::operator == (const QSGShaderEffectMaterialKey &other) const
-{
-    return vertexCode == other.vertexCode && fragmentCode == other.fragmentCode && className == other.className;
-}
-
-uint qHash(const QSGShaderEffectMaterialKey &key)
-{
-    return qHash(qMakePair(qMakePair(key.vertexCode, key.fragmentCode), key.className));
-}
-
-
-QHash<QSGShaderEffectMaterialKey, QSharedPointer<QSGMaterialType> > QSGShaderEffectMaterial::materialMap;
-
-QSGShaderEffectMaterial::QSGShaderEffectMaterial()
-    : m_cullMode(NoCulling)
-{
-    setFlag(Blending, true);
-}
-
-QSGMaterialType *QSGShaderEffectMaterial::type() const
-{
-    return m_type.data();
-}
-
-QSGMaterialShader *QSGShaderEffectMaterial::createShader() const
-{
-    return new QSGCustomMaterialShader(m_source, m_source.attributeNames);
-}
-
-int QSGShaderEffectMaterial::compare(const QSGMaterial *other) const
-{
-    return this - static_cast<const QSGShaderEffectMaterial *>(other);
-}
-
-void QSGShaderEffectMaterial::setCullMode(QSGShaderEffectMaterial::CullMode face)
-{
-    m_cullMode = face;
-}
-
-QSGShaderEffectMaterial::CullMode QSGShaderEffectMaterial::cullMode() const
-{
-    return m_cullMode;
-}
-
-void QSGShaderEffectMaterial::setProgramSource(const QSGShaderEffectProgram &source)
-{
-    m_source = source;
-    m_type = materialMap.value(m_source);
-    if (m_type.isNull()) {
-        m_type = QSharedPointer<QSGMaterialType>(new QSGMaterialType);
-        materialMap.insert(m_source, m_type);
-    }
-}
-
-void QSGShaderEffectMaterial::setUniforms(const QVector<QPair<QByteArray, QVariant> > &uniformValues)
-{
-    m_uniformValues = uniformValues;
-}
-
-void QSGShaderEffectMaterial::setTextureProviders(const QVector<QPair<QByteArray, QSGTextureProvider *> > &textures)
-{
-    m_textures = textures;
-}
-
-const QVector<QPair<QByteArray, QSGTextureProvider *> > &QSGShaderEffectMaterial::textureProviders() const
-{
-    return m_textures;
-}
-
-void QSGShaderEffectMaterial::updateTextures() const
-{
-    for (int i = 0; i < m_textures.size(); ++i) {
-        if (QSGTextureProvider *provider = m_textures.at(i).second) {
-            if (QSGDynamicTexture *texture = qobject_cast<QSGDynamicTexture *>(provider->texture()))
-                texture->updateTexture();
-        }
-    }
-}
-
-
-QSGShaderEffectNode::QSGShaderEffectNode()
-{
-    QSGNode::setFlag(UsePreprocess, true);
-    setMaterial(&m_material);
-}
-
-QSGShaderEffectNode::~QSGShaderEffectNode()
-{
-}
-
-void QSGShaderEffectNode::markDirtyTexture()
-{
-    markDirty(DirtyMaterial);
-}
-
-void QSGShaderEffectNode::preprocess()
-{
-    Q_ASSERT(material());
-    static_cast<QSGShaderEffectMaterial *>(material())->updateTextures();
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgshadereffectnode_p.h b/src/declarative/items/qsgshadereffectnode_p.h
deleted file mode 100644 (file)
index d95dfaf..0000000
+++ /dev/null
@@ -1,152 +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 SHADEREFFECTNODE_H
-#define SHADEREFFECTNODE_H
-
-#include "qsgnode.h"
-#include "qsgmaterial.h"
-#include <private/qsgtextureprovider_p.h>
-#include <qsgitem.h>
-
-#include <QtCore/qsharedpointer.h>
-#include <QtCore/qpointer.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-struct QSGShaderEffectMaterialKey {
-    QByteArray vertexCode;
-    QByteArray fragmentCode;
-    const char *className;
-
-    bool operator == (const QSGShaderEffectMaterialKey &other) const;
-};
-
-uint qHash(const QSGShaderEffectMaterialKey &key);
-
-// TODO: Implement support for multisampling.
-struct QSGShaderEffectProgram : public QSGShaderEffectMaterialKey
-{
-    QSGShaderEffectProgram() : respectsOpacity(false), respectsMatrix(false) {}
-
-    QVector<QByteArray> attributeNames;
-    QSet<QByteArray> uniformNames;
-
-    uint respectsOpacity : 1;
-    uint respectsMatrix : 1;
-};
-
-
-class QSGCustomMaterialShader;
-class QSGShaderEffectMaterial : public QSGMaterial
-{
-public:
-    enum CullMode
-    {
-        NoCulling,
-        BackFaceCulling,
-        FrontFaceCulling
-    };
-
-    QSGShaderEffectMaterial();
-    virtual QSGMaterialType *type() const;
-    virtual QSGMaterialShader *createShader() const;
-    virtual int compare(const QSGMaterial *other) const;
-
-    void setCullMode(CullMode face);
-    CullMode cullMode() const;
-
-    void setProgramSource(const QSGShaderEffectProgram &);
-    void setUniforms(const QVector<QPair<QByteArray, QVariant> > &uniformValues);
-    void setTextureProviders(const QVector<QPair<QByteArray, QSGTextureProvider *> > &textures);
-    const QVector<QPair<QByteArray, QSGTextureProvider *> > &textureProviders() const;
-    void updateTextures() const;
-
-protected:
-    friend class QSGShaderEffect;
-    friend class QSGCustomMaterialShader;
-
-    // The type pointer needs to be unique. It is not safe to let the type object be part of the
-    // QSGShaderEffectMaterial, since it can be deleted and a new one constructed on top of the old
-    // one. The new QSGShaderEffectMaterial would then get the same type pointer as the old one, and
-    // CustomMaterialShaders based on the old one would incorrectly be used together with the new
-    // one. To guarantee that the type pointer is unique, the type object must live as long as
-    // there are any CustomMaterialShaders of that type.
-    QSharedPointer<QSGMaterialType> m_type;
-
-    QSGShaderEffectProgram m_source;
-    QVector<QPair<QByteArray, QVariant> > m_uniformValues;
-    QVector<QPair<QByteArray, QSGTextureProvider *> > m_textures;
-    CullMode m_cullMode;
-
-    static QHash<QSGShaderEffectMaterialKey, QSharedPointer<QSGMaterialType> > materialMap;
-};
-
-
-class QSGShaderEffectMesh;
-
-class QSGShaderEffectNode : public QObject, public QSGGeometryNode
-{
-    Q_OBJECT
-public:
-    QSGShaderEffectNode();
-    virtual ~QSGShaderEffectNode();
-
-    virtual void preprocess();
-
-    QSGShaderEffectMaterial *shaderMaterial() { return &m_material; }
-
-private Q_SLOTS:
-    void markDirtyTexture();
-
-private:
-    QSGShaderEffectMaterial m_material;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // SHADEREFFECTNODE_H
diff --git a/src/declarative/items/qsgshadereffectsource.cpp b/src/declarative/items/qsgshadereffectsource.cpp
deleted file mode 100644 (file)
index 4bbabe1..0000000
+++ /dev/null
@@ -1,905 +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$
-**
-****************************************************************************/
-
-#include "qsgshadereffectsource_p.h"
-
-#include "qsgitem_p.h"
-#include "qsgcanvas_p.h"
-#include <private/qsgadaptationlayer_p.h>
-#include <private/qsgrenderer_p.h>
-
-#include "qopenglframebufferobject.h"
-#include "qmath.h"
-#include <private/qsgtexture_p.h>
-
-QT_BEGIN_NAMESPACE
-
-DEFINE_BOOL_CONFIG_OPTION(qmlFboOverlay, QML_FBO_OVERLAY)
-
-class QSGShaderEffectSourceTextureProvider : public QSGTextureProvider
-{
-    Q_OBJECT
-public:
-    QSGShaderEffectSourceTextureProvider()
-        : sourceTexture(0)
-    {
-    }
-
-    QSGTexture *texture() const {
-        sourceTexture->setMipmapFiltering(mipmapFiltering);
-        sourceTexture->setFiltering(filtering);
-        sourceTexture->setHorizontalWrapMode(horizontalWrap);
-        sourceTexture->setVerticalWrapMode(verticalWrap);
-        return sourceTexture;
-    }
-
-    QSGShaderEffectTexture *sourceTexture;
-
-    QSGTexture::Filtering mipmapFiltering;
-    QSGTexture::Filtering filtering;
-    QSGTexture::WrapMode horizontalWrap;
-    QSGTexture::WrapMode verticalWrap;
-};
-#include "qsgshadereffectsource.moc"
-
-
-QSGShaderEffectSourceNode::QSGShaderEffectSourceNode()
-{
-    setFlag(UsePreprocess, true);
-}
-
-void QSGShaderEffectSourceNode::markDirtyTexture()
-{
-    markDirty(DirtyMaterial);
-}
-
-
-QSGShaderEffectTexture::QSGShaderEffectTexture(QSGItem *shaderSource)
-    : QSGDynamicTexture()
-    , m_item(0)
-    , m_format(GL_RGBA)
-    , m_shaderSource(shaderSource)
-    , m_renderer(0)
-    , m_fbo(0)
-    , m_secondaryFbo(0)
-#ifdef QSG_DEBUG_FBO_OVERLAY
-    , m_debugOverlay(0)
-#endif
-    , m_context(QSGItemPrivate::get(shaderSource)->sceneGraphContext())
-    , m_mipmap(false)
-    , m_live(true)
-    , m_recursive(false)
-    , m_dirtyTexture(true)
-    , m_multisamplingSupportChecked(false)
-    , m_multisampling(false)
-    , m_grab(false)
-{
-}
-
-QSGShaderEffectTexture::~QSGShaderEffectTexture()
-{
-    delete m_renderer;
-    delete m_fbo;
-    delete m_secondaryFbo;
-#ifdef QSG_DEBUG_FBO_OVERLAY
-    delete m_debugOverlay;
-#endif
-}
-
-int QSGShaderEffectTexture::textureId() const
-{
-    return m_fbo ? m_fbo->texture() : 0;
-}
-
-bool QSGShaderEffectTexture::hasAlphaChannel() const
-{
-    return m_format != GL_RGB;
-}
-
-bool QSGShaderEffectTexture::hasMipmaps() const
-{
-    return m_mipmap;
-}
-
-
-void QSGShaderEffectTexture::bind()
-{
-#ifndef QT_NO_DEBUG
-    if (!m_recursive && m_fbo && ((m_multisampling && m_secondaryFbo->isBound()) || m_fbo->isBound()))
-        qWarning("ShaderEffectSource: \'recursive\' must be set to true when rendering recursively.");
-#endif
-    glBindTexture(GL_TEXTURE_2D, m_fbo ? m_fbo->texture() : 0);
-    updateBindOptions();
-}
-
-bool QSGShaderEffectTexture::updateTexture()
-{
-    if ((m_live || m_grab) && m_dirtyTexture) {
-        grab();
-        m_grab = false;
-        return true;
-    }
-    return false;
-}
-
-void QSGShaderEffectTexture::setHasMipmaps(bool mipmap)
-{
-    if (mipmap == m_mipmap)
-        return;
-    m_mipmap = mipmap;
-    if (m_mipmap && m_fbo && !m_fbo->format().mipmap())
-        markDirtyTexture();
-}
-
-
-void QSGShaderEffectTexture::setItem(QSGNode *item)
-{
-    if (item == m_item)
-        return;
-    m_item = item;
-    markDirtyTexture();
-}
-
-void QSGShaderEffectTexture::setRect(const QRectF &rect)
-{
-    if (rect == m_rect)
-        return;
-    m_rect = rect;
-    markDirtyTexture();
-}
-
-void QSGShaderEffectTexture::setSize(const QSize &size)
-{
-    if (size == m_size)
-        return;
-    m_size = size;
-    markDirtyTexture();
-}
-
-void QSGShaderEffectTexture::setFormat(GLenum format)
-{
-    if (format == m_format)
-        return;
-    m_format = format;
-    markDirtyTexture();
-}
-
-void QSGShaderEffectTexture::setLive(bool live)
-{
-    if (live == m_live)
-        return;
-    m_live = live;
-    markDirtyTexture();
-}
-
-void QSGShaderEffectTexture::scheduleUpdate()
-{
-    if (m_grab)
-        return;
-    m_grab = true;
-    if (m_dirtyTexture)
-        emit textureChanged();
-}
-
-void QSGShaderEffectTexture::setRecursive(bool recursive)
-{
-    m_recursive = recursive;
-}
-
-void QSGShaderEffectTexture::markDirtyTexture()
-{
-    m_dirtyTexture = true;
-    if (m_live || m_grab)
-        emit textureChanged();
-}
-
-void QSGShaderEffectTexture::grab()
-{
-    if (!m_item || m_size.isNull()) {
-        delete m_fbo;
-        delete m_secondaryFbo;
-        m_fbo = m_secondaryFbo = 0;
-        m_dirtyTexture = false;
-        return;
-    }
-    QSGNode *root = m_item;
-    while (root->firstChild() && root->type() != QSGNode::RootNodeType)
-        root = root->firstChild();
-    if (root->type() != QSGNode::RootNodeType)
-        return;
-
-    if (m_size.isEmpty()) {
-        delete m_fbo;
-        delete m_secondaryFbo;
-        m_secondaryFbo = m_fbo = 0;
-        return;
-    }
-
-    if (!m_renderer) {
-        m_renderer = m_context->createRenderer();
-        connect(m_renderer, SIGNAL(sceneGraphChanged()), this, SLOT(markDirtyTexture()), Qt::DirectConnection);
-    }
-    m_renderer->setRootNode(static_cast<QSGRootNode *>(root));
-
-    bool deleteFboLater = false;
-    if (!m_fbo || m_fbo->size() != m_size || m_fbo->format().internalTextureFormat() != m_format
-        || (!m_fbo->format().mipmap() && m_mipmap))
-    {
-        if (!m_multisamplingSupportChecked) {
-            QList<QByteArray> extensions = QByteArray((const char *)glGetString(GL_EXTENSIONS)).split(' ');
-            m_multisampling = extensions.contains("GL_EXT_framebuffer_multisample")
-                            && extensions.contains("GL_EXT_framebuffer_blit");
-            m_multisamplingSupportChecked = true;
-        }
-        if (m_multisampling) {
-            // Don't delete the FBO right away in case it is used recursively.
-            deleteFboLater = true;
-            delete m_secondaryFbo;
-            QOpenGLFramebufferObjectFormat format;
-
-            format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
-            format.setInternalTextureFormat(m_format);
-            format.setSamples(8);
-            m_secondaryFbo = new QOpenGLFramebufferObject(m_size, format);
-        } else {
-            QOpenGLFramebufferObjectFormat format;
-            format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
-            format.setInternalTextureFormat(m_format);
-            format.setMipmap(m_mipmap);
-            if (m_recursive) {
-                deleteFboLater = true;
-                delete m_secondaryFbo;
-                m_secondaryFbo = new QOpenGLFramebufferObject(m_size, format);
-                glBindTexture(GL_TEXTURE_2D, m_secondaryFbo->texture());
-                updateBindOptions(true);
-            } else {
-                delete m_fbo;
-                delete m_secondaryFbo;
-                m_fbo = new QOpenGLFramebufferObject(m_size, format);
-                m_secondaryFbo = 0;
-                glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
-                updateBindOptions(true);
-            }
-        }
-    }
-
-    if (m_recursive && !m_secondaryFbo) {
-        // m_fbo already created, m_recursive was just set.
-        Q_ASSERT(m_fbo);
-        Q_ASSERT(!m_multisampling);
-
-        m_secondaryFbo = new QOpenGLFramebufferObject(m_size, m_fbo->format());
-        glBindTexture(GL_TEXTURE_2D, m_secondaryFbo->texture());
-        updateBindOptions(true);
-    }
-
-    // Render texture.
-    root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip and opacity update.
-    m_renderer->nodeChanged(root, QSGNode::DirtyForceUpdate); // Force render list update.
-
-#ifdef QSG_DEBUG_FBO_OVERLAY
-    if (qmlFboOverlay()) {
-        if (!m_debugOverlay)
-            m_debugOverlay = m_context->createRectangleNode();
-        m_debugOverlay->setRect(QRectF(0, 0, m_size.width(), m_size.height()));
-        m_debugOverlay->setColor(QColor(0xff, 0x00, 0x80, 0x40));
-        m_debugOverlay->setPenColor(QColor());
-        m_debugOverlay->setPenWidth(0);
-        m_debugOverlay->setRadius(0);
-        m_debugOverlay->update();
-        root->appendChildNode(m_debugOverlay);
-    }
-#endif
-
-    m_dirtyTexture = false;
-
-    QOpenGLContext *ctx = m_context->glContext();
-    m_renderer->setDeviceRect(m_size);
-    m_renderer->setViewportRect(m_size);
-    QRectF mirrored(m_rect.left(), m_rect.bottom(), m_rect.width(), -m_rect.height());
-    m_renderer->setProjectionMatrixToRect(mirrored);
-    m_renderer->setClearColor(Qt::transparent);
-
-    if (m_multisampling) {
-        m_renderer->renderScene(QSGBindableFbo(m_secondaryFbo));
-
-        if (deleteFboLater) {
-            delete m_fbo;
-            QOpenGLFramebufferObjectFormat format;
-            format.setInternalTextureFormat(m_format);
-            format.setAttachment(QOpenGLFramebufferObject::NoAttachment);
-            format.setMipmap(m_mipmap);
-            format.setSamples(0);
-            m_fbo = new QOpenGLFramebufferObject(m_size, format);
-            glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
-            updateBindOptions(true);
-        }
-
-        QRect r(QPoint(), m_size);
-        QOpenGLFramebufferObject::blitFramebuffer(m_fbo, r, m_secondaryFbo, r);
-    } else {
-        if (m_recursive) {
-            m_renderer->renderScene(QSGBindableFbo(m_secondaryFbo));
-
-            if (deleteFboLater) {
-                delete m_fbo;
-                QOpenGLFramebufferObjectFormat format;
-                format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
-                format.setInternalTextureFormat(m_format);
-                format.setMipmap(m_mipmap);
-                m_fbo = new QOpenGLFramebufferObject(m_size, format);
-                glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
-                updateBindOptions(true);
-            }
-            qSwap(m_fbo, m_secondaryFbo);
-        } else {
-            m_renderer->renderScene(QSGBindableFbo(m_fbo));
-        }
-    }
-
-    if (m_mipmap) {
-        glBindTexture(GL_TEXTURE_2D, textureId());
-        ctx->functions()->glGenerateMipmap(GL_TEXTURE_2D);
-    }
-
-    root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip, opacity and render list update.
-
-#ifdef QSG_DEBUG_FBO_OVERLAY
-    if (qmlFboOverlay())
-        root->removeChildNode(m_debugOverlay);
-#endif
-    if (m_recursive)
-        markDirtyTexture(); // Continuously update if 'live' and 'recursive'.
-}
-
-QImage QSGShaderEffectTexture::toImage() const
-{
-    if (m_fbo)
-        return m_fbo->toImage();
-
-    return QImage();
-}
-
-/*!
-    \qmlclass ShaderEffectSource QSGShaderEffectSource
-    \since 5.0
-    \ingroup qml-basic-visual-elements
-    \brief The ShaderEffectSource element renders a QML element into a texture
-    and displays it.
-    \inherits Item
-
-    The ShaderEffectSource element renders \l sourceItem into a texture and
-    displays it in the scene. \l sourceItem is drawn into the texture as though
-    it was a fully opaque root element. Thus \l sourceItem itself can be
-    invisible, but still appear in the texture.
-
-    ShaderEffectSource can be used as:
-    \list
-    \o a texture source in a \l ShaderEffect.
-       This allows you to apply custom shader effects to any QML element.
-    \o a cache for a complex element.
-       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.
-       ShaderEffectSource allows you to apply an opacity to elements as a group
-       rather than each element individually.
-    \endlist
-
-    \table
-    \row
-    \o \image declarative-shadereffectsource.png
-    \o \qml
-        import QtQuick 2.0
-
-        Rectangle {
-            width: 200
-            height: 100
-            gradient: Gradient {
-                GradientStop { position: 0; color: "white" }
-                GradientStop { position: 1; color: "black" }
-            }
-            Row {
-                opacity: 0.5
-                Item {
-                    id: foo
-                    width: 100; height: 100
-                    Rectangle { x: 5; y: 5; width: 60; height: 60; color: "red" }
-                    Rectangle { x: 20; y: 20; width: 60; height: 60; color: "orange" }
-                    Rectangle { x: 35; y: 35; width: 60; height: 60; color: "yellow" }
-                }
-                ShaderEffectSource {
-                    width: 100; height: 100
-                    sourceItem: foo
-                }
-            }
-        }
-        \endqml
-    \endrow
-    \endtable
-
-    The ShaderEffectSource element does not redirect any mouse or keyboard
-    input to \l sourceItem. If you hide the \l sourceItem by setting
-    \l{Item::visible}{visible} to false or \l{Item::opacity}{opacity} to zero,
-    it will no longer react to input. In cases where the ShaderEffectSource is
-    meant to replace the \l sourceItem, you typically want to hide the
-    \l sourceItem while still handling input. For this, you can use
-    the \l hideSource property.
-
-    \note If \l sourceItem is a \l Rectangle with border, by default half the
-    border width falls outside the texture. To get the whole border, you can
-    extend the \l sourceRect.
-
-    \warning In most cases, using a ShaderEffectSource will decrease
-    performance, and in all cases, it will increase video memory usage.
-    Rendering through a ShaderEffectSource might also lead to lower quality
-    since some OpenGL implementations support multisampled backbuffer,
-    but not multisampled framebuffer objects.
-*/
-
-QSGShaderEffectSource::QSGShaderEffectSource(QSGItem *parent)
-    : QSGItem(parent)
-    , m_provider(0)
-    , m_texture(0)
-    , m_wrapMode(ClampToEdge)
-    , m_sourceItem(0)
-    , m_textureSize(0, 0)
-    , m_format(RGBA)
-    , m_live(true)
-    , m_hideSource(false)
-    , m_mipmap(false)
-    , m_recursive(false)
-    , m_grab(true)
-{
-    setFlag(ItemHasContents);
-}
-
-QSGShaderEffectSource::~QSGShaderEffectSource()
-{
-    if (m_texture)
-        m_texture->deleteLater();
-
-    if (m_provider)
-        m_provider->deleteLater();
-
-    if (m_sourceItem)
-        QSGItemPrivate::get(m_sourceItem)->derefFromEffectItem(m_hideSource);
-}
-
-void QSGShaderEffectSource::ensureTexture()
-{
-    if (m_texture)
-        return;
-
-    Q_ASSERT_X(QSGItemPrivate::get(this)->canvas
-               && QSGItemPrivate::get(this)->sceneGraphContext()
-               && QThread::currentThread() == QSGItemPrivate::get(this)->sceneGraphContext()->thread(),
-               "QSGShaderEffectSource::ensureTexture",
-               "Cannot be used outside the rendering thread");
-
-    m_texture = new QSGShaderEffectTexture(this);
-    connect(m_texture, SIGNAL(textureChanged()), this, SLOT(update()));
-}
-
-QSGTextureProvider *QSGShaderEffectSource::textureProvider() const
-{
-    if (!m_provider) {
-        // Make sure it gets thread affinity on the rendering thread so deletion works properly..
-        Q_ASSERT_X(QSGItemPrivate::get(this)->canvas
-                   && QSGItemPrivate::get(this)->sceneGraphContext()
-                   && QThread::currentThread() == QSGItemPrivate::get(this)->sceneGraphContext()->thread(),
-                   "QSGShaderEffectSource::textureProvider",
-                   "Cannot be used outside the rendering thread");
-        const_cast<QSGShaderEffectSource *>(this)->m_provider = new QSGShaderEffectSourceTextureProvider();
-
-        const_cast<QSGShaderEffectSource *>(this)->ensureTexture();
-        connect(m_texture, SIGNAL(textureChanged()), m_provider, SIGNAL(textureChanged()), Qt::DirectConnection);
-        m_provider->sourceTexture = m_texture;
-    }
-    return m_provider;
-}
-
-/*!
-    \qmlproperty enumeration ShaderEffectSource::wrapMode
-
-    This property defines the OpenGL wrap modes associated with the texture.
-    Modifying this property makes most sense when the element is used as a
-    source texture of a \l ShaderEffect.
-
-    \list
-    \o ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
-    \o ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
-    \o ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
-    \o ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
-    \endlist
-
-    \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
-    wrap mode with non-power-of-two textures.
-*/
-
-QSGShaderEffectSource::WrapMode QSGShaderEffectSource::wrapMode() const
-{
-    return m_wrapMode;
-}
-
-void QSGShaderEffectSource::setWrapMode(WrapMode mode)
-{
-    if (mode == m_wrapMode)
-        return;
-    m_wrapMode = mode;
-    update();
-    emit wrapModeChanged();
-}
-
-/*!
-    \qmlproperty Item ShaderEffectSource::sourceItem
-
-    This property holds the element to be rendered into the texture.
-*/
-
-QSGItem *QSGShaderEffectSource::sourceItem() const
-{
-    return m_sourceItem;
-}
-
-void QSGShaderEffectSource::setSourceItem(QSGItem *item)
-{
-    if (item == m_sourceItem)
-        return;
-    if (m_sourceItem)
-        QSGItemPrivate::get(m_sourceItem)->derefFromEffectItem(m_hideSource);
-    m_sourceItem = item;
-    if (m_sourceItem) {
-        // TODO: Find better solution.
-        // 'm_sourceItem' needs a canvas to get a scenegraph node.
-        // The easiest way to make sure it gets a canvas is to
-        // make it a part of the same item tree as 'this'.
-        if (m_sourceItem->parentItem() == 0) {
-            m_sourceItem->setParentItem(this);
-            m_sourceItem->setVisible(false);
-        }
-        QSGItemPrivate::get(m_sourceItem)->refFromEffectItem(m_hideSource);
-    }
-    update();
-    emit sourceItemChanged();
-}
-
-/*!
-    \qmlproperty rect ShaderEffectSource::sourceRect
-
-    This property defines which rectangular area of the \l sourceItem to
-    render into the texture. The source rectangle can be larger than
-    \l sourceItem itself. If the rectangle is null, which is the default,
-    the whole \l sourceItem is rendered to texture.
-*/
-
-QRectF QSGShaderEffectSource::sourceRect() const
-{
-    return m_sourceRect;
-}
-
-void QSGShaderEffectSource::setSourceRect(const QRectF &rect)
-{
-    if (rect == m_sourceRect)
-        return;
-    m_sourceRect = rect;
-    update();
-    emit sourceRectChanged();
-}
-
-/*!
-    \qmlproperty size ShaderEffectSource::textureSize
-
-    This property holds the requested size of the texture. If it is empty,
-    which is the default, the size of the source rectangle is used.
-
-    \note Some platforms have a limit on how small framebuffer objects can be,
-    which means the actual texture size might be larger than the requested
-    size.
-*/
-
-QSize QSGShaderEffectSource::textureSize() const
-{
-    return m_textureSize;
-}
-
-void QSGShaderEffectSource::setTextureSize(const QSize &size)
-{
-    if (size == m_textureSize)
-        return;
-    m_textureSize = size;
-    update();
-    emit textureSizeChanged();
-}
-
-/*!
-    \qmlproperty enumeration ShaderEffectSource::format
-
-    This property defines the internal OpenGL format of the texture.
-    Modifying this property makes most sense when the element is used as a
-    source texture of a \l ShaderEffect. Depending on the OpenGL
-    implementation, this property might allow you to save some texture memory.
-
-    \list
-    \o ShaderEffectSource.Alpha - GL_ALPHA
-    \o ShaderEffectSource.RGB - GL_RGB
-    \o ShaderEffectSource.RGBA - GL_RGBA
-    \endlist
-
-    \note Some OpenGL implementations do not support the GL_ALPHA format.
-*/
-
-QSGShaderEffectSource::Format QSGShaderEffectSource::format() const
-{
-    return m_format;
-}
-
-void QSGShaderEffectSource::setFormat(QSGShaderEffectSource::Format format)
-{
-    if (format == m_format)
-        return;
-    m_format = format;
-    update();
-    emit formatChanged();
-}
-
-/*!
-    \qmlproperty bool ShaderEffectSource::live
-
-    If this property is true, the texture is updated whenever the
-    \l sourceItem changes. Otherwise, it will be a frozen image of the
-    \l sourceItem. The property is true by default.
-*/
-
-bool QSGShaderEffectSource::live() const
-{
-    return m_live;
-}
-
-void QSGShaderEffectSource::setLive(bool live)
-{
-    if (live == m_live)
-        return;
-    m_live = live;
-    update();
-    emit liveChanged();
-}
-
-/*!
-    \qmlproperty bool ShaderEffectSource::hideSource
-
-    If this property is true, the \l sourceItem is hidden, though it will still
-    be rendered into the texture. As opposed to hiding the \l sourceItem by
-    setting \l{Item::visible}{visible} to false, setting this property to true
-    will not prevent mouse or keyboard input from reaching \l sourceItem.
-    The property is useful when the ShaderEffectSource is anchored on top of,
-    and meant to replace the \l sourceItem.
-*/
-
-bool QSGShaderEffectSource::hideSource() const
-{
-    return m_hideSource;
-}
-
-void QSGShaderEffectSource::setHideSource(bool hide)
-{
-    if (hide == m_hideSource)
-        return;
-    if (m_sourceItem) {
-        QSGItemPrivate::get(m_sourceItem)->refFromEffectItem(hide);
-        QSGItemPrivate::get(m_sourceItem)->derefFromEffectItem(m_hideSource);
-    }
-    m_hideSource = hide;
-    update();
-    emit hideSourceChanged();
-}
-
-/*!
-    \qmlproperty bool ShaderEffectSource::mipmap
-
-    If this property is true, mipmaps are generated for the texture.
-
-    \note Some OpenGL ES 2 implementations do not support mipmapping of
-    non-power-of-two textures.
-*/
-
-bool QSGShaderEffectSource::mipmap() const
-{
-    return m_mipmap;
-}
-
-void QSGShaderEffectSource::setMipmap(bool enabled)
-{
-    if (enabled == m_mipmap)
-        return;
-    m_mipmap = enabled;
-    update();
-    emit mipmapChanged();
-}
-
-/*!
-    \qmlproperty bool ShaderEffectSource::recursive
-
-    Set this property to true if the ShaderEffectSource has a dependency on
-    itself. ShaderEffectSources form a dependency chain, where one
-    ShaderEffectSource can be part of the \l sourceItem of another.
-    If there is a loop in this chain, a ShaderEffectSource could end up trying
-    to render into the same texture it is using as source, which is not allowed
-    by OpenGL. When this property is set to true, an extra texture is allocated
-    so that ShaderEffectSource can keep a copy of the texture from the previous
-    frame. It can then render into one texture and use the texture from the
-    previous frame as source.
-
-    Setting both this property and \l live to true will cause the scene graph
-    to render continuously. Since the ShaderEffectSource depends on itself,
-    updating it means that it immediately becomes dirty again.
-*/
-
-bool QSGShaderEffectSource::recursive() const
-{
-    return m_recursive;
-}
-
-void QSGShaderEffectSource::setRecursive(bool enabled)
-{
-    if (enabled == m_recursive)
-        return;
-    m_recursive = enabled;
-    emit recursiveChanged();
-}
-
-/*!
-    \qmlmethod ShaderEffectSource::scheduleUpdate()
-
-    Schedules a re-rendering of the texture for the next frame.
-    Use this to update the texture when \l live is false.
-*/
-
-void QSGShaderEffectSource::scheduleUpdate()
-{
-    if (m_grab)
-        return;
-    m_grab = true;
-    update();
-}
-
-static void get_wrap_mode(QSGShaderEffectSource::WrapMode mode, QSGTexture::WrapMode *hWrap, QSGTexture::WrapMode *vWrap)
-{
-    switch (mode) {
-    case QSGShaderEffectSource::RepeatHorizontally:
-        *hWrap = QSGTexture::Repeat;
-        *vWrap = QSGTexture::ClampToEdge;
-        break;
-    case QSGShaderEffectSource::RepeatVertically:
-        *vWrap = QSGTexture::Repeat;
-        *hWrap = QSGTexture::ClampToEdge;
-        break;
-    case QSGShaderEffectSource::Repeat:
-        *hWrap = *vWrap = QSGTexture::Repeat;
-        break;
-    default:
-        // QSGShaderEffectSource::ClampToEdge
-        *hWrap = *vWrap = QSGTexture::ClampToEdge;
-        break;
-    }
-}
-
-
-QSGNode *QSGShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
-{
-    if (!m_sourceItem || m_sourceItem->width() == 0 || m_sourceItem->height() == 0) {
-        delete oldNode;
-        return 0;
-    }
-
-    ensureTexture();
-
-    QSGShaderEffectTexture *tex = qobject_cast<QSGShaderEffectTexture *>(m_texture);
-    tex->setLive(m_live);
-    tex->setItem(QSGItemPrivate::get(m_sourceItem)->itemNode());
-    QRectF sourceRect = m_sourceRect.width() == 0 || m_sourceRect.height() == 0
-                      ? QRectF(0, 0, m_sourceItem->width(), m_sourceItem->height())
-                      : m_sourceRect;
-    tex->setRect(sourceRect);
-    QSize textureSize = m_textureSize.isEmpty()
-                      ? QSize(qCeil(qAbs(sourceRect.width())), qCeil(qAbs(sourceRect.height())))
-                      : m_textureSize;
-    Q_ASSERT(!textureSize.isEmpty());
-    QSGItemPrivate *d = static_cast<QSGItemPrivate *>(QObjectPrivate::get(this));
-    const QSize minTextureSize = d->sceneGraphContext()->minimumFBOSize();
-    // Keep power-of-two by doubling the size.
-    while (textureSize.width() < minTextureSize.width())
-        textureSize.rwidth() *= 2;
-    while (textureSize.height() < minTextureSize.height())
-        textureSize.rheight() *= 2;
-
-    tex->setSize(textureSize);
-    tex->setRecursive(m_recursive);
-    tex->setFormat(GLenum(m_format));
-    tex->setHasMipmaps(m_mipmap);
-
-    if (m_grab)
-        tex->scheduleUpdate();
-    m_grab = false;
-
-    QSGTexture::Filtering filtering = QSGItemPrivate::get(this)->smooth
-                                            ? QSGTexture::Linear
-                                            : QSGTexture::Nearest;
-    QSGTexture::Filtering mmFiltering = m_mipmap ? filtering : QSGTexture::None;
-    QSGTexture::WrapMode hWrap, vWrap;
-    get_wrap_mode(m_wrapMode, &hWrap, &vWrap);
-
-    if (m_provider) {
-        m_provider->mipmapFiltering = mmFiltering;
-        m_provider->filtering = filtering;
-        m_provider->horizontalWrap = hWrap;
-        m_provider->verticalWrap = vWrap;
-    }
-
-    // Don't create the paint node if we're not spanning any area
-    if (width() == 0 || height() == 0) {
-        delete oldNode;
-        return 0;
-    }
-
-    QSGShaderEffectSourceNode *node = static_cast<QSGShaderEffectSourceNode *>(oldNode);
-    if (!node) {
-        node = new QSGShaderEffectSourceNode;
-        node->setTexture(m_texture);
-        connect(m_texture, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture()), Qt::DirectConnection);
-    }
-
-    // If live and recursive, update continuously.
-    if (m_live && m_recursive)
-        node->markDirty(QSGNode::DirtyMaterial);
-
-    node->setMipmapFiltering(mmFiltering);
-    node->setFiltering(filtering);
-    node->setHorizontalWrapMode(hWrap);
-    node->setVerticalWrapMode(vWrap);
-    node->setTargetRect(QRectF(0, 0, width(), height()));
-    node->setSourceRect(QRectF(0, 0, 1, 1));
-    node->update();
-
-    return node;
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgshadereffectsource_p.h b/src/declarative/items/qsgshadereffectsource_p.h
deleted file mode 100644 (file)
index 5d65b26..0000000
+++ /dev/null
@@ -1,255 +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 SHADEREFFECTSOURCE_H
-#define SHADEREFFECTSOURCE_H
-
-#include "qsgitem.h"
-#include <private/qsgtextureprovider_p.h>
-#include <private/qsgadaptationlayer_p.h>
-#include <private/qsgcontext_p.h>
-#include <private/qsgdefaultimagenode_p.h>
-
-#include "qpointer.h"
-#include "qsize.h"
-#include "qrect.h"
-
-#define QSG_DEBUG_FBO_OVERLAY
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGNode;
-class UpdatePaintNodeData;
-class QOpenGLFramebufferObject;
-
-class QSGShaderEffectSourceTextureProvider;
-
-class QSGShaderEffectSourceNode : public QObject, public QSGDefaultImageNode
-{
-    Q_OBJECT
-
-public:
-    QSGShaderEffectSourceNode();
-
-private Q_SLOTS:
-    void markDirtyTexture();
-};
-
-class Q_DECLARATIVE_EXPORT QSGShaderEffectTexture : public QSGDynamicTexture
-{
-    Q_OBJECT
-public:
-    QSGShaderEffectTexture(QSGItem *shaderSource);
-    ~QSGShaderEffectTexture();
-
-    virtual bool updateTexture();
-
-    // The item's "paint node", not effect node.
-    QSGNode *item() const { return m_item; }
-    void setItem(QSGNode *item);
-
-    QRectF rect() const { return m_rect; }
-    void setRect(const QRectF &rect);
-
-    QSize size() const { return m_size; }
-    void setSize(const QSize &size);
-
-    void setHasMipmaps(bool mipmap);
-
-    void bind();
-
-    bool hasAlphaChannel() const;
-    bool hasMipmaps() const;
-    int textureId() const;
-    QSize textureSize() const { return m_size; }
-
-    GLenum format() const { return m_format; }
-    void setFormat(GLenum format);
-
-    bool live() const { return bool(m_live); }
-    void setLive(bool live);
-
-    bool recursive() const { return bool(m_recursive); }
-    void setRecursive(bool recursive);
-
-    void scheduleUpdate();
-
-    QImage toImage() const;
-
-Q_SIGNALS:
-    void textureChanged();
-
-public Q_SLOTS:
-    void markDirtyTexture();
-
-private:
-    void grab();
-
-    QSGNode *m_item;
-    QRectF m_rect;
-    QSize m_size;
-    GLenum m_format;
-
-    QSGItem *m_shaderSource;
-    QSGRenderer *m_renderer;
-    QOpenGLFramebufferObject *m_fbo;
-    QOpenGLFramebufferObject *m_secondaryFbo;
-
-#ifdef QSG_DEBUG_FBO_OVERLAY
-    QSGRectangleNode *m_debugOverlay;
-#endif
-
-    QSGContext *m_context;
-
-    uint m_mipmap : 1;
-    uint m_live : 1;
-    uint m_recursive : 1;
-    uint m_dirtyTexture : 1;
-    uint m_multisamplingSupportChecked : 1;
-    uint m_multisampling : 1;
-    uint m_grab : 1;
-};
-
-class Q_DECLARATIVE_EXPORT QSGShaderEffectSource : public QSGItem
-{
-    Q_OBJECT
-    Q_PROPERTY(WrapMode wrapMode READ wrapMode WRITE setWrapMode NOTIFY wrapModeChanged)
-    Q_PROPERTY(QSGItem *sourceItem READ sourceItem WRITE setSourceItem NOTIFY sourceItemChanged)
-    Q_PROPERTY(QRectF sourceRect READ sourceRect WRITE setSourceRect NOTIFY sourceRectChanged)
-    Q_PROPERTY(QSize textureSize READ textureSize WRITE setTextureSize NOTIFY textureSizeChanged)
-    Q_PROPERTY(Format format READ format WRITE setFormat NOTIFY formatChanged)
-    Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged)
-    Q_PROPERTY(bool hideSource READ hideSource WRITE setHideSource NOTIFY hideSourceChanged)
-    Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged)
-    Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged)
-
-    Q_ENUMS(Format WrapMode)
-public:
-    enum WrapMode {
-        ClampToEdge,
-        RepeatHorizontally,
-        RepeatVertically,
-        Repeat
-    };
-
-    enum Format {
-        Alpha = GL_ALPHA,
-        RGB = GL_RGB,
-        RGBA = GL_RGBA
-    };
-
-    QSGShaderEffectSource(QSGItem *parent = 0);
-    ~QSGShaderEffectSource();
-
-    WrapMode wrapMode() const;
-    void setWrapMode(WrapMode mode);
-
-    QSGItem *sourceItem() const;
-    void setSourceItem(QSGItem *item);
-
-    QRectF sourceRect() const;
-    void setSourceRect(const QRectF &rect);
-
-    QSize textureSize() const;
-    void setTextureSize(const QSize &size);
-
-    Format format() const;
-    void setFormat(Format format);
-
-    bool live() const;
-    void setLive(bool live);
-
-    bool hideSource() const;
-    void setHideSource(bool hide);
-
-    bool mipmap() const;
-    void setMipmap(bool enabled);
-
-    bool recursive() const;
-    void setRecursive(bool enabled);
-
-    bool isTextureProvider() const { return true; }
-    QSGTextureProvider *textureProvider() const;
-
-    Q_INVOKABLE void scheduleUpdate();
-
-Q_SIGNALS:
-    void wrapModeChanged();
-    void sourceItemChanged();
-    void sourceRectChanged();
-    void textureSizeChanged();
-    void formatChanged();
-    void liveChanged();
-    void hideSourceChanged();
-    void mipmapChanged();
-    void recursiveChanged();
-
-    void textureChanged();
-
-protected:
-    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
-
-private:
-    void ensureTexture();
-
-    QSGShaderEffectSourceTextureProvider *m_provider;
-    QSGShaderEffectTexture *m_texture;
-    WrapMode m_wrapMode;
-    QPointer<QSGItem> m_sourceItem;
-    QRectF m_sourceRect;
-    QSize m_textureSize;
-    Format m_format;
-    uint m_live : 1;
-    uint m_hideSource : 1;
-    uint m_mipmap : 1;
-    uint m_recursive : 1;
-    uint m_grab : 1;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // SHADEREFFECTSOURCE_H
diff --git a/src/declarative/items/qsgsprite.cpp b/src/declarative/items/qsgsprite.cpp
deleted file mode 100644 (file)
index afd32a6..0000000
+++ /dev/null
@@ -1,130 +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 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 "qsgsprite_p.h"
-#include <QDebug>
-
-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)
-{
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgsprite_p.h b/src/declarative/items/qsgsprite_p.h
deleted file mode 100644 (file)
index 58b6c13..0000000
+++ /dev/null
@@ -1,136 +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 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 SPRITESTATE_H
-#define SPRITESTATE_H
-
-#include <QObject>
-#include <QUrl>
-#include <QVariantMap>
-#include <QDeclarativeListProperty>
-#include "qsgspriteengine_p.h"
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-
-class QSGSprite : public QSGStochasticState
-{
-    Q_OBJECT
-    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)
-
-public:
-    explicit QSGSprite(QObject *parent = 0);
-
-    QUrl source() const
-    {
-        return m_source;
-    }
-
-    int frameHeight() const
-    {
-        return m_frameHeight;
-    }
-
-    int frameWidth() const
-    {
-        return m_frameWidth;
-    }
-
-
-signals:
-
-    void sourceChanged(QUrl arg);
-
-    void frameHeightChanged(int arg);
-
-    void frameWidthChanged(int arg);
-
-public slots:
-
-    void setSource(QUrl arg)
-    {
-        if (m_source != arg) {
-            m_source = arg;
-            emit sourceChanged(arg);
-        }
-    }
-
-    void setFrameHeight(int arg)
-    {
-        if (m_frameHeight != arg) {
-            m_frameHeight = arg;
-            emit frameHeightChanged(arg);
-        }
-    }
-
-    void setFrameWidth(int arg)
-    {
-        if (m_frameWidth != arg) {
-            m_frameWidth = arg;
-            emit frameWidthChanged(arg);
-        }
-    }
-
-
-private:
-    friend class QSGImageParticle;
-    friend class QSGSpriteEngine;
-    friend class QSGStochasticEngine;
-    int m_generatedCount;
-    int m_framesPerRow;
-    QUrl m_source;
-    int m_frameHeight;
-    int m_frameWidth;
-    int m_rowY;
-
-};
-
-QT_END_NAMESPACE
-QT_END_HEADER
-#endif // SPRITESTATE_H
diff --git a/src/declarative/items/qsgspriteengine.cpp b/src/declarative/items/qsgspriteengine.cpp
deleted file mode 100644 (file)
index a376a06..0000000
+++ /dev/null
@@ -1,500 +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 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 "qsgspriteengine_p.h"
-#include "qsgsprite_p.h"
-#include <QDebug>
-#include <QPainter>
-#include <QSet>
-#include <QtGui>
-
-QT_BEGIN_NAMESPACE
-
-/* TODO: Split out image logic from stochastic state logic
-   Also make sharable
-   Also solve the state data initialization/transfer issue so as to not need to make friends
-*/
-
-QSGStochasticEngine::QSGStochasticEngine(QObject *parent) :
-    QObject(parent), m_timeOffset(0)
-{
-    //Default size 1
-    setCount(1);
-    m_advanceTime.start();
-}
-
-QSGStochasticEngine::QSGStochasticEngine(QList<QSGStochasticState*> states, QObject *parent) :
-    QObject(parent), m_states(states), m_timeOffset(0)
-{
-    //Default size 1
-    setCount(1);
-    m_advanceTime.start();
-}
-
-QSGStochasticEngine::~QSGStochasticEngine()
-{
-}
-
-QSGSpriteEngine::QSGSpriteEngine(QObject *parent)
-    : QSGStochasticEngine(parent)
-{
-}
-
-QSGSpriteEngine::QSGSpriteEngine(QList<QSGSprite*> sprites, QObject *parent)
-    : QSGStochasticEngine(parent)
-{
-    foreach (QSGSprite* sprite, sprites)
-        m_states << (QSGStochasticState*)sprite;
-}
-
-QSGSpriteEngine::~QSGSpriteEngine()
-{
-}
-
-
-int QSGSpriteEngine::maxFrames()
-{
-    return m_maxFrames;
-}
-
-/* States too large to fit in one row are split into multiple rows
-   This is more efficient for the implementation, but should remain an implementation detail (invisible from QML)
-   Therefore the below functions abstract sprite from the viewpoint of classes that pass the details onto shaders
-   But States maintain their listed index for internal structures
-TODO: All these calculations should be pre-calculated and cached during initialization for a significant performance boost
-TODO: Above idea needs to have the varying duration offset added to it
-*/
-int QSGSpriteEngine::spriteState(int sprite)
-{
-    int state = m_things[sprite];
-    if (!m_sprites[state]->m_generatedCount)
-        return state;
-    int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow;
-    int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
-    return state + extra;
-}
-
-int QSGSpriteEngine::spriteStart(int sprite)
-{
-    int state = m_things[sprite];
-    if (!m_sprites[state]->m_generatedCount)
-        return m_startTimes[sprite];
-    int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow;
-    int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
-    return state + extra*rowDuration;
-}
-
-int QSGSpriteEngine::spriteFrames(int sprite)
-{
-    int state = m_things[sprite];
-    if (!m_sprites[state]->m_generatedCount)
-        return m_sprites[state]->frames();
-    int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow;
-    int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
-    if (extra == m_sprites[state]->m_generatedCount - 1)//last state
-        return m_sprites[state]->frames() % m_sprites[state]->m_framesPerRow;
-    else
-        return m_sprites[state]->m_framesPerRow;
-}
-
-int QSGSpriteEngine::spriteDuration(int sprite)
-{
-    int state = m_things[sprite];
-    if (!m_sprites[state]->m_generatedCount)
-        return m_duration[sprite];
-    int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow;
-    int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
-    if (extra == m_sprites[state]->m_generatedCount - 1)//last state
-        return (m_duration[sprite] * m_sprites[state]->frames()) % rowDuration;
-    else
-        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;
-}
-
-void QSGStochasticEngine::setGoal(int state, int sprite, bool jump)
-{
-    if (sprite >= m_things.count() || state >= m_states.count())
-        return;
-    if (!jump){
-        m_goals[sprite] = state;
-        return;
-    }
-
-    if (m_things[sprite] == state)
-        return;//Already there
-    m_things[sprite] = state;
-    m_duration[sprite] = m_states[state]->variedDuration();
-    m_goals[sprite] = -1;
-    restart(sprite);
-    emit stateChanged(sprite);
-    emit m_states[state]->entered();
-    return;
-}
-
-QImage QSGSpriteEngine::assembledImage()
-{
-    int h = 0;
-    int w = 0;
-    m_maxFrames = 0;
-    m_imageStateCount = 0;
-    int maxSize = 0;
-
-    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
-    foreach (QSGStochasticState* s, m_states){
-        QSGSprite* sprite = qobject_cast<QSGSprite*>(s);
-        if (sprite)
-            m_sprites << sprite;
-        else
-            qDebug() << "Error: Non-sprite in QSGSpriteEngine";
-    }
-
-    foreach (QSGSprite* state, m_sprites){
-        if (state->frames() > m_maxFrames)
-            m_maxFrames = state->frames();
-
-        QImage img(state->source().toLocalFile());
-        if (img.isNull()) {
-            qWarning() << "SpriteEngine: loading image failed..." << state->source().toLocalFile();
-            return QImage();
-        }
-
-        //Check that the frame sizes are the same within one engine
-        if (!state->m_frameWidth)
-            state->m_frameWidth = img.width() / state->frames();
-
-        if (!state->m_frameHeight)
-            state->m_frameHeight = img.height();
-
-        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, 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
-    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{//Chopping up image case
-            state->m_framesPerRow = image.width()/frameWidth;
-            state->m_rowY = y;
-            int x = 0;
-            int curX = 0;
-            int curY = 0;
-            int framesLeft = state->frames();
-            while (framesLeft > 0){
-                if (image.width() - x + curX <= img.width()){//finish a row in image (dest)
-                    int copied = image.width() - x;
-                    Q_ASSERT(!(copied % frameWidth));//XXX: Just checking
-                    framesLeft -= copied/frameWidth;
-                    p.drawImage(x,y,img.copy(curX,curY,copied,frameHeight));
-                    y += frameHeight;
-                    curX += copied;
-                    x = 0;
-                    if (curX == img.width()){
-                        curX = 0;
-                        curY += frameHeight;
-                    }
-                }else{//finish a row in img (src)
-                    int copied = img.width() - curX;
-                    Q_ASSERT(!(copied % frameWidth));//XXX: Just checking
-                    framesLeft -= copied/frameWidth;
-                    p.drawImage(x,y,img.copy(curX,curY,copied,frameHeight));
-                    curY += frameHeight;
-                    x += copied;
-                    curX = 0;
-                }
-            }
-            if (x)
-                y += frameHeight;
-        }
-    }
-
-    if (image.height() > maxSize){
-        qWarning() << "SpriteEngine: Too many animations to fit in one texture...";
-        qWarning() << "SpriteEngine: Your texture max size today is " << maxSize;
-        return QImage();
-    }
-    return image;
-}
-
-void QSGStochasticEngine::setCount(int c)
-{
-    m_things.resize(c);
-    m_goals.resize(c);
-    m_duration.resize(c);
-    m_startTimes.resize(c);
-}
-
-void QSGStochasticEngine::start(int index, int state)
-{
-    if (index >= m_things.count())
-        return;
-    m_things[index] = state;
-    m_duration[index] = m_states[state]->variedDuration();
-    m_goals[index] = -1;
-    restart(index);
-}
-
-void QSGStochasticEngine::stop(int index)
-{
-    if (index >= m_things.count())
-        return;
-    //Will never change until start is called again with a new state - this is not a 'pause'
-    for (int i=0; i<m_stateUpdates.count(); i++)
-        m_stateUpdates[i].second.removeAll(index);
-}
-
-void QSGStochasticEngine::restart(int index)
-{
-    m_startTimes[index] = m_timeOffset + m_advanceTime.elapsed();
-    int time = m_duration[index] * m_states[m_things[index]]->frames() + m_startTimes[index];
-    for (int i=0; i<m_stateUpdates.count(); i++)
-        m_stateUpdates[i].second.removeAll(index);
-    addToUpdateList(time, index);
-}
-
-uint QSGStochasticEngine::updateSprites(uint time)//### would returning a list of changed idxs be faster than signals?
-{
-    //Sprite State Update;
-    QSet<int> changedIndexes;
-    while (!m_stateUpdates.isEmpty() && time >= m_stateUpdates.first().first){
-        foreach (int idx, m_stateUpdates.first().second){
-            if (idx >= m_things.count())
-                continue;//TODO: Proper fix(because this does happen and I'm just ignoring it)
-            int stateIdx = m_things[idx];
-            int nextIdx = -1;
-            int goalPath = goalSeek(stateIdx, idx);
-            if (goalPath == -1){//Random
-                qreal r =(qreal) qrand() / (qreal) RAND_MAX;
-                qreal total = 0.0;
-                for (QVariantMap::const_iterator iter=m_states[stateIdx]->m_to.constBegin();
-                    iter!=m_states[stateIdx]->m_to.constEnd(); iter++)
-                    total += (*iter).toReal();
-                r*=total;
-                for (QVariantMap::const_iterator iter= m_states[stateIdx]->m_to.constBegin();
-                        iter!=m_states[stateIdx]->m_to.constEnd(); iter++){
-                    if (r < (*iter).toReal()){
-                        bool superBreak = false;
-                        for (int i=0; i<m_states.count(); i++){
-                            if (m_states[i]->name() == iter.key()){
-                                nextIdx = i;
-                                superBreak = true;
-                                break;
-                            }
-                        }
-                        if (superBreak)
-                            break;
-                    }
-                    r -= (*iter).toReal();
-                }
-            }else{//Random out of shortest paths to goal
-                nextIdx = goalPath;
-            }
-            if (nextIdx == -1)//No to states means stay here
-                nextIdx = stateIdx;
-
-            m_things[idx] = nextIdx;
-            m_duration[idx] = m_states[nextIdx]->variedDuration();
-            m_startTimes[idx] = time;
-            if (nextIdx != stateIdx){
-                changedIndexes << idx;
-                emit m_states[nextIdx]->entered();
-            }
-            addToUpdateList((m_duration[idx] * m_states[nextIdx]->frames()) + time, idx);
-        }
-        m_stateUpdates.pop_front();
-    }
-
-    m_timeOffset = time;
-    m_advanceTime.start();
-    //TODO: emit this when a psuedostate changes too
-    foreach (int idx, changedIndexes){//Batched so that update list doesn't change midway
-        emit stateChanged(idx);
-    }
-    if (m_stateUpdates.isEmpty())
-        return -1;
-    return m_stateUpdates.first().first;
-}
-
-int QSGStochasticEngine::goalSeek(int curIdx, int spriteIdx, int dist)
-{
-    QString goalName;
-    if (m_goals[spriteIdx] != -1)
-        goalName = m_states[m_goals[spriteIdx]]->name();
-    else
-        goalName = m_globalGoal;
-    if (goalName.isEmpty())
-        return -1;
-    //TODO: caching instead of excessively redoing iterative deepening (which was chosen arbitarily anyways)
-    // Paraphrased - implement in an *efficient* manner
-    for (int i=0; i<m_states.count(); i++)
-        if (m_states[curIdx]->name() == goalName)
-            return curIdx;
-    if (dist < 0)
-        dist = m_states.count();
-    QSGStochasticState* curState = m_states[curIdx];
-    for (QVariantMap::const_iterator iter = curState->m_to.constBegin();
-        iter!=curState->m_to.constEnd(); iter++){
-        if (iter.key() == goalName)
-            for (int i=0; i<m_states.count(); i++)
-                if (m_states[i]->name() == goalName)
-                    return i;
-    }
-    QSet<int> options;
-    for (int i=1; i<dist; i++){
-        for (QVariantMap::const_iterator iter = curState->m_to.constBegin();
-            iter!=curState->m_to.constEnd(); iter++){
-            int option = -1;
-            for (int j=0; j<m_states.count(); j++)//One place that could be a lot more efficient...
-                if (m_states[j]->name() == iter.key())
-                    if (goalSeek(j, spriteIdx, i) != -1)
-                        option = j;
-            if (option != -1)
-                options << option;
-        }
-        if (!options.isEmpty()){
-            if (options.count()==1)
-                return *(options.begin());
-            int option = -1;
-            qreal r =(qreal) qrand() / (qreal) RAND_MAX;
-            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();
-            r *= total;
-            for (QVariantMap::const_iterator iter = curState->m_to.constBegin();
-                iter!=curState->m_to.constEnd(); iter++){
-                bool superContinue = true;
-                for (int j=0; j<m_states.count(); j++)
-                    if (m_states[j]->name() == iter.key())
-                        if (options.contains(j))
-                            superContinue = false;
-                if (superContinue)
-                    continue;
-                if (r < (*iter).toReal()){
-                    bool superBreak = false;
-                    for (int j=0; j<m_states.count(); j++){
-                        if (m_states[j]->name() == iter.key()){
-                            option = j;
-                            superBreak = true;
-                            break;
-                        }
-                    }
-                    if (superBreak)
-                        break;
-                }
-                r-=(*iter).toReal();
-            }
-            return option;
-        }
-    }
-    return -1;
-}
-
-void QSGStochasticEngine::addToUpdateList(uint t, int idx)
-{
-    for (int i=0; i<m_stateUpdates.count(); i++){
-        if (m_stateUpdates[i].first==t){
-            m_stateUpdates[i].second << idx;
-            return;
-        }else if (m_stateUpdates[i].first > t){
-            QList<int> tmpList;
-            tmpList << idx;
-            m_stateUpdates.insert(i, qMakePair(t, tmpList));
-            return;
-        }
-    }
-    QList<int> tmpList;
-    tmpList << idx;
-    m_stateUpdates << qMakePair(t, tmpList);
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgspriteengine_p.h b/src/declarative/items/qsgspriteengine_p.h
deleted file mode 100644 (file)
index 8140b38..0000000
+++ /dev/null
@@ -1,318 +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 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 SPRITEENGINE_H
-#define SPRITEENGINE_H
-
-#include <QObject>
-#include <QVector>
-#include <QTimer>
-#include <QTime>
-#include <QList>
-#include <QDeclarativeListProperty>
-#include <QImage>
-#include <QPair>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGSprite;
-class Q_AUTOTEST_EXPORT QSGStochasticState : public QObject //For internal use
-{
-    Q_OBJECT
-    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)
-
-public:
-    QSGStochasticState(QObject* parent = 0)
-        : QObject(parent)
-        , m_frames(1)
-        , m_duration(1000)
-    {
-    }
-
-    int duration() const
-    {
-        return m_duration;
-    }
-
-    QString name() const
-    {
-        return m_name;
-    }
-
-    QVariantMap to() const
-    {
-        return m_to;
-    }
-
-    qreal speedModifer() const
-    {
-        return m_speedModifier;
-    }
-
-    int durationVariance() const
-    {
-        return m_durationVariance;
-    }
-
-
-    int variedDuration() const
-    {
-        return m_duration
-                + (m_durationVariance * ((qreal)qrand()/RAND_MAX) * 2)
-                - m_durationVariance;
-    }
-
-    int frames() const
-    {
-        return m_frames;
-    }
-
-signals:
-    void durationChanged(int arg);
-
-    void nameChanged(QString arg);
-
-    void toChanged(QVariantMap arg);
-
-    void speedModifierChanged(qreal arg);
-
-    void durationVarianceChanged(int arg);
-
-    void entered();//### Just playing around - don't expect full state API
-    void framesChanged(int arg);
-
-public slots:
-    void setDuration(int arg)
-    {
-        if (m_duration != arg) {
-            m_duration = arg;
-            emit durationChanged(arg);
-        }
-    }
-
-    void setName(QString arg)
-    {
-        if (m_name != arg) {
-            m_name = arg;
-            emit nameChanged(arg);
-        }
-    }
-
-    void setTo(QVariantMap arg)
-    {
-        if (m_to != arg) {
-            m_to = arg;
-            emit toChanged(arg);
-        }
-    }
-
-    void setSpeedModifier(qreal arg)
-    {
-        if (m_speedModifier != arg) {
-            m_speedModifier = arg;
-            emit speedModifierChanged(arg);
-        }
-    }
-
-    void setDurationVariance(int arg)
-    {
-        if (m_durationVariance != arg) {
-            m_durationVariance = arg;
-            emit durationVarianceChanged(arg);
-        }
-    }
-
-    void setFrames(int arg)
-    {
-        if (m_frames != arg) {
-            m_frames = arg;
-            emit framesChanged(arg);
-        }
-    }
-
-private:
-    QString m_name;
-    int m_frames;
-    QVariantMap m_to;
-    int m_duration;
-    qreal m_speedModifier;
-    int m_durationVariance;
-
-    friend class QSGStochasticEngine;
-};
-
-class Q_AUTOTEST_EXPORT QSGStochasticEngine : public QObject
-{
-    Q_OBJECT
-    //TODO: Optimize single state case?
-    Q_PROPERTY(QString globalGoal READ globalGoal WRITE setGlobalGoal NOTIFY globalGoalChanged)
-    Q_PROPERTY(QDeclarativeListProperty<QSGStochasticState> states READ states)
-public:
-    explicit QSGStochasticEngine(QObject *parent = 0);
-    QSGStochasticEngine(QList<QSGStochasticState*> states, QObject *parent=0);
-    ~QSGStochasticEngine();
-
-    QDeclarativeListProperty<QSGStochasticState> states()
-    {
-        return QDeclarativeListProperty<QSGStochasticState>(this, m_states);
-    }
-
-    QString globalGoal() const
-    {
-        return m_globalGoal;
-    }
-
-    int count() const {return m_things.count();}
-    void setCount(int c);
-
-
-
-    void setGoal(int state, int sprite=0, bool jump=false);
-    void start(int index=0, int state=0);
-    void stop(int index=0);
-    int curState(int index=0) {return m_things[index];}
-
-    QSGStochasticState* state(int idx){return m_states[idx];}
-    int stateIndex(QSGStochasticState* s){return m_states.indexOf(s);}
-    int stateCount() {return m_states.count();}
-private:
-signals:
-
-    void globalGoalChanged(QString arg);
-    void stateChanged(int idx);
-
-public slots:
-    void setGlobalGoal(QString arg)
-    {
-        if (m_globalGoal != arg) {
-            m_globalGoal = arg;
-            emit globalGoalChanged(arg);
-        }
-    }
-
-    uint updateSprites(uint time);
-
-protected:
-    friend class QSGParticleSystem;
-    void restart(int index);
-    void addToUpdateList(uint t, int idx);
-    int goalSeek(int curState, int idx, int dist=-1);
-    QList<QSGStochasticState*> m_states;
-    //### Consider struct or class for the four data variables?
-    QVector<int> m_things;//int is the index in m_states of the current state
-    QVector<int> m_goals;
-    QVector<int> m_duration;
-    QVector<int> m_startTimes;
-    QList<QPair<uint, QList<int> > > m_stateUpdates;//### This could be done faster - priority queue?
-
-    QTime m_advanceTime;
-    uint m_timeOffset;
-    QString m_globalGoal;
-    int m_maxFrames;
-    int m_imageStateCount;
-};
-
-class QSGSpriteEngine : public QSGStochasticEngine
-{
-    Q_OBJECT
-    Q_PROPERTY(QDeclarativeListProperty<QSGSprite> sprites READ sprites)
-public:
-    explicit QSGSpriteEngine(QObject *parent = 0);
-    QSGSpriteEngine(QList<QSGSprite*> sprites, QObject *parent=0);
-    ~QSGSpriteEngine();
-    QDeclarativeListProperty<QSGSprite> sprites()
-    {
-        return QDeclarativeListProperty<QSGSprite>(this, m_sprites);
-    }
-
-
-    int spriteState(int sprite=0);
-    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();
-private:
-    QList<QSGSprite*> m_sprites;
-};
-
-//Common use is to have your own list property which is transparently an engine
-inline void spriteAppend(QDeclarativeListProperty<QSGSprite> *p, QSGSprite* s)
-{
-    reinterpret_cast<QList<QSGSprite *> *>(p->data)->append(s);
-    p->object->metaObject()->invokeMethod(p->object, "createEngine");
-}
-
-inline QSGSprite* spriteAt(QDeclarativeListProperty<QSGSprite> *p, int idx)
-{
-    return reinterpret_cast<QList<QSGSprite *> *>(p->data)->at(idx);
-}
-
-inline void spriteClear(QDeclarativeListProperty<QSGSprite> *p)
-{
-    reinterpret_cast<QList<QSGSprite *> *>(p->data)->clear();
-    p->object->metaObject()->invokeMethod(p->object, "createEngine");
-}
-
-inline int spriteCount(QDeclarativeListProperty<QSGSprite> *p)
-{
-    return reinterpret_cast<QList<QSGSprite *> *>(p->data)->count();
-}
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // SPRITEENGINE_H
diff --git a/src/declarative/items/qsgspriteimage.cpp b/src/declarative/items/qsgspriteimage.cpp
deleted file mode 100644 (file)
index f6cd35f..0000000
+++ /dev/null
@@ -1,421 +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 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 "qsgspriteimage_p.h"
-#include "qsgsprite_p.h"
-#include "qsgspriteengine_p.h"
-#include <private/qsgcontext_p.h>
-#include <private/qsgadaptationlayer_p.h>
-#include <qsgnode.h>
-#include <qsgengine.h>
-#include <qsgtexturematerial.h>
-#include <qsgtexture.h>
-#include <QFile>
-#include <cmath>
-#include <qmath.h>
-#include <QDebug>
-
-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:
-    QSGSpriteMaterial();
-    virtual ~QSGSpriteMaterial();
-    virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; }
-    virtual QSGMaterialShader *createShader() const;
-    virtual int compare(const QSGMaterial *other) const
-    {
-        return this - static_cast<const QSGSpriteMaterial *>(other);
-    }
-
-    QSGTexture *texture;
-
-    qreal timestamp;
-    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)
-    , 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);
-}
-
-QSGSpriteMaterial::~QSGSpriteMaterial()
-{
-    delete texture;
-}
-
-class SpriteMaterialData : public QSGMaterialShader
-{
-public:
-    SpriteMaterialData(const char *vertexFile = 0, const char *fragmentFile = 0)
-    {
-    }
-
-    void deactivate() {
-        QSGMaterialShader::deactivate();
-
-        for (int i=0; i<8; ++i) {
-            program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0);
-        }
-    }
-
-    virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *)
-    {
-        QSGSpriteMaterial *m = static_cast<QSGSpriteMaterial *>(newEffect);
-        m->texture->bind();
-
-        program()->setUniformValue(m_opacity_id, state.opacity());
-        program()->setUniformValue(m_timestamp_id, (float) m->timestamp);
-        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("qt_Matrix");
-        m_opacity_id = program()->uniformLocation("qt_Opacity");
-        m_timestamp_id = program()->uniformLocation("timestamp");
-        m_animData_id = program()->uniformLocation("animData");
-        m_animPos_id = program()->uniformLocation("animPos");
-        m_animSheetSize_id = program()->uniformLocation("animSheetSize");
-    }
-
-    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",
-            0
-        };
-        return attr;
-    }
-
-    int m_matrix_id;
-    int m_opacity_id;
-    int m_timestamp_id;
-    int m_animData_id;
-    int m_animPos_id;
-    int m_animSheetSize_id;
-
-    static float chunkOfBytes[1024];
-};
-
-float SpriteMaterialData::chunkOfBytes[1024];
-
-QSGMaterialShader *QSGSpriteMaterial::createShader() const
-{
-    return new SpriteMaterialData;
-}
-
-struct SpriteVertex {
-    float tx;
-    float ty;
-};
-
-struct SpriteVertices {
-    SpriteVertex v1;
-    SpriteVertex v2;
-    SpriteVertex v3;
-    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)
-    , m_material(0)
-    , m_spriteEngine(0)
-    , m_pleaseReset(false)
-    , m_running(true)
-    , m_interpolate(true)
-{
-    setFlag(ItemHasContents);
-    connect(this, SIGNAL(runningChanged(bool)),
-            this, SLOT(update()));
-}
-
-QDeclarativeListProperty<QSGSprite> QSGSpriteImage::sprites()
-{
-    return QDeclarativeListProperty<QSGSprite>(this, &m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear);
-}
-
-void QSGSpriteImage::createEngine()
-{
-    //TODO: delay until component complete
-    if (m_spriteEngine)
-        delete m_spriteEngine;
-    if (m_sprites.count())
-        m_spriteEngine = new QSGSpriteEngine(m_sprites, this);
-    else
-        m_spriteEngine = 0;
-    reset();
-}
-
-static QSGGeometry::Attribute SpriteImage_Attributes[] = {
-    QSGGeometry::Attribute::create(0, 2, GL_FLOAT),         // tex
-};
-
-static QSGGeometry::AttributeSet SpriteImage_AttributeSet =
-{
-    1, // Attribute Count
-    2 * sizeof(float),
-    SpriteImage_Attributes
-};
-
-QSGGeometryNode* QSGSpriteImage::buildNode()
-{
-    if (!m_spriteEngine) {
-        qWarning() << "SpriteImage: No sprite engine...";
-        return 0;
-    }
-
-    m_material = new QSGSpriteMaterial();
-
-    QImage image = m_spriteEngine->assembledImage();
-    if (image.isNull())
-        return 0;
-    m_material->texture = sceneGraphEngine()->createTextureFromImage(image);
-    m_material->texture->setFiltering(QSGTexture::Linear);
-    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;
-    QSGGeometry *g = new QSGGeometry(SpriteImage_AttributeSet, vCount, iCount);
-    g->setDrawingMode(GL_TRIANGLES);
-
-    SpriteVertices *p = (SpriteVertices *) g->vertexData();
-
-    p->v1.tx = 0;
-    p->v1.ty = 0;
-
-    p->v2.tx = 1.0;
-    p->v2.ty = 0;
-
-    p->v3.tx = 0;
-    p->v3.ty = 1.0;
-
-    p->v4.tx = 1.0;
-    p->v4.ty = 1.0;
-
-    quint16 *indices = g->indexDataAsUShort();
-    indices[0] = 0;
-    indices[1] = 1;
-    indices[2] = 2;
-    indices[3] = 1;
-    indices[4] = 3;
-    indices[5] = 2;
-
-
-    m_timestamp.start();
-    m_node = new QSGGeometryNode();
-    m_node->setGeometry(g);
-    m_node->setMaterial(m_material);
-    m_node->setFlag(QSGGeometryNode::OwnsMaterial);
-    return m_node;
-}
-
-void QSGSpriteImage::reset()
-{
-    m_pleaseReset = true;
-}
-
-QSGNode *QSGSpriteImage::updatePaintNode(QSGNode *, UpdatePaintNodeData *)
-{
-    if (m_pleaseReset) {
-        delete m_node;
-        delete m_material;
-
-        m_node = 0;
-        m_material = 0;
-        m_pleaseReset = false;
-    }
-
-    prepareNextFrame();
-
-    if (m_running) {
-        update();
-        if (m_node)
-            m_node->markDirty(QSGNode::DirtyMaterial);
-    }
-
-    return m_node;
-}
-
-void QSGSpriteImage::prepareNextFrame()
-{
-    if (m_node == 0)
-        m_node = buildNode();
-    if (m_node == 0) //error creating node
-        return;
-
-    uint timeInt = m_timestamp.elapsed();
-    qreal time =  timeInt / 1000.;
-    m_material->timestamp = time;
-    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 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();
-    }
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgspriteimage_p.h b/src/declarative/items/qsgspriteimage_p.h
deleted file mode 100644 (file)
index 84c5b50..0000000
+++ /dev/null
@@ -1,129 +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 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 SPRITEIMAGE_H
-#define SPRITEIMAGE_H
-
-#include <QSGItem>
-#include <QTime>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGContext;
-class QSGSprite;
-class QSGSpriteEngine;
-class QSGGeometryNode;
-class QSGSpriteMaterial;
-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")
-
-public:
-    explicit QSGSpriteImage(QSGItem *parent = 0);
-
-    QDeclarativeListProperty<QSGSprite> sprites();
-
-    bool running() const
-    {
-        return m_running;
-    }
-
-    bool interpolate() const
-    {
-        return m_interpolate;
-    }
-
-signals:
-
-    void runningChanged(bool arg);
-    void interpolateChanged(bool arg);
-
-public slots:
-
-void setRunning(bool arg)
-{
-    if (m_running != arg) {
-        m_running = arg;
-        emit runningChanged(arg);
-    }
-}
-
-void setInterpolate(bool arg)
-{
-    if (m_interpolate != arg) {
-        m_interpolate = arg;
-        emit interpolateChanged(arg);
-    }
-}
-
-private slots:
-    void createEngine();
-protected:
-    void reset();
-    QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
-private:
-    void prepareNextFrame();
-    QSGGeometryNode* buildNode();
-    QSGGeometryNode *m_node;
-    QSGSpriteMaterial *m_material;
-    QList<QSGSprite*> m_sprites;
-    QSGSpriteEngine* m_spriteEngine;
-    QTime m_timestamp;
-    int m_maxFrames;
-    bool m_pleaseReset;
-    bool m_running;
-    bool m_interpolate;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // SPRITEIMAGE_H
diff --git a/src/declarative/items/qsgstateoperations.cpp b/src/declarative/items/qsgstateoperations.cpp
deleted file mode 100644 (file)
index 8f878f3..0000000
+++ /dev/null
@@ -1,1346 +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$
-**
-****************************************************************************/
-
-#include "qsgstateoperations_p.h"
-#include "qsgitem_p.h"
-
-#include <private/qdeclarativestate_p_p.h>
-
-#include <QtDeclarative/qdeclarativeinfo.h>
-#include <QtCore/qmath.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGParentChangePrivate : public QDeclarativeStateOperationPrivate
-{
-    Q_DECLARE_PUBLIC(QSGParentChange)
-public:
-    QSGParentChangePrivate() : target(0), parent(0), origParent(0), origStackBefore(0),
-        rewindParent(0), rewindStackBefore(0) {}
-
-    QSGItem *target;
-    QDeclarativeGuard<QSGItem> parent;
-    QDeclarativeGuard<QSGItem> origParent;
-    QDeclarativeGuard<QSGItem> origStackBefore;
-    QSGItem *rewindParent;
-    QSGItem *rewindStackBefore;
-
-    QDeclarativeNullableValue<QDeclarativeScriptString> xString;
-    QDeclarativeNullableValue<QDeclarativeScriptString> yString;
-    QDeclarativeNullableValue<QDeclarativeScriptString> widthString;
-    QDeclarativeNullableValue<QDeclarativeScriptString> heightString;
-    QDeclarativeNullableValue<QDeclarativeScriptString> scaleString;
-    QDeclarativeNullableValue<QDeclarativeScriptString> rotationString;
-
-    void doChange(QSGItem *targetParent, QSGItem *stackBefore = 0);
-};
-
-void QSGParentChangePrivate::doChange(QSGItem *targetParent, QSGItem *stackBefore)
-{
-    if (targetParent && target && target->parentItem()) {
-        Q_Q(QSGParentChange);
-        bool ok;
-        const QTransform &transform = target->parentItem()->itemTransform(targetParent, &ok);
-        if (transform.type() >= QTransform::TxShear || !ok) {
-            qmlInfo(q) << QSGParentChange::tr("Unable to preserve appearance under complex transform");
-            ok = false;
-        }
-
-        qreal scale = 1;
-        qreal rotation = 0;
-        bool isRotate = (transform.type() == QTransform::TxRotate) || (transform.m11() < 0);
-        if (ok && !isRotate) {
-            if (transform.m11() == transform.m22())
-                scale = transform.m11();
-            else {
-                qmlInfo(q) << QSGParentChange::tr("Unable to preserve appearance under non-uniform scale");
-                ok = false;
-            }
-        } else if (ok && isRotate) {
-            if (transform.m11() == transform.m22())
-                scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12());
-            else {
-                qmlInfo(q) << QSGParentChange::tr("Unable to preserve appearance under non-uniform scale");
-                ok = false;
-            }
-
-            if (scale != 0)
-                rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
-            else {
-                qmlInfo(q) << QSGParentChange::tr("Unable to preserve appearance under scale of 0");
-                ok = false;
-            }
-        }
-
-        const QPointF &point = transform.map(QPointF(target->x(),target->y()));
-        qreal x = point.x();
-        qreal y = point.y();
-
-        // setParentItem will update the transformOriginPoint if needed
-        target->setParentItem(targetParent);
-
-        if (ok && target->transformOrigin() != QSGItem::TopLeft) {
-            qreal tempxt = target->transformOriginPoint().x();
-            qreal tempyt = target->transformOriginPoint().y();
-            QTransform t;
-            t.translate(-tempxt, -tempyt);
-            t.rotate(rotation);
-            t.scale(scale, scale);
-            t.translate(tempxt, tempyt);
-            const QPointF &offset = t.map(QPointF(0,0));
-            x += offset.x();
-            y += offset.y();
-        }
-
-        if (ok) {
-            //qDebug() << x << y << rotation << scale;
-            target->setX(x);
-            target->setY(y);
-            target->setRotation(target->rotation() + rotation);
-            target->setScale(target->scale() * scale);
-        }
-    } else if (target) {
-        target->setParentItem(targetParent);
-    }
-
-    //restore the original stack position.
-    //### if stackBefore has also been reparented this won't work
-    if (stackBefore)
-        target->stackBefore(stackBefore);
-}
-
-QSGParentChange::QSGParentChange(QObject *parent)
-    : QDeclarativeStateOperation(*(new QSGParentChangePrivate), parent)
-{
-}
-
-QSGParentChange::~QSGParentChange()
-{
-}
-
-QDeclarativeScriptString QSGParentChange::x() const
-{
-    Q_D(const QSGParentChange);
-    return d->xString.value;
-}
-
-void QSGParentChange::setX(QDeclarativeScriptString x)
-{
-    Q_D(QSGParentChange);
-    d->xString = x;
-}
-
-bool QSGParentChange::xIsSet() const
-{
-    Q_D(const QSGParentChange);
-    return d->xString.isValid();
-}
-
-QDeclarativeScriptString QSGParentChange::y() const
-{
-    Q_D(const QSGParentChange);
-    return d->yString.value;
-}
-
-void QSGParentChange::setY(QDeclarativeScriptString y)
-{
-    Q_D(QSGParentChange);
-    d->yString = y;
-}
-
-bool QSGParentChange::yIsSet() const
-{
-    Q_D(const QSGParentChange);
-    return d->yString.isValid();
-}
-
-QDeclarativeScriptString QSGParentChange::width() const
-{
-    Q_D(const QSGParentChange);
-    return d->widthString.value;
-}
-
-void QSGParentChange::setWidth(QDeclarativeScriptString width)
-{
-    Q_D(QSGParentChange);
-    d->widthString = width;
-}
-
-bool QSGParentChange::widthIsSet() const
-{
-    Q_D(const QSGParentChange);
-    return d->widthString.isValid();
-}
-
-QDeclarativeScriptString QSGParentChange::height() const
-{
-    Q_D(const QSGParentChange);
-    return d->heightString.value;
-}
-
-void QSGParentChange::setHeight(QDeclarativeScriptString height)
-{
-    Q_D(QSGParentChange);
-    d->heightString = height;
-}
-
-bool QSGParentChange::heightIsSet() const
-{
-    Q_D(const QSGParentChange);
-    return d->heightString.isValid();
-}
-
-QDeclarativeScriptString QSGParentChange::scale() const
-{
-    Q_D(const QSGParentChange);
-    return d->scaleString.value;
-}
-
-void QSGParentChange::setScale(QDeclarativeScriptString scale)
-{
-    Q_D(QSGParentChange);
-    d->scaleString = scale;
-}
-
-bool QSGParentChange::scaleIsSet() const
-{
-    Q_D(const QSGParentChange);
-    return d->scaleString.isValid();
-}
-
-QDeclarativeScriptString QSGParentChange::rotation() const
-{
-    Q_D(const QSGParentChange);
-    return d->rotationString.value;
-}
-
-void QSGParentChange::setRotation(QDeclarativeScriptString rotation)
-{
-    Q_D(QSGParentChange);
-    d->rotationString = rotation;
-}
-
-bool QSGParentChange::rotationIsSet() const
-{
-    Q_D(const QSGParentChange);
-    return d->rotationString.isValid();
-}
-
-QSGItem *QSGParentChange::originalParent() const
-{
-    Q_D(const QSGParentChange);
-    return d->origParent;
-}
-
-QSGItem *QSGParentChange::object() const
-{
-    Q_D(const QSGParentChange);
-    return d->target;
-}
-
-void QSGParentChange::setObject(QSGItem *target)
-{
-    Q_D(QSGParentChange);
-    d->target = target;
-}
-
-QSGItem *QSGParentChange::parent() const
-{
-    Q_D(const QSGParentChange);
-    return d->parent;
-}
-
-void QSGParentChange::setParent(QSGItem *parent)
-{
-    Q_D(QSGParentChange);
-    d->parent = parent;
-}
-
-QDeclarativeStateOperation::ActionList QSGParentChange::actions()
-{
-    Q_D(QSGParentChange);
-    if (!d->target || !d->parent)
-        return ActionList();
-
-    ActionList actions;
-
-    QDeclarativeAction a;
-    a.event = this;
-    actions << a;
-
-    if (d->xString.isValid()) {
-        bool ok = false;
-        QString script = d->xString.value.script();
-        qreal x = script.toFloat(&ok);
-        if (ok) {
-            QDeclarativeAction xa(d->target, QLatin1String("x"), x);
-            actions << xa;
-        } else {
-            QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
-            newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("x")));
-            QDeclarativeAction xa;
-            xa.property = newBinding->property();
-            xa.toBinding = newBinding;
-            xa.fromValue = xa.property.read();
-            xa.deletableToBinding = true;
-            actions << xa;
-        }
-    }
-
-    if (d->yString.isValid()) {
-        bool ok = false;
-        QString script = d->yString.value.script();
-        qreal y = script.toFloat(&ok);
-        if (ok) {
-            QDeclarativeAction ya(d->target, QLatin1String("y"), y);
-            actions << ya;
-        } else {
-            QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
-            newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("y")));
-            QDeclarativeAction ya;
-            ya.property = newBinding->property();
-            ya.toBinding = newBinding;
-            ya.fromValue = ya.property.read();
-            ya.deletableToBinding = true;
-            actions << ya;
-        }
-    }
-
-    if (d->scaleString.isValid()) {
-        bool ok = false;
-        QString script = d->scaleString.value.script();
-        qreal scale = script.toFloat(&ok);
-        if (ok) {
-            QDeclarativeAction sa(d->target, QLatin1String("scale"), scale);
-            actions << sa;
-        } else {
-            QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
-            newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("scale")));
-            QDeclarativeAction sa;
-            sa.property = newBinding->property();
-            sa.toBinding = newBinding;
-            sa.fromValue = sa.property.read();
-            sa.deletableToBinding = true;
-            actions << sa;
-        }
-    }
-
-    if (d->rotationString.isValid()) {
-        bool ok = false;
-        QString script = d->rotationString.value.script();
-        qreal rotation = script.toFloat(&ok);
-        if (ok) {
-            QDeclarativeAction ra(d->target, QLatin1String("rotation"), rotation);
-            actions << ra;
-        } else {
-            QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
-            newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("rotation")));
-            QDeclarativeAction ra;
-            ra.property = newBinding->property();
-            ra.toBinding = newBinding;
-            ra.fromValue = ra.property.read();
-            ra.deletableToBinding = true;
-            actions << ra;
-        }
-    }
-
-    if (d->widthString.isValid()) {
-        bool ok = false;
-        QString script = d->widthString.value.script();
-        qreal width = script.toFloat(&ok);
-        if (ok) {
-            QDeclarativeAction wa(d->target, QLatin1String("width"), width);
-            actions << wa;
-        } else {
-            QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
-            newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("width")));
-            QDeclarativeAction wa;
-            wa.property = newBinding->property();
-            wa.toBinding = newBinding;
-            wa.fromValue = wa.property.read();
-            wa.deletableToBinding = true;
-            actions << wa;
-        }
-    }
-
-    if (d->heightString.isValid()) {
-        bool ok = false;
-        QString script = d->heightString.value.script();
-        qreal height = script.toFloat(&ok);
-        if (ok) {
-            QDeclarativeAction ha(d->target, QLatin1String("height"), height);
-            actions << ha;
-        } else {
-            QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
-            newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("height")));
-            QDeclarativeAction ha;
-            ha.property = newBinding->property();
-            ha.toBinding = newBinding;
-            ha.fromValue = ha.property.read();
-            ha.deletableToBinding = true;
-            actions << ha;
-        }
-    }
-
-    return actions;
-}
-
-void QSGParentChange::saveOriginals()
-{
-    Q_D(QSGParentChange);
-    saveCurrentValues();
-    d->origParent = d->rewindParent;
-    d->origStackBefore = d->rewindStackBefore;
-}
-
-/*void QSGParentChange::copyOriginals(QDeclarativeActionEvent *other)
-{
-    Q_D(QSGParentChange);
-    QSGParentChange *pc = static_cast<QSGParentChange*>(other);
-
-    d->origParent = pc->d_func()->rewindParent;
-    d->origStackBefore = pc->d_func()->rewindStackBefore;
-
-    saveCurrentValues();
-}*/
-
-void QSGParentChange::execute(Reason)
-{
-    Q_D(QSGParentChange);
-    d->doChange(d->parent);
-}
-
-bool QSGParentChange::isReversable()
-{
-    return true;
-}
-
-void QSGParentChange::reverse(Reason)
-{
-    Q_D(QSGParentChange);
-    d->doChange(d->origParent, d->origStackBefore);
-}
-
-QString QSGParentChange::typeName() const
-{
-    return QLatin1String("ParentChange");
-}
-
-bool QSGParentChange::override(QDeclarativeActionEvent*other)
-{
-    Q_D(QSGParentChange);
-    if (other->typeName() != QLatin1String("ParentChange"))
-        return false;
-    if (QSGParentChange *otherPC = static_cast<QSGParentChange*>(other))
-        return (d->target == otherPC->object());
-    return false;
-}
-
-void QSGParentChange::saveCurrentValues()
-{
-    Q_D(QSGParentChange);
-    if (!d->target) {
-        d->rewindParent = 0;
-        d->rewindStackBefore = 0;
-        return;
-    }
-
-    d->rewindParent = d->target->parentItem();
-    d->rewindStackBefore = 0;
-
-    if (!d->rewindParent)
-        return;
-
-    QList<QSGItem *> children = d->rewindParent->childItems();
-    for (int ii = 0; ii < children.count() - 1; ++ii) {
-        if (children.at(ii) == d->target) {
-            d->rewindStackBefore = children.at(ii + 1);
-            break;
-        }
-    }
-}
-
-void QSGParentChange::rewind()
-{
-    Q_D(QSGParentChange);
-    d->doChange(d->rewindParent, d->rewindStackBefore);
-}
-
-class QSGAnchorSetPrivate : public QObjectPrivate
-{
-    Q_DECLARE_PUBLIC(QSGAnchorSet)
-public:
-    QSGAnchorSetPrivate()
-      : usedAnchors(0), resetAnchors(0), fill(0),
-        centerIn(0)/*, leftMargin(0), rightMargin(0), topMargin(0), bottomMargin(0),
-        margins(0), vCenterOffset(0), hCenterOffset(0), baselineOffset(0)*/
-    {
-    }
-
-    QSGAnchors::Anchors usedAnchors;
-    QSGAnchors::Anchors resetAnchors;
-
-    QSGItem *fill;
-    QSGItem *centerIn;
-
-    QDeclarativeScriptString leftScript;
-    QDeclarativeScriptString rightScript;
-    QDeclarativeScriptString topScript;
-    QDeclarativeScriptString bottomScript;
-    QDeclarativeScriptString hCenterScript;
-    QDeclarativeScriptString vCenterScript;
-    QDeclarativeScriptString baselineScript;
-
-    /*qreal leftMargin;
-    qreal rightMargin;
-    qreal topMargin;
-    qreal bottomMargin;
-    qreal margins;
-    qreal vCenterOffset;
-    qreal hCenterOffset;
-    qreal baselineOffset;*/
-};
-
-QSGAnchorSet::QSGAnchorSet(QObject *parent)
-  : QObject(*new QSGAnchorSetPrivate, parent)
-{
-}
-
-QSGAnchorSet::~QSGAnchorSet()
-{
-}
-
-QDeclarativeScriptString QSGAnchorSet::top() const
-{
-    Q_D(const QSGAnchorSet);
-    return d->topScript;
-}
-
-void QSGAnchorSet::setTop(const QDeclarativeScriptString &edge)
-{
-    Q_D(QSGAnchorSet);
-    d->usedAnchors |= QSGAnchors::TopAnchor;
-    d->topScript = edge;
-    if (edge.script() == QLatin1String("undefined"))
-        resetTop();
-}
-
-void QSGAnchorSet::resetTop()
-{
-    Q_D(QSGAnchorSet);
-    d->usedAnchors &= ~QSGAnchors::TopAnchor;
-    d->topScript = QDeclarativeScriptString();
-    d->resetAnchors |= QSGAnchors::TopAnchor;
-}
-
-QDeclarativeScriptString QSGAnchorSet::bottom() const
-{
-    Q_D(const QSGAnchorSet);
-    return d->bottomScript;
-}
-
-void QSGAnchorSet::setBottom(const QDeclarativeScriptString &edge)
-{
-    Q_D(QSGAnchorSet);
-    d->usedAnchors |= QSGAnchors::BottomAnchor;
-    d->bottomScript = edge;
-    if (edge.script() == QLatin1String("undefined"))
-        resetBottom();
-}
-
-void QSGAnchorSet::resetBottom()
-{
-    Q_D(QSGAnchorSet);
-    d->usedAnchors &= ~QSGAnchors::BottomAnchor;
-    d->bottomScript = QDeclarativeScriptString();
-    d->resetAnchors |= QSGAnchors::BottomAnchor;
-}
-
-QDeclarativeScriptString QSGAnchorSet::verticalCenter() const
-{
-    Q_D(const QSGAnchorSet);
-    return d->vCenterScript;
-}
-
-void QSGAnchorSet::setVerticalCenter(const QDeclarativeScriptString &edge)
-{
-    Q_D(QSGAnchorSet);
-    d->usedAnchors |= QSGAnchors::VCenterAnchor;
-    d->vCenterScript = edge;
-    if (edge.script() == QLatin1String("undefined"))
-        resetVerticalCenter();
-}
-
-void QSGAnchorSet::resetVerticalCenter()
-{
-    Q_D(QSGAnchorSet);
-    d->usedAnchors &= ~QSGAnchors::VCenterAnchor;
-    d->vCenterScript = QDeclarativeScriptString();
-    d->resetAnchors |= QSGAnchors::VCenterAnchor;
-}
-
-QDeclarativeScriptString QSGAnchorSet::baseline() const
-{
-    Q_D(const QSGAnchorSet);
-    return d->baselineScript;
-}
-
-void QSGAnchorSet::setBaseline(const QDeclarativeScriptString &edge)
-{
-    Q_D(QSGAnchorSet);
-    d->usedAnchors |= QSGAnchors::BaselineAnchor;
-    d->baselineScript = edge;
-    if (edge.script() == QLatin1String("undefined"))
-        resetBaseline();
-}
-
-void QSGAnchorSet::resetBaseline()
-{
-    Q_D(QSGAnchorSet);
-    d->usedAnchors &= ~QSGAnchors::BaselineAnchor;
-    d->baselineScript = QDeclarativeScriptString();
-    d->resetAnchors |= QSGAnchors::BaselineAnchor;
-}
-
-QDeclarativeScriptString QSGAnchorSet::left() const
-{
-    Q_D(const QSGAnchorSet);
-    return d->leftScript;
-}
-
-void QSGAnchorSet::setLeft(const QDeclarativeScriptString &edge)
-{
-    Q_D(QSGAnchorSet);
-    d->usedAnchors |= QSGAnchors::LeftAnchor;
-    d->leftScript = edge;
-    if (edge.script() == QLatin1String("undefined"))
-        resetLeft();
-}
-
-void QSGAnchorSet::resetLeft()
-{
-    Q_D(QSGAnchorSet);
-    d->usedAnchors &= ~QSGAnchors::LeftAnchor;
-    d->leftScript = QDeclarativeScriptString();
-    d->resetAnchors |= QSGAnchors::LeftAnchor;
-}
-
-QDeclarativeScriptString QSGAnchorSet::right() const
-{
-    Q_D(const QSGAnchorSet);
-    return d->rightScript;
-}
-
-void QSGAnchorSet::setRight(const QDeclarativeScriptString &edge)
-{
-    Q_D(QSGAnchorSet);
-    d->usedAnchors |= QSGAnchors::RightAnchor;
-    d->rightScript = edge;
-    if (edge.script() == QLatin1String("undefined"))
-        resetRight();
-}
-
-void QSGAnchorSet::resetRight()
-{
-    Q_D(QSGAnchorSet);
-    d->usedAnchors &= ~QSGAnchors::RightAnchor;
-    d->rightScript = QDeclarativeScriptString();
-    d->resetAnchors |= QSGAnchors::RightAnchor;
-}
-
-QDeclarativeScriptString QSGAnchorSet::horizontalCenter() const
-{
-    Q_D(const QSGAnchorSet);
-    return d->hCenterScript;
-}
-
-void QSGAnchorSet::setHorizontalCenter(const QDeclarativeScriptString &edge)
-{
-    Q_D(QSGAnchorSet);
-    d->usedAnchors |= QSGAnchors::HCenterAnchor;
-    d->hCenterScript = edge;
-    if (edge.script() == QLatin1String("undefined"))
-        resetHorizontalCenter();
-}
-
-void QSGAnchorSet::resetHorizontalCenter()
-{
-    Q_D(QSGAnchorSet);
-    d->usedAnchors &= ~QSGAnchors::HCenterAnchor;
-    d->hCenterScript = QDeclarativeScriptString();
-    d->resetAnchors |= QSGAnchors::HCenterAnchor;
-}
-
-QSGItem *QSGAnchorSet::fill() const
-{
-    Q_D(const QSGAnchorSet);
-    return d->fill;
-}
-
-void QSGAnchorSet::setFill(QSGItem *f)
-{
-    Q_D(QSGAnchorSet);
-    d->fill = f;
-}
-
-void QSGAnchorSet::resetFill()
-{
-    setFill(0);
-}
-
-QSGItem *QSGAnchorSet::centerIn() const
-{
-    Q_D(const QSGAnchorSet);
-    return d->centerIn;
-}
-
-void QSGAnchorSet::setCenterIn(QSGItem* c)
-{
-    Q_D(QSGAnchorSet);
-    d->centerIn = c;
-}
-
-void QSGAnchorSet::resetCenterIn()
-{
-    setCenterIn(0);
-}
-
-
-class QSGAnchorChangesPrivate : public QDeclarativeStateOperationPrivate
-{
-public:
-    QSGAnchorChangesPrivate()
-        : target(0), anchorSet(new QSGAnchorSet),
-          leftBinding(0), rightBinding(0), hCenterBinding(0),
-          topBinding(0), bottomBinding(0), vCenterBinding(0), baselineBinding(0),
-          origLeftBinding(0), origRightBinding(0), origHCenterBinding(0),
-          origTopBinding(0), origBottomBinding(0), origVCenterBinding(0),
-          origBaselineBinding(0)
-    {
-
-    }
-    ~QSGAnchorChangesPrivate() { delete anchorSet; }
-
-    QSGItem *target;
-    QSGAnchorSet *anchorSet;
-
-    QDeclarativeBinding *leftBinding;
-    QDeclarativeBinding *rightBinding;
-    QDeclarativeBinding *hCenterBinding;
-    QDeclarativeBinding *topBinding;
-    QDeclarativeBinding *bottomBinding;
-    QDeclarativeBinding *vCenterBinding;
-    QDeclarativeBinding *baselineBinding;
-
-    QDeclarativeAbstractBinding *origLeftBinding;
-    QDeclarativeAbstractBinding *origRightBinding;
-    QDeclarativeAbstractBinding *origHCenterBinding;
-    QDeclarativeAbstractBinding *origTopBinding;
-    QDeclarativeAbstractBinding *origBottomBinding;
-    QDeclarativeAbstractBinding *origVCenterBinding;
-    QDeclarativeAbstractBinding *origBaselineBinding;
-
-    QSGAnchorLine rewindLeft;
-    QSGAnchorLine rewindRight;
-    QSGAnchorLine rewindHCenter;
-    QSGAnchorLine rewindTop;
-    QSGAnchorLine rewindBottom;
-    QSGAnchorLine rewindVCenter;
-    QSGAnchorLine rewindBaseline;
-
-    qreal fromX;
-    qreal fromY;
-    qreal fromWidth;
-    qreal fromHeight;
-
-    qreal toX;
-    qreal toY;
-    qreal toWidth;
-    qreal toHeight;
-
-    qreal rewindX;
-    qreal rewindY;
-    qreal rewindWidth;
-    qreal rewindHeight;
-
-    bool applyOrigLeft;
-    bool applyOrigRight;
-    bool applyOrigHCenter;
-    bool applyOrigTop;
-    bool applyOrigBottom;
-    bool applyOrigVCenter;
-    bool applyOrigBaseline;
-
-    QDeclarativeNullableValue<qreal> origWidth;
-    QDeclarativeNullableValue<qreal> origHeight;
-    qreal origX;
-    qreal origY;
-
-    QList<QDeclarativeAbstractBinding*> oldBindings;
-
-    QDeclarativeProperty leftProp;
-    QDeclarativeProperty rightProp;
-    QDeclarativeProperty hCenterProp;
-    QDeclarativeProperty topProp;
-    QDeclarativeProperty bottomProp;
-    QDeclarativeProperty vCenterProp;
-    QDeclarativeProperty baselineProp;
-};
-
-QSGAnchorChanges::QSGAnchorChanges(QObject *parent)
- : QDeclarativeStateOperation(*(new QSGAnchorChangesPrivate), parent)
-{
-}
-
-QSGAnchorChanges::~QSGAnchorChanges()
-{
-}
-
-QSGAnchorChanges::ActionList QSGAnchorChanges::actions()
-{
-    Q_D(QSGAnchorChanges);
-    d->leftBinding = d->rightBinding = d->hCenterBinding = d->topBinding
-                   = d->bottomBinding = d->vCenterBinding = d->baselineBinding = 0;
-
-    d->leftProp = QDeclarativeProperty(d->target, QLatin1String("anchors.left"));
-    d->rightProp = QDeclarativeProperty(d->target, QLatin1String("anchors.right"));
-    d->hCenterProp = QDeclarativeProperty(d->target, QLatin1String("anchors.horizontalCenter"));
-    d->topProp = QDeclarativeProperty(d->target, QLatin1String("anchors.top"));
-    d->bottomProp = QDeclarativeProperty(d->target, QLatin1String("anchors.bottom"));
-    d->vCenterProp = QDeclarativeProperty(d->target, QLatin1String("anchors.verticalCenter"));
-    d->baselineProp = QDeclarativeProperty(d->target, QLatin1String("anchors.baseline"));
-
-    if (d->anchorSet->d_func()->usedAnchors & QSGAnchors::LeftAnchor) {
-        d->leftBinding = new QDeclarativeBinding(d->anchorSet->d_func()->leftScript.script(), d->target, qmlContext(this));
-        d->leftBinding->setTarget(d->leftProp);
-    }
-    if (d->anchorSet->d_func()->usedAnchors & QSGAnchors::RightAnchor) {
-        d->rightBinding = new QDeclarativeBinding(d->anchorSet->d_func()->rightScript.script(), d->target, qmlContext(this));
-        d->rightBinding->setTarget(d->rightProp);
-    }
-    if (d->anchorSet->d_func()->usedAnchors & QSGAnchors::HCenterAnchor) {
-        d->hCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->hCenterScript.script(), d->target, qmlContext(this));
-        d->hCenterBinding->setTarget(d->hCenterProp);
-    }
-    if (d->anchorSet->d_func()->usedAnchors & QSGAnchors::TopAnchor) {
-        d->topBinding = new QDeclarativeBinding(d->anchorSet->d_func()->topScript.script(), d->target, qmlContext(this));
-        d->topBinding->setTarget(d->topProp);
-    }
-    if (d->anchorSet->d_func()->usedAnchors & QSGAnchors::BottomAnchor) {
-        d->bottomBinding = new QDeclarativeBinding(d->anchorSet->d_func()->bottomScript.script(), d->target, qmlContext(this));
-        d->bottomBinding->setTarget(d->bottomProp);
-    }
-    if (d->anchorSet->d_func()->usedAnchors & QSGAnchors::VCenterAnchor) {
-        d->vCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->vCenterScript.script(), d->target, qmlContext(this));
-        d->vCenterBinding->setTarget(d->vCenterProp);
-    }
-    if (d->anchorSet->d_func()->usedAnchors & QSGAnchors::BaselineAnchor) {
-        d->baselineBinding = new QDeclarativeBinding(d->anchorSet->d_func()->baselineScript.script(), d->target, qmlContext(this));
-        d->baselineBinding->setTarget(d->baselineProp);
-    }
-
-    QDeclarativeAction a;
-    a.event = this;
-    return ActionList() << a;
-}
-
-QSGAnchorSet *QSGAnchorChanges::anchors()
-{
-    Q_D(QSGAnchorChanges);
-    return d->anchorSet;
-}
-
-QSGItem *QSGAnchorChanges::object() const
-{
-    Q_D(const QSGAnchorChanges);
-    return d->target;
-}
-
-void QSGAnchorChanges::setObject(QSGItem *target)
-{
-    Q_D(QSGAnchorChanges);
-    d->target = target;
-}
-
-void QSGAnchorChanges::execute(Reason reason)
-{
-    Q_D(QSGAnchorChanges);
-    if (!d->target)
-        return;
-
-    QSGItemPrivate *targetPrivate = QSGItemPrivate::get(d->target);
-    //incorporate any needed "reverts"
-    if (d->applyOrigLeft) {
-        if (!d->origLeftBinding)
-            targetPrivate->anchors()->resetLeft();
-        QDeclarativePropertyPrivate::setBinding(d->leftProp, d->origLeftBinding);
-    }
-    if (d->applyOrigRight) {
-        if (!d->origRightBinding)
-            targetPrivate->anchors()->resetRight();
-        QDeclarativePropertyPrivate::setBinding(d->rightProp, d->origRightBinding);
-    }
-    if (d->applyOrigHCenter) {
-        if (!d->origHCenterBinding)
-            targetPrivate->anchors()->resetHorizontalCenter();
-        QDeclarativePropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding);
-    }
-    if (d->applyOrigTop) {
-        if (!d->origTopBinding)
-            targetPrivate->anchors()->resetTop();
-        QDeclarativePropertyPrivate::setBinding(d->topProp, d->origTopBinding);
-    }
-    if (d->applyOrigBottom) {
-        if (!d->origBottomBinding)
-            targetPrivate->anchors()->resetBottom();
-        QDeclarativePropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding);
-    }
-    if (d->applyOrigVCenter) {
-        if (!d->origVCenterBinding)
-            targetPrivate->anchors()->resetVerticalCenter();
-        QDeclarativePropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding);
-    }
-    if (d->applyOrigBaseline) {
-        if (!d->origBaselineBinding)
-            targetPrivate->anchors()->resetBaseline();
-        QDeclarativePropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding);
-    }
-
-    //destroy old bindings
-    if (reason == ActualChange) {
-        for (int i = 0; i < d->oldBindings.size(); ++i) {
-            QDeclarativeAbstractBinding *binding = d->oldBindings.at(i);
-            if (binding)
-                binding->destroy();
-        }
-        d->oldBindings.clear();
-    }
-
-    //reset any anchors that have been specified as "undefined"
-    if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::LeftAnchor) {
-        targetPrivate->anchors()->resetLeft();
-        QDeclarativePropertyPrivate::setBinding(d->leftProp, 0);
-    }
-    if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::RightAnchor) {
-        targetPrivate->anchors()->resetRight();
-        QDeclarativePropertyPrivate::setBinding(d->rightProp, 0);
-    }
-    if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::HCenterAnchor) {
-        targetPrivate->anchors()->resetHorizontalCenter();
-        QDeclarativePropertyPrivate::setBinding(d->hCenterProp, 0);
-    }
-    if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::TopAnchor) {
-        targetPrivate->anchors()->resetTop();
-        QDeclarativePropertyPrivate::setBinding(d->topProp, 0);
-    }
-    if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::BottomAnchor) {
-        targetPrivate->anchors()->resetBottom();
-        QDeclarativePropertyPrivate::setBinding(d->bottomProp, 0);
-    }
-    if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::VCenterAnchor) {
-        targetPrivate->anchors()->resetVerticalCenter();
-        QDeclarativePropertyPrivate::setBinding(d->vCenterProp, 0);
-    }
-    if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::BaselineAnchor) {
-        targetPrivate->anchors()->resetBaseline();
-        QDeclarativePropertyPrivate::setBinding(d->baselineProp, 0);
-    }
-
-    //set any anchors that have been specified
-    if (d->leftBinding)
-        QDeclarativePropertyPrivate::setBinding(d->leftBinding->property(), d->leftBinding);
-    if (d->rightBinding)
-        QDeclarativePropertyPrivate::setBinding(d->rightBinding->property(), d->rightBinding);
-    if (d->hCenterBinding)
-        QDeclarativePropertyPrivate::setBinding(d->hCenterBinding->property(), d->hCenterBinding);
-    if (d->topBinding)
-        QDeclarativePropertyPrivate::setBinding(d->topBinding->property(), d->topBinding);
-    if (d->bottomBinding)
-        QDeclarativePropertyPrivate::setBinding(d->bottomBinding->property(), d->bottomBinding);
-    if (d->vCenterBinding)
-        QDeclarativePropertyPrivate::setBinding(d->vCenterBinding->property(), d->vCenterBinding);
-    if (d->baselineBinding)
-        QDeclarativePropertyPrivate::setBinding(d->baselineBinding->property(), d->baselineBinding);
-}
-
-bool QSGAnchorChanges::isReversable()
-{
-    return true;
-}
-
-void QSGAnchorChanges::reverse(Reason reason)
-{
-    Q_D(QSGAnchorChanges);
-    if (!d->target)
-        return;
-
-    QSGItemPrivate *targetPrivate = QSGItemPrivate::get(d->target);
-    //reset any anchors set by the state
-    if (d->leftBinding) {
-        targetPrivate->anchors()->resetLeft();
-        QDeclarativePropertyPrivate::setBinding(d->leftBinding->property(), 0);
-        if (reason == ActualChange) {
-            d->leftBinding->destroy(); d->leftBinding = 0;
-        }
-    }
-    if (d->rightBinding) {
-        targetPrivate->anchors()->resetRight();
-        QDeclarativePropertyPrivate::setBinding(d->rightBinding->property(), 0);
-        if (reason == ActualChange) {
-            d->rightBinding->destroy(); d->rightBinding = 0;
-        }
-    }
-    if (d->hCenterBinding) {
-        targetPrivate->anchors()->resetHorizontalCenter();
-        QDeclarativePropertyPrivate::setBinding(d->hCenterBinding->property(), 0);
-        if (reason == ActualChange) {
-            d->hCenterBinding->destroy(); d->hCenterBinding = 0;
-        }
-    }
-    if (d->topBinding) {
-        targetPrivate->anchors()->resetTop();
-        QDeclarativePropertyPrivate::setBinding(d->topBinding->property(), 0);
-        if (reason == ActualChange) {
-            d->topBinding->destroy(); d->topBinding = 0;
-        }
-    }
-    if (d->bottomBinding) {
-        targetPrivate->anchors()->resetBottom();
-        QDeclarativePropertyPrivate::setBinding(d->bottomBinding->property(), 0);
-        if (reason == ActualChange) {
-            d->bottomBinding->destroy(); d->bottomBinding = 0;
-        }
-    }
-    if (d->vCenterBinding) {
-        targetPrivate->anchors()->resetVerticalCenter();
-        QDeclarativePropertyPrivate::setBinding(d->vCenterBinding->property(), 0);
-        if (reason == ActualChange) {
-            d->vCenterBinding->destroy(); d->vCenterBinding = 0;
-        }
-    }
-    if (d->baselineBinding) {
-        targetPrivate->anchors()->resetBaseline();
-        QDeclarativePropertyPrivate::setBinding(d->baselineBinding->property(), 0);
-        if (reason == ActualChange) {
-            d->baselineBinding->destroy(); d->baselineBinding = 0;
-        }
-    }
-
-    //restore previous anchors
-    if (d->origLeftBinding)
-        QDeclarativePropertyPrivate::setBinding(d->leftProp, d->origLeftBinding);
-    if (d->origRightBinding)
-        QDeclarativePropertyPrivate::setBinding(d->rightProp, d->origRightBinding);
-    if (d->origHCenterBinding)
-        QDeclarativePropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding);
-    if (d->origTopBinding)
-        QDeclarativePropertyPrivate::setBinding(d->topProp, d->origTopBinding);
-    if (d->origBottomBinding)
-        QDeclarativePropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding);
-    if (d->origVCenterBinding)
-        QDeclarativePropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding);
-    if (d->origBaselineBinding)
-        QDeclarativePropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding);
-
-    //restore any absolute geometry changed by the state's anchors
-    QSGAnchors::Anchors stateVAnchors = d->anchorSet->d_func()->usedAnchors & QSGAnchors::Vertical_Mask;
-    QSGAnchors::Anchors origVAnchors = targetPrivate->anchors()->usedAnchors() & QSGAnchors::Vertical_Mask;
-    QSGAnchors::Anchors stateHAnchors = d->anchorSet->d_func()->usedAnchors & QSGAnchors::Horizontal_Mask;
-    QSGAnchors::Anchors origHAnchors = targetPrivate->anchors()->usedAnchors() & QSGAnchors::Horizontal_Mask;
-
-    bool stateSetWidth = (stateHAnchors &&
-                          stateHAnchors != QSGAnchors::LeftAnchor &&
-                          stateHAnchors != QSGAnchors::RightAnchor &&
-                          stateHAnchors != QSGAnchors::HCenterAnchor);
-    bool origSetWidth = (origHAnchors &&
-                         origHAnchors != QSGAnchors::LeftAnchor &&
-                         origHAnchors != QSGAnchors::RightAnchor &&
-                         origHAnchors != QSGAnchors::HCenterAnchor);
-    if (d->origWidth.isValid() && stateSetWidth && !origSetWidth)
-        d->target->setWidth(d->origWidth.value);
-
-    bool stateSetHeight = (stateVAnchors &&
-                           stateVAnchors != QSGAnchors::TopAnchor &&
-                           stateVAnchors != QSGAnchors::BottomAnchor &&
-                           stateVAnchors != QSGAnchors::VCenterAnchor &&
-                           stateVAnchors != QSGAnchors::BaselineAnchor);
-    bool origSetHeight = (origVAnchors &&
-                          origVAnchors != QSGAnchors::TopAnchor &&
-                          origVAnchors != QSGAnchors::BottomAnchor &&
-                          origVAnchors != QSGAnchors::VCenterAnchor &&
-                          origVAnchors != QSGAnchors::BaselineAnchor);
-    if (d->origHeight.isValid() && stateSetHeight && !origSetHeight)
-        d->target->setHeight(d->origHeight.value);
-
-    if (stateHAnchors && !origHAnchors)
-        d->target->setX(d->origX);
-
-    if (stateVAnchors && !origVAnchors)
-        d->target->setY(d->origY);
-}
-
-QString QSGAnchorChanges::typeName() const
-{
-    return QLatin1String("AnchorChanges");
-}
-
-QList<QDeclarativeAction> QSGAnchorChanges::additionalActions()
-{
-    Q_D(QSGAnchorChanges);
-    QList<QDeclarativeAction> extra;
-
-    QSGAnchors::Anchors combined = d->anchorSet->d_func()->usedAnchors | d->anchorSet->d_func()->resetAnchors;
-    bool hChange = combined & QSGAnchors::Horizontal_Mask;
-    bool vChange = combined & QSGAnchors::Vertical_Mask;
-
-    if (d->target) {
-        QDeclarativeAction a;
-        if (hChange && d->fromX != d->toX) {
-            a.property = QDeclarativeProperty(d->target, QLatin1String("x"));
-            a.toValue = d->toX;
-            extra << a;
-        }
-        if (vChange && d->fromY != d->toY) {
-            a.property = QDeclarativeProperty(d->target, QLatin1String("y"));
-            a.toValue = d->toY;
-            extra << a;
-        }
-        if (hChange && d->fromWidth != d->toWidth) {
-            a.property = QDeclarativeProperty(d->target, QLatin1String("width"));
-            a.toValue = d->toWidth;
-            extra << a;
-        }
-        if (vChange && d->fromHeight != d->toHeight) {
-            a.property = QDeclarativeProperty(d->target, QLatin1String("height"));
-            a.toValue = d->toHeight;
-            extra << a;
-        }
-    }
-
-    return extra;
-}
-
-bool QSGAnchorChanges::changesBindings()
-{
-    return true;
-}
-
-void QSGAnchorChanges::saveOriginals()
-{
-    Q_D(QSGAnchorChanges);
-    if (!d->target)
-        return;
-
-    d->origLeftBinding = QDeclarativePropertyPrivate::binding(d->leftProp);
-    d->origRightBinding = QDeclarativePropertyPrivate::binding(d->rightProp);
-    d->origHCenterBinding = QDeclarativePropertyPrivate::binding(d->hCenterProp);
-    d->origTopBinding = QDeclarativePropertyPrivate::binding(d->topProp);
-    d->origBottomBinding = QDeclarativePropertyPrivate::binding(d->bottomProp);
-    d->origVCenterBinding = QDeclarativePropertyPrivate::binding(d->vCenterProp);
-    d->origBaselineBinding = QDeclarativePropertyPrivate::binding(d->baselineProp);
-
-    QSGItemPrivate *targetPrivate = QSGItemPrivate::get(d->target);
-    if (targetPrivate->widthValid)
-        d->origWidth = d->target->width();
-    if (targetPrivate->heightValid)
-        d->origHeight = d->target->height();
-    d->origX = d->target->x();
-    d->origY = d->target->y();
-
-    d->applyOrigLeft = d->applyOrigRight = d->applyOrigHCenter = d->applyOrigTop
-      = d->applyOrigBottom = d->applyOrigVCenter = d->applyOrigBaseline = false;
-
-    saveCurrentValues();
-}
-
-void QSGAnchorChanges::copyOriginals(QDeclarativeActionEvent *other)
-{
-    Q_D(QSGAnchorChanges);
-    QSGAnchorChanges *ac = static_cast<QSGAnchorChanges*>(other);
-    QSGAnchorChangesPrivate *acp = ac->d_func();
-
-    QSGAnchors::Anchors combined = acp->anchorSet->d_func()->usedAnchors |
-                                            acp->anchorSet->d_func()->resetAnchors;
-
-    //probably also need to revert some things
-    d->applyOrigLeft = (combined & QSGAnchors::LeftAnchor);
-    d->applyOrigRight = (combined & QSGAnchors::RightAnchor);
-    d->applyOrigHCenter = (combined & QSGAnchors::HCenterAnchor);
-    d->applyOrigTop = (combined & QSGAnchors::TopAnchor);
-    d->applyOrigBottom = (combined & QSGAnchors::BottomAnchor);
-    d->applyOrigVCenter = (combined & QSGAnchors::VCenterAnchor);
-    d->applyOrigBaseline = (combined & QSGAnchors::BaselineAnchor);
-
-    d->origLeftBinding = acp->origLeftBinding;
-    d->origRightBinding = acp->origRightBinding;
-    d->origHCenterBinding = acp->origHCenterBinding;
-    d->origTopBinding = acp->origTopBinding;
-    d->origBottomBinding = acp->origBottomBinding;
-    d->origVCenterBinding = acp->origVCenterBinding;
-    d->origBaselineBinding = acp->origBaselineBinding;
-
-    d->origWidth = acp->origWidth;
-    d->origHeight = acp->origHeight;
-    d->origX = acp->origX;
-    d->origY = acp->origY;
-
-    d->oldBindings.clear();
-    d->oldBindings << acp->leftBinding << acp->rightBinding << acp->hCenterBinding
-                << acp->topBinding << acp->bottomBinding << acp->baselineBinding;
-
-    saveCurrentValues();
-}
-
-void QSGAnchorChanges::clearBindings()
-{
-    Q_D(QSGAnchorChanges);
-    if (!d->target)
-        return;
-
-    //### should this (saving "from" values) be moved to saveCurrentValues()?
-    d->fromX = d->target->x();
-    d->fromY = d->target->y();
-    d->fromWidth = d->target->width();
-    d->fromHeight = d->target->height();
-
-    QSGItemPrivate *targetPrivate = QSGItemPrivate::get(d->target);
-    //reset any anchors with corresponding reverts
-    //reset any anchors that have been specified as "undefined"
-    //reset any anchors that we'll be setting in the state
-    QSGAnchors::Anchors combined = d->anchorSet->d_func()->resetAnchors |
-                                            d->anchorSet->d_func()->usedAnchors;
-    if (d->applyOrigLeft || (combined & QSGAnchors::LeftAnchor)) {
-        targetPrivate->anchors()->resetLeft();
-        QDeclarativePropertyPrivate::setBinding(d->leftProp, 0);
-    }
-    if (d->applyOrigRight || (combined & QSGAnchors::RightAnchor)) {
-        targetPrivate->anchors()->resetRight();
-        QDeclarativePropertyPrivate::setBinding(d->rightProp, 0);
-    }
-    if (d->applyOrigHCenter || (combined & QSGAnchors::HCenterAnchor)) {
-        targetPrivate->anchors()->resetHorizontalCenter();
-        QDeclarativePropertyPrivate::setBinding(d->hCenterProp, 0);
-    }
-    if (d->applyOrigTop || (combined & QSGAnchors::TopAnchor)) {
-        targetPrivate->anchors()->resetTop();
-        QDeclarativePropertyPrivate::setBinding(d->topProp, 0);
-    }
-    if (d->applyOrigBottom || (combined & QSGAnchors::BottomAnchor)) {
-        targetPrivate->anchors()->resetBottom();
-        QDeclarativePropertyPrivate::setBinding(d->bottomProp, 0);
-    }
-    if (d->applyOrigVCenter || (combined & QSGAnchors::VCenterAnchor)) {
-        targetPrivate->anchors()->resetVerticalCenter();
-        QDeclarativePropertyPrivate::setBinding(d->vCenterProp, 0);
-    }
-    if (d->applyOrigBaseline || (combined & QSGAnchors::BaselineAnchor)) {
-        targetPrivate->anchors()->resetBaseline();
-        QDeclarativePropertyPrivate::setBinding(d->baselineProp, 0);
-    }
-}
-
-bool QSGAnchorChanges::override(QDeclarativeActionEvent*other)
-{
-    if (other->typeName() != QLatin1String("AnchorChanges"))
-        return false;
-    if (static_cast<QDeclarativeActionEvent*>(this) == other)
-        return true;
-    if (static_cast<QSGAnchorChanges*>(other)->object() == object())
-        return true;
-    return false;
-}
-
-void QSGAnchorChanges::rewind()
-{
-    Q_D(QSGAnchorChanges);
-    if (!d->target)
-        return;
-
-    QSGItemPrivate *targetPrivate = QSGItemPrivate::get(d->target);
-
-    //restore previous values (but not previous bindings, i.e. anchors)
-    d->target->setX(d->rewindX);
-    d->target->setY(d->rewindY);
-    if (targetPrivate->widthValid) {
-        d->target->setWidth(d->rewindWidth);
-    }
-    if (targetPrivate->heightValid) {
-        d->target->setHeight(d->rewindHeight);
-    }
-}
-
-void QSGAnchorChanges::saveCurrentValues()
-{
-    Q_D(QSGAnchorChanges);
-    if (!d->target)
-        return;
-
-    QSGItemPrivate *targetPrivate = QSGItemPrivate::get(d->target);
-    d->rewindLeft = targetPrivate->anchors()->left();
-    d->rewindRight = targetPrivate->anchors()->right();
-    d->rewindHCenter = targetPrivate->anchors()->horizontalCenter();
-    d->rewindTop = targetPrivate->anchors()->top();
-    d->rewindBottom = targetPrivate->anchors()->bottom();
-    d->rewindVCenter = targetPrivate->anchors()->verticalCenter();
-    d->rewindBaseline = targetPrivate->anchors()->baseline();
-
-    d->rewindX = d->target->x();
-    d->rewindY = d->target->y();
-    d->rewindWidth = d->target->width();
-    d->rewindHeight = d->target->height();
-}
-
-void QSGAnchorChanges::saveTargetValues()
-{
-    Q_D(QSGAnchorChanges);
-    if (!d->target)
-        return;
-
-    d->toX = d->target->x();
-    d->toY = d->target->y();
-    d->toWidth = d->target->width();
-    d->toHeight = d->target->height();
-}
-
-#include <moc_qsgstateoperations_p.cpp>
-
-QT_END_NAMESPACE
-
diff --git a/src/declarative/items/qsgstateoperations_p.h b/src/declarative/items/qsgstateoperations_p.h
deleted file mode 100644 (file)
index 0a4a8f5..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-// Commit: 84c47bbb133304d7ef35642fa1fbb17619d4a43d
-/****************************************************************************
-**
-** 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 QSGSTATEOPERATIONS_H
-#define QSGSTATEOPERATIONS_H
-
-#include "qsgitem.h"
-#include "qsganchors_p.h"
-
-#include <private/qdeclarativestate_p.h>
-
-#include <QtDeclarative/qdeclarativescriptstring.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGParentChangePrivate;
-class Q_AUTOTEST_EXPORT QSGParentChange : public QDeclarativeStateOperation, public QDeclarativeActionEvent
-{
-    Q_OBJECT
-    Q_DECLARE_PRIVATE(QSGParentChange)
-
-    Q_PROPERTY(QSGItem *target READ object WRITE setObject)
-    Q_PROPERTY(QSGItem *parent READ parent WRITE setParent)
-    Q_PROPERTY(QDeclarativeScriptString x READ x WRITE setX)
-    Q_PROPERTY(QDeclarativeScriptString y READ y WRITE setY)
-    Q_PROPERTY(QDeclarativeScriptString width READ width WRITE setWidth)
-    Q_PROPERTY(QDeclarativeScriptString height READ height WRITE setHeight)
-    Q_PROPERTY(QDeclarativeScriptString scale READ scale WRITE setScale)
-    Q_PROPERTY(QDeclarativeScriptString rotation READ rotation WRITE setRotation)
-public:
-    QSGParentChange(QObject *parent=0);
-    ~QSGParentChange();
-
-    QSGItem *object() const;
-    void setObject(QSGItem *);
-
-    QSGItem *parent() const;
-    void setParent(QSGItem *);
-
-    QSGItem *originalParent() const;
-
-    QDeclarativeScriptString x() const;
-    void setX(QDeclarativeScriptString x);
-    bool xIsSet() const;
-
-    QDeclarativeScriptString y() const;
-    void setY(QDeclarativeScriptString y);
-    bool yIsSet() const;
-
-    QDeclarativeScriptString width() const;
-    void setWidth(QDeclarativeScriptString width);
-    bool widthIsSet() const;
-
-    QDeclarativeScriptString height() const;
-    void setHeight(QDeclarativeScriptString height);
-    bool heightIsSet() const;
-
-    QDeclarativeScriptString scale() const;
-    void setScale(QDeclarativeScriptString scale);
-    bool scaleIsSet() const;
-
-    QDeclarativeScriptString rotation() const;
-    void setRotation(QDeclarativeScriptString rotation);
-    bool rotationIsSet() const;
-
-    virtual ActionList actions();
-
-    virtual void saveOriginals();
-    //virtual void copyOriginals(QDeclarativeActionEvent*);
-    virtual void execute(Reason reason = ActualChange);
-    virtual bool isReversable();
-    virtual void reverse(Reason reason = ActualChange);
-    virtual QString typeName() const;
-    virtual bool override(QDeclarativeActionEvent*other);
-    virtual void rewind();
-    virtual void saveCurrentValues();
-};
-
-class QSGAnchorChanges;
-class QSGAnchorSetPrivate;
-class Q_AUTOTEST_EXPORT QSGAnchorSet : public QObject
-{
-    Q_OBJECT
-
-    Q_PROPERTY(QDeclarativeScriptString left READ left WRITE setLeft RESET resetLeft)
-    Q_PROPERTY(QDeclarativeScriptString right READ right WRITE setRight RESET resetRight)
-    Q_PROPERTY(QDeclarativeScriptString horizontalCenter READ horizontalCenter WRITE setHorizontalCenter RESET resetHorizontalCenter)
-    Q_PROPERTY(QDeclarativeScriptString top READ top WRITE setTop RESET resetTop)
-    Q_PROPERTY(QDeclarativeScriptString bottom READ bottom WRITE setBottom RESET resetBottom)
-    Q_PROPERTY(QDeclarativeScriptString verticalCenter READ verticalCenter WRITE setVerticalCenter RESET resetVerticalCenter)
-    Q_PROPERTY(QDeclarativeScriptString baseline READ baseline WRITE setBaseline RESET resetBaseline)
-    //Q_PROPERTY(QSGItem *fill READ fill WRITE setFill RESET resetFill)
-    //Q_PROPERTY(QSGItem *centerIn READ centerIn WRITE setCenterIn RESET resetCenterIn)
-
-    /*Q_PROPERTY(qreal margins READ margins WRITE setMargins NOTIFY marginsChanged)
-    Q_PROPERTY(qreal leftMargin READ leftMargin WRITE setLeftMargin NOTIFY leftMarginChanged)
-    Q_PROPERTY(qreal rightMargin READ rightMargin WRITE setRightMargin NOTIFY rightMarginChanged)
-    Q_PROPERTY(qreal horizontalCenterOffset READ horizontalCenterOffset WRITE setHorizontalCenterOffset NOTIFY horizontalCenterOffsetChanged())
-    Q_PROPERTY(qreal topMargin READ topMargin WRITE setTopMargin NOTIFY topMarginChanged)
-    Q_PROPERTY(qreal bottomMargin READ bottomMargin WRITE setBottomMargin NOTIFY bottomMarginChanged)
-    Q_PROPERTY(qreal verticalCenterOffset READ verticalCenterOffset WRITE setVerticalCenterOffset NOTIFY verticalCenterOffsetChanged())
-    Q_PROPERTY(qreal baselineOffset READ baselineOffset WRITE setBaselineOffset NOTIFY baselineOffsetChanged())*/
-
-public:
-    QSGAnchorSet(QObject *parent=0);
-    virtual ~QSGAnchorSet();
-
-    QDeclarativeScriptString left() const;
-    void setLeft(const QDeclarativeScriptString &edge);
-    void resetLeft();
-
-    QDeclarativeScriptString right() const;
-    void setRight(const QDeclarativeScriptString &edge);
-    void resetRight();
-
-    QDeclarativeScriptString horizontalCenter() const;
-    void setHorizontalCenter(const QDeclarativeScriptString &edge);
-    void resetHorizontalCenter();
-
-    QDeclarativeScriptString top() const;
-    void setTop(const QDeclarativeScriptString &edge);
-    void resetTop();
-
-    QDeclarativeScriptString bottom() const;
-    void setBottom(const QDeclarativeScriptString &edge);
-    void resetBottom();
-
-    QDeclarativeScriptString verticalCenter() const;
-    void setVerticalCenter(const QDeclarativeScriptString &edge);
-    void resetVerticalCenter();
-
-    QDeclarativeScriptString baseline() const;
-    void setBaseline(const QDeclarativeScriptString &edge);
-    void resetBaseline();
-
-    QSGItem *fill() const;
-    void setFill(QSGItem *);
-    void resetFill();
-
-    QSGItem *centerIn() const;
-    void setCenterIn(QSGItem *);
-    void resetCenterIn();
-
-    /*qreal leftMargin() const;
-    void setLeftMargin(qreal);
-
-    qreal rightMargin() const;
-    void setRightMargin(qreal);
-
-    qreal horizontalCenterOffset() const;
-    void setHorizontalCenterOffset(qreal);
-
-    qreal topMargin() const;
-    void setTopMargin(qreal);
-
-    qreal bottomMargin() const;
-    void setBottomMargin(qreal);
-
-    qreal margins() const;
-    void setMargins(qreal);
-
-    qreal verticalCenterOffset() const;
-    void setVerticalCenterOffset(qreal);
-
-    qreal baselineOffset() const;
-    void setBaselineOffset(qreal);*/
-
-    QSGAnchors::Anchors usedAnchors() const;
-
-/*Q_SIGNALS:
-    void leftMarginChanged();
-    void rightMarginChanged();
-    void topMarginChanged();
-    void bottomMarginChanged();
-    void marginsChanged();
-    void verticalCenterOffsetChanged();
-    void horizontalCenterOffsetChanged();
-    void baselineOffsetChanged();*/
-
-private:
-    friend class QSGAnchorChanges;
-    Q_DISABLE_COPY(QSGAnchorSet)
-    Q_DECLARE_PRIVATE(QSGAnchorSet)
-};
-
-class QSGAnchorChangesPrivate;
-class Q_AUTOTEST_EXPORT QSGAnchorChanges : public QDeclarativeStateOperation, public QDeclarativeActionEvent
-{
-    Q_OBJECT
-    Q_DECLARE_PRIVATE(QSGAnchorChanges)
-
-    Q_PROPERTY(QSGItem *target READ object WRITE setObject)
-    Q_PROPERTY(QSGAnchorSet *anchors READ anchors CONSTANT)
-
-public:
-    QSGAnchorChanges(QObject *parent=0);
-    ~QSGAnchorChanges();
-
-    virtual ActionList actions();
-
-    QSGAnchorSet *anchors();
-
-    QSGItem *object() const;
-    void setObject(QSGItem *);
-
-    virtual void execute(Reason reason = ActualChange);
-    virtual bool isReversable();
-    virtual void reverse(Reason reason = ActualChange);
-    virtual QString typeName() const;
-    virtual bool override(QDeclarativeActionEvent*other);
-    virtual bool changesBindings();
-    virtual void saveOriginals();
-    virtual bool needsCopy() { return true; }
-    virtual void copyOriginals(QDeclarativeActionEvent*);
-    virtual void clearBindings();
-    virtual void rewind();
-    virtual void saveCurrentValues();
-
-    QList<QDeclarativeAction> additionalActions();
-    virtual void saveTargetValues();
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGParentChange)
-QML_DECLARE_TYPE(QSGAnchorSet)
-QML_DECLARE_TYPE(QSGAnchorChanges)
-
-QT_END_HEADER
-
-#endif // QSGSTATEOPERATIONS_H
-
diff --git a/src/declarative/items/qsgtext.cpp b/src/declarative/items/qsgtext.cpp
deleted file mode 100644 (file)
index 6c55e82..0000000
+++ /dev/null
@@ -1,1938 +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 "qsgtext_p.h"
-#include "qsgtext_p_p.h"
-
-#include <private/qsgdistancefieldglyphcache_p.h>
-#include <private/qsgcontext_p.h>
-#include <private/qsgadaptationlayer_p.h>
-#include "qsgtextnode_p.h"
-#include "qsgimage_p_p.h"
-#include <private/qsgtexture_p.h>
-
-#include <QtDeclarative/qdeclarativeinfo.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qabstracttextdocumentlayout.h>
-#include <QtGui/qpainter.h>
-#include <QtGui/qtextdocument.h>
-#include <QtGui/qtextobject.h>
-#include <QtGui/qtextcursor.h>
-#include <QtGui/qguiapplication.h>
-
-#include <private/qdeclarativestyledtext_p.h>
-#include <private/qdeclarativepixmapcache_p.h>
-
-#include <qmath.h>
-#include <limits.h>
-
-QT_BEGIN_NAMESPACE
-
-extern Q_GUI_EXPORT bool qt_applefontsmoothing_enabled;
-
-class QSGTextDocumentWithImageResources : public QTextDocument {
-    Q_OBJECT
-
-public:
-    QSGTextDocumentWithImageResources(QSGText *parent);
-    virtual ~QSGTextDocumentWithImageResources();
-
-    void setText(const QString &);
-    int resourcesLoading() const { return outstanding; }
-
-protected:
-    QVariant loadResource(int type, const QUrl &name);
-
-private slots:
-    void requestFinished();
-
-private:
-    QHash<QUrl, QDeclarativePixmap *> m_resources;
-
-    int outstanding;
-    static QSet<QUrl> errors;
-};
-
-DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
-DEFINE_BOOL_CONFIG_OPTION(enableImageCache, QML_ENABLE_TEXT_IMAGE_CACHE);
-
-QString QSGTextPrivate::elideChar = QString(0x2026);
-
-QSGTextPrivate::QSGTextPrivate()
-: color((QRgb)0), style(QSGText::Normal), hAlign(QSGText::AlignLeft),
-  vAlign(QSGText::AlignTop), elideMode(QSGText::ElideNone),
-  format(QSGText::AutoText), wrapMode(QSGText::NoWrap), lineHeight(1),
-  lineHeightMode(QSGText::ProportionalHeight), lineCount(1), maximumLineCount(INT_MAX),
-  maximumLineCountValid(false),
-  texture(0),
-  imageCacheDirty(false), updateOnComponentComplete(true),
-  richText(false), styledText(false), singleline(false), cacheAllTextAsImage(true), internalWidthUpdate(false),
-  requireImplicitWidth(false), truncated(false), hAlignImplicit(true), rightToLeftText(false),
-  layoutTextElided(false), richTextAsImage(false), textureImageCacheDirty(false), textHasChanged(true),
-  naturalWidth(0), doc(0), textLine(0), nodeType(NodeIsNull)
-
-#if defined(Q_OS_MAC)
-, layoutThread(0), paintingThread(0)
-#endif
-
-{
-    cacheAllTextAsImage = enableImageCache();
-}
-
-void QSGTextPrivate::init()
-{
-    Q_Q(QSGText);
-    q->setAcceptedMouseButtons(Qt::LeftButton);
-    q->setFlag(QSGItem::ItemHasContents);
-}
-
-QSGTextDocumentWithImageResources::QSGTextDocumentWithImageResources(QSGText *parent)
-: QTextDocument(parent), outstanding(0)
-{
-    setUndoRedoEnabled(false);
-}
-
-QSGTextDocumentWithImageResources::~QSGTextDocumentWithImageResources()
-{
-    if (!m_resources.isEmpty())
-        qDeleteAll(m_resources);
-}
-
-QVariant QSGTextDocumentWithImageResources::loadResource(int type, const QUrl &name)
-{
-    QDeclarativeContext *context = qmlContext(parent());
-    QUrl url = context->resolvedUrl(name);
-
-    if (type == QTextDocument::ImageResource) {
-        QHash<QUrl, QDeclarativePixmap *>::Iterator iter = m_resources.find(url);
-
-        if (iter == m_resources.end()) {
-            QDeclarativePixmap *p = new QDeclarativePixmap(context->engine(), url);
-            iter = m_resources.insert(name, p);
-
-            if (p->isLoading()) {
-                p->connectFinished(this, SLOT(requestFinished()));
-                outstanding++;
-            }
-        }
-
-        QDeclarativePixmap *p = *iter;
-        if (p->isReady()) {
-            return p->pixmap();
-        } else if (p->isError()) {
-            if (!errors.contains(url)) {
-                errors.insert(url);
-                qmlInfo(parent()) << p->error();
-            }
-        }
-    }
-
-    return QTextDocument::loadResource(type,url); // The *resolved* URL
-}
-
-void QSGTextDocumentWithImageResources::requestFinished()
-{
-    outstanding--;
-    if (outstanding == 0) {
-        QSGText *textItem = static_cast<QSGText*>(parent());
-        QString text = textItem->text();
-#ifndef QT_NO_TEXTHTMLPARSER
-        setHtml(text);
-#else
-        setPlainText(text);
-#endif
-        QSGTextPrivate *d = QSGTextPrivate::get(textItem);
-        d->updateLayout();
-    }
-}
-
-void QSGTextDocumentWithImageResources::setText(const QString &text)
-{
-    if (!m_resources.isEmpty()) {
-        qDeleteAll(m_resources);
-        m_resources.clear();
-        outstanding = 0;
-    }
-
-#ifndef QT_NO_TEXTHTMLPARSER
-    setHtml(text);
-#else
-    setPlainText(text);
-#endif
-}
-
-QSet<QUrl> QSGTextDocumentWithImageResources::errors;
-
-QSGTextPrivate::~QSGTextPrivate()
-{
-    delete textLine; textLine = 0;
-}
-
-qreal QSGTextPrivate::getImplicitWidth() const
-{
-    if (!requireImplicitWidth) {
-        // We don't calculate implicitWidth unless it is required.
-        // We need to force a size update now to ensure implicitWidth is calculated
-        QSGTextPrivate *me = const_cast<QSGTextPrivate*>(this);
-        me->requireImplicitWidth = true;
-        me->updateSize();
-    }
-    return implicitWidth;
-}
-
-void QSGTextPrivate::updateLayout()
-{
-    Q_Q(QSGText);
-    if (!q->isComponentComplete()) {
-        updateOnComponentComplete = true;
-        return;
-    }
-
-    layoutTextElided = false;
-    // Setup instance of QTextLayout for all cases other than richtext
-    if (!richText) {
-        layout.clearLayout();
-        layout.setFont(font);
-        if (!styledText) {
-            QString tmp = text;
-            tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
-            singleline = !tmp.contains(QChar::LineSeparator);
-            if (singleline && !maximumLineCountValid && elideMode != QSGText::ElideNone && q->widthValid()) {
-                QFontMetrics fm(font);
-                tmp = fm.elidedText(tmp,(Qt::TextElideMode)elideMode,q->width());
-                if (tmp != text) {
-                    layoutTextElided = true;
-                    if (!truncated) {
-                        truncated = true;
-                        emit q->truncatedChanged();
-                    }
-                }
-            }
-            layout.setText(tmp);
-        } else {
-            singleline = false;
-            if (textHasChanged) {
-                QDeclarativeStyledText::parse(text, layout);
-                textHasChanged = false;
-            }
-        }
-    } else {
-        ensureDoc();
-        QTextBlockFormat::LineHeightTypes type;
-        type = lineHeightMode == QSGText::FixedHeight ? QTextBlockFormat::FixedHeight : QTextBlockFormat::ProportionalHeight;
-        QTextBlockFormat blockFormat;
-        blockFormat.setLineHeight((lineHeightMode == QSGText::FixedHeight ? lineHeight : lineHeight * 100), type);
-        for (QTextBlock it = doc->begin(); it != doc->end(); it = it.next()) {
-            QTextCursor cursor(it);
-            cursor.mergeBlockFormat(blockFormat);
-        }
-    }
-
-    updateSize();
-}
-
-void QSGTextPrivate::updateSize()
-{
-    Q_Q(QSGText);
-
-    if (!q->isComponentComplete()) {
-        updateOnComponentComplete = true;
-        return;
-    }
-
-    if (!requireImplicitWidth) {
-        emit q->implicitWidthChanged();
-        // if the implicitWidth is used, then updateSize() has already been called (recursively)
-        if (requireImplicitWidth)
-            return;
-    }
-
-    invalidateImageCache();
-
-    QFontMetrics fm(font);
-    if (text.isEmpty()) {
-        q->setImplicitWidth(0);
-        q->setImplicitHeight(fm.height());
-        paintedSize = QSize(0, fm.height());
-        emit q->paintedSizeChanged();
-        q->update();
-        return;
-    }
-
-    int dy = q->height();
-    QSize size(0, 0);
-
-#if defined(Q_OS_MAC)
-    layoutThread = QThread::currentThread();
-#endif
-
-    //setup instance of QTextLayout for all cases other than richtext
-    if (!richText) {
-        QRect textRect = setupTextLayout();
-        layedOutTextRect = textRect;
-        size = textRect.size();
-        dy -= size.height();
-    } else {
-        singleline = false; // richtext can't elide or be optimized for single-line case
-        ensureDoc();
-        doc->setDefaultFont(font);
-        QSGText::HAlignment horizontalAlignment = q->effectiveHAlign();
-        if (rightToLeftText) {
-            if (horizontalAlignment == QSGText::AlignLeft)
-                horizontalAlignment = QSGText::AlignRight;
-            else if (horizontalAlignment == QSGText::AlignRight)
-                horizontalAlignment = QSGText::AlignLeft;
-        }
-        QTextOption option;
-        option.setAlignment((Qt::Alignment)int(horizontalAlignment | vAlign));
-        option.setWrapMode(QTextOption::WrapMode(wrapMode));
-        if (!cacheAllTextAsImage && !richTextAsImage && !qmlDisableDistanceField())
-            option.setUseDesignMetrics(true);
-        doc->setDefaultTextOption(option);
-        if (requireImplicitWidth && q->widthValid()) {
-            doc->setTextWidth(-1);
-            naturalWidth = doc->idealWidth();
-        }
-        if (wrapMode != QSGText::NoWrap && q->widthValid())
-            doc->setTextWidth(q->width());
-        else
-            doc->setTextWidth(doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug)
-        dy -= (int)doc->size().height();
-        QSize dsize = doc->size().toSize();
-        layedOutTextRect = QRect(QPoint(0,0), dsize);
-        size = QSize(int(doc->idealWidth()),dsize.height());
-    }
-    int yoff = 0;
-
-    if (q->heightValid()) {
-        if (vAlign == QSGText::AlignBottom)
-            yoff = dy;
-        else if (vAlign == QSGText::AlignVCenter)
-            yoff = dy/2;
-    }
-    q->setBaselineOffset(fm.ascent() + yoff);
-
-    //### need to comfirm cost of always setting these for richText
-    internalWidthUpdate = true;
-    if (!q->widthValid())
-        q->setImplicitWidth(size.width());
-    else if (requireImplicitWidth)
-        q->setImplicitWidth(naturalWidth);
-    internalWidthUpdate = false;
-
-    q->setImplicitHeight(size.height());
-    if (paintedSize != size) {
-        paintedSize = size;
-        emit q->paintedSizeChanged();
-    }
-    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.
-
-    Returns the size of the final text.  This can be used to position the text vertically (the text is
-    already absolutely positioned horizontally).
-*/
-QRect QSGTextPrivate::setupTextLayout()
-{
-    // ### text layout handling should be profiled and optimized as needed
-    // what about QStackTextEngine engine(tmp, d->font.font()); QTextLayout textLayout(&engine);
-    Q_Q(QSGText);
-    layout.setCacheEnabled(true);
-
-    qreal lineWidth = 0;
-    int visibleCount = 0;
-
-    //set manual width
-    if (q->widthValid())
-        lineWidth = q->width();
-
-    QTextOption textOption = layout.textOption();
-    textOption.setAlignment(Qt::Alignment(q->effectiveHAlign()));
-    textOption.setWrapMode(QTextOption::WrapMode(wrapMode));
-    if (!cacheAllTextAsImage && !richTextAsImage && !qmlDisableDistanceField())
-        textOption.setUseDesignMetrics(true);
-    layout.setTextOption(textOption);
-
-    bool elideText = false;
-    bool truncate = false;
-
-    QFontMetrics fm(layout.font());
-    elidePos = QPointF();
-
-    if (requireImplicitWidth && q->widthValid()) {
-        // requires an extra layout
-        QString elidedText;
-        if (layoutTextElided) {
-            // We have provided elided text to the layout, but we must calculate unelided width.
-            elidedText = layout.text();
-            layout.setText(text);
-        }
-        layout.beginLayout();
-        forever {
-            QTextLine line = layout.createLine();
-            if (!line.isValid())
-                break;
-        }
-        layout.endLayout();
-        QRectF br;
-        for (int i = 0; i < layout.lineCount(); ++i) {
-            QTextLine line = layout.lineAt(i);
-            br = br.united(line.naturalTextRect());
-        }
-        naturalWidth = br.width();
-        if (layoutTextElided)
-            layout.setText(elidedText);
-    }
-
-    qreal height = 0;
-    bool customLayout = isLineLaidOutConnected();
-
-    if (maximumLineCountValid) {
-        layout.beginLayout();
-        if (!lineWidth)
-            lineWidth = INT_MAX;
-        int linesLeft = maximumLineCount;
-        int visibleTextLength = 0;
-        while (linesLeft > 0) {
-            QTextLine line = layout.createLine();
-            if (!line.isValid())
-                break;
-
-            visibleCount++;
-
-            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()) {
-                        qreal elideWidth = fm.width(elideChar);
-                        // Need to correct for alignment
-                        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);
-                        } else {
-                            elidePos.setX(line.naturalTextRect().right());
-                        }
-                        elideText = true;
-                    }
-                }
-            }
-        }
-        layout.endLayout();
-
-        //Update truncated
-        if (truncated != truncate) {
-            truncated = truncate;
-            emit q->truncatedChanged();
-        }
-    } else {
-        layout.beginLayout();
-        forever {
-            QTextLine line = layout.createLine();
-            if (!line.isValid())
-                break;
-            visibleCount++;
-            if (customLayout)
-                setupCustomLineGeometry(line, height);
-            else {
-                if (lineWidth)
-                    line.setLineWidth(lineWidth);
-            }
-        }
-        layout.endLayout();
-    }
-
-    height = 0;
-    QRectF br;
-    for (int i = 0; i < layout.lineCount(); ++i) {
-        QTextLine line = layout.lineAt(i);
-        // set line spacing
-        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())));
-        }
-        br = br.united(line.naturalTextRect());
-        height += (lineHeightMode == QSGText::FixedHeight) ? lineHeight : line.height() * lineHeight;
-    }
-    if (!customLayout)
-        br.setHeight(height);
-
-    if (!q->widthValid())
-        naturalWidth = br.width();
-
-    //Update the number of visible lines
-    if (lineCount != visibleCount) {
-        lineCount = visibleCount;
-        emit q->lineCountChanged();
-    }
-
-    return QRect(qRound(br.x()), qRound(br.y()), qCeil(br.width()), qCeil(br.height()));
-}
-
-/*!
-    Returns a painted version of the QSGTextPrivate::layout QTextLayout.
-    If \a drawStyle is true, the style color overrides all colors in the document.
-*/
-QPixmap QSGTextPrivate::textLayoutImage(bool drawStyle)
-{
-    QSize size = layedOutTextRect.size();
-
-    //paint text
-    QPixmap img(size);
-    if (!size.isEmpty()) {
-        img.fill(Qt::transparent);
-#ifdef Q_WS_MAC
-        bool oldSmooth = qt_applefontsmoothing_enabled;
-        qt_applefontsmoothing_enabled = false;
-#endif
-        QPainter p(&img);
-#ifdef Q_WS_MAC
-        qt_applefontsmoothing_enabled = oldSmooth;
-#endif
-        drawTextLayout(&p, QPointF(-layedOutTextRect.x(),0), drawStyle);
-    }
-    return img;
-}
-
-/*!
-    Paints the QSGTextPrivate::layout QTextLayout into \a painter at \a pos.  If
-    \a drawStyle is true, the style color overrides all colors in the document.
-*/
-void QSGTextPrivate::drawTextLayout(QPainter *painter, const QPointF &pos, bool drawStyle)
-{
-    if (drawStyle)
-        painter->setPen(styleColor);
-    else
-        painter->setPen(color);
-    painter->setFont(font);
-    layout.draw(painter, pos);
-    if (!elidePos.isNull())
-        painter->drawText(pos + elidePos, elideChar);
-}
-
-/*!
-    Returns a painted version of the QSGTextPrivate::doc QTextDocument.
-    If \a drawStyle is true, the style color overrides all colors in the document.
-*/
-QPixmap QSGTextPrivate::textDocumentImage(bool drawStyle)
-{
-    QSize size = doc->size().toSize();
-
-    //paint text
-    QPixmap img(size);
-    img.fill(Qt::transparent);
-#ifdef Q_WS_MAC
-    bool oldSmooth = qt_applefontsmoothing_enabled;
-    qt_applefontsmoothing_enabled = false;
-#endif
-    QPainter p(&img);
-#ifdef Q_WS_MAC
-    qt_applefontsmoothing_enabled = oldSmooth;
-#endif
-
-    QAbstractTextDocumentLayout::PaintContext context;
-
-    QTextOption oldOption(doc->defaultTextOption());
-    if (drawStyle) {
-        context.palette.setColor(QPalette::Text, styleColor);
-        QTextOption colorOption(doc->defaultTextOption());
-        colorOption.setFlags(QTextOption::SuppressColors);
-        doc->setDefaultTextOption(colorOption);
-    } else {
-        context.palette.setColor(QPalette::Text, color);
-    }
-    doc->documentLayout()->draw(&p, context);
-    if (drawStyle)
-        doc->setDefaultTextOption(oldOption);
-    return img;
-}
-
-/*!
-    Mark the image cache as dirty.
-*/
-void QSGTextPrivate::invalidateImageCache()
-{
-    Q_Q(QSGText);
-
-    if (richTextAsImage || cacheAllTextAsImage || (qmlDisableDistanceField() && style != QSGText::Normal)) { // If actually using the image cache
-        if (imageCacheDirty)
-            return;
-
-        imageCacheDirty = true;
-
-        if (q->isComponentComplete())
-            QCoreApplication::postEvent(q, new QEvent(QEvent::User));
-    } else if (q->isComponentComplete())
-        q->update();
-}
-
-/*!
-    Tests if the image cache is dirty, and repaints it if it is.
-*/
-void QSGTextPrivate::checkImageCache()
-{
-    Q_Q(QSGText);
-
-    if (!imageCacheDirty)
-        return;
-
-    if (text.isEmpty()) {
-
-        imageCache = QPixmap();
-
-    } else {
-
-        QPixmap textImage;
-        QPixmap styledImage;
-
-        if (richText) {
-            textImage = textDocumentImage(false);
-            if (style != QSGText::Normal)
-                styledImage = textDocumentImage(true); //### should use styleColor
-        } else {
-            textImage = textLayoutImage(false);
-            if (style != QSGText::Normal)
-                styledImage = textLayoutImage(true); //### should use styleColor
-        }
-
-        switch (style) {
-        case QSGText::Outline:
-            imageCache = drawOutline(textImage, styledImage);
-            break;
-        case QSGText::Sunken:
-            imageCache = drawOutline(textImage, styledImage, -1);
-            break;
-        case QSGText::Raised:
-            imageCache = drawOutline(textImage, styledImage, 1);
-            break;
-        default:
-            imageCache = textImage;
-            break;
-        }
-
-    }
-
-    imageCacheDirty = false;
-    textureImageCacheDirty = true;
-    q->update();
-}
-
-/*!
-    Ensures the QSGTextPrivate::doc variable is set to a valid text document
-*/
-void QSGTextPrivate::ensureDoc()
-{
-    if (!doc) {
-        Q_Q(QSGText);
-        doc = new QSGTextDocumentWithImageResources(q);
-        doc->setDocumentMargin(0);
-    }
-}
-
-/*!
-    Draw \a styleSource as an outline around \a source and return the new image.
-*/
-QPixmap QSGTextPrivate::drawOutline(const QPixmap &source, const QPixmap &styleSource)
-{
-    QPixmap img = QPixmap(styleSource.width() + 2, styleSource.height() + 2);
-    img.fill(Qt::transparent);
-
-    QPainter ppm(&img);
-
-    QPoint pos(0, 0);
-    pos += QPoint(-1, 0);
-    ppm.drawPixmap(pos, styleSource);
-    pos += QPoint(2, 0);
-    ppm.drawPixmap(pos, styleSource);
-    pos += QPoint(-1, -1);
-    ppm.drawPixmap(pos, styleSource);
-    pos += QPoint(0, 2);
-    ppm.drawPixmap(pos, styleSource);
-
-    pos += QPoint(0, -1);
-    ppm.drawPixmap(pos, source);
-    ppm.end();
-
-    return img;
-}
-
-/*!
-    Draw \a styleSource below \a source at \a yOffset and return the new image.
-*/
-QPixmap QSGTextPrivate::drawOutline(const QPixmap &source, const QPixmap &styleSource, int yOffset)
-{
-    QPixmap img = QPixmap(styleSource.width() + 2, styleSource.height() + 2);
-    img.fill(Qt::transparent);
-
-    QPainter ppm(&img);
-
-    ppm.drawPixmap(QPoint(0, yOffset), styleSource);
-    ppm.drawPixmap(0, 0, source);
-
-    ppm.end();
-
-    return img;
-}
-
-/*!
-    \qmlclass Text QSGText
-    \inqmlmodule QtQuick 2
-    \ingroup qml-basic-visual-elements
-    \brief The Text item allows you to add formatted text to a scene.
-    \inherits Item
-
-    Text items can display both plain and rich text. For example, red text with
-    a specific font and size can be defined like this:
-
-    \qml
-    Text {
-        text: "Hello World!"
-        font.family: "Helvetica"
-        font.pointSize: 24
-        color: "red"
-    }
-    \endqml
-
-    Rich text is defined using HTML-style markup:
-
-    \qml
-    Text {
-        text: "<b>Hello</b> <i>World!</i>"
-    }
-    \endqml
-
-    \image declarative-text.png
-
-    If height and width are not explicitly set, Text will attempt to determine how
-    much room is needed and set it accordingly. Unless \l wrapMode is set, it will always
-    prefer width to height (all text will be placed on a single line).
-
-    The \l elide property can alternatively be used to fit a single line of
-    plain text to a set width.
-
-    Note that the \l{Supported HTML Subset} is limited. Also, if the text contains
-    HTML img tags that load remote images, the text is reloaded.
-
-    Text provides read-only text. For editable text, see \l TextEdit.
-
-    \sa {declarative/text/fonts}{Fonts example}
-*/
-QSGText::QSGText(QSGItem *parent)
-: QSGImplicitSizeItem(*(new QSGTextPrivate), parent)
-{
-    Q_D(QSGText);
-    d->init();
-}
-
-QSGText::~QSGText()
-{
-}
-
-/*!
-  \qmlproperty bool QtQuick2::Text::clip
-  This property holds whether the text is clipped.
-
-  Note that if the text does not fit in the bounding rectangle it will be abruptly chopped.
-
-  If you want to display potentially long text in a limited space, you probably want to use \c elide instead.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::Text::smooth
-
-    This property holds whether the text is smoothly scaled or transformed.
-
-    Smooth filtering gives better visual quality, but is slower.  If
-    the item is displayed at its natural size, this property has no visual or
-    performance effect.
-
-    \note Generally scaling artifacts are only visible if the item is stationary on
-    the screen.  A common pattern when animating an item is to disable smooth
-    filtering at the beginning of the animation and reenable it at the conclusion.
-*/
-
-/*!
-    \qmlsignal QtQuick2::Text::onLinkActivated(string link)
-
-    This handler is called when the user clicks on a link embedded in the text.
-    The link must be in rich text or HTML format and the
-    \a link string provides access to the particular link.
-
-    \snippet doc/src/snippets/declarative/text/onLinkActivated.qml 0
-
-    The example code will display the text
-    "The main website is at \l{http://qt.nokia.com}{Nokia Qt DF}."
-
-    Clicking on the highlighted link will output
-    \tt{http://qt.nokia.com link activated} to the console.
-*/
-
-/*!
-    \qmlproperty string QtQuick2::Text::font.family
-
-    Sets the family name of the font.
-
-    The family name is case insensitive and may optionally include a foundry name, e.g. "Helvetica [Cronyx]".
-    If the family is available from more than one foundry and the foundry isn't specified, an arbitrary foundry is chosen.
-    If the family isn't available a family will be set using the font matching algorithm.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::Text::font.bold
-
-    Sets whether the font weight is bold.
-*/
-
-/*!
-    \qmlproperty enumeration QtQuick2::Text::font.weight
-
-    Sets the font's weight.
-
-    The weight can be one of:
-    \list
-    \o Font.Light
-    \o Font.Normal - the default
-    \o Font.DemiBold
-    \o Font.Bold
-    \o Font.Black
-    \endlist
-
-    \qml
-    Text { text: "Hello"; font.weight: Font.DemiBold }
-    \endqml
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::Text::font.italic
-
-    Sets whether the font has an italic style.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::Text::font.underline
-
-    Sets whether the text is underlined.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::Text::font.strikeout
-
-    Sets whether the font has a strikeout style.
-*/
-
-/*!
-    \qmlproperty real QtQuick2::Text::font.pointSize
-
-    Sets the font size in points. The point size must be greater than zero.
-*/
-
-/*!
-    \qmlproperty int QtQuick2::Text::font.pixelSize
-
-    Sets the font size in pixels.
-
-    Using this function makes the font device dependent.
-    Use \c pointSize to set the size of the font in a device independent manner.
-*/
-
-/*!
-    \qmlproperty real QtQuick2::Text::font.letterSpacing
-
-    Sets the letter spacing for the font.
-
-    Letter spacing changes the default spacing between individual letters in the font.
-    A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing.
-*/
-
-/*!
-    \qmlproperty real QtQuick2::Text::font.wordSpacing
-
-    Sets the word spacing for the font.
-
-    Word spacing changes the default spacing between individual words.
-    A positive value increases the word spacing by a corresponding amount of pixels,
-    while a negative value decreases the inter-word spacing accordingly.
-*/
-
-/*!
-    \qmlproperty enumeration QtQuick2::Text::font.capitalization
-
-    Sets the capitalization for the text.
-
-    \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.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character.
-    \endlist
-
-    \qml
-    Text { text: "Hello"; font.capitalization: Font.AllLowercase }
-    \endqml
-*/
-QFont QSGText::font() const
-{
-    Q_D(const QSGText);
-    return d->sourceFont;
-}
-
-void QSGText::setFont(const QFont &font)
-{
-    Q_D(QSGText);
-    if (d->sourceFont == font)
-        return;
-
-    d->sourceFont = font;
-    QFont oldFont = d->font;
-    d->font = font;
-
-    if (d->font.pointSizeF() != -1) {
-        // 0.5pt resolution
-        qreal size = qRound(d->font.pointSizeF()*2.0);
-        d->font.setPointSizeF(size/2.0);
-    }
-
-    if (oldFont != d->font)
-        d->updateLayout();
-
-    emit fontChanged(d->sourceFont);
-}
-
-/*!
-    \qmlproperty string QtQuick2::Text::text
-
-    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 styled text. This determination is made using Qt::mightBeRichText().
-*/
-QString QSGText::text() const
-{
-    Q_D(const QSGText);
-    return d->text;
-}
-
-void QSGText::setText(const QString &n)
-{
-    Q_D(QSGText);
-    if (d->text == n)
-        return;
-
-    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 = enableImageCache();
-        } else {
-            d->rightToLeftText = d->text.isRightToLeft();
-        }
-        d->determineHorizontalAlignment();
-    }
-    d->textHasChanged = true;
-    d->updateLayout();
-    emit textChanged(d->text);
-}
-
-/*!
-    \qmlproperty color QtQuick2::Text::color
-
-    The text color.
-
-    An example of green text defined using hexadecimal notation:
-    \qml
-    Text {
-        color: "#00FF00"
-        text: "green text"
-    }
-    \endqml
-
-    An example of steel blue text defined using an SVG color name:
-    \qml
-    Text {
-        color: "steelblue"
-        text: "blue text"
-    }
-    \endqml
-*/
-QColor QSGText::color() const
-{
-    Q_D(const QSGText);
-    return d->color;
-}
-
-void QSGText::setColor(const QColor &color)
-{
-    Q_D(QSGText);
-    if (d->color == color)
-        return;
-
-    d->color = color;
-    d->invalidateImageCache();
-    emit colorChanged(d->color);
-}
-/*!
-    \qmlproperty enumeration QtQuick2::Text::style
-
-    Set an additional text style.
-
-    Supported text styles are:
-    \list
-    \o Text.Normal - the default
-    \o Text.Outline
-    \o Text.Raised
-    \o Text.Sunken
-    \endlist
-
-    \qml
-    Row {
-        Text { font.pointSize: 24; text: "Normal" }
-        Text { font.pointSize: 24; text: "Raised"; style: Text.Raised; styleColor: "#AAAAAA" }
-        Text { font.pointSize: 24; text: "Outline";style: Text.Outline; styleColor: "red" }
-        Text { font.pointSize: 24; text: "Sunken"; style: Text.Sunken; styleColor: "#AAAAAA" }
-    }
-    \endqml
-
-    \image declarative-textstyle.png
-*/
-QSGText::TextStyle QSGText::style() const
-{
-    Q_D(const QSGText);
-    return d->style;
-}
-
-void QSGText::setStyle(QSGText::TextStyle style)
-{
-    Q_D(QSGText);
-    if (d->style == style)
-        return;
-
-    // changing to/from Normal requires the boundingRect() to change
-    if (isComponentComplete() && (d->style == Normal || style == Normal))
-        update();
-    d->style = style;
-    d->invalidateImageCache();
-    emit styleChanged(d->style);
-}
-
-/*!
-    \qmlproperty color QtQuick2::Text::styleColor
-
-    Defines the secondary color used by text styles.
-
-    \c styleColor is used as the outline color for outlined text, and as the
-    shadow color for raised or sunken text. If no style has been set, it is not
-    used at all.
-
-    \qml
-    Text { font.pointSize: 18; text: "hello"; style: Text.Raised; styleColor: "gray" }
-    \endqml
-
-    \sa style
- */
-QColor QSGText::styleColor() const
-{
-    Q_D(const QSGText);
-    return d->styleColor;
-}
-
-void QSGText::setStyleColor(const QColor &color)
-{
-    Q_D(QSGText);
-    if (d->styleColor == color)
-        return;
-
-    d->styleColor = color;
-    d->invalidateImageCache();
-    emit styleColorChanged(d->styleColor);
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::Text::horizontalAlignment
-    \qmlproperty enumeration QtQuick2::Text::verticalAlignment
-    \qmlproperty enumeration QtQuick2::Text::effectiveHorizontalAlignment
-
-    Sets the horizontal and vertical alignment of the text within the Text items
-    width and height. By default, the text is vertically aligned to the top. Horizontal
-    alignment follows the natural alignment of the text, for example text that is read
-    from left to right will be aligned to the left.
-
-    The valid values for \c horizontalAlignment are \c Text.AlignLeft, \c Text.AlignRight, \c Text.AlignHCenter and
-    \c Text.AlignJustify.  The valid values for \c verticalAlignment are \c Text.AlignTop, \c Text.AlignBottom
-    and \c Text.AlignVCenter.
-
-    Note that for a single line of text, the size of the text is the area of the text. In this common case,
-    all alignments are equivalent. If you want the text to be, say, centered in its parent, then you will
-    need to either modify the Item::anchors, or set horizontalAlignment to Text.AlignHCenter and bind the width to
-    that of the parent.
-
-    When using the attached property LayoutMirroring::enabled to mirror application
-    layouts, the horizontal alignment of text will also be mirrored. However, the property
-    \c horizontalAlignment will remain unchanged. To query the effective horizontal alignment
-    of Text, use the read-only property \c effectiveHorizontalAlignment.
-*/
-QSGText::HAlignment QSGText::hAlign() const
-{
-    Q_D(const QSGText);
-    return d->hAlign;
-}
-
-void QSGText::setHAlign(HAlignment align)
-{
-    Q_D(QSGText);
-    bool forceAlign = d->hAlignImplicit && d->effectiveLayoutMirror;
-    d->hAlignImplicit = false;
-    if (d->setHAlign(align, forceAlign) && isComponentComplete())
-        d->updateLayout();
-}
-
-void QSGText::resetHAlign()
-{
-    Q_D(QSGText);
-    d->hAlignImplicit = true;
-    if (d->determineHorizontalAlignment() && isComponentComplete())
-        d->updateLayout();
-}
-
-QSGText::HAlignment QSGText::effectiveHAlign() const
-{
-    Q_D(const QSGText);
-    QSGText::HAlignment effectiveAlignment = d->hAlign;
-    if (!d->hAlignImplicit && d->effectiveLayoutMirror) {
-        switch (d->hAlign) {
-        case QSGText::AlignLeft:
-            effectiveAlignment = QSGText::AlignRight;
-            break;
-        case QSGText::AlignRight:
-            effectiveAlignment = QSGText::AlignLeft;
-            break;
-        default:
-            break;
-        }
-    }
-    return effectiveAlignment;
-}
-
-bool QSGTextPrivate::setHAlign(QSGText::HAlignment alignment, bool forceAlign)
-{
-    Q_Q(QSGText);
-    if (hAlign != alignment || forceAlign) {
-        QSGText::HAlignment oldEffectiveHAlign = q->effectiveHAlign();
-        hAlign = alignment;
-
-        emit q->horizontalAlignmentChanged(hAlign);
-        if (oldEffectiveHAlign != q->effectiveHAlign())
-            emit q->effectiveHorizontalAlignmentChanged();
-        return true;
-    }
-    return false;
-}
-
-bool QSGTextPrivate::determineHorizontalAlignment()
-{
-    Q_Q(QSGText);
-    if (hAlignImplicit && q->isComponentComplete()) {
-        bool alignToRight = text.isEmpty() ? QGuiApplication::keyboardInputDirection() == Qt::RightToLeft : rightToLeftText;
-        return setHAlign(alignToRight ? QSGText::AlignRight : QSGText::AlignLeft);
-    }
-    return false;
-}
-
-void QSGTextPrivate::mirrorChange()
-{
-    Q_Q(QSGText);
-    if (q->isComponentComplete()) {
-        if (!hAlignImplicit && (hAlign == QSGText::AlignRight || hAlign == QSGText::AlignLeft)) {
-            updateLayout();
-            emit q->effectiveHorizontalAlignmentChanged();
-        }
-    }
-}
-
-QTextDocument *QSGTextPrivate::textDocument()
-{
-    return doc;
-}
-
-QSGText::VAlignment QSGText::vAlign() const
-{
-    Q_D(const QSGText);
-    return d->vAlign;
-}
-
-void QSGText::setVAlign(VAlignment align)
-{
-    Q_D(QSGText);
-    if (d->vAlign == align)
-        return;
-
-    d->vAlign = align;
-    emit verticalAlignmentChanged(align);
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::Text::wrapMode
-
-    Set this property to wrap the text to the Text item's width.  The text will only
-    wrap if an explicit width has been set.  wrapMode can be one of:
-
-    \list
-    \o Text.NoWrap (default) - no wrapping will be performed. If the text contains insufficient newlines, then \l paintedWidth will exceed a set width.
-    \o Text.WordWrap - wrapping is done on word boundaries only. If a word is too long, \l paintedWidth will exceed a set width.
-    \o Text.WrapAnywhere - wrapping is done at any point on a line, even if it occurs in the middle of a word.
-    \o Text.Wrap - if possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word.
-    \endlist
-*/
-QSGText::WrapMode QSGText::wrapMode() const
-{
-    Q_D(const QSGText);
-    return d->wrapMode;
-}
-
-void QSGText::setWrapMode(WrapMode mode)
-{
-    Q_D(QSGText);
-    if (mode == d->wrapMode)
-        return;
-
-    d->wrapMode = mode;
-    d->updateLayout();
-
-    emit wrapModeChanged();
-}
-
-/*!
-    \qmlproperty int QtQuick2::Text::lineCount
-
-    Returns the number of lines visible in the text item.
-
-    This property is not supported for rich text.
-
-    \sa maximumLineCount
-*/
-int QSGText::lineCount() const
-{
-    Q_D(const QSGText);
-    return d->lineCount;
-}
-
-/*!
-    \qmlproperty bool QtQuick2::Text::truncated
-
-    Returns true if the text has been truncated due to \l maximumLineCount
-    or \l elide.
-
-    This property is not supported for rich text.
-
-    \sa maximumLineCount, elide
-*/
-bool QSGText::truncated() const
-{
-    Q_D(const QSGText);
-    return d->truncated;
-}
-
-/*!
-    \qmlproperty int QtQuick2::Text::maximumLineCount
-
-    Set this property to limit the number of lines that the text item will show.
-    If elide is set to Text.ElideRight, the text will be elided appropriately.
-    By default, this is the value of the largest possible integer.
-
-    This property is not supported for rich text.
-
-    \sa lineCount, elide
-*/
-int QSGText::maximumLineCount() const
-{
-    Q_D(const QSGText);
-    return d->maximumLineCount;
-}
-
-void QSGText::setMaximumLineCount(int lines)
-{
-    Q_D(QSGText);
-
-    d->maximumLineCountValid = lines==INT_MAX ? false : true;
-    if (d->maximumLineCount != lines) {
-        d->maximumLineCount = lines;
-        d->updateLayout();
-        emit maximumLineCountChanged();
-    }
-}
-
-void QSGText::resetMaximumLineCount()
-{
-    Q_D(QSGText);
-    setMaximumLineCount(INT_MAX);
-    d->elidePos = QPointF();
-    if (d->truncated != false) {
-        d->truncated = false;
-        emit truncatedChanged();
-    }
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::Text::textFormat
-
-    The way the text property should be displayed.
-
-    Supported text formats are:
-
-    \list
-    \o Text.AutoText (default)
-    \o Text.PlainText
-    \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
-    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:
-
-    \code
-    <b></b> - bold
-    <i></i> - italic
-    <br> - new line
-    <p> - paragraph
-    <u> - underlined text
-    <font color="color_name" size="1-7"></font>
-    <h1> to <h6> - headers
-    <a href=""> - anchor
-    <ol type="">, <ul type=""> and <li> - ordered and unordered lists
-    &gt; &lt; &amp;
-    \endcode
-
-    \c Text.StyledText parser is strict, requiring tags to be correctly nested.
-
-    \table
-    \row
-    \o
-    \qml
-Column {
-    Text {
-        font.pointSize: 24
-        text: "<b>Hello</b> <i>World!</i>"
-    }
-    Text {
-        font.pointSize: 24
-        textFormat: Text.RichText
-        text: "<b>Hello</b> <i>World!</i>"
-    }
-    Text {
-        font.pointSize: 24
-        textFormat: Text.PlainText
-        text: "<b>Hello</b> <i>World!</i>"
-    }
-}
-    \endqml
-    \o \image declarative-textformat.png
-    \endtable
-*/
-QSGText::TextFormat QSGText::textFormat() const
-{
-    Q_D(const QSGText);
-    return d->format;
-}
-
-void QSGText::setTextFormat(TextFormat format)
-{
-    Q_D(QSGText);
-    if (format == d->format)
-        return;
-    d->format = format;
-    bool wasRich = d->richText;
-    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->rightToLeftText = d->doc->toPlainText().isRightToLeft();
-        d->richTextAsImage = enableImageCache();
-    } else {
-        d->rightToLeftText = d->text.isRightToLeft();
-    }
-    d->determineHorizontalAlignment();
-    d->updateLayout();
-
-    emit textFormatChanged(d->format);
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::Text::elide
-
-    Set this property to elide parts of the text fit to the Text item's width.
-    The text will only elide if an explicit width has been set.
-
-    This property cannot be used with rich text.
-
-    Eliding can be:
-    \list
-    \o Text.ElideNone  - the default
-    \o Text.ElideLeft
-    \o Text.ElideMiddle
-    \o Text.ElideRight
-    \endlist
-
-    If this property is set to Text.ElideRight, it can be used with multiline
-    text. The text will only elide if maximumLineCount has been set.
-
-    If the text is a multi-length string, and the mode is not \c Text.ElideNone,
-    the first string that fits will be used, otherwise the last will be elided.
-
-    Multi-length strings are ordered from longest to shortest, separated by the
-    Unicode "String Terminator" character \c U009C (write this in QML with \c{"\u009C"} or \c{"\x9C"}).
-*/
-QSGText::TextElideMode QSGText::elideMode() const
-{
-    Q_D(const QSGText);
-    return d->elideMode;
-}
-
-void QSGText::setElideMode(QSGText::TextElideMode mode)
-{
-    Q_D(QSGText);
-    if (mode == d->elideMode)
-        return;
-
-    d->elideMode = mode;
-    d->updateLayout();
-
-    emit elideModeChanged(d->elideMode);
-}
-
-/*! \internal */
-QRectF QSGText::boundingRect() const
-{
-    Q_D(const QSGText);
-
-    QRect rect = d->layedOutTextRect;
-    if (d->style != Normal)
-        rect.adjust(-1, 0, 1, 2);
-
-    // Could include font max left/right bearings to either side of rectangle.
-
-    int h = height();
-    switch (d->vAlign) {
-    case AlignTop:
-        break;
-    case AlignBottom:
-        rect.moveTop(h - rect.height());
-        break;
-    case AlignVCenter:
-        rect.moveTop((h - rect.height()) / 2);
-        break;
-    }
-
-    return QRectF(rect);
-}
-
-/*! \internal */
-void QSGText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
-{
-    Q_D(QSGText);
-    if ((!d->internalWidthUpdate && newGeometry.width() != oldGeometry.width())
-            && (d->wrapMode != QSGText::NoWrap
-                || d->elideMode != QSGText::ElideNone
-                || d->hAlign != QSGText::AlignLeft)) {
-        if ((d->singleline || d->maximumLineCountValid) && d->elideMode != QSGText::ElideNone && widthValid()) {
-            // We need to re-elide
-            d->updateLayout();
-        } else {
-            // We just need to re-layout
-            d->updateSize();
-        }
-    }
-
-    QSGItem::geometryChanged(newGeometry, oldGeometry);
-}
-
-QSGNode *QSGText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
-{
-    Q_UNUSED(data);
-    Q_D(QSGText);
-
-    if (d->text.isEmpty()) {
-        delete oldNode;
-        return 0;
-    }
-
-    QRectF bounds = boundingRect();
-
-    // We need to make sure the layout is done in the current thread
-#if defined(Q_OS_MAC)
-    d->paintingThread = QThread::currentThread();
-    if (d->layoutThread != d->paintingThread)
-        d->updateLayout();
-#endif
-
-    // XXX todo - some styled text can be done by the QSGTextNode
-    if (d->richTextAsImage || d->cacheAllTextAsImage || (qmlDisableDistanceField() && d->style != Normal)) {
-        bool wasDirty = d->textureImageCacheDirty;
-        d->textureImageCacheDirty = false;
-
-        if (d->imageCache.isNull()) {
-            delete oldNode;
-            return 0;
-        }
-
-        QSGImageNode *node = 0;
-        if (!oldNode || d->nodeType != QSGTextPrivate::NodeIsTexture) {
-            delete oldNode;
-            node = QSGItemPrivate::get(this)->sceneGraphContext()->createImageNode();
-            d->texture = new QSGPlainTexture();
-            wasDirty = true;
-            d->nodeType = QSGTextPrivate::NodeIsTexture;
-        } else {
-            node = static_cast<QSGImageNode *>(oldNode);
-            Q_ASSERT(d->texture);
-        }
-
-        if (wasDirty) {
-            qobject_cast<QSGPlainTexture *>(d->texture)->setImage(d->imageCache.toImage());
-            node->setTexture(0);
-            node->setTexture(d->texture);
-        }
-
-        node->setTargetRect(QRectF(bounds.x(), bounds.y(), d->imageCache.width(), d->imageCache.height()));
-        node->setSourceRect(QRectF(0, 0, 1, 1));
-        node->setHorizontalWrapMode(QSGTexture::ClampToEdge);
-        node->setVerticalWrapMode(QSGTexture::ClampToEdge);
-        node->setFiltering(QSGTexture::Linear); // Nonsmooth text just ugly, so don't do that..
-        node->update();
-
-        return node;
-
-    } else {
-        QSGTextNode *node = 0;
-        if (!oldNode || d->nodeType != QSGTextPrivate::NodeIsText) {
-            delete oldNode;
-            node = new QSGTextNode(QSGItemPrivate::get(this)->sceneGraphContext());
-            d->nodeType = QSGTextPrivate::NodeIsText;
-        } else {
-            node = static_cast<QSGTextNode *>(oldNode);
-        }
-
-        node->deleteContent();
-        node->setMatrix(QMatrix4x4());
-
-        if (d->richText) {
-            d->ensureDoc();
-            node->addTextDocument(bounds.topLeft(), d->doc, QColor(), d->style, d->styleColor);
-
-        } else {
-            node->addTextLayout(QPoint(0, bounds.y()), &d->layout, d->color, d->style, d->styleColor);
-        }
-
-        return node;
-    }
-}
-
-bool QSGText::event(QEvent *e)
-{
-    Q_D(QSGText);
-    if (e->type() == QEvent::User) {
-        d->checkImageCache();
-        return true;
-    } else {
-        return QSGImplicitSizeItem::event(e);
-    }
-}
-
-/*!
-    \qmlproperty real QtQuick2::Text::paintedWidth
-
-    Returns the width of the text, including width past the width
-    which is covered due to insufficient wrapping if WrapMode is set.
-*/
-qreal QSGText::paintedWidth() const
-{
-    Q_D(const QSGText);
-    return d->paintedSize.width();
-}
-
-/*!
-    \qmlproperty real QtQuick2::Text::paintedHeight
-
-    Returns the height of the text, including height past the height
-    which is covered due to there being more text than fits in the set height.
-*/
-qreal QSGText::paintedHeight() const
-{
-    Q_D(const QSGText);
-    return d->paintedSize.height();
-}
-
-/*!
-    \qmlproperty real QtQuick2::Text::lineHeight
-
-    Sets the line height for the text.
-    The value can be in pixels or a multiplier depending on lineHeightMode.
-
-    The default value is a multiplier of 1.0.
-    The line height must be a positive value.
-*/
-qreal QSGText::lineHeight() const
-{
-    Q_D(const QSGText);
-    return d->lineHeight;
-}
-
-void QSGText::setLineHeight(qreal lineHeight)
-{
-    Q_D(QSGText);
-
-    if ((d->lineHeight == lineHeight) || (lineHeight < 0.0))
-        return;
-
-    d->lineHeight = lineHeight;
-    d->updateLayout();
-    emit lineHeightChanged(lineHeight);
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::Text::lineHeightMode
-
-    This property determines how the line height is specified.
-    The possible values are:
-
-    \list
-    \o Text.ProportionalHeight (default) - this sets the spacing proportional to the
-       line (as a multiplier). For example, set to 2 for double spacing.
-    \o Text.FixedHeight - this sets the line height to a fixed line height (in pixels).
-    \endlist
-*/
-QSGText::LineHeightMode QSGText::lineHeightMode() const
-{
-    Q_D(const QSGText);
-    return d->lineHeightMode;
-}
-
-void QSGText::setLineHeightMode(LineHeightMode mode)
-{
-    Q_D(QSGText);
-    if (mode == d->lineHeightMode)
-        return;
-
-    d->lineHeightMode = mode;
-    d->updateLayout();
-
-    emit lineHeightModeChanged(mode);
-}
-
-/*!
-    Returns the number of resources (images) that are being loaded asynchronously.
-*/
-int QSGText::resourcesLoading() const
-{
-    Q_D(const QSGText);
-    return d->doc ? d->doc->resourcesLoading() : 0;
-}
-
-/*! \internal */
-void QSGText::componentComplete()
-{
-    Q_D(QSGText);
-    QSGItem::componentComplete();
-    if (d->updateOnComponentComplete) {
-        d->updateOnComponentComplete = false;
-        if (d->richText) {
-            d->ensureDoc();
-            d->doc->setText(d->text);
-            d->rightToLeftText = d->doc->toPlainText().isRightToLeft();
-            d->richTextAsImage = enableImageCache();
-        } else {
-            d->rightToLeftText = d->text.isRightToLeft();
-        }
-        d->determineHorizontalAlignment();
-        d->updateLayout();
-    }
-}
-
-
-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->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())
-        QSGItem::mousePressEvent(event);
-
-}
-
-/*! \internal */
-void QSGText::mouseReleaseEvent(QMouseEvent *event)
-{
-    Q_D(QSGText);
-
-    // ### 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);
-
-    if (!event->isAccepted())
-        QSGItem::mouseReleaseEvent(event);
-}
-
-QT_END_NAMESPACE
-
-#include "qsgtext.moc"
diff --git a/src/declarative/items/qsgtext_p.h b/src/declarative/items/qsgtext_p.h
deleted file mode 100644 (file)
index aa07c8a..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-// Commit: 27e4302b7f45f22180693d26747f419177c81e27
-/****************************************************************************
-**
-** 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 QSGTEXT_P_H
-#define QSGTEXT_P_H
-
-#include "qsgimplicitsizeitem_p.h"
-
-#include <private/qdeclarativeglobal_p.h>
-
-#include <QtGui/qtextoption.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-class QSGTextPrivate;
-class QSGTextLine;
-class Q_DECLARATIVE_PRIVATE_EXPORT QSGText : public QSGImplicitSizeItem
-{
-    Q_OBJECT
-    Q_ENUMS(HAlignment)
-    Q_ENUMS(VAlignment)
-    Q_ENUMS(TextStyle)
-    Q_ENUMS(TextFormat)
-    Q_ENUMS(TextElideMode)
-    Q_ENUMS(WrapMode)
-    Q_ENUMS(LineHeightMode)
-
-    Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
-    Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
-    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
-    Q_PROPERTY(TextStyle style READ style WRITE setStyle NOTIFY styleChanged)
-    Q_PROPERTY(QColor styleColor READ styleColor WRITE setStyleColor NOTIFY styleColorChanged)
-    Q_PROPERTY(HAlignment horizontalAlignment READ hAlign WRITE setHAlign RESET resetHAlign NOTIFY horizontalAlignmentChanged)
-    Q_PROPERTY(HAlignment effectiveHorizontalAlignment READ effectiveHAlign NOTIFY effectiveHorizontalAlignmentChanged)
-    Q_PROPERTY(VAlignment verticalAlignment READ vAlign WRITE setVAlign NOTIFY verticalAlignmentChanged)
-    Q_PROPERTY(WrapMode wrapMode READ wrapMode WRITE setWrapMode NOTIFY wrapModeChanged)
-    Q_PROPERTY(int lineCount READ lineCount NOTIFY lineCountChanged)
-    Q_PROPERTY(bool truncated READ truncated NOTIFY truncatedChanged)
-    Q_PROPERTY(int maximumLineCount READ maximumLineCount WRITE setMaximumLineCount NOTIFY maximumLineCountChanged RESET resetMaximumLineCount)
-
-    Q_PROPERTY(TextFormat textFormat READ textFormat WRITE setTextFormat NOTIFY textFormatChanged)
-    Q_PROPERTY(TextElideMode elide READ elideMode WRITE setElideMode NOTIFY elideModeChanged) //### elideMode?
-    Q_PROPERTY(qreal paintedWidth READ paintedWidth NOTIFY paintedSizeChanged)
-    Q_PROPERTY(qreal paintedHeight READ paintedHeight NOTIFY paintedSizeChanged)
-    Q_PROPERTY(qreal lineHeight READ lineHeight WRITE setLineHeight NOTIFY lineHeightChanged)
-    Q_PROPERTY(LineHeightMode lineHeightMode READ lineHeightMode WRITE setLineHeightMode NOTIFY lineHeightModeChanged)
-
-public:
-    QSGText(QSGItem *parent=0);
-    ~QSGText();
-
-    enum HAlignment { AlignLeft = Qt::AlignLeft,
-                       AlignRight = Qt::AlignRight,
-                       AlignHCenter = Qt::AlignHCenter,
-                       AlignJustify = Qt::AlignJustify };
-    enum VAlignment { AlignTop = Qt::AlignTop,
-                       AlignBottom = Qt::AlignBottom,
-                       AlignVCenter = Qt::AlignVCenter };
-    enum TextStyle { Normal,
-                      Outline,
-                      Raised,
-                      Sunken };
-    enum TextFormat { PlainText = Qt::PlainText,
-                       RichText = Qt::RichText,
-                       AutoText = Qt::AutoText,
-                       StyledText = 4 };
-    enum TextElideMode { ElideLeft = Qt::ElideLeft,
-                          ElideRight = Qt::ElideRight,
-                          ElideMiddle = Qt::ElideMiddle,
-                          ElideNone = Qt::ElideNone };
-
-    enum WrapMode { NoWrap = QTextOption::NoWrap,
-                    WordWrap = QTextOption::WordWrap,
-                    WrapAnywhere = QTextOption::WrapAnywhere,
-                    WrapAtWordBoundaryOrAnywhere = QTextOption::WrapAtWordBoundaryOrAnywhere, // COMPAT
-                    Wrap = QTextOption::WrapAtWordBoundaryOrAnywhere
-                  };
-
-    enum LineHeightMode { ProportionalHeight, FixedHeight };
-
-    QString text() const;
-    void setText(const QString &);
-
-    QFont font() const;
-    void setFont(const QFont &font);
-
-    QColor color() const;
-    void setColor(const QColor &c);
-
-    TextStyle style() const;
-    void setStyle(TextStyle style);
-
-    QColor styleColor() const;
-    void setStyleColor(const QColor &c);
-
-    HAlignment hAlign() const;
-    void setHAlign(HAlignment align);
-    void resetHAlign();
-    HAlignment effectiveHAlign() const;
-
-    VAlignment vAlign() const;
-    void setVAlign(VAlignment align);
-
-    WrapMode wrapMode() const;
-    void setWrapMode(WrapMode w);
-
-    int lineCount() const;
-    bool truncated() const;
-
-    int maximumLineCount() const;
-    void setMaximumLineCount(int lines);
-    void resetMaximumLineCount();
-
-    TextFormat textFormat() const;
-    void setTextFormat(TextFormat format);
-
-    TextElideMode elideMode() const;
-    void setElideMode(TextElideMode);
-
-    qreal lineHeight() const;
-    void setLineHeight(qreal lineHeight);
-
-    LineHeightMode lineHeightMode() const;
-    void setLineHeightMode(LineHeightMode);
-
-    virtual void componentComplete();
-
-    int resourcesLoading() const; // mainly for testing
-
-    qreal paintedWidth() const;
-    qreal paintedHeight() const;
-
-    QRectF boundingRect() const;
-    Q_INVOKABLE void doLayout();
-
-Q_SIGNALS:
-    void textChanged(const QString &text);
-    void linkActivated(const QString &link);
-    void fontChanged(const QFont &font);
-    void colorChanged(const QColor &color);
-    void styleChanged(TextStyle style);
-    void styleColorChanged(const QColor &color);
-    void horizontalAlignmentChanged(HAlignment alignment);
-    void verticalAlignmentChanged(VAlignment alignment);
-    void wrapModeChanged();
-    void lineCountChanged();
-    void truncatedChanged();
-    void maximumLineCountChanged();
-    void textFormatChanged(TextFormat textFormat);
-    void elideModeChanged(TextElideMode mode);
-    void paintedSizeChanged();
-    void lineHeightChanged(qreal lineHeight);
-    void lineHeightModeChanged(LineHeightMode mode);
-    void effectiveHorizontalAlignmentChanged();
-    void lineLaidOut(QSGTextLine *line);
-
-protected:
-    void mousePressEvent(QMouseEvent *event);
-    void mouseReleaseEvent(QMouseEvent *event);
-    virtual void geometryChanged(const QRectF &newGeometry,
-                                 const QRectF &oldGeometry);
-    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
-    virtual bool event(QEvent *);
-
-private:
-    Q_DISABLE_COPY(QSGText)
-    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
-
-#endif // QSGTEXT_P_H
diff --git a/src/declarative/items/qsgtext_p_p.h b/src/declarative/items/qsgtext_p_p.h
deleted file mode 100644 (file)
index 8b83263..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-// Commit: 6e5a642c9484536fc173714f560f739944368cf5
-/****************************************************************************
-**
-** 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 QSGTEXT_P_P_H
-#define QSGTEXT_P_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 "qsgitem.h"
-#include "qsgimplicitsizeitem_p_p.h"
-
-#include <QtDeclarative/qdeclarative.h>
-#include <QtGui/qtextlayout.h>
-
-QT_BEGIN_NAMESPACE
-
-class QTextLayout;
-class QSGTextDocumentWithImageResources;
-class QSGPlainTexture;
-
-class Q_AUTOTEST_EXPORT QSGTextPrivate : public QSGImplicitSizeItemPrivate
-{
-    Q_DECLARE_PUBLIC(QSGText)
-public:
-    QSGTextPrivate();
-    ~QSGTextPrivate();
-    void init();
-
-    void updateSize();
-    void updateLayout();
-    bool determineHorizontalAlignment();
-    bool setHAlign(QSGText::HAlignment, bool forceAlign = false);
-    void mirrorChange();
-    QTextDocument *textDocument();
-    bool isLineLaidOutConnected();
-
-    QString text;
-    QFont font;
-    QFont sourceFont;
-    QColor  color;
-    QSGText::TextStyle style;
-    QColor  styleColor;
-    QString activeLink;
-    QSGText::HAlignment hAlign;
-    QSGText::VAlignment vAlign;
-    QSGText::TextElideMode elideMode;
-    QSGText::TextFormat format;
-    QSGText::WrapMode wrapMode;
-    qreal lineHeight;
-    QSGText::LineHeightMode lineHeightMode;
-    int lineCount;
-    int maximumLineCount;
-    int maximumLineCountValid;
-    QPointF elidePos;
-
-    static QString elideChar;
-
-    void invalidateImageCache();
-    void checkImageCache();
-    QPixmap imageCache;
-    QSGTexture *texture;
-
-    bool imageCacheDirty:1;
-    bool updateOnComponentComplete:1;
-    bool richText:1;
-    bool styledText:1;
-    bool singleline:1;
-    bool cacheAllTextAsImage:1;
-    bool internalWidthUpdate:1;
-    bool requireImplicitWidth:1;
-    bool truncated:1;
-    bool hAlignImplicit:1;
-    bool rightToLeftText:1;
-    bool layoutTextElided:1;
-    bool richTextAsImage:1;
-    bool textureImageCacheDirty:1;
-    bool textHasChanged:1;
-
-    QRect layedOutTextRect;
-    QSize paintedSize;
-    qreal naturalWidth;
-    virtual qreal getImplicitWidth() const;
-
-    void ensureDoc();
-    QPixmap textDocumentImage(bool drawStyle);
-    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);
-
-    static inline QSGTextPrivate *get(QSGText *t) {
-        return t->d_func();
-    }
-
-    enum NodeType {
-        NodeIsNull,
-        NodeIsTexture,
-        NodeIsText
-    };
-    NodeType nodeType;
-
-#if defined(Q_OS_MAC)
-    QThread *layoutThread;
-    QThread *paintingThread;
-#endif
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGTEXT_P_P_H
diff --git a/src/declarative/items/qsgtextedit.cpp b/src/declarative/items/qsgtextedit.cpp
deleted file mode 100644 (file)
index bbc751f..0000000
+++ /dev/null
@@ -1,1976 +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 "qsgtextedit_p.h"
-#include "qsgtextedit_p_p.h"
-#include "qsgevents_p_p.h"
-#include "qsgcanvas.h"
-#include "qsgtextnode_p.h"
-#include "qsgsimplerectnode.h"
-
-#include <QtDeclarative/qdeclarativeinfo.h>
-#include <QtGui/qguiapplication.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qpainter.h>
-#include <QtGui/qtextobject.h>
-#include <QtCore/qmath.h>
-
-#include <private/qdeclarativeglobal_p.h>
-#include <private/qtextcontrol_p.h>
-#include <private/qtextengine_p.h>
-#include <private/qsgdistancefieldglyphcache_p.h>
-#include <private/qsgtexture_p.h>
-#include <private/qsgadaptationlayer_p.h>
-
-QT_BEGIN_NAMESPACE
-
-DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
-DEFINE_BOOL_CONFIG_OPTION(qmlEnableImageCache, QML_ENABLE_TEXT_IMAGE_CACHE)
-
-/*!
-    \qmlclass TextEdit QSGTextEdit
-    \inqmlmodule QtQuick 2
-    \ingroup qml-basic-visual-elements
-    \brief The TextEdit item displays multiple lines of editable formatted text.
-    \inherits Item
-
-    The TextEdit item displays a block of editable, formatted text.
-
-    It can display both plain and rich text. For example:
-
-    \qml
-TextEdit {
-    width: 240
-    text: "<b>Hello</b> <i>World!</i>"
-    font.family: "Helvetica"
-    font.pointSize: 20
-    color: "blue"
-    focus: true
-}
-    \endqml
-
-    \image declarative-textedit.gif
-
-    Setting \l {Item::focus}{focus} to \c true enables the TextEdit item to receive keyboard focus.
-
-    Note that the TextEdit does not implement scrolling, following the cursor, or other behaviors specific
-    to a look-and-feel. For example, to add flickable scrolling that follows the cursor:
-
-    \snippet snippets/declarative/texteditor.qml 0
-
-    A particular look-and-feel might use smooth scrolling (eg. using SmoothedFollow), might have a visible
-    scrollbar, or a scrollbar that fades in to show location, etc.
-
-    Clipboard support is provided by the cut(), copy(), and paste() functions, and the selection can
-    be handled in a traditional "mouse" mechanism by setting selectByMouse, or handled completely
-    from QML by manipulating selectionStart and selectionEnd, or using selectAll() or selectWord().
-
-    You can translate between cursor positions (characters from the start of the document) and pixel
-    points using positionAt() and positionToRectangle().
-
-    \sa Text, TextInput, {declarative/text/textselection}{Text Selection example}
-*/
-
-/*!
-    \qmlsignal QtQuick2::TextEdit::onLinkActivated(string link)
-
-    This handler is called when the user clicks on a link embedded in the text.
-    The link must be in rich text or HTML format and the
-    \a link string provides access to the particular link.
-*/
-QSGTextEdit::QSGTextEdit(QSGItem *parent)
-: QSGImplicitSizeItem(*(new QSGTextEditPrivate), parent)
-{
-    Q_D(QSGTextEdit);
-    d->init();
-}
-
-QString QSGTextEdit::text() const
-{
-    Q_D(const QSGTextEdit);
-
-#ifndef QT_NO_TEXTHTMLPARSER
-    if (d->richText)
-        return d->document->toHtml();
-    else
-#endif
-        return d->document->toPlainText();
-}
-
-/*!
-    \qmlproperty string QtQuick2::TextEdit::font.family
-
-    Sets the family name of the font.
-
-    The family name is case insensitive and may optionally include a foundry name, e.g. "Helvetica [Cronyx]".
-    If the family is available from more than one foundry and the foundry isn't specified, an arbitrary foundry is chosen.
-    If the family isn't available a family will be set using the font matching algorithm.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::TextEdit::font.bold
-
-    Sets whether the font weight is bold.
-*/
-
-/*!
-    \qmlproperty enumeration QtQuick2::TextEdit::font.weight
-
-    Sets the font's weight.
-
-    The weight can be one of:
-    \list
-    \o Font.Light
-    \o Font.Normal - the default
-    \o Font.DemiBold
-    \o Font.Bold
-    \o Font.Black
-    \endlist
-
-    \qml
-    TextEdit { text: "Hello"; font.weight: Font.DemiBold }
-    \endqml
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::TextEdit::font.italic
-
-    Sets whether the font has an italic style.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::TextEdit::font.underline
-
-    Sets whether the text is underlined.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::TextEdit::font.strikeout
-
-    Sets whether the font has a strikeout style.
-*/
-
-/*!
-    \qmlproperty real QtQuick2::TextEdit::font.pointSize
-
-    Sets the font size in points. The point size must be greater than zero.
-*/
-
-/*!
-    \qmlproperty int QtQuick2::TextEdit::font.pixelSize
-
-    Sets the font size in pixels.
-
-    Using this function makes the font device dependent.  Use
-    \l{TextEdit::font.pointSize} to set the size of the font in a
-    device independent manner.
-*/
-
-/*!
-    \qmlproperty real QtQuick2::TextEdit::font.letterSpacing
-
-    Sets the letter spacing for the font.
-
-    Letter spacing changes the default spacing between individual letters in the font.
-    A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing.
-*/
-
-/*!
-    \qmlproperty real QtQuick2::TextEdit::font.wordSpacing
-
-    Sets the word spacing for the font.
-
-    Word spacing changes the default spacing between individual words.
-    A positive value increases the word spacing by a corresponding amount of pixels,
-    while a negative value decreases the inter-word spacing accordingly.
-*/
-
-/*!
-    \qmlproperty enumeration QtQuick2::TextEdit::font.capitalization
-
-    Sets the capitalization for the text.
-
-    \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.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character.
-    \endlist
-
-    \qml
-    TextEdit { text: "Hello"; font.capitalization: Font.AllLowercase }
-    \endqml
-*/
-
-/*!
-    \qmlproperty string QtQuick2::TextEdit::text
-
-    The text to display.  If the text format is AutoText the text edit will
-    automatically determine whether the text should be treated as
-    rich text.  This determination is made using Qt::mightBeRichText().
-*/
-void QSGTextEdit::setText(const QString &text)
-{
-    Q_D(QSGTextEdit);
-    if (QSGTextEdit::text() == text)
-        return;
-
-    d->richText = d->format == RichText || (d->format == AutoText && Qt::mightBeRichText(text));
-    if (d->richText) {
-#ifndef QT_NO_TEXTHTMLPARSER
-        d->control->setHtml(text);
-#else
-        d->control->setPlainText(text);
-#endif
-        d->useImageFallback = qmlEnableImageCache();
-    } else {
-        d->control->setPlainText(text);
-    }
-    q_textChanged();
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::TextEdit::textFormat
-
-    The way the text property should be displayed.
-
-    \list
-    \o TextEdit.AutoText
-    \o TextEdit.PlainText
-    \o TextEdit.RichText
-    \endlist
-
-    The default is TextEdit.AutoText.  If the text format is TextEdit.AutoText the text edit
-    will automatically determine whether the text should be treated as
-    rich text.  This determination is made using Qt::mightBeRichText().
-
-    \table
-    \row
-    \o
-    \qml
-Column {
-    TextEdit {
-        font.pointSize: 24
-        text: "<b>Hello</b> <i>World!</i>"
-    }
-    TextEdit {
-        font.pointSize: 24
-        textFormat: TextEdit.RichText
-        text: "<b>Hello</b> <i>World!</i>"
-    }
-    TextEdit {
-        font.pointSize: 24
-        textFormat: TextEdit.PlainText
-        text: "<b>Hello</b> <i>World!</i>"
-    }
-}
-    \endqml
-    \o \image declarative-textformat.png
-    \endtable
-*/
-QSGTextEdit::TextFormat QSGTextEdit::textFormat() const
-{
-    Q_D(const QSGTextEdit);
-    return d->format;
-}
-
-void QSGTextEdit::setTextFormat(TextFormat format)
-{
-    Q_D(QSGTextEdit);
-    if (format == d->format)
-        return;
-    bool wasRich = d->richText;
-    d->richText = format == RichText || (format == AutoText && Qt::mightBeRichText(d->text));
-
-    if (wasRich && !d->richText) {
-        d->control->setPlainText(d->text);
-        updateSize();
-    } else if (!wasRich && d->richText) {
-#ifndef QT_NO_TEXTHTMLPARSER
-        d->control->setHtml(d->text);
-#else
-        d->control->setPlainText(d->text);
-#endif
-        updateSize();
-        d->useImageFallback = qmlEnableImageCache();
-    }
-    d->format = format;
-    d->control->setAcceptRichText(d->format != PlainText);
-    emit textFormatChanged(d->format);
-}
-
-QFont QSGTextEdit::font() const
-{
-    Q_D(const QSGTextEdit);
-    return d->sourceFont;
-}
-
-void QSGTextEdit::setFont(const QFont &font)
-{
-    Q_D(QSGTextEdit);
-    if (d->sourceFont == font)
-        return;
-
-    d->sourceFont = font;
-    QFont oldFont = d->font;
-    d->font = font;
-    if (d->font.pointSizeF() != -1) {
-        // 0.5pt resolution
-        qreal size = qRound(d->font.pointSizeF()*2.0);
-        d->font.setPointSizeF(size/2.0);
-    }
-
-    if (oldFont != d->font) {
-        d->document->setDefaultFont(d->font);
-        if (d->cursor) {
-            d->cursor->setHeight(QFontMetrics(d->font).height());
-            moveCursorDelegate();
-        }
-        updateSize();
-        updateDocument();
-    }
-    emit fontChanged(d->sourceFont);
-}
-
-/*!
-    \qmlproperty color QtQuick2::TextEdit::color
-
-    The text color.
-
-    \qml
-    // green text using hexadecimal notation
-    TextEdit { color: "#00FF00" }
-    \endqml
-
-    \qml
-    // steelblue text using SVG color name
-    TextEdit { color: "steelblue" }
-    \endqml
-*/
-QColor QSGTextEdit::color() const
-{
-    Q_D(const QSGTextEdit);
-    return d->color;
-}
-
-void QSGTextEdit::setColor(const QColor &color)
-{
-    Q_D(QSGTextEdit);
-    if (d->color == color)
-        return;
-
-    d->color = color;
-    QPalette pal = d->control->palette();
-    pal.setColor(QPalette::Text, color);
-    d->control->setPalette(pal);
-    updateDocument();
-    emit colorChanged(d->color);
-}
-
-/*!
-    \qmlproperty color QtQuick2::TextEdit::selectionColor
-
-    The text highlight color, used behind selections.
-*/
-QColor QSGTextEdit::selectionColor() const
-{
-    Q_D(const QSGTextEdit);
-    return d->selectionColor;
-}
-
-void QSGTextEdit::setSelectionColor(const QColor &color)
-{
-    Q_D(QSGTextEdit);
-    if (d->selectionColor == color)
-        return;
-
-    d->selectionColor = color;
-    QPalette pal = d->control->palette();
-    pal.setColor(QPalette::Highlight, color);
-    d->control->setPalette(pal);
-    updateDocument();
-    emit selectionColorChanged(d->selectionColor);
-}
-
-/*!
-    \qmlproperty color QtQuick2::TextEdit::selectedTextColor
-
-    The selected text color, used in selections.
-*/
-QColor QSGTextEdit::selectedTextColor() const
-{
-    Q_D(const QSGTextEdit);
-    return d->selectedTextColor;
-}
-
-void QSGTextEdit::setSelectedTextColor(const QColor &color)
-{
-    Q_D(QSGTextEdit);
-    if (d->selectedTextColor == color)
-        return;
-
-    d->selectedTextColor = color;
-    QPalette pal = d->control->palette();
-    pal.setColor(QPalette::HighlightedText, color);
-    d->control->setPalette(pal);
-    updateDocument();
-    emit selectedTextColorChanged(d->selectedTextColor);
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::TextEdit::horizontalAlignment
-    \qmlproperty enumeration QtQuick2::TextEdit::verticalAlignment
-    \qmlproperty enumeration QtQuick2::TextEdit::effectiveHorizontalAlignment
-
-    Sets the horizontal and vertical alignment of the text within the TextEdit item's
-    width and height. By default, the text alignment follows the natural alignment
-    of the text, for example text that is read from left to right will be aligned to
-    the left.
-
-    Valid values for \c horizontalAlignment are:
-    \list
-    \o TextEdit.AlignLeft (default)
-    \o TextEdit.AlignRight
-    \o TextEdit.AlignHCenter
-    \o TextEdit.AlignJustify
-    \endlist
-
-    Valid values for \c verticalAlignment are:
-    \list
-    \o TextEdit.AlignTop (default)
-    \o TextEdit.AlignBottom
-    \o TextEdit.AlignVCenter
-    \endlist
-
-    When using the attached property LayoutMirroring::enabled to mirror application
-    layouts, the horizontal alignment of text will also be mirrored. However, the property
-    \c horizontalAlignment will remain unchanged. To query the effective horizontal alignment
-    of TextEdit, use the read-only property \c effectiveHorizontalAlignment.
-*/
-QSGTextEdit::HAlignment QSGTextEdit::hAlign() const
-{
-    Q_D(const QSGTextEdit);
-    return d->hAlign;
-}
-
-void QSGTextEdit::setHAlign(HAlignment align)
-{
-    Q_D(QSGTextEdit);
-    bool forceAlign = d->hAlignImplicit && d->effectiveLayoutMirror;
-    d->hAlignImplicit = false;
-    if (d->setHAlign(align, forceAlign) && isComponentComplete()) {
-        d->updateDefaultTextOption();
-        updateSize();
-    }
-}
-
-void QSGTextEdit::resetHAlign()
-{
-    Q_D(QSGTextEdit);
-    d->hAlignImplicit = true;
-    if (d->determineHorizontalAlignment() && isComponentComplete()) {
-        d->updateDefaultTextOption();
-        updateSize();
-    }
-}
-
-QSGTextEdit::HAlignment QSGTextEdit::effectiveHAlign() const
-{
-    Q_D(const QSGTextEdit);
-    QSGTextEdit::HAlignment effectiveAlignment = d->hAlign;
-    if (!d->hAlignImplicit && d->effectiveLayoutMirror) {
-        switch (d->hAlign) {
-        case QSGTextEdit::AlignLeft:
-            effectiveAlignment = QSGTextEdit::AlignRight;
-            break;
-        case QSGTextEdit::AlignRight:
-            effectiveAlignment = QSGTextEdit::AlignLeft;
-            break;
-        default:
-            break;
-        }
-    }
-    return effectiveAlignment;
-}
-
-bool QSGTextEditPrivate::setHAlign(QSGTextEdit::HAlignment alignment, bool forceAlign)
-{
-    Q_Q(QSGTextEdit);
-    if (hAlign != alignment || forceAlign) {
-        QSGTextEdit::HAlignment oldEffectiveHAlign = q->effectiveHAlign();
-        hAlign = alignment;
-        emit q->horizontalAlignmentChanged(alignment);
-        if (oldEffectiveHAlign != q->effectiveHAlign())
-            emit q->effectiveHorizontalAlignmentChanged();
-        return true;
-    }
-    return false;
-}
-
-bool QSGTextEditPrivate::determineHorizontalAlignment()
-{
-    Q_Q(QSGTextEdit);
-    if (hAlignImplicit && q->isComponentComplete()) {
-        bool alignToRight = text.isEmpty() ? QGuiApplication::keyboardInputDirection() == Qt::RightToLeft : rightToLeftText;
-        return setHAlign(alignToRight ? QSGTextEdit::AlignRight : QSGTextEdit::AlignLeft);
-    }
-    return false;
-}
-
-void QSGTextEditPrivate::mirrorChange()
-{
-    Q_Q(QSGTextEdit);
-    if (q->isComponentComplete()) {
-        if (!hAlignImplicit && (hAlign == QSGTextEdit::AlignRight || hAlign == QSGTextEdit::AlignLeft)) {
-            updateDefaultTextOption();
-            q->updateSize();
-            emit q->effectiveHorizontalAlignmentChanged();
-        }
-    }
-}
-
-QSGTextEdit::VAlignment QSGTextEdit::vAlign() const
-{
-    Q_D(const QSGTextEdit);
-    return d->vAlign;
-}
-
-void QSGTextEdit::setVAlign(QSGTextEdit::VAlignment alignment)
-{
-    Q_D(QSGTextEdit);
-    if (alignment == d->vAlign)
-        return;
-    d->vAlign = alignment;
-    d->updateDefaultTextOption();
-    updateSize();
-    moveCursorDelegate();
-    emit verticalAlignmentChanged(d->vAlign);
-}
-/*!
-    \qmlproperty enumeration QtQuick2::TextEdit::wrapMode
-
-    Set this property to wrap the text to the TextEdit item's width.
-    The text will only wrap if an explicit width has been set.
-
-    \list
-    \o TextEdit.NoWrap - no wrapping will be performed. If the text contains insufficient newlines, then implicitWidth will exceed a set width.
-    \o TextEdit.WordWrap - wrapping is done on word boundaries only. If a word is too long, implicitWidth will exceed a set width.
-    \o TextEdit.WrapAnywhere - wrapping is done at any point on a line, even if it occurs in the middle of a word.
-    \o TextEdit.Wrap - if possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word.
-    \endlist
-
-    The default is TextEdit.NoWrap. If you set a width, consider using TextEdit.Wrap.
-*/
-QSGTextEdit::WrapMode QSGTextEdit::wrapMode() const
-{
-    Q_D(const QSGTextEdit);
-    return d->wrapMode;
-}
-
-void QSGTextEdit::setWrapMode(WrapMode mode)
-{
-    Q_D(QSGTextEdit);
-    if (mode == d->wrapMode)
-        return;
-    d->wrapMode = mode;
-    d->updateDefaultTextOption();
-    updateSize();
-    emit wrapModeChanged();
-}
-
-/*!
-    \qmlproperty int QtQuick2::TextEdit::lineCount
-
-    Returns the total number of lines in the textEdit item.
-*/
-int QSGTextEdit::lineCount() const
-{
-    Q_D(const QSGTextEdit);
-    return d->lineCount;
-}
-
-/*!
-    \qmlproperty real QtQuick2::TextEdit::paintedWidth
-
-    Returns the width of the text, including the width past the width
-    which is covered due to insufficient wrapping if \l wrapMode is set.
-*/
-qreal QSGTextEdit::paintedWidth() const
-{
-    Q_D(const QSGTextEdit);
-    return d->paintedSize.width();
-}
-
-/*!
-    \qmlproperty real QtQuick2::TextEdit::paintedHeight
-
-    Returns the height of the text, including the height past the height
-    that is covered if the text does not fit within the set height.
-*/
-qreal QSGTextEdit::paintedHeight() const
-{
-    Q_D(const QSGTextEdit);
-    return d->paintedSize.height();
-}
-
-/*!
-    \qmlmethod rectangle QtQuick2::TextEdit::positionToRectangle(position)
-
-    Returns the rectangle at the given \a position in the text. The x, y,
-    and height properties correspond to the cursor that would describe
-    that position.
-*/
-QRectF QSGTextEdit::positionToRectangle(int pos) const
-{
-    Q_D(const QSGTextEdit);
-    QTextCursor c(d->document);
-    c.setPosition(pos);
-    return d->control->cursorRect(c);
-
-}
-
-/*!
-    \qmlmethod int QtQuick2::TextEdit::positionAt(int x, int y)
-
-    Returns the text position closest to pixel position (\a x, \a y).
-
-    Position 0 is before the first character, position 1 is after the first character
-    but before the second, and so on until position \l {text}.length, which is after all characters.
-*/
-int QSGTextEdit::positionAt(int x, int y) const
-{
-    Q_D(const QSGTextEdit);
-    int r = d->document->documentLayout()->hitTest(QPoint(x,y-d->yoff), Qt::FuzzyHit);
-    QTextCursor cursor = d->control->textCursor();
-    if (r > cursor.position()) {
-        // The cursor position includes positions within the preedit text, but only positions in the
-        // same text block are offset so it is possible to get a position that is either part of the
-        // preedit or the next text block.
-        QTextLayout *layout = cursor.block().layout();
-        const int preeditLength = layout
-                ? layout->preeditAreaText().length()
-                : 0;
-        if (preeditLength > 0
-                && d->document->documentLayout()->blockBoundingRect(cursor.block()).contains(x,y-d->yoff)) {
-            r = r > cursor.position() + preeditLength
-                    ? r - preeditLength
-                    : cursor.position();
-        }
-    }
-    return r;
-}
-
-/*!
-    \qmlmethod void QtQuick2::TextEdit::moveCursorSelection(int position, SelectionMode mode = TextEdit.SelectCharacters)
-
-    Moves the cursor to \a position and updates the selection according to the optional \a mode
-    parameter. (To only move the cursor, set the \l cursorPosition property.)
-
-    When this method is called it additionally sets either the
-    selectionStart or the selectionEnd (whichever was at the previous cursor position)
-    to the specified position. This allows you to easily extend and contract the selected
-    text range.
-
-    The selection mode specifies whether the selection is updated on a per character or a per word
-    basis.  If not specified the selection mode will default to TextEdit.SelectCharacters.
-
-    \list
-    \o TextEdit.SelectCharacters - Sets either the selectionStart or selectionEnd (whichever was at
-    the previous cursor position) to the specified position.
-    \o TextEdit.SelectWords - Sets the selectionStart and selectionEnd to include all
-    words between the specified postion and the previous cursor position.  Words partially in the
-    range are included.
-    \endlist
-
-    For example, take this sequence of calls:
-
-    \code
-        cursorPosition = 5
-        moveCursorSelection(9, TextEdit.SelectCharacters)
-        moveCursorSelection(7, TextEdit.SelectCharacters)
-    \endcode
-
-    This moves the cursor to position 5, extend the selection end from 5 to 9
-    and then retract the selection end from 9 to 7, leaving the text from position 5 to 7
-    selected (the 6th and 7th characters).
-
-    The same sequence with TextEdit.SelectWords will extend the selection start to a word boundary
-    before or on position 5 and extend the selection end to a word boundary on or past position 9.
-*/
-void QSGTextEdit::moveCursorSelection(int pos)
-{
-    //Note that this is the same as setCursorPosition but with the KeepAnchor flag set
-    Q_D(QSGTextEdit);
-    QTextCursor cursor = d->control->textCursor();
-    if (cursor.position() == pos)
-        return;
-    cursor.setPosition(pos, QTextCursor::KeepAnchor);
-    d->control->setTextCursor(cursor);
-}
-
-void QSGTextEdit::moveCursorSelection(int pos, SelectionMode mode)
-{
-    Q_D(QSGTextEdit);
-    QTextCursor cursor = d->control->textCursor();
-    if (cursor.position() == pos)
-        return;
-    if (mode == SelectCharacters) {
-        cursor.setPosition(pos, QTextCursor::KeepAnchor);
-    } else if (cursor.anchor() < pos || (cursor.anchor() == pos && cursor.position() < pos)) {
-        if (cursor.anchor() > cursor.position()) {
-            cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
-            cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
-            if (cursor.position() == cursor.anchor())
-                cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::MoveAnchor);
-            else
-                cursor.setPosition(cursor.position(), QTextCursor::MoveAnchor);
-        } else {
-            cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
-            cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
-        }
-
-        cursor.setPosition(pos, QTextCursor::KeepAnchor);
-        cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
-        if (cursor.position() != pos)
-            cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
-    } else if (cursor.anchor() > pos || (cursor.anchor() == pos && cursor.position() > pos)) {
-        if (cursor.anchor() < cursor.position()) {
-            cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
-            cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::MoveAnchor);
-        } else {
-            cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
-            cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor);
-            cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
-            if (cursor.position() != cursor.anchor()) {
-                cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
-                cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::MoveAnchor);
-            }
-        }
-
-        cursor.setPosition(pos, QTextCursor::KeepAnchor);
-        cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
-        if (cursor.position() != pos) {
-            cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor);
-            cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
-        }
-    }
-    d->control->setTextCursor(cursor);
-}
-
-/*!
-    \qmlproperty bool QtQuick2::TextEdit::cursorVisible
-    If true the text edit shows a cursor.
-
-    This property is set and unset when the text edit gets active focus, but it can also
-    be set directly (useful, for example, if a KeyProxy might forward keys to it).
-*/
-bool QSGTextEdit::isCursorVisible() const
-{
-    Q_D(const QSGTextEdit);
-    return d->cursorVisible;
-}
-
-void QSGTextEdit::setCursorVisible(bool on)
-{
-    Q_D(QSGTextEdit);
-    if (d->cursorVisible == on)
-        return;
-    d->cursorVisible = on;
-    QFocusEvent focusEvent(on ? QEvent::FocusIn : QEvent::FocusOut);
-    if (!on && !d->persistentSelection)
-        d->control->setCursorIsFocusIndicator(true);
-    d->control->processEvent(&focusEvent, QPointF(0, -d->yoff));
-    emit cursorVisibleChanged(d->cursorVisible);
-}
-
-/*!
-    \qmlproperty int QtQuick2::TextEdit::cursorPosition
-    The position of the cursor in the TextEdit.
-*/
-int QSGTextEdit::cursorPosition() const
-{
-    Q_D(const QSGTextEdit);
-    return d->control->textCursor().position();
-}
-
-void QSGTextEdit::setCursorPosition(int pos)
-{
-    Q_D(QSGTextEdit);
-    if (pos < 0 || pos > d->text.length())
-        return;
-    QTextCursor cursor = d->control->textCursor();
-    if (cursor.position() == pos && cursor.anchor() == pos)
-        return;
-    cursor.setPosition(pos);
-    d->control->setTextCursor(cursor);
-}
-
-/*!
-    \qmlproperty Component QtQuick2::TextEdit::cursorDelegate
-    The delegate for the cursor in the TextEdit.
-
-    If you set a cursorDelegate for a TextEdit, this delegate will be used for
-    drawing the cursor instead of the standard cursor. An instance of the
-    delegate will be created and managed by the text edit when a cursor is
-    needed, and the x and y properties of delegate instance will be set so as
-    to be one pixel before the top left of the current character.
-
-    Note that the root item of the delegate component must be a QDeclarativeItem or
-    QDeclarativeItem derived item.
-*/
-QDeclarativeComponent* QSGTextEdit::cursorDelegate() const
-{
-    Q_D(const QSGTextEdit);
-    return d->cursorComponent;
-}
-
-void QSGTextEdit::setCursorDelegate(QDeclarativeComponent* c)
-{
-    Q_D(QSGTextEdit);
-    if (d->cursorComponent) {
-        if (d->cursor) {
-            d->control->setCursorWidth(-1);
-            updateCursor();
-            delete d->cursor;
-            d->cursor = 0;
-        }
-    }
-    d->cursorComponent = c;
-    if (c && c->isReady()) {
-        loadCursorDelegate();
-    } else {
-        if (c)
-            connect(c, SIGNAL(statusChanged()),
-                    this, SLOT(loadCursorDelegate()));
-    }
-
-    emit cursorDelegateChanged();
-}
-
-void QSGTextEdit::loadCursorDelegate()
-{
-    Q_D(QSGTextEdit);
-    if (d->cursorComponent->isLoading())
-        return;
-    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);
-        d->cursor->setParentItem(this);
-        d->cursor->setHeight(QFontMetrics(d->font).height());
-        moveCursorDelegate();
-    }else{
-        delete object;
-        qmlInfo(this) << "Error loading cursor delegate.";
-    }
-}
-
-/*!
-    \qmlproperty int QtQuick2::TextEdit::selectionStart
-
-    The cursor position before the first character in the current selection.
-
-    This property is read-only. To change the selection, use select(start,end),
-    selectAll(), or selectWord().
-
-    \sa selectionEnd, cursorPosition, selectedText
-*/
-int QSGTextEdit::selectionStart() const
-{
-    Q_D(const QSGTextEdit);
-    return d->control->textCursor().selectionStart();
-}
-
-/*!
-    \qmlproperty int QtQuick2::TextEdit::selectionEnd
-
-    The cursor position after the last character in the current selection.
-
-    This property is read-only. To change the selection, use select(start,end),
-    selectAll(), or selectWord().
-
-    \sa selectionStart, cursorPosition, selectedText
-*/
-int QSGTextEdit::selectionEnd() const
-{
-    Q_D(const QSGTextEdit);
-    return d->control->textCursor().selectionEnd();
-}
-
-/*!
-    \qmlproperty string QtQuick2::TextEdit::selectedText
-
-    This read-only property provides the text currently selected in the
-    text edit.
-
-    It is equivalent to the following snippet, but is faster and easier
-    to use.
-    \code
-    //myTextEdit is the id of the TextEdit
-    myTextEdit.text.toString().substring(myTextEdit.selectionStart,
-            myTextEdit.selectionEnd);
-    \endcode
-*/
-QString QSGTextEdit::selectedText() const
-{
-    Q_D(const QSGTextEdit);
-    return d->control->textCursor().selectedText();
-}
-
-/*!
-    \qmlproperty bool QtQuick2::TextEdit::activeFocusOnPress
-
-    Whether the TextEdit should gain active focus on a mouse press. By default this is
-    set to true.
-*/
-bool QSGTextEdit::focusOnPress() const
-{
-    Q_D(const QSGTextEdit);
-    return d->focusOnPress;
-}
-
-void QSGTextEdit::setFocusOnPress(bool on)
-{
-    Q_D(QSGTextEdit);
-    if (d->focusOnPress == on)
-        return;
-    d->focusOnPress = on;
-    emit activeFocusOnPressChanged(d->focusOnPress);
-}
-
-/*!
-    \qmlproperty bool QtQuick2::TextEdit::persistentSelection
-
-    Whether the TextEdit should keep the selection visible when it loses active focus to another
-    item in the scene. By default this is set to true;
-*/
-bool QSGTextEdit::persistentSelection() const
-{
-    Q_D(const QSGTextEdit);
-    return d->persistentSelection;
-}
-
-void QSGTextEdit::setPersistentSelection(bool on)
-{
-    Q_D(QSGTextEdit);
-    if (d->persistentSelection == on)
-        return;
-    d->persistentSelection = on;
-    emit persistentSelectionChanged(d->persistentSelection);
-}
-
-/*
-   \qmlproperty real QtQuick2::TextEdit::textMargin
-
-   The margin, in pixels, around the text in the TextEdit.
-*/
-qreal QSGTextEdit::textMargin() const
-{
-    Q_D(const QSGTextEdit);
-    return d->textMargin;
-}
-
-void QSGTextEdit::setTextMargin(qreal margin)
-{
-    Q_D(QSGTextEdit);
-    if (d->textMargin == margin)
-        return;
-    d->textMargin = margin;
-    d->document->setDocumentMargin(d->textMargin);
-    emit textMarginChanged(d->textMargin);
-}
-
-void QSGTextEdit::geometryChanged(const QRectF &newGeometry,
-                                  const QRectF &oldGeometry)
-{
-    if (newGeometry.width() != oldGeometry.width())
-        updateSize();
-    QSGImplicitSizeItem::geometryChanged(newGeometry, oldGeometry);
-}
-
-/*!
-    Ensures any delayed caching or data loading the class
-    needs to performed is complete.
-*/
-void QSGTextEdit::componentComplete()
-{
-    Q_D(QSGTextEdit);
-    QSGImplicitSizeItem::componentComplete();
-
-    if (d->richText)
-        d->useImageFallback = qmlEnableImageCache();
-
-    if (d->dirty) {
-        d->determineHorizontalAlignment();
-        d->updateDefaultTextOption();
-        updateSize();
-        d->dirty = false;
-    }
-
-}
-/*!
-    \qmlproperty bool QtQuick2::TextEdit::selectByMouse
-
-    Defaults to false.
-
-    If true, the user can use the mouse to select text in some
-    platform-specific way. Note that for some platforms this may
-    not be an appropriate interaction (eg. may conflict with how
-    the text needs to behave inside a Flickable.
-*/
-bool QSGTextEdit::selectByMouse() const
-{
-    Q_D(const QSGTextEdit);
-    return d->selectByMouse;
-}
-
-void QSGTextEdit::setSelectByMouse(bool on)
-{
-    Q_D(QSGTextEdit);
-    if (d->selectByMouse != on) {
-        d->selectByMouse = on;
-        setKeepMouseGrab(on);
-        if (on)
-            setTextInteractionFlags(d->control->textInteractionFlags() | Qt::TextSelectableByMouse);
-        else
-            setTextInteractionFlags(d->control->textInteractionFlags() & ~Qt::TextSelectableByMouse);
-        emit selectByMouseChanged(on);
-    }
-}
-
-/*!
-    \qmlproperty enum QtQuick2::TextEdit::mouseSelectionMode
-
-    Specifies how text should be selected using a mouse.
-
-    \list
-    \o TextEdit.SelectCharacters - The selection is updated with individual characters. (Default)
-    \o TextEdit.SelectWords - The selection is updated with whole words.
-    \endlist
-
-    This property only applies when \l selectByMouse is true.
-*/
-QSGTextEdit::SelectionMode QSGTextEdit::mouseSelectionMode() const
-{
-    Q_D(const QSGTextEdit);
-    return d->mouseSelectionMode;
-}
-
-void QSGTextEdit::setMouseSelectionMode(SelectionMode mode)
-{
-    Q_D(QSGTextEdit);
-    if (d->mouseSelectionMode != mode) {
-        d->mouseSelectionMode = mode;
-        d->control->setWordSelectionEnabled(mode == SelectWords);
-        emit mouseSelectionModeChanged(mode);
-    }
-}
-
-/*!
-    \qmlproperty bool QtQuick2::TextEdit::readOnly
-
-    Whether the user can interact with the TextEdit item. If this
-    property is set to true the text cannot be edited by user interaction.
-
-    By default this property is false.
-*/
-void QSGTextEdit::setReadOnly(bool r)
-{
-    Q_D(QSGTextEdit);
-    if (r == isReadOnly())
-        return;
-
-    setFlag(QSGItem::ItemAcceptsInputMethod, !r);
-    Qt::TextInteractionFlags flags = Qt::LinksAccessibleByMouse;
-    if (d->selectByMouse)
-        flags = flags | Qt::TextSelectableByMouse;
-    if (!r)
-        flags = flags | Qt::TextSelectableByKeyboard | Qt::TextEditable;
-    d->control->setTextInteractionFlags(flags);
-    if (!r)
-        d->control->moveCursor(QTextCursor::End);
-
-    emit readOnlyChanged(r);
-}
-
-bool QSGTextEdit::isReadOnly() const
-{
-    Q_D(const QSGTextEdit);
-    return !(d->control->textInteractionFlags() & Qt::TextEditable);
-}
-
-/*!
-    Sets how the text edit should interact with user input to the given
-    \a flags.
-*/
-void QSGTextEdit::setTextInteractionFlags(Qt::TextInteractionFlags flags)
-{
-    Q_D(QSGTextEdit);
-    d->control->setTextInteractionFlags(flags);
-}
-
-/*!
-    Returns the flags specifying how the text edit should interact
-    with user input.
-*/
-Qt::TextInteractionFlags QSGTextEdit::textInteractionFlags() const
-{
-    Q_D(const QSGTextEdit);
-    return d->control->textInteractionFlags();
-}
-
-/*!
-    \qmlproperty rectangle QtQuick2::TextEdit::cursorRectangle
-
-    The rectangle where the text cursor is rendered
-    within the text edit. Read-only.
-*/
-QRect QSGTextEdit::cursorRectangle() const
-{
-    Q_D(const QSGTextEdit);
-    return d->control->cursorRect().toRect().translated(0,d->yoff);
-}
-
-bool QSGTextEdit::event(QEvent *event)
-{
-    Q_D(QSGTextEdit);
-    if (event->type() == QEvent::ShortcutOverride) {
-        d->control->processEvent(event, QPointF(0, -d->yoff));
-        return event->isAccepted();
-    }
-    return QSGImplicitSizeItem::event(event);
-}
-
-/*!
-\overload
-Handles the given key \a event.
-*/
-void QSGTextEdit::keyPressEvent(QKeyEvent *event)
-{
-    Q_D(QSGTextEdit);
-    d->control->processEvent(event, QPointF(0, -d->yoff));
-    if (!event->isAccepted())
-        QSGImplicitSizeItem::keyPressEvent(event);
-}
-
-/*!
-\overload
-Handles the given key \a event.
-*/
-void QSGTextEdit::keyReleaseEvent(QKeyEvent *event)
-{
-    Q_D(QSGTextEdit);
-    d->control->processEvent(event, QPointF(0, -d->yoff));
-    if (!event->isAccepted())
-        QSGImplicitSizeItem::keyReleaseEvent(event);
-}
-
-/*!
-    \qmlmethod void QtQuick2::TextEdit::deselect()
-
-    Removes active text selection.
-*/
-void QSGTextEdit::deselect()
-{
-    Q_D(QSGTextEdit);
-    QTextCursor c = d->control->textCursor();
-    c.clearSelection();
-    d->control->setTextCursor(c);
-}
-
-/*!
-    \qmlmethod void QtQuick2::TextEdit::selectAll()
-
-    Causes all text to be selected.
-*/
-void QSGTextEdit::selectAll()
-{
-    Q_D(QSGTextEdit);
-    d->control->selectAll();
-}
-
-/*!
-    \qmlmethod void QtQuick2::TextEdit::selectWord()
-
-    Causes the word closest to the current cursor position to be selected.
-*/
-void QSGTextEdit::selectWord()
-{
-    Q_D(QSGTextEdit);
-    QTextCursor c = d->control->textCursor();
-    c.select(QTextCursor::WordUnderCursor);
-    d->control->setTextCursor(c);
-}
-
-/*!
-    \qmlmethod void QtQuick2::TextEdit::select(int start, int end)
-
-    Causes the text from \a start to \a end to be selected.
-
-    If either start or end is out of range, the selection is not changed.
-
-    After calling this, selectionStart will become the lesser
-    and selectionEnd will become the greater (regardless of the order passed
-    to this method).
-
-    \sa selectionStart, selectionEnd
-*/
-void QSGTextEdit::select(int start, int end)
-{
-    Q_D(QSGTextEdit);
-    if (start < 0 || end < 0 || start > d->text.length() || end > d->text.length())
-        return;
-    QTextCursor cursor = d->control->textCursor();
-    cursor.beginEditBlock();
-    cursor.setPosition(start, QTextCursor::MoveAnchor);
-    cursor.setPosition(end, QTextCursor::KeepAnchor);
-    cursor.endEditBlock();
-    d->control->setTextCursor(cursor);
-
-    // QTBUG-11100
-    updateSelectionMarkers();
-}
-
-/*!
-    \qmlmethod void QtQuick2::TextEdit::isRightToLeft(int start, int end)
-
-    Returns true if the natural reading direction of the editor text
-    found between positions \a start and \a end is right to left.
-*/
-bool QSGTextEdit::isRightToLeft(int start, int end)
-{
-    Q_D(QSGTextEdit);
-    if (start > end) {
-        qmlInfo(this) << "isRightToLeft(start, end) called with the end property being smaller than the start.";
-        return false;
-    } else {
-        return d->text.mid(start, end - start).isRightToLeft();
-    }
-}
-
-#ifndef QT_NO_CLIPBOARD
-/*!
-    \qmlmethod QtQuick2::TextEdit::cut()
-
-    Moves the currently selected text to the system clipboard.
-*/
-void QSGTextEdit::cut()
-{
-    Q_D(QSGTextEdit);
-    d->control->cut();
-}
-
-/*!
-    \qmlmethod QtQuick2::TextEdit::copy()
-
-    Copies the currently selected text to the system clipboard.
-*/
-void QSGTextEdit::copy()
-{
-    Q_D(QSGTextEdit);
-    d->control->copy();
-}
-
-/*!
-    \qmlmethod QtQuick2::TextEdit::paste()
-
-    Replaces the currently selected text by the contents of the system clipboard.
-*/
-void QSGTextEdit::paste()
-{
-    Q_D(QSGTextEdit);
-    d->control->paste();
-}
-#endif // QT_NO_CLIPBOARD
-
-/*!
-\overload
-Handles the given mouse \a event.
-*/
-void QSGTextEdit::mousePressEvent(QMouseEvent *event)
-{
-    Q_D(QSGTextEdit);
-    if (d->focusOnPress){
-        bool hadActiveFocus = hasActiveFocus();
-        forceActiveFocus();
-        // 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())
-        QSGImplicitSizeItem::mousePressEvent(event);
-}
-
-/*!
-\overload
-Handles the given mouse \a event.
-*/
-void QSGTextEdit::mouseReleaseEvent(QMouseEvent *event)
-{
-    Q_D(QSGTextEdit);
-    d->control->processEvent(event, QPointF(0, -d->yoff));
-
-    if (!event->isAccepted())
-        QSGImplicitSizeItem::mouseReleaseEvent(event);
-}
-
-/*!
-\overload
-Handles the given mouse \a event.
-*/
-void QSGTextEdit::mouseDoubleClickEvent(QMouseEvent *event)
-{
-    Q_D(QSGTextEdit);
-    d->control->processEvent(event, QPointF(0, -d->yoff));
-    if (!event->isAccepted())
-        QSGImplicitSizeItem::mouseDoubleClickEvent(event);
-}
-
-/*!
-\overload
-Handles the given mouse \a event.
-*/
-void QSGTextEdit::mouseMoveEvent(QMouseEvent *event)
-{
-    Q_D(QSGTextEdit);
-    d->control->processEvent(event, QPointF(0, -d->yoff));
-    if (!event->isAccepted())
-        QSGImplicitSizeItem::mouseMoveEvent(event);
-}
-
-/*!
-\overload
-Handles the given input method \a event.
-*/
-void QSGTextEdit::inputMethodEvent(QInputMethodEvent *event)
-{
-    Q_D(QSGTextEdit);
-    const bool wasComposing = isInputMethodComposing();
-    d->control->processEvent(event, QPointF(0, -d->yoff));
-    if (wasComposing != isInputMethodComposing())
-        emit inputMethodComposingChanged();
-}
-
-void QSGTextEdit::itemChange(ItemChange change, const ItemChangeData &value)
-{
-    Q_D(QSGTextEdit);
-    if (change == ItemActiveFocusHasChanged) {
-        setCursorVisible(value.boolValue); // ### refactor: focus handling && d->canvas && d->canvas->hasFocus());
-    }
-    QSGItem::itemChange(change, value);
-}
-
-/*!
-\overload
-Returns the value of the given \a property.
-*/
-QVariant QSGTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const
-{
-    Q_D(const QSGTextEdit);
-
-    QVariant v;
-    switch (property) {
-    case Qt::ImEnabled:
-        v = (bool)(flags() & ItemAcceptsInputMethod);
-        break;
-    case Qt::ImHints:
-        v = (int)inputMethodHints();
-        break;
-    default:
-        v = d->control->inputMethodQuery(property);
-        break;
-    }
-    return v;
-
-}
-
-void QSGTextEdit::updateImageCache(const QRectF &)
-{
-    Q_D(QSGTextEdit);
-
-    // Do we really need the image cache?
-    if (!d->richText || !d->useImageFallback) {
-        if (!d->pixmapCache.isNull())
-            d->pixmapCache = QPixmap();
-        return;
-    }
-
-    if (width() != d->pixmapCache.width() || height() != d->pixmapCache.height())
-        d->pixmapCache = QPixmap(width(), height());
-
-    if (d->pixmapCache.isNull())
-        return;
-
-    // ### Use supplied rect, clear area and update only this part (for cursor updates)
-    QRectF bounds = QRectF(0, 0, width(), height());
-    d->pixmapCache.fill(Qt::transparent);
-    {
-        QPainter painter(&d->pixmapCache);
-
-        painter.setRenderHint(QPainter::TextAntialiasing);
-        painter.translate(0, d->yoff);
-
-        d->control->drawContents(&painter, bounds);
-    }
-
-}
-
-QSGNode *QSGTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData)
-{
-    Q_UNUSED(updatePaintNodeData);
-    Q_D(QSGTextEdit);
-
-    QSGNode *currentNode = oldNode;
-    if (d->richText && d->useImageFallback) {
-        QSGImageNode *node = 0;
-        if (oldNode == 0 || d->nodeType != QSGTextEditPrivate::NodeIsTexture) {
-            delete oldNode;
-            node = QSGItemPrivate::get(this)->sceneGraphContext()->createImageNode();
-            d->texture = new QSGPlainTexture();
-            d->nodeType = QSGTextEditPrivate::NodeIsTexture;
-            currentNode = node;
-        } else {
-            node = static_cast<QSGImageNode *>(oldNode);
-        }
-
-        qobject_cast<QSGPlainTexture *>(d->texture)->setImage(d->pixmapCache.toImage());
-        node->setTexture(0);
-        node->setTexture(d->texture);
-
-        node->setTargetRect(QRectF(0, 0, d->pixmapCache.width(), d->pixmapCache.height()));
-        node->setSourceRect(QRectF(0, 0, 1, 1));
-        node->setHorizontalWrapMode(QSGTexture::ClampToEdge);
-        node->setVerticalWrapMode(QSGTexture::ClampToEdge);
-        node->setFiltering(QSGTexture::Linear); // Nonsmooth text just ugly, so don't do that..
-        node->update();
-
-    } else if (oldNode == 0 || d->documentDirty) {
-        d->documentDirty = false;
-
-#if defined(Q_WS_MAC)
-        // Make sure document is relayouted in the paint node on Mac
-        // to avoid crashes due to the font engines created in the
-        // shaping process
-        d->document->markContentsDirty(0, d->document->characterCount());
-#endif
-
-        QSGTextNode *node = 0;
-        if (oldNode == 0 || d->nodeType != QSGTextEditPrivate::NodeIsText) {
-            delete oldNode;
-            node = new QSGTextNode(QSGItemPrivate::get(this)->sceneGraphContext());
-            d->nodeType = QSGTextEditPrivate::NodeIsText;
-            currentNode = node;
-        } else {
-            node = static_cast<QSGTextNode *>(oldNode);
-        }
-
-        node->deleteContent();
-        node->setMatrix(QMatrix4x4());
-
-        QRectF bounds = boundingRect();
-
-        QColor selectionColor = d->control->palette().color(QPalette::Highlight);
-        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() returns first char after
-                                                    // selection
-
-#if defined(Q_WS_MAC)
-        // We also need to make sure the document layout is redone when
-        // control is returned to the main thread, as all the font engines
-        // are now owned by the rendering thread
-        d->document->markContentsDirty(0, d->document->characterCount());
-#endif
-    }
-
-    if (d->nodeType == QSGTextEditPrivate::NodeIsText && d->cursorComponent == 0 && !isReadOnly()) {
-        QSGTextNode *node = static_cast<QSGTextNode *>(currentNode);
-
-        QColor color = (!d->cursorVisible || !d->control->cursorOn())
-                ? QColor(0, 0, 0, 0)
-                : d->color;
-
-        if (node->cursorNode() == 0) {
-            node->setCursor(cursorRectangle(), color);
-        } else {
-            node->cursorNode()->setRect(cursorRectangle());
-            node->cursorNode()->setColor(color);
-        }
-
-    }
-
-    return currentNode;
-}
-
-/*!
-    \qmlproperty bool QtQuick2::TextEdit::smooth
-
-    This property holds whether the text is smoothly scaled or transformed.
-
-    Smooth filtering gives better visual quality, but is slower.  If
-    the item is displayed at its natural size, this property has no visual or
-    performance effect.
-
-    \note Generally scaling artifacts are only visible if the item is stationary on
-    the screen.  A common pattern when animating an item is to disable smooth
-    filtering at the beginning of the animation and reenable it at the conclusion.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::TextEdit::canPaste
-
-    Returns true if the TextEdit is writable and the content of the clipboard is
-    suitable for pasting into the TextEdit.
-*/
-bool QSGTextEdit::canPaste() const
-{
-    Q_D(const QSGTextEdit);
-    return d->canPaste;
-}
-
-/*!
-    \qmlproperty bool QtQuick2::TextEdit::inputMethodComposing
-
-
-    This property holds whether the TextEdit has partial text input from an
-    input method.
-
-    While it is composing an input method may rely on mouse or key events from
-    the TextEdit to edit or commit the partial text.  This property can be used
-    to determine when to disable events handlers that may interfere with the
-    correct operation of an input method.
-*/
-bool QSGTextEdit::isInputMethodComposing() const
-{
-    Q_D(const QSGTextEdit);
-    if (QTextLayout *layout = d->control->textCursor().block().layout())
-        return layout->preeditAreaText().length() > 0;
-    return false;
-}
-
-void QSGTextEditPrivate::init()
-{
-    Q_Q(QSGTextEdit);
-
-    q->setSmooth(smooth);
-    q->setAcceptedMouseButtons(Qt::LeftButton);
-    q->setFlag(QSGItem::ItemAcceptsInputMethod);
-    q->setFlag(QSGItem::ItemHasContents);
-
-    control = new QTextControl(q);
-    control->setIgnoreUnusedNavigationEvents(true);
-    control->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard | Qt::TextEditable);
-    control->setDragEnabled(false);
-
-    // By default, QTextControl will issue both a updateCursorRequest() and an updateRequest()
-    // when the cursor needs to be repainted. We need the signals to be separate to be able to
-    // distinguish the cursor updates so that we can avoid updating the whole subtree when the
-    // cursor blinks.
-    if (!QObject::disconnect(control, SIGNAL(updateCursorRequest(QRectF)),
-                             control, SIGNAL(updateRequest(QRectF)))) {
-        qWarning("QSGTextEditPrivate::init: Failed to disconnect updateCursorRequest and updateRequest");
-    }
-
-    // QTextControl follows the default text color
-    // defined by the platform, declarative text
-    // should be black by default
-    QPalette pal = control->palette();
-    if (pal.color(QPalette::Text) != color) {
-        pal.setColor(QPalette::Text, color);
-        control->setPalette(pal);
-    }
-
-    QObject::connect(control, SIGNAL(updateRequest(QRectF)), q, SLOT(updateDocument()));
-    QObject::connect(control, SIGNAL(updateCursorRequest()), q, SLOT(updateCursor()));
-    QObject::connect(control, SIGNAL(textChanged()), q, SLOT(q_textChanged()));
-    QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
-    QObject::connect(control, SIGNAL(selectionChanged()), q, SLOT(updateSelectionMarkers()));
-    QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(updateSelectionMarkers()));
-    QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
-    QObject::connect(control, SIGNAL(microFocusChanged()), q, SLOT(moveCursorDelegate()));
-    QObject::connect(control, SIGNAL(linkActivated(QString)), q, SIGNAL(linkActivated(QString)));
-#ifndef QT_NO_CLIPBOARD
-    QObject::connect(q, SIGNAL(readOnlyChanged(bool)), q, SLOT(q_canPasteChanged()));
-    QObject::connect(QGuiApplication::clipboard(), SIGNAL(dataChanged()), q, SLOT(q_canPasteChanged()));
-    canPaste = control->canPaste();
-#endif
-
-    document = control->document();
-    document->setDefaultFont(font);
-    document->setDocumentMargin(textMargin);
-    document->setUndoRedoEnabled(false); // flush undo buffer.
-    document->setUndoRedoEnabled(true);
-    updateDefaultTextOption();
-}
-
-void QSGTextEdit::q_textChanged()
-{
-    Q_D(QSGTextEdit);
-    d->text = text();
-    d->rightToLeftText = d->document->begin().layout()->engine()->isRightToLeft();
-    d->determineHorizontalAlignment();
-    d->updateDefaultTextOption();
-    updateSize();
-    updateTotalLines();
-    emit textChanged(d->text);
-}
-
-void QSGTextEdit::moveCursorDelegate()
-{
-    Q_D(QSGTextEdit);
-    d->determineHorizontalAlignment();
-    updateMicroFocus();
-    emit cursorRectangleChanged();
-    if (!d->cursor)
-        return;
-    QRectF cursorRect = cursorRectangle();
-    d->cursor->setX(cursorRect.x());
-    d->cursor->setY(cursorRect.y());
-}
-
-void QSGTextEditPrivate::updateSelection()
-{
-    Q_Q(QSGTextEdit);
-    QTextCursor cursor = control->textCursor();
-    bool startChange = (lastSelectionStart != cursor.selectionStart());
-    bool endChange = (lastSelectionEnd != cursor.selectionEnd());
-    cursor.beginEditBlock();
-    cursor.setPosition(lastSelectionStart, QTextCursor::MoveAnchor);
-    cursor.setPosition(lastSelectionEnd, QTextCursor::KeepAnchor);
-    cursor.endEditBlock();
-    control->setTextCursor(cursor);
-    if (startChange)
-        q->selectionStartChanged();
-    if (endChange)
-        q->selectionEndChanged();
-}
-
-void QSGTextEdit::updateSelectionMarkers()
-{
-    Q_D(QSGTextEdit);
-    if (d->lastSelectionStart != d->control->textCursor().selectionStart()) {
-        d->lastSelectionStart = d->control->textCursor().selectionStart();
-        emit selectionStartChanged();
-    }
-    if (d->lastSelectionEnd != d->control->textCursor().selectionEnd()) {
-        d->lastSelectionEnd = d->control->textCursor().selectionEnd();
-        emit selectionEndChanged();
-    }
-}
-
-QRectF QSGTextEdit::boundingRect() const
-{
-    Q_D(const QSGTextEdit);
-    QRectF r = QSGImplicitSizeItem::boundingRect();
-    int cursorWidth = 1;
-    if (d->cursor)
-        cursorWidth = d->cursor->width();
-    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.
-
-    r.setRight(r.right() + cursorWidth);
-    return r.translated(0,d->yoff);
-}
-
-qreal QSGTextEditPrivate::getImplicitWidth() const
-{
-    Q_Q(const QSGTextEdit);
-    if (!requireImplicitWidth) {
-        // We don't calculate implicitWidth unless it is required.
-        // We need to force a size update now to ensure implicitWidth is calculated
-        const_cast<QSGTextEditPrivate*>(this)->requireImplicitWidth = true;
-        const_cast<QSGTextEdit*>(q)->updateSize();
-    }
-    return implicitWidth;
-}
-
-//### we should perhaps be a bit smarter here -- depending on what has changed, we shouldn't
-//    need to do all the calculations each time
-void QSGTextEdit::updateSize()
-{
-    Q_D(QSGTextEdit);
-    if (isComponentComplete()) {
-        qreal naturalWidth = d->implicitWidth;
-        // ### assumes that if the width is set, the text will fill to edges
-        // ### (unless wrap is false, then clipping will occur)
-        if (widthValid()) {
-            if (!d->requireImplicitWidth) {
-                emit implicitWidthChanged();
-                // if the implicitWidth is used, then updateSize() has already been called (recursively)
-                if (d->requireImplicitWidth)
-                    return;
-            }
-            if (d->requireImplicitWidth) {
-                d->document->setTextWidth(-1);
-                naturalWidth = d->document->idealWidth();
-            }
-            if (d->document->textWidth() != width())
-                d->document->setTextWidth(width());
-        } else {
-            d->document->setTextWidth(-1);
-        }
-        QFontMetrics fm = QFontMetrics(d->font);
-        int dy = height();
-        dy -= (int)d->document->size().height();
-
-        int nyoff;
-        if (heightValid()) {
-            if (d->vAlign == AlignBottom)
-                nyoff = dy;
-            else if (d->vAlign == AlignVCenter)
-                nyoff = dy/2;
-            else
-                nyoff = 0;
-        } else {
-            nyoff = 0;
-        }
-        if (nyoff != d->yoff)
-            d->yoff = nyoff;
-        setBaselineOffset(fm.ascent() + d->yoff + d->textMargin);
-
-        //### need to comfirm cost of always setting these
-        int newWidth = qCeil(d->document->idealWidth());
-        if (!widthValid() && d->document->textWidth() != newWidth)
-            d->document->setTextWidth(newWidth); // ### Text does not align if width is not set (QTextDoc bug)
-        // ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed.
-        if (!widthValid())
-            setImplicitWidth(newWidth);
-        else if (d->requireImplicitWidth)
-            setImplicitWidth(naturalWidth);
-        qreal newHeight = d->document->isEmpty() ? fm.height() : (int)d->document->size().height();
-        setImplicitHeight(newHeight);
-
-        d->paintedSize = QSize(newWidth, newHeight);
-        emit paintedSizeChanged();
-    } else {
-        d->dirty = true;
-    }
-    updateDocument();
-}
-
-void QSGTextEdit::updateDocument()
-{
-    Q_D(QSGTextEdit);
-    d->documentDirty = true;
-
-    if (isComponentComplete()) {
-        updateImageCache();
-        update();
-    }
-}
-
-void QSGTextEdit::updateCursor()
-{
-    Q_D(QSGTextEdit);
-    if (isComponentComplete()) {
-        updateImageCache(d->control->cursorRect());
-        update();
-    }
-}
-
-void QSGTextEdit::updateTotalLines()
-{
-    Q_D(QSGTextEdit);
-
-    int subLines = 0;
-
-    for (QTextBlock it = d->document->begin(); it != d->document->end(); it = it.next()) {
-        QTextLayout *layout = it.layout();
-        if (!layout)
-            continue;
-        subLines += layout->lineCount()-1;
-    }
-
-    int newTotalLines = d->document->lineCount() + subLines;
-    if (d->lineCount != newTotalLines) {
-        d->lineCount = newTotalLines;
-        emit lineCountChanged();
-    }
-}
-
-void QSGTextEditPrivate::updateDefaultTextOption()
-{
-    Q_Q(QSGTextEdit);
-    QTextOption opt = document->defaultTextOption();
-    int oldAlignment = opt.alignment();
-
-    QSGTextEdit::HAlignment horizontalAlignment = q->effectiveHAlign();
-    if (rightToLeftText) {
-        if (horizontalAlignment == QSGTextEdit::AlignLeft)
-            horizontalAlignment = QSGTextEdit::AlignRight;
-        else if (horizontalAlignment == QSGTextEdit::AlignRight)
-            horizontalAlignment = QSGTextEdit::AlignLeft;
-    }
-    opt.setAlignment((Qt::Alignment)(int)(horizontalAlignment | vAlign));
-
-    QTextOption::WrapMode oldWrapMode = opt.wrapMode();
-    opt.setWrapMode(QTextOption::WrapMode(wrapMode));
-
-    bool oldUseDesignMetrics = opt.useDesignMetrics();
-    bool useDesignMetrics = !qmlDisableDistanceField();
-    opt.setUseDesignMetrics(useDesignMetrics);
-
-    if (oldWrapMode == opt.wrapMode()
-            && oldAlignment == opt.alignment()
-            && oldUseDesignMetrics == useDesignMetrics) {
-        return;
-    }
-    document->setDefaultTextOption(opt);
-}
-
-
-
-/*!
-    \qmlmethod void QtQuick2::TextEdit::openSoftwareInputPanel()
-
-    Opens software input panels like virtual keyboards for typing, useful for
-    customizing when you want the input keyboard to be shown and hidden in
-    your application.
-
-    By default the opening of input panels follows the platform style. On Symbian^1 and
-    Symbian^3 -based devices the panels are opened by clicking TextEdit. On other platforms
-    the panels are automatically opened when TextEdit element gains active focus. Input panels are
-    always closed if no editor has active focus.
-
-    You can disable the automatic behavior by setting the property \c activeFocusOnPress to false
-    and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement
-    the behavior you want.
-
-    Only relevant on platforms, which provide virtual keyboards.
-
-    \code
-        import QtQuick 1.0
-        TextEdit {
-            id: textEdit
-            text: "Hello world!"
-            activeFocusOnPress: false
-            MouseArea {
-                anchors.fill: parent
-                onClicked: {
-                    if (!textEdit.activeFocus) {
-                        textEdit.forceActiveFocus();
-                        textEdit.openSoftwareInputPanel();
-                    } else {
-                        textEdit.focus = false;
-                    }
-                }
-                onPressAndHold: textEdit.closeSoftwareInputPanel();
-            }
-        }
-    \endcode
-*/
-void QSGTextEdit::openSoftwareInputPanel()
-{
-    if (qGuiApp)
-        qGuiApp->inputPanel()->show();
-}
-
-/*!
-    \qmlmethod void QtQuick2::TextEdit::closeSoftwareInputPanel()
-
-    Closes a software input panel like a virtual keyboard shown on the screen, useful
-    for customizing when you want the input keyboard to be shown and hidden in
-    your application.
-
-    By default the opening of input panels follows the platform style. On Symbian^1 and
-    Symbian^3 -based devices the panels are opened by clicking TextEdit. On other platforms
-    the panels are automatically opened when TextEdit element gains active focus. Input panels are
-    always closed if no editor has active focus.
-
-    You can disable the automatic behavior by setting the property \c activeFocusOnPress to false
-    and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement
-    the behavior you want.
-
-    Only relevant on platforms, which provide virtual keyboards.
-
-    \code
-        import QtQuick 1.0
-        TextEdit {
-            id: textEdit
-            text: "Hello world!"
-            activeFocusOnPress: false
-            MouseArea {
-                anchors.fill: parent
-                onClicked: {
-                    if (!textEdit.activeFocus) {
-                        textEdit.forceActiveFocus();
-                        textEdit.openSoftwareInputPanel();
-                    } else {
-                        textEdit.focus = false;
-                    }
-                }
-                onPressAndHold: textEdit.closeSoftwareInputPanel();
-            }
-        }
-    \endcode
-*/
-void QSGTextEdit::closeSoftwareInputPanel()
-{
-    if (qGuiApp)
-        qGuiApp->inputPanel()->hide();
-}
-
-void QSGTextEdit::focusInEvent(QFocusEvent *event)
-{
-    Q_D(const QSGTextEdit);
-    if (d->focusOnPress && !isReadOnly())
-        openSoftwareInputPanel();
-    QSGImplicitSizeItem::focusInEvent(event);
-}
-
-void QSGTextEdit::q_canPasteChanged()
-{
-    Q_D(QSGTextEdit);
-    bool old = d->canPaste;
-    d->canPaste = d->control->canPaste();
-    if (old!=d->canPaste)
-        emit canPasteChanged();
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgtextedit_p.h b/src/declarative/items/qsgtextedit_p.h
deleted file mode 100644 (file)
index fced118..0000000
+++ /dev/null
@@ -1,306 +0,0 @@
-// Commit: 27e4302b7f45f22180693d26747f419177c81e27
-/****************************************************************************
-**
-** 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 QSGTEXTEDIT_P_H
-#define QSGTEXTEDIT_P_H
-
-#include "qsgimplicitsizeitem_p.h"
-
-#include <QtGui/qtextoption.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGTextEditPrivate;
-class Q_AUTOTEST_EXPORT QSGTextEdit : public QSGImplicitSizeItem
-{
-    Q_OBJECT
-    Q_ENUMS(VAlignment)
-    Q_ENUMS(HAlignment)
-    Q_ENUMS(TextFormat)
-    Q_ENUMS(WrapMode)
-    Q_ENUMS(SelectionMode)
-
-    Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
-    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
-    Q_PROPERTY(QColor selectionColor READ selectionColor WRITE setSelectionColor NOTIFY selectionColorChanged)
-    Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor NOTIFY selectedTextColorChanged)
-    Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
-    Q_PROPERTY(HAlignment horizontalAlignment READ hAlign WRITE setHAlign RESET resetHAlign NOTIFY horizontalAlignmentChanged)
-    Q_PROPERTY(HAlignment effectiveHorizontalAlignment READ effectiveHAlign NOTIFY effectiveHorizontalAlignmentChanged)
-    Q_PROPERTY(VAlignment verticalAlignment READ vAlign WRITE setVAlign NOTIFY verticalAlignmentChanged)
-    Q_PROPERTY(WrapMode wrapMode READ wrapMode WRITE setWrapMode NOTIFY wrapModeChanged)
-    Q_PROPERTY(int lineCount READ lineCount NOTIFY lineCountChanged)
-    Q_PROPERTY(qreal paintedWidth READ paintedWidth NOTIFY paintedSizeChanged)
-    Q_PROPERTY(qreal paintedHeight READ paintedHeight NOTIFY paintedSizeChanged)
-    Q_PROPERTY(TextFormat textFormat READ textFormat WRITE setTextFormat NOTIFY textFormatChanged)
-    Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged)
-    Q_PROPERTY(bool cursorVisible READ isCursorVisible WRITE setCursorVisible NOTIFY cursorVisibleChanged)
-    Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged)
-    Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged)
-    Q_PROPERTY(QDeclarativeComponent* cursorDelegate READ cursorDelegate WRITE setCursorDelegate NOTIFY cursorDelegateChanged)
-    Q_PROPERTY(int selectionStart READ selectionStart NOTIFY selectionStartChanged)
-    Q_PROPERTY(int selectionEnd READ selectionEnd NOTIFY selectionEndChanged)
-    Q_PROPERTY(QString selectedText READ selectedText NOTIFY selectionChanged)
-    Q_PROPERTY(bool activeFocusOnPress READ focusOnPress WRITE setFocusOnPress NOTIFY activeFocusOnPressChanged)
-    Q_PROPERTY(bool persistentSelection READ persistentSelection WRITE setPersistentSelection NOTIFY persistentSelectionChanged)
-    Q_PROPERTY(qreal textMargin READ textMargin WRITE setTextMargin NOTIFY textMarginChanged)
-    Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints)
-    Q_PROPERTY(bool selectByMouse READ selectByMouse WRITE setSelectByMouse NOTIFY selectByMouseChanged)
-    Q_PROPERTY(SelectionMode mouseSelectionMode READ mouseSelectionMode WRITE setMouseSelectionMode NOTIFY mouseSelectionModeChanged)
-    Q_PROPERTY(bool canPaste READ canPaste NOTIFY canPasteChanged)
-    Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged)
-
-public:
-    QSGTextEdit(QSGItem *parent=0);
-
-    enum HAlignment {
-        AlignLeft = Qt::AlignLeft,
-        AlignRight = Qt::AlignRight,
-        AlignHCenter = Qt::AlignHCenter,
-        AlignJustify = Qt::AlignJustify
-    };
-
-    enum VAlignment {
-        AlignTop = Qt::AlignTop,
-        AlignBottom = Qt::AlignBottom,
-        AlignVCenter = Qt::AlignVCenter
-    };
-
-    enum TextFormat {
-        PlainText = Qt::PlainText,
-        RichText = Qt::RichText,
-        AutoText = Qt::AutoText
-    };
-
-    enum WrapMode { NoWrap = QTextOption::NoWrap,
-                    WordWrap = QTextOption::WordWrap,
-                    WrapAnywhere = QTextOption::WrapAnywhere,
-                    WrapAtWordBoundaryOrAnywhere = QTextOption::WrapAtWordBoundaryOrAnywhere, // COMPAT
-                    Wrap = QTextOption::WrapAtWordBoundaryOrAnywhere
-                  };
-
-    enum SelectionMode {
-        SelectCharacters,
-        SelectWords
-    };
-
-    Q_INVOKABLE void openSoftwareInputPanel();
-    Q_INVOKABLE void closeSoftwareInputPanel();
-
-    QString text() const;
-    void setText(const QString &);
-
-    TextFormat textFormat() const;
-    void setTextFormat(TextFormat format);
-
-    QFont font() const;
-    void setFont(const QFont &font);
-
-    QColor color() const;
-    void setColor(const QColor &c);
-
-    QColor selectionColor() const;
-    void setSelectionColor(const QColor &c);
-
-    QColor selectedTextColor() const;
-    void setSelectedTextColor(const QColor &c);
-
-    HAlignment hAlign() const;
-    void setHAlign(HAlignment align);
-    void resetHAlign();
-    HAlignment effectiveHAlign() const;
-
-    VAlignment vAlign() const;
-    void setVAlign(VAlignment align);
-
-    WrapMode wrapMode() const;
-    void setWrapMode(WrapMode w);
-
-    int lineCount() const;
-
-    bool isCursorVisible() const;
-    void setCursorVisible(bool on);
-
-    int cursorPosition() const;
-    void setCursorPosition(int pos);
-
-    QDeclarativeComponent* cursorDelegate() const;
-    void setCursorDelegate(QDeclarativeComponent*);
-
-    int selectionStart() const;
-    int selectionEnd() const;
-
-    QString selectedText() const;
-
-    bool focusOnPress() const;
-    void setFocusOnPress(bool on);
-
-    bool persistentSelection() const;
-    void setPersistentSelection(bool on);
-
-    qreal textMargin() const;
-    void setTextMargin(qreal margin);
-
-    bool selectByMouse() const;
-    void setSelectByMouse(bool);
-
-    SelectionMode mouseSelectionMode() const;
-    void setMouseSelectionMode(SelectionMode mode);
-
-    bool canPaste() const;
-
-    virtual void componentComplete();
-
-    /* FROM EDIT */
-    void setReadOnly(bool);
-    bool isReadOnly() const;
-
-    void setTextInteractionFlags(Qt::TextInteractionFlags flags);
-    Qt::TextInteractionFlags textInteractionFlags() const;
-
-    QRect cursorRectangle() const;
-
-    QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
-
-    qreal paintedWidth() const;
-    qreal paintedHeight() const;
-
-    Q_INVOKABLE QRectF positionToRectangle(int) const;
-    Q_INVOKABLE int positionAt(int x, int y) const;
-    Q_INVOKABLE void moveCursorSelection(int pos);
-    Q_INVOKABLE void moveCursorSelection(int pos, SelectionMode mode);
-
-    QRectF boundingRect() const;
-
-    bool isInputMethodComposing() const;
-
-Q_SIGNALS:
-    void textChanged(const QString &);
-    void paintedSizeChanged();
-    void cursorPositionChanged();
-    void cursorRectangleChanged();
-    void selectionStartChanged();
-    void selectionEndChanged();
-    void selectionChanged();
-    void colorChanged(const QColor &color);
-    void selectionColorChanged(const QColor &color);
-    void selectedTextColorChanged(const QColor &color);
-    void fontChanged(const QFont &font);
-    void horizontalAlignmentChanged(HAlignment alignment);
-    void verticalAlignmentChanged(VAlignment alignment);
-    void wrapModeChanged();
-    void lineCountChanged();
-    void textFormatChanged(TextFormat textFormat);
-    void readOnlyChanged(bool isReadOnly);
-    void cursorVisibleChanged(bool isCursorVisible);
-    void cursorDelegateChanged();
-    void activeFocusOnPressChanged(bool activeFocusOnPressed);
-    void persistentSelectionChanged(bool isPersistentSelection);
-    void textMarginChanged(qreal textMargin);
-    void selectByMouseChanged(bool selectByMouse);
-    void mouseSelectionModeChanged(SelectionMode mode);
-    void linkActivated(const QString &link);
-    void canPasteChanged();
-    void inputMethodComposingChanged();
-    void effectiveHorizontalAlignmentChanged();
-
-public Q_SLOTS:
-    void selectAll();
-    void selectWord();
-    void select(int start, int end);
-    void deselect();
-    bool isRightToLeft(int start, int end);
-#ifndef QT_NO_CLIPBOARD
-    void cut();
-    void copy();
-    void paste();
-#endif
-
-private Q_SLOTS:
-    void q_textChanged();
-    void updateSelectionMarkers();
-    void moveCursorDelegate();
-    void loadCursorDelegate();
-    void q_canPasteChanged();
-    void updateDocument();
-    void updateCursor();
-
-private:
-    void updateSize();
-    void updateTotalLines();
-    void updateImageCache(const QRectF &rect = QRectF());
-
-protected:
-    virtual void geometryChanged(const QRectF &newGeometry,
-                                 const QRectF &oldGeometry);
-
-    bool event(QEvent *);
-    void keyPressEvent(QKeyEvent *);
-    void keyReleaseEvent(QKeyEvent *);
-    void focusInEvent(QFocusEvent *event);
-
-    // mouse filter?
-    void mousePressEvent(QMouseEvent *event);
-    void mouseReleaseEvent(QMouseEvent *event);
-    void mouseDoubleClickEvent(QMouseEvent *event);
-    void mouseMoveEvent(QMouseEvent *event);
-    void inputMethodEvent(QInputMethodEvent *e);
-    virtual void itemChange(ItemChange, const ItemChangeData &);
-
-    QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData);
-
-private:
-    Q_DISABLE_COPY(QSGTextEdit)
-    Q_DECLARE_PRIVATE(QSGTextEdit)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGTextEdit)
-
-QT_END_HEADER
-
-#endif // QSGTEXTEDIT_P_H
diff --git a/src/declarative/items/qsgtextedit_p_p.h b/src/declarative/items/qsgtextedit_p_p.h
deleted file mode 100644 (file)
index 51904d1..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-// Commit: 27e4302b7f45f22180693d26747f419177c81e27
-/****************************************************************************
-**
-** 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 QSGTEXTEDIT_P_P_H
-#define QSGTEXTEDIT_P_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 "qsgtextedit_p.h"
-#include "qsgimplicitsizeitem_p_p.h"
-
-#include <QtDeclarative/qdeclarative.h>
-#include <QtGui/qpixmap.h>
-
-QT_BEGIN_NAMESPACE
-class QTextLayout;
-class QTextDocument;
-class QTextControl;
-class QSGTextEditPrivate : public QSGImplicitSizeItemPrivate
-{
-    Q_DECLARE_PUBLIC(QSGTextEdit)
-
-public:
-    QSGTextEditPrivate()
-      : color("black"), hAlign(QSGTextEdit::AlignLeft), vAlign(QSGTextEdit::AlignTop),
-      documentDirty(true), dirty(false), richText(false), cursorVisible(false), focusOnPress(true),
-      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)
-    {
-    }
-
-    void init();
-
-    void updateDefaultTextOption();
-    void relayoutDocument();
-    void updateSelection();
-    bool determineHorizontalAlignment();
-    bool setHAlign(QSGTextEdit::HAlignment, bool forceAlign = false);
-    void mirrorChange();
-    qreal getImplicitWidth() const;
-
-    QString text;
-    QFont font;
-    QFont sourceFont;
-    QColor  color;
-    QColor  selectionColor;
-    QColor  selectedTextColor;
-    QString style;
-    QColor  styleColor;
-    QSGTextEdit::HAlignment hAlign;
-    QSGTextEdit::VAlignment vAlign;
-
-    bool documentDirty : 1;
-    bool dirty : 1;
-    bool richText : 1;
-    bool cursorVisible : 1;
-    bool focusOnPress : 1;
-    bool persistentSelection : 1;
-    bool requireImplicitWidth:1;
-    bool selectByMouse:1;
-    bool canPaste:1;
-    bool hAlignImplicit:1;
-    bool rightToLeftText:1;
-    bool useImageFallback:1;
-
-    qreal textMargin;
-    int lastSelectionStart;
-    int lastSelectionEnd;
-    QDeclarativeComponent* cursorComponent;
-    QSGItem* cursor;
-    QSGTextEdit::TextFormat format;
-    QTextDocument *document;
-    QTextControl *control;
-    QSGTextEdit::WrapMode wrapMode;
-    QSGTextEdit::SelectionMode mouseSelectionMode;
-    int lineCount;
-    int yoff;
-    QSize paintedSize;
-
-    enum NodeType {
-        NodeIsNull,
-        NodeIsTexture,
-        NodeIsText
-    };
-    NodeType nodeType;
-    QSGTexture *texture;
-    QPixmap pixmapCache;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGTEXTEDIT_P_P_H
diff --git a/src/declarative/items/qsgtextinput.cpp b/src/declarative/items/qsgtextinput.cpp
deleted file mode 100644 (file)
index 6d0fa47..0000000
+++ /dev/null
@@ -1,2007 +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 "qsgtextinput_p.h"
-#include "qsgtextinput_p_p.h"
-#include "qsgcanvas.h"
-
-#include <private/qdeclarativeglobal_p.h>
-#include <private/qsgdistancefieldglyphcache_p.h>
-
-#include <QtDeclarative/qdeclarativeinfo.h>
-#include <QtGui/qevent.h>
-#include <QTextBoundaryFinder>
-#include "qsgtextnode_p.h"
-#include <qsgsimplerectnode.h>
-
-#include <QtGui/qstylehints.h>
-#include <QtGui/qinputpanel.h>
-
-QT_BEGIN_NAMESPACE
-
-DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
-
-/*!
-    \qmlclass TextInput QSGTextInput
-    \inqmlmodule QtQuick 2
-    \ingroup qml-basic-visual-elements
-    \brief The TextInput item displays an editable line of text.
-    \inherits Item
-
-    The TextInput element displays a single line of editable plain text.
-
-    TextInput is used to accept a line of text input. Input constraints
-    can be placed on a TextInput item (for example, through a \l validator or \l inputMask),
-    and setting \l echoMode to an appropriate value enables TextInput to be used for
-    a password input field.
-
-    On Mac OS X, the Up/Down key bindings for Home/End are explicitly disabled.
-    If you want such bindings (on any platform), you will need to construct them in QML.
-
-    \sa TextEdit, Text, {declarative/text/textselection}{Text Selection example}
-*/
-QSGTextInput::QSGTextInput(QSGItem* parent)
-: QSGImplicitSizeItem(*(new QSGTextInputPrivate), parent)
-{
-    Q_D(QSGTextInput);
-    d->init();
-}
-
-QSGTextInput::~QSGTextInput()
-{
-}
-
-/*!
-    \qmlproperty string QtQuick2::TextInput::text
-
-    The text in the TextInput.
-*/
-QString QSGTextInput::text() const
-{
-    Q_D(const QSGTextInput);
-    return d->control->text();
-}
-
-void QSGTextInput::setText(const QString &s)
-{
-    Q_D(QSGTextInput);
-    if (s == text())
-        return;
-    d->control->setText(s);
-}
-
-/*!
-    \qmlproperty string QtQuick2::TextInput::font.family
-
-    Sets the family name of the font.
-
-    The family name is case insensitive and may optionally include a foundry name, e.g. "Helvetica [Cronyx]".
-    If the family is available from more than one foundry and the foundry isn't specified, an arbitrary foundry is chosen.
-    If the family isn't available a family will be set using the font matching algorithm.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::TextInput::font.bold
-
-    Sets whether the font weight is bold.
-*/
-
-/*!
-    \qmlproperty enumeration QtQuick2::TextInput::font.weight
-
-    Sets the font's weight.
-
-    The weight can be one of:
-    \list
-    \o Font.Light
-    \o Font.Normal - the default
-    \o Font.DemiBold
-    \o Font.Bold
-    \o Font.Black
-    \endlist
-
-    \qml
-    TextInput { text: "Hello"; font.weight: Font.DemiBold }
-    \endqml
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::TextInput::font.italic
-
-    Sets whether the font has an italic style.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::TextInput::font.underline
-
-    Sets whether the text is underlined.
-*/
-
-/*!
-    \qmlproperty bool QtQuick2::TextInput::font.strikeout
-
-    Sets whether the font has a strikeout style.
-*/
-
-/*!
-    \qmlproperty real QtQuick2::TextInput::font.pointSize
-
-    Sets the font size in points. The point size must be greater than zero.
-*/
-
-/*!
-    \qmlproperty int QtQuick2::TextInput::font.pixelSize
-
-    Sets the font size in pixels.
-
-    Using this function makes the font device dependent.
-    Use \c pointSize to set the size of the font in a device independent manner.
-*/
-
-/*!
-    \qmlproperty real QtQuick2::TextInput::font.letterSpacing
-
-    Sets the letter spacing for the font.
-
-    Letter spacing changes the default spacing between individual letters in the font.
-    A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing.
-*/
-
-/*!
-    \qmlproperty real QtQuick2::TextInput::font.wordSpacing
-
-    Sets the word spacing for the font.
-
-    Word spacing changes the default spacing between individual words.
-    A positive value increases the word spacing by a corresponding amount of pixels,
-    while a negative value decreases the inter-word spacing accordingly.
-*/
-
-/*!
-    \qmlproperty enumeration QtQuick2::TextInput::font.capitalization
-
-    Sets the capitalization for the text.
-
-    \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.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character.
-    \endlist
-
-    \qml
-    TextInput { text: "Hello"; font.capitalization: Font.AllLowercase }
-    \endqml
-*/
-
-QFont QSGTextInput::font() const
-{
-    Q_D(const QSGTextInput);
-    return d->sourceFont;
-}
-
-void QSGTextInput::setFont(const QFont &font)
-{
-    Q_D(QSGTextInput);
-    if (d->sourceFont == font)
-        return;
-
-    d->sourceFont = font;
-    QFont oldFont = d->font;
-    d->font = font;
-    if (d->font.pointSizeF() != -1) {
-        // 0.5pt resolution
-        qreal size = qRound(d->font.pointSizeF()*2.0);
-        d->font.setPointSizeF(size/2.0);
-    }
-    if (oldFont != d->font) {
-        d->control->setFont(d->font);
-        updateSize();
-        updateCursorRectangle();
-        if (d->cursorItem) {
-            d->cursorItem->setHeight(QFontMetrics(d->font).height());
-        }
-    }
-    emit fontChanged(d->sourceFont);
-}
-
-/*!
-    \qmlproperty color QtQuick2::TextInput::color
-
-    The text color.
-*/
-QColor QSGTextInput::color() const
-{
-    Q_D(const QSGTextInput);
-    return d->color;
-}
-
-void QSGTextInput::setColor(const QColor &c)
-{
-    Q_D(QSGTextInput);
-    if (c != d->color) {
-        d->color = c;
-        update();
-        emit colorChanged(c);
-    }
-}
-
-
-/*!
-    \qmlproperty color QtQuick2::TextInput::selectionColor
-
-    The text highlight color, used behind selections.
-*/
-QColor QSGTextInput::selectionColor() const
-{
-    Q_D(const QSGTextInput);
-    return d->selectionColor;
-}
-
-void QSGTextInput::setSelectionColor(const QColor &color)
-{
-    Q_D(QSGTextInput);
-    if (d->selectionColor == color)
-        return;
-
-    d->selectionColor = color;
-    QPalette p = d->control->palette();
-    p.setColor(QPalette::Highlight, d->selectionColor);
-    d->control->setPalette(p);
-    if (d->control->hasSelectedText())
-        update();
-    emit selectionColorChanged(color);
-}
-/*!
-    \qmlproperty color QtQuick2::TextInput::selectedTextColor
-
-    The highlighted text color, used in selections.
-*/
-QColor QSGTextInput::selectedTextColor() const
-{
-    Q_D(const QSGTextInput);
-    return d->selectedTextColor;
-}
-
-void QSGTextInput::setSelectedTextColor(const QColor &color)
-{
-    Q_D(QSGTextInput);
-    if (d->selectedTextColor == color)
-        return;
-
-    d->selectedTextColor = color;
-    QPalette p = d->control->palette();
-    p.setColor(QPalette::HighlightedText, d->selectedTextColor);
-    d->control->setPalette(p);
-    if (d->control->hasSelectedText())
-        update();
-    emit selectedTextColorChanged(color);
-}
-
-/*!
-    \qmlproperty enumeration QtQuick2::TextInput::horizontalAlignment
-    \qmlproperty enumeration QtQuick2::TextInput::effectiveHorizontalAlignment
-
-    Sets the horizontal alignment of the text within the TextInput item's
-    width and height. By default, the text alignment follows the natural alignment
-    of the text, for example text that is read from left to right will be aligned to
-    the left.
-
-    TextInput does not have vertical alignment, as the natural height is
-    exactly the height of the single line of text. If you set the height
-    manually to something larger, TextInput will always be top aligned
-    vertically. You can use anchors to align it however you want within
-    another item.
-
-    The valid values for \c horizontalAlignment are \c TextInput.AlignLeft, \c TextInput.AlignRight and
-    \c TextInput.AlignHCenter.
-
-    When using the attached property LayoutMirroring::enabled to mirror application
-    layouts, the horizontal alignment of text will also be mirrored. However, the property
-    \c horizontalAlignment will remain unchanged. To query the effective horizontal alignment
-    of TextInput, use the read-only property \c effectiveHorizontalAlignment.
-*/
-QSGTextInput::HAlignment QSGTextInput::hAlign() const
-{
-    Q_D(const QSGTextInput);
-    return d->hAlign;
-}
-
-void QSGTextInput::setHAlign(HAlignment align)
-{
-    Q_D(QSGTextInput);
-    bool forceAlign = d->hAlignImplicit && d->effectiveLayoutMirror;
-    d->hAlignImplicit = false;
-    if (d->setHAlign(align, forceAlign) && isComponentComplete()) {
-        updateCursorRectangle();
-    }
-}
-
-void QSGTextInput::resetHAlign()
-{
-    Q_D(QSGTextInput);
-    d->hAlignImplicit = true;
-    if (d->determineHorizontalAlignment() && isComponentComplete()) {
-        updateCursorRectangle();
-    }
-}
-
-QSGTextInput::HAlignment QSGTextInput::effectiveHAlign() const
-{
-    Q_D(const QSGTextInput);
-    QSGTextInput::HAlignment effectiveAlignment = d->hAlign;
-    if (!d->hAlignImplicit && d->effectiveLayoutMirror) {
-        switch (d->hAlign) {
-        case QSGTextInput::AlignLeft:
-            effectiveAlignment = QSGTextInput::AlignRight;
-            break;
-        case QSGTextInput::AlignRight:
-            effectiveAlignment = QSGTextInput::AlignLeft;
-            break;
-        default:
-            break;
-        }
-    }
-    return effectiveAlignment;
-}
-
-bool QSGTextInputPrivate::setHAlign(QSGTextInput::HAlignment alignment, bool forceAlign)
-{
-    Q_Q(QSGTextInput);
-    if ((hAlign != alignment || forceAlign) && alignment <= QSGTextInput::AlignHCenter) { // justify not supported
-        QSGTextInput::HAlignment oldEffectiveHAlign = q->effectiveHAlign();
-        hAlign = alignment;
-        emit q->horizontalAlignmentChanged(alignment);
-        if (oldEffectiveHAlign != q->effectiveHAlign())
-            emit q->effectiveHorizontalAlignmentChanged();
-        return true;
-    }
-    return false;
-}
-
-bool QSGTextInputPrivate::determineHorizontalAlignment()
-{
-    if (hAlignImplicit) {
-        // if no explicit alignment has been set, follow the natural layout direction of the text
-        QString text = control->text();
-        if (text.isEmpty())
-            text = control->preeditAreaText();
-        bool isRightToLeft = text.isEmpty() ? QGuiApplication::keyboardInputDirection() == Qt::RightToLeft : text.isRightToLeft();
-        return setHAlign(isRightToLeft ? QSGTextInput::AlignRight : QSGTextInput::AlignLeft);
-    }
-    return false;
-}
-
-void QSGTextInputPrivate::mirrorChange()
-{
-    Q_Q(QSGTextInput);
-    if (q->isComponentComplete()) {
-        if (!hAlignImplicit && (hAlign == QSGTextInput::AlignRight || hAlign == QSGTextInput::AlignLeft)) {
-            q->updateCursorRectangle();
-            emit q->effectiveHorizontalAlignmentChanged();
-        }
-    }
-}
-
-/*!
-    \qmlproperty bool QtQuick2::TextInput::readOnly
-
-    Sets whether user input can modify the contents of the TextInput.
-
-    If readOnly is set to true, then user input will not affect the text
-    property. Any bindings or attempts to set the text property will still
-    work.
-*/
-bool QSGTextInput::isReadOnly() const
-{
-    Q_D(const QSGTextInput);
-    return d->control->isReadOnly();
-}
-
-void QSGTextInput::setReadOnly(bool ro)
-{
-    Q_D(QSGTextInput);
-    if (d->control->isReadOnly() == ro)
-        return;
-
-    setFlag(QSGItem::ItemAcceptsInputMethod, !ro);
-    d->control->setReadOnly(ro);
-    if (!ro)
-        d->control->setCursorPosition(d->control->end());
-
-    emit readOnlyChanged(ro);
-}
-
-/*!
-    \qmlproperty int QtQuick2::TextInput::maximumLength
-    The maximum permitted length of the text in the TextInput.
-
-    If the text is too long, it is truncated at the limit.
-
-    By default, this property contains a value of 32767.
-*/
-int QSGTextInput::maxLength() const
-{
-    Q_D(const QSGTextInput);
-    return d->control->maxLength();
-}
-
-void QSGTextInput::setMaxLength(int ml)
-{
-    Q_D(QSGTextInput);
-    if (d->control->maxLength() == ml)
-        return;
-
-    d->control->setMaxLength(ml);
-
-    emit maximumLengthChanged(ml);
-}
-
-/*!
-    \qmlproperty bool QtQuick2::TextInput::cursorVisible
-    Set to true when the TextInput shows a cursor.
-
-    This property is set and unset when the TextInput gets active focus, so that other
-    properties can be bound to whether the cursor is currently showing. As it
-    gets set and unset automatically, when you set the value yourself you must
-    keep in mind that your value may be overwritten.
-
-    It can be set directly in script, for example if a KeyProxy might
-    forward keys to it and you desire it to look active when this happens
-    (but without actually giving it active focus).
-
-    It should not be set directly on the element, like in the below QML,
-    as the specified value will be overridden an lost on focus changes.
-
-    \code
-    TextInput {
-        text: "Text"
-        cursorVisible: false
-    }
-    \endcode
-
-    In the above snippet the cursor will still become visible when the
-    TextInput gains active focus.
-*/
-bool QSGTextInput::isCursorVisible() const
-{
-    Q_D(const QSGTextInput);
-    return d->cursorVisible;
-}
-
-void QSGTextInput::setCursorVisible(bool on)
-{
-    Q_D(QSGTextInput);
-    if (d->cursorVisible == on)
-        return;
-    d->cursorVisible = on;
-    d->control->setCursorBlinkPeriod(on ? qApp->styleHints()->cursorFlashTime() : 0);
-    QRect r = d->control->cursorRect();
-    if (d->control->inputMask().isEmpty())
-        updateRect(r);
-    else
-        updateRect();
-    emit cursorVisibleChanged(d->cursorVisible);
-}
-
-/*!
-    \qmlproperty int QtQuick2::TextInput::cursorPosition
-    The position of the cursor in the TextInput.
-*/
-int QSGTextInput::cursorPosition() const
-{
-    Q_D(const QSGTextInput);
-    return d->control->cursor();
-}
-void QSGTextInput::setCursorPosition(int cp)
-{
-    Q_D(QSGTextInput);
-    if (cp < 0 || cp > d->control->text().length())
-        return;
-    d->control->moveCursor(cp);
-}
-
-/*!
-  Returns a Rect which encompasses the cursor, but which may be larger than is
-  required. Ignores custom cursor delegates.
-*/
-QRect QSGTextInput::cursorRectangle() const
-{
-    Q_D(const QSGTextInput);
-    QRect r = d->control->cursorRect();
-    // Scroll and make consistent with TextEdit
-    // QLineControl inexplicably adds 1 to the height and horizontal padding
-    // for unicode direction markers.
-    r.adjust(5 - d->hscroll, 0, -4 - d->hscroll, -1);
-    return r;
-}
-/*!
-    \qmlproperty int QtQuick2::TextInput::selectionStart
-
-    The cursor position before the first character in the current selection.
-
-    This property is read-only. To change the selection, use select(start,end),
-    selectAll(), or selectWord().
-
-    \sa selectionEnd, cursorPosition, selectedText
-*/
-int QSGTextInput::selectionStart() const
-{
-    Q_D(const QSGTextInput);
-    return d->lastSelectionStart;
-}
-/*!
-    \qmlproperty int QtQuick2::TextInput::selectionEnd
-
-    The cursor position after the last character in the current selection.
-
-    This property is read-only. To change the selection, use select(start,end),
-    selectAll(), or selectWord().
-
-    \sa selectionStart, cursorPosition, selectedText
-*/
-int QSGTextInput::selectionEnd() const
-{
-    Q_D(const QSGTextInput);
-    return d->lastSelectionEnd;
-}
-/*!
-    \qmlmethod void QtQuick2::TextInput::select(int start, int end)
-
-    Causes the text from \a start to \a end to be selected.
-
-    If either start or end is out of range, the selection is not changed.
-
-    After calling this, selectionStart will become the lesser
-    and selectionEnd will become the greater (regardless of the order passed
-    to this method).
-
-    \sa selectionStart, selectionEnd
-*/
-void QSGTextInput::select(int start, int end)
-{
-    Q_D(QSGTextInput);
-    if (start < 0 || end < 0 || start > d->control->text().length() || end > d->control->text().length())
-        return;
-    d->control->setSelection(start, end-start);
-}
-
-/*!
-    \qmlproperty string QtQuick2::TextInput::selectedText
-
-    This read-only property provides the text currently selected in the
-    text input.
-
-    It is equivalent to the following snippet, but is faster and easier
-    to use.
-
-    \js
-    myTextInput.text.toString().substring(myTextInput.selectionStart,
-        myTextInput.selectionEnd);
-    \endjs
-*/
-QString QSGTextInput::selectedText() const
-{
-    Q_D(const QSGTextInput);
-    return d->control->selectedText();
-}
-
-/*!
-    \qmlproperty bool QtQuick2::TextInput::activeFocusOnPress
-
-    Whether the TextInput should gain active focus on a mouse press. By default this is
-    set to true.
-*/
-bool QSGTextInput::focusOnPress() const
-{
-    Q_D(const QSGTextInput);
-    return d->focusOnPress;
-}
-
-void QSGTextInput::setFocusOnPress(bool b)
-{
-    Q_D(QSGTextInput);
-    if (d->focusOnPress == b)
-        return;
-
-    d->focusOnPress = b;
-
-    emit activeFocusOnPressChanged(d->focusOnPress);
-}
-/*!
-    \qmlproperty bool QtQuick2::TextInput::autoScroll
-
-    Whether the TextInput should scroll when the text is longer than the width. By default this is
-    set to true.
-*/
-bool QSGTextInput::autoScroll() const
-{
-    Q_D(const QSGTextInput);
-    return d->autoScroll;
-}
-
-void QSGTextInput::setAutoScroll(bool b)
-{
-    Q_D(QSGTextInput);
-    if (d->autoScroll == b)
-        return;
-
-    d->autoScroll = b;
-    //We need to repaint so that the scrolling is taking into account.
-    updateSize(true);
-    updateCursorRectangle();
-    emit autoScrollChanged(d->autoScroll);
-}
-
-#ifndef QT_NO_VALIDATOR
-
-/*!
-    \qmlclass IntValidator QIntValidator
-    \inqmlmodule QtQuick 2
-    \ingroup qml-basic-visual-elements
-
-    This element provides a validator for integer values.
-
-    IntValidator uses the \l {QLocale::setDefault()}{default locale} to interpret the number and
-    will accept locale specific digits, group separators, and positive and negative signs.  In
-    addition, IntValidator is always guaranteed to accept a number formatted according to the "C"
-    locale.
-*/
-/*!
-    \qmlproperty int QtQuick2::IntValidator::top
-
-    This property holds the validator's highest acceptable value.
-    By default, this property's value is derived from the highest signed integer available (typically 2147483647).
-*/
-/*!
-    \qmlproperty int QtQuick2::IntValidator::bottom
-
-    This property holds the validator's lowest acceptable value.
-    By default, this property's value is derived from the lowest signed integer available (typically -2147483647).
-*/
-
-/*!
-    \qmlclass DoubleValidator QDoubleValidator
-    \inqmlmodule QtQuick 2
-    \ingroup qml-basic-visual-elements
-
-    This element provides a validator for non-integer numbers.
-*/
-
-/*!
-    \qmlproperty real QtQuick2::DoubleValidator::top
-
-    This property holds the validator's maximum acceptable value.
-    By default, this property contains a value of infinity.
-*/
-/*!
-    \qmlproperty real QtQuick2::DoubleValidator::bottom
-
-    This property holds the validator's minimum acceptable value.
-    By default, this property contains a value of -infinity.
-*/
-/*!
-    \qmlproperty int QtQuick2::DoubleValidator::decimals
-
-    This property holds the validator's maximum number of digits after the decimal point.
-    By default, this property contains a value of 1000.
-*/
-/*!
-    \qmlproperty enumeration QtQuick2::DoubleValidator::notation
-    This property holds the notation of how a string can describe a number.
-
-    The possible values for this property are:
-
-    \list
-    \o DoubleValidator.StandardNotation
-    \o DoubleValidator.ScientificNotation (default)
-    \endlist
-
-    If this property is set to DoubleValidator.ScientificNotation, the written number may have an exponent part (e.g. 1.5E-2).
-*/
-
-/*!
-    \qmlclass RegExpValidator QRegExpValidator
-    \inqmlmodule QtQuick 2
-    \ingroup qml-basic-visual-elements
-
-    This element provides a validator, which counts as valid any string which
-    matches a specified regular expression.
-*/
-/*!
-   \qmlproperty regExp QtQuick2::RegExpValidator::regExp
-
-   This property holds the regular expression used for validation.
-
-   Note that this property should be a regular expression in JS syntax, e.g /a/ for the regular expression
-   matching "a".
-
-   By default, this property contains a regular expression with the pattern .* that matches any string.
-*/
-
-/*!
-    \qmlproperty Validator QtQuick2::TextInput::validator
-
-    Allows you to set a validator on the TextInput. When a validator is set
-    the TextInput will only accept input which leaves the text property in
-    an acceptable or intermediate state. The accepted signal will only be sent
-    if the text is in an acceptable state when enter is pressed.
-
-    Currently supported validators are IntValidator, DoubleValidator and
-    RegExpValidator. An example of using validators is shown below, which allows
-    input of integers between 11 and 31 into the text input:
-
-    \code
-    import QtQuick 1.0
-    TextInput{
-        validator: IntValidator{bottom: 11; top: 31;}
-        focus: true
-    }
-    \endcode
-
-    \sa acceptableInput, inputMask
-*/
-
-QValidator* QSGTextInput::validator() const
-{
-    Q_D(const QSGTextInput);
-    //###const cast isn't good, but needed for property system?
-    return const_cast<QValidator*>(d->control->validator());
-}
-
-void QSGTextInput::setValidator(QValidator* v)
-{
-    Q_D(QSGTextInput);
-    if (d->control->validator() == v)
-        return;
-
-    d->control->setValidator(v);
-    if (!d->control->hasAcceptableInput()) {
-        d->oldValidity = false;
-        emit acceptableInputChanged();
-    }
-
-    emit validatorChanged();
-}
-#endif // QT_NO_VALIDATOR
-
-/*!
-    \qmlproperty string QtQuick2::TextInput::inputMask
-
-    Allows you to set an input mask on the TextInput, restricting the allowable
-    text inputs. See QLineEdit::inputMask for further details, as the exact
-    same mask strings are used by TextInput.
-
-    \sa acceptableInput, validator
-*/
-QString QSGTextInput::inputMask() const
-{
-    Q_D(const QSGTextInput);
-    return d->control->inputMask();
-}
-
-void QSGTextInput::setInputMask(const QString &im)
-{
-    Q_D(QSGTextInput);
-    if (d->control->inputMask() == im)
-        return;
-
-    d->control->setInputMask(im);
-    emit inputMaskChanged(d->control->inputMask());
-}
-
-/*!
-    \qmlproperty bool QtQuick2::TextInput::acceptableInput
-
-    This property is always true unless a validator or input mask has been set.
-    If a validator or input mask has been set, this property will only be true
-    if the current text is acceptable to the validator or input mask as a final
-    string (not as an intermediate string).
-*/
-bool QSGTextInput::hasAcceptableInput() const
-{
-    Q_D(const QSGTextInput);
-    return d->control->hasAcceptableInput();
-}
-
-/*!
-    \qmlsignal QtQuick2::TextInput::onAccepted()
-
-    This handler is called when the Return or Enter key is pressed.
-    Note that if there is a \l validator or \l inputMask set on the text
-    input, the handler will only be emitted if the input is in an acceptable
-    state.
-*/
-
-void QSGTextInputPrivate::updateInputMethodHints()
-{
-    Q_Q(QSGTextInput);
-    Qt::InputMethodHints hints = inputMethodHints;
-    uint echo = control->echoMode();
-    if (echo == QSGTextInput::Password || echo == QSGTextInput::NoEcho)
-        hints |= Qt::ImhHiddenText;
-    else if (echo == QSGTextInput::PasswordEchoOnEdit)
-        hints &= ~Qt::ImhHiddenText;
-    if (echo != QSGTextInput::Normal)
-        hints |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText);
-    q->setInputMethodHints(hints);
-}
-/*!
-    \qmlproperty enumeration QtQuick2::TextInput::echoMode
-
-    Specifies how the text should be displayed in the TextInput.
-    \list
-    \o TextInput.Normal - Displays the text as it is. (Default)
-    \o TextInput.Password - Displays asterixes instead of characters.
-    \o TextInput.NoEcho - Displays nothing.
-    \o TextInput.PasswordEchoOnEdit - Displays characters as they are entered
-    while editing, otherwise displays asterisks.
-    \endlist
-*/
-QSGTextInput::EchoMode QSGTextInput::echoMode() const
-{
-    Q_D(const QSGTextInput);
-    return (QSGTextInput::EchoMode)d->control->echoMode();
-}
-
-void QSGTextInput::setEchoMode(QSGTextInput::EchoMode echo)
-{
-    Q_D(QSGTextInput);
-    if (echoMode() == echo)
-        return;
-    d->control->setEchoMode((QLineControl::EchoMode)echo);
-    d->updateInputMethodHints();
-    q_textChanged();
-    emit echoModeChanged(echoMode());
-}
-
-Qt::InputMethodHints QSGTextInput::imHints() const
-{
-    Q_D(const QSGTextInput);
-    return d->inputMethodHints;
-}
-
-void QSGTextInput::setIMHints(Qt::InputMethodHints hints)
-{
-    Q_D(QSGTextInput);
-    if (d->inputMethodHints == hints)
-        return;
-    d->inputMethodHints = hints;
-    d->updateInputMethodHints();
-}
-
-/*!
-    \qmlproperty Component QtQuick2::TextInput::cursorDelegate
-    The delegate for the cursor in the TextInput.
-
-    If you set a cursorDelegate for a TextInput, this delegate will be used for
-    drawing the cursor instead of the standard cursor. An instance of the
-    delegate will be created and managed by the TextInput when a cursor is
-    needed, and the x property of delegate instance will be set so as
-    to be one pixel before the top left of the current character.
-
-    Note that the root item of the delegate component must be a QDeclarativeItem or
-    QDeclarativeItem derived item.
-*/
-QDeclarativeComponent* QSGTextInput::cursorDelegate() const
-{
-    Q_D(const QSGTextInput);
-    return d->cursorComponent;
-}
-
-void QSGTextInput::setCursorDelegate(QDeclarativeComponent* c)
-{
-    Q_D(QSGTextInput);
-    if (d->cursorComponent == c)
-        return;
-
-    d->cursorComponent = c;
-    if (!c) {
-        //note that the components are owned by something else
-        delete d->cursorItem;
-    } else {
-        d->startCreatingCursor();
-    }
-
-    emit cursorDelegateChanged();
-}
-
-void QSGTextInputPrivate::startCreatingCursor()
-{
-    Q_Q(QSGTextInput);
-    if (cursorComponent->isReady()) {
-        q->createCursor();
-    } else if (cursorComponent->isLoading()) {
-        q->connect(cursorComponent, SIGNAL(statusChanged(int)),
-                q, SLOT(createCursor()));
-    } else { // isError
-        qmlInfo(q, cursorComponent->errors()) << QSGTextInput::tr("Could not load cursor delegate");
-    }
-}
-
-void QSGTextInput::createCursor()
-{
-    Q_D(QSGTextInput);
-    if (d->cursorComponent->isError()) {
-        qmlInfo(this, d->cursorComponent->errors()) << tr("Could not load cursor delegate");
-        return;
-    }
-
-    if (!d->cursorComponent->isReady())
-        return;
-
-    if (d->cursorItem)
-        delete 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;
-    }
-
-    QDeclarative_setParent_noEvent(d->cursorItem, this);
-    d->cursorItem->setParentItem(this);
-    d->cursorItem->setX(d->control->cursorToX());
-    d->cursorItem->setHeight(d->control->height()-1); // -1 to counter QLineControl's +1 which is not consistent with Text.
-}
-
-/*!
-    \qmlmethod rect QtQuick2::TextInput::positionToRectangle(int pos)
-
-    This function takes a character position and returns the rectangle that the
-    cursor would occupy, if it was placed at that character position.
-
-    This is similar to setting the cursorPosition, and then querying the cursor
-    rectangle, but the cursorPosition is not changed.
-*/
-QRectF QSGTextInput::positionToRectangle(int pos) const
-{
-    Q_D(const QSGTextInput);
-    if (pos > d->control->cursorPosition())
-        pos += d->control->preeditAreaText().length();
-    return QRectF(d->control->cursorToX(pos)-d->hscroll,
-        0.0,
-        d->control->cursorWidth(),
-        cursorRectangle().height());
-}
-
-/*!
-    \qmlmethod int QtQuick2::TextInput::positionAt(int x, CursorPosition position = CursorBetweenCharacters)
-
-    This function returns the character position at
-    x pixels from the left of the textInput. Position 0 is before the
-    first character, position 1 is after the first character but before the second,
-    and so on until position text.length, which is after all characters.
-
-    This means that for all x values before the first character this function returns 0,
-    and for all x values after the last character this function returns text.length.
-
-    The cursor position type specifies how the cursor position should be resolved.
-
-    \list
-    \o TextInput.CursorBetweenCharacters - Returns the position between characters that is nearest x.
-    \o TextInput.CursorOnCharacter - Returns the position before the character that is nearest x.
-    \endlist
-*/
-int QSGTextInput::positionAt(int x) const
-{
-    return positionAt(x, CursorBetweenCharacters);
-}
-
-int QSGTextInput::positionAt(int x, CursorPosition position) const
-{
-    Q_D(const QSGTextInput);
-    int pos = d->control->xToPos(x + d->hscroll, QTextLine::CursorPosition(position));
-    const int cursor = d->control->cursor();
-    if (pos > cursor) {
-        const int preeditLength = d->control->preeditAreaText().length();
-        pos = pos > cursor + preeditLength
-                ? pos - preeditLength
-                : cursor;
-    }
-    return pos;
-}
-
-void QSGTextInput::keyPressEvent(QKeyEvent* ev)
-{
-    Q_D(QSGTextInput);
-    // Don't allow MacOSX up/down support, and we don't allow a completer.
-    bool ignore = (ev->key() == Qt::Key_Up || ev->key() == Qt::Key_Down) && ev->modifiers() == Qt::NoModifier;
-    if (!ignore && (d->lastSelectionStart == d->lastSelectionEnd) && (ev->key() == Qt::Key_Right || ev->key() == Qt::Key_Left)) {
-        // Ignore when moving off the end unless there is a selection,
-        // because then moving will do something (deselect).
-        int cursorPosition = d->control->cursor();
-        if (cursorPosition == 0)
-            ignore = ev->key() == (d->control->layoutDirection() == Qt::LeftToRight ? Qt::Key_Left : Qt::Key_Right);
-        if (cursorPosition == d->control->text().length())
-            ignore = ev->key() == (d->control->layoutDirection() == Qt::LeftToRight ? Qt::Key_Right : Qt::Key_Left);
-    }
-    if (ignore) {
-        ev->ignore();
-    } else {
-        d->control->processKeyEvent(ev);
-    }
-    if (!ev->isAccepted())
-        QSGImplicitSizeItem::keyPressEvent(ev);
-}
-
-void QSGTextInput::inputMethodEvent(QInputMethodEvent *ev)
-{
-    Q_D(QSGTextInput);
-    const bool wasComposing = d->control->preeditAreaText().length() > 0;
-    if (d->control->isReadOnly()) {
-        ev->ignore();
-    } else {
-        d->control->processInputMethodEvent(ev);
-    }
-    if (!ev->isAccepted())
-        QSGImplicitSizeItem::inputMethodEvent(ev);
-
-    if (wasComposing != (d->control->preeditAreaText().length() > 0))
-        emit inputMethodComposingChanged();
-}
-
-void QSGTextInput::mouseDoubleClickEvent(QMouseEvent *event)
-{
-    Q_D(QSGTextInput);
-    if (d->sendMouseEventToInputContext(event))
-        return;
-    if (d->selectByMouse) {
-        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);
-    }
-}
-
-void QSGTextInput::mousePressEvent(QMouseEvent *event)
-{
-    Q_D(QSGTextInput);
-    if (d->sendMouseEventToInputContext(event))
-        return;
-    if (d->focusOnPress) {
-        bool hadActiveFocus = hasActiveFocus();
-        forceActiveFocus();
-        // 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());
-    d->control->moveCursor(cursor, mark);
-    event->setAccepted(true);
-}
-
-void QSGTextInput::mouseMoveEvent(QMouseEvent *event)
-{
-    Q_D(QSGTextInput);
-    if (d->sendMouseEventToInputContext(event))
-        return;
-    if (d->selectPressed) {
-        if (qAbs(int(event->localPos().x() - d->pressPos.x())) > qApp->styleHints()->startDragDistance())
-            setKeepMouseGrab(true);
-        moveCursorSelection(d->xToPos(event->localPos().x()), d->mouseSelectionMode);
-        event->setAccepted(true);
-    } else {
-        QSGImplicitSizeItem::mouseMoveEvent(event);
-    }
-}
-
-void QSGTextInput::mouseReleaseEvent(QMouseEvent *event)
-{
-    Q_D(QSGTextInput);
-    if (d->sendMouseEventToInputContext(event))
-        return;
-    if (d->selectPressed) {
-        d->selectPressed = false;
-        setKeepMouseGrab(false);
-    }
-    d->control->processEvent(event);
-    if (!event->isAccepted())
-        QSGImplicitSizeItem::mouseReleaseEvent(event);
-}
-
-bool QSGTextInputPrivate::sendMouseEventToInputContext(QMouseEvent *event)
-{
-#if !defined QT_NO_IM
-    if (control->composeMode() && event->type() == QEvent::KeyRelease) {
-        int tmp_cursor = xToPos(event->localPos().x());
-        int mousePos = tmp_cursor - control->cursor();
-        if (mousePos < 0 || mousePos > control->preeditAreaText().length()) {
-            mousePos = -1;
-            // don't send move events outside the preedit area
-            if (event->type() == QEvent::MouseMove)
-                return true;
-        }
-
-        // may be causing reset() in some input methods
-        qApp->inputPanel()->invokeAction(QInputPanel::Click, mousePos);
-        if (!control->preeditAreaText().isEmpty())
-            return true;
-    }
-#else
-    Q_UNUSED(event);
-    Q_UNUSED(eventType)
-#endif
-
-    return false;
-}
-
-void QSGTextInput::mouseUngrabEvent()
-{
-    Q_D(QSGTextInput);
-    d->selectPressed = false;
-    setKeepMouseGrab(false);
-}
-
-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()) {
-        case QEvent::KeyPress:
-        case QEvent::KeyRelease://###Should the control be doing anything with release?
-        case QEvent::InputMethod:
-        case QEvent::MouseButtonPress:
-        case QEvent::MouseMove:
-        case QEvent::MouseButtonRelease:
-        case QEvent::MouseButtonDblClick:
-            break;
-        default:
-            handled = d->control->processEvent(ev);
-    }
-    if (!handled)
-        handled = QSGImplicitSizeItem::event(ev);
-    return handled;
-}
-
-void QSGTextInput::geometryChanged(const QRectF &newGeometry,
-                                  const QRectF &oldGeometry)
-{
-    if (newGeometry.width() != oldGeometry.width()) {
-        updateSize();
-        updateCursorRectangle();
-    }
-    QSGImplicitSizeItem::geometryChanged(newGeometry, oldGeometry);
-}
-
-int QSGTextInputPrivate::calculateTextWidth()
-{
-    return qRound(control->naturalTextWidth());
-}
-
-void QSGTextInputPrivate::updateHorizontalScroll()
-{
-    Q_Q(QSGTextInput);
-    const int preeditLength = control->preeditAreaText().length();
-    const int width = q->width();
-    int widthUsed = calculateTextWidth();
-
-    if (!autoScroll || widthUsed <=  width) {
-        QSGTextInput::HAlignment effectiveHAlign = q->effectiveHAlign();
-        // text fits in br; use hscroll for alignment
-        switch (effectiveHAlign & ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask)) {
-        case Qt::AlignRight:
-            hscroll = widthUsed - width;
-            break;
-        case Qt::AlignHCenter:
-            hscroll = (widthUsed - width) / 2;
-            break;
-        default:
-            // Left
-            hscroll = 0;
-            break;
-        }
-    } else {
-        int cix = qRound(control->cursorToX(control->cursor() + preeditLength));
-        if (cix - hscroll >= width) {
-            // text doesn't fit, cursor is to the right of br (scroll right)
-            hscroll = cix - width;
-        } else if (cix - hscroll < 0 && hscroll < widthUsed) {
-            // text doesn't fit, cursor is to the left of br (scroll left)
-            hscroll = cix;
-        } else if (widthUsed - hscroll < width) {
-            // text doesn't fit, text document is to the left of br; align
-            // right
-            hscroll = widthUsed - width;
-        }
-        if (preeditLength > 0) {
-            // check to ensure long pre-edit text doesn't push the cursor
-            // off to the left
-             cix = qRound(control->cursorToX(
-                     control->cursor() + qMax(0, control->preeditCursor() - 1)));
-             if (cix < hscroll)
-                 hscroll = cix;
-        }
-    }
-}
-
-QSGNode *QSGTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
-{
-    Q_UNUSED(data);
-    Q_D(QSGTextInput);
-
-    QSGTextNode *node = static_cast<QSGTextNode *>(oldNode);
-    if (node == 0)
-        node = new QSGTextNode(QSGItemPrivate::get(this)->sceneGraphContext());
-    d->textNode = node;
-
-    if (!d->textLayoutDirty) {
-        QSGSimpleRectNode *cursorNode = node->cursorNode();
-        if (cursorNode != 0 && !isReadOnly()) {
-            QFontMetrics fm = QFontMetrics(d->font);
-            // the y offset is there to keep the baseline constant in case we have script changes in the text.
-            QPoint offset(-d->hscroll, fm.ascent() - d->control->ascent());
-            offset.rx() += d->control->cursorToX();
-
-            QRect br(boundingRect().toRect());
-            cursorNode->setRect(QRectF(offset, QSizeF(d->control->cursorWidth(), br.height())));
-
-            if (!d->cursorVisible
-                    || (!d->control->cursorBlinkStatus() && d->control->cursorBlinkPeriod() > 0)) {
-                d->hideCursor();
-            } else {
-                d->showCursor();
-            }
-        }
-    } else {
-        node->deleteContent();
-        node->setMatrix(QMatrix4x4());
-
-        QPoint offset = QPoint(0,0);
-        QFontMetrics fm = QFontMetrics(d->font);
-        QRect br(boundingRect().toRect());
-        if (d->autoScroll) {
-            // the y offset is there to keep the baseline constant in case we have script changes in the text.
-            offset = br.topLeft() - QPoint(d->hscroll, d->control->ascent() - fm.ascent());
-        } else {
-            offset = QPoint(d->hscroll, 0);
-        }
-
-        QTextLayout *textLayout = d->control->textLayout();
-        if (!textLayout->text().isEmpty()) {
-            node->addTextLayout(offset, textLayout, d->color,
-                                QSGText::Normal, QColor(),
-                                d->selectionColor, d->selectedTextColor,
-                                d->control->selectionStart(),
-                                d->control->selectionEnd() - 1); // selectionEnd() returns first char after
-                                                                 // selection
-        }
-
-        if (!isReadOnly() && d->cursorItem == 0) {
-            offset.rx() += d->control->cursorToX();
-            node->setCursor(QRectF(offset, QSizeF(d->control->cursorWidth(), br.height())), d->color);
-            if (!d->cursorVisible
-                    || (!d->control->cursorBlinkStatus() && d->control->cursorBlinkPeriod() > 0)) {
-                d->hideCursor();
-            } else {
-                d->showCursor();
-            }
-        }
-
-        d->textLayoutDirty = false;
-    }
-
-    return node;
-}
-
-QVariant QSGTextInput::inputMethodQuery(Qt::InputMethodQuery property) const
-{
-    Q_D(const QSGTextInput);
-    switch (property) {
-    case Qt::ImEnabled:
-        return QVariant((bool)(flags() & ItemAcceptsInputMethod));
-    case Qt::ImHints:
-        return QVariant((int)inputMethodHints());
-    case Qt::ImCursorRectangle:
-        return cursorRectangle();
-    case Qt::ImFont:
-        return font();
-    case Qt::ImCursorPosition:
-        return QVariant(d->control->cursor());
-    case Qt::ImSurroundingText:
-        if (d->control->echoMode() == QLineControl::PasswordEchoOnEdit
-            && !d->control->passwordEchoEditing()) {
-            return QVariant(displayText());
-        } else {
-            return QVariant(text());
-        }
-    case Qt::ImCurrentSelection:
-        return QVariant(selectedText());
-    case Qt::ImMaximumTextLength:
-        return QVariant(maxLength());
-    case Qt::ImAnchorPosition:
-        if (d->control->selectionStart() == d->control->selectionEnd())
-            return QVariant(d->control->cursor());
-        else if (d->control->selectionStart() == d->control->cursor())
-            return QVariant(d->control->selectionEnd());
-        else
-            return QVariant(d->control->selectionStart());
-    default:
-        return QVariant();
-    }
-}
-
-/*!
-    \qmlmethod void QtQuick2::TextInput::deselect()
-
-    Removes active text selection.
-*/
-void QSGTextInput::deselect()
-{
-    Q_D(QSGTextInput);
-    d->control->deselect();
-}
-
-/*!
-    \qmlmethod void QtQuick2::TextInput::selectAll()
-
-    Causes all text to be selected.
-*/
-void QSGTextInput::selectAll()
-{
-    Q_D(QSGTextInput);
-    d->control->setSelection(0, d->control->text().length());
-}
-
-/*!
-    \qmlmethod void QtQuick2::TextInput::isRightToLeft(int start, int end)
-
-    Returns true if the natural reading direction of the editor text
-    found between positions \a start and \a end is right to left.
-*/
-bool QSGTextInput::isRightToLeft(int start, int end)
-{
-    Q_D(QSGTextInput);
-    if (start > end) {
-        qmlInfo(this) << "isRightToLeft(start, end) called with the end property being smaller than the start.";
-        return false;
-    } else {
-        return d->control->text().mid(start, end - start).isRightToLeft();
-    }
-}
-
-#ifndef QT_NO_CLIPBOARD
-/*!
-    \qmlmethod QtQuick2::TextInput::cut()
-
-    Moves the currently selected text to the system clipboard.
-*/
-void QSGTextInput::cut()
-{
-    Q_D(QSGTextInput);
-    d->control->copy();
-    d->control->del();
-}
-
-/*!
-    \qmlmethod QtQuick2::TextInput::copy()
-
-    Copies the currently selected text to the system clipboard.
-*/
-void QSGTextInput::copy()
-{
-    Q_D(QSGTextInput);
-    d->control->copy();
-}
-
-/*!
-    \qmlmethod QtQuick2::TextInput::paste()
-
-    Replaces the currently selected text by the contents of the system clipboard.
-*/
-void QSGTextInput::paste()
-{
-    Q_D(QSGTextInput);
-    if (!d->control->isReadOnly())
-        d->control->paste();
-}
-#endif // QT_NO_CLIPBOARD
-
-/*!
-    \qmlmethod void QtQuick2::TextInput::selectWord()
-
-    Causes the word closest to the current cursor position to be selected.
-*/
-void QSGTextInput::selectWord()
-{
-    Q_D(QSGTextInput);
-    d->control->selectWordAtPos(d->control->cursor());
-}
-
-/*!
-    \qmlproperty bool QtQuick2::TextInput::smooth
-
-    This property holds whether the text is smoothly scaled or transformed.
-
-    Smooth filtering gives better visual quality, but is slower.  If
-    the item is displayed at its natural size, this property has no visual or
-    performance effect.
-
-    \note Generally scaling artifacts are only visible if the item is stationary on
-    the screen.  A common pattern when animating an item is to disable smooth
-    filtering at the beginning of the animation and reenable it at the conclusion.
-*/
-
-/*!
-   \qmlproperty string QtQuick2::TextInput::passwordCharacter
-
-   This is the character displayed when echoMode is set to Password or
-   PasswordEchoOnEdit. By default it is an asterisk.
-
-   If this property is set to a string with more than one character,
-   the first character is used. If the string is empty, the value
-   is ignored and the property is not set.
-*/
-QString QSGTextInput::passwordCharacter() const
-{
-    Q_D(const QSGTextInput);
-    return QString(d->control->passwordCharacter());
-}
-
-void QSGTextInput::setPasswordCharacter(const QString &str)
-{
-    Q_D(QSGTextInput);
-    if (str.length() < 1)
-        return;
-    d->control->setPasswordCharacter(str.constData()[0]);
-    EchoMode echoMode_ = echoMode();
-    if (echoMode_ == Password || echoMode_ == PasswordEchoOnEdit) {
-        updateSize();
-    }
-    emit passwordCharacterChanged();
-}
-
-/*!
-   \qmlproperty string QtQuick2::TextInput::displayText
-
-   This is the text displayed in the TextInput.
-
-   If \l echoMode is set to TextInput::Normal, this holds the
-   same value as the TextInput::text property. Otherwise,
-   this property holds the text visible to the user, while
-   the \l text property holds the actual entered text.
-*/
-QString QSGTextInput::displayText() const
-{
-    Q_D(const QSGTextInput);
-    return d->control->displayText();
-}
-
-/*!
-    \qmlproperty bool QtQuick2::TextInput::selectByMouse
-
-    Defaults to false.
-
-    If true, the user can use the mouse to select text in some
-    platform-specific way. Note that for some platforms this may
-    not be an appropriate interaction (eg. may conflict with how
-    the text needs to behave inside a Flickable.
-*/
-bool QSGTextInput::selectByMouse() const
-{
-    Q_D(const QSGTextInput);
-    return d->selectByMouse;
-}
-
-void QSGTextInput::setSelectByMouse(bool on)
-{
-    Q_D(QSGTextInput);
-    if (d->selectByMouse != on) {
-        d->selectByMouse = on;
-        emit selectByMouseChanged(on);
-    }
-}
-
-/*!
-    \qmlproperty enum QtQuick2::TextInput::mouseSelectionMode
-
-    Specifies how text should be selected using a mouse.
-
-    \list
-    \o TextInput.SelectCharacters - The selection is updated with individual characters. (Default)
-    \o TextInput.SelectWords - The selection is updated with whole words.
-    \endlist
-
-    This property only applies when \l selectByMouse is true.
-*/
-
-QSGTextInput::SelectionMode QSGTextInput::mouseSelectionMode() const
-{
-    Q_D(const QSGTextInput);
-    return d->mouseSelectionMode;
-}
-
-void QSGTextInput::setMouseSelectionMode(SelectionMode mode)
-{
-    Q_D(QSGTextInput);
-    if (d->mouseSelectionMode != mode) {
-        d->mouseSelectionMode = mode;
-        emit mouseSelectionModeChanged(mode);
-    }
-}
-
-/*!
-    \qmlproperty bool QtQuick2::TextInput::canPaste
-
-    Returns true if the TextInput is writable and the content of the clipboard is
-    suitable for pasting into the TextEdit.
-*/
-bool QSGTextInput::canPaste() const
-{
-    Q_D(const QSGTextInput);
-    return d->canPaste;
-}
-
-void QSGTextInput::moveCursorSelection(int position)
-{
-    Q_D(QSGTextInput);
-    d->control->moveCursor(position, true);
-}
-
-/*!
-    \qmlmethod void QtQuick2::TextInput::moveCursorSelection(int position, SelectionMode mode = TextInput.SelectCharacters)
-
-    Moves the cursor to \a position and updates the selection according to the optional \a mode
-    parameter.  (To only move the cursor, set the \l cursorPosition property.)
-
-    When this method is called it additionally sets either the
-    selectionStart or the selectionEnd (whichever was at the previous cursor position)
-    to the specified position. This allows you to easily extend and contract the selected
-    text range.
-
-    The selection mode specifies whether the selection is updated on a per character or a per word
-    basis.  If not specified the selection mode will default to TextInput.SelectCharacters.
-
-    \list
-    \o TextEdit.SelectCharacters - Sets either the selectionStart or selectionEnd (whichever was at
-    the previous cursor position) to the specified position.
-    \o TextEdit.SelectWords - Sets the selectionStart and selectionEnd to include all
-    words between the specified postion and the previous cursor position.  Words partially in the
-    range are included.
-    \endlist
-
-    For example, take this sequence of calls:
-
-    \code
-        cursorPosition = 5
-        moveCursorSelection(9, TextInput.SelectCharacters)
-        moveCursorSelection(7, TextInput.SelectCharacters)
-    \endcode
-
-    This moves the cursor to position 5, extend the selection end from 5 to 9
-    and then retract the selection end from 9 to 7, leaving the text from position 5 to 7
-    selected (the 6th and 7th characters).
-
-    The same sequence with TextInput.SelectWords will extend the selection start to a word boundary
-    before or on position 5 and extend the selection end to a word boundary on or past position 9.
-*/
-void QSGTextInput::moveCursorSelection(int pos, SelectionMode mode)
-{
-    Q_D(QSGTextInput);
-
-    if (mode == SelectCharacters) {
-        d->control->moveCursor(pos, true);
-    } else if (pos != d->control->cursor()){
-        const int cursor = d->control->cursor();
-        int anchor;
-        if (!d->control->hasSelectedText())
-            anchor = d->control->cursor();
-        else if (d->control->selectionStart() == d->control->cursor())
-            anchor = d->control->selectionEnd();
-        else
-            anchor = d->control->selectionStart();
-
-        if (anchor < pos || (anchor == pos && cursor < pos)) {
-            const QString text = d->control->text();
-            QTextBoundaryFinder finder(QTextBoundaryFinder::Word, text);
-            finder.setPosition(anchor);
-
-            const QTextBoundaryFinder::BoundaryReasons reasons = finder.boundaryReasons();
-            if (anchor < text.length() && (!(reasons & QTextBoundaryFinder::StartWord)
-                    || ((reasons & QTextBoundaryFinder::EndWord) && anchor > cursor))) {
-                finder.toPreviousBoundary();
-            }
-            anchor = finder.position() != -1 ? finder.position() : 0;
-
-            finder.setPosition(pos);
-            if (pos > 0 && !finder.boundaryReasons())
-                finder.toNextBoundary();
-            const int cursor = finder.position() != -1 ? finder.position() : text.length();
-
-            d->control->setSelection(anchor, cursor - anchor);
-        } else if (anchor > pos || (anchor == pos && cursor > pos)) {
-            const QString text = d->control->text();
-            QTextBoundaryFinder finder(QTextBoundaryFinder::Word, text);
-            finder.setPosition(anchor);
-
-            const QTextBoundaryFinder::BoundaryReasons reasons = finder.boundaryReasons();
-            if (anchor > 0 && (!(reasons & QTextBoundaryFinder::EndWord)
-                    || ((reasons & QTextBoundaryFinder::StartWord) && anchor < cursor))) {
-                finder.toNextBoundary();
-            }
-
-            anchor = finder.position() != -1 ? finder.position() : text.length();
-
-            finder.setPosition(pos);
-            if (pos < text.length() && !finder.boundaryReasons())
-                 finder.toPreviousBoundary();
-            const int cursor = finder.position() != -1 ? finder.position() : 0;
-
-            d->control->setSelection(anchor, cursor - anchor);
-        }
-    }
-}
-
-/*!
-    \qmlmethod void QtQuick2::TextInput::openSoftwareInputPanel()
-
-    Opens software input panels like virtual keyboards for typing, useful for
-    customizing when you want the input keyboard to be shown and hidden in
-    your application.
-
-    By default the opening of input panels follows the platform style. On Symbian^1 and
-    Symbian^3 -based devices the panels are opened by clicking TextInput. On other platforms
-    the panels are automatically opened when TextInput element gains active focus. Input panels are
-    always closed if no editor has active focus.
-
-  . You can disable the automatic behavior by setting the property \c activeFocusOnPress to false
-    and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement
-    the behavior you want.
-
-    Only relevant on platforms, which provide virtual keyboards.
-
-    \qml
-        import QtQuick 1.0
-        TextInput {
-            id: textInput
-            text: "Hello world!"
-            activeFocusOnPress: false
-            MouseArea {
-                anchors.fill: parent
-                onClicked: {
-                    if (!textInput.activeFocus) {
-                        textInput.forceActiveFocus()
-                        textInput.openSoftwareInputPanel();
-                    } else {
-                        textInput.focus = false;
-                    }
-                }
-                onPressAndHold: textInput.closeSoftwareInputPanel();
-            }
-        }
-    \endqml
-*/
-void QSGTextInput::openSoftwareInputPanel()
-{
-    if (qGuiApp)
-        qGuiApp->inputPanel()->show();
-}
-
-/*!
-    \qmlmethod void QtQuick2::TextInput::closeSoftwareInputPanel()
-
-    Closes a software input panel like a virtual keyboard shown on the screen, useful
-    for customizing when you want the input keyboard to be shown and hidden in
-    your application.
-
-    By default the opening of input panels follows the platform style. On Symbian^1 and
-    Symbian^3 -based devices the panels are opened by clicking TextInput. On other platforms
-    the panels are automatically opened when TextInput element gains active focus. Input panels are
-    always closed if no editor has active focus.
-
-  . You can disable the automatic behavior by setting the property \c activeFocusOnPress to false
-    and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement
-    the behavior you want.
-
-    Only relevant on platforms, which provide virtual keyboards.
-
-    \qml
-        import QtQuick 1.0
-        TextInput {
-            id: textInput
-            text: "Hello world!"
-            activeFocusOnPress: false
-            MouseArea {
-                anchors.fill: parent
-                onClicked: {
-                    if (!textInput.activeFocus) {
-                        textInput.forceActiveFocus();
-                        textInput.openSoftwareInputPanel();
-                    } else {
-                        textInput.focus = false;
-                    }
-                }
-                onPressAndHold: textInput.closeSoftwareInputPanel();
-            }
-        }
-    \endqml
-*/
-void QSGTextInput::closeSoftwareInputPanel()
-{
-    if (qGuiApp)
-        qGuiApp->inputPanel()->hide();
-}
-
-void QSGTextInput::focusInEvent(QFocusEvent *event)
-{
-    Q_D(const QSGTextInput);
-    if (d->focusOnPress && !isReadOnly())
-        openSoftwareInputPanel();
-    QSGImplicitSizeItem::focusInEvent(event);
-}
-
-void QSGTextInput::itemChange(ItemChange change, const ItemChangeData &value)
-{
-    Q_D(QSGTextInput);
-    if (change == ItemActiveFocusHasChanged) {
-        bool hasFocus = value.boolValue;
-        d->focused = hasFocus;
-        setCursorVisible(hasFocus); // ### refactor:  && d->canvas && d->canvas->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();
-    }
-    QSGItem::itemChange(change, value);
-}
-
-/*!
-    \qmlproperty bool QtQuick2::TextInput::inputMethodComposing
-
-
-    This property holds whether the TextInput has partial text input from an
-    input method.
-
-    While it is composing an input method may rely on mouse or key events from
-    the TextInput to edit or commit the partial text.  This property can be
-    used to determine when to disable events handlers that may interfere with
-    the correct operation of an input method.
-*/
-bool QSGTextInput::isInputMethodComposing() const
-{
-    Q_D(const QSGTextInput);
-    return d->control->preeditAreaText().length() > 0;
-}
-
-void QSGTextInputPrivate::init()
-{
-    Q_Q(QSGTextInput);
-#if defined(Q_WS_MAC)
-    control->setThreadChecks(true);
-#endif
-    control->setParent(q);//Now mandatory due to accessibility changes
-    control->setCursorWidth(1);
-    control->setPasswordCharacter(QLatin1Char('*'));
-    q->setSmooth(smooth);
-    q->setAcceptedMouseButtons(Qt::LeftButton);
-    q->setFlag(QSGItem::ItemAcceptsInputMethod);
-    q->setFlag(QSGItem::ItemHasContents);
-    q->connect(control, SIGNAL(cursorPositionChanged(int,int)),
-               q, SLOT(cursorPosChanged()));
-    q->connect(control, SIGNAL(selectionChanged()),
-               q, SLOT(selectionChanged()));
-    q->connect(control, SIGNAL(textChanged(QString)),
-               q, SLOT(q_textChanged()));
-    q->connect(control, SIGNAL(accepted()),
-               q, SIGNAL(accepted()));
-    q->connect(control, SIGNAL(updateNeeded(QRect)),
-               q, SLOT(updateRect(QRect)));
-#ifndef QT_NO_CLIPBOARD
-    q->connect(q, SIGNAL(readOnlyChanged(bool)),
-            q, SLOT(q_canPasteChanged()));
-    q->connect(QGuiApplication::clipboard(), SIGNAL(dataChanged()),
-            q, SLOT(q_canPasteChanged()));
-    canPaste = !control->isReadOnly() && QGuiApplication::clipboard()->text().length() != 0;
-#endif // QT_NO_CLIPBOARD
-    q->connect(control, SIGNAL(updateMicroFocus()),
-               q, SLOT(updateCursorRectangle()));
-    q->connect(control, SIGNAL(displayTextChanged(QString)),
-               q, SLOT(updateRect()));
-    q->updateSize();
-    imHints &= ~Qt::ImhMultiLine;
-    oldValidity = control->hasAcceptableInput();
-    lastSelectionStart = 0;
-    lastSelectionEnd = 0;
-    QPalette p = control->palette();
-    selectedTextColor = p.color(QPalette::HighlightedText);
-    selectionColor = p.color(QPalette::Highlight);
-    determineHorizontalAlignment();
-
-    if (!qmlDisableDistanceField()) {
-        QTextOption option = control->textLayout()->textOption();
-        option.setUseDesignMetrics(true);
-        control->textLayout()->setTextOption(option);
-    }
-}
-
-void QSGTextInput::cursorPosChanged()
-{
-    Q_D(QSGTextInput);
-    updateCursorRectangle();
-    emit cursorPositionChanged();
-    // XXX todo - not in 4.8?
-#if 0
-    d->control->resetCursorBlinkTimer();
-#endif
-
-    if (!d->control->hasSelectedText()) {
-        if (d->lastSelectionStart != d->control->cursor()) {
-            d->lastSelectionStart = d->control->cursor();
-            emit selectionStartChanged();
-        }
-        if (d->lastSelectionEnd != d->control->cursor()) {
-            d->lastSelectionEnd = d->control->cursor();
-            emit selectionEndChanged();
-        }
-    }
-}
-
-void QSGTextInput::updateCursorRectangle()
-{
-    Q_D(QSGTextInput);
-    d->determineHorizontalAlignment();
-    d->updateHorizontalScroll();
-    updateRect();//TODO: Only update rect between pos's
-    updateMicroFocus();
-    emit cursorRectangleChanged();
-    if (d->cursorItem)
-        d->cursorItem->setX(d->control->cursorToX() - d->hscroll);
-}
-
-void QSGTextInput::selectionChanged()
-{
-    Q_D(QSGTextInput);
-    updateRect();//TODO: Only update rect in selection
-    emit selectedTextChanged();
-
-    if (d->lastSelectionStart != d->control->selectionStart()) {
-        d->lastSelectionStart = d->control->selectionStart();
-        if (d->lastSelectionStart == -1)
-            d->lastSelectionStart = d->control->cursor();
-        emit selectionStartChanged();
-    }
-    if (d->lastSelectionEnd != d->control->selectionEnd()) {
-        d->lastSelectionEnd = d->control->selectionEnd();
-        if (d->lastSelectionEnd == -1)
-            d->lastSelectionEnd = d->control->cursor();
-        emit selectionEndChanged();
-    }
-}
-
-void QSGTextInput::q_textChanged()
-{
-    Q_D(QSGTextInput);
-    emit textChanged();
-    emit displayTextChanged();
-    updateSize();
-    d->determineHorizontalAlignment();
-    d->updateHorizontalScroll();
-    updateMicroFocus();
-    if (hasAcceptableInput() != d->oldValidity) {
-        d->oldValidity = hasAcceptableInput();
-        emit acceptableInputChanged();
-    }
-}
-
-void QSGTextInputPrivate::showCursor()
-{
-    if (textNode != 0 && textNode->cursorNode() != 0)
-        textNode->cursorNode()->setColor(color);
-}
-
-void QSGTextInputPrivate::hideCursor()
-{
-    if (textNode != 0 && textNode->cursorNode() != 0)
-        textNode->cursorNode()->setColor(QColor(0, 0, 0, 0));
-}
-
-void QSGTextInput::updateRect(const QRect &r)
-{
-    Q_D(QSGTextInput);
-    if (!isComponentComplete())
-        return;
-
-    if (r.isEmpty()) {
-        d->textLayoutDirty = true;
-    }
-
-    update();
-}
-
-QRectF QSGTextInput::boundingRect() const
-{
-    Q_D(const QSGTextInput);
-    QRectF r = QSGImplicitSizeItem::boundingRect();
-
-    int cursorWidth = d->cursorItem ? d->cursorItem->width() : d->control->cursorWidth();
-
-    // Could include font max left/right bearings to either side of rectangle.
-
-    r.setRight(r.right() + cursorWidth);
-    return r;
-}
-
-void QSGTextInput::updateSize(bool needsRedraw)
-{
-    Q_D(QSGTextInput);
-    int w = width();
-    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)
-        update();
-}
-
-void QSGTextInput::q_canPasteChanged()
-{
-    Q_D(QSGTextInput);
-    bool old = d->canPaste;
-#ifndef QT_NO_CLIPBOARD
-    d->canPaste = !d->control->isReadOnly() && QGuiApplication::clipboard()->text().length() != 0;
-#endif
-    if (d->canPaste != old)
-        emit canPasteChanged();
-}
-
-QT_END_NAMESPACE
-
diff --git a/src/declarative/items/qsgtextinput_p.h b/src/declarative/items/qsgtextinput_p.h
deleted file mode 100644 (file)
index 6addc94..0000000
+++ /dev/null
@@ -1,303 +0,0 @@
-// Commit: 2f173e4945dd8414636c1061acfaf9c2d8b718d8
-/****************************************************************************
-**
-** 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 QSGTEXTINPUT_P_H
-#define QSGTEXTINPUT_P_H
-
-#include "qsgimplicitsizeitem_p.h"
-#include <QtGui/qvalidator.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGTextInputPrivate;
-class QValidator;
-class Q_AUTOTEST_EXPORT QSGTextInput : public QSGImplicitSizeItem
-{
-    Q_OBJECT
-    Q_ENUMS(HAlignment)
-    Q_ENUMS(EchoMode)
-    Q_ENUMS(SelectionMode)
-
-    Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
-    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
-    Q_PROPERTY(QColor selectionColor READ selectionColor WRITE setSelectionColor NOTIFY selectionColorChanged)
-    Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor NOTIFY selectedTextColorChanged)
-    Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
-    Q_PROPERTY(HAlignment horizontalAlignment READ hAlign WRITE setHAlign RESET resetHAlign NOTIFY horizontalAlignmentChanged)
-    Q_PROPERTY(HAlignment effectiveHorizontalAlignment READ effectiveHAlign NOTIFY effectiveHorizontalAlignmentChanged)
-
-    Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged)
-    Q_PROPERTY(bool cursorVisible READ isCursorVisible WRITE setCursorVisible NOTIFY cursorVisibleChanged)
-    Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged)
-    Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged)
-    Q_PROPERTY(QDeclarativeComponent *cursorDelegate READ cursorDelegate WRITE setCursorDelegate NOTIFY cursorDelegateChanged)
-    Q_PROPERTY(int selectionStart READ selectionStart NOTIFY selectionStartChanged)
-    Q_PROPERTY(int selectionEnd READ selectionEnd NOTIFY selectionEndChanged)
-    Q_PROPERTY(QString selectedText READ selectedText NOTIFY selectedTextChanged)
-
-    Q_PROPERTY(int maximumLength READ maxLength WRITE setMaxLength NOTIFY maximumLengthChanged)
-#ifndef QT_NO_VALIDATOR
-    Q_PROPERTY(QValidator* validator READ validator WRITE setValidator NOTIFY validatorChanged)
-#endif
-    Q_PROPERTY(QString inputMask READ inputMask WRITE setInputMask NOTIFY inputMaskChanged)
-    Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ imHints WRITE setIMHints)
-
-    Q_PROPERTY(bool acceptableInput READ hasAcceptableInput NOTIFY acceptableInputChanged)
-    Q_PROPERTY(EchoMode echoMode READ echoMode WRITE setEchoMode NOTIFY echoModeChanged)
-    Q_PROPERTY(bool activeFocusOnPress READ focusOnPress WRITE setFocusOnPress NOTIFY activeFocusOnPressChanged)
-    Q_PROPERTY(QString passwordCharacter READ passwordCharacter WRITE setPasswordCharacter NOTIFY passwordCharacterChanged)
-    Q_PROPERTY(QString displayText READ displayText NOTIFY displayTextChanged)
-    Q_PROPERTY(bool autoScroll READ autoScroll WRITE setAutoScroll NOTIFY autoScrollChanged)
-    Q_PROPERTY(bool selectByMouse READ selectByMouse WRITE setSelectByMouse NOTIFY selectByMouseChanged)
-    Q_PROPERTY(SelectionMode mouseSelectionMode READ mouseSelectionMode WRITE setMouseSelectionMode NOTIFY mouseSelectionModeChanged)
-    Q_PROPERTY(bool canPaste READ canPaste NOTIFY canPasteChanged)
-    Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged)
-
-public:
-    QSGTextInput(QSGItem * parent=0);
-    ~QSGTextInput();
-
-    enum EchoMode {//To match QLineEdit::EchoMode
-        Normal,
-        NoEcho,
-        Password,
-        PasswordEchoOnEdit
-    };
-
-    enum HAlignment {
-        AlignLeft = Qt::AlignLeft,
-        AlignRight = Qt::AlignRight,
-        AlignHCenter = Qt::AlignHCenter
-    };
-
-    enum SelectionMode {
-        SelectCharacters,
-        SelectWords
-    };
-
-    enum CursorPosition {
-        CursorBetweenCharacters,
-        CursorOnCharacter
-    };
-
-    //Auxilliary functions needed to control the TextInput from QML
-    Q_INVOKABLE int positionAt(int x) const;
-    Q_INVOKABLE int positionAt(int x, CursorPosition position) const;
-    Q_INVOKABLE QRectF positionToRectangle(int pos) const;
-    Q_INVOKABLE void moveCursorSelection(int pos);
-    Q_INVOKABLE void moveCursorSelection(int pos, SelectionMode mode);
-
-    Q_INVOKABLE void openSoftwareInputPanel();
-    Q_INVOKABLE void closeSoftwareInputPanel();
-
-    QString text() const;
-    void setText(const QString &);
-
-    QFont font() const;
-    void setFont(const QFont &font);
-
-    QColor color() const;
-    void setColor(const QColor &c);
-
-    QColor selectionColor() const;
-    void setSelectionColor(const QColor &c);
-
-    QColor selectedTextColor() const;
-    void setSelectedTextColor(const QColor &c);
-
-    HAlignment hAlign() const;
-    void setHAlign(HAlignment align);
-    void resetHAlign();
-    HAlignment effectiveHAlign() const;
-
-    bool isReadOnly() const;
-    void setReadOnly(bool);
-
-    bool isCursorVisible() const;
-    void setCursorVisible(bool on);
-
-    int cursorPosition() const;
-    void setCursorPosition(int cp);
-
-    QRect cursorRectangle() const;
-
-    int selectionStart() const;
-    int selectionEnd() const;
-
-    QString selectedText() const;
-
-    int maxLength() const;
-    void setMaxLength(int ml);
-
-#ifndef QT_NO_VALIDATOR
-    QValidator * validator() const;
-    void setValidator(QValidator* v);
-#endif
-    QString inputMask() const;
-    void setInputMask(const QString &im);
-
-    EchoMode echoMode() const;
-    void setEchoMode(EchoMode echo);
-
-    QString passwordCharacter() const;
-    void setPasswordCharacter(const QString &str);
-
-    QString displayText() const;
-
-    QDeclarativeComponent* cursorDelegate() const;
-    void setCursorDelegate(QDeclarativeComponent*);
-
-    bool focusOnPress() const;
-    void setFocusOnPress(bool);
-
-    bool autoScroll() const;
-    void setAutoScroll(bool);
-
-    bool selectByMouse() const;
-    void setSelectByMouse(bool);
-
-    SelectionMode mouseSelectionMode() const;
-    void setMouseSelectionMode(SelectionMode mode);
-
-    bool hasAcceptableInput() const;
-
-    QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
-
-    QRectF boundingRect() const;
-    bool canPaste() const;
-
-    bool isInputMethodComposing() const;
-
-    Qt::InputMethodHints imHints() const;
-    void setIMHints(Qt::InputMethodHints hints);
-
-Q_SIGNALS:
-    void textChanged();
-    void cursorPositionChanged();
-    void cursorRectangleChanged();
-    void selectionStartChanged();
-    void selectionEndChanged();
-    void selectedTextChanged();
-    void accepted();
-    void acceptableInputChanged();
-    void colorChanged(const QColor &color);
-    void selectionColorChanged(const QColor &color);
-    void selectedTextColorChanged(const QColor &color);
-    void fontChanged(const QFont &font);
-    void horizontalAlignmentChanged(HAlignment alignment);
-    void readOnlyChanged(bool isReadOnly);
-    void cursorVisibleChanged(bool isCursorVisible);
-    void cursorDelegateChanged();
-    void maximumLengthChanged(int maximumLength);
-    void validatorChanged();
-    void inputMaskChanged(const QString &inputMask);
-    void echoModeChanged(EchoMode echoMode);
-    void passwordCharacterChanged();
-    void displayTextChanged();
-    void activeFocusOnPressChanged(bool activeFocusOnPress);
-    void autoScrollChanged(bool autoScroll);
-    void selectByMouseChanged(bool selectByMouse);
-    void mouseSelectionModeChanged(SelectionMode mode);
-    void canPasteChanged();
-    void inputMethodComposingChanged();
-    void effectiveHorizontalAlignmentChanged();
-
-protected:
-    virtual void geometryChanged(const QRectF &newGeometry,
-                                 const QRectF &oldGeometry);
-
-    void mousePressEvent(QMouseEvent *event);
-    void mouseMoveEvent(QMouseEvent *event);
-    void mouseReleaseEvent(QMouseEvent *event);
-    void mouseDoubleClickEvent(QMouseEvent *event);
-    bool sceneEvent(QEvent *event);
-    void keyPressEvent(QKeyEvent* ev);
-    void inputMethodEvent(QInputMethodEvent *);
-    void mouseUngrabEvent();
-    bool event(QEvent *e);
-    void focusInEvent(QFocusEvent *event);
-    virtual void itemChange(ItemChange, const ItemChangeData &);
-    QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data);
-
-public Q_SLOTS:
-    void selectAll();
-    void selectWord();
-    void select(int start, int end);
-    void deselect();
-    bool isRightToLeft(int start, int end);
-#ifndef QT_NO_CLIPBOARD
-    void cut();
-    void copy();
-    void paste();
-#endif
-
-private Q_SLOTS:
-    void updateSize(bool needsRedraw = true);
-    void q_textChanged();
-    void selectionChanged();
-    void createCursor();
-    void cursorPosChanged();
-    void updateCursorRectangle();
-    void updateRect(const QRect &r = QRect());
-    void q_canPasteChanged();
-
-private:
-    Q_DECLARE_PRIVATE(QSGTextInput)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGTextInput)
-#ifndef QT_NO_VALIDATOR
-QML_DECLARE_TYPE(QValidator)
-QML_DECLARE_TYPE(QIntValidator)
-QML_DECLARE_TYPE(QDoubleValidator)
-QML_DECLARE_TYPE(QRegExpValidator)
-#endif
-
-QT_END_HEADER
-
-#endif // QSGTEXTINPUT_P_H
diff --git a/src/declarative/items/qsgtextinput_p_p.h b/src/declarative/items/qsgtextinput_p_p.h
deleted file mode 100644 (file)
index ed2395b..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-// Commit: 47712d1f330e4b22ce6dd30e7557288ef7f7fca0
-/****************************************************************************
-**
-** 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 QSGTEXTINPUT_P_P_H
-#define QSGTEXTINPUT_P_P_H
-
-#include "qsgtextinput_p.h"
-#include "qsgtext_p.h"
-#include "qsgimplicitsizeitem_p_p.h"
-
-#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>
-
-
-//
-//  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 QSGTextNode;
-
-class Q_AUTOTEST_EXPORT QSGTextInputPrivate : public QSGImplicitSizeItemPrivate
-{
-    Q_DECLARE_PUBLIC(QSGTextInput)
-public:
-    QSGTextInputPrivate()
-                 : control(new QLineControl(QString()))
-                 , color((QRgb)0)
-                 , style(QSGText::Normal)
-                 , styleColor((QRgb)0)
-                 , hAlign(QSGTextInput::AlignLeft)
-                 , mouseSelectionMode(QSGTextInput::SelectCharacters)
-                 , inputMethodHints(Qt::ImhNone)
-                 , textNode(0)
-                 , hscroll(0)
-                 , oldScroll(0)
-                 , oldValidity(false)
-                 , focused(false)
-                 , focusOnPress(true)
-                 , cursorVisible(false)
-                 , autoScroll(true)
-                 , selectByMouse(false)
-                 , canPaste(false)
-                 , hAlignImplicit(true)
-                 , selectPressed(false)
-                 , textLayoutDirty(true)
-    {
-    }
-
-    ~QSGTextInputPrivate()
-    {
-    }
-
-    int xToPos(int x, QTextLine::CursorPosition betweenOrOn = QTextLine::CursorBetweenCharacters) const
-    {
-        Q_Q(const QSGTextInput);
-        QRect cr = q->boundingRect().toRect();
-        x-= cr.x() - hscroll;
-        return control->xToPos(x, betweenOrOn);
-    }
-
-    void init();
-    void startCreatingCursor();
-    void updateHorizontalScroll();
-    bool determineHorizontalAlignment();
-    bool setHAlign(QSGTextInput::HAlignment, bool forceAlign = false);
-    void mirrorChange();
-    int calculateTextWidth();
-    bool sendMouseEventToInputContext(QMouseEvent *event);
-    void updateInputMethodHints();
-    void hideCursor();
-    void showCursor();
-
-    QLineControl* control;
-
-    QFont font;
-    QFont sourceFont;
-    QColor  color;
-    QColor  selectionColor;
-    QColor  selectedTextColor;
-    QSGText::TextStyle style;
-    QColor  styleColor;
-    QSGTextInput::HAlignment hAlign;
-    QSGTextInput::SelectionMode mouseSelectionMode;
-    Qt::InputMethodHints inputMethodHints;
-    QPointer<QDeclarativeComponent> cursorComponent;
-    QPointer<QSGItem> cursorItem;
-    QPointF pressPos;
-    QSGTextNode *textNode;
-    QElapsedTimer tripleClickTimer;
-    QPoint tripleClickStartPoint;
-
-    int lastSelectionStart;
-    int lastSelectionEnd;
-    int oldHeight;
-    int oldWidth;
-    int hscroll;
-    int oldScroll;
-
-    bool oldValidity:1;
-    bool focused:1;
-    bool focusOnPress:1;
-    bool cursorVisible:1;
-    bool autoScroll:1;
-    bool selectByMouse:1;
-    bool canPaste:1;
-    bool hAlignImplicit:1;
-    bool selectPressed:1;
-    bool textLayoutDirty:1;
-
-    static inline QSGTextInputPrivate *get(QSGTextInput *t) {
-        return t->d_func();
-    }
-    bool hasPendingTripleClick() const {
-        return !tripleClickTimer.hasExpired(qApp->styleHints()->mouseDoubleClickInterval());
-    }
-};
-
-QT_END_NAMESPACE
-
-#endif // QSGTEXTINPUT_P_P_H
diff --git a/src/declarative/items/qsgtextnode.cpp b/src/declarative/items/qsgtextnode.cpp
deleted file mode 100644 (file)
index f712bd7..0000000
+++ /dev/null
@@ -1,1343 +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$
-**
-****************************************************************************/
-
-#include "qsgtextnode_p.h"
-#include "qsgsimplerectnode.h"
-#include <private/qsgadaptationlayer_p.h>
-#include <private/qsgdistancefieldglyphcache_p.h>
-#include <private/qsgdistancefieldglyphnode_p.h>
-
-#include <private/qsgcontext_p.h>
-
-#include <QtCore/qpoint.h>
-#include <qmath.h>
-#include <qtextdocument.h>
-#include <qtextlayout.h>
-#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
-
-/*!
-  Creates an empty QSGTextNode
-*/
-QSGTextNode::QSGTextNode(QSGContext *context)
-    : m_context(context), m_cursorNode(0)
-{
-#if defined(QML_RUNTIME_TESTING)
-    description = QLatin1String("text");
-#endif
-}
-
-QSGTextNode::~QSGTextNode()
-{
-    qDeleteAll(m_textures);
-}
-
-#if 0
-void QSGTextNode::setColor(const QColor &color)
-{
-    if (m_usePixmapCache) {
-        setUpdateFlag(UpdateNodes);
-    } else {
-        for (QSGNode *childNode = firstChild(); childNode; childNode = childNode->nextSibling()) {
-            if (childNode->subType() == GlyphNodeSubType) {
-                QSGGlyphNode *glyphNode = static_cast<QSGGlyphNode *>(childNode);
-                if (glyphNode->color() == m_color)
-                    glyphNode->setColor(color);
-            } else if (childNode->subType() == SolidRectNodeSubType) {
-                QSGSimpleRectNode *solidRectNode = static_cast<QSGSimpleRectNode *>(childNode);
-                if (solidRectNode->color() == m_color)
-                    solidRectNode->setColor(color);
-            }
-        }
-    }
-    m_color = color;
-}
-
-void QSGTextNode::setStyleColor(const QColor &styleColor)
-{
-    if (m_textStyle != QSGTextNode::NormalTextStyle) {
-        if (m_usePixmapCache) {
-            setUpdateFlag(UpdateNodes);
-        } else {
-            for (QSGNode *childNode = firstChild(); childNode; childNode = childNode->nextSibling()) {
-                if (childNode->subType() == GlyphNodeSubType) {
-                    QSGGlyphNode *glyphNode = static_cast<QSGGlyphNode *>(childNode);
-                    if (glyphNode->color() == m_styleColor)
-                        glyphNode->setColor(styleColor);
-                } else if (childNode->subType() == SolidRectNodeSubType) {
-                    QSGSimpleRectNode *solidRectNode = static_cast<QSGSimpleRectNode *>(childNode);
-                    if (solidRectNode->color() == m_styleColor)
-                        solidRectNode->setColor(styleColor);
-                }
-            }
-        }
-    }
-    m_styleColor = styleColor;
-}
-#endif
-
-QSGGlyphNode *QSGTextNode::addGlyphs(const QPointF &position, const QGlyphRun &glyphs, const QColor &color,
-                                     QSGText::TextStyle style, const QColor &styleColor,
-                                     QSGNode *parentNode)
-{
-    QSGGlyphNode *node = m_context->createGlyphNode();
-    node->setGlyphs(position + QPointF(0, glyphs.rawFont().ascent()), glyphs);
-    node->setStyle(style);
-    node->setStyleColor(styleColor);
-    node->setColor(color);
-    node->update();
-
-    /* We flag the geometry as static, but we never call markVertexDataDirty
-       or markIndexDataDirty on them. This is because all text nodes are
-       discarded when a change occurs. If we start appending/removing from
-       existing geometry, then we also need to start marking the geometry as
-       dirty.
-     */
-    node->geometry()->setIndexDataPattern(QSGGeometry::StaticPattern);
-    node->geometry()->setVertexDataPattern(QSGGeometry::StaticPattern);
-
-    if (parentNode == 0)
-        parentNode = this;
-    parentNode->appendChildNode(node);
-
-    return node;
-}
-
-void QSGTextNode::setCursor(const QRectF &rect, const QColor &color)
-{
-    if (m_cursorNode != 0)
-        delete m_cursorNode;
-
-    m_cursorNode = new QSGSimpleRectNode(rect, color);
-    appendChildNode(m_cursorNode);
-}
-
-namespace {
-
-    struct BinaryTreeNode {
-        enum SelectionState {
-            Unselected,
-            Selected
-        };
-
-        BinaryTreeNode()
-            : 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, qreal a)
-            : glyphRun(g)
-            , boundingRect(brect)
-            , selectionState(selState)
-            , clipNode(0)
-            , decorations(decs)
-            , color(c)
-            , backgroundColor(bc)
-            , position(pos)
-            , ascent(a)
-            , leftChildIndex(-1)
-            , rightChildIndex(-1)
-        {
-        }
-
-        QGlyphRun glyphRun;
-        QRectF boundingRect;
-        SelectionState selectionState;
-        QSGClipNode *clipNode;
-        QSGTextNode::Decorations decorations;
-        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)
-        {
-            QRectF searchRect = glyphRun.boundingRect();
-            searchRect.translate(position);
-
-            if (qFuzzyIsNull(searchRect.width()) || qFuzzyIsNull(searchRect.height()))
-                return;
-
-            QSGTextNode::Decorations decorations = QSGTextNode::NoDecoration;
-            decorations |= (glyphRun.underline() ? QSGTextNode::Underline : QSGTextNode::NoDecoration);
-            decorations |= (glyphRun.overline()  ? QSGTextNode::Overline  : QSGTextNode::NoDecoration);
-            decorations |= (glyphRun.strikeOut() ? QSGTextNode::StrikeOut : QSGTextNode::NoDecoration);
-            decorations |= (backgroundColor.isValid() ? QSGTextNode::Background : QSGTextNode::NoDecoration);
-
-            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 (binaryTreeNode.boundingRect.left() < node->boundingRect.left()) {
-                    if (node->leftChildIndex < 0) {
-                        node->leftChildIndex = newIndex;
-                        break;
-                    } else {
-                        searchIndex = node->leftChildIndex;
-                    }
-                } else {
-                    if (node->rightChildIndex < 0) {
-                        node->rightChildIndex = newIndex;
-                        break;
-                    } else {
-                        searchIndex = node->rightChildIndex;
-                    }
-                }
-            }
-        }
-
-        static void inOrder(const QVarLengthArray<BinaryTreeNode> &binaryTree,
-                            QVarLengthArray<int> *sortedIndexes,
-                            int currentIndex = 0)
-        {
-            Q_ASSERT(currentIndex < binaryTree.size());
-
-            const BinaryTreeNode *node = binaryTree.data() + currentIndex;
-            if (node->leftChildIndex >= 0)
-                inOrder(binaryTree, sortedIndexes, node->leftChildIndex);
-
-            sortedIndexes->append(currentIndex);
-
-            if (node->rightChildIndex >= 0)
-                inOrder(binaryTree, sortedIndexes, node->rightChildIndex);
-        }
-    };
-
-    // Engine that takes glyph runs as input, and produces a set of glyph nodes, clip nodes,
-    // and rectangle nodes to represent the text, decorations and selection. Will try to minimize
-    // number of nodes, and join decorations in neighbouring items
-    class SelectionEngine
-    {
-    public:
-        SelectionEngine() : m_hasSelection(false) {}
-
-        QTextLine currentLine() const { return m_currentLine; }
-
-        void setCurrentLine(const QTextLine &currentLine)
-        {
-            if (m_currentLine.isValid())
-                processCurrentLine();
-
-            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,
-                              const QColor &color, const QColor &backgroundColor,
-                              int selectionStart, int selectionEnd);
-        void addGlyphsForRanges(const QVarLengthArray<QTextLayout::FormatRange> &ranges,
-                                int start, int end,
-                                int selectionStart, int selectionEnd);
-
-        void addToSceneGraph(QSGTextNode *parent,
-                             QSGText::TextStyle style = QSGText::Normal,
-                             const QColor &styleColor = QColor());
-
-        void setSelectionColor(const QColor &selectionColor)
-        {
-            m_selectionColor = selectionColor;
-        }
-
-        void setSelectedTextColor(const QColor &selectedTextColor)
-        {
-            m_selectedTextColor = selectedTextColor;
-        }
-
-        void setTextColor(const QColor &textColor)
-        {
-            m_textColor = textColor;
-        }
-
-        void setPosition(const QPointF &position)
-        {
-            m_position = position;
-        }
-
-    private:
-        struct TextDecoration
-        {
-            TextDecoration() : selectionState(BinaryTreeNode::Unselected) {}
-            TextDecoration(const BinaryTreeNode::SelectionState &s,
-                           const QRectF &r,
-                           const QColor &c)
-                : selectionState(s)
-                , rect(r)
-                , color(c)
-            {
-            }
-
-            BinaryTreeNode::SelectionState selectionState;
-            QRectF rect;
-            QColor color;
-        };
-
-        void processCurrentLine();
-        void addTextDecorations(const QVarLengthArray<TextDecoration> &textDecorations,
-                                qreal offset, qreal thickness);
-
-        QColor m_selectionColor;
-        QColor m_textColor;
-        QColor m_backgroundColor;
-        QColor m_selectedTextColor;
-        QPointF m_position;
-
-        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,
-                                             qreal offset, qreal thickness)
-    {
-        for (int i=0; i<textDecorations.size(); ++i) {
-            TextDecoration textDecoration = textDecorations.at(i);
-
-            {
-                QRectF &rect = textDecoration.rect;
-                rect.setY(qRound(rect.y() + m_currentLine.ascent() + offset));
-                rect.setHeight(thickness);
-            }
-
-            m_lines.append(textDecoration);
-        }
-    }
-
-    void SelectionEngine::processCurrentLine()
-    {
-        // No glyphs, do nothing
-        if (m_currentLineTree.isEmpty())
-            return;
-
-        // 1. Go through current line and get correct decoration position for each node based on
-        // neighbouring decorations. Add decoration to global list
-        // 2. Create clip nodes for all selected text. Try to merge as many as possible within
-        // the line.
-        // 3. Add QRects to a list of selection rects.
-        // 4. Add all nodes to a global processed list
-        QVarLengthArray<int> sortedIndexes; // Indexes in tree sorted by x position
-        BinaryTreeNode::inOrder(m_currentLineTree, &sortedIndexes);
-
-        Q_ASSERT(sortedIndexes.size() == m_currentLineTree.size());
-
-        BinaryTreeNode::SelectionState currentSelectionState = BinaryTreeNode::Unselected;
-        QRectF currentRect;
-
-        QSGTextNode::Decorations currentDecorations = QSGTextNode::NoDecoration;
-        qreal underlineOffset = 0.0;
-        qreal underlineThickness = 0.0;
-
-        qreal overlineOffset = 0.0;
-        qreal overlineThickness = 0.0;
-
-        qreal strikeOutOffset = 0.0;
-        qreal strikeOutThickness = 0.0;
-
-        QRectF decorationRect = currentRect;
-
-        QColor lastColor;
-        QColor lastBackgroundColor;
-
-        QVarLengthArray<TextDecoration> pendingUnderlines;
-        QVarLengthArray<TextDecoration> pendingOverlines;
-        QVarLengthArray<TextDecoration> pendingStrikeOuts;
-        if (!sortedIndexes.isEmpty()) {
-            QSGClipNode *currentClipNode = m_hasSelection ? new QSGClipNode : 0;
-            bool currentClipNodeUsed = false;
-            for (int i=0; i<=sortedIndexes.size(); ++i) {
-                BinaryTreeNode *node = 0;
-                if (i < sortedIndexes.size()) {
-                    int sortedIndex = sortedIndexes.at(i);
-                    Q_ASSERT(sortedIndex < m_currentLineTree.size());
-
-                    node = m_currentLineTree.data() + sortedIndex;
-                }
-
-                if (i == 0)
-                    currentSelectionState = node->selectionState;
-
-                // Update decorations
-                if (currentDecorations != QSGTextNode::NoDecoration) {
-                    decorationRect.setY(m_position.y() + m_currentLine.y());
-                    decorationRect.setHeight(m_currentLine.height());
-
-                    if (node != 0)
-                        decorationRect.setRight(node->boundingRect.left());
-
-                    TextDecoration textDecoration(currentSelectionState, decorationRect, lastColor);
-                    if (currentDecorations & QSGTextNode::Underline)
-                        pendingUnderlines.append(textDecoration);
-
-                    if (currentDecorations & QSGTextNode::Overline)
-                        pendingOverlines.append(textDecoration);
-
-                    if (currentDecorations & QSGTextNode::StrikeOut)
-                        pendingStrikeOuts.append(textDecoration);
-
-                    if (currentDecorations & QSGTextNode::Background)
-                        m_backgrounds.append(qMakePair(decorationRect, lastBackgroundColor));
-                }
-
-                // If we've reached an unselected node from a selected node, we add the
-                // selection rect to the graph, and we add decoration every time the
-                // selection state changes, because that means the text color changes
-                if (node == 0 || node->selectionState != currentSelectionState) {
-                    if (node != 0)
-                        currentRect.setRight(node->boundingRect.left());
-                    currentRect.setY(m_position.y() + m_currentLine.y());
-                    currentRect.setHeight(m_currentLine.height());
-
-                    // Draw selection all the way up to the left edge of the unselected item
-                    if (currentSelectionState == BinaryTreeNode::Selected)
-                        m_selectionRects.append(currentRect);
-
-                    if (currentClipNode != 0) {
-                        if (!currentClipNodeUsed) {
-                            delete currentClipNode;
-                        } else {
-                            currentClipNode->setIsRectangular(true);
-                            currentClipNode->setClipRect(currentRect);
-                        }
-                    }
-
-                    if (node != 0 && m_hasSelection)
-                        currentClipNode = new QSGClipNode;
-                    else
-                        currentClipNode = 0;
-                    currentClipNodeUsed = false;
-
-                    if (node != 0) {
-                        currentSelectionState = node->selectionState;
-                        currentRect = node->boundingRect;
-
-                        // Make sure currentRect is valid, otherwise the unite won't work
-                        if (currentRect.isNull())
-                            currentRect.setSize(QSizeF(1, 1));
-                    }
-                } else {
-                    if (currentRect.isNull())
-                        currentRect = node->boundingRect;
-                    else
-                        currentRect = currentRect.united(node->boundingRect);
-                }
-
-                if (node != 0) {
-                    node->clipNode = currentClipNode;
-                    currentClipNodeUsed = true;
-
-                    decorationRect = node->boundingRect;
-
-                    // 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()
-                      && !(node->decorations & QSGTextNode::Underline)) {
-                        addTextDecorations(pendingUnderlines, underlineOffset, underlineThickness);
-
-                        pendingUnderlines.clear();
-
-                        underlineOffset = 0.0;
-                        underlineThickness = 0.0;
-                    }
-
-                    // ### Add pending when overlineOffset/thickness changes to minimize number of
-                    // nodes
-                    if (!pendingOverlines.isEmpty()) {
-                        addTextDecorations(pendingOverlines, overlineOffset, overlineThickness);
-
-                        pendingOverlines.clear();
-
-                        overlineOffset = 0.0;
-                        overlineThickness = 0.0;
-                    }
-
-                    // ### Add pending when overlineOffset/thickness changes to minimize number of
-                    // nodes
-                    if (!pendingStrikeOuts.isEmpty()) {
-                        addTextDecorations(pendingStrikeOuts, strikeOutOffset, strikeOutThickness);
-
-                        pendingStrikeOuts.clear();
-
-                        strikeOutOffset = 0.0;
-                        strikeOutThickness = 0.0;
-                    }
-
-                    // Merge current values with previous. Prefer greatest thickness
-                    QRawFont rawFont = node->glyphRun.rawFont();
-                    if (node->decorations & QSGTextNode::Underline) {
-                        if (rawFont.lineThickness() > underlineThickness) {
-                            underlineThickness = rawFont.lineThickness();
-                            underlineOffset = rawFont.underlinePosition();
-                        }
-                    }
-
-                    if (node->decorations & QSGTextNode::Overline) {
-                        overlineOffset = -rawFont.ascent();
-                        overlineThickness = rawFont.lineThickness();
-                    }
-
-                    if (node->decorations & QSGTextNode::StrikeOut) {
-                        strikeOutThickness = rawFont.lineThickness();
-                        strikeOutOffset = rawFont.ascent() / -3.0;
-                    }
-
-                    currentDecorations = node->decorations;
-                    lastColor = node->color;
-                    lastBackgroundColor = node->backgroundColor;
-                    m_processedNodes.append(*node);
-                }
-            }
-
-            if (!pendingUnderlines.isEmpty())
-                addTextDecorations(pendingUnderlines, underlineOffset, underlineThickness);
-
-            if (!pendingOverlines.isEmpty())
-                addTextDecorations(pendingOverlines, overlineOffset, overlineThickness);
-
-            if (!pendingStrikeOuts.isEmpty())
-                addTextDecorations(pendingStrikeOuts, strikeOutOffset, strikeOutThickness);
-        }
-
-        m_currentLineTree.clear();
-        m_currentLine = QTextLine();
-        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,
-                               m_textColor, m_backgroundColor, m_position);
-    }
-
-    void SelectionEngine::addSelectedGlyphs(const QGlyphRun &glyphRun)
-    {
-        int currentSize = m_currentLineTree.size();
-        BinaryTreeNode::insert(&m_currentLineTree, glyphRun, BinaryTreeNode::Selected,
-                               m_textColor, m_backgroundColor, m_position);
-        m_hasSelection = m_hasSelection || m_currentLineTree.size() > currentSize;
-    }
-
-    void SelectionEngine::addGlyphsForRanges(const QVarLengthArray<QTextLayout::FormatRange> &ranges,
-                                             int start, int end,
-                                             int selectionStart, int selectionEnd)
-    {
-        int currentPosition = start;
-        int remainingLength = end - start;
-        for (int j=0; j<ranges.size(); ++j) {
-            const QTextLayout::FormatRange &range = ranges.at(j);
-            if (range.start + range.length >= currentPosition
-                && range.start < currentPosition + remainingLength) {
-
-                if (range.start > currentPosition) {
-                    addGlyphsInRange(currentPosition, range.start - currentPosition,
-                                     QColor(), QColor(), selectionStart, selectionEnd);
-                }
-
-                int rangeEnd = qMin(range.start + range.length, currentPosition + remainingLength);
-                QColor rangeColor = range.format.hasProperty(QTextFormat::ForegroundBrush)
-                        ? range.format.foreground().color()
-                        : QColor();
-                QColor rangeBackgroundColor = range.format.hasProperty(QTextFormat::BackgroundBrush)
-                        ? range.format.background().color()
-                        : QColor();
-
-                addGlyphsInRange(range.start, rangeEnd - range.start,
-                                 rangeColor, rangeBackgroundColor,
-                                 selectionStart, selectionEnd);
-
-                currentPosition = range.start + range.length;
-                remainingLength = end - currentPosition;
-
-            } else if (range.start > currentPosition + remainingLength || remainingLength <= 0) {
-                break;
-            }
-        }
-
-        if (remainingLength > 0) {
-            addGlyphsInRange(currentPosition, remainingLength, QColor(), QColor(),
-                             selectionStart, selectionEnd);
-        }
-
-    }
-
-    void SelectionEngine::addGlyphsInRange(int rangeStart, int rangeLength,
-                                           const QColor &color, const QColor &backgroundColor,
-                                           int selectionStart, int selectionEnd)
-    {
-        QColor oldColor;
-        if (color.isValid()) {
-            oldColor = m_textColor;
-            m_textColor = color;
-        }
-
-        QColor oldBackgroundColor = m_backgroundColor;
-        if (backgroundColor.isValid()) {
-            oldBackgroundColor = m_backgroundColor;
-            m_backgroundColor = backgroundColor;
-        }
-
-        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) {
-                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) {
-                    const QGlyphRun &glyphRun = glyphRuns.at(j);
-                    addUnselectedGlyphs(glyphRun);
-                }
-            }
-
-            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) {
-                    const QGlyphRun &glyphRun = glyphRuns.at(j);
-                    addSelectedGlyphs(glyphRun);
-                }
-            }
-
-            if (selectionEnd >= rangeStart && selectionEnd < rangeEnd) {
-                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);
-                }
-            }
-        }
-
-        if (backgroundColor.isValid())
-            m_backgroundColor = oldBackgroundColor;
-
-        if (oldColor.isValid())
-            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)
-    {
-        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);
-
-            parentNode->appendChildNode(new QSGSimpleRectNode(rect, m_selectionColor));
-        }
-
-        // Finally, add decorations for each node to the tree.
-        for (int i=0; i<m_lines.size(); ++i) {
-            const TextDecoration &textDecoration = m_lines.at(i);
-
-            QColor color = textDecoration.selectionState == BinaryTreeNode::Selected
-                    ? m_selectedTextColor
-                    : textDecoration.color;
-
-            parentNode->appendChildNode(new QSGSimpleRectNode(textDecoration.rect, color));
-        }
-
-        // Then, go through all the nodes for all lines and combine all QGlyphRuns with a common
-        // font, selection state and clip node.
-        typedef QPair<QFontEngine *, QPair<QSGClipNode *, QPair<QRgb, int> > > KeyType;
-        QHash<KeyType, BinaryTreeNode *> map;
-        for (int i=0; i<m_processedNodes.size(); ++i) {
-            BinaryTreeNode *node = m_processedNodes.data() + i;
-
-            if (node->image.isNull()) {
-                QGlyphRun glyphRun = node->glyphRun;
-                QRawFont rawFont = glyphRun.rawFont();
-                QRawFontPrivate *rawFontD = QRawFontPrivate::get(rawFont);
-
-                QFontEngine *fontEngine = rawFontD->fontEngine;
-
-                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;
-
-                    QVector<quint32> otherGlyphIndexes = otherGlyphRun.glyphIndexes();
-                    QVector<QPointF> otherGlyphPositions = otherGlyphRun.positions();
-
-                    otherGlyphIndexes += glyphRun.glyphIndexes();
-
-                    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);
-
-                } else {
-                    map.insert(key, node);
-                }
-            } else {
-                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));
-                }
-            }
-        }
-
-        // ...and add clip nodes and glyphs to tree.
-        QHash<KeyType, BinaryTreeNode *>::const_iterator it = map.constBegin();
-        while (it != map.constEnd()) {
-
-            BinaryTreeNode *node = it.value();
-
-            QSGClipNode *clipNode = node->clipNode;
-            if (clipNode != 0 && clipNode->parent() == 0 )
-                parentNode->appendChildNode(clipNode);
-
-            QColor color = node->selectionState == BinaryTreeNode::Selected
-                    ? m_selectedTextColor
-                    : node->color;
-
-            parentNode->addGlyphs(node->position, node->glyphRun, color, style, styleColor, clipNode);
-
-            ++it;
-        }
-    }
-}
-
-void QSGTextNode::mergeFormats(QTextLayout *textLayout,
-                               QVarLengthArray<QTextLayout::FormatRange> *mergedFormats)
-{
-    Q_ASSERT(mergedFormats != 0);
-    if (textLayout == 0)
-        return;
-
-    QList<QTextLayout::FormatRange> additionalFormats = textLayout->additionalFormats();
-    for (int i=0; i<additionalFormats.size(); ++i) {
-        QTextLayout::FormatRange additionalFormat = additionalFormats.at(i);
-        if (additionalFormat.format.hasProperty(QTextFormat::ForegroundBrush)
-         || additionalFormat.format.hasProperty(QTextFormat::BackgroundBrush)) {
-            // Merge overlapping formats
-            if (!mergedFormats->isEmpty()) {
-                QTextLayout::FormatRange *lastFormat = mergedFormats->data() + mergedFormats->size() - 1;
-
-                if (additionalFormat.start < lastFormat->start + lastFormat->length) {
-                    QTextLayout::FormatRange *mergedRange = 0;
-
-                    int length = additionalFormat.length;
-                    if (additionalFormat.start > lastFormat->start) {
-                        lastFormat->length = additionalFormat.start - lastFormat->start;
-                        length -= lastFormat->length;
-
-                        mergedFormats->append(QTextLayout::FormatRange());
-                        mergedRange = mergedFormats->data() + mergedFormats->size() - 1;
-                        lastFormat = mergedFormats->data() + mergedFormats->size() - 2;
-                    } else {
-                        mergedRange = lastFormat;
-                    }
-
-                    mergedRange->format = lastFormat->format;
-                    mergedRange->format.merge(additionalFormat.format);
-                    mergedRange->start = additionalFormat.start;
-
-                    int end = qMin(additionalFormat.start + additionalFormat.length,
-                                   lastFormat->start + lastFormat->length);
-
-                    mergedRange->length = end - mergedRange->start;
-                    length -= mergedRange->length;
-
-                    additionalFormat.start = end;
-                    additionalFormat.length = length;
-                }
-            }
-
-            if (additionalFormat.length > 0)
-                mergedFormats->append(additionalFormat);
-        }
-    }
-
-}
-
-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)
-{
-    SelectionEngine engine;
-    engine.setTextColor(textColor);
-    engine.setSelectedTextColor(selectedTextColor);
-    engine.setSelectionColor(selectionColor);
-
-    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));
-                    }
-                }
-
-                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;
-                        }
-
-                        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);
-                            }
-
-                            Q_ASSERT(line.textLength() > 0);
-                            int lineEnd = line.textStart() + block.position() + line.textLength();
-
-                            int len = qMin(lineEnd - textPos, fragmentEnd - textPos);
-                            Q_ASSERT(len > 0);
-
-                            int currentStepEnd = textPos + len;
-
-                            engine.addGlyphsForRanges(colorChanges,
-                                                      textPos - block.position(),
-                                                      currentStepEnd - block.position(),
-                                                      selectionStart - block.position(),
-                                                      selectionEnd - block.position());
-
-                            textPos = currentStepEnd;
-                        }
-                    }
-
-                    ++blockIterator;
-                }
-
-                engine.setCurrentLine(QTextLine()); // Reset current line because the text layout changed
-                ++it;
-            }
-        }
-    }
-
-    engine.addToSceneGraph(this, style, styleColor);
-}
-
-void QSGTextNode::addTextLayout(const QPointF &position, QTextLayout *textLayout, const QColor &color,
-                                QSGText::TextStyle style, const QColor &styleColor,
-                                const QColor &selectionColor, const QColor &selectedTextColor,
-                                int selectionStart, int selectionEnd)
-{
-    SelectionEngine engine;
-    engine.setTextColor(color);
-    engine.setSelectedTextColor(selectedTextColor);
-    engine.setSelectionColor(selectionColor);
-    engine.setPosition(position);
-
-    int preeditLength = textLayout->preeditAreaText().length();
-    int preeditPosition = textLayout->preeditAreaPosition();
-
-    QVarLengthArray<QTextLayout::FormatRange> colorChanges;
-    mergeFormats(textLayout, &colorChanges);
-
-    for (int i=0; i<textLayout->lineCount(); ++i) {
-        QTextLine line = textLayout->lineAt(i);
-
-        int start = line.textStart();
-        int length = line.textLength();
-        int end = start + length;
-
-        if (preeditPosition >= 0
-         && preeditPosition >= start
-         && preeditPosition < end) {
-            end += preeditLength;
-        }
-
-        engine.setCurrentLine(line);
-        engine.addGlyphsForRanges(colorChanges, start, end, selectionStart, selectionEnd);
-    }
-
-    engine.addToSceneGraph(this, style, styleColor);
-}
-
-void QSGTextNode::deleteContent()
-{
-    while (firstChild() != 0)
-        delete firstChild();
-    m_cursorNode = 0;
-}
-
-#if 0
-void QSGTextNode::updateNodes()
-{
-    return;
-    deleteContent();
-    if (m_text.isEmpty())
-        return;
-
-    if (m_usePixmapCache) {
-        // ### gunnar: port properly
-//        QPixmap pixmap = generatedPixmap();
-//        if (pixmap.isNull())
-//            return;
-
-//        QSGImageNode *pixmapNode = m_context->createImageNode();
-//        pixmapNode->setRect(pixmap.rect());
-//        pixmapNode->setSourceRect(pixmap.rect());
-//        pixmapNode->setOpacity(m_opacity);
-//        pixmapNode->setClampToEdge(true);
-//        pixmapNode->setLinearFiltering(m_linearFiltering);
-
-//        appendChildNode(pixmapNode);
-    } else {
-        if (m_text.isEmpty())
-            return;
-
-        // Implement styling by drawing text several times at slight shifts. shiftForStyle
-        // contains the sequence of shifted positions at which to draw the text. All except
-        // the last will be drawn with styleColor.
-        QList<QPointF> shiftForStyle;
-        switch (m_textStyle) {
-        case OutlineTextStyle:
-            // ### Should be made faster by implementing outline material
-            shiftForStyle << QPointF(-1, 0);
-            shiftForStyle << QPointF(0, -1);
-            shiftForStyle << QPointF(1, 0);
-            shiftForStyle << QPointF(0, 1);
-            break;
-        case SunkenTextStyle:
-            shiftForStyle << QPointF(0, -1);
-            break;
-        case RaisedTextStyle:
-            shiftForStyle << QPointF(0, 1);
-            break;
-        default:
-            break;
-        }
-
-        shiftForStyle << QPointF(0, 0); // Regular position
-        while (!shiftForStyle.isEmpty()) {
-            QPointF shift = shiftForStyle.takeFirst();
-
-            // Use styleColor for all but last shift
-            if (m_richText) {
-                QColor overrideColor = shiftForStyle.isEmpty() ? QColor() : m_styleColor;
-
-                QTextFrame *textFrame = m_textDocument->rootFrame();
-                QPointF p = m_textDocument->documentLayout()->frameBoundingRect(textFrame).topLeft();
-
-                QTextFrame::iterator it = textFrame->begin();
-                while (!it.atEnd()) {
-                    addTextBlock(shift + p, it.currentBlock(), overrideColor);
-                    ++it;
-                }
-            } else {
-                addTextLayout(shift, m_textLayout, shiftForStyle.isEmpty()
-                                                   ? m_color
-                                                   : m_styleColor);
-            }
-        }
-    }
-}
-#endif
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgtextnode_p.h b/src/declarative/items/qsgtextnode_p.h
deleted file mode 100644 (file)
index 7a9462c..0000000
+++ /dev/null
@@ -1,110 +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 QSGTEXTNODE_P_H
-#define QSGTEXTNODE_P_H
-
-#include <qsgnode.h>
-#include "qsgtext_p.h"
-#include <qglyphrun.h>
-
-#include <QtGui/qcolor.h>
-#include <QtGui/qtextlayout.h>
-#include <QtCore/qvarlengtharray.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGGlyphNode;
-class QTextBlock;
-class QColor;
-class QTextDocument;
-class QSGContext;
-class QRawFont;
-class QSGSimpleRectNode;
-class QSGClipNode;
-class QSGTexture;
-
-class QSGTextNode : public QSGTransformNode
-{
-public:
-    enum Decoration {
-        NoDecoration = 0x0,
-        Underline    = 0x1,
-        Overline     = 0x2,
-        StrikeOut    = 0x4,
-        Background   = 0x8
-    };
-    Q_DECLARE_FLAGS(Decorations, Decoration)
-
-    QSGTextNode(QSGContext *);
-    ~QSGTextNode();
-
-    static bool isComplexRichText(QTextDocument *);
-
-    void deleteContent();
-    void addTextLayout(const QPointF &position, QTextLayout *textLayout, const QColor &color = QColor(),
-                       QSGText::TextStyle style = QSGText::Normal, const QColor &styleColor = QColor(),
-                       const QColor &selectionColor = QColor(), const QColor &selectedTextColor = QColor(),
-                       int selectionStart = -1, int selectionEnd = -1);
-    void addTextDocument(const QPointF &position, QTextDocument *textDocument, const QColor &color = QColor(),
-                         QSGText::TextStyle style = QSGText::Normal, const QColor &styleColor = QColor(),
-                         const QColor &selectionColor = QColor(), const QColor &selectedTextColor = QColor(),
-                         int selectionStart = -1, int selectionEnd = -1);
-
-    void setCursor(const QRectF &rect, const QColor &color);
-    QSGSimpleRectNode *cursorNode() const { return m_cursorNode; }
-
-    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
-
-#endif // QSGTEXTNODE_P_H
diff --git a/src/declarative/items/qsgtranslate.cpp b/src/declarative/items/qsgtranslate.cpp
deleted file mode 100644 (file)
index 577cf4d..0000000
+++ /dev/null
@@ -1,319 +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 "qsgtranslate_p.h"
-#include "qsgitem_p.h"
-
-#include <QtCore/qmath.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGTranslatePrivate : public QSGTransformPrivate
-{
-public:
-    QSGTranslatePrivate()
-    : x(0), y(0) {}
-
-    qreal x;
-    qreal y;
-};
-
-/*!
-    Constructs an empty QSGTranslate object with the given \a parent.
-*/
-QSGTranslate::QSGTranslate(QObject *parent)
-: QSGTransform(*new QSGTranslatePrivate, parent)
-{
-}
-
-/*!
-    Destroys the graphics scale.
-*/
-QSGTranslate::~QSGTranslate()
-{
-}
-
-/*!
-    \property QSGTranslate::x
-    \brief the horizontal translation.
-
-    The translation can be any real number; the default value is 0.0.
-
-    \sa y
-*/
-qreal QSGTranslate::x() const
-{
-    Q_D(const QSGTranslate);
-    return d->x;
-}
-
-void QSGTranslate::setX(qreal x)
-{
-    Q_D(QSGTranslate);
-    if (d->x == x)
-        return;
-    d->x = x;
-    update();
-    emit xChanged();
-}
-
-/*!
-    \property QSGTranslate::y
-    \brief the vertical translation.
-
-    The translation can be any real number; the default value is 0.0.
-
-    \sa x
-*/
-qreal QSGTranslate::y() const
-{
-    Q_D(const QSGTranslate);
-    return d->y;
-}
-void QSGTranslate::setY(qreal y)
-{
-    Q_D(QSGTranslate);
-    if (d->y == y)
-        return;
-    d->y = y;
-    update();
-    emit yChanged();
-}
-
-void QSGTranslate::applyTo(QMatrix4x4 *matrix) const
-{
-    Q_D(const QSGTranslate);
-    matrix->translate(d->x, d->y, 0);
-}
-
-class QSGScalePrivate : public QSGTransformPrivate
-{
-public:
-    QSGScalePrivate()
-        : xScale(1), yScale(1), zScale(1) {}
-    QVector3D origin;
-    qreal xScale;
-    qreal yScale;
-    qreal zScale;
-};
-
-QSGScale::QSGScale(QObject *parent)
-    : QSGTransform(*new QSGScalePrivate, parent)
-{
-}
-
-QSGScale::~QSGScale()
-{
-}
-
-QVector3D QSGScale::origin() const
-{
-    Q_D(const QSGScale);
-    return d->origin;
-}
-void QSGScale::setOrigin(const QVector3D &point)
-{
-    Q_D(QSGScale);
-    if (d->origin == point)
-        return;
-    d->origin = point;
-    update();
-    emit originChanged();
-}
-
-qreal QSGScale::xScale() const
-{
-    Q_D(const QSGScale);
-    return d->xScale;
-}
-void QSGScale::setXScale(qreal scale)
-{
-    Q_D(QSGScale);
-    if (d->xScale == scale)
-        return;
-    d->xScale = scale;
-    update();
-    emit xScaleChanged();
-    emit scaleChanged();
-}
-
-qreal QSGScale::yScale() const
-{
-    Q_D(const QSGScale);
-    return d->yScale;
-}
-void QSGScale::setYScale(qreal scale)
-{
-    Q_D(QSGScale);
-    if (d->yScale == scale)
-        return;
-    d->yScale = scale;
-    update();
-    emit yScaleChanged();
-    emit scaleChanged();
-}
-
-qreal QSGScale::zScale() const
-{
-    Q_D(const QSGScale);
-    return d->zScale;
-}
-void QSGScale::setZScale(qreal scale)
-{
-    Q_D(QSGScale);
-    if (d->zScale == scale)
-        return;
-    d->zScale = scale;
-    update();
-    emit zScaleChanged();
-    emit scaleChanged();
-}
-
-void QSGScale::applyTo(QMatrix4x4 *matrix) const
-{
-    Q_D(const QSGScale);
-    matrix->translate(d->origin);
-    matrix->scale(d->xScale, d->yScale, d->zScale);
-    matrix->translate(-d->origin);
-}
-
-class QSGRotationPrivate : public QSGTransformPrivate
-{
-public:
-    QSGRotationPrivate()
-        : angle(0), axis(0, 0, 1) {}
-    QVector3D origin;
-    qreal angle;
-    QVector3D axis;
-};
-
-QSGRotation::QSGRotation(QObject *parent)
-    : QSGTransform(*new QSGRotationPrivate, parent)
-{
-}
-
-QSGRotation::~QSGRotation()
-{
-}
-
-QVector3D QSGRotation::origin() const
-{
-    Q_D(const QSGRotation);
-    return d->origin;
-}
-
-void QSGRotation::setOrigin(const QVector3D &point)
-{
-    Q_D(QSGRotation);
-    if (d->origin == point)
-        return;
-    d->origin = point;
-    update();
-    emit originChanged();
-}
-
-qreal QSGRotation::angle() const
-{
-    Q_D(const QSGRotation);
-    return d->angle;
-}
-void QSGRotation::setAngle(qreal angle)
-{
-    Q_D(QSGRotation);
-    if (d->angle == angle)
-        return;
-    d->angle = angle;
-    update();
-    emit angleChanged();
-}
-
-QVector3D QSGRotation::axis() const
-{
-    Q_D(const QSGRotation);
-    return d->axis;
-}
-void QSGRotation::setAxis(const QVector3D &axis)
-{
-    Q_D(QSGRotation);
-    if (d->axis == axis)
-         return;
-    d->axis = axis;
-    update();
-    emit axisChanged();
-}
-
-void QSGRotation::setAxis(Qt::Axis axis)
-{
-    switch (axis)
-    {
-    case Qt::XAxis:
-        setAxis(QVector3D(1, 0, 0));
-        break;
-    case Qt::YAxis:
-        setAxis(QVector3D(0, 1, 0));
-        break;
-    case Qt::ZAxis:
-        setAxis(QVector3D(0, 0, 1));
-        break;
-    }
-}
-
-class QGraphicsRotation {
-public:
-    static inline void projectedRotate(QMatrix4x4 *matrix, qreal angle, qreal x, qreal y, qreal z)
-    {
-        matrix->projectedRotate(angle, x, y, z);
-    }
-};
-
-void QSGRotation::applyTo(QMatrix4x4 *matrix) const
-{
-    Q_D(const QSGRotation);
-
-    if (d->angle == 0. || d->axis.isNull())
-        return;
-
-    matrix->translate(d->origin);
-    QGraphicsRotation::projectedRotate(matrix, d->angle, d->axis.x(), d->axis.y(), d->axis.z());
-    matrix->translate(-d->origin);
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgtranslate_p.h b/src/declarative/items/qsgtranslate_p.h
deleted file mode 100644 (file)
index fb85daa..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
-/****************************************************************************
-**
-** 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 QSGTRANSLATE_P_H
-#define QSGTRANSLATE_P_H
-
-#include "qsgitem.h"
-
-#include <QtGui/qmatrix4x4.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGTranslatePrivate;
-class Q_AUTOTEST_EXPORT QSGTranslate : public QSGTransform
-{
-    Q_OBJECT
-
-    Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged)
-    Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged)
-
-public:
-    QSGTranslate(QObject *parent = 0);
-    ~QSGTranslate();
-
-    qreal x() const;
-    void setX(qreal);
-
-    qreal y() const;
-    void setY(qreal);
-
-    void applyTo(QMatrix4x4 *matrix) const;
-
-Q_SIGNALS:
-    void xChanged();
-    void yChanged();
-
-private:
-    Q_DECLARE_PRIVATE(QSGTranslate)
-    Q_DISABLE_COPY(QSGTranslate)
-};
-
-class QSGScalePrivate;
-class Q_AUTOTEST_EXPORT QSGScale : public QSGTransform
-{
-    Q_OBJECT
-
-    Q_PROPERTY(QVector3D origin READ origin WRITE setOrigin NOTIFY originChanged)
-    Q_PROPERTY(qreal xScale READ xScale WRITE setXScale NOTIFY xScaleChanged)
-    Q_PROPERTY(qreal yScale READ yScale WRITE setYScale NOTIFY yScaleChanged)
-    Q_PROPERTY(qreal zScale READ zScale WRITE setZScale NOTIFY zScaleChanged)
-public:
-    QSGScale(QObject *parent = 0);
-    ~QSGScale();
-
-    QVector3D origin() const;
-    void setOrigin(const QVector3D &point);
-
-    qreal xScale() const;
-    void setXScale(qreal);
-
-    qreal yScale() const;
-    void setYScale(qreal);
-
-    qreal zScale() const;
-    void setZScale(qreal);
-
-    void applyTo(QMatrix4x4 *matrix) const;
-
-Q_SIGNALS:
-    void originChanged();
-    void xScaleChanged();
-    void yScaleChanged();
-    void zScaleChanged();
-    void scaleChanged();
-
-private:
-    Q_DECLARE_PRIVATE(QSGScale)
-};
-
-class QSGRotationPrivate;
-class Q_AUTOTEST_EXPORT QSGRotation : public QSGTransform
-{
-    Q_OBJECT
-
-    Q_PROPERTY(QVector3D origin READ origin WRITE setOrigin NOTIFY originChanged)
-    Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged)
-    Q_PROPERTY(QVector3D axis READ axis WRITE setAxis NOTIFY axisChanged)
-public:
-    QSGRotation(QObject *parent = 0);
-    ~QSGRotation();
-
-    QVector3D origin() const;
-    void setOrigin(const QVector3D &point);
-
-    qreal angle() const;
-    void setAngle(qreal);
-
-    QVector3D axis() const;
-    void setAxis(const QVector3D &axis);
-    void setAxis(Qt::Axis axis);
-
-    void applyTo(QMatrix4x4 *matrix) const;
-
-Q_SIGNALS:
-    void originChanged();
-    void angleChanged();
-    void axisChanged();
-
-private:
-    Q_DECLARE_PRIVATE(QSGRotation)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGTranslate)
-
-QT_END_HEADER
-
-#endif
diff --git a/src/declarative/items/qsgview.cpp b/src/declarative/items/qsgview.cpp
deleted file mode 100644 (file)
index 841c8eb..0000000
+++ /dev/null
@@ -1,417 +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$
-**
-****************************************************************************/
-
-#include "qsgview.h"
-#include "qsgview_p.h"
-
-#include "qsgcanvas_p.h"
-#include "qsgitem_p.h"
-#include "qsgitemchangelistener_p.h"
-
-#include <private/qdeclarativedebugtrace_p.h>
-#include <private/qdeclarativeinspectorservice_p.h>
-
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <private/qdeclarativeengine_p.h>
-#include <QtCore/qbasictimer.h>
-
-
-// XXX todo - This whole class should probably be merged with QDeclarativeView for
-// maximum seamlessness
-QT_BEGIN_NAMESPACE
-
-DEFINE_BOOL_CONFIG_OPTION(frameRateDebug, QML_SHOW_FRAMERATE)
-
-void QSGViewPrivate::init()
-{
-    Q_Q(QSGView);
-
-    QDeclarativeEnginePrivate::get(&engine)->sgContext = QSGCanvasPrivate::context;
-
-    engine.setIncubationController(q->incubationController());
-
-    if (QDeclarativeDebugService::isDebuggingEnabled())
-        QDeclarativeInspectorService::instance()->addView(q);
-}
-
-QSGViewPrivate::QSGViewPrivate()
-    : root(0), component(0), resizeMode(QSGView::SizeViewToRootObject), initialSize(0,0), resized(false)
-{
-}
-
-QSGViewPrivate::~QSGViewPrivate()
-{
-    if (QDeclarativeDebugService::isDebuggingEnabled())
-        QDeclarativeInspectorService::instance()->removeView(q_func());
-
-    delete root;
-}
-
-void QSGViewPrivate::execute()
-{
-    Q_Q(QSGView);
-    if (root) {
-        delete root;
-        root = 0;
-    }
-    if (component) {
-        delete component;
-        component = 0;
-    }
-    if (!source.isEmpty()) {
-        component = new QDeclarativeComponent(&engine, source, q);
-        if (!component->isLoading()) {
-            q->continueExecute();
-        } else {
-            QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)),
-                             q, SLOT(continueExecute()));
-        }
-    }
-}
-
-void QSGViewPrivate::itemGeometryChanged(QSGItem *resizeItem, const QRectF &newGeometry, const QRectF &oldGeometry)
-{
-    Q_Q(QSGView);
-    if (resizeItem == root && resizeMode == QSGView::SizeViewToRootObject) {
-        // wait for both width and height to be changed
-        resizetimer.start(0,q);
-    }
-    QSGItemChangeListener::itemGeometryChanged(resizeItem, newGeometry, oldGeometry);
-}
-
-QSGView::QSGView(QWindow *parent, Qt::WindowFlags f)
-: QSGCanvas(*(new QSGViewPrivate), parent)
-{
-    setWindowFlags(f);
-    d_func()->init();
-}
-
-QSGView::QSGView(const QUrl &source, QWindow *parent, Qt::WindowFlags f)
-: QSGCanvas(*(new QSGViewPrivate), parent)
-{
-    setWindowFlags(f);
-    d_func()->init();
-    setSource(source);
-}
-
-QSGView::~QSGView()
-{
-}
-
-void QSGView::setSource(const QUrl& url)
-{
-    Q_D(QSGView);
-    d->source = url;
-    d->execute();
-}
-
-QUrl QSGView::source() const
-{
-    Q_D(const QSGView);
-    return d->source;
-}
-
-QDeclarativeEngine* QSGView::engine() const
-{
-    Q_D(const QSGView);
-    return const_cast<QDeclarativeEngine *>(&d->engine);
-}
-
-QDeclarativeContext* QSGView::rootContext() const
-{
-    Q_D(const QSGView);
-    return d->engine.rootContext();
-}
-
-QSGView::Status QSGView::status() const
-{
-    Q_D(const QSGView);
-    if (!d->component)
-        return QSGView::Null;
-
-    return QSGView::Status(d->component->status());
-}
-
-QList<QDeclarativeError> QSGView::errors() const
-{
-    Q_D(const QSGView);
-    if (d->component)
-        return d->component->errors();
-    return QList<QDeclarativeError>();
-}
-
-void QSGView::setResizeMode(ResizeMode mode)
-{
-    Q_D(QSGView);
-    if (d->resizeMode == mode)
-        return;
-
-    if (d->root) {
-        if (d->resizeMode == SizeViewToRootObject) {
-            QSGItemPrivate *p = QSGItemPrivate::get(d->root);
-            p->removeItemChangeListener(d, QSGItemPrivate::Geometry);
-        }
-    }
-
-    d->resizeMode = mode;
-    if (d->root) {
-        d->initResize();
-    }
-}
-
-void QSGViewPrivate::initResize()
-{
-    if (root) {
-        if (resizeMode == QSGView::SizeViewToRootObject) {
-            QSGItemPrivate *p = QSGItemPrivate::get(root);
-            p->addItemChangeListener(this, QSGItemPrivate::Geometry);
-        }
-    }
-    updateSize();
-}
-
-void QSGViewPrivate::updateSize()
-{
-    Q_Q(QSGView);
-    if (!root)
-        return;
-
-    if (resizeMode == QSGView::SizeViewToRootObject) {
-        QSize newSize = QSize(root->width(), root->height());
-        if (newSize.isValid() && newSize != q->size()) {
-            q->resize(newSize);
-        }
-    } else if (resizeMode == QSGView::SizeRootObjectToView) {
-        if (!qFuzzyCompare(q->width(), root->width()))
-            root->setWidth(q->width());
-        if (!qFuzzyCompare(q->height(), root->height()))
-            root->setHeight(q->height());
-    }
-}
-
-QSize QSGViewPrivate::rootObjectSize() const
-{
-    QSize rootObjectSize(0,0);
-    int widthCandidate = -1;
-    int heightCandidate = -1;
-    if (root) {
-        widthCandidate = root->width();
-        heightCandidate = root->height();
-    }
-    if (widthCandidate > 0) {
-        rootObjectSize.setWidth(widthCandidate);
-    }
-    if (heightCandidate > 0) {
-        rootObjectSize.setHeight(heightCandidate);
-    }
-    return rootObjectSize;
-}
-
-QSGView::ResizeMode QSGView::resizeMode() const
-{
-    Q_D(const QSGView);
-    return d->resizeMode;
-}
-
-/*!
-  \internal
- */
-void QSGView::continueExecute()
-{
-    Q_D(QSGView);
-    disconnect(d->component, SIGNAL(statusChanged(QDeclarativeComponent::Status)), this, SLOT(continueExecute()));
-
-    if (d->component->isError()) {
-        QList<QDeclarativeError> errorList = d->component->errors();
-        foreach (const QDeclarativeError &error, errorList) {
-            qWarning() << error;
-        }
-        emit statusChanged(status());
-        return;
-    }
-
-    QObject *obj = d->component->create();
-
-    if (d->component->isError()) {
-        QList<QDeclarativeError> errorList = d->component->errors();
-        foreach (const QDeclarativeError &error, errorList) {
-            qWarning() << error;
-        }
-        emit statusChanged(status());
-        return;
-    }
-
-    d->setRootObject(obj);
-    emit statusChanged(status());
-}
-
-
-/*!
-  \internal
-*/
-void QSGViewPrivate::setRootObject(QObject *obj)
-{
-    Q_Q(QSGView);
-    if (root == obj)
-        return;
-    if (QSGItem *sgItem = qobject_cast<QSGItem *>(obj)) {
-        root = sgItem;
-        sgItem->setParentItem(q->QSGCanvas::rootItem());
-    } else {
-        qWarning() << "QSGView only supports loading of root objects that derive from QSGItem." << endl
-                   << endl
-                   << "If your example is using QML 2, (such as qmlscene) and the .qml file you" << endl
-                   << "loaded has 'import QtQuick 1.0' or 'import Qt 4.7', this error will occur." << endl
-                   << endl
-                   << "To load files with 'import QtQuick 1.0' with QML 2, specify:" << endl
-                   << "  QMLSCENE_IMPORT_NAME=quick1" << endl
-                   << "on as an environment variable prior to launching the application." << endl
-                   << endl
-                   << "To load files with 'import Qt 4.7' with QML 2, specify:" << endl
-                   << "  QMLSCENE_IMPORT_NAME=qt" << endl
-                   << "on as an environment variable prior to launching the application." << endl;
-        delete obj;
-        root = 0;
-    }
-    if (root) {
-        initialSize = rootObjectSize();
-        if ((resizeMode == QSGView::SizeViewToRootObject || !resized) // ### refactor:  || !q->testAttribute(Qt::WA_Resized)
-             && initialSize != q->size()) {
-
-            q->resize(initialSize);
-            resized = true;
-        }
-        initResize();
-    }
-}
-
-/*!
-  \internal
-  If the \l {QTimerEvent} {timer event} \a e is this
-  view's resize timer, sceneResized() is emitted.
- */
-void QSGView::timerEvent(QTimerEvent* e)
-{
-    Q_D(QSGView);
-    if (!e || e->timerId() == d->resizetimer.timerId()) {
-        d->updateSize();
-        d->resizetimer.stop();
-    }
-}
-
-/*!
-    \internal
-    Preferred size follows the root object geometry.
-*/
-QSize QSGView::sizeHint() const
-{
-    Q_D(const QSGView);
-    QSize rootObjectSize = d->rootObjectSize();
-    if (rootObjectSize.isEmpty()) {
-        return size();
-    } else {
-        return rootObjectSize;
-    }
-}
-
-QSize QSGView::initialSize() const
-{
-    Q_D(const QSGView);
-    return d->initialSize;
-}
-
-QSGItem *QSGView::rootObject() const
-{
-    Q_D(const QSGView);
-    return d->root;
-}
-
-/*!
-  \internal
-  This function handles the \l {QResizeEvent} {resize event}
-  \a e.
- */
-void QSGView::resizeEvent(QResizeEvent *e)
-{
-    Q_D(QSGView);
-    if (d->resizeMode == SizeRootObjectToView)
-        d->updateSize();
-
-    QSGCanvas::resizeEvent(e);
-}
-
-void QSGView::keyPressEvent(QKeyEvent *e)
-{
-    QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Key);
-
-    QSGCanvas::keyPressEvent(e);
-}
-
-void QSGView::keyReleaseEvent(QKeyEvent *e)
-{
-    QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Key);
-
-    QSGCanvas::keyReleaseEvent(e);
-}
-
-void QSGView::mouseMoveEvent(QMouseEvent *e)
-{
-    QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
-
-    QSGCanvas::mouseMoveEvent(e);
-}
-
-void QSGView::mousePressEvent(QMouseEvent *e)
-{
-    QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
-
-    QSGCanvas::mousePressEvent(e);
-}
-
-void QSGView::mouseReleaseEvent(QMouseEvent *e)
-{
-    QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
-
-    QSGCanvas::mouseReleaseEvent(e);
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/declarative/items/qsgview.h b/src/declarative/items/qsgview.h
deleted file mode 100644 (file)
index 2d8e8b4..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-// Commit: 0b83a2161261be525f01359397ab1c8c34827749
-/****************************************************************************
-**
-** 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 QSGVIEW_H
-#define QSGVIEW_H
-
-#include <qsgcanvas.h>
-#include <QtCore/qurl.h>
-#include <QtDeclarative/qdeclarativedebug.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QDeclarativeEngine;
-class QDeclarativeContext;
-class QDeclarativeError;
-class QSGItem;
-
-class QSGViewPrivate;
-class Q_DECLARATIVE_EXPORT QSGView : public QSGCanvas
-{
-    Q_OBJECT
-    Q_PROPERTY(ResizeMode resizeMode READ resizeMode WRITE setResizeMode)
-    Q_PROPERTY(Status status READ status NOTIFY statusChanged)
-    Q_PROPERTY(QUrl source READ source WRITE setSource DESIGNABLE true)
-    Q_ENUMS(ResizeMode Status)
-public:
-    explicit QSGView(QWindow *parent = 0, Qt::WindowFlags f = 0);
-    QSGView(const QUrl &source, QWindow *parent = 0, Qt::WindowFlags f = 0);
-    virtual ~QSGView();
-
-    QUrl source() const;
-
-    QDeclarativeEngine* engine() const;
-    QDeclarativeContext* rootContext() const;
-
-    QSGItem *rootObject() const;
-
-    enum ResizeMode { SizeViewToRootObject, SizeRootObjectToView };
-    ResizeMode resizeMode() const;
-    void setResizeMode(ResizeMode);
-
-    enum Status { Null, Ready, Loading, Error };
-    Status status() const;
-
-    QList<QDeclarativeError> errors() const;
-
-    QSize sizeHint() const;
-    QSize initialSize() const;
-
-public Q_SLOTS:
-    void setSource(const QUrl&);
-
-Q_SIGNALS:
-    void statusChanged(QSGView::Status);
-
-private Q_SLOTS:
-    void continueExecute();
-
-protected:
-    virtual void resizeEvent(QResizeEvent *);
-    virtual void timerEvent(QTimerEvent*);
-
-    virtual void keyPressEvent(QKeyEvent *);
-    virtual void keyReleaseEvent(QKeyEvent *);
-    virtual void mousePressEvent(QMouseEvent *);
-    virtual void mouseReleaseEvent(QMouseEvent *);
-    virtual void mouseMoveEvent(QMouseEvent *);
-private:
-    Q_DISABLE_COPY(QSGView)
-    Q_DECLARE_PRIVATE(QSGView)
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSGVIEW_H
diff --git a/src/declarative/items/qsgview_p.h b/src/declarative/items/qsgview_p.h
deleted file mode 100644 (file)
index f2b962c..0000000
+++ /dev/null
@@ -1,107 +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 QSGVIEW_P_H
-#define QSGVIEW_P_H
-
-#include "qsgview.h"
-
-#include <QtCore/qurl.h>
-#include <QtCore/qelapsedtimer.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qpointer.h>
-#include <QtDeclarative/qdeclarativeengine.h>
-#include "qsgcanvas_p.h"
-
-#include "qsgitemchangelistener_p.h"
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QDeclarativeContext;
-class QDeclarativeError;
-class QSGItem;
-class QDeclarativeComponent;
-
-class QSGViewPrivate : public QSGCanvasPrivate,
-                       public QSGItemChangeListener
-{
-    Q_DECLARE_PUBLIC(QSGView)
-public:
-    static QSGViewPrivate* get(QSGView *view) { return view->d_func(); }
-    static const QSGViewPrivate* get(const QSGView *view) { return view->d_func(); }
-
-    QSGViewPrivate();
-    ~QSGViewPrivate();
-
-    void execute();
-    void itemGeometryChanged(QSGItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
-    void initResize();
-    void updateSize();
-    void setRootObject(QObject *);
-
-    void init();
-
-    QSize rootObjectSize() const;
-
-    QPointer<QSGItem> root;
-
-    QUrl source;
-
-    QDeclarativeEngine engine;
-    QDeclarativeComponent *component;
-    QBasicTimer resizetimer;
-
-    QSGView::ResizeMode resizeMode;
-    QSize initialSize;
-    QElapsedTimer frameTimer;
-
-    bool resized;
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSGVIEW_P_H
diff --git a/src/declarative/items/qsgvisualadaptormodel.cpp b/src/declarative/items/qsgvisualadaptormodel.cpp
deleted file mode 100644 (file)
index 4e3a1a6..0000000
+++ /dev/null
@@ -1,889 +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 "qsgvisualadaptormodel_p.h"
-#include "qsgitem.h"
-
-#include <QtDeclarative/qdeclarativecontext.h>
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativeexpression.h>
-#include <QtDeclarative/qdeclarativeinfo.h>
-
-#include <private/qdeclarativecontext_p.h>
-#include <private/qdeclarativepackage_p.h>
-#include <private/qdeclarativeopenmetaobject_p.h>
-#include <private/qdeclarativelistaccessor_p.h>
-#include <private/qdeclarativedata_p.h>
-#include <private/qdeclarativepropertycache_p.h>
-#include <private/qdeclarativeguard_p.h>
-#include <private/qdeclarativeglobal_p.h>
-#include <private/qlistmodelinterface_p.h>
-#include <private/qmetaobjectbuilder_p.h>
-#include <private/qdeclarativeproperty_p.h>
-#include <private/qintrusivelist_p.h>
-#include <private/qobject_p.h>
-
-#include <QtCore/qhash.h>
-#include <QtCore/qlist.h>
-
-Q_DECLARE_METATYPE(QModelIndex)
-
-QT_BEGIN_NAMESPACE
-
-class VDMDelegateDataType : public QDeclarativeRefCount
-{
-public:
-    VDMDelegateDataType()
-        : metaObject(0)
-        , propertyCache(0)
-        , propertyOffset(0)
-        , signalOffset(0)
-        , shared(true)
-    {
-    }
-
-    VDMDelegateDataType(const VDMDelegateDataType &type)
-        : metaObject(0)
-        , propertyCache(0)
-        , propertyOffset(type.propertyOffset)
-        , signalOffset(type.signalOffset)
-        , shared(false)
-        , builder(type.metaObject, QMetaObjectBuilder::Properties
-                | QMetaObjectBuilder::Signals
-                | QMetaObjectBuilder::SuperClass
-                | QMetaObjectBuilder::ClassName)
-    {
-        builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
-    }
-
-    ~VDMDelegateDataType()
-    {
-        if (propertyCache)
-            propertyCache->release();
-        qFree(metaObject);
-    }
-
-    QMetaObject *metaObject;
-    QDeclarativePropertyCache *propertyCache;
-    int propertyOffset;
-    int signalOffset;
-    bool shared : 1;
-    QMetaObjectBuilder builder;
-};
-
-class QSGVisualAdaptorModelData : public QObject
-{
-    Q_OBJECT
-    Q_PROPERTY(int index READ index NOTIFY indexChanged)
-public:
-    QSGVisualAdaptorModelData(int index, QSGVisualAdaptorModel *model);
-    ~QSGVisualAdaptorModelData();
-
-    int index() const;
-    void setIndex(int index);
-
-Q_SIGNALS:
-    void indexChanged();
-
-public:
-    int m_index;
-    QDeclarativeGuard<QSGVisualAdaptorModel> m_model;
-    QIntrusiveListNode m_cacheNode;
-};
-
-typedef QIntrusiveList<QSGVisualAdaptorModelData, &QSGVisualAdaptorModelData::m_cacheNode> QSGVisualAdaptorModelDataCache;
-
-class QSGVisualAdaptorModelDataMetaObject;
-class QSGVisualAdaptorModelPrivate : public QObjectPrivate
-{
-    Q_DECLARE_PUBLIC(QSGVisualAdaptorModel)
-public:
-    QSGVisualAdaptorModelPrivate()
-        : m_engine(0)
-        , m_listAccessor(0)
-        , m_delegateDataType(0)
-        , createModelData(&initializeModelData)
-        , m_ref(0)
-        , m_count(0)
-        , m_objectList(false)
-    {
-    }
-
-
-    static QSGVisualAdaptorModelPrivate *get(QSGVisualAdaptorModel *m) {
-        return static_cast<QSGVisualAdaptorModelPrivate *>(QObjectPrivate::get(m));
-    }
-
-    void addProperty(int role, int propertyId, const char *propertyName, const char *propertyType, bool isModelData = false);
-    template <typename T> void setModelDataType()
-    {
-        createModelData = &T::create;
-        m_delegateDataType->builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
-        m_delegateDataType->builder.setClassName(T::staticMetaObject.className());
-        m_delegateDataType->builder.setSuperClass(&T::staticMetaObject);
-        m_delegateDataType->propertyOffset = T::staticMetaObject.propertyCount();
-        m_delegateDataType->signalOffset = T::staticMetaObject.methodCount();
-    }
-    QSGVisualAdaptorModelData *createMetaObject(int index, QSGVisualAdaptorModel *model);
-
-    static QSGVisualAdaptorModelData *initializeModelData(int index, QSGVisualAdaptorModel *model) {
-        return get(model)->createMetaObject(index, model);
-    }
-
-    typedef QSGVisualAdaptorModelData *(*CreateModelData)(int index, QSGVisualAdaptorModel *model);
-
-    struct PropertyData {
-        int role;
-        bool isModelData : 1;
-    };
-
-    int modelCount() const {
-        if (m_listModelInterface)
-            return m_listModelInterface->count();
-        if (m_abstractItemModel)
-            return m_abstractItemModel->rowCount(m_root);
-        if (m_listAccessor)
-            return m_listAccessor->count();
-        return 0;
-    }
-
-    QDeclarativeGuard<QDeclarativeEngine> m_engine;
-    QDeclarativeGuard<QListModelInterface> m_listModelInterface;
-    QDeclarativeGuard<QAbstractItemModel> m_abstractItemModel;
-    QDeclarativeListAccessor *m_listAccessor;
-    VDMDelegateDataType *m_delegateDataType;
-    CreateModelData createModelData;
-
-    int m_ref;
-    int m_count;
-    QSGVisualAdaptorModel::Flags m_flags;
-    bool m_objectList : 1;
-
-    QVariant m_modelVariant;
-    QModelIndex m_root;
-
-    QList<int> m_roles;
-    QList<int> watchedRoleIds;
-    QList<QByteArray> watchedRoles;
-    QHash<QByteArray,int> m_roleNames;
-    QVector<PropertyData> m_propertyData;
-    QSGVisualAdaptorModelDataCache m_cache;
-};
-
-class QSGVisualAdaptorModelDataMetaObject : public QAbstractDynamicMetaObject
-{
-public:
-    QSGVisualAdaptorModelDataMetaObject(QSGVisualAdaptorModelData *data, VDMDelegateDataType *type)
-        : m_data(data)
-        , m_type(type)
-    {
-        QObjectPrivate *op = QObjectPrivate::get(m_data);
-        *static_cast<QMetaObject *>(this) = *type->metaObject;
-        op->metaObject = this;
-        m_type->addref();
-    }
-
-    ~QSGVisualAdaptorModelDataMetaObject() { m_type->release(); }
-
-    QSGVisualAdaptorModelData *m_data;
-    VDMDelegateDataType *m_type;
-};
-
-class QSGVDMAbstractItemModelDataMetaObject : public QSGVisualAdaptorModelDataMetaObject
-{
-public:
-    QSGVDMAbstractItemModelDataMetaObject(QSGVisualAdaptorModelData *object, VDMDelegateDataType *type)
-        : QSGVisualAdaptorModelDataMetaObject(object, type) {}
-
-    int metaCall(QMetaObject::Call call, int id, void **arguments)
-    {
-        if (call == QMetaObject::ReadProperty && id >= m_type->propertyOffset) {
-            QSGVisualAdaptorModelPrivate *model = QSGVisualAdaptorModelPrivate::get(m_data->m_model);
-            if (m_data->m_index == -1 || !model->m_abstractItemModel)
-                return -1;
-            *static_cast<QVariant *>(arguments[0]) = model->m_abstractItemModel->index(
-                    m_data->m_index, 0, model->m_root).data(model->m_propertyData.at(id - m_type->propertyOffset).role);
-            return -1;
-        } else {
-            return m_data->qt_metacall(call, id, arguments);
-        }
-    }
-};
-
-class QSGVDMAbstractItemModelData : public QSGVisualAdaptorModelData
-{
-    Q_OBJECT
-    Q_PROPERTY(bool hasModelChildren READ hasModelChildren CONSTANT)
-public:
-    bool hasModelChildren() const
-    {
-        QSGVisualAdaptorModelPrivate *model = QSGVisualAdaptorModelPrivate::get(m_model);
-        return model->m_abstractItemModel->hasChildren(model->m_abstractItemModel->index(m_index, 0, model->m_root));
-    }
-
-    static QSGVisualAdaptorModelData *create(int index, QSGVisualAdaptorModel *model) {
-        return new QSGVDMAbstractItemModelData(index, model); }
-private:
-    QSGVDMAbstractItemModelData(int index, QSGVisualAdaptorModel *model)
-        : QSGVisualAdaptorModelData(index, model)
-    {
-        new QSGVDMAbstractItemModelDataMetaObject(
-                this, QSGVisualAdaptorModelPrivate::get(m_model)->m_delegateDataType);
-    }
-};
-
-class QSGVDMListModelInterfaceDataMetaObject : public QSGVisualAdaptorModelDataMetaObject
-{
-public:
-    QSGVDMListModelInterfaceDataMetaObject(QSGVisualAdaptorModelData *object, VDMDelegateDataType *type)
-        : QSGVisualAdaptorModelDataMetaObject(object, type) {}
-
-    int metaCall(QMetaObject::Call call, int id, void **arguments)
-    {
-        if (call == QMetaObject::ReadProperty && id >= m_type->propertyOffset) {
-            QSGVisualAdaptorModelPrivate *model = QSGVisualAdaptorModelPrivate::get(m_data->m_model);
-            if (m_data->m_index == -1 || !model->m_listModelInterface)
-                return -1;
-            *static_cast<QVariant *>(arguments[0]) = model->m_listModelInterface->data(
-                    m_data->m_index, model->m_propertyData.at(id - m_type->propertyOffset).role);
-            return -1;
-        } else {
-            return m_data->qt_metacall(call, id, arguments);
-        }
-    }
-};
-
-class QSGVDMListModelInterfaceData : public QSGVisualAdaptorModelData
-{
-public:
-    static QSGVisualAdaptorModelData *create(int index, QSGVisualAdaptorModel *model) {
-        return new QSGVDMListModelInterfaceData(index, model); }
-private:
-    QSGVDMListModelInterfaceData(int index, QSGVisualAdaptorModel *model)
-        : QSGVisualAdaptorModelData(index, model)
-    {
-        new QSGVDMListModelInterfaceDataMetaObject(
-                this, QSGVisualAdaptorModelPrivate::get(m_model)->m_delegateDataType);
-    }
-};
-
-class QSGVDMListAccessorData : public QSGVisualAdaptorModelData
-{
-    Q_OBJECT
-    Q_PROPERTY(QVariant modelData READ modelData CONSTANT)
-public:
-    QVariant modelData() const {
-        return QSGVisualAdaptorModelPrivate::get(m_model)->m_listAccessor->at(m_index); }
-
-    static QSGVisualAdaptorModelData *create(int index, QSGVisualAdaptorModel *model) {
-        return new QSGVDMListAccessorData(index, model); }
-private:
-    QSGVDMListAccessorData(int index, QSGVisualAdaptorModel *model)
-        : QSGVisualAdaptorModelData(index, model)
-    {
-    }
-};
-
-class QSGVDMObjectDataMetaObject : public QSGVisualAdaptorModelDataMetaObject
-{
-public:
-    QSGVDMObjectDataMetaObject(QSGVisualAdaptorModelData *data, VDMDelegateDataType *type)
-        : QSGVisualAdaptorModelDataMetaObject(data, type)
-        , m_object(QSGVisualAdaptorModelPrivate::get(data->m_model)->m_listAccessor->at(data->m_index).value<QObject *>())
-    {}
-
-    int metaCall(QMetaObject::Call call, int id, void **arguments)
-    {
-        if (id >= m_type->propertyOffset
-                && (call == QMetaObject::ReadProperty
-                || call == QMetaObject::WriteProperty
-                || call == QMetaObject::ResetProperty)) {
-            if (m_object)
-                QMetaObject::metacall(m_object, call, id - m_type->propertyOffset + 1, arguments);
-            return -1;
-        } else if (id >= m_type->signalOffset && call == QMetaObject::InvokeMetaMethod) {
-            QMetaObject::activate(m_data, this, id, 0);
-            return -1;
-        } else {
-            return m_data->qt_metacall(call, id, arguments);
-        }
-    }
-
-    int createProperty(const char *name, const char *)
-    {
-        if (!m_object)
-            return -1;
-        const QMetaObject *metaObject = m_object->metaObject();
-
-        const int previousPropertyCount = propertyCount() - propertyOffset();
-        int propertyIndex = metaObject->indexOfProperty(name);
-        if (propertyIndex == -1)
-            return -1;
-        if (previousPropertyCount + 1 == metaObject->propertyCount())
-            return propertyIndex + m_type->propertyOffset - 1;
-
-        if (m_type->shared) {
-            VDMDelegateDataType *type = m_type;
-            m_type = new VDMDelegateDataType(*m_type);
-            type->release();
-        }
-
-        const int previousMethodCount = methodCount();
-        int notifierId = previousMethodCount;
-        for (int propertyId = previousPropertyCount; propertyId < metaObject->propertyCount() - 1; ++propertyId) {
-            QMetaProperty property = metaObject->property(propertyId + 1);
-            QMetaPropertyBuilder propertyBuilder;
-            if (property.hasNotifySignal()) {
-                m_type->builder.addSignal("__" + QByteArray::number(propertyId) + "()");
-                propertyBuilder = m_type->builder.addProperty(property.name(), property.typeName(), notifierId);
-                ++notifierId;
-            } else {
-                propertyBuilder = m_type->builder.addProperty(property.name(), property.typeName());
-            }
-            propertyBuilder.setWritable(property.isWritable());
-            propertyBuilder.setResettable(property.isResettable());
-            propertyBuilder.setConstant(property.isConstant());
-        }
-
-        if (m_type->metaObject)
-            qFree(m_type->metaObject);
-        m_type->metaObject = m_type->builder.toMetaObject();
-        *static_cast<QMetaObject *>(this) = *m_type->metaObject;
-
-        notifierId = previousMethodCount;
-        for (int i = previousPropertyCount; i < metaObject->propertyCount(); ++i) {
-            QMetaProperty property = metaObject->property(i);
-            if (property.hasNotifySignal()) {
-                QDeclarativePropertyPrivate::connect(
-                        m_object, property.notifySignalIndex(), m_data, notifierId);
-                ++notifierId;
-            }
-        }
-        return propertyIndex + m_type->propertyOffset - 1;
-    }
-
-    QDeclarativeGuard<QObject> m_object;
-};
-
-class QSGVDMObjectData : public QSGVisualAdaptorModelData, public QSGVisualAdaptorModelProxyInterface
-{
-    Q_OBJECT
-    Q_PROPERTY(QObject *modelData READ modelData CONSTANT)
-    Q_INTERFACES(QSGVisualAdaptorModelProxyInterface)
-public:
-    QObject *modelData() const { return m_metaObject->m_object; }
-    QObject *proxiedObject() { return m_metaObject->m_object; }
-
-    static QSGVisualAdaptorModelData *create(int index, QSGVisualAdaptorModel *model) {
-        return new QSGVDMObjectData(index, model); }
-
-private:
-    QSGVDMObjectData(int index, QSGVisualAdaptorModel *model)
-        : QSGVisualAdaptorModelData(index, model)
-        , m_metaObject(new QSGVDMObjectDataMetaObject(this, QSGVisualAdaptorModelPrivate::get(m_model)->m_delegateDataType))
-    {
-    }
-
-    QSGVDMObjectDataMetaObject *m_metaObject;
-};
-
-void QSGVisualAdaptorModelPrivate::addProperty(
-        int role, int propertyId, const char *propertyName, const char *propertyType, bool isModelData)
-{
-    PropertyData propertyData;
-    propertyData.role = role;
-    propertyData.isModelData = isModelData;
-    m_delegateDataType->builder.addSignal("__" + QByteArray::number(propertyId) + "()");
-    QMetaPropertyBuilder property = m_delegateDataType->builder.addProperty(
-            propertyName, propertyType, propertyId);
-    property.setWritable(false);
-
-    m_propertyData.append(propertyData);
-}
-
-QSGVisualAdaptorModelData *QSGVisualAdaptorModelPrivate::createMetaObject(int index, QSGVisualAdaptorModel *model)
-{
-    Q_ASSERT(!m_delegateDataType);
-
-    m_objectList = false;
-    m_propertyData.clear();
-    if (m_listAccessor
-            && m_listAccessor->type() != QDeclarativeListAccessor::ListProperty
-            && m_listAccessor->type() != QDeclarativeListAccessor::Instance) {
-        createModelData = &QSGVDMListAccessorData::create;
-        m_flags = QSGVisualAdaptorModel::MetaObjectCacheable;
-        return QSGVDMListAccessorData::create(index, model);
-    }
-
-    m_delegateDataType = new VDMDelegateDataType;
-    if (m_listModelInterface) {
-        setModelDataType<QSGVDMListModelInterfaceData>();
-        QList<int> roles = m_listModelInterface->roles();
-        for (int propertyId = 0; propertyId < roles.count(); ++propertyId) {
-            const int role = roles.at(propertyId);
-            const QByteArray propertyName = m_listModelInterface->toString(role).toUtf8();
-            addProperty(role, propertyId, propertyName, "QVariant");
-            m_roleNames.insert(propertyName, role);
-        }
-        if (m_propertyData.count() == 1)
-            addProperty(roles.first(), 1, "modelData", "QVariant", true);
-        m_flags = QSGVisualAdaptorModel::MetaObjectCacheable;
-    } else if (m_abstractItemModel) {
-        setModelDataType<QSGVDMAbstractItemModelData>();
-        QHash<int, QByteArray> roleNames = m_abstractItemModel->roleNames();
-        for (QHash<int, QByteArray>::const_iterator it = roleNames.begin(); it != roleNames.end(); ++it) {
-            addProperty(it.key(), m_propertyData.count(), it.value(), "QVariant");
-            m_roleNames.insert(it.value(), it.key());
-        }
-        if (m_propertyData.count() == 1)
-            addProperty(roleNames.begin().key(), 1, "modelData", "QVariant", true);
-        m_flags = QSGVisualAdaptorModel::MetaObjectCacheable;
-    } else if (m_listAccessor) {
-        setModelDataType<QSGVDMObjectData>();
-        m_objectList = true;
-        m_flags = QSGVisualAdaptorModel::ProxiedObject;
-    } else {
-        Q_ASSERT(!"No model set on VisualDataModel");
-        return 0;
-    }
-    m_delegateDataType->metaObject = m_delegateDataType->builder.toMetaObject();
-    if (!m_objectList) {
-        m_delegateDataType->propertyCache = new QDeclarativePropertyCache(
-                m_engine, m_delegateDataType->metaObject);
-    }
-    return createModelData(index, model);
-}
-
-QSGVisualAdaptorModelData::QSGVisualAdaptorModelData(int index, QSGVisualAdaptorModel *model)
-    : m_index(index)
-    , m_model(model)
-{
-}
-
-QSGVisualAdaptorModelData::~QSGVisualAdaptorModelData()
-{
-}
-
-int QSGVisualAdaptorModelData::index() const
-{
-    return m_index;
-}
-
-// This is internal only - it should not be set from qml
-void QSGVisualAdaptorModelData::setIndex(int index)
-{
-    m_index = index;
-    emit indexChanged();
-}
-
-//---------------------------------------------------------------------------
-
-QSGVisualAdaptorModel::QSGVisualAdaptorModel(QObject *parent)
-    : QObject(*(new QSGVisualAdaptorModelPrivate), parent)
-{
-}
-
-QSGVisualAdaptorModel::~QSGVisualAdaptorModel()
-{
-    Q_D(QSGVisualAdaptorModel);
-    if (d->m_listAccessor)
-        delete d->m_listAccessor;
-    if (d->m_delegateDataType)
-        d->m_delegateDataType->release();
-}
-
-QSGVisualAdaptorModel::Flags QSGVisualAdaptorModel::flags() const
-{
-    Q_D(const QSGVisualAdaptorModel);
-    return d->m_flags;
-}
-
-QVariant QSGVisualAdaptorModel::model() const
-{
-    Q_D(const QSGVisualAdaptorModel);
-    return d->m_modelVariant;
-}
-
-void QSGVisualAdaptorModel::setModel(const QVariant &model, QDeclarativeEngine *engine)
-{
-    Q_D(QSGVisualAdaptorModel);
-    delete d->m_listAccessor;
-    d->m_engine = engine;
-    d->m_listAccessor = 0;
-    d->m_modelVariant = model;
-    if (d->m_listModelInterface) {
-        // Assume caller has released all items.
-        QObject::disconnect(d->m_listModelInterface, SIGNAL(itemsChanged(int,int,QList<int>)),
-                this, SLOT(_q_itemsChanged(int,int,QList<int>)));
-        QObject::disconnect(d->m_listModelInterface, SIGNAL(itemsInserted(int,int)),
-                this, SLOT(_q_itemsInserted(int,int)));
-        QObject::disconnect(d->m_listModelInterface, SIGNAL(itemsRemoved(int,int)),
-                this, SLOT(_q_itemsRemoved(int,int)));
-        QObject::disconnect(d->m_listModelInterface, SIGNAL(itemsMoved(int,int,int)),
-                this, SLOT(_q_itemsMoved(int,int,int)));
-        d->m_listModelInterface = 0;
-    } else if (d->m_abstractItemModel) {
-        QObject::disconnect(d->m_abstractItemModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
-                            this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
-        QObject::disconnect(d->m_abstractItemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
-                            this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
-        QObject::disconnect(d->m_abstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
-                            this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
-        QObject::disconnect(d->m_abstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
-                            this, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int)));
-        QObject::disconnect(d->m_abstractItemModel, SIGNAL(modelReset()), this, SLOT(_q_modelReset()));
-        QObject::disconnect(d->m_abstractItemModel, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
-        d->m_abstractItemModel = 0;
-    }
-
-    d->m_roles.clear();
-    d->m_roleNames.clear();
-    d->m_flags = QSGVisualAdaptorModel::Flags();
-    if (d->m_delegateDataType)
-        d->m_delegateDataType->release();
-    d->m_delegateDataType = 0;
-    d->createModelData = &QSGVisualAdaptorModelPrivate::initializeModelData;
-
-    if (d->m_count)
-        emit itemsRemoved(0, d->m_count);
-
-    QObject *object = qvariant_cast<QObject *>(model);
-    if (object && (d->m_listModelInterface = qobject_cast<QListModelInterface *>(object))) {
-        QObject::connect(d->m_listModelInterface, SIGNAL(itemsChanged(int,int,QList<int>)),
-                         this, SLOT(_q_itemsChanged(int,int,QList<int>)));
-        QObject::connect(d->m_listModelInterface, SIGNAL(itemsInserted(int,int)),
-                         this, SLOT(_q_itemsInserted(int,int)));
-        QObject::connect(d->m_listModelInterface, SIGNAL(itemsRemoved(int,int)),
-                         this, SLOT(_q_itemsRemoved(int,int)));
-        QObject::connect(d->m_listModelInterface, SIGNAL(itemsMoved(int,int,int)),
-                         this, SLOT(_q_itemsMoved(int,int,int)));
-        if ((d->m_count = d->m_listModelInterface->count()))
-            emit itemsInserted(0, d->m_count);
-        return;
-    } else if (object && (d->m_abstractItemModel = qobject_cast<QAbstractItemModel *>(object))) {
-        QObject::connect(d->m_abstractItemModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
-                            this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
-        QObject::connect(d->m_abstractItemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
-                            this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
-        QObject::connect(d->m_abstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
-                            this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
-        QObject::connect(d->m_abstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
-                            this, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int)));
-        QObject::connect(d->m_abstractItemModel, SIGNAL(modelReset()), this, SLOT(_q_modelReset()));
-        QObject::connect(d->m_abstractItemModel, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
-
-        if ((d->m_count = d->m_abstractItemModel->rowCount(d->m_root)))
-            emit itemsInserted(0, d->m_count);
-        return;
-    }
-
-    d->m_listAccessor = new QDeclarativeListAccessor;
-    d->m_listAccessor->setList(model, d->m_engine);
-    if ((d->m_count = d->m_listAccessor->count()))
-        emit itemsInserted(0, d->m_count);
-}
-
-QVariant QSGVisualAdaptorModel::rootIndex() const
-{
-    Q_D(const QSGVisualAdaptorModel);
-    return QVariant::fromValue(d->m_root);
-}
-
-void QSGVisualAdaptorModel::setRootIndex(const QVariant &root)
-{
-    Q_D(QSGVisualAdaptorModel);
-    QModelIndex modelIndex = qvariant_cast<QModelIndex>(root);
-    if (d->m_root != modelIndex) {
-        int oldCount = d->modelCount();
-        d->m_root = modelIndex;
-        if (d->m_abstractItemModel && d->m_abstractItemModel->canFetchMore(modelIndex))
-            d->m_abstractItemModel->fetchMore(modelIndex);
-        int newCount = d->modelCount();
-        if (oldCount)
-            emit itemsRemoved(0, oldCount);
-        if (newCount)
-            emit itemsInserted(0, newCount);
-        emit rootIndexChanged();
-    }
-}
-
-QVariant QSGVisualAdaptorModel::modelIndex(int idx) const
-{
-    Q_D(const QSGVisualAdaptorModel);
-    if (d->m_abstractItemModel)
-        return QVariant::fromValue(d->m_abstractItemModel->index(idx, 0, d->m_root));
-    return QVariant::fromValue(QModelIndex());
-}
-
-QVariant QSGVisualAdaptorModel::parentModelIndex() const
-{
-    Q_D(const QSGVisualAdaptorModel);
-    if (d->m_abstractItemModel)
-        return QVariant::fromValue(d->m_abstractItemModel->parent(d->m_root));
-    return QVariant::fromValue(QModelIndex());
-}
-
-int QSGVisualAdaptorModel::count() const
-{
-    Q_D(const QSGVisualAdaptorModel);
-    return d->modelCount();
-}
-
-QObject *QSGVisualAdaptorModel::data(int index)
-{
-    Q_D(QSGVisualAdaptorModel);
-    QSGVisualAdaptorModelData *data = d->createModelData(index, this);
-    d->m_cache.insert(data);
-    return data;
-}
-
-QString QSGVisualAdaptorModel::stringValue(int index, const QString &name)
-{
-    Q_D(QSGVisualAdaptorModel);
-    if ((!d->m_listModelInterface || !d->m_abstractItemModel) && d->m_listAccessor) {
-        if (QObject *object = d->m_listAccessor->at(index).value<QObject*>())
-            return object->property(name.toUtf8()).toString();
-    }
-
-    QString val;
-    QSGVisualAdaptorModelData *data = d->createModelData(index, this);
-
-    QDeclarativeData *ddata = QDeclarativeData::get(data);
-    if (ddata && ddata->propertyCache) {
-        QDeclarativePropertyCache::Data *prop = ddata->propertyCache->property(name);
-        if (prop) {
-            if (prop->propType == QVariant::String) {
-                void *args[] = { &val, 0 };
-                QMetaObject::metacall(data, QMetaObject::ReadProperty, prop->coreIndex, args);
-            } else if (prop->propType == qMetaTypeId<QVariant>()) {
-                QVariant v;
-                void *args[] = { &v, 0 };
-                QMetaObject::metacall(data, QMetaObject::ReadProperty, prop->coreIndex, args);
-                val = v.toString();
-            }
-        } else {
-            val = data->property(name.toUtf8()).toString();
-        }
-    } else {
-        val = data->property(name.toUtf8()).toString();
-    }
-
-    delete data;
-
-    return val;
-}
-
-int QSGVisualAdaptorModel::indexOf(QObject *object) const
-{
-    if (QSGVisualAdaptorModelData *data = qobject_cast<QSGVisualAdaptorModelData *>(object))
-        return data->index();
-    return -1;
-}
-
-bool QSGVisualAdaptorModel::canFetchMore() const
-{
-    Q_D(const QSGVisualAdaptorModel);
-    return d->m_abstractItemModel && d->m_abstractItemModel->canFetchMore(d->m_root);
-}
-
-void QSGVisualAdaptorModel::fetchMore()
-{
-    Q_D(QSGVisualAdaptorModel);
-    if (d->m_abstractItemModel)
-        d->m_abstractItemModel->fetchMore(d->m_root);
-}
-
-void QSGVisualAdaptorModel::replaceWatchedRoles(const QList<QByteArray> &oldRoles, const QList<QByteArray> &newRoles)
-{
-    Q_D(QSGVisualAdaptorModel);
-    d->watchedRoleIds.clear();
-    foreach (const QByteArray &oldRole, oldRoles)
-        d->watchedRoles.removeOne(oldRole);
-    d->watchedRoles += newRoles;
-}
-
-void QSGVisualAdaptorModel::_q_itemsChanged(int index, int count, const QList<int> &roles)
-{
-    Q_D(QSGVisualAdaptorModel);
-    bool changed = roles.isEmpty();
-    if (!d->watchedRoles.isEmpty() && d->watchedRoleIds.isEmpty()) {
-        foreach (QByteArray r, d->watchedRoles) {
-            if (d->m_roleNames.contains(r))
-                d->watchedRoleIds << d->m_roleNames.value(r);
-        }
-    }
-
-    QVector<int> signalIndexes;
-    for (int i = 0; i < roles.count(); ++i) {
-        const int role = roles.at(i);
-        if (!changed && d->watchedRoleIds.contains(role))
-            changed = true;
-        for (int propertyId = 0; propertyId < d->m_propertyData.count(); ++propertyId) {
-            if (d->m_propertyData.at(propertyId).role == role)
-                signalIndexes.append(propertyId + d->m_delegateDataType->signalOffset);
-        }
-    }
-    if (roles.isEmpty()) {
-        for (int propertyId = 0; propertyId < d->m_propertyData.count(); ++propertyId)
-            signalIndexes.append(propertyId + d->m_delegateDataType->signalOffset);
-    }
-
-    typedef QSGVisualAdaptorModelDataCache::iterator iterator;
-    for (iterator it = d->m_cache.begin(); it != d->m_cache.end(); ++it) {
-        const int idx = it->index();
-        if (idx >= index && idx < index + count) {
-            QSGVisualAdaptorModelData *data = *it;
-            for (int i = 0; i < signalIndexes.count(); ++i)
-                QMetaObject::activate(data, signalIndexes.at(i), 0);
-        }
-    }
-    if (changed)
-        emit itemsChanged(index, count);
-}
-
-void QSGVisualAdaptorModel::_q_itemsInserted(int index, int count)
-{
-    Q_D(QSGVisualAdaptorModel);
-    if (count <= 0)
-        return;
-    d->m_count += count;
-
-    typedef QSGVisualAdaptorModelDataCache::iterator iterator;
-    for (iterator it = d->m_cache.begin(); it != d->m_cache.end(); ++it) {
-        if (it->index() >= index)
-            it->setIndex(it->index() + count);
-    }
-
-    emit itemsInserted(index, count);
-}
-
-void QSGVisualAdaptorModel::_q_itemsRemoved(int index, int count)
-{
-    Q_D(QSGVisualAdaptorModel);
-    if (count <= 0)
-        return;
-    d->m_count -= count;
-
-    typedef QSGVisualAdaptorModelDataCache::iterator iterator;
-    for (iterator it = d->m_cache.begin(); it != d->m_cache.end(); ++it) {
-        if (it->index() >= index + count)
-            it->setIndex(it->index() - count);
-        else  if (it->index() >= index)
-            it->setIndex(-1);
-    }
-
-    emit itemsRemoved(index, count);
-}
-
-void QSGVisualAdaptorModel::_q_itemsMoved(int from, int to, int count)
-{
-    Q_D(QSGVisualAdaptorModel);
-    const int minimum = qMin(from, to);
-    const int maximum = qMax(from, to) + count;
-    const int difference = from > to ? count : -count;
-
-    typedef QSGVisualAdaptorModelDataCache::iterator iterator;
-    for (iterator it = d->m_cache.begin(); it != d->m_cache.end(); ++it) {
-        if (it->index() >= from && it->index() < from + count)
-            it->setIndex(it->index() - from + to);
-        else if (it->index() >= minimum && it->index() < maximum)
-            it->setIndex(it->index() + difference);
-    }
-    emit itemsMoved(from, to, count);
-}
-
-void QSGVisualAdaptorModel::_q_rowsInserted(const QModelIndex &parent, int begin, int end)
-{
-    Q_D(QSGVisualAdaptorModel);
-    if (parent == d->m_root)
-        _q_itemsInserted(begin, end - begin + 1);
-}
-
-void QSGVisualAdaptorModel::_q_rowsRemoved(const QModelIndex &parent, int begin, int end)
-{
-    Q_D(QSGVisualAdaptorModel);
-    if (parent == d->m_root)
-        _q_itemsRemoved(begin, end - begin + 1);
-}
-
-void QSGVisualAdaptorModel::_q_rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
-{
-   Q_D(QSGVisualAdaptorModel);
-    const int count = sourceEnd - sourceStart + 1;
-    if (destinationParent == d->m_root && sourceParent == d->m_root) {
-        _q_itemsMoved(sourceStart, sourceStart > destinationRow ? destinationRow : destinationRow-count, count);
-    } else if (sourceParent == d->m_root) {
-        _q_itemsRemoved(sourceStart, count);
-    } else if (destinationParent == d->m_root) {
-        _q_itemsInserted(destinationRow, count);
-    }
-}
-
-void QSGVisualAdaptorModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end)
-{
-    Q_D(QSGVisualAdaptorModel);
-    if (begin.parent() == d->m_root)
-        _q_itemsChanged(begin.row(), end.row() - begin.row() + 1, d->m_roles);
-}
-
-void QSGVisualAdaptorModel::_q_layoutChanged()
-{
-    Q_D(QSGVisualAdaptorModel);
-    _q_itemsChanged(0, count(), d->m_roles);
-}
-
-void QSGVisualAdaptorModel::_q_modelReset()
-{
-    Q_D(QSGVisualAdaptorModel);
-    int oldCount = d->m_count;
-    d->m_root = QModelIndex();
-    d->m_count = d->modelCount();
-    emit modelReset(oldCount, d->m_count);
-    emit rootIndexChanged();
-    if (d->m_abstractItemModel && d->m_abstractItemModel->canFetchMore(d->m_root))
-        d->m_abstractItemModel->fetchMore(d->m_root);
-}
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QListModelInterface)
-
-#include <qsgvisualadaptormodel.moc>
diff --git a/src/declarative/items/qsgvisualadaptormodel_p.h b/src/declarative/items/qsgvisualadaptormodel_p.h
deleted file mode 100644 (file)
index 43af78b..0000000
+++ /dev/null
@@ -1,129 +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 QSGVISUALADAPTORMODEL_P_H
-#define QSGVISUALADAPTORMODEL_P_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qabstractitemmodel.h>
-
-#include <private/qdeclarativerefcount_p.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-class QDeclarativeEngine;
-
-class QSGVisualAdaptorModelPrivate;
-class QSGVisualAdaptorModel : public QObject
-{
-    Q_OBJECT
-    Q_DECLARE_PRIVATE(QSGVisualAdaptorModel)
-public:
-    enum Flag
-    {
-        MetaObjectCacheable = 0x01,
-        ProxiedObject       = 0x02
-    };
-    Q_DECLARE_FLAGS(Flags, Flag)
-
-    QSGVisualAdaptorModel(QObject *parent = 0);
-    virtual ~QSGVisualAdaptorModel();
-
-    Flags flags() const;
-
-    QVariant model() const;
-    void setModel(const QVariant &, QDeclarativeEngine *);
-
-    QVariant rootIndex() const;
-    void setRootIndex(const QVariant &root);
-
-    QVariant modelIndex(int idx) const;
-    QVariant parentModelIndex() const;
-
-    int count() const;
-    QObject *data(int index);
-    QString stringValue(int index, const QString &role);
-    void replaceWatchedRoles(const QList<QByteArray> &oldRoles, const QList<QByteArray> &newRoles);
-    int indexOf(QObject *object) const;
-
-    bool canFetchMore() const;
-    void fetchMore();
-
-Q_SIGNALS:
-    void rootIndexChanged();
-    void modelReset(int oldCount, int newCount);
-
-    void itemsInserted(int index, int count);
-    void itemsRemoved(int index, int count);
-    void itemsMoved(int from, int to, int count);
-    void itemsChanged(int index, int count);
-
-private Q_SLOTS:
-    void _q_itemsChanged(int, int, const QList<int> &);
-    void _q_itemsInserted(int index, int count);
-    void _q_itemsRemoved(int index, int count);
-    void _q_itemsMoved(int from, int to, int count);
-    void _q_rowsInserted(const QModelIndex &,int,int);
-    void _q_rowsRemoved(const QModelIndex &,int,int);
-    void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
-    void _q_dataChanged(const QModelIndex&,const QModelIndex&);
-    void _q_layoutChanged();
-    void _q_modelReset();
-
-private:
-    Q_DISABLE_COPY(QSGVisualAdaptorModel)
-};
-
-class QSGVisualAdaptorModelProxyInterface
-{
-public:
-    virtual ~QSGVisualAdaptorModelProxyInterface() {}
-
-    virtual QObject *proxiedObject() = 0;
-};
-
-Q_DECLARE_INTERFACE(QSGVisualAdaptorModelProxyInterface, "com.trolltech.qml.QSGVisualAdaptorModelProxyInterface")
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/declarative/items/qsgvisualdatamodel.cpp b/src/declarative/items/qsgvisualdatamodel.cpp
deleted file mode 100644 (file)
index 47edc5d..0000000
+++ /dev/null
@@ -1,2538 +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 "qsgvisualdatamodel_p.h"
-#include "qsgitem.h"
-
-#include <QtCore/qcoreapplication.h>
-#include <QtDeclarative/qdeclarativecontext.h>
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativeexpression.h>
-#include <QtDeclarative/qdeclarativeinfo.h>
-
-#include <private/qdeclarativecontext_p.h>
-#include <private/qdeclarativepackage_p.h>
-#include <private/qdeclarativeopenmetaobject_p.h>
-#include <private/qdeclarativelistaccessor_p.h>
-#include <private/qdeclarativedata_p.h>
-#include <private/qdeclarativepropertycache_p.h>
-#include <private/qdeclarativeguard_p.h>
-#include <private/qdeclarativeglobal_p.h>
-#include <private/qmetaobjectbuilder_p.h>
-#include <private/qdeclarativeproperty_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>
-#include <QtCore/qlist.h>
-
-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 QSGVisualDataModelPrivate : public QObjectPrivate, public QSGVisualDataGroupEmitter
-{
-    Q_DECLARE_PUBLIC(QSGVisualDataModel)
-public:
-    QSGVisualDataModelPrivate(QDeclarativeContext *);
-
-    static QSGVisualDataModelPrivate *get(QSGVisualDataModel *m) {
-        return static_cast<QSGVisualDataModelPrivate *>(QObjectPrivate::get(m));
-    }
-
-    void init();
-    void connectModel(QSGVisualAdaptorModel *model);
-
-    QObject *object(Compositor::Group group, int index, bool complete, bool reference);
-    void destroy(QObject *object);
-    QSGVisualDataModel::ReleaseFlags release(QObject *object);
-    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;
-
-    QList<QSGVisualDataModelCacheItem *> m_cache;
-    QSGVisualDataModelParts *m_parts;
-    QSGVisualDataGroupEmitterList m_pendingParts;
-
-    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;
-
-    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, 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);
-    ReleaseFlags release(QSGItem *item);
-    bool completePending() const;
-    void completeItem();
-    QString stringValue(int index, const QString &role);
-    void setWatchedRoles(QList<QByteArray> roles);
-
-    int indexOf(QSGItem *item, QObject *objectContext) const;
-
-    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
-{
-public:
-    QSGVisualDataModelPartsMetaObject(QObject *parent)
-    : QDeclarativeOpenMetaObject(parent) {}
-
-    virtual void propertyCreated(int, QMetaPropertyBuilder &);
-    virtual QVariant initialValue(int);
-};
-
-class QSGVisualDataModelParts : public QObject
-{
-Q_OBJECT
-public:
-    QSGVisualDataModelParts(QSGVisualDataModel *parent);
-
-    QSGVisualDataModel *model;
-    QList<QSGVisualPartsModel *> models;
-};
-
-void QSGVisualDataModelPartsMetaObject::propertyCreated(int, QMetaPropertyBuilder &prop)
-{
-    prop.setWritable(false);
-}
-
-QVariant QSGVisualDataModelPartsMetaObject::initialValue(int id)
-{
-    QSGVisualDataModelParts *parts = static_cast<QSGVisualDataModelParts *>(object());
-    QSGVisualPartsModel *m = new QSGVisualPartsModel(
-            parts->model, QString::fromUtf8(name(id)), parts);
-    parts->models.append(m);
-    return QVariant::fromValue(static_cast<QObject *>(m));
-}
-
-QSGVisualDataModelParts::QSGVisualDataModelParts(QSGVisualDataModel *parent)
-: QObject(parent), model(parent)
-{
-    new QSGVisualDataModelPartsMetaObject(this);
-}
-
-//---------------------------------------------------------------------------
-
-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
-    \ingroup qml-working-with-data
-    \brief The VisualDataModel encapsulates a model and delegate
-
-    A VisualDataModel encapsulates a model and the delegate that will
-    be instantiated for items in the model.
-
-    It is usually not necessary to create VisualDataModel elements.
-    However, it can be useful for manipulating and accessing the \l modelIndex
-    when a QAbstractItemModel subclass is used as the
-    model. Also, VisualDataModel is used together with \l Package to
-    provide delegates to multiple views.
-
-    The example below illustrates using a VisualDataModel with a ListView.
-
-    \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);
-
-    QObject::connect(model, SIGNAL(itemsInserted(int,int)), q, SLOT(_q_itemsInserted(int,int)));
-    QObject::connect(model, SIGNAL(itemsRemoved(int,int)), q, SLOT(_q_itemsRemoved(int,int)));
-    QObject::connect(model, SIGNAL(itemsMoved(int,int,int)), q, SLOT(_q_itemsMoved(int,int,int)));
-    QObject::connect(model, SIGNAL(itemsChanged(int,int)), q, SLOT(_q_itemsChanged(int,int)));
-    QObject::connect(model, SIGNAL(modelReset(int,int)), q, SLOT(_q_modelReset(int,int)));
-}
-
-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()));
-
-    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()
-: QSGVisualModel(*(new QSGVisualDataModelPrivate(0)))
-{
-    Q_D(QSGVisualDataModel);
-    d->init();
-}
-
-QSGVisualDataModel::QSGVisualDataModel(QDeclarativeContext *ctxt, QObject *parent)
-: QSGVisualModel(*(new QSGVisualDataModelPrivate(ctxt)), parent)
-{
-    Q_D(QSGVisualDataModel);
-    d->init();
-}
-
-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));
-}
-
-/*!
-    \qmlproperty model QtQuick2::VisualDataModel::model
-    This property holds the model providing data for the VisualDataModel.
-
-    The model provides a set of data that is used to create the items
-    for a view.  For large or dynamic datasets the model is usually
-    provided by a C++ model object.  The C++ model object must be a \l
-    {QAbstractItemModel} subclass or a simple list.
-
-    Models can also be created directly in QML, using a \l{ListModel} or
-    \l{XmlListModel}.
-
-    \sa {qmlmodels}{Data Models}
-*/
-QVariant QSGVisualDataModel::model() const
-{
-    Q_D(const QSGVisualDataModel);
-    return d->m_adaptorModel->model();
-}
-
-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_complete && d->m_adaptorModel->canFetchMore())
-        QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
-}
-
-/*!
-    \qmlproperty Component QtQuick2::VisualDataModel::delegate
-
-    The delegate provides a template defining each item instantiated by a view.
-    The index is exposed as an accessible \c index property.  Properties of the
-    model are also available depending upon the type of \l {qmlmodels}{Data Model}.
-*/
-QDeclarativeComponent *QSGVisualDataModel::delegate() const
-{
-    Q_D(const QSGVisualDataModel);
-    return d->m_delegate;
-}
-
-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_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();
-}
-
-/*!
-    \qmlproperty QModelIndex QtQuick2::VisualDataModel::rootIndex
-
-    QAbstractItemModel provides a hierarchical tree of data, whereas
-    QML only operates on list data.  \c rootIndex allows the children of
-    any node in a QAbstractItemModel to be provided by this model.
-
-    This property only affects models of type QAbstractItemModel that
-    are hierarchical (e.g, a tree model).
-
-    For example, here is a simple interactive file system browser.
-    When a directory name is clicked, the view's \c rootIndex is set to the
-    QModelIndex node of the clicked directory, thus updating the view to show
-    the new directory's contents.
-
-    \c main.cpp:
-    \snippet doc/src/snippets/declarative/visualdatamodel_rootindex/main.cpp 0
-
-    \c view.qml:
-    \snippet doc/src/snippets/declarative/visualdatamodel_rootindex/view.qml 0
-
-    If the \l model is a QAbstractItemModel subclass, the delegate can also
-    reference a \c hasModelChildren property (optionally qualified by a
-    \e model. prefix) that indicates whether the delegate's model item has
-    any child nodes.
-
-
-    \sa modelIndex(), parentModelIndex()
-*/
-QVariant QSGVisualDataModel::rootIndex() const
-{
-    Q_D(const QSGVisualDataModel);
-    return d->m_adaptorModel->rootIndex();
-}
-
-void QSGVisualDataModel::setRootIndex(const QVariant &root)
-{
-    Q_D(QSGVisualDataModel);
-    d->m_adaptorModel->setRootIndex(root);
-}
-
-/*!
-    \qmlmethod QModelIndex QtQuick2::VisualDataModel::modelIndex(int index)
-
-    QAbstractItemModel provides a hierarchical tree of data, whereas
-    QML only operates on list data.  This function assists in using
-    tree models in QML.
-
-    Returns a QModelIndex for the specified index.
-    This value can be assigned to rootIndex.
-
-    \sa rootIndex
-*/
-QVariant QSGVisualDataModel::modelIndex(int idx) const
-{
-    Q_D(const QSGVisualDataModel);
-    return d->m_adaptorModel->modelIndex(idx);
-}
-
-/*!
-    \qmlmethod QModelIndex QtQuick2::VisualDataModel::parentModelIndex()
-
-    QAbstractItemModel provides a hierarchical tree of data, whereas
-    QML only operates on list data.  This function assists in using
-    tree models in QML.
-
-    Returns a QModelIndex for the parent of the current rootIndex.
-    This value can be assigned to rootIndex.
-
-    \sa rootIndex
-*/
-QVariant QSGVisualDataModel::parentModelIndex() const
-{
-    Q_D(const QSGVisualDataModel);
-    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_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 (!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;
-}
-
-/*
-  Returns ReleaseStatus flags.
-*/
-
-QSGVisualDataModel::ReleaseFlags QSGVisualDataModel::release(QSGItem *item)
-{
-    Q_D(QSGVisualDataModel);
-    QSGVisualModel::ReleaseFlags stat = d->release(item);
-    if (stat & Destroyed)
-        item->setParentItem(0);
-    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
-
-    The \a parts property selects a VisualDataModel which creates
-    delegates from the part named.  This is used in conjunction with
-    the \l Package element.
-
-    For example, the code below selects a model which creates
-    delegates named \e list from a \l Package:
-
-    \code
-    VisualDataModel {
-        id: visualModel
-        delegate: Package {
-            Item { Package.name: "list" }
-        }
-        model: myModel
-    }
-
-    ListView {
-        width: 200; height:200
-        model: visualModel.parts.list
-    }
-    \endcode
-
-    \sa Package
-*/
-
-QObject *QSGVisualDataModel::parts()
-{
-    Q_D(QSGVisualDataModel);
-    if (!d->m_parts)
-        d->m_parts = new QSGVisualDataModelParts(this);
-    return d->m_parts;
-}
-
-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);
-
-    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(
-                creationContext ? creationContext : m_context.data());
-        QDeclarativeContext *ctxt = rootContext;
-        if (m_adaptorModel->flags() & QSGVisualAdaptorModel::ProxiedObject) {
-            if (QSGVisualAdaptorModelProxyInterface *proxy = qobject_cast<QSGVisualAdaptorModelProxyInterface *>(data)) {
-                ctxt->setContextObject(proxy->proxiedObject());
-                ctxt = new QDeclarativeContext(ctxt, ctxt);
-            }
-        }
-
-        QDeclarative_setParent_noEvent(data, ctxt);
-        ctxt->setContextProperty(QLatin1String("model"), data);
-        ctxt->setContextObject(data);
-
-        m_completePending = false;
-        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_compositor.count(group) - 1 && m_adaptorModel->canFetchMore())
-        QCoreApplication::postEvent(q, new QEvent(QEvent::UpdateRequest));
-    if (reference)
-        cacheItem->referenceObject();
-    return cacheItem->object;
-}
-
-QSGItem *QSGVisualDataModel::item(int index, bool complete)
-{
-    Q_D(QSGVisualDataModel);
-    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 (d->m_completePending)
-        completeItem();
-    d->release(object);
-    if (!d->m_delegateValidated) {
-        if (object)
-            qmlInfo(d->m_delegate) << QSGVisualDataModel::tr("Delegate component must be Item type.");
-        d->m_delegateValidated = true;
-    }
-    return 0;
-}
-
-bool QSGVisualDataModel::completePending() const
-{
-    Q_D(const QSGVisualDataModel);
-    return d->m_completePending;
-}
-
-void QSGVisualDataModel::completeItem()
-{
-    Q_D(QSGVisualDataModel);
-    d->m_delegate->completeCreate();
-    d->m_completePending = false;
-}
-
-QString QSGVisualDataModelPrivate::stringValue(Compositor::Group group, int index, const QString &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(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);
-    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)
-{
-    Q_D(QSGVisualDataModel);
-    d->m_adaptorModel->replaceWatchedRoles(d->watchedRoles, 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);
-    if (e->type() == QEvent::UpdateRequest)
-        d->m_adaptorModel->fetchMore();
-    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 (count <= 0)
-        return;
-    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 (count <= 0)
-        return;
-    QVector<Compositor::Insert> inserts;
-    d->m_compositor.listItemsInserted(d->m_adaptorModel, index, count, &inserts);
-    d->itemsInserted(inserts);
-    d->emitChanges();
-}
-
-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 (!remove.inCache())
-            continue;
-
-        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 {
-            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;
-                }
-            }
-        }
-    }
-
-    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 (count <= 0)
-        return;
-
-    QVector<Compositor::Remove> removes;
-    d->m_compositor.listItemsRemoved(d->m_adaptorModel, index, count, &removes);
-    d->itemsRemoved(removes);
-    d->emitChanges();
-}
-
-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 (count <= 0)
-        return;
-
-    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();
-}
-
-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);
-    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();
-    }
-}
-
-void QSGVisualDataModel::_q_modelReset(int oldCount, int newCount)
-{
-    Q_D(QSGVisualDataModel);
-    if (!d->m_delegate)
-        return;
-
-    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();
-}
-
-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)
-{
-    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
-{
-    QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(m_model);
-    return model->m_delegate
-            ? model->m_compositor.count(m_compositorGroup)
-            : 0;
-}
-
-bool QSGVisualPartsModel::isValid() const
-{
-    return m_model->isValid();
-}
-
-QSGItem *QSGVisualPartsModel::item(int index, bool complete)
-{
-    QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(m_model);
-
-    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);
-        if (!part)
-            return 0;
-        if (QSGItem *item = qobject_cast<QSGItem *>(part)) {
-            m_packaged.insertMulti(item, package);
-            return item;
-        }
-    }
-
-    if (m_model->completePending())
-        m_model->completeItem();
-    model->release(object);
-    if (!model->m_delegateValidated) {
-        if (object)
-            qmlInfo(model->m_delegate) << tr("Delegate component must be Package type.");
-        model->m_delegateValidated = true;
-    }
-
-    return 0;
-}
-
-QSGVisualModel::ReleaseFlags QSGVisualPartsModel::release(QSGItem *item)
-{
-    QSGVisualModel::ReleaseFlags flags = 0;
-
-    QHash<QObject *, QDeclarativePackage *>::iterator it = m_packaged.find(item);
-    if (it != m_packaged.end()) {
-        QDeclarativePackage *package = *it;
-        QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(m_model);
-        flags = model->release(package);
-        m_packaged.erase(it);
-        if (!m_packaged.contains(item))
-            flags &= ~Referenced;
-        if (flags & Destroyed)
-            QSGVisualDataModelPrivate::get(m_model)->emitDestroyingPackage(package);
-    }
-    return flags;
-}
-
-bool QSGVisualPartsModel::completePending() const
-{
-    return m_model->completePending();
-}
-
-void QSGVisualPartsModel::completeItem()
-{
-    m_model->completeItem();
-}
-
-QString QSGVisualPartsModel::stringValue(int index, const QString &role)
-{
-    return QSGVisualDataModelPrivate::get(m_model)->stringValue(m_compositorGroup, index, role);
-}
-
-void QSGVisualPartsModel::setWatchedRoles(QList<QByteArray> roles)
-{
-    QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(m_model);
-    model->m_adaptorModel->replaceWatchedRoles(m_watchedRoles, roles);
-    m_watchedRoles = roles;
-}
-
-int QSGVisualPartsModel::indexOf(QSGItem *item, QObject *) const
-{
-    QHash<QObject *, QDeclarativePackage *>::const_iterator it = m_packaged.find(item);
-    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)
-{
-    if (QSGItem *item = qobject_cast<QSGItem *>(package->part(m_part)))
-        emit createdItem(index, item);
-}
-
-void QSGVisualPartsModel::destroyingPackage(QDeclarativePackage *package)
-{
-    if (QSGItem *item = qobject_cast<QSGItem *>(package->part(m_part))) {
-        Q_ASSERT(!m_packaged.contains(item));
-        emit destroyingItem(item);
-    }
-}
-
-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
deleted file mode 100644 (file)
index 896c51c..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
-/****************************************************************************
-**
-** 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 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
-
-Q_DECLARE_METATYPE(QModelIndex)
-
-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, 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 &);
-
-    QDeclarativeComponent *delegate() const;
-    void setDelegate(QDeclarativeComponent *);
-
-    QVariant rootIndex() const;
-    void setRootIndex(const QVariant &root);
-
-    Q_INVOKABLE QVariant modelIndex(int idx) const;
-    Q_INVOKABLE QVariant parentModelIndex() const;
-
-    int count() const;
-    bool isValid() const { return delegate() != 0; }
-    QSGItem *item(int index, bool complete=true);
-    ReleaseFlags release(QSGItem *item);
-    bool completePending() const;
-    void completeItem();
-    virtual QString stringValue(int index, const QString &role);
-    virtual void setWatchedRoles(QList<QByteArray> roles);
-
-    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 filterGroupChanged();
-    void defaultGroupsChanged();
-    void rootIndexChanged();
-
-private Q_SLOTS:
-    void _q_itemsChanged(int index, int count);
-    void _q_itemsInserted(int index, int count);
-    void _q_itemsRemoved(int index, int count);
-    void _q_itemsMoved(int from, int to, int count);
-    void _q_modelReset(int oldCount, int newCount);
-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
-
-#endif // QSGVISUALDATAMODEL_P_H
diff --git a/src/declarative/items/qsgvisualitemmodel.cpp b/src/declarative/items/qsgvisualitemmodel.cpp
deleted file mode 100644 (file)
index 90d008e..0000000
+++ /dev/null
@@ -1,243 +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 "qsgvisualitemmodel_p.h"
-#include "qsgitem.h"
-
-#include <QtCore/qcoreapplication.h>
-#include <QtDeclarative/qdeclarativecontext.h>
-#include <QtDeclarative/qdeclarativeengine.h>
-
-#include <private/qdeclarativechangeset_p.h>
-#include <private/qdeclarativeglobal_p.h>
-#include <private/qobject_p.h>
-
-#include <QtCore/qhash.h>
-#include <QtCore/qlist.h>
-
-QT_BEGIN_NAMESPACE
-
-QHash<QObject*, QSGVisualItemModelAttached*> QSGVisualItemModelAttached::attachedProperties;
-
-
-class QSGVisualItemModelPrivate : public QObjectPrivate
-{
-    Q_DECLARE_PUBLIC(QSGVisualItemModel)
-public:
-    QSGVisualItemModelPrivate() : QObjectPrivate() {}
-
-    static void children_append(QDeclarativeListProperty<QSGItem> *prop, QSGItem *item) {
-        QDeclarative_setParent_noEvent(item, prop->object);
-        static_cast<QSGVisualItemModelPrivate *>(prop->data)->children.append(Item(item));
-        static_cast<QSGVisualItemModelPrivate *>(prop->data)->itemAppended();
-        static_cast<QSGVisualItemModelPrivate *>(prop->data)->emitChildrenChanged();
-    }
-
-    static int children_count(QDeclarativeListProperty<QSGItem> *prop) {
-        return static_cast<QSGVisualItemModelPrivate *>(prop->data)->children.count();
-    }
-
-    static QSGItem *children_at(QDeclarativeListProperty<QSGItem> *prop, int index) {
-        return static_cast<QSGVisualItemModelPrivate *>(prop->data)->children.at(index).item;
-    }
-
-    void itemAppended() {
-        Q_Q(QSGVisualItemModel);
-        QSGVisualItemModelAttached *attached = QSGVisualItemModelAttached::properties(children.last().item);
-        attached->setIndex(children.count()-1);
-        QDeclarativeChangeSet changeSet;
-        changeSet.insert(children.count() - 1, 1);
-        emit q->modelUpdated(changeSet, false);
-        emit q->countChanged();
-    }
-
-    void emitChildrenChanged() {
-        Q_Q(QSGVisualItemModel);
-        emit q->childrenChanged();
-    }
-
-    int indexOf(QSGItem *item) const {
-        for (int i = 0; i < children.count(); ++i)
-            if (children.at(i).item == item)
-                return i;
-        return -1;
-    }
-
-    class Item {
-    public:
-        Item(QSGItem *i) : item(i), ref(0) {}
-
-        void addRef() { ++ref; }
-        bool deref() { return --ref == 0; }
-
-        QSGItem *item;
-        int ref;
-    };
-
-    QList<Item> children;
-};
-
-
-/*!
-    \qmlclass VisualItemModel QSGVisualItemModel
-    \inqmlmodule QtQuick 2
-    \ingroup qml-working-with-data
-    \brief The VisualItemModel allows items to be provided to a view.
-
-    A VisualItemModel contains the visual items to be used in a view.
-    When a VisualItemModel is used in a view, the view does not require
-    a delegate since the VisualItemModel already contains the visual
-    delegate (items).
-
-    An item can determine its index within the
-    model via the \l{VisualItemModel::index}{index} attached property.
-
-    The example below places three colored rectangles in a ListView.
-    \code
-    import QtQuick 1.0
-
-    Rectangle {
-        VisualItemModel {
-            id: itemModel
-            Rectangle { height: 30; width: 80; color: "red" }
-            Rectangle { height: 30; width: 80; color: "green" }
-            Rectangle { height: 30; width: 80; color: "blue" }
-        }
-
-        ListView {
-            anchors.fill: parent
-            model: itemModel
-        }
-    }
-    \endcode
-
-    \image visualitemmodel.png
-
-    \sa {declarative/modelviews/visualitemmodel}{VisualItemModel example}
-*/
-QSGVisualItemModel::QSGVisualItemModel(QObject *parent)
-    : QSGVisualModel(*(new QSGVisualItemModelPrivate), parent)
-{
-}
-
-/*!
-    \qmlattachedproperty int QtQuick2::VisualItemModel::index
-    This attached property holds the index of this delegate's item within the model.
-
-    It is attached to each instance of the delegate.
-*/
-
-QDeclarativeListProperty<QSGItem> QSGVisualItemModel::children()
-{
-    Q_D(QSGVisualItemModel);
-    return QDeclarativeListProperty<QSGItem>(this, d, d->children_append,
-                                                      d->children_count, d->children_at);
-}
-
-/*!
-    \qmlproperty int QtQuick2::VisualItemModel::count
-
-    The number of items in the model.  This property is readonly.
-*/
-int QSGVisualItemModel::count() const
-{
-    Q_D(const QSGVisualItemModel);
-    return d->children.count();
-}
-
-bool QSGVisualItemModel::isValid() const
-{
-    return true;
-}
-
-QSGItem *QSGVisualItemModel::item(int index, bool)
-{
-    Q_D(QSGVisualItemModel);
-    QSGVisualItemModelPrivate::Item &item = d->children[index];
-    item.addRef();
-    return item.item;
-}
-
-QSGVisualModel::ReleaseFlags QSGVisualItemModel::release(QSGItem *item)
-{
-    Q_D(QSGVisualItemModel);
-    int idx = d->indexOf(item);
-    if (idx >= 0) {
-        if (d->children[idx].deref()) {
-            // XXX todo - the original did item->scene()->removeItem().  Why?
-            item->setParentItem(0);
-            QDeclarative_setParent_noEvent(item, this);
-        }
-    }
-    return 0;
-}
-
-bool QSGVisualItemModel::completePending() const
-{
-    return false;
-}
-
-void QSGVisualItemModel::completeItem()
-{
-    // Nothing to do
-}
-
-QString QSGVisualItemModel::stringValue(int index, const QString &name)
-{
-    Q_D(QSGVisualItemModel);
-    if (index < 0 || index >= d->children.count())
-        return QString();
-    return QDeclarativeEngine::contextForObject(d->children.at(index).item)->contextProperty(name).toString();
-}
-
-int QSGVisualItemModel::indexOf(QSGItem *item, QObject *) const
-{
-    Q_D(const QSGVisualItemModel);
-    return d->indexOf(item);
-}
-
-QSGVisualItemModelAttached *QSGVisualItemModel::qmlAttachedProperties(QObject *obj)
-{
-    return QSGVisualItemModelAttached::properties(obj);
-}
-
-QT_END_NAMESPACE
-
diff --git a/src/declarative/items/qsgvisualitemmodel_p.h b/src/declarative/items/qsgvisualitemmodel_p.h
deleted file mode 100644 (file)
index 6e8606c..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
-/****************************************************************************
-**
-** 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 QSGVISUALITEMMODEL_P_H
-#define QSGVISUALITEMMODEL_P_H
-
-#include <QtDeclarative/qdeclarative.h>
-#include <QtCore/qobject.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGItem;
-class QDeclarativeChangeSet;
-
-class Q_DECLARATIVE_EXPORT QSGVisualModel : public QObject
-{
-    Q_OBJECT
-
-    Q_PROPERTY(int count READ count NOTIFY countChanged)
-
-public:
-    virtual ~QSGVisualModel() {}
-
-    enum ReleaseFlag { Referenced = 0x01, Destroyed = 0x02 };
-    Q_DECLARE_FLAGS(ReleaseFlags, ReleaseFlag)
-
-    virtual int count() const = 0;
-    virtual bool isValid() const = 0;
-    virtual QSGItem *item(int index, bool complete=true) = 0;
-    virtual ReleaseFlags release(QSGItem *item) = 0;
-    virtual bool completePending() const = 0;
-    virtual void completeItem() = 0;
-    virtual QString stringValue(int, const QString &) = 0;
-    virtual void setWatchedRoles(QList<QByteArray> roles) = 0;
-
-    virtual int indexOf(QSGItem *item, QObject *objectContext) const = 0;
-
-Q_SIGNALS:
-    void countChanged();
-    void modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset);
-    void createdItem(int index, QSGItem *item);
-    void destroyingItem(QSGItem *item);
-
-protected:
-    QSGVisualModel(QObjectPrivate &dd, QObject *parent = 0)
-        : QObject(dd, parent) {}
-
-private:
-    Q_DISABLE_COPY(QSGVisualModel)
-};
-
-class QSGVisualItemModelAttached;
-class QSGVisualItemModelPrivate;
-class Q_DECLARATIVE_EXPORT QSGVisualItemModel : public QSGVisualModel
-{
-    Q_OBJECT
-    Q_DECLARE_PRIVATE(QSGVisualItemModel)
-
-    Q_PROPERTY(QDeclarativeListProperty<QSGItem> children READ children NOTIFY childrenChanged DESIGNABLE false)
-    Q_CLASSINFO("DefaultProperty", "children")
-
-public:
-    QSGVisualItemModel(QObject *parent=0);
-    virtual ~QSGVisualItemModel() {}
-
-    virtual int count() const;
-    virtual bool isValid() const;
-    virtual QSGItem *item(int index, bool complete=true);
-    virtual ReleaseFlags release(QSGItem *item);
-    virtual bool completePending() const;
-    virtual void completeItem();
-    virtual QString stringValue(int index, const QString &role);
-    virtual void setWatchedRoles(QList<QByteArray>) {}
-
-    virtual int indexOf(QSGItem *item, QObject *objectContext) const;
-
-    QDeclarativeListProperty<QSGItem> children();
-
-    static QSGVisualItemModelAttached *qmlAttachedProperties(QObject *obj);
-
-Q_SIGNALS:
-    void childrenChanged();
-
-private:
-    Q_DISABLE_COPY(QSGVisualItemModel)
-};
-
-class QSGVisualItemModelAttached : public QObject
-{
-    Q_OBJECT
-
-public:
-    QSGVisualItemModelAttached(QObject *parent)
-        : QObject(parent), m_index(0) {}
-    ~QSGVisualItemModelAttached() {
-        attachedProperties.remove(parent());
-    }
-
-    Q_PROPERTY(int index READ index NOTIFY indexChanged)
-    int index() const { return m_index; }
-    void setIndex(int idx) {
-        if (m_index != idx) {
-            m_index = idx;
-            emit indexChanged();
-        }
-    }
-
-    static QSGVisualItemModelAttached *properties(QObject *obj) {
-        QSGVisualItemModelAttached *rv = attachedProperties.value(obj);
-        if (!rv) {
-            rv = new QSGVisualItemModelAttached(obj);
-            attachedProperties.insert(obj, rv);
-        }
-        return rv;
-    }
-
-Q_SIGNALS:
-    void indexChanged();
-
-public:
-    int m_index;
-
-    static QHash<QObject*, QSGVisualItemModelAttached*> attachedProperties;
-};
-
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QSGVisualModel)
-QML_DECLARE_TYPE(QSGVisualItemModel)
-QML_DECLARE_TYPEINFO(QSGVisualItemModel, QML_HAS_ATTACHED_PROPERTIES)
-
-QT_END_HEADER
-
-#endif // QSGVISUALITEMMODEL_P_H
index da7736a..797dd14 100644 (file)
@@ -76,7 +76,7 @@ QT_BEGIN_NAMESPACE
     Default value is true.
 */
 
-QSGAgeAffector::QSGAgeAffector(QSGItem *parent) :
+QSGAgeAffector::QSGAgeAffector(QQuickItem *parent) :
     QSGParticleAffector(parent), m_lifeLeft(0), m_advancePosition(true)
 {
 }
index 6761220..63ec8f7 100644 (file)
@@ -57,7 +57,7 @@ class QSGAgeAffector : public QSGParticleAffector
     Q_PROPERTY(bool advancePosition READ advancePosition WRITE setAdvancePosition NOTIFY advancePositionChanged)
 
 public:
-    explicit QSGAgeAffector(QSGItem *parent = 0);
+    explicit QSGAgeAffector(QQuickItem *parent = 0);
 
     int lifeLeft() const
     {
index 9f8db2c..ffa86aa 100644 (file)
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
     Note that JS is slower to execute, so it is not recommended to use this in
     high-volume particle systems.
 */
-QSGCustomAffector::QSGCustomAffector(QSGItem *parent) :
+QSGCustomAffector::QSGCustomAffector(QQuickItem *parent) :
     QSGParticleAffector(parent)
 {
 }
index fc0735e..679034e 100644 (file)
@@ -58,7 +58,7 @@ class QSGCustomAffector : public QSGParticleAffector
     Q_OBJECT
 
 public:
-    explicit QSGCustomAffector(QSGItem *parent = 0);
+    explicit QSGCustomAffector(QQuickItem *parent = 0);
     virtual void affectSystem(qreal dt);
 
 signals:
index 89e465b..d00f6bb 100644 (file)
@@ -40,7 +40,7 @@
 ****************************************************************************/
 
 #include "qsgcustomparticle_p.h"
-#include <private/qsgshadereffectmesh_p.h>
+#include <private/qquickshadereffectmesh_p.h>
 #include <cstdlib>
 
 QT_BEGIN_NAMESPACE
@@ -128,16 +128,16 @@ struct PlainVertices {
 
 */
 
-QSGCustomParticle::QSGCustomParticle(QSGItem* parent)
+QSGCustomParticle::QSGCustomParticle(QQuickItem* parent)
     : QSGParticlePainter(parent)
     , m_dirtyData(true)
     , m_material(0)
     , m_rootNode(0)
 {
-    setFlag(QSGItem::ItemHasContents);
+    setFlag(QQuickItem::ItemHasContents);
 }
 
-class QSGShaderEffectMaterialObject : public QObject, public QSGShaderEffectMaterial { };
+class QSGShaderEffectMaterialObject : public QObject, public QQuickShaderEffectMaterial { };
 
 QSGCustomParticle::~QSGCustomParticle()
 {
@@ -277,7 +277,7 @@ void QSGCustomParticle::setSource(const QVariant &var, int index)
     }
 
     QObject *obj = qVariantValue<QObject *>(var);
-    source.item = qobject_cast<QSGItem *>(obj);
+    source.item = qobject_cast<QQuickItem *>(obj);
     if (!source.item || !source.item->isTextureProvider()) {
         qWarning("ShaderEffect: source uniform [%s] is not assigned a valid texture provider: %s [%s]",
                  source.name.constData(), qPrintable(obj->objectName()), obj->metaObject()->className());
@@ -448,7 +448,7 @@ void QSGCustomParticle::prepareNextFrame(){
         buildData();
 }
 
-QSGShaderEffectNode* QSGCustomParticle::buildCustomNodes()
+QQuickShaderEffectNode* QSGCustomParticle::buildCustomNodes()
 {
 #ifdef QT_OPENGL_ES_2
     if (m_count * 4 > 0xffff) {
@@ -464,7 +464,7 @@ QSGShaderEffectNode* QSGCustomParticle::buildCustomNodes()
 
     updateProperties();
 
-    QSGShaderEffectProgram s = m_source;
+    QQuickShaderEffectProgram s = m_source;
     if (s.fragmentCode.isEmpty())
         s.fragmentCode = qt_particles_default_fragment_code;
     if (s.vertexCode.isEmpty())
@@ -480,7 +480,7 @@ QSGShaderEffectNode* QSGCustomParticle::buildCustomNodes()
         int gIdx = m_system->groupIds[str];
         int count = m_system->groupData[gIdx]->size();
 
-        QSGShaderEffectNode* node = new QSGShaderEffectNode();
+        QQuickShaderEffectNode* node = new QQuickShaderEffectNode();
         m_nodes.insert(gIdx, node);
 
         node->setMaterial(m_material);
@@ -520,7 +520,7 @@ QSGShaderEffectNode* QSGCustomParticle::buildCustomNodes()
             indices += 6;
         }
     }
-    foreach (QSGShaderEffectNode* node, m_nodes){
+    foreach (QQuickShaderEffectNode* node, m_nodes){
         if (node == *(m_nodes.begin()))
                 continue;
         (*(m_nodes.begin()))->appendChildNode(node);
@@ -541,7 +541,7 @@ void QSGCustomParticle::buildData()
     for (int i = 0; i < oldTextures.size(); ++i) {
         QSGTextureProvider *t = oldTextures.at(i).second;
         if (t)
-            foreach (QSGShaderEffectNode* node, m_nodes)
+            foreach (QQuickShaderEffectNode* node, m_nodes)
                 disconnect(t, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture()));
     }
     for (int i = 0; i < m_sources.size(); ++i) {
@@ -549,7 +549,7 @@ void QSGCustomParticle::buildData()
         QSGTextureProvider *t = source.item->textureProvider();
         textures.append(qMakePair(source.name, t));
         if (t)
-            foreach (QSGShaderEffectNode* node, m_nodes)
+            foreach (QQuickShaderEffectNode* node, m_nodes)
                 connect(t, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture()), Qt::DirectConnection);
     }
     for (QSet<QByteArray>::const_iterator it = m_source.uniformNames.begin();
@@ -560,7 +560,7 @@ void QSGCustomParticle::buildData()
     m_material->setUniforms(values);
     m_material->setTextureProviders(textures);
     m_dirtyData = false;
-    foreach (QSGShaderEffectNode* node, m_nodes)
+    foreach (QQuickShaderEffectNode* node, m_nodes)
         node->markDirty(QSGNode::DirtyMaterial);
 }
 
index 99f63d5..271cc0a 100644 (file)
@@ -42,7 +42,7 @@
 #ifndef CUSTOM_PARTICLE_H
 #define CUSTOM_PARTICLE_H
 #include "qsgparticlepainter_p.h"
-#include <private/qsgshadereffectnode_p.h>
+#include <private/qquickshadereffectnode_p.h>
 #include <QSignalMapper>
 
 QT_BEGIN_HEADER
@@ -64,7 +64,7 @@ class QSGCustomParticle : public QSGParticlePainter
     Q_PROPERTY(QByteArray vertexShader READ vertexShader WRITE setVertexShader NOTIFY vertexShaderChanged)
 
 public:
-    explicit QSGCustomParticle(QSGItem* parent=0);
+    explicit QSGCustomParticle(QQuickItem* parent=0);
     ~QSGCustomParticle();
 
     QByteArray fragmentShader() const { return m_source.fragmentCode; }
@@ -92,24 +92,24 @@ protected:
     void updateProperties();
     void lookThroughShaderCode(const QByteArray &code);
     virtual void componentComplete();
-    QSGShaderEffectNode *buildCustomNodes();
+    QQuickShaderEffectNode *buildCustomNodes();
     void performPendingResize();
 
 private:
     void buildData();
 
     bool m_dirtyData;
-    QSGShaderEffectProgram m_source;
+    QQuickShaderEffectProgram m_source;
     struct SourceData
     {
         QSignalMapper *mapper;
-        QPointer<QSGItem> item;
+        QPointer<QQuickItem> item;
         QByteArray name;
     };
     QVector<SourceData> m_sources;
     QSGShaderEffectMaterialObject *m_material;
-    QSGShaderEffectNode* m_rootNode;
-    QHash<int, QSGShaderEffectNode*> m_nodes;
+    QQuickShaderEffectNode* m_rootNode;
+    QHash<int, QQuickShaderEffectNode*> m_nodes;
     qreal m_lastTime;
 
 };
index 44b08e3..85a586b 100644 (file)
@@ -59,7 +59,7 @@ static qreal sign(qreal a)
     return a >= 0 ? 1 : -1;
 }
 
-QSGFrictionAffector::QSGFrictionAffector(QSGItem *parent) :
+QSGFrictionAffector::QSGFrictionAffector(QQuickItem *parent) :
     QSGParticleAffector(parent), m_factor(0.0)
 {
 }
index 699a205..e2b3a0c 100644 (file)
@@ -55,7 +55,7 @@ class QSGFrictionAffector : public QSGParticleAffector
     Q_OBJECT
     Q_PROPERTY(qreal factor READ factor WRITE setFactor NOTIFY factorChanged)
 public:
-    explicit QSGFrictionAffector(QSGItem *parent = 0);
+    explicit QSGFrictionAffector(QQuickItem *parent = 0);
 
     qreal factor() const
     {
index dd47f66..2967f7a 100644 (file)
@@ -70,7 +70,7 @@ const qreal CONV = 0.017453292520444443;
     Angle of acceleration.
 */
 
-QSGGravityAffector::QSGGravityAffector(QSGItem *parent) :
+QSGGravityAffector::QSGGravityAffector(QQuickItem *parent) :
     QSGParticleAffector(parent), m_acceleration(-10), m_angle(90), m_xAcc(0), m_yAcc(0)
 {
     connect(this, SIGNAL(accelerationChanged(qreal)),
index f96df1a..42bf144 100644 (file)
@@ -56,7 +56,7 @@ class QSGGravityAffector : public QSGParticleAffector
     Q_PROPERTY(qreal acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged)
     Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged)
 public:
-    explicit QSGGravityAffector(QSGItem *parent = 0);
+    explicit QSGGravityAffector(QQuickItem *parent = 0);
     qreal acceleration() const
     {
         return m_acceleration;
index f380101..78fa786 100644 (file)
@@ -40,8 +40,8 @@
 ****************************************************************************/
 
 #include "qsggroupgoal_p.h"
-#include <private/qsgspriteengine_p.h>
-#include <private/qsgsprite_p.h>
+#include <private/qquickspriteengine_p.h>
+#include <private/qquicksprite_p.h>
 #include "qsgimageparticle_p.h"
 #include <QDebug>
 
@@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE
     Default is false.
 */
 
-QSGGroupGoalAffector::QSGGroupGoalAffector(QSGItem *parent) :
+QSGGroupGoalAffector::QSGGroupGoalAffector(QQuickItem *parent) :
     QSGParticleAffector(parent), m_jump(false)
 {
 }
@@ -90,7 +90,7 @@ void QSGGroupGoalAffector::setGoalState(QString arg)
 bool QSGGroupGoalAffector::affectParticle(QSGParticleData *d, qreal dt)
 {
     Q_UNUSED(dt);
-    QSGStochasticEngine *engine = m_system->stateEngine;
+    QQuickStochasticEngine *engine = m_system->stateEngine;
     bool notUsingEngine = false;
     if (!engine)
         notUsingEngine = true;
index 6357c3f..59ccb7a 100644 (file)
@@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE
 
 QT_MODULE(Declarative)
 
-class QSGStochasticEngine;
+class QQuickStochasticEngine;
 
 class QSGGroupGoalAffector : public QSGParticleAffector
 {
@@ -57,7 +57,7 @@ class QSGGroupGoalAffector : public QSGParticleAffector
     Q_PROPERTY(QString goalState READ goalState WRITE setGoalState NOTIFY goalStateChanged)
     Q_PROPERTY(bool jump READ jump WRITE setJump NOTIFY jumpChanged)
 public:
-    explicit QSGGroupGoalAffector(QSGItem *parent = 0);
+    explicit QSGGroupGoalAffector(QQuickItem *parent = 0);
 
     QString goalState() const
     {
index 02b3a7a..7791db6 100644 (file)
@@ -47,8 +47,8 @@
 #include <QFile>
 #include "qsgimageparticle_p.h"
 #include "qsgparticleemitter_p.h"
-#include <private/qsgsprite_p.h>
-#include <private/qsgspriteengine_p.h>
+#include <private/qquicksprite_p.h>
+#include <private/qquickspriteengine_p.h>
 #include <QOpenGLFunctions>
 #include <qsgengine.h>
 #include <private/qsgtexture_p.h>
@@ -797,7 +797,7 @@ void fillUniformArrayFromImage(float* array, const QImage& img, int size)
 */
 
 
-QSGImageParticle::QSGImageParticle(QSGItem* parent)
+QSGImageParticle::QSGImageParticle(QQuickItem* parent)
     : QSGParticlePainter(parent)
     , m_color_variation(0.0)
     , m_rootNode(0)
@@ -834,9 +834,9 @@ QSGImageParticle::~QSGImageParticle()
 {
 }
 
-QDeclarativeListProperty<QSGSprite> QSGImageParticle::sprites()
+QDeclarativeListProperty<QQuickSprite> QSGImageParticle::sprites()
 {
-    return QDeclarativeListProperty<QSGSprite>(this, &m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear);
+    return QDeclarativeListProperty<QQuickSprite>(this, &m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear);
 }
 
 void QSGImageParticle::setImage(const QUrl &image)
@@ -1115,7 +1115,7 @@ void QSGImageParticle::createEngine()
     if (m_spriteEngine)
         delete m_spriteEngine;
     if (m_sprites.count())
-        m_spriteEngine = new QSGSpriteEngine(m_sprites, this);
+        m_spriteEngine = new QQuickSpriteEngine(m_sprites, this);
     else
         m_spriteEngine = 0;
     m_explicitAnimation = true;
index 89796da..0836e3e 100644 (file)
@@ -56,8 +56,8 @@ QT_MODULE(Declarative)
 class ImageMaterialData;
 class QSGGeometryNode;
 
-class QSGSprite;
-class QSGStochasticEngine;
+class QQuickSprite;
+class QQuickStochasticEngine;
 
 struct SimpleVertex {
     float x;
@@ -180,19 +180,19 @@ class QSGImageParticle : public QSGParticlePainter
     Q_PROPERTY(QSGDirection* xVector READ xVector WRITE setXVector NOTIFY xVectorChanged RESET resetDeformation)
     //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(QDeclarativeListProperty<QQuickSprite> 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
     Q_ENUMS(EntryEffect)
 public:
-    explicit QSGImageParticle(QSGItem *parent = 0);
+    explicit QSGImageParticle(QQuickItem *parent = 0);
     virtual ~QSGImageParticle();
 
 
-    QDeclarativeListProperty<QSGSprite> sprites();
-    QSGStochasticEngine* spriteEngine() {return m_spriteEngine;}
+    QDeclarativeListProperty<QQuickSprite> sprites();
+    QQuickStochasticEngine* spriteEngine() {return m_spriteEngine;}
 
     enum EntryEffect {
         None = 0,
@@ -381,8 +381,8 @@ private:
     QSGDirection* m_xVector;
     QSGDirection* m_yVector;
 
-    QList<QSGSprite*> m_sprites;
-    QSGSpriteEngine* m_spriteEngine;
+    QList<QQuickSprite*> m_sprites;
+    QQuickSpriteEngine* m_spriteEngine;
     bool m_spritesInterpolate;
 
     bool m_explicitColor;
index 20bd18d..3be40dc 100644 (file)
@@ -40,7 +40,7 @@
 ****************************************************************************/
 
 #include "qsgitemparticle_p.h"
-#include <private/qsgvisualitemmodel_p.h>
+#include <private/qquickvisualitemmodel_p.h>
 #include <qsgnode.h>
 #include <QTimer>
 #include <QDeclarativeComponent>
@@ -49,7 +49,7 @@
 QT_BEGIN_NAMESPACE
 
 /*!
-    \qmlclass ItemParticle QSGItemParticle
+    \qmlclass ItemParticle QQuickItemParticle
     \inqmlmodule QtQuick.Particles 2
     \inherits ParticlePainter
     \brief The ItemParticle element allows you to specify your own delegate to paint particles.
@@ -99,10 +99,10 @@ QT_BEGIN_NAMESPACE
     particle, and moved along with it.
 */
 
-QSGItemParticle::QSGItemParticle(QSGItem *parent) :
+QQuickItemParticle::QQuickItemParticle(QQuickItem *parent) :
     QSGParticlePainter(parent), m_fade(true), m_delegate(0)
 {
-    setFlag(QSGItem::ItemHasContents);
+    setFlag(QQuickItem::ItemHasContents);
     QTimer* manageDelegates = new QTimer(this);//TODO: don't leak
     connect(manageDelegates, SIGNAL(timeout()),
             this, SLOT(tick()));
@@ -112,18 +112,18 @@ QSGItemParticle::QSGItemParticle(QSGItem *parent) :
 }
 
 
-void QSGItemParticle::freeze(QSGItem* item)
+void QQuickItemParticle::freeze(QQuickItem* item)
 {
     m_stasis << item;
 }
 
 
-void QSGItemParticle::unfreeze(QSGItem* item)
+void QQuickItemParticle::unfreeze(QQuickItem* item)
 {
     m_stasis.remove(item);
 }
 
-void QSGItemParticle::take(QSGItem *item, bool prioritize)
+void QQuickItemParticle::take(QQuickItem *item, bool prioritize)
 {
     if (prioritize)
         m_pendingItems.push_front(item);
@@ -131,28 +131,28 @@ void QSGItemParticle::take(QSGItem *item, bool prioritize)
         m_pendingItems.push_back(item);
 }
 
-void QSGItemParticle::give(QSGItem *item)
+void QQuickItemParticle::give(QQuickItem *item)
 {
     //TODO: This
 }
 
-void QSGItemParticle::initialize(int gIdx, int pIdx)
+void QQuickItemParticle::initialize(int gIdx, int pIdx)
 {
     m_loadables << m_system->groupData[gIdx]->data[pIdx];//defer to other thread
 }
 
-void QSGItemParticle::commit(int, int)
+void QQuickItemParticle::commit(int, int)
 {
 }
 
-void QSGItemParticle::tick()
+void QQuickItemParticle::tick()
 {
-    foreach (QSGItem* item, m_deletables){
+    foreach (QQuickItem* item, m_deletables){
         if (m_fade)
             item->setOpacity(0.);
         item->setVisible(false);
-        QSGItemParticleAttached* mpa;
-        if ((mpa = qobject_cast<QSGItemParticleAttached*>(qmlAttachedPropertiesObject<QSGItemParticle>(item))))
+        QQuickItemParticleAttached* mpa;
+        if ((mpa = qobject_cast<QQuickItemParticleAttached*>(qmlAttachedPropertiesObject<QQuickItemParticle>(item))))
             mpa->detach();//reparent as well?
         //TODO: Delete iff we created it
         m_activeCount--;
@@ -170,12 +170,12 @@ void QSGItemParticle::tick()
             d->delegate = m_pendingItems.front();
             m_pendingItems.pop_front();
         }else if (m_delegate){
-            d->delegate = qobject_cast<QSGItem*>(m_delegate->create(qmlContext(this)));
+            d->delegate = qobject_cast<QQuickItem*>(m_delegate->create(qmlContext(this)));
         }
         if (d->delegate && d){//###Data can be zero if creating an item leads to a reset - this screws things up.
             d->delegate->setX(d->curX() - d->delegate->width()/2);//TODO: adjust for system?
             d->delegate->setY(d->curY() - d->delegate->height()/2);
-            QSGItemParticleAttached* mpa = qobject_cast<QSGItemParticleAttached*>(qmlAttachedPropertiesObject<QSGItemParticle>(d->delegate));
+            QQuickItemParticleAttached* mpa = qobject_cast<QQuickItemParticleAttached*>(qmlAttachedPropertiesObject<QQuickItemParticle>(d->delegate));
             if (mpa){
                 mpa->m_mp = this;
                 mpa->attach();
@@ -190,7 +190,7 @@ void QSGItemParticle::tick()
     m_loadables.clear();
 }
 
-void QSGItemParticle::reset()
+void QQuickItemParticle::reset()
 {
     QSGParticlePainter::reset();
     //TODO: Cleanup items?
@@ -199,7 +199,7 @@ void QSGItemParticle::reset()
 }
 
 
-QSGNode* QSGItemParticle::updatePaintNode(QSGNode* n, UpdatePaintNodeData* d)
+QSGNode* QQuickItemParticle::updatePaintNode(QSGNode* n, UpdatePaintNodeData* d)
 {
     //Dummy update just to get painting tick
     if (m_pleaseReset){
@@ -211,10 +211,10 @@ QSGNode* QSGItemParticle::updatePaintNode(QSGNode* n, UpdatePaintNodeData* d)
     update();//Get called again
     if (n)
         n->markDirty(QSGNode::DirtyMaterial);
-    return QSGItem::updatePaintNode(n,d);
+    return QQuickItem::updatePaintNode(n,d);
 }
 
-void QSGItemParticle::prepareNextFrame()
+void QQuickItemParticle::prepareNextFrame()
 {
     if (!m_system)
         return;
@@ -232,7 +232,7 @@ void QSGItemParticle::prepareNextFrame()
 
         for (int i=0; i<count; i++){
             QSGParticleData* data = m_system->groupData[gIdx]->data[i];
-            QSGItem* item = data->delegate;
+            QQuickItem* item = data->delegate;
             if (!item)
                 continue;
             qreal t = ((timeStamp/1000.0) - data->t) / data->lifeSpan;
@@ -260,9 +260,9 @@ void QSGItemParticle::prepareNextFrame()
     }
 }
 
-QSGItemParticleAttached *QSGItemParticle::qmlAttachedProperties(QObject *object)
+QQuickItemParticleAttached *QQuickItemParticle::qmlAttachedProperties(QObject *object)
 {
-    return new QSGItemParticleAttached(object);
+    return new QQuickItemParticleAttached(object);
 }
 
 QT_END_NAMESPACE
index d189595..813f1ce 100644 (file)
@@ -49,22 +49,22 @@ QT_BEGIN_HEADER
 QT_BEGIN_NAMESPACE
 
 QT_MODULE(Declarative)
-class QSGVisualDataModel;
-class QSGItemParticleAttached;
+class QQuickVisualDataModel;
+class QQuickItemParticleAttached;
 
-class QSGItemParticle : public QSGParticlePainter
+class QQuickItemParticle : public QSGParticlePainter
 {
     Q_OBJECT
     Q_PROPERTY(bool fade READ fade WRITE setFade NOTIFY fadeChanged)
     Q_PROPERTY(QDeclarativeComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
 public:
-    explicit QSGItemParticle(QSGItem *parent = 0);
+    explicit QQuickItemParticle(QQuickItem *parent = 0);
 
     bool fade() const { return m_fade; }
 
     virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
 
-    static QSGItemParticleAttached *qmlAttachedProperties(QObject *object);
+    static QQuickItemParticleAttached *qmlAttachedProperties(QObject *object);
     QDeclarativeComponent* delegate() const
     {
         return m_delegate;
@@ -77,10 +77,10 @@ signals:
 
 public slots:
     //TODO: Add a follow mode, where moving the delegate causes the logical particle to go with it?
-    void freeze(QSGItem* item);
-    void unfreeze(QSGItem* item);
-    void take(QSGItem* item,bool prioritize=false);//take by modelparticle
-    void give(QSGItem* item);//give from modelparticle
+    void freeze(QQuickItem* item);
+    void unfreeze(QQuickItem* item);
+    void take(QQuickItem* item,bool prioritize=false);//take by modelparticle
+    void give(QQuickItem* item);//give from modelparticle
 
     void setFade(bool arg){if (arg == m_fade) return; m_fade = arg; emit fadeChanged();}
     void setDelegate(QDeclarativeComponent* arg)
@@ -99,32 +99,32 @@ protected:
 private slots:
     void tick();
 private:
-    QList<QSGItem* > m_deletables;
+    QList<QQuickItem* > m_deletables;
     QList< QSGParticleData* > m_loadables;
     bool m_fade;
 
-    QList<QSGItem*> m_pendingItems;
+    QList<QQuickItem*> m_pendingItems;
     QList<int> m_available;
-    QSet<QSGItem*> m_stasis;
+    QSet<QQuickItem*> m_stasis;
     qreal m_lastT;
     int m_activeCount;
     QDeclarativeComponent* m_delegate;
 };
 
-class QSGItemParticleAttached : public QObject
+class QQuickItemParticleAttached : public QObject
 {
     Q_OBJECT
-    Q_PROPERTY(QSGItemParticle* particle READ particle CONSTANT);
+    Q_PROPERTY(QQuickItemParticle* particle READ particle CONSTANT);
 public:
-    QSGItemParticleAttached(QObject* parent)
+    QQuickItemParticleAttached(QObject* parent)
         : QObject(parent), m_mp(0)
     {;}
-    QSGItemParticle* particle() {return m_mp;}
+    QQuickItemParticle* particle() {return m_mp;}
     void detach(){emit detached();}
     void attach(){emit attached();}
 private:
-    QSGItemParticle* m_mp;
-    friend class QSGItemParticle;
+    QQuickItemParticle* m_mp;
+    friend class QQuickItemParticle;
 Q_SIGNALS:
     void detached();
     void attached();
@@ -132,7 +132,7 @@ Q_SIGNALS:
 
 QT_END_NAMESPACE
 
-QML_DECLARE_TYPEINFO(QSGItemParticle, QML_HAS_ATTACHED_PROPERTIES)
+QML_DECLARE_TYPEINFO(QQuickItemParticle, QML_HAS_ATTACHED_PROPERTIES)
 
 QT_END_HEADER
 #endif // ITEMPARTICLE_H
index e885685..9f13fad 100644 (file)
@@ -84,7 +84,7 @@ const qreal CONV = 0.017453292520444443;
     to the new one.
 */
 
-QSGMoveAffector::QSGMoveAffector(QSGItem *parent)
+QSGMoveAffector::QSGMoveAffector(QQuickItem *parent)
     : QSGParticleAffector(parent)
     , m_position(&m_nullVector)
     , m_speed(&m_nullVector)
index 2f7fc83..4ff5239 100644 (file)
@@ -60,7 +60,7 @@ class QSGMoveAffector : public QSGParticleAffector
     Q_PROPERTY(QSGDirection *acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged RESET accelerationReset)
 
 public:
-    explicit QSGMoveAffector(QSGItem *parent = 0);
+    explicit QSGMoveAffector(QQuickItem *parent = 0);
     QSGDirection * position() const
     {
         return m_position;
index 24bddea..2758e93 100644 (file)
@@ -126,8 +126,8 @@ QT_BEGIN_NAMESPACE
 
     x,y is the particles current position.
 */
-QSGParticleAffector::QSGParticleAffector(QSGItem *parent) :
-    QSGItem(parent), m_needsReset(false), m_system(0), m_enabled(true)
+QSGParticleAffector::QSGParticleAffector(QQuickItem *parent) :
+    QQuickItem(parent), m_needsReset(false), m_system(0), m_enabled(true)
   , m_updateIntSet(false), m_shape(new QSGParticleExtruder(this))
 {
 }
@@ -143,7 +143,7 @@ void QSGParticleAffector::componentComplete()
 {
     if (!m_system && qobject_cast<QSGParticleSystem*>(parentItem()))
         setSystem(qobject_cast<QSGParticleSystem*>(parentItem()));
-    QSGItem::componentComplete();
+    QQuickItem::componentComplete();
 }
 
 bool QSGParticleAffector::activeGroup(int g) {
index c46164d..bc6864e 100644 (file)
@@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE
 
 QT_MODULE(Declarative)
 
-class QSGParticleAffector : public QSGItem
+class QSGParticleAffector : public QQuickItem
 {
     Q_OBJECT
     Q_PROPERTY(QSGParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged)
@@ -63,7 +63,7 @@ class QSGParticleAffector : public QSGItem
     Q_PROPERTY(QSGParticleExtruder* shape READ shape WRITE setShape NOTIFY shapeChanged)
 
 public:
-    explicit QSGParticleAffector(QSGItem *parent = 0);
+    explicit QSGParticleAffector(QQuickItem *parent = 0);
     virtual void affectSystem(qreal dt);
     virtual void reset(QSGParticleData*);//As some store their own data per particle?
     QSGParticleSystem* system() const
index e453888..f9a35a1 100644 (file)
@@ -212,8 +212,8 @@ QT_BEGIN_NAMESPACE
     it back off.
 */
 
-QSGParticleEmitter::QSGParticleEmitter(QSGItem *parent) :
-    QSGItem(parent)
+QSGParticleEmitter::QSGParticleEmitter(QQuickItem *parent) :
+    QQuickItem(parent)
   , m_particlesPerSecond(10)
   , m_particleDuration(1000)
   , m_particleDurationVariation(0)
@@ -261,7 +261,7 @@ void QSGParticleEmitter::componentComplete()
 {
     if (!m_system && qobject_cast<QSGParticleSystem*>(parentItem()))
         setSystem(qobject_cast<QSGParticleSystem*>(parentItem()));
-    QSGItem::componentComplete();
+    QQuickItem::componentComplete();
 }
 
 void QSGParticleEmitter::setEnabled(bool arg)
index 8a41cb6..0099c69 100644 (file)
@@ -42,7 +42,7 @@
 #ifndef PARTICLEEMITTER_H
 #define PARTICLEEMITTER_H
 
-#include <QSGItem>
+#include <QQuickItem>
 #include <QDebug>
 #include "qsgparticlesystem_p.h"
 #include "qsgparticleextruder_p.h"
@@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE
 
 QT_MODULE(Declarative)
 
-class QSGParticleEmitter : public QSGItem
+class QSGParticleEmitter : public QQuickItem
 {
     Q_OBJECT
     Q_PROPERTY(QSGParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged)
@@ -81,7 +81,7 @@ class QSGParticleEmitter : public QSGItem
 
     Q_ENUMS(Lifetime)
 public:
-    explicit QSGParticleEmitter(QSGItem *parent = 0);
+    explicit QSGParticleEmitter(QQuickItem *parent = 0);
     virtual ~QSGParticleEmitter();
     virtual void emitWindow(int timeStamp);
 
index bcccf3c..c4eded9 100644 (file)
@@ -90,7 +90,7 @@
 */
 
 QSGParticleGroup::QSGParticleGroup(QObject* parent)
-    : QSGStochasticState(parent)
+    : QQuickStochasticState(parent)
     , m_system(0)
 {
 
index 26bed55..f30539f 100644 (file)
 ****************************************************************************/
 #ifndef QSGPARTICLEGROUP
 #define QSGPARTICLEGROUP
-#include <private/qsgspriteengine_p.h>
+#include <private/qquickspriteengine_p.h>
 #include "qsgparticlesystem_p.h"
 #include "qdeclarativeparserstatus.h"
 
 QT_BEGIN_NAMESPACE
 
-class QSGParticleGroup : public QSGStochasticState, public QDeclarativeParserStatus
+class QSGParticleGroup : public QQuickStochasticState, public QDeclarativeParserStatus
 {
     Q_OBJECT
     //### Would setting limits per group be useful? Or clutter the API?
index 4f6b18c..c89e2ef 100644 (file)
@@ -63,8 +63,8 @@ QT_BEGIN_NAMESPACE
 
     If empty, it will paint the default particle group ("").
 */
-QSGParticlePainter::QSGParticlePainter(QSGItem *parent) :
-    QSGItem(parent),
+QSGParticlePainter::QSGParticlePainter(QQuickItem *parent) :
+    QQuickItem(parent),
     m_system(0), m_count(0), m_pleaseReset(true), m_sentinel(new QSGParticleData(0))
 {
 }
@@ -73,7 +73,7 @@ void QSGParticlePainter::componentComplete()
 {
     if (!m_system && qobject_cast<QSGParticleSystem*>(parentItem()))
         setSystem(qobject_cast<QSGParticleSystem*>(parentItem()));
-    QSGItem::componentComplete();
+    QQuickItem::componentComplete();
 }
 
 
index 78e0127..32b7224 100644 (file)
@@ -54,14 +54,14 @@ QT_BEGIN_NAMESPACE
 QT_MODULE(Declarative)
 
 
-class QSGParticlePainter : public QSGItem
+class QSGParticlePainter : public QQuickItem
 {
     Q_OBJECT
     Q_PROPERTY(QSGParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged)
     Q_PROPERTY(QStringList groups READ groups WRITE setGroups NOTIFY groupsChanged)
 
 public:
-    explicit QSGParticlePainter(QSGItem *parent = 0);
+    explicit QSGParticlePainter(QQuickItem *parent = 0);
     //Data Interface to system
     void load(QSGParticleData*);
     void reload(QSGParticleData*);
index fe2dec9..9e73b82 100644 (file)
@@ -82,7 +82,7 @@ void QSGParticlesModule::defineModule()
 
     qmlRegisterType<QSGImageParticle>(uri, 2, 0, "ImageParticle");
     qmlRegisterType<QSGCustomParticle>(uri, 2, 0, "CustomParticle");
-    qmlRegisterType<QSGItemParticle>(uri, 2, 0, "ItemParticle");
+    qmlRegisterType<QQuickItemParticle>(uri, 2, 0, "ItemParticle");
 
     qmlRegisterType<QSGParticleEmitter>(uri, 2, 0, "Emitter");
     qmlRegisterType<QSGTrailEmitter>(uri, 2, 0, "TrailEmitter");
index 1b01081..0523563 100644 (file)
@@ -44,8 +44,8 @@
 #include "qsgparticleemitter_p.h"
 #include "qsgparticleaffector_p.h"
 #include "qsgparticlepainter_p.h"
-#include <private/qsgspriteengine_p.h>
-#include <private/qsgsprite_p.h>
+#include <private/qquickspriteengine_p.h>
+#include <private/qquicksprite_p.h>
 #include "qsgv8particledata_p.h"
 #include "qsgparticlegroup_p.h"
 
@@ -616,8 +616,8 @@ void QSGParticleData::extendLife(float time)
     vy = evy;
 }
 
-QSGParticleSystem::QSGParticleSystem(QSGItem *parent) :
-    QSGItem(parent),
+QSGParticleSystem::QSGParticleSystem(QQuickItem *parent) :
+    QQuickItem(parent),
     stateEngine(0),
     m_running(true),
     particleCount(0),
@@ -756,7 +756,7 @@ void QSGParticleSystem::stateRedirect(QSGParticleGroup* group, QSGParticleSystem
 void QSGParticleSystem::componentComplete()
 
 {
-    QSGItem::componentComplete();
+    QQuickItem::componentComplete();
     m_componentComplete = true;
     m_animation = new QSGParticleSystemAnimation(this);
     reset();//restarts animation as well
@@ -925,12 +925,12 @@ void QSGParticleSystem::createEngine()
             }
         }
         m_groups = newList;
-        QList<QSGStochasticState*> states;
+        QList<QQuickStochasticState*> states;
         foreach (QSGParticleGroup* g, m_groups)
-            states << (QSGStochasticState*)g;
+            states << (QQuickStochasticState*)g;
 
         if (!stateEngine)
-            stateEngine = new QSGStochasticEngine(this);
+            stateEngine = new QQuickStochasticEngine(this);
         stateEngine->setCount(particleCount);
         stateEngine->m_states = states;
 
index 37fcbac..714b536 100644 (file)
 #ifndef PARTICLESYSTEM_H
 #define PARTICLESYSTEM_H
 
-#include <QSGItem>
+#include <QQuickItem>
 #include <QElapsedTimer>
 #include <QVector>
 #include <QHash>
 #include <QPointer>
 #include <QSignalMapper>
-#include <private/qsgsprite_p.h>
+#include <private/qquicksprite_p.h>
 #include <QAbstractAnimation>
 #include <QtDeclarative/qdeclarative.h>
 #include <private/qv8engine_p.h> //For QDeclarativeV8Handle
@@ -65,8 +65,8 @@ class QSGParticleEmitter;
 class QSGParticlePainter;
 class QSGParticleData;
 class QSGParticleSystemAnimation;
-class QSGStochasticEngine;
-class QSGSprite;
+class QQuickStochasticEngine;
+class QQuickSprite;
 class QSGV8ParticleData;
 class QSGParticleGroup;
 class QSGImageParticle;
@@ -208,7 +208,7 @@ public:
     float animWidth;
     float animHeight;
     float r;
-    QSGItem* delegate;
+    QQuickItem* delegate;
     int modelIndex;
     float update;//Used by custom affectors
 
@@ -229,7 +229,7 @@ private:
     QSGV8ParticleData* v8Datum;
 };
 
-class Q_AUTOTEST_EXPORT QSGParticleSystem : public QSGItem
+class Q_AUTOTEST_EXPORT QSGParticleSystem : public QQuickItem
 {
     Q_OBJECT
     Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
@@ -237,7 +237,7 @@ class Q_AUTOTEST_EXPORT QSGParticleSystem : public QSGItem
     Q_PROPERTY(bool empty READ isEmpty NOTIFY emptyChanged)
 
 public:
-    explicit QSGParticleSystem(QSGItem *parent = 0);
+    explicit QSGParticleSystem(QQuickItem *parent = 0);
     ~QSGParticleSystem();
 
     bool isRunning() const
@@ -296,7 +296,7 @@ public:
     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;
+    QQuickStochasticEngine* stateEngine;
 
     //Also only here for auto-test usage
     void updateCurrentTime( int currentTime );
index 093e55b..8fb7551 100644 (file)
@@ -105,7 +105,7 @@ QT_BEGIN_NAMESPACE
 */
 
 
-QSGAttractorAffector::QSGAttractorAffector(QSGItem *parent) :
+QSGAttractorAffector::QSGAttractorAffector(QQuickItem *parent) :
     QSGParticleAffector(parent), m_strength(0.0), m_x(0), m_y(0)
   , m_physics(Velocity), m_proportionalToDistance(Linear)
 {
index 75dd47e..b7dcf62 100644 (file)
@@ -75,7 +75,7 @@ public:
         Acceleration
     };
 
-    explicit QSGAttractorAffector(QSGItem *parent = 0);
+    explicit QSGAttractorAffector(QQuickItem *parent = 0);
 
     qreal strength() const
     {
index 260929f..4765eb2 100644 (file)
@@ -40,8 +40,8 @@
 ****************************************************************************/
 
 #include "qsgspritegoal_p.h"
-#include <private/qsgspriteengine_p.h>
-#include <private/qsgsprite_p.h>
+#include <private/qquickspriteengine_p.h>
+#include <private/qquicksprite_p.h>
 #include "qsgimageparticle_p.h"
 #include <QDebug>
 
@@ -79,7 +79,7 @@ QT_BEGIN_NAMESPACE
     deprecated, use GroupGoal instead
 */
 
-QSGSpriteGoalAffector::QSGSpriteGoalAffector(QSGItem *parent) :
+QSGSpriteGoalAffector::QSGSpriteGoalAffector(QQuickItem *parent) :
     QSGParticleAffector(parent),
     m_goalIdx(-1),
     m_lastEngine(0),
@@ -89,7 +89,7 @@ QSGSpriteGoalAffector::QSGSpriteGoalAffector(QSGItem *parent) :
 {
 }
 
-void QSGSpriteGoalAffector::updateStateIndex(QSGStochasticEngine* e)
+void QSGSpriteGoalAffector::updateStateIndex(QQuickStochasticEngine* e)
 {
     if (m_systemStates){
         m_goalIdx = m_system->groupIds[m_goalState];
@@ -120,7 +120,7 @@ void QSGSpriteGoalAffector::setGoalState(QString arg)
 bool QSGSpriteGoalAffector::affectParticle(QSGParticleData *d, qreal dt)
 {
     Q_UNUSED(dt);
-    QSGStochasticEngine *engine = 0;
+    QQuickStochasticEngine *engine = 0;
     if (!m_systemStates){
         //TODO: Affect all engines
         foreach (QSGParticlePainter *p, m_system->groupData[d->group]->painters)
index 7f20b1e..bdb86d7 100644 (file)
@@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
 
 QT_MODULE(Declarative)
 
-class QSGStochasticEngine;
+class QQuickStochasticEngine;
 
 class QSGSpriteGoalAffector : public QSGParticleAffector
 {
@@ -59,7 +59,7 @@ class QSGSpriteGoalAffector : public QSGParticleAffector
     Q_PROPERTY(bool jump READ jump WRITE setJump NOTIFY jumpChanged)
     Q_PROPERTY(bool systemStates READ systemStates WRITE setSystemStates NOTIFY systemStatesChanged)
 public:
-    explicit QSGSpriteGoalAffector(QSGItem *parent = 0);
+    explicit QSGSpriteGoalAffector(QQuickItem *parent = 0);
 
     QString goalState() const
     {
@@ -108,10 +108,10 @@ void setSystemStates(bool arg)
 }
 
 private:
-    void updateStateIndex(QSGStochasticEngine* e);
+    void updateStateIndex(QQuickStochasticEngine* e);
     QString m_goalState;
     int m_goalIdx;
-    QSGStochasticEngine* m_lastEngine;
+    QQuickStochasticEngine* m_lastEngine;
     bool m_jump;
     bool m_systemStates;
 
index d84bd4d..86f3250 100644 (file)
@@ -42,7 +42,7 @@
 #include "qsgtargetaffector_p.h"
 #include <QDebug>
 
-QSGTargetAffector::QSGTargetAffector(QSGItem *parent) :
+QSGTargetAffector::QSGTargetAffector(QQuickItem *parent) :
     QSGParticleAffector(parent), m_targetX(0), m_targetY(0),
     m_targetWidth(0), m_targetHeight(0), m_defaultShape(new QSGParticleExtruder(this)),
     m_targetShape(m_defaultShape), m_targetTime(-1)
index a869fe2..264ba30 100644 (file)
@@ -55,7 +55,7 @@ class QSGTargetAffector : public QSGParticleAffector
     Q_PROPERTY(int targetTime READ targetTime WRITE setTargetTime NOTIFY targetTimeChanged)
 
 public:
-    explicit QSGTargetAffector(QSGItem *parent = 0);
+    explicit QSGTargetAffector(QQuickItem *parent = 0);
 
     int targetX() const
     {
index 75c3e08..5a412ee 100644 (file)
@@ -48,14 +48,14 @@ QT_BEGIN_NAMESPACE
 
 QT_MODULE(Declarative)
 
-class QSGItem;
+class QQuickItem;
 class QSGTargetDirection : public QSGDirection
 {
     Q_OBJECT
     Q_PROPERTY(qreal targetX READ targetX WRITE setTargetX NOTIFY targetXChanged)
     Q_PROPERTY(qreal targetY READ targetY WRITE setTargetY NOTIFY targetYChanged)
     //If targetItem is set, X/Y are ignored. Aims at middle of item, use variation for variation
-    Q_PROPERTY(QSGItem* targetItem READ targetItem WRITE setTargetItem NOTIFY targetItemChanged)
+    Q_PROPERTY(QQuickItem* targetItem READ targetItem WRITE setTargetItem NOTIFY targetItemChanged)
 
     Q_PROPERTY(qreal targetVariation READ targetVariation WRITE setTargetVariation NOTIFY targetVariationChanged)
 
@@ -98,7 +98,7 @@ public:
         return m_magnitudeVariation;
     }
 
-    QSGItem* targetItem() const
+    QQuickItem* targetItem() const
     {
         return m_targetItem;
     }
@@ -117,7 +117,7 @@ signals:
 
     void magnitudeVariationChanged(qreal arg);
 
-    void targetItemChanged(QSGItem* arg);
+    void targetItemChanged(QQuickItem* arg);
 
 public slots:
     void setTargetX(qreal arg)
@@ -168,7 +168,7 @@ public slots:
         }
     }
 
-    void setTargetItem(QSGItem* arg)
+    void setTargetItem(QQuickItem* arg)
     {
         if (m_targetItem != arg) {
             m_targetItem = arg;
@@ -183,7 +183,7 @@ private:
     bool m_proportionalMagnitude;
     qreal m_magnitude;
     qreal m_magnitudeVariation;
-    QSGItem *m_targetItem;
+    QQuickItem *m_targetItem;
 };
 
 QT_END_NAMESPACE
index 4298908..08818ec 100644 (file)
@@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE
     This element emits logical particles into the ParticleSystem, with the
     starting positions based on those of other logical particles.
 */
-QSGTrailEmitter::QSGTrailEmitter(QSGItem *parent) :
+QSGTrailEmitter::QSGTrailEmitter(QQuickItem *parent) :
     QSGParticleEmitter(parent)
   , m_particlesPerParticlePerSecond(0)
   , m_lastTimeStamp(0)
index 255dd85..a629f56 100644 (file)
@@ -66,7 +66,7 @@ public:
     enum EmitSize {
         ParticleSize = -2//Anything less than 0 will do
     };
-    explicit QSGTrailEmitter(QSGItem *parent = 0);
+    explicit QSGTrailEmitter(QQuickItem *parent = 0);
     virtual void emitWindow(int timeStamp);
     virtual void reset();
 
index 30d36cc..957f6f1 100644 (file)
@@ -78,7 +78,7 @@ QT_BEGIN_NAMESPACE
     A default image will be used if none is provided.
 */
 
-QSGTurbulenceAffector::QSGTurbulenceAffector(QSGItem *parent) :
+QSGTurbulenceAffector::QSGTurbulenceAffector(QQuickItem *parent) :
     QSGParticleAffector(parent),
     m_strength(10), m_lastT(0), m_gridSize(0), m_field(0), m_vectorField(0), m_inited(false)
 {
index ef3e9ec..022bf35 100644 (file)
@@ -59,7 +59,7 @@ class QSGTurbulenceAffector : public QSGParticleAffector
     Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged)
     Q_PROPERTY(QUrl noiseSource READ noiseSource WRITE setNoiseSource NOTIFY noiseSourceChanged)
     public:
-    explicit QSGTurbulenceAffector(QSGItem *parent = 0);
+    explicit QSGTurbulenceAffector(QQuickItem *parent = 0);
     ~QSGTurbulenceAffector();
     virtual void affectSystem(qreal dt);
 
index 7e2d7ae..a7a2e10 100644 (file)
@@ -193,7 +193,7 @@ QT_BEGIN_NAMESPACE
 
 
 
-//### Particle data handles are not locked to within certain scopes like QSGContext2D, but there's no way to reload either...
+//### Particle data handles are not locked to within certain scopes like QQuickContext2D, but there's no way to reload either...
 class QV8ParticleDataResource : public QV8ObjectResource
 {
     V8_RESOURCE_TYPE(ParticleDataType)
index d3e87fb..2a861c2 100644 (file)
@@ -79,7 +79,7 @@ QT_BEGIN_NAMESPACE
     \endlist
 */
 
-QSGWanderAffector::QSGWanderAffector(QSGItem *parent) :
+QSGWanderAffector::QSGWanderAffector(QQuickItem *parent) :
     QSGParticleAffector(parent), m_xVariance(0), m_yVariance(0), m_pace(0)
     , m_affectedParameter(Velocity)
 {
index 46ad6ea..6447e2f 100644 (file)
@@ -76,7 +76,7 @@ public:
         Acceleration
     };
 
-    explicit QSGWanderAffector(QSGItem *parent = 0);
+    explicit QSGWanderAffector(QQuickItem *parent = 0);
     ~QSGWanderAffector();
     virtual void reset(int systemIdx);
 
index 3f12431..4865a33 100644 (file)
@@ -83,7 +83,7 @@
 #include <private/qobject_p.h>
 
 #include <private/qdeclarativeutilmodule_p.h>
-#include <private/qsgitemsmodule_p.h>
+#include <private/qquickitemsmodule_p.h>
 #include <private/qsgparticlesmodule_p.h>
 
 #ifdef Q_OS_WIN // for %APPDATA%
@@ -344,7 +344,7 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
         qt_QmlQtModule_registered = true;
         QDeclarativeUtilModule::defineModule();
         QDeclarativeEnginePrivate::defineModule();
-        QSGItemsModule::defineModule();
+        QQuickItemsModule::defineModule();
         QSGParticlesModule::defineModule();
         QDeclarativeValueTypeFactory::registerValueTypes();
     }
index 2e8a360..0822321 100644 (file)
@@ -48,7 +48,7 @@
 
 #include <private/qdeclarativefastproperties_p.h>
 #include <private/qdeclarativedebugtrace_p.h>
-#include <private/qsganchors_p_p.h> // For AnchorLine
+#include <private/qquickanchors_p_p.h> // For AnchorLine
 
 #include <QtDeclarative/qdeclarativeinfo.h>
 #include <QtCore/qnumeric.h>
@@ -444,9 +444,9 @@ static bool testCompareVariants(const QVariant &qtscriptRaw, const QVariant &v4)
         QDeclarative1AnchorLine ra = qvariant_cast<QDeclarative1AnchorLine>(v4);
 
         return la == ra;
-    } else if (type == qMetaTypeId<QSGAnchorLine>()) {
-        QSGAnchorLine la = qvariant_cast<QSGAnchorLine>(qtscript);
-        QSGAnchorLine ra = qvariant_cast<QSGAnchorLine>(v4);
+    } else if (type == qMetaTypeId<QQuickAnchorLine>()) {
+        QQuickAnchorLine la = qvariant_cast<QQuickAnchorLine>(qtscript);
+        QQuickAnchorLine ra = qvariant_cast<QQuickAnchorLine>(v4);
 
         return la == ra;
     } else if (type == QMetaType::Double) {
@@ -529,8 +529,8 @@ static void testBindingResult(const QString &binding, int line, int column,
         default:
             if (resultType == qMetaTypeId<QDeclarative1AnchorLine>()) {
                 v4value = qVariantFromValue<QDeclarative1AnchorLine>(*(QDeclarative1AnchorLine *)result.typeDataPtr());
-            } else if (resultType == qMetaTypeId<QSGAnchorLine>()) {
-                v4value = qVariantFromValue<QSGAnchorLine>(*(QSGAnchorLine *)result.typeDataPtr());
+            } else if (resultType == qMetaTypeId<QQuickAnchorLine>()) {
+                v4value = qVariantFromValue<QQuickAnchorLine>(*(QQuickAnchorLine *)result.typeDataPtr());
             } else {
                 iserror = true;
                 v4Result = "Unknown V4 type";
index ba739a9..a9d2338 100644 (file)
@@ -48,7 +48,7 @@
 #include <private/qdeclarativejsast_p.h>
 #include <private/qdeclarativefastproperties_p.h>
 #include <private/qdeclarativejsengine_p.h>
-#include <private/qsganchors_p_p.h> // For AnchorLine
+#include <private/qquickanchors_p_p.h> // For AnchorLine
 
 QT_BEGIN_NAMESPACE
 
@@ -341,7 +341,7 @@ void QV4CompilerPrivate::visitName(IR::Name *e)
         default:
             if (propTy == qMetaTypeId<QDeclarative1AnchorLine>()) {
                 regType = PODValueType;
-            } else if (propTy == qMetaTypeId<QSGAnchorLine>()) {
+            } else if (propTy == qMetaTypeId<QQuickAnchorLine>()) {
                 regType = PODValueType;
             } else if (QDeclarativeMetaType::isQObject(propTy)) {
                 regType = QObjectStarType;
@@ -940,7 +940,7 @@ void QV4CompilerPrivate::visitRet(IR::Ret *s)
             test.regType = qMetaTypeId<QDeclarative1AnchorLine>();
             break;
         case IR::SGAnchorLineType:
-            test.regType = qMetaTypeId<QSGAnchorLine>();
+            test.regType = qMetaTypeId<QQuickAnchorLine>();
             break;
         case IR::ObjectType:
             test.regType = QMetaType::QObjectStar;
index 760c2bc..cfe7721 100644 (file)
@@ -42,7 +42,7 @@
 #include "qv4irbuilder_p.h"
 #include "qv4compiler_p_p.h"
 
-#include <private/qsganchors_p_p.h> // For AnchorLine
+#include <private/qquickanchors_p_p.h> // For AnchorLine
 #include <private/qdeclarativetypenamecache_p.h>
 
 DEFINE_BOOL_CONFIG_OPTION(qmlVerboseCompiler, QML_VERBOSE_COMPILER)
@@ -72,7 +72,7 @@ static IR::Type irTypeFromVariantType(int t, QDeclarativeEnginePrivate *engine,
     default:
         if (t == qMetaTypeId<QDeclarative1AnchorLine>())
             return IR::AnchorLineType;
-        else if (t == qMetaTypeId<QSGAnchorLine>())
+        else if (t == qMetaTypeId<QQuickAnchorLine>())
             return IR::SGAnchorLineType;
         else if (const QMetaObject *m = engine->metaObjectForType(t)) {
             meta = m;
index f1e9a89..0ad6091 100644 (file)
@@ -44,7 +44,6 @@
 
 #include "qsgnode.h"
 #include "qsgtexture.h"
-#include <private/qsgtext_p.h>
 #include <QtCore/qobject.h>
 #include <QtCore/qrect.h>
 #include <QtGui/qbrush.h>
@@ -53,7 +52,8 @@
 #include <QtGui/qglyphrun.h>
 #include <QtCore/qurl.h>
 
-#include <private/qsgtext_p.h>
+// ### remove
+#include <private/qquicktext_p.h>
 
 QT_BEGIN_HEADER
 
@@ -109,7 +109,7 @@ public:
 
     virtual void setGlyphs(const QPointF &position, const QGlyphRun &glyphs) = 0;
     virtual void setColor(const QColor &color) = 0;
-    virtual void setStyle(QSGText::TextStyle style) = 0;
+    virtual void setStyle(QQuickText::TextStyle style) = 0;
     virtual void setStyleColor(const QColor &color) = 0;
     virtual QPointF baseLine() const = 0;
 
index 9016b81..466ae59 100644 (file)
@@ -322,7 +322,7 @@ QSGGlyphNode *QSGContext::createGlyphNode()
     Factory function for the scene graph renderers.
 
     The renderers are used for the toplevel renderer and once for every
-    QSGShaderEffectSource used in the QML scene.
+    QQuickShaderEffectSource used in the QML scene.
  */
 QSGRenderer *QSGContext::createRenderer()
 {
index 993eabc..f9d163c 100644 (file)
@@ -64,7 +64,7 @@ public:
     virtual void setColor(const QColor &color);
 
     virtual void setPreferredAntialiasingMode(AntialiasingMode) { }
-    virtual void setStyle(QSGText::TextStyle) { }
+    virtual void setStyle(QQuickText::TextStyle) { }
     virtual void setStyleColor(const QColor &) { }
 
     virtual void update() { }
index 3586c9d..5426c3b 100644 (file)
@@ -51,7 +51,7 @@ QSGDistanceFieldGlyphNode::QSGDistanceFieldGlyphNode(QSGDistanceFieldGlyphCacheM
     , m_glyph_cacheManager(cacheManager)
     , m_glyph_cache(0)
     , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0)
-    , m_style(QSGText::Normal)
+    , m_style(QQuickText::Normal)
     , m_antialiasingMode(GrayAntialiasing)
     , m_dirtyFont(false)
     , m_dirtyGeometry(false)
@@ -102,7 +102,7 @@ void QSGDistanceFieldGlyphNode::setGlyphs(const QPointF &position, const QGlyphR
     m_dirtyMaterial = true;
 }
 
-void QSGDistanceFieldGlyphNode::setStyle(QSGText::TextStyle style)
+void QSGDistanceFieldGlyphNode::setStyle(QQuickText::TextStyle style)
 {
     if (m_style == style)
         return;
@@ -255,7 +255,7 @@ void QSGDistanceFieldGlyphNode::updateMaterial()
 {
     delete m_material;
 
-    if (m_style == QSGText::Normal) {
+    if (m_style == QQuickText::Normal) {
         switch (m_antialiasingMode) {
         case HighQualitySubPixelAntialiasing:
             m_material = new QSGHiQSubPixelDistanceFieldTextMaterial;
@@ -270,11 +270,11 @@ void QSGDistanceFieldGlyphNode::updateMaterial()
         }
     } else {
         QSGDistanceFieldStyledTextMaterial *material;
-        if (m_style == QSGText::Outline) {
+        if (m_style == QQuickText::Outline) {
             material = new QSGDistanceFieldOutlineTextMaterial;
         } else {
             QSGDistanceFieldShiftedStyleTextMaterial *sMaterial = new QSGDistanceFieldShiftedStyleTextMaterial;
-            if (m_style == QSGText::Raised)
+            if (m_style == QQuickText::Raised)
                 sMaterial->setShift(QPointF(0.0, 1.0));
             else
                 sMaterial->setShift(QPointF(0.0, -1.0));
index 9004549..1d8bcea 100644 (file)
@@ -44,7 +44,8 @@
 
 #include <private/qsgadaptationlayer_p.h>
 #include "qsgtexture.h"
-#include <private/qsgtext_p.h>
+
+#include <private/qquicktext_p.h>
 
 QT_BEGIN_HEADER
 
@@ -67,7 +68,7 @@ public:
 
     virtual void setPreferredAntialiasingMode(AntialiasingMode mode);
 
-    virtual void setStyle(QSGText::TextStyle style);
+    virtual void setStyle(QQuickText::TextStyle style);
     virtual void setStyleColor(const QColor &color);
 
     virtual void update();
@@ -85,7 +86,7 @@ private:
     QSGDistanceFieldGlyphCacheManager *m_glyph_cacheManager;
     QSGDistanceFieldGlyphCache *m_glyph_cache;
     QSGGeometry m_geometry;
-    QSGText::TextStyle m_style;
+    QQuickText::TextStyle m_style;
     QColor m_styleColor;
     AntialiasingMode m_antialiasingMode;
 
index fb35467..3f07f20 100644 (file)
@@ -41,8 +41,8 @@
 
 #include "qsgpainternode_p.h"
 
-#include "qsgpainteditem.h"
-#include <private/qsgpainteditem_p.h>
+#include <private/qquickpainteditem_p.h>
+
 #include <private/qsgcontext_p.h>
 #include <private/qopenglextensions_p.h>
 #include <qopenglframebufferobject.h>
@@ -105,10 +105,10 @@ void QSGPainterTexture::bind()
     m_dirty_rect = QRect();
 }
 
-QSGPainterNode::QSGPainterNode(QSGPaintedItem *item)
+QSGPainterNode::QSGPainterNode(QQuickPaintedItem *item)
     : QSGGeometryNode()
-    , m_preferredRenderTarget(QSGPaintedItem::Image)
-    , m_actualRenderTarget(QSGPaintedItem::Image)
+    , m_preferredRenderTarget(QQuickPaintedItem::Image)
+    , m_actualRenderTarget(QQuickPaintedItem::Image)
     , m_item(item)
     , m_fbo(0)
     , m_multisampledFbo(0)
@@ -130,7 +130,7 @@ QSGPainterNode::QSGPainterNode(QSGPaintedItem *item)
     , m_dirtyRenderTarget(false)
     , m_dirtyTexture(false)
 {
-    m_context = static_cast<QSGPaintedItemPrivate *>(QObjectPrivate::get(item))->sceneGraphContext();
+    m_context = static_cast<QQuickPaintedItemPrivate *>(QObjectPrivate::get(item))->sceneGraphContext();
 
     setMaterial(&m_materialO);
     setOpaqueMaterial(&m_material);
@@ -150,7 +150,7 @@ void QSGPainterNode::paint()
     QRect dirtyRect = m_dirtyRect.isNull() ? QRect(0, 0, m_size.width(), m_size.height()) : m_dirtyRect;
 
     QPainter painter;
-    if (m_actualRenderTarget == QSGPaintedItem::Image)
+    if (m_actualRenderTarget == QQuickPaintedItem::Image)
         painter.begin(&m_image);
     else {
         if (!m_gl_device) {
@@ -188,7 +188,7 @@ void QSGPainterNode::paint()
     m_item->paint(&painter);
     painter.end();
 
-    if (m_actualRenderTarget == QSGPaintedItem::Image) {
+    if (m_actualRenderTarget == QQuickPaintedItem::Image) {
         m_texture->setImage(m_image);
         m_texture->setDirtyRect(dirtyRect);
     } else if (m_multisampledFbo) {
@@ -234,7 +234,7 @@ void QSGPainterNode::updateTexture()
 void QSGPainterNode::updateGeometry()
 {
     QRectF source;
-    if (m_actualRenderTarget == QSGPaintedItem::Image)
+    if (m_actualRenderTarget == QQuickPaintedItem::Image)
         source = QRectF(0, 0, 1, 1);
     else
         source = QRectF(0, 0, qreal(m_size.width()) / m_fboSize.width(), qreal(m_size.height()) / m_fboSize.height());
@@ -255,14 +255,14 @@ void QSGPainterNode::updateRenderTarget()
 
     m_dirtyContents = true;
 
-    QSGPaintedItem::RenderTarget oldTarget = m_actualRenderTarget;
-    if (m_preferredRenderTarget == QSGPaintedItem::Image) {
-        m_actualRenderTarget = QSGPaintedItem::Image;
+    QQuickPaintedItem::RenderTarget oldTarget = m_actualRenderTarget;
+    if (m_preferredRenderTarget == QQuickPaintedItem::Image) {
+        m_actualRenderTarget = QQuickPaintedItem::Image;
     } else {
         if (!m_multisamplingSupported && m_smoothPainting)
-            m_actualRenderTarget = QSGPaintedItem::Image;
+            m_actualRenderTarget = QQuickPaintedItem::Image;
         else
-            m_actualRenderTarget = QSGPaintedItem::FramebufferObject;
+            m_actualRenderTarget = QQuickPaintedItem::FramebufferObject;
     }
     if (oldTarget != m_actualRenderTarget) {
         m_image = QImage();
@@ -271,7 +271,7 @@ void QSGPainterNode::updateRenderTarget()
         m_fbo = m_multisampledFbo = 0;
     }
 
-    if (m_actualRenderTarget == QSGPaintedItem::FramebufferObject) {
+    if (m_actualRenderTarget == QQuickPaintedItem::FramebufferObject) {
         const QOpenGLContext *ctx = m_context->glContext();
         if (m_fbo && !m_dirtyGeometry && (!ctx->format().samples() || !m_multisamplingSupported))
             return;
@@ -309,7 +309,7 @@ void QSGPainterNode::updateRenderTarget()
     }
 
     QSGPainterTexture *texture = new QSGPainterTexture;
-    if (m_actualRenderTarget == QSGPaintedItem::Image) {
+    if (m_actualRenderTarget == QQuickPaintedItem::Image) {
         texture->setOwnsTexture(true);
         texture->setTextureSize(m_size);
     } else {
@@ -341,7 +341,7 @@ void QSGPainterNode::updateFBOSize()
     m_fboSize = QSize(fboWidth, fboHeight);
 }
 
-void QSGPainterNode::setPreferredRenderTarget(QSGPaintedItem::RenderTarget target)
+void QSGPainterNode::setPreferredRenderTarget(QQuickPaintedItem::RenderTarget target)
 {
     if (m_preferredRenderTarget == target)
         return;
@@ -446,7 +446,7 @@ void QSGPainterNode::setFastFBOResizing(bool dynamic)
 
 QImage QSGPainterNode::toImage() const
 {
-    if (m_actualRenderTarget == QSGPaintedItem::Image)
+    if (m_actualRenderTarget == QQuickPaintedItem::Image)
         return m_image;
     else
         return m_fbo->toImage();
index e30dc7c..c838ed1 100644 (file)
@@ -45,7 +45,8 @@
 #include "qsgnode.h"
 #include "qsgtexturematerial.h"
 #include "qsgtexture_p.h"
-#include "qsgpainteditem.h"
+
+#include <qquickpainteditem.h>
 
 #include <QtGui/qcolor.h>
 
@@ -74,10 +75,10 @@ private:
 class Q_DECLARATIVE_EXPORT QSGPainterNode : public QSGGeometryNode
 {
 public:
-    QSGPainterNode(QSGPaintedItem *item);
+    QSGPainterNode(QQuickPaintedItem *item);
     virtual ~QSGPainterNode();
 
-    void setPreferredRenderTarget(QSGPaintedItem::RenderTarget target);
+    void setPreferredRenderTarget(QQuickPaintedItem::RenderTarget target);
 
     void setSize(const QSize &size);
     QSize size() const { return m_size; }
@@ -118,10 +119,10 @@ private:
 
     QSGContext *m_context;
 
-    QSGPaintedItem::RenderTarget m_preferredRenderTarget;
-    QSGPaintedItem::RenderTarget m_actualRenderTarget;
+    QQuickPaintedItem::RenderTarget m_preferredRenderTarget;
+    QQuickPaintedItem::RenderTarget m_actualRenderTarget;
 
-    QSGPaintedItem *m_item;
+    QQuickPaintedItem *m_item;
 
     QOpenGLFramebufferObject *m_fbo;
     QOpenGLFramebufferObject *m_multisampledFbo;
index 5605f28..10faf2e 100644 (file)
@@ -41,9 +41,6 @@
 
 #include "qsgtextureprovider_p.h"
 
-#include <private/qsgimage_p.h>
-#include <private/qsgshadereffectsource_p.h>
-
 #ifndef GL_CLAMP_TO_EDGE
 #define GL_CLAMP_TO_EDGE 0x812F
 #endif
index e449e23..537afb3 100644 (file)
@@ -426,7 +426,7 @@ private:
 private:
     Q_DISABLE_COPY(QDeclarativePath)
     Q_DECLARE_PRIVATE(QDeclarativePath)
-    friend class QSGPathAnimationUpdater;
+    friend class QQuickPathAnimationUpdater;
 
 public:
     QPainterPath createPath(const QPointF &startPoint, const QPointF &endPoint, const QStringList &attributes, qreal &pathLength, QList<AttributePoint> &attributePoints, bool *closed = 0);
index a6fb992..daec00d 100644 (file)
@@ -46,7 +46,7 @@
 #include "QtQuickTest/private/quicktestresult_p.h"
 #include "QtQuickTest/private/quicktestevent_p.h"
 #include "private/qtestoptions_p.h"
-#include "QtDeclarative/qsgitem.h"
+#include "QtDeclarative/qquickitem.h"
 #include <QtDeclarative/private/qdeclarativeengine_p.h>
 
 QML_DECLARE_TYPE(QuickTestResult)
index 7d9ad95..2ac30bc 100644 (file)
@@ -64,7 +64,7 @@ class AbstractTool;
 class ToolBox;
 
 /*
- * The common code between QSGView and QDeclarativeView inspectors lives here,
+ * The common code between QQuickView and QDeclarativeView inspectors lives here,
  */
 class AbstractViewInspector : public QObject
 {
index 82d8e7a..51dfda6 100644 (file)
@@ -46,7 +46,7 @@
 
 #include <QtCore/qplugin.h>
 #include <QtDeclarative/private/qdeclarativeinspectorservice_p.h>
-#include <QtDeclarative/QSGView>
+#include <QtDeclarative/QQuickView>
 
 namespace QmlJSDebugger {
 
@@ -71,7 +71,7 @@ void QDeclarativeInspectorPlugin::activate()
     QObject *firstView = views.first();
     if (QDeclarativeView *declarativeView = qobject_cast<QDeclarativeView*>(firstView))
         m_inspector = new QDeclarativeViewInspector(declarativeView, declarativeView);
-    else if (QSGView *sgView = qobject_cast<QSGView*>(firstView))
+    else if (QQuickView *sgView = qobject_cast<QQuickView*>(firstView))
         m_inspector = new SGViewInspector(sgView, sgView);
 }
 
index 4488214..1af789d 100644 (file)
 
 namespace QmlJSDebugger {
 
-SGHighlight::SGHighlight(QSGItem *item, QSGItem *parent)
-    : QSGPaintedItem(parent)
+SGHighlight::SGHighlight(QQuickItem *item, QQuickItem *parent)
+    : QQuickPaintedItem(parent)
 {
     setItem(item);
 }
 
-void SGHighlight::setItem(QSGItem *item)
+void SGHighlight::setItem(QQuickItem *item)
 {
     if (m_item)
         m_item.data()->disconnect(this);
@@ -72,7 +72,7 @@ void SGHighlight::setItem(QSGItem *item)
 
 void SGHighlight::adjust()
 {
-    const QSGItem *item = m_item.data();
+    const QQuickItem *item = m_item.data();
     setSize(QSizeF(item->width(), item->height()));
     setPos(parentItem()->mapFromItem(item->parentItem(), item->pos()));
     setRotation(item->rotation());
index f3e8edd..8d5659c 100644 (file)
 #define SGHIGHLIGHT_H
 
 #include <QtCore/QWeakPointer>
-#include <QtDeclarative/QSGPaintedItem>
+#include <QtDeclarative/QQuickPaintedItem>
 
 namespace QmlJSDebugger {
 
-class SGHighlight : public QSGPaintedItem
+class SGHighlight : public QQuickPaintedItem
 {
     Q_OBJECT
 
 public:
-    SGHighlight(QSGItem *parent) : QSGPaintedItem(parent) {}
-    SGHighlight(QSGItem *item, QSGItem *parent);
+    SGHighlight(QQuickItem *parent) : QQuickPaintedItem(parent) {}
+    SGHighlight(QQuickItem *item, QQuickItem *parent);
 
-    void setItem(QSGItem *item);
+    void setItem(QQuickItem *item);
 
 private slots:
     void adjust();
 
 private:
-    QWeakPointer<QSGItem> m_item;
+    QWeakPointer<QQuickItem> m_item;
 };
 
 /**
@@ -70,7 +70,7 @@ private:
 class SGSelectionHighlight : public SGHighlight
 {
 public:
-    SGSelectionHighlight(QSGItem *item, QSGItem *parent)
+    SGSelectionHighlight(QQuickItem *item, QQuickItem *parent)
         : SGHighlight(item, parent)
     {}
 
@@ -83,7 +83,7 @@ public:
 class SGHoverHighlight : public SGHighlight
 {
 public:
-    SGHoverHighlight(QSGItem *parent)
+    SGHoverHighlight(QQuickItem *parent)
         : SGHighlight(parent)
     {
         setZ(1); // hover highlight on top of selection highlight
index 653c059..bdfc28f 100644 (file)
@@ -46,8 +46,8 @@
 
 #include <QtWidgets/QMenu>
 #include <QtGui/QMouseEvent>
-#include <QtDeclarative/QSGView>
-#include <QtDeclarative/QSGItem>
+#include <QtDeclarative/QQuickView>
+#include <QtDeclarative/QQuickItem>
 
 namespace QmlJSDebugger {
 
@@ -65,17 +65,17 @@ void SGSelectionTool::leaveEvent(QEvent *)
 void SGSelectionTool::mousePressEvent(QMouseEvent *event)
 {
     if (event->button() == Qt::LeftButton) {
-        if (QSGItem *item = inspector()->topVisibleItemAt(event->pos()))
-            inspector()->setSelectedItems(QList<QSGItem*>() << item);
+        if (QQuickItem *item = inspector()->topVisibleItemAt(event->pos()))
+            inspector()->setSelectedItems(QList<QQuickItem*>() << item);
     } else if (event->button() == Qt::RightButton) {
-        QList<QSGItem*> items = inspector()->itemsAt(event->pos());
+        QList<QQuickItem*> items = inspector()->itemsAt(event->pos());
         createContextMenu(items, event->globalPos());
     }
 }
 
 void SGSelectionTool::hoverMoveEvent(QMouseEvent *event)
 {
-    QSGItem *item = inspector()->topVisibleItemAt(event->pos());
+    QQuickItem *item = inspector()->topVisibleItemAt(event->pos());
     if (!item) {
         m_hoverHighlight->setVisible(false);
     } else {
@@ -84,16 +84,16 @@ void SGSelectionTool::hoverMoveEvent(QMouseEvent *event)
     }
 }
 
-void SGSelectionTool::createContextMenu(const QList<QSGItem *> &items, QPoint pos)
+void SGSelectionTool::createContextMenu(const QList<QQuickItem *> &items, QPoint pos)
 {
     QMenu contextMenu;
     connect(&contextMenu, SIGNAL(hovered(QAction*)),
             this, SLOT(contextMenuElementHovered(QAction*)));
 
-    const QList<QSGItem*> selectedItems = inspector()->selectedItems();
+    const QList<QQuickItem*> selectedItems = inspector()->selectedItems();
     int shortcutKey = Qt::Key_1;
 
-    foreach (QSGItem *item, items) {
+    foreach (QQuickItem *item, items) {
         const QString title = inspector()->titleForItem(item);
         QAction *elementAction = contextMenu.addAction(title);
         elementAction->setData(QVariant::fromValue(item));
@@ -117,14 +117,14 @@ void SGSelectionTool::createContextMenu(const QList<QSGItem *> &items, QPoint po
 
 void SGSelectionTool::contextMenuElementHovered(QAction *action)
 {
-    if (QSGItem *item = action->data().value<QSGItem*>())
+    if (QQuickItem *item = action->data().value<QQuickItem*>())
         m_hoverHighlight->setItem(item);
 }
 
 void SGSelectionTool::contextMenuElementSelected()
 {
-    if (QSGItem *item = static_cast<QAction*>(sender())->data().value<QSGItem*>())
-        inspector()->setSelectedItems(QList<QSGItem*>() << item);
+    if (QQuickItem *item = static_cast<QAction*>(sender())->data().value<QQuickItem*>())
+        inspector()->setSelectedItems(QList<QQuickItem*>() << item);
 }
 
 SGViewInspector *SGSelectionTool::inspector() const
index 9f2171f..5877017 100644 (file)
@@ -48,7 +48,7 @@
 #include <QtCore/QPoint>
 
 QT_FORWARD_DECLARE_CLASS(QAction)
-QT_FORWARD_DECLARE_CLASS(QSGItem)
+QT_FORWARD_DECLARE_CLASS(QQuickItem)
 
 namespace QmlJSDebugger {
 
@@ -79,7 +79,7 @@ private slots:
     void contextMenuElementSelected();
 
 private:
-    void createContextMenu(const QList<QSGItem*> &items, QPoint pos);
+    void createContextMenu(const QList<QQuickItem*> &items, QPoint pos);
 
     SGViewInspector *inspector() const;
 
index a6f4052..89438b6 100644 (file)
 #include "sghighlight.h"
 #include "sgselectiontool.h"
 
-#include <QtDeclarative/private/qsgitem_p.h>
+#include <QtDeclarative/private/qquickitem_p.h>
 
-#include <QtDeclarative/QSGView>
-#include <QtDeclarative/QSGItem>
+#include <QtDeclarative/QQuickView>
+#include <QtDeclarative/QQuickItem>
 
 #include <cfloat>
 
@@ -57,20 +57,20 @@ namespace QmlJSDebugger {
 /*
  * Collects all the items at the given position, from top to bottom.
  */
-static void collectItemsAt(QSGItem *item, const QPointF &pos, QSGItem *overlay,
-                           QList<QSGItem *> &resultList)
+static void collectItemsAt(QQuickItem *item, const QPointF &pos, QQuickItem *overlay,
+                           QList<QQuickItem *> &resultList)
 {
     if (item == overlay)
         return;
 
-    if (item->flags() & QSGItem::ItemClipsChildrenToShape) {
+    if (item->flags() & QQuickItem::ItemClipsChildrenToShape) {
         if (!QRectF(0, 0, item->width(), item->height()).contains(pos))
             return;
     }
 
-    QList<QSGItem *> children = QSGItemPrivate::get(item)->paintOrderChildItems();
+    QList<QQuickItem *> children = QQuickItemPrivate::get(item)->paintOrderChildItems();
     for (int i = children.count() - 1; i >= 0; --i) {
-        QSGItem *child = children.at(i);
+        QQuickItem *child = children.at(i);
         collectItemsAt(child, item->mapToItem(child, pos), overlay, resultList);
     }
 
@@ -84,7 +84,7 @@ static void collectItemsAt(QSGItem *item, const QPointF &pos, QSGItem *overlay,
  * Returns the first visible item at the given position, or 0 when no such
  * child exists.
  */
-static QSGItem *itemAt(QSGItem *item, const QPointF &pos, QSGItem *overlay)
+static QQuickItem *itemAt(QQuickItem *item, const QPointF &pos, QQuickItem *overlay)
 {
     if (item == overlay)
         return 0;
@@ -92,19 +92,19 @@ static QSGItem *itemAt(QSGItem *item, const QPointF &pos, QSGItem *overlay)
     if (!item->isVisible() || item->opacity() == 0.0)
         return 0;
 
-    if (item->flags() & QSGItem::ItemClipsChildrenToShape) {
+    if (item->flags() & QQuickItem::ItemClipsChildrenToShape) {
         if (!QRectF(0, 0, item->width(), item->height()).contains(pos))
             return 0;
     }
 
-    QList<QSGItem *> children = QSGItemPrivate::get(item)->paintOrderChildItems();
+    QList<QQuickItem *> children = QQuickItemPrivate::get(item)->paintOrderChildItems();
     for (int i = children.count() - 1; i >= 0; --i) {
-        QSGItem *child = children.at(i);
-        if (QSGItem *betterCandidate = itemAt(child, item->mapToItem(child, pos), overlay))
+        QQuickItem *child = children.at(i);
+        if (QQuickItem *betterCandidate = itemAt(child, item->mapToItem(child, pos), overlay))
             return betterCandidate;
     }
 
-    if (!(item->flags() & QSGItem::ItemHasContents))
+    if (!(item->flags() & QQuickItem::ItemHasContents))
         return 0;
 
     if (!QRectF(0, 0, item->width(), item->height()).contains(pos))
@@ -114,10 +114,10 @@ static QSGItem *itemAt(QSGItem *item, const QPointF &pos, QSGItem *overlay)
 }
 
 
-SGViewInspector::SGViewInspector(QSGView *view, QObject *parent) :
+SGViewInspector::SGViewInspector(QQuickView *view, QObject *parent) :
     AbstractViewInspector(parent),
     m_view(view),
-    m_overlay(new QSGItem),
+    m_overlay(new QQuickItem),
     m_selectionTool(new SGSelectionTool(this)),
     m_designMode(true)
 {
@@ -128,7 +128,7 @@ SGViewInspector::SGViewInspector(QSGView *view, QObject *parent) :
     // Make sure mouse hover events are received
 //    m_view->setMouseTracking(true);
 
-    if (QSGItem *root = view->rootItem())
+    if (QQuickItem *root = view->rootItem())
         m_overlay->setParentItem(root);
 
     view->installEventFilter(this);
@@ -137,9 +137,9 @@ SGViewInspector::SGViewInspector(QSGView *view, QObject *parent) :
 
 void SGViewInspector::changeCurrentObjects(const QList<QObject*> &objects)
 {
-    QList<QSGItem*> items;
+    QList<QQuickItem*> items;
     foreach (QObject *obj, objects)
-        if (QSGItem *item = qobject_cast<QSGItem*>(obj))
+        if (QQuickItem *item = qobject_cast<QQuickItem*>(obj))
             items << item;
 
     syncSelectedItems(items);
@@ -157,8 +157,8 @@ void SGViewInspector::reparentQmlObject(QObject *object, QObject *newParent)
         return;
 
     object->setParent(newParent);
-    QSGItem *newParentItem = qobject_cast<QSGItem*>(newParent);
-    QSGItem *item = qobject_cast<QSGItem*>(object);
+    QQuickItem *newParentItem = qobject_cast<QQuickItem*>(newParent);
+    QQuickItem *item = qobject_cast<QQuickItem*>(object);
     if (newParentItem && item)
         item->setParentItem(newParentItem);
 }
@@ -212,48 +212,48 @@ QDeclarativeEngine *SGViewInspector::declarativeEngine() const
     return m_view->engine();
 }
 
-QSGItem *SGViewInspector::topVisibleItemAt(const QPointF &pos) const
+QQuickItem *SGViewInspector::topVisibleItemAt(const QPointF &pos) const
 {
-    QSGItem *root = m_view->rootItem();
+    QQuickItem *root = m_view->rootItem();
     return itemAt(root, root->mapFromScene(pos), m_overlay);
 }
 
-QList<QSGItem *> SGViewInspector::itemsAt(const QPointF &pos) const
+QList<QQuickItem *> SGViewInspector::itemsAt(const QPointF &pos) const
 {
-    QSGItem *root = m_view->rootItem();
-    QList<QSGItem *> resultList;
+    QQuickItem *root = m_view->rootItem();
+    QList<QQuickItem *> resultList;
     collectItemsAt(root, root->mapFromScene(pos), m_overlay, resultList);
     return resultList;
 }
 
-QList<QSGItem*> SGViewInspector::selectedItems() const
+QList<QQuickItem*> SGViewInspector::selectedItems() const
 {
-    QList<QSGItem *> selection;
-    foreach (const QWeakPointer<QSGItem> &selectedItem, m_selectedItems) {
+    QList<QQuickItem *> selection;
+    foreach (const QWeakPointer<QQuickItem> &selectedItem, m_selectedItems) {
         if (selectedItem)
             selection << selectedItem.data();
     }
     return selection;
 }
 
-void SGViewInspector::setSelectedItems(const QList<QSGItem *> &items)
+void SGViewInspector::setSelectedItems(const QList<QQuickItem *> &items)
 {
     if (!syncSelectedItems(items))
         return;
 
     QList<QObject*> objectList;
-    foreach (QSGItem *item, items)
+    foreach (QQuickItem *item, items)
         objectList << item;
 
     sendCurrentObjects(objectList);
 }
 
-bool SGViewInspector::syncSelectedItems(const QList<QSGItem *> &items)
+bool SGViewInspector::syncSelectedItems(const QList<QQuickItem *> &items)
 {
     bool selectionChanged = false;
 
     // Disconnect and remove items that are no longer selected
-    foreach (const QWeakPointer<QSGItem> &item, m_selectedItems) {
+    foreach (const QWeakPointer<QQuickItem> &item, m_selectedItems) {
         if (!item) // Don't see how this can happen due to handling of destroyed()
             continue;
         if (items.contains(item.data()))
@@ -266,7 +266,7 @@ bool SGViewInspector::syncSelectedItems(const QList<QSGItem *> &items)
     }
 
     // Connect and add newly selected items
-    foreach (QSGItem *item, items) {
+    foreach (QQuickItem *item, items) {
         if (m_selectedItems.contains(item))
             continue;
 
@@ -281,7 +281,7 @@ bool SGViewInspector::syncSelectedItems(const QList<QSGItem *> &items)
 
 void SGViewInspector::removeFromSelectedItems(QObject *object)
 {
-    if (QSGItem *item = qobject_cast<QSGItem*>(object)) {
+    if (QQuickItem *item = qobject_cast<QQuickItem*>(object)) {
         if (m_selectedItems.removeOne(item))
             delete m_highlightItems.take(item);
     }
@@ -298,7 +298,7 @@ bool SGViewInspector::eventFilter(QObject *obj, QEvent *event)
 bool SGViewInspector::mouseMoveEvent(QMouseEvent *event)
 {
     // TODO
-//    if (QSGItem *item = topVisibleItemAt(event->pos()))
+//    if (QQuickItem *item = topVisibleItemAt(event->pos()))
 //        m_view->setToolTip(titleForItem(item));
 //    else
 //        m_view->setToolTip(QString());
@@ -306,15 +306,15 @@ bool SGViewInspector::mouseMoveEvent(QMouseEvent *event)
     return AbstractViewInspector::mouseMoveEvent(event);
 }
 
-QString SGViewInspector::titleForItem(QSGItem *item) const
+QString SGViewInspector::titleForItem(QQuickItem *item) const
 {
     QString className = QLatin1String(item->metaObject()->className());
     QString objectStringId = idStringForObject(item);
 
     className.remove(QRegExp(QLatin1String("_QMLTYPE_\\d+")));
     className.remove(QRegExp(QLatin1String("_QML_\\d+")));
-    if (className.startsWith(QLatin1String("QSG")))
-        className = className.mid(3);
+    if (className.startsWith(QLatin1String("QQuick")))
+        className = className.mid(6);
 
     QString constructedName;
 
index 38271aa..788d6a0 100644 (file)
@@ -48,8 +48,8 @@
 #include <QtCore/QHash>
 
 QT_BEGIN_NAMESPACE
-class QSGView;
-class QSGItem;
+class QQuickView;
+class QQuickItem;
 QT_END_NAMESPACE
 
 namespace QmlJSDebugger {
@@ -61,7 +61,7 @@ class SGViewInspector : public AbstractViewInspector
 {
     Q_OBJECT
 public:
-    explicit SGViewInspector(QSGView *view, QObject *parent = 0);
+    explicit SGViewInspector(QQuickView *view, QObject *parent = 0);
 
     // AbstractViewInspector
     void changeCurrentObjects(const QList<QObject*> &objects);
@@ -72,16 +72,16 @@ public:
     void setWindowFlags(Qt::WindowFlags flags);
     QDeclarativeEngine *declarativeEngine() const;
 
-    QSGView *view() const { return m_view; }
-    QSGItem *overlay() const { return m_overlay; }
+    QQuickView *view() const { return m_view; }
+    QQuickItem *overlay() const { return m_overlay; }
 
-    QSGItem *topVisibleItemAt(const QPointF &pos) const;
-    QList<QSGItem *> itemsAt(const QPointF &pos) const;
+    QQuickItem *topVisibleItemAt(const QPointF &pos) const;
+    QList<QQuickItem *> itemsAt(const QPointF &pos) const;
 
-    QList<QSGItem *> selectedItems() const;
-    void setSelectedItems(const QList<QSGItem*> &items);
+    QList<QQuickItem *> selectedItems() const;
+    void setSelectedItems(const QList<QQuickItem*> &items);
 
-    QString titleForItem(QSGItem *item) const;
+    QString titleForItem(QQuickItem *item) const;
 
 protected:
     bool eventFilter(QObject *obj, QEvent *event);
@@ -92,15 +92,15 @@ private slots:
     void removeFromSelectedItems(QObject *);
 
 private:
-    bool syncSelectedItems(const QList<QSGItem*> &items);
+    bool syncSelectedItems(const QList<QQuickItem*> &items);
 
-    QSGView *m_view;
-    QSGItem *m_overlay;
+    QQuickView *m_view;
+    QQuickItem *m_overlay;
 
     SGSelectionTool *m_selectionTool;
 
-    QList<QWeakPointer<QSGItem> > m_selectedItems;
-    QHash<QSGItem*, SGSelectionHighlight*> m_highlightItems;
+    QList<QWeakPointer<QQuickItem> > m_selectedItems;
+    QHash<QQuickItem*, SGSelectionHighlight*> m_highlightItems;
 
     bool m_designMode;
 };
index 1503040..3c726d4 100644 (file)
@@ -49,7 +49,7 @@
 #include <QtDeclarative/qdeclarativeengine.h>
 #include <QtDeclarative/qdeclarativecontext.h>
 #if defined(QML_VERSION) && QML_VERSION >= 0x020000
-#include <QtDeclarative/qsgview.h>
+#include <QtDeclarative/qquickview.h>
 #define QUICK_TEST_SCENEGRAPH 1
 #endif
 #include <QtDeclarative/qjsvalue.h>
@@ -175,7 +175,7 @@ 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;
+        QQuickView view;
         QTestRootObject rootobj;
         QEventLoop eventLoop;
         QObject::connect(view.engine(), SIGNAL(quit()),
@@ -199,7 +199,7 @@ int quick_test_main(int argc, char **argv, const char *name, quick_test_viewport
                 view.setSource(QUrl::fromLocalFile(path));
             if (QTest::printAvailableFunctions)
                 continue;
-            if (view.status() == QSGView::Error) {
+            if (view.status() == QQuickView::Error) {
                 // Error compiling the test - flag failure in the log and continue.
                 QList<QDeclarativeError> errors = view.errors();
                 QuickTestResult results;
index 4e62d4a..780d502 100644 (file)
@@ -45,8 +45,8 @@
 #include <QtQuick1/qdeclarativeitem.h>
 #include <QtQuick1/qdeclarativeview.h>
 #if defined(QML_VERSION) && QML_VERSION >= 0x020000
-#include <QtDeclarative/qsgitem.h>
-#include <QtDeclarative/qsgcanvas.h>
+#include <QtDeclarative/qquickitem.h>
+#include <QtDeclarative/qquickcanvas.h>
 #define QUICK_TEST_SCENEGRAPH 1
 #endif
 #include <QtWidgets/qgraphicsscene.h>
@@ -119,7 +119,7 @@ namespace QtQuickTest
         QDeclarativeView *view = qobject_cast<QDeclarativeView *>(window);
         QWindow *eventWindow = window;
 #ifdef QUICK_TEST_SCENEGRAPH
-        QSGItem *sgitem = qobject_cast<QSGItem *>(item);
+        QQuickItem *sgitem = qobject_cast<QQuickItem *>(item);
         if (sgitem) {
             pos = sgitem->mapToScene(_pos).toPoint();
         } else
@@ -181,7 +181,7 @@ namespace QtQuickTest
         QDeclarativeView *view = qobject_cast<QDeclarativeView *>(window);
         QWindow *eventWindow = window;
 #ifdef QUICK_TEST_SCENEGRAPH
-        QSGItem *sgitem = qobject_cast<QSGItem *>(item);
+        QQuickItem *sgitem = qobject_cast<QQuickItem *>(item);
         if (sgitem) {
             pos = sgitem->mapToScene(_pos).toPoint();
         } else
@@ -291,7 +291,7 @@ bool QuickTestEvent::mouseMove
 QWindow *QuickTestEvent::eventWindow()
 {
 #ifdef QUICK_TEST_SCENEGRAPH
-    QSGItem *sgitem = qobject_cast<QSGItem *>(parent());
+    QQuickItem *sgitem = qobject_cast<QQuickItem *>(parent());
     if (sgitem)
         return sgitem->canvas();
 #endif
index 8e31303..65333cc 100644 (file)
@@ -50,7 +50,7 @@
 #include <QtDeclarative/qdeclarativecomponent.h>
 #include <QtDeclarative/qdeclarativeexpression.h>
 #include <QtDeclarative/qdeclarativeproperty.h>
-#include <QtDeclarative/qsgitem.h>
+#include <QtDeclarative/qquickitem.h>
 
 #include <private/qdeclarativebinding_p.h>
 #include <private/qdeclarativeenginedebug_p.h>
@@ -80,7 +80,7 @@ private:
     QDeclarativeDebugConnection *m_conn;
     QDeclarativeEngineDebug *m_dbg;
     QDeclarativeEngine *m_engine;
-    QSGItem *m_rootItem;
+    QQuickItem *m_rootItem;
 
     QObjectList m_components;
 
@@ -224,7 +224,7 @@ void tst_QDeclarativeEngineDebug::recursiveObjectTest(QObject *o, const QDeclara
             QCOMPARE(p.value(), pmeta.read(o));
 
         if (p.name() == "parent")
-            QVERIFY(p.valueTypeName() == "QGraphicsObject*" || p.valueTypeName() == "QSGItem*");
+            QVERIFY(p.valueTypeName() == "QGraphicsObject*" || p.valueTypeName() == "QQuickItem*");
         else
             QCOMPARE(p.valueTypeName(), QString::fromUtf8(pmeta.typeName()));
 
@@ -362,9 +362,9 @@ void tst_QDeclarativeEngineDebug::initTestCase()
         QDeclarativeComponent component(m_engine);
         component.setData(qml[i], QUrl::fromLocalFile(""));
         QVERIFY(component.isReady());  // fails if bad syntax
-        m_components << qobject_cast<QSGItem*>(component.create());
+        m_components << qobject_cast<QQuickItem*>(component.create());
     }
-    m_rootItem = qobject_cast<QSGItem*>(m_components.first());
+    m_rootItem = qobject_cast<QQuickItem*>(m_components.first());
 
     // add an extra context to test for multiple contexts
     QDeclarativeContext *context = new QDeclarativeContext(m_engine->rootContext(), this);
index 0d9459f..cd43094 100644 (file)
@@ -61,32 +61,32 @@ PRIVATETESTS += \
 # 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 \
-    qsgpathview \
-    qsgpincharea \
-    qsgpositioners \
-    qsgrepeater \
-    qsgtext \
-    qsgtextedit \
-    qsgtextinput \
-    qsgvisualdatamodel \
-    qsgview \
-    qsgcanvasitem \
+QUICKTESTS =  \
+    qquickanimatedimage \
+    qquickborderimage \
+    qquickcanvas \
+    qquickdrag \
+    qquickdroparea \
+    qquickflickable \
+    qquickflipable \
+    qquickfocusscope \
+    qquickgridview \
+    qquickimage \
+    qquickitem \
+    qquickitem2 \
+    qquicklistview \
+    qquickloader \
+    qquickmousearea \
+    qquickpathview \
+    qquickpincharea \
+    qquickpositioners \
+    qquickrepeater \
+    qquicktext \
+    qquicktextedit \
+    qquicktextinput \
+    qquickvisualdatamodel \
+    qquickview \
+    qquickcanvasitem \
 
 
 SUBDIRS += $$PUBLICTESTS
@@ -95,5 +95,5 @@ SUBDIRS += debugger
 
 contains(QT_CONFIG, private_tests) {
     SUBDIRS += $$PRIVATETESTS
-    SUBDIRS += $$SGTESTS
+    SUBDIRS += $$QUICKTESTS
 }
index 58f16a4..c14d41a 100644 (file)
@@ -44,7 +44,7 @@
 #include <QDir>
 #include <QProcess>
 #include <QDebug>
-#include <QSGView>
+#include <QQuickView>
 #include <QDeclarativeError>
 
 class tst_examples : public QObject
@@ -72,7 +72,7 @@ tst_examples::tst_examples()
     excludedDirs << "examples/declarative/text/fonts"; // QTBUG-21415
 #endif
 
-    // Not run in QSGView
+    // Not run in QQuickView
     excludedDirs << "examples/declarative/qtquick1";
 
     // These snippets are not expected to run on their own.
@@ -207,16 +207,16 @@ void tst_examples::sgexamples()
 {
     QFETCH(QString, file);
 
-    QSGView view;
+    QQuickView view;
 
     QtMsgHandler old = qInstallMsgHandler(silentErrorsMsgHandler);
     view.setSource(file);
     qInstallMsgHandler(old);
 
-    if (view.status() == QSGView::Error)
+    if (view.status() == QQuickView::Error)
         qWarning() << view.errors();
 
-    QCOMPARE(view.status(), QSGView::Ready);
+    QCOMPARE(view.status(), QQuickView::Ready);
     view.show();
 
     QTest::qWait(100);
index 9d3f415..515c8fa 100644 (file)
 #include <QtTest/QtTest>
 #include <QtDeclarative/qdeclarativeengine.h>
 #include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtDeclarative/qsgview.h>
-#include <QtDeclarative/private/qsgrectangle_p.h>
+#include <QtDeclarative/qquickview.h>
+#include <QtDeclarative/private/qquickrectangle_p.h>
 #include <QtDeclarative/private/qdeclarativeanimation_p.h>
 #include <QtDeclarative/private/qdeclarativetransition_p.h>
-#include <QtDeclarative/private/qsganimation_p.h>
+#include <QtDeclarative/private/qquickanimation_p.h>
 #include <QtDeclarative/private/qdeclarativepathinterpolator_p.h>
-#include <QtDeclarative/private/qsgitem_p.h>
+#include <QtDeclarative/private/qquickitem_p.h>
 #include <QVariantAnimation>
 #include <QEasingCurve>
 
@@ -111,7 +111,7 @@ private slots:
 
 void tst_qdeclarativeanimations::simpleProperty()
 {
-    QSGRectangle rect;
+    QQuickRectangle rect;
     QDeclarativePropertyAnimation animation;
     animation.setTarget(&rect);
     animation.setProperty("x");
@@ -136,7 +136,7 @@ void tst_qdeclarativeanimations::simpleProperty()
 
 void tst_qdeclarativeanimations::simpleNumber()
 {
-    QSGRectangle rect;
+    QQuickRectangle rect;
     QDeclarativeNumberAnimation animation;
     animation.setTarget(&rect);
     animation.setProperty("x");
@@ -161,7 +161,7 @@ void tst_qdeclarativeanimations::simpleNumber()
 
 void tst_qdeclarativeanimations::simpleColor()
 {
-    QSGRectangle rect;
+    QQuickRectangle rect;
     QDeclarativeColorAnimation animation;
     animation.setTarget(&rect);
     animation.setProperty("color");
@@ -195,7 +195,7 @@ void tst_qdeclarativeanimations::simpleColor()
 
 void tst_qdeclarativeanimations::simpleRotation()
 {
-    QSGRectangle rect;
+    QQuickRectangle rect;
     QDeclarativeRotationAnimation animation;
     animation.setTarget(&rect);
     animation.setProperty("rotation");
@@ -224,12 +224,12 @@ void tst_qdeclarativeanimations::simplePath()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathAnimation.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGRectangle *redRect = rect->findChild<QSGRectangle*>();
+        QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>();
         QVERIFY(redRect);
-        QSGPathAnimation *pathAnim = rect->findChild<QSGPathAnimation*>();
+        QQuickPathAnimation *pathAnim = rect->findChild<QQuickPathAnimation*>();
         QVERIFY(pathAnim);
 
         pathAnim->start();
@@ -250,8 +250,8 @@ void tst_qdeclarativeanimations::simplePath()
         QTRY_COMPARE(redRect->x(), qreal(300));
         QCOMPARE(redRect->y(), qreal(300));
 
-        pathAnim->setOrientation(QSGPathAnimation::RightFirst);
-        QCOMPARE(pathAnim->orientation(), QSGPathAnimation::RightFirst);
+        pathAnim->setOrientation(QQuickPathAnimation::RightFirst);
+        QCOMPARE(pathAnim->orientation(), QQuickPathAnimation::RightFirst);
         pathAnim->start();
         QTRY_VERIFY(redRect->rotation() != 0);
         pathAnim->stop();
@@ -260,15 +260,15 @@ void tst_qdeclarativeanimations::simplePath()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathAnimation2.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGRectangle *redRect = rect->findChild<QSGRectangle*>();
+        QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>();
         QVERIFY(redRect);
-        QSGPathAnimation *pathAnim = rect->findChild<QSGPathAnimation*>();
+        QQuickPathAnimation *pathAnim = rect->findChild<QQuickPathAnimation*>();
         QVERIFY(pathAnim);
 
-        QCOMPARE(pathAnim->orientation(), QSGPathAnimation::RightFirst);
+        QCOMPARE(pathAnim->orientation(), QQuickPathAnimation::RightFirst);
 
         pathAnim->start();
         pathAnim->pause();
@@ -349,12 +349,12 @@ void tst_qdeclarativeanimations::pathWithNoStart()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathAnimationNoStart.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect);
 
-    QSGRectangle *redRect = rect->findChild<QSGRectangle*>();
+    QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>();
     QVERIFY(redRect);
-    QSGPathAnimation *pathAnim = rect->findChild<QSGPathAnimation*>();
+    QQuickPathAnimation *pathAnim = rect->findChild<QQuickPathAnimation*>();
     QVERIFY(pathAnim);
 
     pathAnim->start();
@@ -381,7 +381,7 @@ void tst_qdeclarativeanimations::pathWithNoStart()
 
 void tst_qdeclarativeanimations::alwaysRunToEnd()
 {
-    QSGRectangle rect;
+    QQuickRectangle rect;
     QDeclarativePropertyAnimation animation;
     animation.setTarget(&rect);
     animation.setProperty("x");
@@ -401,7 +401,7 @@ void tst_qdeclarativeanimations::alwaysRunToEnd()
 
 void tst_qdeclarativeanimations::complete()
 {
-    QSGRectangle rect;
+    QQuickRectangle rect;
     QDeclarativePropertyAnimation animation;
     animation.setTarget(&rect);
     animation.setProperty("x");
@@ -422,7 +422,7 @@ void tst_qdeclarativeanimations::complete()
 
 void tst_qdeclarativeanimations::resume()
 {
-    QSGRectangle rect;
+    QQuickRectangle rect;
     QDeclarativePropertyAnimation animation;
     animation.setTarget(&rect);
     animation.setProperty("x");
@@ -449,7 +449,7 @@ void tst_qdeclarativeanimations::resume()
 
 void tst_qdeclarativeanimations::dotProperty()
 {
-    QSGRectangle rect;
+    QQuickRectangle rect;
     QDeclarativeNumberAnimation animation;
     animation.setTarget(&rect);
     animation.setProperty("border.width");
@@ -470,7 +470,7 @@ void tst_qdeclarativeanimations::badTypes()
 {
     //don't crash
     {
-        QSGView *view = new QSGView;
+        QQuickView *view = new QQuickView;
         view->setSource(QUrl::fromLocalFile(TESTDATA("badtype1.qml")));
 
         qApp->processEvents();
@@ -504,12 +504,12 @@ void tst_qdeclarativeanimations::badTypes()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("badtype4.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGItemPrivate::get(rect)->setState("state1");
+        QQuickItemPrivate::get(rect)->setState("state1");
         QTest::qWait(1000 + 50);
-        QSGRectangle *myRect = rect->findChild<QSGRectangle*>("MyRect");
+        QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("MyRect");
         QVERIFY(myRect);
         QCOMPARE(myRect->x(),qreal(200));
     }
@@ -524,13 +524,13 @@ void tst_qdeclarativeanimations::badProperties()
         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());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c1.create());
         QVERIFY(rect);
 
         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());
+        rect = qobject_cast<QQuickRectangle*>(c2.create());
         QVERIFY(rect);
 
         //### should we warn here are well?
@@ -546,12 +546,12 @@ void tst_qdeclarativeanimations::mixedTypes()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("mixedtype1.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGItemPrivate::get(rect)->setState("state1");
+        QQuickItemPrivate::get(rect)->setState("state1");
         QTest::qWait(500);
-        QSGRectangle *myRect = rect->findChild<QSGRectangle*>("MyRect");
+        QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("MyRect");
         QVERIFY(myRect);
 
         //rather inexact -- is there a better way?
@@ -562,12 +562,12 @@ void tst_qdeclarativeanimations::mixedTypes()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("mixedtype2.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGItemPrivate::get(rect)->setState("state1");
+        QQuickItemPrivate::get(rect)->setState("state1");
         QTest::qWait(500);
-        QSGRectangle *myRect = rect->findChild<QSGRectangle*>("MyRect");
+        QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("MyRect");
         QVERIFY(myRect);
 
         //rather inexact -- is there a better way?
@@ -582,10 +582,10 @@ void tst_qdeclarativeanimations::properties()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGRectangle *myRect = rect->findChild<QSGRectangle*>("TheRect");
+        QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
         QVERIFY(myRect);
         QTest::qWait(waitDuration);
         QTIMED_COMPARE(myRect->x(),qreal(200));
@@ -594,10 +594,10 @@ void tst_qdeclarativeanimations::properties()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties2.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGRectangle *myRect = rect->findChild<QSGRectangle*>("TheRect");
+        QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
         QVERIFY(myRect);
         QTest::qWait(waitDuration);
         QTIMED_COMPARE(myRect->x(),qreal(200));
@@ -606,10 +606,10 @@ void tst_qdeclarativeanimations::properties()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties3.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGRectangle *myRect = rect->findChild<QSGRectangle*>("TheRect");
+        QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
         QVERIFY(myRect);
         QTest::qWait(waitDuration);
         QTIMED_COMPARE(myRect->x(),qreal(300));
@@ -618,10 +618,10 @@ void tst_qdeclarativeanimations::properties()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties4.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGRectangle *myRect = rect->findChild<QSGRectangle*>("TheRect");
+        QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
         QVERIFY(myRect);
         QTest::qWait(waitDuration);
         QTIMED_COMPARE(myRect->y(),qreal(200));
@@ -631,10 +631,10 @@ void tst_qdeclarativeanimations::properties()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties5.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGRectangle *myRect = rect->findChild<QSGRectangle*>("TheRect");
+        QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
         QVERIFY(myRect);
         QTest::qWait(waitDuration);
         QTIMED_COMPARE(myRect->x(),qreal(100));
@@ -648,11 +648,11 @@ void tst_qdeclarativeanimations::propertiesTransition()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGItemPrivate::get(rect)->setState("moved");
-        QSGRectangle *myRect = rect->findChild<QSGRectangle*>("TheRect");
+        QQuickItemPrivate::get(rect)->setState("moved");
+        QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
         QVERIFY(myRect);
         QTest::qWait(waitDuration);
         QTIMED_COMPARE(myRect->x(),qreal(200));
@@ -661,12 +661,12 @@ void tst_qdeclarativeanimations::propertiesTransition()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition2.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGRectangle *myRect = rect->findChild<QSGRectangle*>("TheRect");
+        QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
         QVERIFY(myRect);
-        QSGItemPrivate::get(rect)->setState("moved");
+        QQuickItemPrivate::get(rect)->setState("moved");
         QCOMPARE(myRect->x(),qreal(200));
         QCOMPARE(myRect->y(),qreal(100));
         QTest::qWait(waitDuration);
@@ -676,12 +676,12 @@ void tst_qdeclarativeanimations::propertiesTransition()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition3.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGRectangle *myRect = rect->findChild<QSGRectangle*>("TheRect");
+        QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
         QVERIFY(myRect);
-        QSGItemPrivate::get(rect)->setState("moved");
+        QQuickItemPrivate::get(rect)->setState("moved");
         QCOMPARE(myRect->x(),qreal(200));
         QCOMPARE(myRect->y(),qreal(100));
     }
@@ -689,12 +689,12 @@ void tst_qdeclarativeanimations::propertiesTransition()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition4.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGRectangle *myRect = rect->findChild<QSGRectangle*>("TheRect");
+        QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
         QVERIFY(myRect);
-        QSGItemPrivate::get(rect)->setState("moved");
+        QQuickItemPrivate::get(rect)->setState("moved");
         QCOMPARE(myRect->x(),qreal(100));
         QTest::qWait(waitDuration);
         QTIMED_COMPARE(myRect->x(),qreal(200));
@@ -703,12 +703,12 @@ void tst_qdeclarativeanimations::propertiesTransition()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition5.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGRectangle *myRect = rect->findChild<QSGRectangle*>("TheRect");
+        QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
         QVERIFY(myRect);
-        QSGItemPrivate::get(rect)->setState("moved");
+        QQuickItemPrivate::get(rect)->setState("moved");
         QCOMPARE(myRect->x(),qreal(100));
         QTest::qWait(waitDuration);
         QTIMED_COMPARE(myRect->x(),qreal(200));
@@ -717,12 +717,12 @@ void tst_qdeclarativeanimations::propertiesTransition()
     /*{
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition6.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGRectangle *myRect = rect->findChild<QSGRectangle*>("TheRect");
+        QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
         QVERIFY(myRect);
-        QSGItemPrivate::get(rect)->setState("moved");
+        QQuickItemPrivate::get(rect)->setState("moved");
         QCOMPARE(myRect->x(),qreal(100));
         QTest::qWait(waitDuration);
         QTIMED_COMPARE(myRect->x(),qreal(100));
@@ -731,11 +731,11 @@ void tst_qdeclarativeanimations::propertiesTransition()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition7.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGItemPrivate::get(rect)->setState("moved");
-        QSGRectangle *myRect = rect->findChild<QSGRectangle*>("TheRect");
+        QQuickItemPrivate::get(rect)->setState("moved");
+        QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
         QVERIFY(myRect);
         QTest::qWait(waitDuration);
         QTIMED_COMPARE(myRect->x(),qreal(200));
@@ -747,18 +747,18 @@ void tst_qdeclarativeanimations::pathTransition()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathTransition.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect);
 
-    QSGRectangle *myRect = rect->findChild<QSGRectangle*>("redRect");
+    QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("redRect");
     QVERIFY(myRect);
 
-    QSGItemPrivate::get(rect)->setState("moved");
+    QQuickItemPrivate::get(rect)->setState("moved");
     QTRY_VERIFY(myRect->x() < 500 && myRect->x() > 100 && myRect->y() > 50 && myRect->y() < 700 );  //animation started
     QTRY_VERIFY(qFuzzyCompare(myRect->x(), qreal(100)) && qFuzzyCompare(myRect->y(), qreal(700)));
     QTest::qWait(100);
 
-    QSGItemPrivate::get(rect)->setState("");
+    QQuickItemPrivate::get(rect)->setState("");
     QTRY_VERIFY(myRect->x() < 500 && myRect->x() > 100 && myRect->y() > 50 && myRect->y() < 700 );  //animation started
     QTRY_VERIFY(qFuzzyCompare(myRect->x(), qreal(500)) && qFuzzyCompare(myRect->y(), qreal(50)));
 }
@@ -767,10 +767,10 @@ void tst_qdeclarativeanimations::disabledTransition()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("disabledTransition.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect);
 
-    QSGRectangle *myRect = rect->findChild<QSGRectangle*>("TheRect");
+    QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
     QVERIFY(myRect);
 
     QDeclarativeTransition *trans = rect->findChild<QDeclarativeTransition*>();
@@ -778,12 +778,12 @@ void tst_qdeclarativeanimations::disabledTransition()
 
     QCOMPARE(trans->enabled(), false);
 
-    QSGItemPrivate::get(rect)->setState("moved");
+    QQuickItemPrivate::get(rect)->setState("moved");
     QCOMPARE(myRect->x(),qreal(200));
 
     trans->setEnabled(true);
 
-    QSGItemPrivate::get(rect)->setState("");
+    QQuickItemPrivate::get(rect)->setState("");
     QCOMPARE(myRect->x(),qreal(200));
     QTest::qWait(300);
     QTIMED_COMPARE(myRect->x(),qreal(100));
@@ -809,7 +809,7 @@ void tst_qdeclarativeanimations::attached()
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("attached.qml")));
     QTest::ignoreMessage(QtDebugMsg, "off");
     QTest::ignoreMessage(QtDebugMsg, "on");
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect);
 }
 
@@ -820,7 +820,7 @@ void tst_qdeclarativeanimations::propertyValueSourceDefaultStart()
 
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("valuesource.qml")));
 
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
         QDeclarativeAbstractAnimation *myAnim = rect->findChild<QDeclarativeAbstractAnimation*>("MyAnim");
@@ -833,7 +833,7 @@ void tst_qdeclarativeanimations::propertyValueSourceDefaultStart()
 
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("valuesource2.qml")));
 
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
         QDeclarativeAbstractAnimation *myAnim = rect->findChild<QDeclarativeAbstractAnimation*>("MyAnim");
@@ -846,7 +846,7 @@ void tst_qdeclarativeanimations::propertyValueSourceDefaultStart()
 
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("dontAutoStart.qml")));
 
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
         QDeclarativeAbstractAnimation *myAnim = rect->findChild<QDeclarativeAbstractAnimation*>("MyAnim");
@@ -865,7 +865,7 @@ void tst_qdeclarativeanimations::dontStart()
 
         QString warning = c.url().toString() + ":14:13: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes.";
         QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
         QDeclarativeAbstractAnimation *myAnim = rect->findChild<QDeclarativeAbstractAnimation*>("MyAnim");
@@ -880,7 +880,7 @@ void tst_qdeclarativeanimations::dontStart()
 
         QString warning = c.url().toString() + ":15:17: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes.";
         QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
         QDeclarativeAbstractAnimation *myAnim = rect->findChild<QDeclarativeAbstractAnimation*>("MyAnim");
@@ -944,15 +944,15 @@ void tst_qdeclarativeanimations::rotation()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("rotation.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect);
 
-    QSGRectangle *rr = rect->findChild<QSGRectangle*>("rr");
-    QSGRectangle *rr2 = rect->findChild<QSGRectangle*>("rr2");
-    QSGRectangle *rr3 = rect->findChild<QSGRectangle*>("rr3");
-    QSGRectangle *rr4 = rect->findChild<QSGRectangle*>("rr4");
+    QQuickRectangle *rr = rect->findChild<QQuickRectangle*>("rr");
+    QQuickRectangle *rr2 = rect->findChild<QQuickRectangle*>("rr2");
+    QQuickRectangle *rr3 = rect->findChild<QQuickRectangle*>("rr3");
+    QQuickRectangle *rr4 = rect->findChild<QQuickRectangle*>("rr4");
 
-    QSGItemPrivate::get(rect)->setState("state1");
+    QQuickItemPrivate::get(rect)->setState("state1");
     QTest::qWait(800);
     qreal r1 = rr->rotation();
     qreal r2 = rr2->rotation();
@@ -975,10 +975,10 @@ void tst_qdeclarativeanimations::runningTrueBug()
     //ensure we start correctly when "running: true" is explicitly set
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("runningTrueBug.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect);
 
-    QSGRectangle *cloud = rect->findChild<QSGRectangle*>("cloud");
+    QQuickRectangle *cloud = rect->findChild<QQuickRectangle*>("cloud");
     QVERIFY(cloud);
     QTest::qWait(1000);
     QVERIFY(cloud->x() > qreal(0));
@@ -992,10 +992,10 @@ void tst_qdeclarativeanimations::nonTransitionBug()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("nonTransitionBug.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
-    QSGRectangle *mover = rect->findChild<QSGRectangle*>("mover");
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+    QQuickRectangle *mover = rect->findChild<QQuickRectangle*>("mover");
 
     mover->setX(100);
     QCOMPARE(mover->x(), qreal(100));
@@ -1018,7 +1018,7 @@ void tst_qdeclarativeanimations::registrationBug()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("registrationBug.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
     QTRY_COMPARE(rect->property("value"), QVariant(int(100)));
 }
@@ -1028,7 +1028,7 @@ void tst_qdeclarativeanimations::doubleRegistrationBug()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("doubleRegistrationBug.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
 
     QDeclarativeAbstractAnimation *anim = rect->findChild<QDeclarativeAbstractAnimation*>("animation");
@@ -1039,7 +1039,7 @@ void tst_qdeclarativeanimations::doubleRegistrationBug()
 //QTBUG-16736
 void tst_qdeclarativeanimations::alwaysRunToEndRestartBug()
 {
-    QSGRectangle rect;
+    QQuickRectangle rect;
     QDeclarativePropertyAnimation animation;
     animation.setTarget(&rect);
     animation.setProperty("x");
@@ -1066,7 +1066,7 @@ void tst_qdeclarativeanimations::transitionAssignmentBug()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("transitionAssignmentBug.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
 
     QCOMPARE(rect->property("nullObject").toBool(), false);
@@ -1078,7 +1078,7 @@ void tst_qdeclarativeanimations::pauseBindingBug()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pauseBindingBug.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
     QDeclarativeAbstractAnimation *anim = rect->findChild<QDeclarativeAbstractAnimation*>("animation");
     QVERIFY(anim->qtAnimation()->state() == QAbstractAnimation::Paused);
index b3fa38d..db345e3 100644 (file)
@@ -42,8 +42,8 @@
 #include <qtest.h>
 #include <QtDeclarative/qdeclarativecomponent.h>
 #include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qsgitem.h>
-#include <QtDeclarative/qsgview.h>
+#include <QtDeclarative/qquickitem.h>
+#include <QtDeclarative/qquickview.h>
 #include <QtGui/qinputpanel.h>
 
 class tst_qdeclarativeapplication : public QObject
@@ -71,9 +71,9 @@ void tst_qdeclarativeapplication::active()
 
     QDeclarativeComponent component(&engine);
     component.setData("import QtQuick 2.0; Item { property bool active: Qt.application.active }", QUrl::fromLocalFile(""));
-    QSGItem *item = qobject_cast<QSGItem *>(component.create());
+    QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
     QVERIFY(item);
-    QSGView view;
+    QQuickView view;
     item->setParentItem(view.rootObject());
 
     // not active
@@ -84,7 +84,7 @@ void tst_qdeclarativeapplication::active()
     view.show();
     view.requestActivateWindow();
     QTest::qWait(50);
-    QTRY_COMPARE(view.status(), QSGView::Ready);
+    QTRY_COMPARE(view.status(), QQuickView::Ready);
     QCOMPARE(item->property("active").toBool(), QGuiApplication::activeWindow() != 0);
 
     // not active again
@@ -104,9 +104,9 @@ void tst_qdeclarativeapplication::layoutDirection()
 
     QDeclarativeComponent component(&engine);
     component.setData("import QtQuick 2.0; Item { property bool layoutDirection: Qt.application.layoutDirection }", QUrl::fromLocalFile(""));
-    QSGItem *item = qobject_cast<QSGItem *>(component.create());
+    QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
     QVERIFY(item);
-    QSGView view;
+    QQuickView view;
     item->setParentItem(view.rootObject());
 
     // not mirrored
@@ -125,9 +125,9 @@ 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());
+    QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
     QVERIFY(item);
-    QSGView view;
+    QQuickView view;
     item->setParentItem(view.rootObject());
 
     // check that the inputPanel property maches with application's input panel
index b2aa311..b6e68d6 100644 (file)
 #include <qsignalspy.h>
 #include <QtDeclarative/qdeclarativeengine.h>
 #include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtDeclarative/qsgview.h>
-#include <private/qsgrectangle_p.h>
-#include <private/qsgtext_p.h>
+#include <QtDeclarative/qquickview.h>
+#include <private/qquickrectangle_p.h>
+#include <private/qquicktext_p.h>
 #include <private/qdeclarativebehavior_p.h>
 #include <private/qdeclarativeanimation_p.h>
-#include <private/qsgitem_p.h>
+#include <private/qquickitem_p.h>
 #include "../shared/util.h"
 
 class tst_qdeclarativebehaviors : public QObject
@@ -83,13 +83,13 @@ void tst_qdeclarativebehaviors::simpleBehavior()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("simple.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QTRY_VERIFY(rect);
     QTRY_VERIFY(qobject_cast<QDeclarativeBehavior*>(rect->findChild<QDeclarativeBehavior*>("MyBehavior"))->animation());
 
-    QSGItemPrivate::get(rect)->setState("moved");
-    QTRY_VERIFY(qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"))->x() > 0);
-    QTRY_VERIFY(qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"))->x() < 200);
+    QQuickItemPrivate::get(rect)->setState("moved");
+    QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() > 0);
+    QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() < 200);
     //i.e. the behavior has been triggered
 
     delete rect;
@@ -99,12 +99,12 @@ void tst_qdeclarativebehaviors::scriptTriggered()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("scripttrigger.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QTRY_VERIFY(rect);
 
     rect->setColor(QColor("red"));
-    QTRY_VERIFY(qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"))->x() > 0);
-    QTRY_VERIFY(qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"))->x() < 200);
+    QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() > 0);
+    QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() < 200);
     //i.e. the behavior has been triggered
 
     delete rect;
@@ -114,10 +114,10 @@ void tst_qdeclarativebehaviors::cppTriggered()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("cpptrigger.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QTRY_VERIFY(rect);
 
-    QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"));
+    QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
     QTRY_VERIFY(innerRect);
 
     innerRect->setProperty("x", 200);
@@ -132,11 +132,11 @@ void tst_qdeclarativebehaviors::loop()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("loop.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QTRY_VERIFY(rect);
 
     //don't crash
-    QSGItemPrivate::get(rect)->setState("moved");
+    QQuickItemPrivate::get(rect)->setState("moved");
 
     delete rect;
 }
@@ -145,12 +145,12 @@ void tst_qdeclarativebehaviors::colorBehavior()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("color.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QTRY_VERIFY(rect);
 
-    QSGItemPrivate::get(rect)->setState("red");
-    QTRY_VERIFY(qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"))->color() != QColor("red"));
-    QTRY_VERIFY(qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"))->color() != QColor("green"));
+    QQuickItemPrivate::get(rect)->setState("red");
+    QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->color() != QColor("red"));
+    QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->color() != QColor("green"));
     //i.e. the behavior has been triggered
 
     delete rect;
@@ -160,12 +160,12 @@ void tst_qdeclarativebehaviors::parentBehavior()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("parent.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QTRY_VERIFY(rect);
 
-    QSGItemPrivate::get(rect)->setState("reparented");
-    QTRY_VERIFY(rect->findChild<QSGRectangle*>("MyRect")->parentItem() != rect->findChild<QSGItem*>("NewParent"));
-    QTRY_VERIFY(rect->findChild<QSGRectangle*>("MyRect")->parentItem() == rect->findChild<QSGItem*>("NewParent"));
+    QQuickItemPrivate::get(rect)->setState("reparented");
+    QTRY_VERIFY(rect->findChild<QQuickRectangle*>("MyRect")->parentItem() != rect->findChild<QQuickItem*>("NewParent"));
+    QTRY_VERIFY(rect->findChild<QQuickRectangle*>("MyRect")->parentItem() == rect->findChild<QQuickItem*>("NewParent"));
 
     delete rect;
 }
@@ -174,11 +174,11 @@ void tst_qdeclarativebehaviors::replaceBinding()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("binding.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QTRY_VERIFY(rect);
 
-    QSGItemPrivate::get(rect)->setState("moved");
-    QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"));
+    QQuickItemPrivate::get(rect)->setState("moved");
+    QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
     QTRY_VERIFY(innerRect);
     QTRY_VERIFY(innerRect->x() > 0);
     QTRY_VERIFY(innerRect->x() < 200);
@@ -189,7 +189,7 @@ void tst_qdeclarativebehaviors::replaceBinding()
     rect->setProperty("movedx", 210);
     QTRY_COMPARE(innerRect->x(), (qreal)210);
 
-    QSGItemPrivate::get(rect)->setState("");
+    QQuickItemPrivate::get(rect)->setState("");
     QTRY_VERIFY(innerRect->x() > 10);
     QTRY_VERIFY(innerRect->x() < 210);  //i.e. the behavior has been triggered
     QTRY_COMPARE(innerRect->x(), (qreal)10);
@@ -207,14 +207,14 @@ void tst_qdeclarativebehaviors::group()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("groupProperty.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         qDebug() << c.errorString();
         QTRY_VERIFY(rect);
 
-        QSGItemPrivate::get(rect)->setState("moved");
+        QQuickItemPrivate::get(rect)->setState("moved");
         //QTest::qWait(200);
-        QTRY_VERIFY(qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"))->x() > 0);
-        QTRY_VERIFY(qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"))->x() < 200);
+        QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() > 0);
+        QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() < 200);
         //i.e. the behavior has been triggered
 
         delete rect;
@@ -224,12 +224,12 @@ void tst_qdeclarativebehaviors::group()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("groupProperty2.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QTRY_VERIFY(rect);
 
-        QSGItemPrivate::get(rect)->setState("moved");
-        QTRY_VERIFY(qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"))->border()->width() > 0);
-        QTRY_VERIFY(qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"))->border()->width() < 4);
+        QQuickItemPrivate::get(rect)->setState("moved");
+        QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->border()->width() > 0);
+        QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->border()->width() < 4);
         //i.e. the behavior has been triggered
 
         delete rect;
@@ -240,11 +240,11 @@ void tst_qdeclarativebehaviors::emptyBehavior()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("empty.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect);
 
-    QSGItemPrivate::get(rect)->setState("moved");
-    qreal x = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"))->x();
+    QQuickItemPrivate::get(rect)->setState("moved");
+    qreal x = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x();
     QCOMPARE(x, qreal(200));    //should change immediately
 
     delete rect;
@@ -254,12 +254,12 @@ void tst_qdeclarativebehaviors::explicitSelection()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("explicit.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect);
 
-    QSGItemPrivate::get(rect)->setState("moved");
-    QTRY_VERIFY(qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"))->x() > 0);
-    QTRY_VERIFY(qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"))->x() < 200);
+    QQuickItemPrivate::get(rect)->setState("moved");
+    QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() > 0);
+    QTRY_VERIFY(qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x() < 200);
     //i.e. the behavior has been triggered
 
     delete rect;
@@ -269,11 +269,11 @@ void tst_qdeclarativebehaviors::nonSelectingBehavior()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("nonSelecting2.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect);
 
-    QSGItemPrivate::get(rect)->setState("moved");
-    qreal x = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"))->x();
+    QQuickItemPrivate::get(rect)->setState("moved");
+    qreal x = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x();
     QCOMPARE(x, qreal(200));    //should change immediately
 
     delete rect;
@@ -285,7 +285,7 @@ void tst_qdeclarativebehaviors::reassignedAnimation()
     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());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect);
     QCOMPARE(qobject_cast<QDeclarativeNumberAnimation*>(
                  rect->findChild<QDeclarativeBehavior*>("MyBehavior")->animation())->duration(), 200);
@@ -297,12 +297,12 @@ void tst_qdeclarativebehaviors::disabled()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("disabled.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect);
     QCOMPARE(rect->findChild<QDeclarativeBehavior*>("MyBehavior")->enabled(), false);
 
-    QSGItemPrivate::get(rect)->setState("moved");
-    qreal x = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"))->x();
+    QQuickItemPrivate::get(rect)->setState("moved");
+    qreal x = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"))->x();
     QCOMPARE(x, qreal(200));    //should change immediately
 
     delete rect;
@@ -316,7 +316,7 @@ void tst_qdeclarativebehaviors::dontStart()
 
     QString warning = c.url().toString() + ":13:13: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes.";
     QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect);
 
     QDeclarativeAbstractAnimation *myAnim = rect->findChild<QDeclarativeAbstractAnimation*>("MyAnim");
@@ -331,10 +331,10 @@ void tst_qdeclarativebehaviors::startup()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("startup.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGRectangle *innerRect = rect->findChild<QSGRectangle*>("innerRect");
+        QQuickRectangle *innerRect = rect->findChild<QQuickRectangle*>("innerRect");
         QVERIFY(innerRect);
 
         QCOMPARE(innerRect->x(), qreal(100));    //should be set immediately
@@ -345,13 +345,13 @@ void tst_qdeclarativebehaviors::startup()
     {
         QDeclarativeEngine engine;
         QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("startup2.qml")));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
         QVERIFY(rect);
 
-        QSGRectangle *innerRect = rect->findChild<QSGRectangle*>("innerRect");
+        QQuickRectangle *innerRect = rect->findChild<QQuickRectangle*>("innerRect");
         QVERIFY(innerRect);
 
-        QSGText *text = rect->findChild<QSGText*>();
+        QQuickText *text = rect->findChild<QQuickText*>();
         QVERIFY(text);
 
         QCOMPARE(innerRect->x(), text->width());    //should be set immediately
@@ -365,7 +365,7 @@ void tst_qdeclarativebehaviors::groupedPropertyCrash()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("groupedPropertyCrash.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect);  //don't crash
 }
 
@@ -374,7 +374,7 @@ void tst_qdeclarativebehaviors::runningTrue()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("runningTrue.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect);
 
     QDeclarativeAbstractAnimation *animation = rect->findChild<QDeclarativeAbstractAnimation*>("rotAnim");
@@ -390,10 +390,10 @@ void tst_qdeclarativebehaviors::sameValue()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("qtbug12295.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect);
 
-    QSGRectangle *target = rect->findChild<QSGRectangle*>("myRect");
+    QQuickRectangle *target = rect->findChild<QQuickRectangle*>("myRect");
     QVERIFY(target);
 
     target->setX(100);
@@ -421,10 +421,10 @@ void tst_qdeclarativebehaviors::delayedRegistration()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("delayedRegistration.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
 
-    QSGItem *innerRect = rect->property("myItem").value<QSGItem*>();
+    QQuickItem *innerRect = rect->property("myItem").value<QQuickItem*>();
     QVERIFY(innerRect != 0);
 
     QCOMPARE(innerRect->property("x").toInt(), int(0));
index de34d9e..ea05963 100644 (file)
@@ -42,7 +42,7 @@
 #include <QtDeclarative/qdeclarativeengine.h>
 #include <QtDeclarative/qdeclarativecomponent.h>
 #include <private/qdeclarativebind_p.h>
-#include <private/qsgrectangle_p.h>
+#include <private/qquickrectangle_p.h>
 #include "../shared/util.h"
 
 class tst_qdeclarativebinding : public QObject
@@ -70,7 +70,7 @@ void tst_qdeclarativebinding::binding()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-binding.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
 
     QDeclarativeBind *binding3 = qobject_cast<QDeclarativeBind*>(rect->findChild<QDeclarativeBind*>("binding3"));
@@ -98,7 +98,7 @@ void tst_qdeclarativebinding::whenAfterValue()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-binding2.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
 
     QVERIFY(rect != 0);
     QCOMPARE(rect->color(), QColor("yellow"));
@@ -114,10 +114,10 @@ void tst_qdeclarativebinding::restoreBinding()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("restoreBinding.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
 
-    QSGRectangle *myItem = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("myItem"));
+    QQuickRectangle *myItem = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("myItem"));
     QVERIFY(myItem != 0);
 
     myItem->setY(25);
@@ -144,10 +144,10 @@ void tst_qdeclarativebinding::restoreBindingWithLoop()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("restoreBindingWithLoop.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
 
-    QSGRectangle *myItem = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("myItem"));
+    QQuickRectangle *myItem = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("myItem"));
     QVERIFY(myItem != 0);
 
     myItem->setY(25);
@@ -179,7 +179,7 @@ void tst_qdeclarativebinding::deletedObject()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("deletedObject.qml")));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
 
     QGuiApplication::sendPostedEvents(0, QEvent::DeferredDelete);
index f3354ac..1dcaaa1 100644 (file)
@@ -43,7 +43,7 @@
 
 #include <QtDeclarative/qdeclarativeengine.h>
 #include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtDeclarative/qsgitem.h>
+#include <QtDeclarative/qquickitem.h>
 #include <QtDeclarative/qdeclarativeproperty.h>
 #include <QtDeclarative/qdeclarativeincubator.h>
 #include <qcolor.h>
@@ -133,7 +133,7 @@ void tst_qdeclarativecomponent::qmlCreateObject()
     QObject *testObject2 = object->property("declarativeitem").value<QObject*>();
     QVERIFY(testObject2);
     QVERIFY(testObject2->parent() == object);
-    QCOMPARE(testObject2->metaObject()->className(), "QSGItem");
+    QCOMPARE(testObject2->metaObject()->className(), "QQuickItem");
 }
 
 void tst_qdeclarativecomponent::qmlCreateObjectWithProperties()
index ec04833..450f16c 100644 (file)
@@ -42,7 +42,7 @@
 #include <QtDeclarative/qdeclarativeengine.h>
 #include <QtDeclarative/qdeclarativecomponent.h>
 #include <private/qdeclarativeconnections_p.h>
-#include <private/qsgitem_p.h>
+#include <private/qquickitem_p.h>
 #include "../shared/util.h"
 #include <QtDeclarative/qdeclarativescriptstring.h>
 
@@ -102,7 +102,7 @@ void tst_qdeclarativeconnection::connection()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-connection.qml")));
-    QSGItem *item = qobject_cast<QSGItem*>(c.create());
+    QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
 
     QVERIFY(item != 0);
 
@@ -119,7 +119,7 @@ void tst_qdeclarativeconnection::trimming()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("trimming.qml")));
-    QSGItem *item = qobject_cast<QSGItem*>(c.create());
+    QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
 
     QVERIFY(item != 0);
 
@@ -140,18 +140,18 @@ void tst_qdeclarativeconnection::targetChanged()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("connection-targetchange.qml")));
-    QSGItem *item = qobject_cast<QSGItem*>(c.create());
+    QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
     QVERIFY(item != 0);
 
     QDeclarativeConnections *connections = item->findChild<QDeclarativeConnections*>("connections");
     QVERIFY(connections);
 
-    QSGItem *item1 = item->findChild<QSGItem*>("item1");
+    QQuickItem *item1 = item->findChild<QQuickItem*>("item1");
     QVERIFY(item1);
 
     item1->setWidth(200);
 
-    QSGItem *item2 = item->findChild<QSGItem*>("item2");
+    QQuickItem *item2 = item->findChild<QQuickItem*>("item2");
     QVERIFY(item2);
     QVERIFY(connections->target() == item2);
 
@@ -185,7 +185,7 @@ void tst_qdeclarativeconnection::unknownSignals()
 
     QDeclarativeEngine engine;
     QDeclarativeComponent c(&engine, url);
-    QSGItem *item = qobject_cast<QSGItem*>(c.create());
+    QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
     QVERIFY(item != 0);
 
     // check that connection is created (they are all runtime errors)
index 9f4e131..e438885 100644 (file)
@@ -42,7 +42,7 @@
 #include <QtTest/QtTest>
 #include <QtDeclarative/qdeclarativeengine.h>
 #include <QtDeclarative/qdeclarativeimageprovider.h>
-#include <private/qsgimage_p.h>
+#include <private/qquickimage_p.h>
 #include <QImageReader>
 #include <QWaitCondition>
 
@@ -228,19 +228,19 @@ void tst_qdeclarativeimageprovider::runTest(bool async, QDeclarativeImageProvide
             + properties + " }";
     QDeclarativeComponent component(&engine);
     component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGImage *obj = qobject_cast<QSGImage*>(component.create());
+    QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
     QVERIFY(obj != 0);
 
     if (async) 
-        QTRY_VERIFY(obj->status() == QSGImage::Loading);
+        QTRY_VERIFY(obj->status() == QQuickImage::Loading);
 
     QCOMPARE(obj->source(), QUrl(source));
 
     if (error.isEmpty()) {
         if (async)
-            QTRY_VERIFY(obj->status() == QSGImage::Ready);
+            QTRY_VERIFY(obj->status() == QQuickImage::Ready);
         else
-            QVERIFY(obj->status() == QSGImage::Ready);
+            QVERIFY(obj->status() == QQuickImage::Ready);
         if (QByteArray(QTest::currentDataTag()).startsWith("qimage"))
             QCOMPARE(static_cast<TestQImageProvider*>(provider)->lastImageId, imageId);
         else
@@ -248,13 +248,13 @@ void tst_qdeclarativeimageprovider::runTest(bool async, QDeclarativeImageProvide
 
         QCOMPARE(obj->width(), qreal(size.width()));
         QCOMPARE(obj->height(), qreal(size.height()));
-        QCOMPARE(obj->fillMode(), QSGImage::Stretch);
+        QCOMPARE(obj->fillMode(), QQuickImage::Stretch);
         QCOMPARE(obj->progress(), 1.0);
     } else {
         if (async)
-            QTRY_VERIFY(obj->status() == QSGImage::Error);
+            QTRY_VERIFY(obj->status() == QQuickImage::Error);
         else
-            QVERIFY(obj->status() == QSGImage::Error);
+            QVERIFY(obj->status() == QQuickImage::Error);
     }
 
     delete obj;
@@ -308,7 +308,7 @@ void tst_qdeclarativeimageprovider::requestPixmap_async()
     QString componentStr = "import QtQuick 2.0\nImage { asynchronous: true; source: \"image://test/pixmap-async-test.png\" }";
     QDeclarativeComponent component(&engine);
     component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGImage *obj = qobject_cast<QSGImage*>(component.create());
+    QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
     QVERIFY(obj != 0);
 
     delete obj;
@@ -335,10 +335,10 @@ void tst_qdeclarativeimageprovider::removeProvider()
     QString componentStr = "import QtQuick 2.0\nImage { source: \"" + newImageFileName() + "\" }";
     QDeclarativeComponent component(&engine);
     component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGImage *obj = qobject_cast<QSGImage*>(component.create());
+    QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
     QVERIFY(obj != 0);
 
-    QCOMPARE(obj->status(), QSGImage::Ready);
+    QCOMPARE(obj->status(), QQuickImage::Ready);
 
     // remove the provider and confirm
     QString fileName = newImageFileName();
@@ -348,7 +348,7 @@ void tst_qdeclarativeimageprovider::removeProvider()
     engine.removeImageProvider("test");
 
     obj->setSource(QUrl(fileName));
-    QCOMPARE(obj->status(), QSGImage::Error);
+    QCOMPARE(obj->status(), QQuickImage::Error);
 
     delete obj;
 }
@@ -404,17 +404,17 @@ void tst_qdeclarativeimageprovider::threadTest()
     QObject *obj = component.create();
     //MUST not deadlock
     QVERIFY(obj != 0);
-    QList<QSGImage *> images = obj->findChildren<QSGImage *>();
+    QList<QQuickImage *> images = obj->findChildren<QQuickImage *>();
     QCOMPARE(images.count(), 4);
     QTest::qWait(100);
-    foreach (QSGImage *img, images) {
-        QCOMPARE(img->status(), QSGImage::Loading);
+    foreach (QQuickImage *img, images) {
+        QCOMPARE(img->status(), QQuickImage::Loading);
     }
     provider->ok = true;
     provider->cond.wakeAll();
     QTest::qWait(250);
-    foreach (QSGImage *img, images) {
-        QTRY_VERIFY(img->status() == QSGImage::Ready);
+    foreach (QQuickImage *img, images) {
+        QTRY_VERIFY(img->status() == QQuickImage::Ready);
     }
 }
 
index bde2c14..538ebbb 100644 (file)
@@ -1644,17 +1644,17 @@ void tst_qdeclarativelanguage::importsLocal_data()
     QTest::newRow("local import")
         << "import \"subdir\"\n" // QT-613
            "Test {}"
-        << "QSGRectangle"
+        << "QQuickRectangle"
         << "";
     QTest::newRow("local import second")
         << "import QtQuick 2.0\nimport \"subdir\"\n"
            "Test {}"
-        << "QSGRectangle"
+        << "QQuickRectangle"
         << "";
     QTest::newRow("local import subsubdir")
         << "import QtQuick 2.0\nimport \"subdir/subsubdir\"\n"
            "SubTest {}"
-        << "QSGRectangle"
+        << "QQuickRectangle"
         << "";
     QTest::newRow("local import QTBUG-7721 A")
         << "subdir.Test {}" // no longer allowed (QTBUG-7721)
@@ -1668,7 +1668,7 @@ void tst_qdeclarativelanguage::importsLocal_data()
     QTest::newRow("local import as")
         << "import \"subdir\" as T\n"
            "T.Test {}"
-        << "QSGRectangle"
+        << "QQuickRectangle"
         << "";
     QTest::newRow("wrong local import as")
         << "import \"subdir\" as T\n"
@@ -1734,11 +1734,11 @@ void tst_qdeclarativelanguage::importsRemote_data()
 
     QString serverdir = "http://127.0.0.1:14447/qtest/declarative/qmllanguage";
 
-    QTest::newRow("remote import") << "import \""+serverdir+"\"\nTest {}" << "QSGRectangle"
+    QTest::newRow("remote import") << "import \""+serverdir+"\"\nTest {}" << "QQuickRectangle"
         << "";
-    QTest::newRow("remote import with subdir") << "import \""+serverdir+"\"\nTestSubDir {}" << "QSGText"
+    QTest::newRow("remote import with subdir") << "import \""+serverdir+"\"\nTestSubDir {}" << "QQuickText"
         << "";
-    QTest::newRow("remote import with local") << "import \""+serverdir+"\"\nTestLocal {}" << "QSGImage"
+    QTest::newRow("remote import with local") << "import \""+serverdir+"\"\nTestLocal {}" << "QQuickImage"
         << "";
     QTest::newRow("wrong remote import with undeclared local") << "import \""+serverdir+"\"\nWrongTestLocal {}" << ""
         << "WrongTestLocal is not a type";
@@ -1772,27 +1772,27 @@ void tst_qdeclarativelanguage::importsInstalled_data()
     QTest::newRow("installed import 0")
         << "import com.nokia.installedtest0 0.0\n"
            "InstalledTestTP {}"
-        << "QSGRectangle"
+        << "QQuickRectangle"
         << "";
     QTest::newRow("installed import 0 as TP")
         << "import com.nokia.installedtest0 0.0 as TP\n"
            "TP.InstalledTestTP {}"
-        << "QSGRectangle"
+        << "QQuickRectangle"
         << "";
     QTest::newRow("installed import 1")
         << "import com.nokia.installedtest 1.0\n"
            "InstalledTest {}"
-        << "QSGRectangle"
+        << "QQuickRectangle"
         << "";
     QTest::newRow("installed import 2")
         << "import com.nokia.installedtest 1.3\n"
            "InstalledTest {}"
-        << "QSGRectangle"
+        << "QQuickRectangle"
         << "";
     QTest::newRow("installed import 3")
         << "import com.nokia.installedtest 1.4\n"
            "InstalledTest {}"
-        << "QSGText"
+        << "QQuickText"
         << "";
     QTest::newRow("installed import minor version not available") // QTBUG-11936
         << "import com.nokia.installedtest 0.1\n"
@@ -1835,26 +1835,26 @@ void tst_qdeclarativelanguage::importsOrder_data()
            "import com.nokia.installedtest 1.4\n"
            "import com.nokia.installedtest 1.4\n"
            "InstalledTest {}"
-           << (!qmlCheckTypes()?"QSGText":"")
+           << (!qmlCheckTypes()?"QQuickText":"")
            << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.4");
     QTest::newRow("installed import overrides 1") <<
            "import com.nokia.installedtest 1.0\n"
            "import com.nokia.installedtest 1.4\n"
            "InstalledTest {}"
-           << (!qmlCheckTypes()?"QSGText":"")
+           << (!qmlCheckTypes()?"QQuickText":"")
            << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.0");
     QTest::newRow("installed import overrides 2") <<
            "import com.nokia.installedtest 1.4\n"
            "import com.nokia.installedtest 1.0\n"
            "InstalledTest {}"
-           << (!qmlCheckTypes()?"QSGRectangle":"")
+           << (!qmlCheckTypes()?"QQuickRectangle":"")
            << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.0 and 1.4");
     QTest::newRow("installed import re-overrides 1") <<
            "import com.nokia.installedtest 1.4\n"
            "import com.nokia.installedtest 1.0\n"
            "import com.nokia.installedtest 1.4\n"
            "InstalledTest {}"
-           << (!qmlCheckTypes()?"QSGText":"")
+           << (!qmlCheckTypes()?"QQuickText":"")
            << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.4 and 1.0");
     QTest::newRow("installed import re-overrides 2") <<
            "import com.nokia.installedtest 1.4\n"
@@ -1862,20 +1862,20 @@ void tst_qdeclarativelanguage::importsOrder_data()
            "import com.nokia.installedtest 1.4\n"
            "import com.nokia.installedtest 1.0\n"
            "InstalledTest {}"
-           << (!qmlCheckTypes()?"QSGRectangle":"")
+           << (!qmlCheckTypes()?"QQuickRectangle":"")
            << (!qmlCheckTypes()?"":"InstalledTest is ambiguous. Found in lib/com/nokia/installedtest in version 1.0 and 1.4");
 
     QTest::newRow("installed import versus builtin 1") <<
            "import com.nokia.installedtest 1.5\n"
            "import QtQuick 2.0\n"
            "Rectangle {}"
-           << (!qmlCheckTypes()?"QSGRectangle":"")
+           << (!qmlCheckTypes()?"QQuickRectangle":"")
            << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in Qt and in lib/com/nokia/installedtest");
     QTest::newRow("installed import versus builtin 2") <<
            "import QtQuick 2.0\n"
            "import com.nokia.installedtest 1.5\n"
            "Rectangle {}"
-           << (!qmlCheckTypes()?"QSGText":"")
+           << (!qmlCheckTypes()?"QQuickText":"")
            << (!qmlCheckTypes()?"":"Rectangle is ambiguous. Found in lib/com/nokia/installedtest and in Qt");
     QTest::newRow("namespaces cannot be overridden by types 1") <<
            "import QtQuick 2.0 as Rectangle\n"
@@ -1887,16 +1887,16 @@ void tst_qdeclarativelanguage::importsOrder_data()
            "import QtQuick 2.0 as Rectangle\n"
            "import com.nokia.installedtest 1.5\n"
            "Rectangle.Image {}"
-        << "QSGImage"
+        << "QQuickImage"
         << "";
     QTest::newRow("local last 1") <<
            "LocalLast {}"
-        << "QSGText"
+        << "QQuickText"
         << "";
     QTest::newRow("local last 2") <<
            "import com.nokia.installedtest 1.0\n"
            "LocalLast {}"
-           << (!qmlCheckTypes()?"QSGRectangle":"")// i.e. from com.nokia.installedtest, not data/LocalLast.qml
+           << (!qmlCheckTypes()?"QQuickRectangle":"")// i.e. from com.nokia.installedtest, not data/LocalLast.qml
            << (!qmlCheckTypes()?"":"LocalLast is ambiguous. Found in lib/com/nokia/installedtest and in local directory");
 }
 
index 92e3a8f..bc6c991 100644 (file)
@@ -39,8 +39,8 @@
 **
 ****************************************************************************/
 #include <qtest.h>
-#include <QtDeclarative/private/qsgitem_p.h>
-#include <QtDeclarative/private/qsgtext_p.h>
+#include <QtDeclarative/private/qquickitem_p.h>
+#include <QtDeclarative/private/qquicktext_p.h>
 #include <QtDeclarative/private/qdeclarativeengine_p.h>
 #include <QtDeclarative/private/qdeclarativelistmodel_p.h>
 #include <QtDeclarative/private/qdeclarativeexpression_p.h>
@@ -62,8 +62,8 @@ public:
 
 private:
     int roleFromName(const QDeclarativeListModel *model, const QString &roleName);
-    QSGItem *createWorkerTest(QDeclarativeEngine *eng, QDeclarativeComponent *component, QDeclarativeListModel *model);
-    void waitForWorker(QSGItem *item);
+    QQuickItem *createWorkerTest(QDeclarativeEngine *eng, QDeclarativeComponent *component, QDeclarativeListModel *model);
+    void waitForWorker(QQuickItem *item);
 
 private slots:
     void static_types();
@@ -113,16 +113,16 @@ int tst_qdeclarativelistmodel::roleFromName(const QDeclarativeListModel *model,
     return -1;
 }
 
-QSGItem *tst_qdeclarativelistmodel::createWorkerTest(QDeclarativeEngine *eng, QDeclarativeComponent *component, QDeclarativeListModel *model)
+QQuickItem *tst_qdeclarativelistmodel::createWorkerTest(QDeclarativeEngine *eng, QDeclarativeComponent *component, QDeclarativeListModel *model)
 {
-    QSGItem *item = qobject_cast<QSGItem*>(component->create());
+    QQuickItem *item = qobject_cast<QQuickItem*>(component->create());
     QDeclarativeEngine::setContextForObject(model, eng->rootContext());
     if (item)
         item->setProperty("model", qVariantFromValue(model)); 
     return item;
 }
 
-void tst_qdeclarativelistmodel::waitForWorker(QSGItem *item)
+void tst_qdeclarativelistmodel::waitForWorker(QQuickItem *item)
 {
     QEventLoop loop;
     QTimer timer;
@@ -164,7 +164,7 @@ void tst_qdeclarativelistmodel::static_types_data()
 
     QTest::newRow("enum")
         << "ListElement { foo: Text.AlignHCenter }"
-        << QVariant(double(QSGText::AlignHCenter));
+        << QVariant(double(QQuickText::AlignHCenter));
 
     QTest::newRow("Qt enum")
         << "ListElement { foo: Qt.AlignBottom }"
@@ -456,7 +456,7 @@ void tst_qdeclarativelistmodel::dynamic_worker()
     QDeclarativeListModel model;
     QDeclarativeEngine eng;
     QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
-    QSGItem *item = createWorkerTest(&eng, &component, &model);
+    QQuickItem *item = createWorkerTest(&eng, &component, &model);
     QVERIFY(item != 0);
 
     QSignalSpy spyCount(&model, SIGNAL(countChanged()));
@@ -502,7 +502,7 @@ void tst_qdeclarativelistmodel::dynamic_worker_sync()
     QDeclarativeListModel model;
     QDeclarativeEngine eng;
     QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
-    QSGItem *item = createWorkerTest(&eng, &component, &model);
+    QQuickItem *item = createWorkerTest(&eng, &component, &model);
     QVERIFY(item != 0);
 
     if (script[0] == QLatin1Char('{') && script[script.length()-1] == QLatin1Char('}'))
@@ -556,7 +556,7 @@ void tst_qdeclarativelistmodel::convertNestedToFlat_fail()
     QDeclarativeListModel model;
     QDeclarativeEngine eng;
     QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
-    QSGItem *item = createWorkerTest(&eng, &component, &model);
+    QQuickItem *item = createWorkerTest(&eng, &component, &model);
     QVERIFY(item != 0);
 
     RUNEVAL(item, "model.append({foo: 123})");
@@ -599,7 +599,7 @@ void tst_qdeclarativelistmodel::convertNestedToFlat_ok()
     QDeclarativeListModel model;
     QDeclarativeEngine eng;
     QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
-    QSGItem *item = createWorkerTest(&eng, &component, &model);
+    QQuickItem *item = createWorkerTest(&eng, &component, &model);
     QVERIFY(item != 0);
 
     RUNEVAL(item, "model.append({foo: 123})");
@@ -643,7 +643,7 @@ void tst_qdeclarativelistmodel::enumerate()
     QDeclarativeEngine eng;
     QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/enumerate.qml"));
     QVERIFY(!component.isError());
-    QSGItem *item = qobject_cast<QSGItem*>(component.create());
+    QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
     QVERIFY(item != 0);
     QStringList r = item->property("result").toString().split(":");
     QCOMPARE(r[0],QLatin1String("val1=1Y"));
@@ -830,7 +830,7 @@ void tst_qdeclarativelistmodel::get_worker()
     QDeclarativeListModel model;
     QDeclarativeEngine eng;
     QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
-    QSGItem *item = createWorkerTest(&eng, &component, &model);
+    QQuickItem *item = createWorkerTest(&eng, &component, &model);
     QVERIFY(item != 0);
 
     // Add some values like get() test
@@ -1131,7 +1131,7 @@ void tst_qdeclarativelistmodel::property_changes_worker()
     QDeclarativeEngine engine;
     QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/model.qml"));
     QVERIFY2(component.errorString().isEmpty(), component.errorString().toUtf8());
-    QSGItem *item = createWorkerTest(&engine, &component, &model);
+    QQuickItem *item = createWorkerTest(&engine, &component, &model);
     QVERIFY(item != 0);
 
     QDeclarativeExpression expr(engine.rootContext(), &model, script_setup);
index 966ac19..510bc59 100644 (file)
@@ -43,7 +43,7 @@
 #include <QtDeclarative/qdeclarativecontext.h>
 #include <QtDeclarative/qdeclarativepropertymap.h>
 #include <QtDeclarative/qdeclarativecomponent.h>
-#include <private/qsgtext_p.h>
+#include <private/qquicktext_p.h>
 #include <QSignalSpy>
 
 class tst_QDeclarativePropertyMap : public QObject
@@ -176,7 +176,7 @@ void tst_QDeclarativePropertyMap::changed()
     component.setData("import QtQuick 2.0\nText { text: { testdata.key1 = 'Hello World'; 'X' } }",
             QUrl::fromLocalFile(""));
     QVERIFY(component.isReady());
-    QSGText *txt = qobject_cast<QSGText*>(component.create());
+    QQuickText *txt = qobject_cast<QQuickText*>(component.create());
     QVERIFY(txt);
     QCOMPARE(txt->text(), QString('X'));
     QCOMPARE(spy.count(), 1);
index dbf5373..b4ac2df 100644 (file)
@@ -50,7 +50,7 @@
 #include <QDir>
 #include <QVector3D>
 #include <QCryptographicHash>
-#include <QSGItem>
+#include <QQuickItem>
 #include <QSignalSpy>
 #include "../shared/util.h"
 
@@ -451,7 +451,7 @@ void tst_qdeclarativeqt::createQmlObject()
     QCOMPARE(object->property("emptyArg").toBool(), true);
     QCOMPARE(object->property("success").toBool(), true);
 
-    QSGItem *item = qobject_cast<QSGItem *>(object);
+    QQuickItem *item = qobject_cast<QQuickItem *>(object);
     QVERIFY(item != 0);
     QVERIFY(item->childItems().count() == 1);
 
index 989edfa..735af52 100644 (file)
@@ -42,7 +42,7 @@
 #include <QtDeclarative/qdeclarativeengine.h>
 #include <QtDeclarative/qdeclarativecomponent.h>
 #include <private/qdeclarativesmoothedanimation_p.h>
-#include <private/qsgrectangle_p.h>
+#include <private/qquickrectangle_p.h>
 #include <private/qdeclarativevaluetype_p.h>
 #include "../shared/util.h"
 
@@ -120,7 +120,7 @@ void tst_qdeclarativesmoothedanimation::disabled()
 
 void tst_qdeclarativesmoothedanimation::simpleAnimation()
 {
-    QSGRectangle rect;
+    QQuickRectangle rect;
     QDeclarativeSmoothedAnimation animation;
     animation.setTarget(&rect);
     animation.setProperty("x");
@@ -150,10 +150,10 @@ void tst_qdeclarativesmoothedanimation::valueSource()
 
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("smoothedanimationValueSource.qml")));
 
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect);
 
-    QSGRectangle *theRect = rect->findChild<QSGRectangle*>("theRect");
+    QQuickRectangle *theRect = rect->findChild<QQuickRectangle*>("theRect");
     QVERIFY(theRect);
 
     QDeclarativeSmoothedAnimation *easeX = rect->findChild<QDeclarativeSmoothedAnimation*>("easeX");
@@ -182,10 +182,10 @@ void tst_qdeclarativesmoothedanimation::behavior()
 
     QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("smoothedanimationBehavior.qml")));
 
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect);
 
-    QSGRectangle *theRect = rect->findChild<QSGRectangle*>("theRect");
+    QQuickRectangle *theRect = rect->findChild<QQuickRectangle*>("theRect");
     QVERIFY(theRect);
 
     QDeclarativeSmoothedAnimation *easeX = rect->findChild<QDeclarativeSmoothedAnimation*>("easeX");
index b7e04b7..f7c520d 100644 (file)
@@ -41,7 +41,7 @@
 #include <qtest.h>
 #include <QtDeclarative/qdeclarativeengine.h>
 #include <QtDeclarative/qdeclarativecomponent.h>
-#include <private/qsgtext_p.h>
+#include <private/qquicktext_p.h>
 #include <private/qdeclarativeengine_p.h>
 #include <QtCore/qcryptographichash.h>
 /*
@@ -206,7 +206,7 @@ void tst_qdeclarativesqldatabase::testQml()
     QDeclarativeComponent component(engine);
     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());
+    QQuickText *text = qobject_cast<QQuickText*>(component.create());
     QVERIFY(text != 0);
     QCOMPARE(text->text(),QString("passed"));
 }
index ac24a0b..f6ab652 100644 (file)
 #include <qtest.h>
 #include <QtDeclarative/qdeclarativeengine.h>
 #include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtDeclarative/qsgview.h>
-#include <private/qsgstateoperations_p.h>
-#include <private/qsganchors_p_p.h>
-#include <private/qsgrectangle_p.h>
-#include <private/qsgimage_p.h>
+#include <QtDeclarative/qquickview.h>
+#include <private/qquickstateoperations_p.h>
+#include <private/qquickanchors_p_p.h>
+#include <private/qquickrectangle_p.h>
+#include <private/qquickimage_p.h>
 #include <private/qdeclarativepropertychanges_p.h>
 #include <private/qdeclarativestategroup_p.h>
-#include <private/qsgitem_p.h>
+#include <private/qquickitem_p.h>
 #include <private/qdeclarativeproperty_p.h>
 #include "../shared/util.h"
 
@@ -66,7 +66,7 @@ private:
     int m_foo;
 };
 
-class MyRect : public QSGRectangle
+class MyRect : public QQuickRectangle
 {
    Q_OBJECT
    Q_PROPERTY(int propertyWithNotify READ propertyWithNotify WRITE setPropertyWithNotify NOTIFY oddlyNamedNotifySignal)
@@ -163,8 +163,8 @@ void tst_qdeclarativestates::basicChanges()
 
     {
         QDeclarativeComponent rectComponent(&engine, TESTDATA("basicChanges.qml"));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
-        QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+        QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
         QVERIFY(rect != 0);
 
         QCOMPARE(rect->color(),QColor("red"));
@@ -178,8 +178,8 @@ void tst_qdeclarativestates::basicChanges()
 
     {
         QDeclarativeComponent rectComponent(&engine, TESTDATA("basicChanges2.qml"));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
-        QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+        QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
         QVERIFY(rect != 0);
 
         QCOMPARE(rect->color(),QColor("red"));
@@ -199,8 +199,8 @@ void tst_qdeclarativestates::basicChanges()
 
     {
         QDeclarativeComponent rectComponent(&engine, TESTDATA("basicChanges3.qml"));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
-        QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+        QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
         QVERIFY(rect != 0);
 
         QCOMPARE(rect->color(),QColor("red"));
@@ -259,7 +259,7 @@ void tst_qdeclarativestates::attachedPropertyChanges()
     QDeclarativeComponent component(&engine, TESTDATA("attachedPropertyChanges.qml"));
     QVERIFY(component.isReady());
 
-    QSGItem *item = qobject_cast<QSGItem*>(component.create());
+    QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
     QVERIFY(item != 0);
     QCOMPARE(item->width(), 50.0);
 
@@ -279,8 +279,8 @@ void tst_qdeclarativestates::basicExtension()
 
     {
         QDeclarativeComponent rectComponent(&engine, TESTDATA("basicExtension.qml"));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
-        QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+        QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
         QVERIFY(rect != 0);
 
         QCOMPARE(rect->color(),QColor("red"));
@@ -313,8 +313,8 @@ void tst_qdeclarativestates::basicExtension()
 
     {
         QDeclarativeComponent rectComponent(&engine, TESTDATA("fakeExtension.qml"));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
-        QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+        QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
         QVERIFY(rect != 0);
 
         QCOMPARE(rect->color(),QColor("red"));
@@ -345,8 +345,8 @@ void tst_qdeclarativestates::basicBinding()
 
     {
         QDeclarativeComponent rectComponent(&engine, TESTDATA("basicBinding.qml"));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
-        QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+        QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
         QVERIFY(rect != 0);
 
         QCOMPARE(rect->color(),QColor("red"));
@@ -373,8 +373,8 @@ void tst_qdeclarativestates::basicBinding()
 
     {
         QDeclarativeComponent rectComponent(&engine, TESTDATA("basicBinding2.qml"));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
-        QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+        QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
         QVERIFY(rect != 0);
 
         QCOMPARE(rect->color(),QColor("red"));
@@ -404,8 +404,8 @@ void tst_qdeclarativestates::basicBinding()
 
     {
         QDeclarativeComponent rectComponent(&engine, TESTDATA("basicBinding3.qml"));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
-        QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+        QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
         QVERIFY(rect != 0);
 
         QCOMPARE(rect->color(),QColor("red"));
@@ -429,8 +429,8 @@ void tst_qdeclarativestates::basicBinding()
 
     {
         QDeclarativeComponent rectComponent(&engine, TESTDATA("basicBinding4.qml"));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
-        QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
+        QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
         QVERIFY(rect != 0);
 
         QCOMPARE(rect->color(),QColor("red"));
@@ -469,7 +469,7 @@ void tst_qdeclarativestates::signalOverride()
         rect->doSomething();
         QCOMPARE(rect->color(),QColor("blue"));
 
-        QSGItemPrivate::get(rect)->setState("green");
+        QQuickItemPrivate::get(rect)->setState("green");
         rect->doSomething();
         QCOMPARE(rect->color(),QColor("green"));
     }
@@ -483,8 +483,8 @@ void tst_qdeclarativestates::signalOverride()
         rect->doSomething();
         QCOMPARE(rect->color(),QColor("blue"));
 
-        QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("extendedRect"));
-        QSGItemPrivate::get(innerRect)->setState("green");
+        QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("extendedRect"));
+        QQuickItemPrivate::get(innerRect)->setState("green");
         rect->doSomething();
         QCOMPARE(rect->color(),QColor("blue"));
         QCOMPARE(innerRect->color(),QColor("green"));
@@ -500,7 +500,7 @@ void tst_qdeclarativestates::signalOverrideCrash()
     MyRect *rect = qobject_cast<MyRect*>(rectComponent.create());
     QVERIFY(rect != 0);
 
-    QSGItemPrivate::get(rect)->setState("overridden");
+    QQuickItemPrivate::get(rect)->setState("overridden");
     rect->doSomething();
 }
 
@@ -509,12 +509,12 @@ void tst_qdeclarativestates::signalOverrideCrash2()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("signalOverrideCrash2.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
 
-    QSGItemPrivate::get(rect)->setState("state1");
-    QSGItemPrivate::get(rect)->setState("state2");
-    QSGItemPrivate::get(rect)->setState("state1");
+    QQuickItemPrivate::get(rect)->setState("state1");
+    QQuickItemPrivate::get(rect)->setState("state2");
+    QQuickItemPrivate::get(rect)->setState("state1");
 
     delete rect;
 }
@@ -525,10 +525,10 @@ void tst_qdeclarativestates::parentChange()
 
     {
         QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange1.qml"));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
         QVERIFY(rect != 0);
 
-        QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"));
+        QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
         QVERIFY(innerRect != 0);
 
         QDeclarativeListReference list(rect, "states");
@@ -536,14 +536,14 @@ void tst_qdeclarativestates::parentChange()
         QVERIFY(state != 0);
 
         qmlExecuteDeferred(state);
-        QSGParentChange *pChange = qobject_cast<QSGParentChange*>(state->operationAt(0));
+        QQuickParentChange *pChange = qobject_cast<QQuickParentChange*>(state->operationAt(0));
         QVERIFY(pChange != 0);
-        QSGItem *nParent = qobject_cast<QSGItem*>(rect->findChild<QSGItem*>("NewParent"));
+        QQuickItem *nParent = qobject_cast<QQuickItem*>(rect->findChild<QQuickItem*>("NewParent"));
         QVERIFY(nParent != 0);
 
         QCOMPARE(pChange->parent(), nParent);
 
-        QSGItemPrivate::get(rect)->setState("reparented");
+        QQuickItemPrivate::get(rect)->setState("reparented");
         QCOMPARE(innerRect->rotation(), qreal(0));
         QCOMPARE(innerRect->scale(), qreal(1));
         QCOMPARE(innerRect->x(), qreal(-133));
@@ -552,10 +552,10 @@ void tst_qdeclarativestates::parentChange()
 
     {
         QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange2.qml"));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
         QVERIFY(rect != 0);
-        QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
-        QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"));
+        QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+        QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
         QVERIFY(innerRect != 0);
 
         rectPrivate->setState("reparented");
@@ -567,10 +567,10 @@ void tst_qdeclarativestates::parentChange()
 
     {
         QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange3.qml"));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
         QVERIFY(rect != 0);
-        QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
-        QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"));
+        QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+        QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
         QVERIFY(innerRect != 0);
 
         rectPrivate->setState("reparented");
@@ -589,13 +589,13 @@ void tst_qdeclarativestates::parentChange()
 
     {
         QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange6.qml"));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
         QVERIFY(rect != 0);
 
-        QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"));
+        QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
         QVERIFY(innerRect != 0);
 
-        QSGItemPrivate::get(rect)->setState("reparented");
+        QQuickItemPrivate::get(rect)->setState("reparented");
         QCOMPARE(innerRect->rotation(), qreal(180));
         QCOMPARE(innerRect->scale(), qreal(1));
         QCOMPARE(innerRect->x(), qreal(-105));
@@ -609,14 +609,14 @@ void tst_qdeclarativestates::parentChangeErrors()
 
     {
         QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange4.qml"));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
         QVERIFY(rect != 0);
 
-        QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"));
+        QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
         QVERIFY(innerRect != 0);
 
         QTest::ignoreMessage(QtWarningMsg, fullDataPath("parentChange4.qml") + ":25:9: QML ParentChange: Unable to preserve appearance under non-uniform scale");
-        QSGItemPrivate::get(rect)->setState("reparented");
+        QQuickItemPrivate::get(rect)->setState("reparented");
         QCOMPARE(innerRect->rotation(), qreal(0));
         QCOMPARE(innerRect->scale(), qreal(1));
         QCOMPARE(innerRect->x(), qreal(5));
@@ -625,14 +625,14 @@ void tst_qdeclarativestates::parentChangeErrors()
 
     {
         QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange5.qml"));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
         QVERIFY(rect != 0);
 
-        QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"));
+        QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
         QVERIFY(innerRect != 0);
 
         QTest::ignoreMessage(QtWarningMsg, fullDataPath("parentChange5.qml") + ":25:9: QML ParentChange: Unable to preserve appearance under complex transform");
-        QSGItemPrivate::get(rect)->setState("reparented");
+        QQuickItemPrivate::get(rect)->setState("reparented");
         QCOMPARE(innerRect->rotation(), qreal(0));
         QCOMPARE(innerRect->scale(), qreal(1));
         QCOMPARE(innerRect->x(), qreal(5));
@@ -645,11 +645,11 @@ void tst_qdeclarativestates::anchorChanges()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges1.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
 
-    QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"));
+    QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
     QVERIFY(innerRect != 0);
 
     QDeclarativeListReference list(rect, "states");
@@ -657,15 +657,15 @@ void tst_qdeclarativestates::anchorChanges()
     QVERIFY(state != 0);
 
     qmlExecuteDeferred(state);
-    QSGAnchorChanges *aChanges = qobject_cast<QSGAnchorChanges*>(state->operationAt(0));
+    QQuickAnchorChanges *aChanges = qobject_cast<QQuickAnchorChanges*>(state->operationAt(0));
     QVERIFY(aChanges != 0);
 
     rectPrivate->setState("right");
     QCOMPARE(innerRect->x(), qreal(150));
-    QCOMPARE(aChanges->object(), qobject_cast<QSGItem*>(innerRect));
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QSGAnchorLine::Invalid);  //### was reset (how do we distinguish from not set at all)
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine);
+    QCOMPARE(aChanges->object(), qobject_cast<QQuickItem*>(innerRect));
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QQuickAnchorLine::Invalid);  //### was reset (how do we distinguish from not set at all)
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine);
 
     rectPrivate->setState("");
     QCOMPARE(innerRect->x(), qreal(5));
@@ -678,11 +678,11 @@ void tst_qdeclarativestates::anchorChanges2()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges2.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
 
-    QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"));
+    QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
     QVERIFY(innerRect != 0);
 
     rectPrivate->setState("right");
@@ -699,17 +699,17 @@ void tst_qdeclarativestates::anchorChanges3()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges3.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
 
-    QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"));
+    QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
     QVERIFY(innerRect != 0);
 
-    QSGItem *leftGuideline = qobject_cast<QSGItem*>(rect->findChild<QSGItem*>("LeftGuideline"));
+    QQuickItem *leftGuideline = qobject_cast<QQuickItem*>(rect->findChild<QQuickItem*>("LeftGuideline"));
     QVERIFY(leftGuideline != 0);
 
-    QSGItem *bottomGuideline = qobject_cast<QSGItem*>(rect->findChild<QSGItem*>("BottomGuideline"));
+    QQuickItem *bottomGuideline = qobject_cast<QQuickItem*>(rect->findChild<QQuickItem*>("BottomGuideline"));
     QVERIFY(bottomGuideline != 0);
 
     QDeclarativeListReference list(rect, "states");
@@ -717,19 +717,19 @@ void tst_qdeclarativestates::anchorChanges3()
     QVERIFY(state != 0);
 
     qmlExecuteDeferred(state);
-    QSGAnchorChanges *aChanges = qobject_cast<QSGAnchorChanges*>(state->operationAt(0));
+    QQuickAnchorChanges *aChanges = qobject_cast<QQuickAnchorChanges*>(state->operationAt(0));
     QVERIFY(aChanges != 0);
 
     rectPrivate->setState("reanchored");
-    QCOMPARE(aChanges->object(), qobject_cast<QSGItem*>(innerRect));
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->left().item, QSGItemPrivate::get(leftGuideline)->left().item);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QSGItemPrivate::get(leftGuideline)->left().anchorLine);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->top().item, rectPrivate->top().item);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->top().anchorLine, rectPrivate->top().anchorLine);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->bottom().item, QSGItemPrivate::get(bottomGuideline)->bottom().item);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->bottom().anchorLine, QSGItemPrivate::get(bottomGuideline)->bottom().anchorLine);
+    QCOMPARE(aChanges->object(), qobject_cast<QQuickItem*>(innerRect));
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().item, QQuickItemPrivate::get(leftGuideline)->left().item);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QQuickItemPrivate::get(leftGuideline)->left().anchorLine);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->top().item, rectPrivate->top().item);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->top().anchorLine, rectPrivate->top().anchorLine);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->bottom().item, QQuickItemPrivate::get(bottomGuideline)->bottom().item);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->bottom().anchorLine, QQuickItemPrivate::get(bottomGuideline)->bottom().anchorLine);
 
     QCOMPARE(innerRect->x(), qreal(10));
     QCOMPARE(innerRect->y(), qreal(0));
@@ -750,16 +750,16 @@ void tst_qdeclarativestates::anchorChanges4()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges4.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
 
-    QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"));
+    QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
     QVERIFY(innerRect != 0);
 
-    QSGItem *leftGuideline = qobject_cast<QSGItem*>(rect->findChild<QSGItem*>("LeftGuideline"));
+    QQuickItem *leftGuideline = qobject_cast<QQuickItem*>(rect->findChild<QQuickItem*>("LeftGuideline"));
     QVERIFY(leftGuideline != 0);
 
-    QSGItem *bottomGuideline = qobject_cast<QSGItem*>(rect->findChild<QSGItem*>("BottomGuideline"));
+    QQuickItem *bottomGuideline = qobject_cast<QQuickItem*>(rect->findChild<QQuickItem*>("BottomGuideline"));
     QVERIFY(bottomGuideline != 0);
 
     QDeclarativeListReference list(rect, "states");
@@ -767,15 +767,15 @@ void tst_qdeclarativestates::anchorChanges4()
     QVERIFY(state != 0);
 
     qmlExecuteDeferred(state);
-    QSGAnchorChanges *aChanges = qobject_cast<QSGAnchorChanges*>(state->operationAt(0));
+    QQuickAnchorChanges *aChanges = qobject_cast<QQuickAnchorChanges*>(state->operationAt(0));
     QVERIFY(aChanges != 0);
 
-    QSGItemPrivate::get(rect)->setState("reanchored");
-    QCOMPARE(aChanges->object(), qobject_cast<QSGItem*>(innerRect));
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->horizontalCenter().item, QSGItemPrivate::get(bottomGuideline)->horizontalCenter().item);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->horizontalCenter().anchorLine, QSGItemPrivate::get(bottomGuideline)->horizontalCenter().anchorLine);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->verticalCenter().item, QSGItemPrivate::get(leftGuideline)->verticalCenter().item);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->verticalCenter().anchorLine, QSGItemPrivate::get(leftGuideline)->verticalCenter().anchorLine);
+    QQuickItemPrivate::get(rect)->setState("reanchored");
+    QCOMPARE(aChanges->object(), qobject_cast<QQuickItem*>(innerRect));
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->horizontalCenter().item, QQuickItemPrivate::get(bottomGuideline)->horizontalCenter().item);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->horizontalCenter().anchorLine, QQuickItemPrivate::get(bottomGuideline)->horizontalCenter().anchorLine);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->verticalCenter().item, QQuickItemPrivate::get(leftGuideline)->verticalCenter().item);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->verticalCenter().anchorLine, QQuickItemPrivate::get(leftGuideline)->verticalCenter().anchorLine);
 
     delete rect;
 }
@@ -785,16 +785,16 @@ void tst_qdeclarativestates::anchorChanges5()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges5.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
 
-    QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"));
+    QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
     QVERIFY(innerRect != 0);
 
-    QSGItem *leftGuideline = qobject_cast<QSGItem*>(rect->findChild<QSGItem*>("LeftGuideline"));
+    QQuickItem *leftGuideline = qobject_cast<QQuickItem*>(rect->findChild<QQuickItem*>("LeftGuideline"));
     QVERIFY(leftGuideline != 0);
 
-    QSGItem *bottomGuideline = qobject_cast<QSGItem*>(rect->findChild<QSGItem*>("BottomGuideline"));
+    QQuickItem *bottomGuideline = qobject_cast<QQuickItem*>(rect->findChild<QQuickItem*>("BottomGuideline"));
     QVERIFY(bottomGuideline != 0);
 
     QDeclarativeListReference list(rect, "states");
@@ -802,11 +802,11 @@ void tst_qdeclarativestates::anchorChanges5()
     QVERIFY(state != 0);
 
     qmlExecuteDeferred(state);
-    QSGAnchorChanges *aChanges = qobject_cast<QSGAnchorChanges*>(state->operationAt(0));
+    QQuickAnchorChanges *aChanges = qobject_cast<QQuickAnchorChanges*>(state->operationAt(0));
     QVERIFY(aChanges != 0);
 
-    QSGItemPrivate::get(rect)->setState("reanchored");
-    QCOMPARE(aChanges->object(), qobject_cast<QSGItem*>(innerRect));
+    QQuickItemPrivate::get(rect)->setState("reanchored");
+    QCOMPARE(aChanges->object(), qobject_cast<QQuickItem*>(innerRect));
     //QCOMPARE(aChanges->anchors()->horizontalCenter().item, bottomGuideline->horizontalCenter().item);
     //QCOMPARE(aChanges->anchors()->horizontalCenter().anchorLine, bottomGuideline->horizontalCenter().anchorLine);
     //QCOMPARE(aChanges->anchors()->baseline().item, leftGuideline->baseline().item);
@@ -815,12 +815,12 @@ void tst_qdeclarativestates::anchorChanges5()
     delete rect;
 }
 
-void mirrorAnchors(QSGItem *item) {
-    QSGItemPrivate *itemPrivate = QSGItemPrivate::get(item);
+void mirrorAnchors(QQuickItem *item) {
+    QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
     itemPrivate->setLayoutMirror(true);
 }
 
-qreal offsetRTL(QSGItem *anchorItem, QSGItem *item) {
+qreal offsetRTL(QQuickItem *anchorItem, QQuickItem *item) {
     return anchorItem->width()+2*anchorItem->x()-item->width();
 }
 
@@ -829,11 +829,11 @@ void tst_qdeclarativestates::anchorChangesRTL()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges1.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
 
-    QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"));
+    QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
     QVERIFY(innerRect != 0);
     mirrorAnchors(innerRect);
 
@@ -842,15 +842,15 @@ void tst_qdeclarativestates::anchorChangesRTL()
     QVERIFY(state != 0);
 
     qmlExecuteDeferred(state);
-    QSGAnchorChanges *aChanges = qobject_cast<QSGAnchorChanges*>(state->operationAt(0));
+    QQuickAnchorChanges *aChanges = qobject_cast<QQuickAnchorChanges*>(state->operationAt(0));
     QVERIFY(aChanges != 0);
 
     rectPrivate->setState("right");
     QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(150));
-    QCOMPARE(aChanges->object(), qobject_cast<QSGItem*>(innerRect));
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QSGAnchorLine::Invalid);  //### was reset (how do we distinguish from not set at all)
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine);
+    QCOMPARE(aChanges->object(), qobject_cast<QQuickItem*>(innerRect));
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QQuickAnchorLine::Invalid);  //### was reset (how do we distinguish from not set at all)
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine);
 
     rectPrivate->setState("");
     QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) -qreal(5));
@@ -863,11 +863,11 @@ void tst_qdeclarativestates::anchorChangesRTL2()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges2.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
 
-    QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"));
+    QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
     QVERIFY(innerRect != 0);
     mirrorAnchors(innerRect);
 
@@ -885,18 +885,18 @@ void tst_qdeclarativestates::anchorChangesRTL3()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges3.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
 
-    QSGRectangle *innerRect = qobject_cast<QSGRectangle*>(rect->findChild<QSGRectangle*>("MyRect"));
+    QQuickRectangle *innerRect = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("MyRect"));
     QVERIFY(innerRect != 0);
     mirrorAnchors(innerRect);
 
-    QSGItem *leftGuideline = qobject_cast<QSGItem*>(rect->findChild<QSGItem*>("LeftGuideline"));
+    QQuickItem *leftGuideline = qobject_cast<QQuickItem*>(rect->findChild<QQuickItem*>("LeftGuideline"));
     QVERIFY(leftGuideline != 0);
 
-    QSGItem *bottomGuideline = qobject_cast<QSGItem*>(rect->findChild<QSGItem*>("BottomGuideline"));
+    QQuickItem *bottomGuideline = qobject_cast<QQuickItem*>(rect->findChild<QQuickItem*>("BottomGuideline"));
     QVERIFY(bottomGuideline != 0);
 
     QDeclarativeListReference list(rect, "states");
@@ -904,19 +904,19 @@ void tst_qdeclarativestates::anchorChangesRTL3()
     QVERIFY(state != 0);
 
     qmlExecuteDeferred(state);
-    QSGAnchorChanges *aChanges = qobject_cast<QSGAnchorChanges*>(state->operationAt(0));
+    QQuickAnchorChanges *aChanges = qobject_cast<QQuickAnchorChanges*>(state->operationAt(0));
     QVERIFY(aChanges != 0);
 
     rectPrivate->setState("reanchored");
-    QCOMPARE(aChanges->object(), qobject_cast<QSGItem*>(innerRect));
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->left().item, QSGItemPrivate::get(leftGuideline)->left().item);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QSGItemPrivate::get(leftGuideline)->left().anchorLine);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->top().item, rectPrivate->top().item);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->top().anchorLine, rectPrivate->top().anchorLine);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->bottom().item, QSGItemPrivate::get(bottomGuideline)->bottom().item);
-    QCOMPARE(QSGItemPrivate::get(aChanges->object())->anchors()->bottom().anchorLine, QSGItemPrivate::get(bottomGuideline)->bottom().anchorLine);
+    QCOMPARE(aChanges->object(), qobject_cast<QQuickItem*>(innerRect));
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().item, QQuickItemPrivate::get(leftGuideline)->left().item);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QQuickItemPrivate::get(leftGuideline)->left().anchorLine);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->top().item, rectPrivate->top().item);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->top().anchorLine, rectPrivate->top().anchorLine);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->bottom().item, QQuickItemPrivate::get(bottomGuideline)->bottom().item);
+    QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->bottom().anchorLine, QQuickItemPrivate::get(bottomGuideline)->bottom().anchorLine);
 
     QCOMPARE(innerRect->x(), offsetRTL(leftGuideline, innerRect) - qreal(10));
     QCOMPARE(innerRect->y(), qreal(0));
@@ -940,10 +940,10 @@ void tst_qdeclarativestates::anchorChangesCrash()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChangesCrash.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
 
-    QSGItemPrivate::get(rect)->setState("reanchored");
+    QQuickItemPrivate::get(rect)->setState("reanchored");
 
     delete rect;
 }
@@ -951,7 +951,7 @@ void tst_qdeclarativestates::anchorChangesCrash()
 // QTBUG-12273
 void tst_qdeclarativestates::anchorRewindBug()
 {
-    QSGView *view = new QSGView;
+    QQuickView *view = new QQuickView;
     view->setSource(QUrl::fromLocalFile(TESTDATA("anchorRewindBug.qml")));
 
     view->show();
@@ -959,29 +959,29 @@ void tst_qdeclarativestates::anchorRewindBug()
 
     QTest::qWaitForWindowShown(view);
 
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(view->rootObject());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(view->rootObject());
     QVERIFY(rect != 0);
 
-    QSGItem * column = rect->findChild<QSGItem*>("column");
+    QQuickItem * column = rect->findChild<QQuickItem*>("column");
 
     QVERIFY(column != 0);
-    QVERIFY(!QSGItemPrivate::get(column)->heightValid);
-    QVERIFY(!QSGItemPrivate::get(column)->widthValid);
+    QVERIFY(!QQuickItemPrivate::get(column)->heightValid);
+    QVERIFY(!QQuickItemPrivate::get(column)->widthValid);
     QCOMPARE(column->height(), 200.0);
-    QSGItemPrivate::get(rect)->setState("reanchored");
+    QQuickItemPrivate::get(rect)->setState("reanchored");
 
     // column height and width should stay implicit
     // and column's implicit resizing should still work
-    QVERIFY(!QSGItemPrivate::get(column)->heightValid);
-    QVERIFY(!QSGItemPrivate::get(column)->widthValid);
+    QVERIFY(!QQuickItemPrivate::get(column)->heightValid);
+    QVERIFY(!QQuickItemPrivate::get(column)->widthValid);
     QTRY_COMPARE(column->height(), 100.0);
 
-    QSGItemPrivate::get(rect)->setState("");
+    QQuickItemPrivate::get(rect)->setState("");
 
     // column height and width should stay implicit
     // and column's implicit resizing should still work
-    QVERIFY(!QSGItemPrivate::get(column)->heightValid);
-    QVERIFY(!QSGItemPrivate::get(column)->widthValid);
+    QVERIFY(!QQuickItemPrivate::get(column)->heightValid);
+    QVERIFY(!QQuickItemPrivate::get(column)->widthValid);
     QTRY_COMPARE(column->height(), 200.0);
 
     delete view;
@@ -993,20 +993,20 @@ void tst_qdeclarativestates::anchorRewindBug2()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorRewindBug2.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
 
-    QSGRectangle *mover = rect->findChild<QSGRectangle*>("mover");
+    QQuickRectangle *mover = rect->findChild<QQuickRectangle*>("mover");
 
     QVERIFY(mover != 0);
     QCOMPARE(mover->y(), qreal(0.0));
     QCOMPARE(mover->width(), qreal(50.0));
 
-    QSGItemPrivate::get(rect)->setState("anchored");
+    QQuickItemPrivate::get(rect)->setState("anchored");
     QCOMPARE(mover->y(), qreal(250.0));
     QCOMPARE(mover->width(), qreal(200.0));
 
-    QSGItemPrivate::get(rect)->setState("");
+    QQuickItemPrivate::get(rect)->setState("");
     QCOMPARE(mover->y(), qreal(0.0));
     QCOMPARE(mover->width(), qreal(50.0));
 
@@ -1019,9 +1019,9 @@ void tst_qdeclarativestates::script()
 
     {
         QDeclarativeComponent rectComponent(&engine, TESTDATA("script.qml"));
-        QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+        QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
         QVERIFY(rect != 0);
-        QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+        QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
         QCOMPARE(rect->color(),QColor("red"));
 
         rectPrivate->setState("blue");
@@ -1037,9 +1037,9 @@ void tst_qdeclarativestates::restoreEntryValues()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("restoreEntryValues.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
     QCOMPARE(rect->color(),QColor("red"));
 
     rectPrivate->setState("blue");
@@ -1054,9 +1054,9 @@ void tst_qdeclarativestates::explicitChanges()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("explicit.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
     QDeclarativeListReference list(rect, "states");
     QDeclarativeState *state = qobject_cast<QDeclarativeState*>(list.at(0));
     QVERIFY(state != 0);
@@ -1087,14 +1087,14 @@ void tst_qdeclarativestates::propertyErrors()
 {
     QDeclarativeEngine engine;
     QDeclarativeComponent rectComponent(&engine, TESTDATA("propertyErrors.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
 
     QCOMPARE(rect->color(),QColor("red"));
 
     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");
+    QQuickItemPrivate::get(rect)->setState("blue");
 }
 
 void tst_qdeclarativestates::incorrectRestoreBug()
@@ -1102,9 +1102,9 @@ void tst_qdeclarativestates::incorrectRestoreBug()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("basicChanges.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
     QCOMPARE(rect->color(),QColor("red"));
 
     rectPrivate->setState("blue");
@@ -1145,9 +1145,9 @@ void tst_qdeclarativestates::deletingChange()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("deleting.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
     rectPrivate->setState("blue");
     QCOMPARE(rect->color(),QColor("blue"));
     QCOMPARE(rect->radius(),qreal(5));
@@ -1177,7 +1177,7 @@ void tst_qdeclarativestates::deletingState()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("deletingState.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
 
     QDeclarativeStateGroup *sg = rect->findChild<QDeclarativeStateGroup*>();
@@ -1208,9 +1208,9 @@ void tst_qdeclarativestates::tempState()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("legalTempState.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
     QTest::ignoreMessage(QtDebugMsg, "entering placed");
     QTest::ignoreMessage(QtDebugMsg, "entering idle");
     rectPrivate->setState("placed");
@@ -1222,9 +1222,9 @@ void tst_qdeclarativestates::illegalTempState()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("illegalTempState.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
     QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML StateGroup: Can't apply a state change as part of a state definition.");
     rectPrivate->setState("placed");
     QCOMPARE(rectPrivate->state(), QLatin1String("placed"));
@@ -1235,9 +1235,9 @@ void tst_qdeclarativestates::nonExistantProperty()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent rectComponent(&engine, TESTDATA("nonExistantProp.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(rectComponent.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(rectComponent.create());
     QVERIFY(rect != 0);
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
     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"));
@@ -1248,15 +1248,15 @@ void tst_qdeclarativestates::reset()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent c(&engine, TESTDATA("reset.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
 
-    QSGImage *image = rect->findChild<QSGImage*>();
+    QQuickImage *image = rect->findChild<QQuickImage*>();
     QVERIFY(image != 0);
     QCOMPARE(image->width(), qreal(40.));
     QCOMPARE(image->height(), qreal(20.));
 
-    QSGItemPrivate::get(rect)->setState("state1");
+    QQuickItemPrivate::get(rect)->setState("state1");
 
     QCOMPARE(image->width(), 20.0);
     QCOMPARE(image->height(), qreal(20.));
@@ -1280,9 +1280,9 @@ void tst_qdeclarativestates::whenOrdering()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent c(&engine, TESTDATA("whenOrdering.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
 
     QCOMPARE(rectPrivate->state(), QLatin1String(""));
     rect->setProperty("condition2", true);
@@ -1303,16 +1303,16 @@ void tst_qdeclarativestates::urlResolution()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent c(&engine, TESTDATA("urlResolution.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
 
-    QSGItem *myType = rect->findChild<QSGItem*>("MyType");
-    QSGImage *image1 = rect->findChild<QSGImage*>("image1");
-    QSGImage *image2 = rect->findChild<QSGImage*>("image2");
-    QSGImage *image3 = rect->findChild<QSGImage*>("image3");
+    QQuickItem *myType = rect->findChild<QQuickItem*>("MyType");
+    QQuickImage *image1 = rect->findChild<QQuickImage*>("image1");
+    QQuickImage *image2 = rect->findChild<QQuickImage*>("image2");
+    QQuickImage *image3 = rect->findChild<QQuickImage*>("image3");
     QVERIFY(myType != 0 && image1 != 0 && image2 != 0 && image3 != 0);
 
-    QSGItemPrivate::get(myType)->setState("SetImageState");
+    QQuickItemPrivate::get(myType)->setState("SetImageState");
     QUrl resolved = QUrl::fromLocalFile(TESTDATA("Implementation/images/qt-logo.png"));
     QCOMPARE(image1->source(), resolved);
     QCOMPARE(image2->source(), resolved);
@@ -1324,9 +1324,9 @@ void tst_qdeclarativestates::unnamedWhen()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent c(&engine, TESTDATA("unnamedWhen.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
 
     QCOMPARE(rectPrivate->state(), QLatin1String(""));
     QCOMPARE(rect->property("stateString").toString(), QLatin1String(""));
@@ -1343,9 +1343,9 @@ void tst_qdeclarativestates::returnToBase()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent c(&engine, TESTDATA("returnToBase.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
 
     QCOMPARE(rectPrivate->state(), QLatin1String(""));
     QCOMPARE(rect->property("stateString").toString(), QLatin1String(""));
@@ -1363,10 +1363,10 @@ void tst_qdeclarativestates::extendsBug()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent c(&engine, TESTDATA("extendsBug.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
-    QSGRectangle *greenRect = rect->findChild<QSGRectangle*>("greenRect");
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+    QQuickRectangle *greenRect = rect->findChild<QQuickRectangle*>("greenRect");
 
     rectPrivate->setState("b");
     QCOMPARE(greenRect->x(), qreal(100));
@@ -1378,10 +1378,10 @@ void tst_qdeclarativestates::editProperties()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent c(&engine, TESTDATA("editProperties.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
 
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
 
     QDeclarativeStateGroup *stateGroup = rectPrivate->_states();
     QVERIFY(stateGroup != 0);
@@ -1401,7 +1401,7 @@ void tst_qdeclarativestates::editProperties()
     QDeclarativePropertyChanges *propertyChangesGreen = qobject_cast<QDeclarativePropertyChanges*>(greenState->operationAt(0));
     QVERIFY(propertyChangesGreen != 0);
 
-    QSGRectangle *childRect = rect->findChild<QSGRectangle*>("rect2");
+    QQuickRectangle *childRect = rect->findChild<QQuickRectangle*>("rect2");
     QVERIFY(childRect != 0);
     QCOMPARE(childRect->width(), qreal(402));
     QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width")));
@@ -1506,9 +1506,9 @@ void tst_qdeclarativestates::QTBUG_14830()
     QDeclarativeEngine engine;
 
     QDeclarativeComponent c(&engine, TESTDATA("QTBUG-14830.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
-    QSGItem *item = rect->findChild<QSGItem*>("area");
+    QQuickItem *item = rect->findChild<QQuickItem*>("area");
 
     QCOMPARE(item->width(), qreal(171));
 }
@@ -1519,10 +1519,10 @@ void tst_qdeclarativestates::avoidFastForward()
 
     //shouldn't fast forward if there isn't a transition
     QDeclarativeComponent c(&engine, TESTDATA("avoidFastForward.qml"));
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(c.create());
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
     QVERIFY(rect != 0);
 
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
     rectPrivate->setState("a");
     QCOMPARE(rect->property("updateCount").toInt(), 1);
 }
index d6cf8c0..1e79509 100644 (file)
@@ -43,7 +43,7 @@
 #include <QtDeclarative/qdeclarativeengine.h>
 #include <QtDeclarative/qdeclarativecomponent.h>
 #include <private/qdeclarativetimer_p.h>
-#include <QtDeclarative/qsgitem.h>
+#include <QtDeclarative/qquickitem.h>
 #include <QDebug>
 
 class tst_qdeclarativetimer : public QObject
@@ -319,7 +319,7 @@ void tst_qdeclarativetimer::parentProperty()
     QDeclarativeEngine engine;
     QDeclarativeComponent component(&engine);
     component.setData(QByteArray("import QtQuick 2.0\nItem { Timer { objectName: \"timer\"; running: parent.visible } }"), QUrl::fromLocalFile(""));
-    QSGItem *item = qobject_cast<QSGItem*>(component.create());
+    QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
     QVERIFY(item != 0);
     QDeclarativeTimer *timer = item->findChild<QDeclarativeTimer*>("timer");
     QVERIFY(timer != 0);
index 7c33670..38de65f 100644 (file)
@@ -44,7 +44,6 @@
 #include <QDir>
 #include <QProcess>
 #include <QDebug>
-#include <QSGView>
 #include <QDeclarativeError>
 #include <cstdlib>
 
@@ -95,7 +94,7 @@ void tst_qmlmin::initTestCase()
     excludedDirs << "doc/src/snippets/qtquick1/imports";
 
     // Add invalid files (i.e. files with syntax errors)
-    invalidFiles << "tests/auto/declarative/qsgloader/data/InvalidSourceComponent.qml";
+    invalidFiles << "tests/auto/declarative/qquickloader/data/InvalidSourceComponent.qml";
     invalidFiles << "tests/auto/declarative/qdeclarativelanguage/data/dynamicObjectProperties.2.qml";
     invalidFiles << "tests/auto/declarative/qdeclarativelanguage/data/signal.3.qml";
     invalidFiles << "tests/auto/declarative/qdeclarativelanguage/data/property.4.qml";
diff --git a/tests/auto/declarative/qquickanimatedimage/qquickanimatedimage.pro b/tests/auto/declarative/qquickanimatedimage/qquickanimatedimage.pro
new file mode 100644 (file)
index 0000000..d6a40e1
--- /dev/null
@@ -0,0 +1,13 @@
+CONFIG += testcase
+TARGET = tst_qquickanimatedimage
+HEADERS += ../shared/testhttpserver.h
+SOURCES += tst_qquickanimatedimage.cpp ../shared/testhttpserver.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qquickanimatedimage/tst_qquickanimatedimage.cpp b/tests/auto/declarative/qquickanimatedimage/tst_qquickanimatedimage.cpp
new file mode 100644 (file)
index 0000000..c9394ef
--- /dev/null
@@ -0,0 +1,375 @@
+/****************************************************************************
+**
+** 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/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qquickview.h>
+#include <private/qquickrectangle_p.h>
+#include <private/qquickimage_p.h>
+#include <private/qquickanimatedimage_p.h>
+#include <QSignalSpy>
+#include <QtDeclarative/qdeclarativecontext.h>
+
+#include "../shared/testhttpserver.h"
+#include "../shared/util.h"
+
+class tst_qquickanimatedimage : public QObject
+{
+    Q_OBJECT
+public:
+    tst_qquickanimatedimage() {}
+
+private slots:
+    void play();
+    void pause();
+    void stopped();
+    void setFrame();
+    void frameCount();
+    void mirror_running();
+    void mirror_notRunning();
+    void mirror_notRunning_data();
+    void remote();
+    void remote_data();
+    void sourceSize();
+    void sourceSizeReadOnly();
+    void invalidSource();
+    void qtbug_16520();
+    void progressAndStatusChanges();
+
+};
+
+void tst_qquickanimatedimage::play()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickman.qml")));
+    QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
+    QVERIFY(anim);
+    QVERIFY(anim->isPlaying());
+
+    delete anim;
+}
+
+void tst_qquickanimatedimage::pause()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanpause.qml")));
+    QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
+    QVERIFY(anim);
+    QVERIFY(anim->isPlaying());
+    QVERIFY(anim->isPaused());
+
+    delete anim;
+}
+
+void tst_qquickanimatedimage::stopped()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanstopped.qml")));
+    QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
+    QVERIFY(anim);
+    QVERIFY(!anim->isPlaying());
+    QCOMPARE(anim->currentFrame(), 0);
+
+    delete anim;
+}
+
+void tst_qquickanimatedimage::setFrame()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanpause.qml")));
+    QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
+    QVERIFY(anim);
+    QVERIFY(anim->isPlaying());
+    QCOMPARE(anim->currentFrame(), 2);
+
+    delete anim;
+}
+
+void tst_qquickanimatedimage::frameCount()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("colors.qml")));
+    QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
+    QVERIFY(anim);
+    QVERIFY(anim->isPlaying());
+    QCOMPARE(anim->frameCount(), 3);
+
+    delete anim;
+}
+
+void tst_qquickanimatedimage::mirror_running()
+{
+    // test where mirror is set to true after animation has started
+
+    QQuickView *canvas = new QQuickView;
+    canvas->show();
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("hearts.qml")));
+    QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(canvas->rootObject());
+    QVERIFY(anim);
+
+    int width = anim->property("width").toInt();
+
+    QCOMPARE(anim->currentFrame(), 0);
+    QPixmap frame0 = QPixmap::fromImage(canvas->grabFrameBuffer());
+
+    anim->setCurrentFrame(1);
+    QPixmap frame1 = QPixmap::fromImage(canvas->grabFrameBuffer());
+
+    anim->setCurrentFrame(0);
+
+    QSignalSpy spy(anim, SIGNAL(frameChanged()));
+    anim->setPlaying(true);
+
+    QTRY_VERIFY(spy.count() == 1); spy.clear();
+    anim->setProperty("mirror", true);
+
+    QCOMPARE(anim->currentFrame(), 1);
+    QPixmap frame1_flipped = QPixmap::fromImage(canvas->grabFrameBuffer());
+
+    QTRY_VERIFY(spy.count() == 1); spy.clear();
+    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");
+
+    QTransform transform;
+    transform.translate(width, 0).scale(-1, 1.0);
+    QPixmap frame0_expected = frame0.transformed(transform);
+    QPixmap frame1_expected = frame1.transformed(transform);
+
+    QCOMPARE(frame0_flipped, frame0_expected);
+    QCOMPARE(frame1_flipped, frame1_expected);
+
+    delete canvas;
+}
+
+void tst_qquickanimatedimage::mirror_notRunning()
+{
+    QFETCH(QUrl, fileUrl);
+
+    QQuickView *canvas = new QQuickView;
+    canvas->show();
+
+    canvas->setSource(fileUrl);
+    QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(canvas->rootObject());
+    QVERIFY(anim);
+
+    int width = anim->property("width").toInt();
+    QPixmap screenshot = QPixmap::fromImage(canvas->grabFrameBuffer());
+
+    QTransform transform;
+    transform.translate(width, 0).scale(-1, 1.0);
+    QPixmap expected = screenshot.transformed(transform);
+
+    int frame = anim->currentFrame();
+    bool playing = anim->isPlaying();
+    bool paused = anim->isPlaying();
+
+    anim->setProperty("mirror", true);
+    screenshot = QPixmap::fromImage(canvas->grabFrameBuffer());
+
+    QSKIP("Skip while QTBUG-19351 and QTBUG-19252 are not resolved");
+    QCOMPARE(screenshot, expected);
+
+    // mirroring should not change the current frame or playing status
+    QCOMPARE(anim->currentFrame(), frame);
+    QCOMPARE(anim->isPlaying(), playing);
+    QCOMPARE(anim->isPaused(), paused);
+
+    delete canvas;
+}
+
+void tst_qquickanimatedimage::mirror_notRunning_data()
+{
+    QTest::addColumn<QUrl>("fileUrl");
+
+    QTest::newRow("paused") << QUrl::fromLocalFile(TESTDATA("stickmanpause.qml"));
+    QTest::newRow("stopped") << QUrl::fromLocalFile(TESTDATA("stickmanstopped.qml"));
+}
+
+void tst_qquickanimatedimage::remote()
+{
+    QFETCH(QString, fileName);
+    QFETCH(bool, paused);
+
+    TestHTTPServer server(14449);
+    QVERIFY(server.isValid());
+    server.serveDirectory(TESTDATA(""));
+
+    QDeclarativeEngine engine;
+    QDeclarativeComponent component(&engine, QUrl("http://127.0.0.1:14449/" + fileName));
+    QTRY_VERIFY(component.isReady());
+
+    QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
+    QVERIFY(anim);
+
+    QTRY_VERIFY(anim->isPlaying());
+    if (paused) {
+        QTRY_VERIFY(anim->isPaused());
+        QCOMPARE(anim->currentFrame(), 2);
+    }
+    QVERIFY(anim->status() != QQuickAnimatedImage::Error);
+
+    delete anim;
+}
+
+void tst_qquickanimatedimage::sourceSize()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanscaled.qml")));
+    QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
+    QVERIFY(anim);
+    QCOMPARE(anim->width(),240.0);
+    QCOMPARE(anim->height(),180.0);
+    QCOMPARE(anim->sourceSize(),QSize(160,120));
+
+    delete anim;
+}
+
+void tst_qquickanimatedimage::sourceSizeReadOnly()
+{
+    QDeclarativeEngine engine;
+    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"));
+}
+
+void tst_qquickanimatedimage::remote_data()
+{
+    QTest::addColumn<QString>("fileName");
+    QTest::addColumn<bool>("paused");
+
+    QTest::newRow("playing") << "stickman.qml" << false;
+    QTest::newRow("paused") << "stickmanpause.qml" << true;
+}
+
+void tst_qquickanimatedimage::invalidSource()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent component(&engine);
+    component.setData("import QtQuick 2.0\n AnimatedImage { source: \"no-such-file.gif\" }", QUrl::fromLocalFile(""));
+    QVERIFY(component.isReady());
+
+    QTest::ignoreMessage(QtWarningMsg, "file::2:2: QML AnimatedImage: Error Reading Animated Image File file:no-such-file.gif");
+
+    QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
+    QVERIFY(anim);
+
+    QVERIFY(!anim->isPlaying());
+    QVERIFY(!anim->isPaused());
+    QCOMPARE(anim->currentFrame(), 0);
+    QCOMPARE(anim->frameCount(), 0);
+    QTRY_VERIFY(anim->status() == 3);
+}
+
+void tst_qquickanimatedimage::qtbug_16520()
+{
+    TestHTTPServer server(14449);
+    QVERIFY(server.isValid());
+    server.serveDirectory(TESTDATA(""));
+
+    QDeclarativeEngine engine;
+    QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("qtbug-16520.qml")));
+    QTRY_VERIFY(component.isReady());
+
+    QQuickRectangle *root = qobject_cast<QQuickRectangle *>(component.create());
+    QVERIFY(root);
+    QQuickAnimatedImage *anim = root->findChild<QQuickAnimatedImage*>("anim");
+
+    anim->setProperty("source", "http://127.0.0.1:14449/stickman.gif");
+
+    QTRY_VERIFY(anim->opacity() == 0);
+    QTRY_VERIFY(anim->opacity() == 1);
+
+    delete anim;
+}
+
+void tst_qquickanimatedimage::progressAndStatusChanges()
+{
+    TestHTTPServer server(14449);
+    QVERIFY(server.isValid());
+    server.serveDirectory(TESTDATA(""));
+
+    QDeclarativeEngine engine;
+    QString componentStr = "import QtQuick 2.0\nAnimatedImage { source: srcImage }";
+    QDeclarativeContext *ctxt = engine.rootContext();
+    ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("stickman.gif")));
+    QDeclarativeComponent component(&engine);
+    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
+    QVERIFY(obj != 0);
+    QVERIFY(obj->status() == QQuickImage::Ready);
+    QTRY_VERIFY(obj->progress() == 1.0);
+
+    QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(const QUrl &)));
+    QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal)));
+    QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QQuickImageBase::Status)));
+
+    // Loading local file
+    ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("colors.gif")));
+    QTRY_VERIFY(obj->status() == QQuickImage::Ready);
+    QTRY_VERIFY(obj->progress() == 1.0);
+    QTRY_COMPARE(sourceSpy.count(), 1);
+    QTRY_COMPARE(progressSpy.count(), 0);
+    QTRY_COMPARE(statusSpy.count(), 0);
+
+    // Loading remote file
+    ctxt->setContextProperty("srcImage", "http://127.0.0.1:14449/stickman.gif");
+    QTRY_VERIFY(obj->status() == QQuickImage::Loading);
+    QTRY_VERIFY(obj->progress() == 0.0);
+    QTRY_VERIFY(obj->status() == QQuickImage::Ready);
+    QTRY_VERIFY(obj->progress() == 1.0);
+    QTRY_COMPARE(sourceSpy.count(), 2);
+    QTRY_VERIFY(progressSpy.count() > 1);
+    QTRY_COMPARE(statusSpy.count(), 2);
+
+    ctxt->setContextProperty("srcImage", "");
+    QTRY_VERIFY(obj->status() == QQuickImage::Null);
+    QTRY_VERIFY(obj->progress() == 0.0);
+    QTRY_COMPARE(sourceSpy.count(), 3);
+    QTRY_VERIFY(progressSpy.count() > 2);
+    QTRY_COMPARE(statusSpy.count(), 3);
+}
+
+QTEST_MAIN(tst_qquickanimatedimage)
+
+#include "tst_qquickanimatedimage.moc"
diff --git a/tests/auto/declarative/qquickborderimage/qquickborderimage.pro b/tests/auto/declarative/qquickborderimage/qquickborderimage.pro
new file mode 100644 (file)
index 0000000..b1ccf4a
--- /dev/null
@@ -0,0 +1,14 @@
+CONFIG += testcase
+TARGET = tst_qquickborderimage
+macx:CONFIG -= app_bundle
+
+HEADERS += ../shared/testhttpserver.h
+SOURCES += tst_qquickborderimage.cpp ../shared/testhttpserver.cpp
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+
+QT += core-private gui-private declarative-private network widgets testlib
diff --git a/tests/auto/declarative/qquickborderimage/tst_qquickborderimage.cpp b/tests/auto/declarative/qquickborderimage/tst_qquickborderimage.cpp
new file mode 100644 (file)
index 0000000..4fb6ed7
--- /dev/null
@@ -0,0 +1,376 @@
+/****************************************************************************
+**
+** 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 <QTextDocument>
+#include <QTcpServer>
+#include <QTcpSocket>
+#include <QDir>
+#include <QGraphicsScene>
+#include <QPainter>
+
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <private/qquickborderimage_p.h>
+#include <private/qquickimagebase_p.h>
+#include <private/qquickscalegrid_p_p.h>
+#include <private/qquickloader_p.h>
+#include <QtDeclarative/qquickview.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+
+#include "../shared/testhttpserver.h"
+#include "../shared/util.h"
+
+#define SERVER_PORT 14446
+#define SERVER_ADDR "http://127.0.0.1:14446"
+
+class tst_qquickborderimage : public QObject
+
+{
+    Q_OBJECT
+public:
+    tst_qquickborderimage();
+
+private slots:
+    void noSource();
+    void imageSource();
+    void imageSource_data();
+    void clearSource();
+    void resized();
+    void smooth();
+    void mirror();
+    void tileModes();
+    void sciSource();
+    void sciSource_data();
+    void invalidSciFile();
+    void pendingRemoteRequest();
+    void pendingRemoteRequest_data();
+
+private:
+    QDeclarativeEngine engine;
+};
+
+tst_qquickborderimage::tst_qquickborderimage()
+{
+}
+
+void tst_qquickborderimage::noSource()
+{
+    QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"\" }";
+    QDeclarativeComponent component(&engine);
+    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickBorderImage *obj = qobject_cast<QQuickBorderImage*>(component.create());
+    QVERIFY(obj != 0);
+    QCOMPARE(obj->source(), QUrl());
+    QCOMPARE(obj->width(), 0.);
+    QCOMPARE(obj->height(), 0.);
+    QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Stretch);
+    QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Stretch);
+
+    delete obj;
+}
+
+void tst_qquickborderimage::imageSource_data()
+{
+    QTest::addColumn<QString>("source");
+    QTest::addColumn<bool>("remote");
+    QTest::addColumn<QString>("error");
+
+    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";
+}
+
+void tst_qquickborderimage::imageSource()
+{
+    QFETCH(QString, source);
+    QFETCH(bool, remote);
+    QFETCH(QString, error);
+
+    TestHTTPServer *server = 0;
+    if (remote) {
+        server = new TestHTTPServer(SERVER_PORT);
+        QVERIFY(server->isValid());
+        server->serveDirectory(TESTDATA(""));
+    }
+
+    if (!error.isEmpty())
+        QTest::ignoreMessage(QtWarningMsg, error.toUtf8());
+
+    QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + source + "\" }";
+    QDeclarativeComponent component(&engine);
+    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickBorderImage *obj = qobject_cast<QQuickBorderImage*>(component.create());
+    QVERIFY(obj != 0);
+
+    if (remote)
+        QTRY_VERIFY(obj->status() == QQuickBorderImage::Loading);
+
+    QCOMPARE(obj->source(), remote ? source : QUrl(source));
+
+    if (error.isEmpty()) {
+        QTRY_VERIFY(obj->status() == QQuickBorderImage::Ready);
+        QCOMPARE(obj->width(), 120.);
+        QCOMPARE(obj->height(), 120.);
+        QCOMPARE(obj->sourceSize().width(), 120);
+        QCOMPARE(obj->sourceSize().height(), 120);
+        QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Stretch);
+        QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Stretch);
+    } else {
+        QTRY_VERIFY(obj->status() == QQuickBorderImage::Error);
+    }
+
+    delete obj;
+    delete server;
+}
+
+void tst_qquickborderimage::clearSource()
+{
+    QString componentStr = "import QtQuick 2.0\nBorderImage { source: srcImage }";
+    QDeclarativeContext *ctxt = engine.rootContext();
+    ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("colors.png")));
+    QDeclarativeComponent component(&engine);
+    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickBorderImage *obj = qobject_cast<QQuickBorderImage*>(component.create());
+    QVERIFY(obj != 0);
+    QVERIFY(obj->status() == QQuickBorderImage::Ready);
+    QCOMPARE(obj->width(), 120.);
+    QCOMPARE(obj->height(), 120.);
+
+    ctxt->setContextProperty("srcImage", "");
+    QVERIFY(obj->source().isEmpty());
+    QVERIFY(obj->status() == QQuickBorderImage::Null);
+    QCOMPARE(obj->width(), 0.);
+    QCOMPARE(obj->height(), 0.);
+}
+
+void tst_qquickborderimage::resized()
+{
+    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(""));
+    QQuickBorderImage *obj = qobject_cast<QQuickBorderImage*>(component.create());
+    QVERIFY(obj != 0);
+    QCOMPARE(obj->width(), 300.);
+    QCOMPARE(obj->height(), 300.);
+    QCOMPARE(obj->sourceSize().width(), 120);
+    QCOMPARE(obj->sourceSize().height(), 120);
+    QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Stretch);
+    QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Stretch);
+
+    delete obj;
+}
+
+void tst_qquickborderimage::smooth()
+{
+    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(""));
+    QQuickBorderImage *obj = qobject_cast<QQuickBorderImage*>(component.create());
+    QVERIFY(obj != 0);
+    QCOMPARE(obj->width(), 300.);
+    QCOMPARE(obj->height(), 300.);
+    QCOMPARE(obj->smooth(), true);
+    QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Stretch);
+    QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Stretch);
+
+    delete obj;
+}
+
+void tst_qquickborderimage::mirror()
+{
+    QQuickView *canvas = new QQuickView;
+    canvas->show();
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("mirror.qml")));
+    QQuickBorderImage *image = qobject_cast<QQuickBorderImage*>(canvas->rootObject());
+    QVERIFY(image != 0);
+    canvas->show();
+
+    QImage screenshot = canvas->grabFrameBuffer();
+
+    QImage srcPixmap(screenshot);
+    QTransform transform;
+    transform.translate(image->width(), 0).scale(-1, 1.0);
+    srcPixmap = srcPixmap.transformed(transform);
+
+    image->setProperty("mirror", true);
+    screenshot = canvas->grabFrameBuffer();
+    QCOMPARE(screenshot, srcPixmap);
+
+    delete canvas;
+}
+
+void tst_qquickborderimage::tileModes()
+{
+    {
+        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(""));
+        QQuickBorderImage *obj = qobject_cast<QQuickBorderImage*>(component.create());
+        QVERIFY(obj != 0);
+        QCOMPARE(obj->width(), 100.);
+        QCOMPARE(obj->height(), 300.);
+        QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Repeat);
+        QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Repeat);
+
+        delete obj;
+    }
+    {
+        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(""));
+        QQuickBorderImage *obj = qobject_cast<QQuickBorderImage*>(component.create());
+        QVERIFY(obj != 0);
+        QCOMPARE(obj->width(), 300.);
+        QCOMPARE(obj->height(), 150.);
+        QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Round);
+        QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Round);
+
+        delete obj;
+    }
+}
+
+void tst_qquickborderimage::sciSource()
+{
+    QFETCH(QString, source);
+    QFETCH(bool, valid);
+
+    bool remote = source.startsWith("http");
+    TestHTTPServer *server = 0;
+    if (remote) {
+        server = new TestHTTPServer(SERVER_PORT);
+        QVERIFY(server->isValid());
+        server->serveDirectory(TESTDATA(""));
+    }
+
+    QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + source + "\"; width: 300; height: 300 }";
+    QDeclarativeComponent component(&engine);
+    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickBorderImage *obj = qobject_cast<QQuickBorderImage*>(component.create());
+    QVERIFY(obj != 0);
+
+    if (remote)
+        QTRY_VERIFY(obj->status() == QQuickBorderImage::Loading);
+
+    QCOMPARE(obj->source(), remote ? source : QUrl(source));
+    QCOMPARE(obj->width(), 300.);
+    QCOMPARE(obj->height(), 300.);
+
+    if (valid) {
+        QTRY_VERIFY(obj->status() == QQuickBorderImage::Ready);
+        QCOMPARE(obj->border()->left(), 10);
+        QCOMPARE(obj->border()->top(), 20);
+        QCOMPARE(obj->border()->right(), 30);
+        QCOMPARE(obj->border()->bottom(), 40);
+        QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Round);
+        QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Repeat);
+    } else {
+        QTRY_VERIFY(obj->status() == QQuickBorderImage::Error);
+    }
+
+    delete obj;
+    delete server;
+}
+
+void tst_qquickborderimage::sciSource_data()
+{
+    QTest::addColumn<QString>("source");
+    QTest::addColumn<bool>("valid");
+
+    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;
+    QTest::newRow("remote not found") << SERVER_ADDR "/no-such-file.sci" << false;
+}
+
+void tst_qquickborderimage::invalidSciFile()
+{
+    QTest::ignoreMessage(QtWarningMsg, "QQuickGridScaledImage: Invalid tile rule specified. Using Stretch."); // for "Roun"
+    QTest::ignoreMessage(QtWarningMsg, "QQuickGridScaledImage: Invalid tile rule specified. Using Stretch."); // for "Repea"
+
+    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(""));
+    QQuickBorderImage *obj = qobject_cast<QQuickBorderImage*>(component.create());
+    QVERIFY(obj != 0);
+    QCOMPARE(obj->width(), 300.);
+    QCOMPARE(obj->height(), 300.);
+    QCOMPARE(obj->status(), QQuickImageBase::Error);
+    QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Stretch);
+    QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Stretch);
+
+    delete obj;
+}
+
+void tst_qquickborderimage::pendingRemoteRequest()
+{
+    QFETCH(QString, source);
+
+    QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + source + "\" }";
+    QDeclarativeComponent component(&engine);
+    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickBorderImage *obj = qobject_cast<QQuickBorderImage*>(component.create());
+    QVERIFY(obj != 0);
+    QCOMPARE(obj->status(), QQuickBorderImage::Loading);
+
+    // verify no crash
+    // This will cause a delayed "QThread: Destroyed while thread is still running" warning
+    delete obj;
+    QTest::qWait(50);
+}
+
+void tst_qquickborderimage::pendingRemoteRequest_data()
+{
+    QTest::addColumn<QString>("source");
+
+    QTest::newRow("png file") << "http://localhost/none.png";
+    QTest::newRow("sci file") << "http://localhost/none.sci";
+}
+
+QTEST_MAIN(tst_qquickborderimage)
+
+#include "tst_qquickborderimage.moc"
diff --git a/tests/auto/declarative/qquickcanvas/qquickcanvas.pro b/tests/auto/declarative/qquickcanvas/qquickcanvas.pro
new file mode 100644 (file)
index 0000000..b45a359
--- /dev/null
@@ -0,0 +1,8 @@
+CONFIG += testcase
+TARGET = tst_qquickcanvas
+SOURCES += tst_qquickcanvas.cpp
+
+macx:CONFIG -= app_bundle
+
+CONFIG += parallel_test
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qquickcanvas/tst_qquickcanvas.cpp b/tests/auto/declarative/qquickcanvas/tst_qquickcanvas.cpp
new file mode 100644 (file)
index 0000000..d2b691d
--- /dev/null
@@ -0,0 +1,521 @@
+/****************************************************************************
+**
+** 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 <QDebug>
+#include <QTouchEvent>
+#include <QtDeclarative/QQuickItem>
+#include <QtDeclarative/QQuickCanvas>
+#include <QtDeclarative/private/qquickrectangle_p.h>
+#include <QtGui/QWindowSystemInterface>
+
+struct TouchEventData {
+    QEvent::Type type;
+    QWidget *widget;
+    QWindow *window;
+    Qt::TouchPointStates states;
+    QList<QTouchEvent::TouchPoint> touchPoints;
+};
+
+static QTouchEvent::TouchPoint makeTouchPoint(QQuickItem *item, const QPointF &p, const QPointF &lastPoint = QPointF())
+{
+    QPointF last = lastPoint.isNull() ? p : lastPoint;
+
+    QTouchEvent::TouchPoint tp;
+
+    tp.setPos(p);
+    tp.setLastPos(last);
+    tp.setScenePos(item->mapToScene(p));
+    tp.setLastScenePos(item->mapToScene(last));
+    tp.setScreenPos(item->canvas()->mapToGlobal(tp.scenePos().toPoint()));
+    tp.setLastScreenPos(item->canvas()->mapToGlobal(tp.lastScenePos().toPoint()));
+    return tp;
+}
+
+static TouchEventData makeTouchData(QEvent::Type type, QWidget *w, Qt::TouchPointStates states, const QList<QTouchEvent::TouchPoint> &touchPoints)
+{
+    TouchEventData d = { type, w, 0, states, touchPoints };
+    return d;
+}
+
+static TouchEventData makeTouchData(QEvent::Type type, QWidget *w, Qt::TouchPointStates states, const QTouchEvent::TouchPoint &touchPoint)
+{
+    QList<QTouchEvent::TouchPoint> points;
+    points << touchPoint;
+    return makeTouchData(type, w, states, points);
+}
+static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, Qt::TouchPointStates states, const QList<QTouchEvent::TouchPoint>& touchPoints)
+{
+    TouchEventData d = { type, 0, w, states, touchPoints };
+    return d;
+}
+static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, Qt::TouchPointStates states, const QTouchEvent::TouchPoint &touchPoint)
+{
+    QList<QTouchEvent::TouchPoint> points;
+    points << touchPoint;
+    return makeTouchData(type, w, states, points);
+}
+
+#define COMPARE_TOUCH_POINTS(tp1, tp2) \
+{ \
+    QCOMPARE(tp1.pos(), tp2.pos()); \
+    QCOMPARE(tp1.lastPos(), tp2.lastPos()); \
+    QCOMPARE(tp1.scenePos(), tp2.scenePos()); \
+    QCOMPARE(tp1.lastScenePos(), tp2.lastScenePos()); \
+    QCOMPARE(tp1.screenPos(), tp2.screenPos()); \
+    QCOMPARE(tp1.lastScreenPos(), tp2.lastScreenPos()); \
+}
+
+#define COMPARE_TOUCH_DATA(d1, d2) \
+{ \
+    QCOMPARE((int)d1.type, (int)d2.type); \
+    QCOMPARE(d1.widget, d2.widget); \
+    QCOMPARE((int)d1.states, (int)d2.states); \
+    QCOMPARE(d1.touchPoints.count(), d2.touchPoints.count()); \
+    for (int i=0; i<d1.touchPoints.count(); i++) { \
+        COMPARE_TOUCH_POINTS(d1.touchPoints[i], d2.touchPoints[i]); \
+    } \
+}
+
+class TestTouchItem : public QQuickRectangle
+{
+    Q_OBJECT
+public:
+    TestTouchItem(QQuickItem *parent = 0)
+        : QQuickRectangle(parent), acceptEvents(true), mousePressId(0)
+    {
+        border()->setWidth(1);
+        setAcceptedMouseButtons(Qt::LeftButton);
+        setFiltersChildMouseEvents(true);
+    }
+
+    void reset() {
+        acceptEvents = true;
+        setEnabled(true);
+        setOpacity(1.0);
+
+        lastEvent = makeTouchData(QEvent::None, canvas(), 0, QList<QTouchEvent::TouchPoint>());//CHECK_VALID
+    }
+
+    bool acceptEvents;
+    TouchEventData lastEvent;
+    int mousePressId;
+
+protected:
+    virtual void touchEvent(QTouchEvent *event) {
+        if (!acceptEvents) {
+            event->ignore();
+            return;
+        }
+        lastEvent = makeTouchData(event->type(), event->widget(), event->touchPointStates(), event->touchPoints());
+        event->accept();
+    }
+
+    virtual void mousePressEvent(QMouseEvent *event) {
+        mousePressId = ++mousePressNum;
+    }
+
+    bool childMouseEventFilter(QQuickItem *, QEvent *) {
+        mousePressId = ++mousePressNum;
+        return false;
+    }
+
+    static int mousePressNum;
+};
+
+int TestTouchItem::mousePressNum = 0;
+
+class ConstantUpdateItem : public QQuickItem
+{
+Q_OBJECT
+public:
+    ConstantUpdateItem(QQuickItem *parent = 0) : QQuickItem(parent), iterations(0) {setFlag(ItemHasContents);}
+
+    int iterations;
+protected:
+    QSGNode* updatePaintNode(QSGNode *, UpdatePaintNodeData *){
+        iterations++;
+        update();
+        return 0;
+    }
+};
+
+class tst_qquickcanvas : public QObject
+{
+    Q_OBJECT
+public:
+    tst_qquickcanvas();
+
+private slots:
+    void initTestCase();
+    void cleanupTestCase();
+
+    void constantUpdates();
+
+    void touchEvent_basic();
+    void touchEvent_propagation();
+    void touchEvent_propagation_data();
+
+    void clearCanvas();
+    void mouseFiltering();
+};
+
+tst_qquickcanvas::tst_qquickcanvas()
+{
+}
+
+void tst_qquickcanvas::initTestCase()
+{
+}
+
+void tst_qquickcanvas::cleanupTestCase()
+{
+}
+
+//If the item calls update inside updatePaintNode, it should schedule another update
+void tst_qquickcanvas::constantUpdates()
+{
+    QQuickCanvas canvas;
+    ConstantUpdateItem item(canvas.rootItem());
+    canvas.show();
+    QTRY_VERIFY(item.iterations > 60);
+}
+
+void tst_qquickcanvas::touchEvent_basic()
+{
+    QQuickCanvas *canvas = new QQuickCanvas;
+    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));
+
+    QPointF pos(10, 10);
+
+    // press single point
+    QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas);
+    QTest::qWait(50);
+
+    QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
+
+    QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
+    QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
+    TouchEventData d = makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem,pos));
+    COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem, pos)));
+    topItem->reset();
+
+    // press multiple points
+    QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas)
+            .press(1, bottomItem->mapToScene(pos).toPoint(), canvas);
+    QTest::qWait(50);
+    QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
+    QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
+    QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
+    COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem, pos)));
+    COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(bottomItem, pos)));
+    topItem->reset();
+    bottomItem->reset();
+
+    // touch point on top item moves to bottom item, but top item should still receive the event
+    QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(), canvas);
+    QTest::qWait(50);
+    QTest::touchEvent(canvas).move(0, bottomItem->mapToScene(pos).toPoint(), canvas);
+    QTest::qWait(50);
+    QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
+    COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchUpdate, canvas, Qt::TouchPointMoved,
+            makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos)));
+    topItem->reset();
+
+    // touch point on bottom item moves to top item, but bottom item should still receive the event
+    QTest::touchEvent(canvas).press(0, bottomItem->mapToScene(pos).toPoint(), canvas);
+    QTest::qWait(50);
+    QTest::touchEvent(canvas).move(0, topItem->mapToScene(pos).toPoint(), canvas);
+    QTest::qWait(50);
+    QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
+    COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchUpdate, canvas, Qt::TouchPointMoved,
+            makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos), pos)));
+    bottomItem->reset();
+
+    // a single stationary press on an item shouldn't cause an event
+    QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(), canvas);
+    QTest::qWait(50);
+    QTest::touchEvent(canvas).stationary(0)
+            .press(1, bottomItem->mapToScene(pos).toPoint(), canvas);
+    QTest::qWait(50);
+    QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);    // received press only, not stationary
+    QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
+    QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
+    COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem, pos)));
+    COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(bottomItem, pos)));
+    topItem->reset();
+    bottomItem->reset();
+
+    // move touch point from top item to bottom, and release
+    QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas);
+    QTest::qWait(50);
+    QTest::touchEvent(canvas).release(0, bottomItem->mapToScene(pos).toPoint(),canvas);
+    QTest::qWait(50);
+    QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
+    COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchEnd, canvas, Qt::TouchPointReleased,
+            makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos)));
+    topItem->reset();
+
+    // release while another point is pressed
+    QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas)
+            .press(1, bottomItem->mapToScene(pos).toPoint(), canvas);
+    QTest::qWait(50);
+    QTest::touchEvent(canvas).move(0, bottomItem->mapToScene(pos).toPoint(), canvas);
+    QTest::qWait(50);
+    QTest::touchEvent(canvas).release(0, bottomItem->mapToScene(pos).toPoint(), canvas)
+                             .stationary(1);
+    QTest::qWait(50);
+    QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
+    QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
+    QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
+    COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchEnd, canvas, Qt::TouchPointReleased,
+            makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos))));
+    COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(bottomItem, pos)));
+    topItem->reset();
+    bottomItem->reset();
+
+    delete topItem;
+    delete middleItem;
+    delete bottomItem;
+    delete canvas;
+}
+
+void tst_qquickcanvas::touchEvent_propagation()
+{
+    QFETCH(bool, acceptEvents);
+    QFETCH(bool, enableItem);
+    QFETCH(qreal, itemOpacity);
+
+    QQuickCanvas *canvas = new QQuickCanvas;
+    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));
+
+    QPointF pos(10, 10);
+    QPoint pointInBottomItem = bottomItem->mapToScene(pos).toPoint();  // (10, 10)
+    QPoint pointInMiddleItem = middleItem->mapToScene(pos).toPoint();  // (60, 60) overlaps with bottomItem
+    QPoint pointInTopItem = topItem->mapToScene(pos).toPoint();  // (110, 110) overlaps with bottom & top items
+
+    // disable topItem
+    topItem->acceptEvents = acceptEvents;
+    topItem->setEnabled(enableItem);
+    topItem->setOpacity(itemOpacity);
+
+    // single touch to top item, should be received by middle item
+    QTest::touchEvent(canvas).press(0, pointInTopItem, canvas);
+    QTest::qWait(50);
+    QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
+    QCOMPARE(middleItem->lastEvent.touchPoints.count(), 1);
+    QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
+    COMPARE_TOUCH_DATA(middleItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed,
+            makeTouchPoint(middleItem, middleItem->mapFromItem(topItem, pos))));
+
+    // touch top and middle items, middle item should get both events
+    QTest::touchEvent(canvas).press(0, pointInTopItem, canvas)
+            .press(1, pointInMiddleItem, canvas);
+    QTest::qWait(50);
+    QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
+    QCOMPARE(middleItem->lastEvent.touchPoints.count(), 2);
+    QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
+    COMPARE_TOUCH_DATA(middleItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed,
+           (QList<QTouchEvent::TouchPoint>() << makeTouchPoint(middleItem, middleItem->mapFromItem(topItem, pos))
+                                              << makeTouchPoint(middleItem, pos) )));
+    middleItem->reset();
+
+    // disable middleItem as well
+    middleItem->acceptEvents = acceptEvents;
+    middleItem->setEnabled(enableItem);
+    middleItem->setOpacity(itemOpacity);
+
+    // touch top and middle items, bottom item should get all events
+    QTest::touchEvent(canvas).press(0, pointInTopItem, canvas)
+            .press(1, pointInMiddleItem, canvas);
+    QTest::qWait(50);
+    QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
+    QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
+    QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 2);
+    COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed,
+            (QList<QTouchEvent::TouchPoint>() << makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos))
+                                              << makeTouchPoint(bottomItem, bottomItem->mapFromItem(middleItem, pos)) )));
+    bottomItem->reset();
+
+    // disable bottom item as well
+    bottomItem->acceptEvents = acceptEvents;
+    bottomItem->setEnabled(enableItem);
+    bottomItem->setOpacity(itemOpacity);
+
+    // no events should be received
+    QTest::touchEvent(canvas).press(0, pointInTopItem, canvas)
+            .press(1, pointInMiddleItem, canvas)
+            .press(2, pointInBottomItem, canvas);
+    QTest::qWait(50);
+    QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
+    QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
+    QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
+
+    topItem->reset();
+    middleItem->reset();
+    bottomItem->reset();
+
+    // disable middle item, touch on top item
+    middleItem->acceptEvents = acceptEvents;
+    middleItem->setEnabled(enableItem);
+    middleItem->setOpacity(itemOpacity);
+    QTest::touchEvent(canvas).press(0, pointInTopItem, canvas);
+    QTest::qWait(50);
+    if (!enableItem || itemOpacity == 0) {
+        // middle item is disabled or has 0 opacity, bottom item receives the event
+        QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
+        QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
+        QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
+        COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed,
+                makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos))));
+    } else {
+        // middle item ignores event, sends it to the top item (top-most child)
+        QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
+        QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
+        QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
+        COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed,
+                makeTouchPoint(topItem, pos)));
+    }
+
+    delete topItem;
+    delete middleItem;
+    delete bottomItem;
+    delete canvas;
+}
+
+void tst_qquickcanvas::touchEvent_propagation_data()
+{
+    QTest::addColumn<bool>("acceptEvents");
+    QTest::addColumn<bool>("enableItem");
+    QTest::addColumn<qreal>("itemOpacity");
+
+    QTest::newRow("disable events") << false << true << 1.0;
+    QTest::newRow("disable item") << true << false << 1.0;
+    QTest::newRow("opacity of 0") << true << true << 0.0;
+}
+
+void tst_qquickcanvas::clearCanvas()
+{
+    QQuickCanvas *canvas = new QQuickCanvas;
+    QQuickItem *item = new QQuickItem;
+    item->setParentItem(canvas->rootItem());
+
+    QVERIFY(item->canvas() == canvas);
+
+    delete canvas;
+
+    QVERIFY(item->canvas() == 0);
+
+    delete item;
+}
+
+void tst_qquickcanvas::mouseFiltering()
+{
+    QQuickCanvas *canvas = new QQuickCanvas;
+    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_qquickcanvas)
+
+#include "tst_qquickcanvas.moc"
diff --git a/tests/auto/declarative/qquickcanvasitem/qquickcanvasitem.pro b/tests/auto/declarative/qquickcanvasitem/qquickcanvasitem.pro
new file mode 100644 (file)
index 0000000..269aabb
--- /dev/null
@@ -0,0 +1,34 @@
+QT += core-private gui-private declarative-private widgets
+TEMPLATE=app
+TARGET=tst_qquickcanvasitem
+
+CONFIG+=insignificant_test
+CONFIG += warn_on qmltestcase
+SOURCES += tst_qquickcanvasitem.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/qquickcanvasitem/tst_qquickcanvasitem.cpp b/tests/auto/declarative/qquickcanvasitem/tst_qquickcanvasitem.cpp
new file mode 100644 (file)
index 0000000..57195ba
--- /dev/null
@@ -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(qquickcanvasitem)
diff --git a/tests/auto/declarative/qquickdrag/qquickdrag.pro b/tests/auto/declarative/qquickdrag/qquickdrag.pro
new file mode 100644 (file)
index 0000000..416ecdb
--- /dev/null
@@ -0,0 +1,9 @@
+TARGET = tst_qquickdrag
+CONFIG += testcase
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qquickdrag.cpp
+
+CONFIG += parallel_test
+
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qquickdrag/tst_qquickdrag.cpp b/tests/auto/declarative/qquickdrag/tst_qquickdrag.cpp
new file mode 100644 (file)
index 0000000..6bc0866
--- /dev/null
@@ -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/qquickitem.h>
+#include <QtDeclarative/qquickview.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 QQuickItem
+{
+    Q_OBJECT
+public:
+    TestDropTarget(QQuickItem *parent = 0)
+        : QQuickItem(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_QQuickDrag: 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_QQuickDrag::initTestCase()
+{
+
+}
+
+void tst_QQuickDrag::cleanupTestCase()
+{
+
+}
+
+void tst_QQuickDrag::active()
+{
+    QQuickCanvas 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());
+    QQuickItem *item = qobject_cast<QQuickItem *>(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 QQuickItem::ItemAcceptsDrops flag.
+    dropTarget.setFlags(QQuickItem::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(QQuickItem::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(QQuickItem::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(QQuickItem::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_QQuickDrag::drop()
+{
+    QQuickCanvas 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());
+    QQuickItem *item = qobject_cast<QQuickItem *>(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(QQuickItem::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_QQuickDrag::move()
+{
+    QQuickCanvas 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());
+    QQuickItem *item = qobject_cast<QQuickItem *>(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 QQuickItem::ItemAcceptsDrops flag from the outer target after it accepted an enter event.
+    outerTarget.setFlags(QQuickItem::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 QQuickItem::ItemAcceptsDrops flag from the left target before it accepts an enter event.
+    leftTarget.setFlags(QQuickItem::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_QQuickDrag::hotSpot()
+{
+    QQuickCanvas 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());
+    QQuickItem *item = qobject_cast<QQuickItem *>(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_QQuickDrag::supportedActions()
+{
+    QQuickCanvas 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());
+    QQuickItem *item = qobject_cast<QQuickItem *>(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_QQuickDrag::proposedAction()
+{
+    QQuickCanvas 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());
+    QQuickItem *item = qobject_cast<QQuickItem *>(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_QQuickDrag::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());
+    QQuickItem *item = qobject_cast<QQuickItem *>(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_QQuickDrag::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());
+    QQuickItem *item = qobject_cast<QQuickItem *>(object.data());
+    QVERIFY(item);
+
+    QCOMPARE(evaluate<QObject *>(item, "Drag.source"), static_cast<QObject *>(item));
+    QCOMPARE(evaluate<QObject *>(item, "source"), static_cast<QObject *>(item));
+
+    QQuickItem *proxySource = item->findChild<QQuickItem *>("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_QQuickDrag)
+
+#include "tst_qquickdrag.moc"
diff --git a/tests/auto/declarative/qquickdroparea/qquickdroparea.pro b/tests/auto/declarative/qquickdroparea/qquickdroparea.pro
new file mode 100644 (file)
index 0000000..eff08a2
--- /dev/null
@@ -0,0 +1,9 @@
+TARGET = tst_qquickdroparea
+CONFIG += testcase
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qquickdroparea.cpp
+
+CONFIG += parallel_test
+
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qquickdroparea/tst_qquickdroparea.cpp b/tests/auto/declarative/qquickdroparea/tst_qquickdroparea.cpp
new file mode 100644 (file)
index 0000000..0147536
--- /dev/null
@@ -0,0 +1,1117 @@
+/****************************************************************************
+**
+** 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/qquickitem.h>
+#include <QtDeclarative/qquickview.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_QQuickDropArea: 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_QQuickDropArea::initTestCase()
+{
+
+}
+
+void tst_QQuickDropArea::cleanupTestCase()
+{
+
+}
+
+void tst_QQuickDropArea::containsDrag_internal()
+{
+    QQuickCanvas 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());
+    QQuickItem *dropArea = qobject_cast<QQuickItem *>(object.data());
+    QVERIFY(dropArea);
+    dropArea->setParentItem(canvas.rootItem());
+
+    QQuickItem *dragItem = dropArea->findChild<QQuickItem *>("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_QQuickDropArea::containsDrag_external()
+{
+    QQuickCanvas 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());
+    QQuickItem *dropArea = qobject_cast<QQuickItem *>(object.data());
+    QVERIFY(dropArea);
+    dropArea->setParentItem(canvas.rootItem());
+
+    QMimeData data;
+    QQuickCanvas 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_QQuickDropArea::keys_internal()
+{
+    QQuickCanvas 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());
+    QQuickItem *dropArea = qobject_cast<QQuickItem *>(object.data());
+    QVERIFY(dropArea);
+    dropArea->setParentItem(canvas.rootItem());
+
+    QQuickItem *dragItem = dropArea->findChild<QQuickItem *>("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_QQuickDropArea::keys_external()
+{
+    QQuickCanvas 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());
+    QQuickItem *dropArea = qobject_cast<QQuickItem *>(object.data());
+    dropArea->setParentItem(canvas.rootItem());
+
+    QMimeData data;
+    QQuickCanvas 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_QQuickDropArea::source_internal()
+{
+    QQuickCanvas 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());
+    QQuickItem *dropArea = qobject_cast<QQuickItem *>(object.data());
+    QVERIFY(dropArea);
+    dropArea->setParentItem(canvas.rootItem());
+
+    QQuickItem *dragItem = dropArea->findChild<QQuickItem *>("dragItem");
+    QVERIFY(dragItem);
+
+    QQuickItem *dragSource = dropArea->findChild<QQuickItem *>("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_QQuickDropArea::source_external()
+//{
+//}
+
+void tst_QQuickDropArea::position_internal()
+{
+    QQuickCanvas 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());
+    QQuickItem *dropArea = qobject_cast<QQuickItem *>(object.data());
+    QVERIFY(dropArea);
+    dropArea->setParentItem(canvas.rootItem());
+
+    QQuickItem *dragItem = dropArea->findChild<QQuickItem *>("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_QQuickDropArea::position_external()
+{
+    QQuickCanvas 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());
+    QQuickItem *dropArea = qobject_cast<QQuickItem *>(object.data());
+    QVERIFY(dropArea);
+    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_QQuickDropArea::drop_internal()
+{
+    QQuickCanvas 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());
+    QQuickItem *dropArea = qobject_cast<QQuickItem *>(object.data());
+    QVERIFY(dropArea);
+    dropArea->setParentItem(canvas.rootItem());
+
+    QQuickItem *dragItem = dropArea->findChild<QQuickItem *>("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_QQuickDropArea::drop_external()
+//{
+//}
+
+void tst_QQuickDropArea::simultaneousDrags()
+{
+    QQuickCanvas 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());
+    QQuickItem *dropArea1 = qobject_cast<QQuickItem *>(object.data());
+    QVERIFY(dropArea1);
+    dropArea1->setParentItem(canvas.rootItem());
+
+    QQuickItem *dropArea2 = dropArea1->findChild<QQuickItem *>("dropArea2");
+    QVERIFY(dropArea2);
+
+    QQuickItem *dragItem1 = dropArea1->findChild<QQuickItem *>("dragItem1");
+    QVERIFY(dragItem1);
+
+    QQuickItem *dragItem2 = dropArea1->findChild<QQuickItem *>("dragItem2");
+    QVERIFY(dragItem2);
+
+    QMimeData data;
+    data.setData("text/x-red", "red");
+    data.setData("text/x-blue", "blue");
+
+    QQuickCanvas 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_QQuickDropArea)
+
+#include "tst_qquickdroparea.moc"
diff --git a/tests/auto/declarative/qquickflickable/qquickflickable.pro b/tests/auto/declarative/qquickflickable/qquickflickable.pro
new file mode 100644 (file)
index 0000000..ba951cc
--- /dev/null
@@ -0,0 +1,12 @@
+CONFIG += testcase
+TARGET = tst_qquickflickable
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qquickflickable.cpp
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+QT += core-private gui-private v8-private declarative-private testlib
diff --git a/tests/auto/declarative/qquickflickable/tst_qquickflickable.cpp b/tests/auto/declarative/qquickflickable/tst_qquickflickable.cpp
new file mode 100644 (file)
index 0000000..2f155e2
--- /dev/null
@@ -0,0 +1,662 @@
+/****************************************************************************
+**
+** 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/QSignalSpy>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qquickview.h>
+#include <private/qquickflickable_p.h>
+#include <private/qdeclarativevaluetype_p.h>
+#include <math.h>
+#include "../shared/util.h"
+#include <QtOpenGL/QGLShaderProgram>
+
+class tst_qquickflickable : public QObject
+{
+    Q_OBJECT
+public:
+    tst_qquickflickable();
+
+private slots:
+    void initTestCase();
+    void cleanupTestCase();
+
+    void create();
+    void horizontalViewportSize();
+    void verticalViewportSize();
+    void properties();
+    void boundsBehavior();
+    void maximumFlickVelocity();
+    void flickDeceleration();
+    void pressDelay();
+    void nestedPressDelay();
+    void flickableDirection();
+    void resizeContent();
+    void returnToBounds();
+    void wheel();
+    void movingAndDragging();
+    void disabled();
+    void flickVelocity();
+    void margins();
+
+private:
+    QDeclarativeEngine engine;
+
+    void flick(QQuickView *canvas, const QPoint &from, const QPoint &to, int duration);
+    template<typename T>
+    T *findItem(QQuickItem *parent, const QString &objectName);
+};
+
+tst_qquickflickable::tst_qquickflickable()
+{
+}
+
+void tst_qquickflickable::initTestCase()
+{
+
+}
+
+void tst_qquickflickable::cleanupTestCase()
+{
+
+}
+
+void tst_qquickflickable::create()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable01.qml")));
+    QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(c.create());
+
+    QVERIFY(obj != 0);
+    QCOMPARE(obj->isAtXBeginning(), true);
+    QCOMPARE(obj->isAtXEnd(), false);
+    QCOMPARE(obj->isAtYBeginning(), true);
+    QCOMPARE(obj->isAtYEnd(), false);
+    QCOMPARE(obj->contentX(), 0.);
+    QCOMPARE(obj->contentY(), 0.);
+
+    QCOMPARE(obj->horizontalVelocity(), 0.);
+    QCOMPARE(obj->verticalVelocity(), 0.);
+
+    QCOMPARE(obj->isInteractive(), true);
+    QCOMPARE(obj->boundsBehavior(), QQuickFlickable::DragAndOvershootBounds);
+    QCOMPARE(obj->pressDelay(), 0);
+    QCOMPARE(obj->maximumFlickVelocity(), 2500.);
+
+    delete obj;
+}
+
+void tst_qquickflickable::horizontalViewportSize()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable02.qml")));
+    QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(c.create());
+
+    QVERIFY(obj != 0);
+    QCOMPARE(obj->contentWidth(), 800.);
+    QCOMPARE(obj->contentHeight(), 300.);
+    QCOMPARE(obj->isAtXBeginning(), true);
+    QCOMPARE(obj->isAtXEnd(), false);
+    QCOMPARE(obj->isAtYBeginning(), true);
+    QCOMPARE(obj->isAtYEnd(), false);
+
+    delete obj;
+}
+
+void tst_qquickflickable::verticalViewportSize()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable03.qml")));
+    QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(c.create());
+
+    QVERIFY(obj != 0);
+    QCOMPARE(obj->contentWidth(), 200.);
+    QCOMPARE(obj->contentHeight(), 1200.);
+    QCOMPARE(obj->isAtXBeginning(), true);
+    QCOMPARE(obj->isAtXEnd(), false);
+    QCOMPARE(obj->isAtYBeginning(), true);
+    QCOMPARE(obj->isAtYEnd(), false);
+
+    delete obj;
+}
+
+void tst_qquickflickable::properties()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable04.qml")));
+    QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(c.create());
+
+    QVERIFY(obj != 0);
+    QCOMPARE(obj->isInteractive(), false);
+    QCOMPARE(obj->boundsBehavior(), QQuickFlickable::StopAtBounds);
+    QCOMPARE(obj->pressDelay(), 200);
+    QCOMPARE(obj->maximumFlickVelocity(), 2000.);
+
+    QVERIFY(obj->property("ok").toBool() == false);
+    QMetaObject::invokeMethod(obj, "check");
+    QVERIFY(obj->property("ok").toBool() == true);
+
+    delete obj;
+}
+
+void tst_qquickflickable::boundsBehavior()
+{
+    QDeclarativeComponent component(&engine);
+    component.setData("import QtQuick 2.0; Flickable { boundsBehavior: Flickable.StopAtBounds }", QUrl::fromLocalFile(""));
+    QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(component.create());
+    QSignalSpy spy(flickable, SIGNAL(boundsBehaviorChanged()));
+
+    QVERIFY(flickable);
+    QVERIFY(flickable->boundsBehavior() == QQuickFlickable::StopAtBounds);
+
+    flickable->setBoundsBehavior(QQuickFlickable::DragAndOvershootBounds);
+    QVERIFY(flickable->boundsBehavior() == QQuickFlickable::DragAndOvershootBounds);
+    QCOMPARE(spy.count(),1);
+    flickable->setBoundsBehavior(QQuickFlickable::DragAndOvershootBounds);
+    QCOMPARE(spy.count(),1);
+
+    flickable->setBoundsBehavior(QQuickFlickable::DragOverBounds);
+    QVERIFY(flickable->boundsBehavior() == QQuickFlickable::DragOverBounds);
+    QCOMPARE(spy.count(),2);
+    flickable->setBoundsBehavior(QQuickFlickable::DragOverBounds);
+    QCOMPARE(spy.count(),2);
+
+    flickable->setBoundsBehavior(QQuickFlickable::StopAtBounds);
+    QVERIFY(flickable->boundsBehavior() == QQuickFlickable::StopAtBounds);
+    QCOMPARE(spy.count(),3);
+    flickable->setBoundsBehavior(QQuickFlickable::StopAtBounds);
+    QCOMPARE(spy.count(),3);
+}
+
+void tst_qquickflickable::maximumFlickVelocity()
+{
+    QDeclarativeComponent component(&engine);
+    component.setData("import QtQuick 2.0; Flickable { maximumFlickVelocity: 1.0; }", QUrl::fromLocalFile(""));
+    QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(component.create());
+    QSignalSpy spy(flickable, SIGNAL(maximumFlickVelocityChanged()));
+
+    QVERIFY(flickable);
+    QCOMPARE(flickable->maximumFlickVelocity(), 1.0);
+
+    flickable->setMaximumFlickVelocity(2.0);
+    QCOMPARE(flickable->maximumFlickVelocity(), 2.0);
+    QCOMPARE(spy.count(),1);
+    flickable->setMaximumFlickVelocity(2.0);
+    QCOMPARE(spy.count(),1);
+}
+
+void tst_qquickflickable::flickDeceleration()
+{
+    QDeclarativeComponent component(&engine);
+    component.setData("import QtQuick 2.0; Flickable { flickDeceleration: 1.0; }", QUrl::fromLocalFile(""));
+    QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(component.create());
+    QSignalSpy spy(flickable, SIGNAL(flickDecelerationChanged()));
+
+    QVERIFY(flickable);
+    QCOMPARE(flickable->flickDeceleration(), 1.0);
+
+    flickable->setFlickDeceleration(2.0);
+    QCOMPARE(flickable->flickDeceleration(), 2.0);
+    QCOMPARE(spy.count(),1);
+    flickable->setFlickDeceleration(2.0);
+    QCOMPARE(spy.count(),1);
+}
+
+void tst_qquickflickable::pressDelay()
+{
+    QDeclarativeComponent component(&engine);
+    component.setData("import QtQuick 2.0; Flickable { pressDelay: 100; }", QUrl::fromLocalFile(""));
+    QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(component.create());
+    QSignalSpy spy(flickable, SIGNAL(pressDelayChanged()));
+
+    QVERIFY(flickable);
+    QCOMPARE(flickable->pressDelay(), 100);
+
+    flickable->setPressDelay(200);
+    QCOMPARE(flickable->pressDelay(), 200);
+    QCOMPARE(spy.count(),1);
+    flickable->setPressDelay(200);
+    QCOMPARE(spy.count(),1);
+}
+
+// QTBUG-17361
+void tst_qquickflickable::nestedPressDelay()
+{
+    QQuickView *canvas = new QQuickView;
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("nestedPressDelay.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QVERIFY(canvas->rootObject() != 0);
+
+    QQuickFlickable *outer = qobject_cast<QQuickFlickable*>(canvas->rootObject());
+    QVERIFY(outer != 0);
+
+    QQuickFlickable *inner = canvas->rootObject()->findChild<QQuickFlickable*>("innerFlickable");
+    QVERIFY(inner != 0);
+
+    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(150, 150));
+    // the MouseArea is not pressed immediately
+    QVERIFY(outer->property("pressed").toBool() == false);
+
+    // The outer pressDelay will prevail (50ms, vs. 10sec)
+    // QTRY_VERIFY() has 5sec timeout, so will timeout well within 10sec.
+    QTRY_VERIFY(outer->property("pressed").toBool() == true);
+
+    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(150, 150));
+
+    delete canvas;
+}
+
+void tst_qquickflickable::flickableDirection()
+{
+    QDeclarativeComponent component(&engine);
+    component.setData("import QtQuick 2.0; Flickable { flickableDirection: Flickable.VerticalFlick; }", QUrl::fromLocalFile(""));
+    QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(component.create());
+    QSignalSpy spy(flickable, SIGNAL(flickableDirectionChanged()));
+
+    QVERIFY(flickable);
+    QCOMPARE(flickable->flickableDirection(), QQuickFlickable::VerticalFlick);
+
+    flickable->setFlickableDirection(QQuickFlickable::HorizontalAndVerticalFlick);
+    QCOMPARE(flickable->flickableDirection(), QQuickFlickable::HorizontalAndVerticalFlick);
+    QCOMPARE(spy.count(),1);
+
+    flickable->setFlickableDirection(QQuickFlickable::AutoFlickDirection);
+    QCOMPARE(flickable->flickableDirection(), QQuickFlickable::AutoFlickDirection);
+    QCOMPARE(spy.count(),2);
+
+    flickable->setFlickableDirection(QQuickFlickable::HorizontalFlick);
+    QCOMPARE(flickable->flickableDirection(), QQuickFlickable::HorizontalFlick);
+    QCOMPARE(spy.count(),3);
+
+    flickable->setFlickableDirection(QQuickFlickable::HorizontalFlick);
+    QCOMPARE(flickable->flickableDirection(), QQuickFlickable::HorizontalFlick);
+    QCOMPARE(spy.count(),3);
+}
+
+// QtQuick 1.1
+void tst_qquickflickable::resizeContent()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("resize.qml")));
+    QQuickItem *root = qobject_cast<QQuickItem*>(c.create());
+    QQuickFlickable *obj = findItem<QQuickFlickable>(root, "flick");
+
+    QVERIFY(obj != 0);
+    QCOMPARE(obj->contentX(), 0.);
+    QCOMPARE(obj->contentY(), 0.);
+    QCOMPARE(obj->contentWidth(), 300.);
+    QCOMPARE(obj->contentHeight(), 300.);
+
+    QMetaObject::invokeMethod(root, "resizeContent");
+
+    QCOMPARE(obj->contentX(), 100.);
+    QCOMPARE(obj->contentY(), 100.);
+    QCOMPARE(obj->contentWidth(), 600.);
+    QCOMPARE(obj->contentHeight(), 600.);
+
+    delete root;
+}
+
+// QtQuick 1.1
+void tst_qquickflickable::returnToBounds()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("resize.qml")));
+    QQuickItem *root = qobject_cast<QQuickItem*>(c.create());
+    QQuickFlickable *obj = findItem<QQuickFlickable>(root, "flick");
+
+    QVERIFY(obj != 0);
+    QCOMPARE(obj->contentX(), 0.);
+    QCOMPARE(obj->contentY(), 0.);
+    QCOMPARE(obj->contentWidth(), 300.);
+    QCOMPARE(obj->contentHeight(), 300.);
+
+    obj->setContentX(100);
+    obj->setContentY(400);
+    QTRY_COMPARE(obj->contentX(), 100.);
+    QTRY_COMPARE(obj->contentY(), 400.);
+
+    QMetaObject::invokeMethod(root, "returnToBounds");
+
+    QTRY_COMPARE(obj->contentX(), 0.);
+    QTRY_COMPARE(obj->contentY(), 0.);
+
+    delete root;
+}
+
+void tst_qquickflickable::wheel()
+{
+    QQuickView *canvas = new QQuickView;
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("wheel.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QVERIFY(canvas->rootObject() != 0);
+
+    QQuickFlickable *flick = canvas->rootObject()->findChild<QQuickFlickable*>("flick");
+    QVERIFY(flick != 0);
+
+    {
+        QWheelEvent event(QPoint(200, 200), -120, Qt::NoButton, Qt::NoModifier, Qt::Vertical);
+        event.setAccepted(false);
+        QApplication::sendEvent(canvas, &event);
+    }
+
+    QTRY_VERIFY(flick->contentY() > 0);
+    QVERIFY(flick->contentX() == 0);
+
+    flick->setContentY(0);
+    QVERIFY(flick->contentY() == 0);
+
+    {
+        QWheelEvent event(QPoint(200, 200), -120, Qt::NoButton, Qt::NoModifier, Qt::Horizontal);
+        event.setAccepted(false);
+        QApplication::sendEvent(canvas, &event);
+    }
+
+    QTRY_VERIFY(flick->contentX() > 0);
+    QVERIFY(flick->contentY() == 0);
+
+    delete canvas;
+}
+
+void tst_qquickflickable::movingAndDragging()
+{
+    QQuickView *canvas = new QQuickView;
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("flickable03.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QTest::qWaitForWindowShown(canvas);
+    QVERIFY(canvas->rootObject() != 0);
+
+    QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(canvas->rootObject());
+    QVERIFY(flickable != 0);
+
+    QSignalSpy vDragSpy(flickable, SIGNAL(draggingVerticallyChanged()));
+    QSignalSpy hDragSpy(flickable, SIGNAL(draggingHorizontallyChanged()));
+    QSignalSpy dragSpy(flickable, SIGNAL(draggingChanged()));
+    QSignalSpy vMoveSpy(flickable, SIGNAL(movingVerticallyChanged()));
+    QSignalSpy hMoveSpy(flickable, SIGNAL(movingHorizontallyChanged()));
+    QSignalSpy moveSpy(flickable, SIGNAL(movingChanged()));
+    QSignalSpy dragStartSpy(flickable, SIGNAL(dragStarted()));
+    QSignalSpy dragEndSpy(flickable, SIGNAL(dragEnded()));
+
+    //Vertical
+    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50, 90));
+
+    QTest::mouseMove(canvas, QPoint(50, 80));
+    QTest::mouseMove(canvas, QPoint(50, 70));
+    QTest::mouseMove(canvas, QPoint(50, 60));
+
+    QMouseEvent moveEvent(QEvent::MouseMove, QPoint(50, 80), Qt::LeftButton, Qt::LeftButton, 0);
+
+    QVERIFY(!flickable->isDraggingHorizontally());
+    QVERIFY(flickable->isDraggingVertically());
+    QVERIFY(flickable->isDragging());
+    QCOMPARE(vDragSpy.count(), 1);
+    QCOMPARE(dragSpy.count(), 1);
+    QCOMPARE(hDragSpy.count(), 0);
+    QCOMPARE(dragStartSpy.count(), 1);
+    QCOMPARE(dragEndSpy.count(), 0);
+
+    QVERIFY(!flickable->isMovingHorizontally());
+    QVERIFY(flickable->isMovingVertically());
+    QVERIFY(flickable->isMoving());
+    QCOMPARE(vMoveSpy.count(), 1);
+    QCOMPARE(moveSpy.count(), 1);
+    QCOMPARE(hMoveSpy.count(), 0);
+
+    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 60));
+
+    QTRY_VERIFY(!flickable->isDraggingVertically());
+    QVERIFY(!flickable->isDragging());
+    QCOMPARE(vDragSpy.count(), 2);
+    QCOMPARE(dragSpy.count(), 2);
+    QCOMPARE(hDragSpy.count(), 0);
+    QCOMPARE(dragStartSpy.count(), 1);
+    QCOMPARE(dragEndSpy.count(), 1);
+
+    // wait for any motion to end
+    QTRY_VERIFY(flickable->isMoving() == false);
+
+    //Horizontal
+    vDragSpy.clear();
+    hDragSpy.clear();
+    dragSpy.clear();
+    vMoveSpy.clear();
+    hMoveSpy.clear();
+    moveSpy.clear();
+    dragStartSpy.clear();
+    dragEndSpy.clear();
+
+    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(90, 50));
+
+    QTest::mouseMove(canvas, QPoint(80, 50));
+    QTest::mouseMove(canvas, QPoint(70, 50));
+    QTest::mouseMove(canvas, QPoint(60, 50));
+
+    QVERIFY(flickable->isDraggingHorizontally());
+    QVERIFY(flickable->isDragging());
+    QCOMPARE(vDragSpy.count(), 0);
+    QCOMPARE(dragSpy.count(), 1);
+    QCOMPARE(hDragSpy.count(), 1);
+    QCOMPARE(dragStartSpy.count(), 1);
+    QCOMPARE(dragEndSpy.count(), 0);
+
+    QVERIFY(!flickable->isMovingVertically());
+    QVERIFY(flickable->isMovingHorizontally());
+    QVERIFY(flickable->isMoving());
+    QCOMPARE(vMoveSpy.count(), 0);
+    QCOMPARE(moveSpy.count(), 1);
+    QCOMPARE(hMoveSpy.count(), 1);
+
+    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(60, 50));
+
+    QTRY_VERIFY(!flickable->isDraggingHorizontally());
+    QVERIFY(!flickable->isDragging());
+    QCOMPARE(vDragSpy.count(), 0);
+    QCOMPARE(dragSpy.count(), 2);
+    QCOMPARE(hDragSpy.count(), 2);
+    QCOMPARE(dragStartSpy.count(), 1);
+    QCOMPARE(dragEndSpy.count(), 1);
+
+    // Don't test moving because a flick could occur
+
+    delete canvas;
+}
+
+void tst_qquickflickable::disabled()
+{
+    QQuickView *canvas = new QQuickView;
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("disabled.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QVERIFY(canvas->rootObject() != 0);
+
+    QQuickFlickable *flick = canvas->rootObject()->findChild<QQuickFlickable*>("flickable");
+    QVERIFY(flick != 0);
+
+    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50, 90));
+
+    QTest::mouseMove(canvas, QPoint(50, 80));
+    QTest::mouseMove(canvas, QPoint(50, 70));
+    QTest::mouseMove(canvas, QPoint(50, 60));
+
+    QVERIFY(flick->isMoving() == false);
+
+    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 60));
+
+    // verify that mouse clicks on other elements still work (QTBUG-20584)
+    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50, 10));
+    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 10));
+
+    QTRY_VERIFY(canvas->rootObject()->property("clicked").toBool() == true);
+}
+
+void tst_qquickflickable::flickVelocity()
+{
+#ifdef Q_WS_MAC
+    QSKIP("Producing flicks on Mac CI impossible due to timing problems");
+#endif
+
+    QQuickView *canvas = new QQuickView;
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("flickable03.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QVERIFY(canvas->rootObject() != 0);
+
+    QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(canvas->rootObject());
+    QVERIFY(flickable != 0);
+
+    // flick up
+    flick(canvas, QPoint(20,190), QPoint(20, 50), 200);
+    QVERIFY(flickable->verticalVelocity() > 0.0);
+    QTRY_VERIFY(flickable->verticalVelocity() == 0.0);
+
+    // flick down
+    flick(canvas, QPoint(20,10), QPoint(20, 140), 200);
+    QVERIFY(flickable->verticalVelocity() < 0.0);
+    QTRY_VERIFY(flickable->verticalVelocity() == 0.0);
+
+    delete canvas;
+}
+
+void tst_qquickflickable::margins()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("margins.qml")));
+    QQuickItem *root = qobject_cast<QQuickItem*>(c.create());
+    QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(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_qquickflickable::flick(QQuickView *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);
+}
+
+template<typename T>
+T *tst_qquickflickable::findItem(QQuickItem *parent, const QString &objectName)
+{
+    const QMetaObject &mo = T::staticMetaObject;
+    //qDebug() << parent->childItems().count() << "children";
+    for (int i = 0; i < parent->childItems().count(); ++i) {
+        QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
+        if (!item)
+            continue;
+        //qDebug() << "try" << item;
+        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
+            return static_cast<T*>(item);
+        }
+        item = findItem<T>(item, objectName);
+        if (item)
+            return static_cast<T*>(item);
+    }
+
+    return 0;
+}
+
+QTEST_MAIN(tst_qquickflickable)
+
+#include "tst_qquickflickable.moc"
diff --git a/tests/auto/declarative/qquickflipable/qquickflipable.pro b/tests/auto/declarative/qquickflipable/qquickflipable.pro
new file mode 100644 (file)
index 0000000..a36c468
--- /dev/null
@@ -0,0 +1,13 @@
+CONFIG += testcase
+TARGET = tst_qquickflipable
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qquickflipable.cpp
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+
+QT += core-private gui-private v8-private declarative-private testlib
diff --git a/tests/auto/declarative/qquickflipable/tst_qquickflipable.cpp b/tests/auto/declarative/qquickflipable/tst_qquickflipable.cpp
new file mode 100644 (file)
index 0000000..7243836
--- /dev/null
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** 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/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qquickview.h>
+#include <private/qquickflipable_p.h>
+#include <private/qdeclarativevaluetype_p.h>
+#include <QFontMetrics>
+#include <private/qquickrectangle_p.h>
+#include <math.h>
+#include <QtOpenGL/QGLShaderProgram>
+#include "../shared/util.h"
+
+class tst_qquickflipable : public QObject
+{
+    Q_OBJECT
+public:
+    tst_qquickflipable();
+
+private slots:
+    void initTestCase();
+    void cleanupTestCase();
+    void create();
+    void checkFrontAndBack();
+    void setFrontAndBack();
+
+    // below here task issues
+    void QTBUG_9161_crash();
+    void QTBUG_8474_qgv_abort();
+
+private:
+    QDeclarativeEngine engine;
+};
+
+tst_qquickflipable::tst_qquickflipable()
+{
+}
+void tst_qquickflipable::initTestCase()
+{
+}
+
+void tst_qquickflipable::cleanupTestCase()
+{
+
+}
+
+void tst_qquickflipable::create()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-flipable.qml")));
+    QQuickFlipable *obj = qobject_cast<QQuickFlipable*>(c.create());
+
+    QVERIFY(obj != 0);
+    delete obj;
+}
+
+void tst_qquickflipable::checkFrontAndBack()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-flipable.qml")));
+    QQuickFlipable *obj = qobject_cast<QQuickFlipable*>(c.create());
+
+    QVERIFY(obj != 0);
+    QVERIFY(obj->front() != 0);
+    QVERIFY(obj->back() != 0);
+    delete obj;
+}
+
+void tst_qquickflipable::setFrontAndBack()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-flipable.qml")));
+    QQuickFlipable *obj = qobject_cast<QQuickFlipable*>(c.create());
+
+    QVERIFY(obj != 0);
+    QVERIFY(obj->front() != 0);
+    QVERIFY(obj->back() != 0);
+
+    QString message = c.url().toString() + ":3:1: QML Flipable: front is a write-once property";
+    QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
+    obj->setFront(new QQuickRectangle());
+
+    message = c.url().toString() + ":3:1: QML Flipable: back is a write-once property";
+    QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
+    obj->setBack(new QQuickRectangle());
+    delete obj;
+}
+
+void tst_qquickflipable::QTBUG_9161_crash()
+{
+    QQuickView *canvas = new QQuickView;
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("crash.qml")));
+    QQuickItem *root = canvas->rootObject();
+    QVERIFY(root != 0);
+    canvas->show();
+    delete canvas;
+}
+
+void tst_qquickflipable::QTBUG_8474_qgv_abort()
+{
+    QQuickView *canvas = new QQuickView;
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("flipable-abort.qml")));
+    QQuickItem *root = canvas->rootObject();
+    QVERIFY(root != 0);
+    canvas->show();
+    delete canvas;
+}
+
+QTEST_MAIN(tst_qquickflipable)
+
+#include "tst_qquickflipable.moc"
diff --git a/tests/auto/declarative/qquickfocusscope/qquickfocusscope.pro b/tests/auto/declarative/qquickfocusscope/qquickfocusscope.pro
new file mode 100644 (file)
index 0000000..79649eb
--- /dev/null
@@ -0,0 +1,10 @@
+CONFIG += testcase
+TARGET = tst_qquickfocusscope
+SOURCES += tst_qquickfocusscope.cpp
+macx:CONFIG -= app_bundle
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qquickfocusscope/tst_qquickfocusscope.cpp b/tests/auto/declarative/qquickfocusscope/tst_qquickfocusscope.cpp
new file mode 100644 (file)
index 0000000..6e7dd98
--- /dev/null
@@ -0,0 +1,658 @@
+/****************************************************************************
+**
+** 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>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qquickview.h>
+#include <private/qquickrectangle_p.h>
+#include <private/qquicktextedit_p.h>
+#include <private/qquicktext_p.h>
+#include <QtDeclarative/private/qquickfocusscope_p.h>
+#include "../shared/util.h"
+
+class tst_qquickfocusscope : public QObject
+{
+    Q_OBJECT
+public:
+    tst_qquickfocusscope() {}
+
+    template<typename T>
+    T *findItem(QQuickItem *parent, const QString &id);
+
+private slots:
+    void initTestCase();
+    void cleanupTestCase();
+    void basic();
+    void nested();
+    void noFocus();
+    void textEdit();
+    void forceFocus();
+    void noParentFocus();
+    void signalEmission();
+    void qtBug13380();
+    void forceActiveFocus();
+    void canvasFocus();
+};
+void tst_qquickfocusscope::initTestCase()
+{
+}
+
+void tst_qquickfocusscope::cleanupTestCase()
+{
+
+}
+
+/*
+   Find an item with the specified id.
+*/
+template<typename T>
+T *tst_qquickfocusscope::findItem(QQuickItem *parent, const QString &objectName)
+{
+    const QMetaObject &mo = T::staticMetaObject;
+    QList<QQuickItem *> children = parent->childItems();
+    for (int i = 0; i < children.count(); ++i) {
+        QQuickItem *item = children.at(i);
+        if (item) {
+            if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
+                return static_cast<T*>(item);
+            }
+            item = findItem<T>(item, objectName);
+            if (item)
+                return static_cast<T*>(item);
+        }
+    }
+    return 0;
+}
+
+void tst_qquickfocusscope::basic()
+{
+    QQuickView *view = new QQuickView;
+    view->setSource(QUrl::fromLocalFile(TESTDATA("test.qml")));
+
+    QQuickFocusScope *item0 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item0"));
+    QQuickRectangle *item1 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item1"));
+    QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2"));
+    QQuickRectangle *item3 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item3"));
+    QVERIFY(item0 != 0);
+    QVERIFY(item1 != 0);
+    QVERIFY(item2 != 0);
+    QVERIFY(item3 != 0);
+
+    view->show();
+    view->requestActivateWindow();
+
+    QTest::qWaitForWindowShown(view);
+
+    QVERIFY(view->isTopLevel());
+    QVERIFY(item0->hasActiveFocus() == true);
+    QVERIFY(item1->hasActiveFocus() == true);
+    QVERIFY(item2->hasActiveFocus() == false);
+    QVERIFY(item3->hasActiveFocus() == false);
+
+    QTest::keyClick(view, Qt::Key_Right);
+    QTest::qWait(50);
+    QVERIFY(item0->hasActiveFocus() == true);
+    QVERIFY(item1->hasActiveFocus() == false);
+    QVERIFY(item2->hasActiveFocus() == true);
+    QVERIFY(item3->hasActiveFocus() == false);
+
+    QTest::keyClick(view, Qt::Key_Down);
+    QTest::qWait(50);
+    QVERIFY(item0->hasActiveFocus() == false);
+    QVERIFY(item1->hasActiveFocus() == false);
+    QVERIFY(item2->hasActiveFocus() == false);
+    QVERIFY(item3->hasActiveFocus() == true);
+
+    delete view;
+}
+
+void tst_qquickfocusscope::nested()
+{
+    QQuickView *view = new QQuickView;
+    view->setSource(QUrl::fromLocalFile(TESTDATA("test2.qml")));
+
+    QQuickFocusScope *item1 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item1"));
+    QQuickFocusScope *item2 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item2"));
+    QQuickFocusScope *item3 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item3"));
+    QQuickFocusScope *item4 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item4"));
+    QQuickFocusScope *item5 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item5"));
+    QVERIFY(item1 != 0);
+    QVERIFY(item2 != 0);
+    QVERIFY(item3 != 0);
+    QVERIFY(item4 != 0);
+    QVERIFY(item5 != 0);
+
+    view->show();
+    view->requestActivateWindow();
+
+    QTest::qWaitForWindowShown(view);
+
+    QVERIFY(item1->hasActiveFocus() == true);
+    QVERIFY(item2->hasActiveFocus() == true);
+    QVERIFY(item3->hasActiveFocus() == true);
+    QVERIFY(item4->hasActiveFocus() == true);
+    QVERIFY(item5->hasActiveFocus() == true);
+    delete view;
+}
+
+void tst_qquickfocusscope::noFocus()
+{
+    QQuickView *view = new QQuickView;
+    view->setSource(QUrl::fromLocalFile(TESTDATA("test4.qml")));
+
+    QQuickRectangle *item0 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item0"));
+    QQuickRectangle *item1 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item1"));
+    QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2"));
+    QQuickRectangle *item3 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item3"));
+    QVERIFY(item0 != 0);
+    QVERIFY(item1 != 0);
+    QVERIFY(item2 != 0);
+    QVERIFY(item3 != 0);
+
+    view->show();
+    view->requestActivateWindow();
+    QTest::qWaitForWindowShown(view);
+
+    QVERIFY(item0->hasActiveFocus() == false);
+    QVERIFY(item1->hasActiveFocus() == false);
+    QVERIFY(item2->hasActiveFocus() == false);
+    QVERIFY(item3->hasActiveFocus() == false);
+
+    QTest::keyClick(view, Qt::Key_Right);
+    QVERIFY(item0->hasActiveFocus() == false);
+    QVERIFY(item1->hasActiveFocus() == false);
+    QVERIFY(item2->hasActiveFocus() == false);
+    QVERIFY(item3->hasActiveFocus() == false);
+
+    QTest::keyClick(view, Qt::Key_Down);
+    QVERIFY(item0->hasActiveFocus() == false);
+    QVERIFY(item1->hasActiveFocus() == false);
+    QVERIFY(item2->hasActiveFocus() == false);
+    QVERIFY(item3->hasActiveFocus() == false);
+
+    delete view;
+}
+
+void tst_qquickfocusscope::textEdit()
+{
+    QQuickView *view = new QQuickView;
+    view->setSource(QUrl::fromLocalFile(TESTDATA("test5.qml")));
+
+    QQuickFocusScope *item0 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item0"));
+    QQuickTextEdit *item1 = findItem<QQuickTextEdit>(view->rootObject(), QLatin1String("item1"));
+    QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2"));
+    QQuickTextEdit *item3 = findItem<QQuickTextEdit>(view->rootObject(), QLatin1String("item3"));
+    QVERIFY(item0 != 0);
+    QVERIFY(item1 != 0);
+    QVERIFY(item2 != 0);
+    QVERIFY(item3 != 0);
+
+    view->show();
+    view->requestActivateWindow();
+
+    QTest::qWaitForWindowShown(view);
+
+    QTRY_VERIFY(view == qGuiApp->focusWindow());
+    QVERIFY(item0->hasActiveFocus() == true);
+    QVERIFY(item1->hasActiveFocus() == true);
+    QVERIFY(item2->hasActiveFocus() == false);
+    QVERIFY(item3->hasActiveFocus() == false);
+
+    QTest::keyClick(view, Qt::Key_Right);
+    QVERIFY(item0->hasActiveFocus() == true);
+    QVERIFY(item1->hasActiveFocus() == true);
+    QVERIFY(item2->hasActiveFocus() == false);
+    QVERIFY(item3->hasActiveFocus() == false);
+
+    QTest::keyClick(view, Qt::Key_Right);
+    QTest::keyClick(view, Qt::Key_Right);
+    QTest::keyClick(view, Qt::Key_Right);
+    QTest::keyClick(view, Qt::Key_Right);
+    QTest::keyClick(view, Qt::Key_Right);
+    QVERIFY(item0->hasActiveFocus() == true);
+    QVERIFY(item1->hasActiveFocus() == false);
+    QVERIFY(item2->hasActiveFocus() == true);
+    QVERIFY(item3->hasActiveFocus() == false);
+
+    QTest::keyClick(view, Qt::Key_Down);
+    QVERIFY(item0->hasActiveFocus() == false);
+    QVERIFY(item1->hasActiveFocus() == false);
+    QVERIFY(item2->hasActiveFocus() == false);
+    QVERIFY(item3->hasActiveFocus() == true);
+
+    delete view;
+}
+
+void tst_qquickfocusscope::forceFocus()
+{
+    QQuickView *view = new QQuickView;
+    view->setSource(QUrl::fromLocalFile(TESTDATA("forcefocus.qml")));
+
+    QQuickFocusScope *item0 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item0"));
+    QQuickRectangle *item1 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item1"));
+    QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2"));
+    QQuickFocusScope *item3 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item3"));
+    QQuickRectangle *item4 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item4"));
+    QQuickRectangle *item5 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item5"));
+    QVERIFY(item0 != 0);
+    QVERIFY(item1 != 0);
+    QVERIFY(item2 != 0);
+    QVERIFY(item3 != 0);
+    QVERIFY(item4 != 0);
+    QVERIFY(item5 != 0);
+
+    view->show();
+    view->requestActivateWindow();
+    QTest::qWaitForWindowShown(view);
+
+    QVERIFY(item0->hasActiveFocus() == true);
+    QVERIFY(item1->hasActiveFocus() == true);
+    QVERIFY(item2->hasActiveFocus() == false);
+    QVERIFY(item3->hasActiveFocus() == false);
+    QVERIFY(item4->hasActiveFocus() == false);
+    QVERIFY(item5->hasActiveFocus() == false);
+
+    QTest::keyClick(view, Qt::Key_4);
+    QVERIFY(item0->hasActiveFocus() == true);
+    QVERIFY(item1->hasActiveFocus() == true);
+    QVERIFY(item2->hasActiveFocus() == false);
+    QVERIFY(item3->hasActiveFocus() == false);
+    QVERIFY(item4->hasActiveFocus() == false);
+    QVERIFY(item5->hasActiveFocus() == false);
+
+    QTest::keyClick(view, Qt::Key_5);
+    QVERIFY(item0->hasActiveFocus() == false);
+    QVERIFY(item1->hasActiveFocus() == false);
+    QVERIFY(item2->hasActiveFocus() == false);
+    QVERIFY(item3->hasActiveFocus() == true);
+    QVERIFY(item4->hasActiveFocus() == false);
+    QVERIFY(item5->hasActiveFocus() == true);
+
+    delete view;
+}
+
+void tst_qquickfocusscope::noParentFocus()
+{
+    QQuickView *view = new QQuickView;
+    view->setSource(QUrl::fromLocalFile(TESTDATA("chain.qml")));
+    QVERIFY(view->rootObject());
+
+    view->show();
+    view->requestActivateWindow();
+    qApp->processEvents();
+
+#ifdef Q_WS_X11
+    // to be safe and avoid failing setFocus with window managers
+    qt_x11_wait_for_window_manager(view);
+#endif
+
+    QVERIFY(view->rootObject()->property("focus1") == false);
+    QVERIFY(view->rootObject()->property("focus2") == false);
+    QVERIFY(view->rootObject()->property("focus3") == true);
+    QVERIFY(view->rootObject()->property("focus4") == true);
+    QVERIFY(view->rootObject()->property("focus5") == true);
+
+    delete view;
+}
+
+void tst_qquickfocusscope::signalEmission()
+{
+    QQuickView *view = new QQuickView;
+    view->setSource(QUrl::fromLocalFile(TESTDATA("signalEmission.qml")));
+
+    QQuickRectangle *item1 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item1"));
+    QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2"));
+    QQuickRectangle *item3 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item3"));
+    QQuickRectangle *item4 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item4"));
+    QVERIFY(item1 != 0);
+    QVERIFY(item2 != 0);
+    QVERIFY(item3 != 0);
+    QVERIFY(item4 != 0);
+
+    view->show();
+    view->requestActivateWindow();
+
+    QTest::qWaitForWindowShown(view);
+
+    QVariant blue(QColor("blue"));
+    QVariant red(QColor("red"));
+
+    item1->setFocus(true);
+    QCOMPARE(item1->property("color"), red);
+    QCOMPARE(item2->property("color"), blue);
+    QCOMPARE(item3->property("color"), blue);
+    QCOMPARE(item4->property("color"), blue);
+
+    item2->setFocus(true);
+    QCOMPARE(item1->property("color"), blue);
+    QCOMPARE(item2->property("color"), red);
+    QCOMPARE(item3->property("color"), blue);
+    QCOMPARE(item4->property("color"), blue);
+
+    item3->setFocus(true);
+    QCOMPARE(item1->property("color"), blue);
+    QCOMPARE(item2->property("color"), red);
+    QCOMPARE(item3->property("color"), red);
+    QCOMPARE(item4->property("color"), blue);
+
+    item4->setFocus(true);
+    QCOMPARE(item1->property("color"), blue);
+    QCOMPARE(item2->property("color"), red);
+    QCOMPARE(item3->property("color"), blue);
+    QCOMPARE(item4->property("color"), red);
+
+    item4->setFocus(false);
+    QCOMPARE(item1->property("color"), blue);
+    QCOMPARE(item2->property("color"), red);
+    QCOMPARE(item3->property("color"), blue);
+    QCOMPARE(item4->property("color"), blue);
+
+    delete view;
+}
+
+void tst_qquickfocusscope::qtBug13380()
+{
+    QQuickView *view = new QQuickView;
+    view->setSource(QUrl::fromLocalFile(TESTDATA("qtBug13380.qml")));
+
+    view->show();
+    QVERIFY(view->rootObject());
+    view->requestActivateWindow();
+    qApp->processEvents();
+
+    QTest::qWaitForWindowShown(view);
+
+    QTRY_VERIFY(view == qGuiApp->focusWindow());
+    QVERIFY(view->rootObject()->property("noFocus").toBool());
+
+    view->rootObject()->setProperty("showRect", true);
+    QVERIFY(view->rootObject()->property("noFocus").toBool());
+
+    delete view;
+}
+
+void tst_qquickfocusscope::forceActiveFocus()
+{
+    QQuickView *view = new QQuickView;
+    view->setSource(QUrl::fromLocalFile(TESTDATA("forceActiveFocus.qml")));
+
+    view->show();
+    view->requestActivateWindow();
+    qApp->processEvents();
+
+#ifdef Q_WS_X11
+    // to be safe and avoid failing setFocus with window managers
+    qt_x11_wait_for_window_manager(view);
+#endif
+
+    QQuickItem *rootObject = view->rootObject();
+    QVERIFY(rootObject);
+
+    QQuickItem *scope = findItem<QQuickItem>(rootObject, QLatin1String("scope"));
+    QQuickItem *itemA1 = findItem<QQuickItem>(rootObject, QLatin1String("item-a1"));
+    QQuickItem *scopeA = findItem<QQuickItem>(rootObject, QLatin1String("scope-a"));
+    QQuickItem *itemA2 = findItem<QQuickItem>(rootObject, QLatin1String("item-a2"));
+    QQuickItem *itemB1 = findItem<QQuickItem>(rootObject, QLatin1String("item-b1"));
+    QQuickItem *scopeB = findItem<QQuickItem>(rootObject, QLatin1String("scope-b"));
+    QQuickItem *itemB2 = findItem<QQuickItem>(rootObject, QLatin1String("item-b2"));
+
+    QVERIFY(scope);
+    QVERIFY(itemA1);
+    QVERIFY(scopeA);
+    QVERIFY(itemA2);
+    QVERIFY(itemB1);
+    QVERIFY(scopeB);
+    QVERIFY(itemB2);
+
+    QSignalSpy rootSpy(rootObject, SIGNAL(activeFocusChanged(bool)));
+    QSignalSpy scopeSpy(scope, SIGNAL(activeFocusChanged(bool)));
+    QSignalSpy scopeASpy(scopeA, SIGNAL(activeFocusChanged(bool)));
+    QSignalSpy scopeBSpy(scopeB, SIGNAL(activeFocusChanged(bool)));
+
+    // First, walk the focus from item-a1 down to item-a2 and back again
+    itemA1->forceActiveFocus();
+    QVERIFY(itemA1->hasActiveFocus());
+    QVERIFY(!rootObject->hasActiveFocus());
+    QCOMPARE(rootSpy.count(), 0);
+    QCOMPARE(scopeSpy.count(), 1);
+
+    scopeA->forceActiveFocus();
+    QVERIFY(!itemA1->hasActiveFocus());
+    QVERIFY(scopeA->hasActiveFocus());
+    QCOMPARE(scopeASpy.count(), 1);
+    QCOMPARE(rootSpy.count(), 0);
+    QCOMPARE(scopeSpy.count(), 1);
+
+    itemA2->forceActiveFocus();
+    QVERIFY(!itemA1->hasActiveFocus());
+    QVERIFY(itemA2->hasActiveFocus());
+    QVERIFY(scopeA->hasActiveFocus());
+    QCOMPARE(scopeASpy.count(), 1);
+    QCOMPARE(rootSpy.count(), 0);
+    QCOMPARE(scopeSpy.count(), 1);
+
+    scopeA->forceActiveFocus();
+    QVERIFY(!itemA1->hasActiveFocus());
+    QVERIFY(itemA2->hasActiveFocus());
+    QVERIFY(scopeA->hasActiveFocus());
+    QCOMPARE(scopeASpy.count(), 1);
+    QCOMPARE(rootSpy.count(), 0);
+    QCOMPARE(scopeSpy.count(), 1);
+
+    itemA1->forceActiveFocus();
+    QVERIFY(itemA1->hasActiveFocus());
+    QVERIFY(!scopeA->hasActiveFocus());
+    QVERIFY(!itemA2->hasActiveFocus());
+    QCOMPARE(scopeASpy.count(), 2);
+    QCOMPARE(rootSpy.count(), 0);
+    QCOMPARE(scopeSpy.count(), 1);
+
+    // Then jump back and forth between branch 'a' and 'b'
+    itemB1->forceActiveFocus();
+    QVERIFY(itemB1->hasActiveFocus());
+    QCOMPARE(rootSpy.count(), 0);
+    QCOMPARE(scopeSpy.count(), 1);
+
+    scopeA->forceActiveFocus();
+    QVERIFY(!itemA1->hasActiveFocus());
+    QVERIFY(!itemB1->hasActiveFocus());
+    QVERIFY(scopeA->hasActiveFocus());
+    QCOMPARE(scopeASpy.count(), 3);
+    QCOMPARE(rootSpy.count(), 0);
+    QCOMPARE(scopeSpy.count(), 1);
+
+    scopeB->forceActiveFocus();
+    QVERIFY(!scopeA->hasActiveFocus());
+    QVERIFY(!itemB1->hasActiveFocus());
+    QVERIFY(scopeB->hasActiveFocus());
+    QCOMPARE(scopeASpy.count(), 4);
+    QCOMPARE(scopeBSpy.count(), 1);
+    QCOMPARE(rootSpy.count(), 0);
+    QCOMPARE(scopeSpy.count(), 1);
+
+    itemA2->forceActiveFocus();
+    QVERIFY(!scopeB->hasActiveFocus());
+    QVERIFY(itemA2->hasActiveFocus());
+    QCOMPARE(scopeASpy.count(), 5);
+    QCOMPARE(scopeBSpy.count(), 2);
+    QCOMPARE(rootSpy.count(), 0);
+    QCOMPARE(scopeSpy.count(), 1);
+
+    itemB2->forceActiveFocus();
+    QVERIFY(!itemA2->hasActiveFocus());
+    QVERIFY(itemB2->hasActiveFocus());
+    QCOMPARE(scopeASpy.count(), 6);
+    QCOMPARE(scopeBSpy.count(), 3);
+    QCOMPARE(rootSpy.count(), 0);
+    QCOMPARE(scopeSpy.count(), 1);
+
+    delete view;
+}
+
+void tst_qquickfocusscope::canvasFocus()
+{
+    QQuickView *view = new QQuickView;
+    view->setSource(QUrl::fromLocalFile(TESTDATA("canvasFocus.qml")));
+
+    QQuickItem *rootObject = view->rootObject();
+    QVERIFY(rootObject);
+
+    QQuickItem *rootItem = view->rootItem();
+    QQuickItem *scope1 = findItem<QQuickItem>(rootObject, QLatin1String("scope1"));
+    QQuickItem *item1 = findItem<QQuickItem>(rootObject, QLatin1String("item1"));
+    QQuickItem *scope2 = findItem<QQuickItem>(rootObject, QLatin1String("scope2"));
+    QQuickItem *item2 = findItem<QQuickItem>(rootObject, QLatin1String("item2"));
+
+    QVERIFY(scope1);
+    QVERIFY(item1);
+    QVERIFY(scope2);
+    QVERIFY(item2);
+
+    QSignalSpy rootFocusSpy(rootItem, SIGNAL(focusChanged(bool)));
+    QSignalSpy scope1FocusSpy(scope1, SIGNAL(focusChanged(bool)));
+    QSignalSpy item1FocusSpy(item1, SIGNAL(focusChanged(bool)));
+    QSignalSpy scope2FocusSpy(scope2, SIGNAL(focusChanged(bool)));
+    QSignalSpy item2FocusSpy(item2, SIGNAL(focusChanged(bool)));
+    QSignalSpy rootActiveFocusSpy(rootItem, SIGNAL(activeFocusChanged(bool)));
+    QSignalSpy scope1ActiveFocusSpy(scope1, SIGNAL(activeFocusChanged(bool)));
+    QSignalSpy item1ActiveFocusSpy(item1, SIGNAL(activeFocusChanged(bool)));
+    QSignalSpy scope2ActiveFocusSpy(scope2, SIGNAL(activeFocusChanged(bool)));
+    QSignalSpy item2ActiveFocusSpy(item2, SIGNAL(activeFocusChanged(bool)));
+
+    QEXPECT_FAIL("", "QTBUG-21054 - Root item hasFocus returns true already", Abort);
+
+    QCOMPARE(rootItem->hasFocus(), false);
+    QCOMPARE(rootItem->hasActiveFocus(), false);
+    QCOMPARE(scope1->hasFocus(), true);
+    QCOMPARE(scope1->hasActiveFocus(), false);
+    QCOMPARE(item1->hasFocus(), true);
+    QCOMPARE(item1->hasActiveFocus(), false);
+    QCOMPARE(scope2->hasFocus(), false);
+    QCOMPARE(scope2->hasActiveFocus(), false);
+    QCOMPARE(item2->hasFocus(), false);
+    QCOMPARE(item2->hasActiveFocus(), false);
+
+    view->show();
+    view->requestActivateWindow();
+
+    QTest::qWaitForWindowShown(view);
+
+    // Now the canvas has focus, active focus given to item1
+    QCOMPARE(rootItem->hasFocus(), true);
+    QCOMPARE(rootItem->hasActiveFocus(), true);
+    QCOMPARE(scope1->hasFocus(), true);
+    QCOMPARE(scope1->hasActiveFocus(), true);
+    QCOMPARE(item1->hasFocus(), true);
+    QCOMPARE(item1->hasActiveFocus(), true);
+    QCOMPARE(scope2->hasFocus(), false);
+    QCOMPARE(scope2->hasActiveFocus(), false);
+    QCOMPARE(item2->hasFocus(), false);
+    QCOMPARE(item2->hasActiveFocus(), false);
+    QCOMPARE(rootFocusSpy.count(), 1);
+    QCOMPARE(rootActiveFocusSpy.count(), 1);
+    QCOMPARE(scope1FocusSpy.count(), 0);
+    QCOMPARE(scope1ActiveFocusSpy.count(), 1);
+    QCOMPARE(item1FocusSpy.count(), 0);
+    QCOMPARE(item1ActiveFocusSpy.count(), 1);
+
+
+    view->hide();
+    QCOMPARE(rootItem->hasFocus(), false);
+    QCOMPARE(rootItem->hasActiveFocus(), false);
+    QCOMPARE(scope1->hasFocus(), true);
+    QCOMPARE(scope1->hasActiveFocus(), false);
+    QCOMPARE(item1->hasFocus(), true);
+    QCOMPARE(item1->hasActiveFocus(), false);
+    QCOMPARE(rootFocusSpy.count(), 2);
+    QCOMPARE(rootActiveFocusSpy.count(), 2);
+    QCOMPARE(scope1FocusSpy.count(), 0);
+    QCOMPARE(scope1ActiveFocusSpy.count(), 2);
+    QCOMPARE(item1FocusSpy.count(), 0);
+    QCOMPARE(item1ActiveFocusSpy.count(), 2);
+
+    // canvas does not have focus, so item2 will not get active focus
+    item2->forceActiveFocus();
+
+    QCOMPARE(rootItem->hasFocus(), false);
+    QCOMPARE(rootItem->hasActiveFocus(), false);
+    QCOMPARE(scope1->hasFocus(), false);
+    QCOMPARE(scope1->hasActiveFocus(), false);
+    QCOMPARE(item1->hasFocus(), true);
+    QCOMPARE(item1->hasActiveFocus(), false);
+    QCOMPARE(scope2->hasFocus(), true);
+    QCOMPARE(scope2->hasActiveFocus(), false);
+    QCOMPARE(item2->hasFocus(), true);
+    QCOMPARE(item2->hasActiveFocus(), false);
+
+    QCOMPARE(rootFocusSpy.count(), 2);
+    QCOMPARE(rootActiveFocusSpy.count(), 2);
+    QCOMPARE(scope1FocusSpy.count(), 1);
+    QCOMPARE(scope1ActiveFocusSpy.count(), 2);
+    QCOMPARE(item1FocusSpy.count(), 0);
+    QCOMPARE(item1ActiveFocusSpy.count(), 2);
+    QCOMPARE(scope2FocusSpy.count(), 1);
+    QCOMPARE(scope2ActiveFocusSpy.count(), 0);
+    QCOMPARE(item2FocusSpy.count(), 1);
+    QCOMPARE(item2ActiveFocusSpy.count(), 0);
+
+    // give the canvas focus, and item2 will get active focus
+    view->show();
+
+    QCOMPARE(rootItem->hasFocus(), true);
+    QCOMPARE(rootItem->hasActiveFocus(), true);
+    QCOMPARE(scope2->hasFocus(), true);
+    QCOMPARE(scope2->hasActiveFocus(), true);
+    QCOMPARE(item2->hasFocus(), true);
+    QCOMPARE(item2->hasActiveFocus(), true);
+    QCOMPARE(rootFocusSpy.count(), 3);
+    QCOMPARE(rootActiveFocusSpy.count(), 3);
+    QCOMPARE(scope2FocusSpy.count(), 1);
+    QCOMPARE(scope2ActiveFocusSpy.count(), 1);
+    QCOMPARE(item2FocusSpy.count(), 1);
+    QCOMPARE(item2ActiveFocusSpy.count(), 1);
+
+    delete view;
+}
+
+QTEST_MAIN(tst_qquickfocusscope)
+
+#include "tst_qquickfocusscope.moc"
diff --git a/tests/auto/declarative/qquickgridview/qquickgridview.pro b/tests/auto/declarative/qquickgridview/qquickgridview.pro
new file mode 100644 (file)
index 0000000..cf03024
--- /dev/null
@@ -0,0 +1,14 @@
+CONFIG += testcase
+TARGET = tst_qquickgridview
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qquickgridview.cpp
+
+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 testlib
diff --git a/tests/auto/declarative/qquickgridview/tst_qquickgridview.cpp b/tests/auto/declarative/qquickgridview/tst_qquickgridview.cpp
new file mode 100644 (file)
index 0000000..333398a
--- /dev/null
@@ -0,0 +1,3353 @@
+/****************************************************************************
+**
+** 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 <QtWidgets/qstringlistmodel.h>
+#include <QtDeclarative/qquickview.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qdeclarativeexpression.h>
+#include <QtDeclarative/private/qquickitem_p.h>
+#include <QtDeclarative/private/qlistmodelinterface_p.h>
+#include <QtDeclarative/private/qquickgridview_p.h>
+#include <QtDeclarative/private/qquicktext_p.h>
+#include <QtDeclarative/private/qdeclarativelistmodel_p.h>
+#include "../shared/util.h"
+#include <QtGui/qguiapplication.h>
+
+Q_DECLARE_METATYPE(Qt::LayoutDirection)
+Q_DECLARE_METATYPE(QQuickGridView::Flow)
+
+class tst_QQuickGridView : public QObject
+{
+    Q_OBJECT
+public:
+    tst_QQuickGridView();
+
+private slots:
+    void initTestCase();
+    void cleanupTestCase();
+    void items();
+    void changed();
+    void inserted();
+    void inserted_more();
+    void inserted_more_data();
+    void removed();
+    void clear();
+    void moved();
+    void moved_data();
+    void multipleChanges();
+    void multipleChanges_data();
+    void swapWithFirstItem();
+    void changeFlow();
+    void currentIndex();
+    void noCurrentIndex();
+    void defaultValues();
+    void properties();
+    void propertyChanges();
+    void componentChanges();
+    void modelChanges();
+    void positionViewAtIndex();
+    void positionViewAtIndex_rightToLeft();
+    void mirroring();
+    void snapping();
+    void resetModel();
+    void enforceRange();
+    void enforceRange_rightToLeft();
+    void QTBUG_8456();
+    void manualHighlight();
+    void footer();
+    void footer_data();
+    void header();
+    void header_data();
+    void resizeViewAndRepaint();
+    void indexAt();
+    void onAdd();
+    void onAdd_data();
+    void onRemove();
+    void onRemove_data();
+    void testQtQuick11Attributes();
+    void testQtQuick11Attributes_data();
+    void columnCount();
+    void margins();
+    void creationContext();
+    void snapToRow_data();
+    void snapToRow();
+
+private:
+    QQuickView *createView();
+    void flick(QQuickView *canvas, const QPoint &from, const QPoint &to, int duration);
+    template<typename T>
+    T *findItem(QQuickItem *parent, const QString &id, int index=-1);
+    template<typename T>
+    QList<T*> findItems(QQuickItem *parent, const QString &objectName);
+    void dumpTree(QQuickItem *parent, int depth = 0);
+};
+
+template<typename T>
+void tst_qquickgridview_move(int from, int to, int n, T *items)
+{
+    if (n == 1) {
+        items->move(from, to);
+    } else {
+        T replaced;
+        int i=0;
+        typename T::ConstIterator it=items->begin(); it += from+n;
+        for (; i<to-from; ++i,++it)
+            replaced.append(*it);
+        i=0;
+        it=items->begin(); it += from;
+        for (; i<n; ++i,++it)
+            replaced.append(*it);
+        typename T::ConstIterator f=replaced.begin();
+        typename T::Iterator t=items->begin(); t += from;
+        for (; f != replaced.end(); ++f, ++t)
+            *t = *f;
+    }
+}
+
+void tst_QQuickGridView::initTestCase()
+{
+}
+
+void tst_QQuickGridView::cleanupTestCase()
+{
+
+}
+
+
+class TestModel : public QAbstractListModel
+{
+public:
+    enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 };
+
+    TestModel(QObject *parent=0) : QAbstractListModel(parent) {
+        QHash<int, QByteArray> roles;
+        roles[Name] = "name";
+        roles[Number] = "number";
+        setRoleNames(roles);
+    }
+
+    int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); }
+    QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
+        QVariant rv;
+        if (role == Name)
+            rv = list.at(index.row()).first;
+        else if (role == Number)
+            rv = list.at(index.row()).second;
+
+        return rv;
+    }
+
+    int count() const { return rowCount(); }
+    QString name(int index) const { return list.at(index).first; }
+    QString number(int index) const { return list.at(index).second; }
+
+    void addItem(const QString &name, const QString &number) {
+        emit beginInsertRows(QModelIndex(), list.count(), list.count());
+        list.append(QPair<QString,QString>(name, number));
+        emit endInsertRows();
+    }
+
+    void addItems(const QList<QPair<QString, QString> > &items) {
+        emit beginInsertRows(QModelIndex(), list.count(), list.count()+items.count()-1);
+        for (int i=0; i<items.count(); i++)
+            list.append(QPair<QString,QString>(items[i].first, items[i].second));
+        emit endInsertRows();
+    }
+
+    void insertItem(int index, const QString &name, const QString &number) {
+        emit beginInsertRows(QModelIndex(), index, index);
+        list.insert(index, QPair<QString,QString>(name, number));
+        emit endInsertRows();
+    }
+
+    void insertItems(int index, const QList<QPair<QString, QString> > &items) {
+        emit beginInsertRows(QModelIndex(), index, index + items.count() - 1);
+        for (int i=0; i<items.count(); i++)
+            list.insert(index + i, QPair<QString,QString>(items[i].first, items[i].second));
+        emit endInsertRows();
+    }
+
+    void removeItem(int index) {
+        emit beginRemoveRows(QModelIndex(), index, index);
+        list.removeAt(index);
+        emit endRemoveRows();
+    }
+
+    void removeItems(int index, int count) {
+        emit beginRemoveRows(QModelIndex(), index, index+count-1);
+        while (count--)
+            list.removeAt(index);
+        emit endRemoveRows();
+    }
+
+    void moveItem(int from, int to) {
+        emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
+        list.move(from, to);
+        emit endMoveRows();
+    }
+
+    void moveItems(int from, int to, int count) {
+        emit beginMoveRows(QModelIndex(), from, from+count-1, QModelIndex(), to > from ? to+count : to);
+        tst_qquickgridview_move(from, to, count, &list);
+        emit endMoveRows();
+    }
+
+    void modifyItem(int idx, const QString &name, const QString &number) {
+        list[idx] = QPair<QString,QString>(name, number);
+        emit dataChanged(index(idx,0), index(idx,0));
+    }
+
+    void clear() {
+        int count = list.count();
+        emit beginRemoveRows(QModelIndex(), 0, count-1);
+        list.clear();
+        emit endRemoveRows();
+    }
+
+
+private:
+    QList<QPair<QString,QString> > list;
+};
+
+tst_QQuickGridView::tst_QQuickGridView()
+{
+}
+
+void tst_QQuickGridView::items()
+{
+    QQuickView *canvas = createView();
+
+    TestModel model;
+    model.addItem("Fred", "12345");
+    model.addItem("John", "2345");
+    model.addItem("Bob", "54321");
+    model.addItem("Billy", "22345");
+    model.addItem("Sam", "2945");
+    model.addItem("Ben", "04321");
+    model.addItem("Jim", "0780");
+
+    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();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+
+    QQuickItem *contentItem = gridview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QTRY_COMPARE(gridview->count(), model.count());
+    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
+    QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
+
+    for (int i = 0; i < model.count(); ++i) {
+        QQuickText *name = findItem<QQuickText>(contentItem, "textName", i);
+        QTRY_VERIFY(name != 0);
+        QTRY_COMPARE(name->text(), model.name(i));
+        QQuickText *number = findItem<QQuickText>(contentItem, "textNumber", i);
+        QTRY_VERIFY(number != 0);
+        QTRY_COMPARE(number->text(), model.number(i));
+    }
+
+    // set an empty model and confirm that items are destroyed
+    TestModel model2;
+    ctxt->setContextProperty("testModel", &model2);
+
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    QTRY_VERIFY(itemCount == 0);
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::changed()
+{
+    QQuickView *canvas = createView();
+
+    TestModel model;
+    model.addItem("Fred", "12345");
+    model.addItem("John", "2345");
+    model.addItem("Bob", "54321");
+    model.addItem("Billy", "22345");
+    model.addItem("Sam", "2945");
+    model.addItem("Ben", "04321");
+    model.addItem("Jim", "0780");
+
+    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();
+
+    QQuickFlickable *gridview = findItem<QQuickFlickable>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+
+    QQuickItem *contentItem = gridview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    model.modifyItem(1, "Will", "9876");
+    QQuickText *name = findItem<QQuickText>(contentItem, "textName", 1);
+    QTRY_VERIFY(name != 0);
+    QTRY_COMPARE(name->text(), model.name(1));
+    QQuickText *number = findItem<QQuickText>(contentItem, "textNumber", 1);
+    QTRY_VERIFY(number != 0);
+    QTRY_COMPARE(number->text(), model.number(1));
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::inserted()
+{
+    QQuickView *canvas = createView();
+    canvas->show();
+
+    TestModel model;
+    model.addItem("Fred", "12345");
+    model.addItem("John", "2345");
+    model.addItem("Bob", "54321");
+
+    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();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+
+    QQuickItem *contentItem = gridview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    model.insertItem(1, "Will", "9876");
+
+    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
+    QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
+
+    QQuickText *name = findItem<QQuickText>(contentItem, "textName", 1);
+    QTRY_VERIFY(name != 0);
+    QTRY_COMPARE(name->text(), model.name(1));
+    QQuickText *number = findItem<QQuickText>(contentItem, "textNumber", 1);
+    QTRY_VERIFY(number != 0);
+    QTRY_COMPARE(number->text(), model.number(1));
+
+    // Checks that onAdd is called
+    int added = canvas->rootObject()->property("added").toInt();
+    QTRY_COMPARE(added, 1);
+
+    // Confirm items positioned correctly
+    for (int i = 0; i < model.count(); ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        QTRY_COMPARE(item->x(), (i%3)*80.0);
+        QTRY_COMPARE(item->y(), (i/3)*60.0);
+    }
+
+    model.insertItem(0, "Foo", "1111"); // zero index, and current item
+
+    QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
+
+    name = findItem<QQuickText>(contentItem, "textName", 0);
+    QTRY_VERIFY(name != 0);
+    QTRY_COMPARE(name->text(), model.name(0));
+    number = findItem<QQuickText>(contentItem, "textNumber", 0);
+    QTRY_VERIFY(number != 0);
+    QTRY_COMPARE(number->text(), model.number(0));
+
+    QTRY_COMPARE(gridview->currentIndex(), 1);
+
+    // Confirm items positioned correctly
+    for (int i = 0; i < model.count(); ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        QTRY_VERIFY(item->x() == (i%3)*80);
+        QTRY_VERIFY(item->y() == (i/3)*60);
+    }
+
+    for (int i = model.count(); i < 30; ++i)
+        model.insertItem(i, "Hello", QString::number(i));
+
+    gridview->setContentY(120);
+
+    // Insert item outside visible area
+    model.insertItem(1, "Hello", "1324");
+
+    QTRY_VERIFY(gridview->contentY() == 120);
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::inserted_more()
+{
+    QFETCH(qreal, contentY);
+    QFETCH(int, insertIndex);
+    QFETCH(int, insertCount);
+    QFETCH(qreal, itemsOffsetAfterMove);
+
+    QQuickText *name;
+    QQuickText *number;
+    QQuickView *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();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+    QQuickItem *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
+    QQuickItem *item0 = findItem<QQuickItem>(contentItem, "wrapper", 0);
+    QVERIFY(item0);
+    QCOMPARE(item0->y(), itemsOffsetAfterMove);
+
+    QList<QQuickItem*> items = findItems<QQuickItem>(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<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(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<QQuickText>(contentItem, "textName", i);
+        QVERIFY(name != 0);
+        QCOMPARE(name->text(), model.name(i));
+        number = findItem<QQuickText>(contentItem, "textNumber", i);
+        QVERIFY(number != 0);
+        QCOMPARE(number->text(), model.number(i));
+    }
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::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_QQuickGridView::removed()
+{
+    QQuickView *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));
+    ctxt->setContextProperty("testTopToBottom", QVariant(false));
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
+    qApp->processEvents();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+
+    QQuickItem *contentItem = gridview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    model.removeItem(1);
+    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
+
+    QQuickText *name = findItem<QQuickText>(contentItem, "textName", 1);
+    QTRY_VERIFY(name != 0);
+    QTRY_COMPARE(name->text(), model.name(1));
+    QQuickText *number = findItem<QQuickText>(contentItem, "textNumber", 1);
+    QTRY_VERIFY(number != 0);
+    QTRY_COMPARE(number->text(), model.number(1));
+
+
+    // Checks that onRemove is called
+    QString removed = canvas->rootObject()->property("removed").toString();
+    QTRY_COMPARE(removed, QString("Item1"));
+
+    // Confirm items positioned correctly
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item->x() == (i%3)*80);
+        QTRY_VERIFY(item->y() == (i/3)*60);
+    }
+
+    // Remove first item (which is the current item);
+    model.removeItem(0);
+    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
+
+    name = findItem<QQuickText>(contentItem, "textName", 0);
+    QTRY_VERIFY(name != 0);
+    QTRY_COMPARE(name->text(), model.name(0));
+    number = findItem<QQuickText>(contentItem, "textNumber", 0);
+    QTRY_VERIFY(number != 0);
+    QTRY_COMPARE(number->text(), model.number(0));
+
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item->x() == (i%3)*80);
+        QTRY_VERIFY(item->y() == (i/3)*60);
+    }
+
+    // Remove items not visible
+    model.removeItem(25);
+    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item->x() == (i%3)*80);
+        QTRY_VERIFY(item->y() == (i/3)*60);
+    }
+
+    // Remove items before visible
+    gridview->setContentY(120);
+    gridview->setCurrentIndex(10);
+
+    // Setting currentIndex above shouldn't cause view to scroll
+    QTRY_COMPARE(gridview->contentY(), 120.0);
+
+    model.removeItem(1);
+    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
+
+    // Confirm items positioned correctly
+    for (int i = 6; i < 18; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item->x() == (i%3)*80);
+        QTRY_VERIFY(item->y() == (i/3)*60);
+    }
+
+    // Remove currentIndex
+    QQuickItem *oldCurrent = gridview->currentItem();
+    model.removeItem(9);
+    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
+
+    QTRY_COMPARE(gridview->currentIndex(), 9);
+    QTRY_VERIFY(gridview->currentItem() != oldCurrent);
+
+    gridview->setContentY(0);
+    // let transitions settle.
+    QTest::qWait(300);
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        QTRY_VERIFY(item->x() == (i%3)*80);
+        QTRY_VERIFY(item->y() == (i/3)*60);
+    }
+
+    // remove item outside current view.
+    gridview->setCurrentIndex(32);
+    gridview->setContentY(240);
+
+    model.removeItem(30);
+    QTRY_VERIFY(gridview->currentIndex() == 31);
+
+    // remove current item beyond visible items.
+    gridview->setCurrentIndex(20);
+    gridview->setContentY(0);
+    model.removeItem(20);
+
+    QTRY_COMPARE(gridview->currentIndex(), 20);
+    QTRY_VERIFY(gridview->currentItem() != 0);
+
+    // remove item before current, but visible
+    gridview->setCurrentIndex(8);
+    gridview->setContentY(240);
+    oldCurrent = gridview->currentItem();
+    model.removeItem(6);
+
+    QTRY_COMPARE(gridview->currentIndex(), 7);
+    QTRY_VERIFY(gridview->currentItem() == oldCurrent);
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::clear()
+{
+    QQuickView *canvas = createView();
+
+    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();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QVERIFY(gridview != 0);
+
+    QQuickItem *contentItem = gridview->contentItem();
+    QVERIFY(contentItem != 0);
+
+    model.clear();
+
+    QVERIFY(gridview->count() == 0);
+    QVERIFY(gridview->currentItem() == 0);
+    QVERIFY(gridview->contentY() == 0);
+    QVERIFY(gridview->currentIndex() == -1);
+
+    // confirm sanity when adding an item to cleared list
+    model.addItem("New", "1");
+    QTRY_COMPARE(gridview->count(), 1);
+    QVERIFY(gridview->currentItem() != 0);
+    QVERIFY(gridview->currentIndex() == 0);
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::moved()
+{
+    QFETCH(qreal, contentY);
+    QFETCH(int, from);
+    QFETCH(int, to);
+    QFETCH(int, count);
+    QFETCH(qreal, itemsOffsetAfterMove);
+
+    QQuickText *name;
+    QQuickText *number;
+    QQuickView *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();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+
+    QQuickItem *contentItem = gridview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QQuickItem *currentItem = gridview->currentItem();
+    QTRY_VERIFY(currentItem != 0);
+
+    gridview->setContentY(contentY);
+    model.moveItems(from, to, count);
+
+    // wait for items to move
+    QTest::qWait(300);
+
+    // Confirm items positioned correctly and indexes correct
+    int firstVisibleIndex = qCeil(contentY / 60.0) * 3;
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) {
+        if (i >= firstVisibleIndex + 18)    // index has moved out of view
+            continue;
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+
+        QTRY_COMPARE(item->x(), (i%3)*80.0);
+        QTRY_COMPARE(item->y(), (i/3)*60.0 + itemsOffsetAfterMove);
+
+        name = findItem<QQuickText>(contentItem, "textName", i);
+        QVERIFY(name != 0);
+        QTRY_COMPARE(name->text(), model.name(i));
+        number = findItem<QQuickText>(contentItem, "textNumber", i);
+        QVERIFY(number != 0);
+        QTRY_COMPARE(number->text(), model.number(i));
+
+        // current index should have been updated
+        if (item == currentItem)
+            QTRY_COMPARE(gridview->currentIndex(), i);
+    }
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::moved_data()
+{
+    QTest::addColumn<qreal>("contentY");
+    QTest::addColumn<int>("from");
+    QTest::addColumn<int>("to");
+    QTest::addColumn<int>("count");
+    QTest::addColumn<qreal>("itemsOffsetAfterMove");
+
+    // model starts with 30 items, each 80x60, in area 240x320
+    // 18 items should be visible at a time
+
+    QTest::newRow("move 1 forwards, within visible items")
+            << 0.0
+            << 1 << 8 << 1
+            << 0.0;
+
+    QTest::newRow("move 1 forwards, from non-visible -> visible")
+            << 120.0     // show 6-23
+            << 1 << 23 << 1
+            << 0.0;     // only 1 item was removed from the 1st row, so it doesn't move down
+
+    QTest::newRow("move 1 forwards, from non-visible -> visible (move first item)")
+            << 120.0     // // show 6-23
+            << 0 << 6 << 1
+            << 0.0;     // only 1 item was removed from the 1st row, so it doesn't move down
+
+    QTest::newRow("move 1 forwards, from visible -> non-visible")
+            << 0.0
+            << 1 << 20 << 1
+            << 0.0;
+
+    QTest::newRow("move 1 forwards, from visible -> non-visible (move first item)")
+            << 0.0
+            << 0 << 20 << 1
+            << 0.0;
+
+
+    QTest::newRow("move 1 backwards, within visible items")
+            << 0.0
+            << 10 << 5 << 1
+            << 0.0;
+
+    QTest::newRow("move 1 backwards, within visible items (to first index)")
+            << 0.0
+            << 10 << 0 << 1
+            << 0.0;
+
+    QTest::newRow("move 1 backwards, from non-visible -> visible")
+            << 0.0
+            << 28 << 8 << 1
+            << 0.0;
+
+    QTest::newRow("move 1 backwards, from non-visible -> visible (move last item)")
+            << 0.0
+            << 29 << 14 << 1
+            << 0.0;
+
+    QTest::newRow("move 1 backwards, from visible -> non-visible")
+            << 120.0     // show 6-23
+            << 7 << 1 << 1
+            << 0.0;     // only 1 item moved back, so items shift accordingly and first row doesn't move
+
+    QTest::newRow("move 1 backwards, from visible -> non-visible (move first item)")
+            << 120.0     // show 6-23
+            << 7 << 0 << 1
+            << 0.0;     // only 1 item moved back, so items shift accordingly and first row doesn't move
+
+
+    QTest::newRow("move multiple forwards, within visible items")
+            << 0.0
+            << 0 << 5 << 3
+            << 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
+            << 1 << 6 << 3
+            << 60.0; // 1st row (it's above visible area) disappears, 0 drops down 1 row, first visible item (6) stays where it is
+
+    QTest::newRow("move multiple forwards, from non-visible -> visible (move first item)")
+            << 120.0     // show 6-23
+            << 0 << 6 << 3
+            << 60.0;    // top row moved and shifted to below 3rd row, all items should shift down by 1 row
+
+    QTest::newRow("move multiple forwards, from visible -> non-visible")
+            << 0.0
+            << 1 << 16 << 3
+            << 0.0;
+
+    QTest::newRow("move multiple forwards, from visible -> non-visible (move first item)")
+            << 0.0
+            << 0 << 16 << 3
+            << 0.0;
+
+
+    QTest::newRow("move multiple backwards, within visible items")
+            << 0.0
+            << 4 << 1 << 3
+            << 0.0;
+
+    QTest::newRow("move multiple backwards, from non-visible -> visible")
+            << 0.0
+            << 20 << 4 << 3
+            << 0.0;
+
+    QTest::newRow("move multiple backwards, from non-visible -> visible (move last item)")
+            << 0.0
+            << 27 << 10 << 3
+            << 0.0;
+
+    QTest::newRow("move multiple backwards, from visible -> non-visible")
+            << 120.0     // show 6-23
+            << 16 << 1 << 3
+            << -60.0;   // to minimize movement, items are added above visible area, all items move up by 1 row
+
+    QTest::newRow("move multiple backwards, from visible -> non-visible (move first item)")
+            << 120.0     // show 6-23
+            << 16 << 0 << 3
+            << -60.0;   // 16,17,18 move to above item 0, all items move up by 1 row
+}
+
+struct ListChange {
+    enum { Inserted, Removed, Moved, SetCurrent } type;
+    int index;
+    int count;
+    int to;     // Move
+
+    static ListChange insert(int index, int count = 1) { ListChange c = { Inserted, index, count, -1 }; return c; }
+    static ListChange remove(int index, int count = 1) { ListChange c = { Removed, index, count, -1 }; return c; }
+    static ListChange move(int index, int to, int count) { ListChange c = { Moved, index, count, to }; return c; }
+    static ListChange setCurrent(int index) { ListChange c = { SetCurrent, index, -1, -1 }; return c; }
+};
+Q_DECLARE_METATYPE(QList<ListChange>)
+
+void tst_QQuickGridView::multipleChanges()
+{
+    QFETCH(int, startCount);
+    QFETCH(QList<ListChange>, changes);
+    QFETCH(int, newCount);
+    QFETCH(int, newCurrentIndex);
+
+    QQuickView *canvas = createView();
+    canvas->show();
+
+    TestModel model;
+    for (int i = 0; i < startCount; 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();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+
+    for (int i=0; i<changes.count(); i++) {
+        switch (changes[i].type) {
+            case ListChange::Inserted:
+            {
+                QList<QPair<QString, QString> > items;
+                for (int j=changes[i].index; j<changes[i].index + changes[i].count; ++j)
+                    items << qMakePair(QString("new item " + j), QString::number(j));
+                model.insertItems(changes[i].index, items);
+                break;
+            }
+            case ListChange::Removed:
+                model.removeItems(changes[i].index, changes[i].count);
+                break;
+            case ListChange::Moved:
+                model.moveItems(changes[i].index, changes[i].to, changes[i].count);
+                break;
+            case ListChange::SetCurrent:
+                gridview->setCurrentIndex(changes[i].index);
+                break;
+        }
+    }
+
+    QTRY_COMPARE(gridview->count(), newCount);
+    QCOMPARE(gridview->count(), model.count());
+    QTRY_COMPARE(gridview->currentIndex(), newCurrentIndex);
+
+    QQuickText *name;
+    QQuickText *number;
+    QQuickItem *contentItem = gridview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i=0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+        name = findItem<QQuickText>(contentItem, "textName", i);
+        QVERIFY(name != 0);
+        QTRY_COMPARE(name->text(), model.name(i));
+        number = findItem<QQuickText>(contentItem, "textNumber", i);
+        QVERIFY(number != 0);
+        QTRY_COMPARE(number->text(), model.number(i));
+    }
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::multipleChanges_data()
+{
+    QTest::addColumn<int>("startCount");
+    QTest::addColumn<QList<ListChange> >("changes");
+    QTest::addColumn<int>("newCount");
+    QTest::addColumn<int>("newCurrentIndex");
+
+    QList<ListChange> changes;
+
+    for (int i=1; i<30; i++)
+        changes << ListChange::remove(0);
+    QTest::newRow("remove all but 1, first->last") << 30 << changes << 1 << 0;
+
+    changes << ListChange::remove(0);
+    QTest::newRow("remove all") << 30 << changes << 0 << -1;
+
+    changes.clear();
+    changes << ListChange::setCurrent(29);
+    for (int i=29; i>0; i--)
+        changes << ListChange::remove(i);
+    QTest::newRow("remove last (current) -> first") << 30 << changes << 1 << 0;
+
+    QTest::newRow("remove then insert at 0") << 10 << (QList<ListChange>()
+            << ListChange::remove(0, 1)
+            << ListChange::insert(0, 1)
+            ) << 10 << 1;
+
+    QTest::newRow("remove then insert at non-zero index") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(2)
+            << ListChange::remove(2, 1)
+            << ListChange::insert(2, 1)
+            ) << 10 << 3;
+
+    QTest::newRow("remove current then insert below it") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(1)
+            << ListChange::remove(1, 3)
+            << ListChange::insert(2, 2)
+            ) << 9 << 1;
+
+    QTest::newRow("remove current index then move it down") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(2)
+            << ListChange::remove(1, 3)
+            << ListChange::move(1, 5, 1)
+            ) << 7 << 5;
+
+    QTest::newRow("remove current index then move it up") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(5)
+            << ListChange::remove(4, 3)
+            << ListChange::move(4, 1, 1)
+            ) << 7 << 1;
+
+
+    QTest::newRow("insert multiple times") << 0 << (QList<ListChange>()
+            << ListChange::insert(0, 2)
+            << ListChange::insert(0, 4)
+            << ListChange::insert(0, 6)
+            ) << 12 << 10;
+
+    QTest::newRow("insert multiple times with current index changes") << 0 << (QList<ListChange>()
+            << ListChange::insert(0, 2)
+            << ListChange::insert(0, 4)
+            << ListChange::insert(0, 6)
+            << ListChange::setCurrent(3)
+            << ListChange::insert(3, 2)
+            ) << 14 << 5;
+
+    QTest::newRow("insert and remove all") << 0 << (QList<ListChange>()
+            << ListChange::insert(0, 30)
+            << ListChange::remove(0, 30)
+            ) << 0 << -1;
+
+    QTest::newRow("insert and remove current") << 30 << (QList<ListChange>()
+            << ListChange::insert(1)
+            << ListChange::setCurrent(1)
+            << ListChange::remove(1)
+            ) << 30 << 1;
+
+    QTest::newRow("insert before 0, then remove cross section of new and old items") << 10 << (QList<ListChange>()
+            << ListChange::insert(0, 10)
+            << ListChange::remove(5, 10)
+            ) << 10 << 5;
+
+    QTest::newRow("insert multiple, then move new items to end") << 10 << (QList<ListChange>()
+            << ListChange::insert(0, 3)
+            << ListChange::move(0, 10, 3)
+            ) << 13 << 0;
+
+    QTest::newRow("insert multiple, then move new and some old items to end") << 10 << (QList<ListChange>()
+            << ListChange::insert(0, 3)
+            << ListChange::move(0, 8, 5)
+            ) << 13 << 11;
+
+    QTest::newRow("insert multiple at end, then move new and some old items to start") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(9)
+            << ListChange::insert(10, 3)
+            << ListChange::move(8, 0, 5)
+            ) << 13 << 1;
+
+
+    QTest::newRow("move back and forth to same index") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(1)
+            << ListChange::move(1, 2, 2)
+            << ListChange::move(2, 1, 2)
+            ) << 10 << 1;
+
+    QTest::newRow("move forwards then back") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(2)
+            << ListChange::move(1, 2, 3)
+            << ListChange::move(3, 0, 5)
+            ) << 10 << 0;
+
+    QTest::newRow("move current, then remove it") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(5)
+            << ListChange::move(5, 0, 1)
+            << ListChange::remove(0)
+            ) << 9 << 0;
+
+    QTest::newRow("move current, then insert before it") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(5)
+            << ListChange::move(5, 0, 1)
+            << ListChange::insert(0)
+            ) << 11 << 1;
+
+    QTest::newRow("move multiple, then remove them") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(1)
+            << ListChange::move(5, 1, 3)
+            << ListChange::remove(1, 3)
+            ) << 7 << 1;
+
+    QTest::newRow("move multiple, then insert before them") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(5)
+            << ListChange::move(5, 1, 3)
+            << ListChange::insert(1, 5)
+            ) << 15 << 6;
+
+    QTest::newRow("move multiple, then insert after them") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(3)
+            << ListChange::move(0, 1, 2)
+            << ListChange::insert(3, 5)
+            ) << 15 << 8;
+
+
+    QTest::newRow("clear current") << 0 << (QList<ListChange>()
+            << ListChange::insert(0, 5)
+            << ListChange::setCurrent(-1)
+            << ListChange::remove(0, 5)
+            << ListChange::insert(0, 5)
+            ) << 5 << -1;
+}
+
+
+void tst_QQuickGridView::swapWithFirstItem()
+{
+    // QTBUG_9697
+    QQuickView *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();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+
+    // ensure content position is stable
+    gridview->setContentY(0);
+    model.moveItem(10, 0);
+    QTRY_VERIFY(gridview->contentY() == 0);
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::currentIndex()
+{
+    TestModel model;
+    for (int i = 0; i < 60; i++)
+        model.addItem("Item" + QString::number(i), QString::number(i));
+
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setGeometry(0,0,240,320);
+    canvas->show();
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    QString filename(TESTDATA("gridview-initCurrent.qml"));
+    canvas->setSource(QUrl::fromLocalFile(filename));
+
+    qApp->processEvents();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QVERIFY(gridview != 0);
+
+    QQuickItem *contentItem = gridview->contentItem();
+    QVERIFY(contentItem != 0);
+
+    // current item should be third item
+    QCOMPARE(gridview->currentIndex(), 35);
+    QCOMPARE(gridview->currentItem(), findItem<QQuickItem>(contentItem, "wrapper", 35));
+    QCOMPARE(gridview->currentItem()->y(), gridview->highlightItem()->y());
+    QCOMPARE(gridview->contentY(), 400.0);
+
+    gridview->moveCurrentIndexRight();
+    QCOMPARE(gridview->currentIndex(), 36);
+    gridview->moveCurrentIndexDown();
+    QCOMPARE(gridview->currentIndex(), 39);
+    gridview->moveCurrentIndexUp();
+    QCOMPARE(gridview->currentIndex(), 36);
+    gridview->moveCurrentIndexLeft();
+    QCOMPARE(gridview->currentIndex(), 35);
+
+    // no wrap
+    gridview->setCurrentIndex(0);
+    QCOMPARE(gridview->currentIndex(), 0);
+    // confirm that the velocity is updated
+    QTRY_VERIFY(gridview->verticalVelocity() != 0.0);
+
+    gridview->moveCurrentIndexUp();
+    QCOMPARE(gridview->currentIndex(), 0);
+
+    gridview->moveCurrentIndexLeft();
+    QCOMPARE(gridview->currentIndex(), 0);
+
+    gridview->setCurrentIndex(model.count()-1);
+    QCOMPARE(gridview->currentIndex(), model.count()-1);
+
+    gridview->moveCurrentIndexRight();
+    QCOMPARE(gridview->currentIndex(), model.count()-1);
+
+    gridview->moveCurrentIndexDown();
+    QCOMPARE(gridview->currentIndex(), model.count()-1);
+
+    // with wrap
+    gridview->setWrapEnabled(true);
+
+    gridview->setCurrentIndex(0);
+    QCOMPARE(gridview->currentIndex(), 0);
+
+    gridview->moveCurrentIndexLeft();
+    QCOMPARE(gridview->currentIndex(), model.count()-1);
+
+    qApp->processEvents();
+    QTRY_COMPARE(gridview->contentY(), 880.0);
+
+    gridview->moveCurrentIndexRight();
+    QCOMPARE(gridview->currentIndex(), 0);
+
+    QTRY_COMPARE(gridview->contentY(), 0.0);
+
+
+    // footer should become visible if it is out of view, and then current index moves to the first row
+    canvas->rootObject()->setProperty("showFooter", true);
+    QTRY_VERIFY(gridview->footerItem());
+    gridview->setCurrentIndex(model.count()-3);
+    QTRY_VERIFY(gridview->footerItem()->y() > gridview->contentY() + gridview->height());
+    gridview->setCurrentIndex(model.count()-2);
+    QTRY_COMPARE(gridview->contentY() + gridview->height(), (60.0 * model.count()/3) + gridview->footerItem()->height());
+    canvas->rootObject()->setProperty("showFooter", false);
+
+    // header should become visible if it is out of view, and then current index moves to the last row
+    canvas->rootObject()->setProperty("showHeader", true);
+    QTRY_VERIFY(gridview->headerItem());
+    gridview->setCurrentIndex(3);
+    QTRY_VERIFY(gridview->headerItem()->y() + gridview->headerItem()->height() < gridview->contentY());
+    gridview->setCurrentIndex(1);
+    QTRY_COMPARE(gridview->contentY(), -gridview->headerItem()->height());
+    canvas->rootObject()->setProperty("showHeader", false);
+
+
+    // Test keys
+    canvas->requestActivateWindow();
+    QTest::qWaitForWindowShown(canvas);
+    QTRY_VERIFY(qGuiApp->focusWindow() == canvas);
+
+    gridview->setCurrentIndex(0);
+
+    QTest::keyClick(canvas, Qt::Key_Down);
+    QCOMPARE(gridview->currentIndex(), 3);
+
+    QTest::keyClick(canvas, Qt::Key_Up);
+    QCOMPARE(gridview->currentIndex(), 0);
+
+    // hold down Key_Down
+    for (int i=0; i<(model.count() / 3) - 1; i++) {
+        QTest::simulateEvent(canvas, true, Qt::Key_Down, Qt::NoModifier, "", true);
+        QTRY_COMPARE(gridview->currentIndex(), i*3 + 3);
+    }
+    QTest::keyRelease(canvas, Qt::Key_Down);
+    QTRY_COMPARE(gridview->currentIndex(), 57);
+    QTRY_COMPARE(gridview->contentY(), 880.0);
+
+    // hold down Key_Up
+    for (int i=(model.count() / 3) - 1; i > 0; i--) {
+        QTest::simulateEvent(canvas, true, Qt::Key_Up, Qt::NoModifier, "", true);
+        QTRY_COMPARE(gridview->currentIndex(), i*3 - 3);
+    }
+    QTest::keyRelease(canvas, Qt::Key_Up);
+    QTRY_COMPARE(gridview->currentIndex(), 0);
+    QTRY_COMPARE(gridview->contentY(), 0.0);
+
+
+    gridview->setFlow(QQuickGridView::TopToBottom);
+
+    canvas->requestActivateWindow();
+    QTest::qWaitForWindowShown(canvas);
+    QVERIFY(qGuiApp->focusWindow() == canvas);
+    qApp->processEvents();
+
+    QTest::keyClick(canvas, Qt::Key_Right);
+    QCOMPARE(gridview->currentIndex(), 5);
+
+    QTest::keyClick(canvas, Qt::Key_Left);
+    QCOMPARE(gridview->currentIndex(), 0);
+
+    QTest::keyClick(canvas, Qt::Key_Down);
+    QCOMPARE(gridview->currentIndex(), 1);
+
+    QTest::keyClick(canvas, Qt::Key_Up);
+    QCOMPARE(gridview->currentIndex(), 0);
+
+    // hold down Key_Right
+    for (int i=0; i<(model.count() / 5) - 1; i++) {
+        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);
+
+    // hold down Key_Left
+    for (int i=(model.count() / 5) - 1; i > 0; i--) {
+        QTest::simulateEvent(canvas, true, Qt::Key_Left, Qt::NoModifier, "", true);
+        QTRY_COMPARE(gridview->currentIndex(), i*5 - 5);
+    }
+    QTest::keyRelease(canvas, Qt::Key_Left);
+    QTRY_COMPARE(gridview->currentIndex(), 0);
+    QTRY_COMPARE(gridview->contentX(), 0.0);
+
+
+    // turn off auto highlight
+    gridview->setHighlightFollowsCurrentItem(false);
+    QVERIFY(gridview->highlightFollowsCurrentItem() == false);
+    QVERIFY(gridview->highlightItem());
+    qreal hlPosX = gridview->highlightItem()->x();
+    qreal hlPosY = gridview->highlightItem()->y();
+
+    gridview->setCurrentIndex(5);
+    QTRY_COMPARE(gridview->highlightItem()->x(), hlPosX);
+    QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY);
+
+    // insert item before currentIndex
+    gridview->setCurrentIndex(28);
+    model.insertItem(0, "Foo", "1111");
+    QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29);
+
+    // check removing highlight by setting currentIndex to -1;
+    gridview->setCurrentIndex(-1);
+
+    QCOMPARE(gridview->currentIndex(), -1);
+    QVERIFY(!gridview->highlightItem());
+    QVERIFY(!gridview->currentItem());
+
+    gridview->setHighlightFollowsCurrentItem(true);
+
+    gridview->setFlow(QQuickGridView::LeftToRight);
+    gridview->setLayoutDirection(Qt::RightToLeft);
+
+    canvas->requestActivateWindow();
+    QTest::qWaitForWindowShown(canvas);
+    QTRY_VERIFY(qGuiApp->focusWindow() == canvas);
+    qApp->processEvents();
+
+    gridview->setCurrentIndex(35);
+
+    QTest::keyClick(canvas, Qt::Key_Right);
+    QCOMPARE(gridview->currentIndex(), 34);
+
+    QTest::keyClick(canvas, Qt::Key_Down);
+    QCOMPARE(gridview->currentIndex(), 37);
+
+    QTest::keyClick(canvas, Qt::Key_Up);
+    QCOMPARE(gridview->currentIndex(), 34);
+
+    QTest::keyClick(canvas, Qt::Key_Left);
+    QCOMPARE(gridview->currentIndex(), 35);
+
+
+    // turn off auto highlight
+    gridview->setHighlightFollowsCurrentItem(false);
+    QVERIFY(gridview->highlightFollowsCurrentItem() == false);
+    QVERIFY(gridview->highlightItem());
+    hlPosX = gridview->highlightItem()->x();
+    hlPosY = gridview->highlightItem()->y();
+
+    gridview->setCurrentIndex(5);
+    QTRY_COMPARE(gridview->highlightItem()->x(), hlPosX);
+    QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY);
+
+    // insert item before currentIndex
+    gridview->setCurrentIndex(28);
+    model.insertItem(0, "Foo", "1111");
+    QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29);
+
+    // check removing highlight by setting currentIndex to -1;
+    gridview->setCurrentIndex(-1);
+
+    QCOMPARE(gridview->currentIndex(), -1);
+    QVERIFY(!gridview->highlightItem());
+    QVERIFY(!gridview->currentItem());
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::noCurrentIndex()
+{
+    TestModel model;
+    for (int i = 0; i < 60; i++)
+        model.addItem("Item" + QString::number(i), QString::number(i));
+
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setGeometry(0,0,240,320);
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    QString filename(TESTDATA("gridview-noCurrent.qml"));
+    canvas->setSource(QUrl::fromLocalFile(filename));
+
+    qApp->processEvents();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QVERIFY(gridview != 0);
+
+    QQuickItem *contentItem = gridview->contentItem();
+    QVERIFY(contentItem != 0);
+
+    // current index should be -1
+    QCOMPARE(gridview->currentIndex(), -1);
+    QVERIFY(!gridview->currentItem());
+    QVERIFY(!gridview->highlightItem());
+    QCOMPARE(gridview->contentY(), 0.0);
+
+    gridview->setCurrentIndex(5);
+    QCOMPARE(gridview->currentIndex(), 5);
+    QVERIFY(gridview->currentItem());
+    QVERIFY(gridview->highlightItem());
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::changeFlow()
+{
+    QQuickView *canvas = createView();
+
+    TestModel model;
+    for (int i = 0; i < 30; i++)
+        model.addItem("Item" + QString::number(i), 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();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+
+    QQuickItem *contentItem = gridview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    // Confirm items positioned correctly and indexes correct
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->x(), qreal((i%3)*80));
+        QTRY_COMPARE(item->y(), qreal((i/3)*60));
+        QQuickText *name = findItem<QQuickText>(contentItem, "textName", i);
+        QTRY_VERIFY(name != 0);
+        QTRY_COMPARE(name->text(), model.name(i));
+        QQuickText *number = findItem<QQuickText>(contentItem, "textNumber", i);
+        QTRY_VERIFY(number != 0);
+        QTRY_COMPARE(number->text(), model.number(i));
+    }
+
+    ctxt->setContextProperty("testTopToBottom", QVariant(true));
+
+    // Confirm items positioned correctly and indexes correct
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->x(), qreal((i/5)*80));
+        QTRY_COMPARE(item->y(), qreal((i%5)*60));
+        QQuickText *name = findItem<QQuickText>(contentItem, "textName", i);
+        QTRY_VERIFY(name != 0);
+        QTRY_COMPARE(name->text(), model.name(i));
+        QQuickText *number = findItem<QQuickText>(contentItem, "textNumber", i);
+        QTRY_VERIFY(number != 0);
+        QTRY_COMPARE(number->text(), model.number(i));
+    }
+
+    ctxt->setContextProperty("testRightToLeft", QVariant(true));
+
+    // Confirm items positioned correctly and indexes correct
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->x(), qreal(-(i/5)*80 - item->width()));
+        QTRY_COMPARE(item->y(), qreal((i%5)*60));
+        QQuickText *name = findItem<QQuickText>(contentItem, "textName", i);
+        QTRY_VERIFY(name != 0);
+        QTRY_COMPARE(name->text(), model.name(i));
+        QQuickText *number = findItem<QQuickText>(contentItem, "textNumber", i);
+        QTRY_VERIFY(number != 0);
+        QTRY_COMPARE(number->text(), model.number(i));
+    }
+    gridview->setContentX(100);
+    QTRY_COMPARE(gridview->contentX(), 100.);
+    ctxt->setContextProperty("testTopToBottom", QVariant(false));
+    QTRY_COMPARE(gridview->contentX(), 0.);
+
+    // Confirm items positioned correctly and indexes correct
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->x(), qreal(240 - (i%3+1)*80));
+        QTRY_COMPARE(item->y(), qreal((i/3)*60));
+        QQuickText *name = findItem<QQuickText>(contentItem, "textName", i);
+        QTRY_VERIFY(name != 0);
+        QTRY_COMPARE(name->text(), model.name(i));
+        QQuickText *number = findItem<QQuickText>(contentItem, "textNumber", i);
+        QTRY_VERIFY(number != 0);
+        QTRY_COMPARE(number->text(), model.number(i));
+    }
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::defaultValues()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("gridview3.qml")));
+    QQuickGridView *obj = qobject_cast<QQuickGridView*>(c.create());
+
+    QTRY_VERIFY(obj != 0);
+    QTRY_VERIFY(obj->model() == QVariant());
+    QTRY_VERIFY(obj->delegate() == 0);
+    QTRY_COMPARE(obj->currentIndex(), -1);
+    QTRY_VERIFY(obj->currentItem() == 0);
+    QTRY_COMPARE(obj->count(), 0);
+    QTRY_VERIFY(obj->highlight() == 0);
+    QTRY_VERIFY(obj->highlightItem() == 0);
+    QTRY_COMPARE(obj->highlightFollowsCurrentItem(), true);
+    QTRY_VERIFY(obj->flow() == 0);
+    QTRY_COMPARE(obj->isWrapEnabled(), false);
+    QTRY_COMPARE(obj->cacheBuffer(), 0);
+    QTRY_COMPARE(obj->cellWidth(), qreal(100)); //### Should 100 be the default?
+    QTRY_COMPARE(obj->cellHeight(), qreal(100));
+    delete obj;
+}
+
+void tst_QQuickGridView::properties()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("gridview2.qml")));
+    QQuickGridView *obj = qobject_cast<QQuickGridView*>(c.create());
+
+    QTRY_VERIFY(obj != 0);
+    QTRY_VERIFY(obj->model() != QVariant());
+    QTRY_VERIFY(obj->delegate() != 0);
+    QTRY_COMPARE(obj->currentIndex(), 0);
+    QTRY_VERIFY(obj->currentItem() != 0);
+    QTRY_COMPARE(obj->count(), 4);
+    QTRY_VERIFY(obj->highlight() != 0);
+    QTRY_VERIFY(obj->highlightItem() != 0);
+    QTRY_COMPARE(obj->highlightFollowsCurrentItem(), false);
+    QTRY_VERIFY(obj->flow() == 0);
+    QTRY_COMPARE(obj->isWrapEnabled(), true);
+    QTRY_COMPARE(obj->cacheBuffer(), 200);
+    QTRY_COMPARE(obj->cellWidth(), qreal(100));
+    QTRY_COMPARE(obj->cellHeight(), qreal(100));
+    delete obj;
+}
+
+void tst_QQuickGridView::propertyChanges()
+{
+    QQuickView *canvas = createView();
+    QTRY_VERIFY(canvas);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml")));
+
+    QQuickGridView *gridView = canvas->rootObject()->findChild<QQuickGridView*>("gridView");
+    QTRY_VERIFY(gridView);
+
+    QSignalSpy keyNavigationWrapsSpy(gridView, SIGNAL(keyNavigationWrapsChanged()));
+    QSignalSpy cacheBufferSpy(gridView, SIGNAL(cacheBufferChanged()));
+    QSignalSpy layoutSpy(gridView, SIGNAL(layoutDirectionChanged()));
+    QSignalSpy flowSpy(gridView, SIGNAL(flowChanged()));
+
+    QTRY_COMPARE(gridView->isWrapEnabled(), true);
+    QTRY_COMPARE(gridView->cacheBuffer(), 10);
+    QTRY_COMPARE(gridView->flow(), QQuickGridView::LeftToRight);
+
+    gridView->setWrapEnabled(false);
+    gridView->setCacheBuffer(3);
+    gridView->setFlow(QQuickGridView::TopToBottom);
+
+    QTRY_COMPARE(gridView->isWrapEnabled(), false);
+    QTRY_COMPARE(gridView->cacheBuffer(), 3);
+    QTRY_COMPARE(gridView->flow(), QQuickGridView::TopToBottom);
+
+    QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
+    QTRY_COMPARE(cacheBufferSpy.count(),1);
+    QTRY_COMPARE(flowSpy.count(),1);
+
+    gridView->setWrapEnabled(false);
+    gridView->setCacheBuffer(3);
+    gridView->setFlow(QQuickGridView::TopToBottom);
+
+    QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
+    QTRY_COMPARE(cacheBufferSpy.count(),1);
+    QTRY_COMPARE(flowSpy.count(),1);
+
+    gridView->setFlow(QQuickGridView::LeftToRight);
+    QTRY_COMPARE(gridView->flow(), QQuickGridView::LeftToRight);
+
+    gridView->setWrapEnabled(true);
+    gridView->setCacheBuffer(5);
+    gridView->setLayoutDirection(Qt::RightToLeft);
+
+    QTRY_COMPARE(gridView->isWrapEnabled(), true);
+    QTRY_COMPARE(gridView->cacheBuffer(), 5);
+    QTRY_COMPARE(gridView->layoutDirection(), Qt::RightToLeft);
+
+    QTRY_COMPARE(keyNavigationWrapsSpy.count(),2);
+    QTRY_COMPARE(cacheBufferSpy.count(),2);
+    QTRY_COMPARE(layoutSpy.count(),1);
+    QTRY_COMPARE(flowSpy.count(),2);
+
+    gridView->setWrapEnabled(true);
+    gridView->setCacheBuffer(5);
+    gridView->setLayoutDirection(Qt::RightToLeft);
+
+    QTRY_COMPARE(keyNavigationWrapsSpy.count(),2);
+    QTRY_COMPARE(cacheBufferSpy.count(),2);
+    QTRY_COMPARE(layoutSpy.count(),1);
+    QTRY_COMPARE(flowSpy.count(),2);
+
+    gridView->setFlow(QQuickGridView::TopToBottom);
+    QTRY_COMPARE(gridView->flow(), QQuickGridView::TopToBottom);
+    QTRY_COMPARE(flowSpy.count(),3);
+
+    gridView->setFlow(QQuickGridView::TopToBottom);
+    QTRY_COMPARE(flowSpy.count(),3);
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::componentChanges()
+{
+    QQuickView *canvas = createView();
+    QTRY_VERIFY(canvas);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml")));
+
+    QQuickGridView *gridView = canvas->rootObject()->findChild<QQuickGridView*>("gridView");
+    QTRY_VERIFY(gridView);
+
+    QDeclarativeComponent component(canvas->engine());
+    component.setData("import QtQuick 1.0; Rectangle { color: \"blue\"; }", QUrl::fromLocalFile(""));
+
+    QDeclarativeComponent delegateComponent(canvas->engine());
+    delegateComponent.setData("import QtQuick 1.0; Text { text: '<b>Name:</b> ' + name }", QUrl::fromLocalFile(""));
+
+    QSignalSpy highlightSpy(gridView, SIGNAL(highlightChanged()));
+    QSignalSpy delegateSpy(gridView, SIGNAL(delegateChanged()));
+    QSignalSpy headerSpy(gridView, SIGNAL(headerChanged()));
+    QSignalSpy footerSpy(gridView, SIGNAL(footerChanged()));
+
+    gridView->setHighlight(&component);
+    gridView->setDelegate(&delegateComponent);
+    gridView->setHeader(&component);
+    gridView->setFooter(&component);
+
+    QTRY_COMPARE(gridView->highlight(), &component);
+    QTRY_COMPARE(gridView->delegate(), &delegateComponent);
+    QTRY_COMPARE(gridView->header(), &component);
+    QTRY_COMPARE(gridView->footer(), &component);
+
+    QTRY_COMPARE(highlightSpy.count(),1);
+    QTRY_COMPARE(delegateSpy.count(),1);
+    QTRY_COMPARE(headerSpy.count(),1);
+    QTRY_COMPARE(footerSpy.count(),1);
+
+    gridView->setHighlight(&component);
+    gridView->setDelegate(&delegateComponent);
+    gridView->setHeader(&component);
+    gridView->setFooter(&component);
+
+    QTRY_COMPARE(highlightSpy.count(),1);
+    QTRY_COMPARE(delegateSpy.count(),1);
+    QTRY_COMPARE(headerSpy.count(),1);
+    QTRY_COMPARE(footerSpy.count(),1);
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::modelChanges()
+{
+    QQuickView *canvas = createView();
+    QTRY_VERIFY(canvas);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml")));
+
+    QQuickGridView *gridView = canvas->rootObject()->findChild<QQuickGridView*>("gridView");
+    QTRY_VERIFY(gridView);
+
+    QDeclarativeListModel *alternateModel = canvas->rootObject()->findChild<QDeclarativeListModel*>("alternateModel");
+    QTRY_VERIFY(alternateModel);
+    QVariant modelVariant = QVariant::fromValue<QObject *>(alternateModel);
+    QSignalSpy modelSpy(gridView, SIGNAL(modelChanged()));
+
+    gridView->setModel(modelVariant);
+    QTRY_COMPARE(gridView->model(), modelVariant);
+    QTRY_COMPARE(modelSpy.count(),1);
+
+    gridView->setModel(modelVariant);
+    QTRY_COMPARE(modelSpy.count(),1);
+
+    gridView->setModel(QVariant());
+    QTRY_COMPARE(modelSpy.count(),2);
+    delete canvas;
+}
+
+void tst_QQuickGridView::positionViewAtIndex()
+{
+    QQuickView *canvas = createView();
+
+    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));
+    ctxt->setContextProperty("testTopToBottom", QVariant(false));
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
+    qApp->processEvents();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+
+    QQuickItem *contentItem = gridview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    // Confirm items positioned correctly
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->x(), (i%3)*80.);
+        QTRY_COMPARE(item->y(), (i/3)*60.);
+    }
+
+    // Position on a currently visible item
+    gridview->positionViewAtIndex(4, QQuickGridView::Beginning);
+    QTRY_COMPARE(gridview->indexAt(120, 90), 4);
+    QTRY_COMPARE(gridview->contentY(), 60.);
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 3; i < model.count() && i < itemCount-3-1; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->x(), (i%3)*80.);
+        QTRY_COMPARE(item->y(), (i/3)*60.);
+    }
+
+    // Position on an item beyond the visible items
+    gridview->positionViewAtIndex(21, QQuickGridView::Beginning);
+    QTRY_COMPARE(gridview->indexAt(40, 450), 21);
+    QTRY_COMPARE(gridview->contentY(), 420.);
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 22; i < model.count() && i < itemCount-22-1; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->x(), (i%3)*80.);
+        QTRY_COMPARE(item->y(), (i/3)*60.);
+    }
+
+    // Position on an item that would leave empty space if positioned at the top
+    gridview->positionViewAtIndex(31, QQuickGridView::Beginning);
+    QTRY_COMPARE(gridview->indexAt(120, 630), 31);
+    QTRY_COMPARE(gridview->contentY(), 520.);
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 24; i < model.count() && i < itemCount-24-1; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->x(), (i%3)*80.);
+        QTRY_COMPARE(item->y(), (i/3)*60.);
+    }
+
+    // Position at the beginning again
+    gridview->positionViewAtIndex(0, QQuickGridView::Beginning);
+    QTRY_COMPARE(gridview->indexAt(0, 0), 0);
+    QTRY_COMPARE(gridview->indexAt(40, 30), 0);
+    QTRY_COMPARE(gridview->indexAt(80, 60), 4);
+    QTRY_COMPARE(gridview->contentY(), 0.);
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->x(), (i%3)*80.);
+        QTRY_COMPARE(item->y(), (i/3)*60.);
+    }
+
+    // Position at End
+    gridview->positionViewAtIndex(30, QQuickGridView::End);
+    QTRY_COMPARE(gridview->contentY(), 340.);
+
+    // Position in Center
+    gridview->positionViewAtIndex(15, QQuickGridView::Center);
+    QTRY_COMPARE(gridview->contentY(), 170.);
+
+    // Ensure at least partially visible
+    gridview->positionViewAtIndex(15, QQuickGridView::Visible);
+    QTRY_COMPARE(gridview->contentY(), 170.);
+
+    gridview->setContentY(302);
+    gridview->positionViewAtIndex(15, QQuickGridView::Visible);
+    QTRY_COMPARE(gridview->contentY(), 302.);
+
+    gridview->setContentY(360);
+    gridview->positionViewAtIndex(15, QQuickGridView::Visible);
+    QTRY_COMPARE(gridview->contentY(), 300.);
+
+    gridview->setContentY(60);
+    gridview->positionViewAtIndex(20, QQuickGridView::Visible);
+    QTRY_COMPARE(gridview->contentY(), 60.);
+
+    gridview->setContentY(20);
+    gridview->positionViewAtIndex(20, QQuickGridView::Visible);
+    QTRY_COMPARE(gridview->contentY(), 100.);
+
+    // Ensure completely visible
+    gridview->setContentY(120);
+    gridview->positionViewAtIndex(20, QQuickGridView::Contain);
+    QTRY_COMPARE(gridview->contentY(), 120.);
+
+    gridview->setContentY(302);
+    gridview->positionViewAtIndex(15, QQuickGridView::Contain);
+    QTRY_COMPARE(gridview->contentY(), 300.);
+
+    gridview->setContentY(60);
+    gridview->positionViewAtIndex(20, QQuickGridView::Contain);
+    QTRY_COMPARE(gridview->contentY(), 100.);
+
+    // Test for Top To Bottom layout
+    ctxt->setContextProperty("testTopToBottom", QVariant(true));
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->x(), (i/5)*80.);
+        QTRY_COMPARE(item->y(), (i%5)*60.);
+    }
+
+    // Position at End
+    gridview->positionViewAtIndex(30, QQuickGridView::End);
+    QTRY_COMPARE(gridview->contentX(), 320.);
+    QTRY_COMPARE(gridview->contentY(), 0.);
+
+    // Position in Center
+    gridview->positionViewAtIndex(15, QQuickGridView::Center);
+    QTRY_COMPARE(gridview->contentX(), 160.);
+
+    // Ensure at least partially visible
+    gridview->positionViewAtIndex(15, QQuickGridView::Visible);
+    QTRY_COMPARE(gridview->contentX(), 160.);
+
+    gridview->setContentX(170);
+    gridview->positionViewAtIndex(25, QQuickGridView::Visible);
+    QTRY_COMPARE(gridview->contentX(), 170.);
+
+    gridview->positionViewAtIndex(30, QQuickGridView::Visible);
+    QTRY_COMPARE(gridview->contentX(), 320.);
+
+    gridview->setContentX(170);
+    gridview->positionViewAtIndex(25, QQuickGridView::Contain);
+    QTRY_COMPARE(gridview->contentX(), 240.);
+
+    // positionViewAtBeginning
+    gridview->positionViewAtBeginning();
+    QTRY_COMPARE(gridview->contentX(), 0.);
+
+    gridview->setContentX(80);
+    canvas->rootObject()->setProperty("showHeader", true);
+    gridview->positionViewAtBeginning();
+    QTRY_COMPARE(gridview->contentX(), -30.);
+
+    // positionViewAtEnd
+    gridview->positionViewAtEnd();
+    QTRY_COMPARE(gridview->contentX(), 400.);   // 8*80 - 240   (8 columns)
+
+    gridview->setContentX(80);
+    canvas->rootObject()->setProperty("showFooter", true);
+    gridview->positionViewAtEnd();
+    QTRY_COMPARE(gridview->contentX(), 430.);
+
+    // set current item to outside visible view, position at beginning
+    // and ensure highlight moves to current item
+    gridview->setCurrentIndex(6);
+    gridview->positionViewAtBeginning();
+    QTRY_COMPARE(gridview->contentX(), -30.);
+    QVERIFY(gridview->highlightItem());
+    QCOMPARE(gridview->highlightItem()->x(), 80.);
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::snapping()
+{
+    QQuickView *canvas = createView();
+
+    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("testTopToBottom", QVariant(false));
+    ctxt->setContextProperty("testRightToLeft", QVariant(false));
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
+    qApp->processEvents();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+
+    gridview->setHeight(220);
+    QCOMPARE(gridview->height(), 220.);
+
+    gridview->positionViewAtIndex(12, QQuickGridView::Visible);
+    QCOMPARE(gridview->contentY(), 80.);
+
+    gridview->setContentY(0);
+    QCOMPARE(gridview->contentY(), 0.);
+
+    gridview->setSnapMode(QQuickGridView::SnapToRow);
+    QCOMPARE(gridview->snapMode(), QQuickGridView::SnapToRow);
+
+    gridview->positionViewAtIndex(12, QQuickGridView::Visible);
+    QCOMPARE(gridview->contentY(), 60.);
+
+    gridview->positionViewAtIndex(15, QQuickGridView::End);
+    QCOMPARE(gridview->contentY(), 120.);
+
+    delete canvas;
+
+}
+
+void tst_QQuickGridView::mirroring()
+{
+    QQuickView *canvasA = createView();
+    canvasA->setSource(QUrl::fromLocalFile(TESTDATA("mirroring.qml")));
+    QQuickGridView *gridviewA = findItem<QQuickGridView>(canvasA->rootObject(), "view");
+    QTRY_VERIFY(gridviewA != 0);
+
+    QQuickView *canvasB = createView();
+    canvasB->setSource(QUrl::fromLocalFile(TESTDATA("mirroring.qml")));
+    QQuickGridView *gridviewB = findItem<QQuickGridView>(canvasB->rootObject(), "view");
+    QTRY_VERIFY(gridviewA != 0);
+    qApp->processEvents();
+
+    QList<QString> objectNames;
+    objectNames << "item1" << "item2"; // << "item3"
+
+    gridviewA->setProperty("layoutDirection", Qt::LeftToRight);
+    gridviewB->setProperty("layoutDirection", Qt::RightToLeft);
+    QCOMPARE(gridviewA->layoutDirection(), gridviewA->effectiveLayoutDirection());
+
+    // LTR != RTL
+    foreach (const QString objectName, objectNames)
+        QVERIFY(findItem<QQuickItem>(gridviewA, objectName)->x() != findItem<QQuickItem>(gridviewB, objectName)->x());
+
+    gridviewA->setProperty("layoutDirection", Qt::LeftToRight);
+    gridviewB->setProperty("layoutDirection", Qt::LeftToRight);
+
+    // LTR == LTR
+    foreach (const QString objectName, objectNames)
+        QCOMPARE(findItem<QQuickItem>(gridviewA, objectName)->x(), findItem<QQuickItem>(gridviewB, objectName)->x());
+
+    QVERIFY(gridviewB->layoutDirection() == gridviewB->effectiveLayoutDirection());
+    QQuickItemPrivate::get(gridviewB)->setLayoutMirror(true);
+    QVERIFY(gridviewB->layoutDirection() != gridviewB->effectiveLayoutDirection());
+
+    // LTR != LTR+mirror
+    foreach (const QString objectName, objectNames)
+        QVERIFY(findItem<QQuickItem>(gridviewA, objectName)->x() != findItem<QQuickItem>(gridviewB, objectName)->x());
+
+    gridviewA->setProperty("layoutDirection", Qt::RightToLeft);
+
+    // RTL == LTR+mirror
+    foreach (const QString objectName, objectNames)
+        QCOMPARE(findItem<QQuickItem>(gridviewA, objectName)->x(), findItem<QQuickItem>(gridviewB, objectName)->x());
+
+    gridviewB->setProperty("layoutDirection", Qt::RightToLeft);
+
+    // RTL != RTL+mirror
+    foreach (const QString objectName, objectNames)
+        QVERIFY(findItem<QQuickItem>(gridviewA, objectName)->x() != findItem<QQuickItem>(gridviewB, objectName)->x());
+
+    gridviewA->setProperty("layoutDirection", Qt::LeftToRight);
+
+    // LTR == RTL+mirror
+    foreach (const QString objectName, objectNames)
+        QCOMPARE(findItem<QQuickItem>(gridviewA, objectName)->x(), findItem<QQuickItem>(gridviewB, objectName)->x());
+
+    delete canvasA;
+    delete canvasB;
+}
+
+void tst_QQuickGridView::positionViewAtIndex_rightToLeft()
+{
+    QQuickView *canvas = createView();
+
+    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("testTopToBottom", QVariant(true));
+    ctxt->setContextProperty("testRightToLeft", QVariant(true));
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
+    qApp->processEvents();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+
+    QQuickItem *contentItem = gridview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    // Confirm items positioned correctly
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
+        QTRY_COMPARE(item->y(), qreal((i%5)*60));
+    }
+
+    // Position on a currently visible item
+    gridview->positionViewAtIndex(6, QQuickGridView::Beginning);
+    QTRY_COMPARE(gridview->contentX(), -320.);
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 3; i < model.count() && i < itemCount-3-1; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
+        QTRY_COMPARE(item->y(), qreal((i%5)*60));
+    }
+
+    // Position on an item beyond the visible items
+    gridview->positionViewAtIndex(21, QQuickGridView::Beginning);
+    QTRY_COMPARE(gridview->contentX(), -560.);
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 22; i < model.count() && i < itemCount-22-1; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
+        QTRY_COMPARE(item->y(), qreal((i%5)*60));
+    }
+
+    // Position on an item that would leave empty space if positioned at the top
+    gridview->positionViewAtIndex(31, QQuickGridView::Beginning);
+    QTRY_COMPARE(gridview->contentX(), -640.);
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 24; i < model.count() && i < itemCount-24-1; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
+        QTRY_COMPARE(item->y(), qreal((i%5)*60));
+    }
+
+    // Position at the beginning again
+    gridview->positionViewAtIndex(0, QQuickGridView::Beginning);
+    QTRY_COMPARE(gridview->contentX(), -240.);
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
+        QTRY_COMPARE(item->y(), qreal((i%5)*60));
+    }
+
+    // Position at End
+    gridview->positionViewAtIndex(30, QQuickGridView::End);
+    QTRY_COMPARE(gridview->contentX(), -560.);
+
+    // Position in Center
+    gridview->positionViewAtIndex(15, QQuickGridView::Center);
+    QTRY_COMPARE(gridview->contentX(), -400.);
+
+    // Ensure at least partially visible
+    gridview->positionViewAtIndex(15, QQuickGridView::Visible);
+    QTRY_COMPARE(gridview->contentX(), -400.);
+
+    gridview->setContentX(-555.);
+    gridview->positionViewAtIndex(15, QQuickGridView::Visible);
+    QTRY_COMPARE(gridview->contentX(), -555.);
+
+    gridview->setContentX(-239);
+    gridview->positionViewAtIndex(15, QQuickGridView::Visible);
+    QTRY_COMPARE(gridview->contentX(), -320.);
+
+    gridview->setContentX(-239);
+    gridview->positionViewAtIndex(20, QQuickGridView::Visible);
+    QTRY_COMPARE(gridview->contentX(), -400.);
+
+    gridview->setContentX(-640);
+    gridview->positionViewAtIndex(20, QQuickGridView::Visible);
+    QTRY_COMPARE(gridview->contentX(), -560.);
+
+    // Ensure completely visible
+    gridview->setContentX(-400);
+    gridview->positionViewAtIndex(20, QQuickGridView::Contain);
+    QTRY_COMPARE(gridview->contentX(), -400.);
+
+    gridview->setContentX(-315);
+    gridview->positionViewAtIndex(15, QQuickGridView::Contain);
+    QTRY_COMPARE(gridview->contentX(), -320.);
+
+    gridview->setContentX(-640);
+    gridview->positionViewAtIndex(20, QQuickGridView::Contain);
+    QTRY_COMPARE(gridview->contentX(), -560.);
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::resetModel()
+{
+    QQuickView *canvas = createView();
+
+    QStringList strings;
+    strings << "one" << "two" << "three";
+    QStringListModel model(strings);
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaygrid.qml")));
+    qApp->processEvents();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+
+    QQuickItem *contentItem = gridview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QTRY_COMPARE(gridview->count(), model.rowCount());
+
+    for (int i = 0; i < model.rowCount(); ++i) {
+        QQuickText *display = findItem<QQuickText>(contentItem, "displayText", i);
+        QTRY_VERIFY(display != 0);
+        QTRY_COMPARE(display->text(), strings.at(i));
+    }
+
+    strings.clear();
+    strings << "four" << "five" << "six" << "seven";
+    model.setStringList(strings);
+
+    QTRY_COMPARE(gridview->count(), model.rowCount());
+
+    for (int i = 0; i < model.rowCount(); ++i) {
+        QQuickText *display = findItem<QQuickText>(contentItem, "displayText", i);
+        QTRY_VERIFY(display != 0);
+        QTRY_COMPARE(display->text(), strings.at(i));
+    }
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::enforceRange()
+{
+    QQuickView *canvas = createView();
+
+    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("gridview-enforcerange.qml")));
+    qApp->processEvents();
+    QVERIFY(canvas->rootObject() != 0);
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+
+    QTRY_COMPARE(gridview->preferredHighlightBegin(), 100.0);
+    QTRY_COMPARE(gridview->preferredHighlightEnd(), 100.0);
+    QTRY_COMPARE(gridview->highlightRangeMode(), QQuickGridView::StrictlyEnforceRange);
+
+    QQuickItem *contentItem = gridview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    // view should be positioned at the top of the range.
+    QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", 0);
+    QTRY_VERIFY(item);
+    QTRY_COMPARE(gridview->contentY(), -100.0);
+
+    QQuickText *name = findItem<QQuickText>(contentItem, "textName", 0);
+    QTRY_VERIFY(name != 0);
+    QTRY_COMPARE(name->text(), model.name(0));
+    QQuickText *number = findItem<QQuickText>(contentItem, "textNumber", 0);
+    QTRY_VERIFY(number != 0);
+    QTRY_COMPARE(number->text(), model.number(0));
+
+    // Check currentIndex is updated when contentItem moves
+    gridview->setContentY(0);
+    QTRY_COMPARE(gridview->currentIndex(), 2);
+
+    gridview->setCurrentIndex(5);
+    QTRY_COMPARE(gridview->contentY(), 100.);
+
+    TestModel model2;
+    for (int i = 0; i < 5; i++)
+        model2.addItem("Item" + QString::number(i), "");
+
+    ctxt->setContextProperty("testModel", &model2);
+    QCOMPARE(gridview->count(), 5);
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::enforceRange_rightToLeft()
+{
+    QQuickView *canvas = createView();
+
+    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(true));
+    ctxt->setContextProperty("testTopToBottom", QVariant(true));
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview-enforcerange.qml")));
+    qApp->processEvents();
+    QVERIFY(canvas->rootObject() != 0);
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+
+    QTRY_COMPARE(gridview->preferredHighlightBegin(), 100.0);
+    QTRY_COMPARE(gridview->preferredHighlightEnd(), 100.0);
+    QTRY_COMPARE(gridview->highlightRangeMode(), QQuickGridView::StrictlyEnforceRange);
+
+    QQuickItem *contentItem = gridview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    // view should be positioned at the top of the range.
+    QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", 0);
+    QTRY_VERIFY(item);
+    QTRY_COMPARE(gridview->contentX(), -100.);
+    QTRY_COMPARE(gridview->contentY(), 0.0);
+
+    QQuickText *name = findItem<QQuickText>(contentItem, "textName", 0);
+    QTRY_VERIFY(name != 0);
+    QTRY_COMPARE(name->text(), model.name(0));
+    QQuickText *number = findItem<QQuickText>(contentItem, "textNumber", 0);
+    QTRY_VERIFY(number != 0);
+    QTRY_COMPARE(number->text(), model.number(0));
+
+    // Check currentIndex is updated when contentItem moves
+    gridview->setContentX(-200);
+    QTRY_COMPARE(gridview->currentIndex(), 3);
+
+    gridview->setCurrentIndex(7);
+    QTRY_COMPARE(gridview->contentX(), -300.);
+    QTRY_COMPARE(gridview->contentY(), 0.0);
+
+    TestModel model2;
+    for (int i = 0; i < 5; i++)
+        model2.addItem("Item" + QString::number(i), "");
+
+    ctxt->setContextProperty("testModel", &model2);
+    QCOMPARE(gridview->count(), 5);
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::QTBUG_8456()
+{
+    QQuickView *canvas = createView();
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("setindex.qml")));
+    qApp->processEvents();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+
+    QTRY_COMPARE(gridview->currentIndex(), 0);
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::manualHighlight()
+{
+    QQuickView *canvas = createView();
+
+    QString filename(TESTDATA("manual-highlight.qml"));
+    canvas->setSource(QUrl::fromLocalFile(filename));
+
+    qApp->processEvents();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+
+    QQuickItem *contentItem = gridview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QTRY_COMPARE(gridview->currentIndex(), 0);
+    QTRY_COMPARE(gridview->currentItem(), findItem<QQuickItem>(contentItem, "wrapper", 0));
+    QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
+    QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
+
+    gridview->setCurrentIndex(2);
+
+    QTRY_COMPARE(gridview->currentIndex(), 2);
+    QTRY_COMPARE(gridview->currentItem(), findItem<QQuickItem>(contentItem, "wrapper", 2));
+    QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
+    QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
+
+    gridview->positionViewAtIndex(8, QQuickGridView::Contain);
+
+    QTRY_COMPARE(gridview->currentIndex(), 2);
+    QTRY_COMPARE(gridview->currentItem(), findItem<QQuickItem>(contentItem, "wrapper", 2));
+    QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
+    QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
+
+    gridview->setFlow(QQuickGridView::TopToBottom);
+    QTRY_COMPARE(gridview->flow(), QQuickGridView::TopToBottom);
+
+    gridview->setCurrentIndex(0);
+    QTRY_COMPARE(gridview->currentIndex(), 0);
+    QTRY_COMPARE(gridview->currentItem(), findItem<QQuickItem>(contentItem, "wrapper", 0));
+    QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
+    QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
+
+    delete canvas;
+}
+
+
+void tst_QQuickGridView::footer()
+{
+    QFETCH(QQuickGridView::Flow, flow);
+    QFETCH(Qt::LayoutDirection, layoutDirection);
+    QFETCH(QPointF, initialFooterPos);
+    QFETCH(QPointF, changedFooterPos);
+    QFETCH(QPointF, initialContentPos);
+    QFETCH(QPointF, changedContentPos);
+    QFETCH(QPointF, firstDelegatePos);
+    QFETCH(QPointF, resizeContentPos);
+
+    QQuickView *canvas = createView();
+    canvas->show();
+
+    TestModel model;
+    for (int i = 0; i < 7; i++)
+        model.addItem("Item" + QString::number(i), "");
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("footer.qml")));
+    qApp->processEvents();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+    gridview->setFlow(flow);
+    gridview->setLayoutDirection(layoutDirection);
+
+    QQuickItem *contentItem = gridview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QQuickText *footer = findItem<QQuickText>(contentItem, "footer");
+    QVERIFY(footer);
+
+    QVERIFY(footer == gridview->footerItem());
+
+    QCOMPARE(footer->pos(), initialFooterPos);
+    QCOMPARE(footer->width(), 100.);
+    QCOMPARE(footer->height(), 30.);
+    QCOMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos);
+
+    QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", 0);
+    QVERIFY(item);
+    QCOMPARE(item->pos(), firstDelegatePos);
+
+    if (flow == QQuickGridView::LeftToRight) {
+        // shrink by one row
+        model.removeItem(2);
+        QTRY_COMPARE(footer->y(), initialFooterPos.y() - gridview->cellHeight());
+    } else {
+        // shrink by one column
+        model.removeItem(2);
+        model.removeItem(3);
+        if (layoutDirection == Qt::LeftToRight)
+            QTRY_COMPARE(footer->x(), initialFooterPos.x() - gridview->cellWidth());
+        else
+            QTRY_COMPARE(footer->x(), initialFooterPos.x() + gridview->cellWidth());
+    }
+
+    // remove all items
+    model.clear();
+
+    QPointF posWhenNoItems(0, 0);
+    if (layoutDirection == Qt::RightToLeft)
+        posWhenNoItems.setX(flow == QQuickGridView::LeftToRight ? gridview->width() - footer->width() : -footer->width());
+    QTRY_COMPARE(footer->pos(), posWhenNoItems);
+
+    // if header is present, it's at a negative pos, so the footer should not move
+    canvas->rootObject()->setProperty("showHeader", true);
+    QVERIFY(findItem<QQuickItem>(contentItem, "header") != 0);
+    QTRY_COMPARE(footer->pos(), posWhenNoItems);
+    canvas->rootObject()->setProperty("showHeader", false);
+
+    // add 30 items
+    for (int i = 0; i < 30; i++)
+        model.addItem("Item" + QString::number(i), "");
+
+    QSignalSpy footerItemSpy(gridview, SIGNAL(footerItemChanged()));
+    QMetaObject::invokeMethod(canvas->rootObject(), "changeFooter");
+
+    QCOMPARE(footerItemSpy.count(), 1);
+
+    footer = findItem<QQuickText>(contentItem, "footer");
+    QVERIFY(!footer);
+    footer = findItem<QQuickText>(contentItem, "footer2");
+    QVERIFY(footer);
+
+    QVERIFY(footer == gridview->footerItem());
+
+    QCOMPARE(footer->pos(), changedFooterPos);
+    QCOMPARE(footer->width(), 50.);
+    QCOMPARE(footer->height(), 20.);
+    QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), changedContentPos);
+
+    item = findItem<QQuickItem>(contentItem, "wrapper", 0);
+    QVERIFY(item);
+    QCOMPARE(item->pos(), firstDelegatePos);
+
+    gridview->positionViewAtEnd();
+    footer->setHeight(10);
+    footer->setWidth(40);
+    QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), resizeContentPos);
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::footer_data()
+{
+    QTest::addColumn<QQuickGridView::Flow>("flow");
+    QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+    QTest::addColumn<QPointF>("initialFooterPos");
+    QTest::addColumn<QPointF>("changedFooterPos");
+    QTest::addColumn<QPointF>("initialContentPos");
+    QTest::addColumn<QPointF>("changedContentPos");
+    QTest::addColumn<QPointF>("firstDelegatePos");
+    QTest::addColumn<QPointF>("resizeContentPos");
+
+    // footer1 = 100 x 30
+    // footer2 = 50 x 20
+    // cells = 80 * 60
+    // view width = 240
+    // view height = 320
+
+    // footer below items, bottom left
+    QTest::newRow("flow left to right") << QQuickGridView::LeftToRight << Qt::LeftToRight
+        << QPointF(0, 3 * 60)  // 180 = height of 3 rows (cell height is 60)
+        << QPointF(0, 10 * 60)  // 30 items = 10 rows
+        << QPointF(0, 0)
+        << QPointF(0, 0)
+        << QPointF(0, 0)
+        << QPointF(0, 10 * 60 - 320 + 10);
+
+    // footer below items, bottom right
+    QTest::newRow("flow left to right, layout right to left") << QQuickGridView::LeftToRight << Qt::RightToLeft
+        << QPointF(240 - 100, 3 * 60)
+        << QPointF((240 - 100) + 50, 10 * 60)     // 50 = width diff between old and new footers
+        << QPointF(0, 0)
+        << QPointF(0, 0)
+        << QPointF(240 - 80, 0)
+        << QPointF(0, 10 * 60 - 320 + 10);
+
+    // footer to right of items
+    QTest::newRow("flow top to bottom, layout left to right") << QQuickGridView::TopToBottom << Qt::LeftToRight
+        << QPointF(2 * 80, 0)      // 2 columns, cell width 80
+        << QPointF(6 * 80, 0)      // 30 items = 6 columns
+        << QPointF(0, 0)
+        << QPointF(0, 0)
+        << QPointF(0, 0)
+        << QPointF(6 * 80 - 240 + 40, 0);
+
+    // footer to left of items
+    QTest::newRow("flow top to bottom, layout right to left") << QQuickGridView::TopToBottom << Qt::RightToLeft
+        << QPointF(-(2 * 80) - 100, 0)
+        << QPointF(-(6 * 80) - 50, 0)     // 50 = new footer width
+        << QPointF(-240, 0)
+        << QPointF(-240, 0)    // unchanged, footer change doesn't change content pos
+        << QPointF(-80, 0)
+        << QPointF(-(6 * 80) - 40, 0);
+}
+
+void tst_QQuickGridView::header()
+{
+    QFETCH(QQuickGridView::Flow, flow);
+    QFETCH(Qt::LayoutDirection, layoutDirection);
+    QFETCH(QPointF, initialHeaderPos);
+    QFETCH(QPointF, changedHeaderPos);
+    QFETCH(QPointF, initialContentPos);
+    QFETCH(QPointF, changedContentPos);
+    QFETCH(QPointF, firstDelegatePos);
+    QFETCH(QPointF, resizeContentPos);
+
+    TestModel model;
+    for (int i = 0; i < 30; i++)
+        model.addItem("Item" + QString::number(i), "");
+
+    QQuickView *canvas = createView();
+    canvas->rootContext()->setContextProperty("testModel", &model);
+    canvas->rootContext()->setContextProperty("initialViewWidth", 240);
+    canvas->rootContext()->setContextProperty("initialViewHeight", 320);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml")));
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+    gridview->setFlow(flow);
+    gridview->setLayoutDirection(layoutDirection);
+
+    QQuickItem *contentItem = gridview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QQuickText *header = findItem<QQuickText>(contentItem, "header");
+    QVERIFY(header);
+
+    QVERIFY(header == gridview->headerItem());
+
+    QCOMPARE(header->pos(), initialHeaderPos);
+    QCOMPARE(header->width(), 100.);
+    QCOMPARE(header->height(), 30.);
+    QCOMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos);
+
+    QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", 0);
+    QVERIFY(item);
+    QCOMPARE(item->pos(), firstDelegatePos);
+
+    model.clear();
+    QCOMPARE(header->pos(), initialHeaderPos); // header should stay where it is
+
+    for (int i = 0; i < 30; i++)
+        model.addItem("Item" + QString::number(i), "");
+
+    QSignalSpy headerItemSpy(gridview, SIGNAL(headerItemChanged()));
+    QMetaObject::invokeMethod(canvas->rootObject(), "changeHeader");
+
+    QCOMPARE(headerItemSpy.count(), 1);
+
+    header = findItem<QQuickText>(contentItem, "header");
+    QVERIFY(!header);
+    header = findItem<QQuickText>(contentItem, "header2");
+    QVERIFY(header);
+
+    QVERIFY(header == gridview->headerItem());
+
+    QCOMPARE(header->pos(), changedHeaderPos);
+    QCOMPARE(header->width(), 50.);
+    QCOMPARE(header->height(), 20.);
+    QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), changedContentPos);
+
+    item = findItem<QQuickItem>(contentItem, "wrapper", 0);
+    QVERIFY(item);
+    QCOMPARE(item->pos(), firstDelegatePos);
+
+    header->setHeight(10);
+    header->setWidth(40);
+    QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), resizeContentPos);
+
+    delete canvas;
+
+
+    // QTBUG-21207 header should become visible if view resizes from initial empty size
+
+    canvas = createView();
+    canvas->rootContext()->setContextProperty("testModel", &model);
+    canvas->rootContext()->setContextProperty("initialViewWidth", 240);
+    canvas->rootContext()->setContextProperty("initialViewHeight", 320);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml")));
+
+    gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+    gridview->setFlow(flow);
+    gridview->setLayoutDirection(layoutDirection);
+
+    gridview->setWidth(240);
+    gridview->setHeight(320);
+    QTRY_COMPARE(gridview->headerItem()->pos(), initialHeaderPos);
+    QCOMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos);
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::header_data()
+{
+    QTest::addColumn<QQuickGridView::Flow>("flow");
+    QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+    QTest::addColumn<QPointF>("initialHeaderPos");
+    QTest::addColumn<QPointF>("changedHeaderPos");
+    QTest::addColumn<QPointF>("initialContentPos");
+    QTest::addColumn<QPointF>("changedContentPos");
+    QTest::addColumn<QPointF>("firstDelegatePos");
+    QTest::addColumn<QPointF>("resizeContentPos");
+
+    // header1 = 100 x 30
+    // header2 = 50 x 20
+    // cells = 80 x 60
+    // view width = 240
+
+    // header above items, top left
+    QTest::newRow("flow left to right") << QQuickGridView::LeftToRight << Qt::LeftToRight
+        << QPointF(0, -30)
+        << QPointF(0, -20)
+        << QPointF(0, -30)
+        << QPointF(0, -20)
+        << QPointF(0, 0)
+        << QPointF(0, -10);
+
+    // header above items, top right
+    QTest::newRow("flow left to right, layout right to left") << QQuickGridView::LeftToRight << Qt::RightToLeft
+        << QPointF(240 - 100, -30)
+        << QPointF((240 - 100) + 50, -20)     // 50 = width diff between old and new headers
+        << QPointF(0, -30)
+        << QPointF(0, -20)
+        << QPointF(160, 0)
+        << QPointF(0, -10);
+
+    // header to left of items
+    QTest::newRow("flow top to bottom, layout left to right") << QQuickGridView::TopToBottom << Qt::LeftToRight
+        << QPointF(-100, 0)
+        << QPointF(-50, 0)
+        << QPointF(-100, 0)
+        << QPointF(-50, 0)
+        << QPointF(0, 0)
+        << QPointF(-40, 0);
+
+    // header to right of items
+    QTest::newRow("flow top to bottom, layout right to left") << QQuickGridView::TopToBottom << Qt::RightToLeft
+        << QPointF(0, 0)
+        << QPointF(0, 0)
+        << QPointF(-(240 - 100), 0)
+        << QPointF(-(240 - 50), 0)
+        << QPointF(-80, 0)
+        << QPointF(-(240 - 40), 0);
+}
+
+void tst_QQuickGridView::resizeViewAndRepaint()
+{
+    QQuickView *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();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+    QQuickItem *contentItem = gridview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    // item at index 10 should not be currently visible
+    QVERIFY(!findItem<QQuickItem>(contentItem, "wrapper", 10));
+
+    gridview->setHeight(320);
+    QTRY_VERIFY(findItem<QQuickItem>(contentItem, "wrapper", 10));
+
+    gridview->setHeight(100);
+    QTRY_VERIFY(!findItem<QQuickItem>(contentItem, "wrapper", 10));
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::indexAt()
+{
+    QQuickView *canvas = createView();
+
+    TestModel model;
+    model.addItem("Fred", "12345");
+    model.addItem("John", "2345");
+    model.addItem("Bob", "54321");
+    model.addItem("Billy", "22345");
+    model.addItem("Sam", "2945");
+    model.addItem("Ben", "04321");
+    model.addItem("Jim", "0780");
+
+    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();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+
+    QQuickItem *contentItem = gridview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QTRY_COMPARE(gridview->count(), model.count());
+
+    QCOMPARE(gridview->indexAt(0, 0), 0);
+    QCOMPARE(gridview->indexAt(79, 59), 0);
+    QCOMPARE(gridview->indexAt(80, 0), 1);
+    QCOMPARE(gridview->indexAt(0, 60), 3);
+    QCOMPARE(gridview->indexAt(240, 0), -1);
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::onAdd()
+{
+    QFETCH(int, initialItemCount);
+    QFETCH(int, itemsToAdd);
+
+    const int delegateWidth = 50;
+    const int delegateHeight = 100;
+    TestModel model;
+    QQuickView *canvas = createView();
+    canvas->setGeometry(0,0,5 * delegateWidth, 5 * delegateHeight); // just ensure all items fit
+
+    // these initial items should not trigger GridView.onAdd
+    for (int i=0; i<initialItemCount; i++)
+        model.addItem("dummy value", "dummy value");
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+    ctxt->setContextProperty("delegateWidth", delegateWidth);
+    ctxt->setContextProperty("delegateHeight", delegateHeight);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml")));
+
+    QObject *object = canvas->rootObject();
+    object->setProperty("width", canvas->width());
+    object->setProperty("height", canvas->height());
+    qApp->processEvents();
+
+    QList<QPair<QString, QString> > items;
+    for (int i=0; i<itemsToAdd; i++)
+        items << qMakePair(QString("value %1").arg(i), QString::number(i));
+    model.addItems(items);
+
+    QTRY_COMPARE(model.count(), qobject_cast<QQuickGridView*>(canvas->rootObject())->count());
+    qApp->processEvents();
+
+    QVariantList result = object->property("addedDelegates").toList();
+    QTRY_COMPARE(result.count(), items.count());
+    for (int i=0; i<items.count(); i++)
+        QCOMPARE(result[i].toString(), items[i].first);
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::onAdd_data()
+{
+    QTest::addColumn<int>("initialItemCount");
+    QTest::addColumn<int>("itemsToAdd");
+
+    QTest::newRow("0, add 1") << 0 << 1;
+    QTest::newRow("0, add 2") << 0 << 2;
+    QTest::newRow("0, add 10") << 0 << 10;
+
+    QTest::newRow("1, add 1") << 1 << 1;
+    QTest::newRow("1, add 2") << 1 << 2;
+    QTest::newRow("1, add 10") << 1 << 10;
+
+    QTest::newRow("5, add 1") << 5 << 1;
+    QTest::newRow("5, add 2") << 5 << 2;
+    QTest::newRow("5, add 10") << 5 << 10;
+}
+
+void tst_QQuickGridView::onRemove()
+{
+    QFETCH(int, initialItemCount);
+    QFETCH(int, indexToRemove);
+    QFETCH(int, removeCount);
+
+    const int delegateWidth = 50;
+    const int delegateHeight = 100;
+    TestModel model;
+    for (int i=0; i<initialItemCount; i++)
+        model.addItem(QString("value %1").arg(i), "dummy value");
+
+    QQuickView *canvas = createView();
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+    ctxt->setContextProperty("delegateWidth", delegateWidth);
+    ctxt->setContextProperty("delegateHeight", delegateHeight);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml")));
+    QObject *object = canvas->rootObject();
+
+    model.removeItems(indexToRemove, removeCount);
+    QTRY_COMPARE(model.count(), qobject_cast<QQuickGridView*>(canvas->rootObject())->count());
+    QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount));
+
+    delete canvas;
+}
+
+void tst_QQuickGridView::onRemove_data()
+{
+    QTest::addColumn<int>("initialItemCount");
+    QTest::addColumn<int>("indexToRemove");
+    QTest::addColumn<int>("removeCount");
+
+    QTest::newRow("remove first") << 1 << 0 << 1;
+    QTest::newRow("two items, remove first") << 2 << 0 << 1;
+    QTest::newRow("two items, remove last") << 2 << 1 << 1;
+    QTest::newRow("two items, remove all") << 2 << 0 << 2;
+
+    QTest::newRow("four items, remove first") << 4 << 0 << 1;
+    QTest::newRow("four items, remove 0-2") << 4 << 0 << 2;
+    QTest::newRow("four items, remove 1-3") << 4 << 1 << 2;
+    QTest::newRow("four items, remove 2-4") << 4 << 2 << 2;
+    QTest::newRow("four items, remove last") << 4 << 3 << 1;
+    QTest::newRow("four items, remove all") << 4 << 0 << 4;
+
+    QTest::newRow("ten items, remove 1-8") << 10 << 0 << 8;
+    QTest::newRow("ten items, remove 2-7") << 10 << 2 << 5;
+    QTest::newRow("ten items, remove 4-10") << 10 << 4 << 6;
+}
+
+void tst_QQuickGridView::testQtQuick11Attributes()
+{
+    QFETCH(QString, code);
+    QFETCH(QString, warning);
+    QFETCH(QString, error);
+
+    QDeclarativeEngine engine;
+    QObject *obj;
+
+    QDeclarativeComponent valid(&engine);
+    valid.setData("import QtQuick 1.1; GridView { " + code.toUtf8() + " }", QUrl(""));
+    obj = valid.create();
+    QVERIFY(obj);
+    QVERIFY(valid.errorString().isEmpty());
+    delete obj;
+
+    QDeclarativeComponent invalid(&engine);
+    invalid.setData("import QtQuick 1.0; GridView { " + code.toUtf8() + " }", QUrl(""));
+    QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
+    obj = invalid.create();
+    QCOMPARE(invalid.errorString(), error);
+    delete obj;
+}
+
+void tst_QQuickGridView::testQtQuick11Attributes_data()
+{
+    QTest::addColumn<QString>("code");
+    QTest::addColumn<QString>("warning");
+    QTest::addColumn<QString>("error");
+
+    QTest::newRow("positionViewAtBeginning") << "Component.onCompleted: positionViewAtBeginning()"
+        << "<Unknown File>:1: ReferenceError: Can't find variable: positionViewAtBeginning"
+        << "";
+
+    QTest::newRow("positionViewAtEnd") << "Component.onCompleted: positionViewAtEnd()"
+        << "<Unknown File>:1: ReferenceError: Can't find variable: positionViewAtEnd"
+        << "";
+}
+
+void tst_QQuickGridView::columnCount()
+{
+    QQuickView canvas;
+    canvas.setSource(QUrl::fromLocalFile(TESTDATA("gridview4.qml")));
+    canvas.show();
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&canvas);
+
+    QQuickGridView *view = qobject_cast<QQuickGridView*>(canvas.rootObject());
+
+    QCOMPARE(view->cellWidth(), qreal(405)/qreal(9));
+    QCOMPARE(view->cellHeight(), qreal(100));
+
+    QList<QQuickItem*> items = findItems<QQuickItem>(view, "delegate");
+    QCOMPARE(items.size(), 18);
+    QCOMPARE(items.at(8)->y(), qreal(0));
+    QCOMPARE(items.at(9)->y(), qreal(100));
+}
+
+void tst_QQuickGridView::margins()
+{
+    {
+        QQuickView *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();
+
+        QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+        QTRY_VERIFY(gridview != 0);
+
+        QQuickItem *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
+        QQuickView *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();
+
+        QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+        QTRY_VERIFY(gridview != 0);
+
+        QQuickItem *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_QQuickGridView::creationContext()
+{
+    QQuickView canvas;
+    canvas.setGeometry(0,0,240,320);
+    canvas.setSource(QUrl::fromLocalFile(TESTDATA("creationContext.qml")));
+    qApp->processEvents();
+
+    QQuickItem *rootItem = qobject_cast<QQuickItem *>(canvas.rootObject());
+    QVERIFY(rootItem);
+    QVERIFY(rootItem->property("count").toInt() > 0);
+
+    QQuickItem *item;
+    QVERIFY(item = rootItem->findChild<QQuickItem *>("listItem"));
+    QCOMPARE(item->property("text").toString(), QString("Hello!"));
+    QVERIFY(item = rootItem->findChild<QQuickItem *>("header"));
+    QCOMPARE(item->property("text").toString(), QString("Hello!"));
+    QVERIFY(item = rootItem->findChild<QQuickItem *>("footer"));
+    QCOMPARE(item->property("text").toString(), QString("Hello!"));
+}
+
+void tst_QQuickGridView::snapToRow_data()
+{
+    QTest::addColumn<QQuickGridView::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") << QQuickGridView::LeftToRight << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
+        << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 1200.0 << 0.0;
+
+    QTest::newRow("horizontal, left to right") << QQuickGridView::TopToBottom << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
+        << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 1200.0 << 0.0;
+
+    QTest::newRow("horizontal, right to left") << QQuickGridView::TopToBottom << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange)
+        << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -1200.0 - 240.0 << -240.0;
+
+    QTest::newRow("vertical, left to right, enforce range") << QQuickGridView::LeftToRight << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
+        << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 1340.0 << -20.0;
+
+    QTest::newRow("horizontal, left to right, enforce range") << QQuickGridView::TopToBottom << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
+        << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 1340.0 << -20.0;
+
+    QTest::newRow("horizontal, right to left, enforce range") << QQuickGridView::TopToBottom << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange)
+        << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -1200.0 - 240.0 - 140.0 << -220.0;
+}
+
+void tst_QQuickGridView::snapToRow()
+{
+    QFETCH(QQuickGridView::Flow, flow);
+    QFETCH(Qt::LayoutDirection, layoutDirection);
+    QFETCH(int, highlightRangeMode);
+    QFETCH(QPoint, flickStart);
+    QFETCH(QPoint, flickEnd);
+    QFETCH(qreal, snapAlignment);
+    QFETCH(qreal, endExtent);
+    QFETCH(qreal, startExtent);
+
+    QQuickView *canvas = createView();
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("snapToRow.qml")));
+    canvas->show();
+    qApp->processEvents();
+
+    QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+    QTRY_VERIFY(gridview != 0);
+
+    gridview->setFlow(flow);
+    gridview->setLayoutDirection(layoutDirection);
+    gridview->setHighlightRangeMode(QQuickItemView::HighlightRangeMode(highlightRangeMode));
+
+    QQuickItem *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 == QQuickGridView::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 == QQuickGridView::LeftToRight
+           ? !gridview->isAtYEnd()
+           : layoutDirection == Qt::LeftToRight ? !gridview->isAtXEnd() : !gridview->isAtXBeginning());
+
+    if (flow == QQuickGridView::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 == QQuickGridView::LeftToRight
+           ? !gridview->isAtYBeginning()
+           : layoutDirection == Qt::LeftToRight ? !gridview->isAtXBeginning() : !gridview->isAtXEnd());
+
+    if (flow == QQuickGridView::LeftToRight)
+        QCOMPARE(gridview->contentY(), startExtent);
+    else
+        QCOMPARE(gridview->contentX(), startExtent);
+
+    delete canvas;
+}
+
+
+QQuickView *tst_QQuickGridView::createView()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setGeometry(0,0,240,320);
+
+    return canvas;
+}
+
+void tst_QQuickGridView::flick(QQuickView *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
+*/
+template<typename T>
+T *tst_QQuickGridView::findItem(QQuickItem *parent, const QString &objectName, int index)
+{
+    const QMetaObject &mo = T::staticMetaObject;
+    //qDebug() << parent->childItems().count() << "children";
+    for (int i = 0; i < parent->childItems().count(); ++i) {
+        QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
+        if (!item)
+            continue;
+        //qDebug() << "try" << item;
+        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
+            if (index != -1) {
+                QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item);
+                if (context) {
+                    if (context->contextProperty("index").toInt() == index) {
+                        return static_cast<T*>(item);
+                    }
+                }
+            } else {
+                return static_cast<T*>(item);
+            }
+        }
+        item = findItem<T>(item, objectName, index);
+        if (item)
+            return static_cast<T*>(item);
+    }
+
+    return 0;
+}
+
+template<typename T>
+QList<T*> tst_QQuickGridView::findItems(QQuickItem *parent, const QString &objectName)
+{
+    QList<T*> items;
+    const QMetaObject &mo = T::staticMetaObject;
+    //qDebug() << parent->childItems().count() << "children";
+    for (int i = 0; i < parent->childItems().count(); ++i) {
+        QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
+        if (!item)
+            continue;
+        //qDebug() << "try" << item;
+        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
+            items.append(static_cast<T*>(item));
+            //qDebug() << " found:" << item;
+        }
+        items += findItems<T>(item, objectName);
+    }
+
+    return items;
+}
+
+void tst_QQuickGridView::dumpTree(QQuickItem *parent, int depth)
+{
+    static QString padding("                       ");
+    for (int i = 0; i < parent->childItems().count(); ++i) {
+        QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
+        if (!item)
+            continue;
+        QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item);
+        qDebug() << padding.left(depth*2) << item << (context ? context->contextProperty("index").toInt() : -1);
+        dumpTree(item, depth+1);
+    }
+}
+
+
+QTEST_MAIN(tst_QQuickGridView)
+
+#include "tst_qquickgridview.moc"
+
diff --git a/tests/auto/declarative/qquickimage/qquickimage.pro b/tests/auto/declarative/qquickimage/qquickimage.pro
new file mode 100644 (file)
index 0000000..46cbdb4
--- /dev/null
@@ -0,0 +1,13 @@
+CONFIG += testcase
+TARGET = tst_qquickimage
+macx:CONFIG -= app_bundle
+
+HEADERS += ../shared/testhttpserver.h
+SOURCES += tst_qquickimage.cpp ../shared/testhttpserver.cpp
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qquickimage/tst_qquickimage.cpp b/tests/auto/declarative/qquickimage/tst_qquickimage.cpp
new file mode 100644 (file)
index 0000000..3d7ee07
--- /dev/null
@@ -0,0 +1,689 @@
+/****************************************************************************
+**
+** 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 <QTextDocument>
+#include <QTcpServer>
+#include <QTcpSocket>
+#include <QDir>
+
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qquickview.h>
+#include <private/qquickimage_p.h>
+#include <private/qquickimagebase_p.h>
+#include <private/qquickloader_p.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qdeclarativeexpression.h>
+#include <QtTest/QSignalSpy>
+#include <QtGui/QPainter>
+#include <QtGui/QImageReader>
+
+#include "../shared/util.h"
+#include "../shared/testhttpserver.h"
+
+#define SERVER_PORT 14451
+#define SERVER_ADDR "http://127.0.0.1:14451"
+
+class tst_qquickimage : public QObject
+{
+    Q_OBJECT
+public:
+    tst_qquickimage();
+
+private slots:
+    void noSource();
+    void imageSource();
+    void imageSource_data();
+    void clearSource();
+    void resized();
+    void preserveAspectRatio();
+    void smooth();
+    void mirror();
+    void svg();
+    void geometry();
+    void geometry_data();
+    void big();
+    void tiling_QTBUG_6716();
+    void tiling_QTBUG_6716_data();
+    void noLoading();
+    void paintedWidthHeight();
+    void sourceSize_QTBUG_14303();
+    void sourceSize_QTBUG_16389();
+    void nullPixmapPaint();
+
+private:
+    template<typename T>
+    T *findItem(QQuickItem *parent, const QString &id, int index=-1);
+
+    QDeclarativeEngine engine;
+};
+
+tst_qquickimage::tst_qquickimage()
+{
+}
+
+void tst_qquickimage::noSource()
+{
+    QString componentStr = "import QtQuick 2.0\nImage { source: \"\" }";
+    QDeclarativeComponent component(&engine);
+    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
+    QVERIFY(obj != 0);
+    QCOMPARE(obj->source(), QUrl());
+    QVERIFY(obj->status() == QQuickImage::Null);
+    QCOMPARE(obj->width(), 0.);
+    QCOMPARE(obj->height(), 0.);
+    QCOMPARE(obj->fillMode(), QQuickImage::Stretch);
+    QCOMPARE(obj->progress(), 0.0);
+
+    delete obj;
+}
+
+void tst_qquickimage::imageSource_data()
+{
+    QTest::addColumn<QString>("source");
+    QTest::addColumn<double>("width");
+    QTest::addColumn<double>("height");
+    QTest::addColumn<bool>("remote");
+    QTest::addColumn<bool>("async");
+    QTest::addColumn<bool>("cache");
+    QTest::addColumn<QString>("error");
+
+    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 << "";
+    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";
+
+}
+
+void tst_qquickimage::imageSource()
+{
+    QFETCH(QString, source);
+    QFETCH(double, width);
+    QFETCH(double, height);
+    QFETCH(bool, remote);
+    QFETCH(bool, async);
+    QFETCH(bool, cache);
+    QFETCH(QString, error);
+
+    TestHTTPServer server(SERVER_PORT);
+    if (remote) {
+        QVERIFY(server.isValid());
+        server.serveDirectory(TESTDATA(""));
+        server.addRedirect("oldcolors.png", SERVER_ADDR "/colors.png");
+    }
+
+    if (!error.isEmpty())
+        QTest::ignoreMessage(QtWarningMsg, error.toUtf8());
+
+    QString componentStr = "import QtQuick 2.0\nImage { source: \"" + source + "\"; asynchronous: "
+        + (async ? QLatin1String("true") : QLatin1String("false")) + "; cache: "
+        + (cache ? QLatin1String("true") : QLatin1String("false")) + " }";
+    QDeclarativeComponent component(&engine);
+    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
+    QVERIFY(obj != 0);
+
+    if (async)
+        QVERIFY(obj->asynchronous() == true);
+    else
+        QVERIFY(obj->asynchronous() == false);
+
+    if (cache)
+        QVERIFY(obj->cache() == true);
+    else
+        QVERIFY(obj->cache() == false);
+
+    if (remote || async)
+        QTRY_VERIFY(obj->status() == QQuickImage::Loading);
+
+    QCOMPARE(obj->source(), remote ? source : QUrl(source));
+
+    if (error.isEmpty()) {
+        QTRY_VERIFY(obj->status() == QQuickImage::Ready);
+        QCOMPARE(obj->width(), qreal(width));
+        QCOMPARE(obj->height(), qreal(height));
+        QCOMPARE(obj->fillMode(), QQuickImage::Stretch);
+        QCOMPARE(obj->progress(), 1.0);
+    } else {
+        QTRY_VERIFY(obj->status() == QQuickImage::Error);
+    }
+
+    delete obj;
+}
+
+void tst_qquickimage::clearSource()
+{
+    QString componentStr = "import QtQuick 2.0\nImage { source: srcImage }";
+    QDeclarativeContext *ctxt = engine.rootContext();
+    ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("colors.png")));
+    QDeclarativeComponent component(&engine);
+    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
+    QVERIFY(obj != 0);
+    QVERIFY(obj->status() == QQuickImage::Ready);
+    QCOMPARE(obj->width(), 120.);
+    QCOMPARE(obj->height(), 120.);
+    QCOMPARE(obj->progress(), 1.0);
+
+    ctxt->setContextProperty("srcImage", "");
+    QVERIFY(obj->source().isEmpty());
+    QVERIFY(obj->status() == QQuickImage::Null);
+    QCOMPARE(obj->width(), 0.);
+    QCOMPARE(obj->height(), 0.);
+    QCOMPARE(obj->progress(), 0.0);
+
+    delete obj;
+}
+
+void tst_qquickimage::resized()
+{
+    QString componentStr = "import QtQuick 2.0\nImage { source: \"" + TESTDATA("colors.png") + "\"; width: 300; height: 300 }";
+    QDeclarativeComponent component(&engine);
+    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
+    QVERIFY(obj != 0);
+    QCOMPARE(obj->width(), 300.);
+    QCOMPARE(obj->height(), 300.);
+    QCOMPARE(obj->fillMode(), QQuickImage::Stretch);
+    delete obj;
+}
+
+
+void tst_qquickimage::preserveAspectRatio()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->show();
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("aspectratio.qml")));
+    QQuickImage *image = qobject_cast<QQuickImage*>(canvas->rootObject());
+    QVERIFY(image != 0);
+    image->setWidth(80.0);
+    QCOMPARE(image->width(), 80.);
+    QCOMPARE(image->height(), 80.);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("aspectratio.qml")));
+    image = qobject_cast<QQuickImage*>(canvas->rootObject());
+    image->setHeight(60.0);
+    QVERIFY(image != 0);
+    QCOMPARE(image->height(), 60.);
+    QCOMPARE(image->width(), 60.);
+    delete canvas;
+}
+
+void tst_qquickimage::smooth()
+{
+    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(""));
+    QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
+    QVERIFY(obj != 0);
+    QCOMPARE(obj->width(), 300.);
+    QCOMPARE(obj->height(), 300.);
+    QCOMPARE(obj->smooth(), true);
+    QCOMPARE(obj->fillMode(), QQuickImage::Stretch);
+
+    delete obj;
+}
+
+void tst_qquickimage::mirror()
+{
+    QMap<QQuickImage::FillMode, QImage> screenshots;
+    QList<QQuickImage::FillMode> fillModes;
+    fillModes << QQuickImage::Stretch << QQuickImage::PreserveAspectFit << QQuickImage::PreserveAspectCrop
+              << QQuickImage::Tile << QQuickImage::TileVertically << QQuickImage::TileHorizontally;
+
+    qreal width = 300;
+    qreal height = 250;
+
+    foreach (QQuickImage::FillMode fillMode, fillModes) {
+        QQuickView *canvas = new QQuickView;
+        canvas->setSource(QUrl::fromLocalFile(TESTDATA("mirror.qml")));
+
+        QQuickImage *obj = canvas->rootObject()->findChild<QQuickImage*>("image");
+        QVERIFY(obj != 0);
+
+        obj->setFillMode(fillMode);
+        obj->setProperty("mirror", true);
+        canvas->show();
+
+        QImage screenshot = canvas->grabFrameBuffer();
+        screenshots[fillMode] = screenshot;
+        delete canvas;
+    }
+
+    foreach (QQuickImage::FillMode fillMode, fillModes) {
+        QPixmap srcPixmap;
+        QVERIFY(srcPixmap.load(TESTDATA("pattern.png")));
+
+        QPixmap expected(width, height);
+        expected.fill();
+        QPainter p_e(&expected);
+        QTransform transform;
+        transform.translate(width, 0).scale(-1, 1.0);
+        p_e.setTransform(transform);
+
+        switch (fillMode) {
+        case QQuickImage::Stretch:
+            p_e.drawPixmap(QRect(0, 0, width, height), srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height()));
+            break;
+        case QQuickImage::PreserveAspectFit:
+            p_e.drawPixmap(QRect(25, 0, height, height), srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height()));
+            break;
+        case QQuickImage::PreserveAspectCrop:
+        {
+            qreal ratio = width/srcPixmap.width(); // width is the longer side
+            QRect rect(0, 0, srcPixmap.width()*ratio, srcPixmap.height()*ratio);
+            rect.moveCenter(QRect(0, 0, width, height).center());
+            p_e.drawPixmap(rect, srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height()));
+            break;
+        }
+        case QQuickImage::Tile:
+            p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap);
+            break;
+        case QQuickImage::TileVertically:
+            transform.scale(width / srcPixmap.width(), 1.0);
+            p_e.setTransform(transform);
+            p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap);
+            break;
+        case QQuickImage::TileHorizontally:
+            transform.scale(1.0, height / srcPixmap.height());
+            p_e.setTransform(transform);
+            p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap);
+            break;
+        }
+
+        QImage img = expected.toImage();
+#ifdef Q_WS_QPA
+        QEXPECT_FAIL("", "QTBUG-21005 fails", Continue);
+#endif
+        QCOMPARE(screenshots[fillMode], img);
+    }
+}
+
+void tst_qquickimage::svg()
+{
+    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(""));
+    QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
+    QVERIFY(obj != 0);
+    QCOMPARE(obj->width(), 300.0);
+    QCOMPARE(obj->height(), 300.0);
+    obj->setSourceSize(QSize(200,200));
+
+    QCOMPARE(obj->width(), 200.0);
+    QCOMPARE(obj->height(), 200.0);
+    delete obj;
+}
+
+void tst_qquickimage::geometry_data()
+{
+    QTest::addColumn<QString>("fillMode");
+    QTest::addColumn<bool>("explicitWidth");
+    QTest::addColumn<bool>("explicitHeight");
+    QTest::addColumn<double>("itemWidth");
+    QTest::addColumn<double>("paintedWidth");
+    QTest::addColumn<double>("boundingWidth");
+    QTest::addColumn<double>("itemHeight");
+    QTest::addColumn<double>("paintedHeight");
+    QTest::addColumn<double>("boundingHeight");
+
+    // tested image has width 200, height 100
+
+    // bounding rect and item rect are equal with fillMode PreserveAspectFit, painted rect may be smaller if the aspect ratio doesn't match
+    QTest::newRow("PreserveAspectFit") << "PreserveAspectFit" << false << false << 200.0 << 200.0 << 200.0 << 100.0 << 100.0 << 100.0;
+    QTest::newRow("PreserveAspectFit explicit width 300") << "PreserveAspectFit" << true << false << 300.0 << 200.0 << 300.0 << 100.0 << 100.0 << 100.0;
+    QTest::newRow("PreserveAspectFit explicit height 400") << "PreserveAspectFit" << false << true << 200.0 << 200.0 << 200.0 << 400.0 << 100.0 << 400.0;
+    QTest::newRow("PreserveAspectFit explicit width 300, height 400") << "PreserveAspectFit" << true << true << 300.0 << 300.0 << 300.0 << 400.0 << 150.0 << 400.0;
+
+    // bounding rect and painted rect are equal with fillMode PreserveAspectCrop, item rect may be smaller if the aspect ratio doesn't match
+    QTest::newRow("PreserveAspectCrop") << "PreserveAspectCrop" << false << false << 200.0 << 200.0 << 200.0 << 100.0 << 100.0 << 100.0;
+    QTest::newRow("PreserveAspectCrop explicit width 300") << "PreserveAspectCrop" << true << false << 300.0 << 300.0 << 300.0 << 100.0 << 150.0 << 150.0;
+    QTest::newRow("PreserveAspectCrop explicit height 400") << "PreserveAspectCrop" << false << true << 200.0 << 800.0 << 800.0 << 400.0 << 400.0 << 400.0;
+    QTest::newRow("PreserveAspectCrop explicit width 300, height 400") << "PreserveAspectCrop" << true << true << 300.0 << 800.0 << 800.0 << 400.0 << 400.0 << 400.0;
+
+    // bounding rect, painted rect and item rect are equal in stretching and tiling images
+    QStringList fillModes;
+    fillModes << "Stretch" << "Tile" << "TileVertically" << "TileHorizontally";
+    foreach (QString fillMode, fillModes) {
+        QTest::newRow(fillMode.toLatin1()) << fillMode << false << false << 200.0 << 200.0 << 200.0 << 100.0 << 100.0 << 100.0;
+        QTest::newRow(QString(fillMode + " explicit width 300").toLatin1()) << fillMode << true << false << 300.0 << 300.0 << 300.0 << 100.0 << 100.0 << 100.0;
+        QTest::newRow(QString(fillMode + " explicit height 400").toLatin1()) << fillMode << false << true << 200.0 << 200.0 << 200.0 << 400.0 << 400.0 << 400.0;
+        QTest::newRow(QString(fillMode + " explicit width 300, height 400").toLatin1()) << fillMode << true << true << 300.0 << 300.0 << 300.0 << 400.0 << 400.0 << 400.0;
+    }
+}
+
+void tst_qquickimage::geometry()
+{
+    QFETCH(QString, fillMode);
+    QFETCH(bool, explicitWidth);
+    QFETCH(bool, explicitHeight);
+    QFETCH(double, itemWidth);
+    QFETCH(double, itemHeight);
+    QFETCH(double, paintedWidth);
+    QFETCH(double, paintedHeight);
+    QFETCH(double, boundingWidth);
+    QFETCH(double, boundingHeight);
+
+    QString src = QUrl::fromLocalFile(TESTDATA("rect.png")).toString();
+    QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; fillMode: Image." + fillMode + "; ";
+
+    if (explicitWidth)
+        componentStr.append("width: 300; ");
+    if (explicitHeight)
+        componentStr.append("height: 400; ");
+    componentStr.append("}");
+    QDeclarativeComponent component(&engine);
+    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
+    QVERIFY(obj != 0);
+
+    QCOMPARE(obj->width(), itemWidth);
+    QCOMPARE(obj->paintedWidth(), paintedWidth);
+    QCOMPARE(obj->boundingRect().width(), boundingWidth);
+
+    QCOMPARE(obj->height(), itemHeight);
+    QCOMPARE(obj->paintedHeight(), paintedHeight);
+    QCOMPARE(obj->boundingRect().height(), boundingHeight);
+    delete obj;
+}
+
+void tst_qquickimage::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(TESTDATA("big.jpeg")).toString();
+    QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; width: 100; sourceSize.height: 256 }";
+
+    QDeclarativeComponent component(&engine);
+    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
+    QVERIFY(obj != 0);
+    QCOMPARE(obj->width(), 100.0);
+    QCOMPARE(obj->height(), 256.0);
+
+    delete obj;
+}
+
+void tst_qquickimage::tiling_QTBUG_6716()
+{
+    QFETCH(QString, source);
+
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA(source)));
+    canvas->show();
+    qApp->processEvents();
+
+    QQuickImage *tiling = findItem<QQuickImage>(canvas->rootObject(), "tiling");
+
+    QVERIFY(tiling != 0);
+    QImage img = canvas->grabFrameBuffer();
+    for (int x = 0; x < tiling->width(); ++x) {
+        for (int y = 0; y < tiling->height(); ++y) {
+            QEXPECT_FAIL("horizontal_tiling", "QTBUG-21005 - stable failing test", Abort);
+            QVERIFY(img.pixel(x, y) == qRgb(0, 255, 0));
+        }
+    }
+    delete canvas;
+}
+
+void tst_qquickimage::tiling_QTBUG_6716_data()
+{
+    QTest::addColumn<QString>("source");
+    QTest::newRow("vertical_tiling") << "vtiling.qml";
+    QTest::newRow("horizontal_tiling") << "htiling.qml";
+}
+
+void tst_qquickimage::noLoading()
+{
+    TestHTTPServer server(SERVER_PORT);
+    QVERIFY(server.isValid());
+    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(TESTDATA("heart.png")));
+    QDeclarativeComponent component(&engine);
+    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
+    QVERIFY(obj != 0);
+    QVERIFY(obj->status() == QQuickImage::Ready);
+
+    QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(const QUrl &)));
+    QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal)));
+    QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QQuickImageBase::Status)));
+
+    // Loading local file
+    ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("green.png")));
+    QTRY_VERIFY(obj->status() == QQuickImage::Ready);
+    QTRY_VERIFY(obj->progress() == 1.0);
+    QTRY_COMPARE(sourceSpy.count(), 1);
+    QTRY_COMPARE(progressSpy.count(), 0);
+    QTRY_COMPARE(statusSpy.count(), 0);
+
+    // Loading remote file
+    ctxt->setContextProperty("srcImage", QString(SERVER_ADDR) + "/rect.png");
+    QTRY_VERIFY(obj->status() == QQuickImage::Loading);
+    QTRY_VERIFY(obj->progress() == 0.0);
+    QTRY_VERIFY(obj->status() == QQuickImage::Ready);
+    QTRY_VERIFY(obj->progress() == 1.0);
+    QTRY_COMPARE(sourceSpy.count(), 2);
+    QTRY_COMPARE(progressSpy.count(), 2);
+    QTRY_COMPARE(statusSpy.count(), 2);
+
+    // Loading remote file again - should not go through 'Loading' state.
+    ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("green.png")));
+    ctxt->setContextProperty("srcImage", QString(SERVER_ADDR) + "/rect.png");
+    QTRY_VERIFY(obj->status() == QQuickImage::Ready);
+    QTRY_VERIFY(obj->progress() == 1.0);
+    QTRY_COMPARE(sourceSpy.count(), 4);
+    QTRY_COMPARE(progressSpy.count(), 2);
+    QTRY_COMPARE(statusSpy.count(), 2);
+
+    delete obj;
+}
+
+void tst_qquickimage::paintedWidthHeight()
+{
+    {
+        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);
+        component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
+        QVERIFY(obj != 0);
+        QCOMPARE(obj->width(), 200.0);
+        QCOMPARE(obj->height(), 25.0);
+        QCOMPARE(obj->paintedWidth(), 25.0);
+        QCOMPARE(obj->paintedHeight(), 25.0);
+
+        delete obj;
+    }
+
+    {
+        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(""));
+        QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
+        QVERIFY(obj != 0);
+        QCOMPARE(obj->width(), 26.0);
+        QCOMPARE(obj->height(), 175.0);
+        QCOMPARE(obj->paintedWidth(), 26.0);
+        QCOMPARE(obj->paintedHeight(), 26.0);
+
+        delete obj;
+    }
+}
+
+void tst_qquickimage::sourceSize_QTBUG_14303()
+{
+    QString componentStr = "import QtQuick 2.0\nImage { source: srcImage }";
+    QDeclarativeContext *ctxt = engine.rootContext();
+    ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("heart200.png")));
+    QDeclarativeComponent component(&engine);
+    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
+
+    QSignalSpy sourceSizeSpy(obj, SIGNAL(sourceSizeChanged()));
+
+    QTRY_VERIFY(obj != 0);
+    QTRY_VERIFY(obj->status() == QQuickImage::Ready);
+
+    QTRY_COMPARE(obj->sourceSize().width(), 200);
+    QTRY_COMPARE(obj->sourceSize().height(), 200);
+    QTRY_COMPARE(sourceSizeSpy.count(), 0);
+
+    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(TESTDATA("heart200.png")));
+    QTRY_COMPARE(obj->sourceSize().width(), 200);
+    QTRY_COMPARE(obj->sourceSize().height(), 200);
+    QTRY_COMPARE(sourceSizeSpy.count(), 2);
+
+    delete obj;
+}
+
+void tst_qquickimage::sourceSize_QTBUG_16389()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("qtbug_16389.qml")));
+    canvas->show();
+    qApp->processEvents();
+
+    QQuickImage *image = findItem<QQuickImage>(canvas->rootObject(), "iconImage");
+    QQuickItem *handle = findItem<QQuickItem>(canvas->rootObject(), "blueHandle");
+
+    QCOMPARE(image->sourceSize().width(), 200);
+    QCOMPARE(image->sourceSize().height(), 200);
+    QCOMPARE(image->paintedWidth(), 0.0);
+    QCOMPARE(image->paintedHeight(), 0.0);
+
+    handle->setY(20);
+
+    QCOMPARE(image->sourceSize().width(), 200);
+    QCOMPARE(image->sourceSize().height(), 200);
+    QCOMPARE(image->paintedWidth(), 20.0);
+    QCOMPARE(image->paintedHeight(), 20.0);
+}
+
+static int numberOfWarnings = 0;
+static void checkWarnings(QtMsgType, const char *msg)
+{
+    if (!QString(msg).contains("QGLContext::makeCurrent(): Failed."))
+        numberOfWarnings++;
+}
+
+// QTBUG-15690
+void tst_qquickimage::nullPixmapPaint()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("nullpixmap.qml")));
+    canvas->show();
+
+    QQuickImage *image = qobject_cast<QQuickImage*>(canvas->rootObject());
+    QTRY_VERIFY(image != 0);
+    image->setSource(SERVER_ADDR + QString("/no-such-file.png"));
+
+    QtMsgHandler previousMsgHandler = qInstallMsgHandler(checkWarnings);
+
+    // used to print "QTransform::translate with NaN called"
+    QPixmap pm = QPixmap::fromImage(canvas->grabFrameBuffer());
+    qInstallMsgHandler(previousMsgHandler);
+    QVERIFY(numberOfWarnings == 0);
+    delete image;
+}
+
+/*
+   Find an item with the specified objectName.  If index is supplied then the
+   item must also evaluate the {index} expression equal to index
+*/
+template<typename T>
+T *tst_qquickimage::findItem(QQuickItem *parent, const QString &objectName, int index)
+{
+    const QMetaObject &mo = T::staticMetaObject;
+    //qDebug() << parent->childItems().count() << "children";
+    for (int i = 0; i < parent->childItems().count(); ++i) {
+        QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
+        if (!item)
+            continue;
+        //qDebug() << "try" << item;
+        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
+            if (index != -1) {
+                QDeclarativeExpression e(qmlContext(item), item, "index");
+                if (e.evaluate().toInt() == index)
+                    return static_cast<T*>(item);
+            } else {
+                return static_cast<T*>(item);
+            }
+        }
+        item = findItem<T>(item, objectName, index);
+        if (item)
+            return static_cast<T*>(item);
+    }
+
+    return 0;
+}
+
+QTEST_MAIN(tst_qquickimage)
+
+#include "tst_qquickimage.moc"
diff --git a/tests/auto/declarative/qquickitem/qquickitem.pro b/tests/auto/declarative/qquickitem/qquickitem.pro
new file mode 100644 (file)
index 0000000..c1c7b82
--- /dev/null
@@ -0,0 +1,8 @@
+CONFIG += testcase
+TARGET = tst_qquickitem
+SOURCES += tst_qquickitem.cpp
+
+macx:CONFIG -= app_bundle
+
+CONFIG += parallel_test
+QT += core-private gui-private declarative-private widgets testlib
diff --git a/tests/auto/declarative/qquickitem/tst_qquickitem.cpp b/tests/auto/declarative/qquickitem/tst_qquickitem.cpp
new file mode 100644 (file)
index 0000000..694fdc0
--- /dev/null
@@ -0,0 +1,1061 @@
+/****************************************************************************
+**
+** 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 "qquickitem.h"
+#include "qquickcanvas.h"
+#include <QtWidgets/QGraphicsSceneMouseEvent>
+#include "private/qquickfocusscope_p.h"
+#include <QDebug>
+#include <QTimer>
+
+class TestItem : public QQuickItem
+{
+Q_OBJECT
+public:
+    TestItem(QQuickItem *parent = 0) : QQuickItem(parent), focused(false), pressCount(0), releaseCount(0), wheelCount(0) {}
+
+    bool focused;
+    int pressCount;
+    int releaseCount;
+    int wheelCount;
+protected:
+    virtual void focusInEvent(QFocusEvent *) { Q_ASSERT(!focused); focused = true; }
+    virtual void focusOutEvent(QFocusEvent *) { Q_ASSERT(focused); focused = false; }
+    virtual void mousePressEvent(QMouseEvent *event) { event->accept(); ++pressCount; }
+    virtual void mouseReleaseEvent(QMouseEvent *event) { event->accept(); ++releaseCount; }
+    virtual void wheelEvent(QWheelEvent *event) { event->accept(); ++wheelCount; }
+};
+
+class TestPolishItem : public QQuickItem
+{
+Q_OBJECT
+public:
+    TestPolishItem(QQuickItem *parent)
+    : QQuickItem(parent), wasPolished(false) {
+        QTimer::singleShot(10, this, SLOT(doPolish()));
+    }
+
+    bool wasPolished;
+
+protected:
+    virtual void updatePolish() {
+        wasPolished = true;
+    }
+
+public slots:
+    void doPolish() {
+        polish();
+    }
+};
+
+class TestFocusScope : public QQuickFocusScope
+{
+Q_OBJECT
+public:
+    TestFocusScope(QQuickItem *parent = 0) : QQuickFocusScope(parent), focused(false) {}
+
+    bool focused;
+protected:
+    virtual void focusInEvent(QFocusEvent *) { Q_ASSERT(!focused); focused = true; }
+    virtual void focusOutEvent(QFocusEvent *) { Q_ASSERT(focused); focused = false; }
+};
+
+class tst_qquickitem : public QObject
+{
+    Q_OBJECT
+public:
+    tst_qquickitem();
+
+private slots:
+    void initTestCase();
+    void cleanupTestCase();
+
+    void noCanvas();
+    void simpleFocus();
+    void scopedFocus();
+    void addedToCanvas();
+    void changeParent();
+
+    void constructor();
+    void setParentItem();
+
+    void visible();
+    void enabled();
+
+    void mouseGrab();
+    void polishOutsideAnimation();
+
+    void wheelEvent_data();
+    void wheelEvent();
+    void hoverEvent_data();
+    void hoverEvent();
+    void hoverEventInParent();
+
+private:
+
+    void ensureFocus(QWindow *w) {
+        w->show();
+        w->requestActivateWindow();
+        qApp->processEvents();
+
+#ifdef Q_WS_X11
+        // to be safe and avoid failing setFocus with window managers
+        qt_x11_wait_for_window_manager(w);
+#endif
+    }
+};
+
+tst_qquickitem::tst_qquickitem()
+{
+}
+
+void tst_qquickitem::initTestCase()
+{
+}
+
+void tst_qquickitem::cleanupTestCase()
+{
+}
+
+// Focus has no effect when outside a canvas
+void tst_qquickitem::noCanvas()
+{
+    QQuickItem *root = new TestItem;
+    QQuickItem *child = new TestItem(root);
+    QQuickItem *scope = new TestItem(root);
+    QQuickFocusScope *scopedChild = new TestFocusScope(scope);
+    QQuickFocusScope *scopedChild2 = new TestFocusScope(scope);
+
+    QCOMPARE(root->hasFocus(), false);
+    QCOMPARE(child->hasFocus(), false);
+    QCOMPARE(scope->hasFocus(), false);
+    QCOMPARE(scopedChild->hasFocus(), false);
+    QCOMPARE(scopedChild2->hasFocus(), false);
+
+    root->setFocus(true);
+    scope->setFocus(true);
+    scopedChild2->setFocus(true);
+    QCOMPARE(root->hasFocus(), true);
+    QCOMPARE(child->hasFocus(), false);
+    QCOMPARE(scope->hasFocus(), true);
+    QCOMPARE(scopedChild->hasFocus(), false);
+    QCOMPARE(scopedChild2->hasFocus(), true);
+
+    root->setFocus(false);
+    child->setFocus(true);
+    scopedChild->setFocus(true);
+    scope->setFocus(false);
+    QCOMPARE(root->hasFocus(), false);
+    QCOMPARE(child->hasFocus(), true);
+    QCOMPARE(scope->hasFocus(), false);
+    QCOMPARE(scopedChild->hasFocus(), true);
+    QCOMPARE(scopedChild2->hasFocus(), true);
+
+    delete root;
+}
+
+struct FocusData {
+    FocusData() : focus(false), activeFocus(false) {}
+
+    void set(bool f, bool af) { focus = f; activeFocus = af; }
+    bool focus;
+    bool activeFocus;
+};
+struct FocusState : public QHash<QQuickItem *, FocusData>
+{
+    FocusState() : activeFocusItem(0) {}
+    FocusState &operator<<(QQuickItem *item) {
+        insert(item, FocusData());
+        return *this;
+    }
+
+    void active(QQuickItem *i) {
+        activeFocusItem = i;
+    }
+    QQuickItem *activeFocusItem;
+};
+
+#define FVERIFY() \
+    do { \
+        if (focusState.activeFocusItem) { \
+            QCOMPARE(canvas.activeFocusItem(), focusState.activeFocusItem); \
+            if (qobject_cast<TestItem *>(canvas.activeFocusItem())) \
+                QCOMPARE(qobject_cast<TestItem *>(canvas.activeFocusItem())->focused, true); \
+            else if (qobject_cast<TestFocusScope *>(canvas.activeFocusItem())) \
+                QCOMPARE(qobject_cast<TestFocusScope *>(canvas.activeFocusItem())->focused, true); \
+        } else { \
+            QCOMPARE(canvas.activeFocusItem(), canvas.rootItem()); \
+        } \
+        for (QHash<QQuickItem *, 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)
+
+// Tests a simple set of top-level scoped items
+void tst_qquickitem::simpleFocus()
+{
+    QQuickCanvas canvas;
+    ensureFocus(&canvas);
+
+    QQuickItem *l1c1 = new TestItem(canvas.rootItem());
+    QQuickItem *l1c2 = new TestItem(canvas.rootItem());
+    QQuickItem *l1c3 = new TestItem(canvas.rootItem());
+
+    QQuickItem *l2c1 = new TestItem(l1c1);
+    QQuickItem *l2c2 = new TestItem(l1c1);
+    QQuickItem *l2c3 = new TestItem(l1c3);
+
+    FocusState focusState;
+    focusState << l1c1 << l1c2 << l1c3
+               << l2c1 << l2c2 << l2c3;
+    FVERIFY();
+
+    l1c1->setFocus(true);
+    focusState[l1c1].set(true, true);
+    focusState.active(l1c1);
+    FVERIFY();
+
+    l2c3->setFocus(true);
+    focusState[l1c1].set(false, false);
+    focusState[l2c3].set(true, true);
+    focusState.active(l2c3);
+    FVERIFY();
+
+    l1c3->setFocus(true);
+    focusState[l2c3].set(false, false);
+    focusState[l1c3].set(true, true);
+    focusState.active(l1c3);
+    FVERIFY();
+
+    l1c2->setFocus(false);
+    FVERIFY();
+
+    l1c3->setFocus(false);
+    focusState[l1c3].set(false, false);
+    focusState.active(0);
+    FVERIFY();
+
+    l2c1->setFocus(true);
+    focusState[l2c1].set(true, true);
+    focusState.active(l2c1);
+    FVERIFY();
+}
+
+// Items with a focus scope
+void tst_qquickitem::scopedFocus()
+{
+    QQuickCanvas canvas;
+    ensureFocus(&canvas);
+
+    QQuickItem *l1c1 = new TestItem(canvas.rootItem());
+    QQuickItem *l1c2 = new TestItem(canvas.rootItem());
+    QQuickItem *l1c3 = new TestItem(canvas.rootItem());
+
+    QQuickItem *l2c1 = new TestItem(l1c1);
+    QQuickItem *l2c2 = new TestItem(l1c1);
+    QQuickItem *l2c3 = new TestFocusScope(l1c3);
+
+    QQuickItem *l3c1 = new TestItem(l2c3);
+    QQuickItem *l3c2 = new TestFocusScope(l2c3);
+
+    QQuickItem *l4c1 = new TestItem(l3c2);
+    QQuickItem *l4c2 = new TestItem(l3c2);
+
+    FocusState focusState;
+    focusState << l1c1 << l1c2 << l1c3
+               << l2c1 << l2c2 << l2c3
+               << l3c1 << l3c2
+               << l4c1 << l4c2;
+    FVERIFY();
+
+    l4c2->setFocus(true);
+    focusState[l4c2].set(true, false);
+    FVERIFY();
+
+    l4c1->setFocus(true);
+    focusState[l4c2].set(false, false);
+    focusState[l4c1].set(true, false);
+    FVERIFY();
+
+    l1c1->setFocus(true);
+    focusState[l1c1].set(true, true);
+    focusState.active(l1c1);
+    FVERIFY();
+
+    l3c2->setFocus(true);
+    focusState[l3c2].set(true, false);
+    FVERIFY();
+
+    l2c3->setFocus(true);
+    focusState[l1c1].set(false, false);
+    focusState[l2c3].set(true, true);
+    focusState[l3c2].set(true, true);
+    focusState[l4c1].set(true, true);
+    focusState.active(l4c1);
+    FVERIFY();
+
+    l3c2->setFocus(false);
+    focusState[l3c2].set(false, false);
+    focusState[l4c1].set(true, false);
+    focusState.active(l2c3);
+    FVERIFY();
+
+    l3c2->setFocus(true);
+    focusState[l3c2].set(true, true);
+    focusState[l4c1].set(true, true);
+    focusState.active(l4c1);
+    FVERIFY();
+
+    l4c1->setFocus(false);
+    focusState[l4c1].set(false, false);
+    focusState.active(l3c2);
+    FVERIFY();
+
+    l1c3->setFocus(true);
+    focusState[l1c3].set(true, true);
+    focusState[l2c3].set(false, false);
+    focusState[l3c2].set(true, false);
+    focusState.active(l1c3);
+    FVERIFY();
+}
+
+// Tests focus corrects itself when a tree is added to a canvas for the first time
+void tst_qquickitem::addedToCanvas()
+{
+    {
+    QQuickCanvas canvas;
+    ensureFocus(&canvas);
+
+    QQuickItem *item = new TestItem;
+
+    FocusState focusState;
+    focusState << item;
+
+    item->setFocus(true);
+    focusState[item].set(true, false);
+    FVERIFY();
+
+    item->setParentItem(canvas.rootItem());
+    focusState[item].set(true, true);
+    focusState.active(item);
+    FVERIFY();
+    }
+
+    {
+    QQuickCanvas canvas;
+    ensureFocus(&canvas);
+
+    QQuickItem *item = new TestItem(canvas.rootItem());
+
+    QQuickItem *tree = new TestItem;
+    QQuickItem *c1 = new TestItem(tree);
+    QQuickItem *c2 = new TestItem(tree);
+
+    FocusState focusState;
+    focusState << item << tree << c1 << c2;
+
+    item->setFocus(true);
+    c1->setFocus(true);
+    c2->setFocus(true);
+    focusState[item].set(true, true);
+    focusState[c1].set(true, false);
+    focusState[c2].set(true, false);
+    focusState.active(item);
+    FVERIFY();
+
+    tree->setParentItem(item);
+    focusState[c1].set(false, false);
+    focusState[c2].set(false, false);
+    FVERIFY();
+    }
+
+    {
+    QQuickCanvas canvas;
+    ensureFocus(&canvas);
+
+    QQuickItem *tree = new TestItem;
+    QQuickItem *c1 = new TestItem(tree);
+    QQuickItem *c2 = new TestItem(tree);
+
+    FocusState focusState;
+    focusState << tree << c1 << c2;
+    c1->setFocus(true);
+    c2->setFocus(true);
+    focusState[c1].set(true, false);
+    focusState[c2].set(true, false);
+    FVERIFY();
+
+    tree->setParentItem(canvas.rootItem());
+    focusState[c1].set(true, true);
+    focusState[c2].set(false, false);
+    focusState.active(c1);
+    FVERIFY();
+    }
+
+    {
+    QQuickCanvas canvas;
+    ensureFocus(&canvas);
+    QQuickItem *tree = new TestFocusScope;
+    QQuickItem *c1 = new TestItem(tree);
+    QQuickItem *c2 = new TestItem(tree);
+
+    FocusState focusState;
+    focusState << tree << c1 << c2;
+    c1->setFocus(true);
+    c2->setFocus(true);
+    focusState[c1].set(true, false);
+    focusState[c2].set(true, false);
+    FVERIFY();
+
+    tree->setParentItem(canvas.rootItem());
+    focusState[c1].set(true, false);
+    focusState[c2].set(false, false);
+    FVERIFY();
+
+    tree->setFocus(true);
+    focusState[tree].set(true, true);
+    focusState[c1].set(true, true);
+    focusState.active(c1);
+    FVERIFY();
+    }
+
+    {
+    QQuickCanvas canvas;
+    ensureFocus(&canvas);
+    QQuickItem *tree = new TestFocusScope;
+    QQuickItem *c1 = new TestItem(tree);
+    QQuickItem *c2 = new TestItem(tree);
+
+    FocusState focusState;
+    focusState << tree << c1 << c2;
+    tree->setFocus(true);
+    c1->setFocus(true);
+    c2->setFocus(true);
+    focusState[tree].set(true, false);
+    focusState[c1].set(true, false);
+    focusState[c2].set(true, false);
+    FVERIFY();
+
+    tree->setParentItem(canvas.rootItem());
+    focusState[tree].set(true, true);
+    focusState[c1].set(true, true);
+    focusState[c2].set(false, false);
+    focusState.active(c1);
+    FVERIFY();
+    }
+
+    {
+    QQuickCanvas canvas;
+    ensureFocus(&canvas);
+    QQuickItem *child = new TestItem(canvas.rootItem());
+    QQuickItem *tree = new TestFocusScope;
+    QQuickItem *c1 = new TestItem(tree);
+    QQuickItem *c2 = new TestItem(tree);
+
+    FocusState focusState;
+    focusState << child << tree << c1 << c2;
+    child->setFocus(true);
+    tree->setFocus(true);
+    c1->setFocus(true);
+    c2->setFocus(true);
+    focusState[child].set(true, true);
+    focusState[tree].set(true, false);
+    focusState[c1].set(true, false);
+    focusState[c2].set(true, false);
+    focusState.active(child);
+    FVERIFY();
+
+    tree->setParentItem(canvas.rootItem());
+    focusState[tree].set(false, false);
+    focusState[c1].set(true, false);
+    focusState[c2].set(false, false);
+    FVERIFY();
+
+    tree->setFocus(true);
+    focusState[child].set(false, false);
+    focusState[tree].set(true, true);
+    focusState[c1].set(true, true);
+    focusState.active(c1);
+    FVERIFY();
+    }
+}
+
+void tst_qquickitem::changeParent()
+{
+    // Parent to no parent
+    {
+    QQuickCanvas canvas;
+    ensureFocus(&canvas);
+    QQuickItem *child = new TestItem(canvas.rootItem());
+
+    FocusState focusState;
+    focusState << child;
+    FVERIFY();
+
+    child->setFocus(true);
+    focusState[child].set(true, true);
+    focusState.active(child);
+    FVERIFY();
+
+    child->setParentItem(0);
+    focusState[child].set(true, false);
+    focusState.active(0);
+    FVERIFY();
+    }
+
+    // Different parent, same focus scope
+    {
+    QQuickCanvas canvas;
+    ensureFocus(&canvas);
+    QQuickItem *child = new TestItem(canvas.rootItem());
+    QQuickItem *child2 = new TestItem(canvas.rootItem());
+
+    FocusState focusState;
+    focusState << child << child2;
+    FVERIFY();
+
+    child->setFocus(true);
+    focusState[child].set(true, true);
+    focusState.active(child);
+    FVERIFY();
+
+    child->setParentItem(child2);
+    FVERIFY();
+    }
+
+    // Different parent, different focus scope
+    {
+    QQuickCanvas canvas;
+    ensureFocus(&canvas);
+    QQuickItem *child = new TestItem(canvas.rootItem());
+    QQuickItem *child2 = new TestFocusScope(canvas.rootItem());
+    QQuickItem *item = new TestItem(child);
+
+    FocusState focusState;
+    focusState << child << child2 << item;
+    FVERIFY();
+
+    item->setFocus(true);
+    focusState[item].set(true, true);
+    focusState.active(item);
+    FVERIFY();
+
+    item->setParentItem(child2);
+    focusState[item].set(true, false);
+    focusState.active(0);
+    FVERIFY();
+    }
+    {
+    QQuickCanvas canvas;
+    ensureFocus(&canvas);
+    QQuickItem *child = new TestItem(canvas.rootItem());
+    QQuickItem *child2 = new TestFocusScope(canvas.rootItem());
+    QQuickItem *item = new TestItem(child2);
+
+    FocusState focusState;
+    focusState << child << child2 << item;
+    FVERIFY();
+
+    item->setFocus(true);
+    focusState[item].set(true, false);
+    focusState.active(0);
+    FVERIFY();
+
+    item->setParentItem(child);
+    focusState[item].set(true, true);
+    focusState.active(item);
+    FVERIFY();
+    }
+    {
+    QQuickCanvas canvas;
+    ensureFocus(&canvas);
+    QQuickItem *child = new TestItem(canvas.rootItem());
+    QQuickItem *child2 = new TestFocusScope(canvas.rootItem());
+    QQuickItem *item = new TestItem(child2);
+
+    FocusState focusState;
+    focusState << child << child2 << item;
+    FVERIFY();
+
+    child->setFocus(true);
+    item->setFocus(true);
+    focusState[child].set(true, true);
+    focusState[item].set(true, false);
+    focusState.active(child);
+    FVERIFY();
+
+    item->setParentItem(child);
+    focusState[item].set(false, false);
+    FVERIFY();
+    }
+
+}
+
+void tst_qquickitem::constructor()
+{
+    QQuickItem *root = new QQuickItem;
+    QVERIFY(root->parent() == 0);
+    QVERIFY(root->parentItem() == 0);
+
+    QQuickItem *child1 = new QQuickItem(root);
+    QVERIFY(child1->parent() == root);
+    QVERIFY(child1->parentItem() == root);
+    QCOMPARE(root->childItems().count(), 1);
+    QCOMPARE(root->childItems().at(0), child1);
+
+    QQuickItem *child2 = new QQuickItem(root);
+    QVERIFY(child2->parent() == root);
+    QVERIFY(child2->parentItem() == root);
+    QCOMPARE(root->childItems().count(), 2);
+    QCOMPARE(root->childItems().at(0), child1);
+    QCOMPARE(root->childItems().at(1), child2);
+
+    delete root;
+}
+
+void tst_qquickitem::setParentItem()
+{
+    QQuickItem *root = new QQuickItem;
+    QVERIFY(root->parent() == 0);
+    QVERIFY(root->parentItem() == 0);
+
+    QQuickItem *child1 = new QQuickItem;
+    QVERIFY(child1->parent() == 0);
+    QVERIFY(child1->parentItem() == 0);
+
+    child1->setParentItem(root);
+    QVERIFY(child1->parent() == 0);
+    QVERIFY(child1->parentItem() == root);
+    QCOMPARE(root->childItems().count(), 1);
+    QCOMPARE(root->childItems().at(0), child1);
+
+    QQuickItem *child2 = new QQuickItem;
+    QVERIFY(child2->parent() == 0);
+    QVERIFY(child2->parentItem() == 0);
+    child2->setParentItem(root);
+    QVERIFY(child2->parent() == 0);
+    QVERIFY(child2->parentItem() == root);
+    QCOMPARE(root->childItems().count(), 2);
+    QCOMPARE(root->childItems().at(0), child1);
+    QCOMPARE(root->childItems().at(1), child2);
+
+    child1->setParentItem(0);
+    QVERIFY(child1->parent() == 0);
+    QVERIFY(child1->parentItem() == 0);
+    QCOMPARE(root->childItems().count(), 1);
+    QCOMPARE(root->childItems().at(0), child2);
+
+    delete root;
+
+    QVERIFY(child1->parent() == 0);
+    QVERIFY(child1->parentItem() == 0);
+    QVERIFY(child2->parent() == 0);
+    QVERIFY(child2->parentItem() == 0);
+
+    delete child1;
+    delete child2;
+}
+
+void tst_qquickitem::visible()
+{
+    QQuickItem *root = new QQuickItem;
+
+    QQuickItem *child1 = new QQuickItem;
+    child1->setParentItem(root);
+
+    QQuickItem *child2 = new QQuickItem;
+    child2->setParentItem(root);
+
+    QVERIFY(child1->isVisible());
+    QVERIFY(child2->isVisible());
+
+    root->setVisible(false);
+    QVERIFY(!child1->isVisible());
+    QVERIFY(!child2->isVisible());
+
+    root->setVisible(true);
+    QVERIFY(child1->isVisible());
+    QVERIFY(child2->isVisible());
+
+    child1->setVisible(false);
+    QVERIFY(!child1->isVisible());
+    QVERIFY(child2->isVisible());
+
+    child2->setParentItem(child1);
+    QVERIFY(!child1->isVisible());
+    QVERIFY(!child2->isVisible());
+
+    child2->setParentItem(root);
+    QVERIFY(!child1->isVisible());
+    QVERIFY(child2->isVisible());
+
+    delete root;
+    delete child1;
+    delete child2;
+}
+
+void tst_qquickitem::enabled()
+{
+    QQuickItem *root = new QQuickItem;
+
+    QQuickItem *child1 = new QQuickItem;
+    child1->setParentItem(root);
+
+    QQuickItem *child2 = new QQuickItem;
+    child2->setParentItem(root);
+
+    QVERIFY(child1->isEnabled());
+    QVERIFY(child2->isEnabled());
+
+    root->setEnabled(false);
+    QVERIFY(!child1->isEnabled());
+    QVERIFY(!child2->isEnabled());
+
+    root->setEnabled(true);
+    QVERIFY(child1->isEnabled());
+    QVERIFY(child2->isEnabled());
+
+    child1->setEnabled(false);
+    QVERIFY(!child1->isEnabled());
+    QVERIFY(child2->isEnabled());
+
+    child2->setParentItem(child1);
+    QVERIFY(!child1->isEnabled());
+    QVERIFY(!child2->isEnabled());
+
+    child2->setParentItem(root);
+    QVERIFY(!child1->isEnabled());
+    QVERIFY(child2->isEnabled());
+
+    delete root;
+    delete child1;
+    delete child2;
+}
+
+void tst_qquickitem::mouseGrab()
+{
+    QQuickCanvas *canvas = new QQuickCanvas;
+    canvas->resize(200, 200);
+    canvas->show();
+
+    TestItem *child1 = new TestItem;
+    child1->setAcceptedMouseButtons(Qt::LeftButton);
+    child1->setSize(QSizeF(200, 100));
+    child1->setParentItem(canvas->rootItem());
+
+    TestItem *child2 = new TestItem;
+    child2->setAcceptedMouseButtons(Qt::LeftButton);
+    child2->setY(51);
+    child2->setSize(QSizeF(200, 100));
+    child2->setParentItem(canvas->rootItem());
+
+    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
+    QTest::qWait(100);
+    qDebug() << canvas->mouseGrabberItem();
+    QVERIFY(canvas->mouseGrabberItem() == child1);
+    QTest::qWait(100);
+
+    QCOMPARE(child1->pressCount, 1);
+    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
+    QTest::qWait(50);
+    QVERIFY(canvas->mouseGrabberItem() == 0);
+    QCOMPARE(child1->releaseCount, 1);
+
+    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
+    QTest::qWait(50);
+    QVERIFY(canvas->mouseGrabberItem() == child1);
+    QCOMPARE(child1->pressCount, 2);
+    child1->setEnabled(false);
+    QVERIFY(canvas->mouseGrabberItem() == 0);
+    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
+    QTest::qWait(50);
+    QCOMPARE(child1->releaseCount, 1);
+    child1->setEnabled(true);
+
+    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
+    QTest::qWait(50);
+    QVERIFY(canvas->mouseGrabberItem() == child1);
+    QCOMPARE(child1->pressCount, 3);
+    child1->setVisible(false);
+    QVERIFY(canvas->mouseGrabberItem() == 0);
+    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
+    QCOMPARE(child1->releaseCount, 1);
+    child1->setVisible(true);
+
+    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
+    QTest::qWait(50);
+    QVERIFY(canvas->mouseGrabberItem() == child1);
+    QCOMPARE(child1->pressCount, 4);
+    child2->grabMouse();
+    QVERIFY(canvas->mouseGrabberItem() == child2);
+    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
+    QTest::qWait(50);
+    QCOMPARE(child1->releaseCount, 1);
+    QCOMPARE(child2->releaseCount, 1);
+
+    child2->grabMouse();
+    QVERIFY(canvas->mouseGrabberItem() == child2);
+    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
+    QTest::qWait(50);
+    QCOMPARE(child1->pressCount, 4);
+    QCOMPARE(child2->pressCount, 1);
+    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
+    QTest::qWait(50);
+    QCOMPARE(child1->releaseCount, 1);
+    QCOMPARE(child2->releaseCount, 2);
+
+    delete child1;
+    delete child2;
+    delete canvas;
+}
+
+void tst_qquickitem::polishOutsideAnimation()
+{
+    QQuickCanvas *canvas = new QQuickCanvas;
+    canvas->resize(200, 200);
+    canvas->show();
+
+    TestPolishItem *item = new TestPolishItem(canvas->rootItem());
+    item->setSize(QSizeF(200, 100));
+    QTest::qWait(50);
+    QTRY_VERIFY(item->wasPolished);
+
+    delete item;
+    delete canvas;
+}
+
+void tst_qquickitem::wheelEvent_data()
+{
+    QTest::addColumn<bool>("visible");
+    QTest::addColumn<bool>("enabled");
+
+    QTest::newRow("visible and enabled") << true << true;
+    QTest::newRow("visible and disabled") << true << false;
+    QTest::newRow("invisible and enabled") << false << true;
+    QTest::newRow("invisible and disabled") << false << false;
+}
+
+void tst_qquickitem::wheelEvent()
+{
+    QFETCH(bool, visible);
+    QFETCH(bool, enabled);
+
+    const bool shouldReceiveWheelEvents = visible && enabled;
+
+    QQuickCanvas *canvas = new QQuickCanvas;
+    canvas->resize(200, 200);
+    canvas->show();
+
+    TestItem *item = new TestItem;
+    item->setSize(QSizeF(200, 100));
+    item->setParentItem(canvas->rootItem());
+
+    item->setEnabled(enabled);
+    item->setVisible(visible);
+
+    QWheelEvent event(QPoint(100, 50), -120, Qt::NoButton, Qt::NoModifier, Qt::Vertical);
+    event.setAccepted(false);
+    QApplication::sendEvent(canvas, &event);
+
+    if (shouldReceiveWheelEvents) {
+        QVERIFY(event.isAccepted());
+        QCOMPARE(item->wheelCount, 1);
+    } else {
+        QVERIFY(!event.isAccepted());
+        QCOMPARE(item->wheelCount, 0);
+    }
+
+    delete canvas;
+}
+
+class HoverItem : public QQuickItem
+{
+Q_OBJECT
+public:
+    HoverItem(QQuickItem *parent = 0)
+        : QQuickItem(parent), hoverEnterCount(0), hoverMoveCount(0), hoverLeaveCount(0)
+    { }
+    void resetCounters() {
+        hoverEnterCount = 0;
+        hoverMoveCount = 0;
+        hoverLeaveCount = 0;
+    }
+    int hoverEnterCount;
+    int hoverMoveCount;
+    int hoverLeaveCount;
+protected:
+    virtual void hoverEnterEvent(QHoverEvent *event) {
+        event->accept();
+        ++hoverEnterCount;
+    }
+    virtual void hoverMoveEvent(QHoverEvent *event) {
+        event->accept();
+        ++hoverMoveCount;
+    }
+    virtual void hoverLeaveEvent(QHoverEvent *event) {
+        event->accept();
+        ++hoverLeaveCount;
+    }
+};
+
+void tst_qquickitem::hoverEvent_data()
+{
+    QTest::addColumn<bool>("visible");
+    QTest::addColumn<bool>("enabled");
+    QTest::addColumn<bool>("acceptHoverEvents");
+
+    QTest::newRow("visible, enabled, accept hover") << true << true << true;
+    QTest::newRow("visible, disabled, accept hover") << true << false << true;
+    QTest::newRow("invisible, enabled, accept hover") << false << true << true;
+    QTest::newRow("invisible, disabled, accept hover") << false << false << true;
+
+    QTest::newRow("visible, enabled, not accept hover") << true << true << false;
+    QTest::newRow("visible, disabled, not accept hover") << true << false << false;
+    QTest::newRow("invisible, enabled, not accept hover") << false << true << false;
+    QTest::newRow("invisible, disabled, not accept hover") << false << false << false;
+}
+
+// ### For some unknown reason QTest::mouseMove() isn't working correctly.
+static void sendMouseMove(QObject *object, const QPoint &position)
+{
+    QMouseEvent moveEvent(QEvent::MouseMove, position, Qt::NoButton, Qt::NoButton, 0);
+    QApplication::sendEvent(object, &moveEvent);
+}
+
+void tst_qquickitem::hoverEvent()
+{
+    QFETCH(bool, visible);
+    QFETCH(bool, enabled);
+    QFETCH(bool, acceptHoverEvents);
+
+    QQuickCanvas *canvas = new QQuickCanvas();
+    canvas->resize(200, 200);
+    canvas->show();
+
+    HoverItem *item = new HoverItem;
+    item->setSize(QSizeF(100, 100));
+    item->setParentItem(canvas->rootItem());
+
+    item->setEnabled(enabled);
+    item->setVisible(visible);
+    item->setAcceptHoverEvents(acceptHoverEvents);
+
+    const QPoint outside(150, 150);
+    const QPoint inside(50, 50);
+    const QPoint anotherInside(51, 51);
+
+    sendMouseMove(canvas, outside);
+    item->resetCounters();
+
+    // Enter, then move twice inside, then leave.
+    sendMouseMove(canvas, inside);
+    sendMouseMove(canvas, anotherInside);
+    sendMouseMove(canvas, inside);
+    sendMouseMove(canvas, outside);
+
+    const bool shouldReceiveHoverEvents = visible && enabled && acceptHoverEvents;
+    if (shouldReceiveHoverEvents) {
+        QCOMPARE(item->hoverEnterCount, 1);
+        QCOMPARE(item->hoverMoveCount, 2);
+        QCOMPARE(item->hoverLeaveCount, 1);
+    } else {
+        QCOMPARE(item->hoverEnterCount, 0);
+        QCOMPARE(item->hoverMoveCount, 0);
+        QCOMPARE(item->hoverLeaveCount, 0);
+    }
+
+    delete canvas;
+}
+
+void tst_qquickitem::hoverEventInParent()
+{
+    QQuickCanvas *canvas = new QQuickCanvas();
+    canvas->resize(200, 200);
+    canvas->show();
+
+    HoverItem *parentItem = new HoverItem(canvas->rootItem());
+    parentItem->setSize(QSizeF(200, 200));
+    parentItem->setAcceptHoverEvents(true);
+
+    HoverItem *leftItem = new HoverItem(parentItem);
+    leftItem->setSize(QSizeF(100, 200));
+    leftItem->setAcceptHoverEvents(true);
+
+    HoverItem *rightItem = new HoverItem(parentItem);
+    rightItem->setSize(QSizeF(100, 200));
+    rightItem->setPos(QPointF(100, 0));
+    rightItem->setAcceptHoverEvents(true);
+
+    const QPoint insideLeft(50, 100);
+    const QPoint insideRight(150, 100);
+
+    sendMouseMove(canvas, insideLeft);
+    parentItem->resetCounters();
+    leftItem->resetCounters();
+    rightItem->resetCounters();
+
+    sendMouseMove(canvas, insideRight);
+    QCOMPARE(parentItem->hoverEnterCount, 0);
+    QCOMPARE(parentItem->hoverLeaveCount, 0);
+    QCOMPARE(leftItem->hoverEnterCount, 0);
+    QCOMPARE(leftItem->hoverLeaveCount, 1);
+    QCOMPARE(rightItem->hoverEnterCount, 1);
+    QCOMPARE(rightItem->hoverLeaveCount, 0);
+
+    sendMouseMove(canvas, insideLeft);
+    QCOMPARE(parentItem->hoverEnterCount, 0);
+    QCOMPARE(parentItem->hoverLeaveCount, 0);
+    QCOMPARE(leftItem->hoverEnterCount, 1);
+    QCOMPARE(leftItem->hoverLeaveCount, 1);
+    QCOMPARE(rightItem->hoverEnterCount, 1);
+    QCOMPARE(rightItem->hoverLeaveCount, 1);
+
+    delete canvas;
+}
+
+QTEST_MAIN(tst_qquickitem)
+
+#include "tst_qquickitem.moc"
diff --git a/tests/auto/declarative/qquickitem2/qquickitem2.pro b/tests/auto/declarative/qquickitem2/qquickitem2.pro
new file mode 100644 (file)
index 0000000..47b31d9
--- /dev/null
@@ -0,0 +1,13 @@
+CONFIG += testcase
+TARGET = tst_qquickitem
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qquickitem.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/qquickitem2/tst_qquickitem.cpp b/tests/auto/declarative/qquickitem2/tst_qquickitem.cpp
new file mode 100644 (file)
index 0000000..711ca17
--- /dev/null
@@ -0,0 +1,1261 @@
+/****************************************************************************
+**
+** 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/QSignalSpy>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qquickview.h>
+#include <private/qquickrectangle_p.h>
+#include <private/qquickitem_p.h>
+#include "../shared/util.h"
+
+class tst_QQuickItem : public QObject
+{
+    Q_OBJECT
+public:
+    tst_QQuickItem();
+
+private slots:
+    void initTestCase();
+    void keys();
+    void keysProcessingOrder();
+    void keyNavigation();
+    void keyNavigation_RightToLeft();
+    void keyNavigation_skipNotVisible();
+    void keyNavigation_implicitSetting();
+    void layoutMirroring();
+    void layoutMirroringIllegalParent();
+    void smooth();
+    void clip();
+    void mapCoordinates();
+    void mapCoordinates_data();
+    void propertyChanges();
+    void transforms();
+    void transforms_data();
+    void childrenRect();
+    void childrenRectBug();
+    void childrenRectBug2();
+    void childrenRectBug3();
+
+    void childrenProperty();
+    void resourcesProperty();
+
+    void transformCrash();
+    void implicitSize();
+    void qtbug_16871();
+private:
+    QDeclarativeEngine engine;
+};
+
+template<typename T>
+T *findItem(QQuickItem *parent, const QString &objectName)
+{
+    if (!parent)
+        return 0;
+
+    const QMetaObject &mo = T::staticMetaObject;
+    //qDebug() << parent->QQuickItem::children().count() << "children";
+    for (int i = 0; i < parent->childItems().count(); ++i) {
+        QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
+        if (!item)
+            continue;
+        //qDebug() << "try" << item;
+        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName))
+            return static_cast<T*>(item);
+        item = findItem<T>(item, objectName);
+        if (item)
+            return static_cast<T*>(item);
+    }
+
+    return 0;
+}
+
+class KeysTestObject : public QObject
+{
+    Q_OBJECT
+
+    Q_PROPERTY(bool processLast READ processLast NOTIFY processLastChanged)
+
+public:
+    KeysTestObject() : mKey(0), mModifiers(0), mForwardedKey(0), mLast(false) {}
+
+    void reset() {
+        mKey = 0;
+        mText = QString();
+        mModifiers = 0;
+        mForwardedKey = 0;
+    }
+
+    bool processLast() const { return mLast; }
+    void setProcessLast(bool b) {
+        if (b != mLast) {
+            mLast = b;
+            emit processLastChanged();
+        }
+    }
+
+public slots:
+    void keyPress(int key, QString text, int modifiers) {
+        mKey = key;
+        mText = text;
+        mModifiers = modifiers;
+    }
+    void keyRelease(int key, QString text, int modifiers) {
+        mKey = key;
+        mText = text;
+        mModifiers = modifiers;
+    }
+    void forwardedKey(int key) {
+        mForwardedKey = key;
+    }
+
+signals:
+    void processLastChanged();
+
+public:
+    int mKey;
+    QString mText;
+    int mModifiers;
+    int mForwardedKey;
+    bool mLast;
+
+private:
+};
+
+class KeyTestItem : public QQuickItem
+{
+    Q_OBJECT
+public:
+    KeyTestItem(QQuickItem *parent=0) : QQuickItem(parent), mKey(0) {}
+
+protected:
+    void keyPressEvent(QKeyEvent *e) {
+        mKey = e->key();
+
+        if (e->key() == Qt::Key_A)
+            e->accept();
+        else
+            e->ignore();
+    }
+
+    void keyReleaseEvent(QKeyEvent *e) {
+        if (e->key() == Qt::Key_B)
+            e->accept();
+        else
+            e->ignore();
+    }
+
+public:
+    int mKey;
+};
+
+QML_DECLARE_TYPE(KeyTestItem);
+
+
+tst_QQuickItem::tst_QQuickItem()
+{
+}
+
+void tst_QQuickItem::initTestCase()
+{
+    qmlRegisterType<KeyTestItem>("Test",1,0,"KeyTestItem");
+}
+
+void tst_QQuickItem::keys()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setBaseSize(QSize(240,320));
+
+    KeysTestObject *testObject = new KeysTestObject;
+    canvas->rootContext()->setContextProperty("keysTestObject", testObject);
+
+    canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(true));
+    canvas->rootContext()->setContextProperty("forwardeeVisible", QVariant(true));
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("keystest.qml")));
+    canvas->show();
+    qApp->processEvents();
+
+    QEvent wa(QEvent::WindowActivate);
+    QApplication::sendEvent(canvas, &wa);
+    QFocusEvent fe(QEvent::FocusIn);
+    QApplication::sendEvent(canvas, &fe);
+
+    QVERIFY(canvas->rootObject());
+    QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), true);
+
+    QKeyEvent key(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QCOMPARE(testObject->mKey, int(Qt::Key_A));
+    QCOMPARE(testObject->mForwardedKey, int(Qt::Key_A));
+    QCOMPARE(testObject->mText, QLatin1String("A"));
+    QVERIFY(testObject->mModifiers == Qt::NoModifier);
+    QVERIFY(!key.isAccepted());
+
+    testObject->reset();
+
+    key = QKeyEvent(QEvent::KeyRelease, Qt::Key_A, Qt::ShiftModifier, "A", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QCOMPARE(testObject->mKey, int(Qt::Key_A));
+    QCOMPARE(testObject->mForwardedKey, int(Qt::Key_A));
+    QCOMPARE(testObject->mText, QLatin1String("A"));
+    QVERIFY(testObject->mModifiers == Qt::ShiftModifier);
+    QVERIFY(key.isAccepted());
+
+    testObject->reset();
+
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QCOMPARE(testObject->mKey, int(Qt::Key_Return));
+    QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Return));
+    QCOMPARE(testObject->mText, QLatin1String("Return"));
+    QVERIFY(testObject->mModifiers == Qt::NoModifier);
+    QVERIFY(key.isAccepted());
+
+    testObject->reset();
+
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_0, Qt::NoModifier, "0", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QCOMPARE(testObject->mKey, int(Qt::Key_0));
+    QCOMPARE(testObject->mForwardedKey, int(Qt::Key_0));
+    QCOMPARE(testObject->mText, QLatin1String("0"));
+    QVERIFY(testObject->mModifiers == Qt::NoModifier);
+    QVERIFY(key.isAccepted());
+
+    testObject->reset();
+
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_9, Qt::NoModifier, "9", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QCOMPARE(testObject->mKey, int(Qt::Key_9));
+    QCOMPARE(testObject->mForwardedKey, int(Qt::Key_9));
+    QCOMPARE(testObject->mText, QLatin1String("9"));
+    QVERIFY(testObject->mModifiers == Qt::NoModifier);
+    QVERIFY(!key.isAccepted());
+
+    testObject->reset();
+
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QCOMPARE(testObject->mKey, int(Qt::Key_Tab));
+    QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Tab));
+    QCOMPARE(testObject->mText, QLatin1String("Tab"));
+    QVERIFY(testObject->mModifiers == Qt::NoModifier);
+    QVERIFY(key.isAccepted());
+
+    testObject->reset();
+
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QCOMPARE(testObject->mKey, int(Qt::Key_Backtab));
+    QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Backtab));
+    QCOMPARE(testObject->mText, QLatin1String("Backtab"));
+    QVERIFY(testObject->mModifiers == Qt::NoModifier);
+    QVERIFY(key.isAccepted());
+
+    testObject->reset();
+
+    canvas->rootContext()->setContextProperty("forwardeeVisible", QVariant(false));
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QCOMPARE(testObject->mKey, int(Qt::Key_A));
+    QCOMPARE(testObject->mForwardedKey, 0);
+    QCOMPARE(testObject->mText, QLatin1String("A"));
+    QVERIFY(testObject->mModifiers == Qt::NoModifier);
+    QVERIFY(!key.isAccepted());
+
+    testObject->reset();
+
+    canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(false));
+    QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), false);
+
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QCOMPARE(testObject->mKey, 0);
+    QVERIFY(!key.isAccepted());
+
+    canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(true));
+    QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), true);
+
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QCOMPARE(testObject->mKey, int(Qt::Key_Return));
+    QVERIFY(key.isAccepted());
+
+    delete canvas;
+    delete testObject;
+}
+
+void tst_QQuickItem::keysProcessingOrder()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setBaseSize(QSize(240,320));
+
+    KeysTestObject *testObject = new KeysTestObject;
+    canvas->rootContext()->setContextProperty("keysTestObject", testObject);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("keyspriority.qml")));
+    canvas->show();
+    qApp->processEvents();
+
+    KeyTestItem *testItem = qobject_cast<KeyTestItem*>(canvas->rootObject());
+    QVERIFY(testItem);
+
+    QEvent wa(QEvent::WindowActivate);
+    QApplication::sendEvent(canvas, &wa);
+    QFocusEvent fe(QEvent::FocusIn);
+    QApplication::sendEvent(canvas, &fe);
+
+    QKeyEvent key(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QCOMPARE(testObject->mKey, int(Qt::Key_A));
+    QCOMPARE(testObject->mText, QLatin1String("A"));
+    QVERIFY(testObject->mModifiers == Qt::NoModifier);
+    QVERIFY(key.isAccepted());
+
+    testObject->reset();
+
+    testObject->setProcessLast(true);
+
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QCOMPARE(testObject->mKey, 0);
+    QVERIFY(key.isAccepted());
+
+    testObject->reset();
+
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_B, Qt::NoModifier, "B", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QCOMPARE(testObject->mKey, int(Qt::Key_B));
+    QCOMPARE(testObject->mText, QLatin1String("B"));
+    QVERIFY(testObject->mModifiers == Qt::NoModifier);
+    QVERIFY(!key.isAccepted());
+
+    testObject->reset();
+
+    key = QKeyEvent(QEvent::KeyRelease, Qt::Key_B, Qt::NoModifier, "B", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QCOMPARE(testObject->mKey, 0);
+    QVERIFY(key.isAccepted());
+
+    delete canvas;
+    delete testObject;
+}
+
+QQuickItemPrivate *childPrivate(QQuickItem *rootItem, const char * itemString)
+{
+    QQuickItem *item = findItem<QQuickItem>(rootItem, QString(QLatin1String(itemString)));
+    QQuickItemPrivate* itemPrivate = QQuickItemPrivate::get(item);
+    return itemPrivate;
+}
+
+QVariant childProperty(QQuickItem *rootItem, const char * itemString, const char * property)
+{
+    QQuickItem *item = findItem<QQuickItem>(rootItem, QString(QLatin1String(itemString)));
+    return item->property(property);
+}
+
+bool anchorsMirrored(QQuickItem *rootItem, const char * itemString)
+{
+    QQuickItem *item = findItem<QQuickItem>(rootItem, QString(QLatin1String(itemString)));
+    QQuickItemPrivate* itemPrivate = QQuickItemPrivate::get(item);
+    return itemPrivate->anchors()->mirrored();
+}
+
+void tst_QQuickItem::layoutMirroring()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("layoutmirroring.qml")));
+    canvas->show();
+
+    QQuickItem *rootItem = qobject_cast<QQuickItem*>(canvas->rootObject());
+    QVERIFY(rootItem);
+    QQuickItemPrivate *rootPrivate = QQuickItemPrivate::get(rootItem);
+    QVERIFY(rootPrivate);
+
+    QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true);
+    QCOMPARE(childPrivate(rootItem, "mirrored2")->effectiveLayoutMirror, true);
+    QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false);
+    QCOMPARE(childPrivate(rootItem, "notMirrored2")->effectiveLayoutMirror, false);
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, true);
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, true);
+
+    QCOMPARE(anchorsMirrored(rootItem, "mirrored1"), true);
+    QCOMPARE(anchorsMirrored(rootItem, "mirrored2"), true);
+    QCOMPARE(anchorsMirrored(rootItem, "notMirrored1"), false);
+    QCOMPARE(anchorsMirrored(rootItem, "notMirrored2"), false);
+    QCOMPARE(anchorsMirrored(rootItem, "inheritedMirror1"), true);
+    QCOMPARE(anchorsMirrored(rootItem, "inheritedMirror2"), true);
+
+    QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, true);
+    QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritedLayoutMirror, false);
+    QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, true);
+    QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritedLayoutMirror, false);
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, true);
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, true);
+
+    QCOMPARE(childPrivate(rootItem, "mirrored1")->isMirrorImplicit, false);
+    QCOMPARE(childPrivate(rootItem, "mirrored2")->isMirrorImplicit, false);
+    QCOMPARE(childPrivate(rootItem, "notMirrored1")->isMirrorImplicit, false);
+    QCOMPARE(childPrivate(rootItem, "notMirrored2")->isMirrorImplicit, true);
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->isMirrorImplicit, true);
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->isMirrorImplicit, true);
+
+    QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritMirrorFromParent, true);
+    QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritMirrorFromParent, false);
+    QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritMirrorFromParent, true);
+    QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritMirrorFromParent, false);
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritMirrorFromParent, true);
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritMirrorFromParent, true);
+
+    QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritMirrorFromItem, true);
+    QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritMirrorFromItem, false);
+    QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritMirrorFromItem, false);
+    QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritMirrorFromItem, false);
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritMirrorFromItem, false);
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritMirrorFromItem, false);
+
+    // load dynamic content using Loader that needs to inherit mirroring
+    rootItem->setProperty("state", "newContent");
+    QCOMPARE(childPrivate(rootItem, "notMirrored3")->effectiveLayoutMirror, false);
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->effectiveLayoutMirror, true);
+
+    QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritedLayoutMirror, true);
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->inheritedLayoutMirror, true);
+
+    QCOMPARE(childPrivate(rootItem, "notMirrored3")->isMirrorImplicit, false);
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->isMirrorImplicit, true);
+
+    QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromParent, true);
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->inheritMirrorFromParent, true);
+
+    QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromItem, false);
+    QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromItem, false);
+
+    // disable inheritance
+    rootItem->setProperty("childrenInherit", false);
+
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, false);
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, false);
+    QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true);
+    QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false);
+
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, false);
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, false);
+    QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, false);
+    QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, false);
+
+    // re-enable inheritance
+    rootItem->setProperty("childrenInherit", true);
+
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, true);
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, true);
+    QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true);
+    QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false);
+
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, true);
+    QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, true);
+    QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, true);
+    QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, true);
+
+    //
+    // dynamic parenting
+    //
+    QQuickItem *parentItem1 = new QQuickItem();
+    QQuickItemPrivate::get(parentItem1)->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true
+    QQuickItemPrivate::get(parentItem1)->isMirrorImplicit = false;
+    QQuickItemPrivate::get(parentItem1)->inheritMirrorFromItem = true; // LayoutMirroring.childrenInherit: true
+    QQuickItemPrivate::get(parentItem1)->resolveLayoutMirror();
+
+    // inherit in constructor
+    QQuickItem *childItem1 = new QQuickItem(parentItem1);
+    QCOMPARE(QQuickItemPrivate::get(childItem1)->effectiveLayoutMirror, true);
+    QCOMPARE(QQuickItemPrivate::get(childItem1)->inheritMirrorFromParent, true);
+
+    // inherit through a parent change
+    QQuickItem *childItem2 = new QQuickItem();
+    QCOMPARE(QQuickItemPrivate::get(childItem2)->effectiveLayoutMirror, false);
+    QCOMPARE(QQuickItemPrivate::get(childItem2)->inheritMirrorFromParent, false);
+    childItem2->setParentItem(parentItem1);
+    QCOMPARE(QQuickItemPrivate::get(childItem2)->effectiveLayoutMirror, true);
+    QCOMPARE(QQuickItemPrivate::get(childItem2)->inheritMirrorFromParent, true);
+
+    // stop inherting through a parent change
+    QQuickItem *parentItem2 = new QQuickItem();
+    QQuickItemPrivate::get(parentItem2)->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true
+    QQuickItemPrivate::get(parentItem2)->resolveLayoutMirror();
+    childItem2->setParentItem(parentItem2);
+    QCOMPARE(QQuickItemPrivate::get(childItem2)->effectiveLayoutMirror, false);
+    QCOMPARE(QQuickItemPrivate::get(childItem2)->inheritMirrorFromParent, false);
+
+    delete parentItem1;
+    delete parentItem2;
+}
+
+void tst_QQuickItem::layoutMirroringIllegalParent()
+{
+    QDeclarativeComponent component(&engine);
+    component.setData("import QtQuick 2.0; QtObject { LayoutMirroring.enabled: true; LayoutMirroring.childrenInherit: true }", QUrl::fromLocalFile(""));
+    QTest::ignoreMessage(QtWarningMsg, "file::1:21: QML QtObject: LayoutDirection attached property only works with Items");
+    QObject *object = component.create();
+    QVERIFY(object != 0);
+}
+
+void tst_QQuickItem::keyNavigation()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setBaseSize(QSize(240,320));
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest.qml")));
+    canvas->show();
+    qApp->processEvents();
+
+    QEvent wa(QEvent::WindowActivate);
+    QApplication::sendEvent(canvas, &wa);
+    QFocusEvent fe(QEvent::FocusIn);
+    QApplication::sendEvent(canvas, &fe);
+
+    QQuickItem *item = findItem<QQuickItem>(canvas->rootObject(), "item1");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    QVariant result;
+    QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify",
+            Q_RETURN_ARG(QVariant, result)));
+    QVERIFY(result.toBool());
+
+    // right
+    QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item2");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // down
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item4");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // left
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item3");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // up
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item1");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // tab
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item2");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // backtab
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item1");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    delete canvas;
+}
+
+void tst_QQuickItem::keyNavigation_RightToLeft()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setBaseSize(QSize(240,320));
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest.qml")));
+    canvas->show();
+    qApp->processEvents();
+
+    QQuickItem *rootItem = qobject_cast<QQuickItem*>(canvas->rootObject());
+    QVERIFY(rootItem);
+    QQuickItemPrivate* rootItemPrivate = QQuickItemPrivate::get(rootItem);
+
+    rootItemPrivate->effectiveLayoutMirror = true; // LayoutMirroring.mirror: true
+    rootItemPrivate->isMirrorImplicit = false;
+    rootItemPrivate->inheritMirrorFromItem = true; // LayoutMirroring.inherit: true
+    rootItemPrivate->resolveLayoutMirror();
+
+    QEvent wa(QEvent::WindowActivate);
+    QApplication::sendEvent(canvas, &wa);
+    QFocusEvent fe(QEvent::FocusIn);
+    QApplication::sendEvent(canvas, &fe);
+
+    QQuickItem *item = findItem<QQuickItem>(canvas->rootObject(), "item1");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    QVariant result;
+    QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify",
+            Q_RETURN_ARG(QVariant, result)));
+    QVERIFY(result.toBool());
+
+    // right
+    QKeyEvent key(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item2");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // left
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item1");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    delete canvas;
+}
+
+void tst_QQuickItem::keyNavigation_skipNotVisible()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setBaseSize(QSize(240,320));
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest.qml")));
+    canvas->show();
+    qApp->processEvents();
+
+    QEvent wa(QEvent::WindowActivate);
+    QApplication::sendEvent(canvas, &wa);
+    QFocusEvent fe(QEvent::FocusIn);
+    QApplication::sendEvent(canvas, &fe);
+
+    QQuickItem *item = findItem<QQuickItem>(canvas->rootObject(), "item1");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // Set item 2 to not visible
+    item = findItem<QQuickItem>(canvas->rootObject(), "item2");
+    QVERIFY(item);
+    item->setVisible(false);
+    QVERIFY(!item->isVisible());
+
+    // right
+    QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item1");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // tab
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item3");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // backtab
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item1");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    //Set item 3 to not visible
+    item = findItem<QQuickItem>(canvas->rootObject(), "item3");
+    QVERIFY(item);
+    item->setVisible(false);
+    QVERIFY(!item->isVisible());
+
+    // tab
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item4");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // backtab
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item1");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    delete canvas;
+}
+
+void tst_QQuickItem::keyNavigation_implicitSetting()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setBaseSize(QSize(240,320));
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest_implicit.qml")));
+    canvas->show();
+    qApp->processEvents();
+
+    QEvent wa(QEvent::WindowActivate);
+    QApplication::sendEvent(canvas, &wa);
+    QFocusEvent fe(QEvent::FocusIn);
+    QApplication::sendEvent(canvas, &fe);
+
+    QQuickItem *item = findItem<QQuickItem>(canvas->rootObject(), "item1");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    QVariant result;
+    QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify",
+            Q_RETURN_ARG(QVariant, result)));
+    QVERIFY(result.toBool());
+
+    // right
+    QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item2");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // back to item1
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item1");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // down
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item3");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // move to item4
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item4");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // left
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item3");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // back to item4
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item4");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // up
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item2");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // back to item4
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item4");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // tab
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item1");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // back to item4
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item4");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    // backtab
+    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
+    QApplication::sendEvent(canvas, &key);
+    QVERIFY(key.isAccepted());
+
+    item = findItem<QQuickItem>(canvas->rootObject(), "item3");
+    QVERIFY(item);
+    QVERIFY(item->hasActiveFocus());
+
+    delete canvas;
+}
+
+void tst_QQuickItem::smooth()
+{
+    QDeclarativeComponent component(&engine);
+    component.setData("import QtQuick 2.0; Item { smooth: false; }", QUrl::fromLocalFile(""));
+    QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+    QSignalSpy spy(item, SIGNAL(smoothChanged(bool)));
+
+    QVERIFY(item);
+    QVERIFY(!item->smooth());
+
+    item->setSmooth(true);
+    QVERIFY(item->smooth());
+    QCOMPARE(spy.count(),1);
+    QList<QVariant> arguments = spy.first();
+    QVERIFY(arguments.count() == 1);
+    QVERIFY(arguments.at(0).toBool() == true);
+
+    item->setSmooth(true);
+    QCOMPARE(spy.count(),1);
+
+    item->setSmooth(false);
+    QVERIFY(!item->smooth());
+    QCOMPARE(spy.count(),2);
+    item->setSmooth(false);
+    QCOMPARE(spy.count(),2);
+
+    delete item;
+}
+
+void tst_QQuickItem::clip()
+{
+    QDeclarativeComponent component(&engine);
+    component.setData("import QtQuick 2.0\nItem { clip: false\n }", QUrl::fromLocalFile(""));
+    QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+    QSignalSpy spy(item, SIGNAL(clipChanged(bool)));
+
+    QVERIFY(item);
+    QVERIFY(!item->clip());
+
+    item->setClip(true);
+    QVERIFY(item->clip());
+
+    QList<QVariant> arguments = spy.first();
+    QVERIFY(arguments.count() == 1);
+    QVERIFY(arguments.at(0).toBool() == true);
+
+    QCOMPARE(spy.count(),1);
+    item->setClip(true);
+    QCOMPARE(spy.count(),1);
+
+    item->setClip(false);
+    QVERIFY(!item->clip());
+    QCOMPARE(spy.count(),2);
+    item->setClip(false);
+    QCOMPARE(spy.count(),2);
+
+    delete item;
+}
+
+void tst_QQuickItem::mapCoordinates()
+{
+    QFETCH(int, x);
+    QFETCH(int, y);
+
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setBaseSize(QSize(300, 300));
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("mapCoordinates.qml")));
+    canvas->show();
+    qApp->processEvents();
+
+    QQuickItem *root = qobject_cast<QQuickItem*>(canvas->rootObject());
+    QVERIFY(root != 0);
+    QQuickItem *a = findItem<QQuickItem>(canvas->rootObject(), "itemA");
+    QVERIFY(a != 0);
+    QQuickItem *b = findItem<QQuickItem>(canvas->rootObject(), "itemB");
+    QVERIFY(b != 0);
+
+    QVariant result;
+
+    QVERIFY(QMetaObject::invokeMethod(root, "mapAToB",
+            Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
+    QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapToItem(b, QPointF(x, y)));
+
+    QVERIFY(QMetaObject::invokeMethod(root, "mapAFromB",
+            Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
+    QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapFromItem(b, QPointF(x, y)));
+
+    QVERIFY(QMetaObject::invokeMethod(root, "mapAToNull",
+            Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
+    QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapToScene(QPointF(x, y)));
+
+    QVERIFY(QMetaObject::invokeMethod(root, "mapAFromNull",
+            Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
+    QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapFromScene(QPointF(x, y)));
+
+    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",
+            Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
+    QVERIFY(result.toBool());
+
+    QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
+    QVERIFY(QMetaObject::invokeMethod(root, "checkMapAFromInvalid",
+            Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
+    QVERIFY(result.toBool());
+
+    delete canvas;
+}
+
+void tst_QQuickItem::mapCoordinates_data()
+{
+    QTest::addColumn<int>("x");
+    QTest::addColumn<int>("y");
+
+    for (int i=-20; i<=20; i+=10)
+        QTest::newRow(QTest::toString(i)) << i << i;
+}
+
+void tst_QQuickItem::transforms_data()
+{
+    QTest::addColumn<QByteArray>("qml");
+    QTest::addColumn<QTransform>("transform");
+    QTest::newRow("translate") << QByteArray("Translate { x: 10; y: 20 }")
+        << QTransform(1,0,0,0,1,0,10,20,1);
+    QTest::newRow("rotation") << QByteArray("Rotation { angle: 90 }")
+        << QTransform(0,1,0,-1,0,0,0,0,1);
+    QTest::newRow("scale") << QByteArray("Scale { xScale: 1.5; yScale: -2  }")
+        << QTransform(1.5,0,0,0,-2,0,0,0,1);
+    QTest::newRow("sequence") << QByteArray("[ Translate { x: 10; y: 20 }, Scale { xScale: 1.5; yScale: -2  } ]")
+        << QTransform(1,0,0,0,1,0,10,20,1) * QTransform(1.5,0,0,0,-2,0,0,0,1);
+}
+
+void tst_QQuickItem::transforms()
+{
+    QFETCH(QByteArray, qml);
+    QFETCH(QTransform, transform);
+    QDeclarativeComponent component(&engine);
+    component.setData("import QtQuick 2.0\nItem { transform: "+qml+"}", QUrl::fromLocalFile(""));
+    QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+    QCOMPARE(item->itemTransform(0,0), transform);
+}
+
+void tst_QQuickItem::childrenProperty()
+{
+    QDeclarativeComponent component(&engine, TESTDATA("childrenProperty.qml"));
+
+    QObject *o = component.create();
+    QVERIFY(o != 0);
+
+    QCOMPARE(o->property("test1").toBool(), true);
+    QCOMPARE(o->property("test2").toBool(), true);
+    QCOMPARE(o->property("test3").toBool(), true);
+    QCOMPARE(o->property("test4").toBool(), true);
+    QCOMPARE(o->property("test5").toBool(), true);
+    delete o;
+}
+
+void tst_QQuickItem::resourcesProperty()
+{
+    QDeclarativeComponent component(&engine, TESTDATA("resourcesProperty.qml"));
+
+    QObject *o = component.create();
+    QVERIFY(o != 0);
+
+    QCOMPARE(o->property("test1").toBool(), true);
+    QCOMPARE(o->property("test2").toBool(), true);
+    QCOMPARE(o->property("test3").toBool(), true);
+    QCOMPARE(o->property("test4").toBool(), true);
+    QCOMPARE(o->property("test5").toBool(), true);
+    delete o;
+}
+
+void tst_QQuickItem::propertyChanges()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setBaseSize(QSize(300, 300));
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml")));
+    canvas->show();
+
+    QTest::qWaitForWindowShown(canvas);
+
+    QQuickItem *item = findItem<QQuickItem>(canvas->rootObject(), "item");
+    QQuickItem *parentItem = findItem<QQuickItem>(canvas->rootObject(), "parentItem");
+
+    QVERIFY(item);
+    QVERIFY(parentItem);
+
+    QSignalSpy parentSpy(item, SIGNAL(parentChanged(QQuickItem *)));
+    QSignalSpy widthSpy(item, SIGNAL(widthChanged()));
+    QSignalSpy heightSpy(item, SIGNAL(heightChanged()));
+    QSignalSpy baselineOffsetSpy(item, SIGNAL(baselineOffsetChanged(qreal)));
+    QSignalSpy childrenRectSpy(parentItem, SIGNAL(childrenRectChanged(QRectF)));
+    QSignalSpy focusSpy(item, SIGNAL(focusChanged(bool)));
+    QSignalSpy wantsFocusSpy(parentItem, SIGNAL(activeFocusChanged(bool)));
+    QSignalSpy childrenChangedSpy(parentItem, SIGNAL(childrenChanged()));
+    QSignalSpy xSpy(item, SIGNAL(xChanged()));
+    QSignalSpy ySpy(item, SIGNAL(yChanged()));
+
+    item->setParentItem(parentItem);
+    item->setWidth(100.0);
+    item->setHeight(200.0);
+    item->setFocus(true);
+    item->setBaselineOffset(10.0);
+
+    QCOMPARE(item->parentItem(), parentItem);
+    QCOMPARE(parentSpy.count(),1);
+    QList<QVariant> parentArguments = parentSpy.first();
+    QVERIFY(parentArguments.count() == 1);
+    QCOMPARE(item->parentItem(), qvariant_cast<QQuickItem *>(parentArguments.at(0)));
+    QCOMPARE(childrenChangedSpy.count(),1);
+
+    item->setParentItem(parentItem);
+    QCOMPARE(childrenChangedSpy.count(),1);
+
+    QCOMPARE(item->width(), 100.0);
+    QCOMPARE(widthSpy.count(),1);
+
+    QCOMPARE(item->height(), 200.0);
+    QCOMPARE(heightSpy.count(),1);
+
+    QCOMPARE(item->baselineOffset(), 10.0);
+    QCOMPARE(baselineOffsetSpy.count(),1);
+    QList<QVariant> baselineOffsetArguments = baselineOffsetSpy.first();
+    QVERIFY(baselineOffsetArguments.count() == 1);
+    QCOMPARE(item->baselineOffset(), baselineOffsetArguments.at(0).toReal());
+
+    QCOMPARE(parentItem->childrenRect(), QRectF(0.0,0.0,100.0,200.0));
+    QCOMPARE(childrenRectSpy.count(),2);
+    QList<QVariant> childrenRectArguments = childrenRectSpy.at(1);
+    QVERIFY(childrenRectArguments.count() == 1);
+    QCOMPARE(parentItem->childrenRect(), childrenRectArguments.at(0).toRectF());
+
+    QCOMPARE(item->hasActiveFocus(), true);
+    QCOMPARE(focusSpy.count(),1);
+    QList<QVariant> focusArguments = focusSpy.first();
+    QVERIFY(focusArguments.count() == 1);
+    QCOMPARE(focusArguments.at(0).toBool(), true);
+
+    QCOMPARE(parentItem->hasActiveFocus(), false);
+    QCOMPARE(parentItem->hasFocus(), false);
+    QCOMPARE(wantsFocusSpy.count(),0);
+
+    item->setX(10.0);
+    QCOMPARE(item->x(), 10.0);
+    QCOMPARE(xSpy.count(), 1);
+
+    item->setY(10.0);
+    QCOMPARE(item->y(), 10.0);
+    QCOMPARE(ySpy.count(), 1);
+
+    delete canvas;
+}
+
+void tst_QQuickItem::childrenRect()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRect.qml")));
+    canvas->setBaseSize(QSize(240,320));
+    canvas->show();
+
+    QQuickItem *o = canvas->rootObject();
+    QQuickItem *item = o->findChild<QQuickItem*>("testItem");
+    QCOMPARE(item->width(), qreal(0));
+    QCOMPARE(item->height(), qreal(0));
+
+    o->setProperty("childCount", 1);
+    QCOMPARE(item->width(), qreal(10));
+    QCOMPARE(item->height(), qreal(20));
+
+    o->setProperty("childCount", 5);
+    QCOMPARE(item->width(), qreal(50));
+    QCOMPARE(item->height(), qreal(100));
+
+    o->setProperty("childCount", 0);
+    QCOMPARE(item->width(), qreal(0));
+    QCOMPARE(item->height(), qreal(0));
+
+    delete o;
+    delete canvas;
+}
+
+// QTBUG-11383
+void tst_QQuickItem::childrenRectBug()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRectBug.qml")));
+    canvas->show();
+
+    QQuickItem *o = canvas->rootObject();
+    QQuickItem *item = o->findChild<QQuickItem*>("theItem");
+    QCOMPARE(item->width(), qreal(200));
+    QCOMPARE(item->height(), qreal(100));
+    QCOMPARE(item->x(), qreal(100));
+
+    delete canvas;
+}
+
+// QTBUG-11465
+void tst_QQuickItem::childrenRectBug2()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRectBug2.qml")));
+    canvas->show();
+
+    QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(canvas->rootObject());
+    QVERIFY(rect);
+    QQuickItem *item = rect->findChild<QQuickItem*>("theItem");
+    QCOMPARE(item->width(), qreal(100));
+    QCOMPARE(item->height(), qreal(110));
+    QCOMPARE(item->x(), qreal(130));
+
+    QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
+    rectPrivate->setState("row");
+    QCOMPARE(item->width(), qreal(210));
+    QCOMPARE(item->height(), qreal(50));
+    QCOMPARE(item->x(), qreal(75));
+
+    delete canvas;
+}
+
+// QTBUG-12722
+void tst_QQuickItem::childrenRectBug3()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRectBug3.qml")));
+    canvas->show();
+
+    //don't crash on delete
+    delete canvas;
+}
+
+// QTBUG-13893
+void tst_QQuickItem::transformCrash()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("transformCrash.qml")));
+    canvas->show();
+
+    delete canvas;
+}
+
+void tst_QQuickItem::implicitSize()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("implicitsize.qml")));
+    canvas->show();
+
+    QQuickItem *item = qobject_cast<QQuickItem*>(canvas->rootObject());
+    QVERIFY(item);
+    QCOMPARE(item->width(), qreal(80));
+    QCOMPARE(item->height(), qreal(60));
+
+    QCOMPARE(item->implicitWidth(), qreal(200));
+    QCOMPARE(item->implicitHeight(), qreal(100));
+
+    QMetaObject::invokeMethod(item, "resetSize");
+
+    QCOMPARE(item->width(), qreal(200));
+    QCOMPARE(item->height(), qreal(100));
+
+    QMetaObject::invokeMethod(item, "changeImplicit");
+
+    QCOMPARE(item->implicitWidth(), qreal(150));
+    QCOMPARE(item->implicitHeight(), qreal(80));
+    QCOMPARE(item->width(), qreal(150));
+    QCOMPARE(item->height(), qreal(80));
+
+    delete canvas;
+}
+
+void tst_QQuickItem::qtbug_16871()
+{
+    QDeclarativeComponent component(&engine, TESTDATA("qtbug_16871.qml"));
+    QObject *o = component.create();
+    QVERIFY(o != 0);
+    delete o;
+}
+
+QTEST_MAIN(tst_QQuickItem)
+
+#include "tst_qquickitem.moc"
diff --git a/tests/auto/declarative/qquicklistview/qquicklistview.pro b/tests/auto/declarative/qquicklistview/qquicklistview.pro
new file mode 100644 (file)
index 0000000..a047651
--- /dev/null
@@ -0,0 +1,13 @@
+CONFIG += testcase
+TARGET = tst_qquicklistview
+macx:CONFIG -= app_bundle
+
+HEADERS += incrementalmodel.h
+SOURCES += tst_qquicklistview.cpp incrementalmodel.cpp
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+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/qquicklistview/tst_qquicklistview.cpp b/tests/auto/declarative/qquicklistview/tst_qquicklistview.cpp
new file mode 100644 (file)
index 0000000..ae37724
--- /dev/null
@@ -0,0 +1,4166 @@
+/****************************************************************************
+**
+** 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 <QtWidgets/QStringListModel>
+#include <QtDeclarative/qquickview.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qdeclarativeexpression.h>
+#include <QtDeclarative/private/qquickitem_p.h>
+#include <QtDeclarative/private/qquicklistview_p.h>
+#include <QtDeclarative/private/qquicktext_p.h>
+#include <QtDeclarative/private/qquickvisualitemmodel_p.h>
+#include <QtDeclarative/private/qdeclarativelistmodel_p.h>
+#include <QtDeclarative/private/qlistmodelinterface_p.h>
+#include <QtDeclarative/private/qdeclarativechangeset_p.h>
+#include "../shared/util.h"
+#include "incrementalmodel.h"
+#include <math.h>
+
+Q_DECLARE_METATYPE(Qt::LayoutDirection)
+Q_DECLARE_METATYPE(QQuickListView::Orientation)
+
+class tst_QQuickListView : public QObject
+{
+    Q_OBJECT
+public:
+    tst_QQuickListView();
+
+private slots:
+    void initTestCase();
+    void cleanupTestCase();
+    // Test both QListModelInterface and QAbstractItemModel model types
+    void qListModelInterface_items();
+    void qAbstractItemModel_items();
+
+    void qListModelInterface_changed();
+    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();
+
+    void qListModelInterface_moved();
+    void qListModelInterface_moved_data();
+    void qAbstractItemModel_moved();
+    void qAbstractItemModel_moved_data();
+
+    void multipleChanges();
+    void multipleChanges_data();
+
+    void qListModelInterface_clear();
+    void qAbstractItemModel_clear();
+
+    void swapWithFirstItem();
+    void itemList();
+    void currentIndex_delayedItemCreation();
+    void currentIndex_delayedItemCreation_data();
+    void currentIndex();
+    void noCurrentIndex();
+    void enforceRange();
+    void enforceRange_withoutHighlight();
+    void spacing();
+    void sections();
+    void sectionsPositioning();
+    void sectionsDelegate();
+    void cacheBuffer();
+    void positionViewAtIndex();
+    void resetModel();
+    void propertyChanges();
+    void componentChanges();
+    void modelChanges();
+    void manualHighlight();
+    void header();
+    void header_data();
+    void header_delayItemCreation();
+    void footer();
+    void footer_data();
+    void headerFooter();
+    void resizeView();
+    void resizeViewAndRepaint();
+    void sizeLessThan1();
+    void QTBUG_14821();
+    void resizeDelegate();
+    void resizeFirstDelegate();
+    void QTBUG_16037();
+    void indexAt();
+    void incrementalModel();
+    void onAdd();
+    void onAdd_data();
+    void onRemove();
+    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();
+    QQuickView *createView();
+    void flick(QQuickView *canvas, const QPoint &from, const QPoint &to, int duration);
+    QQuickItem *findVisibleChild(QQuickItem *parent, const QString &objectName);
+    template<typename T>
+    T *findItem(QQuickItem *parent, const QString &id, int index=-1);
+    template<typename T>
+    QList<T*> findItems(QQuickItem *parent, const QString &objectName);
+    void dumpTree(QQuickItem *parent, int depth = 0);
+
+    void inserted_more_data();
+    void moved_data();
+};
+
+void tst_QQuickListView::initTestCase()
+{
+}
+
+void tst_QQuickListView::cleanupTestCase()
+{
+
+}
+class TestObject : public QObject
+{
+    Q_OBJECT
+
+    Q_PROPERTY(bool error READ error WRITE setError NOTIFY changedError)
+    Q_PROPERTY(bool animate READ animate NOTIFY changedAnim)
+    Q_PROPERTY(bool invalidHighlight READ invalidHighlight NOTIFY changedHl)
+    Q_PROPERTY(int cacheBuffer READ cacheBuffer NOTIFY changedCacheBuffer)
+
+public:
+    TestObject(QObject *parent = 0)
+        : QObject(parent), mError(true), mAnimate(false), mInvalidHighlight(false)
+        , mCacheBuffer(0) {}
+
+    bool error() const { return mError; }
+    void setError(bool err) { mError = err; emit changedError(); }
+
+    bool animate() const { return mAnimate; }
+    void setAnimate(bool anim) { mAnimate = anim; emit changedAnim(); }
+
+    bool invalidHighlight() const { return mInvalidHighlight; }
+    void setInvalidHighlight(bool invalid) { mInvalidHighlight = invalid; emit changedHl(); }
+
+    int cacheBuffer() const { return mCacheBuffer; }
+    void setCacheBuffer(int buffer) { mCacheBuffer = buffer; emit changedCacheBuffer(); }
+
+signals:
+    void changedError();
+    void changedAnim();
+    void changedHl();
+    void changedCacheBuffer();
+
+public:
+    bool mError;
+    bool mAnimate;
+    bool mInvalidHighlight;
+    int mCacheBuffer;
+};
+
+template<typename T>
+void tst_qquicklistview_move(int from, int to, int n, T *items)
+{
+    if (from > to) {
+        // Only move forwards - flip if backwards moving
+        int tfrom = from;
+        int tto = to;
+        from = tto;
+        to = tto+n;
+        n = tfrom-tto;
+    }
+    if (n == 1) {
+        items->move(from, to);
+    } else {
+        T replaced;
+        int i=0;
+        typename T::ConstIterator it=items->begin(); it += from+n;
+        for (; i<to-from; ++i,++it)
+            replaced.append(*it);
+        i=0;
+        it=items->begin(); it += from;
+        for (; i<n; ++i,++it)
+            replaced.append(*it);
+        typename T::ConstIterator f=replaced.begin();
+        typename T::Iterator t=items->begin(); t += from;
+        for (; f != replaced.end(); ++f, ++t)
+            *t = *f;
+    }
+}
+
+class TestModel : public QListModelInterface
+{
+    Q_OBJECT
+public:
+    TestModel(QObject *parent = 0) : QListModelInterface(parent) {}
+    ~TestModel() {}
+
+    enum Roles { Name, Number };
+
+    QString name(int index) const { return list.at(index).first; }
+    QString number(int index) const { return list.at(index).second; }
+
+    int count() const { return list.count(); }
+
+    QList<int> roles() const { return QList<int>() << Name << Number; }
+    QString toString(int role) const {
+        switch (role) {
+        case Name:
+            return "name";
+        case Number:
+            return "number";
+        default:
+            return "";
+        }
+    }
+
+    QVariant data(int index, int role) const
+    {
+        if (role==0)
+            return list.at(index).first;
+        if (role==1)
+            return list.at(index).second;
+        return QVariant();
+    }
+    QHash<int, QVariant> data(int index, const QList<int> &roles) const {
+        QHash<int,QVariant> returnHash;
+
+        for (int i = 0; i < roles.size(); ++i) {
+            int role = roles.at(i);
+            QVariant info;
+            switch (role) {
+            case Name:
+                info = list.at(index).first;
+                break;
+            case Number:
+                info = list.at(index).second;
+                break;
+            default:
+                break;
+            }
+            returnHash.insert(role, info);
+        }
+        return returnHash;
+    }
+
+    void addItem(const QString &name, const QString &number) {
+        list.append(QPair<QString,QString>(name, number));
+        emit itemsInserted(list.count()-1, 1);
+    }
+
+    void insertItem(int index, const QString &name, const QString &number) {
+        list.insert(index, QPair<QString,QString>(name, number));
+        emit itemsInserted(index, 1);
+    }
+
+    void insertItems(int index, const QList<QPair<QString, QString> > &items) {
+        for (int i=0; i<items.count(); i++)
+            list.insert(index + i, QPair<QString,QString>(items[i].first, items[i].second));
+        emit itemsInserted(index, items.count());
+    }
+
+    void removeItem(int index) {
+        list.removeAt(index);
+        emit itemsRemoved(index, 1);
+    }
+
+    void removeItems(int index, int count) {
+        int c = count;
+        while (c--)
+            list.removeAt(index);
+        emit itemsRemoved(index, count);
+    }
+
+    void moveItem(int from, int to) {
+        list.move(from, to);
+        emit itemsMoved(from, to, 1);
+    }
+
+    void moveItems(int from, int to, int count) {
+        tst_qquicklistview_move(from, to, count, &list);
+        emit itemsMoved(from, to, count);
+    }
+
+    void modifyItem(int index, const QString &name, const QString &number) {
+        list[index] = QPair<QString,QString>(name, number);
+        emit itemsChanged(index, 1, roles());
+    }
+
+    void clear() {
+        int count = list.count();
+        list.clear();
+        emit itemsRemoved(0, count);
+    }
+
+private:
+    QList<QPair<QString,QString> > list;
+};
+
+
+class TestModel2 : public QAbstractListModel
+{
+public:
+    enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 };
+
+    TestModel2(QObject *parent=0) : QAbstractListModel(parent) {
+        QHash<int, QByteArray> roles;
+        roles[Name] = "name";
+        roles[Number] = "number";
+        setRoleNames(roles);
+    }
+
+    int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); }
+    QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
+        QVariant rv;
+        if (role == Name)
+            rv = list.at(index.row()).first;
+        else if (role == Number)
+            rv = list.at(index.row()).second;
+
+        return rv;
+    }
+
+    int count() const { return rowCount(); }
+    QString name(int index) const { return list.at(index).first; }
+    QString number(int index) const { return list.at(index).second; }
+
+    void addItem(const QString &name, const QString &number) {
+        emit beginInsertRows(QModelIndex(), list.count(), list.count());
+        list.append(QPair<QString,QString>(name, number));
+        emit endInsertRows();
+    }
+
+    void addItems(const QList<QPair<QString, QString> > &items) {
+        emit beginInsertRows(QModelIndex(), list.count(), list.count()+items.count()-1);
+        for (int i=0; i<items.count(); i++)
+            list.append(QPair<QString,QString>(items[i].first, items[i].second));
+        emit endInsertRows();
+    }
+
+    void insertItem(int index, const QString &name, const QString &number) {
+        emit beginInsertRows(QModelIndex(), index, index);
+        list.insert(index, QPair<QString,QString>(name, number));
+        emit endInsertRows();
+    }
+
+    void insertItems(int index, const QList<QPair<QString, QString> > &items) {
+        emit beginInsertRows(QModelIndex(), index, index+items.count()-1);
+        for (int i=0; i<items.count(); i++)
+            list.insert(index + i, QPair<QString,QString>(items[i].first, items[i].second));
+        emit endInsertRows();
+    }
+
+    void removeItem(int index) {
+        emit beginRemoveRows(QModelIndex(), index, index);
+        list.removeAt(index);
+        emit endRemoveRows();
+    }
+
+    void removeItems(int index, int count) {
+        emit beginRemoveRows(QModelIndex(), index, index+count-1);
+        while (count--)
+            list.removeAt(index);
+        emit endRemoveRows();
+    }
+
+    void moveItem(int from, int to) {
+        emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
+        list.move(from, to);
+        emit endMoveRows();
+    }
+
+    void moveItems(int from, int to, int count) {
+        emit beginMoveRows(QModelIndex(), from, from+count-1, QModelIndex(), to > from ? to+count : to);
+        tst_qquicklistview_move(from, to, count, &list);
+        emit endMoveRows();
+    }
+
+    void modifyItem(int idx, const QString &name, const QString &number) {
+        list[idx] = QPair<QString,QString>(name, number);
+        emit dataChanged(index(idx,0), index(idx,0));
+    }
+
+    void clear() {
+        int count = list.count();
+        emit beginRemoveRows(QModelIndex(), 0, count-1);
+        list.clear();
+        emit endRemoveRows();
+    }
+
+private:
+    QList<QPair<QString,QString> > list;
+};
+
+tst_QQuickListView::tst_QQuickListView()
+{
+}
+
+template <class T>
+void tst_QQuickListView::items()
+{
+    QQuickView *canvas = createView();
+
+    T model;
+    model.addItem("Fred", "12345");
+    model.addItem("John", "2345");
+    model.addItem("Bob", "54321");
+
+    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();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
+    QTRY_VERIFY(testObject->error() == false);
+
+    QTRY_VERIFY(listview->highlightItem() != 0);
+    QTRY_COMPARE(listview->count(), model.count());
+    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
+    QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
+
+    // current item should be first item
+    QTRY_COMPARE(listview->currentItem(), findItem<QQuickItem>(contentItem, "wrapper", 0));
+
+    for (int i = 0; i < model.count(); ++i) {
+        QQuickText *name = findItem<QQuickText>(contentItem, "textName", i);
+        QTRY_VERIFY(name != 0);
+        QTRY_COMPARE(name->text(), model.name(i));
+        QQuickText *number = findItem<QQuickText>(contentItem, "textNumber", i);
+        QTRY_VERIFY(number != 0);
+        QTRY_COMPARE(number->text(), model.number(i));
+    }
+
+    // switch to other delegate
+    testObject->setAnimate(true);
+    QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
+    QTRY_VERIFY(testObject->error() == false);
+    QTRY_VERIFY(listview->currentItem());
+
+    // set invalid highlight
+    testObject->setInvalidHighlight(true);
+    QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
+    QTRY_VERIFY(testObject->error() == false);
+    QTRY_VERIFY(listview->currentItem());
+    QTRY_VERIFY(listview->highlightItem() == 0);
+
+    // back to normal highlight
+    testObject->setInvalidHighlight(false);
+    QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
+    QTRY_VERIFY(testObject->error() == false);
+    QTRY_VERIFY(listview->currentItem());
+    QTRY_VERIFY(listview->highlightItem() != 0);
+
+    // set an empty model and confirm that items are destroyed
+    T model2;
+    ctxt->setContextProperty("testModel", &model2);
+
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    QTRY_VERIFY(itemCount == 0);
+
+    QTRY_COMPARE(listview->highlightResizeSpeed(), 1000.0);
+    QTRY_COMPARE(listview->highlightMoveSpeed(), 1000.0);
+
+    delete canvas;
+    delete testObject;
+}
+
+
+template <class T>
+void tst_QQuickListView::changed()
+{
+    QQuickView *canvas = createView();
+
+    T model;
+    model.addItem("Fred", "12345");
+    model.addItem("John", "2345");
+    model.addItem("Bob", "54321");
+
+    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();
+
+    QQuickFlickable *listview = findItem<QQuickFlickable>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    model.modifyItem(1, "Will", "9876");
+    QQuickText *name = findItem<QQuickText>(contentItem, "textName", 1);
+    QTRY_VERIFY(name != 0);
+    QTRY_COMPARE(name->text(), model.name(1));
+    QQuickText *number = findItem<QQuickText>(contentItem, "textNumber", 1);
+    QTRY_VERIFY(number != 0);
+    QTRY_COMPARE(number->text(), model.number(1));
+
+    delete canvas;
+    delete testObject;
+}
+
+template <class T>
+void tst_QQuickListView::inserted()
+{
+    QQuickView *canvas = createView();
+    canvas->show();
+
+    T model;
+    model.addItem("Fred", "12345");
+    model.addItem("John", "2345");
+    model.addItem("Bob", "54321");
+
+    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();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    model.insertItem(1, "Will", "9876");
+
+    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
+    QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
+
+    QQuickText *name = findItem<QQuickText>(contentItem, "textName", 1);
+    QTRY_VERIFY(name != 0);
+    QTRY_COMPARE(name->text(), model.name(1));
+    QQuickText *number = findItem<QQuickText>(contentItem, "textNumber", 1);
+    QTRY_VERIFY(number != 0);
+    QTRY_COMPARE(number->text(), model.number(1));
+
+    // Confirm items positioned correctly
+    for (int i = 0; i < model.count(); ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        QTRY_COMPARE(item->y(), i*20.0);
+    }
+
+    model.insertItem(0, "Foo", "1111"); // zero index, and current item
+
+    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
+    QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
+
+    name = findItem<QQuickText>(contentItem, "textName", 0);
+    QTRY_VERIFY(name != 0);
+    QTRY_COMPARE(name->text(), model.name(0));
+    number = findItem<QQuickText>(contentItem, "textNumber", 0);
+    QTRY_VERIFY(number != 0);
+    QTRY_COMPARE(number->text(), model.number(0));
+
+    QTRY_COMPARE(listview->currentIndex(), 1);
+
+    // Confirm items positioned correctly
+    for (int i = 0; i < model.count(); ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        QTRY_COMPARE(item->y(), i*20.0);
+    }
+
+    for (int i = model.count(); i < 30; ++i)
+        model.insertItem(i, "Hello", QString::number(i));
+
+    listview->setContentY(80);
+
+    // Insert item outside visible area
+    model.insertItem(1, "Hello", "1324");
+
+    QTRY_VERIFY(listview->contentY() == 80);
+
+    // Confirm items positioned correctly
+    for (int i = 5; i < 5+15; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->y(), i*20.0 - 20.0);
+    }
+
+//    QTRY_COMPARE(listview->contentItemHeight(), model.count() * 20.0);
+
+    // QTBUG-19675
+    model.clear();
+    model.insertItem(0, "Hello", "1234");
+    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
+
+    QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", 0);
+    QVERIFY(item);
+    QCOMPARE(item->y(), 0.);
+    QVERIFY(listview->contentY() == 0);
+
+    delete canvas;
+    delete testObject;
+}
+
+template <class T>
+void tst_QQuickListView::inserted_more()
+{
+    QFETCH(qreal, contentY);
+    QFETCH(int, insertIndex);
+    QFETCH(int, insertCount);
+    QFETCH(qreal, itemsOffsetAfterMove);
+
+    QQuickText *name;
+    QQuickText *number;
+    QQuickView *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();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+    QQuickItem *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
+    QQuickItem *item0 = findItem<QQuickItem>(contentItem, "wrapper", 0);
+    QVERIFY(item0);
+    QCOMPARE(item0->y(), itemsOffsetAfterMove);
+
+    QList<QQuickItem*> items = findItems<QQuickItem>(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<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+        QTRY_COMPARE(item->y(), i*20.0 + itemsOffsetAfterMove);
+        name = findItem<QQuickText>(contentItem, "textName", i);
+        QVERIFY(name != 0);
+        QTRY_COMPARE(name->text(), model.name(i));
+        number = findItem<QQuickText>(contentItem, "textNumber", i);
+        QVERIFY(number != 0);
+        QTRY_COMPARE(number->text(), model.number(i));
+    }
+
+    delete canvas;
+    delete testObject;
+}
+
+void tst_QQuickListView::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_QQuickListView::removed(bool animated)
+{
+    QQuickView *canvas = createView();
+
+    T model;
+    for (int i = 0; i < 50; 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")));
+    canvas->show();
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    model.removeItem(1);
+    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
+
+    QQuickText *name = findItem<QQuickText>(contentItem, "textName", 1);
+    QTRY_VERIFY(name != 0);
+    QTRY_COMPARE(name->text(), model.name(1));
+    QQuickText *number = findItem<QQuickText>(contentItem, "textNumber", 1);
+    QTRY_VERIFY(number != 0);
+    QTRY_COMPARE(number->text(), model.number(1));
+
+    // Confirm items positioned correctly
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_VERIFY(item->y() == i*20);
+    }
+
+    // Remove first item (which is the current item);
+    model.removeItem(0);  // post: top item starts at 20
+    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
+
+    name = findItem<QQuickText>(contentItem, "textName", 0);
+    QTRY_VERIFY(name != 0);
+    QTRY_COMPARE(name->text(), model.name(0));
+    number = findItem<QQuickText>(contentItem, "textNumber", 0);
+    QTRY_VERIFY(number != 0);
+    QTRY_COMPARE(number->text(), model.number(0));
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->y(),i*20.0 + 20.0);
+    }
+
+    // Remove items not visible
+    model.removeItem(18);
+    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->y(),i*20.0+20.0);
+    }
+
+    // Remove items before visible
+    listview->setContentY(80);
+    listview->setCurrentIndex(10);
+
+    model.removeItem(1); // post: top item will be at 40
+    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
+
+    // Confirm items positioned correctly
+    for (int i = 2; i < 18; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->y(),40+i*20.0);
+    }
+
+    // Remove current index
+    QTRY_VERIFY(listview->currentIndex() == 9);
+    QQuickItem *oldCurrent = listview->currentItem();
+    model.removeItem(9);
+
+    QTRY_COMPARE(listview->currentIndex(), 9);
+    QTRY_VERIFY(listview->currentItem() != oldCurrent);
+
+    listview->setContentY(40); // That's the top now
+    // let transitions settle.
+    QTest::qWait(300);
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->y(),40+i*20.0);
+    }
+
+    // remove current item beyond visible items.
+    listview->setCurrentIndex(20);
+    listview->setContentY(40);
+    model.removeItem(20);
+
+    QTRY_COMPARE(listview->currentIndex(), 20);
+    QTRY_VERIFY(listview->currentItem() != 0);
+
+    // remove item before current, but visible
+    listview->setCurrentIndex(8);
+    oldCurrent = listview->currentItem();
+    model.removeItem(6);
+
+    QTRY_COMPARE(listview->currentIndex(), 7);
+    QTRY_VERIFY(listview->currentItem() == oldCurrent);
+
+    listview->setContentY(80);
+    QTest::qWait(300);
+
+    // remove all visible items
+    model.removeItems(1, 18);
+    QTRY_COMPARE(listview->count() , model.count());
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i+2);
+        if (!item) qWarning() << "Item" << i+2 << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->y(),80+i*20.0);
+    }
+
+    model.removeItems(1, 17);
+    QTRY_COMPARE(listview->count() , model.count());
+
+    model.removeItems(2, 1);
+    QTRY_COMPARE(listview->count() , model.count());
+
+    model.addItem("New", "1");
+    QTRY_COMPARE(listview->count() , model.count());
+
+    QTRY_VERIFY(name = findItem<QQuickText>(contentItem, "textName", model.count()-1));
+    QCOMPARE(name->text(), QString("New"));
+
+    // Add some more items so that we don't run out
+    model.clear();
+    for (int i = 0; i < 50; i++)
+        model.addItem("Item" + QString::number(i), "");
+
+    // QTBUG-QTBUG-20575
+    listview->setCurrentIndex(0);
+    listview->setContentY(30);
+    model.removeItem(0);
+    QTRY_VERIFY(name = findItem<QQuickText>(contentItem, "textName", 0));
+
+    // QTBUG-19198 move to end and remove all visible items one at a time.
+    listview->positionViewAtEnd();
+    for (int i = 0; i < 18; ++i)
+        model.removeItems(model.count() - 1, 1);
+    QTRY_VERIFY(findItems<QQuickItem>(contentItem, "wrapper").count() > 16);
+
+    delete canvas;
+    delete testObject;
+}
+
+template <class T>
+void tst_QQuickListView::clear()
+{
+    QQuickView *canvas = createView();
+
+    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();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    model.clear();
+
+    QTRY_VERIFY(listview->count() == 0);
+    QTRY_VERIFY(listview->currentItem() == 0);
+    QTRY_VERIFY(listview->contentY() == 0);
+    QVERIFY(listview->currentIndex() == -1);
+
+    // confirm sanity when adding an item to cleared list
+    model.addItem("New", "1");
+    QTRY_VERIFY(listview->count() == 1);
+    QVERIFY(listview->currentItem() != 0);
+    QVERIFY(listview->currentIndex() == 0);
+
+    delete canvas;
+    delete testObject;
+}
+
+template <class T>
+void tst_QQuickListView::moved()
+{
+    QFETCH(qreal, contentY);
+    QFETCH(int, from);
+    QFETCH(int, to);
+    QFETCH(int, count);
+    QFETCH(qreal, itemsOffsetAfterMove);
+
+    QQuickText *name;
+    QQuickText *number;
+    QQuickView *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();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QQuickItem *currentItem = listview->currentItem();
+    QTRY_VERIFY(currentItem != 0);
+
+    listview->setContentY(contentY);
+    model.moveItems(from, to, count);
+
+    // wait for items to move
+    QTest::qWait(100);
+
+    QList<QQuickItem*> items = findItems<QQuickItem>(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<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) {
+        if (i >= firstVisibleIndex + 16)    // index has moved out of view
+            continue;
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+        QTRY_COMPARE(item->y(), i*20.0 + itemsOffsetAfterMove);
+        name = findItem<QQuickText>(contentItem, "textName", i);
+        QVERIFY(name != 0);
+        QTRY_COMPARE(name->text(), model.name(i));
+        number = findItem<QQuickText>(contentItem, "textNumber", i);
+        QVERIFY(number != 0);
+        QTRY_COMPARE(number->text(), model.number(i));
+
+        // current index should have been updated
+        if (item == currentItem)
+            QTRY_COMPARE(listview->currentIndex(), i);
+    }
+
+    delete canvas;
+    delete testObject;
+}
+
+void tst_QQuickListView::moved_data()
+{
+    QTest::addColumn<qreal>("contentY");
+    QTest::addColumn<int>("from");
+    QTest::addColumn<int>("to");
+    QTest::addColumn<int>("count");
+    QTest::addColumn<qreal>("itemsOffsetAfterMove");
+
+    // model starts with 30 items, each 20px high, in area 320px high
+    // 16 items should be visible at a time
+    // itemsOffsetAfterMove should be > 0 whenever items above the visible pos have moved
+
+    QTest::newRow("move 1 forwards, within visible items")
+            << 0.0
+            << 1 << 4 << 1
+            << 0.0;
+
+    QTest::newRow("move 1 forwards, from non-visible -> visible")
+            << 80.0     // show 4-19
+            << 1 << 18 << 1
+            << 20.0;    // removed 1 item above the first visible, so item 0 should drop down by 1 to minimize movement
+
+    QTest::newRow("move 1 forwards, from non-visible -> visible (move first item)")
+            << 80.0     // show 4-19
+            << 0 << 4 << 1
+            << 20.0;    // first item has moved to below item4, everything drops down by size of 1 item
+
+    QTest::newRow("move 1 forwards, from visible -> non-visible")
+            << 0.0
+            << 1 << 16 << 1
+            << 0.0;
+
+    QTest::newRow("move 1 forwards, from visible -> non-visible (move first item)")
+            << 0.0
+            << 0 << 16 << 1
+            << 0.0;
+
+
+    QTest::newRow("move 1 backwards, within visible items")
+            << 0.0
+            << 4 << 1 << 1
+            << 0.0;
+
+    QTest::newRow("move 1 backwards, within visible items (to first index)")
+            << 0.0
+            << 4 << 0 << 1
+            << 0.0;
+
+    QTest::newRow("move 1 backwards, from non-visible -> visible")
+            << 0.0
+            << 20 << 4 << 1
+            << 0.0;
+
+    QTest::newRow("move 1 backwards, from non-visible -> visible (move last item)")
+            << 0.0
+            << 29 << 15 << 1
+            << 0.0;
+
+    QTest::newRow("move 1 backwards, from visible -> non-visible")
+            << 80.0     // show 4-19
+            << 16 << 1 << 1
+            << -20.0;   // to minimize movement, item 0 moves to -20, and other items do not move
+
+    QTest::newRow("move 1 backwards, from visible -> non-visible (move first item)")
+            << 80.0     // show 4-19
+            << 16 << 0 << 1
+            << -20.0;   // to minimize movement, item 16 (now at 0) moves to -20, and other items do not move
+
+
+    QTest::newRow("move multiple forwards, within visible items")
+            << 0.0
+            << 0 << 5 << 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
+            << 1 << 5 << 3
+            << 20.0 * 3;    // moving 3 from above the content y should adjust y positions accordingly
+
+    QTest::newRow("move multiple forwards, from non-visible -> visible (move first item)")
+            << 80.0     // show 4-19
+            << 0 << 5 << 3
+            << 20.0 * 3;        // moving 3 from above the content y should adjust y positions accordingly
+
+    QTest::newRow("move multiple forwards, from visible -> non-visible")
+            << 0.0
+            << 1 << 16 << 3
+            << 0.0;
+
+    QTest::newRow("move multiple forwards, from visible -> non-visible (move first item)")
+            << 0.0
+            << 0 << 16 << 3
+            << 0.0;
+
+
+    QTest::newRow("move multiple backwards, within visible items")
+            << 0.0
+            << 4 << 1 << 3
+            << 0.0;
+
+    QTest::newRow("move multiple backwards, from non-visible -> visible")
+            << 0.0
+            << 20 << 4 << 3
+            << 0.0;
+
+    QTest::newRow("move multiple backwards, from non-visible -> visible (move last item)")
+            << 0.0
+            << 27 << 10 << 3
+            << 0.0;
+
+    QTest::newRow("move multiple backwards, from visible -> non-visible")
+            << 80.0     // show 4-19
+            << 16 << 1 << 3
+            << -20.0 * 3;   // to minimize movement, 0 moves by -60, and other items do not move
+
+    QTest::newRow("move multiple backwards, from visible -> non-visible (move first item)")
+            << 80.0     // show 4-19
+            << 16 << 0 << 3
+            << -20.0 * 3;   // to minimize movement, 16,17,18 move to above item 0, and other items do not move
+}
+
+
+struct ListChange {
+    enum { Inserted, Removed, Moved, SetCurrent } type;
+    int index;
+    int count;
+    int to;     // Move
+
+    static ListChange insert(int index, int count = 1) { ListChange c = { Inserted, index, count, -1 }; return c; }
+    static ListChange remove(int index, int count = 1) { ListChange c = { Removed, index, count, -1 }; return c; }
+    static ListChange move(int index, int to, int count) { ListChange c = { Moved, index, count, to }; return c; }
+    static ListChange setCurrent(int index) { ListChange c = { SetCurrent, index, -1, -1 }; return c; }
+};
+Q_DECLARE_METATYPE(QList<ListChange>)
+
+void tst_QQuickListView::multipleChanges()
+{
+    QFETCH(int, startCount);
+    QFETCH(QList<ListChange>, changes);
+    QFETCH(int, newCount);
+    QFETCH(int, newCurrentIndex);
+
+    QQuickView *canvas = createView();
+    canvas->show();
+
+    TestModel model;
+    for (int i = 0; i < startCount; 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();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    for (int i=0; i<changes.count(); i++) {
+        switch (changes[i].type) {
+            case ListChange::Inserted:
+            {
+                QList<QPair<QString, QString> > items;
+                for (int j=changes[i].index; j<changes[i].index + changes[i].count; ++j)
+                    items << qMakePair(QString("new item " + j), QString::number(j));
+                model.insertItems(changes[i].index, items);
+                break;
+            }
+            case ListChange::Removed:
+                model.removeItems(changes[i].index, changes[i].count);
+                break;
+            case ListChange::Moved:
+                model.moveItems(changes[i].index, changes[i].to, changes[i].count);
+                break;
+            case ListChange::SetCurrent:
+                listview->setCurrentIndex(changes[i].index);
+                break;
+        }
+    }
+
+    QTRY_COMPARE(listview->count(), newCount);
+    QCOMPARE(listview->count(), model.count());
+    QTRY_COMPARE(listview->currentIndex(), newCurrentIndex);
+
+    QQuickText *name;
+    QQuickText *number;
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i=0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+        name = findItem<QQuickText>(contentItem, "textName", i);
+        QVERIFY(name != 0);
+        QTRY_COMPARE(name->text(), model.name(i));
+        number = findItem<QQuickText>(contentItem, "textNumber", i);
+        QVERIFY(number != 0);
+        QTRY_COMPARE(number->text(), model.number(i));
+    }
+
+    delete testObject;
+    delete canvas;
+}
+
+void tst_QQuickListView::multipleChanges_data()
+{
+    QTest::addColumn<int>("startCount");
+    QTest::addColumn<QList<ListChange> >("changes");
+    QTest::addColumn<int>("newCount");
+    QTest::addColumn<int>("newCurrentIndex");
+
+    QList<ListChange> changes;
+
+    for (int i=1; i<30; i++)
+        changes << ListChange::remove(0);
+    QTest::newRow("remove all but 1, first->last") << 30 << changes << 1 << 0;
+
+    changes << ListChange::remove(0);
+    QTest::newRow("remove all") << 30 << changes << 0 << -1;
+
+    changes.clear();
+    changes << ListChange::setCurrent(29);
+    for (int i=29; i>0; i--)
+        changes << ListChange::remove(i);
+    QTest::newRow("remove last (current) -> first") << 30 << changes << 1 << 0;
+
+    QTest::newRow("remove then insert at 0") << 10 << (QList<ListChange>()
+            << ListChange::remove(0, 1)
+            << ListChange::insert(0, 1)
+            ) << 10 << 1;
+
+    QTest::newRow("remove then insert at non-zero index") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(2)
+            << ListChange::remove(2, 1)
+            << ListChange::insert(2, 1)
+            ) << 10 << 3;
+
+    QTest::newRow("remove current then insert below it") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(1)
+            << ListChange::remove(1, 3)
+            << ListChange::insert(2, 2)
+            ) << 9 << 1;
+
+    QTest::newRow("remove current index then move it down") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(2)
+            << ListChange::remove(1, 3)
+            << ListChange::move(1, 5, 1)
+            ) << 7 << 5;
+
+    QTest::newRow("remove current index then move it up") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(5)
+            << ListChange::remove(4, 3)
+            << ListChange::move(4, 1, 1)
+            ) << 7 << 1;
+
+
+    QTest::newRow("insert multiple times") << 0 << (QList<ListChange>()
+            << ListChange::insert(0, 2)
+            << ListChange::insert(0, 4)
+            << ListChange::insert(0, 6)
+            ) << 12 << 10;
+
+    QTest::newRow("insert multiple times with current index changes") << 0 << (QList<ListChange>()
+            << ListChange::insert(0, 2)
+            << ListChange::insert(0, 4)
+            << ListChange::insert(0, 6)
+            << ListChange::setCurrent(3)
+            << ListChange::insert(3, 2)
+            ) << 14 << 5;
+
+    QTest::newRow("insert and remove all") << 0 << (QList<ListChange>()
+            << ListChange::insert(0, 30)
+            << ListChange::remove(0, 30)
+            ) << 0 << -1;
+
+    QTest::newRow("insert and remove current") << 30 << (QList<ListChange>()
+            << ListChange::insert(1)
+            << ListChange::setCurrent(1)
+            << ListChange::remove(1)
+            ) << 30 << 1;
+
+    QTest::newRow("insert before 0, then remove cross section of new and old items") << 10 << (QList<ListChange>()
+            << ListChange::insert(0, 10)
+            << ListChange::remove(5, 10)
+            ) << 10 << 5;
+
+    QTest::newRow("insert multiple, then move new items to end") << 10 << (QList<ListChange>()
+            << ListChange::insert(0, 3)
+            << ListChange::move(0, 10, 3)
+            ) << 13 << 0;
+
+    QTest::newRow("insert multiple, then move new and some old items to end") << 10 << (QList<ListChange>()
+            << ListChange::insert(0, 3)
+            << ListChange::move(0, 8, 5)
+            ) << 13 << 11;
+
+    QTest::newRow("insert multiple at end, then move new and some old items to start") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(9)
+            << ListChange::insert(10, 3)
+            << ListChange::move(8, 0, 5)
+            ) << 13 << 1;
+
+
+    QTest::newRow("move back and forth to same index") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(1)
+            << ListChange::move(1, 2, 2)
+            << ListChange::move(2, 1, 2)
+            ) << 10 << 1;
+
+    QTest::newRow("move forwards then back") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(2)
+            << ListChange::move(1, 2, 3)
+            << ListChange::move(3, 0, 5)
+            ) << 10 << 0;
+
+    QTest::newRow("move current, then remove it") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(5)
+            << ListChange::move(5, 0, 1)
+            << ListChange::remove(0)
+            ) << 9 << 0;
+
+    QTest::newRow("move current, then insert before it") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(5)
+            << ListChange::move(5, 0, 1)
+            << ListChange::insert(0)
+            ) << 11 << 1;
+
+    QTest::newRow("move multiple, then remove them") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(1)
+            << ListChange::move(5, 1, 3)
+            << ListChange::remove(1, 3)
+            ) << 7 << 1;
+
+    QTest::newRow("move multiple, then insert before them") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(5)
+            << ListChange::move(5, 1, 3)
+            << ListChange::insert(1, 5)
+            ) << 15 << 6;
+
+    QTest::newRow("move multiple, then insert after them") << 10 << (QList<ListChange>()
+            << ListChange::setCurrent(3)
+            << ListChange::move(0, 1, 2)
+            << ListChange::insert(3, 5)
+            ) << 15 << 8;
+
+
+    QTest::newRow("clear current") << 0 << (QList<ListChange>()
+            << ListChange::insert(0, 5)
+            << ListChange::setCurrent(-1)
+            << ListChange::remove(0, 5)
+            << ListChange::insert(0, 5)
+            ) << 5 << -1;
+}
+
+void tst_QQuickListView::swapWithFirstItem()
+{
+    QQuickView *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);
+
+    TestObject *testObject = new TestObject;
+    ctxt->setContextProperty("testObject", testObject);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")));
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    // ensure content position is stable
+    listview->setContentY(0);
+    model.moveItem(1, 0);
+    QTRY_VERIFY(listview->contentY() == 0);
+
+    delete testObject;
+    delete canvas;
+}
+
+void tst_QQuickListView::enforceRange()
+{
+    QQuickView *canvas = createView();
+
+    TestModel model;
+    for (int i = 0; i < 30; i++)
+        model.addItem("Item" + QString::number(i), "");
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-enforcerange.qml")));
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QTRY_COMPARE(listview->preferredHighlightBegin(), 100.0);
+    QTRY_COMPARE(listview->preferredHighlightEnd(), 100.0);
+    QTRY_COMPARE(listview->highlightRangeMode(), QQuickListView::StrictlyEnforceRange);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    // view should be positioned at the top of the range.
+    QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", 0);
+    QTRY_VERIFY(item);
+    QTRY_COMPARE(listview->contentY(), -100.0);
+
+    QQuickText *name = findItem<QQuickText>(contentItem, "textName", 0);
+    QTRY_VERIFY(name != 0);
+    QTRY_COMPARE(name->text(), model.name(0));
+    QQuickText *number = findItem<QQuickText>(contentItem, "textNumber", 0);
+    QTRY_VERIFY(number != 0);
+    QTRY_COMPARE(number->text(), model.number(0));
+
+    // Check currentIndex is updated when contentItem moves
+    listview->setContentY(20);
+
+    QTRY_COMPARE(listview->currentIndex(), 6);
+
+    // change model
+    TestModel model2;
+    for (int i = 0; i < 5; i++)
+        model2.addItem("Item" + QString::number(i), "");
+
+    ctxt->setContextProperty("testModel", &model2);
+    QCOMPARE(listview->count(), 5);
+
+    delete canvas;
+}
+
+void tst_QQuickListView::enforceRange_withoutHighlight()
+{
+    // QTBUG-20287
+    // If no highlight is set but StrictlyEnforceRange is used, the content should still move
+    // to the correct position (i.e. to the next/previous item, not next/previous section)
+    // when moving up/down via incrementCurrentIndex() and decrementCurrentIndex()
+
+    QQuickView *canvas = createView();
+    canvas->show();
+    QTest::qWait(200);
+
+    TestModel model;
+    model.addItem("Item 0", "a");
+    model.addItem("Item 1", "b");
+    model.addItem("Item 2", "b");
+    model.addItem("Item 3", "c");
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-enforcerange-nohighlight.qml")));
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    qreal expectedPos = -100.0;
+
+    expectedPos += 10.0;    // scroll past 1st section's delegate (10px height)
+    QTRY_COMPARE(listview->contentY(), expectedPos);
+
+    expectedPos += 20 + 10;     // scroll past 1st section and section delegate of 2nd section
+    QTest::keyClick(canvas, Qt::Key_Down);
+
+    QTRY_COMPARE(listview->contentY(), expectedPos);
+
+    expectedPos += 20;     // scroll past 1st item of 2nd section
+    QTest::keyClick(canvas, Qt::Key_Down);
+    QTRY_COMPARE(listview->contentY(), expectedPos);
+
+    expectedPos += 20 + 10;     // scroll past 2nd item of 2nd section and section delegate of 3rd section
+    QTest::keyClick(canvas, Qt::Key_Down);
+    QTRY_COMPARE(listview->contentY(), expectedPos);
+
+    delete canvas;
+}
+
+void tst_QQuickListView::spacing()
+{
+    QQuickView *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);
+
+    TestObject *testObject = new TestObject;
+    ctxt->setContextProperty("testObject", testObject);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml")));
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    // Confirm items positioned correctly
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_VERIFY(item->y() == i*20);
+    }
+
+    listview->setSpacing(10);
+    QTRY_VERIFY(listview->spacing() == 10);
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_VERIFY(item->y() == i*30);
+    }
+
+    listview->setSpacing(0);
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->y(), i*20.0);
+    }
+
+    delete canvas;
+    delete testObject;
+}
+
+void tst_QQuickListView::sections()
+{
+    QQuickView *canvas = createView();
+    canvas->show();
+
+    TestModel model;
+    for (int i = 0; i < 30; i++)
+        model.addItem("Item" + QString::number(i), QString::number(i/5));
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-sections.qml")));
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    // Confirm items positioned correctly
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->y(), qreal(i*20 + ((i+4)/5) * 20));
+        QQuickText *next = findItem<QQuickText>(item, "nextSection");
+        QCOMPARE(next->text().toInt(), (i+1)/5);
+    }
+
+    QSignalSpy currentSectionChangedSpy(listview, SIGNAL(currentSectionChanged()));
+
+    // Remove section boundary
+    model.removeItem(5);
+    QTRY_COMPARE(listview->count(), model.count());
+
+    // New section header created
+    QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", 5);
+    QTRY_VERIFY(item);
+    QTRY_COMPARE(item->height(), 40.0);
+
+    model.insertItem(3, "New Item", "0");
+    QTRY_COMPARE(listview->count(), model.count());
+
+    // Section header moved
+    item = findItem<QQuickItem>(contentItem, "wrapper", 5);
+    QTRY_VERIFY(item);
+    QTRY_COMPARE(item->height(), 20.0);
+
+    item = findItem<QQuickItem>(contentItem, "wrapper", 6);
+    QTRY_VERIFY(item);
+    QTRY_COMPARE(item->height(), 40.0);
+
+    // insert item which will become a section header
+    model.insertItem(6, "Replace header", "1");
+    QTRY_COMPARE(listview->count(), model.count());
+
+    item = findItem<QQuickItem>(contentItem, "wrapper", 6);
+    QTRY_VERIFY(item);
+    QTRY_COMPARE(item->height(), 40.0);
+
+    item = findItem<QQuickItem>(contentItem, "wrapper", 7);
+    QTRY_VERIFY(item);
+    QTRY_COMPARE(item->height(), 20.0);
+
+    QTRY_COMPARE(listview->currentSection(), QString("0"));
+
+    listview->setContentY(140);
+    QTRY_COMPARE(listview->currentSection(), QString("1"));
+
+    QTRY_COMPARE(currentSectionChangedSpy.count(), 1);
+
+    listview->setContentY(20);
+    QTRY_COMPARE(listview->currentSection(), QString("0"));
+
+    QTRY_COMPARE(currentSectionChangedSpy.count(), 2);
+
+    item = findItem<QQuickItem>(contentItem, "wrapper", 1);
+    QTRY_VERIFY(item);
+    QTRY_COMPARE(item->height(), 20.0);
+
+    // check that headers change when item changes
+    listview->setContentY(0);
+    model.modifyItem(0, "changed", "2");
+    QTest::qWait(300);
+
+    item = findItem<QQuickItem>(contentItem, "wrapper", 1);
+    QTRY_VERIFY(item);
+    QTRY_COMPARE(item->height(), 40.0);
+
+    delete canvas;
+}
+
+void tst_QQuickListView::sectionsDelegate()
+{
+    QQuickView *canvas = createView();
+    canvas->show();
+
+    TestModel model;
+    for (int i = 0; i < 30; i++)
+        model.addItem("Item" + QString::number(i), QString::number(i/5));
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-sections_delegate.qml")));
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    // Confirm items positioned correctly
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->y(), qreal(i*20 + ((i+5)/5) * 20));
+        QQuickText *next = findItem<QQuickText>(item, "nextSection");
+        QCOMPARE(next->text().toInt(), (i+1)/5);
+    }
+
+    for (int i = 0; i < 3; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "sect_" + QString::number(i));
+        QVERIFY(item);
+        QTRY_COMPARE(item->y(), qreal(i*20*6));
+    }
+
+    model.modifyItem(0, "One", "aaa");
+    model.modifyItem(1, "Two", "aaa");
+    model.modifyItem(2, "Three", "aaa");
+    model.modifyItem(3, "Four", "aaa");
+    model.modifyItem(4, "Five", "aaa");
+    QTest::qWait(300);
+
+    for (int i = 0; i < 3; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem,
+                "sect_" + (i == 0 ? QString("aaa") : QString::number(i)));
+        QVERIFY(item);
+        QTRY_COMPARE(item->y(), qreal(i*20*6));
+    }
+
+    // remove section boundary
+    model.removeItem(5);
+    QTRY_COMPARE(listview->count(), model.count());
+    for (int i = 0; i < 3; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem,
+                "sect_" + (i == 0 ? QString("aaa") : QString::number(i)));
+        QVERIFY(item);
+    }
+
+    // QTBUG-17606
+    QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "sect_1");
+    QCOMPARE(items.count(), 1);
+
+    // QTBUG-17759
+    model.modifyItem(0, "One", "aaa");
+    model.modifyItem(1, "One", "aaa");
+    model.modifyItem(2, "One", "aaa");
+    model.modifyItem(3, "Four", "aaa");
+    model.modifyItem(4, "Four", "aaa");
+    model.modifyItem(5, "Four", "aaa");
+    model.modifyItem(6, "Five", "aaa");
+    model.modifyItem(7, "Five", "aaa");
+    model.modifyItem(8, "Five", "aaa");
+    model.modifyItem(9, "Two", "aaa");
+    model.modifyItem(10, "Two", "aaa");
+    model.modifyItem(11, "Two", "aaa");
+    QTRY_COMPARE(findItems<QQuickItem>(contentItem, "sect_aaa").count(), 1);
+    canvas->rootObject()->setProperty("sectionProperty", "name");
+    // ensure view has settled.
+    QTRY_COMPARE(findItems<QQuickItem>(contentItem, "sect_Four").count(), 1);
+    for (int i = 0; i < 4; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem,
+                "sect_" + model.name(i*3));
+        QVERIFY(item);
+        QTRY_COMPARE(item->y(), qreal(i*20*4));
+    }
+
+    // QTBUG-17769
+    model.removeItems(10, 20);
+    // ensure view has settled.
+    QTRY_COMPARE(findItems<QQuickItem>(contentItem, "wrapper").count(), 10);
+    // Drag view up beyond bounds
+    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(20,20));
+    {
+        QMouseEvent mv(QEvent::MouseMove, QPoint(20,0), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+        QApplication::sendEvent(canvas, &mv);
+    }
+    {
+        QMouseEvent mv(QEvent::MouseMove, QPoint(20,-50), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+        QApplication::sendEvent(canvas, &mv);
+    }
+    {
+        QMouseEvent mv(QEvent::MouseMove, QPoint(20,-200), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+        QApplication::sendEvent(canvas, &mv);
+    }
+    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(20,-200));
+    // view should settle back at 0
+    QTRY_COMPARE(listview->contentY(), 0.0);
+
+    delete canvas;
+}
+
+void tst_QQuickListView::sectionsPositioning()
+{
+    QQuickView *canvas = createView();
+    canvas->show();
+
+    TestModel model;
+    for (int i = 0; i < 30; i++)
+        model.addItem("Item" + QString::number(i), QString::number(i/5));
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-sections_delegate.qml")));
+    qApp->processEvents();
+    canvas->rootObject()->setProperty("sectionPositioning", QVariant(int(QQuickViewSection::InlineLabels | QQuickViewSection::CurrentLabelAtStart | QQuickViewSection::NextLabelAtEnd)));
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    for (int i = 0; i < 3; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "sect_" + QString::number(i));
+        QVERIFY(item);
+        QTRY_COMPARE(item->y(), qreal(i*20*6));
+    }
+
+    QQuickItem *topItem = findVisibleChild(contentItem, "sect_0"); // section header
+    QVERIFY(topItem);
+    QCOMPARE(topItem->y(), 0.);
+
+    QQuickItem *bottomItem = findVisibleChild(contentItem, "sect_3"); // section footer
+    QVERIFY(bottomItem);
+    QCOMPARE(bottomItem->y(), 300.);
+
+    // move down a little and check that section header is at top
+    listview->setContentY(10);
+    QCOMPARE(topItem->y(), 0.);
+
+    // push the top header up
+    listview->setContentY(110);
+    topItem = findVisibleChild(contentItem, "sect_0"); // section header
+    QVERIFY(topItem);
+    QCOMPARE(topItem->y(), 100.);
+
+    QQuickItem *item = findVisibleChild(contentItem, "sect_1");
+    QVERIFY(item);
+    QCOMPARE(item->y(), 120.);
+
+    bottomItem = findVisibleChild(contentItem, "sect_4"); // section footer
+    QVERIFY(bottomItem);
+    QCOMPARE(bottomItem->y(), 410.);
+
+    // Move past section 0
+    listview->setContentY(120);
+    topItem = findVisibleChild(contentItem, "sect_0"); // section header
+    QVERIFY(!topItem);
+
+    // Push section footer down
+    listview->setContentY(70);
+    bottomItem = findVisibleChild(contentItem, "sect_4"); // section footer
+    QVERIFY(bottomItem);
+    QCOMPARE(bottomItem->y(), 380.);
+
+    // Change current section
+    listview->setContentY(10);
+    model.modifyItem(0, "One", "aaa");
+    model.modifyItem(1, "Two", "aaa");
+    model.modifyItem(2, "Three", "aaa");
+    model.modifyItem(3, "Four", "aaa");
+    model.modifyItem(4, "Five", "aaa");
+    QTest::qWait(300);
+
+    QTRY_COMPARE(listview->currentSection(), QString("aaa"));
+
+    for (int i = 0; i < 3; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem,
+                "sect_" + (i == 0 ? QString("aaa") : QString::number(i)));
+        QVERIFY(item);
+        QTRY_COMPARE(item->y(), qreal(i*20*6));
+    }
+
+    topItem = findVisibleChild(contentItem, "sect_aaa"); // section header
+    QVERIFY(topItem);
+    QCOMPARE(topItem->y(), 10.);
+
+    // remove section boundary
+    listview->setContentY(120);
+    model.removeItem(5);
+    QTRY_COMPARE(listview->count(), model.count());
+    for (int i = 0; i < 3; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem,
+                "sect_" + (i == 0 ? QString("aaa") : QString::number(i)));
+        QVERIFY(item);
+        QTRY_COMPARE(item->y(), qreal(i*20*6));
+    }
+
+    QTRY_VERIFY(topItem = findVisibleChild(contentItem, "sect_aaa")); // section header
+    QCOMPARE(topItem->y(), 120.);
+    QVERIFY(topItem = findVisibleChild(contentItem, "sect_1"));
+    QTRY_COMPARE(topItem->y(), 140.);
+
+    // Change the next section
+    listview->setContentY(0);
+    bottomItem = findVisibleChild(contentItem, "sect_3"); // section footer
+    QVERIFY(bottomItem);
+    QTRY_COMPARE(bottomItem->y(), 320.);
+
+    model.modifyItem(14, "New", "new");
+
+    QTRY_VERIFY(bottomItem = findVisibleChild(contentItem, "sect_new")); // section footer
+    QTRY_COMPARE(bottomItem->y(), 320.);
+
+    // Turn sticky footer off
+    listview->setContentY(50);
+    canvas->rootObject()->setProperty("sectionPositioning", QVariant(int(QQuickViewSection::InlineLabels | QQuickViewSection::CurrentLabelAtStart)));
+    item = findVisibleChild(contentItem, "sect_new"); // inline label restored
+    QCOMPARE(item->y(), 360.);
+
+    // Turn sticky header off
+    listview->setContentY(50);
+    canvas->rootObject()->setProperty("sectionPositioning", QVariant(int(QQuickViewSection::InlineLabels)));
+    item = findVisibleChild(contentItem, "sect_aaa"); // inline label restored
+    QCOMPARE(item->y(), 20.);
+
+    delete canvas;
+}
+
+void tst_QQuickListView::currentIndex_delayedItemCreation()
+{
+    QFETCH(bool, setCurrentToZero);
+
+    QQuickView *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();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *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_QQuickListView::currentIndex_delayedItemCreation_data()
+{
+    QTest::addColumn<bool>("setCurrentToZero");
+
+    QTest::newRow("set to 0") << true;
+    QTest::newRow("don't set to 0") << false;
+}
+
+void tst_QQuickListView::currentIndex()
+{
+    TestModel model;
+    for (int i = 0; i < 30; i++)
+        model.addItem("Item" + QString::number(i), QString::number(i));
+
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setGeometry(0,0,240,320);
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+    ctxt->setContextProperty("testWrap", QVariant(false));
+
+    QString filename(TESTDATA("listview-initCurrent.qml"));
+    canvas->setSource(QUrl::fromLocalFile(filename));
+
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    // current item should be 20th item at startup
+    // and current item should be in view
+    QCOMPARE(listview->currentIndex(), 20);
+    QCOMPARE(listview->contentY(), 100.0);
+    QCOMPARE(listview->currentItem(), findItem<QQuickItem>(contentItem, "wrapper", 20));
+    QCOMPARE(listview->highlightItem()->y(), listview->currentItem()->y());
+
+    // no wrap
+    listview->setCurrentIndex(0);
+    QCOMPARE(listview->currentIndex(), 0);
+    // confirm that the velocity is updated
+    QTRY_VERIFY(listview->verticalVelocity() != 0.0);
+
+    listview->incrementCurrentIndex();
+    QCOMPARE(listview->currentIndex(), 1);
+    listview->decrementCurrentIndex();
+    QCOMPARE(listview->currentIndex(), 0);
+
+    listview->decrementCurrentIndex();
+    QCOMPARE(listview->currentIndex(), 0);
+
+    // with wrap
+    ctxt->setContextProperty("testWrap", QVariant(true));
+    QVERIFY(listview->isWrapEnabled());
+
+    listview->decrementCurrentIndex();
+    QCOMPARE(listview->currentIndex(), model.count()-1);
+
+    QTRY_COMPARE(listview->contentY(), 280.0);
+
+    listview->incrementCurrentIndex();
+    QCOMPARE(listview->currentIndex(), 0);
+
+    QTRY_COMPARE(listview->contentY(), 0.0);
+
+
+    // footer should become visible if it is out of view, and then current index is set to count-1
+    canvas->rootObject()->setProperty("showFooter", true);
+    QTRY_VERIFY(listview->footerItem());
+    listview->setCurrentIndex(model.count()-2);
+    QTRY_VERIFY(listview->footerItem()->y() > listview->contentY() + listview->height());
+    listview->setCurrentIndex(model.count()-1);
+    QTRY_COMPARE(listview->contentY() + listview->height(), (20.0 * model.count()) + listview->footerItem()->height());
+    canvas->rootObject()->setProperty("showFooter", false);
+
+    // header should become visible if it is out of view, and then current index is set to 0
+    canvas->rootObject()->setProperty("showHeader", true);
+    QTRY_VERIFY(listview->headerItem());
+    listview->setCurrentIndex(1);
+    QTRY_VERIFY(listview->headerItem()->y() + listview->headerItem()->height() < listview->contentY());
+    listview->setCurrentIndex(0);
+    QTRY_COMPARE(listview->contentY(), -listview->headerItem()->height());
+    canvas->rootObject()->setProperty("showHeader", false);
+
+
+    // Test keys
+    canvas->show();
+    canvas->requestActivateWindow();
+    QTest::qWaitForWindowShown(canvas);
+    QTRY_VERIFY(qGuiApp->focusWindow() == canvas);
+
+    listview->setCurrentIndex(0);
+
+    QTest::keyClick(canvas, Qt::Key_Down);
+    QCOMPARE(listview->currentIndex(), 1);
+
+    QTest::keyClick(canvas, Qt::Key_Up);
+    QCOMPARE(listview->currentIndex(), 0);
+
+    // hold down Key_Down
+    for (int i=0; i<model.count()-1; i++) {
+        QTest::simulateEvent(canvas, true, Qt::Key_Down, Qt::NoModifier, "", true);
+        QTRY_COMPARE(listview->currentIndex(), i+1);
+    }
+    QTest::keyRelease(canvas, Qt::Key_Down);
+    QTRY_COMPARE(listview->currentIndex(), model.count()-1);
+    QTRY_COMPARE(listview->contentY(), 280.0);
+
+    // hold down Key_Up
+    for (int i=model.count()-1; i > 0; i--) {
+        QTest::simulateEvent(canvas, true, Qt::Key_Up, Qt::NoModifier, "", true);
+        QTRY_COMPARE(listview->currentIndex(), i-1);
+    }
+    QTest::keyRelease(canvas, Qt::Key_Up);
+    QTRY_COMPARE(listview->currentIndex(), 0);
+    QTRY_COMPARE(listview->contentY(), 0.0);
+
+
+    // turn off auto highlight
+    listview->setHighlightFollowsCurrentItem(false);
+    QVERIFY(listview->highlightFollowsCurrentItem() == false);
+
+    QVERIFY(listview->highlightItem());
+    qreal hlPos = listview->highlightItem()->y();
+
+    listview->setCurrentIndex(4);
+    QTRY_COMPARE(listview->highlightItem()->y(), hlPos);
+
+    // insert item before currentIndex
+    listview->setCurrentIndex(28);
+    model.insertItem(0, "Foo", "1111");
+    QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29);
+
+    // check removing highlight by setting currentIndex to -1;
+    listview->setCurrentIndex(-1);
+
+    QCOMPARE(listview->currentIndex(), -1);
+    QVERIFY(!listview->highlightItem());
+    QVERIFY(!listview->currentItem());
+
+    delete canvas;
+}
+
+void tst_QQuickListView::noCurrentIndex()
+{
+    TestModel model;
+    for (int i = 0; i < 30; i++)
+        model.addItem("Item" + QString::number(i), QString::number(i));
+
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setGeometry(0,0,240,320);
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    QString filename(TESTDATA("listview-noCurrent.qml"));
+    canvas->setSource(QUrl::fromLocalFile(filename));
+
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    // current index should be -1 at startup
+    // and we should not have a currentItem or highlightItem
+    QCOMPARE(listview->currentIndex(), -1);
+    QCOMPARE(listview->contentY(), 0.0);
+    QVERIFY(!listview->highlightItem());
+    QVERIFY(!listview->currentItem());
+
+    listview->setCurrentIndex(2);
+    QCOMPARE(listview->currentIndex(), 2);
+    QVERIFY(listview->highlightItem());
+    QVERIFY(listview->currentItem());
+
+    delete canvas;
+}
+
+void tst_QQuickListView::itemList()
+{
+    QQuickView *canvas = createView();
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("itemlist.qml")));
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "view");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QQuickVisualItemModel *model = canvas->rootObject()->findChild<QQuickVisualItemModel*>("itemModel");
+    QTRY_VERIFY(model != 0);
+
+    QTRY_VERIFY(model->count() == 3);
+    QTRY_COMPARE(listview->currentIndex(), 0);
+
+    QQuickItem *item = findItem<QQuickItem>(contentItem, "item1");
+    QTRY_VERIFY(item);
+    QTRY_COMPARE(item->x(), 0.0);
+    QCOMPARE(item->height(), listview->height());
+
+    QQuickText *text = findItem<QQuickText>(contentItem, "text1");
+    QTRY_VERIFY(text);
+    QTRY_COMPARE(text->text(), QLatin1String("index: 0"));
+
+    listview->setCurrentIndex(2);
+
+    item = findItem<QQuickItem>(contentItem, "item3");
+    QTRY_VERIFY(item);
+    QTRY_COMPARE(item->x(), 480.0);
+
+    text = findItem<QQuickText>(contentItem, "text3");
+    QTRY_VERIFY(text);
+    QTRY_COMPARE(text->text(), QLatin1String("index: 2"));
+
+    delete canvas;
+}
+
+void tst_QQuickListView::cacheBuffer()
+{
+    QQuickView *canvas = createView();
+
+    TestModel 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();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+    QTRY_VERIFY(listview->delegate() != 0);
+    QTRY_VERIFY(listview->model() != 0);
+    QTRY_VERIFY(listview->highlight() != 0);
+
+    // Confirm items positioned correctly
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_VERIFY(item->y() == i*20);
+    }
+
+    testObject->setCacheBuffer(400);
+    QTRY_VERIFY(listview->cacheBuffer() == 400);
+
+    int newItemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    QTRY_VERIFY(newItemCount > itemCount);
+
+    // Confirm items positioned correctly
+    for (int i = 0; i < model.count() && i < newItemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_VERIFY(item->y() == i*20);
+    }
+
+    delete canvas;
+    delete testObject;
+}
+
+void tst_QQuickListView::positionViewAtIndex()
+{
+    QQuickView *canvas = createView();
+
+    TestModel model;
+    for (int i = 0; i < 40; 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();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    // Confirm items positioned correctly
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->y(), i*20.);
+    }
+
+    // Position on a currently visible item
+    listview->positionViewAtIndex(3, QQuickListView::Beginning);
+    QTRY_COMPARE(listview->contentY(), 60.);
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 3; i < model.count() && i < itemCount-3-1; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->y(), i*20.);
+    }
+
+    // Position on an item beyond the visible items
+    listview->positionViewAtIndex(22, QQuickListView::Beginning);
+    QTRY_COMPARE(listview->contentY(), 440.);
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 22; i < model.count() && i < itemCount-22-1; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->y(), i*20.);
+    }
+
+    // Position on an item that would leave empty space if positioned at the top
+    listview->positionViewAtIndex(28, QQuickListView::Beginning);
+    QTRY_COMPARE(listview->contentY(), 480.);
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 24; i < model.count() && i < itemCount-24-1; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->y(), i*20.);
+    }
+
+    // Position at the beginning again
+    listview->positionViewAtIndex(0, QQuickListView::Beginning);
+    QTRY_COMPARE(listview->contentY(), 0.);
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->y(), i*20.);
+    }
+
+    // Position at End using last index
+    listview->positionViewAtIndex(model.count()-1, QQuickListView::End);
+    QTRY_COMPARE(listview->contentY(), 480.);
+
+    // Confirm items positioned correctly
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 24; i < model.count(); ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->y(), i*20.);
+    }
+
+    // Position at End
+    listview->positionViewAtIndex(20, QQuickListView::End);
+    QTRY_COMPARE(listview->contentY(), 100.);
+
+    // Position in Center
+    listview->positionViewAtIndex(15, QQuickListView::Center);
+    QTRY_COMPARE(listview->contentY(), 150.);
+
+    // Ensure at least partially visible
+    listview->positionViewAtIndex(15, QQuickListView::Visible);
+    QTRY_COMPARE(listview->contentY(), 150.);
+
+    listview->setContentY(302);
+    listview->positionViewAtIndex(15, QQuickListView::Visible);
+    QTRY_COMPARE(listview->contentY(), 302.);
+
+    listview->setContentY(320);
+    listview->positionViewAtIndex(15, QQuickListView::Visible);
+    QTRY_COMPARE(listview->contentY(), 300.);
+
+    listview->setContentY(85);
+    listview->positionViewAtIndex(20, QQuickListView::Visible);
+    QTRY_COMPARE(listview->contentY(), 85.);
+
+    listview->setContentY(75);
+    listview->positionViewAtIndex(20, QQuickListView::Visible);
+    QTRY_COMPARE(listview->contentY(), 100.);
+
+    // Ensure completely visible
+    listview->setContentY(120);
+    listview->positionViewAtIndex(20, QQuickListView::Contain);
+    QTRY_COMPARE(listview->contentY(), 120.);
+
+    listview->setContentY(302);
+    listview->positionViewAtIndex(15, QQuickListView::Contain);
+    QTRY_COMPARE(listview->contentY(), 300.);
+
+    listview->setContentY(85);
+    listview->positionViewAtIndex(20, QQuickListView::Contain);
+    QTRY_COMPARE(listview->contentY(), 100.);
+
+    // positionAtBeginnging
+    listview->positionViewAtBeginning();
+    QTRY_COMPARE(listview->contentY(), 0.);
+
+    listview->setContentY(80);
+    canvas->rootObject()->setProperty("showHeader", true);
+    listview->positionViewAtBeginning();
+    QTRY_COMPARE(listview->contentY(), -30.);
+
+    // positionAtEnd
+    listview->positionViewAtEnd();
+    QTRY_COMPARE(listview->contentY(), 480.); // 40*20 - 320
+
+    listview->setContentY(80);
+    canvas->rootObject()->setProperty("showFooter", true);
+    listview->positionViewAtEnd();
+    QTRY_COMPARE(listview->contentY(), 510.);
+
+    // set current item to outside visible view, position at beginning
+    // and ensure highlight moves to current item
+    listview->setCurrentIndex(1);
+    listview->positionViewAtBeginning();
+    QTRY_COMPARE(listview->contentY(), -30.);
+    QVERIFY(listview->highlightItem());
+    QCOMPARE(listview->highlightItem()->y(), 20.);
+
+    delete canvas;
+    delete testObject;
+}
+
+void tst_QQuickListView::resetModel()
+{
+    QQuickView *canvas = createView();
+
+    QStringList strings;
+    strings << "one" << "two" << "three";
+    QStringListModel model(strings);
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaylist.qml")));
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QTRY_COMPARE(listview->count(), model.rowCount());
+
+    for (int i = 0; i < model.rowCount(); ++i) {
+        QQuickText *display = findItem<QQuickText>(contentItem, "displayText", i);
+        QTRY_VERIFY(display != 0);
+        QTRY_COMPARE(display->text(), strings.at(i));
+    }
+
+    strings.clear();
+    strings << "four" << "five" << "six" << "seven";
+    model.setStringList(strings);
+
+    QTRY_COMPARE(listview->count(), model.rowCount());
+
+    for (int i = 0; i < model.rowCount(); ++i) {
+        QQuickText *display = findItem<QQuickText>(contentItem, "displayText", i);
+        QTRY_VERIFY(display != 0);
+        QTRY_COMPARE(display->text(), strings.at(i));
+    }
+
+    delete canvas;
+}
+
+void tst_QQuickListView::propertyChanges()
+{
+    QQuickView *canvas = createView();
+    QTRY_VERIFY(canvas);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml")));
+
+    QQuickListView *listView = canvas->rootObject()->findChild<QQuickListView*>("listView");
+    QTRY_VERIFY(listView);
+
+    QSignalSpy highlightFollowsCurrentItemSpy(listView, SIGNAL(highlightFollowsCurrentItemChanged()));
+    QSignalSpy preferredHighlightBeginSpy(listView, SIGNAL(preferredHighlightBeginChanged()));
+    QSignalSpy preferredHighlightEndSpy(listView, SIGNAL(preferredHighlightEndChanged()));
+    QSignalSpy highlightRangeModeSpy(listView, SIGNAL(highlightRangeModeChanged()));
+    QSignalSpy keyNavigationWrapsSpy(listView, SIGNAL(keyNavigationWrapsChanged()));
+    QSignalSpy cacheBufferSpy(listView, SIGNAL(cacheBufferChanged()));
+    QSignalSpy snapModeSpy(listView, SIGNAL(snapModeChanged()));
+
+    QTRY_COMPARE(listView->highlightFollowsCurrentItem(), true);
+    QTRY_COMPARE(listView->preferredHighlightBegin(), 0.0);
+    QTRY_COMPARE(listView->preferredHighlightEnd(), 0.0);
+    QTRY_COMPARE(listView->highlightRangeMode(), QQuickListView::ApplyRange);
+    QTRY_COMPARE(listView->isWrapEnabled(), true);
+    QTRY_COMPARE(listView->cacheBuffer(), 10);
+    QTRY_COMPARE(listView->snapMode(), QQuickListView::SnapToItem);
+
+    listView->setHighlightFollowsCurrentItem(false);
+    listView->setPreferredHighlightBegin(1.0);
+    listView->setPreferredHighlightEnd(1.0);
+    listView->setHighlightRangeMode(QQuickListView::StrictlyEnforceRange);
+    listView->setWrapEnabled(false);
+    listView->setCacheBuffer(3);
+    listView->setSnapMode(QQuickListView::SnapOneItem);
+
+    QTRY_COMPARE(listView->highlightFollowsCurrentItem(), false);
+    QTRY_COMPARE(listView->preferredHighlightBegin(), 1.0);
+    QTRY_COMPARE(listView->preferredHighlightEnd(), 1.0);
+    QTRY_COMPARE(listView->highlightRangeMode(), QQuickListView::StrictlyEnforceRange);
+    QTRY_COMPARE(listView->isWrapEnabled(), false);
+    QTRY_COMPARE(listView->cacheBuffer(), 3);
+    QTRY_COMPARE(listView->snapMode(), QQuickListView::SnapOneItem);
+
+    QTRY_COMPARE(highlightFollowsCurrentItemSpy.count(),1);
+    QTRY_COMPARE(preferredHighlightBeginSpy.count(),1);
+    QTRY_COMPARE(preferredHighlightEndSpy.count(),1);
+    QTRY_COMPARE(highlightRangeModeSpy.count(),1);
+    QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
+    QTRY_COMPARE(cacheBufferSpy.count(),1);
+    QTRY_COMPARE(snapModeSpy.count(),1);
+
+    listView->setHighlightFollowsCurrentItem(false);
+    listView->setPreferredHighlightBegin(1.0);
+    listView->setPreferredHighlightEnd(1.0);
+    listView->setHighlightRangeMode(QQuickListView::StrictlyEnforceRange);
+    listView->setWrapEnabled(false);
+    listView->setCacheBuffer(3);
+    listView->setSnapMode(QQuickListView::SnapOneItem);
+
+    QTRY_COMPARE(highlightFollowsCurrentItemSpy.count(),1);
+    QTRY_COMPARE(preferredHighlightBeginSpy.count(),1);
+    QTRY_COMPARE(preferredHighlightEndSpy.count(),1);
+    QTRY_COMPARE(highlightRangeModeSpy.count(),1);
+    QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
+    QTRY_COMPARE(cacheBufferSpy.count(),1);
+    QTRY_COMPARE(snapModeSpy.count(),1);
+
+    delete canvas;
+}
+
+void tst_QQuickListView::componentChanges()
+{
+    QQuickView *canvas = createView();
+    QTRY_VERIFY(canvas);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml")));
+
+    QQuickListView *listView = canvas->rootObject()->findChild<QQuickListView*>("listView");
+    QTRY_VERIFY(listView);
+
+    QDeclarativeComponent component(canvas->engine());
+    component.setData("import QtQuick 2.0; Rectangle { color: \"blue\"; }", QUrl::fromLocalFile(""));
+
+    QDeclarativeComponent delegateComponent(canvas->engine());
+    delegateComponent.setData("import QtQuick 2.0; Text { text: '<b>Name:</b> ' + name }", QUrl::fromLocalFile(""));
+
+    QSignalSpy highlightSpy(listView, SIGNAL(highlightChanged()));
+    QSignalSpy delegateSpy(listView, SIGNAL(delegateChanged()));
+    QSignalSpy headerSpy(listView, SIGNAL(headerChanged()));
+    QSignalSpy footerSpy(listView, SIGNAL(footerChanged()));
+
+    listView->setHighlight(&component);
+    listView->setHeader(&component);
+    listView->setFooter(&component);
+    listView->setDelegate(&delegateComponent);
+
+    QTRY_COMPARE(listView->highlight(), &component);
+    QTRY_COMPARE(listView->header(), &component);
+    QTRY_COMPARE(listView->footer(), &component);
+    QTRY_COMPARE(listView->delegate(), &delegateComponent);
+
+    QTRY_COMPARE(highlightSpy.count(),1);
+    QTRY_COMPARE(delegateSpy.count(),1);
+    QTRY_COMPARE(headerSpy.count(),1);
+    QTRY_COMPARE(footerSpy.count(),1);
+
+    listView->setHighlight(&component);
+    listView->setHeader(&component);
+    listView->setFooter(&component);
+    listView->setDelegate(&delegateComponent);
+
+    QTRY_COMPARE(highlightSpy.count(),1);
+    QTRY_COMPARE(delegateSpy.count(),1);
+    QTRY_COMPARE(headerSpy.count(),1);
+    QTRY_COMPARE(footerSpy.count(),1);
+
+    delete canvas;
+}
+
+void tst_QQuickListView::modelChanges()
+{
+    QQuickView *canvas = createView();
+    QTRY_VERIFY(canvas);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml")));
+
+    QQuickListView *listView = canvas->rootObject()->findChild<QQuickListView*>("listView");
+    QTRY_VERIFY(listView);
+
+    QDeclarativeListModel *alternateModel = canvas->rootObject()->findChild<QDeclarativeListModel*>("alternateModel");
+    QTRY_VERIFY(alternateModel);
+    QVariant modelVariant = QVariant::fromValue<QObject *>(alternateModel);
+    QSignalSpy modelSpy(listView, SIGNAL(modelChanged()));
+
+    listView->setModel(modelVariant);
+    QTRY_COMPARE(listView->model(), modelVariant);
+    QTRY_COMPARE(modelSpy.count(),1);
+
+    listView->setModel(modelVariant);
+    QTRY_COMPARE(modelSpy.count(),1);
+
+    listView->setModel(QVariant());
+    QTRY_COMPARE(modelSpy.count(),2);
+
+    delete canvas;
+}
+
+void tst_QQuickListView::QTBUG_9791()
+{
+    QQuickView *canvas = createView();
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("strictlyenforcerange.qml")));
+    qApp->processEvents();
+
+    QQuickListView *listview = qobject_cast<QQuickListView*>(canvas->rootObject());
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+    QTRY_VERIFY(listview->delegate() != 0);
+    QTRY_VERIFY(listview->model() != 0);
+
+    QMetaObject::invokeMethod(listview, "fillModel");
+    qApp->processEvents();
+
+    // Confirm items positioned correctly
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    QCOMPARE(itemCount, 3);
+
+    for (int i = 0; i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->x(), i*300.0);
+    }
+
+    // check that view is positioned correctly
+    QTRY_COMPARE(listview->contentX(), 590.0);
+
+    delete canvas;
+}
+
+void tst_QQuickListView::manualHighlight()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setGeometry(0,0,240,320);
+
+    QString filename(TESTDATA("manual-highlight.qml"));
+    canvas->setSource(QUrl::fromLocalFile(filename));
+
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QTRY_COMPARE(listview->currentIndex(), 0);
+    QTRY_COMPARE(listview->currentItem(), findItem<QQuickItem>(contentItem, "wrapper", 0));
+    QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y());
+
+    listview->setCurrentIndex(2);
+
+    QTRY_COMPARE(listview->currentIndex(), 2);
+    QTRY_COMPARE(listview->currentItem(), findItem<QQuickItem>(contentItem, "wrapper", 2));
+    QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y());
+
+    // QTBUG-15972
+    listview->positionViewAtIndex(3, QQuickListView::Contain);
+
+    QTRY_COMPARE(listview->currentIndex(), 2);
+    QTRY_COMPARE(listview->currentItem(), findItem<QQuickItem>(contentItem, "wrapper", 2));
+    QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y());
+
+    delete canvas;
+}
+
+void tst_QQuickListView::QTBUG_11105()
+{
+    QQuickView *canvas = createView();
+
+    TestModel 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();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    // Confirm items positioned correctly
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_VERIFY(item->y() == i*20);
+    }
+
+    listview->positionViewAtIndex(20, QQuickListView::Beginning);
+    QCOMPARE(listview->contentY(), 280.);
+
+    TestModel model2;
+    for (int i = 0; i < 5; i++)
+        model2.addItem("Item" + QString::number(i), "");
+
+    ctxt->setContextProperty("testModel", &model2);
+
+    itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    QCOMPARE(itemCount, 5);
+
+    delete canvas;
+    delete testObject;
+}
+
+void tst_QQuickListView::header()
+{
+    QFETCH(QQuickListView::Orientation, orientation);
+    QFETCH(Qt::LayoutDirection, layoutDirection);
+    QFETCH(QPointF, initialHeaderPos);
+    QFETCH(QPointF, firstDelegatePos);
+    QFETCH(QPointF, initialContentPos);
+    QFETCH(QPointF, changedHeaderPos);
+    QFETCH(QPointF, changedContentPos);
+    QFETCH(QPointF, resizeContentPos);
+
+    TestModel model;
+    for (int i = 0; i < 30; i++)
+        model.addItem("Item" + QString::number(i), "");
+
+    QQuickView *canvas = createView();
+    canvas->rootContext()->setContextProperty("testModel", &model);
+    canvas->rootContext()->setContextProperty("initialViewWidth", 240);
+    canvas->rootContext()->setContextProperty("initialViewHeight", 320);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml")));
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+    listview->setOrientation(orientation);
+    listview->setLayoutDirection(layoutDirection);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QQuickText *header = findItem<QQuickText>(contentItem, "header");
+    QVERIFY(header);
+
+    QVERIFY(header == listview->headerItem());
+
+    QCOMPARE(header->width(), 100.);
+    QCOMPARE(header->height(), 30.);
+    QCOMPARE(header->pos(), initialHeaderPos);
+    QCOMPARE(QPointF(listview->contentX(), listview->contentY()), initialContentPos);
+
+    QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", 0);
+    QVERIFY(item);
+    QCOMPARE(item->pos(), firstDelegatePos);
+
+    model.clear();
+    QCOMPARE(header->pos(), initialHeaderPos); // header should stay where it is
+
+    for (int i = 0; i < 30; i++)
+        model.addItem("Item" + QString::number(i), "");
+
+    QSignalSpy headerItemSpy(listview, SIGNAL(headerItemChanged()));
+    QMetaObject::invokeMethod(canvas->rootObject(), "changeHeader");
+
+    QCOMPARE(headerItemSpy.count(), 1);
+
+    header = findItem<QQuickText>(contentItem, "header");
+    QVERIFY(!header);
+    header = findItem<QQuickText>(contentItem, "header2");
+    QVERIFY(header);
+
+    QVERIFY(header == listview->headerItem());
+
+    QCOMPARE(header->pos(), changedHeaderPos);
+    QCOMPARE(header->width(), 50.);
+    QCOMPARE(header->height(), 20.);
+    QTRY_COMPARE(QPointF(listview->contentX(), listview->contentY()), changedContentPos);
+    QCOMPARE(item->pos(), firstDelegatePos);
+
+    delete canvas;
+
+
+    // QTBUG-21207 header should become visible if view resizes from initial empty size
+
+    canvas = createView();
+    canvas->rootContext()->setContextProperty("testModel", &model);
+    canvas->rootContext()->setContextProperty("initialViewWidth", 0.0);
+    canvas->rootContext()->setContextProperty("initialViewHeight", 0.0);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml")));
+
+    listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+    listview->setOrientation(orientation);
+    listview->setLayoutDirection(layoutDirection);
+
+    listview->setWidth(240);
+    listview->setHeight(320);
+    QTRY_COMPARE(listview->headerItem()->pos(), initialHeaderPos);
+    QCOMPARE(QPointF(listview->contentX(), listview->contentY()), initialContentPos);
+
+
+    delete canvas;
+}
+
+void tst_QQuickListView::header_data()
+{
+    QTest::addColumn<QQuickListView::Orientation>("orientation");
+    QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+    QTest::addColumn<QPointF>("initialHeaderPos");
+    QTest::addColumn<QPointF>("changedHeaderPos");
+    QTest::addColumn<QPointF>("initialContentPos");
+    QTest::addColumn<QPointF>("changedContentPos");
+    QTest::addColumn<QPointF>("firstDelegatePos");
+    QTest::addColumn<QPointF>("resizeContentPos");
+
+    // header1 = 100 x 30
+    // header2 = 50 x 20
+    // delegates = 240 x 20
+    // view width = 240
+
+    // header above items, top left
+    QTest::newRow("vertical, left to right") << QQuickListView::Vertical << Qt::LeftToRight
+        << QPointF(0, -30)
+        << QPointF(0, -20)
+        << QPointF(0, -30)
+        << QPointF(0, -20)
+        << QPointF(0, 0)
+        << QPointF(0, -10);
+
+    // header above items, top right
+    QTest::newRow("vertical, layout right to left") << QQuickListView::Vertical << Qt::RightToLeft
+        << QPointF(0, -30)
+        << QPointF(0, -20)
+        << QPointF(0, -30)
+        << QPointF(0, -20)
+        << QPointF(0, 0)
+        << QPointF(0, -10);
+
+    // header to left of items
+    QTest::newRow("horizontal, layout left to right") << QQuickListView::Horizontal << Qt::LeftToRight
+        << QPointF(-100, 0)
+        << QPointF(-50, 0)
+        << QPointF(-100, 0)
+        << QPointF(-50, 0)
+        << QPointF(0, 0)
+        << QPointF(-40, 0);
+
+    // header to right of items
+    QTest::newRow("horizontal, layout right to left") << QQuickListView::Horizontal << Qt::RightToLeft
+        << QPointF(0, 0)
+        << QPointF(0, 0)
+        << QPointF(-240 + 100, 0)
+        << QPointF(-240 + 50, 0)
+        << QPointF(-240, 0)
+        << QPointF(-240 + 40, 0);
+}
+
+void tst_QQuickListView::header_delayItemCreation()
+{
+    QQuickView *canvas = createView();
+
+    TestModel model;
+
+    canvas->rootContext()->setContextProperty("setCurrentToZero", false);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("fillModelOnComponentCompleted.qml")));
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QQuickText *header = findItem<QQuickText>(contentItem, "header");
+    QVERIFY(header);
+    QCOMPARE(header->y(), -header->height());
+
+    QCOMPARE(listview->contentY(), -header->height());
+
+    model.clear();
+    QTRY_COMPARE(header->y(), -header->height());
+
+    delete canvas;
+}
+
+void tst_QQuickListView::footer()
+{
+    QFETCH(QQuickListView::Orientation, orientation);
+    QFETCH(Qt::LayoutDirection, layoutDirection);
+    QFETCH(QPointF, initialFooterPos);
+    QFETCH(QPointF, firstDelegatePos);
+    QFETCH(QPointF, initialContentPos);
+    QFETCH(QPointF, changedFooterPos);
+    QFETCH(QPointF, changedContentPos);
+    QFETCH(QPointF, resizeContentPos);
+
+    QQuickView *canvas = createView();
+
+    TestModel model;
+    for (int i = 0; i < 3; i++)
+        model.addItem("Item" + QString::number(i), "");
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("footer.qml")));
+    canvas->show();
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+    listview->setOrientation(orientation);
+    listview->setLayoutDirection(layoutDirection);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QQuickText *footer = findItem<QQuickText>(contentItem, "footer");
+    QVERIFY(footer);
+
+    QVERIFY(footer == listview->footerItem());
+
+    QCOMPARE(footer->pos(), initialFooterPos);
+    QCOMPARE(footer->width(), 100.);
+    QCOMPARE(footer->height(), 30.);
+    QCOMPARE(QPointF(listview->contentX(), listview->contentY()), initialContentPos);
+
+    QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", 0);
+    QVERIFY(item);
+    QCOMPARE(item->pos(), firstDelegatePos);
+
+    // remove one item
+    model.removeItem(1);
+
+    if (orientation == QQuickListView::Vertical) {
+        QTRY_COMPARE(footer->y(), initialFooterPos.y() - 20);   // delegate height = 20
+    } else {
+        QTRY_COMPARE(footer->x(), layoutDirection == Qt::LeftToRight ?
+                initialFooterPos.x() - 40 : initialFooterPos.x() + 40);  // delegate width = 40
+    }
+
+    // remove all items
+    model.clear();
+
+    QPointF posWhenNoItems(0, 0);
+    if (orientation == QQuickListView::Horizontal && layoutDirection == Qt::RightToLeft)
+        posWhenNoItems.setX(-100);
+    QTRY_COMPARE(footer->pos(), posWhenNoItems);
+
+    // if header is present, it's at a negative pos, so the footer should not move
+    canvas->rootObject()->setProperty("showHeader", true);
+    QTRY_COMPARE(footer->pos(), posWhenNoItems);
+    canvas->rootObject()->setProperty("showHeader", false);
+
+    // add 30 items
+    for (int i = 0; i < 30; i++)
+        model.addItem("Item" + QString::number(i), "");
+
+    QSignalSpy footerItemSpy(listview, SIGNAL(footerItemChanged()));
+    QMetaObject::invokeMethod(canvas->rootObject(), "changeFooter");
+
+    QCOMPARE(footerItemSpy.count(), 1);
+
+    footer = findItem<QQuickText>(contentItem, "footer");
+    QVERIFY(!footer);
+    footer = findItem<QQuickText>(contentItem, "footer2");
+    QVERIFY(footer);
+
+    QVERIFY(footer == listview->footerItem());
+
+    QCOMPARE(footer->pos(), changedFooterPos);
+    QCOMPARE(footer->width(), 50.);
+    QCOMPARE(footer->height(), 20.);
+    QTRY_COMPARE(QPointF(listview->contentX(), listview->contentY()), changedContentPos);
+
+    item = findItem<QQuickItem>(contentItem, "wrapper", 0);
+    QVERIFY(item);
+    QCOMPARE(item->pos(), firstDelegatePos);
+
+    listview->positionViewAtEnd();
+    footer->setHeight(10);
+    footer->setWidth(40);
+    QTRY_COMPARE(QPointF(listview->contentX(), listview->contentY()), resizeContentPos);
+
+    delete canvas;
+}
+
+void tst_QQuickListView::footer_data()
+{
+    QTest::addColumn<QQuickListView::Orientation>("orientation");
+    QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+    QTest::addColumn<QPointF>("initialFooterPos");
+    QTest::addColumn<QPointF>("changedFooterPos");
+    QTest::addColumn<QPointF>("initialContentPos");
+    QTest::addColumn<QPointF>("changedContentPos");
+    QTest::addColumn<QPointF>("firstDelegatePos");
+    QTest::addColumn<QPointF>("resizeContentPos");
+
+    // footer1 = 100 x 30
+    // footer2 = 50 x 20
+    // delegates = 40 x 20
+    // view width = 240
+    // view height = 320
+
+    // footer below items, bottom left
+    QTest::newRow("vertical, layout left to right") << QQuickListView::Vertical << Qt::LeftToRight
+        << QPointF(0, 3 * 20)
+        << QPointF(0, 30 * 20)  // added 30 items
+        << QPointF(0, 0)
+        << QPointF(0, 0)
+        << QPointF(0, 0)
+        << QPointF(0, 30 * 20 - 320 + 10);
+
+    // footer below items, bottom right
+    QTest::newRow("vertical, layout right to left") << QQuickListView::Vertical << Qt::RightToLeft
+        << QPointF(0, 3 * 20)
+        << QPointF(0, 30 * 20)
+        << QPointF(0, 0)
+        << QPointF(0, 0)
+        << QPointF(0, 0)
+        << QPointF(0, 30 * 20 - 320 + 10);
+
+    // footer to right of items
+    QTest::newRow("horizontal, layout left to right") << QQuickListView::Horizontal << Qt::LeftToRight
+        << QPointF(40 * 3, 0)
+        << QPointF(40 * 30, 0)
+        << QPointF(0, 0)
+        << QPointF(0, 0)
+        << QPointF(0, 0)
+        << QPointF(40 * 30 - 240 + 40, 0);
+
+    // footer to left of items
+    QTest::newRow("horizontal, layout right to left") << QQuickListView::Horizontal << Qt::RightToLeft
+        << QPointF(-(40 * 3) - 100, 0)
+        << QPointF(-(40 * 30) - 50, 0)     // 50 = new footer width
+        << QPointF(-240, 0)
+        << QPointF(-240, 0)
+        << QPointF(-40, 0)
+        << QPointF(-(40 * 30) - 40, 0);
+}
+
+class LVAccessor : public QQuickListView
+{
+public:
+    qreal minY() const { return minYExtent(); }
+    qreal maxY() const { return maxYExtent(); }
+    qreal minX() const { return minXExtent(); }
+    qreal maxX() const { return maxXExtent(); }
+};
+
+void tst_QQuickListView::headerFooter()
+{
+    {
+        // Vertical
+        QQuickView *canvas = createView();
+
+        TestModel model;
+        QDeclarativeContext *ctxt = canvas->rootContext();
+        ctxt->setContextProperty("testModel", &model);
+
+        canvas->setSource(QUrl::fromLocalFile(TESTDATA("headerfooter.qml")));
+        qApp->processEvents();
+
+        QQuickListView *listview = qobject_cast<QQuickListView*>(canvas->rootObject());
+        QTRY_VERIFY(listview != 0);
+
+        QQuickItem *contentItem = listview->contentItem();
+        QTRY_VERIFY(contentItem != 0);
+
+        QQuickItem *header = findItem<QQuickItem>(contentItem, "header");
+        QVERIFY(header);
+        QCOMPARE(header->y(), -header->height());
+
+        QQuickItem *footer = findItem<QQuickItem>(contentItem, "footer");
+        QVERIFY(footer);
+        QCOMPARE(footer->y(), 0.);
+
+        QCOMPARE(static_cast<LVAccessor*>(listview)->minY(), header->height());
+        QCOMPARE(static_cast<LVAccessor*>(listview)->maxY(), header->height());
+
+        delete canvas;
+    }
+    {
+        // Horizontal
+        QQuickView *canvas = createView();
+
+        TestModel model;
+        QDeclarativeContext *ctxt = canvas->rootContext();
+        ctxt->setContextProperty("testModel", &model);
+
+        canvas->setSource(QUrl::fromLocalFile(TESTDATA("headerfooter.qml")));
+        canvas->rootObject()->setProperty("horizontal", true);
+        qApp->processEvents();
+
+        QQuickListView *listview = qobject_cast<QQuickListView*>(canvas->rootObject());
+        QTRY_VERIFY(listview != 0);
+
+        QQuickItem *contentItem = listview->contentItem();
+        QTRY_VERIFY(contentItem != 0);
+
+        QQuickItem *header = findItem<QQuickItem>(contentItem, "header");
+        QVERIFY(header);
+        QCOMPARE(header->x(), -header->width());
+
+        QQuickItem *footer = findItem<QQuickItem>(contentItem, "footer");
+        QVERIFY(footer);
+        QCOMPARE(footer->x(), 0.);
+
+        QCOMPARE(static_cast<LVAccessor*>(listview)->minX(), header->width());
+        QCOMPARE(static_cast<LVAccessor*>(listview)->maxX(), header->width());
+
+        delete canvas;
+    }
+    {
+        // Horizontal RTL
+        QQuickView *canvas = createView();
+
+        TestModel model;
+        QDeclarativeContext *ctxt = canvas->rootContext();
+        ctxt->setContextProperty("testModel", &model);
+
+        canvas->setSource(QUrl::fromLocalFile(TESTDATA("headerfooter.qml")));
+        canvas->rootObject()->setProperty("horizontal", true);
+        canvas->rootObject()->setProperty("rtl", true);
+        qApp->processEvents();
+
+        QQuickListView *listview = qobject_cast<QQuickListView*>(canvas->rootObject());
+        QTRY_VERIFY(listview != 0);
+
+        QQuickItem *contentItem = listview->contentItem();
+        QTRY_VERIFY(contentItem != 0);
+
+        QQuickItem *header = findItem<QQuickItem>(contentItem, "header");
+        QVERIFY(header);
+        QCOMPARE(header->x(), 0.);
+
+        QQuickItem *footer = findItem<QQuickItem>(contentItem, "footer");
+        QVERIFY(footer);
+        QCOMPARE(footer->x(), -footer->width());
+
+        QCOMPARE(static_cast<LVAccessor*>(listview)->minX(), 240. - header->width());
+        QCOMPARE(static_cast<LVAccessor*>(listview)->maxX(), 240. - header->width());
+
+        delete canvas;
+    }
+}
+
+void tst_QQuickListView::resizeView()
+{
+    QQuickView *canvas = createView();
+
+    TestModel model;
+    for (int i = 0; i < 40; 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();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    // Confirm items positioned correctly
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->y(), i*20.);
+    }
+
+    QVariant heightRatio;
+    QMetaObject::invokeMethod(canvas->rootObject(), "heightRatio", Q_RETURN_ARG(QVariant, heightRatio));
+    QCOMPARE(heightRatio.toReal(), 0.4);
+
+    listview->setHeight(200);
+
+    QMetaObject::invokeMethod(canvas->rootObject(), "heightRatio", Q_RETURN_ARG(QVariant, heightRatio));
+    QCOMPARE(heightRatio.toReal(), 0.25);
+
+    delete canvas;
+    delete testObject;
+}
+
+void tst_QQuickListView::resizeViewAndRepaint()
+{
+    QQuickView *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();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    // item at index 10 should not be currently visible
+    QVERIFY(!findItem<QQuickItem>(contentItem, "wrapper", 10));
+
+    listview->setHeight(320);
+    QTRY_VERIFY(findItem<QQuickItem>(contentItem, "wrapper", 10));
+
+    listview->setHeight(100);
+    QTRY_VERIFY(!findItem<QQuickItem>(contentItem, "wrapper", 10));
+
+    delete canvas;
+}
+
+void tst_QQuickListView::sizeLessThan1()
+{
+    QQuickView *canvas = createView();
+
+    TestModel 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("sizelessthan1.qml")));
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    // Confirm items positioned correctly
+    int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
+    for (int i = 0; i < model.count() && i < itemCount; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        if (!item) qWarning() << "Item" << i << "not found";
+        QTRY_VERIFY(item);
+        QTRY_COMPARE(item->y(), i*0.5);
+    }
+
+    delete canvas;
+    delete testObject;
+}
+
+void tst_QQuickListView::QTBUG_14821()
+{
+    QQuickView *canvas = createView();
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("qtbug14821.qml")));
+    qApp->processEvents();
+
+    QQuickListView *listview = qobject_cast<QQuickListView*>(canvas->rootObject());
+    QVERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QVERIFY(contentItem != 0);
+
+    listview->decrementCurrentIndex();
+    QCOMPARE(listview->currentIndex(), 99);
+
+    listview->incrementCurrentIndex();
+    QCOMPARE(listview->currentIndex(), 0);
+
+    delete canvas;
+}
+
+void tst_QQuickListView::resizeDelegate()
+{
+    QQuickView *canvas = createView();
+    canvas->show();
+
+    QStringList strings;
+    for (int i = 0; i < 30; ++i)
+        strings << QString::number(i);
+    QStringListModel model(strings);
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaylist.qml")));
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QVERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QVERIFY(contentItem != 0);
+
+    QCOMPARE(listview->count(), model.rowCount());
+
+    listview->setCurrentIndex(25);
+    listview->setContentY(0);
+    QTest::qWait(300);
+
+    for (int i = 0; i < 16; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        QVERIFY(item != 0);
+        QCOMPARE(item->y(), i*20.0);
+    }
+
+    QCOMPARE(listview->currentItem()->y(), 500.0);
+    QTRY_COMPARE(listview->highlightItem()->y(), 500.0);
+
+    canvas->rootObject()->setProperty("delegateHeight", 30);
+    QTest::qWait(300);
+
+    for (int i = 0; i < 11; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        QVERIFY(item != 0);
+        QTRY_COMPARE(item->y(), i*30.0);
+    }
+
+    QTRY_COMPARE(listview->currentItem()->y(), 750.0);
+    QTRY_COMPARE(listview->highlightItem()->y(), 750.0);
+
+    listview->setCurrentIndex(1);
+    listview->positionViewAtIndex(25, QQuickListView::Beginning);
+    listview->positionViewAtIndex(5, QQuickListView::Beginning);
+
+    for (int i = 5; i < 16; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        QVERIFY(item != 0);
+        QCOMPARE(item->y(), i*30.0);
+    }
+
+    QTRY_COMPARE(listview->currentItem()->y(), 30.0);
+    QTRY_COMPARE(listview->highlightItem()->y(), 30.0);
+
+    canvas->rootObject()->setProperty("delegateHeight", 20);
+    QTest::qWait(300);
+
+    for (int i = 5; i < 11; ++i) {
+        QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        QVERIFY(item != 0);
+        QTRY_COMPARE(item->y(), 150 + (i-5)*20.0);
+    }
+
+    QTRY_COMPARE(listview->currentItem()->y(), 70.0);
+    QTRY_COMPARE(listview->highlightItem()->y(), 70.0);
+
+    delete canvas;
+}
+
+void tst_QQuickListView::resizeFirstDelegate()
+{
+    // QTBUG-20712: Content Y jumps constantly if first delegate height == 0
+    // and other delegates have height > 0
+
+    QQuickView *canvas = createView();
+    canvas->show();
+
+    // bug only occurs when all items in the model are visible
+    TestModel model;
+    for (int i = 0; i < 10; 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();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QVERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QVERIFY(contentItem != 0);
+
+    QQuickItem *item = 0;
+    for (int i = 0; i < model.count(); ++i) {
+        item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        QVERIFY(item != 0);
+        QCOMPARE(item->y(), i*20.0);
+    }
+
+    item = findItem<QQuickItem>(contentItem, "wrapper", 0);
+    item->setHeight(0);
+
+    // check the content y has not jumped up and down
+    QCOMPARE(listview->contentY(), 0.0);
+    QSignalSpy spy(listview, SIGNAL(contentYChanged()));
+    QTest::qWait(300);
+    QCOMPARE(spy.count(), 0);
+
+    for (int i = 1; i < model.count(); ++i) {
+        item = findItem<QQuickItem>(contentItem, "wrapper", i);
+        QVERIFY(item != 0);
+        QTRY_COMPARE(item->y(), (i-1)*20.0);
+    }
+
+    delete testObject;
+    delete canvas;
+}
+
+void tst_QQuickListView::QTBUG_16037()
+{
+    QQuickView *canvas = createView();
+    canvas->show();
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("qtbug16037.qml")));
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "listview");
+    QTRY_VERIFY(listview != 0);
+
+    QVERIFY(listview->contentHeight() <= 0.0);
+
+    QMetaObject::invokeMethod(canvas->rootObject(), "setModel");
+
+    QTRY_COMPARE(listview->contentHeight(), 80.0);
+
+    delete canvas;
+}
+
+void tst_QQuickListView::indexAt()
+{
+    QQuickView *canvas = createView();
+
+    TestModel 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();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QCOMPARE(listview->indexAt(0,0), 0);
+    QCOMPARE(listview->indexAt(0,19), 0);
+    QCOMPARE(listview->indexAt(239,19), 0);
+    QCOMPARE(listview->indexAt(0,20), 1);
+    QCOMPARE(listview->indexAt(240,20), -1);
+
+    delete canvas;
+    delete testObject;
+}
+
+void tst_QQuickListView::incrementalModel()
+{
+    QQuickView *canvas = createView();
+
+    IncrementalModel model;
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaylist.qml")));
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QTRY_COMPARE(listview->count(), 20);
+
+    listview->positionViewAtIndex(10, QQuickListView::Beginning);
+
+    QTRY_COMPARE(listview->count(), 25);
+
+    delete canvas;
+}
+
+void tst_QQuickListView::onAdd()
+{
+    QFETCH(int, initialItemCount);
+    QFETCH(int, itemsToAdd);
+
+    const int delegateHeight = 10;
+    TestModel2 model;
+
+    // these initial items should not trigger ListView.onAdd
+    for (int i=0; i<initialItemCount; i++)
+        model.addItem("dummy value", "dummy value");
+
+    QQuickView *canvas = createView();
+    canvas->setGeometry(0,0,200, delegateHeight * (initialItemCount + itemsToAdd));
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+    ctxt->setContextProperty("delegateHeight", delegateHeight);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml")));
+
+    QObject *object = canvas->rootObject();
+    object->setProperty("width", canvas->width());
+    object->setProperty("height", canvas->height());
+    qApp->processEvents();
+
+    QList<QPair<QString, QString> > items;
+    for (int i=0; i<itemsToAdd; i++)
+        items << qMakePair(QString("value %1").arg(i), QString::number(i));
+    model.addItems(items);
+    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
+
+    QVariantList result = object->property("addedDelegates").toList();
+    QCOMPARE(result.count(), items.count());
+    for (int i=0; i<items.count(); i++)
+        QCOMPARE(result[i].toString(), items[i].first);
+
+    delete canvas;
+}
+
+void tst_QQuickListView::onAdd_data()
+{
+    QTest::addColumn<int>("initialItemCount");
+    QTest::addColumn<int>("itemsToAdd");
+
+    QTest::newRow("0, add 1") << 0 << 1;
+    QTest::newRow("0, add 2") << 0 << 2;
+    QTest::newRow("0, add 10") << 0 << 10;
+
+    QTest::newRow("1, add 1") << 1 << 1;
+    QTest::newRow("1, add 2") << 1 << 2;
+    QTest::newRow("1, add 10") << 1 << 10;
+
+    QTest::newRow("5, add 1") << 5 << 1;
+    QTest::newRow("5, add 2") << 5 << 2;
+    QTest::newRow("5, add 10") << 5 << 10;
+}
+
+void tst_QQuickListView::onRemove()
+{
+    QFETCH(int, initialItemCount);
+    QFETCH(int, indexToRemove);
+    QFETCH(int, removeCount);
+
+    const int delegateHeight = 10;
+    TestModel2 model;
+    for (int i=0; i<initialItemCount; i++)
+        model.addItem(QString("value %1").arg(i), "dummy value");
+
+    QQuickView *canvas = createView();
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+    ctxt->setContextProperty("delegateHeight", delegateHeight);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml")));
+    QObject *object = canvas->rootObject();
+
+    model.removeItems(indexToRemove, removeCount);
+    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
+
+    QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount));
+
+    delete canvas;
+}
+
+void tst_QQuickListView::onRemove_data()
+{
+    QTest::addColumn<int>("initialItemCount");
+    QTest::addColumn<int>("indexToRemove");
+    QTest::addColumn<int>("removeCount");
+
+    QTest::newRow("remove first") << 1 << 0 << 1;
+    QTest::newRow("two items, remove first") << 2 << 0 << 1;
+    QTest::newRow("two items, remove last") << 2 << 1 << 1;
+    QTest::newRow("two items, remove all") << 2 << 0 << 2;
+
+    QTest::newRow("four items, remove first") << 4 << 0 << 1;
+    QTest::newRow("four items, remove 0-2") << 4 << 0 << 2;
+    QTest::newRow("four items, remove 1-3") << 4 << 1 << 2;
+    QTest::newRow("four items, remove 2-4") << 4 << 2 << 2;
+    QTest::newRow("four items, remove last") << 4 << 3 << 1;
+    QTest::newRow("four items, remove all") << 4 << 0 << 4;
+
+    QTest::newRow("ten items, remove 1-8") << 10 << 0 << 8;
+    QTest::newRow("ten items, remove 2-7") << 10 << 2 << 5;
+    QTest::newRow("ten items, remove 4-10") << 10 << 4 << 6;
+}
+
+void tst_QQuickListView::rightToLeft()
+{
+    QQuickView *canvas = createView();
+    canvas->setGeometry(0,0,640,320);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("rightToLeft.qml")));
+    qApp->processEvents();
+
+    QVERIFY(canvas->rootObject() != 0);
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "view");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QTRY_VERIFY(contentItem != 0);
+
+    QQuickVisualItemModel *model = canvas->rootObject()->findChild<QQuickVisualItemModel*>("itemModel");
+    QTRY_VERIFY(model != 0);
+
+    QTRY_VERIFY(model->count() == 3);
+    QTRY_COMPARE(listview->currentIndex(), 0);
+
+    // initial position at first item, right edge aligned
+    QCOMPARE(listview->contentX(), -640.);
+
+    QQuickItem *item = findItem<QQuickItem>(contentItem, "item1");
+    QTRY_VERIFY(item);
+    QTRY_COMPARE(item->x(), -100.0);
+    QCOMPARE(item->height(), listview->height());
+
+    QQuickText *text = findItem<QQuickText>(contentItem, "text1");
+    QTRY_VERIFY(text);
+    QTRY_COMPARE(text->text(), QLatin1String("index: 0"));
+
+    listview->setCurrentIndex(2);
+
+    item = findItem<QQuickItem>(contentItem, "item3");
+    QTRY_VERIFY(item);
+    QTRY_COMPARE(item->x(), -540.0);
+
+    text = findItem<QQuickText>(contentItem, "text3");
+    QTRY_VERIFY(text);
+    QTRY_COMPARE(text->text(), QLatin1String("index: 2"));
+
+    QCOMPARE(listview->contentX(), -640.);
+
+    // Ensure resizing maintains position relative to right edge
+    qobject_cast<QQuickItem*>(canvas->rootObject())->setWidth(600);
+    QTRY_COMPARE(listview->contentX(), -600.);
+
+    delete canvas;
+}
+
+void tst_QQuickListView::test_mirroring()
+{
+    QQuickView *canvasA = createView();
+    canvasA->setSource(QUrl::fromLocalFile(TESTDATA("rightToLeft.qml")));
+    QQuickListView *listviewA = findItem<QQuickListView>(canvasA->rootObject(), "view");
+    QTRY_VERIFY(listviewA != 0);
+
+    QQuickView *canvasB = createView();
+    canvasB->setSource(QUrl::fromLocalFile(TESTDATA("rightToLeft.qml")));
+    QQuickListView *listviewB = findItem<QQuickListView>(canvasB->rootObject(), "view");
+    QTRY_VERIFY(listviewA != 0);
+    qApp->processEvents();
+
+    QList<QString> objectNames;
+    objectNames << "item1" << "item2"; // << "item3"
+
+    listviewA->setProperty("layoutDirection", Qt::LeftToRight);
+    listviewB->setProperty("layoutDirection", Qt::RightToLeft);
+    QCOMPARE(listviewA->layoutDirection(), listviewA->effectiveLayoutDirection());
+
+    // LTR != RTL
+    foreach (const QString objectName, objectNames)
+        QVERIFY(findItem<QQuickItem>(listviewA, objectName)->x() != findItem<QQuickItem>(listviewB, objectName)->x());
+
+    listviewA->setProperty("layoutDirection", Qt::LeftToRight);
+    listviewB->setProperty("layoutDirection", Qt::LeftToRight);
+
+    // LTR == LTR
+    foreach (const QString objectName, objectNames)
+        QCOMPARE(findItem<QQuickItem>(listviewA, objectName)->x(), findItem<QQuickItem>(listviewB, objectName)->x());
+
+    QVERIFY(listviewB->layoutDirection() == listviewB->effectiveLayoutDirection());
+    QQuickItemPrivate::get(listviewB)->setLayoutMirror(true);
+    QVERIFY(listviewB->layoutDirection() != listviewB->effectiveLayoutDirection());
+
+    // LTR != LTR+mirror
+    foreach (const QString objectName, objectNames)
+        QVERIFY(findItem<QQuickItem>(listviewA, objectName)->x() != findItem<QQuickItem>(listviewB, objectName)->x());
+
+    listviewA->setProperty("layoutDirection", Qt::RightToLeft);
+
+    // RTL == LTR+mirror
+    foreach (const QString objectName, objectNames)
+        QCOMPARE(findItem<QQuickItem>(listviewA, objectName)->x(), findItem<QQuickItem>(listviewB, objectName)->x());
+
+    listviewB->setProperty("layoutDirection", Qt::RightToLeft);
+
+    // RTL != RTL+mirror
+    foreach (const QString objectName, objectNames)
+        QVERIFY(findItem<QQuickItem>(listviewA, objectName)->x() != findItem<QQuickItem>(listviewB, objectName)->x());
+
+    listviewA->setProperty("layoutDirection", Qt::LeftToRight);
+
+    // LTR == RTL+mirror
+    foreach (const QString objectName, objectNames)
+        QCOMPARE(findItem<QQuickItem>(listviewA, objectName)->x(), findItem<QQuickItem>(listviewB, objectName)->x());
+
+    delete canvasA;
+    delete canvasB;
+}
+
+void tst_QQuickListView::margins()
+{
+    QQuickView *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();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    QQuickItem *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_QQuickListView::snapToItem_data()
+{
+    QTest::addColumn<QQuickListView::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") << QQuickListView::Vertical << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
+        << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 1200.0 << 0.0;
+
+    QTest::newRow("horizontal, left to right") << QQuickListView::Horizontal << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
+        << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 1200.0 << 0.0;
+
+    QTest::newRow("horizontal, right to left") << QQuickListView::Horizontal << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange)
+        << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -1200.0 - 240.0 << -240.0;
+
+    QTest::newRow("vertical, left to right, enforce range") << QQuickListView::Vertical << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
+        << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 1340.0 << -20.0;
+
+    QTest::newRow("horizontal, left to right, enforce range") << QQuickListView::Horizontal << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
+        << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 1340.0 << -20.0;
+
+    QTest::newRow("horizontal, right to left, enforce range") << QQuickListView::Horizontal << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange)
+        << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -1200.0 - 240.0 - 140.0 << -220.0;
+}
+
+void tst_QQuickListView::snapToItem()
+{
+    QFETCH(QQuickListView::Orientation, orientation);
+    QFETCH(Qt::LayoutDirection, layoutDirection);
+    QFETCH(int, highlightRangeMode);
+    QFETCH(QPoint, flickStart);
+    QFETCH(QPoint, flickEnd);
+    QFETCH(qreal, snapAlignment);
+    QFETCH(qreal, endExtent);
+    QFETCH(qreal, startExtent);
+
+    QQuickView *canvas = createView();
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("snapToItem.qml")));
+    canvas->show();
+    qApp->processEvents();
+
+    QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    listview->setOrientation(orientation);
+    listview->setLayoutDirection(layoutDirection);
+    listview->setHighlightRangeMode(QQuickItemView::HighlightRangeMode(highlightRangeMode));
+
+    QQuickItem *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 == QQuickListView::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 == QQuickListView::Vertical
+           ? !listview->isAtYEnd()
+           : layoutDirection == Qt::LeftToRight ? !listview->isAtXEnd() : !listview->isAtXBeginning());
+
+    if (orientation == QQuickListView::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 == QQuickListView::Vertical
+           ? !listview->isAtYBeginning()
+           : layoutDirection == Qt::LeftToRight ? !listview->isAtXBeginning() : !listview->isAtXEnd());
+
+    if (orientation == QQuickListView::Vertical)
+        QCOMPARE(listview->contentY(), startExtent);
+    else
+        QCOMPARE(listview->contentX(), startExtent);
+
+    delete canvas;
+}
+
+void tst_QQuickListView::qListModelInterface_items()
+{
+    items<TestModel>();
+}
+
+void tst_QQuickListView::qAbstractItemModel_items()
+{
+    items<TestModel2>();
+}
+
+void tst_QQuickListView::qListModelInterface_changed()
+{
+    changed<TestModel>();
+}
+
+void tst_QQuickListView::qAbstractItemModel_changed()
+{
+    changed<TestModel2>();
+}
+
+void tst_QQuickListView::qListModelInterface_inserted()
+{
+    inserted<TestModel>();
+}
+
+void tst_QQuickListView::qListModelInterface_inserted_more()
+{
+    inserted_more<TestModel>();
+}
+
+void tst_QQuickListView::qListModelInterface_inserted_more_data()
+{
+    inserted_more_data();
+}
+
+void tst_QQuickListView::qAbstractItemModel_inserted()
+{
+    inserted<TestModel2>();
+}
+
+void tst_QQuickListView::qAbstractItemModel_inserted_more()
+{
+    inserted_more<TestModel2>();
+}
+
+void tst_QQuickListView::qAbstractItemModel_inserted_more_data()
+{
+    inserted_more_data();
+}
+
+void tst_QQuickListView::qListModelInterface_removed()
+{
+    removed<TestModel>(false);
+    removed<TestModel>(true);
+}
+
+void tst_QQuickListView::qAbstractItemModel_removed()
+{
+    removed<TestModel2>(false);
+    removed<TestModel2>(true);
+}
+
+void tst_QQuickListView::qListModelInterface_moved()
+{
+    moved<TestModel>();
+}
+
+void tst_QQuickListView::qListModelInterface_moved_data()
+{
+    moved_data();
+}
+
+void tst_QQuickListView::qAbstractItemModel_moved()
+{
+    moved<TestModel2>();
+}
+
+void tst_QQuickListView::qAbstractItemModel_moved_data()
+{
+    moved_data();
+}
+
+void tst_QQuickListView::qListModelInterface_clear()
+{
+    clear<TestModel>();
+}
+
+void tst_QQuickListView::qAbstractItemModel_clear()
+{
+    clear<TestModel2>();
+}
+
+void tst_QQuickListView::creationContext()
+{
+    QQuickView canvas;
+    canvas.setGeometry(0,0,240,320);
+    canvas.setSource(QUrl::fromLocalFile(TESTDATA("creationContext.qml")));
+    qApp->processEvents();
+
+    QQuickItem *rootItem = qobject_cast<QQuickItem *>(canvas.rootObject());
+    QVERIFY(rootItem);
+    QVERIFY(rootItem->property("count").toInt() > 0);
+
+    QQuickItem *item;
+    QVERIFY(item = rootItem->findChild<QQuickItem *>("listItem"));
+    QCOMPARE(item->property("text").toString(), QString("Hello!"));
+    QVERIFY(item = rootItem->findChild<QQuickItem *>("header"));
+    QCOMPARE(item->property("text").toString(), QString("Hello!"));
+    QVERIFY(item = rootItem->findChild<QQuickItem *>("footer"));
+    QCOMPARE(item->property("text").toString(), QString("Hello!"));
+    QVERIFY(item = rootItem->findChild<QQuickItem *>("section"));
+    QCOMPARE(item->property("text").toString(), QString("Hello!"));
+}
+
+void tst_QQuickListView::QTBUG_21742()
+{
+    QQuickView canvas;
+    canvas.setGeometry(0,0,200,200);
+    canvas.setSource(QUrl::fromLocalFile(TESTDATA("qtbug-21742.qml")));
+    qApp->processEvents();
+
+    QQuickItem *rootItem = qobject_cast<QQuickItem *>(canvas.rootObject());
+    QVERIFY(rootItem);
+    QCOMPARE(rootItem->property("count").toInt(), 1);
+}
+
+QQuickView *tst_QQuickListView::createView()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setGeometry(0,0,240,320);
+
+    return canvas;
+}
+
+void tst_QQuickListView::flick(QQuickView *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);
+}
+
+
+QQuickItem *tst_QQuickListView::findVisibleChild(QQuickItem *parent, const QString &objectName)
+{
+    QQuickItem *item = 0;
+    QList<QQuickItem*> items = parent->findChildren<QQuickItem*>(objectName);
+    for (int i = 0; i < items.count(); ++i) {
+        if (items.at(i)->isVisible()) {
+            item = items.at(i);
+            break;
+        }
+    }
+    return item;
+}
+/*
+   Find an item with the specified objectName.  If index is supplied then the
+   item must also evaluate the {index} expression equal to index
+*/
+template<typename T>
+T *tst_QQuickListView::findItem(QQuickItem *parent, const QString &objectName, int index)
+{
+    const QMetaObject &mo = T::staticMetaObject;
+    //qDebug() << parent->childItems().count() << "children";
+    for (int i = 0; i < parent->childItems().count(); ++i) {
+        QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
+        if (!item)
+            continue;
+        //qDebug() << "try" << item;
+        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
+            if (index != -1) {
+                QDeclarativeExpression e(qmlContext(item), item, "index");
+                if (e.evaluate().toInt() == index)
+                    return static_cast<T*>(item);
+            } else {
+                return static_cast<T*>(item);
+            }
+        }
+        item = findItem<T>(item, objectName, index);
+        if (item)
+            return static_cast<T*>(item);
+    }
+
+    return 0;
+}
+
+template<typename T>
+QList<T*> tst_QQuickListView::findItems(QQuickItem *parent, const QString &objectName)
+{
+    QList<T*> items;
+    const QMetaObject &mo = T::staticMetaObject;
+    //qDebug() << parent->childItems().count() << "children";
+    for (int i = 0; i < parent->childItems().count(); ++i) {
+        QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
+        if (!item || !item->isVisible())
+            continue;
+        //qDebug() << "try" << item;
+        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName))
+            items.append(static_cast<T*>(item));
+        items += findItems<T>(item, objectName);
+    }
+
+    return items;
+}
+
+void tst_QQuickListView::dumpTree(QQuickItem *parent, int depth)
+{
+    static QString padding("                       ");
+    for (int i = 0; i < parent->childItems().count(); ++i) {
+        QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
+        if (!item)
+            continue;
+        qDebug() << padding.left(depth*2) << item;
+        dumpTree(item, depth+1);
+    }
+}
+
+QTEST_MAIN(tst_QQuickListView)
+
+#include "tst_qquicklistview.moc"
+
diff --git a/tests/auto/declarative/qquickloader/qquickloader.pro b/tests/auto/declarative/qquickloader/qquickloader.pro
new file mode 100644 (file)
index 0000000..9ccecce
--- /dev/null
@@ -0,0 +1,16 @@
+CONFIG += testcase
+TARGET = tst_qquickloader
+macx:CONFIG -= app_bundle
+
+INCLUDEPATH += ../shared/
+HEADERS += ../shared/testhttpserver.h
+SOURCES += tst_qquickloader.cpp \
+           ../shared/testhttpserver.cpp
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qquickloader/tst_qquickloader.cpp b/tests/auto/declarative/qquickloader/tst_qquickloader.cpp
new file mode 100644 (file)
index 0000000..0096bc3
--- /dev/null
@@ -0,0 +1,950 @@
+/****************************************************************************
+**
+** 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>
+
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qdeclarativeincubator.h>
+#include <private/qquickloader_p.h>
+#include "testhttpserver.h"
+#include "../shared/util.h"
+
+#define SERVER_PORT 14450
+
+inline QUrl TEST_FILE(const QString &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_QQuickLoader : public QObject
+
+{
+    Q_OBJECT
+public:
+    tst_QQuickLoader();
+
+private slots:
+    void sourceOrComponent();
+    void sourceOrComponent_data();
+    void clear();
+    void urlToComponent();
+    void componentToUrl();
+    void anchoredLoader();
+    void sizeLoaderToItem();
+    void sizeItemToLoader();
+    void noResize();
+    void networkRequestUrl();
+    void failNetworkRequest();
+//    void networkComponent();
+    void active();
+    void initialPropertyValues_data();
+    void initialPropertyValues();
+    void initialPropertyValuesBinding();
+    void initialPropertyValuesError_data();
+    void initialPropertyValuesError();
+
+    void deleteComponentCrash();
+    void nonItem();
+    void vmeErrors();
+    void creationContext();
+    void QTBUG_16928();
+    void implicitSize();
+    void QTBUG_17114();
+    void asynchronous_data();
+    void asynchronous();
+    void asynchronous_clear();
+
+private:
+    QDeclarativeEngine engine;
+};
+
+
+tst_QQuickLoader::tst_QQuickLoader()
+{
+}
+
+void tst_QQuickLoader::sourceOrComponent()
+{
+    QFETCH(QString, sourceOrComponent);
+    QFETCH(QString, sourceDefinition);
+    QFETCH(QUrl, sourceUrl);
+    QFETCH(QString, errorString);
+
+    bool error = !errorString.isEmpty();
+    if (error)
+        QTest::ignoreMessage(QtWarningMsg, errorString.toUtf8().constData());
+
+    QDeclarativeComponent component(&engine);
+    component.setData(QByteArray(
+            "import QtQuick 2.0\n"
+            "Loader {\n"
+            "   property int onItemChangedCount: 0\n"
+            "   property int onSourceChangedCount: 0\n"
+            "   property int onSourceComponentChangedCount: 0\n"
+            "   property int onStatusChangedCount: 0\n"
+            "   property int onProgressChangedCount: 0\n"
+            "   property int onLoadedCount: 0\n")
+            + sourceDefinition.toUtf8()
+            + QByteArray(
+            "   onItemChanged: onItemChangedCount += 1\n"
+            "   onSourceChanged: onSourceChangedCount += 1\n"
+            "   onSourceComponentChanged: onSourceComponentChangedCount += 1\n"
+            "   onStatusChanged: onStatusChangedCount += 1\n"
+            "   onProgressChanged: onProgressChangedCount += 1\n"
+            "   onLoaded: onLoadedCount += 1\n"
+            "}")
+        , TEST_FILE(""));
+
+    QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+    QVERIFY(loader != 0);
+    QCOMPARE(loader->item() == 0, error);
+    QCOMPARE(loader->source(), sourceUrl);
+    QCOMPARE(loader->progress(), 1.0);
+
+    QCOMPARE(loader->status(), error ? QQuickLoader::Error : QQuickLoader::Ready);
+    QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), error ? 0: 1);
+
+    if (!error) {
+        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") {
+        QCOMPARE(loader->property("onSourceComponentChangedCount").toInt(), 1);
+        QCOMPARE(loader->property("onSourceChangedCount").toInt(), 0);
+    } else {
+        QCOMPARE(loader->property("onSourceComponentChangedCount").toInt(), 0);
+        QCOMPARE(loader->property("onSourceChangedCount").toInt(), 1);
+    }
+    QCOMPARE(loader->property("onStatusChangedCount").toInt(), 1);
+    QCOMPARE(loader->property("onProgressChangedCount").toInt(), 1);
+
+    QCOMPARE(loader->property("onItemChangedCount").toInt(), error ? 0 : 1);
+    QCOMPARE(loader->property("onLoadedCount").toInt(), error ? 0 : 1);
+
+    delete loader;
+}
+
+void tst_QQuickLoader::sourceOrComponent_data()
+{
+    QTest::addColumn<QString>("sourceOrComponent");
+    QTest::addColumn<QString>("sourceDefinition");
+    QTest::addColumn<QUrl>("sourceUrl");
+    QTest::addColumn<QString>("errorString");
+
+    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(TESTDATA("IDontExist.qml"))
+            << QString(QUrl::fromLocalFile(TESTDATA("IDontExist.qml")).toString() + ": File not found");
+}
+
+void tst_QQuickLoader::clear()
+{
+    {
+        QDeclarativeComponent component(&engine);
+        component.setData(QByteArray(
+                    "import QtQuick 2.0\n"
+                    " Loader { id: loader\n"
+                    "  source: 'Rect120x60.qml'\n"
+                    "  Timer { interval: 200; running: true; onTriggered: loader.source = '' }\n"
+                    " }")
+                , TEST_FILE(""));
+        QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+        QVERIFY(loader != 0);
+        QVERIFY(loader->item());
+        QCOMPARE(loader->progress(), 1.0);
+        QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
+
+        QTRY_VERIFY(loader->item() == 0);
+        QCOMPARE(loader->progress(), 0.0);
+        QCOMPARE(loader->status(), QQuickLoader::Null);
+        QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 0);
+
+        delete loader;
+    }
+    {
+        QDeclarativeComponent component(&engine, TEST_FILE("/SetSourceComponent.qml"));
+        QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+        QVERIFY(item);
+
+        QQuickLoader *loader = qobject_cast<QQuickLoader*>(item->QQuickItem::childItems().at(0));
+        QVERIFY(loader);
+        QVERIFY(loader->item());
+        QCOMPARE(loader->progress(), 1.0);
+        QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
+
+        loader->setSourceComponent(0);
+
+        QVERIFY(loader->item() == 0);
+        QCOMPARE(loader->progress(), 0.0);
+        QCOMPARE(loader->status(), QQuickLoader::Null);
+        QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 0);
+
+        delete item;
+    }
+    {
+        QDeclarativeComponent component(&engine, TEST_FILE("/SetSourceComponent.qml"));
+        QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+        QVERIFY(item);
+
+        QQuickLoader *loader = qobject_cast<QQuickLoader*>(item->QQuickItem::childItems().at(0));
+        QVERIFY(loader);
+        QVERIFY(loader->item());
+        QCOMPARE(loader->progress(), 1.0);
+        QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
+
+        QMetaObject::invokeMethod(item, "clear");
+
+        QVERIFY(loader->item() == 0);
+        QCOMPARE(loader->progress(), 0.0);
+        QCOMPARE(loader->status(), QQuickLoader::Null);
+        QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 0);
+
+        delete item;
+    }
+}
+
+void tst_QQuickLoader::urlToComponent()
+{
+    QDeclarativeComponent component(&engine);
+    component.setData(QByteArray("import QtQuick 2.0\n"
+                "Loader {\n"
+                " id: loader\n"
+                " Component { id: myComp; Rectangle { width: 10; height: 10 } }\n"
+                " source: \"Rect120x60.qml\"\n"
+                " Timer { interval: 100; running: true; onTriggered: loader.sourceComponent = myComp }\n"
+                "}" )
+            , TEST_FILE(""));
+    QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+    QTest::qWait(200);
+    QTRY_VERIFY(loader != 0);
+    QVERIFY(loader->item());
+    QCOMPARE(loader->progress(), 1.0);
+    QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
+    QCOMPARE(loader->width(), 10.0);
+    QCOMPARE(loader->height(), 10.0);
+
+    delete loader;
+}
+
+void tst_QQuickLoader::componentToUrl()
+{
+    QDeclarativeComponent component(&engine, TEST_FILE("/SetSourceComponent.qml"));
+    QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+
+    QQuickLoader *loader = qobject_cast<QQuickLoader*>(item->QQuickItem::childItems().at(0));
+    QVERIFY(loader);
+    QVERIFY(loader->item());
+    QCOMPARE(loader->progress(), 1.0);
+    QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
+
+    loader->setSource(TEST_FILE("/Rect120x60.qml"));
+    QVERIFY(loader->item());
+    QCOMPARE(loader->progress(), 1.0);
+    QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
+    QCOMPARE(loader->width(), 120.0);
+    QCOMPARE(loader->height(), 60.0);
+
+    delete item;
+}
+
+void tst_QQuickLoader::anchoredLoader()
+{
+    QDeclarativeComponent component(&engine, TEST_FILE("/AnchoredLoader.qml"));
+    QQuickItem *rootItem = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(rootItem != 0);
+    QQuickItem *loader = rootItem->findChild<QQuickItem*>("loader");
+    QQuickItem *sourceElement = rootItem->findChild<QQuickItem*>("sourceElement");
+
+    QVERIFY(loader != 0);
+    QVERIFY(sourceElement != 0);
+
+    QCOMPARE(rootItem->width(), 300.0);
+    QCOMPARE(rootItem->height(), 200.0);
+
+    QCOMPARE(loader->width(), 300.0);
+    QCOMPARE(loader->height(), 200.0);
+
+    QCOMPARE(sourceElement->width(), 300.0);
+    QCOMPARE(sourceElement->height(), 200.0);
+}
+
+void tst_QQuickLoader::sizeLoaderToItem()
+{
+    QDeclarativeComponent component(&engine, TEST_FILE("/SizeToItem.qml"));
+    QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+    QVERIFY(loader != 0);
+    QCOMPARE(loader->width(), 120.0);
+    QCOMPARE(loader->height(), 60.0);
+
+    // Check resize
+    QQuickItem *rect = qobject_cast<QQuickItem*>(loader->item());
+    QVERIFY(rect);
+    rect->setWidth(150);
+    rect->setHeight(45);
+    QCOMPARE(loader->width(), 150.0);
+    QCOMPARE(loader->height(), 45.0);
+
+    // Check explicit width
+    loader->setWidth(200.0);
+    QCOMPARE(loader->width(), 200.0);
+    QCOMPARE(rect->width(), 200.0);
+    rect->setWidth(100.0); // when rect changes ...
+    QCOMPARE(rect->width(), 100.0); // ... it changes
+    QCOMPARE(loader->width(), 200.0); // ... but loader stays the same
+
+    // Check explicit height
+    loader->setHeight(200.0);
+    QCOMPARE(loader->height(), 200.0);
+    QCOMPARE(rect->height(), 200.0);
+    rect->setHeight(100.0); // when rect changes ...
+    QCOMPARE(rect->height(), 100.0); // ... it changes
+    QCOMPARE(loader->height(), 200.0); // ... but loader stays the same
+
+    // Switch mode
+    loader->setWidth(180);
+    loader->setHeight(30);
+    QCOMPARE(rect->width(), 180.0);
+    QCOMPARE(rect->height(), 30.0);
+
+    delete loader;
+}
+
+void tst_QQuickLoader::sizeItemToLoader()
+{
+    QDeclarativeComponent component(&engine, TEST_FILE("/SizeToLoader.qml"));
+    QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+    QVERIFY(loader != 0);
+    QCOMPARE(loader->width(), 200.0);
+    QCOMPARE(loader->height(), 80.0);
+
+    QQuickItem *rect = qobject_cast<QQuickItem*>(loader->item());
+    QVERIFY(rect);
+    QCOMPARE(rect->width(), 200.0);
+    QCOMPARE(rect->height(), 80.0);
+
+    // Check resize
+    loader->setWidth(180);
+    loader->setHeight(30);
+    QCOMPARE(rect->width(), 180.0);
+    QCOMPARE(rect->height(), 30.0);
+
+    // Switch mode
+    loader->resetWidth(); // reset explicit size
+    loader->resetHeight();
+    rect->setWidth(160);
+    rect->setHeight(45);
+    QCOMPARE(loader->width(), 160.0);
+    QCOMPARE(loader->height(), 45.0);
+
+    delete loader;
+}
+
+void tst_QQuickLoader::noResize()
+{
+    QDeclarativeComponent component(&engine, TEST_FILE("/NoResize.qml"));
+    QQuickItem* item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item != 0);
+    QCOMPARE(item->width(), 200.0);
+    QCOMPARE(item->height(), 80.0);
+
+    delete item;
+}
+
+void tst_QQuickLoader::networkRequestUrl()
+{
+    TestHTTPServer server(SERVER_PORT);
+    QVERIFY(server.isValid());
+    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(TESTDATA("../dummy.qml")));
+    if (component.isError())
+        qDebug() << component.errors();
+    QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+    QVERIFY(loader != 0);
+
+    QTRY_VERIFY(loader->status() == QQuickLoader::Ready);
+
+    QVERIFY(loader->item());
+    QCOMPARE(loader->progress(), 1.0);
+    QCOMPARE(loader->property("signalCount").toInt(), 1);
+    QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
+
+    delete loader;
+}
+
+/* XXX Component waits until all dependencies are loaded.  Is this actually possible?
+void tst_QQuickLoader::networkComponent()
+{
+    TestHTTPServer server(SERVER_PORT);
+    QVERIFY(server.isValid());
+    server.serveDirectory("slowdata", TestHTTPServer::Delay);
+
+    QDeclarativeComponent component(&engine);
+    component.setData(QByteArray(
+                "import QtQuick 2.0\n"
+                "import \"http://127.0.0.1:14450/\" as NW\n"
+                "Item {\n"
+                " Component { id: comp; NW.SlowRect {} }\n"
+                " Loader { sourceComponent: comp } }")
+            , TEST_FILE(""));
+
+    QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+
+    QQuickLoader *loader = qobject_cast<QQuickLoader*>(item->QQuickItem::children().at(1));
+    QVERIFY(loader);
+    QTRY_VERIFY(loader->status() == QQuickLoader::Ready);
+
+    QVERIFY(loader->item());
+    QCOMPARE(loader->progress(), 1.0);
+    QCOMPARE(loader->status(), QQuickLoader::Ready);
+    QCOMPARE(static_cast<QQuickItem*>(loader)->children().count(), 1);
+
+    delete loader;
+}
+*/
+
+void tst_QQuickLoader::failNetworkRequest()
+{
+    TestHTTPServer server(SERVER_PORT);
+    QVERIFY(server.isValid());
+    server.serveDirectory(TESTDATA(""));
+
+    QTest::ignoreMessage(QtWarningMsg, "http://127.0.0.1:14450/IDontExist.qml: File not found");
+
+    QDeclarativeComponent component(&engine);
+    component.setData(QByteArray("import QtQuick 2.0\nLoader { property int did_load: 123; source: \"http://127.0.0.1:14450/IDontExist.qml\"; onLoaded: did_load=456 }"), QUrl::fromLocalFile("http://127.0.0.1:14450/dummy.qml"));
+    QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+    QVERIFY(loader != 0);
+
+    QTRY_VERIFY(loader->status() == QQuickLoader::Error);
+
+    QVERIFY(loader->item() == 0);
+    QCOMPARE(loader->progress(), 0.0);
+    QCOMPARE(loader->property("did_load").toInt(), 123);
+    QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 0);
+
+    delete loader;
+}
+
+void tst_QQuickLoader::active()
+{
+    // check that the item isn't instantiated until active is set to true
+    {
+        QDeclarativeComponent component(&engine, TEST_FILE("active.1.qml"));
+        QObject *object = component.create();
+        QVERIFY(object != 0);
+        QQuickLoader *loader = object->findChild<QQuickLoader*>("loader");
+
+        QVERIFY(loader->active() == false); // set manually to false
+        QVERIFY(loader->item() == 0);
+        QMetaObject::invokeMethod(object, "doSetSourceComponent");
+        QVERIFY(loader->item() == 0);
+        QMetaObject::invokeMethod(object, "doSetSource");
+        QVERIFY(loader->item() == 0);
+        QMetaObject::invokeMethod(object, "doSetActive");
+        QVERIFY(loader->item() != 0);
+
+        delete object;
+    }
+
+    // check that the status is Null if active is set to false
+    {
+        QDeclarativeComponent component(&engine, TEST_FILE("active.2.qml"));
+        QObject *object = component.create();
+        QVERIFY(object != 0);
+        QQuickLoader *loader = object->findChild<QQuickLoader*>("loader");
+
+        QVERIFY(loader->active() == true); // active is true by default
+        QCOMPARE(loader->status(), QQuickLoader::Ready);
+        int currStatusChangedCount = loader->property("statusChangedCount").toInt();
+        QMetaObject::invokeMethod(object, "doSetInactive");
+        QCOMPARE(loader->status(), QQuickLoader::Null);
+        QCOMPARE(loader->property("statusChangedCount").toInt(), (currStatusChangedCount+1));
+
+        delete object;
+    }
+
+    // check that the source is not cleared if active is set to false
+    {
+        QDeclarativeComponent component(&engine, TEST_FILE("active.3.qml"));
+        QObject *object = component.create();
+        QVERIFY(object != 0);
+        QQuickLoader *loader = object->findChild<QQuickLoader*>("loader");
+
+        QVERIFY(loader->active() == true); // active is true by default
+        QVERIFY(!loader->source().isEmpty());
+        int currSourceChangedCount = loader->property("sourceChangedCount").toInt();
+        QMetaObject::invokeMethod(object, "doSetInactive");
+        QVERIFY(!loader->source().isEmpty());
+        QCOMPARE(loader->property("sourceChangedCount").toInt(), currSourceChangedCount);
+
+        delete object;
+    }
+
+    // check that the sourceComponent is not cleared if active is set to false
+    {
+        QDeclarativeComponent component(&engine, TEST_FILE("active.4.qml"));
+        QObject *object = component.create();
+        QVERIFY(object != 0);
+        QQuickLoader *loader = object->findChild<QQuickLoader*>("loader");
+
+        QVERIFY(loader->active() == true); // active is true by default
+        QVERIFY(loader->sourceComponent() != 0);
+        int currSourceComponentChangedCount = loader->property("sourceComponentChangedCount").toInt();
+        QMetaObject::invokeMethod(object, "doSetInactive");
+        QVERIFY(loader->sourceComponent() != 0);
+        QCOMPARE(loader->property("sourceComponentChangedCount").toInt(), currSourceComponentChangedCount);
+
+        delete object;
+    }
+
+    // check that the item is released if active is set to false
+    {
+        QDeclarativeComponent component(&engine, TEST_FILE("active.5.qml"));
+        QObject *object = component.create();
+        QVERIFY(object != 0);
+        QQuickLoader *loader = object->findChild<QQuickLoader*>("loader");
+
+        QVERIFY(loader->active() == true); // active is true by default
+        QVERIFY(loader->item() != 0);
+        int currItemChangedCount = loader->property("itemChangedCount").toInt();
+        QMetaObject::invokeMethod(object, "doSetInactive");
+        QVERIFY(loader->item() == 0);
+        QCOMPARE(loader->property("itemChangedCount").toInt(), (currItemChangedCount+1));
+
+        delete object;
+    }
+
+    // check that the activeChanged signal is emitted correctly
+    {
+        QDeclarativeComponent component(&engine, TEST_FILE("active.6.qml"));
+        QObject *object = component.create();
+        QVERIFY(object != 0);
+        QQuickLoader *loader = object->findChild<QQuickLoader*>("loader");
+
+        QVERIFY(loader->active() == true); // active is true by default
+        loader->setActive(true);           // no effect
+        QCOMPARE(loader->property("activeChangedCount").toInt(), 0);
+        loader->setActive(false);          // change signal should be emitted
+        QCOMPARE(loader->property("activeChangedCount").toInt(), 1);
+        loader->setActive(false);          // no effect
+        QCOMPARE(loader->property("activeChangedCount").toInt(), 1);
+        loader->setActive(true);           // change signal should be emitted
+        QCOMPARE(loader->property("activeChangedCount").toInt(), 2);
+        loader->setActive(false);          // change signal should be emitted
+        QCOMPARE(loader->property("activeChangedCount").toInt(), 3);
+        QMetaObject::invokeMethod(object, "doSetActive");
+        QCOMPARE(loader->property("activeChangedCount").toInt(), 4);
+        QMetaObject::invokeMethod(object, "doSetActive");
+        QCOMPARE(loader->property("activeChangedCount").toInt(), 4);
+        QMetaObject::invokeMethod(object, "doSetInactive");
+        QCOMPARE(loader->property("activeChangedCount").toInt(), 5);
+        loader->setActive(true);           // change signal should be emitted
+        QCOMPARE(loader->property("activeChangedCount").toInt(), 6);
+
+        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_QQuickLoader::initialPropertyValues_data()
+{
+    QTest::addColumn<QUrl>("qmlFile");
+    QTest::addColumn<QStringList>("expectedWarnings");
+    QTest::addColumn<QStringList>("propertyNames");
+    QTest::addColumn<QVariantList>("propertyValues");
+
+    QTest::newRow("source url with value set in onLoaded, initially active = true") << TEST_FILE("initialPropertyValues.1.qml")
+            << QStringList()
+            << (QStringList() << "initialValue" << "behaviorCount")
+            << (QVariantList() << 1 << 1);
+
+    QTest::newRow("set source with initial property values specified, active = true") << TEST_FILE("initialPropertyValues.2.qml")
+            << QStringList()
+            << (QStringList() << "initialValue" << "behaviorCount")
+            << (QVariantList() << 2 << 0);
+
+    QTest::newRow("set source with initial property values specified, active = false") << TEST_FILE("initialPropertyValues.3.qml")
+            << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("initialPropertyValues.3.qml").toLocalFile() + QLatin1String(":16: TypeError: Cannot read property 'canary' of null")))
+            << (QStringList())
+            << (QVariantList());
+
+    QTest::newRow("set source with initial property values specified, active = false, with active set true later") << TEST_FILE("initialPropertyValues.4.qml")
+            << QStringList()
+            << (QStringList() << "initialValue" << "behaviorCount")
+            << (QVariantList() << 4 << 0);
+
+    QTest::newRow("set source without initial property values specified, active = true") << TEST_FILE("initialPropertyValues.5.qml")
+            << QStringList()
+            << (QStringList() << "initialValue" << "behaviorCount")
+            << (QVariantList() << 0 << 0);
+
+    QTest::newRow("set source with initial property values specified with binding, active = true") << TEST_FILE("initialPropertyValues.6.qml")
+            << QStringList()
+            << (QStringList() << "initialValue" << "behaviorCount")
+            << (QVariantList() << 6 << 0);
+
+    QTest::newRow("ensure initial property value semantics mimic createObject") << TEST_FILE("initialPropertyValues.7.qml")
+            << 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_QQuickLoader::initialPropertyValues()
+{
+    QFETCH(QUrl, qmlFile);
+    QFETCH(QStringList, expectedWarnings);
+    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));
+
+    delete object;
+}
+
+void tst_QQuickLoader::initialPropertyValuesBinding()
+{
+    QDeclarativeComponent component(&engine, TEST_FILE("initialPropertyValues.binding.qml"));
+    QObject *object = component.create();
+    QVERIFY(object != 0);
+
+    QVERIFY(object->setProperty("bindable", QVariant(8)));
+    QCOMPARE(object->property("canaryValue").toInt(), 8);
+
+    delete object;
+}
+
+void tst_QQuickLoader::initialPropertyValuesError_data()
+{
+    QTest::addColumn<QUrl>("qmlFile");
+    QTest::addColumn<QStringList>("expectedWarnings");
+
+    QTest::newRow("invalid initial property values object") << TEST_FILE("initialPropertyValues.error.1.qml")
+            << (QStringList() << QString(TEST_FILE("initialPropertyValues.error.1.qml").toString() + ":6:5: QML Loader: setSource: value is not an object"));
+
+    QTest::newRow("nonexistent source url") << TEST_FILE("initialPropertyValues.error.2.qml")
+            << (QStringList() << QString(TEST_FILE("NonexistentSourceComponent.qml").toString() + ": File not found"));
+
+    QTest::newRow("invalid source url") << TEST_FILE("initialPropertyValues.error.3.qml")
+            << (QStringList() << QString(TEST_FILE("InvalidSourceComponent.qml").toString() + ":5:1: Syntax error"));
+
+    QTest::newRow("invalid initial property values object with invalid property access") << TEST_FILE("initialPropertyValues.error.4.qml")
+            << (QStringList() << QString(TEST_FILE("initialPropertyValues.error.4.qml").toString() + ":7:5: QML Loader: setSource: value is not an object")
+                              << QString(TEST_FILE("initialPropertyValues.error.4.qml").toString() + ":5: TypeError: Cannot read property 'canary' of null"));
+}
+
+void tst_QQuickLoader::initialPropertyValuesError()
+{
+    QFETCH(QUrl, qmlFile);
+    QFETCH(QStringList, expectedWarnings);
+
+    foreach (const QString &warning, expectedWarnings)
+        QTest::ignoreMessage(QtWarningMsg, warning.toUtf8().constData());
+
+    QDeclarativeComponent component(&engine, qmlFile);
+    QObject *object = component.create();
+    QVERIFY(object != 0);
+    QQuickLoader *loader = object->findChild<QQuickLoader*>("loader");
+    QVERIFY(loader != 0);
+    QVERIFY(loader->item() == 0);
+    delete object;
+}
+
+// QTBUG-9241
+void tst_QQuickLoader::deleteComponentCrash()
+{
+    QDeclarativeComponent component(&engine, TEST_FILE("crash.qml"));
+    QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+
+    item->metaObject()->invokeMethod(item, "setLoaderSource");
+
+    QQuickLoader *loader = qobject_cast<QQuickLoader*>(item->QQuickItem::childItems().at(0));
+    QVERIFY(loader);
+    QVERIFY(loader->item());
+    QCOMPARE(loader->item()->objectName(), QLatin1String("blue"));
+    QCOMPARE(loader->progress(), 1.0);
+    QCOMPARE(loader->status(), QQuickLoader::Ready);
+    qApp->processEvents(QEventLoop::DeferredDeletion);
+    QTRY_COMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
+    QVERIFY(loader->source() == QUrl::fromLocalFile(TESTDATA("BlueRect.qml")));
+
+    delete item;
+}
+
+void tst_QQuickLoader::nonItem()
+{
+    QDeclarativeComponent component(&engine, TEST_FILE("nonItem.qml"));
+    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());
+    QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+    QVERIFY(loader);
+    QVERIFY(loader->item() == 0);
+
+    delete loader;
+}
+
+void tst_QQuickLoader::vmeErrors()
+{
+    QDeclarativeComponent component(&engine, TEST_FILE("vmeErrors.qml"));
+    QString err = QUrl::fromLocalFile(TESTDATA("VmeError.qml")).toString() + ":6: Cannot assign object type QObject with no default method";
+    QTest::ignoreMessage(QtWarningMsg, err.toLatin1().constData());
+    QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+    QVERIFY(loader);
+    QVERIFY(loader->item() == 0);
+
+    delete loader;
+}
+
+// QTBUG-13481
+void tst_QQuickLoader::creationContext()
+{
+    QDeclarativeComponent component(&engine, TEST_FILE("creationContext.qml"));
+
+    QObject *o = component.create();
+    QVERIFY(o != 0);
+
+    QCOMPARE(o->property("test").toBool(), true);
+
+    delete o;
+}
+
+void tst_QQuickLoader::QTBUG_16928()
+{
+    QDeclarativeComponent component(&engine, TEST_FILE("QTBUG_16928.qml"));
+    QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+
+    QCOMPARE(item->width(), 250.);
+    QCOMPARE(item->height(), 250.);
+
+    delete item;
+}
+
+void tst_QQuickLoader::implicitSize()
+{
+    QDeclarativeComponent component(&engine, TEST_FILE("implicitSize.qml"));
+    QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+
+    QCOMPARE(item->width(), 150.);
+    QCOMPARE(item->height(), 150.);
+
+    QCOMPARE(item->property("implHeight").toReal(), 100.);
+    QCOMPARE(item->property("implWidth").toReal(), 100.);
+
+    delete item;
+}
+
+void tst_QQuickLoader::QTBUG_17114()
+{
+    QDeclarativeComponent component(&engine, TEST_FILE("QTBUG_17114.qml"));
+    QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+
+    QCOMPARE(item->property("loaderWidth").toReal(), 32.);
+    QCOMPARE(item->property("loaderHeight").toReal(), 32.);
+
+    delete item;
+}
+
+void tst_QQuickLoader::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_QQuickLoader::asynchronous()
+{
+    QFETCH(QUrl, qmlFile);
+    QFETCH(QStringList, expectedWarnings);
+
+    if (!engine.incubationController())
+        engine.setIncubationController(new PeriodicIncubationController);
+    QDeclarativeComponent component(&engine, TEST_FILE("asynchronous.qml"));
+    QQuickItem *root = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(root);
+
+    QQuickLoader *loader = root->findChild<QQuickLoader*>("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(), QQuickLoader::Loading);
+        QCOMPARE(engine.incubationController()->incubatingObjectCount(), 1);
+
+        QTRY_VERIFY(loader->item());
+        QCOMPARE(loader->progress(), 1.0);
+        QCOMPARE(loader->status(), QQuickLoader::Ready);
+    } else {
+        QCOMPARE(loader->progress(), 1.0);
+        QTRY_COMPARE(loader->status(), QQuickLoader::Error);
+    }
+
+    delete root;
+}
+
+void tst_QQuickLoader::asynchronous_clear()
+{
+    if (!engine.incubationController())
+        engine.setIncubationController(new PeriodicIncubationController);
+    QDeclarativeComponent component(&engine, TEST_FILE("asynchronous.qml"));
+    QQuickItem *root = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(root);
+
+    QQuickLoader *loader = root->findChild<QQuickLoader*>("loader");
+    QVERIFY(loader);
+
+    QVERIFY(!loader->item());
+    root->setProperty("comp", "BigComponent.qml");
+    QMetaObject::invokeMethod(root, "loadComponent");
+    QVERIFY(!loader->item());
+
+    QCOMPARE(loader->status(), QQuickLoader::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(), QQuickLoader::Null);
+    QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 0);
+
+    // check loading component
+    root->setProperty("comp", "Rect120x60.qml");
+    QMetaObject::invokeMethod(root, "loadComponent");
+    QVERIFY(!loader->item());
+
+    QCOMPARE(loader->status(), QQuickLoader::Loading);
+    QCOMPARE(engine.incubationController()->incubatingObjectCount(), 1);
+
+    QTRY_VERIFY(loader->item());
+    QCOMPARE(loader->progress(), 1.0);
+    QCOMPARE(loader->status(), QQuickLoader::Ready);
+    QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
+}
+
+
+QTEST_MAIN(tst_QQuickLoader)
+
+#include "tst_qquickloader.moc"
diff --git a/tests/auto/declarative/qquickmousearea/qquickmousearea.pro b/tests/auto/declarative/qquickmousearea/qquickmousearea.pro
new file mode 100644 (file)
index 0000000..3581a7b
--- /dev/null
@@ -0,0 +1,14 @@
+CONFIG += testcase
+TARGET = tst_qquickmousearea
+macx:CONFIG -= app_bundle
+
+HEADERS += ../shared/testhttpserver.h
+SOURCES += tst_qquickmousearea.cpp ../shared/testhttpserver.cpp
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+
+QT += core-private gui-private declarative-private network testlib
diff --git a/tests/auto/declarative/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/declarative/qquickmousearea/tst_qquickmousearea.cpp
new file mode 100644 (file)
index 0000000..af4dc61
--- /dev/null
@@ -0,0 +1,805 @@
+/****************************************************************************
+**
+** 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 <private/qquickmousearea_p.h>
+#include <private/qquickrectangle_p.h>
+#include <private/qquickflickable_p.h>
+#include <QtDeclarative/qquickview.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtOpenGL/QGLShaderProgram>
+#include "../shared/util.h"
+
+//#define OLDWAY
+
+class tst_QQuickMouseArea: public QObject
+{
+    Q_OBJECT
+private slots:
+    void initTestCase();
+    void cleanupTestCase();
+    void dragProperties();
+    void resetDrag();
+    void dragging();
+    void updateMouseAreaPosOnClick();
+    void updateMouseAreaPosOnResize();
+    void noOnClickedWithPressAndHold();
+    void onMousePressRejected();
+    void pressedCanceledOnWindowDeactivate();
+    void doubleClick();
+    void clickTwice();
+    void pressedOrdering();
+    void preventStealing();
+    void clickThrough();
+    void testQtQuick11Attributes();
+    void testQtQuick11Attributes_data();
+    void hoverPosition();
+    void hoverPropagation();
+
+private:
+    QQuickView *createView();
+};
+
+void tst_QQuickMouseArea::initTestCase()
+{
+
+}
+
+void tst_QQuickMouseArea::cleanupTestCase()
+{
+
+}
+
+void tst_QQuickMouseArea::dragProperties()
+{
+    QQuickView *canvas = createView();
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragproperties.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QVERIFY(canvas->rootObject() != 0);
+
+    QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
+    QQuickDrag *drag = mouseRegion->drag();
+    QVERIFY(mouseRegion != 0);
+    QVERIFY(drag != 0);
+
+    // target
+    QQuickItem *blackRect = canvas->rootObject()->findChild<QQuickItem*>("blackrect");
+    QVERIFY(blackRect != 0);
+    QVERIFY(blackRect == drag->target());
+    QQuickItem *rootItem = qobject_cast<QQuickItem*>(canvas->rootObject());
+    QVERIFY(rootItem != 0);
+    QSignalSpy targetSpy(drag, SIGNAL(targetChanged()));
+    drag->setTarget(rootItem);
+    QCOMPARE(targetSpy.count(),1);
+    drag->setTarget(rootItem);
+    QCOMPARE(targetSpy.count(),1);
+
+    // axis
+    QCOMPARE(drag->axis(), QQuickDrag::XandYAxis);
+    QSignalSpy axisSpy(drag, SIGNAL(axisChanged()));
+    drag->setAxis(QQuickDrag::XAxis);
+    QCOMPARE(drag->axis(), QQuickDrag::XAxis);
+    QCOMPARE(axisSpy.count(),1);
+    drag->setAxis(QQuickDrag::XAxis);
+    QCOMPARE(axisSpy.count(),1);
+
+    // minimum and maximum properties
+    QSignalSpy xminSpy(drag, SIGNAL(minimumXChanged()));
+    QSignalSpy xmaxSpy(drag, SIGNAL(maximumXChanged()));
+    QSignalSpy yminSpy(drag, SIGNAL(minimumYChanged()));
+    QSignalSpy ymaxSpy(drag, SIGNAL(maximumYChanged()));
+
+    QCOMPARE(drag->xmin(), 0.0);
+    QCOMPARE(drag->xmax(), rootItem->width()-blackRect->width());
+    QCOMPARE(drag->ymin(), 0.0);
+    QCOMPARE(drag->ymax(), rootItem->height()-blackRect->height());
+
+    drag->setXmin(10);
+    drag->setXmax(10);
+    drag->setYmin(10);
+    drag->setYmax(10);
+
+    QCOMPARE(drag->xmin(), 10.0);
+    QCOMPARE(drag->xmax(), 10.0);
+    QCOMPARE(drag->ymin(), 10.0);
+    QCOMPARE(drag->ymax(), 10.0);
+
+    QCOMPARE(xminSpy.count(),1);
+    QCOMPARE(xmaxSpy.count(),1);
+    QCOMPARE(yminSpy.count(),1);
+    QCOMPARE(ymaxSpy.count(),1);
+
+    drag->setXmin(10);
+    drag->setXmax(10);
+    drag->setYmin(10);
+    drag->setYmax(10);
+
+    QCOMPARE(xminSpy.count(),1);
+    QCOMPARE(xmaxSpy.count(),1);
+    QCOMPARE(yminSpy.count(),1);
+    QCOMPARE(ymaxSpy.count(),1);
+
+    // filterChildren
+    QSignalSpy filterChildrenSpy(drag, SIGNAL(filterChildrenChanged()));
+
+    drag->setFilterChildren(true);
+
+    QVERIFY(drag->filterChildren());
+    QCOMPARE(filterChildrenSpy.count(), 1);
+
+    drag->setFilterChildren(true);
+    QCOMPARE(filterChildrenSpy.count(), 1);
+
+    delete canvas;
+}
+
+void tst_QQuickMouseArea::resetDrag()
+{
+    QQuickView *canvas = createView();
+
+    canvas->rootContext()->setContextProperty("haveTarget", QVariant(true));
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragreset.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QVERIFY(canvas->rootObject() != 0);
+
+    QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
+    QQuickDrag *drag = mouseRegion->drag();
+    QVERIFY(mouseRegion != 0);
+    QVERIFY(drag != 0);
+
+    // target
+    QQuickItem *blackRect = canvas->rootObject()->findChild<QQuickItem*>("blackrect");
+    QVERIFY(blackRect != 0);
+    QVERIFY(blackRect == drag->target());
+    QQuickItem *rootItem = qobject_cast<QQuickItem*>(canvas->rootObject());
+    QVERIFY(rootItem != 0);
+    QSignalSpy targetSpy(drag, SIGNAL(targetChanged()));
+    QVERIFY(drag->target() != 0);
+    canvas->rootContext()->setContextProperty("haveTarget", QVariant(false));
+    QCOMPARE(targetSpy.count(),1);
+    QVERIFY(drag->target() == 0);
+
+    delete canvas;
+}
+
+
+void tst_QQuickMouseArea::dragging()
+{
+    QQuickView *canvas = createView();
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragging.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QTest::qWait(20);
+    QVERIFY(canvas->rootObject() != 0);
+
+    QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
+    QQuickDrag *drag = mouseRegion->drag();
+    QVERIFY(mouseRegion != 0);
+    QVERIFY(drag != 0);
+
+    // target
+    QQuickItem *blackRect = canvas->rootObject()->findChild<QQuickItem*>("blackrect");
+    QVERIFY(blackRect != 0);
+    QVERIFY(blackRect == drag->target());
+
+    QVERIFY(!drag->active());
+
+#ifdef OLDWAY
+    QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+    QApplication::sendEvent(canvas, &pressEvent);
+#else
+    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
+#endif
+
+    QVERIFY(!drag->active());
+    QCOMPARE(blackRect->x(), 50.0);
+    QCOMPARE(blackRect->y(), 50.0);
+
+    // First move event triggers drag, second is acted upon.
+    // This is due to possibility of higher stacked area taking precedence.
+
+    QTest::mouseMove(canvas, QPoint(111,111));
+    QTest::qWait(50);
+    QTest::mouseMove(canvas, QPoint(122,122));
+    QTest::qWait(50);
+
+    QVERIFY(drag->active());
+    QCOMPARE(blackRect->x(), 72.0);
+    QCOMPARE(blackRect->y(), 72.0);
+
+#ifdef OLDWAY
+    QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+    QApplication::sendEvent(canvas, &releaseEvent);
+#else
+    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(122,122));
+    QTest::qWait(50);
+#endif
+
+    QVERIFY(!drag->active());
+    QCOMPARE(blackRect->x(), 72.0);
+    QCOMPARE(blackRect->y(), 72.0);
+
+    delete canvas;
+}
+
+QQuickView *tst_QQuickMouseArea::createView()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setBaseSize(QSize(240,320));
+
+    return canvas;
+}
+
+void tst_QQuickMouseArea::updateMouseAreaPosOnClick()
+{
+    QQuickView *canvas = createView();
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("updateMousePosOnClick.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QVERIFY(canvas->rootObject() != 0);
+
+    QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
+    QVERIFY(mouseRegion != 0);
+
+    QQuickRectangle *rect = canvas->rootObject()->findChild<QQuickRectangle*>("ball");
+    QVERIFY(rect != 0);
+
+    QCOMPARE(mouseRegion->mouseX(), rect->x());
+    QCOMPARE(mouseRegion->mouseY(), rect->y());
+
+    QMouseEvent event(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+    QApplication::sendEvent(canvas, &event);
+
+    QCOMPARE(mouseRegion->mouseX(), 100.0);
+    QCOMPARE(mouseRegion->mouseY(), 100.0);
+
+    QCOMPARE(mouseRegion->mouseX(), rect->x());
+    QCOMPARE(mouseRegion->mouseY(), rect->y());
+
+    delete canvas;
+}
+
+void tst_QQuickMouseArea::updateMouseAreaPosOnResize()
+{
+    QQuickView *canvas = createView();
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("updateMousePosOnResize.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QVERIFY(canvas->rootObject() != 0);
+
+    QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
+    QVERIFY(mouseRegion != 0);
+
+    QQuickRectangle *rect = canvas->rootObject()->findChild<QQuickRectangle*>("brother");
+    QVERIFY(rect != 0);
+
+    QCOMPARE(mouseRegion->mouseX(), 0.0);
+    QCOMPARE(mouseRegion->mouseY(), 0.0);
+
+    QMouseEvent event(QEvent::MouseButtonPress, rect->pos().toPoint(), Qt::LeftButton, Qt::LeftButton, 0);
+    QApplication::sendEvent(canvas, &event);
+
+    QVERIFY(!mouseRegion->property("emitPositionChanged").toBool());
+    QVERIFY(mouseRegion->property("mouseMatchesPos").toBool());
+
+    QCOMPARE(mouseRegion->property("x1").toInt(), 0);
+    QCOMPARE(mouseRegion->property("y1").toInt(), 0);
+
+    // XXX: is it on purpose that mouseX is real and mouse.x is int?
+    QCOMPARE(mouseRegion->property("x2").toInt(), (int) rect->x());
+    QCOMPARE(mouseRegion->property("y2").toInt(), (int) rect->y());
+
+    QCOMPARE(mouseRegion->mouseX(), rect->x());
+    QCOMPARE(mouseRegion->mouseY(), rect->y());
+
+    delete canvas;
+}
+
+void tst_QQuickMouseArea::noOnClickedWithPressAndHold()
+{
+    {
+        // We handle onPressAndHold, therefore no onClicked
+        QQuickView *canvas = createView();
+        canvas->setSource(QUrl::fromLocalFile(TESTDATA("clickandhold.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);
+
+        QVERIFY(!canvas->rootObject()->property("clicked").toBool());
+        QVERIFY(!canvas->rootObject()->property("held").toBool());
+
+        QTest::qWait(1000);
+
+        QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+        QApplication::sendEvent(canvas, &releaseEvent);
+
+        QVERIFY(!canvas->rootObject()->property("clicked").toBool());
+        QVERIFY(canvas->rootObject()->property("held").toBool());
+
+        delete canvas;
+    }
+
+    {
+        // We do not handle onPressAndHold, therefore we get onClicked
+        QQuickView *canvas = createView();
+        canvas->setSource(QUrl::fromLocalFile(TESTDATA("noclickandhold.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);
+
+        QVERIFY(!canvas->rootObject()->property("clicked").toBool());
+
+        QTest::qWait(1000);
+
+        QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+        QApplication::sendEvent(canvas, &releaseEvent);
+
+        QVERIFY(canvas->rootObject()->property("clicked").toBool());
+
+        delete canvas;
+    }
+}
+
+void tst_QQuickMouseArea::onMousePressRejected()
+{
+    QQuickView *canvas = createView();
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("rejectEvent.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QVERIFY(canvas->rootObject() != 0);
+    QVERIFY(canvas->rootObject()->property("enabled").toBool());
+
+    QVERIFY(!canvas->rootObject()->property("mr1_pressed").toBool());
+    QVERIFY(!canvas->rootObject()->property("mr1_released").toBool());
+    QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
+    QVERIFY(!canvas->rootObject()->property("mr2_pressed").toBool());
+    QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
+    QVERIFY(!canvas->rootObject()->property("mr2_canceled").toBool());
+
+    QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+    QApplication::sendEvent(canvas, &pressEvent);
+
+    QVERIFY(canvas->rootObject()->property("mr1_pressed").toBool());
+    QVERIFY(!canvas->rootObject()->property("mr1_released").toBool());
+    QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
+    QVERIFY(canvas->rootObject()->property("mr2_pressed").toBool());
+    QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
+    QVERIFY(canvas->rootObject()->property("mr2_canceled").toBool());
+
+    QTest::qWait(200);
+
+    QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+    QApplication::sendEvent(canvas, &releaseEvent);
+
+    QVERIFY(canvas->rootObject()->property("mr1_released").toBool());
+    QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
+    QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
+
+    delete canvas;
+}
+void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate()
+{
+    QQuickView *canvas = createView();
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pressedCanceled.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QVERIFY(canvas->rootObject() != 0);
+    QVERIFY(!canvas->rootObject()->property("pressed").toBool());
+    QVERIFY(!canvas->rootObject()->property("canceled").toBool());
+    QVERIFY(!canvas->rootObject()->property("released").toBool());
+
+    QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+    QApplication::sendEvent(canvas, &pressEvent);
+
+    QVERIFY(canvas->rootObject()->property("pressed").toBool());
+    QVERIFY(!canvas->rootObject()->property("canceled").toBool());
+    QVERIFY(!canvas->rootObject()->property("released").toBool());
+
+    QTest::qWait(200);
+
+    QEvent windowDeactivateEvent(QEvent::WindowDeactivate);
+    QApplication::sendEvent(canvas, &windowDeactivateEvent);
+    QVERIFY(!canvas->rootObject()->property("pressed").toBool());
+    QVERIFY(canvas->rootObject()->property("canceled").toBool());
+    QVERIFY(!canvas->rootObject()->property("released").toBool());
+
+    QTest::qWait(200);
+
+    //press again
+    QApplication::sendEvent(canvas, &pressEvent);
+    QVERIFY(canvas->rootObject()->property("pressed").toBool());
+    QVERIFY(!canvas->rootObject()->property("canceled").toBool());
+    QVERIFY(!canvas->rootObject()->property("released").toBool());
+
+    QTest::qWait(200);
+
+    //release
+    QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+    QApplication::sendEvent(canvas, &releaseEvent);
+    QVERIFY(!canvas->rootObject()->property("pressed").toBool());
+    QVERIFY(!canvas->rootObject()->property("canceled").toBool());
+    QVERIFY(canvas->rootObject()->property("released").toBool());
+
+    delete canvas;
+}
+void tst_QQuickMouseArea::doubleClick()
+{
+    QQuickView *canvas = createView();
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("doubleclick.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);
+
+    QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+    QApplication::sendEvent(canvas, &releaseEvent);
+
+    QCOMPARE(canvas->rootObject()->property("released").toInt(), 1);
+
+    pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+    QApplication::sendEvent(canvas, &pressEvent);
+
+    QApplication::sendEvent(canvas, &releaseEvent);
+
+    QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 1);
+    QCOMPARE(canvas->rootObject()->property("doubleClicked").toInt(), 1);
+    QCOMPARE(canvas->rootObject()->property("released").toInt(), 2);
+
+    delete canvas;
+}
+
+// QTBUG-14832
+void tst_QQuickMouseArea::clickTwice()
+{
+    QQuickView *canvas = createView();
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("clicktwice.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);
+
+    QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+    QApplication::sendEvent(canvas, &releaseEvent);
+
+    QCOMPARE(canvas->rootObject()->property("pressed").toInt(), 1);
+    QCOMPARE(canvas->rootObject()->property("released").toInt(), 1);
+    QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 1);
+
+    pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+    QApplication::sendEvent(canvas, &pressEvent);
+
+    QApplication::sendEvent(canvas, &pressEvent);
+    QApplication::sendEvent(canvas, &releaseEvent);
+
+    QCOMPARE(canvas->rootObject()->property("pressed").toInt(), 2);
+    QCOMPARE(canvas->rootObject()->property("released").toInt(), 2);
+    QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 2);
+
+    delete canvas;
+}
+
+void tst_QQuickMouseArea::pressedOrdering()
+{
+    QQuickView *canvas = createView();
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pressedOrdering.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QVERIFY(canvas->rootObject() != 0);
+
+    QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("base"));
+
+    QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+    QApplication::sendEvent(canvas, &pressEvent);
+
+    QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("pressed"));
+
+    QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
+    QApplication::sendEvent(canvas, &releaseEvent);
+
+    QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("toggled"));
+
+    QApplication::sendEvent(canvas, &pressEvent);
+
+    QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("pressed"));
+
+    delete canvas;
+}
+
+void tst_QQuickMouseArea::preventStealing()
+{
+    QQuickView *canvas = createView();
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("preventstealing.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QVERIFY(canvas->rootObject() != 0);
+
+    QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(canvas->rootObject());
+    QVERIFY(flickable != 0);
+
+    QQuickMouseArea *mouseArea = canvas->rootObject()->findChild<QQuickMouseArea*>("mousearea");
+    QVERIFY(mouseArea != 0);
+
+    QSignalSpy mousePositionSpy(mouseArea, SIGNAL(positionChanged(QQuickMouseEvent*)));
+
+    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(80, 80));
+
+    // Without preventStealing, mouse movement over MouseArea would
+    // cause the Flickable to steal mouse and trigger content movement.
+
+    QTest::mouseMove(canvas,QPoint(69,69));
+    QTest::mouseMove(canvas,QPoint(58,58));
+    QTest::mouseMove(canvas,QPoint(47,47));
+
+    // We should have received all three move events
+    QCOMPARE(mousePositionSpy.count(), 3);
+    QVERIFY(mouseArea->pressed());
+
+    // Flickable content should not have moved.
+    QCOMPARE(flickable->contentX(), 0.);
+    QCOMPARE(flickable->contentY(), 0.);
+
+    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(47, 47));
+
+    // Now allow stealing and confirm Flickable does its thing.
+    canvas->rootObject()->setProperty("stealing", false);
+
+    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(80, 80));
+
+    // Without preventStealing, mouse movement over MouseArea would
+    // cause the Flickable to steal mouse and trigger content movement.
+
+    QTest::mouseMove(canvas,QPoint(69,69));
+    QTest::mouseMove(canvas,QPoint(58,58));
+    QTest::mouseMove(canvas,QPoint(47,47));
+
+    // We should only have received the first move event
+    QCOMPARE(mousePositionSpy.count(), 4);
+    // Our press should be taken away
+    QVERIFY(!mouseArea->pressed());
+
+    // Flickable content should have moved.
+
+    QCOMPARE(flickable->contentX(), 11.);
+    QCOMPARE(flickable->contentY(), 11.);
+
+    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 50));
+
+    delete canvas;
+}
+
+void tst_QQuickMouseArea::clickThrough()
+{
+    //With no handlers defined click, doubleClick and PressAndHold should propagate to those with handlers
+    QQuickView *canvas = createView();
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("clickThrough.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QVERIFY(canvas->rootObject() != 0);
+
+    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
+    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
+
+    QTRY_COMPARE(canvas->rootObject()->property("presses").toInt(), 0);
+    QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
+
+    QTest::qWait(800); // to avoid generating a double click.
+
+    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
+    QTest::qWait(1000);
+    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
+
+    QTRY_COMPARE(canvas->rootObject()->property("presses").toInt(), 0);
+    QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
+    QTRY_COMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
+
+    QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
+    QTest::qWait(100);
+
+    QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
+    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(TESTDATA("clickThrough2.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QVERIFY(canvas->rootObject() != 0);
+
+    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);
+
+    QTest::qWait(800); // to avoid generating a double click.
+
+    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
+    QTest::qWait(1000);
+    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);
+
+    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);
+    QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 0);
+    QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 0);
+
+    canvas->rootObject()->setProperty("letThrough", QVariant(true));
+
+    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);
+    QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
+
+    QTest::qWait(800); // to avoid generating a double click.
+    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
+    QTest::qWait(1000);
+    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);
+
+    QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
+    QTest::qWait(100);
+
+    QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
+    QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2);
+    QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1);
+    QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
+
+    delete canvas;
+}
+
+void tst_QQuickMouseArea::testQtQuick11Attributes()
+{
+    QFETCH(QString, code);
+    QFETCH(QString, warning);
+    QFETCH(QString, error);
+
+    QDeclarativeEngine engine;
+    QObject *obj;
+
+    QDeclarativeComponent valid(&engine);
+    valid.setData("import QtQuick 1.1; MouseArea { " + code.toUtf8() + " }", QUrl(""));
+    obj = valid.create();
+    QVERIFY(obj);
+    QVERIFY(valid.errorString().isEmpty());
+    delete obj;
+
+    QDeclarativeComponent invalid(&engine);
+    invalid.setData("import QtQuick 1.0; MouseArea { " + code.toUtf8() + " }", QUrl(""));
+    QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
+    obj = invalid.create();
+    QCOMPARE(invalid.errorString(), error);
+    delete obj;
+}
+
+void tst_QQuickMouseArea::testQtQuick11Attributes_data()
+{
+    QTest::addColumn<QString>("code");
+    QTest::addColumn<QString>("warning");
+    QTest::addColumn<QString>("error");
+
+    QTest::newRow("preventStealing") << "preventStealing: true"
+        << "QDeclarativeComponent: Component is not ready"
+        << ":1 \"MouseArea.preventStealing\" is not available in QtQuick 1.0.\n";
+}
+
+void tst_QQuickMouseArea::hoverPosition()
+{
+    QQuickView *canvas = createView();
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("hoverPosition.qml")));
+
+    QQuickItem *root = canvas->rootObject();
+    QVERIFY(root != 0);
+
+    QCOMPARE(root->property("mouseX").toReal(), qreal(0));
+    QCOMPARE(root->property("mouseY").toReal(), qreal(0));
+
+    QTest::mouseMove(canvas,QPoint(10,32));
+
+
+    QCOMPARE(root->property("mouseX").toReal(), qreal(10));
+    QCOMPARE(root->property("mouseY").toReal(), qreal(32));
+
+    delete canvas;
+}
+
+void tst_QQuickMouseArea::hoverPropagation()
+{
+    //QTBUG-18175, to behave like GV did.
+    QQuickView *canvas = createView();
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("hoverPropagation.qml")));
+
+    QQuickItem *root = canvas->rootObject();
+    QVERIFY(root != 0);
+
+    QCOMPARE(root->property("point1").toBool(), false);
+    QCOMPARE(root->property("point2").toBool(), false);
+
+    QMouseEvent moveEvent(QEvent::MouseMove, QPoint(32, 32), Qt::NoButton, Qt::NoButton, 0);
+    QApplication::sendEvent(canvas, &moveEvent);
+
+    QCOMPARE(root->property("point1").toBool(), true);
+    QCOMPARE(root->property("point2").toBool(), false);
+
+    QMouseEvent moveEvent2(QEvent::MouseMove, QPoint(232, 32), Qt::NoButton, Qt::NoButton, 0);
+    QApplication::sendEvent(canvas, &moveEvent2);
+    QCOMPARE(root->property("point1").toBool(), false);
+    QCOMPARE(root->property("point2").toBool(), true);
+
+    delete canvas;
+}
+
+QTEST_MAIN(tst_QQuickMouseArea)
+
+#include "tst_qquickmousearea.moc"
diff --git a/tests/auto/declarative/qquickpathview/qquickpathview.pro b/tests/auto/declarative/qquickpathview/qquickpathview.pro
new file mode 100644 (file)
index 0000000..d03cd4e
--- /dev/null
@@ -0,0 +1,12 @@
+CONFIG += testcase
+TARGET = tst_qquickpathview
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qquickpathview.cpp
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+QT += core-private gui-private v8-private declarative-private widgets testlib
diff --git a/tests/auto/declarative/qquickpathview/tst_qquickpathview.cpp b/tests/auto/declarative/qquickpathview/tst_qquickpathview.cpp
new file mode 100644 (file)
index 0000000..dc85f59
--- /dev/null
@@ -0,0 +1,1155 @@
+/****************************************************************************
+**
+** 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 <QtDeclarative/qquickview.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qdeclarativeexpression.h>
+#include <QtDeclarative/private/qquickpathview_p.h>
+#include <QtDeclarative/private/qdeclarativepath_p.h>
+#include <QtDeclarative/private/qquicktext_p.h>
+#include <QtDeclarative/private/qquickrectangle_p.h>
+#include <QtDeclarative/private/qdeclarativelistmodel_p.h>
+#include <QtDeclarative/private/qdeclarativevaluetype_p.h>
+#include <QAbstractListModel>
+#include <QStringListModel>
+#include <QStandardItemModel>
+#include <QFile>
+
+#include "../shared/util.h"
+
+static void initStandardTreeModel(QStandardItemModel *model)
+{
+    QStandardItem *item;
+    item = new QStandardItem(QLatin1String("Row 1 Item"));
+    model->insertRow(0, item);
+
+    item = new QStandardItem(QLatin1String("Row 2 Item"));
+    item->setCheckable(true);
+    model->insertRow(1, item);
+
+    QStandardItem *childItem = new QStandardItem(QLatin1String("Row 2 Child Item"));
+    item->setChild(0, childItem);
+
+    item = new QStandardItem(QLatin1String("Row 3 Item"));
+    item->setIcon(QIcon());
+    model->insertRow(2, item);
+}
+
+
+class tst_QQuickPathView : public QObject
+{
+    Q_OBJECT
+public:
+    tst_QQuickPathView();
+
+private slots:
+    void initTestCase();
+    void cleanupTestCase();
+    void initValues();
+    void items();
+    void dataModel();
+    void pathview2();
+    void pathview3();
+    void path();
+    void pathMoved();
+    void setCurrentIndex();
+    void resetModel();
+    void propertyChanges();
+    void pathChanges();
+    void componentChanges();
+    void modelChanges();
+    void pathUpdateOnStartChanged();
+    void package();
+    void emptyModel();
+    void closed();
+    void pathUpdate();
+    void visualDataModel();
+    void undefinedPath();
+    void mouseDrag();
+    void treeModel();
+    void changePreferredHighlight();
+    void missingPercent();
+    void creationContext();
+
+private:
+    QQuickView *createView();
+    template<typename T>
+    T *findItem(QQuickItem *parent, const QString &objectName, int index=-1);
+    template<typename T>
+    QList<T*> findItems(QQuickItem *parent, const QString &objectName);
+};
+
+void tst_QQuickPathView::initTestCase()
+{
+}
+
+void tst_QQuickPathView::cleanupTestCase()
+{
+
+}
+
+class TestObject : public QObject
+{
+    Q_OBJECT
+
+    Q_PROPERTY(bool error READ error WRITE setError)
+    Q_PROPERTY(bool useModel READ useModel NOTIFY useModelChanged)
+    Q_PROPERTY(int pathItemCount READ pathItemCount NOTIFY pathItemCountChanged)
+
+public:
+    TestObject() : QObject(), mError(true), mUseModel(true), mPathItemCount(-1) {}
+
+    bool error() const { return mError; }
+    void setError(bool err) { mError = err; }
+
+    bool useModel() const { return mUseModel; }
+    void setUseModel(bool use) { mUseModel = use; emit useModelChanged(); }
+
+    int pathItemCount() const { return mPathItemCount; }
+    void setPathItemCount(int count) { mPathItemCount = count; emit pathItemCountChanged(); }
+
+signals:
+    void useModelChanged();
+    void pathItemCountChanged();
+
+private:
+    bool mError;
+    bool mUseModel;
+    int mPathItemCount;
+};
+
+class TestModel : public QAbstractListModel
+{
+public:
+    enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 };
+
+    TestModel(QObject *parent=0) : QAbstractListModel(parent) {
+        QHash<int, QByteArray> roles;
+        roles[Name] = "name";
+        roles[Number] = "number";
+        setRoleNames(roles);
+    }
+
+    int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); }
+    QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
+        QVariant rv;
+        if (role == Name)
+            rv = list.at(index.row()).first;
+        else if (role == Number)
+            rv = list.at(index.row()).second;
+
+        return rv;
+    }
+
+    int count() const { return rowCount(); }
+    QString name(int index) const { return list.at(index).first; }
+    QString number(int index) const { return list.at(index).second; }
+
+    void addItem(const QString &name, const QString &number) {
+        beginInsertRows(QModelIndex(), list.count(), list.count());
+        list.append(QPair<QString,QString>(name, number));
+        endInsertRows();
+    }
+
+    void insertItem(int index, const QString &name, const QString &number) {
+        beginInsertRows(QModelIndex(), index, index);
+        list.insert(index, QPair<QString,QString>(name, number));
+        endInsertRows();
+    }
+
+    void removeItem(int index) {
+        beginRemoveRows(QModelIndex(), index, index);
+        list.removeAt(index);
+        endRemoveRows();
+    }
+
+    void moveItem(int from, int to) {
+        beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
+        list.move(from, to);
+        endMoveRows();
+    }
+
+    void modifyItem(int idx, const QString &name, const QString &number) {
+        list[idx] = QPair<QString,QString>(name, number);
+        emit dataChanged(index(idx,0), index(idx,0));
+    }
+
+private:
+    QList<QPair<QString,QString> > list;
+};
+
+
+tst_QQuickPathView::tst_QQuickPathView()
+{
+}
+
+void tst_QQuickPathView::initValues()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathview1.qml")));
+    QQuickPathView *obj = qobject_cast<QQuickPathView*>(c.create());
+
+    QVERIFY(obj != 0);
+    QVERIFY(obj->path() == 0);
+    QVERIFY(obj->delegate() == 0);
+    QCOMPARE(obj->model(), QVariant());
+    QCOMPARE(obj->currentIndex(), 0);
+    QCOMPARE(obj->offset(), 0.);
+    QCOMPARE(obj->preferredHighlightBegin(), 0.);
+    QCOMPARE(obj->dragMargin(), 0.);
+    QCOMPARE(obj->count(), 0);
+    QCOMPARE(obj->pathItemCount(), -1);
+}
+
+void tst_QQuickPathView::items()
+{
+    QQuickView *canvas = createView();
+
+    TestModel model;
+    model.addItem("Fred", "12345");
+    model.addItem("John", "2345");
+    model.addItem("Bob", "54321");
+    model.addItem("Bill", "4321");
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml")));
+    qApp->processEvents();
+
+    QQuickPathView *pathview = findItem<QQuickPathView>(canvas->rootObject(), "view");
+    QVERIFY(pathview != 0);
+
+    QCOMPARE(pathview->count(), model.count());
+    QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count());
+    QCOMPARE(pathview->childItems().count(), model.count()+1); // assumes all are visible, including highlight
+
+    for (int i = 0; i < model.count(); ++i) {
+        QQuickText *name = findItem<QQuickText>(pathview, "textName", i);
+        QVERIFY(name != 0);
+        QCOMPARE(name->text(), model.name(i));
+        QQuickText *number = findItem<QQuickText>(pathview, "textNumber", i);
+        QVERIFY(number != 0);
+        QCOMPARE(number->text(), model.number(i));
+    }
+
+    QDeclarativePath *path = qobject_cast<QDeclarativePath*>(pathview->path());
+    QVERIFY(path);
+
+    QVERIFY(pathview->highlightItem());
+    QPointF start = path->pointAt(0.0);
+    QPointF offset;
+    offset.setX(pathview->highlightItem()->width()/2);
+    offset.setY(pathview->highlightItem()->height()/2);
+    QCOMPARE(pathview->highlightItem()->pos() + offset, start);
+
+    delete canvas;
+}
+
+void tst_QQuickPathView::pathview2()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathview2.qml")));
+    QQuickPathView *obj = qobject_cast<QQuickPathView*>(c.create());
+
+    QVERIFY(obj != 0);
+    QVERIFY(obj->path() != 0);
+    QVERIFY(obj->delegate() != 0);
+    QVERIFY(obj->model() != QVariant());
+    QCOMPARE(obj->currentIndex(), 0);
+    QCOMPARE(obj->offset(), 0.);
+    QCOMPARE(obj->preferredHighlightBegin(), 0.);
+    QCOMPARE(obj->dragMargin(), 0.);
+    QCOMPARE(obj->count(), 8);
+    QCOMPARE(obj->pathItemCount(), 10);
+}
+
+void tst_QQuickPathView::pathview3()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathview3.qml")));
+    QQuickPathView *obj = qobject_cast<QQuickPathView*>(c.create());
+
+    QVERIFY(obj != 0);
+    QVERIFY(obj->path() != 0);
+    QVERIFY(obj->delegate() != 0);
+    QVERIFY(obj->model() != QVariant());
+    QCOMPARE(obj->currentIndex(), 0);
+    QCOMPARE(obj->offset(), 1.0);
+    QCOMPARE(obj->preferredHighlightBegin(), 0.5);
+    QCOMPARE(obj->dragMargin(), 24.);
+    QCOMPARE(obj->count(), 8);
+    QCOMPARE(obj->pathItemCount(), 4);
+}
+
+void tst_QQuickPathView::path()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathtest.qml")));
+    QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create());
+
+    QVERIFY(obj != 0);
+    QCOMPARE(obj->startX(), 120.);
+    QCOMPARE(obj->startY(), 100.);
+    QVERIFY(obj->path() != QPainterPath());
+
+    QDeclarativeListReference list(obj, "pathElements");
+    QCOMPARE(list.count(), 5);
+
+    QDeclarativePathAttribute* attr = qobject_cast<QDeclarativePathAttribute*>(list.at(0));
+    QVERIFY(attr != 0);
+    QCOMPARE(attr->name(), QString("scale"));
+    QCOMPARE(attr->value(), 1.0);
+
+    QDeclarativePathQuad* quad = qobject_cast<QDeclarativePathQuad*>(list.at(1));
+    QVERIFY(quad != 0);
+    QCOMPARE(quad->x(), 120.);
+    QCOMPARE(quad->y(), 25.);
+    QCOMPARE(quad->controlX(), 260.);
+    QCOMPARE(quad->controlY(), 75.);
+
+    QDeclarativePathPercent* perc = qobject_cast<QDeclarativePathPercent*>(list.at(2));
+    QVERIFY(perc != 0);
+    QCOMPARE(perc->value(), 0.3);
+
+    QDeclarativePathLine* line = qobject_cast<QDeclarativePathLine*>(list.at(3));
+    QVERIFY(line != 0);
+    QCOMPARE(line->x(), 120.);
+    QCOMPARE(line->y(), 100.);
+
+    QDeclarativePathCubic* cubic = qobject_cast<QDeclarativePathCubic*>(list.at(4));
+    QVERIFY(cubic != 0);
+    QCOMPARE(cubic->x(), 180.);
+    QCOMPARE(cubic->y(), 0.);
+    QCOMPARE(cubic->control1X(), -10.);
+    QCOMPARE(cubic->control1Y(), 90.);
+    QCOMPARE(cubic->control2X(), 210.);
+    QCOMPARE(cubic->control2Y(), 90.);
+}
+
+void tst_QQuickPathView::dataModel()
+{
+    QQuickView *canvas = createView();
+    canvas->show();
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    TestObject *testObject = new TestObject;
+    ctxt->setContextProperty("testObject", testObject);
+
+    TestModel model;
+    model.addItem("red", "1");
+    model.addItem("green", "2");
+    model.addItem("blue", "3");
+    model.addItem("purple", "4");
+    model.addItem("gray", "5");
+    model.addItem("brown", "6");
+    model.addItem("yellow", "7");
+    model.addItem("thistle", "8");
+    model.addItem("cyan", "9");
+    model.addItem("peachpuff", "10");
+    model.addItem("powderblue", "11");
+    model.addItem("gold", "12");
+    model.addItem("sandybrown", "13");
+
+    ctxt->setContextProperty("testData", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("datamodel.qml")));
+    qApp->processEvents();
+
+    QQuickPathView *pathview = qobject_cast<QQuickPathView*>(canvas->rootObject());
+    QVERIFY(pathview != 0);
+
+    QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
+    QVERIFY(testObject->error() == false);
+
+    QQuickItem *item = findItem<QQuickItem>(pathview, "wrapper", 0);
+    QVERIFY(item);
+    QCOMPARE(item->x(), 110.0);
+    QCOMPARE(item->y(), 10.0);
+
+    model.insertItem(4, "orange", "10");
+    QTest::qWait(100);
+
+    QCOMPARE(canvas->rootObject()->property("viewCount").toInt(), model.count());
+    QTRY_COMPARE(findItems<QQuickItem>(pathview, "wrapper").count(), 14);
+
+    QVERIFY(pathview->currentIndex() == 0);
+    QCOMPARE(pathview->currentItem(), findItem<QQuickItem>(pathview, "wrapper", 0));
+
+    QQuickText *text = findItem<QQuickText>(pathview, "myText", 4);
+    QVERIFY(text);
+    QCOMPARE(text->text(), model.name(4));
+
+    model.removeItem(2);
+    QCOMPARE(canvas->rootObject()->property("viewCount").toInt(), model.count());
+    text = findItem<QQuickText>(pathview, "myText", 2);
+    QVERIFY(text);
+    QCOMPARE(text->text(), model.name(2));
+    QCOMPARE(pathview->currentItem(), findItem<QQuickItem>(pathview, "wrapper", 0));
+
+    testObject->setPathItemCount(5);
+    QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
+    QVERIFY(testObject->error() == false);
+
+    QTRY_COMPARE(findItems<QQuickItem>(pathview, "wrapper").count(), 5);
+
+    QQuickRectangle *testItem = findItem<QQuickRectangle>(pathview, "wrapper", 4);
+    QVERIFY(testItem != 0);
+    testItem = findItem<QQuickRectangle>(pathview, "wrapper", 5);
+    QVERIFY(testItem == 0);
+
+    pathview->setCurrentIndex(1);
+    QCOMPARE(pathview->currentItem(), findItem<QQuickItem>(pathview, "wrapper", 1));
+    QTest::qWait(100);
+
+    model.insertItem(2, "pink", "2");
+    QTest::qWait(100);
+
+    QTRY_COMPARE(findItems<QQuickItem>(pathview, "wrapper").count(), 5);
+    QVERIFY(pathview->currentIndex() == 1);
+    QCOMPARE(pathview->currentItem(), findItem<QQuickItem>(pathview, "wrapper", 1));
+
+    text = findItem<QQuickText>(pathview, "myText", 2);
+    QVERIFY(text);
+    QCOMPARE(text->text(), model.name(2));
+
+    model.removeItem(3);
+    QTRY_COMPARE(findItems<QQuickItem>(pathview, "wrapper").count(), 5);
+    text = findItem<QQuickText>(pathview, "myText", 3);
+    QVERIFY(text);
+    QCOMPARE(text->text(), model.name(3));
+    QCOMPARE(pathview->currentItem(), findItem<QQuickItem>(pathview, "wrapper", 1));
+
+    model.moveItem(3, 5);
+    QTRY_COMPARE(findItems<QQuickItem>(pathview, "wrapper").count(), 5);
+    QList<QQuickItem*> items = findItems<QQuickItem>(pathview, "wrapper");
+    foreach (QQuickItem *item, items) {
+        QVERIFY(item->property("onPath").toBool());
+    }
+    QCOMPARE(pathview->currentItem(), findItem<QQuickItem>(pathview, "wrapper", 1));
+
+    // QTBUG-14199
+    pathview->setOffset(7);
+    pathview->setOffset(0);
+    QCOMPARE(findItems<QQuickItem>(pathview, "wrapper").count(), 5);
+
+    pathview->setCurrentIndex(model.count()-1);
+    model.removeItem(model.count()-1);
+    QCOMPARE(pathview->currentIndex(), model.count()-1);
+
+    delete canvas;
+    delete testObject;
+}
+
+void tst_QQuickPathView::pathMoved()
+{
+    QQuickView *canvas = createView();
+    canvas->show();
+
+    TestModel model;
+    model.addItem("Ben", "12345");
+    model.addItem("Bohn", "2345");
+    model.addItem("Bob", "54321");
+    model.addItem("Bill", "4321");
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml")));
+    qApp->processEvents();
+
+    QQuickPathView *pathview = findItem<QQuickPathView>(canvas->rootObject(), "view");
+    QVERIFY(pathview != 0);
+
+    QQuickRectangle *firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 0);
+    QVERIFY(firstItem);
+    QDeclarativePath *path = qobject_cast<QDeclarativePath*>(pathview->path());
+    QVERIFY(path);
+    QPointF start = path->pointAt(0.0);
+    QPointF offset;//Center of item is at point, but pos is from corner
+    offset.setX(firstItem->width()/2);
+    offset.setY(firstItem->height()/2);
+    QCOMPARE(firstItem->pos() + offset, start);
+    pathview->setOffset(1.0);
+
+    for (int i=0; i<model.count(); i++) {
+        QQuickRectangle *curItem = findItem<QQuickRectangle>(pathview, "wrapper", i);
+        QPointF itemPos(path->pointAt(0.25 + i*0.25));
+        QCOMPARE(curItem->pos() + offset, QPointF(qRound(itemPos.x()), qRound(itemPos.y())));
+    }
+
+    pathview->setOffset(0.0);
+    QCOMPARE(firstItem->pos() + offset, start);
+
+    // Change delegate size
+    pathview->setOffset(0.1);
+    pathview->setOffset(0.0);
+    canvas->rootObject()->setProperty("delegateWidth", 30);
+    QCOMPARE(firstItem->width(), 30.0);
+    offset.setX(firstItem->width()/2);
+    QTRY_COMPARE(firstItem->pos() + offset, start);
+
+    // Change delegate scale
+    pathview->setOffset(0.1);
+    pathview->setOffset(0.0);
+    canvas->rootObject()->setProperty("delegateScale", 1.2);
+    QTRY_COMPARE(firstItem->pos() + offset, start);
+
+    delete canvas;
+}
+
+void tst_QQuickPathView::setCurrentIndex()
+{
+    QQuickView *canvas = createView();
+    canvas->show();
+
+    TestModel model;
+    model.addItem("Ben", "12345");
+    model.addItem("Bohn", "2345");
+    model.addItem("Bob", "54321");
+    model.addItem("Bill", "4321");
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml")));
+    qApp->processEvents();
+
+    QQuickPathView *pathview = findItem<QQuickPathView>(canvas->rootObject(), "view");
+    QVERIFY(pathview != 0);
+
+    QQuickRectangle *firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 0);
+    QVERIFY(firstItem);
+    QDeclarativePath *path = qobject_cast<QDeclarativePath*>(pathview->path());
+    QVERIFY(path);
+    QPointF start = path->pointAt(0.0);
+    QPointF offset;//Center of item is at point, but pos is from corner
+    offset.setX(firstItem->width()/2);
+    offset.setY(firstItem->height()/2);
+    QCOMPARE(firstItem->pos() + offset, start);
+    QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 0);
+    QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 0);
+
+    pathview->setCurrentIndex(2);
+
+    firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 2);
+    QTRY_COMPARE(firstItem->pos() + offset, start);
+    QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 2);
+    QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 2);
+    QCOMPARE(pathview->currentItem(), firstItem);
+    QCOMPARE(firstItem->property("onPath"), QVariant(true));
+
+    pathview->decrementCurrentIndex();
+    QTRY_COMPARE(pathview->currentIndex(), 1);
+    firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 1);
+    QVERIFY(firstItem);
+    QTRY_COMPARE(firstItem->pos() + offset, start);
+    QCOMPARE(pathview->currentItem(), firstItem);
+    QCOMPARE(firstItem->property("onPath"), QVariant(true));
+
+    pathview->decrementCurrentIndex();
+    QTRY_COMPARE(pathview->currentIndex(), 0);
+    firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 0);
+    QVERIFY(firstItem);
+    QTRY_COMPARE(firstItem->pos() + offset, start);
+    QCOMPARE(pathview->currentItem(), firstItem);
+    QCOMPARE(firstItem->property("onPath"), QVariant(true));
+
+    pathview->decrementCurrentIndex();
+    QTRY_COMPARE(pathview->currentIndex(), 3);
+    firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 3);
+    QVERIFY(firstItem);
+    QTRY_COMPARE(firstItem->pos() + offset, start);
+    QCOMPARE(pathview->currentItem(), firstItem);
+    QCOMPARE(firstItem->property("onPath"), QVariant(true));
+
+    pathview->incrementCurrentIndex();
+    QTRY_COMPARE(pathview->currentIndex(), 0);
+    firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 0);
+    QVERIFY(firstItem);
+    QTRY_COMPARE(firstItem->pos() + offset, start);
+    QCOMPARE(pathview->currentItem(), firstItem);
+    QCOMPARE(firstItem->property("onPath"), QVariant(true));
+
+    // Check the current item is still created when outside the bounds of pathItemCount.
+    pathview->setPathItemCount(2);
+    pathview->setHighlightRangeMode(QQuickPathView::NoHighlightRange);
+    QVERIFY(findItem<QQuickRectangle>(pathview, "wrapper", 0));
+    QVERIFY(findItem<QQuickRectangle>(pathview, "wrapper", 1));
+    QVERIFY(!findItem<QQuickRectangle>(pathview, "wrapper", 2));
+    QVERIFY(!findItem<QQuickRectangle>(pathview, "wrapper", 3));
+
+    pathview->setCurrentIndex(2);
+    firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 2);
+    QCOMPARE(pathview->currentItem(), firstItem);
+    QCOMPARE(firstItem->property("onPath"), QVariant(false));
+
+    pathview->decrementCurrentIndex();
+    QTRY_COMPARE(pathview->currentIndex(), 1);
+    firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 1);
+    QVERIFY(firstItem);
+    QCOMPARE(pathview->currentItem(), firstItem);
+    QCOMPARE(firstItem->property("onPath"), QVariant(true));
+
+    pathview->decrementCurrentIndex();
+    QTRY_COMPARE(pathview->currentIndex(), 0);
+    firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 0);
+    QVERIFY(firstItem);
+    QCOMPARE(pathview->currentItem(), firstItem);
+    QCOMPARE(firstItem->property("onPath"), QVariant(true));
+
+    pathview->decrementCurrentIndex();
+    QTRY_COMPARE(pathview->currentIndex(), 3);
+    firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 3);
+    QVERIFY(firstItem);
+    QCOMPARE(pathview->currentItem(), firstItem);
+    QCOMPARE(firstItem->property("onPath"), QVariant(false));
+
+    pathview->incrementCurrentIndex();
+    QTRY_COMPARE(pathview->currentIndex(), 0);
+    firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 0);
+    QVERIFY(firstItem);
+    QCOMPARE(pathview->currentItem(), firstItem);
+    QCOMPARE(firstItem->property("onPath"), QVariant(true));
+
+    delete canvas;
+}
+
+void tst_QQuickPathView::resetModel()
+{
+    QQuickView *canvas = createView();
+
+    QStringList strings;
+    strings << "one" << "two" << "three";
+    QStringListModel model(strings);
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaypath.qml")));
+    qApp->processEvents();
+
+    QQuickPathView *pathview = findItem<QQuickPathView>(canvas->rootObject(), "view");
+    QVERIFY(pathview != 0);
+
+    QCOMPARE(pathview->count(), model.rowCount());
+
+    for (int i = 0; i < model.rowCount(); ++i) {
+        QQuickText *display = findItem<QQuickText>(pathview, "displayText", i);
+        QVERIFY(display != 0);
+        QCOMPARE(display->text(), strings.at(i));
+    }
+
+    strings.clear();
+    strings << "four" << "five" << "six" << "seven";
+    model.setStringList(strings);
+
+    QCOMPARE(pathview->count(), model.rowCount());
+
+    for (int i = 0; i < model.rowCount(); ++i) {
+        QQuickText *display = findItem<QQuickText>(pathview, "displayText", i);
+        QVERIFY(display != 0);
+        QCOMPARE(display->text(), strings.at(i));
+    }
+
+    delete canvas;
+}
+
+void tst_QQuickPathView::propertyChanges()
+{
+    QQuickView *canvas = createView();
+    QVERIFY(canvas);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml")));
+
+    QQuickPathView *pathView = canvas->rootObject()->findChild<QQuickPathView*>("pathView");
+    QVERIFY(pathView);
+
+    QSignalSpy snapPositionSpy(pathView, SIGNAL(preferredHighlightBeginChanged()));
+    QSignalSpy dragMarginSpy(pathView, SIGNAL(dragMarginChanged()));
+
+    QCOMPARE(pathView->preferredHighlightBegin(), 0.1);
+    QCOMPARE(pathView->dragMargin(), 5.0);
+
+    pathView->setPreferredHighlightBegin(0.4);
+    pathView->setPreferredHighlightEnd(0.4);
+    pathView->setDragMargin(20.0);
+
+    QCOMPARE(pathView->preferredHighlightBegin(), 0.4);
+    QCOMPARE(pathView->preferredHighlightEnd(), 0.4);
+    QCOMPARE(pathView->dragMargin(), 20.0);
+
+    QCOMPARE(snapPositionSpy.count(), 1);
+    QCOMPARE(dragMarginSpy.count(), 1);
+
+    pathView->setPreferredHighlightBegin(0.4);
+    pathView->setPreferredHighlightEnd(0.4);
+    pathView->setDragMargin(20.0);
+
+    QCOMPARE(snapPositionSpy.count(), 1);
+    QCOMPARE(dragMarginSpy.count(), 1);
+    delete canvas;
+}
+
+void tst_QQuickPathView::pathChanges()
+{
+    QQuickView *canvas = createView();
+    QVERIFY(canvas);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml")));
+
+    QQuickPathView *pathView = canvas->rootObject()->findChild<QQuickPathView*>("pathView");
+    QVERIFY(pathView);
+
+    QDeclarativePath *path = canvas->rootObject()->findChild<QDeclarativePath*>("path");
+    QVERIFY(path);
+
+    QSignalSpy startXSpy(path, SIGNAL(startXChanged()));
+    QSignalSpy startYSpy(path, SIGNAL(startYChanged()));
+
+    QCOMPARE(path->startX(), 220.0);
+    QCOMPARE(path->startY(), 200.0);
+
+    path->setStartX(240.0);
+    path->setStartY(220.0);
+
+    QCOMPARE(path->startX(), 240.0);
+    QCOMPARE(path->startY(), 220.0);
+
+    QCOMPARE(startXSpy.count(),1);
+    QCOMPARE(startYSpy.count(),1);
+
+    path->setStartX(240);
+    path->setStartY(220);
+
+    QCOMPARE(startXSpy.count(),1);
+    QCOMPARE(startYSpy.count(),1);
+
+    QDeclarativePath *alternatePath = canvas->rootObject()->findChild<QDeclarativePath*>("alternatePath");
+    QVERIFY(alternatePath);
+
+    QSignalSpy pathSpy(pathView, SIGNAL(pathChanged()));
+
+    QCOMPARE(pathView->path(), path);
+
+    pathView->setPath(alternatePath);
+    QCOMPARE(pathView->path(), alternatePath);
+    QCOMPARE(pathSpy.count(),1);
+
+    pathView->setPath(alternatePath);
+    QCOMPARE(pathSpy.count(),1);
+
+    QDeclarativePathAttribute *pathAttribute = canvas->rootObject()->findChild<QDeclarativePathAttribute*>("pathAttribute");
+    QVERIFY(pathAttribute);
+
+    QSignalSpy nameSpy(pathAttribute, SIGNAL(nameChanged()));
+    QCOMPARE(pathAttribute->name(), QString("opacity"));
+
+    pathAttribute->setName("scale");
+    QCOMPARE(pathAttribute->name(), QString("scale"));
+    QCOMPARE(nameSpy.count(),1);
+
+    pathAttribute->setName("scale");
+    QCOMPARE(nameSpy.count(),1);
+    delete canvas;
+}
+
+void tst_QQuickPathView::componentChanges()
+{
+    QQuickView *canvas = createView();
+    QVERIFY(canvas);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml")));
+
+    QQuickPathView *pathView = canvas->rootObject()->findChild<QQuickPathView*>("pathView");
+    QVERIFY(pathView);
+
+    QDeclarativeComponent delegateComponent(canvas->engine());
+    delegateComponent.setData("import QtQuick 2.0; Text { text: '<b>Name:</b> ' + name }", QUrl::fromLocalFile(""));
+
+    QSignalSpy delegateSpy(pathView, SIGNAL(delegateChanged()));
+
+    pathView->setDelegate(&delegateComponent);
+    QCOMPARE(pathView->delegate(), &delegateComponent);
+    QCOMPARE(delegateSpy.count(),1);
+
+    pathView->setDelegate(&delegateComponent);
+    QCOMPARE(delegateSpy.count(),1);
+    delete canvas;
+}
+
+void tst_QQuickPathView::modelChanges()
+{
+    QQuickView *canvas = createView();
+    QVERIFY(canvas);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml")));
+
+    QQuickPathView *pathView = canvas->rootObject()->findChild<QQuickPathView*>("pathView");
+    QVERIFY(pathView);
+
+    QDeclarativeListModel *alternateModel = canvas->rootObject()->findChild<QDeclarativeListModel*>("alternateModel");
+    QVERIFY(alternateModel);
+    QVariant modelVariant = QVariant::fromValue<QObject *>(alternateModel);
+    QSignalSpy modelSpy(pathView, SIGNAL(modelChanged()));
+
+    pathView->setModel(modelVariant);
+    QCOMPARE(pathView->model(), modelVariant);
+    QCOMPARE(modelSpy.count(),1);
+
+    pathView->setModel(modelVariant);
+    QCOMPARE(modelSpy.count(),1);
+
+    pathView->setModel(QVariant());
+    QCOMPARE(modelSpy.count(),2);
+
+    delete canvas;
+}
+
+void tst_QQuickPathView::pathUpdateOnStartChanged()
+{
+    QQuickView *canvas = createView();
+    QVERIFY(canvas);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathUpdateOnStartChanged.qml")));
+
+    QQuickPathView *pathView = canvas->rootObject()->findChild<QQuickPathView*>("pathView");
+    QVERIFY(pathView);
+
+    QDeclarativePath *path = canvas->rootObject()->findChild<QDeclarativePath*>("path");
+    QVERIFY(path);
+    QCOMPARE(path->startX(), 400.0);
+    QCOMPARE(path->startY(), 300.0);
+
+    QQuickItem *item = findItem<QQuickItem>(pathView, "wrapper", 0);
+    QVERIFY(item);
+    QCOMPARE(item->x(), path->startX() - item->width() / 2.0);
+    QCOMPARE(item->y(), path->startY() - item->height() / 2.0);
+
+    delete canvas;
+}
+
+void tst_QQuickPathView::package()
+{
+    QQuickView *canvas = createView();
+    QVERIFY(canvas);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview_package.qml")));
+
+    QQuickPathView *pathView = canvas->rootObject()->findChild<QQuickPathView*>("photoPathView");
+    QVERIFY(pathView);
+
+    QQuickItem *item = findItem<QQuickItem>(pathView, "pathItem");
+    QVERIFY(item);
+    QVERIFY(item->scale() != 1.0);
+
+    delete canvas;
+}
+
+//QTBUG-13017
+void tst_QQuickPathView::emptyModel()
+{
+    QQuickView *canvas = createView();
+
+    QStringListModel model;
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("emptyModel", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("emptymodel.qml")));
+    qApp->processEvents();
+
+    QQuickPathView *pathview = qobject_cast<QQuickPathView*>(canvas->rootObject());
+    QVERIFY(pathview != 0);
+
+    QCOMPARE(pathview->offset(), qreal(0.0));
+
+    delete canvas;
+}
+
+void tst_QQuickPathView::closed()
+{
+    QDeclarativeEngine engine;
+
+    {
+        QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("openPath.qml")));
+        QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create());
+        QVERIFY(obj);
+        QCOMPARE(obj->isClosed(), false);
+        delete obj;
+    }
+
+    {
+        QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("closedPath.qml")));
+        QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create());
+        QVERIFY(obj);
+        QCOMPARE(obj->isClosed(), true);
+        delete obj;
+    }
+}
+
+// QTBUG-14239
+void tst_QQuickPathView::pathUpdate()
+{
+    QQuickView *canvas = createView();
+    QVERIFY(canvas);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathUpdate.qml")));
+
+    QQuickPathView *pathView = canvas->rootObject()->findChild<QQuickPathView*>("pathView");
+    QVERIFY(pathView);
+
+    QQuickItem *item = findItem<QQuickItem>(pathView, "wrapper", 0);
+    QVERIFY(item);
+    QCOMPARE(item->x(), 150.0);
+
+    delete canvas;
+}
+
+void tst_QQuickPathView::visualDataModel()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("vdm.qml")));
+
+    QQuickPathView *obj = qobject_cast<QQuickPathView*>(c.create());
+    QVERIFY(obj != 0);
+
+    QCOMPARE(obj->count(), 3);
+
+    delete obj;
+}
+
+void tst_QQuickPathView::undefinedPath()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("undefinedpath.qml")));
+
+    QQuickPathView *obj = qobject_cast<QQuickPathView*>(c.create());
+    QVERIFY(obj != 0);
+
+    QCOMPARE(obj->count(), 3);
+
+    delete obj;
+}
+
+void tst_QQuickPathView::mouseDrag()
+{
+    QQuickView *canvas = createView();
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragpath.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QTest::qWaitForWindowShown(canvas);
+    QTRY_COMPARE(canvas, qGuiApp->focusWindow());
+
+    QQuickPathView *pathview = qobject_cast<QQuickPathView*>(canvas->rootObject());
+    QVERIFY(pathview != 0);
+
+    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);
+        QApplication::sendEvent(canvas, &mv);
+    }
+    {
+        QMouseEvent mv(QEvent::MouseMove, QPoint(90,100), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+        QApplication::sendEvent(canvas, &mv);
+    }
+
+    QVERIFY(pathview->currentIndex() != current);
+
+    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(40,100));
+
+    delete canvas;
+}
+
+void tst_QQuickPathView::treeModel()
+{
+    QQuickView *canvas = createView();
+    canvas->show();
+
+    QStandardItemModel model;
+    initStandardTreeModel(&model);
+    canvas->engine()->rootContext()->setContextProperty("myModel", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("treemodel.qml")));
+
+    QQuickPathView *pathview = qobject_cast<QQuickPathView*>(canvas->rootObject());
+    QVERIFY(pathview != 0);
+    QCOMPARE(pathview->count(), 3);
+
+    QQuickText *item = findItem<QQuickText>(pathview, "wrapper", 0);
+    QVERIFY(item);
+    QCOMPARE(item->text(), QLatin1String("Row 1 Item"));
+
+    QVERIFY(QMetaObject::invokeMethod(pathview, "setRoot", Q_ARG(QVariant, 1)));
+    QCOMPARE(pathview->count(), 1);
+
+    QTRY_VERIFY(item = findItem<QQuickText>(pathview, "wrapper", 0));
+    QTRY_COMPARE(item->text(), QLatin1String("Row 2 Child Item"));
+
+    delete canvas;
+}
+
+void tst_QQuickPathView::changePreferredHighlight()
+{
+    QQuickView *canvas = createView();
+    canvas->setGeometry(0,0,400,200);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragpath.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QTest::qWaitForWindowShown(canvas);
+    QTRY_COMPARE(canvas, qGuiApp->focusWindow());
+
+    QQuickPathView *pathview = qobject_cast<QQuickPathView*>(canvas->rootObject());
+    QVERIFY(pathview != 0);
+
+    int current = pathview->currentIndex();
+    QCOMPARE(current, 0);
+
+    QQuickRectangle *firstItem = findItem<QQuickRectangle>(pathview, "wrapper", 0);
+    QVERIFY(firstItem);
+    QDeclarativePath *path = qobject_cast<QDeclarativePath*>(pathview->path());
+    QVERIFY(path);
+    QPointF start = path->pointAt(0.5);
+    start.setX(qRound(start.x()));
+    start.setY(qRound(start.y()));
+    QPointF offset;//Center of item is at point, but pos is from corner
+    offset.setX(firstItem->width()/2);
+    offset.setY(firstItem->height()/2);
+    QTRY_COMPARE(firstItem->pos() + offset, start);
+
+    pathview->setPreferredHighlightBegin(0.8);
+    pathview->setPreferredHighlightEnd(0.8);
+    start = path->pointAt(0.8);
+    start.setX(qRound(start.x()));
+    start.setY(qRound(start.y()));
+    QTRY_COMPARE(firstItem->pos() + offset, start);
+    QCOMPARE(pathview->currentIndex(), 0);
+
+    delete canvas;
+}
+
+void tst_QQuickPathView::creationContext()
+{
+    QQuickView canvas;
+    canvas.setGeometry(0,0,240,320);
+    canvas.setSource(QUrl::fromLocalFile(TESTDATA("creationContext.qml")));
+
+    QQuickItem *rootItem = qobject_cast<QQuickItem *>(canvas.rootObject());
+    QVERIFY(rootItem);
+    QVERIFY(rootItem->property("count").toInt() > 0);
+
+    QQuickItem *item;
+    QVERIFY(item = findItem<QQuickItem>(rootItem, "listItem", 0));
+    QCOMPARE(item->property("text").toString(), QString("Hello!"));
+}
+
+QQuickView *tst_QQuickPathView::createView()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setGeometry(0,0,240,320);
+
+    return canvas;
+}
+
+/*
+   Find an item with the specified objectName.  If index is supplied then the
+   item must also evaluate the {index} expression equal to index
+ */
+template<typename T>
+T *tst_QQuickPathView::findItem(QQuickItem *parent, const QString &objectName, int index)
+{
+    const QMetaObject &mo = T::staticMetaObject;
+    //qDebug() << parent->childItems().count() << "children";
+    for (int i = 0; i < parent->childItems().count(); ++i) {
+        QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
+        if (!item)
+            continue;
+        //qDebug() << "try" << item;
+        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
+            if (index != -1) {
+                QDeclarativeExpression e(qmlContext(item), item, "index");
+                if (e.evaluate().toInt() == index)
+                    return static_cast<T*>(item);
+            } else {
+                return static_cast<T*>(item);
+            }
+        }
+        item = findItem<T>(item, objectName, index);
+        if (item)
+            return static_cast<T*>(item);
+    }
+
+    return 0;
+}
+
+template<typename T>
+QList<T*> tst_QQuickPathView::findItems(QQuickItem *parent, const QString &objectName)
+{
+    QList<T*> items;
+    const QMetaObject &mo = T::staticMetaObject;
+    //qDebug() << parent->QQuickItem::children().count() << "children";
+    for (int i = 0; i < parent->childItems().count(); ++i) {
+        QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
+        if (!item)
+            continue;
+        //qDebug() << "try" << item;
+        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName))
+            items.append(static_cast<T*>(item));
+        items += findItems<T>(item, objectName);
+    }
+
+    return items;
+}
+
+void tst_QQuickPathView::missingPercent()
+{
+    QDeclarativeEngine engine;
+    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));
+    delete obj;
+}
+
+
+QTEST_MAIN(tst_QQuickPathView)
+
+#include "tst_qquickpathview.moc"
diff --git a/tests/auto/declarative/qquickpincharea/qquickpincharea.pro b/tests/auto/declarative/qquickpincharea/qquickpincharea.pro
new file mode 100644 (file)
index 0000000..df750fb
--- /dev/null
@@ -0,0 +1,13 @@
+CONFIG += testcase
+TARGET = tst_qquickpincharea
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qquickpincharea.cpp
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qquickpincharea/tst_qquickpincharea.cpp b/tests/auto/declarative/qquickpincharea/tst_qquickpincharea.cpp
new file mode 100644 (file)
index 0000000..0d6126e
--- /dev/null
@@ -0,0 +1,395 @@
+/****************************************************************************
+**
+** 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 <private/qquickpincharea_p.h>
+#include <private/qquickrectangle_p.h>
+#include <QtDeclarative/qquickview.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include "../shared/util.h"
+
+class tst_QQuickPinchArea: public QObject
+{
+    Q_OBJECT
+private slots:
+    void initTestCase();
+    void cleanupTestCase();
+    void pinchProperties();
+    void scale();
+    void pan();
+    void retouch();
+
+private:
+    QQuickView *createView();
+};
+void tst_QQuickPinchArea::initTestCase()
+{
+}
+
+void tst_QQuickPinchArea::cleanupTestCase()
+{
+
+}
+void tst_QQuickPinchArea::pinchProperties()
+{
+    QQuickView *canvas = createView();
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QVERIFY(canvas->rootObject() != 0);
+
+    QQuickPinchArea *pinchArea = canvas->rootObject()->findChild<QQuickPinchArea*>("pincharea");
+    QQuickPinch *pinch = pinchArea->pinch();
+    QVERIFY(pinchArea != 0);
+    QVERIFY(pinch != 0);
+
+    // target
+    QQuickItem *blackRect = canvas->rootObject()->findChild<QQuickItem*>("blackrect");
+    QVERIFY(blackRect != 0);
+    QVERIFY(blackRect == pinch->target());
+    QQuickItem *rootItem = qobject_cast<QQuickItem*>(canvas->rootObject());
+    QVERIFY(rootItem != 0);
+    QSignalSpy targetSpy(pinch, SIGNAL(targetChanged()));
+    pinch->setTarget(rootItem);
+    QCOMPARE(targetSpy.count(),1);
+    pinch->setTarget(rootItem);
+    QCOMPARE(targetSpy.count(),1);
+
+    // axis
+    QCOMPARE(pinch->axis(), QQuickPinch::XandYAxis);
+    QSignalSpy axisSpy(pinch, SIGNAL(dragAxisChanged()));
+    pinch->setAxis(QQuickPinch::XAxis);
+    QCOMPARE(pinch->axis(), QQuickPinch::XAxis);
+    QCOMPARE(axisSpy.count(),1);
+    pinch->setAxis(QQuickPinch::XAxis);
+    QCOMPARE(axisSpy.count(),1);
+
+    // minimum and maximum drag properties
+    QSignalSpy xminSpy(pinch, SIGNAL(minimumXChanged()));
+    QSignalSpy xmaxSpy(pinch, SIGNAL(maximumXChanged()));
+    QSignalSpy yminSpy(pinch, SIGNAL(minimumYChanged()));
+    QSignalSpy ymaxSpy(pinch, SIGNAL(maximumYChanged()));
+
+    QCOMPARE(pinch->xmin(), 0.0);
+    QCOMPARE(pinch->xmax(), rootItem->width()-blackRect->width());
+    QCOMPARE(pinch->ymin(), 0.0);
+    QCOMPARE(pinch->ymax(), rootItem->height()-blackRect->height());
+
+    pinch->setXmin(10);
+    pinch->setXmax(10);
+    pinch->setYmin(10);
+    pinch->setYmax(10);
+
+    QCOMPARE(pinch->xmin(), 10.0);
+    QCOMPARE(pinch->xmax(), 10.0);
+    QCOMPARE(pinch->ymin(), 10.0);
+    QCOMPARE(pinch->ymax(), 10.0);
+
+    QCOMPARE(xminSpy.count(),1);
+    QCOMPARE(xmaxSpy.count(),1);
+    QCOMPARE(yminSpy.count(),1);
+    QCOMPARE(ymaxSpy.count(),1);
+
+    pinch->setXmin(10);
+    pinch->setXmax(10);
+    pinch->setYmin(10);
+    pinch->setYmax(10);
+
+    QCOMPARE(xminSpy.count(),1);
+    QCOMPARE(xmaxSpy.count(),1);
+    QCOMPARE(yminSpy.count(),1);
+    QCOMPARE(ymaxSpy.count(),1);
+
+    // minimum and maximum scale properties
+    QSignalSpy scaleMinSpy(pinch, SIGNAL(minimumScaleChanged()));
+    QSignalSpy scaleMaxSpy(pinch, SIGNAL(maximumScaleChanged()));
+
+    QCOMPARE(pinch->minimumScale(), 1.0);
+    QCOMPARE(pinch->maximumScale(), 2.0);
+
+    pinch->setMinimumScale(0.5);
+    pinch->setMaximumScale(1.5);
+
+    QCOMPARE(pinch->minimumScale(), 0.5);
+    QCOMPARE(pinch->maximumScale(), 1.5);
+
+    QCOMPARE(scaleMinSpy.count(),1);
+    QCOMPARE(scaleMaxSpy.count(),1);
+
+    pinch->setMinimumScale(0.5);
+    pinch->setMaximumScale(1.5);
+
+    QCOMPARE(scaleMinSpy.count(),1);
+    QCOMPARE(scaleMaxSpy.count(),1);
+
+    // minimum and maximum rotation properties
+    QSignalSpy rotMinSpy(pinch, SIGNAL(minimumRotationChanged()));
+    QSignalSpy rotMaxSpy(pinch, SIGNAL(maximumRotationChanged()));
+
+    QCOMPARE(pinch->minimumRotation(), 0.0);
+    QCOMPARE(pinch->maximumRotation(), 90.0);
+
+    pinch->setMinimumRotation(-90.0);
+    pinch->setMaximumRotation(45.0);
+
+    QCOMPARE(pinch->minimumRotation(), -90.0);
+    QCOMPARE(pinch->maximumRotation(), 45.0);
+
+    QCOMPARE(rotMinSpy.count(),1);
+    QCOMPARE(rotMaxSpy.count(),1);
+
+    pinch->setMinimumRotation(-90.0);
+    pinch->setMaximumRotation(45.0);
+
+    QCOMPARE(rotMinSpy.count(),1);
+    QCOMPARE(rotMaxSpy.count(),1);
+
+    delete canvas;
+}
+
+QTouchEvent::TouchPoint makeTouchPoint(int id, QPoint p, QQuickView *v, QQuickItem *i)
+{
+    QTouchEvent::TouchPoint touchPoint(id);
+    touchPoint.setPos(i->mapFromScene(p));
+    touchPoint.setScreenPos(v->mapToGlobal(p));
+    touchPoint.setScenePos(p);
+    return touchPoint;
+}
+
+void tst_QQuickPinchArea::scale()
+{
+    QQuickView *canvas = createView();
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QTest::qWaitForWindowShown(canvas);
+    QVERIFY(canvas->rootObject() != 0);
+    qApp->processEvents();
+
+    QQuickPinchArea *pinchArea = canvas->rootObject()->findChild<QQuickPinchArea*>("pincharea");
+    QQuickPinch *pinch = pinchArea->pinch();
+    QVERIFY(pinchArea != 0);
+    QVERIFY(pinch != 0);
+
+    QQuickItem *root = qobject_cast<QQuickItem*>(canvas->rootObject());
+    QVERIFY(root != 0);
+
+    // target
+    QQuickItem *blackRect = canvas->rootObject()->findChild<QQuickItem*>("blackrect");
+    QVERIFY(blackRect != 0);
+
+    QPoint p1(80, 80);
+    QPoint p2(100, 100);
+
+    QTest::touchEvent(canvas).press(0, p1, canvas);
+    QTest::touchEvent(canvas).stationary(0).press(1, p2, canvas);
+    p1 -= QPoint(10,10);
+    p2 += QPoint(10,10);
+    QTest::touchEvent(canvas).move(0, p1,canvas).move(1, p2,canvas);
+
+    QCOMPARE(root->property("scale").toReal(), 1.0);
+
+    p1 -= QPoint(10,10);
+    p2 += QPoint(10,10);
+    QTest::touchEvent(canvas).move(0, p1,canvas).move(1, p2,canvas);
+
+    QCOMPARE(root->property("scale").toReal(), 1.5);
+    QCOMPARE(root->property("center").toPointF(), QPointF(40, 40)); // blackrect is at 50,50
+    QCOMPARE(blackRect->scale(), 1.5);
+
+    // scale beyond bound
+    p1 -= QPoint(50,50);
+    p2 += QPoint(50,50);
+    QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas);
+
+    QCOMPARE(blackRect->scale(), 2.0);
+
+    QTest::touchEvent(canvas).release(0, p1, canvas).release(1, p2, canvas);
+
+    delete canvas;
+}
+
+void tst_QQuickPinchArea::pan()
+{
+    QQuickView *canvas = createView();
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QTest::qWaitForWindowShown(canvas);
+    QVERIFY(canvas->rootObject() != 0);
+    qApp->processEvents();
+
+    QQuickPinchArea *pinchArea = canvas->rootObject()->findChild<QQuickPinchArea*>("pincharea");
+    QQuickPinch *pinch = pinchArea->pinch();
+    QVERIFY(pinchArea != 0);
+    QVERIFY(pinch != 0);
+
+    QQuickItem *root = qobject_cast<QQuickItem*>(canvas->rootObject());
+    QVERIFY(root != 0);
+
+    // target
+    QQuickItem *blackRect = canvas->rootObject()->findChild<QQuickItem*>("blackrect");
+    QVERIFY(blackRect != 0);
+
+    QPoint p1(80, 80);
+    QPoint p2(100, 100);
+
+    QTest::touchEvent(canvas).press(0, p1, canvas);
+    QTest::touchEvent(canvas).stationary(0).press(1, p2, canvas);
+    p1 += QPoint(10,10);
+    p2 += QPoint(10,10);
+    QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas);
+
+    QCOMPARE(root->property("scale").toReal(), 1.0);
+
+    p1 += QPoint(10,10);
+    p2 += QPoint(10,10);
+    QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas);
+
+    QCOMPARE(root->property("center").toPointF(), QPointF(60, 60)); // blackrect is at 50,50
+
+    QCOMPARE(blackRect->x(), 60.0);
+    QCOMPARE(blackRect->y(), 60.0);
+
+    // pan x beyond bound
+    p1 += QPoint(100,100);
+    p2 += QPoint(100,100);
+    QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas);
+
+    QCOMPARE(blackRect->x(), 140.0);
+    QCOMPARE(blackRect->y(), 160.0);
+
+    QTest::touchEvent(canvas).release(0, p1, canvas).release(1, p2, canvas);
+
+    delete canvas;
+}
+
+// test pinch, release one point, touch again to continue pinch
+void tst_QQuickPinchArea::retouch()
+{
+    QQuickView *canvas = createView();
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml")));
+    canvas->show();
+    canvas->requestActivateWindow();
+    QTest::qWaitForWindowShown(canvas);
+    QVERIFY(canvas->rootObject() != 0);
+    qApp->processEvents();
+
+    QQuickPinchArea *pinchArea = canvas->rootObject()->findChild<QQuickPinchArea*>("pincharea");
+    QQuickPinch *pinch = pinchArea->pinch();
+    QVERIFY(pinchArea != 0);
+    QVERIFY(pinch != 0);
+
+    QQuickItem *root = qobject_cast<QQuickItem*>(canvas->rootObject());
+    QVERIFY(root != 0);
+
+    QSignalSpy startedSpy(pinchArea, SIGNAL(pinchStarted(QQuickPinchEvent *)));
+    QSignalSpy finishedSpy(pinchArea, SIGNAL(pinchFinished(QQuickPinchEvent *)));
+
+    // target
+    QQuickItem *blackRect = canvas->rootObject()->findChild<QQuickItem*>("blackrect");
+    QVERIFY(blackRect != 0);
+
+    QPoint p1(80, 80);
+    QPoint p2(100, 100);
+
+    QTest::touchEvent(canvas).press(0, p1, canvas);
+    QTest::touchEvent(canvas).stationary(0).press(1, p2, canvas);
+    p1 -= QPoint(10,10);
+    p2 += QPoint(10,10);
+    QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas);
+
+    QCOMPARE(root->property("scale").toReal(), 1.0);
+
+    p1 -= QPoint(10,10);
+    p2 += QPoint(10,10);
+    QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas);
+
+    QCOMPARE(startedSpy.count(), 1);
+
+    QCOMPARE(root->property("scale").toReal(), 1.5);
+    QCOMPARE(root->property("center").toPointF(), QPointF(40, 40)); // blackrect is at 50,50
+    QCOMPARE(blackRect->scale(), 1.5);
+
+    QCOMPARE(canvas->rootObject()->property("pointCount").toInt(), 2);
+
+    QCOMPARE(startedSpy.count(), 1);
+    QCOMPARE(finishedSpy.count(), 0);
+
+    QTest::touchEvent(canvas).stationary(0).release(1, p2, canvas);
+
+    QCOMPARE(startedSpy.count(), 1);
+    QCOMPARE(finishedSpy.count(), 0);
+
+    QCOMPARE(canvas->rootObject()->property("pointCount").toInt(), 1);
+
+    QTest::touchEvent(canvas).stationary(0).press(1, p2, canvas);
+    p1 -= QPoint(10,10);
+    p2 += QPoint(10,10);
+    QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas);
+
+    // Lifting and retouching results in onPinchStarted being called again
+    QCOMPARE(startedSpy.count(), 2);
+    QCOMPARE(finishedSpy.count(), 0);
+
+    QCOMPARE(canvas->rootObject()->property("pointCount").toInt(), 2);
+
+    QTest::touchEvent(canvas).release(0, p1, canvas).release(1, p2, canvas);
+
+    QCOMPARE(startedSpy.count(), 2);
+    QCOMPARE(finishedSpy.count(), 1);
+
+    delete canvas;
+}
+
+
+QQuickView *tst_QQuickPinchArea::createView()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setGeometry(0,0,240,320);
+
+    return canvas;
+}
+
+QTEST_MAIN(tst_QQuickPinchArea)
+
+#include "tst_qquickpincharea.moc"
diff --git a/tests/auto/declarative/qquickpositioners/qquickpositioners.pro b/tests/auto/declarative/qquickpositioners/qquickpositioners.pro
new file mode 100644 (file)
index 0000000..eee9eca
--- /dev/null
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qquickpositioners
+SOURCES += tst_qquickpositioners.cpp
+macx:CONFIG -= app_bundle
+
+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/qquickpositioners/tst_qquickpositioners.cpp b/tests/auto/declarative/qquickpositioners/tst_qquickpositioners.cpp
new file mode 100644 (file)
index 0000000..1d3ccab
--- /dev/null
@@ -0,0 +1,1476 @@
+/****************************************************************************
+**
+** 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 <private/qlistmodelinterface_p.h>
+#include <qquickview.h>
+#include <qdeclarativeengine.h>
+#include <private/qquickrectangle_p.h>
+#include <private/qquickpositioners_p.h>
+#include <private/qdeclarativetransition_p.h>
+#include <private/qquickitem_p.h>
+#include <qdeclarativeexpression.h>
+#include "../shared/util.h"
+
+class tst_qquickpositioners : public QObject
+{
+    Q_OBJECT
+public:
+    tst_qquickpositioners();
+
+private slots:
+    void test_horizontal();
+    void test_horizontal_rtl();
+    void test_horizontal_spacing();
+    void test_horizontal_spacing_rightToLeft();
+    void test_horizontal_animated();
+    void test_horizontal_animated_rightToLeft();
+    void test_horizontal_animated_disabled();
+    void test_vertical();
+    void test_vertical_spacing();
+    void test_vertical_animated();
+    void test_grid();
+    void test_grid_topToBottom();
+    void test_grid_rightToLeft();
+    void test_grid_spacing();
+    void test_grid_row_column_spacing();
+    void test_grid_animated();
+    void test_grid_animated_rightToLeft();
+    void test_grid_zero_columns();
+    void test_propertychanges();
+    void test_repeater();
+    void test_flow();
+    void test_flow_rightToLeft();
+    void test_flow_topToBottom();
+    void test_flow_resize();
+    void test_flow_resize_rightToLeft();
+    void test_flow_implicit_resize();
+    void test_conflictinganchors();
+    void test_mirroring();
+    void test_allInvisible();
+    void test_attachedproperties();
+    void test_attachedproperties_data();
+    void test_attachedproperties_dynamic();
+
+private:
+    QQuickView *createView(const QString &filename, bool wait=true);
+};
+
+tst_qquickpositioners::tst_qquickpositioners()
+{
+}
+
+void tst_qquickpositioners::test_horizontal()
+{
+    QQuickView *canvas = createView(TESTDATA("horizontal.qml"));
+
+    canvas->rootObject()->setProperty("testRightToLeft", false);
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+
+    QCOMPARE(one->x(), 0.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 50.0);
+    QCOMPARE(two->y(), 0.0);
+    QCOMPARE(three->x(), 70.0);
+    QCOMPARE(three->y(), 0.0);
+
+    QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
+    QCOMPARE(row->width(), 110.0);
+    QCOMPARE(row->height(), 50.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_horizontal_rtl()
+{
+    QQuickView *canvas = createView(TESTDATA("horizontal.qml"));
+
+    canvas->rootObject()->setProperty("testRightToLeft", true);
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+
+    QCOMPARE(one->x(), 60.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 40.0);
+    QCOMPARE(two->y(), 0.0);
+    QCOMPARE(three->x(), 0.0);
+    QCOMPARE(three->y(), 0.0);
+
+    QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
+    QCOMPARE(row->width(), 110.0);
+    QCOMPARE(row->height(), 50.0);
+
+    // Change the width of the row and check that items stay to the right
+    row->setWidth(200);
+    QTRY_COMPARE(one->x(), 150.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 130.0);
+    QCOMPARE(two->y(), 0.0);
+    QCOMPARE(three->x(), 90.0);
+    QCOMPARE(three->y(), 0.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_horizontal_spacing()
+{
+    QQuickView *canvas = createView(TESTDATA("horizontal-spacing.qml"));
+
+    canvas->rootObject()->setProperty("testRightToLeft", false);
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+
+    QCOMPARE(one->x(), 0.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 60.0);
+    QCOMPARE(two->y(), 0.0);
+    QCOMPARE(three->x(), 90.0);
+    QCOMPARE(three->y(), 0.0);
+
+    QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
+    QCOMPARE(row->width(), 130.0);
+    QCOMPARE(row->height(), 50.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_horizontal_spacing_rightToLeft()
+{
+    QQuickView *canvas = createView(TESTDATA("horizontal-spacing.qml"));
+
+    canvas->rootObject()->setProperty("testRightToLeft", true);
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+
+    QCOMPARE(one->x(), 80.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 50.0);
+    QCOMPARE(two->y(), 0.0);
+    QCOMPARE(three->x(), 00.0);
+    QCOMPARE(three->y(), 0.0);
+
+    QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
+    QCOMPARE(row->width(), 130.0);
+    QCOMPARE(row->height(), 50.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_horizontal_animated()
+{
+    QQuickView *canvas = createView(TESTDATA("horizontal-animated.qml"), false);
+
+    canvas->rootObject()->setProperty("testRightToLeft", false);
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+
+    //Note that they animate in
+    QCOMPARE(one->x(), -100.0);
+    QCOMPARE(two->x(), -100.0);
+    QCOMPARE(three->x(), -100.0);
+
+    QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
+
+    QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
+    QVERIFY(row);
+    QCOMPARE(row->width(), 100.0);
+    QCOMPARE(row->height(), 50.0);
+
+    //QTRY_COMPARE used instead of waiting for the expected time of animation completion
+    //Note that this means the duration of the animation is NOT tested
+
+    QTRY_COMPARE(one->x(), 0.0);
+    QTRY_COMPARE(one->y(), 0.0);
+    QTRY_COMPARE(two->isVisible(), false);
+    QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet
+    QTRY_COMPARE(two->y(), 0.0);
+    QTRY_COMPARE(three->x(), 50.0);
+    QTRY_COMPARE(three->y(), 0.0);
+
+    //Add 'two'
+    two->setVisible(true);
+    QTRY_COMPARE(two->isVisible(), true);
+    QTRY_COMPARE(row->width(), 150.0);
+    QTRY_COMPARE(row->height(), 50.0);
+
+    QTest::qWait(0);//Let the animation start
+    QCOMPARE(two->x(), -100.0);
+    QCOMPARE(three->x(), 50.0);
+
+    QTRY_COMPARE(two->x(), 50.0);
+    QTRY_COMPARE(three->x(), 100.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_horizontal_animated_rightToLeft()
+{
+    QQuickView *canvas = createView(TESTDATA("horizontal-animated.qml"), false);
+
+    canvas->rootObject()->setProperty("testRightToLeft", true);
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+
+    //Note that they animate in
+    QCOMPARE(one->x(), -100.0);
+    QCOMPARE(two->x(), -100.0);
+    QCOMPARE(three->x(), -100.0);
+
+    QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
+
+    QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
+    QVERIFY(row);
+    QCOMPARE(row->width(), 100.0);
+    QCOMPARE(row->height(), 50.0);
+
+    //QTRY_COMPARE used instead of waiting for the expected time of animation completion
+    //Note that this means the duration of the animation is NOT tested
+
+    QTRY_COMPARE(one->x(), 50.0);
+    QTRY_COMPARE(one->y(), 0.0);
+    QTRY_COMPARE(two->isVisible(), false);
+    QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet
+    QTRY_COMPARE(two->y(), 0.0);
+    QTRY_COMPARE(three->x(), 0.0);
+    QTRY_COMPARE(three->y(), 0.0);
+
+    //Add 'two'
+    two->setVisible(true);
+    QTRY_COMPARE(two->isVisible(), true);
+
+    // New size should propagate after visible change
+    QTRY_COMPARE(row->width(), 150.0);
+    QTRY_COMPARE(row->height(), 50.0);
+
+    QTest::qWait(0);//Let the animation start
+    QCOMPARE(one->x(), 50.0);
+    QCOMPARE(two->x(), -100.0);
+
+    QTRY_COMPARE(one->x(), 100.0);
+    QTRY_COMPARE(two->x(), 50.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_horizontal_animated_disabled()
+{
+    QQuickView *canvas = createView(TESTDATA("horizontal-animated-disabled.qml"));
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+
+    QQuickItem *row = canvas->rootObject()->findChild<QQuickItem*>("row");
+    QVERIFY(row);
+
+    qApp->processEvents();
+
+    QCOMPARE(one->x(), 0.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->isVisible(), false);
+    QCOMPARE(two->x(), -100.0);//Not 'in' yet
+    QCOMPARE(two->y(), 0.0);
+    QCOMPARE(three->x(), 50.0);
+    QCOMPARE(three->y(), 0.0);
+
+    //Add 'two'
+    two->setVisible(true);
+    QCOMPARE(two->isVisible(), true);
+    qApp->processEvents();
+    QCOMPARE(row->width(), 150.0);
+    QCOMPARE(row->height(), 50.0);
+
+    qApp->processEvents();
+    QCOMPARE(two->x(), 50.0);
+    QCOMPARE(three->x(), 100.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_vertical()
+{
+    QQuickView *canvas = createView(TESTDATA("vertical.qml"));
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+
+    QCOMPARE(one->x(), 0.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 0.0);
+    QCOMPARE(two->y(), 50.0);
+    QCOMPARE(three->x(), 0.0);
+    QCOMPARE(three->y(), 60.0);
+
+    QQuickItem *column = canvas->rootObject()->findChild<QQuickItem*>("column");
+    QVERIFY(column);
+    QCOMPARE(column->height(), 80.0);
+    QCOMPARE(column->width(), 50.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_vertical_spacing()
+{
+    QQuickView *canvas = createView(TESTDATA("vertical-spacing.qml"));
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+
+    QCOMPARE(one->x(), 0.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 0.0);
+    QCOMPARE(two->y(), 60.0);
+    QCOMPARE(three->x(), 0.0);
+    QCOMPARE(three->y(), 80.0);
+
+    QQuickItem *column = canvas->rootObject()->findChild<QQuickItem*>("column");
+    QCOMPARE(column->height(), 100.0);
+    QCOMPARE(column->width(), 50.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_vertical_animated()
+{
+    QQuickView *canvas = createView(TESTDATA("vertical-animated.qml"), false);
+
+    //Note that they animate in
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+    QCOMPARE(one->y(), -100.0);
+
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+    QCOMPARE(two->y(), -100.0);
+
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+    QCOMPARE(three->y(), -100.0);
+
+    QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
+
+    QQuickItem *column = canvas->rootObject()->findChild<QQuickItem*>("column");
+    QVERIFY(column);
+    QCOMPARE(column->height(), 100.0);
+    QCOMPARE(column->width(), 50.0);
+
+    //QTRY_COMPARE used instead of waiting for the expected time of animation completion
+    //Note that this means the duration of the animation is NOT tested
+
+    QTRY_COMPARE(one->y(), 0.0);
+    QTRY_COMPARE(one->x(), 0.0);
+    QTRY_COMPARE(two->isVisible(), false);
+    QTRY_COMPARE(two->y(), -100.0);//Not 'in' yet
+    QTRY_COMPARE(two->x(), 0.0);
+    QTRY_COMPARE(three->y(), 50.0);
+    QTRY_COMPARE(three->x(), 0.0);
+
+    //Add 'two'
+    two->setVisible(true);
+    QTRY_COMPARE(two->isVisible(), true);
+    QTRY_COMPARE(column->height(), 150.0);
+    QTRY_COMPARE(column->width(), 50.0);
+    QTest::qWait(0);//Let the animation start
+    QCOMPARE(two->y(), -100.0);
+    QCOMPARE(three->y(), 50.0);
+
+    QTRY_COMPARE(two->y(), 50.0);
+    QTRY_COMPARE(three->y(), 100.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_grid()
+{
+    QQuickView *canvas = createView(TESTDATA("gridtest.qml"));
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+    QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+    QVERIFY(four != 0);
+    QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+    QVERIFY(five != 0);
+
+    QCOMPARE(one->x(), 0.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 50.0);
+    QCOMPARE(two->y(), 0.0);
+    QCOMPARE(three->x(), 70.0);
+    QCOMPARE(three->y(), 0.0);
+    QCOMPARE(four->x(), 0.0);
+    QCOMPARE(four->y(), 50.0);
+    QCOMPARE(five->x(), 50.0);
+    QCOMPARE(five->y(), 50.0);
+
+    QQuickGrid *grid = canvas->rootObject()->findChild<QQuickGrid*>("grid");
+    QCOMPARE(grid->flow(), QQuickGrid::LeftToRight);
+    QCOMPARE(grid->width(), 100.0);
+    QCOMPARE(grid->height(), 100.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_grid_topToBottom()
+{
+    QQuickView *canvas = createView(TESTDATA("grid-toptobottom.qml"));
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+    QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+    QVERIFY(four != 0);
+    QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+    QVERIFY(five != 0);
+
+    QCOMPARE(one->x(), 0.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 0.0);
+    QCOMPARE(two->y(), 50.0);
+    QCOMPARE(three->x(), 0.0);
+    QCOMPARE(three->y(), 100.0);
+    QCOMPARE(four->x(), 50.0);
+    QCOMPARE(four->y(), 0.0);
+    QCOMPARE(five->x(), 50.0);
+    QCOMPARE(five->y(), 50.0);
+
+    QQuickGrid *grid = canvas->rootObject()->findChild<QQuickGrid*>("grid");
+    QCOMPARE(grid->flow(), QQuickGrid::TopToBottom);
+    QCOMPARE(grid->width(), 100.0);
+    QCOMPARE(grid->height(), 120.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_grid_rightToLeft()
+{
+    QQuickView *canvas = createView(TESTDATA("gridtest.qml"));
+
+    canvas->rootObject()->setProperty("testRightToLeft", true);
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+    QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+    QVERIFY(four != 0);
+    QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+    QVERIFY(five != 0);
+
+    QCOMPARE(one->x(), 50.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 30.0);
+    QCOMPARE(two->y(), 0.0);
+    QCOMPARE(three->x(), 0.0);
+    QCOMPARE(three->y(), 0.0);
+    QCOMPARE(four->x(), 50.0);
+    QCOMPARE(four->y(), 50.0);
+    QCOMPARE(five->x(), 40.0);
+    QCOMPARE(five->y(), 50.0);
+
+    QQuickGrid *grid = canvas->rootObject()->findChild<QQuickGrid*>("grid");
+    QCOMPARE(grid->layoutDirection(), Qt::RightToLeft);
+    QCOMPARE(grid->width(), 100.0);
+    QCOMPARE(grid->height(), 100.0);
+
+    // Change the width of the grid and check that items stay to the right
+    grid->setWidth(200);
+    QTRY_COMPARE(one->x(), 150.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 130.0);
+    QCOMPARE(two->y(), 0.0);
+    QCOMPARE(three->x(), 100.0);
+    QCOMPARE(three->y(), 0.0);
+    QCOMPARE(four->x(), 150.0);
+    QCOMPARE(four->y(), 50.0);
+    QCOMPARE(five->x(), 140.0);
+    QCOMPARE(five->y(), 50.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_grid_spacing()
+{
+    QQuickView *canvas = createView(TESTDATA("grid-spacing.qml"));
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+    QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+    QVERIFY(four != 0);
+    QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+    QVERIFY(five != 0);
+
+    QCOMPARE(one->x(), 0.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 54.0);
+    QCOMPARE(two->y(), 0.0);
+    QCOMPARE(three->x(), 78.0);
+    QCOMPARE(three->y(), 0.0);
+    QCOMPARE(four->x(), 0.0);
+    QCOMPARE(four->y(), 54.0);
+    QCOMPARE(five->x(), 54.0);
+    QCOMPARE(five->y(), 54.0);
+
+    QQuickItem *grid = canvas->rootObject()->findChild<QQuickItem*>("grid");
+    QCOMPARE(grid->width(), 128.0);
+    QCOMPARE(grid->height(), 104.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_grid_row_column_spacing()
+{
+    QQuickView *canvas = createView(TESTDATA("grid-row-column-spacing.qml"));
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+    QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+    QVERIFY(four != 0);
+    QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+    QVERIFY(five != 0);
+
+    QCOMPARE(one->x(), 0.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 61.0);
+    QCOMPARE(two->y(), 0.0);
+    QCOMPARE(three->x(), 92.0);
+    QCOMPARE(three->y(), 0.0);
+    QCOMPARE(four->x(), 0.0);
+    QCOMPARE(four->y(), 57.0);
+    QCOMPARE(five->x(), 61.0);
+    QCOMPARE(five->y(), 57.0);
+
+    QQuickItem *grid = canvas->rootObject()->findChild<QQuickItem*>("grid");
+    QCOMPARE(grid->width(), 142.0);
+    QCOMPARE(grid->height(), 107.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_grid_animated()
+{
+    QQuickView *canvas = createView(TESTDATA("grid-animated.qml"), false);
+
+    canvas->rootObject()->setProperty("testRightToLeft", false);
+
+    //Note that all animate in
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+    QCOMPARE(one->x(), -100.0);
+    QCOMPARE(one->y(), -100.0);
+
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+    QCOMPARE(two->x(), -100.0);
+    QCOMPARE(two->y(), -100.0);
+
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+    QCOMPARE(three->x(), -100.0);
+    QCOMPARE(three->y(), -100.0);
+
+    QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+    QVERIFY(four != 0);
+    QCOMPARE(four->x(), -100.0);
+    QCOMPARE(four->y(), -100.0);
+
+    QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+    QVERIFY(five != 0);
+    QCOMPARE(five->x(), -100.0);
+    QCOMPARE(five->y(), -100.0);
+
+    QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
+
+    QQuickItem *grid = canvas->rootObject()->findChild<QQuickItem*>("grid");
+    QVERIFY(grid);
+    QCOMPARE(grid->width(), 150.0);
+    QCOMPARE(grid->height(), 100.0);
+
+    //QTRY_COMPARE used instead of waiting for the expected time of animation completion
+    //Note that this means the duration of the animation is NOT tested
+
+    QTRY_COMPARE(one->y(), 0.0);
+    QTRY_COMPARE(one->x(), 0.0);
+    QTRY_COMPARE(two->isVisible(), false);
+    QTRY_COMPARE(two->y(), -100.0);
+    QTRY_COMPARE(two->x(), -100.0);
+    QTRY_COMPARE(three->y(), 0.0);
+    QTRY_COMPARE(three->x(), 50.0);
+    QTRY_COMPARE(four->y(), 0.0);
+    QTRY_COMPARE(four->x(), 100.0);
+    QTRY_COMPARE(five->y(), 50.0);
+    QTRY_COMPARE(five->x(), 0.0);
+
+    //Add 'two'
+    two->setVisible(true);
+    QCOMPARE(two->isVisible(), true);
+    QCOMPARE(grid->width(), 150.0);
+    QCOMPARE(grid->height(), 100.0);
+    QTest::qWait(0);//Let the animation start
+    QCOMPARE(two->x(), -100.0);
+    QCOMPARE(two->y(), -100.0);
+    QCOMPARE(one->x(), 0.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(three->x(), 50.0);
+    QCOMPARE(three->y(), 0.0);
+    QCOMPARE(four->x(), 100.0);
+    QCOMPARE(four->y(), 0.0);
+    QCOMPARE(five->x(), 0.0);
+    QCOMPARE(five->y(), 50.0);
+    //Let the animation complete
+    QTRY_COMPARE(two->x(), 50.0);
+    QTRY_COMPARE(two->y(), 0.0);
+    QTRY_COMPARE(one->x(), 0.0);
+    QTRY_COMPARE(one->y(), 0.0);
+    QTRY_COMPARE(three->x(), 100.0);
+    QTRY_COMPARE(three->y(), 0.0);
+    QTRY_COMPARE(four->x(), 0.0);
+    QTRY_COMPARE(four->y(), 50.0);
+    QTRY_COMPARE(five->x(), 50.0);
+    QTRY_COMPARE(five->y(), 50.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_grid_animated_rightToLeft()
+{
+    QQuickView *canvas = createView(TESTDATA("grid-animated.qml"), false);
+
+    canvas->rootObject()->setProperty("testRightToLeft", true);
+
+    //Note that all animate in
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+    QCOMPARE(one->x(), -100.0);
+    QCOMPARE(one->y(), -100.0);
+
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+    QCOMPARE(two->x(), -100.0);
+    QCOMPARE(two->y(), -100.0);
+
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+    QCOMPARE(three->x(), -100.0);
+    QCOMPARE(three->y(), -100.0);
+
+    QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+    QVERIFY(four != 0);
+    QCOMPARE(four->x(), -100.0);
+    QCOMPARE(four->y(), -100.0);
+
+    QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+    QVERIFY(five != 0);
+    QCOMPARE(five->x(), -100.0);
+    QCOMPARE(five->y(), -100.0);
+
+    QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
+
+    QQuickItem *grid = canvas->rootObject()->findChild<QQuickItem*>("grid");
+    QVERIFY(grid);
+    QCOMPARE(grid->width(), 150.0);
+    QCOMPARE(grid->height(), 100.0);
+
+    //QTRY_COMPARE used instead of waiting for the expected time of animation completion
+    //Note that this means the duration of the animation is NOT tested
+
+    QTRY_COMPARE(one->y(), 0.0);
+    QTRY_COMPARE(one->x(), 100.0);
+    QTRY_COMPARE(two->isVisible(), false);
+    QTRY_COMPARE(two->y(), -100.0);
+    QTRY_COMPARE(two->x(), -100.0);
+    QTRY_COMPARE(three->y(), 0.0);
+    QTRY_COMPARE(three->x(), 50.0);
+    QTRY_COMPARE(four->y(), 0.0);
+    QTRY_COMPARE(four->x(), 0.0);
+    QTRY_COMPARE(five->y(), 50.0);
+    QTRY_COMPARE(five->x(), 100.0);
+
+    //Add 'two'
+    two->setVisible(true);
+    QCOMPARE(two->isVisible(), true);
+    QCOMPARE(grid->width(), 150.0);
+    QCOMPARE(grid->height(), 100.0);
+    QTest::qWait(0);//Let the animation start
+    QCOMPARE(two->x(), -100.0);
+    QCOMPARE(two->y(), -100.0);
+    QCOMPARE(one->x(), 100.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(three->x(), 50.0);
+    QCOMPARE(three->y(), 0.0);
+    QCOMPARE(four->x(), 0.0);
+    QCOMPARE(four->y(), 0.0);
+    QCOMPARE(five->x(), 100.0);
+    QCOMPARE(five->y(), 50.0);
+    //Let the animation complete
+    QTRY_COMPARE(two->x(), 50.0);
+    QTRY_COMPARE(two->y(), 0.0);
+    QTRY_COMPARE(one->x(), 100.0);
+    QTRY_COMPARE(one->y(), 0.0);
+    QTRY_COMPARE(three->x(), 0.0);
+    QTRY_COMPARE(three->y(), 0.0);
+    QTRY_COMPARE(four->x(), 100.0);
+    QTRY_COMPARE(four->y(), 50.0);
+    QTRY_COMPARE(five->x(), 50.0);
+    QTRY_COMPARE(five->y(), 50.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_grid_zero_columns()
+{
+    QQuickView *canvas = createView(TESTDATA("gridzerocolumns.qml"));
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+    QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+    QVERIFY(four != 0);
+    QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+    QVERIFY(five != 0);
+
+    QCOMPARE(one->x(), 0.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 50.0);
+    QCOMPARE(two->y(), 0.0);
+    QCOMPARE(three->x(), 70.0);
+    QCOMPARE(three->y(), 0.0);
+    QCOMPARE(four->x(), 120.0);
+    QCOMPARE(four->y(), 0.0);
+    QCOMPARE(five->x(), 0.0);
+    QCOMPARE(five->y(), 50.0);
+
+    QQuickItem *grid = canvas->rootObject()->findChild<QQuickItem*>("grid");
+    QCOMPARE(grid->width(), 170.0);
+    QCOMPARE(grid->height(), 60.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_propertychanges()
+{
+    QQuickView *canvas = createView(TESTDATA("propertychangestest.qml"));
+
+    QQuickGrid *grid = qobject_cast<QQuickGrid*>(canvas->rootObject());
+    QVERIFY(grid != 0);
+    QDeclarativeTransition *rowTransition = canvas->rootObject()->findChild<QDeclarativeTransition*>("rowTransition");
+    QDeclarativeTransition *columnTransition = canvas->rootObject()->findChild<QDeclarativeTransition*>("columnTransition");
+
+    QSignalSpy addSpy(grid, SIGNAL(addChanged()));
+    QSignalSpy moveSpy(grid, SIGNAL(moveChanged()));
+    QSignalSpy columnsSpy(grid, SIGNAL(columnsChanged()));
+    QSignalSpy rowsSpy(grid, SIGNAL(rowsChanged()));
+
+    QVERIFY(grid);
+    QVERIFY(rowTransition);
+    QVERIFY(columnTransition);
+    QCOMPARE(grid->add(), columnTransition);
+    QCOMPARE(grid->move(), columnTransition);
+    QCOMPARE(grid->columns(), 4);
+    QCOMPARE(grid->rows(), -1);
+
+    grid->setAdd(rowTransition);
+    grid->setMove(rowTransition);
+    QCOMPARE(grid->add(), rowTransition);
+    QCOMPARE(grid->move(), rowTransition);
+    QCOMPARE(addSpy.count(),1);
+    QCOMPARE(moveSpy.count(),1);
+
+    grid->setAdd(rowTransition);
+    grid->setMove(rowTransition);
+    QCOMPARE(addSpy.count(),1);
+    QCOMPARE(moveSpy.count(),1);
+
+    grid->setAdd(0);
+    grid->setMove(0);
+    QCOMPARE(addSpy.count(),2);
+    QCOMPARE(moveSpy.count(),2);
+
+    grid->setColumns(-1);
+    grid->setRows(3);
+    QCOMPARE(grid->columns(), -1);
+    QCOMPARE(grid->rows(), 3);
+    QCOMPARE(columnsSpy.count(),1);
+    QCOMPARE(rowsSpy.count(),1);
+
+    grid->setColumns(-1);
+    grid->setRows(3);
+    QCOMPARE(columnsSpy.count(),1);
+    QCOMPARE(rowsSpy.count(),1);
+
+    grid->setColumns(2);
+    grid->setRows(2);
+    QCOMPARE(columnsSpy.count(),2);
+    QCOMPARE(rowsSpy.count(),2);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_repeater()
+{
+    QQuickView *canvas = createView(TESTDATA("repeatertest.qml"));
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+
+    QCOMPARE(one->x(), 0.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 50.0);
+    QCOMPARE(two->y(), 0.0);
+    QCOMPARE(three->x(), 100.0);
+    QCOMPARE(three->y(), 0.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_flow()
+{
+    QQuickView *canvas = createView(TESTDATA("flowtest.qml"));
+
+    canvas->rootObject()->setProperty("testRightToLeft", false);
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+    QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+    QVERIFY(four != 0);
+    QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+    QVERIFY(five != 0);
+
+    QCOMPARE(one->x(), 0.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 50.0);
+    QCOMPARE(two->y(), 0.0);
+    QCOMPARE(three->x(), 0.0);
+    QCOMPARE(three->y(), 50.0);
+    QCOMPARE(four->x(), 0.0);
+    QCOMPARE(four->y(), 70.0);
+    QCOMPARE(five->x(), 50.0);
+    QCOMPARE(five->y(), 70.0);
+
+    QQuickItem *flow = canvas->rootObject()->findChild<QQuickItem*>("flow");
+    QVERIFY(flow);
+    QCOMPARE(flow->width(), 90.0);
+    QCOMPARE(flow->height(), 120.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_flow_rightToLeft()
+{
+    QQuickView *canvas = createView(TESTDATA("flowtest.qml"));
+
+    canvas->rootObject()->setProperty("testRightToLeft", true);
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+    QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+    QVERIFY(four != 0);
+    QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+    QVERIFY(five != 0);
+
+    QCOMPARE(one->x(), 40.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 20.0);
+    QCOMPARE(two->y(), 0.0);
+    QCOMPARE(three->x(), 40.0);
+    QCOMPARE(three->y(), 50.0);
+    QCOMPARE(four->x(), 40.0);
+    QCOMPARE(four->y(), 70.0);
+    QCOMPARE(five->x(), 30.0);
+    QCOMPARE(five->y(), 70.0);
+
+    QQuickItem *flow = canvas->rootObject()->findChild<QQuickItem*>("flow");
+    QVERIFY(flow);
+    QCOMPARE(flow->width(), 90.0);
+    QCOMPARE(flow->height(), 120.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_flow_topToBottom()
+{
+    QQuickView *canvas = createView(TESTDATA("flowtest-toptobottom.qml"));
+
+    canvas->rootObject()->setProperty("testRightToLeft", false);
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+    QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+    QVERIFY(four != 0);
+    QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+    QVERIFY(five != 0);
+
+    QCOMPARE(one->x(), 0.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 50.0);
+    QCOMPARE(two->y(), 0.0);
+    QCOMPARE(three->x(), 50.0);
+    QCOMPARE(three->y(), 50.0);
+    QCOMPARE(four->x(), 100.0);
+    QCOMPARE(four->y(), 00.0);
+    QCOMPARE(five->x(), 100.0);
+    QCOMPARE(five->y(), 50.0);
+
+    QQuickItem *flow = canvas->rootObject()->findChild<QQuickItem*>("flow");
+    QVERIFY(flow);
+    QCOMPARE(flow->height(), 90.0);
+    QCOMPARE(flow->width(), 150.0);
+
+    canvas->rootObject()->setProperty("testRightToLeft", true);
+
+    QVERIFY(flow);
+    QCOMPARE(flow->height(), 90.0);
+    QCOMPARE(flow->width(), 150.0);
+
+    QCOMPARE(one->x(), 100.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 80.0);
+    QCOMPARE(two->y(), 0.0);
+    QCOMPARE(three->x(), 50.0);
+    QCOMPARE(three->y(), 50.0);
+    QCOMPARE(four->x(), 0.0);
+    QCOMPARE(four->y(), 0.0);
+    QCOMPARE(five->x(), 40.0);
+    QCOMPARE(five->y(), 50.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_flow_resize()
+{
+    QQuickView *canvas = createView(TESTDATA("flowtest.qml"));
+
+    QQuickItem *root = qobject_cast<QQuickItem*>(canvas->rootObject());
+    QVERIFY(root);
+    root->setWidth(125);
+    root->setProperty("testRightToLeft", false);
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QVERIFY(one != 0);
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+    QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+    QVERIFY(four != 0);
+    QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+    QVERIFY(five != 0);
+
+    QTRY_COMPARE(one->x(), 0.0);
+    QTRY_COMPARE(one->y(), 0.0);
+    QTRY_COMPARE(two->x(), 50.0);
+    QTRY_COMPARE(two->y(), 0.0);
+    QTRY_COMPARE(three->x(), 70.0);
+    QTRY_COMPARE(three->y(), 0.0);
+    QTRY_COMPARE(four->x(), 0.0);
+    QTRY_COMPARE(four->y(), 50.0);
+    QTRY_COMPARE(five->x(), 50.0);
+    QTRY_COMPARE(five->y(), 50.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_flow_resize_rightToLeft()
+{
+    QQuickView *canvas = createView(TESTDATA("flowtest.qml"));
+
+    QQuickItem *root = qobject_cast<QQuickItem*>(canvas->rootObject());
+    QVERIFY(root);
+    root->setWidth(125);
+    root->setProperty("testRightToLeft", true);
+
+    QQuickRectangle *one = canvas->rootObject()->findChild<QQuickRectangle*>("one");
+    QTRY_VERIFY(one != 0);
+    QQuickRectangle *two = canvas->rootObject()->findChild<QQuickRectangle*>("two");
+    QVERIFY(two != 0);
+    QQuickRectangle *three = canvas->rootObject()->findChild<QQuickRectangle*>("three");
+    QVERIFY(three != 0);
+    QQuickRectangle *four = canvas->rootObject()->findChild<QQuickRectangle*>("four");
+    QVERIFY(four != 0);
+    QQuickRectangle *five = canvas->rootObject()->findChild<QQuickRectangle*>("five");
+    QVERIFY(five != 0);
+
+    QCOMPARE(one->x(), 75.0);
+    QCOMPARE(one->y(), 0.0);
+    QCOMPARE(two->x(), 55.0);
+    QCOMPARE(two->y(), 0.0);
+    QCOMPARE(three->x(), 5.0);
+    QCOMPARE(three->y(), 0.0);
+    QCOMPARE(four->x(), 75.0);
+    QCOMPARE(four->y(), 50.0);
+    QCOMPARE(five->x(), 65.0);
+    QCOMPARE(five->y(), 50.0);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_flow_implicit_resize()
+{
+    QQuickView *canvas = createView(TESTDATA("flow-testimplicitsize.qml"));
+    QVERIFY(canvas->rootObject() != 0);
+
+    QQuickFlow *flow = canvas->rootObject()->findChild<QQuickFlow*>("flow");
+    QVERIFY(flow != 0);
+
+    QCOMPARE(flow->width(), 100.0);
+    QCOMPARE(flow->height(), 120.0);
+
+    canvas->rootObject()->setProperty("flowLayout", 0);
+    QCOMPARE(flow->flow(), QQuickFlow::LeftToRight);
+    QCOMPARE(flow->width(), 220.0);
+    QCOMPARE(flow->height(), 50.0);
+
+    canvas->rootObject()->setProperty("flowLayout", 1);
+    QCOMPARE(flow->flow(), QQuickFlow::TopToBottom);
+    QCOMPARE(flow->width(), 100.0);
+    QCOMPARE(flow->height(), 120.0);
+
+    canvas->rootObject()->setProperty("flowLayout", 2);
+    QCOMPARE(flow->layoutDirection(), Qt::RightToLeft);
+    QCOMPARE(flow->width(), 220.0);
+    QCOMPARE(flow->height(), 50.0);
+
+    delete canvas;
+}
+
+QString warningMessage;
+
+void interceptWarnings(QtMsgType type, const char *msg)
+{
+    Q_UNUSED( type );
+    warningMessage = msg;
+}
+
+void tst_qquickpositioners::test_conflictinganchors()
+{
+    QtMsgHandler oldMsgHandler = qInstallMsgHandler(interceptWarnings);
+    QDeclarativeEngine engine;
+    QDeclarativeComponent component(&engine);
+
+    component.setData("import QtQuick 2.0\nColumn { Item {} }", QUrl::fromLocalFile(""));
+    QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+    QVERIFY(warningMessage.isEmpty());
+    delete item;
+
+    component.setData("import QtQuick 2.0\nRow { Item {} }", QUrl::fromLocalFile(""));
+    item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+    QVERIFY(warningMessage.isEmpty());
+    delete item;
+
+    component.setData("import QtQuick 2.0\nGrid { Item {} }", QUrl::fromLocalFile(""));
+    item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+    QVERIFY(warningMessage.isEmpty());
+    delete item;
+
+    component.setData("import QtQuick 2.0\nFlow { Item {} }", QUrl::fromLocalFile(""));
+    item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+    QVERIFY(warningMessage.isEmpty());
+    delete item;
+
+    component.setData("import QtQuick 2.0\nColumn { Item { anchors.top: parent.top } }", QUrl::fromLocalFile(""));
+    item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+    QCOMPARE(warningMessage, QString("file::2:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column"));
+    warningMessage.clear();
+    delete item;
+
+    component.setData("import QtQuick 2.0\nColumn { Item { anchors.centerIn: parent } }", QUrl::fromLocalFile(""));
+    item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+    QCOMPARE(warningMessage, QString("file::2:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column"));
+    warningMessage.clear();
+    delete item;
+
+    component.setData("import QtQuick 2.0\nColumn { Item { anchors.left: parent.left } }", QUrl::fromLocalFile(""));
+    item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+    QVERIFY(warningMessage.isEmpty());
+    warningMessage.clear();
+    delete item;
+
+    component.setData("import QtQuick 2.0\nRow { Item { anchors.left: parent.left } }", QUrl::fromLocalFile(""));
+    item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+    QCOMPARE(warningMessage, QString("file::2:1: QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row"));
+    warningMessage.clear();
+    delete item;
+
+    component.setData("import QtQuick 2.0\nRow { Item { anchors.fill: parent } }", QUrl::fromLocalFile(""));
+    item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+    QCOMPARE(warningMessage, QString("file::2:1: QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row"));
+    warningMessage.clear();
+    delete item;
+
+    component.setData("import QtQuick 2.0\nRow { Item { anchors.top: parent.top } }", QUrl::fromLocalFile(""));
+    item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+    QVERIFY(warningMessage.isEmpty());
+    warningMessage.clear();
+    delete item;
+
+    component.setData("import QtQuick 2.0\nGrid { Item { anchors.horizontalCenter: parent.horizontalCenter } }", QUrl::fromLocalFile(""));
+    item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+    QCOMPARE(warningMessage, QString("file::2:1: QML Grid: Cannot specify anchors for items inside Grid"));
+    warningMessage.clear();
+    delete item;
+
+    component.setData("import QtQuick 2.0\nGrid { Item { anchors.centerIn: parent } }", QUrl::fromLocalFile(""));
+    item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+    QCOMPARE(warningMessage, QString("file::2:1: QML Grid: Cannot specify anchors for items inside Grid"));
+    warningMessage.clear();
+    delete item;
+
+    component.setData("import QtQuick 2.0\nFlow { Item { anchors.verticalCenter: parent.verticalCenter } }", QUrl::fromLocalFile(""));
+    item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+    QCOMPARE(warningMessage, QString("file::2:1: QML Flow: Cannot specify anchors for items inside Flow"));
+    delete item;
+
+    component.setData("import QtQuick 2.0\nFlow { Item { anchors.fill: parent } }", QUrl::fromLocalFile(""));
+    item = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(item);
+    QCOMPARE(warningMessage, QString("file::2:1: QML Flow: Cannot specify anchors for items inside Flow"));
+    qInstallMsgHandler(oldMsgHandler);
+    delete item;
+}
+
+void tst_qquickpositioners::test_mirroring()
+{
+    QList<QString> qmlFiles;
+    qmlFiles << "horizontal.qml" << "gridtest.qml" << "flowtest.qml";
+    QList<QString> objectNames;
+    objectNames << "one" << "two" << "three" << "four" << "five";
+
+    foreach (const QString qmlFile, qmlFiles) {
+        QQuickView *canvasA = createView(TESTDATA(qmlFile));
+        QQuickItem *rootA = qobject_cast<QQuickItem*>(canvasA->rootObject());
+
+        QQuickView *canvasB = createView(TESTDATA(qmlFile));
+        QQuickItem *rootB = qobject_cast<QQuickItem*>(canvasB->rootObject());
+
+        rootA->setProperty("testRightToLeft", true); // layoutDirection: Qt.RightToLeft
+
+        // LTR != RTL
+        foreach (const QString objectName, objectNames) {
+            // horizontal.qml only has three items
+            if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
+                break;
+            QQuickItem *itemA = rootA->findChild<QQuickItem*>(objectName);
+            QQuickItem *itemB = rootB->findChild<QQuickItem*>(objectName);
+            QTRY_VERIFY(itemA->x() != itemB->x());
+        }
+
+        QQuickItemPrivate* rootPrivateB = QQuickItemPrivate::get(rootB);
+
+        rootPrivateB->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true
+        rootPrivateB->isMirrorImplicit = false;
+        rootPrivateB->inheritMirrorFromItem = true; // LayoutMirroring.childrenInherit: true
+        rootPrivateB->resolveLayoutMirror();
+
+        // RTL == mirror
+        foreach (const QString objectName, objectNames) {
+            // horizontal.qml only has three items
+            if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
+                break;
+            QQuickItem *itemA = rootA->findChild<QQuickItem*>(objectName);
+            QQuickItem *itemB = rootB->findChild<QQuickItem*>(objectName);
+            QTRY_COMPARE(itemA->x(), itemB->x());
+        }
+
+        rootA->setProperty("testRightToLeft", false); // layoutDirection: Qt.LeftToRight
+        rootB->setProperty("testRightToLeft", true); // layoutDirection: Qt.RightToLeft
+
+        // LTR == RTL + mirror
+        foreach (const QString objectName, objectNames) {
+            // horizontal.qml only has three items
+            if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
+                break;
+            QQuickItem *itemA = rootA->findChild<QQuickItem*>(objectName);
+            QQuickItem *itemB = rootB->findChild<QQuickItem*>(objectName);
+            QTRY_COMPARE(itemA->x(), itemB->x());
+        }
+        delete canvasA;
+        delete canvasB;
+    }
+}
+
+void tst_qquickpositioners::test_allInvisible()
+{
+    //QTBUG-19361
+    QQuickView *canvas = createView(TESTDATA("allInvisible.qml"));
+
+    QQuickItem *root = qobject_cast<QQuickItem*>(canvas->rootObject());
+    QVERIFY(root);
+
+    QQuickRow *row = canvas->rootObject()->findChild<QQuickRow*>("row");
+    QVERIFY(row != 0);
+    QVERIFY(row->width() == 0);
+    QVERIFY(row->height() == 0);
+    QQuickColumn *column = canvas->rootObject()->findChild<QQuickColumn*>("column");
+    QVERIFY(column != 0);
+    QVERIFY(column->width() == 0);
+    QVERIFY(column->height() == 0);
+}
+
+void tst_qquickpositioners::test_attachedproperties()
+{
+    QFETCH(QString, filename);
+
+    QQuickView *canvas = createView(filename);
+    QVERIFY(canvas->rootObject() != 0);
+
+    QQuickRectangle *greenRect = canvas->rootObject()->findChild<QQuickRectangle *>("greenRect");
+    QVERIFY(greenRect != 0);
+
+    int posIndex = greenRect->property("posIndex").toInt();
+    QVERIFY(posIndex == 0);
+    bool isFirst = greenRect->property("isFirstItem").toBool();
+    QVERIFY(isFirst == true);
+    bool isLast = greenRect->property("isLastItem").toBool();
+    QVERIFY(isLast == false);
+
+    QQuickRectangle *yellowRect = canvas->rootObject()->findChild<QQuickRectangle *>("yellowRect");
+    QVERIFY(yellowRect != 0);
+
+    posIndex = yellowRect->property("posIndex").toInt();
+    QVERIFY(posIndex == -1);
+    isFirst = yellowRect->property("isFirstItem").toBool();
+    QVERIFY(isFirst == false);
+    isLast = yellowRect->property("isLastItem").toBool();
+    QVERIFY(isLast == false);
+
+    yellowRect->metaObject()->invokeMethod(yellowRect, "onDemandPositioner");
+
+    posIndex = yellowRect->property("posIndex").toInt();
+    QVERIFY(posIndex == 1);
+    isFirst = yellowRect->property("isFirstItem").toBool();
+    QVERIFY(isFirst == false);
+    isLast = yellowRect->property("isLastItem").toBool();
+    QVERIFY(isLast == true);
+
+    delete canvas;
+}
+
+void tst_qquickpositioners::test_attachedproperties_data()
+{
+    QTest::addColumn<QString>("filename");
+
+    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_qquickpositioners::test_attachedproperties_dynamic()
+{
+    QSKIP("QTBUG-21995 - Test crashes on exit");
+    QQuickView *canvas = createView(TESTDATA("attachedproperties-dynamic.qml"));
+    QVERIFY(canvas->rootObject() != 0);
+
+    QQuickRow *row = canvas->rootObject()->findChild<QQuickRow *>("pos");
+    QVERIFY(row != 0);
+
+    QQuickRectangle *rect0 = canvas->rootObject()->findChild<QQuickRectangle *>("rect0");
+    QVERIFY(rect0 != 0);
+
+    int posIndex = rect0->property("index").toInt();
+    QVERIFY(posIndex == 0);
+    bool isFirst = rect0->property("firstItem").toBool();
+    QVERIFY(isFirst == true);
+    bool isLast = rect0->property("lastItem").toBool();
+    QVERIFY(isLast == false);
+
+    QQuickRectangle *rect1 = canvas->rootObject()->findChild<QQuickRectangle *>("rect1");
+    QVERIFY(rect1 != 0);
+
+    posIndex = rect1->property("index").toInt();
+    QVERIFY(posIndex == 1);
+    isFirst = rect1->property("firstItem").toBool();
+    QVERIFY(isFirst == false);
+    isLast = rect1->property("lastItem").toBool();
+    QVERIFY(isLast == true);
+
+    row->metaObject()->invokeMethod(row, "createSubRect");
+
+    QTRY_VERIFY(rect1->property("index").toInt() == 1);
+    QTRY_VERIFY(rect1->property("firstItem").toBool() == false);
+    QTRY_VERIFY(rect1->property("lastItem").toBool() == false);
+
+    QQuickRectangle *rect2 = canvas->rootObject()->findChild<QQuickRectangle *>("rect2");
+    QVERIFY(rect2 != 0);
+
+    posIndex = rect2->property("index").toInt();
+    QVERIFY(posIndex == 2);
+    isFirst = rect2->property("firstItem").toBool();
+    QVERIFY(isFirst == false);
+    isLast = rect2->property("lastItem").toBool();
+    QVERIFY(isLast == true);
+
+    row->metaObject()->invokeMethod(row, "destroySubRect");
+
+    qApp->processEvents(QEventLoop::DeferredDeletion);
+
+    QTRY_VERIFY(rect1->property("index").toInt() == 1);
+    QTRY_VERIFY(rect1->property("firstItem").toBool() == false);
+    QTRY_VERIFY(rect1->property("lastItem").toBool() == true);
+
+    delete canvas;
+}
+
+QQuickView *tst_qquickpositioners::createView(const QString &filename, bool wait)
+{
+    QQuickView *canvas = new QQuickView(0);
+
+    canvas->setSource(QUrl::fromLocalFile(filename));
+    canvas->show();
+    if (wait)
+        QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
+
+    return canvas;
+}
+
+
+QTEST_MAIN(tst_qquickpositioners)
+
+#include "tst_qquickpositioners.moc"
diff --git a/tests/auto/declarative/qquickrepeater/qquickrepeater.pro b/tests/auto/declarative/qquickrepeater/qquickrepeater.pro
new file mode 100644 (file)
index 0000000..9cdb9c2
--- /dev/null
@@ -0,0 +1,12 @@
+CONFIG += testcase
+TARGET = tst_qquickrepeater
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qquickrepeater.cpp
+
+testFiles.files = data
+testFiles.path = .
+DEPLOYMENT += testFiles
+
+CONFIG += parallel_test
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/declarative/qquickrepeater/tst_qquickrepeater.cpp
new file mode 100644 (file)
index 0000000..355dd0d
--- /dev/null
@@ -0,0 +1,694 @@
+/****************************************************************************
+**
+** 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 <QtTest/QSignalSpy>
+#include <private/qlistmodelinterface_p.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qquickview.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qdeclarativeexpression.h>
+#include <private/qquickrepeater_p.h>
+#include <private/qquicktext_p.h>
+
+#include "../shared/util.h"
+
+inline QUrl TEST_FILE(const QString &filename)
+{
+    return QUrl::fromLocalFile(TESTDATA(filename));
+}
+
+class tst_QQuickRepeater : public QObject
+{
+    Q_OBJECT
+public:
+    tst_QQuickRepeater();
+
+private slots:
+    void numberModel();
+    void objectList();
+    void stringList();
+    void dataModel_adding();
+    void dataModel_removing();
+    void dataModel_changes();
+    void itemModel();
+    void resetModel();
+    void modelChanged();
+    void properties();
+
+private:
+    QQuickView *createView();
+    template<typename T>
+    T *findItem(QObject *parent, const QString &objectName, int index);
+    template<typename T>
+    T *findItem(QObject *parent, const QString &id);
+};
+
+class TestObject : public QObject
+{
+    Q_OBJECT
+
+    Q_PROPERTY(bool error READ error WRITE setError)
+    Q_PROPERTY(bool useModel READ useModel NOTIFY useModelChanged)
+
+public:
+    TestObject() : QObject(), mError(true), mUseModel(false) {}
+
+    bool error() const { return mError; }
+    void setError(bool err) { mError = err; }
+
+    bool useModel() const { return mUseModel; }
+    void setUseModel(bool use) { mUseModel = use; emit useModelChanged(); }
+
+signals:
+    void useModelChanged();
+
+private:
+    bool mError;
+    bool mUseModel;
+};
+
+class TestModel : public QAbstractListModel
+{
+public:
+    enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 };
+
+    TestModel(QObject *parent=0) : QAbstractListModel(parent) {
+        QHash<int, QByteArray> roles;
+        roles[Name] = "name";
+        roles[Number] = "number";
+        setRoleNames(roles);
+    }
+
+    int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); }
+    QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
+        QVariant rv;
+        if (role == Name)
+            rv = list.at(index.row()).first;
+        else if (role == Number)
+            rv = list.at(index.row()).second;
+
+        return rv;
+    }
+
+    int count() const { return rowCount(); }
+    QString name(int index) const { return list.at(index).first; }
+    QString number(int index) const { return list.at(index).second; }
+
+    void addItem(const QString &name, const QString &number) {
+        emit beginInsertRows(QModelIndex(), list.count(), list.count());
+        list.append(QPair<QString,QString>(name, number));
+        emit endInsertRows();
+    }
+
+    void insertItem(int index, const QString &name, const QString &number) {
+        emit beginInsertRows(QModelIndex(), index, index);
+        list.insert(index, QPair<QString,QString>(name, number));
+        emit endInsertRows();
+    }
+
+    void removeItem(int index) {
+        emit beginRemoveRows(QModelIndex(), index, index);
+        list.removeAt(index);
+        emit endRemoveRows();
+    }
+
+    void moveItem(int from, int to) {
+        emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
+        list.move(from, to);
+        emit endMoveRows();
+    }
+
+    void modifyItem(int idx, const QString &name, const QString &number) {
+        list[idx] = QPair<QString,QString>(name, number);
+        emit dataChanged(index(idx,0), index(idx,0));
+    }
+
+private:
+    QList<QPair<QString,QString> > list;
+};
+
+
+tst_QQuickRepeater::tst_QQuickRepeater()
+{
+}
+
+void tst_QQuickRepeater::numberModel()
+{
+    QQuickView *canvas = createView();
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testData", 5);
+    TestObject *testObject = new TestObject;
+    ctxt->setContextProperty("testObject", testObject);
+
+    canvas->setSource(TEST_FILE("intmodel.qml"));
+    qApp->processEvents();
+
+    QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
+    QVERIFY(repeater != 0);
+    QCOMPARE(repeater->parentItem()->childItems().count(), 5+1);
+
+    QVERIFY(!repeater->itemAt(-1));
+    for (int i=0; i<repeater->count(); i++)
+        QCOMPARE(repeater->itemAt(i), repeater->parentItem()->childItems().at(i));
+    QVERIFY(!repeater->itemAt(repeater->count()));
+
+    QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
+    QVERIFY(testObject->error() == false);
+
+    delete testObject;
+    delete canvas;
+}
+
+class MyObject : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(int idx READ idx CONSTANT)
+public:
+    MyObject(int i) : QObject(), m_idx(i) {}
+
+    int idx() const { return m_idx; }
+
+    int m_idx;
+};
+
+void tst_QQuickRepeater::objectList()
+{
+    QQuickView *canvas = createView();
+    QObjectList data;
+    for (int i=0; i<100; i++)
+        data << new MyObject(i);
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testData", QVariant::fromValue(data));
+
+    canvas->setSource(TEST_FILE("objlist.qml"));
+    qApp->processEvents();
+
+    QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
+    QVERIFY(repeater != 0);
+    QCOMPARE(repeater->property("errors").toInt(), 0);//If this fails either they are out of order or can't find the object's data
+    QCOMPARE(repeater->property("instantiated").toInt(), 100);
+
+    QVERIFY(!repeater->itemAt(-1));
+    for (int i=0; i<data.count(); i++)
+        QCOMPARE(repeater->itemAt(i), repeater->parentItem()->childItems().at(i));
+    QVERIFY(!repeater->itemAt(data.count()));
+
+    QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QQuickItem*)));
+    QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QQuickItem*)));
+    ctxt->setContextProperty("testData", QVariant::fromValue(data));
+    QCOMPARE(addedSpy.count(), data.count());
+    QCOMPARE(removedSpy.count(), data.count());
+
+    qDeleteAll(data);
+    delete canvas;
+}
+
+/*
+The Repeater element creates children at its own position in its parent's
+stacking order.  In this test we insert a repeater between two other Text
+elements to test this.
+*/
+void tst_QQuickRepeater::stringList()
+{
+    QQuickView *canvas = createView();
+
+    QStringList data;
+    data << "One";
+    data << "Two";
+    data << "Three";
+    data << "Four";
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testData", data);
+
+    canvas->setSource(TEST_FILE("repeater1.qml"));
+    qApp->processEvents();
+
+    QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
+    QVERIFY(repeater != 0);
+
+    QQuickItem *container = findItem<QQuickItem>(canvas->rootObject(), "container");
+    QVERIFY(container != 0);
+
+    QCOMPARE(container->childItems().count(), data.count() + 3);
+
+    bool saw_repeater = false;
+    for (int i = 0; i < container->childItems().count(); ++i) {
+
+        if (i == 0) {
+            QQuickText *name = qobject_cast<QQuickText*>(container->childItems().at(i));
+            QVERIFY(name != 0);
+            QCOMPARE(name->text(), QLatin1String("Zero"));
+        } else if (i == container->childItems().count() - 2) {
+            // The repeater itself
+            QQuickRepeater *rep = qobject_cast<QQuickRepeater*>(container->childItems().at(i));
+            QCOMPARE(rep, repeater);
+            saw_repeater = true;
+            continue;
+        } else if (i == container->childItems().count() - 1) {
+            QQuickText *name = qobject_cast<QQuickText*>(container->childItems().at(i));
+            QVERIFY(name != 0);
+            QCOMPARE(name->text(), QLatin1String("Last"));
+        } else {
+            QQuickText *name = qobject_cast<QQuickText*>(container->childItems().at(i));
+            QVERIFY(name != 0);
+            QCOMPARE(name->text(), data.at(i-1));
+        }
+    }
+    QVERIFY(saw_repeater);
+
+    delete canvas;
+}
+
+void tst_QQuickRepeater::dataModel_adding()
+{
+    QQuickView *canvas = createView();
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    TestObject *testObject = new TestObject;
+    ctxt->setContextProperty("testObject", testObject);
+
+    TestModel testModel;
+    ctxt->setContextProperty("testData", &testModel);
+    canvas->setSource(TEST_FILE("repeater2.qml"));
+    qApp->processEvents();
+
+    QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
+    QVERIFY(repeater != 0);
+    QQuickItem *container = findItem<QQuickItem>(canvas->rootObject(), "container");
+    QVERIFY(container != 0);
+
+    QVERIFY(!repeater->itemAt(0));
+
+    QSignalSpy countSpy(repeater, SIGNAL(countChanged()));
+    QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QQuickItem*)));
+
+    // add to empty model
+    testModel.addItem("two", "2");
+    QCOMPARE(repeater->itemAt(0), container->childItems().at(0));
+    QCOMPARE(countSpy.count(), 1); countSpy.clear();
+    QCOMPARE(addedSpy.count(), 1);
+    QCOMPARE(addedSpy.at(0).at(0).toInt(), 0);
+    QCOMPARE(addedSpy.at(0).at(1).value<QQuickItem*>(), container->childItems().at(0));
+    addedSpy.clear();
+
+    // insert at start
+    testModel.insertItem(0, "one", "1");
+    QCOMPARE(repeater->itemAt(0), container->childItems().at(0));
+    QCOMPARE(countSpy.count(), 1); countSpy.clear();
+    QCOMPARE(addedSpy.count(), 1);
+    QCOMPARE(addedSpy.at(0).at(0).toInt(), 0);
+    QCOMPARE(addedSpy.at(0).at(1).value<QQuickItem*>(), container->childItems().at(0));
+    addedSpy.clear();
+
+    // insert at end
+    testModel.insertItem(2, "four", "4");
+    QCOMPARE(repeater->itemAt(2), container->childItems().at(2));
+    QCOMPARE(countSpy.count(), 1); countSpy.clear();
+    QCOMPARE(addedSpy.count(), 1);
+    QCOMPARE(addedSpy.at(0).at(0).toInt(), 2);
+    QCOMPARE(addedSpy.at(0).at(1).value<QQuickItem*>(), container->childItems().at(2));
+    addedSpy.clear();
+
+    // insert in middle
+    testModel.insertItem(2, "three", "3");
+    QCOMPARE(repeater->itemAt(2), container->childItems().at(2));
+    QCOMPARE(countSpy.count(), 1); countSpy.clear();
+    QCOMPARE(addedSpy.count(), 1);
+    QCOMPARE(addedSpy.at(0).at(0).toInt(), 2);
+    QCOMPARE(addedSpy.at(0).at(1).value<QQuickItem*>(), container->childItems().at(2));
+    addedSpy.clear();
+
+    delete testObject;
+    addedSpy.clear();
+    countSpy.clear();
+    delete canvas;
+}
+
+void tst_QQuickRepeater::dataModel_removing()
+{
+    QQuickView *canvas = createView();
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    TestObject *testObject = new TestObject;
+    ctxt->setContextProperty("testObject", testObject);
+
+    TestModel testModel;
+    testModel.addItem("one", "1");
+    testModel.addItem("two", "2");
+    testModel.addItem("three", "3");
+    testModel.addItem("four", "4");
+    testModel.addItem("five", "5");
+
+    ctxt->setContextProperty("testData", &testModel);
+    canvas->setSource(TEST_FILE("repeater2.qml"));
+    qApp->processEvents();
+
+    QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
+    QVERIFY(repeater != 0);
+    QQuickItem *container = findItem<QQuickItem>(canvas->rootObject(), "container");
+    QVERIFY(container != 0);
+    QCOMPARE(container->childItems().count(), repeater->count()+1);
+
+    QSignalSpy countSpy(repeater, SIGNAL(countChanged()));
+    QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QQuickItem*)));
+
+    // remove at start
+    QQuickItem *item = repeater->itemAt(0);
+    QCOMPARE(item, container->childItems().at(0));
+
+    testModel.removeItem(0);
+    QVERIFY(repeater->itemAt(0) != item);
+    QCOMPARE(countSpy.count(), 1); countSpy.clear();
+    QCOMPARE(removedSpy.count(), 1);
+    QCOMPARE(removedSpy.at(0).at(0).toInt(), 0);
+    QCOMPARE(removedSpy.at(0).at(1).value<QQuickItem*>(), item);
+    removedSpy.clear();
+
+    // remove at end
+    int lastIndex = testModel.count()-1;
+    item = repeater->itemAt(lastIndex);
+    QCOMPARE(item, container->childItems().at(lastIndex));
+
+    testModel.removeItem(lastIndex);
+    QVERIFY(repeater->itemAt(lastIndex) != item);
+    QCOMPARE(countSpy.count(), 1); countSpy.clear();
+    QCOMPARE(removedSpy.count(), 1);
+    QCOMPARE(removedSpy.at(0).at(0).toInt(), lastIndex);
+    QCOMPARE(removedSpy.at(0).at(1).value<QQuickItem*>(), item);
+    removedSpy.clear();
+
+    // remove from middle
+    item = repeater->itemAt(1);
+    QCOMPARE(item, container->childItems().at(1));
+
+    testModel.removeItem(1);
+    QVERIFY(repeater->itemAt(lastIndex) != item);
+    QCOMPARE(countSpy.count(), 1); countSpy.clear();
+    QCOMPARE(removedSpy.count(), 1);
+    QCOMPARE(removedSpy.at(0).at(0).toInt(), 1);
+    QCOMPARE(removedSpy.at(0).at(1).value<QQuickItem*>(), item);
+    removedSpy.clear();
+
+    delete testObject;
+    delete canvas;
+}
+
+void tst_QQuickRepeater::dataModel_changes()
+{
+    QQuickView *canvas = createView();
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    TestObject *testObject = new TestObject;
+    ctxt->setContextProperty("testObject", testObject);
+
+    TestModel testModel;
+    testModel.addItem("one", "1");
+    testModel.addItem("two", "2");
+    testModel.addItem("three", "3");
+
+    ctxt->setContextProperty("testData", &testModel);
+    canvas->setSource(TEST_FILE("repeater2.qml"));
+    qApp->processEvents();
+
+    QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
+    QVERIFY(repeater != 0);
+    QQuickItem *container = findItem<QQuickItem>(canvas->rootObject(), "container");
+    QVERIFY(container != 0);
+    QCOMPARE(container->childItems().count(), repeater->count()+1);
+
+    // Check that model changes are propagated
+    QQuickText *text = findItem<QQuickText>(canvas->rootObject(), "myName", 1);
+    QVERIFY(text);
+    QCOMPARE(text->text(), QString("two"));
+
+    testModel.modifyItem(1, "Item two", "_2");
+    text = findItem<QQuickText>(canvas->rootObject(), "myName", 1);
+    QVERIFY(text);
+    QCOMPARE(text->text(), QString("Item two"));
+
+    text = findItem<QQuickText>(canvas->rootObject(), "myNumber", 1);
+    QVERIFY(text);
+    QCOMPARE(text->text(), QString("_2"));
+
+    delete testObject;
+    delete canvas;
+}
+
+void tst_QQuickRepeater::itemModel()
+{
+    QQuickView *canvas = createView();
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    TestObject *testObject = new TestObject;
+    ctxt->setContextProperty("testObject", testObject);
+
+    canvas->setSource(TEST_FILE("itemlist.qml"));
+    qApp->processEvents();
+
+    QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
+    QVERIFY(repeater != 0);
+
+    QQuickItem *container = findItem<QQuickItem>(canvas->rootObject(), "container");
+    QVERIFY(container != 0);
+
+    QCOMPARE(container->childItems().count(), 1);
+
+    testObject->setUseModel(true);
+    QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
+    QVERIFY(testObject->error() == false);
+
+    QCOMPARE(container->childItems().count(), 4);
+    QVERIFY(qobject_cast<QObject*>(container->childItems().at(0))->objectName() == "item1");
+    QVERIFY(qobject_cast<QObject*>(container->childItems().at(1))->objectName() == "item2");
+    QVERIFY(qobject_cast<QObject*>(container->childItems().at(2))->objectName() == "item3");
+    QVERIFY(container->childItems().at(3) == repeater);
+
+    QMetaObject::invokeMethod(canvas->rootObject(), "switchModel");
+    QCOMPARE(container->childItems().count(), 3);
+    QVERIFY(qobject_cast<QObject*>(container->childItems().at(0))->objectName() == "item4");
+    QVERIFY(qobject_cast<QObject*>(container->childItems().at(1))->objectName() == "item5");
+    QVERIFY(container->childItems().at(2) == repeater);
+
+    testObject->setUseModel(false);
+    QCOMPARE(container->childItems().count(), 1);
+
+    delete testObject;
+    delete canvas;
+}
+
+void tst_QQuickRepeater::resetModel()
+{
+    QQuickView *canvas = createView();
+
+    QStringList dataA;
+    for (int i=0; i<10; i++)
+        dataA << QString::number(i);
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testData", dataA);
+    canvas->setSource(TEST_FILE("repeater1.qml"));
+    qApp->processEvents();
+    QQuickRepeater *repeater = findItem<QQuickRepeater>(canvas->rootObject(), "repeater");
+    QVERIFY(repeater != 0);
+    QQuickItem *container = findItem<QQuickItem>(canvas->rootObject(), "container");
+    QVERIFY(container != 0);
+
+    QCOMPARE(repeater->count(), dataA.count());
+    for (int i=0; i<repeater->count(); i++)
+        QCOMPARE(repeater->itemAt(i), container->childItems().at(i+1)); // +1 to skip first Text object
+
+    QSignalSpy modelChangedSpy(repeater, SIGNAL(modelChanged()));
+    QSignalSpy countSpy(repeater, SIGNAL(countChanged()));
+    QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QQuickItem*)));
+    QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QQuickItem*)));
+
+    QStringList dataB;
+    for (int i=0; i<20; i++)
+        dataB << QString::number(i);
+
+    // reset context property
+    ctxt->setContextProperty("testData", dataB);
+    QCOMPARE(repeater->count(), dataB.count());
+
+    QCOMPARE(modelChangedSpy.count(), 1);
+    QCOMPARE(countSpy.count(), 1);
+    QCOMPARE(removedSpy.count(), dataA.count());
+    QCOMPARE(addedSpy.count(), dataB.count());
+    for (int i=0; i<dataB.count(); i++) {
+        QCOMPARE(addedSpy.at(i).at(0).toInt(), i);
+        QCOMPARE(addedSpy.at(i).at(1).value<QQuickItem*>(), repeater->itemAt(i));
+    }
+    modelChangedSpy.clear();
+    countSpy.clear();
+    removedSpy.clear();
+    addedSpy.clear();
+
+    // reset via setModel()
+    repeater->setModel(dataA);
+    QCOMPARE(repeater->count(), dataA.count());
+
+    QCOMPARE(modelChangedSpy.count(), 1);
+    QCOMPARE(countSpy.count(), 1);
+    QCOMPARE(removedSpy.count(), dataB.count());
+    QCOMPARE(addedSpy.count(), dataA.count());
+    for (int i=0; i<dataA.count(); i++) {
+        QCOMPARE(addedSpy.at(i).at(0).toInt(), i);
+        QCOMPARE(addedSpy.at(i).at(1).value<QQuickItem*>(), repeater->itemAt(i));
+    }
+
+    modelChangedSpy.clear();
+    countSpy.clear();
+    removedSpy.clear();
+    addedSpy.clear();
+
+    delete canvas;
+}
+
+// QTBUG-17156
+void tst_QQuickRepeater::modelChanged()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent component(&engine, TEST_FILE("modelChanged.qml"));
+
+    QQuickItem *rootObject = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(rootObject);
+    QQuickRepeater *repeater = findItem<QQuickRepeater>(rootObject, "repeater");
+    QVERIFY(repeater);
+
+    repeater->setModel(4);
+    QCOMPARE(repeater->count(), 4);
+    QCOMPARE(repeater->property("itemsCount").toInt(), 4);
+    QCOMPARE(repeater->property("itemsFound").toList().count(), 4);
+
+    repeater->setModel(10);
+    QCOMPARE(repeater->count(), 10);
+    QCOMPARE(repeater->property("itemsCount").toInt(), 10);
+    QCOMPARE(repeater->property("itemsFound").toList().count(), 10);
+
+    delete rootObject;
+}
+
+void tst_QQuickRepeater::properties()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent component(&engine, TEST_FILE("properties.qml"));
+
+    QQuickItem *rootObject = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(rootObject);
+
+    QQuickRepeater *repeater = findItem<QQuickRepeater>(rootObject, "repeater");
+    QVERIFY(repeater);
+
+    QSignalSpy modelSpy(repeater, SIGNAL(modelChanged()));
+    repeater->setModel(3);
+    QCOMPARE(modelSpy.count(),1);
+    repeater->setModel(3);
+    QCOMPARE(modelSpy.count(),1);
+
+    QSignalSpy delegateSpy(repeater, SIGNAL(delegateChanged()));
+
+    QDeclarativeComponent rectComponent(&engine);
+    rectComponent.setData("import QtQuick 2.0; Rectangle {}", QUrl::fromLocalFile(""));
+
+    repeater->setDelegate(&rectComponent);
+    QCOMPARE(delegateSpy.count(),1);
+    repeater->setDelegate(&rectComponent);
+    QCOMPARE(delegateSpy.count(),1);
+
+    delete rootObject;
+}
+
+QQuickView *tst_QQuickRepeater::createView()
+{
+    QQuickView *canvas = new QQuickView(0);
+    canvas->setGeometry(0,0,240,320);
+
+    return canvas;
+}
+
+template<typename T>
+T *tst_QQuickRepeater::findItem(QObject *parent, const QString &objectName, int index)
+{
+    const QMetaObject &mo = T::staticMetaObject;
+    //qDebug() << parent->children().count() << "children";
+    for (int i = 0; i < parent->children().count(); ++i) {
+        QQuickItem *item = qobject_cast<QQuickItem*>(parent->children().at(i));
+        if (!item)
+            continue;
+        //qDebug() << "try" << item;
+        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
+            if (index != -1) {
+                QDeclarativeExpression e(qmlContext(item), item, "index");
+                if (e.evaluate().toInt() == index)
+                    return static_cast<T*>(item);
+            } else {
+                return static_cast<T*>(item);
+            }
+        }
+        item = findItem<T>(item, objectName, index);
+        if (item)
+            return static_cast<T*>(item);
+    }
+
+    return 0;
+}
+
+template<typename T>
+T *tst_QQuickRepeater::findItem(QObject *parent, const QString &objectName)
+{
+    const QMetaObject &mo = T::staticMetaObject;
+    if (mo.cast(parent) && (objectName.isEmpty() || parent->objectName() == objectName))
+        return static_cast<T*>(parent);
+    for (int i = 0; i < parent->children().count(); ++i) {
+        QQuickItem *child = qobject_cast<QQuickItem*>(parent->children().at(i));
+        if (!child)
+            continue;
+        QQuickItem *item = findItem<T>(child, objectName);
+        if (item)
+            return static_cast<T*>(item);
+    }
+
+    return 0;
+}
+
+QTEST_MAIN(tst_QQuickRepeater)
+
+#include "tst_qquickrepeater.moc"
diff --git a/tests/auto/declarative/qquicktext/qquicktext.pro b/tests/auto/declarative/qquicktext/qquicktext.pro
new file mode 100644 (file)
index 0000000..fe69f75
--- /dev/null
@@ -0,0 +1,17 @@
+CONFIG += testcase
+TARGET = tst_qquicktext
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qquicktext.cpp
+
+INCLUDEPATH += ../shared/
+HEADERS += ../shared/testhttpserver.h
+SOURCES += ../shared/testhttpserver.cpp
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+
+QT += core-private gui-private v8-private declarative-private widgets-private opengl-private network testlib
diff --git a/tests/auto/declarative/qquicktext/tst_qquicktext.cpp b/tests/auto/declarative/qquicktext/tst_qquicktext.cpp
new file mode 100644 (file)
index 0000000..2fd4e23
--- /dev/null
@@ -0,0 +1,1433 @@
+/****************************************************************************
+**
+** 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 <QTextDocument>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <private/qquicktext_p.h>
+#include <private/qquicktext_p_p.h>
+#include <private/qdeclarativevaluetype_p.h>
+#include <private/qsgdistancefieldglyphcache_p.h>
+#include <QFontMetrics>
+#include <QGraphicsSceneMouseEvent>
+#include <qmath.h>
+#include <QQuickView>
+#include <private/qapplication_p.h>
+#include <limits.h>
+#include <QtGui/QMouseEvent>
+#include "../shared/util.h"
+#include "testhttpserver.h"
+
+DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
+
+class tst_qquicktext : public QObject
+{
+    Q_OBJECT
+public:
+    tst_qquicktext();
+
+private slots:
+    void initTestCase();
+    void cleanupTestCase();
+    void text();
+    void width();
+    void wrap();
+    void elide();
+    void textFormat();
+
+    void alignments_data();
+    void alignments();
+
+    void embeddedImages_data();
+    void embeddedImages();
+
+    void lineCount();
+    void lineHeight();
+
+    // ### these tests may be trivial
+    void horizontalAlignment();
+    void horizontalAlignment_RightToLeft();
+    void verticalAlignment();
+    void font();
+    void style();
+    void color();
+    void smooth();
+
+    // QDeclarativeFontValueType
+    void weight();
+    void underline();
+    void overline();
+    void strikeout();
+    void capitalization();
+    void letterSpacing();
+    void wordSpacing();
+
+    void clickLink();
+
+    void implicitSize_data();
+    void implicitSize();
+
+    void lineLaidOut();
+
+
+private:
+    QStringList standard;
+    QStringList richText;
+
+    QStringList horizontalAlignmentmentStrings;
+    QStringList verticalAlignmentmentStrings;
+
+    QList<Qt::Alignment> verticalAlignmentments;
+    QList<Qt::Alignment> horizontalAlignmentments;
+
+    QStringList styleStrings;
+    QList<QQuickText::TextStyle> styles;
+
+    QStringList colorStrings;
+
+    QDeclarativeEngine engine;
+
+    QQuickView *createView(const QString &filename);
+};
+void tst_qquicktext::initTestCase()
+{
+}
+
+void tst_qquicktext::cleanupTestCase()
+{
+
+}
+tst_qquicktext::tst_qquicktext()
+{
+    standard << "the quick brown fox jumped over the lazy dog"
+            << "the quick brown fox\n jumped over the lazy dog";
+
+    richText << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a> jumped over the <b>lazy</b> dog</i>"
+            << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a><br>jumped over the <b>lazy</b> dog</i>";
+
+    horizontalAlignmentmentStrings << "AlignLeft"
+            << "AlignRight"
+            << "AlignHCenter";
+
+    verticalAlignmentmentStrings << "AlignTop"
+            << "AlignBottom"
+            << "AlignVCenter";
+
+    horizontalAlignmentments << Qt::AlignLeft
+            << Qt::AlignRight
+            << Qt::AlignHCenter;
+
+    verticalAlignmentments << Qt::AlignTop
+            << Qt::AlignBottom
+            << Qt::AlignVCenter;
+
+    styleStrings << "Normal"
+            << "Outline"
+            << "Raised"
+            << "Sunken";
+
+    styles << QQuickText::Normal
+            << QQuickText::Outline
+            << QQuickText::Raised
+            << QQuickText::Sunken;
+
+    colorStrings << "aliceblue"
+            << "antiquewhite"
+            << "aqua"
+            << "darkkhaki"
+            << "darkolivegreen"
+            << "dimgray"
+            << "palevioletred"
+            << "lightsteelblue"
+            << "#000000"
+            << "#AAAAAA"
+            << "#FFFFFF"
+            << "#2AC05F";
+    //
+    // need a different test to do alpha channel test
+    // << "#AA0011DD"
+    // << "#00F16B11";
+    //
+}
+
+QQuickView *tst_qquicktext::createView(const QString &filename)
+{
+    QQuickView *canvas = new QQuickView(0);
+
+    canvas->setSource(QUrl::fromLocalFile(filename));
+    return canvas;
+}
+
+void tst_qquicktext::text()
+{
+    {
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData("import QtQuick 2.0\nText { text: \"\" }", QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE(textObject->text(), QString(""));
+        QVERIFY(textObject->width() == 0);
+
+        delete textObject;
+    }
+
+    for (int i = 0; i < standard.size(); i++)
+    {
+        QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE(textObject->text(), standard.at(i));
+        QVERIFY(textObject->width() > 0);
+
+        delete textObject;
+    }
+
+    for (int i = 0; i < richText.size(); i++)
+    {
+        QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QString expected = richText.at(i);
+        QCOMPARE(textObject->text(), expected.replace("\\\"", "\""));
+        QVERIFY(textObject->width() > 0);
+
+        delete textObject;
+    }
+}
+
+void tst_qquicktext::width()
+{
+    // uses Font metrics to find the width for standard and document to find the width for rich
+    {
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData("import QtQuick 2.0\nText { text: \"\" }", QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE(textObject->width(), 0.);
+
+        delete textObject;
+    }
+
+    bool requiresUnhintedMetrics = !qmlDisableDistanceField();
+
+    for (int i = 0; i < standard.size(); i++)
+    {
+        QVERIFY(!Qt::mightBeRichText(standard.at(i))); // self-test
+
+        QFont f;
+        qreal metricWidth = 0.0;
+
+        if (requiresUnhintedMetrics) {
+            QString s = standard.at(i);
+            s.replace(QLatin1Char('\n'), QChar::LineSeparator);
+
+            QTextLayout layout(s);
+            layout.setFlags(Qt::TextExpandTabs | Qt::TextShowMnemonic);
+            {
+                QTextOption option;
+                option.setUseDesignMetrics(true);
+                layout.setTextOption(option);
+            }
+
+            layout.beginLayout();
+            forever {
+                QTextLine line = layout.createLine();
+                if (!line.isValid())
+                    break;
+            }
+
+            layout.endLayout();
+
+            metricWidth = qCeil(layout.boundingRect().width());
+        } else {
+            QFontMetricsF fm(f);
+            qreal metricWidth = fm.size(Qt::TextExpandTabs && Qt::TextShowMnemonic, standard.at(i)).width();
+            metricWidth = qCeil(metricWidth);
+        }
+
+        QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QVERIFY(textObject->boundingRect().width() > 0);
+        QCOMPARE(textObject->width(), qreal(metricWidth));
+        QVERIFY(textObject->textFormat() == QQuickText::AutoText); // setting text doesn't change format
+
+        delete textObject;
+    }
+
+    for (int i = 0; i < richText.size(); i++)
+    {
+        QVERIFY(Qt::mightBeRichText(richText.at(i))); // self-test
+
+        QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\"; textFormat: Text.RichText }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+        QVERIFY(textObject != 0);
+
+        QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject);
+        QVERIFY(textPrivate != 0);
+
+        QTextDocument *doc = textPrivate->textDocument();
+        QVERIFY(doc != 0);
+
+        QCOMPARE(int(textObject->width()), int(doc->idealWidth()));
+        QVERIFY(textObject->textFormat() == QQuickText::RichText);
+
+        delete textObject;
+    }
+}
+
+void tst_qquicktext::wrap()
+{
+    int textHeight = 0;
+    // for specified width and wrap set true
+    {
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData("import QtQuick 2.0\nText { text: \"Hello\"; wrapMode: Text.WordWrap; width: 300 }", QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+        textHeight = textObject->height();
+
+        QVERIFY(textObject != 0);
+        QVERIFY(textObject->wrapMode() == QQuickText::WordWrap);
+        QCOMPARE(textObject->width(), 300.);
+
+        delete textObject;
+    }
+
+    for (int i = 0; i < standard.size(); i++)
+    {
+        QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; text: \"" + standard.at(i) + "\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE(textObject->width(), 30.);
+        QVERIFY(textObject->height() > textHeight);
+
+        int oldHeight = textObject->height();
+        textObject->setWidth(100);
+        QVERIFY(textObject->height() < oldHeight);
+
+        delete textObject;
+    }
+
+    for (int i = 0; i < richText.size(); i++)
+    {
+        QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; text: \"" + richText.at(i) + "\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE(textObject->width(), 30.);
+        QVERIFY(textObject->height() > textHeight);
+
+        qreal oldHeight = textObject->height();
+        textObject->setWidth(100);
+        QVERIFY(textObject->height() < oldHeight);
+
+        delete textObject;
+    }
+
+    // richtext again with a fixed height
+    for (int i = 0; i < richText.size(); i++)
+    {
+        QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; height: 50; text: \"" + richText.at(i) + "\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE(textObject->width(), 30.);
+        QVERIFY(textObject->implicitHeight() > textHeight);
+
+        qreal oldHeight = textObject->implicitHeight();
+        textObject->setWidth(100);
+        QVERIFY(textObject->implicitHeight() < oldHeight);
+
+        delete textObject;
+    }
+}
+
+void tst_qquicktext::elide()
+{
+    for (QQuickText::TextElideMode m = QQuickText::ElideLeft; m<=QQuickText::ElideNone; m=QQuickText::TextElideMode(int(m)+1)) {
+        const char* elidename[]={"ElideLeft", "ElideRight", "ElideMiddle", "ElideNone"};
+        QString elide = "elide: Text." + QString(elidename[int(m)]) + ";";
+
+        // XXX Poor coverage.
+
+        {
+            QDeclarativeComponent textComponent(&engine);
+            textComponent.setData(("import QtQuick 2.0\nText { text: \"\"; "+elide+" width: 100 }").toLatin1(), QUrl::fromLocalFile(""));
+            QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+            QCOMPARE(textObject->elideMode(), m);
+            QCOMPARE(textObject->width(), 100.);
+
+            delete textObject;
+        }
+
+        for (int i = 0; i < standard.size(); i++)
+        {
+            QString componentStr = "import QtQuick 2.0\nText { "+elide+" width: 100; text: \"" + standard.at(i) + "\" }";
+            QDeclarativeComponent textComponent(&engine);
+            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+            QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+            QCOMPARE(textObject->elideMode(), m);
+            QCOMPARE(textObject->width(), 100.);
+
+            delete textObject;
+        }
+
+        // richtext - does nothing
+        for (int i = 0; i < richText.size(); i++)
+        {
+            QString componentStr = "import QtQuick 2.0\nText { "+elide+" width: 100; text: \"" + richText.at(i) + "\" }";
+            QDeclarativeComponent textComponent(&engine);
+            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+            QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+            QCOMPARE(textObject->elideMode(), m);
+            QCOMPARE(textObject->width(), 100.);
+
+            delete textObject;
+        }
+    }
+}
+
+void tst_qquicktext::textFormat()
+{
+    {
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData("import QtQuick 2.0\nText { text: \"Hello\"; textFormat: Text.RichText }", QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QVERIFY(textObject->textFormat() == QQuickText::RichText);
+
+        QQuickTextPrivate *textPrivate = QQuickTextPrivate::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(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QVERIFY(textObject->textFormat() == QQuickText::AutoText);
+
+        QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject);
+        QVERIFY(textPrivate != 0);
+        QVERIFY(textPrivate->styledText == true);
+
+        delete textObject;
+    }
+    {
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData("import QtQuick 2.0\nText { text: \"<b>Hello</b>\"; textFormat: Text.PlainText }", QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QVERIFY(textObject->textFormat() == QQuickText::PlainText);
+
+        delete textObject;
+    }
+}
+
+
+void tst_qquicktext::alignments_data()
+{
+    QTest::addColumn<int>("hAlign");
+    QTest::addColumn<int>("vAlign");
+    QTest::addColumn<QString>("expectfile");
+
+    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) << 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) << 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_qquicktext::alignments()
+{
+    QSKIP("Text alignment pixmap comparison tests will not work with scenegraph");
+#if (0)// No widgets in scenegraph
+    QFETCH(int, hAlign);
+    QFETCH(int, vAlign);
+    QFETCH(QString, expectfile);
+
+#ifdef Q_WS_X11
+    // Font-specific, but not likely platform-specific, so only test on one platform
+    QFont fn;
+    fn.setRawName("-misc-fixed-medium-r-*-*-8-*-*-*-*-*-*-*");
+    QApplication::setFont(fn);
+#endif
+
+    QQuickView *canvas = createView(TESTDATA("alignments.qml"));
+
+    canvas->show();
+    canvas->requestActivateWindow();
+    QTest::qWait(50);
+    QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
+
+    QObject *ob = canvas->rootObject();
+    QVERIFY(ob != 0);
+    ob->setProperty("horizontalAlignment",hAlign);
+    ob->setProperty("verticalAlignment",vAlign);
+    QTRY_COMPARE(ob->property("running").toBool(),false);
+    QImage actual(canvas->width(), canvas->height(), QImage::Format_RGB32);
+    actual.fill(qRgb(255,255,255));
+    QPainter p(&actual);
+    canvas->render(&p);
+
+    QImage expect(expectfile);
+
+#ifdef Q_WS_X11
+    // Font-specific, but not likely platform-specific, so only test on one platform
+    if (QApplicationPrivate::graphics_system_name == "raster" || QApplicationPrivate::graphics_system_name == "") {
+        QCOMPARE(actual,expect);
+    }
+#endif
+
+    delete canvas;
+#endif
+}
+
+//the alignment tests may be trivial o.oa
+void tst_qquicktext::horizontalAlignment()
+{
+    //test one align each, and then test if two align fails.
+
+    for (int i = 0; i < standard.size(); i++)
+    {
+        for (int j=0; j < horizontalAlignmentmentStrings.size(); j++)
+        {
+            QString componentStr = "import QtQuick 2.0\nText { horizontalAlignment: \"" + horizontalAlignmentmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }";
+            QDeclarativeComponent textComponent(&engine);
+            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+            QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+            QCOMPARE((int)textObject->hAlign(), (int)horizontalAlignmentments.at(j));
+
+            delete textObject;
+        }
+    }
+
+    for (int i = 0; i < richText.size(); i++)
+    {
+        for (int j=0; j < horizontalAlignmentmentStrings.size(); j++)
+        {
+            QString componentStr = "import QtQuick 2.0\nText { horizontalAlignment: \"" + horizontalAlignmentmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }";
+            QDeclarativeComponent textComponent(&engine);
+            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+            QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+            QCOMPARE((int)textObject->hAlign(), (int)horizontalAlignmentments.at(j));
+
+            delete textObject;
+        }
+    }
+
+}
+
+void tst_qquicktext::horizontalAlignment_RightToLeft()
+{
+    QQuickView *canvas = createView(TESTDATA("horizontalAlignment_RightToLeft.qml"));
+    QQuickText *text = canvas->rootObject()->findChild<QQuickText*>("text");
+    QVERIFY(text != 0);
+    canvas->show();
+
+    QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(text);
+    QVERIFY(textPrivate != 0);
+
+    // implicit alignment should follow the reading direction of RTL text
+    QCOMPARE(text->hAlign(), QQuickText::AlignRight);
+    QCOMPARE(text->effectiveHAlign(), text->hAlign());
+    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
+
+    // explicitly left aligned text
+    text->setHAlign(QQuickText::AlignLeft);
+    QCOMPARE(text->hAlign(), QQuickText::AlignLeft);
+    QCOMPARE(text->effectiveHAlign(), text->hAlign());
+    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
+
+    // explicitly right aligned text
+    text->setHAlign(QQuickText::AlignRight);
+    QCOMPARE(text->hAlign(), QQuickText::AlignRight);
+    QCOMPARE(text->effectiveHAlign(), text->hAlign());
+    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
+
+    // change to rich text
+    QString textString = text->text();
+    text->setText(QString("<i>") + textString + QString("</i>"));
+    text->setTextFormat(QQuickText::RichText);
+    text->resetHAlign();
+
+    // implicitly aligned rich text should follow the reading direction of text
+    QCOMPARE(text->hAlign(), QQuickText::AlignRight);
+    QCOMPARE(text->effectiveHAlign(), text->hAlign());
+    QVERIFY(textPrivate->textDocument()->defaultTextOption().alignment() & Qt::AlignLeft);
+
+    // explicitly left aligned rich text
+    text->setHAlign(QQuickText::AlignLeft);
+    QCOMPARE(text->hAlign(), QQuickText::AlignLeft);
+    QCOMPARE(text->effectiveHAlign(), text->hAlign());
+    QVERIFY(textPrivate->textDocument()->defaultTextOption().alignment() & Qt::AlignRight);
+
+    // explicitly right aligned rich text
+    text->setHAlign(QQuickText::AlignRight);
+    QCOMPARE(text->hAlign(), QQuickText::AlignRight);
+    QCOMPARE(text->effectiveHAlign(), text->hAlign());
+    QVERIFY(textPrivate->textDocument()->defaultTextOption().alignment() & Qt::AlignLeft);
+
+    text->setText(textString);
+    text->setTextFormat(QQuickText::PlainText);
+
+    // explicitly center aligned
+    text->setHAlign(QQuickText::AlignHCenter);
+    QCOMPARE(text->hAlign(), QQuickText::AlignHCenter);
+    QCOMPARE(text->effectiveHAlign(), text->hAlign());
+    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
+    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().right() > canvas->width()/2);
+
+    // reseted alignment should go back to following the text reading direction
+    text->resetHAlign();
+    QCOMPARE(text->hAlign(), QQuickText::AlignRight);
+    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
+
+    // mirror the text item
+    QQuickItemPrivate::get(text)->setLayoutMirror(true);
+
+    // mirrored implicit alignment should continue to follow the reading direction of the text
+    QCOMPARE(text->hAlign(), QQuickText::AlignRight);
+    QCOMPARE(text->effectiveHAlign(), QQuickText::AlignRight);
+    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
+
+    // mirrored explicitly right aligned behaves as left aligned
+    text->setHAlign(QQuickText::AlignRight);
+    QCOMPARE(text->hAlign(), QQuickText::AlignRight);
+    QCOMPARE(text->effectiveHAlign(), QQuickText::AlignLeft);
+    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
+
+    // mirrored explicitly left aligned behaves as right aligned
+    text->setHAlign(QQuickText::AlignLeft);
+    QCOMPARE(text->hAlign(), QQuickText::AlignLeft);
+    QCOMPARE(text->effectiveHAlign(), QQuickText::AlignRight);
+    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
+
+    // disable mirroring
+    QQuickItemPrivate::get(text)->setLayoutMirror(false);
+    text->resetHAlign();
+
+    // English text should be implicitly left aligned
+    text->setText("Hello world!");
+    QCOMPARE(text->hAlign(), QQuickText::AlignLeft);
+    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
+
+#ifndef Q_OS_MAC    // QTBUG-18040
+    // empty text with implicit alignment follows the system locale-based
+    // keyboard input direction from QApplication::keyboardInputDirection
+    text->setText("");
+    QCOMPARE(text->hAlign(), QApplication::keyboardInputDirection() == Qt::LeftToRight ?
+                                  QQuickText::AlignLeft : QQuickText::AlignRight);
+    text->setHAlign(QQuickText::AlignRight);
+    QCOMPARE(text->hAlign(), QQuickText::AlignRight);
+#endif
+
+    delete canvas;
+
+#ifndef Q_OS_MAC    // QTBUG-18040
+    // alignment of Text with no text set to it
+    QString componentStr = "import QtQuick 2.0\nText {}";
+    QDeclarativeComponent textComponent(&engine);
+    textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+    QCOMPARE(textObject->hAlign(), QApplication::keyboardInputDirection() == Qt::LeftToRight ?
+                                  QQuickText::AlignLeft : QQuickText::AlignRight);
+    delete textObject;
+#endif
+}
+
+void tst_qquicktext::verticalAlignment()
+{
+    //test one align each, and then test if two align fails.
+
+    for (int i = 0; i < standard.size(); i++)
+    {
+        for (int j=0; j < verticalAlignmentmentStrings.size(); j++)
+        {
+            QString componentStr = "import QtQuick 2.0\nText { verticalAlignment: \"" + verticalAlignmentmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }";
+            QDeclarativeComponent textComponent(&engine);
+            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+            QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+            QVERIFY(textObject != 0);
+            QCOMPARE((int)textObject->vAlign(), (int)verticalAlignmentments.at(j));
+
+            delete textObject;
+        }
+    }
+
+    for (int i = 0; i < richText.size(); i++)
+    {
+        for (int j=0; j < verticalAlignmentmentStrings.size(); j++)
+        {
+            QString componentStr = "import QtQuick 2.0\nText { verticalAlignment: \"" + verticalAlignmentmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }";
+            QDeclarativeComponent textComponent(&engine);
+            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+            QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+            QVERIFY(textObject != 0);
+            QCOMPARE((int)textObject->vAlign(), (int)verticalAlignmentments.at(j));
+
+            delete textObject;
+        }
+    }
+
+}
+
+void tst_qquicktext::font()
+{
+    //test size, then bold, then italic, then family
+    {
+        QString componentStr = "import QtQuick 2.0\nText { font.pointSize: 40; text: \"Hello World\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QCOMPARE(textObject->font().pointSize(), 40);
+        QCOMPARE(textObject->font().bold(), false);
+        QCOMPARE(textObject->font().italic(), false);
+
+        delete textObject;
+    }
+
+    {
+        QString componentStr = "import QtQuick 2.0\nText { font.pixelSize: 40; text: \"Hello World\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QCOMPARE(textObject->font().pixelSize(), 40);
+        QCOMPARE(textObject->font().bold(), false);
+        QCOMPARE(textObject->font().italic(), false);
+
+        delete textObject;
+    }
+
+    {
+        QString componentStr = "import QtQuick 2.0\nText { font.bold: true; text: \"Hello World\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QCOMPARE(textObject->font().bold(), true);
+        QCOMPARE(textObject->font().italic(), false);
+
+        delete textObject;
+    }
+
+    {
+        QString componentStr = "import QtQuick 2.0\nText { font.italic: true; text: \"Hello World\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QCOMPARE(textObject->font().italic(), true);
+        QCOMPARE(textObject->font().bold(), false);
+
+        delete textObject;
+    }
+
+    {
+        QString componentStr = "import QtQuick 2.0\nText { font.family: \"Helvetica\"; text: \"Hello World\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QCOMPARE(textObject->font().family(), QString("Helvetica"));
+        QCOMPARE(textObject->font().bold(), false);
+        QCOMPARE(textObject->font().italic(), false);
+
+        delete textObject;
+    }
+
+    {
+        QString componentStr = "import QtQuick 2.0\nText { font.family: \"\"; text: \"Hello World\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QCOMPARE(textObject->font().family(), QString(""));
+
+        delete textObject;
+    }
+}
+
+void tst_qquicktext::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(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QCOMPARE((int)textObject->style(), (int)styles.at(i));
+        QCOMPARE(textObject->styleColor(), QColor("white"));
+
+        delete textObject;
+    }
+    QString componentStr = "import QtQuick 2.0\nText { text: \"Hello World\" }";
+    QDeclarativeComponent textComponent(&engine);
+    textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+    QRectF brPre = textObject->boundingRect();
+    textObject->setStyle(QQuickText::Outline);
+    QRectF brPost = textObject->boundingRect();
+
+    QVERIFY(brPre.width() < brPost.width());
+    QVERIFY(brPre.height() < brPost.height());
+
+    delete textObject;
+}
+
+void tst_qquicktext::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(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QCOMPARE(textObject->color(), QColor(colorStrings.at(i)));
+        QCOMPARE(textObject->styleColor(), QColor());
+
+        delete textObject;
+    }
+
+    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(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QCOMPARE(textObject->styleColor(), QColor(colorStrings.at(i)));
+        // default color to black?
+        QCOMPARE(textObject->color(), QColor("black"));
+
+        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\" }";
+            QDeclarativeComponent textComponent(&engine);
+            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+            QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+            QCOMPARE(textObject->color(), QColor(colorStrings.at(i)));
+            QCOMPARE(textObject->styleColor(), QColor(colorStrings.at(j)));
+
+            delete textObject;
+        }
+    }
+    {
+        QString colorStr = "#AA001234";
+        QColor testColor("#001234");
+        testColor.setAlpha(170);
+
+        QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStr + "\"; text: \"Hello World\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QCOMPARE(textObject->color(), testColor);
+
+        delete textObject;
+    }
+}
+
+void tst_qquicktext::smooth()
+{
+    for (int i = 0; i < standard.size(); i++)
+    {
+        {
+            QString componentStr = "import QtQuick 2.0\nText { smooth: true; text: \"" + standard.at(i) + "\" }";
+            QDeclarativeComponent textComponent(&engine);
+            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+            QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+            QCOMPARE(textObject->smooth(), true);
+
+            delete textObject;
+        }
+        {
+            QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }";
+            QDeclarativeComponent textComponent(&engine);
+            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+            QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+            QCOMPARE(textObject->smooth(), false);
+
+            delete textObject;
+        }
+    }
+    for (int i = 0; i < richText.size(); i++)
+    {
+        {
+            QString componentStr = "import QtQuick 2.0\nText { smooth: true; text: \"" + richText.at(i) + "\" }";
+            QDeclarativeComponent textComponent(&engine);
+            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+            QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+            QCOMPARE(textObject->smooth(), true);
+
+            delete textObject;
+        }
+        {
+            QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\" }";
+            QDeclarativeComponent textComponent(&engine);
+            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+            QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+            QCOMPARE(textObject->smooth(), false);
+
+            delete textObject;
+        }
+    }
+}
+
+void tst_qquicktext::weight()
+{
+    {
+        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE((int)textObject->font().weight(), (int)QDeclarativeFontValueType::Normal);
+
+        delete textObject;
+    }
+    {
+        QString componentStr = "import QtQuick 2.0\nText { font.weight: \"Bold\"; text: \"Hello world!\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE((int)textObject->font().weight(), (int)QDeclarativeFontValueType::Bold);
+
+        delete textObject;
+    }
+}
+
+void tst_qquicktext::underline()
+{
+    {
+        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE(textObject->font().underline(), false);
+
+        delete textObject;
+    }
+    {
+        QString componentStr = "import QtQuick 2.0\nText { font.underline: true; text: \"Hello world!\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE(textObject->font().underline(), true);
+
+        delete textObject;
+    }
+}
+
+void tst_qquicktext::overline()
+{
+    {
+        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE(textObject->font().overline(), false);
+
+        delete textObject;
+    }
+    {
+        QString componentStr = "import QtQuick 2.0\nText { font.overline: true; text: \"Hello world!\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE(textObject->font().overline(), true);
+
+        delete textObject;
+    }
+}
+
+void tst_qquicktext::strikeout()
+{
+    {
+        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE(textObject->font().strikeOut(), false);
+
+        delete textObject;
+    }
+    {
+        QString componentStr = "import QtQuick 2.0\nText { font.strikeout: true; text: \"Hello world!\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE(textObject->font().strikeOut(), true);
+
+        delete textObject;
+    }
+}
+
+void tst_qquicktext::capitalization()
+{
+    {
+        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::MixedCase);
+
+        delete textObject;
+    }
+    {
+        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"AllUppercase\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::AllUppercase);
+
+        delete textObject;
+    }
+    {
+        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"AllLowercase\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::AllLowercase);
+
+        delete textObject;
+    }
+    {
+        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"SmallCaps\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::SmallCaps);
+
+        delete textObject;
+    }
+    {
+        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"Capitalize\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::Capitalize);
+
+        delete textObject;
+    }
+}
+
+void tst_qquicktext::letterSpacing()
+{
+    {
+        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE(textObject->font().letterSpacing(), 0.0);
+
+        delete textObject;
+    }
+    {
+        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.letterSpacing: -2 }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE(textObject->font().letterSpacing(), -2.);
+
+        delete textObject;
+    }
+    {
+        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.letterSpacing: 3 }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE(textObject->font().letterSpacing(), 3.);
+
+        delete textObject;
+    }
+}
+
+void tst_qquicktext::wordSpacing()
+{
+    {
+        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE(textObject->font().wordSpacing(), 0.0);
+
+        delete textObject;
+    }
+    {
+        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.wordSpacing: -50 }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE(textObject->font().wordSpacing(), -50.);
+
+        delete textObject;
+    }
+    {
+        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.wordSpacing: 200 }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QCOMPARE(textObject->font().wordSpacing(), 200.);
+
+        delete textObject;
+    }
+}
+
+
+
+
+class EventSender : public QQuickItem
+{
+public:
+    void sendEvent(QMouseEvent *event) {
+        if (event->type() == QEvent::MouseButtonPress)
+            mousePressEvent(event);
+        else if (event->type() == QEvent::MouseButtonRelease)
+            mouseReleaseEvent(event);
+        else
+            qWarning() << "Trying to send unsupported event type";
+    }
+};
+
+class LinkTest : public QObject
+{
+    Q_OBJECT
+public:
+    LinkTest() {}
+
+    QString link;
+
+public slots:
+    void linkClicked(QString l) { link = l; }
+};
+
+void tst_qquicktext::clickLink()
+{
+    {
+        QString componentStr = "import QtQuick 2.0\nText { text: \"<a href=\\\"http://qt.nokia.com\\\">Hello world!</a>\" }";
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+        QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+
+        LinkTest test;
+        QObject::connect(textObject, SIGNAL(linkActivated(QString)), &test, SLOT(linkClicked(QString)));
+
+        {
+            QMouseEvent me(QEvent::MouseButtonPress,QPointF(textObject->x()/2, textObject->y()/2), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
+            static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&me);
+
+        }
+
+        {
+            QMouseEvent me(QEvent::MouseButtonRelease,QPointF(textObject->x()/2, textObject->y()/2), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
+            static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&me);
+
+        }
+
+
+        QCOMPARE(test.link, QLatin1String("http://qt.nokia.com"));
+
+        delete textObject;
+    }
+}
+
+void tst_qquicktext::embeddedImages_data()
+{
+    QTest::addColumn<QUrl>("qmlfile");
+    QTest::addColumn<QString>("error");
+    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_qquicktext::embeddedImages()
+{
+    // Tests QTBUG-9900
+
+    QFETCH(QUrl, qmlfile);
+    QFETCH(QString, error);
+
+    TestHTTPServer server(14453);
+    server.serveDirectory(TESTDATA("http"));
+
+    if (!error.isEmpty())
+        QTest::ignoreMessage(QtWarningMsg, error.toLatin1());
+
+    QDeclarativeComponent textComponent(&engine, qmlfile);
+    QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+    QVERIFY(textObject != 0);
+
+    QTRY_COMPARE(textObject->resourcesLoading(), 0);
+
+    QPixmap pm(TESTDATA("http/exists.png"));
+    if (error.isEmpty()) {
+        QCOMPARE(textObject->width(), double(pm.width()));
+        QCOMPARE(textObject->height(), double(pm.height()));
+    } else {
+        QVERIFY(16 != pm.width()); // check test is effective
+        QCOMPARE(textObject->width(), 16.0); // default size of QTextDocument broken image icon
+        QCOMPARE(textObject->height(), 16.0);
+    }
+
+    delete textObject;
+}
+
+void tst_qquicktext::lineCount()
+{
+    QQuickView *canvas = createView(TESTDATA("lineCount.qml"));
+
+    QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
+    QVERIFY(myText != 0);
+
+    QVERIFY(myText->lineCount() > 1);
+    QVERIFY(!myText->truncated());
+    QCOMPARE(myText->maximumLineCount(), INT_MAX);
+
+    myText->setMaximumLineCount(2);
+    QCOMPARE(myText->lineCount(), 2);
+    QCOMPARE(myText->truncated(), true);
+    QCOMPARE(myText->maximumLineCount(), 2);
+
+    myText->resetMaximumLineCount();
+    QCOMPARE(myText->maximumLineCount(), INT_MAX);
+    QCOMPARE(myText->truncated(), false);
+
+    myText->setElideMode(QQuickText::ElideRight);
+    myText->setMaximumLineCount(2);
+    QCOMPARE(myText->lineCount(), 2);
+    QCOMPARE(myText->truncated(), true);
+    QCOMPARE(myText->maximumLineCount(), 2);
+
+    delete canvas;
+}
+
+void tst_qquicktext::lineHeight()
+{
+    QQuickView *canvas = createView(TESTDATA("lineHeight.qml"));
+
+    QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
+    QVERIFY(myText != 0);
+
+    QVERIFY(myText->lineHeight() == 1);
+    QVERIFY(myText->lineHeightMode() == QQuickText::ProportionalHeight);
+
+    qreal h = myText->height();
+    myText->setLineHeight(1.5);
+#ifdef Q_WS_QPA
+    QEXPECT_FAIL("", "QTBUG-21009 fails", Continue);
+#endif
+    QVERIFY(myText->height() == h * 1.5);
+
+    myText->setLineHeightMode(QQuickText::FixedHeight);
+    myText->setLineHeight(20);
+    QCOMPARE(myText->height(), myText->lineCount() * 20.0);
+
+    myText->setText("Lorem ipsum sit <b>amet</b>, consectetur adipiscing elit. Integer felis nisl, varius in pretium nec, venenatis non erat. Proin lobortis interdum dictum.");
+    myText->setLineHeightMode(QQuickText::ProportionalHeight);
+    myText->setLineHeight(1.0);
+
+    qreal h2 = myText->height();
+    myText->setLineHeight(2.0);
+    QVERIFY(myText->height() == h2 * 2.0);
+
+    myText->setLineHeightMode(QQuickText::FixedHeight);
+    myText->setLineHeight(10);
+    QCOMPARE(myText->height(), myText->lineCount() * 10.0);
+
+    delete canvas;
+}
+
+void tst_qquicktext::implicitSize_data()
+{
+    QTest::addColumn<QString>("text");
+    QTest::addColumn<QString>("wrap");
+    QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "Text.NoWrap";
+    QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "Text.NoWrap";
+    QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "Text.Wrap";
+    QTest::newRow("richtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "Text.Wrap";
+}
+
+void tst_qquicktext::implicitSize()
+{
+    QFETCH(QString, text);
+    QFETCH(QString, wrap);
+    QString componentStr = "import QtQuick 2.0\nText { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + " }";
+    QDeclarativeComponent textComponent(&engine);
+    textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+    QVERIFY(textObject->width() < textObject->implicitWidth());
+    QVERIFY(textObject->height() == textObject->implicitHeight());
+
+    textObject->resetWidth();
+    QVERIFY(textObject->width() == textObject->implicitWidth());
+    QVERIFY(textObject->height() == textObject->implicitHeight());
+
+    delete textObject;
+}
+
+void tst_qquicktext::lineLaidOut()
+{
+    QQuickView *canvas = createView(TESTDATA("lineLayout.qml"));
+
+    QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
+    QVERIFY(myText != 0);
+
+    QQuickTextPrivate *textPrivate = QQuickTextPrivate::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_qquicktext)
+
+#include "tst_qquicktext.moc"
diff --git a/tests/auto/declarative/qquicktextedit/qquicktextedit.pro b/tests/auto/declarative/qquicktextedit/qquicktextedit.pro
new file mode 100644 (file)
index 0000000..ae2233d
--- /dev/null
@@ -0,0 +1,12 @@
+CONFIG += testcase
+TARGET = tst_qquicktextedit
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qquicktextedit.cpp ../shared/testhttpserver.cpp
+HEADERS += ../shared/testhttpserver.h
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private network widgets-private testlib
diff --git a/tests/auto/declarative/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/declarative/qquicktextedit/tst_qquicktextedit.cpp
new file mode 100644 (file)
index 0000000..a0d36d6
--- /dev/null
@@ -0,0 +1,2467 @@
+/****************************************************************************
+**
+** 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/QSignalSpy>
+#include "../shared/testhttpserver.h"
+#include <math.h>
+#include <QFile>
+#include <QTextDocument>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qdeclarativeexpression.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtGui/qguiapplication.h>
+#include <private/qquicktextedit_p.h>
+#include <private/qquicktextedit_p_p.h>
+#include <private/qsgdistancefieldglyphcache_p.h>
+#include <QFontMetrics>
+#include <QQuickView>
+#include <QDir>
+#include <QStyle>
+#include <QInputContext>
+#include <QInputPanel>
+#include <QClipboard>
+#include <QMimeData>
+#include <private/qtextcontrol_p.h>
+#include "../shared/util.h"
+
+#ifdef Q_WS_MAC
+#include <Carbon/Carbon.h>
+#endif
+
+#define QTBUG_21691
+#define QTBUG_21691_MESSAGE "QTBUG-21691: The test needs to be rewritten to not use QInputContext"
+
+Q_DECLARE_METATYPE(QQuickTextEdit::SelectionMode)
+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 = TESTDATA("");
+    QString arch = "unknown-architecture"; // QTest needs to help with this.
+
+    QString expectfile = persistent_dir + QDir::separator() + filebasename + "-" + arch + ".png";
+
+    if (!QFile::exists(expectfile)) {
+        actual.save(expectfile);
+        qWarning() << "created" << expectfile;
+    }
+
+    return expectfile;
+}
+
+
+class tst_qquicktextedit : public QObject
+
+{
+    Q_OBJECT
+public:
+    tst_qquicktextedit();
+
+private slots:
+    void initTestCase();
+    void cleanupTestCase();
+    void text();
+    void width();
+    void wrap();
+    void textFormat();
+    void alignments();
+    void alignments_data();
+
+    // ### these tests may be trivial
+    void hAlign();
+    void hAlign_RightToLeft();
+    void vAlign();
+    void font();
+    void color();
+    void textMargin();
+    void persistentSelection();
+    void focusOnPress();
+    void selection();
+    void isRightToLeft_data();
+    void isRightToLeft();
+    void keySelection();
+    void moveCursorSelection_data();
+    void moveCursorSelection();
+    void moveCursorSelectionSequence_data();
+    void moveCursorSelectionSequence();
+    void mouseSelection_data();
+    void mouseSelection();
+    void mouseSelectionMode_data();
+    void mouseSelectionMode();
+    void dragMouseSelection();
+    void inputMethodHints();
+
+    void positionAt();
+
+    void cursorDelegate();
+    void cursorVisible();
+    void delegateLoading_data();
+    void delegateLoading();
+    void navigation();
+    void readOnly();
+    void copyAndPaste();
+    void canPaste();
+    void canPasteEmpty();
+    void textInput();
+    void openInputPanel();
+    void geometrySignals();
+    void pastingRichText_QTBUG_14003();
+    void implicitSize_data();
+    void implicitSize();
+    void testQtQuick11Attributes();
+    void testQtQuick11Attributes_data();
+
+    void preeditMicroFocus();
+    void inputContextMouseHandler();
+    void inputMethodComposing();
+    void cursorRectangleSize();
+
+    void emptytags_QTBUG_22058();
+
+private:
+    void simulateKey(QQuickView *, int key, Qt::KeyboardModifiers modifiers = 0);
+
+    QStringList standard;
+    QStringList richText;
+
+    QStringList hAlignmentStrings;
+    QStringList vAlignmentStrings;
+
+    QList<Qt::Alignment> vAlignments;
+    QList<Qt::Alignment> hAlignments;
+
+    QStringList colorStrings;
+
+    QDeclarativeEngine engine;
+};
+void tst_qquicktextedit::initTestCase()
+{
+}
+
+void tst_qquicktextedit::cleanupTestCase()
+{
+
+}
+tst_qquicktextedit::tst_qquicktextedit()
+{
+    standard << "the quick brown fox jumped over the lazy dog"
+             << "the quick brown fox\n jumped over the lazy dog"
+             << "Hello, world!"
+             << "!dlrow ,olleH";
+
+    richText << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a> jumped over the <b>lazy</b> dog</i>"
+             << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a><br>jumped over the <b>lazy</b> dog</i>";
+
+    hAlignmentStrings << "AlignLeft"
+                      << "AlignRight"
+                      << "AlignHCenter";
+
+    vAlignmentStrings << "AlignTop"
+                      << "AlignBottom"
+                      << "AlignVCenter";
+
+    hAlignments << Qt::AlignLeft
+                << Qt::AlignRight
+                << Qt::AlignHCenter;
+
+    vAlignments << Qt::AlignTop
+                << Qt::AlignBottom
+                << Qt::AlignVCenter;
+
+    colorStrings << "aliceblue"
+                 << "antiquewhite"
+                 << "aqua"
+                 << "darkkhaki"
+                 << "darkolivegreen"
+                 << "dimgray"
+                 << "palevioletred"
+                 << "lightsteelblue"
+                 << "#000000"
+                 << "#AAAAAA"
+                 << "#FFFFFF"
+                 << "#2AC05F";
+                 //
+                 // need a different test to do alpha channel test
+                 // << "#AA0011DD"
+                 // << "#00F16B11";
+                 //
+}
+
+void tst_qquicktextedit::text()
+{
+    {
+        QDeclarativeComponent texteditComponent(&engine);
+        texteditComponent.setData("import QtQuick 2.0\nTextEdit {  text: \"\"  }", QUrl());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->text(), QString(""));
+    }
+
+    for (int i = 0; i < standard.size(); i++)
+    {
+        QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + standard.at(i) + "\" }";
+        QDeclarativeComponent texteditComponent(&engine);
+        texteditComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->text(), standard.at(i));
+    }
+
+    for (int i = 0; i < richText.size(); i++)
+    {
+        QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + richText.at(i) + "\" }";
+        QDeclarativeComponent texteditComponent(&engine);
+        texteditComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+        QVERIFY(textEditObject != 0);
+        QString actual = textEditObject->text();
+        QString expected = richText.at(i);
+        actual.replace(QRegExp(".*<body[^>]*>"),"");
+        actual.replace(QRegExp("(<[^>]*>)+"),"<>");
+        expected.replace(QRegExp("(<[^>]*>)+"),"<>");
+        QCOMPARE(actual.simplified(),expected.simplified());
+    }
+}
+
+void tst_qquicktextedit::width()
+{
+    // uses Font metrics to find the width for standard and document to find the width for rich
+    {
+        QDeclarativeComponent texteditComponent(&engine);
+        texteditComponent.setData("import QtQuick 2.0\nTextEdit {  text: \"\" }", QUrl());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->width(), 0.0);
+    }
+
+    bool requiresUnhintedMetrics = !qmlDisableDistanceField();
+
+    for (int i = 0; i < standard.size(); i++)
+    {
+        QFont f;
+        qreal metricWidth = 0.0;
+
+        if (requiresUnhintedMetrics) {
+            QString s = standard.at(i);
+            s.replace(QLatin1Char('\n'), QChar::LineSeparator);
+
+            QTextLayout layout(s);
+            layout.setFlags(Qt::TextExpandTabs | Qt::TextShowMnemonic);
+            {
+                QTextOption option;
+                option.setUseDesignMetrics(true);
+                layout.setTextOption(option);
+            }
+
+            layout.beginLayout();
+            forever {
+                QTextLine line = layout.createLine();
+                if (!line.isValid())
+                    break;
+            }
+
+            layout.endLayout();
+
+            metricWidth = ceil(layout.boundingRect().width());
+        } else {
+            QFontMetricsF fm(f);
+            metricWidth = fm.size(Qt::TextExpandTabs | Qt::TextShowMnemonic, standard.at(i)).width();
+            metricWidth = ceil(metricWidth);
+        }
+
+        QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + standard.at(i) + "\" }";
+        QDeclarativeComponent texteditComponent(&engine);
+        texteditComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->width(), qreal(metricWidth));
+    }
+
+    for (int i = 0; i < richText.size(); i++)
+    {
+        QTextDocument document;
+        document.setHtml(richText.at(i));
+        document.setDocumentMargin(0);
+        if (requiresUnhintedMetrics)
+            document.setUseDesignMetrics(true);
+
+        int documentWidth = ceil(document.idealWidth());
+
+        QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + richText.at(i) + "\" }";
+        QDeclarativeComponent texteditComponent(&engine);
+        texteditComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->width(), qreal(documentWidth));
+    }
+}
+
+void tst_qquicktextedit::wrap()
+{
+    // for specified width and wrap set true
+    {
+        QDeclarativeComponent texteditComponent(&engine);
+        texteditComponent.setData("import QtQuick 2.0\nTextEdit {  text: \"\"; wrapMode: TextEdit.WordWrap; width: 300 }", QUrl());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->width(), 300.);
+    }
+
+    for (int i = 0; i < standard.size(); i++)
+    {
+        QString componentStr = "import QtQuick 2.0\nTextEdit {  wrapMode: TextEdit.WordWrap; width: 300; text: \"" + standard.at(i) + "\" }";
+        QDeclarativeComponent texteditComponent(&engine);
+        texteditComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->width(), 300.);
+    }
+
+    for (int i = 0; i < richText.size(); i++)
+    {
+        QString componentStr = "import QtQuick 2.0\nTextEdit {  wrapMode: TextEdit.WordWrap; width: 300; text: \"" + richText.at(i) + "\" }";
+        QDeclarativeComponent texteditComponent(&engine);
+        texteditComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->width(), 300.);
+    }
+
+}
+
+void tst_qquicktextedit::textFormat()
+{
+    {
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData("import QtQuick 2.0\nTextEdit { text: \"Hello\"; textFormat: Text.RichText }", QUrl::fromLocalFile(""));
+        QQuickTextEdit *textObject = qobject_cast<QQuickTextEdit*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QVERIFY(textObject->textFormat() == QQuickTextEdit::RichText);
+    }
+    {
+        QDeclarativeComponent textComponent(&engine);
+        textComponent.setData("import QtQuick 2.0\nTextEdit { text: \"<b>Hello</b>\"; textFormat: Text.PlainText }", QUrl::fromLocalFile(""));
+        QQuickTextEdit *textObject = qobject_cast<QQuickTextEdit*>(textComponent.create());
+
+        QVERIFY(textObject != 0);
+        QVERIFY(textObject->textFormat() == QQuickTextEdit::PlainText);
+    }
+}
+
+void tst_qquicktextedit::alignments_data()
+{
+    QTest::addColumn<int>("hAlign");
+    QTest::addColumn<int>("vAlign");
+    QTest::addColumn<QString>("expectfile");
+
+    QTest::newRow("LT") << int(Qt::AlignLeft) << int(Qt::AlignTop) << "alignments_lt";
+    QTest::newRow("RT") << int(Qt::AlignRight) << int(Qt::AlignTop) << "alignments_rt";
+    QTest::newRow("CT") << int(Qt::AlignHCenter) << int(Qt::AlignTop) << "alignments_ct";
+
+    QTest::newRow("LB") << int(Qt::AlignLeft) << int(Qt::AlignBottom) << "alignments_lb";
+    QTest::newRow("RB") << int(Qt::AlignRight) << int(Qt::AlignBottom) << "alignments_rb";
+    QTest::newRow("CB") << int(Qt::AlignHCenter) << int(Qt::AlignBottom) << "alignments_cb";
+
+    QTest::newRow("LC") << int(Qt::AlignLeft) << int(Qt::AlignVCenter) << "alignments_lc";
+    QTest::newRow("RC") << int(Qt::AlignRight) << int(Qt::AlignVCenter) << "alignments_rc";
+    QTest::newRow("CC") << int(Qt::AlignHCenter) << int(Qt::AlignVCenter) << "alignments_cc";
+}
+
+
+void tst_qquicktextedit::alignments()
+{
+    QSKIP("Image comparison of text is almost guaranteed to fail during development");
+
+    QFETCH(int, hAlign);
+    QFETCH(int, vAlign);
+    QFETCH(QString, expectfile);
+
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("alignments.qml")));
+
+    canvas.show();
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&canvas);
+    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
+
+    QObject *ob = canvas.rootObject();
+    QVERIFY(ob != 0);
+    ob->setProperty("horizontalAlignment",hAlign);
+    ob->setProperty("verticalAlignment",vAlign);
+    QTRY_COMPARE(ob->property("running").toBool(),false);
+    QImage actual = canvas.grabFrameBuffer();
+
+    expectfile = createExpectedFileIfNotFound(expectfile, actual);
+
+    QImage expect(expectfile);
+
+    QCOMPARE(actual,expect);
+}
+
+
+//the alignment tests may be trivial o.oa
+void tst_qquicktextedit::hAlign()
+{
+    //test one align each, and then test if two align fails.
+
+    for (int i = 0; i < standard.size(); i++)
+    {
+        for (int j=0; j < hAlignmentStrings.size(); j++)
+        {
+            QString componentStr = "import QtQuick 2.0\nTextEdit {  horizontalAlignment: \"" + hAlignmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }";
+            QDeclarativeComponent texteditComponent(&engine);
+            texteditComponent.setData(componentStr.toLatin1(), QUrl());
+            QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+            QVERIFY(textEditObject != 0);
+            QCOMPARE((int)textEditObject->hAlign(), (int)hAlignments.at(j));
+        }
+    }
+
+    for (int i = 0; i < richText.size(); i++)
+    {
+        for (int j=0; j < hAlignmentStrings.size(); j++)
+        {
+            QString componentStr = "import QtQuick 2.0\nTextEdit {  horizontalAlignment: \"" + hAlignmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }";
+            QDeclarativeComponent texteditComponent(&engine);
+            texteditComponent.setData(componentStr.toLatin1(), QUrl());
+            QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+            QVERIFY(textEditObject != 0);
+            QCOMPARE((int)textEditObject->hAlign(), (int)hAlignments.at(j));
+        }
+    }
+
+}
+
+void tst_qquicktextedit::hAlign_RightToLeft()
+{
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("horizontalAlignment_RightToLeft.qml")));
+    QQuickTextEdit *textEdit = canvas.rootObject()->findChild<QQuickTextEdit*>("text");
+    QVERIFY(textEdit != 0);
+    canvas.show();
+
+    const QString rtlText = textEdit->text();
+
+    // implicit alignment should follow the reading direction of text
+    QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight);
+    QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
+
+    // explicitly left aligned
+    textEdit->setHAlign(QQuickTextEdit::AlignLeft);
+    QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignLeft);
+    QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2);
+
+    // explicitly right aligned
+    textEdit->setHAlign(QQuickTextEdit::AlignRight);
+    QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight);
+    QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
+
+    QString textString = textEdit->text();
+    textEdit->setText(QString("<i>") + textString + QString("</i>"));
+    textEdit->resetHAlign();
+
+    // implicitly aligned rich text should follow the reading direction of RTL text
+    QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight);
+    QCOMPARE(textEdit->effectiveHAlign(), textEdit->hAlign());
+    QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
+
+    // explicitly left aligned rich text
+    textEdit->setHAlign(QQuickTextEdit::AlignLeft);
+    QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignLeft);
+    QCOMPARE(textEdit->effectiveHAlign(), textEdit->hAlign());
+    QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2);
+
+    // explicitly right aligned rich text
+    textEdit->setHAlign(QQuickTextEdit::AlignRight);
+    QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight);
+    QCOMPARE(textEdit->effectiveHAlign(), textEdit->hAlign());
+    QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
+
+    textEdit->setText(textString);
+
+    // explicitly center aligned
+    textEdit->setHAlign(QQuickTextEdit::AlignHCenter);
+    QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignHCenter);
+    QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
+
+    // reseted alignment should go back to following the text reading direction
+    textEdit->resetHAlign();
+    QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight);
+    QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
+
+    // mirror the text item
+    QQuickItemPrivate::get(textEdit)->setLayoutMirror(true);
+
+    // mirrored implicit alignment should continue to follow the reading direction of the text
+    QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight);
+    QCOMPARE(textEdit->effectiveHAlign(), QQuickTextEdit::AlignRight);
+    QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
+
+    // mirrored explicitly right aligned behaves as left aligned
+    textEdit->setHAlign(QQuickTextEdit::AlignRight);
+    QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight);
+    QCOMPARE(textEdit->effectiveHAlign(), QQuickTextEdit::AlignLeft);
+    QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2);
+
+    // mirrored explicitly left aligned behaves as right aligned
+    textEdit->setHAlign(QQuickTextEdit::AlignLeft);
+    QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignLeft);
+    QCOMPARE(textEdit->effectiveHAlign(), QQuickTextEdit::AlignRight);
+    QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
+
+    // disable mirroring
+    QQuickItemPrivate::get(textEdit)->setLayoutMirror(false);
+    textEdit->resetHAlign();
+
+    // English text should be implicitly left aligned
+    textEdit->setText("Hello world!");
+    QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignLeft);
+    QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2);
+
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&canvas);
+    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
+
+    textEdit->setText(QString());
+    { QInputMethodEvent ev(rtlText, QList<QInputMethodEvent::Attribute>()); QGuiApplication::sendEvent(&canvas, &ev); }
+    QEXPECT_FAIL("", "QTBUG-21691", Abort);
+    QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight);
+    { QInputMethodEvent ev("Hello world!", QList<QInputMethodEvent::Attribute>()); QGuiApplication::sendEvent(&canvas, &ev); }
+    QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignLeft);
+
+#ifndef Q_OS_MAC    // QTBUG-18040
+    // empty text with implicit alignment follows the system locale-based
+    // keyboard input direction from QGuiApplication::keyboardInputDirection
+    textEdit->setText("");
+    QCOMPARE(textEdit->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ?
+                                  QQuickTextEdit::AlignLeft : QQuickTextEdit::AlignRight);
+    if (QGuiApplication::keyboardInputDirection() == Qt::LeftToRight)
+        QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2);
+    else
+        QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
+    textEdit->setHAlign(QQuickTextEdit::AlignRight);
+    QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight);
+    QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
+#endif
+
+#ifndef Q_OS_MAC    // QTBUG-18040
+    // alignment of TextEdit with no text set to it
+    QString componentStr = "import QtQuick 2.0\nTextEdit {}";
+    QDeclarativeComponent textComponent(&engine);
+    textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickTextEdit *textObject = qobject_cast<QQuickTextEdit*>(textComponent.create());
+    QCOMPARE(textObject->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ?
+                                  QQuickTextEdit::AlignLeft : QQuickTextEdit::AlignRight);
+    delete textObject;
+#endif
+}
+
+void tst_qquicktextedit::vAlign()
+{
+    //test one align each, and then test if two align fails.
+
+    for (int i = 0; i < standard.size(); i++)
+    {
+        for (int j=0; j < vAlignmentStrings.size(); j++)
+        {
+            QString componentStr = "import QtQuick 2.0\nTextEdit {  verticalAlignment: \"" + vAlignmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }";
+            QDeclarativeComponent texteditComponent(&engine);
+            texteditComponent.setData(componentStr.toLatin1(), QUrl());
+            QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+            QVERIFY(textEditObject != 0);
+            QCOMPARE((int)textEditObject->vAlign(), (int)vAlignments.at(j));
+        }
+    }
+
+    for (int i = 0; i < richText.size(); i++)
+    {
+        for (int j=0; j < vAlignmentStrings.size(); j++)
+        {
+            QString componentStr = "import QtQuick 2.0\nTextEdit {  verticalAlignment: \"" + vAlignmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }";
+            QDeclarativeComponent texteditComponent(&engine);
+            texteditComponent.setData(componentStr.toLatin1(), QUrl());
+            QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+            QVERIFY(textEditObject != 0);
+            QCOMPARE((int)textEditObject->vAlign(), (int)vAlignments.at(j));
+        }
+    }
+
+}
+
+void tst_qquicktextedit::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());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->font().pointSize(), 40);
+        QCOMPARE(textEditObject->font().bold(), false);
+        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());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->font().bold(), true);
+        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());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->font().italic(), true);
+        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());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->font().family(), QString("Helvetica"));
+        QCOMPARE(textEditObject->font().bold(), false);
+        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());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->font().family(), QString(""));
+    }
+}
+
+void tst_qquicktextedit::color()
+{
+    //test initial color
+    {
+        QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"Hello World\" }";
+        QDeclarativeComponent texteditComponent(&engine);
+        texteditComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+        QQuickTextEditPrivate *textEditPrivate = static_cast<QQuickTextEditPrivate*>(QQuickItemPrivate::get(textEditObject));
+
+        QVERIFY(textEditObject);
+        QVERIFY(textEditPrivate);
+        QVERIFY(textEditPrivate->control);
+
+        QPalette pal = textEditPrivate->control->palette();
+        QCOMPARE(textEditPrivate->color, QColor("black"));
+        QCOMPARE(textEditPrivate->color, pal.color(QPalette::Text));
+    }
+    //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());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+        //qDebug() << "textEditObject: " << textEditObject->color() << "vs. " << QColor(colorStrings.at(i));
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->color(), QColor(colorStrings.at(i)));
+    }
+
+    //test selection
+    for (int i = 0; i < colorStrings.size(); i++)
+    {
+        QString componentStr = "import QtQuick 2.0\nTextEdit {  selectionColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
+        QDeclarativeComponent texteditComponent(&engine);
+        texteditComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->selectionColor(), QColor(colorStrings.at(i)));
+    }
+
+    //test selected text
+    for (int i = 0; i < colorStrings.size(); i++)
+    {
+        QString componentStr = "import QtQuick 2.0\nTextEdit {  selectedTextColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
+        QDeclarativeComponent texteditComponent(&engine);
+        texteditComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->selectedTextColor(), QColor(colorStrings.at(i)));
+    }
+
+    {
+        QString colorStr = "#AA001234";
+        QColor testColor("#001234");
+        testColor.setAlpha(170);
+
+        QString componentStr = "import QtQuick 2.0\nTextEdit {  color: \"" + colorStr + "\"; text: \"Hello World\" }";
+        QDeclarativeComponent texteditComponent(&engine);
+        texteditComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->color(), testColor);
+    }
+}
+
+void tst_qquicktextedit::textMargin()
+{
+    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());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->textMargin(), i);
+    }
+}
+
+void tst_qquicktextedit::persistentSelection()
+{
+    {
+        QString componentStr = "import QtQuick 2.0\nTextEdit {  persistentSelection: true; text: \"Hello World\" }";
+        QDeclarativeComponent texteditComponent(&engine);
+        texteditComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->persistentSelection(), true);
+    }
+
+    {
+        QString componentStr = "import QtQuick 2.0\nTextEdit {  persistentSelection: false; text: \"Hello World\" }";
+        QDeclarativeComponent texteditComponent(&engine);
+        texteditComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->persistentSelection(), false);
+    }
+}
+
+void tst_qquicktextedit::focusOnPress()
+{
+    {
+        QString componentStr = "import QtQuick 2.0\nTextEdit {  activeFocusOnPress: true; text: \"Hello World\" }";
+        QDeclarativeComponent texteditComponent(&engine);
+        texteditComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->focusOnPress(), true);
+    }
+
+    {
+        QString componentStr = "import QtQuick 2.0\nTextEdit {  activeFocusOnPress: false; text: \"Hello World\" }";
+        QDeclarativeComponent texteditComponent(&engine);
+        texteditComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+        QVERIFY(textEditObject != 0);
+        QCOMPARE(textEditObject->focusOnPress(), false);
+    }
+}
+
+void tst_qquicktextedit::selection()
+{
+    QString testStr = standard[0];//TODO: What should happen for multiline/rich text?
+    QString componentStr = "import QtQuick 2.0\nTextEdit {  text: \""+ testStr +"\"; }";
+    QDeclarativeComponent texteditComponent(&engine);
+    texteditComponent.setData(componentStr.toLatin1(), QUrl());
+    QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+    QVERIFY(textEditObject != 0);
+
+
+    //Test selection follows cursor
+    for (int i=0; i<= testStr.size(); i++) {
+        textEditObject->setCursorPosition(i);
+        QCOMPARE(textEditObject->cursorPosition(), i);
+        QCOMPARE(textEditObject->selectionStart(), i);
+        QCOMPARE(textEditObject->selectionEnd(), i);
+        QVERIFY(textEditObject->selectedText().isNull());
+    }
+
+    textEditObject->setCursorPosition(0);
+    QVERIFY(textEditObject->cursorPosition() == 0);
+    QVERIFY(textEditObject->selectionStart() == 0);
+    QVERIFY(textEditObject->selectionEnd() == 0);
+    QVERIFY(textEditObject->selectedText().isNull());
+
+    // Verify invalid positions are ignored.
+    textEditObject->setCursorPosition(-1);
+    QVERIFY(textEditObject->cursorPosition() == 0);
+    QVERIFY(textEditObject->selectionStart() == 0);
+    QVERIFY(textEditObject->selectionEnd() == 0);
+    QVERIFY(textEditObject->selectedText().isNull());
+
+    textEditObject->setCursorPosition(textEditObject->text().count()+1);
+    QVERIFY(textEditObject->cursorPosition() == 0);
+    QVERIFY(textEditObject->selectionStart() == 0);
+    QVERIFY(textEditObject->selectionEnd() == 0);
+    QVERIFY(textEditObject->selectedText().isNull());
+
+    //Test selection
+    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++) {
+        textEditObject->select(i,testStr.size());
+        QCOMPARE(testStr.mid(i,testStr.size()-i), textEditObject->selectedText());
+    }
+
+    textEditObject->setCursorPosition(0);
+    QVERIFY(textEditObject->cursorPosition() == 0);
+    QVERIFY(textEditObject->selectionStart() == 0);
+    QVERIFY(textEditObject->selectionEnd() == 0);
+    QVERIFY(textEditObject->selectedText().isNull());
+
+    //Test Error Ignoring behaviour
+    textEditObject->setCursorPosition(0);
+    QVERIFY(textEditObject->selectedText().isNull());
+    textEditObject->select(-10,0);
+    QVERIFY(textEditObject->selectedText().isNull());
+    textEditObject->select(100,101);
+    QVERIFY(textEditObject->selectedText().isNull());
+    textEditObject->select(0,-10);
+    QVERIFY(textEditObject->selectedText().isNull());
+    textEditObject->select(0,100);
+    QVERIFY(textEditObject->selectedText().isNull());
+    textEditObject->select(0,10);
+    QVERIFY(textEditObject->selectedText().size() == 10);
+    textEditObject->select(-10,0);
+    QVERIFY(textEditObject->selectedText().size() == 10);
+    textEditObject->select(100,101);
+    QVERIFY(textEditObject->selectedText().size() == 10);
+    textEditObject->select(0,-10);
+    QVERIFY(textEditObject->selectedText().size() == 10);
+    textEditObject->select(0,100);
+    QVERIFY(textEditObject->selectedText().size() == 10);
+
+    textEditObject->deselect();
+    QVERIFY(textEditObject->selectedText().isNull());
+    textEditObject->select(0,10);
+    QVERIFY(textEditObject->selectedText().size() == 10);
+    textEditObject->deselect();
+    QVERIFY(textEditObject->selectedText().isNull());
+}
+
+void tst_qquicktextedit::isRightToLeft_data()
+{
+    QTest::addColumn<QString>("text");
+    QTest::addColumn<bool>("emptyString");
+    QTest::addColumn<bool>("firstCharacter");
+    QTest::addColumn<bool>("lastCharacter");
+    QTest::addColumn<bool>("middleCharacter");
+    QTest::addColumn<bool>("startString");
+    QTest::addColumn<bool>("midString");
+    QTest::addColumn<bool>("endString");
+
+    const quint16 arabic_str[] = { 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0647};
+    QTest::newRow("Empty") << "" << false << false << false << false << false << false << false;
+    QTest::newRow("Neutral") << "23244242" << false << false << false << false << false << false << false;
+    QTest::newRow("LTR") << "Hello world" << false << false << false << false << false << false << false;
+    QTest::newRow("RTL") << QString::fromUtf16(arabic_str, 11) << false << true << true << true << true << true << true;
+    QTest::newRow("Bidi RTL + LTR + RTL") << QString::fromUtf16(arabic_str, 11) + QString("Hello world") + QString::fromUtf16(arabic_str, 11) << false << true << true << false << true << true << true;
+    QTest::newRow("Bidi LTR + RTL + LTR") << QString("Hello world") + QString::fromUtf16(arabic_str, 11) + QString("Hello world") << false << false << false << true << false << false << false;
+}
+
+void tst_qquicktextedit::isRightToLeft()
+{
+    QFETCH(QString, text);
+    QFETCH(bool, emptyString);
+    QFETCH(bool, firstCharacter);
+    QFETCH(bool, lastCharacter);
+    QFETCH(bool, middleCharacter);
+    QFETCH(bool, startString);
+    QFETCH(bool, midString);
+    QFETCH(bool, endString);
+
+    QQuickTextEdit textEdit;
+    textEdit.setText(text);
+
+    // first test that the right string is delivered to the QString::isRightToLeft()
+    QCOMPARE(textEdit.isRightToLeft(0,0), text.mid(0,0).isRightToLeft());
+    QCOMPARE(textEdit.isRightToLeft(0,1), text.mid(0,1).isRightToLeft());
+    QCOMPARE(textEdit.isRightToLeft(text.count()-2, text.count()-1), text.mid(text.count()-2, text.count()-1).isRightToLeft());
+    QCOMPARE(textEdit.isRightToLeft(text.count()/2, text.count()/2 + 1), text.mid(text.count()/2, text.count()/2 + 1).isRightToLeft());
+    QCOMPARE(textEdit.isRightToLeft(0,text.count()/4), text.mid(0,text.count()/4).isRightToLeft());
+    QCOMPARE(textEdit.isRightToLeft(text.count()/4,3*text.count()/4), text.mid(text.count()/4,3*text.count()/4).isRightToLeft());
+    if (text.isEmpty())
+        QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML TextEdit: isRightToLeft(start, end) called with the end property being smaller than the start.");
+    QCOMPARE(textEdit.isRightToLeft(3*text.count()/4,text.count()-1), text.mid(3*text.count()/4,text.count()-1).isRightToLeft());
+
+    // then test that the feature actually works
+    QCOMPARE(textEdit.isRightToLeft(0,0), emptyString);
+    QCOMPARE(textEdit.isRightToLeft(0,1), firstCharacter);
+    QCOMPARE(textEdit.isRightToLeft(text.count()-2, text.count()-1), lastCharacter);
+    QCOMPARE(textEdit.isRightToLeft(text.count()/2, text.count()/2 + 1), middleCharacter);
+    QCOMPARE(textEdit.isRightToLeft(0,text.count()/4), startString);
+    QCOMPARE(textEdit.isRightToLeft(text.count()/4,3*text.count()/4), midString);
+    if (text.isEmpty())
+        QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML TextEdit: isRightToLeft(start, end) called with the end property being smaller than the start.");
+    QCOMPARE(textEdit.isRightToLeft(3*text.count()/4,text.count()-1), endString);
+}
+
+void tst_qquicktextedit::keySelection()
+{
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml")));
+    canvas.show();
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&canvas);
+    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
+    canvas.requestActivateWindow();
+
+    QVERIFY(canvas.rootObject() != 0);
+
+    QQuickTextEdit *input = qobject_cast<QQuickTextEdit *>(qvariant_cast<QObject *>(canvas.rootObject()->property("myInput")));
+
+    QVERIFY(input != 0);
+    QTRY_VERIFY(input->hasActiveFocus() == true);
+
+    QSignalSpy spy(input, SIGNAL(selectionChanged()));
+
+    simulateKey(&canvas, Qt::Key_Right, Qt::ShiftModifier);
+    QVERIFY(input->hasActiveFocus() == true);
+    QCOMPARE(input->selectedText(), QString("a"));
+    QCOMPARE(spy.count(), 1);
+    simulateKey(&canvas, Qt::Key_Right);
+    QVERIFY(input->hasActiveFocus() == true);
+    QCOMPARE(input->selectedText(), QString());
+    QCOMPARE(spy.count(), 2);
+    simulateKey(&canvas, Qt::Key_Right);
+    QVERIFY(input->hasActiveFocus() == false);
+    QCOMPARE(input->selectedText(), QString());
+    QCOMPARE(spy.count(), 2);
+
+    simulateKey(&canvas, Qt::Key_Left);
+    QVERIFY(input->hasActiveFocus() == true);
+    QCOMPARE(spy.count(), 2);
+    simulateKey(&canvas, Qt::Key_Left, Qt::ShiftModifier);
+    QVERIFY(input->hasActiveFocus() == true);
+    QCOMPARE(input->selectedText(), QString("a"));
+    QCOMPARE(spy.count(), 3);
+    simulateKey(&canvas, Qt::Key_Left);
+    QVERIFY(input->hasActiveFocus() == true);
+    QCOMPARE(input->selectedText(), QString());
+    QCOMPARE(spy.count(), 4);
+    simulateKey(&canvas, Qt::Key_Left);
+    QVERIFY(input->hasActiveFocus() == false);
+    QCOMPARE(input->selectedText(), QString());
+    QCOMPARE(spy.count(), 4);
+}
+
+void tst_qquicktextedit::moveCursorSelection_data()
+{
+    QTest::addColumn<QString>("testStr");
+    QTest::addColumn<int>("cursorPosition");
+    QTest::addColumn<int>("movePosition");
+    QTest::addColumn<QQuickTextEdit::SelectionMode>("mode");
+    QTest::addColumn<int>("selectionStart");
+    QTest::addColumn<int>("selectionEnd");
+    QTest::addColumn<bool>("reversible");
+
+    QTest::newRow("(t)he|characters")
+            << standard[0] << 0 << 1 << QQuickTextEdit::SelectCharacters << 0 << 1 << true;
+    QTest::newRow("do(g)|characters")
+            << standard[0] << 43 << 44 << QQuickTextEdit::SelectCharacters << 43 << 44 << true;
+    QTest::newRow("jum(p)ed|characters")
+            << standard[0] << 23 << 24 << QQuickTextEdit::SelectCharacters << 23 << 24 << true;
+    QTest::newRow("jumped( )over|characters")
+            << standard[0] << 26 << 27 << QQuickTextEdit::SelectCharacters << 26 << 27 << true;
+    QTest::newRow("(the )|characters")
+            << standard[0] << 0 << 4 << QQuickTextEdit::SelectCharacters << 0 << 4 << true;
+    QTest::newRow("( dog)|characters")
+            << standard[0] << 40 << 44 << QQuickTextEdit::SelectCharacters << 40 << 44 << true;
+    QTest::newRow("( jumped )|characters")
+            << standard[0] << 19 << 27 << QQuickTextEdit::SelectCharacters << 19 << 27 << true;
+    QTest::newRow("th(e qu)ick|characters")
+            << standard[0] << 2 << 6 << QQuickTextEdit::SelectCharacters << 2 << 6 << true;
+    QTest::newRow("la(zy d)og|characters")
+            << standard[0] << 38 << 42 << QQuickTextEdit::SelectCharacters << 38 << 42 << true;
+    QTest::newRow("jum(ped ov)er|characters")
+            << standard[0] << 23 << 29 << QQuickTextEdit::SelectCharacters << 23 << 29 << true;
+    QTest::newRow("()the|characters")
+            << standard[0] << 0 << 0 << QQuickTextEdit::SelectCharacters << 0 << 0 << true;
+    QTest::newRow("dog()|characters")
+            << standard[0] << 44 << 44 << QQuickTextEdit::SelectCharacters << 44 << 44 << true;
+    QTest::newRow("jum()ped|characters")
+            << standard[0] << 23 << 23 << QQuickTextEdit::SelectCharacters << 23 << 23 << true;
+
+    QTest::newRow("<(t)he>|words")
+            << standard[0] << 0 << 1 << QQuickTextEdit::SelectWords << 0 << 3 << true;
+    QTest::newRow("<do(g)>|words")
+            << standard[0] << 43 << 44 << QQuickTextEdit::SelectWords << 41 << 44 << true;
+    QTest::newRow("<jum(p)ed>|words")
+            << standard[0] << 23 << 24 << QQuickTextEdit::SelectWords << 20 << 26 << true;
+    QTest::newRow("<jumped( )>over|words")
+            << standard[0] << 26 << 27 << QQuickTextEdit::SelectWords << 20 << 27 << false;
+    QTest::newRow("jumped<( )over>|words,reversed")
+            << standard[0] << 27 << 26 << QQuickTextEdit::SelectWords << 26 << 31 << false;
+    QTest::newRow("<(the )>quick|words")
+            << standard[0] << 0 << 4 << QQuickTextEdit::SelectWords << 0 << 4 << false;
+    QTest::newRow("<(the )quick>|words,reversed")
+            << standard[0] << 4 << 0 << QQuickTextEdit::SelectWords << 0 << 9 << false;
+    QTest::newRow("<lazy( dog)>|words")
+            << standard[0] << 40 << 44 << QQuickTextEdit::SelectWords << 36 << 44 << false;
+    QTest::newRow("lazy<( dog)>|words,reversed")
+            << standard[0] << 44 << 40 << QQuickTextEdit::SelectWords << 40 << 44 << false;
+    QTest::newRow("<fox( jumped )>over|words")
+            << standard[0] << 19 << 27 << QQuickTextEdit::SelectWords << 16 << 27 << false;
+    QTest::newRow("fox<( jumped )over>|words,reversed")
+            << standard[0] << 27 << 19 << QQuickTextEdit::SelectWords << 19 << 31 << false;
+    QTest::newRow("<th(e qu)ick>|words")
+            << standard[0] << 2 << 6 << QQuickTextEdit::SelectWords << 0 << 9 << true;
+    QTest::newRow("<la(zy d)og|words>")
+            << standard[0] << 38 << 42 << QQuickTextEdit::SelectWords << 36 << 44 << true;
+    QTest::newRow("<jum(ped ov)er>|words")
+            << standard[0] << 23 << 29 << QQuickTextEdit::SelectWords << 20 << 31 << true;
+    QTest::newRow("<()>the|words")
+            << standard[0] << 0 << 0 << QQuickTextEdit::SelectWords << 0 << 0 << true;
+    QTest::newRow("dog<()>|words")
+            << standard[0] << 44 << 44 << QQuickTextEdit::SelectWords << 44 << 44 << true;
+    QTest::newRow("jum<()>ped|words")
+            << standard[0] << 23 << 23 << QQuickTextEdit::SelectWords << 23 << 23 << true;
+
+    QTest::newRow("Hello<(,)> |words")
+            << standard[2] << 5 << 6 << QQuickTextEdit::SelectWords << 5 << 6 << true;
+    QTest::newRow("Hello<(, )>world|words")
+            << standard[2] << 5 << 7 << QQuickTextEdit::SelectWords << 5 << 7 << false;
+    QTest::newRow("Hello<(, )world>|words,reversed")
+            << standard[2] << 7 << 5 << QQuickTextEdit::SelectWords << 5 << 12 << false;
+    QTest::newRow("<Hel(lo, )>world|words")
+            << standard[2] << 3 << 7 << QQuickTextEdit::SelectWords << 0 << 7 << false;
+    QTest::newRow("<Hel(lo, )world>|words,reversed")
+            << standard[2] << 7 << 3 << QQuickTextEdit::SelectWords << 0 << 12 << false;
+    QTest::newRow("<Hel(lo)>,|words")
+            << standard[2] << 3 << 5 << QQuickTextEdit::SelectWords << 0 << 5 << true;
+    QTest::newRow("Hello<()>,|words")
+            << standard[2] << 5 << 5 << QQuickTextEdit::SelectWords << 5 << 5 << true;
+    QTest::newRow("Hello,<()>|words")
+            << standard[2] << 6 << 6 << QQuickTextEdit::SelectWords << 6 << 6 << true;
+    QTest::newRow("Hello<,( )>world|words")
+            << standard[2] << 6 << 7 << QQuickTextEdit::SelectWords << 5 << 7 << false;
+    QTest::newRow("Hello,<( )world>|words,reversed")
+            << standard[2] << 7 << 6 << QQuickTextEdit::SelectWords << 6 << 12 << false;
+    QTest::newRow("Hello<,( world)>|words")
+            << standard[2] << 6 << 12 << QQuickTextEdit::SelectWords << 5 << 12 << false;
+    QTest::newRow("Hello,<( world)>|words,reversed")
+            << standard[2] << 12 << 6 << QQuickTextEdit::SelectWords << 6 << 12 << false;
+    QTest::newRow("Hello<,( world!)>|words")
+            << standard[2] << 6 << 13 << QQuickTextEdit::SelectWords << 5 << 13 << false;
+    QTest::newRow("Hello,<( world!)>|words,reversed")
+            << standard[2] << 13 << 6 << QQuickTextEdit::SelectWords << 6 << 13 << false;
+    QTest::newRow("Hello<(, world!)>|words")
+            << standard[2] << 5 << 13 << QQuickTextEdit::SelectWords << 5 << 13 << true;
+    QTest::newRow("world<(!)>|words")
+            << standard[2] << 12 << 13 << QQuickTextEdit::SelectWords << 12 << 13 << true;
+    QTest::newRow("world!<()>)|words")
+            << standard[2] << 13 << 13 << QQuickTextEdit::SelectWords << 13 << 13 << true;
+    QTest::newRow("world<()>!)|words")
+            << standard[2] << 12 << 12 << QQuickTextEdit::SelectWords << 12 << 12 << true;
+
+    QTest::newRow("<(,)>olleH |words")
+            << standard[3] << 7 << 8 << QQuickTextEdit::SelectWords << 7 << 8 << true;
+    QTest::newRow("<dlrow( ,)>olleH|words")
+            << standard[3] << 6 << 8 << QQuickTextEdit::SelectWords << 1 << 8 << false;
+    QTest::newRow("dlrow<( ,)>olleH|words,reversed")
+            << standard[3] << 8 << 6 << QQuickTextEdit::SelectWords << 6 << 8 << false;
+    QTest::newRow("<dlrow( ,ol)leH>|words")
+            << standard[3] << 6 << 10 << QQuickTextEdit::SelectWords << 1 << 13 << false;
+    QTest::newRow("dlrow<( ,ol)leH>|words,reversed")
+            << standard[3] << 10 << 6 << QQuickTextEdit::SelectWords << 6 << 13 << false;
+    QTest::newRow(",<(ol)leH>,|words")
+            << standard[3] << 8 << 10 << QQuickTextEdit::SelectWords << 8 << 13 << true;
+    QTest::newRow(",<()>olleH|words")
+            << standard[3] << 8 << 8 << QQuickTextEdit::SelectWords << 8 << 8 << true;
+    QTest::newRow("<()>,olleH|words")
+            << standard[3] << 7 << 7 << QQuickTextEdit::SelectWords << 7 << 7 << true;
+    QTest::newRow("<dlrow( )>,olleH|words")
+            << standard[3] << 6 << 7 << QQuickTextEdit::SelectWords << 1 << 7 << false;
+    QTest::newRow("dlrow<( ),>olleH|words,reversed")
+            << standard[3] << 7 << 6 << QQuickTextEdit::SelectWords << 6 << 8 << false;
+    QTest::newRow("<(dlrow )>,olleH|words")
+            << standard[3] << 1 << 7 << QQuickTextEdit::SelectWords << 1 << 7 << false;
+    QTest::newRow("<(dlrow ),>olleH|words,reversed")
+            << standard[3] << 7 << 1 << QQuickTextEdit::SelectWords << 1 << 8 << false;
+    QTest::newRow("<(!dlrow )>,olleH|words")
+            << standard[3] << 0 << 7 << QQuickTextEdit::SelectWords << 0 << 7 << false;
+    QTest::newRow("<(!dlrow ),>olleH|words,reversed")
+            << standard[3] << 7 << 0 << QQuickTextEdit::SelectWords << 0 << 8 << false;
+    QTest::newRow("(!dlrow ,)olleH|words")
+            << standard[3] << 0 << 8 << QQuickTextEdit::SelectWords << 0 << 8 << true;
+    QTest::newRow("<(!)>dlrow|words")
+            << standard[3] << 0 << 1 << QQuickTextEdit::SelectWords << 0 << 1 << true;
+    QTest::newRow("<()>!dlrow|words")
+            << standard[3] << 0 << 0 << QQuickTextEdit::SelectWords << 0 << 0 << true;
+    QTest::newRow("!<()>dlrow|words")
+            << standard[3] << 1 << 1 << QQuickTextEdit::SelectWords << 1 << 1 << true;
+}
+
+void tst_qquicktextedit::moveCursorSelection()
+{
+    QFETCH(QString, testStr);
+    QFETCH(int, cursorPosition);
+    QFETCH(int, movePosition);
+    QFETCH(QQuickTextEdit::SelectionMode, mode);
+    QFETCH(int, selectionStart);
+    QFETCH(int, selectionEnd);
+    QFETCH(bool, reversible);
+
+    QString componentStr = "import QtQuick 2.0\nTextEdit {  text: \""+ testStr +"\"; }";
+    QDeclarativeComponent textinputComponent(&engine);
+    textinputComponent.setData(componentStr.toLatin1(), QUrl());
+    QQuickTextEdit *texteditObject = qobject_cast<QQuickTextEdit*>(textinputComponent.create());
+    QVERIFY(texteditObject != 0);
+
+    texteditObject->setCursorPosition(cursorPosition);
+    texteditObject->moveCursorSelection(movePosition, mode);
+
+    QCOMPARE(texteditObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart));
+    QCOMPARE(texteditObject->selectionStart(), selectionStart);
+    QCOMPARE(texteditObject->selectionEnd(), selectionEnd);
+
+    if (reversible) {
+        texteditObject->setCursorPosition(movePosition);
+        texteditObject->moveCursorSelection(cursorPosition, mode);
+
+        QCOMPARE(texteditObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart));
+        QCOMPARE(texteditObject->selectionStart(), selectionStart);
+        QCOMPARE(texteditObject->selectionEnd(), selectionEnd);
+    }
+}
+
+void tst_qquicktextedit::moveCursorSelectionSequence_data()
+{
+    QTest::addColumn<QString>("testStr");
+    QTest::addColumn<int>("cursorPosition");
+    QTest::addColumn<int>("movePosition1");
+    QTest::addColumn<int>("movePosition2");
+    QTest::addColumn<int>("selection1Start");
+    QTest::addColumn<int>("selection1End");
+    QTest::addColumn<int>("selection2Start");
+    QTest::addColumn<int>("selection2End");
+
+    QTest::newRow("the {<quick( bro)wn> f^ox} jumped|ltr")
+            << standard[0]
+            << 9 << 13 << 17
+            << 4 << 15
+            << 4 << 19;
+    QTest::newRow("the quick<( {bro)wn> f^ox} jumped|rtl")
+            << standard[0]
+            << 13 << 9 << 17
+            << 9 << 15
+            << 10 << 19;
+    QTest::newRow("the {<quick( bro)wn> ^}fox jumped|ltr")
+            << standard[0]
+            << 9 << 13 << 16
+            << 4 << 15
+            << 4 << 16;
+    QTest::newRow("the quick<( {bro)wn> ^}fox jumped|rtl")
+            << standard[0]
+            << 13 << 9 << 16
+            << 9 << 15
+            << 10 << 16;
+    QTest::newRow("the {<quick( bro)wn^>} fox jumped|ltr")
+            << standard[0]
+            << 9 << 13 << 15
+            << 4 << 15
+            << 4 << 15;
+    QTest::newRow("the quick<( {bro)wn^>} f^ox jumped|rtl")
+            << standard[0]
+            << 13 << 9 << 15
+            << 9 << 15
+            << 10 << 15;
+    QTest::newRow("the {<quick() ^}bro)wn> fox|ltr")
+            << standard[0]
+            << 9 << 13 << 10
+            << 4 << 15
+            << 4 << 10;
+    QTest::newRow("the quick<(^ {^bro)wn>} fox|rtl")
+            << standard[0]
+            << 13 << 9 << 10
+            << 9 << 15
+            << 10 << 15;
+    QTest::newRow("the {<quick^}( bro)wn> fox|ltr")
+            << standard[0]
+            << 9 << 13 << 9
+            << 4 << 15
+            << 4 << 9;
+    QTest::newRow("the quick{<(^ bro)wn>} fox|rtl")
+            << standard[0]
+            << 13 << 9 << 9
+            << 9 << 15
+            << 9 << 15;
+    QTest::newRow("the {<qui^ck}( bro)wn> fox|ltr")
+            << standard[0]
+            << 9 << 13 << 7
+            << 4 << 15
+            << 4 << 9;
+    QTest::newRow("the {<qui^ck}( bro)wn> fox|rtl")
+            << standard[0]
+            << 13 << 9 << 7
+            << 9 << 15
+            << 4 << 15;
+    QTest::newRow("the {<^quick}( bro)wn> fox|ltr")
+            << standard[0]
+            << 9 << 13 << 4
+            << 4 << 15
+            << 4 << 9;
+    QTest::newRow("the {<^quick}( bro)wn> fox|rtl")
+            << standard[0]
+            << 13 << 9 << 4
+            << 9 << 15
+            << 4 << 15;
+    QTest::newRow("the{^ <quick}( bro)wn> fox|ltr")
+            << standard[0]
+            << 9 << 13 << 3
+            << 4 << 15
+            << 3 << 9;
+    QTest::newRow("the{^ <quick}( bro)wn> fox|rtl")
+            << standard[0]
+            << 13 << 9 << 3
+            << 9 << 15
+            << 3 << 15;
+    QTest::newRow("{t^he <quick}( bro)wn> fox|ltr")
+            << standard[0]
+            << 9 << 13 << 1
+            << 4 << 15
+            << 0 << 9;
+    QTest::newRow("{t^he <quick}( bro)wn> fox|rtl")
+            << standard[0]
+            << 13 << 9 << 1
+            << 9 << 15
+            << 0 << 15;
+
+    QTest::newRow("{<He(ll)o>, w^orld}!|ltr")
+            << standard[2]
+            << 2 << 4 << 8
+            << 0 << 5
+            << 0 << 12;
+    QTest::newRow("{<He(ll)o>, w^orld}!|rtl")
+            << standard[2]
+            << 4 << 2 << 8
+            << 0 << 5
+            << 0 << 12;
+
+    QTest::newRow("!{dlro^w ,<o(ll)eH>}|ltr")
+            << standard[3]
+            << 9 << 11 << 5
+            << 8 << 13
+            << 1 << 13;
+    QTest::newRow("!{dlro^w ,<o(ll)eH>}|rtl")
+            << standard[3]
+            << 11 << 9 << 5
+            << 8 << 13
+            << 1 << 13;
+}
+
+void tst_qquicktextedit::moveCursorSelectionSequence()
+{
+    QFETCH(QString, testStr);
+    QFETCH(int, cursorPosition);
+    QFETCH(int, movePosition1);
+    QFETCH(int, movePosition2);
+    QFETCH(int, selection1Start);
+    QFETCH(int, selection1End);
+    QFETCH(int, selection2Start);
+    QFETCH(int, selection2End);
+
+    QString componentStr = "import QtQuick 2.0\nTextEdit {  text: \""+ testStr +"\"; }";
+    QDeclarativeComponent texteditComponent(&engine);
+    texteditComponent.setData(componentStr.toLatin1(), QUrl());
+    QQuickTextEdit *texteditObject = qobject_cast<QQuickTextEdit*>(texteditComponent.create());
+    QVERIFY(texteditObject != 0);
+
+    texteditObject->setCursorPosition(cursorPosition);
+
+    texteditObject->moveCursorSelection(movePosition1, QQuickTextEdit::SelectWords);
+    QCOMPARE(texteditObject->selectedText(), testStr.mid(selection1Start, selection1End - selection1Start));
+    QCOMPARE(texteditObject->selectionStart(), selection1Start);
+    QCOMPARE(texteditObject->selectionEnd(), selection1End);
+
+    texteditObject->moveCursorSelection(movePosition2, QQuickTextEdit::SelectWords);
+    QCOMPARE(texteditObject->selectedText(), testStr.mid(selection2Start, selection2End - selection2Start));
+    QCOMPARE(texteditObject->selectionStart(), selection2Start);
+    QCOMPARE(texteditObject->selectionEnd(), selection2End);
+}
+
+
+void tst_qquicktextedit::mouseSelection_data()
+{
+    QTest::addColumn<QString>("qmlfile");
+    QTest::addColumn<int>("from");
+    QTest::addColumn<int>("to");
+    QTest::addColumn<QString>("selectedText");
+
+    // import installed
+    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_qquicktextedit::mouseSelection()
+{
+    QFETCH(QString, qmlfile);
+    QFETCH(int, from);
+    QFETCH(int, to);
+    QFETCH(QString, selectedText);
+
+    QQuickView canvas(QUrl::fromLocalFile(qmlfile));
+
+    canvas.show();
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&canvas);
+    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
+
+    QVERIFY(canvas.rootObject() != 0);
+    QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit *>(canvas.rootObject());
+    QVERIFY(textEditObject != 0);
+
+    // press-and-drag-and-release from x1 to x2
+    QPoint p1 = textEditObject->positionToRectangle(from).center().toPoint();
+    QPoint p2 = textEditObject->positionToRectangle(to).center().toPoint();
+    QTest::mousePress(&canvas, Qt::LeftButton, 0, p1);
+    QTest::mouseMove(&canvas, p2);
+    QTest::mouseRelease(&canvas, Qt::LeftButton, 0, p2);
+    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);
+    QTest::qWait(50);
+    if (!selectedText.isEmpty())
+        QEXPECT_FAIL("", "QTBUG-21743", Continue);
+    QTRY_COMPARE(textEditObject->selectedText(), selectedText);
+}
+
+void tst_qquicktextedit::dragMouseSelection()
+{
+    QString qmlfile = TESTDATA("mouseselection_true.qml");
+
+    QQuickView canvas(QUrl::fromLocalFile(qmlfile));
+
+    canvas.show();
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&canvas);
+    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
+
+    QVERIFY(canvas.rootObject() != 0);
+    QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit *>(canvas.rootObject());
+    QVERIFY(textEditObject != 0);
+
+    // press-and-drag-and-release from x1 to x2
+    int x1 = 10;
+    int x2 = 70;
+    int y = textEditObject->height()/2;
+    QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y));
+    QTest::mouseMove(&canvas, QPoint(x2, y));
+    QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y));
+    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));
+    QTest::mouseMove(&canvas, QPoint(x2, y));
+    QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y));
+    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.
+}
+
+void tst_qquicktextedit::mouseSelectionMode_data()
+{
+    QTest::addColumn<QString>("qmlfile");
+    QTest::addColumn<bool>("selectWords");
+
+    // import installed
+    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_qquicktextedit::mouseSelectionMode()
+{
+    QFETCH(QString, qmlfile);
+    QFETCH(bool, selectWords);
+
+    QString text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+    QQuickView canvas(QUrl::fromLocalFile(qmlfile));
+
+    canvas.show();
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&canvas);
+    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
+
+    QVERIFY(canvas.rootObject() != 0);
+    QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit *>(canvas.rootObject());
+    QVERIFY(textEditObject != 0);
+
+    // press-and-drag-and-release from x1 to x2
+    int x1 = 10;
+    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);
+//    QGuiApplication::sendEvent(&canvas, &mv);
+    QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y));
+    QString str = textEditObject->selectedText();
+    if (selectWords) {
+        QTRY_COMPARE(textEditObject->selectedText(), text);
+    } else {
+        QTRY_VERIFY(textEditObject->selectedText().length() > 3);
+        QVERIFY(str != text);
+    }
+}
+
+void tst_qquicktextedit::inputMethodHints()
+{
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("inputmethodhints.qml")));
+    canvas.show();
+    canvas.requestActivateWindow();
+
+    QVERIFY(canvas.rootObject() != 0);
+    QQuickTextEdit *textEditObject = qobject_cast<QQuickTextEdit *>(canvas.rootObject());
+    QVERIFY(textEditObject != 0);
+    QVERIFY(textEditObject->inputMethodHints() & Qt::ImhNoPredictiveText);
+    textEditObject->setInputMethodHints(Qt::ImhUppercaseOnly);
+    QVERIFY(textEditObject->inputMethodHints() & Qt::ImhUppercaseOnly);
+}
+
+void tst_qquicktextedit::positionAt()
+{
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("positionAt.qml")));
+    QVERIFY(canvas.rootObject() != 0);
+    canvas.show();
+    canvas.requestActivateWindow();
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&canvas);
+
+    QQuickTextEdit *texteditObject = qobject_cast<QQuickTextEdit *>(canvas.rootObject());
+    QVERIFY(texteditObject != 0);
+
+    QFontMetrics fm(texteditObject->font());
+    const int y0 = fm.height() / 2;
+    const int y1 = fm.height() * 3 / 2;
+
+    int pos = texteditObject->positionAt(texteditObject->width()/2, y0);
+    int width = 0;
+    if (!qmlDisableDistanceField()) {
+        QTextLayout layout(texteditObject->text().left(pos));
+
+        {
+            QTextOption option;
+            option.setUseDesignMetrics(true);
+            layout.setTextOption(option);
+        }
+
+        layout.beginLayout();
+        QTextLine line = layout.createLine();
+        layout.endLayout();
+
+        width = ceil(line.horizontalAdvance());
+
+    } else {
+        width = fm.width(texteditObject->text().left(pos));
+    }
+
+
+    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);
+#else
+    QVERIFY(diff < 5);
+#endif
+
+    const qreal x0 = texteditObject->positionToRectangle(pos).x();
+    const qreal x1 = texteditObject->positionToRectangle(pos + 1).x();
+
+    QString preeditText = texteditObject->text().mid(0, pos);
+    texteditObject->setText(texteditObject->text().mid(pos));
+    texteditObject->setCursorPosition(0);
+
+    QInputMethodEvent inputEvent(preeditText, QList<QInputMethodEvent::Attribute>());
+    QGuiApplication::sendEvent(&canvas, &inputEvent);
+
+    // Check all points within the preedit text return the same position.
+    QCOMPARE(texteditObject->positionAt(0, y0), 0);
+    QCOMPARE(texteditObject->positionAt(x0 / 2, y0), 0);
+    QCOMPARE(texteditObject->positionAt(x0, y0), 0);
+
+    // Verify positioning returns to normal after the preedit text.
+    QCOMPARE(texteditObject->positionAt(x1, y0), 1);
+    QCOMPARE(texteditObject->positionToRectangle(1).x(), x1);
+
+    QVERIFY(texteditObject->positionAt(x0 / 2, y1) > 0);
+}
+
+void tst_qquicktextedit::cursorDelegate()
+{
+    QQuickView view(QUrl::fromLocalFile(TESTDATA("cursorTest.qml")));
+    view.show();
+    view.requestActivateWindow();
+    QQuickTextEdit *textEditObject = view.rootObject()->findChild<QQuickTextEdit*>("textEditObject");
+    QVERIFY(textEditObject != 0);
+    QVERIFY(textEditObject->findChild<QQuickItem*>("cursorInstance"));
+    //Test Delegate gets created
+    textEditObject->setFocus(true);
+    QQuickItem* delegateObject = textEditObject->findChild<QQuickItem*>("cursorInstance");
+    QVERIFY(delegateObject);
+    QCOMPARE(delegateObject->property("localProperty").toString(), QString("Hello"));
+    //Test Delegate gets moved
+    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;
+    QGuiApplication::sendEvent(&view, &event);
+
+
+    // Test delegate gets moved on mouse press.
+    textEditObject->setSelectByMouse(true);
+    textEditObject->setCursorPosition(0);
+    const QPoint point1 = textEditObject->positionToRectangle(5).center().toPoint();
+    QTest::mouseClick(&view, Qt::LeftButton, 0, point1);
+    QTest::qWait(50);
+    QTRY_VERIFY(textEditObject->cursorPosition() != 0);
+    QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
+    QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
+
+    // Test delegate gets moved on mouse drag
+    textEditObject->setCursorPosition(0);
+    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);
+    QGuiApplication::sendEvent(&view, &mv);
+    QTest::mouseRelease(&view, Qt::LeftButton, 0, point2);
+    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());
+    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());
+    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);
+    QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
+    QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
+    //Test Delegate gets deleted
+    textEditObject->setCursorDelegate(0);
+    QVERIFY(!textEditObject->findChild<QQuickItem*>("cursorInstance"));
+}
+
+void tst_qquicktextedit::cursorVisible()
+{
+    QQuickView view(QUrl::fromLocalFile(TESTDATA("cursorVisible.qml")));
+    view.show();
+    view.requestActivateWindow();
+    QTest::qWaitForWindowShown(&view);
+    QTRY_COMPARE(&view, qGuiApp->focusWindow());
+
+    QQuickTextEdit edit;
+    QSignalSpy spy(&edit, SIGNAL(cursorVisibleChanged(bool)));
+
+    QCOMPARE(edit.isCursorVisible(), false);
+
+    edit.setCursorVisible(true);
+    QCOMPARE(edit.isCursorVisible(), true);
+    QCOMPARE(spy.count(), 1);
+
+    edit.setCursorVisible(false);
+    QCOMPARE(edit.isCursorVisible(), false);
+    QCOMPARE(spy.count(), 2);
+
+    edit.setFocus(true);
+    QCOMPARE(edit.isCursorVisible(), false);
+    QCOMPARE(spy.count(), 2);
+
+    edit.setParentItem(view.rootObject());
+    QCOMPARE(edit.isCursorVisible(), true);
+    QCOMPARE(spy.count(), 3);
+
+    edit.setFocus(false);
+    QCOMPARE(edit.isCursorVisible(), false);
+    QCOMPARE(spy.count(), 4);
+
+    edit.setFocus(true);
+    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);
+
+    view.requestActivateWindow();
+    QCOMPARE(edit.isCursorVisible(), true);
+    QCOMPARE(spy.count(), 7);
+
+    // 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)
+    // 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
+}
+
+void tst_qquicktextedit::delegateLoading_data()
+{
+    QTest::addColumn<QString>("qmlfile");
+    QTest::addColumn<QString>("error");
+
+    // import installed
+    QTest::newRow("pass") << "cursorHttpTestPass.qml" << "";
+    QTest::newRow("fail1") << "cursorHttpTestFail1.qml" << "http://localhost:42332/FailItem.qml: Remote host closed the connection ";
+    QTest::newRow("fail2") << "cursorHttpTestFail2.qml" << "http://localhost:42332/ErrItem.qml:4:5: Fungus is not a type ";
+}
+
+void tst_qquicktextedit::delegateLoading()
+{
+    QFETCH(QString, qmlfile);
+    QFETCH(QString, error);
+
+    TestHTTPServer server(42332);
+    server.serveDirectory(TESTDATA("httpfail"), TestHTTPServer::Disconnect);
+    server.serveDirectory(TESTDATA("httpslow"), TestHTTPServer::Delay);
+    server.serveDirectory(TESTDATA("http"));
+
+    QQuickView view(QUrl(QLatin1String("http://localhost:42332/") + qmlfile));
+    view.show();
+    view.requestActivateWindow();
+
+    if (!error.isEmpty()) {
+        QTest::ignoreMessage(QtWarningMsg, error.toUtf8());
+        QTRY_VERIFY(view.status()==QQuickView::Error);
+        QTRY_VERIFY(!view.rootObject()); // there is fail item inside this test
+    } else {
+        QTRY_VERIFY(view.rootObject());//Wait for loading to finish.
+        QQuickTextEdit *textEditObject = view.rootObject()->findChild<QQuickTextEdit*>("textEditObject");
+        //    view.rootObject()->dumpObjectTree();
+        QVERIFY(textEditObject != 0);
+        textEditObject->setFocus(true);
+        QQuickItem *delegate;
+        delegate = view.rootObject()->findChild<QQuickItem*>("delegateOkay");
+        QVERIFY(delegate);
+        delegate = view.rootObject()->findChild<QQuickItem*>("delegateSlow");
+        QVERIFY(delegate);
+
+        delete delegate;
+    }
+
+
+    //A test should be added here with a component which is ready but component.create() returns null
+    //Not sure how to accomplish this with QQuickTextEdits cursor delegate
+    //###This was only needed for code coverage, and could be a case of overzealous defensive programming
+    //delegate = view.rootObject()->findChild<QQuickItem*>("delegateErrorB");
+    //QVERIFY(!delegate);
+}
+
+/*
+TextEdit element should only handle left/right keys until the cursor reaches
+the extent of the text, then they should ignore the keys.
+*/
+void tst_qquicktextedit::navigation()
+{
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml")));
+    canvas.show();
+    canvas.requestActivateWindow();
+
+    QVERIFY(canvas.rootObject() != 0);
+
+    QQuickItem *input = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(canvas.rootObject()->property("myInput")));
+
+    QVERIFY(input != 0);
+    QTRY_VERIFY(input->hasActiveFocus() == true);
+    simulateKey(&canvas, Qt::Key_Left);
+    QVERIFY(input->hasActiveFocus() == false);
+    simulateKey(&canvas, Qt::Key_Right);
+    QVERIFY(input->hasActiveFocus() == true);
+    simulateKey(&canvas, Qt::Key_Right);
+    QVERIFY(input->hasActiveFocus() == true);
+    simulateKey(&canvas, Qt::Key_Right);
+    QVERIFY(input->hasActiveFocus() == false);
+    simulateKey(&canvas, Qt::Key_Left);
+    QVERIFY(input->hasActiveFocus() == true);
+}
+
+void tst_qquicktextedit::copyAndPaste() {
+#ifndef QT_NO_CLIPBOARD
+
+#ifdef Q_WS_MAC
+    {
+        PasteboardRef pasteboard;
+        OSStatus status = PasteboardCreate(0, &pasteboard);
+        if (status == noErr)
+            CFRelease(pasteboard);
+        else
+            QSKIP("This machine doesn't support the clipboard");
+    }
+#endif
+
+    QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"Hello world!\" }";
+    QDeclarativeComponent textEditComponent(&engine);
+    textEditComponent.setData(componentStr.toLatin1(), QUrl());
+    QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit*>(textEditComponent.create());
+    QVERIFY(textEdit != 0);
+
+    // copy and paste
+    QCOMPARE(textEdit->text().length(), 12);
+    textEdit->select(0, textEdit->text().length());;
+    textEdit->copy();
+    QCOMPARE(textEdit->selectedText(), QString("Hello world!"));
+    QCOMPARE(textEdit->selectedText().length(), 12);
+    textEdit->setCursorPosition(0);
+    QVERIFY(textEdit->canPaste());
+    textEdit->paste();
+    QCOMPARE(textEdit->text(), QString("Hello world!Hello world!"));
+    QCOMPARE(textEdit->text().length(), 24);
+
+    // canPaste
+    QVERIFY(textEdit->canPaste());
+    textEdit->setReadOnly(true);
+    QVERIFY(!textEdit->canPaste());
+    textEdit->setReadOnly(false);
+    QVERIFY(textEdit->canPaste());
+
+    // QTBUG-12339
+    // test that document and internal text attribute are in sync
+    QQuickItemPrivate* pri = QQuickItemPrivate::get(textEdit);
+    QQuickTextEditPrivate *editPrivate = static_cast<QQuickTextEditPrivate*>(pri);
+    QCOMPARE(textEdit->text(), editPrivate->text);
+
+    // select word
+    textEdit->setCursorPosition(0);
+    textEdit->selectWord();
+    QCOMPARE(textEdit->selectedText(), QString("Hello"));
+
+    // select all and cut
+    textEdit->selectAll();
+    textEdit->cut();
+    QCOMPARE(textEdit->text().length(), 0);
+    textEdit->paste();
+    QCOMPARE(textEdit->text(), QString("Hello world!Hello world!"));
+    QCOMPARE(textEdit->text().length(), 24);
+#endif
+}
+
+void tst_qquicktextedit::canPaste() {
+#ifndef QT_NO_CLIPBOARD
+
+    QGuiApplication::clipboard()->setText("Some text");
+
+    QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"Hello world!\" }";
+    QDeclarativeComponent textEditComponent(&engine);
+    textEditComponent.setData(componentStr.toLatin1(), QUrl());
+    QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit*>(textEditComponent.create());
+    QVERIFY(textEdit != 0);
+
+    // check initial value - QTBUG-17765
+    QTextControl tc;
+    QCOMPARE(textEdit->canPaste(), tc.canPaste());
+
+#endif
+}
+
+void tst_qquicktextedit::canPasteEmpty() {
+#ifndef QT_NO_CLIPBOARD
+
+    QGuiApplication::clipboard()->clear();
+
+    QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"Hello world!\" }";
+    QDeclarativeComponent textEditComponent(&engine);
+    textEditComponent.setData(componentStr.toLatin1(), QUrl());
+    QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit*>(textEditComponent.create());
+    QVERIFY(textEdit != 0);
+
+    // check initial value - QTBUG-17765
+    QTextControl tc;
+    QCOMPARE(textEdit->canPaste(), tc.canPaste());
+
+#endif
+}
+
+void tst_qquicktextedit::readOnly()
+{
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("readOnly.qml")));
+    canvas.show();
+    canvas.requestActivateWindow();
+
+    QVERIFY(canvas.rootObject() != 0);
+
+    QQuickTextEdit *edit = qobject_cast<QQuickTextEdit *>(qvariant_cast<QObject *>(canvas.rootObject()->property("myInput")));
+
+    QVERIFY(edit != 0);
+    QTRY_VERIFY(edit->hasActiveFocus() == true);
+    QVERIFY(edit->isReadOnly() == true);
+    QString initial = edit->text();
+    for (int k=Qt::Key_0; k<=Qt::Key_Z; k++)
+        simulateKey(&canvas, k);
+    simulateKey(&canvas, Qt::Key_Return);
+    simulateKey(&canvas, Qt::Key_Space);
+    simulateKey(&canvas, Qt::Key_Escape);
+    QCOMPARE(edit->text(), initial);
+
+    edit->setCursorPosition(3);
+    edit->setReadOnly(false);
+    QCOMPARE(edit->isReadOnly(), false);
+    QCOMPARE(edit->cursorPosition(), edit->text().length());
+}
+
+void tst_qquicktextedit::simulateKey(QQuickView *view, int key, Qt::KeyboardModifiers modifiers)
+{
+    QKeyEvent press(QKeyEvent::KeyPress, key, modifiers);
+    QKeyEvent release(QKeyEvent::KeyRelease, key, modifiers);
+
+    QGuiApplication::sendEvent(view, &press);
+    QGuiApplication::sendEvent(view, &release);
+}
+
+
+#ifndef QTBUG_21691
+class MyInputContext : public QInputContext
+{
+public:
+    MyInputContext() : updateReceived(false), eventType(QEvent::None) {}
+    ~MyInputContext() {}
+
+    QString identifierName() { return QString(); }
+    QString language() { return QString(); }
+
+    void reset() {}
+
+    bool isComposing() const { return false; }
+
+    void update() { updateReceived = true; }
+
+    void sendPreeditText(const QString &text, int cursor)
+    {
+        QList<QInputMethodEvent::Attribute> attributes;
+        attributes.append(QInputMethodEvent::Attribute(
+                QInputMethodEvent::Cursor, cursor, text.length(), QVariant()));
+
+        QInputMethodEvent event(text, attributes);
+        sendEvent(event);
+    }
+
+    void mouseHandler(int x, QMouseEvent *event)
+    {
+        cursor = x;
+        eventType = event->type();
+        eventPosition = event->pos();
+        eventGlobalPosition = event->globalPos();
+        eventButton = event->button();
+        eventButtons = event->buttons();
+        eventModifiers = event->modifiers();
+    }
+
+    bool updateReceived;
+    int cursor;
+    QEvent::Type eventType;
+    QPoint eventPosition;
+    QPoint eventGlobalPosition;
+    Qt::MouseButton eventButton;
+    Qt::MouseButtons eventButtons;
+    Qt::KeyboardModifiers eventModifiers;
+};
+#endif
+
+void tst_qquicktextedit::textInput()
+{
+    QQuickView view(QUrl::fromLocalFile(TESTDATA("inputMethodEvent.qml")));
+    view.show();
+    view.requestActivateWindow();
+    QTest::qWaitForWindowShown(&view);
+    QTRY_COMPARE(&view, qGuiApp->focusWindow());
+    QQuickTextEdit *edit = qobject_cast<QQuickTextEdit *>(view.rootObject());
+    QVERIFY(edit);
+    QVERIFY(edit->hasActiveFocus() == true);
+
+    // test that input method event is committed
+    QInputMethodEvent event;
+    event.setCommitString( "Hello world!", 0, 0);
+    QGuiApplication::sendEvent(&view, &event);
+    QEXPECT_FAIL("", "QTBUG-21689", Abort);
+    QCOMPARE(edit->text(), QString("Hello world!"));
+
+    // QTBUG-12339
+    // test that document and internal text attribute are in sync
+    QQuickTextEditPrivate *editPrivate = static_cast<QQuickTextEditPrivate*>(QQuickItemPrivate::get(edit));
+    QCOMPARE(editPrivate->text, QString("Hello world!"));
+}
+
+void tst_qquicktextedit::openInputPanel()
+{
+    QQuickView view(QUrl::fromLocalFile(TESTDATA("openInputPanel.qml")));
+    view.show();
+    view.requestActivateWindow();
+    QTest::qWaitForWindowShown(&view);
+    QTRY_COMPARE(&view, qGuiApp->focusWindow());
+
+    QQuickTextEdit *edit = qobject_cast<QQuickTextEdit *>(view.rootObject());
+    QVERIFY(edit);
+
+    // check default values
+    QVERIFY(edit->focusOnPress());
+    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(qApp->inputPanel()->inputItem(), edit);
+    QCOMPARE(qApp->inputPanel()->visible(), true);
+    QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint);
+
+    // 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, noModifiers, centerPoint);
+    QGuiApplication::processEvents();
+    QCOMPARE(qApp->inputPanel()->visible(), true);
+    QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint);
+
+    // input panel should stay visible if focus is lost to another text editor
+    QSignalSpy inputPanelVisibilitySpy(qApp->inputPanel(), SIGNAL(visibleChanged()));
+    QQuickTextEdit anotherEdit;
+    anotherEdit.setParentItem(view.rootObject());
+    anotherEdit.setFocus(true);
+    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
+    QQuickItem item;
+    item.setParentItem(view.rootObject());
+    item.setFocus(true);
+    QCOMPARE(qApp->inputPanel()->inputItem(), static_cast<QObject*>(0));
+    QCOMPARE(view.activeFocusItem(), &item);
+
+    qApp->inputPanel()->hide();
+
+    // input panel should not be opened if TextEdit is read only
+    edit->setReadOnly(true);
+    edit->setFocus(true);
+    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);
+
+    // input panel should not be opened if focusOnPress is set to false
+    edit->setFocusOnPress(false);
+    edit->setFocus(false);
+    edit->setFocus(true);
+    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 panel should open when openSoftwareInputPanel is called
+    edit->openSoftwareInputPanel();
+    QCOMPARE(qApp->inputPanel()->visible(), true);
+
+    // input panel should close when closeSoftwareInputPanel is called
+    edit->closeSoftwareInputPanel();
+    QCOMPARE(qApp->inputPanel()->visible(), false);
+}
+
+void tst_qquicktextedit::geometrySignals()
+{
+    QDeclarativeComponent component(&engine, TESTDATA("geometrySignals.qml"));
+    QObject *o = component.create();
+    QVERIFY(o);
+    QCOMPARE(o->property("bindingWidth").toInt(), 400);
+    QCOMPARE(o->property("bindingHeight").toInt(), 500);
+    delete o;
+}
+
+void tst_qquicktextedit::pastingRichText_QTBUG_14003()
+{
+#ifndef QT_NO_CLIPBOARD
+    QString componentStr = "import QtQuick 2.0\nTextEdit { textFormat: TextEdit.PlainText }";
+    QDeclarativeComponent component(&engine);
+    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickTextEdit *obj = qobject_cast<QQuickTextEdit*>(component.create());
+
+    QTRY_VERIFY(obj != 0);
+    QTRY_VERIFY(obj->textFormat() == QQuickTextEdit::PlainText);
+
+    QMimeData *mData = new QMimeData;
+    mData->setHtml("<font color=\"red\">Hello</font>");
+    QGuiApplication::clipboard()->setMimeData(mData);
+
+    obj->paste();
+    QTRY_VERIFY(obj->text() == "");
+    QTRY_VERIFY(obj->textFormat() == QQuickTextEdit::PlainText);
+#endif
+}
+
+void tst_qquicktextedit::implicitSize_data()
+{
+    QTest::addColumn<QString>("text");
+    QTest::addColumn<QString>("wrap");
+    QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap";
+    QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.NoWrap";
+    QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap";
+    QTest::newRow("richtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.Wrap";
+}
+
+void tst_qquicktextedit::implicitSize()
+{
+    QFETCH(QString, text);
+    QFETCH(QString, wrap);
+    QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + " }";
+    QDeclarativeComponent textComponent(&engine);
+    textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickTextEdit *textObject = qobject_cast<QQuickTextEdit*>(textComponent.create());
+
+    QVERIFY(textObject->width() < textObject->implicitWidth());
+    QVERIFY(textObject->height() == textObject->implicitHeight());
+
+    textObject->resetWidth();
+    QVERIFY(textObject->width() == textObject->implicitWidth());
+    QVERIFY(textObject->height() == textObject->implicitHeight());
+}
+
+void tst_qquicktextedit::testQtQuick11Attributes()
+{
+    QFETCH(QString, code);
+    QFETCH(QString, warning);
+    QFETCH(QString, error);
+
+    QDeclarativeEngine engine;
+    QObject *obj;
+
+    QDeclarativeComponent valid(&engine);
+    valid.setData("import QtQuick 2.0; TextEdit { " + code.toUtf8() + " }", QUrl(""));
+    obj = valid.create();
+    QVERIFY(obj);
+    QVERIFY(valid.errorString().isEmpty());
+    delete obj;
+
+    QDeclarativeComponent invalid(&engine);
+    invalid.setData("import QtQuick 1.0; TextEdit { " + code.toUtf8() + " }", QUrl(""));
+    QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
+    obj = invalid.create();
+    QCOMPARE(invalid.errorString(), error);
+    delete obj;
+}
+
+void tst_qquicktextedit::testQtQuick11Attributes_data()
+{
+    QTest::addColumn<QString>("code");
+    QTest::addColumn<QString>("warning");
+    QTest::addColumn<QString>("error");
+
+    QTest::newRow("canPaste") << "property bool foo: canPaste"
+        << "<Unknown File>:1: ReferenceError: Can't find variable: canPaste"
+        << "";
+
+    QTest::newRow("lineCount") << "property int foo: lineCount"
+        << "<Unknown File>:1: ReferenceError: Can't find variable: lineCount"
+        << "";
+
+    QTest::newRow("moveCursorSelection") << "Component.onCompleted: moveCursorSelection(0, TextEdit.SelectCharacters)"
+        << "<Unknown File>:1: ReferenceError: Can't find variable: moveCursorSelection"
+        << "";
+
+    QTest::newRow("deselect") << "Component.onCompleted: deselect()"
+        << "<Unknown File>:1: ReferenceError: Can't find variable: deselect"
+        << "";
+
+    QTest::newRow("onLinkActivated") << "onLinkActivated: {}"
+        << "QDeclarativeComponent: Component is not ready"
+        << ":1 \"TextEdit.onLinkActivated\" is not available in QtQuick 1.0.\n";
+}
+
+void tst_qquicktextedit::preeditMicroFocus()
+{
+#ifdef QTBUG_21691
+    QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
+    QVERIFY(false);
+#else
+    QString preeditText = "super";
+
+    QQuickView view(QUrl::fromLocalFile(TESTDATA("inputMethodEvent.qml")));
+    view.show();
+    view.requestActivateWindow();
+    QTest::qWaitForWindowShown(&view);
+
+    QTRY_COMPARE(&view, qGuiApp->focusWindow());
+    QQuickTextEdit *edit = qobject_cast<QQuickTextEdit *>(view.rootObject());
+    QVERIFY(edit);
+
+    QSignalSpy cursorRectangleSpy(edit, SIGNAL(cursorRectangleChanged()));
+
+    QRect currentRect;
+    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::ImCursorRectangle).toRect();
+    QCOMPARE(currentRect, previousRect);
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
+    QCOMPARE(ic.updateReceived, false); // The cursor position hasn't changed.
+#endif
+    QCOMPARE(cursorRectangleSpy.count(), 0);
+
+    // Verify that the micro focus rect moves to the left as the cursor position
+    // is incremented.
+    for (int i = 1; i <= 5; ++i) {
+        ic.updateReceived = false;
+        ic.sendPreeditText(preeditText, i);
+        currentRect = edit->inputMethodQuery(Qt::ImCursorRectangle).toRect();
+        QVERIFY(previousRect.left() < currentRect.left());
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
+        QCOMPARE(ic.updateReceived, true);
+#endif
+        QVERIFY(cursorRectangleSpy.count() > 0);
+        cursorRectangleSpy.clear();
+        previousRect = currentRect;
+    }
+
+    // Verify that if there is no preedit cursor then the micro focus rect is the
+    // same as it would be if it were positioned at the end of the preedit text.
+    ic.sendPreeditText(preeditText, 0);
+    ic.updateReceived = false;
+    ic.sendEvent(QInputMethodEvent(preeditText, QList<QInputMethodEvent::Attribute>()));
+    currentRect = edit->inputMethodQuery(Qt::ImCursorRectangle).toRect();
+    QCOMPARE(currentRect, previousRect);
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
+    QCOMPARE(ic.updateReceived, true);
+#endif
+    QVERIFY(cursorRectangleSpy.count() > 0);
+#endif
+}
+
+void tst_qquicktextedit::inputContextMouseHandler()
+{
+
+#ifdef QTBUG_21691
+    QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
+    QVERIFY(false);
+#else
+    QString text = "supercalifragisiticexpialidocious!";
+
+    QQuickView view(QUrl::fromLocalFile(TESTDATA("inputContext.qml")));
+    MyInputContext ic;
+    // QQuickCanvas 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();
+    view.requestActivateWindow();
+    QTest::qWaitForWindowShown(&view);
+
+    QTRY_COMPARE(&view, qGuiApp->focusWindow());
+    QQuickTextEdit *edit = qobject_cast<QQuickTextEdit *>(view.rootObject());
+    QVERIFY(edit);
+    edit->setCursorPosition(12);
+
+    QFontMetricsF fm(edit->font());
+    const qreal y = fm.height() / 2;
+
+    QPoint position2 = edit->mapToScene(QPointF(fm.width(text.mid(0, 2)), y)).toPoint();
+    QPoint position8 = edit->mapToScene(QPointF(fm.width(text.mid(0, 8)), y)).toPoint();
+    QPoint position20 = edit->mapToScene(QPointF(fm.width(text.mid(0, 20)), y)).toPoint();
+    QPoint position27 = edit->mapToScene(QPointF(fm.width(text.mid(0, 27)), y)).toPoint();
+    QPoint globalPosition2 = view.mapToGlobal(position2);
+    QPoint globalposition8 = view.mapToGlobal(position8);
+    QPoint globalposition20 = view.mapToGlobal(position20);
+    QPoint globalposition27 = view.mapToGlobal(position27);
+
+    ic.sendEvent(QInputMethodEvent(text.mid(12), QList<QInputMethodEvent::Attribute>()));
+
+    QTest::mouseDClick(&view, Qt::LeftButton, Qt::NoModifier, position2);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
+    QCOMPARE(ic.eventPosition, position2);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition2);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
+    QVERIFY(ic.cursor < 0);
+    ic.eventType = QEvent::None;
+
+    QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, position2);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
+    QCOMPARE(ic.eventPosition, position2);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition2);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
+    QVERIFY(ic.cursor < 0);
+    ic.eventType = QEvent::None;
+
+    {   QMouseEvent mv(QEvent::MouseMove, position8, globalposition8, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+        QGuiApplication::sendEvent(&view, &mv); }
+    QCOMPARE(ic.eventType, QEvent::None);
+
+    {   QMouseEvent mv(QEvent::MouseMove, position27, globalposition27, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+        QGuiApplication::sendEvent(&view, &mv); }
+    QCOMPARE(ic.eventType, QEvent::MouseMove);
+    QCOMPARE(ic.eventPosition, position27);
+        QCOMPARE(ic.eventGlobalPosition, globalposition27);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
+    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);    // 15 is expected but some platforms may be off by one.
+    ic.eventType = QEvent::None;
+
+    QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, position27);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
+    QCOMPARE(ic.eventPosition, position27);
+    QCOMPARE(ic.eventGlobalPosition, globalposition27);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
+    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
+    ic.eventType = QEvent::None;
+
+    // And in the other direction.
+    QTest::mouseDClick(&view, Qt::LeftButton, Qt::ControlModifier, position27);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
+    QCOMPARE(ic.eventPosition, position27);
+    QCOMPARE(ic.eventGlobalPosition, globalposition27);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
+    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
+    ic.eventType = QEvent::None;
+
+    QTest::mousePress(&view, Qt::RightButton, Qt::ControlModifier, position27);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
+    QCOMPARE(ic.eventPosition, position27);
+    QCOMPARE(ic.eventGlobalPosition, globalposition27);
+    QCOMPARE(ic.eventButton, Qt::RightButton);
+    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
+    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
+    ic.eventType = QEvent::None;
+
+    {   QMouseEvent mv(QEvent::MouseMove, position20, globalposition20, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
+        QGuiApplication::sendEvent(&view, &mv); }
+    QCOMPARE(ic.eventType, QEvent::MouseMove);
+    QCOMPARE(ic.eventPosition, position20);
+    QCOMPARE(ic.eventGlobalPosition, globalposition20);
+    QCOMPARE(ic.eventButton, Qt::RightButton);
+    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
+    QVERIFY(ic.cursor >= 7 && ic.cursor <= 9);
+    ic.eventType = QEvent::None;
+
+    {   QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
+        QGuiApplication::sendEvent(&view, &mv); }
+    QCOMPARE(ic.eventType, QEvent::None);
+
+    QTest::mouseRelease(&view, Qt::RightButton, Qt::ControlModifier, position2);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
+    QCOMPARE(ic.eventPosition, position2);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition2);
+    QCOMPARE(ic.eventButton, Qt::RightButton);
+    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
+    QVERIFY(ic.cursor < 0);
+    ic.eventType = QEvent::None;
+#endif
+}
+
+void tst_qquicktextedit::inputMethodComposing()
+{
+    QString text = "supercalifragisiticexpialidocious!";
+
+    QQuickView view(QUrl::fromLocalFile(TESTDATA("inputContext.qml")));
+    view.show();
+    view.requestActivateWindow();
+    QTest::qWaitForWindowShown(&view);
+    QTRY_COMPARE(&view, qGuiApp->focusWindow());
+    QQuickTextEdit *edit = qobject_cast<QQuickTextEdit *>(view.rootObject());
+    QVERIFY(edit);
+    QSignalSpy spy(edit, SIGNAL(inputMethodComposingChanged()));
+    edit->setCursorPosition(12);
+
+    QCOMPARE(edit->isInputMethodComposing(), false);
+
+    {
+        QInputMethodEvent event(text.mid(3), QList<QInputMethodEvent::Attribute>());
+        QGuiApplication::sendEvent(edit, &event);
+    }
+
+    QCOMPARE(edit->isInputMethodComposing(), true);
+    QCOMPARE(spy.count(), 1);
+
+    {
+        QInputMethodEvent event(text.mid(12), QList<QInputMethodEvent::Attribute>());
+        QGuiApplication::sendEvent(edit, &event);
+    }
+    QCOMPARE(spy.count(), 1);
+
+    {
+        QInputMethodEvent event;
+        QGuiApplication::sendEvent(edit, &event);
+    }
+    QCOMPARE(edit->isInputMethodComposing(), false);
+    QCOMPARE(spy.count(), 2);
+}
+
+void tst_qquicktextedit::cursorRectangleSize()
+{
+    QQuickView *canvas = new QQuickView(QUrl::fromLocalFile(TESTDATA("CursorRect.qml")));
+    QVERIFY(canvas->rootObject() != 0);
+    canvas->show();
+    canvas->requestActivateWindow();
+    QTest::qWaitForWindowShown(canvas);
+
+    QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit *>(canvas->rootObject());
+    QVERIFY(textEdit != 0);
+    textEdit->setFocus(Qt::OtherFocusReason);
+    QRectF cursorRect = textEdit->positionToRectangle(textEdit->cursorPosition());
+    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());
+
+    delete canvas;
+}
+
+void tst_qquicktextedit::emptytags_QTBUG_22058()
+{
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("qtbug-22058.qml")));
+    QVERIFY(canvas.rootObject() != 0);
+
+    canvas.show();
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&canvas);
+    QQuickTextEdit *input = qobject_cast<QQuickTextEdit *>(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_qquicktextedit)
+
+#include "tst_qquicktextedit.moc"
diff --git a/tests/auto/declarative/qquicktextinput/qquicktextinput.pro b/tests/auto/declarative/qquicktextinput/qquicktextinput.pro
new file mode 100644 (file)
index 0000000..9c74559
--- /dev/null
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qquicktextinput
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qquicktextinput.cpp
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private v8-private declarative-private opengl-private testlib
diff --git a/tests/auto/declarative/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/declarative/qquicktextinput/tst_qquicktextinput.cpp
new file mode 100644 (file)
index 0000000..8c8166b
--- /dev/null
@@ -0,0 +1,2725 @@
+/****************************************************************************
+**
+** 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/QSignalSpy>
+#include "../shared/util.h"
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QFile>
+#include <QtDeclarative/qquickview.h>
+#include <QtGui/qguiapplication.h>
+#include <QInputPanel>
+#include <private/qquicktextinput_p.h>
+#include <private/qquicktextinput_p_p.h>
+#include <QDebug>
+#include <QDir>
+#include <QStyle>
+#include <QInputContext>
+#include <private/qsgdistancefieldglyphcache_p.h>
+#include <QtOpenGL/QGLShaderProgram>
+#include <math.h>
+
+#include "qplatformdefs.h"
+
+Q_DECLARE_METATYPE(QQuickTextInput::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 = TESTDATA("");
+    QString arch = "unknown-architecture"; // QTest needs to help with this.
+
+    QString expectfile = persistent_dir + QDir::separator() + filebasename + "-" + arch + ".png";
+
+    if (!QFile::exists(expectfile)) {
+        actual.save(expectfile);
+        qWarning() << "created" << expectfile;
+    }
+
+    return expectfile;
+}
+
+class tst_qquicktextinput : public QObject
+
+{
+    Q_OBJECT
+public:
+    tst_qquicktextinput();
+
+private slots:
+    void initTestCase();
+    void cleanupTestCase();
+    void text();
+    void width();
+    void font();
+    void color();
+    void selection();
+    void isRightToLeft_data();
+    void isRightToLeft();
+    void moveCursorSelection_data();
+    void moveCursorSelection();
+    void moveCursorSelectionSequence_data();
+    void moveCursorSelectionSequence();
+    void dragMouseSelection();
+    void mouseSelectionMode_data();
+    void mouseSelectionMode();
+    void tripleClickSelectsAll();
+
+    void horizontalAlignment_data();
+    void horizontalAlignment();
+    void horizontalAlignment_RightToLeft();
+
+    void positionAt();
+
+    void maxLength();
+    void masks();
+    void validators();
+    void inputMethods();
+
+    void passwordCharacter();
+    void cursorDelegate();
+    void cursorVisible();
+    void cursorRectangle();
+    void navigation();
+    void navigation_RTL();
+    void copyAndPaste();
+    void canPasteEmpty();
+    void canPaste();
+    void readOnly();
+
+    void openInputPanel();
+    void setHAlignClearCache();
+    void focusOutClearSelection();
+
+    void echoMode();
+#ifdef QT_GUI_PASSWORD_ECHO_DELAY
+    void passwordEchoDelay();
+#endif
+    void geometrySignals();
+    void testQtQuick11Attributes();
+    void testQtQuick11Attributes_data();
+
+    void preeditAutoScroll();
+    void preeditMicroFocus();
+    void inputContextMouseHandler();
+    void inputMethodComposing();
+    void cursorRectangleSize();
+
+    void QTBUG_19956();
+    void QTBUG_19956_data();
+    void QTBUG_19956_regexp();
+
+private:
+    void simulateKey(QQuickView *, int key);
+
+    QDeclarativeEngine engine;
+    QStringList standard;
+    QStringList colorStrings;
+};
+void tst_qquicktextinput::initTestCase()
+{
+}
+
+void tst_qquicktextinput::cleanupTestCase()
+{
+
+}
+tst_qquicktextinput::tst_qquicktextinput()
+{
+    standard << "the quick brown fox jumped over the lazy dog"
+        << "It's supercalifragisiticexpialidocious!"
+        << "Hello, world!"
+        << "!dlrow ,olleH"
+        << " spacey   text ";
+
+    colorStrings << "aliceblue"
+                 << "antiquewhite"
+                 << "aqua"
+                 << "darkkhaki"
+                 << "darkolivegreen"
+                 << "dimgray"
+                 << "palevioletred"
+                 << "lightsteelblue"
+                 << "#000000"
+                 << "#AAAAAA"
+                 << "#FFFFFF"
+                 << "#2AC05F";
+}
+
+void tst_qquicktextinput::text()
+{
+    {
+        QDeclarativeComponent textinputComponent(&engine);
+        textinputComponent.setData("import QtQuick 2.0\nTextInput {  text: \"\"  }", QUrl());
+        QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput*>(textinputComponent.create());
+
+        QVERIFY(textinputObject != 0);
+        QCOMPARE(textinputObject->text(), QString(""));
+
+        delete textinputObject;
+    }
+
+    for (int i = 0; i < standard.size(); i++)
+    {
+        QString componentStr = "import QtQuick 2.0\nTextInput { text: \"" + standard.at(i) + "\" }";
+        QDeclarativeComponent textinputComponent(&engine);
+        textinputComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput*>(textinputComponent.create());
+
+        QVERIFY(textinputObject != 0);
+        QCOMPARE(textinputObject->text(), standard.at(i));
+
+        delete textinputObject;
+    }
+
+}
+
+void tst_qquicktextinput::width()
+{
+    // uses Font metrics to find the width for standard
+    {
+        QDeclarativeComponent textinputComponent(&engine);
+        textinputComponent.setData("import QtQuick 2.0\nTextInput {  text: \"\" }", QUrl());
+        QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput*>(textinputComponent.create());
+
+        QVERIFY(textinputObject != 0);
+        QCOMPARE(textinputObject->width(), 0.0);
+
+        delete textinputObject;
+    }
+
+    bool requiresUnhintedMetrics = !qmlDisableDistanceField();
+
+    for (int i = 0; i < standard.size(); i++)
+    {
+        QFont f;
+        qreal metricWidth = 0.0;
+        if (requiresUnhintedMetrics) {
+            QString s = standard.at(i);
+            s.replace(QLatin1Char('\n'), QChar::LineSeparator);
+
+            QTextLayout layout(s);
+            layout.setFlags(Qt::TextExpandTabs | Qt::TextShowMnemonic);
+            {
+                QTextOption option;
+                option.setUseDesignMetrics(true);
+                layout.setTextOption(option);
+            }
+
+            layout.beginLayout();
+            forever {
+                QTextLine line = layout.createLine();
+                if (!line.isValid())
+                    break;
+            }
+
+            layout.endLayout();
+
+            metricWidth = ceil(layout.boundingRect().width());
+        } else {
+            QFontMetricsF fm(f);
+            metricWidth = fm.width(standard.at(i));
+        }
+
+        QString componentStr = "import QtQuick 2.0\nTextInput { text: \"" + standard.at(i) + "\" }";
+        QDeclarativeComponent textinputComponent(&engine);
+        textinputComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput*>(textinputComponent.create());
+
+        QVERIFY(textinputObject != 0);
+        int delta = abs(int(int(textinputObject->width()) - metricWidth));
+        QVERIFY(delta <= 3.0); // As best as we can hope for cross-platform.
+
+        delete textinputObject;
+    }
+}
+
+void tst_qquicktextinput::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());
+        QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput*>(textinputComponent.create());
+
+        QVERIFY(textinputObject != 0);
+        QCOMPARE(textinputObject->font().pointSize(), 40);
+        QCOMPARE(textinputObject->font().bold(), false);
+        QCOMPARE(textinputObject->font().italic(), false);
+
+        delete textinputObject;
+    }
+
+    {
+        QString componentStr = "import QtQuick 2.0\nTextInput {  font.bold: true; text: \"Hello World\" }";
+        QDeclarativeComponent textinputComponent(&engine);
+        textinputComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput*>(textinputComponent.create());
+
+        QVERIFY(textinputObject != 0);
+        QCOMPARE(textinputObject->font().bold(), true);
+        QCOMPARE(textinputObject->font().italic(), false);
+
+        delete textinputObject;
+    }
+
+    {
+        QString componentStr = "import QtQuick 2.0\nTextInput {  font.italic: true; text: \"Hello World\" }";
+        QDeclarativeComponent textinputComponent(&engine);
+        textinputComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput*>(textinputComponent.create());
+
+        QVERIFY(textinputObject != 0);
+        QCOMPARE(textinputObject->font().italic(), true);
+        QCOMPARE(textinputObject->font().bold(), false);
+
+        delete textinputObject;
+    }
+
+    {
+        QString componentStr = "import QtQuick 2.0\nTextInput {  font.family: \"Helvetica\"; text: \"Hello World\" }";
+        QDeclarativeComponent textinputComponent(&engine);
+        textinputComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput*>(textinputComponent.create());
+
+        QVERIFY(textinputObject != 0);
+        QCOMPARE(textinputObject->font().family(), QString("Helvetica"));
+        QCOMPARE(textinputObject->font().bold(), false);
+        QCOMPARE(textinputObject->font().italic(), false);
+
+        delete textinputObject;
+    }
+
+    {
+        QString componentStr = "import QtQuick 2.0\nTextInput {  font.family: \"\"; text: \"Hello World\" }";
+        QDeclarativeComponent textinputComponent(&engine);
+        textinputComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput*>(textinputComponent.create());
+
+        QVERIFY(textinputObject != 0);
+        QCOMPARE(textinputObject->font().family(), QString(""));
+
+        delete textinputObject;
+    }
+}
+
+void tst_qquicktextinput::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());
+        QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput*>(textinputComponent.create());
+        QVERIFY(textinputObject != 0);
+        QCOMPARE(textinputObject->color(), QColor(colorStrings.at(i)));
+
+        delete textinputObject;
+    }
+
+    //test selection color
+    for (int i = 0; i < colorStrings.size(); i++)
+    {
+        QString componentStr = "import QtQuick 2.0\nTextInput {  selectionColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
+        QDeclarativeComponent textinputComponent(&engine);
+        textinputComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput*>(textinputComponent.create());
+        QVERIFY(textinputObject != 0);
+        QCOMPARE(textinputObject->selectionColor(), QColor(colorStrings.at(i)));
+
+        delete textinputObject;
+    }
+
+    //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());
+        QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput*>(textinputComponent.create());
+        QVERIFY(textinputObject != 0);
+        QCOMPARE(textinputObject->selectedTextColor(), QColor(colorStrings.at(i)));
+
+        delete textinputObject;
+    }
+
+    {
+        QString colorStr = "#AA001234";
+        QColor testColor("#001234");
+        testColor.setAlpha(170);
+
+        QString componentStr = "import QtQuick 2.0\nTextInput {  color: \"" + colorStr + "\"; text: \"Hello World\" }";
+        QDeclarativeComponent textinputComponent(&engine);
+        textinputComponent.setData(componentStr.toLatin1(), QUrl());
+        QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput*>(textinputComponent.create());
+
+        QVERIFY(textinputObject != 0);
+        QCOMPARE(textinputObject->color(), testColor);
+
+        delete textinputObject;
+    }
+}
+
+void tst_qquicktextinput::selection()
+{
+    QString testStr = standard[0];
+    QString componentStr = "import QtQuick 2.0\nTextInput {  text: \""+ testStr +"\"; }";
+    QDeclarativeComponent textinputComponent(&engine);
+    textinputComponent.setData(componentStr.toLatin1(), QUrl());
+    QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput*>(textinputComponent.create());
+    QVERIFY(textinputObject != 0);
+
+
+    //Test selection follows cursor
+    for (int i=0; i<= testStr.size(); i++) {
+        textinputObject->setCursorPosition(i);
+        QCOMPARE(textinputObject->cursorPosition(), i);
+        QCOMPARE(textinputObject->selectionStart(), i);
+        QCOMPARE(textinputObject->selectionEnd(), i);
+        QVERIFY(textinputObject->selectedText().isNull());
+    }
+
+    textinputObject->setCursorPosition(0);
+    QVERIFY(textinputObject->cursorPosition() == 0);
+    QVERIFY(textinputObject->selectionStart() == 0);
+    QVERIFY(textinputObject->selectionEnd() == 0);
+    QVERIFY(textinputObject->selectedText().isNull());
+
+    // Verify invalid positions are ignored.
+    textinputObject->setCursorPosition(-1);
+    QVERIFY(textinputObject->cursorPosition() == 0);
+    QVERIFY(textinputObject->selectionStart() == 0);
+    QVERIFY(textinputObject->selectionEnd() == 0);
+    QVERIFY(textinputObject->selectedText().isNull());
+
+    textinputObject->setCursorPosition(textinputObject->text().count()+1);
+    QVERIFY(textinputObject->cursorPosition() == 0);
+    QVERIFY(textinputObject->selectionStart() == 0);
+    QVERIFY(textinputObject->selectionEnd() == 0);
+    QVERIFY(textinputObject->selectedText().isNull());
+
+    //Test selection
+    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++) {
+        textinputObject->select(i,testStr.size());
+        QCOMPARE(testStr.mid(i,testStr.size()-i), textinputObject->selectedText());
+    }
+
+    textinputObject->setCursorPosition(0);
+    QVERIFY(textinputObject->cursorPosition() == 0);
+    QVERIFY(textinputObject->selectionStart() == 0);
+    QVERIFY(textinputObject->selectionEnd() == 0);
+    QVERIFY(textinputObject->selectedText().isNull());
+
+    //Test Error Ignoring behaviour
+    textinputObject->setCursorPosition(0);
+    QVERIFY(textinputObject->selectedText().isNull());
+    textinputObject->select(-10,0);
+    QVERIFY(textinputObject->selectedText().isNull());
+    textinputObject->select(100,110);
+    QVERIFY(textinputObject->selectedText().isNull());
+    textinputObject->select(0,-10);
+    QVERIFY(textinputObject->selectedText().isNull());
+    textinputObject->select(0,100);
+    QVERIFY(textinputObject->selectedText().isNull());
+    textinputObject->select(0,10);
+    QVERIFY(textinputObject->selectedText().size() == 10);
+    textinputObject->select(-10,10);
+    QVERIFY(textinputObject->selectedText().size() == 10);
+    textinputObject->select(100,101);
+    QVERIFY(textinputObject->selectedText().size() == 10);
+    textinputObject->select(0,-10);
+    QVERIFY(textinputObject->selectedText().size() == 10);
+    textinputObject->select(0,100);
+    QVERIFY(textinputObject->selectedText().size() == 10);
+
+    textinputObject->deselect();
+    QVERIFY(textinputObject->selectedText().isNull());
+    textinputObject->select(0,10);
+    QVERIFY(textinputObject->selectedText().size() == 10);
+    textinputObject->deselect();
+    QVERIFY(textinputObject->selectedText().isNull());
+
+    delete textinputObject;
+}
+
+void tst_qquicktextinput::isRightToLeft_data()
+{
+    QTest::addColumn<QString>("text");
+    QTest::addColumn<bool>("emptyString");
+    QTest::addColumn<bool>("firstCharacter");
+    QTest::addColumn<bool>("lastCharacter");
+    QTest::addColumn<bool>("middleCharacter");
+    QTest::addColumn<bool>("startString");
+    QTest::addColumn<bool>("midString");
+    QTest::addColumn<bool>("endString");
+
+    const quint16 arabic_str[] = { 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0647};
+    QTest::newRow("Empty") << "" << false << false << false << false << false << false << false;
+    QTest::newRow("Neutral") << "23244242" << false << false << false << false << false << false << false;
+    QTest::newRow("LTR") << "Hello world" << false << false << false << false << false << false << false;
+    QTest::newRow("RTL") << QString::fromUtf16(arabic_str, 11) << false << true << true << true << true << true << true;
+    QTest::newRow("Bidi RTL + LTR + RTL") << QString::fromUtf16(arabic_str, 11) + QString("Hello world") + QString::fromUtf16(arabic_str, 11) << false << true << true << false << true << true << true;
+    QTest::newRow("Bidi LTR + RTL + LTR") << QString("Hello world") + QString::fromUtf16(arabic_str, 11) + QString("Hello world") << false << false << false << true << false << false << false;
+}
+
+void tst_qquicktextinput::isRightToLeft()
+{
+    QFETCH(QString, text);
+    QFETCH(bool, emptyString);
+    QFETCH(bool, firstCharacter);
+    QFETCH(bool, lastCharacter);
+    QFETCH(bool, middleCharacter);
+    QFETCH(bool, startString);
+    QFETCH(bool, midString);
+    QFETCH(bool, endString);
+
+    QQuickTextInput textInput;
+    textInput.setText(text);
+
+    // first test that the right string is delivered to the QString::isRightToLeft()
+    QCOMPARE(textInput.isRightToLeft(0,0), text.mid(0,0).isRightToLeft());
+    QCOMPARE(textInput.isRightToLeft(0,1), text.mid(0,1).isRightToLeft());
+    QCOMPARE(textInput.isRightToLeft(text.count()-2, text.count()-1), text.mid(text.count()-2, text.count()-1).isRightToLeft());
+    QCOMPARE(textInput.isRightToLeft(text.count()/2, text.count()/2 + 1), text.mid(text.count()/2, text.count()/2 + 1).isRightToLeft());
+    QCOMPARE(textInput.isRightToLeft(0,text.count()/4), text.mid(0,text.count()/4).isRightToLeft());
+    QCOMPARE(textInput.isRightToLeft(text.count()/4,3*text.count()/4), text.mid(text.count()/4,3*text.count()/4).isRightToLeft());
+    if (text.isEmpty())
+        QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML TextInput: isRightToLeft(start, end) called with the end property being smaller than the start.");
+    QCOMPARE(textInput.isRightToLeft(3*text.count()/4,text.count()-1), text.mid(3*text.count()/4,text.count()-1).isRightToLeft());
+
+    // then test that the feature actually works
+    QCOMPARE(textInput.isRightToLeft(0,0), emptyString);
+    QCOMPARE(textInput.isRightToLeft(0,1), firstCharacter);
+    QCOMPARE(textInput.isRightToLeft(text.count()-2, text.count()-1), lastCharacter);
+    QCOMPARE(textInput.isRightToLeft(text.count()/2, text.count()/2 + 1), middleCharacter);
+    QCOMPARE(textInput.isRightToLeft(0,text.count()/4), startString);
+    QCOMPARE(textInput.isRightToLeft(text.count()/4,3*text.count()/4), midString);
+    if (text.isEmpty())
+        QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML TextInput: isRightToLeft(start, end) called with the end property being smaller than the start.");
+    QCOMPARE(textInput.isRightToLeft(3*text.count()/4,text.count()-1), endString);
+}
+
+void tst_qquicktextinput::moveCursorSelection_data()
+{
+    QTest::addColumn<QString>("testStr");
+    QTest::addColumn<int>("cursorPosition");
+    QTest::addColumn<int>("movePosition");
+    QTest::addColumn<QQuickTextInput::SelectionMode>("mode");
+    QTest::addColumn<int>("selectionStart");
+    QTest::addColumn<int>("selectionEnd");
+    QTest::addColumn<bool>("reversible");
+
+    // () contains the text selected by the cursor.
+    // <> contains the actual selection.
+
+    QTest::newRow("(t)he|characters")
+            << standard[0] << 0 << 1 << QQuickTextInput::SelectCharacters << 0 << 1 << true;
+    QTest::newRow("do(g)|characters")
+            << standard[0] << 43 << 44 << QQuickTextInput::SelectCharacters << 43 << 44 << true;
+    QTest::newRow("jum(p)ed|characters")
+            << standard[0] << 23 << 24 << QQuickTextInput::SelectCharacters << 23 << 24 << true;
+    QTest::newRow("jumped( )over|characters")
+            << standard[0] << 26 << 27 << QQuickTextInput::SelectCharacters << 26 << 27 << true;
+    QTest::newRow("(the )|characters")
+            << standard[0] << 0 << 4 << QQuickTextInput::SelectCharacters << 0 << 4 << true;
+    QTest::newRow("( dog)|characters")
+            << standard[0] << 40 << 44 << QQuickTextInput::SelectCharacters << 40 << 44 << true;
+    QTest::newRow("( jumped )|characters")
+            << standard[0] << 19 << 27 << QQuickTextInput::SelectCharacters << 19 << 27 << true;
+    QTest::newRow("th(e qu)ick|characters")
+            << standard[0] << 2 << 6 << QQuickTextInput::SelectCharacters << 2 << 6 << true;
+    QTest::newRow("la(zy d)og|characters")
+            << standard[0] << 38 << 42 << QQuickTextInput::SelectCharacters << 38 << 42 << true;
+    QTest::newRow("jum(ped ov)er|characters")
+            << standard[0] << 23 << 29 << QQuickTextInput::SelectCharacters << 23 << 29 << true;
+    QTest::newRow("()the|characters")
+            << standard[0] << 0 << 0 << QQuickTextInput::SelectCharacters << 0 << 0 << true;
+    QTest::newRow("dog()|characters")
+            << standard[0] << 44 << 44 << QQuickTextInput::SelectCharacters << 44 << 44 << true;
+    QTest::newRow("jum()ped|characters")
+            << standard[0] << 23 << 23 << QQuickTextInput::SelectCharacters << 23 << 23 << true;
+
+    QTest::newRow("<(t)he>|words")
+            << standard[0] << 0 << 1 << QQuickTextInput::SelectWords << 0 << 3 << true;
+    QTest::newRow("<do(g)>|words")
+            << standard[0] << 43 << 44 << QQuickTextInput::SelectWords << 41 << 44 << true;
+    QTest::newRow("<jum(p)ed>|words")
+            << standard[0] << 23 << 24 << QQuickTextInput::SelectWords << 20 << 26 << true;
+    QTest::newRow("<jumped( )>over|words,ltr")
+            << standard[0] << 26 << 27 << QQuickTextInput::SelectWords << 20 << 27 << false;
+    QTest::newRow("jumped<( )over>|words,rtl")
+            << standard[0] << 27 << 26 << QQuickTextInput::SelectWords << 26 << 31 << false;
+    QTest::newRow("<(the )>quick|words,ltr")
+            << standard[0] << 0 << 4 << QQuickTextInput::SelectWords << 0 << 4 << false;
+    QTest::newRow("<(the )quick>|words,rtl")
+            << standard[0] << 4 << 0 << QQuickTextInput::SelectWords << 0 << 9 << false;
+    QTest::newRow("<lazy( dog)>|words,ltr")
+            << standard[0] << 40 << 44 << QQuickTextInput::SelectWords << 36 << 44 << false;
+    QTest::newRow("lazy<( dog)>|words,rtl")
+            << standard[0] << 44 << 40 << QQuickTextInput::SelectWords << 40 << 44 << false;
+    QTest::newRow("<fox( jumped )>over|words,ltr")
+            << standard[0] << 19 << 27 << QQuickTextInput::SelectWords << 16 << 27 << false;
+    QTest::newRow("fox<( jumped )over>|words,rtl")
+            << standard[0] << 27 << 19 << QQuickTextInput::SelectWords << 19 << 31 << false;
+    QTest::newRow("<th(e qu)ick>|words")
+            << standard[0] << 2 << 6 << QQuickTextInput::SelectWords << 0 << 9 << true;
+    QTest::newRow("<la(zy d)og|words>")
+            << standard[0] << 38 << 42 << QQuickTextInput::SelectWords << 36 << 44 << true;
+    QTest::newRow("<jum(ped ov)er>|words")
+            << standard[0] << 23 << 29 << QQuickTextInput::SelectWords << 20 << 31 << true;
+    QTest::newRow("<()>the|words")
+            << standard[0] << 0 << 0 << QQuickTextInput::SelectWords << 0 << 0 << true;
+    QTest::newRow("dog<()>|words")
+            << standard[0] << 44 << 44 << QQuickTextInput::SelectWords << 44 << 44 << true;
+    QTest::newRow("jum<()>ped|words")
+            << standard[0] << 23 << 23 << QQuickTextInput::SelectWords << 23 << 23 << true;
+
+    QTest::newRow("Hello<(,)> |words")
+            << standard[2] << 5 << 6 << QQuickTextInput::SelectWords << 5 << 6 << true;
+    QTest::newRow("Hello<(, )>world|words,ltr")
+            << standard[2] << 5 << 7 << QQuickTextInput::SelectWords << 5 << 7 << false;
+    QTest::newRow("Hello<(, )world>|words,rtl")
+            << standard[2] << 7 << 5 << QQuickTextInput::SelectWords << 5 << 12 << false;
+    QTest::newRow("<Hel(lo, )>world|words,ltr")
+            << standard[2] << 3 << 7 << QQuickTextInput::SelectWords << 0 << 7 << false;
+    QTest::newRow("<Hel(lo, )world>|words,rtl")
+            << standard[2] << 7 << 3 << QQuickTextInput::SelectWords << 0 << 12 << false;
+    QTest::newRow("<Hel(lo)>,|words")
+            << standard[2] << 3 << 5 << QQuickTextInput::SelectWords << 0 << 5 << true;
+    QTest::newRow("Hello<()>,|words")
+            << standard[2] << 5 << 5 << QQuickTextInput::SelectWords << 5 << 5 << true;
+    QTest::newRow("Hello,<()>|words")
+            << standard[2] << 6 << 6 << QQuickTextInput::SelectWords << 6 << 6 << true;
+    QTest::newRow("Hello<,( )>world|words,ltr")
+            << standard[2] << 6 << 7 << QQuickTextInput::SelectWords << 5 << 7 << false;
+    QTest::newRow("Hello,<( )world>|words,rtl")
+            << standard[2] << 7 << 6 << QQuickTextInput::SelectWords << 6 << 12 << false;
+    QTest::newRow("Hello<,( world)>|words,ltr")
+            << standard[2] << 6 << 12 << QQuickTextInput::SelectWords << 5 << 12 << false;
+    QTest::newRow("Hello,<( world)>|words,rtl")
+            << standard[2] << 12 << 6 << QQuickTextInput::SelectWords << 6 << 12 << false;
+    QTest::newRow("Hello<,( world!)>|words,ltr")
+            << standard[2] << 6 << 13 << QQuickTextInput::SelectWords << 5 << 13 << false;
+    QTest::newRow("Hello,<( world!)>|words,rtl")
+            << standard[2] << 13 << 6 << QQuickTextInput::SelectWords << 6 << 13 << false;
+    QTest::newRow("Hello<(, world!)>|words")
+            << standard[2] << 5 << 13 << QQuickTextInput::SelectWords << 5 << 13 << true;
+    // Fails due to an issue with QTextBoundaryFinder and punctuation at the end of strings.
+    // QTBUG-11365
+    // QTest::newRow("world<(!)>|words")
+    //         << standard[2] << 12 << 13 << QQuickTextInput::SelectWords << 12 << 13 << true;
+    QTest::newRow("world!<()>)|words")
+            << standard[2] << 13 << 13 << QQuickTextInput::SelectWords << 13 << 13 << true;
+    QTest::newRow("world<()>!)|words")
+            << standard[2] << 12 << 12 << QQuickTextInput::SelectWords << 12 << 12 << true;
+
+    QTest::newRow("<(,)>olleH |words")
+            << standard[3] << 7 << 8 << QQuickTextInput::SelectWords << 7 << 8 << true;
+    QTest::newRow("<dlrow( ,)>olleH|words,ltr")
+            << standard[3] << 6 << 8 << QQuickTextInput::SelectWords << 1 << 8 << false;
+    QTest::newRow("dlrow<( ,)>olleH|words,rtl")
+            << standard[3] << 8 << 6 << QQuickTextInput::SelectWords << 6 << 8 << false;
+    QTest::newRow("<dlrow( ,ol)leH>|words,ltr")
+            << standard[3] << 6 << 10 << QQuickTextInput::SelectWords << 1 << 13 << false;
+    QTest::newRow("dlrow<( ,ol)leH>|words,rtl")
+            << standard[3] << 10 << 6 << QQuickTextInput::SelectWords << 6 << 13 << false;
+    QTest::newRow(",<(ol)leH>,|words")
+            << standard[3] << 8 << 10 << QQuickTextInput::SelectWords << 8 << 13 << true;
+    QTest::newRow(",<()>olleH|words")
+            << standard[3] << 8 << 8 << QQuickTextInput::SelectWords << 8 << 8 << true;
+    QTest::newRow("<()>,olleH|words")
+            << standard[3] << 7 << 7 << QQuickTextInput::SelectWords << 7 << 7 << true;
+    QTest::newRow("<dlrow( )>,olleH|words,ltr")
+            << standard[3] << 6 << 7 << QQuickTextInput::SelectWords << 1 << 7 << false;
+    QTest::newRow("dlrow<( ),>olleH|words,rtl")
+            << standard[3] << 7 << 6 << QQuickTextInput::SelectWords << 6 << 8 << false;
+    QTest::newRow("<(dlrow )>,olleH|words,ltr")
+            << standard[3] << 1 << 7 << QQuickTextInput::SelectWords << 1 << 7 << false;
+    QTest::newRow("<(dlrow ),>olleH|words,rtl")
+            << standard[3] << 7 << 1 << QQuickTextInput::SelectWords << 1 << 8 << false;
+    QTest::newRow("<(!dlrow )>,olleH|words,ltr")
+            << standard[3] << 0 << 7 << QQuickTextInput::SelectWords << 0 << 7 << false;
+    QTest::newRow("<(!dlrow ),>olleH|words,rtl")
+            << standard[3] << 7 << 0 << QQuickTextInput::SelectWords << 0 << 8 << false;
+    QTest::newRow("(!dlrow ,)olleH|words")
+            << standard[3] << 0 << 8 << QQuickTextInput::SelectWords << 0 << 8 << true;
+    QTest::newRow("<(!)>dlrow|words")
+            << standard[3] << 0 << 1 << QQuickTextInput::SelectWords << 0 << 1 << true;
+    QTest::newRow("<()>!dlrow|words")
+            << standard[3] << 0 << 0 << QQuickTextInput::SelectWords << 0 << 0 << true;
+    QTest::newRow("!<()>dlrow|words")
+            << standard[3] << 1 << 1 << QQuickTextInput::SelectWords << 1 << 1 << true;
+
+    QTest::newRow(" <s(pac)ey>   text |words")
+            << standard[4] << 1 << 4 << QQuickTextInput::SelectWords << 1 << 7 << true;
+    QTest::newRow(" spacey   <t(ex)t> |words")
+            << standard[4] << 11 << 13 << QQuickTextInput::SelectWords << 10 << 14 << false; // Should be reversible. QTBUG-11365
+    QTest::newRow("<( )>spacey   text |words|ltr")
+            << standard[4] << 0 << 1 << QQuickTextInput::SelectWords << 0 << 1 << false;
+    QTest::newRow("<( )spacey>   text |words|rtl")
+            << standard[4] << 1 << 0 << QQuickTextInput::SelectWords << 0 << 7 << false;
+    QTest::newRow("spacey   <text( )>|words|ltr")
+            << standard[4] << 14 << 15 << QQuickTextInput::SelectWords << 10 << 15 << false;
+//    QTBUG-11365
+//    QTest::newRow("spacey   text<( )>|words|rtl")
+//            << standard[4] << 15 << 14 << QQuickTextInput::SelectWords << 14 << 15 << false;
+    QTest::newRow("<()> spacey   text |words")
+            << standard[4] << 0 << 0 << QQuickTextInput::SelectWords << 0 << 0 << false;
+    QTest::newRow(" spacey   text <()>|words")
+            << standard[4] << 15 << 15 << QQuickTextInput::SelectWords << 15 << 15 << false;
+}
+
+void tst_qquicktextinput::moveCursorSelection()
+{
+    QFETCH(QString, testStr);
+    QFETCH(int, cursorPosition);
+    QFETCH(int, movePosition);
+    QFETCH(QQuickTextInput::SelectionMode, mode);
+    QFETCH(int, selectionStart);
+    QFETCH(int, selectionEnd);
+    QFETCH(bool, reversible);
+
+    QString componentStr = "import QtQuick 2.0\nTextInput {  text: \""+ testStr +"\"; }";
+    QDeclarativeComponent textinputComponent(&engine);
+    textinputComponent.setData(componentStr.toLatin1(), QUrl());
+    QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput*>(textinputComponent.create());
+    QVERIFY(textinputObject != 0);
+
+    textinputObject->setCursorPosition(cursorPosition);
+    textinputObject->moveCursorSelection(movePosition, mode);
+
+    QCOMPARE(textinputObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart));
+    QCOMPARE(textinputObject->selectionStart(), selectionStart);
+    QCOMPARE(textinputObject->selectionEnd(), selectionEnd);
+
+    if (reversible) {
+        textinputObject->setCursorPosition(movePosition);
+        textinputObject->moveCursorSelection(cursorPosition, mode);
+
+        QCOMPARE(textinputObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart));
+        QCOMPARE(textinputObject->selectionStart(), selectionStart);
+        QCOMPARE(textinputObject->selectionEnd(), selectionEnd);
+    }
+
+    delete textinputObject;
+}
+
+void tst_qquicktextinput::moveCursorSelectionSequence_data()
+{
+    QTest::addColumn<QString>("testStr");
+    QTest::addColumn<int>("cursorPosition");
+    QTest::addColumn<int>("movePosition1");
+    QTest::addColumn<int>("movePosition2");
+    QTest::addColumn<int>("selection1Start");
+    QTest::addColumn<int>("selection1End");
+    QTest::addColumn<int>("selection2Start");
+    QTest::addColumn<int>("selection2End");
+
+    // () contains the text selected by the cursor.
+    // <> contains the actual selection.
+    // ^ is the revised cursor position.
+    // {} contains the revised selection.
+
+    QTest::newRow("the {<quick( bro)wn> f^ox} jumped|ltr")
+            << standard[0]
+            << 9 << 13 << 17
+            << 4 << 15
+            << 4 << 19;
+    QTest::newRow("the quick<( {bro)wn> f^ox} jumped|rtl")
+            << standard[0]
+            << 13 << 9 << 17
+            << 9 << 15
+            << 10 << 19;
+    QTest::newRow("the {<quick( bro)wn> ^}fox jumped|ltr")
+            << standard[0]
+            << 9 << 13 << 16
+            << 4 << 15
+            << 4 << 16;
+    QTest::newRow("the quick<( {bro)wn> ^}fox jumped|rtl")
+            << standard[0]
+            << 13 << 9 << 16
+            << 9 << 15
+            << 10 << 16;
+    QTest::newRow("the {<quick( bro)wn^>} fox jumped|ltr")
+            << standard[0]
+            << 9 << 13 << 15
+            << 4 << 15
+            << 4 << 15;
+    QTest::newRow("the quick<( {bro)wn^>} f^ox jumped|rtl")
+            << standard[0]
+            << 13 << 9 << 15
+            << 9 << 15
+            << 10 << 15;
+    QTest::newRow("the {<quick() ^}bro)wn> fox|ltr")
+            << standard[0]
+            << 9 << 13 << 10
+            << 4 << 15
+            << 4 << 10;
+    QTest::newRow("the quick<( {^bro)wn>} fox|rtl")
+            << standard[0]
+            << 13 << 9 << 10
+            << 9 << 15
+            << 10 << 15;
+    QTest::newRow("the {<quick^}( bro)wn> fox|ltr")
+            << standard[0]
+            << 9 << 13 << 9
+            << 4 << 15
+            << 4 << 9;
+    QTest::newRow("the quick{<(^ bro)wn>} fox|rtl")
+            << standard[0]
+            << 13 << 9 << 9
+            << 9 << 15
+            << 9 << 15;
+    QTest::newRow("the {<qui^ck}( bro)wn> fox|ltr")
+            << standard[0]
+            << 9 << 13 << 7
+            << 4 << 15
+            << 4 << 9;
+    QTest::newRow("the {<qui^ck}( bro)wn> fox|rtl")
+            << standard[0]
+            << 13 << 9 << 7
+            << 9 << 15
+            << 4 << 15;
+    QTest::newRow("the {<^quick}( bro)wn> fox|ltr")
+            << standard[0]
+            << 9 << 13 << 4
+            << 4 << 15
+            << 4 << 9;
+    QTest::newRow("the {<^quick}( bro)wn> fox|rtl")
+            << standard[0]
+            << 13 << 9 << 4
+            << 9 << 15
+            << 4 << 15;
+    QTest::newRow("the{^ <quick}( bro)wn> fox|ltr")
+            << standard[0]
+            << 9 << 13 << 3
+            << 4 << 15
+            << 3 << 9;
+    QTest::newRow("the{^ <quick}( bro)wn> fox|rtl")
+            << standard[0]
+            << 13 << 9 << 3
+            << 9 << 15
+            << 3 << 15;
+    QTest::newRow("{t^he <quick}( bro)wn> fox|ltr")
+            << standard[0]
+            << 9 << 13 << 1
+            << 4 << 15
+            << 0 << 9;
+    QTest::newRow("{t^he <quick}( bro)wn> fox|rtl")
+            << standard[0]
+            << 13 << 9 << 1
+            << 9 << 15
+            << 0 << 15;
+
+    QTest::newRow("{<He(ll)o>, w^orld}!|ltr")
+            << standard[2]
+            << 2 << 4 << 8
+            << 0 << 5
+            << 0 << 12;
+    QTest::newRow("{<He(ll)o>, w^orld}!|rtl")
+            << standard[2]
+            << 4 << 2 << 8
+            << 0 << 5
+            << 0 << 12;
+
+    QTest::newRow("!{dlro^w ,<o(ll)eH>}|ltr")
+            << standard[3]
+            << 9 << 11 << 5
+            << 8 << 13
+            << 1 << 13;
+    QTest::newRow("!{dlro^w ,<o(ll)eH>}|rtl")
+            << standard[3]
+            << 11 << 9 << 5
+            << 8 << 13
+            << 1 << 13;
+
+    QTest::newRow("{<(^} sp)acey>   text |ltr")
+            << standard[4]
+            << 0 << 3 << 0
+            << 0 << 7
+            << 0 << 0;
+    QTest::newRow("{<( ^}sp)acey>   text |ltr")
+            << standard[4]
+            << 0 << 3 << 1
+            << 0 << 7
+            << 0 << 1;
+    QTest::newRow("<( {s^p)acey>}   text |rtl")
+            << standard[4]
+            << 3 << 0 << 2
+            << 0 << 7
+            << 1 << 7;
+    QTest::newRow("<( {^sp)acey>}   text |rtl")
+            << standard[4]
+            << 3 << 0 << 1
+            << 0 << 7
+            << 1 << 7;
+
+    QTest::newRow(" spacey   <te(xt {^)>}|rtl")
+            << standard[4]
+            << 15 << 12 << 15
+            << 10 << 15
+            << 15 << 15;
+//    QTBUG-11365
+//    QTest::newRow(" spacey   <te(xt{^ )>}|rtl")
+//            << standard[4]
+//            << 15 << 12 << 14
+//            << 10 << 15
+//            << 14 << 15;
+    QTest::newRow(" spacey   {<te(x^t} )>|ltr")
+            << standard[4]
+            << 12 << 15 << 13
+            << 10 << 15
+            << 10 << 14;
+//    QTBUG-11365
+//    QTest::newRow(" spacey   {<te(xt^} )>|ltr")
+//            << standard[4]
+//            << 12 << 15 << 14
+//            << 10 << 15
+//            << 10 << 14;
+}
+
+void tst_qquicktextinput::moveCursorSelectionSequence()
+{
+    QFETCH(QString, testStr);
+    QFETCH(int, cursorPosition);
+    QFETCH(int, movePosition1);
+    QFETCH(int, movePosition2);
+    QFETCH(int, selection1Start);
+    QFETCH(int, selection1End);
+    QFETCH(int, selection2Start);
+    QFETCH(int, selection2End);
+
+    QString componentStr = "import QtQuick 2.0\nTextInput {  text: \""+ testStr +"\"; }";
+    QDeclarativeComponent textinputComponent(&engine);
+    textinputComponent.setData(componentStr.toLatin1(), QUrl());
+    QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput*>(textinputComponent.create());
+    QVERIFY(textinputObject != 0);
+
+    textinputObject->setCursorPosition(cursorPosition);
+
+    textinputObject->moveCursorSelection(movePosition1, QQuickTextInput::SelectWords);
+    QCOMPARE(textinputObject->selectedText(), testStr.mid(selection1Start, selection1End - selection1Start));
+    QCOMPARE(textinputObject->selectionStart(), selection1Start);
+    QCOMPARE(textinputObject->selectionEnd(), selection1End);
+
+    textinputObject->moveCursorSelection(movePosition2, QQuickTextInput::SelectWords);
+    QCOMPARE(textinputObject->selectedText(), testStr.mid(selection2Start, selection2End - selection2Start));
+    QCOMPARE(textinputObject->selectionStart(), selection2Start);
+    QCOMPARE(textinputObject->selectionEnd(), selection2End);
+
+    delete textinputObject;
+}
+
+void tst_qquicktextinput::dragMouseSelection()
+{
+    QString qmlfile = TESTDATA("mouseselection_true.qml");
+
+    QQuickView canvas(QUrl::fromLocalFile(qmlfile));
+
+    canvas.show();
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&canvas);
+
+    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
+
+    QVERIFY(canvas.rootObject() != 0);
+    QQuickTextInput *textInputObject = qobject_cast<QQuickTextInput *>(canvas.rootObject());
+    QVERIFY(textInputObject != 0);
+
+    // press-and-drag-and-release from x1 to x2
+    int x1 = 10;
+    int x2 = 70;
+    int y = textInputObject->height()/2;
+    QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y));
+    QTest::mouseMove(&canvas, QPoint(x2, y));
+    QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y));
+    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));
+    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);
+}
+
+void tst_qquicktextinput::mouseSelectionMode_data()
+{
+    QTest::addColumn<QString>("qmlfile");
+    QTest::addColumn<bool>("selectWords");
+
+    // import installed
+    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_qquicktextinput::mouseSelectionMode()
+{
+    QFETCH(QString, qmlfile);
+    QFETCH(bool, selectWords);
+
+    QString text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+    QQuickView canvas(QUrl::fromLocalFile(qmlfile));
+
+    canvas.show();
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&canvas);
+    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
+
+    QVERIFY(canvas.rootObject() != 0);
+    QQuickTextInput *textInputObject = qobject_cast<QQuickTextInput *>(canvas.rootObject());
+    QVERIFY(textInputObject != 0);
+
+    // press-and-drag-and-release from x1 to x2
+    int x1 = 10;
+    int x2 = 70;
+    int y = textInputObject->height()/2;
+    QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y));
+    QTest::mouseMove(&canvas, QPoint(x2,y)); // doesn't work
+    QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y));
+    QTest::qWait(300);
+    if (selectWords) {
+        QTRY_COMPARE(textInputObject->selectedText(), text);
+    } else {
+        QTRY_VERIFY(textInputObject->selectedText().length() > 3);
+        QVERIFY(textInputObject->selectedText() != text);
+    }
+}
+
+void tst_qquicktextinput::horizontalAlignment_data()
+{
+    QTest::addColumn<int>("hAlign");
+    QTest::addColumn<QString>("expectfile");
+
+    QTest::newRow("L") << int(Qt::AlignLeft) << "halign_left";
+    QTest::newRow("R") << int(Qt::AlignRight) << "halign_right";
+    QTest::newRow("C") << int(Qt::AlignHCenter) << "halign_center";
+}
+
+void tst_qquicktextinput::horizontalAlignment()
+{
+    QSKIP("Image comparison of text is almost guaranteed to fail during development");
+
+    QFETCH(int, hAlign);
+    QFETCH(QString, expectfile);
+
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("horizontalAlignment.qml")));
+
+    canvas.show();
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&canvas);
+    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
+    QObject *ob = canvas.rootObject();
+    QVERIFY(ob != 0);
+    ob->setProperty("horizontalAlignment",hAlign);
+    QImage actual = canvas.grabFrameBuffer();
+
+    expectfile = createExpectedFileIfNotFound(expectfile, actual);
+
+    QImage expect(expectfile);
+
+    QCOMPARE(actual,expect);
+}
+
+void tst_qquicktextinput::horizontalAlignment_RightToLeft()
+{
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("horizontalAlignment_RightToLeft.qml")));
+    QQuickTextInput *textInput = canvas.rootObject()->findChild<QQuickTextInput*>("text");
+    QVERIFY(textInput != 0);
+    canvas.show();
+
+    const QString rtlText = textInput->text();
+
+    QQuickTextInputPrivate *textInputPrivate = QQuickTextInputPrivate::get(textInput);
+    QVERIFY(textInputPrivate != 0);
+    QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
+
+    // implicit alignment should follow the reading direction of RTL text
+    QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight);
+    QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
+    QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
+
+    // explicitly left aligned
+    textInput->setHAlign(QQuickTextInput::AlignLeft);
+    QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignLeft);
+    QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
+    QVERIFY(-textInputPrivate->hscroll < canvas.width()/2);
+
+    // explicitly right aligned
+    textInput->setHAlign(QQuickTextInput::AlignRight);
+    QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
+    QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight);
+    QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
+
+    // explicitly center aligned
+    textInput->setHAlign(QQuickTextInput::AlignHCenter);
+    QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
+    QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignHCenter);
+    QVERIFY(-textInputPrivate->hscroll < canvas.width()/2);
+    QVERIFY(-textInputPrivate->hscroll + textInputPrivate->width > canvas.width()/2);
+
+    // reseted alignment should go back to following the text reading direction
+    textInput->resetHAlign();
+    QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight);
+    QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
+    QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
+
+    // mirror the text item
+    QQuickItemPrivate::get(textInput)->setLayoutMirror(true);
+
+    // mirrored implicit alignment should continue to follow the reading direction of the text
+    QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight);
+    QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
+    QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
+
+    // explicitly right aligned behaves as left aligned
+    textInput->setHAlign(QQuickTextInput::AlignRight);
+    QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight);
+    QCOMPARE(textInput->effectiveHAlign(), QQuickTextInput::AlignLeft);
+    QVERIFY(-textInputPrivate->hscroll < canvas.width()/2);
+
+    // mirrored explicitly left aligned behaves as right aligned
+    textInput->setHAlign(QQuickTextInput::AlignLeft);
+    QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignLeft);
+    QCOMPARE(textInput->effectiveHAlign(), QQuickTextInput::AlignRight);
+    QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
+
+    // disable mirroring
+    QQuickItemPrivate::get(textInput)->setLayoutMirror(false);
+    QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
+    textInput->resetHAlign();
+
+    // English text should be implicitly left aligned
+    textInput->setText("Hello world!");
+    QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignLeft);
+    QVERIFY(-textInputPrivate->hscroll < canvas.width()/2);
+
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&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>()); QGuiApplication::sendEvent(&canvas, &ev); }
+    QEXPECT_FAIL("", "QTBUG-21691", Continue);
+    QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight);
+    { QInputMethodEvent ev("Hello world!", QList<QInputMethodEvent::Attribute>()); QGuiApplication::sendEvent(&canvas, &ev); }
+    QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignLeft);
+
+#ifndef Q_OS_MAC    // QTBUG-18040
+    // empty text with implicit alignment follows the system locale-based
+    // keyboard input direction from QGuiApplication::keyboardInputDirection
+    textInput->setText("");
+    QCOMPARE(textInput->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ?
+                                  QQuickTextInput::AlignLeft : QQuickTextInput::AlignRight);
+    if (QGuiApplication::keyboardInputDirection() == Qt::LeftToRight)
+        QVERIFY(-textInputPrivate->hscroll < canvas.width()/2);
+    else
+        QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
+    textInput->setHAlign(QQuickTextInput::AlignRight);
+    QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight);
+    QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
+#endif
+
+#ifndef Q_OS_MAC    // QTBUG-18040
+    // alignment of TextInput with no text set to it
+    QString componentStr = "import QtQuick 2.0\nTextInput {}";
+    QDeclarativeComponent textComponent(&engine);
+    textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickTextInput *textObject = qobject_cast<QQuickTextInput*>(textComponent.create());
+    QCOMPARE(textObject->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ?
+                                  QQuickTextInput::AlignLeft : QQuickTextInput::AlignRight);
+    delete textObject;
+#endif
+}
+
+void tst_qquicktextinput::positionAt()
+{
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("positionAt.qml")));
+    QVERIFY(canvas.rootObject() != 0);
+    canvas.show();
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&canvas);
+
+    QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput *>(canvas.rootObject());
+    QVERIFY(textinputObject != 0);
+
+    // Check autoscrolled...
+    QFontMetrics fm(textinputObject->font());
+
+    int pos = textinputObject->positionAt(textinputObject->width()/2);
+    int textWidth = 0;
+    int textLeftWidth = 0;
+    if (!qmlDisableDistanceField()) {
+        {
+            QTextLayout layout(textinputObject->text().left(pos));
+
+            {
+                QTextOption option;
+                option.setUseDesignMetrics(true);
+                layout.setTextOption(option);
+            }
+
+            layout.beginLayout();
+            QTextLine line = layout.createLine();
+            layout.endLayout();
+
+            textLeftWidth = ceil(line.horizontalAdvance());
+        }
+        {
+            QTextLayout layout(textinputObject->text());
+
+            {
+                QTextOption option;
+                option.setUseDesignMetrics(true);
+                layout.setTextOption(option);
+            }
+
+            layout.beginLayout();
+            QTextLine line = layout.createLine();
+            layout.endLayout();
+
+            textWidth = ceil(line.horizontalAdvance());
+        }
+    } else {
+        textWidth = fm.width(textinputObject->text());
+        textLeftWidth = fm.width(textinputObject->text().left(pos));
+    }
+
+    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
+    QVERIFY(diff < 5);
+#endif
+
+    int x = textinputObject->positionToRectangle(pos + 1).x() - 1;
+    QCOMPARE(textinputObject->positionAt(x, QQuickTextInput::CursorBetweenCharacters), pos + 1);
+    QCOMPARE(textinputObject->positionAt(x, QQuickTextInput::CursorOnCharacter), pos);
+
+    // Check without autoscroll...
+    textinputObject->setAutoScroll(false);
+    pos = textinputObject->positionAt(textinputObject->width()/2);
+
+    if (!qmlDisableDistanceField()) {
+        {
+            QTextLayout layout(textinputObject->text().left(pos));
+
+            {
+                QTextOption option;
+                option.setUseDesignMetrics(true);
+                layout.setTextOption(option);
+            }
+
+            layout.beginLayout();
+            QTextLine line = layout.createLine();
+            layout.endLayout();
+
+            textLeftWidth = ceil(line.horizontalAdvance());
+        }
+    } else {
+        textLeftWidth = fm.width(textinputObject->text().left(pos));
+    }
+
+    diff = abs(int(textLeftWidth-textinputObject->width()/2));
+
+    // some tollerance for different fonts.
+#ifdef Q_OS_LINUX
+    QVERIFY(diff < 2);
+#else
+    QVERIFY(diff < 5);
+#endif
+
+    x = textinputObject->positionToRectangle(pos + 1).x() - 1;
+    QCOMPARE(textinputObject->positionAt(x, QQuickTextInput::CursorBetweenCharacters), pos + 1);
+    QCOMPARE(textinputObject->positionAt(x, QQuickTextInput::CursorOnCharacter), pos);
+
+    const qreal x0 = textinputObject->positionToRectangle(pos).x();
+    const qreal x1 = textinputObject->positionToRectangle(pos + 1).x();
+
+    QString preeditText = textinputObject->text().mid(0, pos);
+    textinputObject->setText(textinputObject->text().mid(pos));
+    textinputObject->setCursorPosition(0);
+
+    QInputMethodEvent inputEvent(preeditText, QList<QInputMethodEvent::Attribute>());
+    QGuiApplication::sendEvent(&canvas, &inputEvent);
+
+    // Check all points within the preedit text return the same position.
+    QCOMPARE(textinputObject->positionAt(0), 0);
+    QCOMPARE(textinputObject->positionAt(x0 / 2), 0);
+    QCOMPARE(textinputObject->positionAt(x0), 0);
+
+    // Verify positioning returns to normal after the preedit text.
+    QCOMPARE(textinputObject->positionAt(x1), 1);
+    QCOMPARE(textinputObject->positionToRectangle(1).x(), x1);
+}
+
+void tst_qquicktextinput::maxLength()
+{
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("maxLength.qml")));
+    QVERIFY(canvas.rootObject() != 0);
+    canvas.show();
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&canvas);
+
+    QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput *>(canvas.rootObject());
+    QVERIFY(textinputObject != 0);
+    QVERIFY(textinputObject->text().isEmpty());
+    QVERIFY(textinputObject->maxLength() == 10);
+    foreach (const QString &str, standard) {
+        QVERIFY(textinputObject->text().length() <= 10);
+        textinputObject->setText(str);
+        QVERIFY(textinputObject->text().length() <= 10);
+    }
+
+    textinputObject->setText("");
+    QTRY_VERIFY(textinputObject->hasActiveFocus() == true);
+    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);
+    }
+}
+
+void tst_qquicktextinput::masks()
+{
+    //Not a comprehensive test of the possible masks, that's done elsewhere (QLineEdit)
+    //QString componentStr = "import QtQuick 2.0\nTextInput {  inputMask: 'HHHHhhhh'; }";
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("masks.qml")));
+    canvas.show();
+    canvas.requestActivateWindow();
+    QVERIFY(canvas.rootObject() != 0);
+    QQuickTextInput *textinputObject = qobject_cast<QQuickTextInput *>(canvas.rootObject());
+    QVERIFY(textinputObject != 0);
+    QTRY_VERIFY(textinputObject->hasActiveFocus() == true);
+    QVERIFY(textinputObject->text().length() == 0);
+    QCOMPARE(textinputObject->inputMask(), QString("HHHHhhhh; "));
+    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);
+    }
+}
+
+void tst_qquicktextinput::validators()
+{
+    // Note that this test assumes that the validators are working properly
+    // so you may need to run their tests first. All validators are checked
+    // here to ensure that their exposure to QML is working.
+
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("validators.qml")));
+    canvas.show();
+    canvas.requestActivateWindow();
+
+    QVERIFY(canvas.rootObject() != 0);
+
+    QQuickTextInput *intInput = qobject_cast<QQuickTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("intInput")));
+    QVERIFY(intInput);
+    intInput->setFocus(true);
+    QTRY_VERIFY(intInput->hasActiveFocus());
+    QTest::keyPress(&canvas, Qt::Key_1);
+    QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10);
+    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);
+    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);
+
+    QQuickTextInput *dblInput = qobject_cast<QQuickTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("dblInput")));
+    QTRY_VERIFY(dblInput);
+    dblInput->setFocus(true);
+    QVERIFY(dblInput->hasActiveFocus() == true);
+    QTest::keyPress(&canvas, Qt::Key_1);
+    QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10);
+    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);
+    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);
+    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);
+    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);
+    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);
+    QTest::qWait(50);
+    QTRY_COMPARE(dblInput->text(), QLatin1String("12.11"));
+    QCOMPARE(dblInput->hasAcceptableInput(), true);
+
+    QQuickTextInput *strInput = qobject_cast<QQuickTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("strInput")));
+    QTRY_VERIFY(strInput);
+    strInput->setFocus(true);
+    QVERIFY(strInput->hasActiveFocus() == true);
+    QTest::keyPress(&canvas, Qt::Key_1);
+    QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10);
+    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);
+    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);
+    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);
+    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);
+    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);
+    QTest::qWait(50);
+    QTRY_COMPARE(strInput->text(), QLatin1String("aaaa"));
+    QCOMPARE(strInput->hasAcceptableInput(), true);
+}
+
+void tst_qquicktextinput::inputMethods()
+{
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("inputmethods.qml")));
+    canvas.show();
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&canvas);
+
+    // test input method hints
+    QVERIFY(canvas.rootObject() != 0);
+    QQuickTextInput *input = qobject_cast<QQuickTextInput *>(canvas.rootObject());
+    QVERIFY(input != 0);
+    QVERIFY(input->inputMethodHints() & Qt::ImhNoPredictiveText);
+    input->setInputMethodHints(Qt::ImhUppercaseOnly);
+    QVERIFY(input->inputMethodHints() & Qt::ImhUppercaseOnly);
+
+    input->setFocus(true);
+    QVERIFY(input->hasActiveFocus() == true);
+    // test that input method event is committed
+    QInputMethodEvent event;
+    event.setCommitString( "My ", -12, 0);
+    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);
+    QGuiApplication::sendEvent(&canvas, &event);
+    QCOMPARE(input->text(), QString("Your Hello world!"));
+    QCOMPARE(input->cursorPosition(), 4);
+
+    input->setCursorPosition(7);
+    event.setCommitString("Goodbye", -2, 5);
+    QGuiApplication::sendEvent(&canvas, &event);
+    QCOMPARE(input->text(), QString("Your Goodbye world!"));
+    QCOMPARE(input->cursorPosition(), 12);
+
+    input->setCursorPosition(8);
+    event.setCommitString("Our", -8, 4);
+    QGuiApplication::sendEvent(&canvas, &event);
+    QCOMPARE(input->text(), QString("Our Goodbye world!"));
+    QCOMPARE(input->cursorPosition(), 7);
+}
+
+/*
+TextInput element should only handle left/right keys until the cursor reaches
+the extent of the text, then they should ignore the keys.
+
+*/
+void tst_qquicktextinput::navigation()
+{
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml")));
+    canvas.show();
+    canvas.requestActivateWindow();
+
+    QVERIFY(canvas.rootObject() != 0);
+
+    QQuickTextInput *input = qobject_cast<QQuickTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("myInput")));
+
+    QVERIFY(input != 0);
+    input->setCursorPosition(0);
+    QTRY_VERIFY(input->hasActiveFocus() == true);
+    simulateKey(&canvas, Qt::Key_Left);
+    QVERIFY(input->hasActiveFocus() == false);
+    simulateKey(&canvas, Qt::Key_Right);
+    QVERIFY(input->hasActiveFocus() == true);
+    //QT-2944: If text is selected, ensure we deselect upon cursor motion
+    input->setCursorPosition(input->text().length());
+    input->select(0,input->text().length());
+    QVERIFY(input->selectionStart() != input->selectionEnd());
+    simulateKey(&canvas, Qt::Key_Right);
+    QVERIFY(input->selectionStart() == input->selectionEnd());
+    QVERIFY(input->selectionStart() == input->text().length());
+    QVERIFY(input->hasActiveFocus() == true);
+    simulateKey(&canvas, Qt::Key_Right);
+    QVERIFY(input->hasActiveFocus() == false);
+    simulateKey(&canvas, Qt::Key_Left);
+    QVERIFY(input->hasActiveFocus() == true);
+
+    // Up and Down should NOT do Home/End, even on Mac OS X (QTBUG-10438).
+    input->setCursorPosition(2);
+    QCOMPARE(input->cursorPosition(),2);
+    simulateKey(&canvas, Qt::Key_Up);
+    QCOMPARE(input->cursorPosition(),2);
+    simulateKey(&canvas, Qt::Key_Down);
+    QCOMPARE(input->cursorPosition(),2);
+}
+
+void tst_qquicktextinput::navigation_RTL()
+{
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml")));
+    canvas.show();
+    canvas.requestActivateWindow();
+
+    QVERIFY(canvas.rootObject() != 0);
+
+    QQuickTextInput *input = qobject_cast<QQuickTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("myInput")));
+
+    QVERIFY(input != 0);
+    const quint16 arabic_str[] = { 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0647};
+    input->setText(QString::fromUtf16(arabic_str, 11));
+
+    input->setCursorPosition(0);
+    QTRY_VERIFY(input->hasActiveFocus() == true);
+
+    // move off
+    simulateKey(&canvas, Qt::Key_Right);
+    QVERIFY(input->hasActiveFocus() == false);
+
+    // move back
+    simulateKey(&canvas, Qt::Key_Left);
+    QVERIFY(input->hasActiveFocus() == true);
+
+    input->setCursorPosition(input->text().length());
+    QVERIFY(input->hasActiveFocus() == true);
+
+    // move off
+    simulateKey(&canvas, Qt::Key_Left);
+    QVERIFY(input->hasActiveFocus() == false);
+
+    // move back
+    simulateKey(&canvas, Qt::Key_Right);
+    QVERIFY(input->hasActiveFocus() == true);
+}
+
+void tst_qquicktextinput::copyAndPaste() {
+#ifndef QT_NO_CLIPBOARD
+
+#ifdef Q_WS_MAC
+    {
+        PasteboardRef pasteboard;
+        OSStatus status = PasteboardCreate(0, &pasteboard);
+        if (status == noErr)
+            CFRelease(pasteboard);
+        else
+            QSKIP("This machine doesn't support the clipboard");
+    }
+#endif
+
+    QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\" }";
+    QDeclarativeComponent textInputComponent(&engine);
+    textInputComponent.setData(componentStr.toLatin1(), QUrl());
+    QQuickTextInput *textInput = qobject_cast<QQuickTextInput*>(textInputComponent.create());
+    QVERIFY(textInput != 0);
+
+    // copy and paste
+    QCOMPARE(textInput->text().length(), 12);
+    textInput->select(0, textInput->text().length());;
+    textInput->copy();
+    QCOMPARE(textInput->selectedText(), QString("Hello world!"));
+    QCOMPARE(textInput->selectedText().length(), 12);
+    textInput->setCursorPosition(0);
+    QVERIFY(textInput->canPaste());
+    textInput->paste();
+    QCOMPARE(textInput->text(), QString("Hello world!Hello world!"));
+    QCOMPARE(textInput->text().length(), 24);
+
+    // can paste
+    QVERIFY(textInput->canPaste());
+    textInput->setReadOnly(true);
+    QVERIFY(!textInput->canPaste());
+    textInput->setReadOnly(false);
+    QVERIFY(textInput->canPaste());
+
+    // select word
+    textInput->setCursorPosition(0);
+    textInput->selectWord();
+    QCOMPARE(textInput->selectedText(), QString("Hello"));
+
+    // select all and cut
+    textInput->selectAll();
+    textInput->cut();
+    QCOMPARE(textInput->text().length(), 0);
+    textInput->paste();
+    QCOMPARE(textInput->text(), QString("Hello world!Hello world!"));
+    QCOMPARE(textInput->text().length(), 24);
+
+    // clear copy buffer
+    QClipboard *clipboard = QGuiApplication::clipboard();
+    QVERIFY(clipboard);
+    clipboard->clear();
+    QVERIFY(!textInput->canPaste());
+
+    // test that copy functionality is disabled
+    // when echo mode is set to hide text/password mode
+    int index = 0;
+    while (index < 4) {
+        QQuickTextInput::EchoMode echoMode = QQuickTextInput::EchoMode(index);
+        textInput->setEchoMode(echoMode);
+        textInput->setText("My password");
+        textInput->select(0, textInput->text().length());;
+        textInput->copy();
+        if (echoMode == QQuickTextInput::Normal) {
+            QVERIFY(!clipboard->text().isEmpty());
+            QCOMPARE(clipboard->text(), QString("My password"));
+            clipboard->clear();
+        } else {
+            QVERIFY(clipboard->text().isEmpty());
+        }
+        index++;
+    }
+
+    delete textInput;
+#endif
+}
+
+void tst_qquicktextinput::canPasteEmpty() {
+#ifndef QT_NO_CLIPBOARD
+
+    QGuiApplication::clipboard()->clear();
+
+    QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\" }";
+    QDeclarativeComponent textInputComponent(&engine);
+    textInputComponent.setData(componentStr.toLatin1(), QUrl());
+    QQuickTextInput *textInput = qobject_cast<QQuickTextInput*>(textInputComponent.create());
+    QVERIFY(textInput != 0);
+
+    QLineControl lc;
+    bool cp = !lc.isReadOnly() && QGuiApplication::clipboard()->text().length() != 0;
+    QCOMPARE(textInput->canPaste(), cp);
+
+#endif
+}
+
+void tst_qquicktextinput::canPaste() {
+#ifndef QT_NO_CLIPBOARD
+
+    QGuiApplication::clipboard()->setText("Some text");
+
+    QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\" }";
+    QDeclarativeComponent textInputComponent(&engine);
+    textInputComponent.setData(componentStr.toLatin1(), QUrl());
+    QQuickTextInput *textInput = qobject_cast<QQuickTextInput*>(textInputComponent.create());
+    QVERIFY(textInput != 0);
+
+    QLineControl lc;
+    bool cp = !lc.isReadOnly() && QGuiApplication::clipboard()->text().length() != 0;
+    QCOMPARE(textInput->canPaste(), cp);
+
+#endif
+}
+
+void tst_qquicktextinput::passwordCharacter()
+{
+    QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\"; font.family: \"Helvetica\"; echoMode: TextInput.Password }";
+    QDeclarativeComponent textInputComponent(&engine);
+    textInputComponent.setData(componentStr.toLatin1(), QUrl());
+    QQuickTextInput *textInput = qobject_cast<QQuickTextInput*>(textInputComponent.create());
+    QVERIFY(textInput != 0);
+
+    textInput->setPasswordCharacter("X");
+    qreal implicitWidth = textInput->implicitWidth();
+    textInput->setPasswordCharacter(".");
+
+    // QTBUG-12383 content is updated and redrawn
+    QVERIFY(textInput->implicitWidth() < implicitWidth);
+
+    delete textInput;
+}
+
+void tst_qquicktextinput::cursorDelegate()
+{
+    QQuickView view(QUrl::fromLocalFile(TESTDATA("cursorTest.qml")));
+    view.show();
+    view.requestActivateWindow();
+    QQuickTextInput *textInputObject = view.rootObject()->findChild<QQuickTextInput*>("textInputObject");
+    QVERIFY(textInputObject != 0);
+    QVERIFY(textInputObject->findChild<QQuickItem*>("cursorInstance"));
+    //Test Delegate gets created
+    textInputObject->setFocus(true);
+    QQuickItem* delegateObject = textInputObject->findChild<QQuickItem*>("cursorInstance");
+    QVERIFY(delegateObject);
+    QCOMPARE(delegateObject->property("localProperty").toString(), QString("Hello"));
+    //Test Delegate gets moved
+    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()));
+    }
+    textInputObject->setCursorPosition(0);
+    QCOMPARE(textInputObject->cursorRectangle().x(), qRound(delegateObject->x()));
+    QCOMPARE(textInputObject->cursorRectangle().y(), qRound(delegateObject->y()));
+    //Test Delegate gets deleted
+    textInputObject->setCursorDelegate(0);
+    QVERIFY(!textInputObject->findChild<QQuickItem*>("cursorInstance"));
+}
+
+void tst_qquicktextinput::cursorVisible()
+{
+    QQuickView view(QUrl::fromLocalFile(TESTDATA("cursorVisible.qml")));
+    view.show();
+    view.requestActivateWindow();
+    QTest::qWaitForWindowShown(&view);
+    QTRY_COMPARE(&view, qGuiApp->focusWindow());
+
+    QQuickTextInput input;
+    QSignalSpy spy(&input, SIGNAL(cursorVisibleChanged(bool)));
+
+    QCOMPARE(input.isCursorVisible(), false);
+
+    input.setCursorVisible(true);
+    QCOMPARE(input.isCursorVisible(), true);
+    QCOMPARE(spy.count(), 1);
+
+    input.setCursorVisible(false);
+    QCOMPARE(input.isCursorVisible(), false);
+    QCOMPARE(spy.count(), 2);
+
+    input.setFocus(true);
+    QCOMPARE(input.isCursorVisible(), false);
+    QCOMPARE(spy.count(), 2);
+
+    input.setParentItem(view.rootObject());
+    QCOMPARE(input.isCursorVisible(), true);
+    QCOMPARE(spy.count(), 3);
+
+    input.setFocus(false);
+    QCOMPARE(input.isCursorVisible(), false);
+    QCOMPARE(spy.count(), 4);
+
+    input.setFocus(true);
+    QCOMPARE(input.isCursorVisible(), true);
+    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);
+
+    view.requestActivateWindow();
+    QCOMPARE(input.isCursorVisible(), true);
+    QCOMPARE(spy.count(), 7);
+
+    // 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)
+    // 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_qquicktextinput::cursorRectangle()
+{
+    QSKIP("QTBUG-21689");
+
+    QString text = "Hello World!";
+
+    QQuickTextInput input;
+    input.setText(text);
+    QFontMetricsF fm(input.font());
+    input.setWidth(fm.width(text.mid(0, 5)));
+
+    QRect r;
+
+    // some tolerance for different fonts.
+#ifdef Q_OS_LINUX
+    const int error = 2;
+#else
+    const int error = 5;
+#endif
+
+
+    for (int i = 0; i <= 5; ++i) {
+        input.setCursorPosition(i);
+        r = input.cursorRectangle();
+        int textWidth = fm.width(text.mid(0, i));
+
+        QVERIFY(r.left() < textWidth + error);
+        QVERIFY(r.right() > textWidth - error);
+        QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
+    }
+
+    // Check the cursor rectangle remains within the input bounding rect when auto scrolling.
+    QVERIFY(r.left() < input.boundingRect().width());
+    QVERIFY(r.right() >= input.width() - error);
+
+    for (int i = 6; i < text.length(); ++i) {
+        input.setCursorPosition(i);
+        QCOMPARE(r, input.cursorRectangle());
+        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::ImCursorRectangle).toRect(), r);
+    }
+
+    input.setText("Hi!");
+    input.setHAlign(QQuickTextInput::AlignRight);
+    r = input.cursorRectangle();
+    QVERIFY(r.left() < input.boundingRect().width());
+    QVERIFY(r.right() >= input.width() - error);
+}
+
+void tst_qquicktextinput::readOnly()
+{
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("readOnly.qml")));
+    canvas.show();
+    canvas.requestActivateWindow();
+
+    QVERIFY(canvas.rootObject() != 0);
+
+    QQuickTextInput *input = qobject_cast<QQuickTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("myInput")));
+
+    QVERIFY(input != 0);
+    QTRY_VERIFY(input->hasActiveFocus() == true);
+    QVERIFY(input->isReadOnly() == true);
+    QString initial = input->text();
+    for (int k=Qt::Key_0; k<=Qt::Key_Z; k++)
+        simulateKey(&canvas, k);
+    simulateKey(&canvas, Qt::Key_Return);
+    simulateKey(&canvas, Qt::Key_Space);
+    simulateKey(&canvas, Qt::Key_Escape);
+    QCOMPARE(input->text(), initial);
+
+    input->setCursorPosition(3);
+    input->setReadOnly(false);
+    QCOMPARE(input->isReadOnly(), false);
+    QCOMPARE(input->cursorPosition(), input->text().length());
+}
+
+void tst_qquicktextinput::echoMode()
+{
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("echoMode.qml")));
+    canvas.show();
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&canvas);
+    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
+
+    QVERIFY(canvas.rootObject() != 0);
+
+    QQuickTextInput *input = qobject_cast<QQuickTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("myInput")));
+
+    QVERIFY(input != 0);
+    QTRY_VERIFY(input->hasActiveFocus() == true);
+    QString initial = input->text();
+    Qt::InputMethodHints ref;
+    QCOMPARE(initial, QLatin1String("ABCDefgh"));
+    QCOMPARE(input->echoMode(), QQuickTextInput::Normal);
+    QCOMPARE(input->displayText(), input->text());
+    //Normal
+    ref &= ~Qt::ImhHiddenText;
+    ref &= ~(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText);
+    QCOMPARE(input->inputMethodHints(), ref);
+    input->setEchoMode(QQuickTextInput::NoEcho);
+    QCOMPARE(input->text(), initial);
+    QCOMPARE(input->displayText(), QLatin1String(""));
+    QCOMPARE(input->passwordCharacter(), QLatin1String("*"));
+    //NoEcho
+    ref |= Qt::ImhHiddenText;
+    ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText);
+    QCOMPARE(input->inputMethodHints(), ref);
+    input->setEchoMode(QQuickTextInput::Password);
+    //Password
+    ref |= Qt::ImhHiddenText;
+    ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText);
+    QCOMPARE(input->text(), initial);
+    QCOMPARE(input->displayText(), QLatin1String("********"));
+    QCOMPARE(input->inputMethodHints(), ref);
+    input->setPasswordCharacter(QChar('Q'));
+    QCOMPARE(input->passwordCharacter(), QLatin1String("Q"));
+    QCOMPARE(input->text(), initial);
+    QCOMPARE(input->displayText(), QLatin1String("QQQQQQQQ"));
+    input->setEchoMode(QQuickTextInput::PasswordEchoOnEdit);
+    //PasswordEchoOnEdit
+    ref &= ~Qt::ImhHiddenText;
+    ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText);
+    QCOMPARE(input->inputMethodHints(), ref);
+    QCOMPARE(input->text(), initial);
+    QCOMPARE(input->displayText(), QLatin1String("QQQQQQQQ"));
+    QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QLatin1String("QQQQQQQQ"));
+    QTest::keyPress(&canvas, Qt::Key_A);//Clearing previous entry is part of PasswordEchoOnEdit
+    QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10);
+    QCOMPARE(input->text(), QLatin1String("a"));
+    QCOMPARE(input->displayText(), QLatin1String("a"));
+    QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QLatin1String("a"));
+    input->setFocus(false);
+    QVERIFY(input->hasActiveFocus() == false);
+    QCOMPARE(input->displayText(), QLatin1String("Q"));
+    QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QLatin1String("Q"));
+    input->setFocus(true);
+    QVERIFY(input->hasActiveFocus());
+    QInputMethodEvent inputEvent;
+    inputEvent.setCommitString(initial);
+    QGuiApplication::sendEvent(input, &inputEvent);
+    QCOMPARE(input->text(), initial);
+    QCOMPARE(input->displayText(), initial);
+    QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), initial);
+}
+
+#ifdef QT_GUI_PASSWORD_ECHO_DELAY
+void tst_qdeclarativetextinput::passwordEchoDelay()
+{
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("echoMode.qml")));
+    canvas.show();
+    canvas.setFocus();
+    QGuiApplication::setActiveWindow(&canvas);
+    QTest::qWaitForWindowShown(&canvas);
+    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
+
+    QVERIFY(canvas.rootObject() != 0);
+
+    QQuickTextInput *input = qobject_cast<QQuickTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("myInput")));
+
+    QChar fillChar = QLatin1Char('*');
+
+    input->setEchoMode(QDeclarativeTextInput::Password);
+    QCOMPARE(input->displayText(), QString(8, fillChar));
+    input->setText(QString());
+    QCOMPARE(input->displayText(), QString());
+
+    QTest::keyPress(&canvas, '0');
+    QTest::keyPress(&canvas, '1');
+    QTest::keyPress(&canvas, '2');
+    QCOMPARE(input->displayText(), QString(2, fillChar) + QLatin1Char('2'));
+    QTest::keyPress(&canvas, '3');
+    QTest::keyPress(&canvas, '4');
+    QCOMPARE(input->displayText(), QString(4, fillChar) + QLatin1Char('4'));
+    QTest::keyPress(&canvas, Qt::Key_Backspace);
+    QCOMPARE(input->displayText(), QString(4, fillChar));
+    QTest::keyPress(&canvas, '4');
+    QCOMPARE(input->displayText(), QString(4, fillChar) + QLatin1Char('4'));
+    QTest::qWait(QT_GUI_PASSWORD_ECHO_DELAY);
+    QTRY_COMPARE(input->displayText(), QString(5, fillChar));
+    QTest::keyPress(&canvas, '5');
+    QCOMPARE(input->displayText(), QString(5, fillChar) + QLatin1Char('5'));
+    input->setFocus(false);
+    QVERIFY(!input->hasFocus());
+    QCOMPARE(input->displayText(), QString(6, fillChar));
+    input->setFocus(true);
+    QTRY_VERIFY(input->hasFocus());
+    QCOMPARE(input->displayText(), QString(6, fillChar));
+    QTest::keyPress(&canvas, '6');
+    QCOMPARE(input->displayText(), QString(6, fillChar) + QLatin1Char('6'));
+
+    QInputMethodEvent ev;
+    ev.setCommitString(QLatin1String("7"));
+    QGuiApplication::sendEvent(&canvas, &ev);
+    QCOMPARE(input->displayText(), QString(7, fillChar) + QLatin1Char('7'));
+}
+#endif
+
+
+void tst_qquicktextinput::simulateKey(QQuickView *view, int key)
+{
+    QKeyEvent press(QKeyEvent::KeyPress, key, 0);
+    QKeyEvent release(QKeyEvent::KeyRelease, key, 0);
+
+    QGuiApplication::sendEvent(view, &press);
+    QGuiApplication::sendEvent(view, &release);
+}
+
+#ifndef QTBUG_21691
+class MyInputContext : public QInputContext
+{
+public:
+    MyInputContext() : updateReceived(false), eventType(QEvent::None) {}
+    ~MyInputContext() {}
+
+    QString identifierName() { return QString(); }
+    QString language() { return QString(); }
+
+    void reset() {}
+
+    bool isComposing() const { return false; }
+
+    void update() { updateReceived = true; }
+
+    void mouseHandler(int x, QMouseEvent *event)
+    {
+        cursor = x;
+        eventType = event->type();
+        eventPosition = event->pos();
+        eventGlobalPosition = event->globalPos();
+        eventButton = event->button();
+        eventButtons = event->buttons();
+        eventModifiers = event->modifiers();
+    }
+
+    void sendPreeditText(const QString &text, int cursor)
+    {
+        QList<QInputMethodEvent::Attribute> attributes;
+        attributes.append(QInputMethodEvent::Attribute(
+                QInputMethodEvent::Cursor, cursor, text.length(), QVariant()));
+
+        QInputMethodEvent event(text, attributes);
+        sendEvent(event);
+    }
+
+    bool updateReceived;
+    int cursor;
+    QEvent::Type eventType;
+    QPoint eventPosition;
+    QPoint eventGlobalPosition;
+    Qt::MouseButton eventButton;
+    Qt::MouseButtons eventButtons;
+    Qt::KeyboardModifiers eventModifiers;
+};
+#endif
+
+void tst_qquicktextinput::openInputPanel()
+{
+    QQuickView view(QUrl::fromLocalFile(TESTDATA("openInputPanel.qml")));
+    view.show();
+    view.requestActivateWindow();
+    QTest::qWaitForWindowShown(&view);
+    QTRY_COMPARE(&view, qGuiApp->focusWindow());
+
+    QQuickTextInput *input = qobject_cast<QQuickTextInput *>(view.rootObject());
+    QVERIFY(input);
+
+    // check default values
+    QVERIFY(input->focusOnPress());
+    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(qApp->inputPanel()->inputItem(), input);
+    QCOMPARE(qApp->inputPanel()->visible(), true);
+    QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint);
+
+    // 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, noModifiers, centerPoint);
+    QGuiApplication::processEvents();
+    QCOMPARE(qApp->inputPanel()->visible(), true);
+    QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint);
+
+    // input panel should stay visible if focus is lost to another text inputor
+    QSignalSpy inputPanelVisibilitySpy(qApp->inputPanel(), SIGNAL(visibleChanged()));
+    QQuickTextInput anotherInput;
+    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);
+
+    // input item should be null if focus is lost to an item that doesn't accept inputs
+    QQuickItem item;
+    item.setParentItem(view.rootObject());
+    item.setFocus(true);
+    QCOMPARE(qApp->inputPanel()->inputItem(), static_cast<QObject*>(0));
+    QCOMPARE(view.activeFocusItem(), &item);
+
+    qApp->inputPanel()->hide();
+
+    // input panel should not be opened if TextInput is read only
+    input->setReadOnly(true);
+    input->setFocus(true);
+    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);
+
+    // input panel should not be opened if focusOnPress is set to false
+    input->setFocusOnPress(false);
+    input->setFocus(false);
+    input->setFocus(true);
+    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 panel should open when openSoftwareInputPanel is called
+    input->openSoftwareInputPanel();
+    QCOMPARE(qApp->inputPanel()->visible(), true);
+
+    // input panel should close when closeSoftwareInputPanel is called
+    input->closeSoftwareInputPanel();
+    QCOMPARE(qApp->inputPanel()->visible(), false);
+}
+
+class MyTextInput : public QQuickTextInput
+{
+public:
+    MyTextInput(QQuickItem *parent = 0) : QQuickTextInput(parent)
+    {
+        nbPaint = 0;
+    }
+    virtual QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *data)
+    {
+       nbPaint++;
+       return QQuickTextInput::updatePaintNode(node, data);
+    }
+    int nbPaint;
+};
+
+void tst_qquicktextinput::setHAlignClearCache()
+{
+    QQuickView view;
+    MyTextInput input;
+    input.setText("Hello world");
+    input.setParentItem(view.rootItem());
+    view.show();
+    view.requestActivateWindow();
+    QTest::qWaitForWindowShown(&view);
+    QTRY_COMPARE(input.nbPaint, 1);
+    input.setHAlign(QQuickTextInput::AlignRight);
+    //Changing the alignment should trigger a repaint
+    QTRY_COMPARE(input.nbPaint, 2);
+}
+
+void tst_qquicktextinput::focusOutClearSelection()
+{
+    QQuickView view;
+    QQuickTextInput input;
+    QQuickTextInput input2;
+    input.setText(QLatin1String("Hello world"));
+    input.setFocus(true);
+    input2.setParentItem(view.rootItem());
+    input.setParentItem(view.rootItem());
+    view.show();
+    view.requestActivateWindow();
+    QTest::qWaitForWindowShown(&view);
+    input.select(2,5);
+    //The selection should work
+    QTRY_COMPARE(input.selectedText(), QLatin1String("llo"));
+    input2.setFocus(true);
+    QGuiApplication::processEvents();
+    //The input lost the focus selection should be cleared
+    QTRY_COMPARE(input.selectedText(), QLatin1String(""));
+}
+
+void tst_qquicktextinput::geometrySignals()
+{
+    QDeclarativeComponent component(&engine, TESTDATA("geometrySignals.qml"));
+    QObject *o = component.create();
+    QVERIFY(o);
+    QCOMPARE(o->property("bindingWidth").toInt(), 400);
+    QCOMPARE(o->property("bindingHeight").toInt(), 500);
+    delete o;
+}
+
+void tst_qquicktextinput::testQtQuick11Attributes()
+{
+    QFETCH(QString, code);
+    QFETCH(QString, warning);
+    QFETCH(QString, error);
+
+    QDeclarativeEngine engine;
+    QObject *obj;
+
+    QDeclarativeComponent valid(&engine);
+    valid.setData("import QtQuick 2.0; TextInput { " + code.toUtf8() + " }", QUrl(""));
+    obj = valid.create();
+    QVERIFY(obj);
+    QVERIFY(valid.errorString().isEmpty());
+    delete obj;
+
+    QDeclarativeComponent invalid(&engine);
+    invalid.setData("import QtQuick 1.0; TextInput { " + code.toUtf8() + " }", QUrl(""));
+    QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
+    obj = invalid.create();
+    QCOMPARE(invalid.errorString(), error);
+    delete obj;
+}
+
+void tst_qquicktextinput::testQtQuick11Attributes_data()
+{
+    QTest::addColumn<QString>("code");
+    QTest::addColumn<QString>("warning");
+    QTest::addColumn<QString>("error");
+
+    QTest::newRow("canPaste") << "property bool foo: canPaste"
+        << "<Unknown File>:1: ReferenceError: Can't find variable: canPaste"
+        << "";
+
+    QTest::newRow("moveCursorSelection") << "Component.onCompleted: moveCursorSelection(0, TextEdit.SelectCharacters)"
+        << "<Unknown File>:1: ReferenceError: Can't find variable: moveCursorSelection"
+        << "";
+
+    QTest::newRow("deselect") << "Component.onCompleted: deselect()"
+        << "<Unknown File>:1: ReferenceError: Can't find variable: deselect"
+        << "";
+}
+
+void tst_qquicktextinput::preeditAutoScroll()
+{
+#ifdef QTBUG_21691
+    QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
+    QVERIFY(false);
+#else
+    QString preeditText = "califragisiticexpialidocious!";
+
+    QQuickView view(QUrl::fromLocalFile(TESTDATA("preeditAutoScroll.qml")));
+    MyInputContext ic;
+    // QQuickCanvas 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.
+    view.setAttribute(Qt::WA_InputMethodEnabled, true);
+    view.setInputContext(&ic);
+    view.setAttribute(Qt::WA_InputMethodEnabled, false);
+    view.show();
+    view.requestActivateWindow();
+    QTest::qWaitForWindowShown(&view);
+    QTRY_COMPARE(&view, qGuiApp->focusWindow());
+    QQuickTextInput *input = qobject_cast<QQuickTextInput *>(view.rootObject());
+    QVERIFY(input);
+
+    QSignalSpy cursorRectangleSpy(input, SIGNAL(cursorRectangleChanged()));
+    int cursorRectangleChanges = 0;
+
+    QFontMetricsF fm(input->font());
+    input->setWidth(fm.width(input->text()));
+
+    // test the text is scrolled so the preedit is visible.
+    ic.sendPreeditText(preeditText.mid(0, 3), 1);
+    QVERIFY(input->positionAt(0) != 0);
+    QVERIFY(input->cursorRectangle().left() < input->boundingRect().width());
+    QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
+
+    // test the text is scrolled back when the preedit is removed.
+    ic.sendEvent(QInputMethodEvent());
+    QCOMPARE(input->positionAt(0), 0);
+    QCOMPARE(input->positionAt(input->width()), 5);
+    QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
+
+    // some tolerance for different fonts.
+#ifdef Q_OS_LINUX
+    const int error = 2;
+#else
+    const int error = 5;
+#endif
+
+    // test if the preedit is larger than the text input that the
+    // character preceding the cursor is still visible.
+    qreal x = input->positionToRectangle(0).x();
+    for (int i = 0; i < 3; ++i) {
+        ic.sendPreeditText(preeditText, i + 1);
+        QVERIFY(input->cursorRectangle().right() >= fm.width(preeditText.at(i)) - error);
+        QVERIFY(input->positionToRectangle(0).x() < x);
+        QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
+        x = input->positionToRectangle(0).x();
+    }
+    for (int i = 1; i >= 0; --i) {
+        ic.sendPreeditText(preeditText, i + 1);
+        QVERIFY(input->cursorRectangle().right() >= fm.width(preeditText.at(i)) - error);
+        QVERIFY(input->positionToRectangle(0).x() > x);
+        QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
+        x = input->positionToRectangle(0).x();
+    }
+
+    // Test incrementing the preedit cursor doesn't cause further
+    // scrolling when right most text is visible.
+    ic.sendPreeditText(preeditText, preeditText.length() - 3);
+    QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
+    x = input->positionToRectangle(0).x();
+    for (int i = 2; i >= 0; --i) {
+        ic.sendPreeditText(preeditText, preeditText.length() - i);
+        QCOMPARE(input->positionToRectangle(0).x(), x);
+        QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
+    }
+    for (int i = 1; i <  3; ++i) {
+        ic.sendPreeditText(preeditText, preeditText.length() - i);
+        QCOMPARE(input->positionToRectangle(0).x(), x);
+        QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
+    }
+
+    // Test disabling auto scroll.
+    ic.sendEvent(QInputMethodEvent());
+
+    input->setAutoScroll(false);
+    ic.sendPreeditText(preeditText.mid(0, 3), 1);
+    QCOMPARE(input->positionAt(0), 0);
+    QCOMPARE(input->positionAt(input->width()), 5);
+#endif
+}
+
+void tst_qquicktextinput::preeditMicroFocus()
+{
+#ifdef QTBUG_21691
+    QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
+    QVERIFY(false);
+#else
+    QString preeditText = "super";
+
+    QQuickView view(QUrl::fromLocalFile(TESTDATA("inputMethodEvent.qml")));
+    MyInputContext ic;
+    // QQuickCanvas 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.
+    view.setAttribute(Qt::WA_InputMethodEnabled, true);
+    view.setInputContext(&ic);
+    view.setAttribute(Qt::WA_InputMethodEnabled, false);
+    view.show();
+    view.requestActivateWindow();
+    QTest::qWaitForWindowShown(&view);
+    QTRY_COMPARE(&view, qGuiApp->focusWindow());
+    QQuickTextInput *input = qobject_cast<QQuickTextInput *>(view.rootObject());
+    QVERIFY(input);
+
+    QRect currentRect;
+    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::ImCursorRectangle).toRect();
+    QCOMPARE(currentRect, previousRect);
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
+    QCOMPARE(ic.updateReceived, true);
+#endif
+
+    // Verify that the micro focus rect moves to the left as the cursor position
+    // is incremented.
+    for (int i = 1; i <= 5; ++i) {
+        ic.updateReceived = false;
+        ic.sendPreeditText(preeditText, i);
+        currentRect = input->inputMethodQuery(Qt::ImCursorRectangle).toRect();
+        QVERIFY(previousRect.left() < currentRect.left());
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
+        QCOMPARE(ic.updateReceived, true);
+#endif
+        previousRect = currentRect;
+    }
+
+    // Verify that if there is no preedit cursor then the micro focus rect is the
+    // same as it would be if it were positioned at the end of the preedit text.
+    ic.sendPreeditText(preeditText, 0);
+    ic.updateReceived = false;
+    ic.sendEvent(QInputMethodEvent(preeditText, QList<QInputMethodEvent::Attribute>()));
+    currentRect = input->inputMethodQuery(Qt::ImCursorRectangle).toRect();
+    QCOMPARE(currentRect, previousRect);
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
+    QCOMPARE(ic.updateReceived, true);
+#endif
+#endif
+}
+
+void tst_qquicktextinput::inputContextMouseHandler()
+{
+#ifdef QTBUG_21691
+    QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
+    QVERIFY(false);
+#else
+    QString text = "supercalifragisiticexpialidocious!";
+
+    QQuickView view(QUrl::fromLocalFile(TESTDATA("inputContext.qml")));
+    MyInputContext ic;
+    // QQuickCanvas 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.
+    view.setAttribute(Qt::WA_InputMethodEnabled, true);
+    view.setInputContext(&ic);
+    view.setAttribute(Qt::WA_InputMethodEnabled, false);
+    view.show();
+    view.requestActivateWindow();
+    QTest::qWaitForWindowShown(&view);
+    QTRY_COMPARE(&view, qGuiApp->focusWindow());
+    QQuickTextInput *input = qobject_cast<QQuickTextInput *>(view.rootObject());
+    QVERIFY(input);
+
+    QFontMetricsF fm(input->font());
+    const qreal y = fm.height() / 2;
+
+    QPoint position2 = input->mapToScene(QPointF(fm.width(text.mid(0, 2)), y)).toPoint();
+    QPoint position8 = input->mapToScene(QPointF(fm.width(text.mid(0, 8)), y)).toPoint();
+    QPoint position20 = input->mapToScene(QPointF(fm.width(text.mid(0, 20)), y)).toPoint();
+    QPoint position27 = input->mapToScene(QPointF(fm.width(text.mid(0, 27)), y)).toPoint();
+    QPoint globalPosition2 = view.mapToGlobal(position2);
+    QPoint globalposition8 = view.mapToGlobal(position8);
+    QPoint globalposition20 = view.mapToGlobal(position20);
+    QPoint globalposition27 = view.mapToGlobal(position27);
+
+    ic.sendEvent(QInputMethodEvent(text.mid(12), QList<QInputMethodEvent::Attribute>()));
+
+    QTest::mouseDClick(&view, Qt::LeftButton, Qt::NoModifier, position2);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
+    QCOMPARE(ic.eventPosition, position2);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition2);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
+    QVERIFY(ic.cursor < 0);
+    ic.eventType = QEvent::None;
+
+    QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, position2);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
+    QCOMPARE(ic.eventPosition, position2);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition2);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
+    QVERIFY(ic.cursor < 0);
+    ic.eventType = QEvent::None;
+
+    {   QMouseEvent mv(QEvent::MouseMove, position8, globalposition8, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+        QGuiApplication::sendEvent(&view, &mv); }
+    QCOMPARE(ic.eventType, QEvent::None);
+
+    {   QMouseEvent mv(QEvent::MouseMove, position27, globalposition27, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
+        QGuiApplication::sendEvent(&view, &mv); }
+    QCOMPARE(ic.eventType, QEvent::MouseMove);
+    QCOMPARE(ic.eventPosition, position27);
+    QCOMPARE(ic.eventGlobalPosition, globalposition27);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
+    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);    // 15 is expected but some platforms may be off by one.
+    ic.eventType = QEvent::None;
+
+    QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, position27);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
+    QCOMPARE(ic.eventPosition, position27);
+    QCOMPARE(ic.eventGlobalPosition, globalposition27);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
+    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
+    ic.eventType = QEvent::None;
+
+    // And in the other direction.
+    QTest::mouseDClick(&view, Qt::LeftButton, Qt::ControlModifier, position27);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
+    QCOMPARE(ic.eventPosition, position27);
+    QCOMPARE(ic.eventGlobalPosition, globalposition27);
+    QCOMPARE(ic.eventButton, Qt::LeftButton);
+    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
+    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
+    ic.eventType = QEvent::None;
+
+    QTest::mousePress(&view, Qt::RightButton, Qt::ControlModifier, position27);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
+    QCOMPARE(ic.eventPosition, position27);
+    QCOMPARE(ic.eventGlobalPosition, globalposition27);
+    QCOMPARE(ic.eventButton, Qt::RightButton);
+    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
+    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
+    ic.eventType = QEvent::None;
+
+    {   QMouseEvent mv(QEvent::MouseMove, position20, globalposition20, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
+        QGuiApplication::sendEvent(&view, &mv); }
+    QCOMPARE(ic.eventType, QEvent::MouseMove);
+    QCOMPARE(ic.eventPosition, position20);
+    QCOMPARE(ic.eventGlobalPosition, globalposition20);
+    QCOMPARE(ic.eventButton, Qt::RightButton);
+    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
+    QVERIFY(ic.cursor >= 7 && ic.cursor <= 9);
+    ic.eventType = QEvent::None;
+
+    {   QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
+        QGuiApplication::sendEvent(&view, &mv); }
+    QCOMPARE(ic.eventType, QEvent::None);
+
+    QTest::mouseRelease(&view, Qt::RightButton, Qt::ControlModifier, position2);
+    QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
+    QCOMPARE(ic.eventPosition, position2);
+    QCOMPARE(ic.eventGlobalPosition, globalPosition2);
+    QCOMPARE(ic.eventButton, Qt::RightButton);
+    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
+    QVERIFY(ic.cursor < 0);
+    ic.eventType = QEvent::None;
+#endif
+}
+
+void tst_qquicktextinput::inputMethodComposing()
+{
+    QString text = "supercalifragisiticexpialidocious!";
+
+    QQuickView view(QUrl::fromLocalFile(TESTDATA("inputContext.qml")));
+    view.show();
+    view.requestActivateWindow();
+    QTest::qWaitForWindowShown(&view);
+    QTRY_COMPARE(&view, qGuiApp->focusWindow());
+    QQuickTextInput *input = qobject_cast<QQuickTextInput *>(view.rootObject());
+    QVERIFY(input);
+    QSignalSpy spy(input, SIGNAL(inputMethodComposingChanged()));
+
+    QCOMPARE(input->isInputMethodComposing(), false);
+    {
+        QInputMethodEvent event(text.mid(3), QList<QInputMethodEvent::Attribute>());
+        QGuiApplication::sendEvent(input, &event);
+    }
+    QCOMPARE(input->isInputMethodComposing(), true);
+    QCOMPARE(spy.count(), 1);
+
+    {
+        QInputMethodEvent event(text.mid(12), QList<QInputMethodEvent::Attribute>());
+        QGuiApplication::sendEvent(input, &event);
+    }
+    QCOMPARE(spy.count(), 1);
+
+    {
+        QInputMethodEvent event;
+        QGuiApplication::sendEvent(input, &event);
+    }
+    QCOMPARE(input->isInputMethodComposing(), false);
+    QCOMPARE(spy.count(), 2);
+}
+
+void tst_qquicktextinput::cursorRectangleSize()
+{
+    QQuickView *canvas = new QQuickView(QUrl::fromLocalFile(TESTDATA("positionAt.qml")));
+    QVERIFY(canvas->rootObject() != 0);
+    canvas->show();
+    canvas->requestActivateWindow();
+    QTest::qWaitForWindowShown(canvas);
+
+    QQuickTextInput *textInput = qobject_cast<QQuickTextInput *>(canvas->rootObject());
+    QVERIFY(textInput != 0);
+    textInput->setFocus(Qt::OtherFocusReason);
+    QRectF cursorRect = textInput->positionToRectangle(textInput->cursorPosition());
+    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());
+
+    delete canvas;
+}
+
+void tst_qquicktextinput::tripleClickSelectsAll()
+{
+    QString qmlfile = TESTDATA("positionAt.qml");
+    QQuickView view(QUrl::fromLocalFile(qmlfile));
+    view.show();
+    view.requestActivateWindow();
+    QTest::qWaitForWindowShown(&view);
+
+    QTRY_COMPARE(&view, qGuiApp->focusWindow());
+
+    QQuickTextInput* input = qobject_cast<QQuickTextInput*>(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());
+}
+
+void tst_qquicktextinput::QTBUG_19956_data()
+{
+    QTest::addColumn<QString>("url");
+    QTest::newRow("intvalidator") << "qtbug-19956int.qml";
+    QTest::newRow("doublevalidator") << "qtbug-19956double.qml";
+}
+
+void tst_qquicktextinput::QTBUG_19956()
+{
+    QFETCH(QString, url);
+
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA(url)));
+    canvas.show();
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&canvas);
+    QVERIFY(canvas.rootObject() != 0);
+    QQuickTextInput *input = qobject_cast<QQuickTextInput*>(canvas.rootObject());
+    QVERIFY(input);
+    input->setFocus(true);
+    QVERIFY(input->hasActiveFocus());
+
+    QCOMPARE(canvas.rootObject()->property("topvalue").toInt(), 30);
+    QCOMPARE(canvas.rootObject()->property("bottomvalue").toInt(), 10);
+    QCOMPARE(canvas.rootObject()->property("text").toString(), QString("20"));
+    QVERIFY(canvas.rootObject()->property("acceptableInput").toBool());
+
+    canvas.rootObject()->setProperty("topvalue", 15);
+    QCOMPARE(canvas.rootObject()->property("topvalue").toInt(), 15);
+    QVERIFY(!canvas.rootObject()->property("acceptableInput").toBool());
+
+    canvas.rootObject()->setProperty("topvalue", 25);
+    QCOMPARE(canvas.rootObject()->property("topvalue").toInt(), 25);
+    QVERIFY(canvas.rootObject()->property("acceptableInput").toBool());
+
+    canvas.rootObject()->setProperty("bottomvalue", 21);
+    QCOMPARE(canvas.rootObject()->property("bottomvalue").toInt(), 21);
+    QVERIFY(!canvas.rootObject()->property("acceptableInput").toBool());
+
+    canvas.rootObject()->setProperty("bottomvalue", 10);
+    QCOMPARE(canvas.rootObject()->property("bottomvalue").toInt(), 10);
+    QVERIFY(canvas.rootObject()->property("acceptableInput").toBool());
+}
+
+void tst_qquicktextinput::QTBUG_19956_regexp()
+{
+    QQuickView canvas(QUrl::fromLocalFile(TESTDATA("qtbug-19956regexp.qml")));
+    canvas.show();
+    canvas.requestActivateWindow();
+    QTest::qWaitForWindowShown(&canvas);
+    QVERIFY(canvas.rootObject() != 0);
+    QQuickTextInput *input = qobject_cast<QQuickTextInput*>(canvas.rootObject());
+    QVERIFY(input);
+    input->setFocus(true);
+    QVERIFY(input->hasActiveFocus());
+
+    canvas.rootObject()->setProperty("regexvalue", QRegExp("abc"));
+    QCOMPARE(canvas.rootObject()->property("regexvalue").toRegExp(), QRegExp("abc"));
+    QCOMPARE(canvas.rootObject()->property("text").toString(), QString("abc"));
+    QVERIFY(canvas.rootObject()->property("acceptableInput").toBool());
+
+    canvas.rootObject()->setProperty("regexvalue", QRegExp("abcd"));
+    QCOMPARE(canvas.rootObject()->property("regexvalue").toRegExp(), QRegExp("abcd"));
+    QVERIFY(!canvas.rootObject()->property("acceptableInput").toBool());
+
+    canvas.rootObject()->setProperty("regexvalue", QRegExp("abc"));
+    QCOMPARE(canvas.rootObject()->property("regexvalue").toRegExp(), QRegExp("abc"));
+    QVERIFY(canvas.rootObject()->property("acceptableInput").toBool());
+}
+
+QTEST_MAIN(tst_qquicktextinput)
+
+#include "tst_qquicktextinput.moc"
diff --git a/tests/auto/declarative/qquickview/qquickview.pro b/tests/auto/declarative/qquickview/qquickview.pro
new file mode 100644 (file)
index 0000000..c5cc3ce
--- /dev/null
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_qquickview
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qquickview.cpp
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+QT += core-private gui-private declarative-private testlib
diff --git a/tests/auto/declarative/qquickview/tst_qquickview.cpp b/tests/auto/declarative/qquickview/tst_qquickview.cpp
new file mode 100644 (file)
index 0000000..a2334d2
--- /dev/null
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** 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/QSignalSpy>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qquickview.h>
+#include <QtDeclarative/qquickitem.h>
+#include "../shared/util.h"
+#include <QtGui/QWindow>
+#include <QtCore/QDebug>
+
+class tst_QQuickView : public QObject
+{
+    Q_OBJECT
+public:
+    tst_QQuickView();
+
+private slots:
+    void resizemodeitem();
+    void errors();
+};
+
+
+tst_QQuickView::tst_QQuickView()
+{
+}
+
+void tst_QQuickView::resizemodeitem()
+{
+    QWindow window;
+    window.setGeometry(0, 0, 400, 400);
+
+    QQuickView *canvas = new QQuickView(&window);
+    QVERIFY(canvas);
+    canvas->setResizeMode(QQuickView::SizeRootObjectToView);
+    QCOMPARE(QSize(0,0), canvas->initialSize());
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizemodeitem.qml")));
+    QQuickItem* item = qobject_cast<QQuickItem*>(canvas->rootObject());
+    QVERIFY(item);
+    window.show();
+
+    canvas->show();
+
+    // initial size from root object
+    QCOMPARE(item->width(), 200.0);
+    QCOMPARE(item->height(), 200.0);
+    QCOMPARE(canvas->size(), QSize(200, 200));
+    QCOMPARE(canvas->size(), canvas->sizeHint());
+    QCOMPARE(canvas->size(), canvas->initialSize());
+
+    // size update from view
+    canvas->resize(QSize(80,100));
+    QTest::qWait(50);
+
+    QCOMPARE(item->width(), 80.0);
+    QCOMPARE(item->height(), 100.0);
+    QCOMPARE(canvas->size(), QSize(80, 100));
+    QCOMPARE(canvas->size(), canvas->sizeHint());
+
+    canvas->setResizeMode(QQuickView::SizeViewToRootObject);
+
+    // size update from view disabled
+    canvas->resize(QSize(60,80));
+    QCOMPARE(item->width(), 80.0);
+    QCOMPARE(item->height(), 100.0);
+    QTest::qWait(50);
+    QCOMPARE(canvas->size(), QSize(60, 80));
+
+    // size update from root object
+    item->setWidth(250);
+    item->setHeight(350);
+    QCOMPARE(item->width(), 250.0);
+    QCOMPARE(item->height(), 350.0);
+    QTRY_COMPARE(canvas->size(), QSize(250, 350));
+    QCOMPARE(canvas->size(), QSize(250, 350));
+    QCOMPARE(canvas->size(), canvas->sizeHint());
+
+    // reset canvas
+    window.hide();
+    delete canvas;
+    canvas = new QQuickView(&window);
+    QVERIFY(canvas);
+    canvas->setResizeMode(QQuickView::SizeViewToRootObject);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizemodeitem.qml")));
+    item = qobject_cast<QQuickItem*>(canvas->rootObject());
+    QVERIFY(item);
+    window.show();
+
+    canvas->show();
+
+    // initial size for root object
+    QCOMPARE(item->width(), 200.0);
+    QCOMPARE(item->height(), 200.0);
+    QCOMPARE(canvas->size(), canvas->sizeHint());
+    QCOMPARE(canvas->size(), canvas->initialSize());
+
+    // size update from root object
+    item->setWidth(80);
+    item->setHeight(100);
+    QCOMPARE(item->width(), 80.0);
+    QCOMPARE(item->height(), 100.0);
+    QTRY_COMPARE(canvas->size(), QSize(80, 100));
+    QCOMPARE(canvas->size(), QSize(80, 100));
+    QCOMPARE(canvas->size(), canvas->sizeHint());
+
+    // size update from root object disabled
+    canvas->setResizeMode(QQuickView::SizeRootObjectToView);
+    item->setWidth(60);
+    item->setHeight(80);
+    QCOMPARE(canvas->width(), 80);
+    QCOMPARE(canvas->height(), 100);
+    QCOMPARE(QSize(item->width(), item->height()), canvas->sizeHint());
+
+    // size update from view
+    canvas->resize(QSize(200,300));
+    QTest::qWait(50);
+    QCOMPARE(item->width(), 200.0);
+    QCOMPARE(item->height(), 300.0);
+    QCOMPARE(canvas->size(), QSize(200, 300));
+    QCOMPARE(canvas->size(), canvas->sizeHint());
+
+    window.hide();
+    delete canvas;
+
+    // if we set a specific size for the view then it should keep that size
+    // for SizeRootObjectToView mode.
+    canvas = new QQuickView(&window);
+    canvas->resize(300, 300);
+    canvas->setResizeMode(QQuickView::SizeRootObjectToView);
+    QCOMPARE(QSize(0,0), canvas->initialSize());
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizemodeitem.qml")));
+    canvas->resize(300, 300);
+    item = qobject_cast<QQuickItem*>(canvas->rootObject());
+    QVERIFY(item);
+    window.show();
+
+    canvas->show();
+    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));
+    QCOMPARE(canvas->size(), canvas->sizeHint());
+    QCOMPARE(canvas->initialSize(), QSize(200, 200)); // initial object size
+
+    delete canvas;
+}
+
+static void silentErrorsMsgHandler(QtMsgType, const char *)
+{
+}
+
+void tst_QQuickView::errors()
+{
+    QQuickView *canvas = new QQuickView;
+    QVERIFY(canvas);
+    QtMsgHandler old = qInstallMsgHandler(silentErrorsMsgHandler);
+    canvas->setSource(QUrl::fromLocalFile(TESTDATA("error1.qml")));
+    qInstallMsgHandler(old);
+    QVERIFY(canvas->status() == QQuickView::Error);
+    QVERIFY(canvas->errors().count() == 1);
+    delete canvas;
+}
+
+
+QTEST_MAIN(tst_QQuickView)
+
+#include "tst_qquickview.moc"
diff --git a/tests/auto/declarative/qquickvisualdatamodel/qquickvisualdatamodel.pro b/tests/auto/declarative/qquickvisualdatamodel/qquickvisualdatamodel.pro
new file mode 100644 (file)
index 0000000..35e627c
--- /dev/null
@@ -0,0 +1,13 @@
+CONFIG += testcase
+TARGET = tst_qquickvisualdatamodel
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qquickvisualdatamodel.cpp
+
+testDataFiles.files = data
+testDataFiles.path = .
+DEPLOYMENT += testDataFiles
+
+CONFIG += parallel_test
+
+QT += core-private gui-private v8-private declarative-private widgets testlib
diff --git a/tests/auto/declarative/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/declarative/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
new file mode 100644 (file)
index 0000000..aba760d
--- /dev/null
@@ -0,0 +1,1555 @@
+/****************************************************************************
+**
+** 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 "../shared/util.h"
+#include <qtest.h>
+#include <QtTest/QSignalSpy>
+#include <QStandardItemModel>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qdeclarativeexpression.h>
+#include <QtDeclarative/qquickview.h>
+#include <private/qquicklistview_p.h>
+#include <private/qquicktext_p.h>
+#include <private/qquickvisualdatamodel_p.h>
+#include <private/qdeclarativevaluetype_p.h>
+#include <private/qdeclarativechangeset_p.h>
+#include <private/qdeclarativeengine_p.h>
+#include <math.h>
+
+template <typename T, int N> int lengthOf(const T (&)[N]) { return N; }
+
+static void initStandardTreeModel(QStandardItemModel *model)
+{
+    QStandardItem *item;
+    item = new QStandardItem(QLatin1String("Row 1 Item"));
+    model->insertRow(0, item);
+
+    item = new QStandardItem(QLatin1String("Row 2 Item"));
+    item->setCheckable(true);
+    model->insertRow(1, item);
+
+    QStandardItem *childItem = new QStandardItem(QLatin1String("Row 2 Child Item"));
+    item->setChild(0, childItem);
+
+    item = new QStandardItem(QLatin1String("Row 3 Item"));
+    item->setIcon(QIcon());
+    model->insertRow(2, item);
+}
+
+class SingleRoleModel : public QAbstractListModel
+{
+    Q_OBJECT
+
+public:
+    SingleRoleModel(const QByteArray &role = "name", QObject *parent = 0) {
+        QHash<int, QByteArray> roles;
+        roles.insert(Qt::DisplayRole , role);
+        setRoleNames(roles);
+        list << "one" << "two" << "three" << "four";
+    }
+
+    void emitMove(int sourceFirst, int sourceLast, int destinationChild) {
+        emit beginMoveRows(QModelIndex(), sourceFirst, sourceLast, QModelIndex(), destinationChild);
+        emit endMoveRows();
+    }
+
+    QStringList list;
+
+public slots:
+    void set(int idx, QString string) {
+        list[idx] = string;
+        emit dataChanged(index(idx,0), index(idx,0));
+    }
+
+protected:
+    int rowCount(const QModelIndex &parent = QModelIndex()) const {
+        return list.count();
+    }
+    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const {
+        if (role == Qt::DisplayRole)
+            return list.at(index.row());
+        return QVariant();
+    }
+};
+
+
+class tst_qquickvisualdatamodel : public QObject
+{
+    Q_OBJECT
+public:
+    tst_qquickvisualdatamodel();
+
+private slots:
+    void initTestCase();
+    void cleanupTestCase();
+    void rootIndex();
+    void updateLayout();
+    void childChanged();
+    void objectListModel();
+    void singleRole();
+    void modelProperties();
+    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,
+            QQuickItem *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,
+            QQuickVisualDataModel *visualModel,
+            QQuickVisualDataGroup *visibleItems,
+            QQuickVisualDataGroup *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(QQuickItem *parent, const QString &objectName, int index);
+};
+
+Q_DECLARE_METATYPE(QDeclarativeChangeSet)
+
+void tst_qquickvisualdatamodel::initTestCase()
+{
+    qRegisterMetaType<QDeclarativeChangeSet>();
+}
+
+void tst_qquickvisualdatamodel::cleanupTestCase()
+{
+
+}
+class DataObject : public QObject
+{
+    Q_OBJECT
+
+    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+    Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
+
+public:
+    DataObject(QObject *parent=0) : QObject(parent) {}
+    DataObject(const QString &name, const QString &color, QObject *parent=0)
+        : QObject(parent), m_name(name), m_color(color) { }
+
+
+    QString name() const { return m_name; }
+    void setName(const QString &name) {
+        if (name != m_name) {
+            m_name = name;
+            emit nameChanged();
+        }
+    }
+
+    QString color() const { return m_color; }
+    void setColor(const QString &color) {
+        if (color != m_color) {
+            m_color = color;
+            emit colorChanged();
+        }
+    }
+
+signals:
+    void nameChanged();
+    void colorChanged();
+
+private:
+    QString m_name;
+    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_qquickvisualdatamodel::tst_qquickvisualdatamodel()
+{
+}
+
+void tst_qquickvisualdatamodel::rootIndex()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("visualdatamodel.qml")));
+
+    QStandardItemModel model;
+    initStandardTreeModel(&model);
+
+    engine.rootContext()->setContextProperty("myModel", &model);
+
+    QQuickVisualDataModel *obj = qobject_cast<QQuickVisualDataModel*>(c.create());
+    QVERIFY(obj != 0);
+
+    QMetaObject::invokeMethod(obj, "setRoot");
+    QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == model.index(0,0));
+
+    QMetaObject::invokeMethod(obj, "setRootToParent");
+    QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex());
+
+    QMetaObject::invokeMethod(obj, "setRoot");
+    QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == model.index(0,0));
+    model.clear(); // will emit modelReset()
+    QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex());
+
+    delete obj;
+}
+
+void tst_qquickvisualdatamodel::updateLayout()
+{
+    QQuickView view;
+
+    QStandardItemModel model;
+    initStandardTreeModel(&model);
+
+    view.rootContext()->setContextProperty("myModel", &model);
+
+    view.setSource(QUrl::fromLocalFile(TESTDATA("datalist.qml")));
+
+    QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
+    QVERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QVERIFY(contentItem != 0);
+
+    QQuickText *name = findItem<QQuickText>(contentItem, "display", 0);
+    QVERIFY(name);
+    QCOMPARE(name->text(), QString("Row 1 Item"));
+    name = findItem<QQuickText>(contentItem, "display", 1);
+    QVERIFY(name);
+    QCOMPARE(name->text(), QString("Row 2 Item"));
+    name = findItem<QQuickText>(contentItem, "display", 2);
+    QVERIFY(name);
+    QCOMPARE(name->text(), QString("Row 3 Item"));
+
+    model.invisibleRootItem()->sortChildren(0, Qt::DescendingOrder);
+
+    name = findItem<QQuickText>(contentItem, "display", 0);
+    QVERIFY(name);
+    QCOMPARE(name->text(), QString("Row 3 Item"));
+    name = findItem<QQuickText>(contentItem, "display", 1);
+    QVERIFY(name);
+    QCOMPARE(name->text(), QString("Row 2 Item"));
+    name = findItem<QQuickText>(contentItem, "display", 2);
+    QVERIFY(name);
+    QCOMPARE(name->text(), QString("Row 1 Item"));
+}
+
+void tst_qquickvisualdatamodel::childChanged()
+{
+    QQuickView view;
+
+    QStandardItemModel model;
+    initStandardTreeModel(&model);
+
+    view.rootContext()->setContextProperty("myModel", &model);
+
+    view.setSource(QUrl::fromLocalFile(TESTDATA("datalist.qml")));
+
+    QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
+    QVERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QVERIFY(contentItem != 0);
+
+    QQuickVisualDataModel *vdm = listview->findChild<QQuickVisualDataModel*>("visualModel");
+    vdm->setRootIndex(QVariant::fromValue(model.indexFromItem(model.item(1,0))));
+    QCOMPARE(listview->count(), 1);
+
+    QQuickText *name = findItem<QQuickText>(contentItem, "display", 0);
+    QVERIFY(name);
+    QCOMPARE(name->text(), QString("Row 2 Child Item"));
+
+    model.item(1,0)->child(0,0)->setText("Row 2 updated child");
+
+    name = findItem<QQuickText>(contentItem, "display", 0);
+    QVERIFY(name);
+    QCOMPARE(name->text(), QString("Row 2 updated child"));
+
+    model.item(1,0)->appendRow(new QStandardItem(QLatin1String("Row 2 Child Item 2")));
+    QCOMPARE(listview->count(), 2);
+
+    name = findItem<QQuickText>(contentItem, "display", 1);
+    QVERIFY(name != 0);
+    QCOMPARE(name->text(), QString("Row 2 Child Item 2"));
+
+    model.item(1,0)->takeRow(1);
+    name = findItem<QQuickText>(contentItem, "display", 1);
+    QVERIFY(name == 0);
+
+    vdm->setRootIndex(QVariant::fromValue(QModelIndex()));
+    QCOMPARE(listview->count(), 3);
+    name = findItem<QQuickText>(contentItem, "display", 0);
+    QVERIFY(name);
+    QCOMPARE(name->text(), QString("Row 1 Item"));
+    name = findItem<QQuickText>(contentItem, "display", 1);
+    QVERIFY(name);
+    QCOMPARE(name->text(), QString("Row 2 Item"));
+    name = findItem<QQuickText>(contentItem, "display", 2);
+    QVERIFY(name);
+    QCOMPARE(name->text(), QString("Row 3 Item"));
+}
+
+void tst_qquickvisualdatamodel::objectListModel()
+{
+    QQuickView view;
+
+    QList<QObject*> dataList;
+    dataList.append(new DataObject("Item 1", "red"));
+    dataList.append(new DataObject("Item 2", "green"));
+    dataList.append(new DataObject("Item 3", "blue"));
+    dataList.append(new DataObject("Item 4", "yellow"));
+
+    QDeclarativeContext *ctxt = view.rootContext();
+    ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
+
+    view.setSource(QUrl::fromLocalFile(TESTDATA("objectlist.qml")));
+
+    QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
+    QVERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QVERIFY(contentItem != 0);
+
+    QQuickText *name = findItem<QQuickText>(contentItem, "name", 0);
+    QCOMPARE(name->text(), QString("Item 1"));
+
+    QQuickText *section = findItem<QQuickText>(contentItem, "section", 0);
+    QCOMPARE(section->text(), QString("Item 1"));
+
+    dataList[0]->setProperty("name", QLatin1String("Changed"));
+    QCOMPARE(name->text(), QString("Changed"));
+}
+
+void tst_qquickvisualdatamodel::singleRole()
+{
+    {
+        QQuickView view;
+
+        SingleRoleModel model;
+
+        QDeclarativeContext *ctxt = view.rootContext();
+        ctxt->setContextProperty("myModel", &model);
+
+        view.setSource(QUrl::fromLocalFile(TESTDATA("singlerole1.qml")));
+
+        QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
+        QVERIFY(listview != 0);
+
+        QQuickItem *contentItem = listview->contentItem();
+        QVERIFY(contentItem != 0);
+
+        QQuickText *name = findItem<QQuickText>(contentItem, "name", 1);
+        QCOMPARE(name->text(), QString("two"));
+
+        model.set(1, "Changed");
+        QCOMPARE(name->text(), QString("Changed"));
+    }
+    {
+        QQuickView view;
+
+        SingleRoleModel model;
+
+        QDeclarativeContext *ctxt = view.rootContext();
+        ctxt->setContextProperty("myModel", &model);
+
+        view.setSource(QUrl::fromLocalFile(TESTDATA("singlerole2.qml")));
+
+        QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
+        QVERIFY(listview != 0);
+
+        QQuickItem *contentItem = listview->contentItem();
+        QVERIFY(contentItem != 0);
+
+        QQuickText *name = findItem<QQuickText>(contentItem, "name", 1);
+        QCOMPARE(name->text(), QString("two"));
+
+        model.set(1, "Changed");
+        QCOMPARE(name->text(), QString("Changed"));
+    }
+    {
+        QQuickView view;
+
+        SingleRoleModel model("modelData");
+
+        QDeclarativeContext *ctxt = view.rootContext();
+        ctxt->setContextProperty("myModel", &model);
+
+        view.setSource(QUrl::fromLocalFile(TESTDATA("singlerole2.qml")));
+
+        QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
+        QVERIFY(listview != 0);
+
+        QQuickItem *contentItem = listview->contentItem();
+        QVERIFY(contentItem != 0);
+
+        QQuickText *name = findItem<QQuickText>(contentItem, "name", 1);
+        QCOMPARE(name->text(), QString("two"));
+
+        model.set(1, "Changed");
+        QCOMPARE(name->text(), QString("Changed"));
+    }
+}
+
+void tst_qquickvisualdatamodel::modelProperties()
+{
+    {
+        QQuickView view;
+
+        SingleRoleModel model;
+
+        QDeclarativeContext *ctxt = view.rootContext();
+        ctxt->setContextProperty("myModel", &model);
+
+        view.setSource(QUrl::fromLocalFile(TESTDATA("modelproperties.qml")));
+
+        QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
+        QVERIFY(listview != 0);
+
+        QQuickItem *contentItem = listview->contentItem();
+        QVERIFY(contentItem != 0);
+
+        QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 1);
+        QVERIFY(delegate);
+        QCOMPARE(delegate->property("test1").toString(),QString("two"));
+        QCOMPARE(delegate->property("test2").toString(),QString("two"));
+        QCOMPARE(delegate->property("test3").toString(),QString("two"));
+        QCOMPARE(delegate->property("test4").toString(),QString("two"));
+        QVERIFY(!delegate->property("test9").isValid());
+        QCOMPARE(delegate->property("test5").toString(),QString(""));
+        QVERIFY(delegate->property("test6").value<QObject*>() != 0);
+        QCOMPARE(delegate->property("test7").toInt(),1);
+        QCOMPARE(delegate->property("test8").toInt(),1);
+    }
+
+    {
+        QQuickView view;
+
+        QList<QObject*> dataList;
+        dataList.append(new DataObject("Item 1", "red"));
+        dataList.append(new DataObject("Item 2", "green"));
+        dataList.append(new DataObject("Item 3", "blue"));
+        dataList.append(new DataObject("Item 4", "yellow"));
+
+        QDeclarativeContext *ctxt = view.rootContext();
+        ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
+
+        view.setSource(QUrl::fromLocalFile(TESTDATA("modelproperties.qml")));
+
+        QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
+        QVERIFY(listview != 0);
+
+        QQuickItem *contentItem = listview->contentItem();
+        QVERIFY(contentItem != 0);
+
+        QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 1);
+        QVERIFY(delegate);
+        QCOMPARE(delegate->property("test1").toString(),QString("Item 2"));
+        QCOMPARE(delegate->property("test2").toString(),QString("Item 2"));
+        QVERIFY(qobject_cast<DataObject*>(delegate->property("test3").value<QObject*>()) != 0);
+        QVERIFY(qobject_cast<DataObject*>(delegate->property("test4").value<QObject*>()) != 0);
+        QCOMPARE(delegate->property("test5").toString(),QString("Item 2"));
+        QCOMPARE(delegate->property("test9").toString(),QString("Item 2"));
+        QVERIFY(delegate->property("test6").value<QObject*>() != 0);
+        QCOMPARE(delegate->property("test7").toInt(),1);
+        QCOMPARE(delegate->property("test8").toInt(),1);
+    }
+
+    {
+        QQuickView view;
+
+        QStandardItemModel model;
+        initStandardTreeModel(&model);
+
+        view.rootContext()->setContextProperty("myModel", &model);
+
+        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");
+        QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData");
+        QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData");
+        QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData");
+        QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData");
+        QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData");
+        QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
+        QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
+        QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
+
+        view.setSource(source);
+
+        QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
+        QVERIFY(listview != 0);
+
+        QQuickItem *contentItem = listview->contentItem();
+        QVERIFY(contentItem != 0);
+
+        QQuickItem *delegate = findItem<QQuickItem>(contentItem, "delegate", 1);
+        QVERIFY(delegate);
+        QCOMPARE(delegate->property("test1").toString(),QString("Row 2 Item"));
+        QCOMPARE(delegate->property("test2").toString(),QString("Row 2 Item"));
+        QVERIFY(!delegate->property("test3").isValid());
+        QVERIFY(!delegate->property("test4").isValid());
+        QVERIFY(!delegate->property("test5").isValid());
+        QVERIFY(!delegate->property("test9").isValid());
+        QVERIFY(delegate->property("test6").value<QObject*>() != 0);
+        QCOMPARE(delegate->property("test7").toInt(),1);
+        QCOMPARE(delegate->property("test8").toInt(),1);
+    }
+
+    //### should also test QStringList and QVariantList
+}
+
+void tst_qquickvisualdatamodel::noDelegate()
+{
+    QQuickView view;
+
+    QStandardItemModel model;
+    initStandardTreeModel(&model);
+
+    view.rootContext()->setContextProperty("myModel", &model);
+
+    view.setSource(QUrl::fromLocalFile(TESTDATA("datalist.qml")));
+
+    QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
+    QVERIFY(listview != 0);
+
+    QQuickVisualDataModel *vdm = listview->findChild<QQuickVisualDataModel*>("visualModel");
+    QVERIFY(vdm != 0);
+    QCOMPARE(vdm->count(), 3);
+
+    vdm->setDelegate(0);
+    QCOMPARE(vdm->count(), 0);
+}
+
+
+void tst_qquickvisualdatamodel::qaimRowsMoved()
+{
+    // Test parameters passed in QAIM::rowsMoved() signal are converted correctly
+    // when translated and emitted as the QListModelInterface::itemsMoved() signal
+    QFETCH(int, sourceFirst);
+    QFETCH(int, sourceLast);
+    QFETCH(int, destinationChild);
+    QFETCH(int, expectFrom);
+    QFETCH(int, expectTo);
+    QFETCH(int, expectCount);
+
+    QDeclarativeEngine engine;
+    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("visualdatamodel.qml")));
+
+    SingleRoleModel model;
+    model.list.clear();
+    for (int i=0; i<30; i++)
+        model.list << ("item " + i);
+    engine.rootContext()->setContextProperty("myModel", &model);
+
+    QQuickVisualDataModel *obj = qobject_cast<QQuickVisualDataModel*>(c.create());
+    QVERIFY(obj != 0);
+
+    QSignalSpy spy(obj, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)));
+    model.emitMove(sourceFirst, sourceLast, destinationChild);
+    // QAbstractItemModel also emits the changed signal when items are moved.
+    QCOMPARE(spy.count(), 2);
+
+    bool move = false;
+    for (int i = 0; i < 2; ++i) {
+        QCOMPARE(spy[1].count(), 2);
+        QDeclarativeChangeSet changeSet = spy[i][0].value<QDeclarativeChangeSet>();
+        if (!changeSet.changes().isEmpty())
+            continue;
+        move = true;
+        QCOMPARE(changeSet.removes().count(), 1);
+        QCOMPARE(changeSet.removes().at(0).index, expectFrom);
+        QCOMPARE(changeSet.removes().at(0).count, expectCount);
+        QCOMPARE(changeSet.inserts().count(), 1);
+        QCOMPARE(changeSet.inserts().at(0).index, expectTo);
+        QCOMPARE(changeSet.inserts().at(0).count, expectCount);
+        QCOMPARE(changeSet.removes().at(0).moveId, changeSet.inserts().at(0).moveId);
+        QCOMPARE(spy[i][1].toBool(), false);
+    }
+    QVERIFY(move);
+
+    delete obj;
+}
+
+void tst_qquickvisualdatamodel::qaimRowsMoved_data()
+{
+    QTest::addColumn<int>("sourceFirst");
+    QTest::addColumn<int>("sourceLast");
+    QTest::addColumn<int>("destinationChild");
+    QTest::addColumn<int>("expectFrom");
+    QTest::addColumn<int>("expectTo");
+    QTest::addColumn<int>("expectCount");
+
+    QTest::newRow("move 1 forward")
+        << 1 << 1 << 6
+        << 1 << 5 << 1;
+
+    QTest::newRow("move 1 backwards")
+        << 4 << 4 << 1
+        << 4 << 1 << 1;
+
+    QTest::newRow("move multiple forwards")
+        << 0 << 2 << 13
+        << 0 << 10 << 3;
+
+    QTest::newRow("move multiple forwards, with same to")
+        << 0 << 1 << 3
+        << 0 << 1 << 2;
+
+    QTest::newRow("move multiple backwards")
+        << 10 << 14 << 1
+        << 10 << 1 << 5;
+}
+
+void tst_qquickvisualdatamodel::remove()
+{
+    QQuickView 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")));
+
+    QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
+    QVERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QVERIFY(contentItem != 0);
+
+    QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(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) {
+            QQuickItem *delegate = findItem<QQuickItem>(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) {
+            QQuickItem *delegate = findItem<QQuickItem>(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) {
+            QQuickItem *delegate = findItem<QQuickItem>(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_qquickvisualdatamodel::move()
+{
+    QQuickView 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")));
+
+    QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
+    QVERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QVERIFY(contentItem != 0);
+
+    QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(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) {
+            QQuickItem *delegate = findItem<QQuickItem>(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) {
+            QQuickItem *delegate = findItem<QQuickItem>(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) {
+            QQuickItem *delegate = findItem<QQuickItem>(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) {
+            QQuickItem *delegate = findItem<QQuickItem>(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) {
+            QQuickItem *delegate = findItem<QQuickItem>(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_qquickvisualdatamodel::groups_verify(
+        const SingleRoleModel &model,
+        QQuickItem *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) {
+        QQuickItem *delegate = findItem<QQuickItem>(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_qquickvisualdatamodel::groups()
+{
+    QQuickView 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")));
+
+    QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
+    QVERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QVERIFY(contentItem != 0);
+
+    QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
+    QVERIFY(visualModel);
+
+    QQuickVisualDataGroup *visibleItems = visualModel->findChild<QQuickVisualDataGroup *>("visibleItems");
+    QVERIFY(visibleItems);
+
+    QQuickVisualDataGroup *selectedItems = visualModel->findChild<QQuickVisualDataGroup *>("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);
+    } {
+        QQuickItem *delegate = findItem<QQuickItem>(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;
+    } {
+        QQuickItem *delegate = findItem<QQuickItem>(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_qquickvisualdatamodel::get_verify(
+        const SingleRoleModel &model,
+        QQuickVisualDataModel *visualModel,
+        QQuickVisualDataGroup *visibleItems,
+        QQuickVisualDataGroup *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_qquickvisualdatamodel::get()
+{
+    QQuickView 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")));
+
+    QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
+    QVERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QVERIFY(contentItem != 0);
+
+    QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
+    QVERIFY(visualModel);
+
+    QQuickVisualDataGroup *visibleItems = visualModel->findChild<QQuickVisualDataGroup *>("visibleItems");
+    QVERIFY(visibleItems);
+
+    QQuickVisualDataGroup *selectedItems = visualModel->findChild<QQuickVisualDataGroup *>("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_qquickvisualdatamodel::create()
+{
+    QQuickView 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")));
+
+    QQuickListView *listview = qobject_cast<QQuickListView*>(view.rootObject());
+    QVERIFY(listview != 0);
+
+    QQuickItem *contentItem = listview->contentItem();
+    QVERIFY(contentItem != 0);
+
+    QQuickVisualDataModel *visualModel = qobject_cast<QQuickVisualDataModel *>(qvariant_cast<QObject *>(listview->model()));
+    QVERIFY(visualModel);
+
+    QCOMPARE(listview->count(), 20);
+
+    QQuickItem *delegate;
+
+    // Request an item instantiated by the view.
+    QVERIFY(findItem<QQuickItem>(contentItem, "delegate", 1));
+    QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(1)")));
+    QCOMPARE(delegate, findItem<QQuickItem>(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<QQuickItem>(contentItem, "delegate", 15));
+    QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(15)")));
+    QCOMPARE(delegate, findItem<QQuickItem>(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<QQuickItem>(contentItem, "delegate", 16));
+    QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(16)")));
+    QCOMPARE(delegate, findItem<QQuickItem>(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<QQuickItem>(contentItem, "delegate", 17));
+    QVERIFY(delegate = qobject_cast<QQuickItem *>(evaluate<QObject *>(visualModel, "items.create(17)")));
+    QCOMPARE(delegate, findItem<QQuickItem>(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<QQuickItem>(contentItem, "delegate", 18));
+    evaluate<void>(listview, "positionViewAtIndex(19, ListView.End)");
+    QCOMPARE(listview->count(), 20);
+    QVERIFY(delegate = findItem<QQuickItem>(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_qquickvisualdatamodel::findItem(QQuickItem *parent, const QString &objectName, int index)
+{
+    const QMetaObject &mo = T::staticMetaObject;
+    //qDebug() << parent->childItems().count() << "children";
+    for (int i = 0; i < parent->childItems().count(); ++i) {
+        QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
+        if (!item)
+            continue;
+        //qDebug() << "try" << item;
+        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
+            if (index != -1) {
+                QDeclarativeExpression e(qmlContext(item), item, "index");
+                if (e.evaluate().toInt() == index)
+                    return static_cast<T*>(item);
+            } else {
+                return static_cast<T*>(item);
+            }
+        }
+        item = findItem<T>(item, objectName, index);
+        if (item)
+        return static_cast<T*>(item);
+    }
+
+    return 0;
+}
+
+QTEST_MAIN(tst_qquickvisualdatamodel)
+
+#include "tst_qquickvisualdatamodel.moc"
diff --git a/tests/auto/declarative/qsganimatedimage/qsganimatedimage.pro b/tests/auto/declarative/qsganimatedimage/qsganimatedimage.pro
deleted file mode 100644 (file)
index eaf83cc..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsganimatedimage
-HEADERS += ../shared/testhttpserver.h
-SOURCES += tst_qsganimatedimage.cpp ../shared/testhttpserver.cpp
-macx:CONFIG -= app_bundle
-
-testDataFiles.files = data
-testDataFiles.path = .
-DEPLOYMENT += testDataFiles
-
-CONFIG += parallel_test
-
-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
deleted file mode 100644 (file)
index aa39c52..0000000
+++ /dev/null
@@ -1,375 +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/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtDeclarative/qsgview.h>
-#include <private/qsgrectangle_p.h>
-#include <private/qsgimage_p.h>
-#include <private/qsganimatedimage_p.h>
-#include <QSignalSpy>
-#include <QtDeclarative/qdeclarativecontext.h>
-
-#include "../shared/testhttpserver.h"
-#include "../shared/util.h"
-
-class tst_qsganimatedimage : public QObject
-{
-    Q_OBJECT
-public:
-    tst_qsganimatedimage() {}
-
-private slots:
-    void play();
-    void pause();
-    void stopped();
-    void setFrame();
-    void frameCount();
-    void mirror_running();
-    void mirror_notRunning();
-    void mirror_notRunning_data();
-    void remote();
-    void remote_data();
-    void sourceSize();
-    void sourceSizeReadOnly();
-    void invalidSource();
-    void qtbug_16520();
-    void progressAndStatusChanges();
-
-};
-
-void tst_qsganimatedimage::play()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickman.qml")));
-    QSGAnimatedImage *anim = qobject_cast<QSGAnimatedImage *>(component.create());
-    QVERIFY(anim);
-    QVERIFY(anim->isPlaying());
-
-    delete anim;
-}
-
-void tst_qsganimatedimage::pause()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanpause.qml")));
-    QSGAnimatedImage *anim = qobject_cast<QSGAnimatedImage *>(component.create());
-    QVERIFY(anim);
-    QVERIFY(anim->isPlaying());
-    QVERIFY(anim->isPaused());
-
-    delete anim;
-}
-
-void tst_qsganimatedimage::stopped()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanstopped.qml")));
-    QSGAnimatedImage *anim = qobject_cast<QSGAnimatedImage *>(component.create());
-    QVERIFY(anim);
-    QVERIFY(!anim->isPlaying());
-    QCOMPARE(anim->currentFrame(), 0);
-
-    delete anim;
-}
-
-void tst_qsganimatedimage::setFrame()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanpause.qml")));
-    QSGAnimatedImage *anim = qobject_cast<QSGAnimatedImage *>(component.create());
-    QVERIFY(anim);
-    QVERIFY(anim->isPlaying());
-    QCOMPARE(anim->currentFrame(), 2);
-
-    delete anim;
-}
-
-void tst_qsganimatedimage::frameCount()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("colors.qml")));
-    QSGAnimatedImage *anim = qobject_cast<QSGAnimatedImage *>(component.create());
-    QVERIFY(anim);
-    QVERIFY(anim->isPlaying());
-    QCOMPARE(anim->frameCount(), 3);
-
-    delete anim;
-}
-
-void tst_qsganimatedimage::mirror_running()
-{
-    // test where mirror is set to true after animation has started
-
-    QSGView *canvas = new QSGView;
-    canvas->show();
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("hearts.qml")));
-    QSGAnimatedImage *anim = qobject_cast<QSGAnimatedImage *>(canvas->rootObject());
-    QVERIFY(anim);
-
-    int width = anim->property("width").toInt();
-
-    QCOMPARE(anim->currentFrame(), 0);
-    QPixmap frame0 = QPixmap::fromImage(canvas->grabFrameBuffer());
-
-    anim->setCurrentFrame(1);
-    QPixmap frame1 = QPixmap::fromImage(canvas->grabFrameBuffer());
-
-    anim->setCurrentFrame(0);
-
-    QSignalSpy spy(anim, SIGNAL(frameChanged()));
-    anim->setPlaying(true);
-
-    QTRY_VERIFY(spy.count() == 1); spy.clear();
-    anim->setProperty("mirror", true);
-
-    QCOMPARE(anim->currentFrame(), 1);
-    QPixmap frame1_flipped = QPixmap::fromImage(canvas->grabFrameBuffer());
-
-    QTRY_VERIFY(spy.count() == 1); spy.clear();
-    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");
-
-    QTransform transform;
-    transform.translate(width, 0).scale(-1, 1.0);
-    QPixmap frame0_expected = frame0.transformed(transform);
-    QPixmap frame1_expected = frame1.transformed(transform);
-
-    QCOMPARE(frame0_flipped, frame0_expected);
-    QCOMPARE(frame1_flipped, frame1_expected);
-
-    delete canvas;
-}
-
-void tst_qsganimatedimage::mirror_notRunning()
-{
-    QFETCH(QUrl, fileUrl);
-
-    QSGView *canvas = new QSGView;
-    canvas->show();
-
-    canvas->setSource(fileUrl);
-    QSGAnimatedImage *anim = qobject_cast<QSGAnimatedImage *>(canvas->rootObject());
-    QVERIFY(anim);
-
-    int width = anim->property("width").toInt();
-    QPixmap screenshot = QPixmap::fromImage(canvas->grabFrameBuffer());
-
-    QTransform transform;
-    transform.translate(width, 0).scale(-1, 1.0);
-    QPixmap expected = screenshot.transformed(transform);
-
-    int frame = anim->currentFrame();
-    bool playing = anim->isPlaying();
-    bool paused = anim->isPlaying();
-
-    anim->setProperty("mirror", true);
-    screenshot = QPixmap::fromImage(canvas->grabFrameBuffer());
-
-    QSKIP("Skip while QTBUG-19351 and QTBUG-19252 are not resolved");
-    QCOMPARE(screenshot, expected);
-
-    // mirroring should not change the current frame or playing status
-    QCOMPARE(anim->currentFrame(), frame);
-    QCOMPARE(anim->isPlaying(), playing);
-    QCOMPARE(anim->isPaused(), paused);
-
-    delete canvas;
-}
-
-void tst_qsganimatedimage::mirror_notRunning_data()
-{
-    QTest::addColumn<QUrl>("fileUrl");
-
-    QTest::newRow("paused") << QUrl::fromLocalFile(TESTDATA("stickmanpause.qml"));
-    QTest::newRow("stopped") << QUrl::fromLocalFile(TESTDATA("stickmanstopped.qml"));
-}
-
-void tst_qsganimatedimage::remote()
-{
-    QFETCH(QString, fileName);
-    QFETCH(bool, paused);
-
-    TestHTTPServer server(14449);
-    QVERIFY(server.isValid());
-    server.serveDirectory(TESTDATA(""));
-
-    QDeclarativeEngine engine;
-    QDeclarativeComponent component(&engine, QUrl("http://127.0.0.1:14449/" + fileName));
-    QTRY_VERIFY(component.isReady());
-
-    QSGAnimatedImage *anim = qobject_cast<QSGAnimatedImage *>(component.create());
-    QVERIFY(anim);
-
-    QTRY_VERIFY(anim->isPlaying());
-    if (paused) {
-        QTRY_VERIFY(anim->isPaused());
-        QCOMPARE(anim->currentFrame(), 2);
-    }
-    QVERIFY(anim->status() != QSGAnimatedImage::Error);
-
-    delete anim;
-}
-
-void tst_qsganimatedimage::sourceSize()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanscaled.qml")));
-    QSGAnimatedImage *anim = qobject_cast<QSGAnimatedImage *>(component.create());
-    QVERIFY(anim);
-    QCOMPARE(anim->width(),240.0);
-    QCOMPARE(anim->height(),180.0);
-    QCOMPARE(anim->sourceSize(),QSize(160,120));
-
-    delete anim;
-}
-
-void tst_qsganimatedimage::sourceSizeReadOnly()
-{
-    QDeclarativeEngine engine;
-    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"));
-}
-
-void tst_qsganimatedimage::remote_data()
-{
-    QTest::addColumn<QString>("fileName");
-    QTest::addColumn<bool>("paused");
-
-    QTest::newRow("playing") << "stickman.qml" << false;
-    QTest::newRow("paused") << "stickmanpause.qml" << true;
-}
-
-void tst_qsganimatedimage::invalidSource()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent component(&engine);
-    component.setData("import QtQuick 2.0\n AnimatedImage { source: \"no-such-file.gif\" }", QUrl::fromLocalFile(""));
-    QVERIFY(component.isReady());
-
-    QTest::ignoreMessage(QtWarningMsg, "file::2:2: QML AnimatedImage: Error Reading Animated Image File file:no-such-file.gif");
-
-    QSGAnimatedImage *anim = qobject_cast<QSGAnimatedImage *>(component.create());
-    QVERIFY(anim);
-
-    QVERIFY(!anim->isPlaying());
-    QVERIFY(!anim->isPaused());
-    QCOMPARE(anim->currentFrame(), 0);
-    QCOMPARE(anim->frameCount(), 0);
-    QTRY_VERIFY(anim->status() == 3);
-}
-
-void tst_qsganimatedimage::qtbug_16520()
-{
-    TestHTTPServer server(14449);
-    QVERIFY(server.isValid());
-    server.serveDirectory(TESTDATA(""));
-
-    QDeclarativeEngine engine;
-    QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("qtbug-16520.qml")));
-    QTRY_VERIFY(component.isReady());
-
-    QSGRectangle *root = qobject_cast<QSGRectangle *>(component.create());
-    QVERIFY(root);
-    QSGAnimatedImage *anim = root->findChild<QSGAnimatedImage*>("anim");
-
-    anim->setProperty("source", "http://127.0.0.1:14449/stickman.gif");
-
-    QTRY_VERIFY(anim->opacity() == 0);
-    QTRY_VERIFY(anim->opacity() == 1);
-
-    delete anim;
-}
-
-void tst_qsganimatedimage::progressAndStatusChanges()
-{
-    TestHTTPServer server(14449);
-    QVERIFY(server.isValid());
-    server.serveDirectory(TESTDATA(""));
-
-    QDeclarativeEngine engine;
-    QString componentStr = "import QtQuick 2.0\nAnimatedImage { source: srcImage }";
-    QDeclarativeContext *ctxt = engine.rootContext();
-    ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("stickman.gif")));
-    QDeclarativeComponent component(&engine);
-    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGImage *obj = qobject_cast<QSGImage*>(component.create());
-    QVERIFY(obj != 0);
-    QVERIFY(obj->status() == QSGImage::Ready);
-    QTRY_VERIFY(obj->progress() == 1.0);
-
-    QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(const QUrl &)));
-    QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal)));
-    QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QSGImageBase::Status)));
-
-    // Loading local file
-    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);
-    QTRY_COMPARE(progressSpy.count(), 0);
-    QTRY_COMPARE(statusSpy.count(), 0);
-
-    // Loading remote file
-    ctxt->setContextProperty("srcImage", "http://127.0.0.1:14449/stickman.gif");
-    QTRY_VERIFY(obj->status() == QSGImage::Loading);
-    QTRY_VERIFY(obj->progress() == 0.0);
-    QTRY_VERIFY(obj->status() == QSGImage::Ready);
-    QTRY_VERIFY(obj->progress() == 1.0);
-    QTRY_COMPARE(sourceSpy.count(), 2);
-    QTRY_VERIFY(progressSpy.count() > 1);
-    QTRY_COMPARE(statusSpy.count(), 2);
-
-    ctxt->setContextProperty("srcImage", "");
-    QTRY_VERIFY(obj->status() == QSGImage::Null);
-    QTRY_VERIFY(obj->progress() == 0.0);
-    QTRY_COMPARE(sourceSpy.count(), 3);
-    QTRY_VERIFY(progressSpy.count() > 2);
-    QTRY_COMPARE(statusSpy.count(), 3);
-}
-
-QTEST_MAIN(tst_qsganimatedimage)
-
-#include "tst_qsganimatedimage.moc"
diff --git a/tests/auto/declarative/qsgborderimage/qsgborderimage.pro b/tests/auto/declarative/qsgborderimage/qsgborderimage.pro
deleted file mode 100644 (file)
index 65200a9..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsgborderimage
-macx:CONFIG -= app_bundle
-
-HEADERS += ../shared/testhttpserver.h
-SOURCES += tst_qsgborderimage.cpp ../shared/testhttpserver.cpp
-
-testDataFiles.files = data
-testDataFiles.path = .
-DEPLOYMENT += testDataFiles
-
-CONFIG += parallel_test
-
-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
deleted file mode 100644 (file)
index 0835a66..0000000
+++ /dev/null
@@ -1,376 +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 <QTextDocument>
-#include <QTcpServer>
-#include <QTcpSocket>
-#include <QDir>
-#include <QGraphicsScene>
-#include <QPainter>
-
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativecomponent.h>
-#include <private/qsgborderimage_p.h>
-#include <private/qsgimagebase_p.h>
-#include <private/qsgscalegrid_p_p.h>
-#include <private/qsgloader_p.h>
-#include <QtDeclarative/qsgview.h>
-#include <QtDeclarative/qdeclarativecontext.h>
-
-#include "../shared/testhttpserver.h"
-#include "../shared/util.h"
-
-#define SERVER_PORT 14446
-#define SERVER_ADDR "http://127.0.0.1:14446"
-
-class tst_qsgborderimage : public QObject
-
-{
-    Q_OBJECT
-public:
-    tst_qsgborderimage();
-
-private slots:
-    void noSource();
-    void imageSource();
-    void imageSource_data();
-    void clearSource();
-    void resized();
-    void smooth();
-    void mirror();
-    void tileModes();
-    void sciSource();
-    void sciSource_data();
-    void invalidSciFile();
-    void pendingRemoteRequest();
-    void pendingRemoteRequest_data();
-
-private:
-    QDeclarativeEngine engine;
-};
-
-tst_qsgborderimage::tst_qsgborderimage()
-{
-}
-
-void tst_qsgborderimage::noSource()
-{
-    QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"\" }";
-    QDeclarativeComponent component(&engine);
-    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGBorderImage *obj = qobject_cast<QSGBorderImage*>(component.create());
-    QVERIFY(obj != 0);
-    QCOMPARE(obj->source(), QUrl());
-    QCOMPARE(obj->width(), 0.);
-    QCOMPARE(obj->height(), 0.);
-    QCOMPARE(obj->horizontalTileMode(), QSGBorderImage::Stretch);
-    QCOMPARE(obj->verticalTileMode(), QSGBorderImage::Stretch);
-
-    delete obj;
-}
-
-void tst_qsgborderimage::imageSource_data()
-{
-    QTest::addColumn<QString>("source");
-    QTest::addColumn<bool>("remote");
-    QTest::addColumn<QString>("error");
-
-    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";
-}
-
-void tst_qsgborderimage::imageSource()
-{
-    QFETCH(QString, source);
-    QFETCH(bool, remote);
-    QFETCH(QString, error);
-
-    TestHTTPServer *server = 0;
-    if (remote) {
-        server = new TestHTTPServer(SERVER_PORT);
-        QVERIFY(server->isValid());
-        server->serveDirectory(TESTDATA(""));
-    }
-
-    if (!error.isEmpty())
-        QTest::ignoreMessage(QtWarningMsg, error.toUtf8());
-
-    QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + source + "\" }";
-    QDeclarativeComponent component(&engine);
-    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGBorderImage *obj = qobject_cast<QSGBorderImage*>(component.create());
-    QVERIFY(obj != 0);
-
-    if (remote)
-        QTRY_VERIFY(obj->status() == QSGBorderImage::Loading);
-
-    QCOMPARE(obj->source(), remote ? source : QUrl(source));
-
-    if (error.isEmpty()) {
-        QTRY_VERIFY(obj->status() == QSGBorderImage::Ready);
-        QCOMPARE(obj->width(), 120.);
-        QCOMPARE(obj->height(), 120.);
-        QCOMPARE(obj->sourceSize().width(), 120);
-        QCOMPARE(obj->sourceSize().height(), 120);
-        QCOMPARE(obj->horizontalTileMode(), QSGBorderImage::Stretch);
-        QCOMPARE(obj->verticalTileMode(), QSGBorderImage::Stretch);
-    } else {
-        QTRY_VERIFY(obj->status() == QSGBorderImage::Error);
-    }
-
-    delete obj;
-    delete server;
-}
-
-void tst_qsgborderimage::clearSource()
-{
-    QString componentStr = "import QtQuick 2.0\nBorderImage { source: srcImage }";
-    QDeclarativeContext *ctxt = engine.rootContext();
-    ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("colors.png")));
-    QDeclarativeComponent component(&engine);
-    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGBorderImage *obj = qobject_cast<QSGBorderImage*>(component.create());
-    QVERIFY(obj != 0);
-    QVERIFY(obj->status() == QSGBorderImage::Ready);
-    QCOMPARE(obj->width(), 120.);
-    QCOMPARE(obj->height(), 120.);
-
-    ctxt->setContextProperty("srcImage", "");
-    QVERIFY(obj->source().isEmpty());
-    QVERIFY(obj->status() == QSGBorderImage::Null);
-    QCOMPARE(obj->width(), 0.);
-    QCOMPARE(obj->height(), 0.);
-}
-
-void tst_qsgborderimage::resized()
-{
-    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());
-    QVERIFY(obj != 0);
-    QCOMPARE(obj->width(), 300.);
-    QCOMPARE(obj->height(), 300.);
-    QCOMPARE(obj->sourceSize().width(), 120);
-    QCOMPARE(obj->sourceSize().height(), 120);
-    QCOMPARE(obj->horizontalTileMode(), QSGBorderImage::Stretch);
-    QCOMPARE(obj->verticalTileMode(), QSGBorderImage::Stretch);
-
-    delete obj;
-}
-
-void tst_qsgborderimage::smooth()
-{
-    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());
-    QVERIFY(obj != 0);
-    QCOMPARE(obj->width(), 300.);
-    QCOMPARE(obj->height(), 300.);
-    QCOMPARE(obj->smooth(), true);
-    QCOMPARE(obj->horizontalTileMode(), QSGBorderImage::Stretch);
-    QCOMPARE(obj->verticalTileMode(), QSGBorderImage::Stretch);
-
-    delete obj;
-}
-
-void tst_qsgborderimage::mirror()
-{
-    QSGView *canvas = new QSGView;
-    canvas->show();
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("mirror.qml")));
-    QSGBorderImage *image = qobject_cast<QSGBorderImage*>(canvas->rootObject());
-    QVERIFY(image != 0);
-    canvas->show();
-
-    QImage screenshot = canvas->grabFrameBuffer();
-
-    QImage srcPixmap(screenshot);
-    QTransform transform;
-    transform.translate(image->width(), 0).scale(-1, 1.0);
-    srcPixmap = srcPixmap.transformed(transform);
-
-    image->setProperty("mirror", true);
-    screenshot = canvas->grabFrameBuffer();
-    QCOMPARE(screenshot, srcPixmap);
-
-    delete canvas;
-}
-
-void tst_qsgborderimage::tileModes()
-{
-    {
-        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());
-        QVERIFY(obj != 0);
-        QCOMPARE(obj->width(), 100.);
-        QCOMPARE(obj->height(), 300.);
-        QCOMPARE(obj->horizontalTileMode(), QSGBorderImage::Repeat);
-        QCOMPARE(obj->verticalTileMode(), QSGBorderImage::Repeat);
-
-        delete obj;
-    }
-    {
-        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());
-        QVERIFY(obj != 0);
-        QCOMPARE(obj->width(), 300.);
-        QCOMPARE(obj->height(), 150.);
-        QCOMPARE(obj->horizontalTileMode(), QSGBorderImage::Round);
-        QCOMPARE(obj->verticalTileMode(), QSGBorderImage::Round);
-
-        delete obj;
-    }
-}
-
-void tst_qsgborderimage::sciSource()
-{
-    QFETCH(QString, source);
-    QFETCH(bool, valid);
-
-    bool remote = source.startsWith("http");
-    TestHTTPServer *server = 0;
-    if (remote) {
-        server = new TestHTTPServer(SERVER_PORT);
-        QVERIFY(server->isValid());
-        server->serveDirectory(TESTDATA(""));
-    }
-
-    QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + source + "\"; width: 300; height: 300 }";
-    QDeclarativeComponent component(&engine);
-    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGBorderImage *obj = qobject_cast<QSGBorderImage*>(component.create());
-    QVERIFY(obj != 0);
-
-    if (remote)
-        QTRY_VERIFY(obj->status() == QSGBorderImage::Loading);
-
-    QCOMPARE(obj->source(), remote ? source : QUrl(source));
-    QCOMPARE(obj->width(), 300.);
-    QCOMPARE(obj->height(), 300.);
-
-    if (valid) {
-        QTRY_VERIFY(obj->status() == QSGBorderImage::Ready);
-        QCOMPARE(obj->border()->left(), 10);
-        QCOMPARE(obj->border()->top(), 20);
-        QCOMPARE(obj->border()->right(), 30);
-        QCOMPARE(obj->border()->bottom(), 40);
-        QCOMPARE(obj->horizontalTileMode(), QSGBorderImage::Round);
-        QCOMPARE(obj->verticalTileMode(), QSGBorderImage::Repeat);
-    } else {
-        QTRY_VERIFY(obj->status() == QSGBorderImage::Error);
-    }
-
-    delete obj;
-    delete server;
-}
-
-void tst_qsgborderimage::sciSource_data()
-{
-    QTest::addColumn<QString>("source");
-    QTest::addColumn<bool>("valid");
-
-    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;
-    QTest::newRow("remote not found") << SERVER_ADDR "/no-such-file.sci" << false;
-}
-
-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(TESTDATA("invalid.sci")).toString() +"\"; width: 300; height: 300 }";
-    QDeclarativeComponent component(&engine);
-    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGBorderImage *obj = qobject_cast<QSGBorderImage*>(component.create());
-    QVERIFY(obj != 0);
-    QCOMPARE(obj->width(), 300.);
-    QCOMPARE(obj->height(), 300.);
-    QCOMPARE(obj->status(), QSGImageBase::Error);
-    QCOMPARE(obj->horizontalTileMode(), QSGBorderImage::Stretch);
-    QCOMPARE(obj->verticalTileMode(), QSGBorderImage::Stretch);
-
-    delete obj;
-}
-
-void tst_qsgborderimage::pendingRemoteRequest()
-{
-    QFETCH(QString, source);
-
-    QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + source + "\" }";
-    QDeclarativeComponent component(&engine);
-    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGBorderImage *obj = qobject_cast<QSGBorderImage*>(component.create());
-    QVERIFY(obj != 0);
-    QCOMPARE(obj->status(), QSGBorderImage::Loading);
-
-    // verify no crash
-    // This will cause a delayed "QThread: Destroyed while thread is still running" warning
-    delete obj;
-    QTest::qWait(50);
-}
-
-void tst_qsgborderimage::pendingRemoteRequest_data()
-{
-    QTest::addColumn<QString>("source");
-
-    QTest::newRow("png file") << "http://localhost/none.png";
-    QTest::newRow("sci file") << "http://localhost/none.sci";
-}
-
-QTEST_MAIN(tst_qsgborderimage)
-
-#include "tst_qsgborderimage.moc"
diff --git a/tests/auto/declarative/qsgcanvas/qsgcanvas.pro b/tests/auto/declarative/qsgcanvas/qsgcanvas.pro
deleted file mode 100644 (file)
index d874911..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsgcanvas
-SOURCES += tst_qsgcanvas.cpp
-
-macx:CONFIG -= app_bundle
-
-CONFIG += parallel_test
-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
deleted file mode 100644 (file)
index d8135ed..0000000
+++ /dev/null
@@ -1,521 +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 <QDebug>
-#include <QTouchEvent>
-#include <QtDeclarative/QSGItem>
-#include <QtDeclarative/QSGCanvas>
-#include <QtDeclarative/private/qsgrectangle_p.h>
-#include <QtGui/QWindowSystemInterface>
-
-struct TouchEventData {
-    QEvent::Type type;
-    QWidget *widget;
-    QWindow *window;
-    Qt::TouchPointStates states;
-    QList<QTouchEvent::TouchPoint> touchPoints;
-};
-
-static QTouchEvent::TouchPoint makeTouchPoint(QSGItem *item, const QPointF &p, const QPointF &lastPoint = QPointF())
-{
-    QPointF last = lastPoint.isNull() ? p : lastPoint;
-
-    QTouchEvent::TouchPoint tp;
-
-    tp.setPos(p);
-    tp.setLastPos(last);
-    tp.setScenePos(item->mapToScene(p));
-    tp.setLastScenePos(item->mapToScene(last));
-    tp.setScreenPos(item->canvas()->mapToGlobal(tp.scenePos().toPoint()));
-    tp.setLastScreenPos(item->canvas()->mapToGlobal(tp.lastScenePos().toPoint()));
-    return tp;
-}
-
-static TouchEventData makeTouchData(QEvent::Type type, QWidget *w, Qt::TouchPointStates states, const QList<QTouchEvent::TouchPoint> &touchPoints)
-{
-    TouchEventData d = { type, w, 0, states, touchPoints };
-    return d;
-}
-
-static TouchEventData makeTouchData(QEvent::Type type, QWidget *w, Qt::TouchPointStates states, const QTouchEvent::TouchPoint &touchPoint)
-{
-    QList<QTouchEvent::TouchPoint> points;
-    points << touchPoint;
-    return makeTouchData(type, w, states, points);
-}
-static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, Qt::TouchPointStates states, const QList<QTouchEvent::TouchPoint>& touchPoints)
-{
-    TouchEventData d = { type, 0, w, states, touchPoints };
-    return d;
-}
-static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, Qt::TouchPointStates states, const QTouchEvent::TouchPoint &touchPoint)
-{
-    QList<QTouchEvent::TouchPoint> points;
-    points << touchPoint;
-    return makeTouchData(type, w, states, points);
-}
-
-#define COMPARE_TOUCH_POINTS(tp1, tp2) \
-{ \
-    QCOMPARE(tp1.pos(), tp2.pos()); \
-    QCOMPARE(tp1.lastPos(), tp2.lastPos()); \
-    QCOMPARE(tp1.scenePos(), tp2.scenePos()); \
-    QCOMPARE(tp1.lastScenePos(), tp2.lastScenePos()); \
-    QCOMPARE(tp1.screenPos(), tp2.screenPos()); \
-    QCOMPARE(tp1.lastScreenPos(), tp2.lastScreenPos()); \
-}
-
-#define COMPARE_TOUCH_DATA(d1, d2) \
-{ \
-    QCOMPARE((int)d1.type, (int)d2.type); \
-    QCOMPARE(d1.widget, d2.widget); \
-    QCOMPARE((int)d1.states, (int)d2.states); \
-    QCOMPARE(d1.touchPoints.count(), d2.touchPoints.count()); \
-    for (int i=0; i<d1.touchPoints.count(); i++) { \
-        COMPARE_TOUCH_POINTS(d1.touchPoints[i], d2.touchPoints[i]); \
-    } \
-}
-
-class TestTouchItem : public QSGRectangle
-{
-    Q_OBJECT
-public:
-    TestTouchItem(QSGItem *parent = 0)
-        : QSGRectangle(parent), acceptEvents(true), mousePressId(0)
-    {
-        border()->setWidth(1);
-        setAcceptedMouseButtons(Qt::LeftButton);
-        setFiltersChildMouseEvents(true);
-    }
-
-    void reset() {
-        acceptEvents = true;
-        setEnabled(true);
-        setOpacity(1.0);
-
-        lastEvent = makeTouchData(QEvent::None, canvas(), 0, QList<QTouchEvent::TouchPoint>());//CHECK_VALID
-    }
-
-    bool acceptEvents;
-    TouchEventData lastEvent;
-    int mousePressId;
-
-protected:
-    virtual void touchEvent(QTouchEvent *event) {
-        if (!acceptEvents) {
-            event->ignore();
-            return;
-        }
-        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
-{
-Q_OBJECT
-public:
-    ConstantUpdateItem(QSGItem *parent = 0) : QSGItem(parent), iterations(0) {setFlag(ItemHasContents);}
-
-    int iterations;
-protected:
-    QSGNode* updatePaintNode(QSGNode *, UpdatePaintNodeData *){
-        iterations++;
-        update();
-        return 0;
-    }
-};
-
-class tst_qsgcanvas : public QObject
-{
-    Q_OBJECT
-public:
-    tst_qsgcanvas();
-
-private slots:
-    void initTestCase();
-    void cleanupTestCase();
-
-    void constantUpdates();
-
-    void touchEvent_basic();
-    void touchEvent_propagation();
-    void touchEvent_propagation_data();
-
-    void clearCanvas();
-    void mouseFiltering();
-};
-
-tst_qsgcanvas::tst_qsgcanvas()
-{
-}
-
-void tst_qsgcanvas::initTestCase()
-{
-}
-
-void tst_qsgcanvas::cleanupTestCase()
-{
-}
-
-//If the item calls update inside updatePaintNode, it should schedule another update
-void tst_qsgcanvas::constantUpdates()
-{
-    QSGCanvas canvas;
-    ConstantUpdateItem item(canvas.rootItem());
-    canvas.show();
-    QTRY_VERIFY(item.iterations > 60);
-}
-
-void tst_qsgcanvas::touchEvent_basic()
-{
-    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));
-
-    QPointF pos(10, 10);
-
-    // press single point
-    QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas);
-    QTest::qWait(50);
-
-    QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
-
-    QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
-    QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
-    TouchEventData d = makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem,pos));
-    COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem, pos)));
-    topItem->reset();
-
-    // press multiple points
-    QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas)
-            .press(1, bottomItem->mapToScene(pos).toPoint(), canvas);
-    QTest::qWait(50);
-    QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
-    QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
-    QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
-    COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem, pos)));
-    COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(bottomItem, pos)));
-    topItem->reset();
-    bottomItem->reset();
-
-    // touch point on top item moves to bottom item, but top item should still receive the event
-    QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(), canvas);
-    QTest::qWait(50);
-    QTest::touchEvent(canvas).move(0, bottomItem->mapToScene(pos).toPoint(), canvas);
-    QTest::qWait(50);
-    QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
-    COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchUpdate, canvas, Qt::TouchPointMoved,
-            makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos)));
-    topItem->reset();
-
-    // touch point on bottom item moves to top item, but bottom item should still receive the event
-    QTest::touchEvent(canvas).press(0, bottomItem->mapToScene(pos).toPoint(), canvas);
-    QTest::qWait(50);
-    QTest::touchEvent(canvas).move(0, topItem->mapToScene(pos).toPoint(), canvas);
-    QTest::qWait(50);
-    QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
-    COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchUpdate, canvas, Qt::TouchPointMoved,
-            makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos), pos)));
-    bottomItem->reset();
-
-    // a single stationary press on an item shouldn't cause an event
-    QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(), canvas);
-    QTest::qWait(50);
-    QTest::touchEvent(canvas).stationary(0)
-            .press(1, bottomItem->mapToScene(pos).toPoint(), canvas);
-    QTest::qWait(50);
-    QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);    // received press only, not stationary
-    QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
-    QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
-    COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem, pos)));
-    COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(bottomItem, pos)));
-    topItem->reset();
-    bottomItem->reset();
-
-    // move touch point from top item to bottom, and release
-    QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas);
-    QTest::qWait(50);
-    QTest::touchEvent(canvas).release(0, bottomItem->mapToScene(pos).toPoint(),canvas);
-    QTest::qWait(50);
-    QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
-    COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchEnd, canvas, Qt::TouchPointReleased,
-            makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos)));
-    topItem->reset();
-
-    // release while another point is pressed
-    QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas)
-            .press(1, bottomItem->mapToScene(pos).toPoint(), canvas);
-    QTest::qWait(50);
-    QTest::touchEvent(canvas).move(0, bottomItem->mapToScene(pos).toPoint(), canvas);
-    QTest::qWait(50);
-    QTest::touchEvent(canvas).release(0, bottomItem->mapToScene(pos).toPoint(), canvas)
-                             .stationary(1);
-    QTest::qWait(50);
-    QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
-    QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
-    QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
-    COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchEnd, canvas, Qt::TouchPointReleased,
-            makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos))));
-    COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(bottomItem, pos)));
-    topItem->reset();
-    bottomItem->reset();
-
-    delete topItem;
-    delete middleItem;
-    delete bottomItem;
-    delete canvas;
-}
-
-void tst_qsgcanvas::touchEvent_propagation()
-{
-    QFETCH(bool, acceptEvents);
-    QFETCH(bool, enableItem);
-    QFETCH(qreal, itemOpacity);
-
-    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));
-
-    QPointF pos(10, 10);
-    QPoint pointInBottomItem = bottomItem->mapToScene(pos).toPoint();  // (10, 10)
-    QPoint pointInMiddleItem = middleItem->mapToScene(pos).toPoint();  // (60, 60) overlaps with bottomItem
-    QPoint pointInTopItem = topItem->mapToScene(pos).toPoint();  // (110, 110) overlaps with bottom & top items
-
-    // disable topItem
-    topItem->acceptEvents = acceptEvents;
-    topItem->setEnabled(enableItem);
-    topItem->setOpacity(itemOpacity);
-
-    // single touch to top item, should be received by middle item
-    QTest::touchEvent(canvas).press(0, pointInTopItem, canvas);
-    QTest::qWait(50);
-    QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
-    QCOMPARE(middleItem->lastEvent.touchPoints.count(), 1);
-    QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
-    COMPARE_TOUCH_DATA(middleItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed,
-            makeTouchPoint(middleItem, middleItem->mapFromItem(topItem, pos))));
-
-    // touch top and middle items, middle item should get both events
-    QTest::touchEvent(canvas).press(0, pointInTopItem, canvas)
-            .press(1, pointInMiddleItem, canvas);
-    QTest::qWait(50);
-    QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
-    QCOMPARE(middleItem->lastEvent.touchPoints.count(), 2);
-    QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
-    COMPARE_TOUCH_DATA(middleItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed,
-           (QList<QTouchEvent::TouchPoint>() << makeTouchPoint(middleItem, middleItem->mapFromItem(topItem, pos))
-                                              << makeTouchPoint(middleItem, pos) )));
-    middleItem->reset();
-
-    // disable middleItem as well
-    middleItem->acceptEvents = acceptEvents;
-    middleItem->setEnabled(enableItem);
-    middleItem->setOpacity(itemOpacity);
-
-    // touch top and middle items, bottom item should get all events
-    QTest::touchEvent(canvas).press(0, pointInTopItem, canvas)
-            .press(1, pointInMiddleItem, canvas);
-    QTest::qWait(50);
-    QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
-    QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
-    QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 2);
-    COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed,
-            (QList<QTouchEvent::TouchPoint>() << makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos))
-                                              << makeTouchPoint(bottomItem, bottomItem->mapFromItem(middleItem, pos)) )));
-    bottomItem->reset();
-
-    // disable bottom item as well
-    bottomItem->acceptEvents = acceptEvents;
-    bottomItem->setEnabled(enableItem);
-    bottomItem->setOpacity(itemOpacity);
-
-    // no events should be received
-    QTest::touchEvent(canvas).press(0, pointInTopItem, canvas)
-            .press(1, pointInMiddleItem, canvas)
-            .press(2, pointInBottomItem, canvas);
-    QTest::qWait(50);
-    QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
-    QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
-    QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
-
-    topItem->reset();
-    middleItem->reset();
-    bottomItem->reset();
-
-    // disable middle item, touch on top item
-    middleItem->acceptEvents = acceptEvents;
-    middleItem->setEnabled(enableItem);
-    middleItem->setOpacity(itemOpacity);
-    QTest::touchEvent(canvas).press(0, pointInTopItem, canvas);
-    QTest::qWait(50);
-    if (!enableItem || itemOpacity == 0) {
-        // middle item is disabled or has 0 opacity, bottom item receives the event
-        QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
-        QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
-        QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
-        COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed,
-                makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos))));
-    } else {
-        // middle item ignores event, sends it to the top item (top-most child)
-        QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
-        QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
-        QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
-        COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed,
-                makeTouchPoint(topItem, pos)));
-    }
-
-    delete topItem;
-    delete middleItem;
-    delete bottomItem;
-    delete canvas;
-}
-
-void tst_qsgcanvas::touchEvent_propagation_data()
-{
-    QTest::addColumn<bool>("acceptEvents");
-    QTest::addColumn<bool>("enableItem");
-    QTest::addColumn<qreal>("itemOpacity");
-
-    QTest::newRow("disable events") << false << true << 1.0;
-    QTest::newRow("disable item") << true << false << 1.0;
-    QTest::newRow("opacity of 0") << true << true << 0.0;
-}
-
-void tst_qsgcanvas::clearCanvas()
-{
-    QSGCanvas *canvas = new QSGCanvas;
-    QSGItem *item = new QSGItem;
-    item->setParentItem(canvas->rootItem());
-
-    QVERIFY(item->canvas() == canvas);
-
-    delete canvas;
-
-    QVERIFY(item->canvas() == 0);
-
-    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)
-
-#include "tst_qsgcanvas.moc"
diff --git a/tests/auto/declarative/qsgcanvasitem/qsgcanvasitem.pro b/tests/auto/declarative/qsgcanvasitem/qsgcanvasitem.pro
deleted file mode 100644 (file)
index 18c1ea6..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-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
deleted file mode 100644 (file)
index 680e452..0000000
+++ /dev/null
@@ -1,42 +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 <QtQuickTest/quicktest.h>
-QUICK_TEST_MAIN(qsgcanvasitem)
diff --git a/tests/auto/declarative/qsgdrag/qsgdrag.pro b/tests/auto/declarative/qsgdrag/qsgdrag.pro
deleted file mode 100644 (file)
index a799860..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644 (file)
index 9719114..0000000
+++ /dev/null
@@ -1,827 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644 (file)
index f07071f..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644 (file)
index 1c303b4..0000000
+++ /dev/null
@@ -1,1110 +0,0 @@
-/****************************************************************************
-**
-** 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/qsgflickable.pro b/tests/auto/declarative/qsgflickable/qsgflickable.pro
deleted file mode 100644 (file)
index 48cf8b6..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsgflickable
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_qsgflickable.cpp
-
-testDataFiles.files = data
-testDataFiles.path = .
-DEPLOYMENT += testDataFiles
-
-CONFIG += parallel_test
-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
deleted file mode 100644 (file)
index f8d7bfd..0000000
+++ /dev/null
@@ -1,662 +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 <QtTest/QSignalSpy>
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtDeclarative/qsgview.h>
-#include <private/qsgflickable_p.h>
-#include <private/qdeclarativevaluetype_p.h>
-#include <math.h>
-#include "../shared/util.h"
-#include <QtOpenGL/QGLShaderProgram>
-
-class tst_qsgflickable : public QObject
-{
-    Q_OBJECT
-public:
-    tst_qsgflickable();
-
-private slots:
-    void initTestCase();
-    void cleanupTestCase();
-
-    void create();
-    void horizontalViewportSize();
-    void verticalViewportSize();
-    void properties();
-    void boundsBehavior();
-    void maximumFlickVelocity();
-    void flickDeceleration();
-    void pressDelay();
-    void nestedPressDelay();
-    void flickableDirection();
-    void resizeContent();
-    void returnToBounds();
-    void wheel();
-    void movingAndDragging();
-    void disabled();
-    void flickVelocity();
-    void margins();
-
-private:
-    QDeclarativeEngine engine;
-
-    void flick(QSGView *canvas, const QPoint &from, const QPoint &to, int duration);
-    template<typename T>
-    T *findItem(QSGItem *parent, const QString &objectName);
-};
-
-tst_qsgflickable::tst_qsgflickable()
-{
-}
-
-void tst_qsgflickable::initTestCase()
-{
-
-}
-
-void tst_qsgflickable::cleanupTestCase()
-{
-
-}
-
-void tst_qsgflickable::create()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable01.qml")));
-    QSGFlickable *obj = qobject_cast<QSGFlickable*>(c.create());
-
-    QVERIFY(obj != 0);
-    QCOMPARE(obj->isAtXBeginning(), true);
-    QCOMPARE(obj->isAtXEnd(), false);
-    QCOMPARE(obj->isAtYBeginning(), true);
-    QCOMPARE(obj->isAtYEnd(), false);
-    QCOMPARE(obj->contentX(), 0.);
-    QCOMPARE(obj->contentY(), 0.);
-
-    QCOMPARE(obj->horizontalVelocity(), 0.);
-    QCOMPARE(obj->verticalVelocity(), 0.);
-
-    QCOMPARE(obj->isInteractive(), true);
-    QCOMPARE(obj->boundsBehavior(), QSGFlickable::DragAndOvershootBounds);
-    QCOMPARE(obj->pressDelay(), 0);
-    QCOMPARE(obj->maximumFlickVelocity(), 2500.);
-
-    delete obj;
-}
-
-void tst_qsgflickable::horizontalViewportSize()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable02.qml")));
-    QSGFlickable *obj = qobject_cast<QSGFlickable*>(c.create());
-
-    QVERIFY(obj != 0);
-    QCOMPARE(obj->contentWidth(), 800.);
-    QCOMPARE(obj->contentHeight(), 300.);
-    QCOMPARE(obj->isAtXBeginning(), true);
-    QCOMPARE(obj->isAtXEnd(), false);
-    QCOMPARE(obj->isAtYBeginning(), true);
-    QCOMPARE(obj->isAtYEnd(), false);
-
-    delete obj;
-}
-
-void tst_qsgflickable::verticalViewportSize()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable03.qml")));
-    QSGFlickable *obj = qobject_cast<QSGFlickable*>(c.create());
-
-    QVERIFY(obj != 0);
-    QCOMPARE(obj->contentWidth(), 200.);
-    QCOMPARE(obj->contentHeight(), 1200.);
-    QCOMPARE(obj->isAtXBeginning(), true);
-    QCOMPARE(obj->isAtXEnd(), false);
-    QCOMPARE(obj->isAtYBeginning(), true);
-    QCOMPARE(obj->isAtYEnd(), false);
-
-    delete obj;
-}
-
-void tst_qsgflickable::properties()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable04.qml")));
-    QSGFlickable *obj = qobject_cast<QSGFlickable*>(c.create());
-
-    QVERIFY(obj != 0);
-    QCOMPARE(obj->isInteractive(), false);
-    QCOMPARE(obj->boundsBehavior(), QSGFlickable::StopAtBounds);
-    QCOMPARE(obj->pressDelay(), 200);
-    QCOMPARE(obj->maximumFlickVelocity(), 2000.);
-
-    QVERIFY(obj->property("ok").toBool() == false);
-    QMetaObject::invokeMethod(obj, "check");
-    QVERIFY(obj->property("ok").toBool() == true);
-
-    delete obj;
-}
-
-void tst_qsgflickable::boundsBehavior()
-{
-    QDeclarativeComponent component(&engine);
-    component.setData("import QtQuick 2.0; Flickable { boundsBehavior: Flickable.StopAtBounds }", QUrl::fromLocalFile(""));
-    QSGFlickable *flickable = qobject_cast<QSGFlickable*>(component.create());
-    QSignalSpy spy(flickable, SIGNAL(boundsBehaviorChanged()));
-
-    QVERIFY(flickable);
-    QVERIFY(flickable->boundsBehavior() == QSGFlickable::StopAtBounds);
-
-    flickable->setBoundsBehavior(QSGFlickable::DragAndOvershootBounds);
-    QVERIFY(flickable->boundsBehavior() == QSGFlickable::DragAndOvershootBounds);
-    QCOMPARE(spy.count(),1);
-    flickable->setBoundsBehavior(QSGFlickable::DragAndOvershootBounds);
-    QCOMPARE(spy.count(),1);
-
-    flickable->setBoundsBehavior(QSGFlickable::DragOverBounds);
-    QVERIFY(flickable->boundsBehavior() == QSGFlickable::DragOverBounds);
-    QCOMPARE(spy.count(),2);
-    flickable->setBoundsBehavior(QSGFlickable::DragOverBounds);
-    QCOMPARE(spy.count(),2);
-
-    flickable->setBoundsBehavior(QSGFlickable::StopAtBounds);
-    QVERIFY(flickable->boundsBehavior() == QSGFlickable::StopAtBounds);
-    QCOMPARE(spy.count(),3);
-    flickable->setBoundsBehavior(QSGFlickable::StopAtBounds);
-    QCOMPARE(spy.count(),3);
-}
-
-void tst_qsgflickable::maximumFlickVelocity()
-{
-    QDeclarativeComponent component(&engine);
-    component.setData("import QtQuick 2.0; Flickable { maximumFlickVelocity: 1.0; }", QUrl::fromLocalFile(""));
-    QSGFlickable *flickable = qobject_cast<QSGFlickable*>(component.create());
-    QSignalSpy spy(flickable, SIGNAL(maximumFlickVelocityChanged()));
-
-    QVERIFY(flickable);
-    QCOMPARE(flickable->maximumFlickVelocity(), 1.0);
-
-    flickable->setMaximumFlickVelocity(2.0);
-    QCOMPARE(flickable->maximumFlickVelocity(), 2.0);
-    QCOMPARE(spy.count(),1);
-    flickable->setMaximumFlickVelocity(2.0);
-    QCOMPARE(spy.count(),1);
-}
-
-void tst_qsgflickable::flickDeceleration()
-{
-    QDeclarativeComponent component(&engine);
-    component.setData("import QtQuick 2.0; Flickable { flickDeceleration: 1.0; }", QUrl::fromLocalFile(""));
-    QSGFlickable *flickable = qobject_cast<QSGFlickable*>(component.create());
-    QSignalSpy spy(flickable, SIGNAL(flickDecelerationChanged()));
-
-    QVERIFY(flickable);
-    QCOMPARE(flickable->flickDeceleration(), 1.0);
-
-    flickable->setFlickDeceleration(2.0);
-    QCOMPARE(flickable->flickDeceleration(), 2.0);
-    QCOMPARE(spy.count(),1);
-    flickable->setFlickDeceleration(2.0);
-    QCOMPARE(spy.count(),1);
-}
-
-void tst_qsgflickable::pressDelay()
-{
-    QDeclarativeComponent component(&engine);
-    component.setData("import QtQuick 2.0; Flickable { pressDelay: 100; }", QUrl::fromLocalFile(""));
-    QSGFlickable *flickable = qobject_cast<QSGFlickable*>(component.create());
-    QSignalSpy spy(flickable, SIGNAL(pressDelayChanged()));
-
-    QVERIFY(flickable);
-    QCOMPARE(flickable->pressDelay(), 100);
-
-    flickable->setPressDelay(200);
-    QCOMPARE(flickable->pressDelay(), 200);
-    QCOMPARE(spy.count(),1);
-    flickable->setPressDelay(200);
-    QCOMPARE(spy.count(),1);
-}
-
-// QTBUG-17361
-void tst_qsgflickable::nestedPressDelay()
-{
-    QSGView *canvas = new QSGView;
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("nestedPressDelay.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QVERIFY(canvas->rootObject() != 0);
-
-    QSGFlickable *outer = qobject_cast<QSGFlickable*>(canvas->rootObject());
-    QVERIFY(outer != 0);
-
-    QSGFlickable *inner = canvas->rootObject()->findChild<QSGFlickable*>("innerFlickable");
-    QVERIFY(inner != 0);
-
-    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(150, 150));
-    // the MouseArea is not pressed immediately
-    QVERIFY(outer->property("pressed").toBool() == false);
-
-    // The outer pressDelay will prevail (50ms, vs. 10sec)
-    // QTRY_VERIFY() has 5sec timeout, so will timeout well within 10sec.
-    QTRY_VERIFY(outer->property("pressed").toBool() == true);
-
-    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(150, 150));
-
-    delete canvas;
-}
-
-void tst_qsgflickable::flickableDirection()
-{
-    QDeclarativeComponent component(&engine);
-    component.setData("import QtQuick 2.0; Flickable { flickableDirection: Flickable.VerticalFlick; }", QUrl::fromLocalFile(""));
-    QSGFlickable *flickable = qobject_cast<QSGFlickable*>(component.create());
-    QSignalSpy spy(flickable, SIGNAL(flickableDirectionChanged()));
-
-    QVERIFY(flickable);
-    QCOMPARE(flickable->flickableDirection(), QSGFlickable::VerticalFlick);
-
-    flickable->setFlickableDirection(QSGFlickable::HorizontalAndVerticalFlick);
-    QCOMPARE(flickable->flickableDirection(), QSGFlickable::HorizontalAndVerticalFlick);
-    QCOMPARE(spy.count(),1);
-
-    flickable->setFlickableDirection(QSGFlickable::AutoFlickDirection);
-    QCOMPARE(flickable->flickableDirection(), QSGFlickable::AutoFlickDirection);
-    QCOMPARE(spy.count(),2);
-
-    flickable->setFlickableDirection(QSGFlickable::HorizontalFlick);
-    QCOMPARE(flickable->flickableDirection(), QSGFlickable::HorizontalFlick);
-    QCOMPARE(spy.count(),3);
-
-    flickable->setFlickableDirection(QSGFlickable::HorizontalFlick);
-    QCOMPARE(flickable->flickableDirection(), QSGFlickable::HorizontalFlick);
-    QCOMPARE(spy.count(),3);
-}
-
-// QtQuick 1.1
-void tst_qsgflickable::resizeContent()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("resize.qml")));
-    QSGItem *root = qobject_cast<QSGItem*>(c.create());
-    QSGFlickable *obj = findItem<QSGFlickable>(root, "flick");
-
-    QVERIFY(obj != 0);
-    QCOMPARE(obj->contentX(), 0.);
-    QCOMPARE(obj->contentY(), 0.);
-    QCOMPARE(obj->contentWidth(), 300.);
-    QCOMPARE(obj->contentHeight(), 300.);
-
-    QMetaObject::invokeMethod(root, "resizeContent");
-
-    QCOMPARE(obj->contentX(), 100.);
-    QCOMPARE(obj->contentY(), 100.);
-    QCOMPARE(obj->contentWidth(), 600.);
-    QCOMPARE(obj->contentHeight(), 600.);
-
-    delete root;
-}
-
-// QtQuick 1.1
-void tst_qsgflickable::returnToBounds()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("resize.qml")));
-    QSGItem *root = qobject_cast<QSGItem*>(c.create());
-    QSGFlickable *obj = findItem<QSGFlickable>(root, "flick");
-
-    QVERIFY(obj != 0);
-    QCOMPARE(obj->contentX(), 0.);
-    QCOMPARE(obj->contentY(), 0.);
-    QCOMPARE(obj->contentWidth(), 300.);
-    QCOMPARE(obj->contentHeight(), 300.);
-
-    obj->setContentX(100);
-    obj->setContentY(400);
-    QTRY_COMPARE(obj->contentX(), 100.);
-    QTRY_COMPARE(obj->contentY(), 400.);
-
-    QMetaObject::invokeMethod(root, "returnToBounds");
-
-    QTRY_COMPARE(obj->contentX(), 0.);
-    QTRY_COMPARE(obj->contentY(), 0.);
-
-    delete root;
-}
-
-void tst_qsgflickable::wheel()
-{
-    QSGView *canvas = new QSGView;
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("wheel.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QVERIFY(canvas->rootObject() != 0);
-
-    QSGFlickable *flick = canvas->rootObject()->findChild<QSGFlickable*>("flick");
-    QVERIFY(flick != 0);
-
-    {
-        QWheelEvent event(QPoint(200, 200), -120, Qt::NoButton, Qt::NoModifier, Qt::Vertical);
-        event.setAccepted(false);
-        QApplication::sendEvent(canvas, &event);
-    }
-
-    QTRY_VERIFY(flick->contentY() > 0);
-    QVERIFY(flick->contentX() == 0);
-
-    flick->setContentY(0);
-    QVERIFY(flick->contentY() == 0);
-
-    {
-        QWheelEvent event(QPoint(200, 200), -120, Qt::NoButton, Qt::NoModifier, Qt::Horizontal);
-        event.setAccepted(false);
-        QApplication::sendEvent(canvas, &event);
-    }
-
-    QTRY_VERIFY(flick->contentX() > 0);
-    QVERIFY(flick->contentY() == 0);
-
-    delete canvas;
-}
-
-void tst_qsgflickable::movingAndDragging()
-{
-    QSGView *canvas = new QSGView;
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("flickable03.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QTest::qWaitForWindowShown(canvas);
-    QVERIFY(canvas->rootObject() != 0);
-
-    QSGFlickable *flickable = qobject_cast<QSGFlickable*>(canvas->rootObject());
-    QVERIFY(flickable != 0);
-
-    QSignalSpy vDragSpy(flickable, SIGNAL(draggingVerticallyChanged()));
-    QSignalSpy hDragSpy(flickable, SIGNAL(draggingHorizontallyChanged()));
-    QSignalSpy dragSpy(flickable, SIGNAL(draggingChanged()));
-    QSignalSpy vMoveSpy(flickable, SIGNAL(movingVerticallyChanged()));
-    QSignalSpy hMoveSpy(flickable, SIGNAL(movingHorizontallyChanged()));
-    QSignalSpy moveSpy(flickable, SIGNAL(movingChanged()));
-    QSignalSpy dragStartSpy(flickable, SIGNAL(dragStarted()));
-    QSignalSpy dragEndSpy(flickable, SIGNAL(dragEnded()));
-
-    //Vertical
-    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50, 90));
-
-    QTest::mouseMove(canvas, QPoint(50, 80));
-    QTest::mouseMove(canvas, QPoint(50, 70));
-    QTest::mouseMove(canvas, QPoint(50, 60));
-
-    QMouseEvent moveEvent(QEvent::MouseMove, QPoint(50, 80), Qt::LeftButton, Qt::LeftButton, 0);
-
-    QVERIFY(!flickable->isDraggingHorizontally());
-    QVERIFY(flickable->isDraggingVertically());
-    QVERIFY(flickable->isDragging());
-    QCOMPARE(vDragSpy.count(), 1);
-    QCOMPARE(dragSpy.count(), 1);
-    QCOMPARE(hDragSpy.count(), 0);
-    QCOMPARE(dragStartSpy.count(), 1);
-    QCOMPARE(dragEndSpy.count(), 0);
-
-    QVERIFY(!flickable->isMovingHorizontally());
-    QVERIFY(flickable->isMovingVertically());
-    QVERIFY(flickable->isMoving());
-    QCOMPARE(vMoveSpy.count(), 1);
-    QCOMPARE(moveSpy.count(), 1);
-    QCOMPARE(hMoveSpy.count(), 0);
-
-    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 60));
-
-    QTRY_VERIFY(!flickable->isDraggingVertically());
-    QVERIFY(!flickable->isDragging());
-    QCOMPARE(vDragSpy.count(), 2);
-    QCOMPARE(dragSpy.count(), 2);
-    QCOMPARE(hDragSpy.count(), 0);
-    QCOMPARE(dragStartSpy.count(), 1);
-    QCOMPARE(dragEndSpy.count(), 1);
-
-    // wait for any motion to end
-    QTRY_VERIFY(flickable->isMoving() == false);
-
-    //Horizontal
-    vDragSpy.clear();
-    hDragSpy.clear();
-    dragSpy.clear();
-    vMoveSpy.clear();
-    hMoveSpy.clear();
-    moveSpy.clear();
-    dragStartSpy.clear();
-    dragEndSpy.clear();
-
-    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(90, 50));
-
-    QTest::mouseMove(canvas, QPoint(80, 50));
-    QTest::mouseMove(canvas, QPoint(70, 50));
-    QTest::mouseMove(canvas, QPoint(60, 50));
-
-    QVERIFY(flickable->isDraggingHorizontally());
-    QVERIFY(flickable->isDragging());
-    QCOMPARE(vDragSpy.count(), 0);
-    QCOMPARE(dragSpy.count(), 1);
-    QCOMPARE(hDragSpy.count(), 1);
-    QCOMPARE(dragStartSpy.count(), 1);
-    QCOMPARE(dragEndSpy.count(), 0);
-
-    QVERIFY(!flickable->isMovingVertically());
-    QVERIFY(flickable->isMovingHorizontally());
-    QVERIFY(flickable->isMoving());
-    QCOMPARE(vMoveSpy.count(), 0);
-    QCOMPARE(moveSpy.count(), 1);
-    QCOMPARE(hMoveSpy.count(), 1);
-
-    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(60, 50));
-
-    QTRY_VERIFY(!flickable->isDraggingHorizontally());
-    QVERIFY(!flickable->isDragging());
-    QCOMPARE(vDragSpy.count(), 0);
-    QCOMPARE(dragSpy.count(), 2);
-    QCOMPARE(hDragSpy.count(), 2);
-    QCOMPARE(dragStartSpy.count(), 1);
-    QCOMPARE(dragEndSpy.count(), 1);
-
-    // Don't test moving because a flick could occur
-
-    delete canvas;
-}
-
-void tst_qsgflickable::disabled()
-{
-    QSGView *canvas = new QSGView;
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("disabled.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QVERIFY(canvas->rootObject() != 0);
-
-    QSGFlickable *flick = canvas->rootObject()->findChild<QSGFlickable*>("flickable");
-    QVERIFY(flick != 0);
-
-    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50, 90));
-
-    QTest::mouseMove(canvas, QPoint(50, 80));
-    QTest::mouseMove(canvas, QPoint(50, 70));
-    QTest::mouseMove(canvas, QPoint(50, 60));
-
-    QVERIFY(flick->isMoving() == false);
-
-    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 60));
-
-    // verify that mouse clicks on other elements still work (QTBUG-20584)
-    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50, 10));
-    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 10));
-
-    QTRY_VERIFY(canvas->rootObject()->property("clicked").toBool() == true);
-}
-
-void tst_qsgflickable::flickVelocity()
-{
-#ifdef Q_WS_MAC
-    QSKIP("Producing flicks on Mac CI impossible due to timing problems");
-#endif
-
-    QSGView *canvas = new QSGView;
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("flickable03.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QVERIFY(canvas->rootObject() != 0);
-
-    QSGFlickable *flickable = qobject_cast<QSGFlickable*>(canvas->rootObject());
-    QVERIFY(flickable != 0);
-
-    // flick up
-    flick(canvas, QPoint(20,190), QPoint(20, 50), 200);
-    QVERIFY(flickable->verticalVelocity() > 0.0);
-    QTRY_VERIFY(flickable->verticalVelocity() == 0.0);
-
-    // flick down
-    flick(canvas, QPoint(20,10), QPoint(20, 140), 200);
-    QVERIFY(flickable->verticalVelocity() < 0.0);
-    QTRY_VERIFY(flickable->verticalVelocity() == 0.0);
-
-    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;
-    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);
-}
-
-template<typename T>
-T *tst_qsgflickable::findItem(QSGItem *parent, const QString &objectName)
-{
-    const QMetaObject &mo = T::staticMetaObject;
-    //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)
-            continue;
-        //qDebug() << "try" << item;
-        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
-            return static_cast<T*>(item);
-        }
-        item = findItem<T>(item, objectName);
-        if (item)
-            return static_cast<T*>(item);
-    }
-
-    return 0;
-}
-
-QTEST_MAIN(tst_qsgflickable)
-
-#include "tst_qsgflickable.moc"
diff --git a/tests/auto/declarative/qsgflipable/qsgflipable.pro b/tests/auto/declarative/qsgflipable/qsgflipable.pro
deleted file mode 100644 (file)
index 806aeb2..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsgflipable
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_qsgflipable.cpp
-
-testDataFiles.files = data
-testDataFiles.path = .
-DEPLOYMENT += testDataFiles
-
-CONFIG += parallel_test
-
-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
deleted file mode 100644 (file)
index 2fc1924..0000000
+++ /dev/null
@@ -1,150 +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/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtDeclarative/qsgview.h>
-#include <private/qsgflipable_p.h>
-#include <private/qdeclarativevaluetype_p.h>
-#include <QFontMetrics>
-#include <private/qsgrectangle_p.h>
-#include <math.h>
-#include <QtOpenGL/QGLShaderProgram>
-#include "../shared/util.h"
-
-class tst_qsgflipable : public QObject
-{
-    Q_OBJECT
-public:
-    tst_qsgflipable();
-
-private slots:
-    void initTestCase();
-    void cleanupTestCase();
-    void create();
-    void checkFrontAndBack();
-    void setFrontAndBack();
-
-    // below here task issues
-    void QTBUG_9161_crash();
-    void QTBUG_8474_qgv_abort();
-
-private:
-    QDeclarativeEngine engine;
-};
-
-tst_qsgflipable::tst_qsgflipable()
-{
-}
-void tst_qsgflipable::initTestCase()
-{
-}
-
-void tst_qsgflipable::cleanupTestCase()
-{
-
-}
-
-void tst_qsgflipable::create()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-flipable.qml")));
-    QSGFlipable *obj = qobject_cast<QSGFlipable*>(c.create());
-
-    QVERIFY(obj != 0);
-    delete obj;
-}
-
-void tst_qsgflipable::checkFrontAndBack()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-flipable.qml")));
-    QSGFlipable *obj = qobject_cast<QSGFlipable*>(c.create());
-
-    QVERIFY(obj != 0);
-    QVERIFY(obj->front() != 0);
-    QVERIFY(obj->back() != 0);
-    delete obj;
-}
-
-void tst_qsgflipable::setFrontAndBack()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-flipable.qml")));
-    QSGFlipable *obj = qobject_cast<QSGFlipable*>(c.create());
-
-    QVERIFY(obj != 0);
-    QVERIFY(obj->front() != 0);
-    QVERIFY(obj->back() != 0);
-
-    QString message = c.url().toString() + ":3:1: QML Flipable: front is a write-once property";
-    QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
-    obj->setFront(new QSGRectangle());
-
-    message = c.url().toString() + ":3:1: QML Flipable: back is a write-once property";
-    QTest::ignoreMessage(QtWarningMsg, qPrintable(message));
-    obj->setBack(new QSGRectangle());
-    delete obj;
-}
-
-void tst_qsgflipable::QTBUG_9161_crash()
-{
-    QSGView *canvas = new QSGView;
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("crash.qml")));
-    QSGItem *root = canvas->rootObject();
-    QVERIFY(root != 0);
-    canvas->show();
-    delete canvas;
-}
-
-void tst_qsgflipable::QTBUG_8474_qgv_abort()
-{
-    QSGView *canvas = new QSGView;
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("flipable-abort.qml")));
-    QSGItem *root = canvas->rootObject();
-    QVERIFY(root != 0);
-    canvas->show();
-    delete canvas;
-}
-
-QTEST_MAIN(tst_qsgflipable)
-
-#include "tst_qsgflipable.moc"
diff --git a/tests/auto/declarative/qsgfocusscope/qsgfocusscope.pro b/tests/auto/declarative/qsgfocusscope/qsgfocusscope.pro
deleted file mode 100644 (file)
index 4b7b436..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsgfocusscope
-SOURCES += tst_qsgfocusscope.cpp
-macx:CONFIG -= app_bundle
-
-testDataFiles.files = data
-testDataFiles.path = .
-DEPLOYMENT += testDataFiles
-
-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
deleted file mode 100644 (file)
index c70ba69..0000000
+++ /dev/null
@@ -1,658 +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 <QSignalSpy>
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtDeclarative/qsgview.h>
-#include <private/qsgrectangle_p.h>
-#include <private/qsgtextedit_p.h>
-#include <private/qsgtext_p.h>
-#include <QtDeclarative/private/qsgfocusscope_p.h>
-#include "../shared/util.h"
-
-class tst_qsgfocusscope : public QObject
-{
-    Q_OBJECT
-public:
-    tst_qsgfocusscope() {}
-
-    template<typename T>
-    T *findItem(QSGItem *parent, const QString &id);
-
-private slots:
-    void initTestCase();
-    void cleanupTestCase();
-    void basic();
-    void nested();
-    void noFocus();
-    void textEdit();
-    void forceFocus();
-    void noParentFocus();
-    void signalEmission();
-    void qtBug13380();
-    void forceActiveFocus();
-    void canvasFocus();
-};
-void tst_qsgfocusscope::initTestCase()
-{
-}
-
-void tst_qsgfocusscope::cleanupTestCase()
-{
-
-}
-
-/*
-   Find an item with the specified id.
-*/
-template<typename T>
-T *tst_qsgfocusscope::findItem(QSGItem *parent, const QString &objectName)
-{
-    const QMetaObject &mo = T::staticMetaObject;
-    QList<QSGItem *> children = parent->childItems();
-    for (int i = 0; i < children.count(); ++i) {
-        QSGItem *item = children.at(i);
-        if (item) {
-            if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
-                return static_cast<T*>(item);
-            }
-            item = findItem<T>(item, objectName);
-            if (item)
-                return static_cast<T*>(item);
-        }
-    }
-    return 0;
-}
-
-void tst_qsgfocusscope::basic()
-{
-    QSGView *view = new QSGView;
-    view->setSource(QUrl::fromLocalFile(TESTDATA("test.qml")));
-
-    QSGFocusScope *item0 = findItem<QSGFocusScope>(view->rootObject(), QLatin1String("item0"));
-    QSGRectangle *item1 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item1"));
-    QSGRectangle *item2 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item2"));
-    QSGRectangle *item3 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item3"));
-    QVERIFY(item0 != 0);
-    QVERIFY(item1 != 0);
-    QVERIFY(item2 != 0);
-    QVERIFY(item3 != 0);
-
-    view->show();
-    view->requestActivateWindow();
-
-    QTest::qWaitForWindowShown(view);
-
-    QVERIFY(view->isTopLevel());
-    QVERIFY(item0->hasActiveFocus() == true);
-    QVERIFY(item1->hasActiveFocus() == true);
-    QVERIFY(item2->hasActiveFocus() == false);
-    QVERIFY(item3->hasActiveFocus() == false);
-
-    QTest::keyClick(view, Qt::Key_Right);
-    QTest::qWait(50);
-    QVERIFY(item0->hasActiveFocus() == true);
-    QVERIFY(item1->hasActiveFocus() == false);
-    QVERIFY(item2->hasActiveFocus() == true);
-    QVERIFY(item3->hasActiveFocus() == false);
-
-    QTest::keyClick(view, Qt::Key_Down);
-    QTest::qWait(50);
-    QVERIFY(item0->hasActiveFocus() == false);
-    QVERIFY(item1->hasActiveFocus() == false);
-    QVERIFY(item2->hasActiveFocus() == false);
-    QVERIFY(item3->hasActiveFocus() == true);
-
-    delete view;
-}
-
-void tst_qsgfocusscope::nested()
-{
-    QSGView *view = new QSGView;
-    view->setSource(QUrl::fromLocalFile(TESTDATA("test2.qml")));
-
-    QSGFocusScope *item1 = findItem<QSGFocusScope>(view->rootObject(), QLatin1String("item1"));
-    QSGFocusScope *item2 = findItem<QSGFocusScope>(view->rootObject(), QLatin1String("item2"));
-    QSGFocusScope *item3 = findItem<QSGFocusScope>(view->rootObject(), QLatin1String("item3"));
-    QSGFocusScope *item4 = findItem<QSGFocusScope>(view->rootObject(), QLatin1String("item4"));
-    QSGFocusScope *item5 = findItem<QSGFocusScope>(view->rootObject(), QLatin1String("item5"));
-    QVERIFY(item1 != 0);
-    QVERIFY(item2 != 0);
-    QVERIFY(item3 != 0);
-    QVERIFY(item4 != 0);
-    QVERIFY(item5 != 0);
-
-    view->show();
-    view->requestActivateWindow();
-
-    QTest::qWaitForWindowShown(view);
-
-    QVERIFY(item1->hasActiveFocus() == true);
-    QVERIFY(item2->hasActiveFocus() == true);
-    QVERIFY(item3->hasActiveFocus() == true);
-    QVERIFY(item4->hasActiveFocus() == true);
-    QVERIFY(item5->hasActiveFocus() == true);
-    delete view;
-}
-
-void tst_qsgfocusscope::noFocus()
-{
-    QSGView *view = new QSGView;
-    view->setSource(QUrl::fromLocalFile(TESTDATA("test4.qml")));
-
-    QSGRectangle *item0 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item0"));
-    QSGRectangle *item1 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item1"));
-    QSGRectangle *item2 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item2"));
-    QSGRectangle *item3 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item3"));
-    QVERIFY(item0 != 0);
-    QVERIFY(item1 != 0);
-    QVERIFY(item2 != 0);
-    QVERIFY(item3 != 0);
-
-    view->show();
-    view->requestActivateWindow();
-    QTest::qWaitForWindowShown(view);
-
-    QVERIFY(item0->hasActiveFocus() == false);
-    QVERIFY(item1->hasActiveFocus() == false);
-    QVERIFY(item2->hasActiveFocus() == false);
-    QVERIFY(item3->hasActiveFocus() == false);
-
-    QTest::keyClick(view, Qt::Key_Right);
-    QVERIFY(item0->hasActiveFocus() == false);
-    QVERIFY(item1->hasActiveFocus() == false);
-    QVERIFY(item2->hasActiveFocus() == false);
-    QVERIFY(item3->hasActiveFocus() == false);
-
-    QTest::keyClick(view, Qt::Key_Down);
-    QVERIFY(item0->hasActiveFocus() == false);
-    QVERIFY(item1->hasActiveFocus() == false);
-    QVERIFY(item2->hasActiveFocus() == false);
-    QVERIFY(item3->hasActiveFocus() == false);
-
-    delete view;
-}
-
-void tst_qsgfocusscope::textEdit()
-{
-    QSGView *view = new QSGView;
-    view->setSource(QUrl::fromLocalFile(TESTDATA("test5.qml")));
-
-    QSGFocusScope *item0 = findItem<QSGFocusScope>(view->rootObject(), QLatin1String("item0"));
-    QSGTextEdit *item1 = findItem<QSGTextEdit>(view->rootObject(), QLatin1String("item1"));
-    QSGRectangle *item2 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item2"));
-    QSGTextEdit *item3 = findItem<QSGTextEdit>(view->rootObject(), QLatin1String("item3"));
-    QVERIFY(item0 != 0);
-    QVERIFY(item1 != 0);
-    QVERIFY(item2 != 0);
-    QVERIFY(item3 != 0);
-
-    view->show();
-    view->requestActivateWindow();
-
-    QTest::qWaitForWindowShown(view);
-
-    QTRY_VERIFY(view == qGuiApp->focusWindow());
-    QVERIFY(item0->hasActiveFocus() == true);
-    QVERIFY(item1->hasActiveFocus() == true);
-    QVERIFY(item2->hasActiveFocus() == false);
-    QVERIFY(item3->hasActiveFocus() == false);
-
-    QTest::keyClick(view, Qt::Key_Right);
-    QVERIFY(item0->hasActiveFocus() == true);
-    QVERIFY(item1->hasActiveFocus() == true);
-    QVERIFY(item2->hasActiveFocus() == false);
-    QVERIFY(item3->hasActiveFocus() == false);
-
-    QTest::keyClick(view, Qt::Key_Right);
-    QTest::keyClick(view, Qt::Key_Right);
-    QTest::keyClick(view, Qt::Key_Right);
-    QTest::keyClick(view, Qt::Key_Right);
-    QTest::keyClick(view, Qt::Key_Right);
-    QVERIFY(item0->hasActiveFocus() == true);
-    QVERIFY(item1->hasActiveFocus() == false);
-    QVERIFY(item2->hasActiveFocus() == true);
-    QVERIFY(item3->hasActiveFocus() == false);
-
-    QTest::keyClick(view, Qt::Key_Down);
-    QVERIFY(item0->hasActiveFocus() == false);
-    QVERIFY(item1->hasActiveFocus() == false);
-    QVERIFY(item2->hasActiveFocus() == false);
-    QVERIFY(item3->hasActiveFocus() == true);
-
-    delete view;
-}
-
-void tst_qsgfocusscope::forceFocus()
-{
-    QSGView *view = new QSGView;
-    view->setSource(QUrl::fromLocalFile(TESTDATA("forcefocus.qml")));
-
-    QSGFocusScope *item0 = findItem<QSGFocusScope>(view->rootObject(), QLatin1String("item0"));
-    QSGRectangle *item1 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item1"));
-    QSGRectangle *item2 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item2"));
-    QSGFocusScope *item3 = findItem<QSGFocusScope>(view->rootObject(), QLatin1String("item3"));
-    QSGRectangle *item4 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item4"));
-    QSGRectangle *item5 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item5"));
-    QVERIFY(item0 != 0);
-    QVERIFY(item1 != 0);
-    QVERIFY(item2 != 0);
-    QVERIFY(item3 != 0);
-    QVERIFY(item4 != 0);
-    QVERIFY(item5 != 0);
-
-    view->show();
-    view->requestActivateWindow();
-    QTest::qWaitForWindowShown(view);
-
-    QVERIFY(item0->hasActiveFocus() == true);
-    QVERIFY(item1->hasActiveFocus() == true);
-    QVERIFY(item2->hasActiveFocus() == false);
-    QVERIFY(item3->hasActiveFocus() == false);
-    QVERIFY(item4->hasActiveFocus() == false);
-    QVERIFY(item5->hasActiveFocus() == false);
-
-    QTest::keyClick(view, Qt::Key_4);
-    QVERIFY(item0->hasActiveFocus() == true);
-    QVERIFY(item1->hasActiveFocus() == true);
-    QVERIFY(item2->hasActiveFocus() == false);
-    QVERIFY(item3->hasActiveFocus() == false);
-    QVERIFY(item4->hasActiveFocus() == false);
-    QVERIFY(item5->hasActiveFocus() == false);
-
-    QTest::keyClick(view, Qt::Key_5);
-    QVERIFY(item0->hasActiveFocus() == false);
-    QVERIFY(item1->hasActiveFocus() == false);
-    QVERIFY(item2->hasActiveFocus() == false);
-    QVERIFY(item3->hasActiveFocus() == true);
-    QVERIFY(item4->hasActiveFocus() == false);
-    QVERIFY(item5->hasActiveFocus() == true);
-
-    delete view;
-}
-
-void tst_qsgfocusscope::noParentFocus()
-{
-    QSGView *view = new QSGView;
-    view->setSource(QUrl::fromLocalFile(TESTDATA("chain.qml")));
-    QVERIFY(view->rootObject());
-
-    view->show();
-    view->requestActivateWindow();
-    qApp->processEvents();
-
-#ifdef Q_WS_X11
-    // to be safe and avoid failing setFocus with window managers
-    qt_x11_wait_for_window_manager(view);
-#endif
-
-    QVERIFY(view->rootObject()->property("focus1") == false);
-    QVERIFY(view->rootObject()->property("focus2") == false);
-    QVERIFY(view->rootObject()->property("focus3") == true);
-    QVERIFY(view->rootObject()->property("focus4") == true);
-    QVERIFY(view->rootObject()->property("focus5") == true);
-
-    delete view;
-}
-
-void tst_qsgfocusscope::signalEmission()
-{
-    QSGView *view = new QSGView;
-    view->setSource(QUrl::fromLocalFile(TESTDATA("signalEmission.qml")));
-
-    QSGRectangle *item1 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item1"));
-    QSGRectangle *item2 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item2"));
-    QSGRectangle *item3 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item3"));
-    QSGRectangle *item4 = findItem<QSGRectangle>(view->rootObject(), QLatin1String("item4"));
-    QVERIFY(item1 != 0);
-    QVERIFY(item2 != 0);
-    QVERIFY(item3 != 0);
-    QVERIFY(item4 != 0);
-
-    view->show();
-    view->requestActivateWindow();
-
-    QTest::qWaitForWindowShown(view);
-
-    QVariant blue(QColor("blue"));
-    QVariant red(QColor("red"));
-
-    item1->setFocus(true);
-    QCOMPARE(item1->property("color"), red);
-    QCOMPARE(item2->property("color"), blue);
-    QCOMPARE(item3->property("color"), blue);
-    QCOMPARE(item4->property("color"), blue);
-
-    item2->setFocus(true);
-    QCOMPARE(item1->property("color"), blue);
-    QCOMPARE(item2->property("color"), red);
-    QCOMPARE(item3->property("color"), blue);
-    QCOMPARE(item4->property("color"), blue);
-
-    item3->setFocus(true);
-    QCOMPARE(item1->property("color"), blue);
-    QCOMPARE(item2->property("color"), red);
-    QCOMPARE(item3->property("color"), red);
-    QCOMPARE(item4->property("color"), blue);
-
-    item4->setFocus(true);
-    QCOMPARE(item1->property("color"), blue);
-    QCOMPARE(item2->property("color"), red);
-    QCOMPARE(item3->property("color"), blue);
-    QCOMPARE(item4->property("color"), red);
-
-    item4->setFocus(false);
-    QCOMPARE(item1->property("color"), blue);
-    QCOMPARE(item2->property("color"), red);
-    QCOMPARE(item3->property("color"), blue);
-    QCOMPARE(item4->property("color"), blue);
-
-    delete view;
-}
-
-void tst_qsgfocusscope::qtBug13380()
-{
-    QSGView *view = new QSGView;
-    view->setSource(QUrl::fromLocalFile(TESTDATA("qtBug13380.qml")));
-
-    view->show();
-    QVERIFY(view->rootObject());
-    view->requestActivateWindow();
-    qApp->processEvents();
-
-    QTest::qWaitForWindowShown(view);
-
-    QTRY_VERIFY(view == qGuiApp->focusWindow());
-    QVERIFY(view->rootObject()->property("noFocus").toBool());
-
-    view->rootObject()->setProperty("showRect", true);
-    QVERIFY(view->rootObject()->property("noFocus").toBool());
-
-    delete view;
-}
-
-void tst_qsgfocusscope::forceActiveFocus()
-{
-    QSGView *view = new QSGView;
-    view->setSource(QUrl::fromLocalFile(TESTDATA("forceActiveFocus.qml")));
-
-    view->show();
-    view->requestActivateWindow();
-    qApp->processEvents();
-
-#ifdef Q_WS_X11
-    // to be safe and avoid failing setFocus with window managers
-    qt_x11_wait_for_window_manager(view);
-#endif
-
-    QSGItem *rootObject = view->rootObject();
-    QVERIFY(rootObject);
-
-    QSGItem *scope = findItem<QSGItem>(rootObject, QLatin1String("scope"));
-    QSGItem *itemA1 = findItem<QSGItem>(rootObject, QLatin1String("item-a1"));
-    QSGItem *scopeA = findItem<QSGItem>(rootObject, QLatin1String("scope-a"));
-    QSGItem *itemA2 = findItem<QSGItem>(rootObject, QLatin1String("item-a2"));
-    QSGItem *itemB1 = findItem<QSGItem>(rootObject, QLatin1String("item-b1"));
-    QSGItem *scopeB = findItem<QSGItem>(rootObject, QLatin1String("scope-b"));
-    QSGItem *itemB2 = findItem<QSGItem>(rootObject, QLatin1String("item-b2"));
-
-    QVERIFY(scope);
-    QVERIFY(itemA1);
-    QVERIFY(scopeA);
-    QVERIFY(itemA2);
-    QVERIFY(itemB1);
-    QVERIFY(scopeB);
-    QVERIFY(itemB2);
-
-    QSignalSpy rootSpy(rootObject, SIGNAL(activeFocusChanged(bool)));
-    QSignalSpy scopeSpy(scope, SIGNAL(activeFocusChanged(bool)));
-    QSignalSpy scopeASpy(scopeA, SIGNAL(activeFocusChanged(bool)));
-    QSignalSpy scopeBSpy(scopeB, SIGNAL(activeFocusChanged(bool)));
-
-    // First, walk the focus from item-a1 down to item-a2 and back again
-    itemA1->forceActiveFocus();
-    QVERIFY(itemA1->hasActiveFocus());
-    QVERIFY(!rootObject->hasActiveFocus());
-    QCOMPARE(rootSpy.count(), 0);
-    QCOMPARE(scopeSpy.count(), 1);
-
-    scopeA->forceActiveFocus();
-    QVERIFY(!itemA1->hasActiveFocus());
-    QVERIFY(scopeA->hasActiveFocus());
-    QCOMPARE(scopeASpy.count(), 1);
-    QCOMPARE(rootSpy.count(), 0);
-    QCOMPARE(scopeSpy.count(), 1);
-
-    itemA2->forceActiveFocus();
-    QVERIFY(!itemA1->hasActiveFocus());
-    QVERIFY(itemA2->hasActiveFocus());
-    QVERIFY(scopeA->hasActiveFocus());
-    QCOMPARE(scopeASpy.count(), 1);
-    QCOMPARE(rootSpy.count(), 0);
-    QCOMPARE(scopeSpy.count(), 1);
-
-    scopeA->forceActiveFocus();
-    QVERIFY(!itemA1->hasActiveFocus());
-    QVERIFY(itemA2->hasActiveFocus());
-    QVERIFY(scopeA->hasActiveFocus());
-    QCOMPARE(scopeASpy.count(), 1);
-    QCOMPARE(rootSpy.count(), 0);
-    QCOMPARE(scopeSpy.count(), 1);
-
-    itemA1->forceActiveFocus();
-    QVERIFY(itemA1->hasActiveFocus());
-    QVERIFY(!scopeA->hasActiveFocus());
-    QVERIFY(!itemA2->hasActiveFocus());
-    QCOMPARE(scopeASpy.count(), 2);
-    QCOMPARE(rootSpy.count(), 0);
-    QCOMPARE(scopeSpy.count(), 1);
-
-    // Then jump back and forth between branch 'a' and 'b'
-    itemB1->forceActiveFocus();
-    QVERIFY(itemB1->hasActiveFocus());
-    QCOMPARE(rootSpy.count(), 0);
-    QCOMPARE(scopeSpy.count(), 1);
-
-    scopeA->forceActiveFocus();
-    QVERIFY(!itemA1->hasActiveFocus());
-    QVERIFY(!itemB1->hasActiveFocus());
-    QVERIFY(scopeA->hasActiveFocus());
-    QCOMPARE(scopeASpy.count(), 3);
-    QCOMPARE(rootSpy.count(), 0);
-    QCOMPARE(scopeSpy.count(), 1);
-
-    scopeB->forceActiveFocus();
-    QVERIFY(!scopeA->hasActiveFocus());
-    QVERIFY(!itemB1->hasActiveFocus());
-    QVERIFY(scopeB->hasActiveFocus());
-    QCOMPARE(scopeASpy.count(), 4);
-    QCOMPARE(scopeBSpy.count(), 1);
-    QCOMPARE(rootSpy.count(), 0);
-    QCOMPARE(scopeSpy.count(), 1);
-
-    itemA2->forceActiveFocus();
-    QVERIFY(!scopeB->hasActiveFocus());
-    QVERIFY(itemA2->hasActiveFocus());
-    QCOMPARE(scopeASpy.count(), 5);
-    QCOMPARE(scopeBSpy.count(), 2);
-    QCOMPARE(rootSpy.count(), 0);
-    QCOMPARE(scopeSpy.count(), 1);
-
-    itemB2->forceActiveFocus();
-    QVERIFY(!itemA2->hasActiveFocus());
-    QVERIFY(itemB2->hasActiveFocus());
-    QCOMPARE(scopeASpy.count(), 6);
-    QCOMPARE(scopeBSpy.count(), 3);
-    QCOMPARE(rootSpy.count(), 0);
-    QCOMPARE(scopeSpy.count(), 1);
-
-    delete view;
-}
-
-void tst_qsgfocusscope::canvasFocus()
-{
-    QSGView *view = new QSGView;
-    view->setSource(QUrl::fromLocalFile(TESTDATA("canvasFocus.qml")));
-
-    QSGItem *rootObject = view->rootObject();
-    QVERIFY(rootObject);
-
-    QSGItem *rootItem = view->rootItem();
-    QSGItem *scope1 = findItem<QSGItem>(rootObject, QLatin1String("scope1"));
-    QSGItem *item1 = findItem<QSGItem>(rootObject, QLatin1String("item1"));
-    QSGItem *scope2 = findItem<QSGItem>(rootObject, QLatin1String("scope2"));
-    QSGItem *item2 = findItem<QSGItem>(rootObject, QLatin1String("item2"));
-
-    QVERIFY(scope1);
-    QVERIFY(item1);
-    QVERIFY(scope2);
-    QVERIFY(item2);
-
-    QSignalSpy rootFocusSpy(rootItem, SIGNAL(focusChanged(bool)));
-    QSignalSpy scope1FocusSpy(scope1, SIGNAL(focusChanged(bool)));
-    QSignalSpy item1FocusSpy(item1, SIGNAL(focusChanged(bool)));
-    QSignalSpy scope2FocusSpy(scope2, SIGNAL(focusChanged(bool)));
-    QSignalSpy item2FocusSpy(item2, SIGNAL(focusChanged(bool)));
-    QSignalSpy rootActiveFocusSpy(rootItem, SIGNAL(activeFocusChanged(bool)));
-    QSignalSpy scope1ActiveFocusSpy(scope1, SIGNAL(activeFocusChanged(bool)));
-    QSignalSpy item1ActiveFocusSpy(item1, SIGNAL(activeFocusChanged(bool)));
-    QSignalSpy scope2ActiveFocusSpy(scope2, SIGNAL(activeFocusChanged(bool)));
-    QSignalSpy item2ActiveFocusSpy(item2, SIGNAL(activeFocusChanged(bool)));
-
-    QEXPECT_FAIL("", "QTBUG-21054 - Root item hasFocus returns true already", Abort);
-
-    QCOMPARE(rootItem->hasFocus(), false);
-    QCOMPARE(rootItem->hasActiveFocus(), false);
-    QCOMPARE(scope1->hasFocus(), true);
-    QCOMPARE(scope1->hasActiveFocus(), false);
-    QCOMPARE(item1->hasFocus(), true);
-    QCOMPARE(item1->hasActiveFocus(), false);
-    QCOMPARE(scope2->hasFocus(), false);
-    QCOMPARE(scope2->hasActiveFocus(), false);
-    QCOMPARE(item2->hasFocus(), false);
-    QCOMPARE(item2->hasActiveFocus(), false);
-
-    view->show();
-    view->requestActivateWindow();
-
-    QTest::qWaitForWindowShown(view);
-
-    // Now the canvas has focus, active focus given to item1
-    QCOMPARE(rootItem->hasFocus(), true);
-    QCOMPARE(rootItem->hasActiveFocus(), true);
-    QCOMPARE(scope1->hasFocus(), true);
-    QCOMPARE(scope1->hasActiveFocus(), true);
-    QCOMPARE(item1->hasFocus(), true);
-    QCOMPARE(item1->hasActiveFocus(), true);
-    QCOMPARE(scope2->hasFocus(), false);
-    QCOMPARE(scope2->hasActiveFocus(), false);
-    QCOMPARE(item2->hasFocus(), false);
-    QCOMPARE(item2->hasActiveFocus(), false);
-    QCOMPARE(rootFocusSpy.count(), 1);
-    QCOMPARE(rootActiveFocusSpy.count(), 1);
-    QCOMPARE(scope1FocusSpy.count(), 0);
-    QCOMPARE(scope1ActiveFocusSpy.count(), 1);
-    QCOMPARE(item1FocusSpy.count(), 0);
-    QCOMPARE(item1ActiveFocusSpy.count(), 1);
-
-
-    view->hide();
-    QCOMPARE(rootItem->hasFocus(), false);
-    QCOMPARE(rootItem->hasActiveFocus(), false);
-    QCOMPARE(scope1->hasFocus(), true);
-    QCOMPARE(scope1->hasActiveFocus(), false);
-    QCOMPARE(item1->hasFocus(), true);
-    QCOMPARE(item1->hasActiveFocus(), false);
-    QCOMPARE(rootFocusSpy.count(), 2);
-    QCOMPARE(rootActiveFocusSpy.count(), 2);
-    QCOMPARE(scope1FocusSpy.count(), 0);
-    QCOMPARE(scope1ActiveFocusSpy.count(), 2);
-    QCOMPARE(item1FocusSpy.count(), 0);
-    QCOMPARE(item1ActiveFocusSpy.count(), 2);
-
-    // canvas does not have focus, so item2 will not get active focus
-    item2->forceActiveFocus();
-
-    QCOMPARE(rootItem->hasFocus(), false);
-    QCOMPARE(rootItem->hasActiveFocus(), false);
-    QCOMPARE(scope1->hasFocus(), false);
-    QCOMPARE(scope1->hasActiveFocus(), false);
-    QCOMPARE(item1->hasFocus(), true);
-    QCOMPARE(item1->hasActiveFocus(), false);
-    QCOMPARE(scope2->hasFocus(), true);
-    QCOMPARE(scope2->hasActiveFocus(), false);
-    QCOMPARE(item2->hasFocus(), true);
-    QCOMPARE(item2->hasActiveFocus(), false);
-
-    QCOMPARE(rootFocusSpy.count(), 2);
-    QCOMPARE(rootActiveFocusSpy.count(), 2);
-    QCOMPARE(scope1FocusSpy.count(), 1);
-    QCOMPARE(scope1ActiveFocusSpy.count(), 2);
-    QCOMPARE(item1FocusSpy.count(), 0);
-    QCOMPARE(item1ActiveFocusSpy.count(), 2);
-    QCOMPARE(scope2FocusSpy.count(), 1);
-    QCOMPARE(scope2ActiveFocusSpy.count(), 0);
-    QCOMPARE(item2FocusSpy.count(), 1);
-    QCOMPARE(item2ActiveFocusSpy.count(), 0);
-
-    // give the canvas focus, and item2 will get active focus
-    view->show();
-
-    QCOMPARE(rootItem->hasFocus(), true);
-    QCOMPARE(rootItem->hasActiveFocus(), true);
-    QCOMPARE(scope2->hasFocus(), true);
-    QCOMPARE(scope2->hasActiveFocus(), true);
-    QCOMPARE(item2->hasFocus(), true);
-    QCOMPARE(item2->hasActiveFocus(), true);
-    QCOMPARE(rootFocusSpy.count(), 3);
-    QCOMPARE(rootActiveFocusSpy.count(), 3);
-    QCOMPARE(scope2FocusSpy.count(), 1);
-    QCOMPARE(scope2ActiveFocusSpy.count(), 1);
-    QCOMPARE(item2FocusSpy.count(), 1);
-    QCOMPARE(item2ActiveFocusSpy.count(), 1);
-
-    delete view;
-}
-
-QTEST_MAIN(tst_qsgfocusscope)
-
-#include "tst_qsgfocusscope.moc"
diff --git a/tests/auto/declarative/qsggridview/qsggridview.pro b/tests/auto/declarative/qsggridview/qsggridview.pro
deleted file mode 100644 (file)
index 6588472..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsggridview
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_qsggridview.cpp
-
-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 testlib
diff --git a/tests/auto/declarative/qsggridview/tst_qsggridview.cpp b/tests/auto/declarative/qsggridview/tst_qsggridview.cpp
deleted file mode 100644 (file)
index 9e5c425..0000000
+++ /dev/null
@@ -1,3353 +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 <QtTest/QtTest>
-#include <QtWidgets/qstringlistmodel.h>
-#include <QtDeclarative/qsgview.h>
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtDeclarative/qdeclarativecontext.h>
-#include <QtDeclarative/qdeclarativeexpression.h>
-#include <QtDeclarative/private/qsgitem_p.h>
-#include <QtDeclarative/private/qlistmodelinterface_p.h>
-#include <QtDeclarative/private/qsggridview_p.h>
-#include <QtDeclarative/private/qsgtext_p.h>
-#include <QtDeclarative/private/qdeclarativelistmodel_p.h>
-#include "../shared/util.h"
-#include <QtGui/qguiapplication.h>
-
-Q_DECLARE_METATYPE(Qt::LayoutDirection)
-Q_DECLARE_METATYPE(QSGGridView::Flow)
-
-class tst_QSGGridView : public QObject
-{
-    Q_OBJECT
-public:
-    tst_QSGGridView();
-
-private slots:
-    void initTestCase();
-    void cleanupTestCase();
-    void items();
-    void changed();
-    void inserted();
-    void inserted_more();
-    void inserted_more_data();
-    void removed();
-    void clear();
-    void moved();
-    void moved_data();
-    void multipleChanges();
-    void multipleChanges_data();
-    void swapWithFirstItem();
-    void changeFlow();
-    void currentIndex();
-    void noCurrentIndex();
-    void defaultValues();
-    void properties();
-    void propertyChanges();
-    void componentChanges();
-    void modelChanges();
-    void positionViewAtIndex();
-    void positionViewAtIndex_rightToLeft();
-    void mirroring();
-    void snapping();
-    void resetModel();
-    void enforceRange();
-    void enforceRange_rightToLeft();
-    void QTBUG_8456();
-    void manualHighlight();
-    void footer();
-    void footer_data();
-    void header();
-    void header_data();
-    void resizeViewAndRepaint();
-    void indexAt();
-    void onAdd();
-    void onAdd_data();
-    void onRemove();
-    void onRemove_data();
-    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>
-    QList<T*> findItems(QSGItem *parent, const QString &objectName);
-    void dumpTree(QSGItem *parent, int depth = 0);
-};
-
-template<typename T>
-void tst_qsggridview_move(int from, int to, int n, T *items)
-{
-    if (n == 1) {
-        items->move(from, to);
-    } else {
-        T replaced;
-        int i=0;
-        typename T::ConstIterator it=items->begin(); it += from+n;
-        for (; i<to-from; ++i,++it)
-            replaced.append(*it);
-        i=0;
-        it=items->begin(); it += from;
-        for (; i<n; ++i,++it)
-            replaced.append(*it);
-        typename T::ConstIterator f=replaced.begin();
-        typename T::Iterator t=items->begin(); t += from;
-        for (; f != replaced.end(); ++f, ++t)
-            *t = *f;
-    }
-}
-
-void tst_QSGGridView::initTestCase()
-{
-}
-
-void tst_QSGGridView::cleanupTestCase()
-{
-
-}
-
-
-class TestModel : public QAbstractListModel
-{
-public:
-    enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 };
-
-    TestModel(QObject *parent=0) : QAbstractListModel(parent) {
-        QHash<int, QByteArray> roles;
-        roles[Name] = "name";
-        roles[Number] = "number";
-        setRoleNames(roles);
-    }
-
-    int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); }
-    QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
-        QVariant rv;
-        if (role == Name)
-            rv = list.at(index.row()).first;
-        else if (role == Number)
-            rv = list.at(index.row()).second;
-
-        return rv;
-    }
-
-    int count() const { return rowCount(); }
-    QString name(int index) const { return list.at(index).first; }
-    QString number(int index) const { return list.at(index).second; }
-
-    void addItem(const QString &name, const QString &number) {
-        emit beginInsertRows(QModelIndex(), list.count(), list.count());
-        list.append(QPair<QString,QString>(name, number));
-        emit endInsertRows();
-    }
-
-    void addItems(const QList<QPair<QString, QString> > &items) {
-        emit beginInsertRows(QModelIndex(), list.count(), list.count()+items.count()-1);
-        for (int i=0; i<items.count(); i++)
-            list.append(QPair<QString,QString>(items[i].first, items[i].second));
-        emit endInsertRows();
-    }
-
-    void insertItem(int index, const QString &name, const QString &number) {
-        emit beginInsertRows(QModelIndex(), index, index);
-        list.insert(index, QPair<QString,QString>(name, number));
-        emit endInsertRows();
-    }
-
-    void insertItems(int index, const QList<QPair<QString, QString> > &items) {
-        emit beginInsertRows(QModelIndex(), index, index + items.count() - 1);
-        for (int i=0; i<items.count(); i++)
-            list.insert(index + i, QPair<QString,QString>(items[i].first, items[i].second));
-        emit endInsertRows();
-    }
-
-    void removeItem(int index) {
-        emit beginRemoveRows(QModelIndex(), index, index);
-        list.removeAt(index);
-        emit endRemoveRows();
-    }
-
-    void removeItems(int index, int count) {
-        emit beginRemoveRows(QModelIndex(), index, index+count-1);
-        while (count--)
-            list.removeAt(index);
-        emit endRemoveRows();
-    }
-
-    void moveItem(int from, int to) {
-        emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
-        list.move(from, to);
-        emit endMoveRows();
-    }
-
-    void moveItems(int from, int to, int count) {
-        emit beginMoveRows(QModelIndex(), from, from+count-1, QModelIndex(), to > from ? to+count : to);
-        tst_qsggridview_move(from, to, count, &list);
-        emit endMoveRows();
-    }
-
-    void modifyItem(int idx, const QString &name, const QString &number) {
-        list[idx] = QPair<QString,QString>(name, number);
-        emit dataChanged(index(idx,0), index(idx,0));
-    }
-
-    void clear() {
-        int count = list.count();
-        emit beginRemoveRows(QModelIndex(), 0, count-1);
-        list.clear();
-        emit endRemoveRows();
-    }
-
-
-private:
-    QList<QPair<QString,QString> > list;
-};
-
-tst_QSGGridView::tst_QSGGridView()
-{
-}
-
-void tst_QSGGridView::items()
-{
-    QSGView *canvas = createView();
-
-    TestModel model;
-    model.addItem("Fred", "12345");
-    model.addItem("John", "2345");
-    model.addItem("Bob", "54321");
-    model.addItem("Billy", "22345");
-    model.addItem("Sam", "2945");
-    model.addItem("Ben", "04321");
-    model.addItem("Jim", "0780");
-
-    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);
-
-    QTRY_COMPARE(gridview->count(), model.count());
-    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
-    QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
-
-    for (int i = 0; i < model.count(); ++i) {
-        QSGText *name = findItem<QSGText>(contentItem, "textName", i);
-        QTRY_VERIFY(name != 0);
-        QTRY_COMPARE(name->text(), model.name(i));
-        QSGText *number = findItem<QSGText>(contentItem, "textNumber", i);
-        QTRY_VERIFY(number != 0);
-        QTRY_COMPARE(number->text(), model.number(i));
-    }
-
-    // set an empty model and confirm that items are destroyed
-    TestModel model2;
-    ctxt->setContextProperty("testModel", &model2);
-
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    QTRY_VERIFY(itemCount == 0);
-
-    delete canvas;
-}
-
-void tst_QSGGridView::changed()
-{
-    QSGView *canvas = createView();
-
-    TestModel model;
-    model.addItem("Fred", "12345");
-    model.addItem("John", "2345");
-    model.addItem("Bob", "54321");
-    model.addItem("Billy", "22345");
-    model.addItem("Sam", "2945");
-    model.addItem("Ben", "04321");
-    model.addItem("Jim", "0780");
-
-    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();
-
-    QSGFlickable *gridview = findItem<QSGFlickable>(canvas->rootObject(), "grid");
-    QTRY_VERIFY(gridview != 0);
-
-    QSGItem *contentItem = gridview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    model.modifyItem(1, "Will", "9876");
-    QSGText *name = findItem<QSGText>(contentItem, "textName", 1);
-    QTRY_VERIFY(name != 0);
-    QTRY_COMPARE(name->text(), model.name(1));
-    QSGText *number = findItem<QSGText>(contentItem, "textNumber", 1);
-    QTRY_VERIFY(number != 0);
-    QTRY_COMPARE(number->text(), model.number(1));
-
-    delete canvas;
-}
-
-void tst_QSGGridView::inserted()
-{
-    QSGView *canvas = createView();
-    canvas->show();
-
-    TestModel model;
-    model.addItem("Fred", "12345");
-    model.addItem("John", "2345");
-    model.addItem("Bob", "54321");
-
-    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);
-
-    model.insertItem(1, "Will", "9876");
-
-    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
-    QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
-
-    QSGText *name = findItem<QSGText>(contentItem, "textName", 1);
-    QTRY_VERIFY(name != 0);
-    QTRY_COMPARE(name->text(), model.name(1));
-    QSGText *number = findItem<QSGText>(contentItem, "textNumber", 1);
-    QTRY_VERIFY(number != 0);
-    QTRY_COMPARE(number->text(), model.number(1));
-
-    // Checks that onAdd is called
-    int added = canvas->rootObject()->property("added").toInt();
-    QTRY_COMPARE(added, 1);
-
-    // Confirm items positioned correctly
-    for (int i = 0; i < model.count(); ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        QTRY_COMPARE(item->x(), (i%3)*80.0);
-        QTRY_COMPARE(item->y(), (i/3)*60.0);
-    }
-
-    model.insertItem(0, "Foo", "1111"); // zero index, and current item
-
-    QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
-
-    name = findItem<QSGText>(contentItem, "textName", 0);
-    QTRY_VERIFY(name != 0);
-    QTRY_COMPARE(name->text(), model.name(0));
-    number = findItem<QSGText>(contentItem, "textNumber", 0);
-    QTRY_VERIFY(number != 0);
-    QTRY_COMPARE(number->text(), model.number(0));
-
-    QTRY_COMPARE(gridview->currentIndex(), 1);
-
-    // Confirm items positioned correctly
-    for (int i = 0; i < model.count(); ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        QTRY_VERIFY(item->x() == (i%3)*80);
-        QTRY_VERIFY(item->y() == (i/3)*60);
-    }
-
-    for (int i = model.count(); i < 30; ++i)
-        model.insertItem(i, "Hello", QString::number(i));
-
-    gridview->setContentY(120);
-
-    // Insert item outside visible area
-    model.insertItem(1, "Hello", "1324");
-
-    QTRY_VERIFY(gridview->contentY() == 120);
-
-    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();
-    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));
-    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);
-
-    model.removeItem(1);
-    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
-
-    QSGText *name = findItem<QSGText>(contentItem, "textName", 1);
-    QTRY_VERIFY(name != 0);
-    QTRY_COMPARE(name->text(), model.name(1));
-    QSGText *number = findItem<QSGText>(contentItem, "textNumber", 1);
-    QTRY_VERIFY(number != 0);
-    QTRY_COMPARE(number->text(), model.number(1));
-
-
-    // Checks that onRemove is called
-    QString removed = canvas->rootObject()->property("removed").toString();
-    QTRY_COMPARE(removed, QString("Item1"));
-
-    // Confirm items positioned correctly
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item->x() == (i%3)*80);
-        QTRY_VERIFY(item->y() == (i/3)*60);
-    }
-
-    // Remove first item (which is the current item);
-    model.removeItem(0);
-    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
-
-    name = findItem<QSGText>(contentItem, "textName", 0);
-    QTRY_VERIFY(name != 0);
-    QTRY_COMPARE(name->text(), model.name(0));
-    number = findItem<QSGText>(contentItem, "textNumber", 0);
-    QTRY_VERIFY(number != 0);
-    QTRY_COMPARE(number->text(), model.number(0));
-
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item->x() == (i%3)*80);
-        QTRY_VERIFY(item->y() == (i/3)*60);
-    }
-
-    // Remove items not visible
-    model.removeItem(25);
-    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item->x() == (i%3)*80);
-        QTRY_VERIFY(item->y() == (i/3)*60);
-    }
-
-    // Remove items before visible
-    gridview->setContentY(120);
-    gridview->setCurrentIndex(10);
-
-    // Setting currentIndex above shouldn't cause view to scroll
-    QTRY_COMPARE(gridview->contentY(), 120.0);
-
-    model.removeItem(1);
-    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
-
-    // Confirm items positioned correctly
-    for (int i = 6; i < 18; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item->x() == (i%3)*80);
-        QTRY_VERIFY(item->y() == (i/3)*60);
-    }
-
-    // Remove currentIndex
-    QSGItem *oldCurrent = gridview->currentItem();
-    model.removeItem(9);
-    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
-
-    QTRY_COMPARE(gridview->currentIndex(), 9);
-    QTRY_VERIFY(gridview->currentItem() != oldCurrent);
-
-    gridview->setContentY(0);
-    // let transitions settle.
-    QTest::qWait(300);
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        QTRY_VERIFY(item->x() == (i%3)*80);
-        QTRY_VERIFY(item->y() == (i/3)*60);
-    }
-
-    // remove item outside current view.
-    gridview->setCurrentIndex(32);
-    gridview->setContentY(240);
-
-    model.removeItem(30);
-    QTRY_VERIFY(gridview->currentIndex() == 31);
-
-    // remove current item beyond visible items.
-    gridview->setCurrentIndex(20);
-    gridview->setContentY(0);
-    model.removeItem(20);
-
-    QTRY_COMPARE(gridview->currentIndex(), 20);
-    QTRY_VERIFY(gridview->currentItem() != 0);
-
-    // remove item before current, but visible
-    gridview->setCurrentIndex(8);
-    gridview->setContentY(240);
-    oldCurrent = gridview->currentItem();
-    model.removeItem(6);
-
-    QTRY_COMPARE(gridview->currentIndex(), 7);
-    QTRY_VERIFY(gridview->currentItem() == oldCurrent);
-
-    delete canvas;
-}
-
-void tst_QSGGridView::clear()
-{
-    QSGView *canvas = createView();
-
-    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");
-    QVERIFY(gridview != 0);
-
-    QSGItem *contentItem = gridview->contentItem();
-    QVERIFY(contentItem != 0);
-
-    model.clear();
-
-    QVERIFY(gridview->count() == 0);
-    QVERIFY(gridview->currentItem() == 0);
-    QVERIFY(gridview->contentY() == 0);
-    QVERIFY(gridview->currentIndex() == -1);
-
-    // confirm sanity when adding an item to cleared list
-    model.addItem("New", "1");
-    QTRY_COMPARE(gridview->count(), 1);
-    QVERIFY(gridview->currentItem() != 0);
-    QVERIFY(gridview->currentIndex() == 0);
-
-    delete canvas;
-}
-
-void tst_QSGGridView::moved()
-{
-    QFETCH(qreal, contentY);
-    QFETCH(int, from);
-    QFETCH(int, to);
-    QFETCH(int, count);
-    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);
-
-    QSGItem *currentItem = gridview->currentItem();
-    QTRY_VERIFY(currentItem != 0);
-
-    gridview->setContentY(contentY);
-    model.moveItems(from, to, count);
-
-    // wait for items to move
-    QTest::qWait(300);
-
-    // Confirm items positioned correctly and indexes correct
-    int firstVisibleIndex = qCeil(contentY / 60.0) * 3;
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) {
-        if (i >= firstVisibleIndex + 18)    // index has moved out of view
-            continue;
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
-
-        QTRY_COMPARE(item->x(), (i%3)*80.0);
-        QTRY_COMPARE(item->y(), (i/3)*60.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));
-
-        // current index should have been updated
-        if (item == currentItem)
-            QTRY_COMPARE(gridview->currentIndex(), i);
-    }
-
-    delete canvas;
-}
-
-void tst_QSGGridView::moved_data()
-{
-    QTest::addColumn<qreal>("contentY");
-    QTest::addColumn<int>("from");
-    QTest::addColumn<int>("to");
-    QTest::addColumn<int>("count");
-    QTest::addColumn<qreal>("itemsOffsetAfterMove");
-
-    // model starts with 30 items, each 80x60, in area 240x320
-    // 18 items should be visible at a time
-
-    QTest::newRow("move 1 forwards, within visible items")
-            << 0.0
-            << 1 << 8 << 1
-            << 0.0;
-
-    QTest::newRow("move 1 forwards, from non-visible -> visible")
-            << 120.0     // show 6-23
-            << 1 << 23 << 1
-            << 0.0;     // only 1 item was removed from the 1st row, so it doesn't move down
-
-    QTest::newRow("move 1 forwards, from non-visible -> visible (move first item)")
-            << 120.0     // // show 6-23
-            << 0 << 6 << 1
-            << 0.0;     // only 1 item was removed from the 1st row, so it doesn't move down
-
-    QTest::newRow("move 1 forwards, from visible -> non-visible")
-            << 0.0
-            << 1 << 20 << 1
-            << 0.0;
-
-    QTest::newRow("move 1 forwards, from visible -> non-visible (move first item)")
-            << 0.0
-            << 0 << 20 << 1
-            << 0.0;
-
-
-    QTest::newRow("move 1 backwards, within visible items")
-            << 0.0
-            << 10 << 5 << 1
-            << 0.0;
-
-    QTest::newRow("move 1 backwards, within visible items (to first index)")
-            << 0.0
-            << 10 << 0 << 1
-            << 0.0;
-
-    QTest::newRow("move 1 backwards, from non-visible -> visible")
-            << 0.0
-            << 28 << 8 << 1
-            << 0.0;
-
-    QTest::newRow("move 1 backwards, from non-visible -> visible (move last item)")
-            << 0.0
-            << 29 << 14 << 1
-            << 0.0;
-
-    QTest::newRow("move 1 backwards, from visible -> non-visible")
-            << 120.0     // show 6-23
-            << 7 << 1 << 1
-            << 0.0;     // only 1 item moved back, so items shift accordingly and first row doesn't move
-
-    QTest::newRow("move 1 backwards, from visible -> non-visible (move first item)")
-            << 120.0     // show 6-23
-            << 7 << 0 << 1
-            << 0.0;     // only 1 item moved back, so items shift accordingly and first row doesn't move
-
-
-    QTest::newRow("move multiple forwards, within visible items")
-            << 0.0
-            << 0 << 5 << 3
-            << 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
-            << 1 << 6 << 3
-            << 60.0; // 1st row (it's above visible area) disappears, 0 drops down 1 row, first visible item (6) stays where it is
-
-    QTest::newRow("move multiple forwards, from non-visible -> visible (move first item)")
-            << 120.0     // show 6-23
-            << 0 << 6 << 3
-            << 60.0;    // top row moved and shifted to below 3rd row, all items should shift down by 1 row
-
-    QTest::newRow("move multiple forwards, from visible -> non-visible")
-            << 0.0
-            << 1 << 16 << 3
-            << 0.0;
-
-    QTest::newRow("move multiple forwards, from visible -> non-visible (move first item)")
-            << 0.0
-            << 0 << 16 << 3
-            << 0.0;
-
-
-    QTest::newRow("move multiple backwards, within visible items")
-            << 0.0
-            << 4 << 1 << 3
-            << 0.0;
-
-    QTest::newRow("move multiple backwards, from non-visible -> visible")
-            << 0.0
-            << 20 << 4 << 3
-            << 0.0;
-
-    QTest::newRow("move multiple backwards, from non-visible -> visible (move last item)")
-            << 0.0
-            << 27 << 10 << 3
-            << 0.0;
-
-    QTest::newRow("move multiple backwards, from visible -> non-visible")
-            << 120.0     // show 6-23
-            << 16 << 1 << 3
-            << -60.0;   // to minimize movement, items are added above visible area, all items move up by 1 row
-
-    QTest::newRow("move multiple backwards, from visible -> non-visible (move first item)")
-            << 120.0     // show 6-23
-            << 16 << 0 << 3
-            << -60.0;   // 16,17,18 move to above item 0, all items move up by 1 row
-}
-
-struct ListChange {
-    enum { Inserted, Removed, Moved, SetCurrent } type;
-    int index;
-    int count;
-    int to;     // Move
-
-    static ListChange insert(int index, int count = 1) { ListChange c = { Inserted, index, count, -1 }; return c; }
-    static ListChange remove(int index, int count = 1) { ListChange c = { Removed, index, count, -1 }; return c; }
-    static ListChange move(int index, int to, int count) { ListChange c = { Moved, index, count, to }; return c; }
-    static ListChange setCurrent(int index) { ListChange c = { SetCurrent, index, -1, -1 }; return c; }
-};
-Q_DECLARE_METATYPE(QList<ListChange>)
-
-void tst_QSGGridView::multipleChanges()
-{
-    QFETCH(int, startCount);
-    QFETCH(QList<ListChange>, changes);
-    QFETCH(int, newCount);
-    QFETCH(int, newCurrentIndex);
-
-    QSGView *canvas = createView();
-    canvas->show();
-
-    TestModel model;
-    for (int i = 0; i < startCount; 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);
-
-    for (int i=0; i<changes.count(); i++) {
-        switch (changes[i].type) {
-            case ListChange::Inserted:
-            {
-                QList<QPair<QString, QString> > items;
-                for (int j=changes[i].index; j<changes[i].index + changes[i].count; ++j)
-                    items << qMakePair(QString("new item " + j), QString::number(j));
-                model.insertItems(changes[i].index, items);
-                break;
-            }
-            case ListChange::Removed:
-                model.removeItems(changes[i].index, changes[i].count);
-                break;
-            case ListChange::Moved:
-                model.moveItems(changes[i].index, changes[i].to, changes[i].count);
-                break;
-            case ListChange::SetCurrent:
-                gridview->setCurrentIndex(changes[i].index);
-                break;
-        }
-    }
-
-    QTRY_COMPARE(gridview->count(), newCount);
-    QCOMPARE(gridview->count(), model.count());
-    QTRY_COMPARE(gridview->currentIndex(), newCurrentIndex);
-
-    QSGText *name;
-    QSGText *number;
-    QSGItem *contentItem = gridview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i=0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
-        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;
-}
-
-void tst_QSGGridView::multipleChanges_data()
-{
-    QTest::addColumn<int>("startCount");
-    QTest::addColumn<QList<ListChange> >("changes");
-    QTest::addColumn<int>("newCount");
-    QTest::addColumn<int>("newCurrentIndex");
-
-    QList<ListChange> changes;
-
-    for (int i=1; i<30; i++)
-        changes << ListChange::remove(0);
-    QTest::newRow("remove all but 1, first->last") << 30 << changes << 1 << 0;
-
-    changes << ListChange::remove(0);
-    QTest::newRow("remove all") << 30 << changes << 0 << -1;
-
-    changes.clear();
-    changes << ListChange::setCurrent(29);
-    for (int i=29; i>0; i--)
-        changes << ListChange::remove(i);
-    QTest::newRow("remove last (current) -> first") << 30 << changes << 1 << 0;
-
-    QTest::newRow("remove then insert at 0") << 10 << (QList<ListChange>()
-            << ListChange::remove(0, 1)
-            << ListChange::insert(0, 1)
-            ) << 10 << 1;
-
-    QTest::newRow("remove then insert at non-zero index") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(2)
-            << ListChange::remove(2, 1)
-            << ListChange::insert(2, 1)
-            ) << 10 << 3;
-
-    QTest::newRow("remove current then insert below it") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(1)
-            << ListChange::remove(1, 3)
-            << ListChange::insert(2, 2)
-            ) << 9 << 1;
-
-    QTest::newRow("remove current index then move it down") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(2)
-            << ListChange::remove(1, 3)
-            << ListChange::move(1, 5, 1)
-            ) << 7 << 5;
-
-    QTest::newRow("remove current index then move it up") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(5)
-            << ListChange::remove(4, 3)
-            << ListChange::move(4, 1, 1)
-            ) << 7 << 1;
-
-
-    QTest::newRow("insert multiple times") << 0 << (QList<ListChange>()
-            << ListChange::insert(0, 2)
-            << ListChange::insert(0, 4)
-            << ListChange::insert(0, 6)
-            ) << 12 << 10;
-
-    QTest::newRow("insert multiple times with current index changes") << 0 << (QList<ListChange>()
-            << ListChange::insert(0, 2)
-            << ListChange::insert(0, 4)
-            << ListChange::insert(0, 6)
-            << ListChange::setCurrent(3)
-            << ListChange::insert(3, 2)
-            ) << 14 << 5;
-
-    QTest::newRow("insert and remove all") << 0 << (QList<ListChange>()
-            << ListChange::insert(0, 30)
-            << ListChange::remove(0, 30)
-            ) << 0 << -1;
-
-    QTest::newRow("insert and remove current") << 30 << (QList<ListChange>()
-            << ListChange::insert(1)
-            << ListChange::setCurrent(1)
-            << ListChange::remove(1)
-            ) << 30 << 1;
-
-    QTest::newRow("insert before 0, then remove cross section of new and old items") << 10 << (QList<ListChange>()
-            << ListChange::insert(0, 10)
-            << ListChange::remove(5, 10)
-            ) << 10 << 5;
-
-    QTest::newRow("insert multiple, then move new items to end") << 10 << (QList<ListChange>()
-            << ListChange::insert(0, 3)
-            << ListChange::move(0, 10, 3)
-            ) << 13 << 0;
-
-    QTest::newRow("insert multiple, then move new and some old items to end") << 10 << (QList<ListChange>()
-            << ListChange::insert(0, 3)
-            << ListChange::move(0, 8, 5)
-            ) << 13 << 11;
-
-    QTest::newRow("insert multiple at end, then move new and some old items to start") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(9)
-            << ListChange::insert(10, 3)
-            << ListChange::move(8, 0, 5)
-            ) << 13 << 1;
-
-
-    QTest::newRow("move back and forth to same index") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(1)
-            << ListChange::move(1, 2, 2)
-            << ListChange::move(2, 1, 2)
-            ) << 10 << 1;
-
-    QTest::newRow("move forwards then back") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(2)
-            << ListChange::move(1, 2, 3)
-            << ListChange::move(3, 0, 5)
-            ) << 10 << 0;
-
-    QTest::newRow("move current, then remove it") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(5)
-            << ListChange::move(5, 0, 1)
-            << ListChange::remove(0)
-            ) << 9 << 0;
-
-    QTest::newRow("move current, then insert before it") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(5)
-            << ListChange::move(5, 0, 1)
-            << ListChange::insert(0)
-            ) << 11 << 1;
-
-    QTest::newRow("move multiple, then remove them") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(1)
-            << ListChange::move(5, 1, 3)
-            << ListChange::remove(1, 3)
-            ) << 7 << 1;
-
-    QTest::newRow("move multiple, then insert before them") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(5)
-            << ListChange::move(5, 1, 3)
-            << ListChange::insert(1, 5)
-            ) << 15 << 6;
-
-    QTest::newRow("move multiple, then insert after them") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(3)
-            << ListChange::move(0, 1, 2)
-            << ListChange::insert(3, 5)
-            ) << 15 << 8;
-
-
-    QTest::newRow("clear current") << 0 << (QList<ListChange>()
-            << ListChange::insert(0, 5)
-            << ListChange::setCurrent(-1)
-            << ListChange::remove(0, 5)
-            << ListChange::insert(0, 5)
-            ) << 5 << -1;
-}
-
-
-void tst_QSGGridView::swapWithFirstItem()
-{
-    // QTBUG_9697
-    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);
-
-    // ensure content position is stable
-    gridview->setContentY(0);
-    model.moveItem(10, 0);
-    QTRY_VERIFY(gridview->contentY() == 0);
-
-    delete canvas;
-}
-
-void tst_QSGGridView::currentIndex()
-{
-    TestModel model;
-    for (int i = 0; i < 60; i++)
-        model.addItem("Item" + QString::number(i), QString::number(i));
-
-    QSGView *canvas = new QSGView(0);
-    canvas->setGeometry(0,0,240,320);
-    canvas->show();
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-
-    QString filename(TESTDATA("gridview-initCurrent.qml"));
-    canvas->setSource(QUrl::fromLocalFile(filename));
-
-    qApp->processEvents();
-
-    QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
-    QVERIFY(gridview != 0);
-
-    QSGItem *contentItem = gridview->contentItem();
-    QVERIFY(contentItem != 0);
-
-    // current item should be third item
-    QCOMPARE(gridview->currentIndex(), 35);
-    QCOMPARE(gridview->currentItem(), findItem<QSGItem>(contentItem, "wrapper", 35));
-    QCOMPARE(gridview->currentItem()->y(), gridview->highlightItem()->y());
-    QCOMPARE(gridview->contentY(), 400.0);
-
-    gridview->moveCurrentIndexRight();
-    QCOMPARE(gridview->currentIndex(), 36);
-    gridview->moveCurrentIndexDown();
-    QCOMPARE(gridview->currentIndex(), 39);
-    gridview->moveCurrentIndexUp();
-    QCOMPARE(gridview->currentIndex(), 36);
-    gridview->moveCurrentIndexLeft();
-    QCOMPARE(gridview->currentIndex(), 35);
-
-    // no wrap
-    gridview->setCurrentIndex(0);
-    QCOMPARE(gridview->currentIndex(), 0);
-    // confirm that the velocity is updated
-    QTRY_VERIFY(gridview->verticalVelocity() != 0.0);
-
-    gridview->moveCurrentIndexUp();
-    QCOMPARE(gridview->currentIndex(), 0);
-
-    gridview->moveCurrentIndexLeft();
-    QCOMPARE(gridview->currentIndex(), 0);
-
-    gridview->setCurrentIndex(model.count()-1);
-    QCOMPARE(gridview->currentIndex(), model.count()-1);
-
-    gridview->moveCurrentIndexRight();
-    QCOMPARE(gridview->currentIndex(), model.count()-1);
-
-    gridview->moveCurrentIndexDown();
-    QCOMPARE(gridview->currentIndex(), model.count()-1);
-
-    // with wrap
-    gridview->setWrapEnabled(true);
-
-    gridview->setCurrentIndex(0);
-    QCOMPARE(gridview->currentIndex(), 0);
-
-    gridview->moveCurrentIndexLeft();
-    QCOMPARE(gridview->currentIndex(), model.count()-1);
-
-    qApp->processEvents();
-    QTRY_COMPARE(gridview->contentY(), 880.0);
-
-    gridview->moveCurrentIndexRight();
-    QCOMPARE(gridview->currentIndex(), 0);
-
-    QTRY_COMPARE(gridview->contentY(), 0.0);
-
-
-    // footer should become visible if it is out of view, and then current index moves to the first row
-    canvas->rootObject()->setProperty("showFooter", true);
-    QTRY_VERIFY(gridview->footerItem());
-    gridview->setCurrentIndex(model.count()-3);
-    QTRY_VERIFY(gridview->footerItem()->y() > gridview->contentY() + gridview->height());
-    gridview->setCurrentIndex(model.count()-2);
-    QTRY_COMPARE(gridview->contentY() + gridview->height(), (60.0 * model.count()/3) + gridview->footerItem()->height());
-    canvas->rootObject()->setProperty("showFooter", false);
-
-    // header should become visible if it is out of view, and then current index moves to the last row
-    canvas->rootObject()->setProperty("showHeader", true);
-    QTRY_VERIFY(gridview->headerItem());
-    gridview->setCurrentIndex(3);
-    QTRY_VERIFY(gridview->headerItem()->y() + gridview->headerItem()->height() < gridview->contentY());
-    gridview->setCurrentIndex(1);
-    QTRY_COMPARE(gridview->contentY(), -gridview->headerItem()->height());
-    canvas->rootObject()->setProperty("showHeader", false);
-
-
-    // Test keys
-    canvas->requestActivateWindow();
-    QTest::qWaitForWindowShown(canvas);
-    QTRY_VERIFY(qGuiApp->focusWindow() == canvas);
-
-    gridview->setCurrentIndex(0);
-
-    QTest::keyClick(canvas, Qt::Key_Down);
-    QCOMPARE(gridview->currentIndex(), 3);
-
-    QTest::keyClick(canvas, Qt::Key_Up);
-    QCOMPARE(gridview->currentIndex(), 0);
-
-    // hold down Key_Down
-    for (int i=0; i<(model.count() / 3) - 1; i++) {
-        QTest::simulateEvent(canvas, true, Qt::Key_Down, Qt::NoModifier, "", true);
-        QTRY_COMPARE(gridview->currentIndex(), i*3 + 3);
-    }
-    QTest::keyRelease(canvas, Qt::Key_Down);
-    QTRY_COMPARE(gridview->currentIndex(), 57);
-    QTRY_COMPARE(gridview->contentY(), 880.0);
-
-    // hold down Key_Up
-    for (int i=(model.count() / 3) - 1; i > 0; i--) {
-        QTest::simulateEvent(canvas, true, Qt::Key_Up, Qt::NoModifier, "", true);
-        QTRY_COMPARE(gridview->currentIndex(), i*3 - 3);
-    }
-    QTest::keyRelease(canvas, Qt::Key_Up);
-    QTRY_COMPARE(gridview->currentIndex(), 0);
-    QTRY_COMPARE(gridview->contentY(), 0.0);
-
-
-    gridview->setFlow(QSGGridView::TopToBottom);
-
-    canvas->requestActivateWindow();
-    QTest::qWaitForWindowShown(canvas);
-    QVERIFY(qGuiApp->focusWindow() == canvas);
-    qApp->processEvents();
-
-    QTest::keyClick(canvas, Qt::Key_Right);
-    QCOMPARE(gridview->currentIndex(), 5);
-
-    QTest::keyClick(canvas, Qt::Key_Left);
-    QCOMPARE(gridview->currentIndex(), 0);
-
-    QTest::keyClick(canvas, Qt::Key_Down);
-    QCOMPARE(gridview->currentIndex(), 1);
-
-    QTest::keyClick(canvas, Qt::Key_Up);
-    QCOMPARE(gridview->currentIndex(), 0);
-
-    // hold down Key_Right
-    for (int i=0; i<(model.count() / 5) - 1; i++) {
-        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);
-
-    // hold down Key_Left
-    for (int i=(model.count() / 5) - 1; i > 0; i--) {
-        QTest::simulateEvent(canvas, true, Qt::Key_Left, Qt::NoModifier, "", true);
-        QTRY_COMPARE(gridview->currentIndex(), i*5 - 5);
-    }
-    QTest::keyRelease(canvas, Qt::Key_Left);
-    QTRY_COMPARE(gridview->currentIndex(), 0);
-    QTRY_COMPARE(gridview->contentX(), 0.0);
-
-
-    // turn off auto highlight
-    gridview->setHighlightFollowsCurrentItem(false);
-    QVERIFY(gridview->highlightFollowsCurrentItem() == false);
-    QVERIFY(gridview->highlightItem());
-    qreal hlPosX = gridview->highlightItem()->x();
-    qreal hlPosY = gridview->highlightItem()->y();
-
-    gridview->setCurrentIndex(5);
-    QTRY_COMPARE(gridview->highlightItem()->x(), hlPosX);
-    QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY);
-
-    // insert item before currentIndex
-    gridview->setCurrentIndex(28);
-    model.insertItem(0, "Foo", "1111");
-    QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29);
-
-    // check removing highlight by setting currentIndex to -1;
-    gridview->setCurrentIndex(-1);
-
-    QCOMPARE(gridview->currentIndex(), -1);
-    QVERIFY(!gridview->highlightItem());
-    QVERIFY(!gridview->currentItem());
-
-    gridview->setHighlightFollowsCurrentItem(true);
-
-    gridview->setFlow(QSGGridView::LeftToRight);
-    gridview->setLayoutDirection(Qt::RightToLeft);
-
-    canvas->requestActivateWindow();
-    QTest::qWaitForWindowShown(canvas);
-    QTRY_VERIFY(qGuiApp->focusWindow() == canvas);
-    qApp->processEvents();
-
-    gridview->setCurrentIndex(35);
-
-    QTest::keyClick(canvas, Qt::Key_Right);
-    QCOMPARE(gridview->currentIndex(), 34);
-
-    QTest::keyClick(canvas, Qt::Key_Down);
-    QCOMPARE(gridview->currentIndex(), 37);
-
-    QTest::keyClick(canvas, Qt::Key_Up);
-    QCOMPARE(gridview->currentIndex(), 34);
-
-    QTest::keyClick(canvas, Qt::Key_Left);
-    QCOMPARE(gridview->currentIndex(), 35);
-
-
-    // turn off auto highlight
-    gridview->setHighlightFollowsCurrentItem(false);
-    QVERIFY(gridview->highlightFollowsCurrentItem() == false);
-    QVERIFY(gridview->highlightItem());
-    hlPosX = gridview->highlightItem()->x();
-    hlPosY = gridview->highlightItem()->y();
-
-    gridview->setCurrentIndex(5);
-    QTRY_COMPARE(gridview->highlightItem()->x(), hlPosX);
-    QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY);
-
-    // insert item before currentIndex
-    gridview->setCurrentIndex(28);
-    model.insertItem(0, "Foo", "1111");
-    QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29);
-
-    // check removing highlight by setting currentIndex to -1;
-    gridview->setCurrentIndex(-1);
-
-    QCOMPARE(gridview->currentIndex(), -1);
-    QVERIFY(!gridview->highlightItem());
-    QVERIFY(!gridview->currentItem());
-
-    delete canvas;
-}
-
-void tst_QSGGridView::noCurrentIndex()
-{
-    TestModel model;
-    for (int i = 0; i < 60; i++)
-        model.addItem("Item" + QString::number(i), QString::number(i));
-
-    QSGView *canvas = new QSGView(0);
-    canvas->setGeometry(0,0,240,320);
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-
-    QString filename(TESTDATA("gridview-noCurrent.qml"));
-    canvas->setSource(QUrl::fromLocalFile(filename));
-
-    qApp->processEvents();
-
-    QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
-    QVERIFY(gridview != 0);
-
-    QSGItem *contentItem = gridview->contentItem();
-    QVERIFY(contentItem != 0);
-
-    // current index should be -1
-    QCOMPARE(gridview->currentIndex(), -1);
-    QVERIFY(!gridview->currentItem());
-    QVERIFY(!gridview->highlightItem());
-    QCOMPARE(gridview->contentY(), 0.0);
-
-    gridview->setCurrentIndex(5);
-    QCOMPARE(gridview->currentIndex(), 5);
-    QVERIFY(gridview->currentItem());
-    QVERIFY(gridview->highlightItem());
-
-    delete canvas;
-}
-
-void tst_QSGGridView::changeFlow()
-{
-    QSGView *canvas = createView();
-
-    TestModel model;
-    for (int i = 0; i < 30; i++)
-        model.addItem("Item" + QString::number(i), 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);
-
-    // Confirm items positioned correctly and indexes correct
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->x(), qreal((i%3)*80));
-        QTRY_COMPARE(item->y(), qreal((i/3)*60));
-        QSGText *name = findItem<QSGText>(contentItem, "textName", i);
-        QTRY_VERIFY(name != 0);
-        QTRY_COMPARE(name->text(), model.name(i));
-        QSGText *number = findItem<QSGText>(contentItem, "textNumber", i);
-        QTRY_VERIFY(number != 0);
-        QTRY_COMPARE(number->text(), model.number(i));
-    }
-
-    ctxt->setContextProperty("testTopToBottom", QVariant(true));
-
-    // Confirm items positioned correctly and indexes correct
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->x(), qreal((i/5)*80));
-        QTRY_COMPARE(item->y(), qreal((i%5)*60));
-        QSGText *name = findItem<QSGText>(contentItem, "textName", i);
-        QTRY_VERIFY(name != 0);
-        QTRY_COMPARE(name->text(), model.name(i));
-        QSGText *number = findItem<QSGText>(contentItem, "textNumber", i);
-        QTRY_VERIFY(number != 0);
-        QTRY_COMPARE(number->text(), model.number(i));
-    }
-
-    ctxt->setContextProperty("testRightToLeft", QVariant(true));
-
-    // Confirm items positioned correctly and indexes correct
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->x(), qreal(-(i/5)*80 - item->width()));
-        QTRY_COMPARE(item->y(), qreal((i%5)*60));
-        QSGText *name = findItem<QSGText>(contentItem, "textName", i);
-        QTRY_VERIFY(name != 0);
-        QTRY_COMPARE(name->text(), model.name(i));
-        QSGText *number = findItem<QSGText>(contentItem, "textNumber", i);
-        QTRY_VERIFY(number != 0);
-        QTRY_COMPARE(number->text(), model.number(i));
-    }
-    gridview->setContentX(100);
-    QTRY_COMPARE(gridview->contentX(), 100.);
-    ctxt->setContextProperty("testTopToBottom", QVariant(false));
-    QTRY_COMPARE(gridview->contentX(), 0.);
-
-    // Confirm items positioned correctly and indexes correct
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->x(), qreal(240 - (i%3+1)*80));
-        QTRY_COMPARE(item->y(), qreal((i/3)*60));
-        QSGText *name = findItem<QSGText>(contentItem, "textName", i);
-        QTRY_VERIFY(name != 0);
-        QTRY_COMPARE(name->text(), model.name(i));
-        QSGText *number = findItem<QSGText>(contentItem, "textNumber", i);
-        QTRY_VERIFY(number != 0);
-        QTRY_COMPARE(number->text(), model.number(i));
-    }
-
-    delete canvas;
-}
-
-void tst_QSGGridView::defaultValues()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("gridview3.qml")));
-    QSGGridView *obj = qobject_cast<QSGGridView*>(c.create());
-
-    QTRY_VERIFY(obj != 0);
-    QTRY_VERIFY(obj->model() == QVariant());
-    QTRY_VERIFY(obj->delegate() == 0);
-    QTRY_COMPARE(obj->currentIndex(), -1);
-    QTRY_VERIFY(obj->currentItem() == 0);
-    QTRY_COMPARE(obj->count(), 0);
-    QTRY_VERIFY(obj->highlight() == 0);
-    QTRY_VERIFY(obj->highlightItem() == 0);
-    QTRY_COMPARE(obj->highlightFollowsCurrentItem(), true);
-    QTRY_VERIFY(obj->flow() == 0);
-    QTRY_COMPARE(obj->isWrapEnabled(), false);
-    QTRY_COMPARE(obj->cacheBuffer(), 0);
-    QTRY_COMPARE(obj->cellWidth(), qreal(100)); //### Should 100 be the default?
-    QTRY_COMPARE(obj->cellHeight(), qreal(100));
-    delete obj;
-}
-
-void tst_QSGGridView::properties()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("gridview2.qml")));
-    QSGGridView *obj = qobject_cast<QSGGridView*>(c.create());
-
-    QTRY_VERIFY(obj != 0);
-    QTRY_VERIFY(obj->model() != QVariant());
-    QTRY_VERIFY(obj->delegate() != 0);
-    QTRY_COMPARE(obj->currentIndex(), 0);
-    QTRY_VERIFY(obj->currentItem() != 0);
-    QTRY_COMPARE(obj->count(), 4);
-    QTRY_VERIFY(obj->highlight() != 0);
-    QTRY_VERIFY(obj->highlightItem() != 0);
-    QTRY_COMPARE(obj->highlightFollowsCurrentItem(), false);
-    QTRY_VERIFY(obj->flow() == 0);
-    QTRY_COMPARE(obj->isWrapEnabled(), true);
-    QTRY_COMPARE(obj->cacheBuffer(), 200);
-    QTRY_COMPARE(obj->cellWidth(), qreal(100));
-    QTRY_COMPARE(obj->cellHeight(), qreal(100));
-    delete obj;
-}
-
-void tst_QSGGridView::propertyChanges()
-{
-    QSGView *canvas = createView();
-    QTRY_VERIFY(canvas);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml")));
-
-    QSGGridView *gridView = canvas->rootObject()->findChild<QSGGridView*>("gridView");
-    QTRY_VERIFY(gridView);
-
-    QSignalSpy keyNavigationWrapsSpy(gridView, SIGNAL(keyNavigationWrapsChanged()));
-    QSignalSpy cacheBufferSpy(gridView, SIGNAL(cacheBufferChanged()));
-    QSignalSpy layoutSpy(gridView, SIGNAL(layoutDirectionChanged()));
-    QSignalSpy flowSpy(gridView, SIGNAL(flowChanged()));
-
-    QTRY_COMPARE(gridView->isWrapEnabled(), true);
-    QTRY_COMPARE(gridView->cacheBuffer(), 10);
-    QTRY_COMPARE(gridView->flow(), QSGGridView::LeftToRight);
-
-    gridView->setWrapEnabled(false);
-    gridView->setCacheBuffer(3);
-    gridView->setFlow(QSGGridView::TopToBottom);
-
-    QTRY_COMPARE(gridView->isWrapEnabled(), false);
-    QTRY_COMPARE(gridView->cacheBuffer(), 3);
-    QTRY_COMPARE(gridView->flow(), QSGGridView::TopToBottom);
-
-    QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
-    QTRY_COMPARE(cacheBufferSpy.count(),1);
-    QTRY_COMPARE(flowSpy.count(),1);
-
-    gridView->setWrapEnabled(false);
-    gridView->setCacheBuffer(3);
-    gridView->setFlow(QSGGridView::TopToBottom);
-
-    QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
-    QTRY_COMPARE(cacheBufferSpy.count(),1);
-    QTRY_COMPARE(flowSpy.count(),1);
-
-    gridView->setFlow(QSGGridView::LeftToRight);
-    QTRY_COMPARE(gridView->flow(), QSGGridView::LeftToRight);
-
-    gridView->setWrapEnabled(true);
-    gridView->setCacheBuffer(5);
-    gridView->setLayoutDirection(Qt::RightToLeft);
-
-    QTRY_COMPARE(gridView->isWrapEnabled(), true);
-    QTRY_COMPARE(gridView->cacheBuffer(), 5);
-    QTRY_COMPARE(gridView->layoutDirection(), Qt::RightToLeft);
-
-    QTRY_COMPARE(keyNavigationWrapsSpy.count(),2);
-    QTRY_COMPARE(cacheBufferSpy.count(),2);
-    QTRY_COMPARE(layoutSpy.count(),1);
-    QTRY_COMPARE(flowSpy.count(),2);
-
-    gridView->setWrapEnabled(true);
-    gridView->setCacheBuffer(5);
-    gridView->setLayoutDirection(Qt::RightToLeft);
-
-    QTRY_COMPARE(keyNavigationWrapsSpy.count(),2);
-    QTRY_COMPARE(cacheBufferSpy.count(),2);
-    QTRY_COMPARE(layoutSpy.count(),1);
-    QTRY_COMPARE(flowSpy.count(),2);
-
-    gridView->setFlow(QSGGridView::TopToBottom);
-    QTRY_COMPARE(gridView->flow(), QSGGridView::TopToBottom);
-    QTRY_COMPARE(flowSpy.count(),3);
-
-    gridView->setFlow(QSGGridView::TopToBottom);
-    QTRY_COMPARE(flowSpy.count(),3);
-
-    delete canvas;
-}
-
-void tst_QSGGridView::componentChanges()
-{
-    QSGView *canvas = createView();
-    QTRY_VERIFY(canvas);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml")));
-
-    QSGGridView *gridView = canvas->rootObject()->findChild<QSGGridView*>("gridView");
-    QTRY_VERIFY(gridView);
-
-    QDeclarativeComponent component(canvas->engine());
-    component.setData("import QtQuick 1.0; Rectangle { color: \"blue\"; }", QUrl::fromLocalFile(""));
-
-    QDeclarativeComponent delegateComponent(canvas->engine());
-    delegateComponent.setData("import QtQuick 1.0; Text { text: '<b>Name:</b> ' + name }", QUrl::fromLocalFile(""));
-
-    QSignalSpy highlightSpy(gridView, SIGNAL(highlightChanged()));
-    QSignalSpy delegateSpy(gridView, SIGNAL(delegateChanged()));
-    QSignalSpy headerSpy(gridView, SIGNAL(headerChanged()));
-    QSignalSpy footerSpy(gridView, SIGNAL(footerChanged()));
-
-    gridView->setHighlight(&component);
-    gridView->setDelegate(&delegateComponent);
-    gridView->setHeader(&component);
-    gridView->setFooter(&component);
-
-    QTRY_COMPARE(gridView->highlight(), &component);
-    QTRY_COMPARE(gridView->delegate(), &delegateComponent);
-    QTRY_COMPARE(gridView->header(), &component);
-    QTRY_COMPARE(gridView->footer(), &component);
-
-    QTRY_COMPARE(highlightSpy.count(),1);
-    QTRY_COMPARE(delegateSpy.count(),1);
-    QTRY_COMPARE(headerSpy.count(),1);
-    QTRY_COMPARE(footerSpy.count(),1);
-
-    gridView->setHighlight(&component);
-    gridView->setDelegate(&delegateComponent);
-    gridView->setHeader(&component);
-    gridView->setFooter(&component);
-
-    QTRY_COMPARE(highlightSpy.count(),1);
-    QTRY_COMPARE(delegateSpy.count(),1);
-    QTRY_COMPARE(headerSpy.count(),1);
-    QTRY_COMPARE(footerSpy.count(),1);
-
-    delete canvas;
-}
-
-void tst_QSGGridView::modelChanges()
-{
-    QSGView *canvas = createView();
-    QTRY_VERIFY(canvas);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml")));
-
-    QSGGridView *gridView = canvas->rootObject()->findChild<QSGGridView*>("gridView");
-    QTRY_VERIFY(gridView);
-
-    QDeclarativeListModel *alternateModel = canvas->rootObject()->findChild<QDeclarativeListModel*>("alternateModel");
-    QTRY_VERIFY(alternateModel);
-    QVariant modelVariant = QVariant::fromValue<QObject *>(alternateModel);
-    QSignalSpy modelSpy(gridView, SIGNAL(modelChanged()));
-
-    gridView->setModel(modelVariant);
-    QTRY_COMPARE(gridView->model(), modelVariant);
-    QTRY_COMPARE(modelSpy.count(),1);
-
-    gridView->setModel(modelVariant);
-    QTRY_COMPARE(modelSpy.count(),1);
-
-    gridView->setModel(QVariant());
-    QTRY_COMPARE(modelSpy.count(),2);
-    delete canvas;
-}
-
-void tst_QSGGridView::positionViewAtIndex()
-{
-    QSGView *canvas = createView();
-
-    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));
-    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);
-
-    // Confirm items positioned correctly
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->x(), (i%3)*80.);
-        QTRY_COMPARE(item->y(), (i/3)*60.);
-    }
-
-    // Position on a currently visible item
-    gridview->positionViewAtIndex(4, QSGGridView::Beginning);
-    QTRY_COMPARE(gridview->indexAt(120, 90), 4);
-    QTRY_COMPARE(gridview->contentY(), 60.);
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 3; i < model.count() && i < itemCount-3-1; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->x(), (i%3)*80.);
-        QTRY_COMPARE(item->y(), (i/3)*60.);
-    }
-
-    // Position on an item beyond the visible items
-    gridview->positionViewAtIndex(21, QSGGridView::Beginning);
-    QTRY_COMPARE(gridview->indexAt(40, 450), 21);
-    QTRY_COMPARE(gridview->contentY(), 420.);
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 22; i < model.count() && i < itemCount-22-1; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->x(), (i%3)*80.);
-        QTRY_COMPARE(item->y(), (i/3)*60.);
-    }
-
-    // Position on an item that would leave empty space if positioned at the top
-    gridview->positionViewAtIndex(31, QSGGridView::Beginning);
-    QTRY_COMPARE(gridview->indexAt(120, 630), 31);
-    QTRY_COMPARE(gridview->contentY(), 520.);
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 24; i < model.count() && i < itemCount-24-1; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->x(), (i%3)*80.);
-        QTRY_COMPARE(item->y(), (i/3)*60.);
-    }
-
-    // Position at the beginning again
-    gridview->positionViewAtIndex(0, QSGGridView::Beginning);
-    QTRY_COMPARE(gridview->indexAt(0, 0), 0);
-    QTRY_COMPARE(gridview->indexAt(40, 30), 0);
-    QTRY_COMPARE(gridview->indexAt(80, 60), 4);
-    QTRY_COMPARE(gridview->contentY(), 0.);
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->x(), (i%3)*80.);
-        QTRY_COMPARE(item->y(), (i/3)*60.);
-    }
-
-    // Position at End
-    gridview->positionViewAtIndex(30, QSGGridView::End);
-    QTRY_COMPARE(gridview->contentY(), 340.);
-
-    // Position in Center
-    gridview->positionViewAtIndex(15, QSGGridView::Center);
-    QTRY_COMPARE(gridview->contentY(), 170.);
-
-    // Ensure at least partially visible
-    gridview->positionViewAtIndex(15, QSGGridView::Visible);
-    QTRY_COMPARE(gridview->contentY(), 170.);
-
-    gridview->setContentY(302);
-    gridview->positionViewAtIndex(15, QSGGridView::Visible);
-    QTRY_COMPARE(gridview->contentY(), 302.);
-
-    gridview->setContentY(360);
-    gridview->positionViewAtIndex(15, QSGGridView::Visible);
-    QTRY_COMPARE(gridview->contentY(), 300.);
-
-    gridview->setContentY(60);
-    gridview->positionViewAtIndex(20, QSGGridView::Visible);
-    QTRY_COMPARE(gridview->contentY(), 60.);
-
-    gridview->setContentY(20);
-    gridview->positionViewAtIndex(20, QSGGridView::Visible);
-    QTRY_COMPARE(gridview->contentY(), 100.);
-
-    // Ensure completely visible
-    gridview->setContentY(120);
-    gridview->positionViewAtIndex(20, QSGGridView::Contain);
-    QTRY_COMPARE(gridview->contentY(), 120.);
-
-    gridview->setContentY(302);
-    gridview->positionViewAtIndex(15, QSGGridView::Contain);
-    QTRY_COMPARE(gridview->contentY(), 300.);
-
-    gridview->setContentY(60);
-    gridview->positionViewAtIndex(20, QSGGridView::Contain);
-    QTRY_COMPARE(gridview->contentY(), 100.);
-
-    // Test for Top To Bottom layout
-    ctxt->setContextProperty("testTopToBottom", QVariant(true));
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->x(), (i/5)*80.);
-        QTRY_COMPARE(item->y(), (i%5)*60.);
-    }
-
-    // Position at End
-    gridview->positionViewAtIndex(30, QSGGridView::End);
-    QTRY_COMPARE(gridview->contentX(), 320.);
-    QTRY_COMPARE(gridview->contentY(), 0.);
-
-    // Position in Center
-    gridview->positionViewAtIndex(15, QSGGridView::Center);
-    QTRY_COMPARE(gridview->contentX(), 160.);
-
-    // Ensure at least partially visible
-    gridview->positionViewAtIndex(15, QSGGridView::Visible);
-    QTRY_COMPARE(gridview->contentX(), 160.);
-
-    gridview->setContentX(170);
-    gridview->positionViewAtIndex(25, QSGGridView::Visible);
-    QTRY_COMPARE(gridview->contentX(), 170.);
-
-    gridview->positionViewAtIndex(30, QSGGridView::Visible);
-    QTRY_COMPARE(gridview->contentX(), 320.);
-
-    gridview->setContentX(170);
-    gridview->positionViewAtIndex(25, QSGGridView::Contain);
-    QTRY_COMPARE(gridview->contentX(), 240.);
-
-    // positionViewAtBeginning
-    gridview->positionViewAtBeginning();
-    QTRY_COMPARE(gridview->contentX(), 0.);
-
-    gridview->setContentX(80);
-    canvas->rootObject()->setProperty("showHeader", true);
-    gridview->positionViewAtBeginning();
-    QTRY_COMPARE(gridview->contentX(), -30.);
-
-    // positionViewAtEnd
-    gridview->positionViewAtEnd();
-    QTRY_COMPARE(gridview->contentX(), 400.);   // 8*80 - 240   (8 columns)
-
-    gridview->setContentX(80);
-    canvas->rootObject()->setProperty("showFooter", true);
-    gridview->positionViewAtEnd();
-    QTRY_COMPARE(gridview->contentX(), 430.);
-
-    // set current item to outside visible view, position at beginning
-    // and ensure highlight moves to current item
-    gridview->setCurrentIndex(6);
-    gridview->positionViewAtBeginning();
-    QTRY_COMPARE(gridview->contentX(), -30.);
-    QVERIFY(gridview->highlightItem());
-    QCOMPARE(gridview->highlightItem()->x(), 80.);
-
-    delete canvas;
-}
-
-void tst_QSGGridView::snapping()
-{
-    QSGView *canvas = createView();
-
-    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("testTopToBottom", QVariant(false));
-    ctxt->setContextProperty("testRightToLeft", QVariant(false));
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml")));
-    qApp->processEvents();
-
-    QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
-    QTRY_VERIFY(gridview != 0);
-
-    gridview->setHeight(220);
-    QCOMPARE(gridview->height(), 220.);
-
-    gridview->positionViewAtIndex(12, QSGGridView::Visible);
-    QCOMPARE(gridview->contentY(), 80.);
-
-    gridview->setContentY(0);
-    QCOMPARE(gridview->contentY(), 0.);
-
-    gridview->setSnapMode(QSGGridView::SnapToRow);
-    QCOMPARE(gridview->snapMode(), QSGGridView::SnapToRow);
-
-    gridview->positionViewAtIndex(12, QSGGridView::Visible);
-    QCOMPARE(gridview->contentY(), 60.);
-
-    gridview->positionViewAtIndex(15, QSGGridView::End);
-    QCOMPARE(gridview->contentY(), 120.);
-
-    delete canvas;
-
-}
-
-void tst_QSGGridView::mirroring()
-{
-    QSGView *canvasA = createView();
-    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(TESTDATA("mirroring.qml")));
-    QSGGridView *gridviewB = findItem<QSGGridView>(canvasB->rootObject(), "view");
-    QTRY_VERIFY(gridviewA != 0);
-    qApp->processEvents();
-
-    QList<QString> objectNames;
-    objectNames << "item1" << "item2"; // << "item3"
-
-    gridviewA->setProperty("layoutDirection", Qt::LeftToRight);
-    gridviewB->setProperty("layoutDirection", Qt::RightToLeft);
-    QCOMPARE(gridviewA->layoutDirection(), gridviewA->effectiveLayoutDirection());
-
-    // LTR != RTL
-    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)
-        QCOMPARE(findItem<QSGItem>(gridviewA, objectName)->x(), findItem<QSGItem>(gridviewB, objectName)->x());
-
-    QVERIFY(gridviewB->layoutDirection() == gridviewB->effectiveLayoutDirection());
-    QSGItemPrivate::get(gridviewB)->setLayoutMirror(true);
-    QVERIFY(gridviewB->layoutDirection() != gridviewB->effectiveLayoutDirection());
-
-    // LTR != LTR+mirror
-    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)
-        QCOMPARE(findItem<QSGItem>(gridviewA, objectName)->x(), findItem<QSGItem>(gridviewB, objectName)->x());
-
-    gridviewB->setProperty("layoutDirection", Qt::RightToLeft);
-
-    // RTL != RTL+mirror
-    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)
-        QCOMPARE(findItem<QSGItem>(gridviewA, objectName)->x(), findItem<QSGItem>(gridviewB, objectName)->x());
-
-    delete canvasA;
-    delete canvasB;
-}
-
-void tst_QSGGridView::positionViewAtIndex_rightToLeft()
-{
-    QSGView *canvas = createView();
-
-    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("testTopToBottom", QVariant(true));
-    ctxt->setContextProperty("testRightToLeft", QVariant(true));
-
-    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);
-
-    // Confirm items positioned correctly
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
-        QTRY_COMPARE(item->y(), qreal((i%5)*60));
-    }
-
-    // Position on a currently visible item
-    gridview->positionViewAtIndex(6, QSGGridView::Beginning);
-    QTRY_COMPARE(gridview->contentX(), -320.);
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 3; i < model.count() && i < itemCount-3-1; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
-        QTRY_COMPARE(item->y(), qreal((i%5)*60));
-    }
-
-    // Position on an item beyond the visible items
-    gridview->positionViewAtIndex(21, QSGGridView::Beginning);
-    QTRY_COMPARE(gridview->contentX(), -560.);
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 22; i < model.count() && i < itemCount-22-1; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
-        QTRY_COMPARE(item->y(), qreal((i%5)*60));
-    }
-
-    // Position on an item that would leave empty space if positioned at the top
-    gridview->positionViewAtIndex(31, QSGGridView::Beginning);
-    QTRY_COMPARE(gridview->contentX(), -640.);
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 24; i < model.count() && i < itemCount-24-1; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
-        QTRY_COMPARE(item->y(), qreal((i%5)*60));
-    }
-
-    // Position at the beginning again
-    gridview->positionViewAtIndex(0, QSGGridView::Beginning);
-    QTRY_COMPARE(gridview->contentX(), -240.);
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width()));
-        QTRY_COMPARE(item->y(), qreal((i%5)*60));
-    }
-
-    // Position at End
-    gridview->positionViewAtIndex(30, QSGGridView::End);
-    QTRY_COMPARE(gridview->contentX(), -560.);
-
-    // Position in Center
-    gridview->positionViewAtIndex(15, QSGGridView::Center);
-    QTRY_COMPARE(gridview->contentX(), -400.);
-
-    // Ensure at least partially visible
-    gridview->positionViewAtIndex(15, QSGGridView::Visible);
-    QTRY_COMPARE(gridview->contentX(), -400.);
-
-    gridview->setContentX(-555.);
-    gridview->positionViewAtIndex(15, QSGGridView::Visible);
-    QTRY_COMPARE(gridview->contentX(), -555.);
-
-    gridview->setContentX(-239);
-    gridview->positionViewAtIndex(15, QSGGridView::Visible);
-    QTRY_COMPARE(gridview->contentX(), -320.);
-
-    gridview->setContentX(-239);
-    gridview->positionViewAtIndex(20, QSGGridView::Visible);
-    QTRY_COMPARE(gridview->contentX(), -400.);
-
-    gridview->setContentX(-640);
-    gridview->positionViewAtIndex(20, QSGGridView::Visible);
-    QTRY_COMPARE(gridview->contentX(), -560.);
-
-    // Ensure completely visible
-    gridview->setContentX(-400);
-    gridview->positionViewAtIndex(20, QSGGridView::Contain);
-    QTRY_COMPARE(gridview->contentX(), -400.);
-
-    gridview->setContentX(-315);
-    gridview->positionViewAtIndex(15, QSGGridView::Contain);
-    QTRY_COMPARE(gridview->contentX(), -320.);
-
-    gridview->setContentX(-640);
-    gridview->positionViewAtIndex(20, QSGGridView::Contain);
-    QTRY_COMPARE(gridview->contentX(), -560.);
-
-    delete canvas;
-}
-
-void tst_QSGGridView::resetModel()
-{
-    QSGView *canvas = createView();
-
-    QStringList strings;
-    strings << "one" << "two" << "three";
-    QStringListModel model(strings);
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaygrid.qml")));
-    qApp->processEvents();
-
-    QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
-    QTRY_VERIFY(gridview != 0);
-
-    QSGItem *contentItem = gridview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    QTRY_COMPARE(gridview->count(), model.rowCount());
-
-    for (int i = 0; i < model.rowCount(); ++i) {
-        QSGText *display = findItem<QSGText>(contentItem, "displayText", i);
-        QTRY_VERIFY(display != 0);
-        QTRY_COMPARE(display->text(), strings.at(i));
-    }
-
-    strings.clear();
-    strings << "four" << "five" << "six" << "seven";
-    model.setStringList(strings);
-
-    QTRY_COMPARE(gridview->count(), model.rowCount());
-
-    for (int i = 0; i < model.rowCount(); ++i) {
-        QSGText *display = findItem<QSGText>(contentItem, "displayText", i);
-        QTRY_VERIFY(display != 0);
-        QTRY_COMPARE(display->text(), strings.at(i));
-    }
-
-    delete canvas;
-}
-
-void tst_QSGGridView::enforceRange()
-{
-    QSGView *canvas = createView();
-
-    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("gridview-enforcerange.qml")));
-    qApp->processEvents();
-    QVERIFY(canvas->rootObject() != 0);
-
-    QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
-    QTRY_VERIFY(gridview != 0);
-
-    QTRY_COMPARE(gridview->preferredHighlightBegin(), 100.0);
-    QTRY_COMPARE(gridview->preferredHighlightEnd(), 100.0);
-    QTRY_COMPARE(gridview->highlightRangeMode(), QSGGridView::StrictlyEnforceRange);
-
-    QSGItem *contentItem = gridview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    // view should be positioned at the top of the range.
-    QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", 0);
-    QTRY_VERIFY(item);
-    QTRY_COMPARE(gridview->contentY(), -100.0);
-
-    QSGText *name = findItem<QSGText>(contentItem, "textName", 0);
-    QTRY_VERIFY(name != 0);
-    QTRY_COMPARE(name->text(), model.name(0));
-    QSGText *number = findItem<QSGText>(contentItem, "textNumber", 0);
-    QTRY_VERIFY(number != 0);
-    QTRY_COMPARE(number->text(), model.number(0));
-
-    // Check currentIndex is updated when contentItem moves
-    gridview->setContentY(0);
-    QTRY_COMPARE(gridview->currentIndex(), 2);
-
-    gridview->setCurrentIndex(5);
-    QTRY_COMPARE(gridview->contentY(), 100.);
-
-    TestModel model2;
-    for (int i = 0; i < 5; i++)
-        model2.addItem("Item" + QString::number(i), "");
-
-    ctxt->setContextProperty("testModel", &model2);
-    QCOMPARE(gridview->count(), 5);
-
-    delete canvas;
-}
-
-void tst_QSGGridView::enforceRange_rightToLeft()
-{
-    QSGView *canvas = createView();
-
-    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(true));
-    ctxt->setContextProperty("testTopToBottom", QVariant(true));
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview-enforcerange.qml")));
-    qApp->processEvents();
-    QVERIFY(canvas->rootObject() != 0);
-
-    QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
-    QTRY_VERIFY(gridview != 0);
-
-    QTRY_COMPARE(gridview->preferredHighlightBegin(), 100.0);
-    QTRY_COMPARE(gridview->preferredHighlightEnd(), 100.0);
-    QTRY_COMPARE(gridview->highlightRangeMode(), QSGGridView::StrictlyEnforceRange);
-
-    QSGItem *contentItem = gridview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    // view should be positioned at the top of the range.
-    QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", 0);
-    QTRY_VERIFY(item);
-    QTRY_COMPARE(gridview->contentX(), -100.);
-    QTRY_COMPARE(gridview->contentY(), 0.0);
-
-    QSGText *name = findItem<QSGText>(contentItem, "textName", 0);
-    QTRY_VERIFY(name != 0);
-    QTRY_COMPARE(name->text(), model.name(0));
-    QSGText *number = findItem<QSGText>(contentItem, "textNumber", 0);
-    QTRY_VERIFY(number != 0);
-    QTRY_COMPARE(number->text(), model.number(0));
-
-    // Check currentIndex is updated when contentItem moves
-    gridview->setContentX(-200);
-    QTRY_COMPARE(gridview->currentIndex(), 3);
-
-    gridview->setCurrentIndex(7);
-    QTRY_COMPARE(gridview->contentX(), -300.);
-    QTRY_COMPARE(gridview->contentY(), 0.0);
-
-    TestModel model2;
-    for (int i = 0; i < 5; i++)
-        model2.addItem("Item" + QString::number(i), "");
-
-    ctxt->setContextProperty("testModel", &model2);
-    QCOMPARE(gridview->count(), 5);
-
-    delete canvas;
-}
-
-void tst_QSGGridView::QTBUG_8456()
-{
-    QSGView *canvas = createView();
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("setindex.qml")));
-    qApp->processEvents();
-
-    QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
-    QTRY_VERIFY(gridview != 0);
-
-    QTRY_COMPARE(gridview->currentIndex(), 0);
-
-    delete canvas;
-}
-
-void tst_QSGGridView::manualHighlight()
-{
-    QSGView *canvas = createView();
-
-    QString filename(TESTDATA("manual-highlight.qml"));
-    canvas->setSource(QUrl::fromLocalFile(filename));
-
-    qApp->processEvents();
-
-    QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
-    QTRY_VERIFY(gridview != 0);
-
-    QSGItem *contentItem = gridview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    QTRY_COMPARE(gridview->currentIndex(), 0);
-    QTRY_COMPARE(gridview->currentItem(), findItem<QSGItem>(contentItem, "wrapper", 0));
-    QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
-    QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
-
-    gridview->setCurrentIndex(2);
-
-    QTRY_COMPARE(gridview->currentIndex(), 2);
-    QTRY_COMPARE(gridview->currentItem(), findItem<QSGItem>(contentItem, "wrapper", 2));
-    QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
-    QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
-
-    gridview->positionViewAtIndex(8, QSGGridView::Contain);
-
-    QTRY_COMPARE(gridview->currentIndex(), 2);
-    QTRY_COMPARE(gridview->currentItem(), findItem<QSGItem>(contentItem, "wrapper", 2));
-    QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
-    QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
-
-    gridview->setFlow(QSGGridView::TopToBottom);
-    QTRY_COMPARE(gridview->flow(), QSGGridView::TopToBottom);
-
-    gridview->setCurrentIndex(0);
-    QTRY_COMPARE(gridview->currentIndex(), 0);
-    QTRY_COMPARE(gridview->currentItem(), findItem<QSGItem>(contentItem, "wrapper", 0));
-    QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y());
-    QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x());
-
-    delete canvas;
-}
-
-
-void tst_QSGGridView::footer()
-{
-    QFETCH(QSGGridView::Flow, flow);
-    QFETCH(Qt::LayoutDirection, layoutDirection);
-    QFETCH(QPointF, initialFooterPos);
-    QFETCH(QPointF, changedFooterPos);
-    QFETCH(QPointF, initialContentPos);
-    QFETCH(QPointF, changedContentPos);
-    QFETCH(QPointF, firstDelegatePos);
-    QFETCH(QPointF, resizeContentPos);
-
-    QSGView *canvas = createView();
-    canvas->show();
-
-    TestModel model;
-    for (int i = 0; i < 7; i++)
-        model.addItem("Item" + QString::number(i), "");
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("footer.qml")));
-    qApp->processEvents();
-
-    QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
-    QTRY_VERIFY(gridview != 0);
-    gridview->setFlow(flow);
-    gridview->setLayoutDirection(layoutDirection);
-
-    QSGItem *contentItem = gridview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    QSGText *footer = findItem<QSGText>(contentItem, "footer");
-    QVERIFY(footer);
-
-    QVERIFY(footer == gridview->footerItem());
-
-    QCOMPARE(footer->pos(), initialFooterPos);
-    QCOMPARE(footer->width(), 100.);
-    QCOMPARE(footer->height(), 30.);
-    QCOMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos);
-
-    QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", 0);
-    QVERIFY(item);
-    QCOMPARE(item->pos(), firstDelegatePos);
-
-    if (flow == QSGGridView::LeftToRight) {
-        // shrink by one row
-        model.removeItem(2);
-        QTRY_COMPARE(footer->y(), initialFooterPos.y() - gridview->cellHeight());
-    } else {
-        // shrink by one column
-        model.removeItem(2);
-        model.removeItem(3);
-        if (layoutDirection == Qt::LeftToRight)
-            QTRY_COMPARE(footer->x(), initialFooterPos.x() - gridview->cellWidth());
-        else
-            QTRY_COMPARE(footer->x(), initialFooterPos.x() + gridview->cellWidth());
-    }
-
-    // remove all items
-    model.clear();
-
-    QPointF posWhenNoItems(0, 0);
-    if (layoutDirection == Qt::RightToLeft)
-        posWhenNoItems.setX(flow == QSGGridView::LeftToRight ? gridview->width() - footer->width() : -footer->width());
-    QTRY_COMPARE(footer->pos(), posWhenNoItems);
-
-    // if header is present, it's at a negative pos, so the footer should not move
-    canvas->rootObject()->setProperty("showHeader", true);
-    QVERIFY(findItem<QSGItem>(contentItem, "header") != 0);
-    QTRY_COMPARE(footer->pos(), posWhenNoItems);
-    canvas->rootObject()->setProperty("showHeader", false);
-
-    // add 30 items
-    for (int i = 0; i < 30; i++)
-        model.addItem("Item" + QString::number(i), "");
-
-    QSignalSpy footerItemSpy(gridview, SIGNAL(footerItemChanged()));
-    QMetaObject::invokeMethod(canvas->rootObject(), "changeFooter");
-
-    QCOMPARE(footerItemSpy.count(), 1);
-
-    footer = findItem<QSGText>(contentItem, "footer");
-    QVERIFY(!footer);
-    footer = findItem<QSGText>(contentItem, "footer2");
-    QVERIFY(footer);
-
-    QVERIFY(footer == gridview->footerItem());
-
-    QCOMPARE(footer->pos(), changedFooterPos);
-    QCOMPARE(footer->width(), 50.);
-    QCOMPARE(footer->height(), 20.);
-    QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), changedContentPos);
-
-    item = findItem<QSGItem>(contentItem, "wrapper", 0);
-    QVERIFY(item);
-    QCOMPARE(item->pos(), firstDelegatePos);
-
-    gridview->positionViewAtEnd();
-    footer->setHeight(10);
-    footer->setWidth(40);
-    QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), resizeContentPos);
-
-    delete canvas;
-}
-
-void tst_QSGGridView::footer_data()
-{
-    QTest::addColumn<QSGGridView::Flow>("flow");
-    QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
-    QTest::addColumn<QPointF>("initialFooterPos");
-    QTest::addColumn<QPointF>("changedFooterPos");
-    QTest::addColumn<QPointF>("initialContentPos");
-    QTest::addColumn<QPointF>("changedContentPos");
-    QTest::addColumn<QPointF>("firstDelegatePos");
-    QTest::addColumn<QPointF>("resizeContentPos");
-
-    // footer1 = 100 x 30
-    // footer2 = 50 x 20
-    // cells = 80 * 60
-    // view width = 240
-    // view height = 320
-
-    // footer below items, bottom left
-    QTest::newRow("flow left to right") << QSGGridView::LeftToRight << Qt::LeftToRight
-        << QPointF(0, 3 * 60)  // 180 = height of 3 rows (cell height is 60)
-        << QPointF(0, 10 * 60)  // 30 items = 10 rows
-        << QPointF(0, 0)
-        << QPointF(0, 0)
-        << QPointF(0, 0)
-        << QPointF(0, 10 * 60 - 320 + 10);
-
-    // footer below items, bottom right
-    QTest::newRow("flow left to right, layout right to left") << QSGGridView::LeftToRight << Qt::RightToLeft
-        << QPointF(240 - 100, 3 * 60)
-        << QPointF((240 - 100) + 50, 10 * 60)     // 50 = width diff between old and new footers
-        << QPointF(0, 0)
-        << QPointF(0, 0)
-        << QPointF(240 - 80, 0)
-        << QPointF(0, 10 * 60 - 320 + 10);
-
-    // footer to right of items
-    QTest::newRow("flow top to bottom, layout left to right") << QSGGridView::TopToBottom << Qt::LeftToRight
-        << QPointF(2 * 80, 0)      // 2 columns, cell width 80
-        << QPointF(6 * 80, 0)      // 30 items = 6 columns
-        << QPointF(0, 0)
-        << QPointF(0, 0)
-        << QPointF(0, 0)
-        << QPointF(6 * 80 - 240 + 40, 0);
-
-    // footer to left of items
-    QTest::newRow("flow top to bottom, layout right to left") << QSGGridView::TopToBottom << Qt::RightToLeft
-        << QPointF(-(2 * 80) - 100, 0)
-        << QPointF(-(6 * 80) - 50, 0)     // 50 = new footer width
-        << QPointF(-240, 0)
-        << QPointF(-240, 0)    // unchanged, footer change doesn't change content pos
-        << QPointF(-80, 0)
-        << QPointF(-(6 * 80) - 40, 0);
-}
-
-void tst_QSGGridView::header()
-{
-    QFETCH(QSGGridView::Flow, flow);
-    QFETCH(Qt::LayoutDirection, layoutDirection);
-    QFETCH(QPointF, initialHeaderPos);
-    QFETCH(QPointF, changedHeaderPos);
-    QFETCH(QPointF, initialContentPos);
-    QFETCH(QPointF, changedContentPos);
-    QFETCH(QPointF, firstDelegatePos);
-    QFETCH(QPointF, resizeContentPos);
-
-    TestModel model;
-    for (int i = 0; i < 30; i++)
-        model.addItem("Item" + QString::number(i), "");
-
-    QSGView *canvas = createView();
-    canvas->rootContext()->setContextProperty("testModel", &model);
-    canvas->rootContext()->setContextProperty("initialViewWidth", 240);
-    canvas->rootContext()->setContextProperty("initialViewHeight", 320);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml")));
-
-    QSGGridView *gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
-    QTRY_VERIFY(gridview != 0);
-    gridview->setFlow(flow);
-    gridview->setLayoutDirection(layoutDirection);
-
-    QSGItem *contentItem = gridview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    QSGText *header = findItem<QSGText>(contentItem, "header");
-    QVERIFY(header);
-
-    QVERIFY(header == gridview->headerItem());
-
-    QCOMPARE(header->pos(), initialHeaderPos);
-    QCOMPARE(header->width(), 100.);
-    QCOMPARE(header->height(), 30.);
-    QCOMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos);
-
-    QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", 0);
-    QVERIFY(item);
-    QCOMPARE(item->pos(), firstDelegatePos);
-
-    model.clear();
-    QCOMPARE(header->pos(), initialHeaderPos); // header should stay where it is
-
-    for (int i = 0; i < 30; i++)
-        model.addItem("Item" + QString::number(i), "");
-
-    QSignalSpy headerItemSpy(gridview, SIGNAL(headerItemChanged()));
-    QMetaObject::invokeMethod(canvas->rootObject(), "changeHeader");
-
-    QCOMPARE(headerItemSpy.count(), 1);
-
-    header = findItem<QSGText>(contentItem, "header");
-    QVERIFY(!header);
-    header = findItem<QSGText>(contentItem, "header2");
-    QVERIFY(header);
-
-    QVERIFY(header == gridview->headerItem());
-
-    QCOMPARE(header->pos(), changedHeaderPos);
-    QCOMPARE(header->width(), 50.);
-    QCOMPARE(header->height(), 20.);
-    QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), changedContentPos);
-
-    item = findItem<QSGItem>(contentItem, "wrapper", 0);
-    QVERIFY(item);
-    QCOMPARE(item->pos(), firstDelegatePos);
-
-    header->setHeight(10);
-    header->setWidth(40);
-    QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), resizeContentPos);
-
-    delete canvas;
-
-
-    // QTBUG-21207 header should become visible if view resizes from initial empty size
-
-    canvas = createView();
-    canvas->rootContext()->setContextProperty("testModel", &model);
-    canvas->rootContext()->setContextProperty("initialViewWidth", 240);
-    canvas->rootContext()->setContextProperty("initialViewHeight", 320);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml")));
-
-    gridview = findItem<QSGGridView>(canvas->rootObject(), "grid");
-    QTRY_VERIFY(gridview != 0);
-    gridview->setFlow(flow);
-    gridview->setLayoutDirection(layoutDirection);
-
-    gridview->setWidth(240);
-    gridview->setHeight(320);
-    QTRY_COMPARE(gridview->headerItem()->pos(), initialHeaderPos);
-    QCOMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos);
-
-    delete canvas;
-}
-
-void tst_QSGGridView::header_data()
-{
-    QTest::addColumn<QSGGridView::Flow>("flow");
-    QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
-    QTest::addColumn<QPointF>("initialHeaderPos");
-    QTest::addColumn<QPointF>("changedHeaderPos");
-    QTest::addColumn<QPointF>("initialContentPos");
-    QTest::addColumn<QPointF>("changedContentPos");
-    QTest::addColumn<QPointF>("firstDelegatePos");
-    QTest::addColumn<QPointF>("resizeContentPos");
-
-    // header1 = 100 x 30
-    // header2 = 50 x 20
-    // cells = 80 x 60
-    // view width = 240
-
-    // header above items, top left
-    QTest::newRow("flow left to right") << QSGGridView::LeftToRight << Qt::LeftToRight
-        << QPointF(0, -30)
-        << QPointF(0, -20)
-        << QPointF(0, -30)
-        << QPointF(0, -20)
-        << QPointF(0, 0)
-        << QPointF(0, -10);
-
-    // header above items, top right
-    QTest::newRow("flow left to right, layout right to left") << QSGGridView::LeftToRight << Qt::RightToLeft
-        << QPointF(240 - 100, -30)
-        << QPointF((240 - 100) + 50, -20)     // 50 = width diff between old and new headers
-        << QPointF(0, -30)
-        << QPointF(0, -20)
-        << QPointF(160, 0)
-        << QPointF(0, -10);
-
-    // header to left of items
-    QTest::newRow("flow top to bottom, layout left to right") << QSGGridView::TopToBottom << Qt::LeftToRight
-        << QPointF(-100, 0)
-        << QPointF(-50, 0)
-        << QPointF(-100, 0)
-        << QPointF(-50, 0)
-        << QPointF(0, 0)
-        << QPointF(-40, 0);
-
-    // header to right of items
-    QTest::newRow("flow top to bottom, layout right to left") << QSGGridView::TopToBottom << Qt::RightToLeft
-        << QPointF(0, 0)
-        << QPointF(0, 0)
-        << QPointF(-(240 - 100), 0)
-        << QPointF(-(240 - 50), 0)
-        << QPointF(-80, 0)
-        << 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();
-
-    TestModel model;
-    model.addItem("Fred", "12345");
-    model.addItem("John", "2345");
-    model.addItem("Bob", "54321");
-    model.addItem("Billy", "22345");
-    model.addItem("Sam", "2945");
-    model.addItem("Ben", "04321");
-    model.addItem("Jim", "0780");
-
-    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);
-
-    QTRY_COMPARE(gridview->count(), model.count());
-
-    QCOMPARE(gridview->indexAt(0, 0), 0);
-    QCOMPARE(gridview->indexAt(79, 59), 0);
-    QCOMPARE(gridview->indexAt(80, 0), 1);
-    QCOMPARE(gridview->indexAt(0, 60), 3);
-    QCOMPARE(gridview->indexAt(240, 0), -1);
-
-    delete canvas;
-}
-
-void tst_QSGGridView::onAdd()
-{
-    QFETCH(int, initialItemCount);
-    QFETCH(int, itemsToAdd);
-
-    const int delegateWidth = 50;
-    const int delegateHeight = 100;
-    TestModel model;
-    QSGView *canvas = createView();
-    canvas->setGeometry(0,0,5 * delegateWidth, 5 * delegateHeight); // just ensure all items fit
-
-    // these initial items should not trigger GridView.onAdd
-    for (int i=0; i<initialItemCount; i++)
-        model.addItem("dummy value", "dummy value");
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-    ctxt->setContextProperty("delegateWidth", delegateWidth);
-    ctxt->setContextProperty("delegateHeight", delegateHeight);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml")));
-
-    QObject *object = canvas->rootObject();
-    object->setProperty("width", canvas->width());
-    object->setProperty("height", canvas->height());
-    qApp->processEvents();
-
-    QList<QPair<QString, QString> > items;
-    for (int i=0; i<itemsToAdd; i++)
-        items << qMakePair(QString("value %1").arg(i), QString::number(i));
-    model.addItems(items);
-
-    QTRY_COMPARE(model.count(), qobject_cast<QSGGridView*>(canvas->rootObject())->count());
-    qApp->processEvents();
-
-    QVariantList result = object->property("addedDelegates").toList();
-    QTRY_COMPARE(result.count(), items.count());
-    for (int i=0; i<items.count(); i++)
-        QCOMPARE(result[i].toString(), items[i].first);
-
-    delete canvas;
-}
-
-void tst_QSGGridView::onAdd_data()
-{
-    QTest::addColumn<int>("initialItemCount");
-    QTest::addColumn<int>("itemsToAdd");
-
-    QTest::newRow("0, add 1") << 0 << 1;
-    QTest::newRow("0, add 2") << 0 << 2;
-    QTest::newRow("0, add 10") << 0 << 10;
-
-    QTest::newRow("1, add 1") << 1 << 1;
-    QTest::newRow("1, add 2") << 1 << 2;
-    QTest::newRow("1, add 10") << 1 << 10;
-
-    QTest::newRow("5, add 1") << 5 << 1;
-    QTest::newRow("5, add 2") << 5 << 2;
-    QTest::newRow("5, add 10") << 5 << 10;
-}
-
-void tst_QSGGridView::onRemove()
-{
-    QFETCH(int, initialItemCount);
-    QFETCH(int, indexToRemove);
-    QFETCH(int, removeCount);
-
-    const int delegateWidth = 50;
-    const int delegateHeight = 100;
-    TestModel model;
-    for (int i=0; i<initialItemCount; i++)
-        model.addItem(QString("value %1").arg(i), "dummy value");
-
-    QSGView *canvas = createView();
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-    ctxt->setContextProperty("delegateWidth", delegateWidth);
-    ctxt->setContextProperty("delegateHeight", delegateHeight);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml")));
-    QObject *object = canvas->rootObject();
-
-    model.removeItems(indexToRemove, removeCount);
-    QTRY_COMPARE(model.count(), qobject_cast<QSGGridView*>(canvas->rootObject())->count());
-    QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount));
-
-    delete canvas;
-}
-
-void tst_QSGGridView::onRemove_data()
-{
-    QTest::addColumn<int>("initialItemCount");
-    QTest::addColumn<int>("indexToRemove");
-    QTest::addColumn<int>("removeCount");
-
-    QTest::newRow("remove first") << 1 << 0 << 1;
-    QTest::newRow("two items, remove first") << 2 << 0 << 1;
-    QTest::newRow("two items, remove last") << 2 << 1 << 1;
-    QTest::newRow("two items, remove all") << 2 << 0 << 2;
-
-    QTest::newRow("four items, remove first") << 4 << 0 << 1;
-    QTest::newRow("four items, remove 0-2") << 4 << 0 << 2;
-    QTest::newRow("four items, remove 1-3") << 4 << 1 << 2;
-    QTest::newRow("four items, remove 2-4") << 4 << 2 << 2;
-    QTest::newRow("four items, remove last") << 4 << 3 << 1;
-    QTest::newRow("four items, remove all") << 4 << 0 << 4;
-
-    QTest::newRow("ten items, remove 1-8") << 10 << 0 << 8;
-    QTest::newRow("ten items, remove 2-7") << 10 << 2 << 5;
-    QTest::newRow("ten items, remove 4-10") << 10 << 4 << 6;
-}
-
-void tst_QSGGridView::testQtQuick11Attributes()
-{
-    QFETCH(QString, code);
-    QFETCH(QString, warning);
-    QFETCH(QString, error);
-
-    QDeclarativeEngine engine;
-    QObject *obj;
-
-    QDeclarativeComponent valid(&engine);
-    valid.setData("import QtQuick 1.1; GridView { " + code.toUtf8() + " }", QUrl(""));
-    obj = valid.create();
-    QVERIFY(obj);
-    QVERIFY(valid.errorString().isEmpty());
-    delete obj;
-
-    QDeclarativeComponent invalid(&engine);
-    invalid.setData("import QtQuick 1.0; GridView { " + code.toUtf8() + " }", QUrl(""));
-    QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
-    obj = invalid.create();
-    QCOMPARE(invalid.errorString(), error);
-    delete obj;
-}
-
-void tst_QSGGridView::testQtQuick11Attributes_data()
-{
-    QTest::addColumn<QString>("code");
-    QTest::addColumn<QString>("warning");
-    QTest::addColumn<QString>("error");
-
-    QTest::newRow("positionViewAtBeginning") << "Component.onCompleted: positionViewAtBeginning()"
-        << "<Unknown File>:1: ReferenceError: Can't find variable: positionViewAtBeginning"
-        << "";
-
-    QTest::newRow("positionViewAtEnd") << "Component.onCompleted: positionViewAtEnd()"
-        << "<Unknown File>:1: ReferenceError: Can't find variable: positionViewAtEnd"
-        << "";
-}
-
-void tst_QSGGridView::columnCount()
-{
-    QSGView canvas;
-    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(405)/qreal(9));
-    QCOMPARE(view->cellHeight(), qreal(100));
-
-    QList<QSGItem*> items = findItems<QSGItem>(view, "delegate");
-    QCOMPARE(items.size(), 18);
-    QCOMPARE(items.at(8)->y(), qreal(0));
-    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);
-    canvas->setGeometry(0,0,240,320);
-
-    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
-*/
-template<typename T>
-T *tst_QSGGridView::findItem(QSGItem *parent, const QString &objectName, int index)
-{
-    const QMetaObject &mo = T::staticMetaObject;
-    //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)
-            continue;
-        //qDebug() << "try" << item;
-        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
-            if (index != -1) {
-                QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item);
-                if (context) {
-                    if (context->contextProperty("index").toInt() == index) {
-                        return static_cast<T*>(item);
-                    }
-                }
-            } else {
-                return static_cast<T*>(item);
-            }
-        }
-        item = findItem<T>(item, objectName, index);
-        if (item)
-            return static_cast<T*>(item);
-    }
-
-    return 0;
-}
-
-template<typename T>
-QList<T*> tst_QSGGridView::findItems(QSGItem *parent, const QString &objectName)
-{
-    QList<T*> items;
-    const QMetaObject &mo = T::staticMetaObject;
-    //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)
-            continue;
-        //qDebug() << "try" << item;
-        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
-            items.append(static_cast<T*>(item));
-            //qDebug() << " found:" << item;
-        }
-        items += findItems<T>(item, objectName);
-    }
-
-    return items;
-}
-
-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)
-            continue;
-        QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item);
-        qDebug() << padding.left(depth*2) << item << (context ? context->contextProperty("index").toInt() : -1);
-        dumpTree(item, depth+1);
-    }
-}
-
-
-QTEST_MAIN(tst_QSGGridView)
-
-#include "tst_qsggridview.moc"
-
diff --git a/tests/auto/declarative/qsgimage/qsgimage.pro b/tests/auto/declarative/qsgimage/qsgimage.pro
deleted file mode 100644 (file)
index 11abb9f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsgimage
-macx:CONFIG -= app_bundle
-
-HEADERS += ../shared/testhttpserver.h
-SOURCES += tst_qsgimage.cpp ../shared/testhttpserver.cpp
-
-testDataFiles.files = data
-testDataFiles.path = .
-DEPLOYMENT += testDataFiles
-
-CONFIG += parallel_test
-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
deleted file mode 100644 (file)
index d0125e6..0000000
+++ /dev/null
@@ -1,689 +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 <QTextDocument>
-#include <QTcpServer>
-#include <QTcpSocket>
-#include <QDir>
-
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtDeclarative/qsgview.h>
-#include <private/qsgimage_p.h>
-#include <private/qsgimagebase_p.h>
-#include <private/qsgloader_p.h>
-#include <QtDeclarative/qdeclarativecontext.h>
-#include <QtDeclarative/qdeclarativeexpression.h>
-#include <QtTest/QSignalSpy>
-#include <QtGui/QPainter>
-#include <QtGui/QImageReader>
-
-#include "../shared/util.h"
-#include "../shared/testhttpserver.h"
-
-#define SERVER_PORT 14451
-#define SERVER_ADDR "http://127.0.0.1:14451"
-
-class tst_qsgimage : public QObject
-{
-    Q_OBJECT
-public:
-    tst_qsgimage();
-
-private slots:
-    void noSource();
-    void imageSource();
-    void imageSource_data();
-    void clearSource();
-    void resized();
-    void preserveAspectRatio();
-    void smooth();
-    void mirror();
-    void svg();
-    void geometry();
-    void geometry_data();
-    void big();
-    void tiling_QTBUG_6716();
-    void tiling_QTBUG_6716_data();
-    void noLoading();
-    void paintedWidthHeight();
-    void sourceSize_QTBUG_14303();
-    void sourceSize_QTBUG_16389();
-    void nullPixmapPaint();
-
-private:
-    template<typename T>
-    T *findItem(QSGItem *parent, const QString &id, int index=-1);
-
-    QDeclarativeEngine engine;
-};
-
-tst_qsgimage::tst_qsgimage()
-{
-}
-
-void tst_qsgimage::noSource()
-{
-    QString componentStr = "import QtQuick 2.0\nImage { source: \"\" }";
-    QDeclarativeComponent component(&engine);
-    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGImage *obj = qobject_cast<QSGImage*>(component.create());
-    QVERIFY(obj != 0);
-    QCOMPARE(obj->source(), QUrl());
-    QVERIFY(obj->status() == QSGImage::Null);
-    QCOMPARE(obj->width(), 0.);
-    QCOMPARE(obj->height(), 0.);
-    QCOMPARE(obj->fillMode(), QSGImage::Stretch);
-    QCOMPARE(obj->progress(), 0.0);
-
-    delete obj;
-}
-
-void tst_qsgimage::imageSource_data()
-{
-    QTest::addColumn<QString>("source");
-    QTest::addColumn<double>("width");
-    QTest::addColumn<double>("height");
-    QTest::addColumn<bool>("remote");
-    QTest::addColumn<bool>("async");
-    QTest::addColumn<bool>("cache");
-    QTest::addColumn<QString>("error");
-
-    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 << "";
-    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";
-
-}
-
-void tst_qsgimage::imageSource()
-{
-    QFETCH(QString, source);
-    QFETCH(double, width);
-    QFETCH(double, height);
-    QFETCH(bool, remote);
-    QFETCH(bool, async);
-    QFETCH(bool, cache);
-    QFETCH(QString, error);
-
-    TestHTTPServer server(SERVER_PORT);
-    if (remote) {
-        QVERIFY(server.isValid());
-        server.serveDirectory(TESTDATA(""));
-        server.addRedirect("oldcolors.png", SERVER_ADDR "/colors.png");
-    }
-
-    if (!error.isEmpty())
-        QTest::ignoreMessage(QtWarningMsg, error.toUtf8());
-
-    QString componentStr = "import QtQuick 2.0\nImage { source: \"" + source + "\"; asynchronous: "
-        + (async ? QLatin1String("true") : QLatin1String("false")) + "; cache: "
-        + (cache ? QLatin1String("true") : QLatin1String("false")) + " }";
-    QDeclarativeComponent component(&engine);
-    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGImage *obj = qobject_cast<QSGImage*>(component.create());
-    QVERIFY(obj != 0);
-
-    if (async)
-        QVERIFY(obj->asynchronous() == true);
-    else
-        QVERIFY(obj->asynchronous() == false);
-
-    if (cache)
-        QVERIFY(obj->cache() == true);
-    else
-        QVERIFY(obj->cache() == false);
-
-    if (remote || async)
-        QTRY_VERIFY(obj->status() == QSGImage::Loading);
-
-    QCOMPARE(obj->source(), remote ? source : QUrl(source));
-
-    if (error.isEmpty()) {
-        QTRY_VERIFY(obj->status() == QSGImage::Ready);
-        QCOMPARE(obj->width(), qreal(width));
-        QCOMPARE(obj->height(), qreal(height));
-        QCOMPARE(obj->fillMode(), QSGImage::Stretch);
-        QCOMPARE(obj->progress(), 1.0);
-    } else {
-        QTRY_VERIFY(obj->status() == QSGImage::Error);
-    }
-
-    delete obj;
-}
-
-void tst_qsgimage::clearSource()
-{
-    QString componentStr = "import QtQuick 2.0\nImage { source: srcImage }";
-    QDeclarativeContext *ctxt = engine.rootContext();
-    ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("colors.png")));
-    QDeclarativeComponent component(&engine);
-    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGImage *obj = qobject_cast<QSGImage*>(component.create());
-    QVERIFY(obj != 0);
-    QVERIFY(obj->status() == QSGImage::Ready);
-    QCOMPARE(obj->width(), 120.);
-    QCOMPARE(obj->height(), 120.);
-    QCOMPARE(obj->progress(), 1.0);
-
-    ctxt->setContextProperty("srcImage", "");
-    QVERIFY(obj->source().isEmpty());
-    QVERIFY(obj->status() == QSGImage::Null);
-    QCOMPARE(obj->width(), 0.);
-    QCOMPARE(obj->height(), 0.);
-    QCOMPARE(obj->progress(), 0.0);
-
-    delete obj;
-}
-
-void tst_qsgimage::resized()
-{
-    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());
-    QVERIFY(obj != 0);
-    QCOMPARE(obj->width(), 300.);
-    QCOMPARE(obj->height(), 300.);
-    QCOMPARE(obj->fillMode(), QSGImage::Stretch);
-    delete obj;
-}
-
-
-void tst_qsgimage::preserveAspectRatio()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->show();
-
-    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(TESTDATA("aspectratio.qml")));
-    image = qobject_cast<QSGImage*>(canvas->rootObject());
-    image->setHeight(60.0);
-    QVERIFY(image != 0);
-    QCOMPARE(image->height(), 60.);
-    QCOMPARE(image->width(), 60.);
-    delete canvas;
-}
-
-void tst_qsgimage::smooth()
-{
-    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());
-    QVERIFY(obj != 0);
-    QCOMPARE(obj->width(), 300.);
-    QCOMPARE(obj->height(), 300.);
-    QCOMPARE(obj->smooth(), true);
-    QCOMPARE(obj->fillMode(), QSGImage::Stretch);
-
-    delete obj;
-}
-
-void tst_qsgimage::mirror()
-{
-    QMap<QSGImage::FillMode, QImage> screenshots;
-    QList<QSGImage::FillMode> fillModes;
-    fillModes << QSGImage::Stretch << QSGImage::PreserveAspectFit << QSGImage::PreserveAspectCrop
-              << QSGImage::Tile << QSGImage::TileVertically << QSGImage::TileHorizontally;
-
-    qreal width = 300;
-    qreal height = 250;
-
-    foreach (QSGImage::FillMode fillMode, fillModes) {
-        QSGView *canvas = new QSGView;
-        canvas->setSource(QUrl::fromLocalFile(TESTDATA("mirror.qml")));
-
-        QSGImage *obj = canvas->rootObject()->findChild<QSGImage*>("image");
-        QVERIFY(obj != 0);
-
-        obj->setFillMode(fillMode);
-        obj->setProperty("mirror", true);
-        canvas->show();
-
-        QImage screenshot = canvas->grabFrameBuffer();
-        screenshots[fillMode] = screenshot;
-        delete canvas;
-    }
-
-    foreach (QSGImage::FillMode fillMode, fillModes) {
-        QPixmap srcPixmap;
-        QVERIFY(srcPixmap.load(TESTDATA("pattern.png")));
-
-        QPixmap expected(width, height);
-        expected.fill();
-        QPainter p_e(&expected);
-        QTransform transform;
-        transform.translate(width, 0).scale(-1, 1.0);
-        p_e.setTransform(transform);
-
-        switch (fillMode) {
-        case QSGImage::Stretch:
-            p_e.drawPixmap(QRect(0, 0, width, height), srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height()));
-            break;
-        case QSGImage::PreserveAspectFit:
-            p_e.drawPixmap(QRect(25, 0, height, height), srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height()));
-            break;
-        case QSGImage::PreserveAspectCrop:
-        {
-            qreal ratio = width/srcPixmap.width(); // width is the longer side
-            QRect rect(0, 0, srcPixmap.width()*ratio, srcPixmap.height()*ratio);
-            rect.moveCenter(QRect(0, 0, width, height).center());
-            p_e.drawPixmap(rect, srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height()));
-            break;
-        }
-        case QSGImage::Tile:
-            p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap);
-            break;
-        case QSGImage::TileVertically:
-            transform.scale(width / srcPixmap.width(), 1.0);
-            p_e.setTransform(transform);
-            p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap);
-            break;
-        case QSGImage::TileHorizontally:
-            transform.scale(1.0, height / srcPixmap.height());
-            p_e.setTransform(transform);
-            p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap);
-            break;
-        }
-
-        QImage img = expected.toImage();
-#ifdef Q_WS_QPA
-        QEXPECT_FAIL("", "QTBUG-21005 fails", Continue);
-#endif
-        QCOMPARE(screenshots[fillMode], img);
-    }
-}
-
-void tst_qsgimage::svg()
-{
-    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(""));
-    QSGImage *obj = qobject_cast<QSGImage*>(component.create());
-    QVERIFY(obj != 0);
-    QCOMPARE(obj->width(), 300.0);
-    QCOMPARE(obj->height(), 300.0);
-    obj->setSourceSize(QSize(200,200));
-
-    QCOMPARE(obj->width(), 200.0);
-    QCOMPARE(obj->height(), 200.0);
-    delete obj;
-}
-
-void tst_qsgimage::geometry_data()
-{
-    QTest::addColumn<QString>("fillMode");
-    QTest::addColumn<bool>("explicitWidth");
-    QTest::addColumn<bool>("explicitHeight");
-    QTest::addColumn<double>("itemWidth");
-    QTest::addColumn<double>("paintedWidth");
-    QTest::addColumn<double>("boundingWidth");
-    QTest::addColumn<double>("itemHeight");
-    QTest::addColumn<double>("paintedHeight");
-    QTest::addColumn<double>("boundingHeight");
-
-    // tested image has width 200, height 100
-
-    // bounding rect and item rect are equal with fillMode PreserveAspectFit, painted rect may be smaller if the aspect ratio doesn't match
-    QTest::newRow("PreserveAspectFit") << "PreserveAspectFit" << false << false << 200.0 << 200.0 << 200.0 << 100.0 << 100.0 << 100.0;
-    QTest::newRow("PreserveAspectFit explicit width 300") << "PreserveAspectFit" << true << false << 300.0 << 200.0 << 300.0 << 100.0 << 100.0 << 100.0;
-    QTest::newRow("PreserveAspectFit explicit height 400") << "PreserveAspectFit" << false << true << 200.0 << 200.0 << 200.0 << 400.0 << 100.0 << 400.0;
-    QTest::newRow("PreserveAspectFit explicit width 300, height 400") << "PreserveAspectFit" << true << true << 300.0 << 300.0 << 300.0 << 400.0 << 150.0 << 400.0;
-
-    // bounding rect and painted rect are equal with fillMode PreserveAspectCrop, item rect may be smaller if the aspect ratio doesn't match
-    QTest::newRow("PreserveAspectCrop") << "PreserveAspectCrop" << false << false << 200.0 << 200.0 << 200.0 << 100.0 << 100.0 << 100.0;
-    QTest::newRow("PreserveAspectCrop explicit width 300") << "PreserveAspectCrop" << true << false << 300.0 << 300.0 << 300.0 << 100.0 << 150.0 << 150.0;
-    QTest::newRow("PreserveAspectCrop explicit height 400") << "PreserveAspectCrop" << false << true << 200.0 << 800.0 << 800.0 << 400.0 << 400.0 << 400.0;
-    QTest::newRow("PreserveAspectCrop explicit width 300, height 400") << "PreserveAspectCrop" << true << true << 300.0 << 800.0 << 800.0 << 400.0 << 400.0 << 400.0;
-
-    // bounding rect, painted rect and item rect are equal in stretching and tiling images
-    QStringList fillModes;
-    fillModes << "Stretch" << "Tile" << "TileVertically" << "TileHorizontally";
-    foreach (QString fillMode, fillModes) {
-        QTest::newRow(fillMode.toLatin1()) << fillMode << false << false << 200.0 << 200.0 << 200.0 << 100.0 << 100.0 << 100.0;
-        QTest::newRow(QString(fillMode + " explicit width 300").toLatin1()) << fillMode << true << false << 300.0 << 300.0 << 300.0 << 100.0 << 100.0 << 100.0;
-        QTest::newRow(QString(fillMode + " explicit height 400").toLatin1()) << fillMode << false << true << 200.0 << 200.0 << 200.0 << 400.0 << 400.0 << 400.0;
-        QTest::newRow(QString(fillMode + " explicit width 300, height 400").toLatin1()) << fillMode << true << true << 300.0 << 300.0 << 300.0 << 400.0 << 400.0 << 400.0;
-    }
-}
-
-void tst_qsgimage::geometry()
-{
-    QFETCH(QString, fillMode);
-    QFETCH(bool, explicitWidth);
-    QFETCH(bool, explicitHeight);
-    QFETCH(double, itemWidth);
-    QFETCH(double, itemHeight);
-    QFETCH(double, paintedWidth);
-    QFETCH(double, paintedHeight);
-    QFETCH(double, boundingWidth);
-    QFETCH(double, boundingHeight);
-
-    QString src = QUrl::fromLocalFile(TESTDATA("rect.png")).toString();
-    QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; fillMode: Image." + fillMode + "; ";
-
-    if (explicitWidth)
-        componentStr.append("width: 300; ");
-    if (explicitHeight)
-        componentStr.append("height: 400; ");
-    componentStr.append("}");
-    QDeclarativeComponent component(&engine);
-    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGImage *obj = qobject_cast<QSGImage*>(component.create());
-    QVERIFY(obj != 0);
-
-    QCOMPARE(obj->width(), itemWidth);
-    QCOMPARE(obj->paintedWidth(), paintedWidth);
-    QCOMPARE(obj->boundingRect().width(), boundingWidth);
-
-    QCOMPARE(obj->height(), itemHeight);
-    QCOMPARE(obj->paintedHeight(), paintedHeight);
-    QCOMPARE(obj->boundingRect().height(), boundingHeight);
-    delete obj;
-}
-
-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(TESTDATA("big.jpeg")).toString();
-    QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; width: 100; sourceSize.height: 256 }";
-
-    QDeclarativeComponent component(&engine);
-    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGImage *obj = qobject_cast<QSGImage*>(component.create());
-    QVERIFY(obj != 0);
-    QCOMPARE(obj->width(), 100.0);
-    QCOMPARE(obj->height(), 256.0);
-
-    delete obj;
-}
-
-void tst_qsgimage::tiling_QTBUG_6716()
-{
-    QFETCH(QString, source);
-
-    QSGView *canvas = new QSGView(0);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA(source)));
-    canvas->show();
-    qApp->processEvents();
-
-    QSGImage *tiling = findItem<QSGImage>(canvas->rootObject(), "tiling");
-
-    QVERIFY(tiling != 0);
-    QImage img = canvas->grabFrameBuffer();
-    for (int x = 0; x < tiling->width(); ++x) {
-        for (int y = 0; y < tiling->height(); ++y) {
-            QEXPECT_FAIL("horizontal_tiling", "QTBUG-21005 - stable failing test", Abort);
-            QVERIFY(img.pixel(x, y) == qRgb(0, 255, 0));
-        }
-    }
-    delete canvas;
-}
-
-void tst_qsgimage::tiling_QTBUG_6716_data()
-{
-    QTest::addColumn<QString>("source");
-    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(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(TESTDATA("heart.png")));
-    QDeclarativeComponent component(&engine);
-    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGImage *obj = qobject_cast<QSGImage*>(component.create());
-    QVERIFY(obj != 0);
-    QVERIFY(obj->status() == QSGImage::Ready);
-
-    QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(const QUrl &)));
-    QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal)));
-    QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QSGImageBase::Status)));
-
-    // Loading local file
-    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);
-    QTRY_COMPARE(progressSpy.count(), 0);
-    QTRY_COMPARE(statusSpy.count(), 0);
-
-    // Loading remote file
-    ctxt->setContextProperty("srcImage", QString(SERVER_ADDR) + "/rect.png");
-    QTRY_VERIFY(obj->status() == QSGImage::Loading);
-    QTRY_VERIFY(obj->progress() == 0.0);
-    QTRY_VERIFY(obj->status() == QSGImage::Ready);
-    QTRY_VERIFY(obj->progress() == 1.0);
-    QTRY_COMPARE(sourceSpy.count(), 2);
-    QTRY_COMPARE(progressSpy.count(), 2);
-    QTRY_COMPARE(statusSpy.count(), 2);
-
-    // Loading remote file again - should not go through 'Loading' state.
-    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);
-    QTRY_COMPARE(sourceSpy.count(), 4);
-    QTRY_COMPARE(progressSpy.count(), 2);
-    QTRY_COMPARE(statusSpy.count(), 2);
-
-    delete obj;
-}
-
-void tst_qsgimage::paintedWidthHeight()
-{
-    {
-        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);
-        component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGImage *obj = qobject_cast<QSGImage*>(component.create());
-        QVERIFY(obj != 0);
-        QCOMPARE(obj->width(), 200.0);
-        QCOMPARE(obj->height(), 25.0);
-        QCOMPARE(obj->paintedWidth(), 25.0);
-        QCOMPARE(obj->paintedHeight(), 25.0);
-
-        delete obj;
-    }
-
-    {
-        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(""));
-        QSGImage *obj = qobject_cast<QSGImage*>(component.create());
-        QVERIFY(obj != 0);
-        QCOMPARE(obj->width(), 26.0);
-        QCOMPARE(obj->height(), 175.0);
-        QCOMPARE(obj->paintedWidth(), 26.0);
-        QCOMPARE(obj->paintedHeight(), 26.0);
-
-        delete obj;
-    }
-}
-
-void tst_qsgimage::sourceSize_QTBUG_14303()
-{
-    QString componentStr = "import QtQuick 2.0\nImage { source: srcImage }";
-    QDeclarativeContext *ctxt = engine.rootContext();
-    ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("heart200.png")));
-    QDeclarativeComponent component(&engine);
-    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGImage *obj = qobject_cast<QSGImage*>(component.create());
-
-    QSignalSpy sourceSizeSpy(obj, SIGNAL(sourceSizeChanged()));
-
-    QTRY_VERIFY(obj != 0);
-    QTRY_VERIFY(obj->status() == QSGImage::Ready);
-
-    QTRY_COMPARE(obj->sourceSize().width(), 200);
-    QTRY_COMPARE(obj->sourceSize().height(), 200);
-    QTRY_COMPARE(sourceSizeSpy.count(), 0);
-
-    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(TESTDATA("heart200.png")));
-    QTRY_COMPARE(obj->sourceSize().width(), 200);
-    QTRY_COMPARE(obj->sourceSize().height(), 200);
-    QTRY_COMPARE(sourceSizeSpy.count(), 2);
-
-    delete obj;
-}
-
-void tst_qsgimage::sourceSize_QTBUG_16389()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("qtbug_16389.qml")));
-    canvas->show();
-    qApp->processEvents();
-
-    QSGImage *image = findItem<QSGImage>(canvas->rootObject(), "iconImage");
-    QSGItem *handle = findItem<QSGItem>(canvas->rootObject(), "blueHandle");
-
-    QCOMPARE(image->sourceSize().width(), 200);
-    QCOMPARE(image->sourceSize().height(), 200);
-    QCOMPARE(image->paintedWidth(), 0.0);
-    QCOMPARE(image->paintedHeight(), 0.0);
-
-    handle->setY(20);
-
-    QCOMPARE(image->sourceSize().width(), 200);
-    QCOMPARE(image->sourceSize().height(), 200);
-    QCOMPARE(image->paintedWidth(), 20.0);
-    QCOMPARE(image->paintedHeight(), 20.0);
-}
-
-static int numberOfWarnings = 0;
-static void checkWarnings(QtMsgType, const char *msg)
-{
-    if (!QString(msg).contains("QGLContext::makeCurrent(): Failed."))
-        numberOfWarnings++;
-}
-
-// QTBUG-15690
-void tst_qsgimage::nullPixmapPaint()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("nullpixmap.qml")));
-    canvas->show();
-
-    QSGImage *image = qobject_cast<QSGImage*>(canvas->rootObject());
-    QTRY_VERIFY(image != 0);
-    image->setSource(SERVER_ADDR + QString("/no-such-file.png"));
-
-    QtMsgHandler previousMsgHandler = qInstallMsgHandler(checkWarnings);
-
-    // used to print "QTransform::translate with NaN called"
-    QPixmap pm = QPixmap::fromImage(canvas->grabFrameBuffer());
-    qInstallMsgHandler(previousMsgHandler);
-    QVERIFY(numberOfWarnings == 0);
-    delete image;
-}
-
-/*
-   Find an item with the specified objectName.  If index is supplied then the
-   item must also evaluate the {index} expression equal to index
-*/
-template<typename T>
-T *tst_qsgimage::findItem(QSGItem *parent, const QString &objectName, int index)
-{
-    const QMetaObject &mo = T::staticMetaObject;
-    //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)
-            continue;
-        //qDebug() << "try" << item;
-        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
-            if (index != -1) {
-                QDeclarativeExpression e(qmlContext(item), item, "index");
-                if (e.evaluate().toInt() == index)
-                    return static_cast<T*>(item);
-            } else {
-                return static_cast<T*>(item);
-            }
-        }
-        item = findItem<T>(item, objectName, index);
-        if (item)
-            return static_cast<T*>(item);
-    }
-
-    return 0;
-}
-
-QTEST_MAIN(tst_qsgimage)
-
-#include "tst_qsgimage.moc"
diff --git a/tests/auto/declarative/qsgitem/qsgitem.pro b/tests/auto/declarative/qsgitem/qsgitem.pro
deleted file mode 100644 (file)
index 76d6547..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsgitem
-SOURCES += tst_qsgitem.cpp
-
-macx:CONFIG -= app_bundle
-
-CONFIG += parallel_test
-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
deleted file mode 100644 (file)
index 84c52bd..0000000
+++ /dev/null
@@ -1,1061 +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 "qsgitem.h"
-#include "qsgcanvas.h"
-#include <QtWidgets/QGraphicsSceneMouseEvent>
-#include "private/qsgfocusscope_p.h"
-#include <QDebug>
-#include <QTimer>
-
-class TestItem : public QSGItem
-{
-Q_OBJECT
-public:
-    TestItem(QSGItem *parent = 0) : QSGItem(parent), focused(false), pressCount(0), releaseCount(0), wheelCount(0) {}
-
-    bool focused;
-    int pressCount;
-    int releaseCount;
-    int wheelCount;
-protected:
-    virtual void focusInEvent(QFocusEvent *) { Q_ASSERT(!focused); focused = true; }
-    virtual void focusOutEvent(QFocusEvent *) { Q_ASSERT(focused); focused = false; }
-    virtual void mousePressEvent(QMouseEvent *event) { event->accept(); ++pressCount; }
-    virtual void mouseReleaseEvent(QMouseEvent *event) { event->accept(); ++releaseCount; }
-    virtual void wheelEvent(QWheelEvent *event) { event->accept(); ++wheelCount; }
-};
-
-class TestPolishItem : public QSGItem
-{
-Q_OBJECT
-public:
-    TestPolishItem(QSGItem *parent)
-    : QSGItem(parent), wasPolished(false) {
-        QTimer::singleShot(10, this, SLOT(doPolish()));
-    }
-
-    bool wasPolished;
-
-protected:
-    virtual void updatePolish() {
-        wasPolished = true;
-    }
-
-public slots:
-    void doPolish() {
-        polish();
-    }
-};
-
-class TestFocusScope : public QSGFocusScope
-{
-Q_OBJECT
-public:
-    TestFocusScope(QSGItem *parent = 0) : QSGFocusScope(parent), focused(false) {}
-
-    bool focused;
-protected:
-    virtual void focusInEvent(QFocusEvent *) { Q_ASSERT(!focused); focused = true; }
-    virtual void focusOutEvent(QFocusEvent *) { Q_ASSERT(focused); focused = false; }
-};
-
-class tst_qsgitem : public QObject
-{
-    Q_OBJECT
-public:
-    tst_qsgitem();
-
-private slots:
-    void initTestCase();
-    void cleanupTestCase();
-
-    void noCanvas();
-    void simpleFocus();
-    void scopedFocus();
-    void addedToCanvas();
-    void changeParent();
-
-    void constructor();
-    void setParentItem();
-
-    void visible();
-    void enabled();
-
-    void mouseGrab();
-    void polishOutsideAnimation();
-
-    void wheelEvent_data();
-    void wheelEvent();
-    void hoverEvent_data();
-    void hoverEvent();
-    void hoverEventInParent();
-
-private:
-
-    void ensureFocus(QWindow *w) {
-        w->show();
-        w->requestActivateWindow();
-        qApp->processEvents();
-
-#ifdef Q_WS_X11
-        // to be safe and avoid failing setFocus with window managers
-        qt_x11_wait_for_window_manager(w);
-#endif
-    }
-};
-
-tst_qsgitem::tst_qsgitem()
-{
-}
-
-void tst_qsgitem::initTestCase()
-{
-}
-
-void tst_qsgitem::cleanupTestCase()
-{
-}
-
-// Focus has no effect when outside a canvas
-void tst_qsgitem::noCanvas()
-{
-    QSGItem *root = new TestItem;
-    QSGItem *child = new TestItem(root);
-    QSGItem *scope = new TestItem(root);
-    QSGFocusScope *scopedChild = new TestFocusScope(scope);
-    QSGFocusScope *scopedChild2 = new TestFocusScope(scope);
-
-    QCOMPARE(root->hasFocus(), false);
-    QCOMPARE(child->hasFocus(), false);
-    QCOMPARE(scope->hasFocus(), false);
-    QCOMPARE(scopedChild->hasFocus(), false);
-    QCOMPARE(scopedChild2->hasFocus(), false);
-
-    root->setFocus(true);
-    scope->setFocus(true);
-    scopedChild2->setFocus(true);
-    QCOMPARE(root->hasFocus(), true);
-    QCOMPARE(child->hasFocus(), false);
-    QCOMPARE(scope->hasFocus(), true);
-    QCOMPARE(scopedChild->hasFocus(), false);
-    QCOMPARE(scopedChild2->hasFocus(), true);
-
-    root->setFocus(false);
-    child->setFocus(true);
-    scopedChild->setFocus(true);
-    scope->setFocus(false);
-    QCOMPARE(root->hasFocus(), false);
-    QCOMPARE(child->hasFocus(), true);
-    QCOMPARE(scope->hasFocus(), false);
-    QCOMPARE(scopedChild->hasFocus(), true);
-    QCOMPARE(scopedChild2->hasFocus(), true);
-
-    delete root;
-}
-
-struct FocusData {
-    FocusData() : focus(false), activeFocus(false) {}
-
-    void set(bool f, bool af) { focus = f; activeFocus = af; }
-    bool focus;
-    bool activeFocus;
-};
-struct FocusState : public QHash<QSGItem *, FocusData>
-{
-    FocusState() : activeFocusItem(0) {}
-    FocusState &operator<<(QSGItem *item) {
-        insert(item, FocusData());
-        return *this;
-    }
-
-    void active(QSGItem *i) {
-        activeFocusItem = i;
-    }
-    QSGItem *activeFocusItem;
-};
-
-#define FVERIFY() \
-    do { \
-        if (focusState.activeFocusItem) { \
-            QCOMPARE(canvas.activeFocusItem(), focusState.activeFocusItem); \
-            if (qobject_cast<TestItem *>(canvas.activeFocusItem())) \
-                QCOMPARE(qobject_cast<TestItem *>(canvas.activeFocusItem())->focused, true); \
-            else if (qobject_cast<TestFocusScope *>(canvas.activeFocusItem())) \
-                QCOMPARE(qobject_cast<TestFocusScope *>(canvas.activeFocusItem())->focused, true); \
-        } else { \
-            QCOMPARE(canvas.activeFocusItem(), canvas.rootItem()); \
-        } \
-        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)
-
-// Tests a simple set of top-level scoped items
-void tst_qsgitem::simpleFocus()
-{
-    QSGCanvas canvas;
-    ensureFocus(&canvas);
-
-    QSGItem *l1c1 = new TestItem(canvas.rootItem());
-    QSGItem *l1c2 = new TestItem(canvas.rootItem());
-    QSGItem *l1c3 = new TestItem(canvas.rootItem());
-
-    QSGItem *l2c1 = new TestItem(l1c1);
-    QSGItem *l2c2 = new TestItem(l1c1);
-    QSGItem *l2c3 = new TestItem(l1c3);
-
-    FocusState focusState;
-    focusState << l1c1 << l1c2 << l1c3
-               << l2c1 << l2c2 << l2c3;
-    FVERIFY();
-
-    l1c1->setFocus(true);
-    focusState[l1c1].set(true, true);
-    focusState.active(l1c1);
-    FVERIFY();
-
-    l2c3->setFocus(true);
-    focusState[l1c1].set(false, false);
-    focusState[l2c3].set(true, true);
-    focusState.active(l2c3);
-    FVERIFY();
-
-    l1c3->setFocus(true);
-    focusState[l2c3].set(false, false);
-    focusState[l1c3].set(true, true);
-    focusState.active(l1c3);
-    FVERIFY();
-
-    l1c2->setFocus(false);
-    FVERIFY();
-
-    l1c3->setFocus(false);
-    focusState[l1c3].set(false, false);
-    focusState.active(0);
-    FVERIFY();
-
-    l2c1->setFocus(true);
-    focusState[l2c1].set(true, true);
-    focusState.active(l2c1);
-    FVERIFY();
-}
-
-// Items with a focus scope
-void tst_qsgitem::scopedFocus()
-{
-    QSGCanvas canvas;
-    ensureFocus(&canvas);
-
-    QSGItem *l1c1 = new TestItem(canvas.rootItem());
-    QSGItem *l1c2 = new TestItem(canvas.rootItem());
-    QSGItem *l1c3 = new TestItem(canvas.rootItem());
-
-    QSGItem *l2c1 = new TestItem(l1c1);
-    QSGItem *l2c2 = new TestItem(l1c1);
-    QSGItem *l2c3 = new TestFocusScope(l1c3);
-
-    QSGItem *l3c1 = new TestItem(l2c3);
-    QSGItem *l3c2 = new TestFocusScope(l2c3);
-
-    QSGItem *l4c1 = new TestItem(l3c2);
-    QSGItem *l4c2 = new TestItem(l3c2);
-
-    FocusState focusState;
-    focusState << l1c1 << l1c2 << l1c3
-               << l2c1 << l2c2 << l2c3
-               << l3c1 << l3c2
-               << l4c1 << l4c2;
-    FVERIFY();
-
-    l4c2->setFocus(true);
-    focusState[l4c2].set(true, false);
-    FVERIFY();
-
-    l4c1->setFocus(true);
-    focusState[l4c2].set(false, false);
-    focusState[l4c1].set(true, false);
-    FVERIFY();
-
-    l1c1->setFocus(true);
-    focusState[l1c1].set(true, true);
-    focusState.active(l1c1);
-    FVERIFY();
-
-    l3c2->setFocus(true);
-    focusState[l3c2].set(true, false);
-    FVERIFY();
-
-    l2c3->setFocus(true);
-    focusState[l1c1].set(false, false);
-    focusState[l2c3].set(true, true);
-    focusState[l3c2].set(true, true);
-    focusState[l4c1].set(true, true);
-    focusState.active(l4c1);
-    FVERIFY();
-
-    l3c2->setFocus(false);
-    focusState[l3c2].set(false, false);
-    focusState[l4c1].set(true, false);
-    focusState.active(l2c3);
-    FVERIFY();
-
-    l3c2->setFocus(true);
-    focusState[l3c2].set(true, true);
-    focusState[l4c1].set(true, true);
-    focusState.active(l4c1);
-    FVERIFY();
-
-    l4c1->setFocus(false);
-    focusState[l4c1].set(false, false);
-    focusState.active(l3c2);
-    FVERIFY();
-
-    l1c3->setFocus(true);
-    focusState[l1c3].set(true, true);
-    focusState[l2c3].set(false, false);
-    focusState[l3c2].set(true, false);
-    focusState.active(l1c3);
-    FVERIFY();
-}
-
-// Tests focus corrects itself when a tree is added to a canvas for the first time
-void tst_qsgitem::addedToCanvas()
-{
-    {
-    QSGCanvas canvas;
-    ensureFocus(&canvas);
-
-    QSGItem *item = new TestItem;
-
-    FocusState focusState;
-    focusState << item;
-
-    item->setFocus(true);
-    focusState[item].set(true, false);
-    FVERIFY();
-
-    item->setParentItem(canvas.rootItem());
-    focusState[item].set(true, true);
-    focusState.active(item);
-    FVERIFY();
-    }
-
-    {
-    QSGCanvas canvas;
-    ensureFocus(&canvas);
-
-    QSGItem *item = new TestItem(canvas.rootItem());
-
-    QSGItem *tree = new TestItem;
-    QSGItem *c1 = new TestItem(tree);
-    QSGItem *c2 = new TestItem(tree);
-
-    FocusState focusState;
-    focusState << item << tree << c1 << c2;
-
-    item->setFocus(true);
-    c1->setFocus(true);
-    c2->setFocus(true);
-    focusState[item].set(true, true);
-    focusState[c1].set(true, false);
-    focusState[c2].set(true, false);
-    focusState.active(item);
-    FVERIFY();
-
-    tree->setParentItem(item);
-    focusState[c1].set(false, false);
-    focusState[c2].set(false, false);
-    FVERIFY();
-    }
-
-    {
-    QSGCanvas canvas;
-    ensureFocus(&canvas);
-
-    QSGItem *tree = new TestItem;
-    QSGItem *c1 = new TestItem(tree);
-    QSGItem *c2 = new TestItem(tree);
-
-    FocusState focusState;
-    focusState << tree << c1 << c2;
-    c1->setFocus(true);
-    c2->setFocus(true);
-    focusState[c1].set(true, false);
-    focusState[c2].set(true, false);
-    FVERIFY();
-
-    tree->setParentItem(canvas.rootItem());
-    focusState[c1].set(true, true);
-    focusState[c2].set(false, false);
-    focusState.active(c1);
-    FVERIFY();
-    }
-
-    {
-    QSGCanvas canvas;
-    ensureFocus(&canvas);
-    QSGItem *tree = new TestFocusScope;
-    QSGItem *c1 = new TestItem(tree);
-    QSGItem *c2 = new TestItem(tree);
-
-    FocusState focusState;
-    focusState << tree << c1 << c2;
-    c1->setFocus(true);
-    c2->setFocus(true);
-    focusState[c1].set(true, false);
-    focusState[c2].set(true, false);
-    FVERIFY();
-
-    tree->setParentItem(canvas.rootItem());
-    focusState[c1].set(true, false);
-    focusState[c2].set(false, false);
-    FVERIFY();
-
-    tree->setFocus(true);
-    focusState[tree].set(true, true);
-    focusState[c1].set(true, true);
-    focusState.active(c1);
-    FVERIFY();
-    }
-
-    {
-    QSGCanvas canvas;
-    ensureFocus(&canvas);
-    QSGItem *tree = new TestFocusScope;
-    QSGItem *c1 = new TestItem(tree);
-    QSGItem *c2 = new TestItem(tree);
-
-    FocusState focusState;
-    focusState << tree << c1 << c2;
-    tree->setFocus(true);
-    c1->setFocus(true);
-    c2->setFocus(true);
-    focusState[tree].set(true, false);
-    focusState[c1].set(true, false);
-    focusState[c2].set(true, false);
-    FVERIFY();
-
-    tree->setParentItem(canvas.rootItem());
-    focusState[tree].set(true, true);
-    focusState[c1].set(true, true);
-    focusState[c2].set(false, false);
-    focusState.active(c1);
-    FVERIFY();
-    }
-
-    {
-    QSGCanvas canvas;
-    ensureFocus(&canvas);
-    QSGItem *child = new TestItem(canvas.rootItem());
-    QSGItem *tree = new TestFocusScope;
-    QSGItem *c1 = new TestItem(tree);
-    QSGItem *c2 = new TestItem(tree);
-
-    FocusState focusState;
-    focusState << child << tree << c1 << c2;
-    child->setFocus(true);
-    tree->setFocus(true);
-    c1->setFocus(true);
-    c2->setFocus(true);
-    focusState[child].set(true, true);
-    focusState[tree].set(true, false);
-    focusState[c1].set(true, false);
-    focusState[c2].set(true, false);
-    focusState.active(child);
-    FVERIFY();
-
-    tree->setParentItem(canvas.rootItem());
-    focusState[tree].set(false, false);
-    focusState[c1].set(true, false);
-    focusState[c2].set(false, false);
-    FVERIFY();
-
-    tree->setFocus(true);
-    focusState[child].set(false, false);
-    focusState[tree].set(true, true);
-    focusState[c1].set(true, true);
-    focusState.active(c1);
-    FVERIFY();
-    }
-}
-
-void tst_qsgitem::changeParent()
-{
-    // Parent to no parent
-    {
-    QSGCanvas canvas;
-    ensureFocus(&canvas);
-    QSGItem *child = new TestItem(canvas.rootItem());
-
-    FocusState focusState;
-    focusState << child;
-    FVERIFY();
-
-    child->setFocus(true);
-    focusState[child].set(true, true);
-    focusState.active(child);
-    FVERIFY();
-
-    child->setParentItem(0);
-    focusState[child].set(true, false);
-    focusState.active(0);
-    FVERIFY();
-    }
-
-    // Different parent, same focus scope
-    {
-    QSGCanvas canvas;
-    ensureFocus(&canvas);
-    QSGItem *child = new TestItem(canvas.rootItem());
-    QSGItem *child2 = new TestItem(canvas.rootItem());
-
-    FocusState focusState;
-    focusState << child << child2;
-    FVERIFY();
-
-    child->setFocus(true);
-    focusState[child].set(true, true);
-    focusState.active(child);
-    FVERIFY();
-
-    child->setParentItem(child2);
-    FVERIFY();
-    }
-
-    // Different parent, different focus scope
-    {
-    QSGCanvas canvas;
-    ensureFocus(&canvas);
-    QSGItem *child = new TestItem(canvas.rootItem());
-    QSGItem *child2 = new TestFocusScope(canvas.rootItem());
-    QSGItem *item = new TestItem(child);
-
-    FocusState focusState;
-    focusState << child << child2 << item;
-    FVERIFY();
-
-    item->setFocus(true);
-    focusState[item].set(true, true);
-    focusState.active(item);
-    FVERIFY();
-
-    item->setParentItem(child2);
-    focusState[item].set(true, false);
-    focusState.active(0);
-    FVERIFY();
-    }
-    {
-    QSGCanvas canvas;
-    ensureFocus(&canvas);
-    QSGItem *child = new TestItem(canvas.rootItem());
-    QSGItem *child2 = new TestFocusScope(canvas.rootItem());
-    QSGItem *item = new TestItem(child2);
-
-    FocusState focusState;
-    focusState << child << child2 << item;
-    FVERIFY();
-
-    item->setFocus(true);
-    focusState[item].set(true, false);
-    focusState.active(0);
-    FVERIFY();
-
-    item->setParentItem(child);
-    focusState[item].set(true, true);
-    focusState.active(item);
-    FVERIFY();
-    }
-    {
-    QSGCanvas canvas;
-    ensureFocus(&canvas);
-    QSGItem *child = new TestItem(canvas.rootItem());
-    QSGItem *child2 = new TestFocusScope(canvas.rootItem());
-    QSGItem *item = new TestItem(child2);
-
-    FocusState focusState;
-    focusState << child << child2 << item;
-    FVERIFY();
-
-    child->setFocus(true);
-    item->setFocus(true);
-    focusState[child].set(true, true);
-    focusState[item].set(true, false);
-    focusState.active(child);
-    FVERIFY();
-
-    item->setParentItem(child);
-    focusState[item].set(false, false);
-    FVERIFY();
-    }
-
-}
-
-void tst_qsgitem::constructor()
-{
-    QSGItem *root = new QSGItem;
-    QVERIFY(root->parent() == 0);
-    QVERIFY(root->parentItem() == 0);
-
-    QSGItem *child1 = new QSGItem(root);
-    QVERIFY(child1->parent() == root);
-    QVERIFY(child1->parentItem() == root);
-    QCOMPARE(root->childItems().count(), 1);
-    QCOMPARE(root->childItems().at(0), child1);
-
-    QSGItem *child2 = new QSGItem(root);
-    QVERIFY(child2->parent() == root);
-    QVERIFY(child2->parentItem() == root);
-    QCOMPARE(root->childItems().count(), 2);
-    QCOMPARE(root->childItems().at(0), child1);
-    QCOMPARE(root->childItems().at(1), child2);
-
-    delete root;
-}
-
-void tst_qsgitem::setParentItem()
-{
-    QSGItem *root = new QSGItem;
-    QVERIFY(root->parent() == 0);
-    QVERIFY(root->parentItem() == 0);
-
-    QSGItem *child1 = new QSGItem;
-    QVERIFY(child1->parent() == 0);
-    QVERIFY(child1->parentItem() == 0);
-
-    child1->setParentItem(root);
-    QVERIFY(child1->parent() == 0);
-    QVERIFY(child1->parentItem() == root);
-    QCOMPARE(root->childItems().count(), 1);
-    QCOMPARE(root->childItems().at(0), child1);
-
-    QSGItem *child2 = new QSGItem;
-    QVERIFY(child2->parent() == 0);
-    QVERIFY(child2->parentItem() == 0);
-    child2->setParentItem(root);
-    QVERIFY(child2->parent() == 0);
-    QVERIFY(child2->parentItem() == root);
-    QCOMPARE(root->childItems().count(), 2);
-    QCOMPARE(root->childItems().at(0), child1);
-    QCOMPARE(root->childItems().at(1), child2);
-
-    child1->setParentItem(0);
-    QVERIFY(child1->parent() == 0);
-    QVERIFY(child1->parentItem() == 0);
-    QCOMPARE(root->childItems().count(), 1);
-    QCOMPARE(root->childItems().at(0), child2);
-
-    delete root;
-
-    QVERIFY(child1->parent() == 0);
-    QVERIFY(child1->parentItem() == 0);
-    QVERIFY(child2->parent() == 0);
-    QVERIFY(child2->parentItem() == 0);
-
-    delete child1;
-    delete child2;
-}
-
-void tst_qsgitem::visible()
-{
-    QSGItem *root = new QSGItem;
-
-    QSGItem *child1 = new QSGItem;
-    child1->setParentItem(root);
-
-    QSGItem *child2 = new QSGItem;
-    child2->setParentItem(root);
-
-    QVERIFY(child1->isVisible());
-    QVERIFY(child2->isVisible());
-
-    root->setVisible(false);
-    QVERIFY(!child1->isVisible());
-    QVERIFY(!child2->isVisible());
-
-    root->setVisible(true);
-    QVERIFY(child1->isVisible());
-    QVERIFY(child2->isVisible());
-
-    child1->setVisible(false);
-    QVERIFY(!child1->isVisible());
-    QVERIFY(child2->isVisible());
-
-    child2->setParentItem(child1);
-    QVERIFY(!child1->isVisible());
-    QVERIFY(!child2->isVisible());
-
-    child2->setParentItem(root);
-    QVERIFY(!child1->isVisible());
-    QVERIFY(child2->isVisible());
-
-    delete root;
-    delete child1;
-    delete child2;
-}
-
-void tst_qsgitem::enabled()
-{
-    QSGItem *root = new QSGItem;
-
-    QSGItem *child1 = new QSGItem;
-    child1->setParentItem(root);
-
-    QSGItem *child2 = new QSGItem;
-    child2->setParentItem(root);
-
-    QVERIFY(child1->isEnabled());
-    QVERIFY(child2->isEnabled());
-
-    root->setEnabled(false);
-    QVERIFY(!child1->isEnabled());
-    QVERIFY(!child2->isEnabled());
-
-    root->setEnabled(true);
-    QVERIFY(child1->isEnabled());
-    QVERIFY(child2->isEnabled());
-
-    child1->setEnabled(false);
-    QVERIFY(!child1->isEnabled());
-    QVERIFY(child2->isEnabled());
-
-    child2->setParentItem(child1);
-    QVERIFY(!child1->isEnabled());
-    QVERIFY(!child2->isEnabled());
-
-    child2->setParentItem(root);
-    QVERIFY(!child1->isEnabled());
-    QVERIFY(child2->isEnabled());
-
-    delete root;
-    delete child1;
-    delete child2;
-}
-
-void tst_qsgitem::mouseGrab()
-{
-    QSGCanvas *canvas = new QSGCanvas;
-    canvas->resize(200, 200);
-    canvas->show();
-
-    TestItem *child1 = new TestItem;
-    child1->setAcceptedMouseButtons(Qt::LeftButton);
-    child1->setSize(QSizeF(200, 100));
-    child1->setParentItem(canvas->rootItem());
-
-    TestItem *child2 = new TestItem;
-    child2->setAcceptedMouseButtons(Qt::LeftButton);
-    child2->setY(51);
-    child2->setSize(QSizeF(200, 100));
-    child2->setParentItem(canvas->rootItem());
-
-    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
-    QTest::qWait(100);
-    qDebug() << canvas->mouseGrabberItem();
-    QVERIFY(canvas->mouseGrabberItem() == child1);
-    QTest::qWait(100);
-
-    QCOMPARE(child1->pressCount, 1);
-    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
-    QTest::qWait(50);
-    QVERIFY(canvas->mouseGrabberItem() == 0);
-    QCOMPARE(child1->releaseCount, 1);
-
-    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
-    QTest::qWait(50);
-    QVERIFY(canvas->mouseGrabberItem() == child1);
-    QCOMPARE(child1->pressCount, 2);
-    child1->setEnabled(false);
-    QVERIFY(canvas->mouseGrabberItem() == 0);
-    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
-    QTest::qWait(50);
-    QCOMPARE(child1->releaseCount, 1);
-    child1->setEnabled(true);
-
-    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
-    QTest::qWait(50);
-    QVERIFY(canvas->mouseGrabberItem() == child1);
-    QCOMPARE(child1->pressCount, 3);
-    child1->setVisible(false);
-    QVERIFY(canvas->mouseGrabberItem() == 0);
-    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
-    QCOMPARE(child1->releaseCount, 1);
-    child1->setVisible(true);
-
-    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
-    QTest::qWait(50);
-    QVERIFY(canvas->mouseGrabberItem() == child1);
-    QCOMPARE(child1->pressCount, 4);
-    child2->grabMouse();
-    QVERIFY(canvas->mouseGrabberItem() == child2);
-    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
-    QTest::qWait(50);
-    QCOMPARE(child1->releaseCount, 1);
-    QCOMPARE(child2->releaseCount, 1);
-
-    child2->grabMouse();
-    QVERIFY(canvas->mouseGrabberItem() == child2);
-    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
-    QTest::qWait(50);
-    QCOMPARE(child1->pressCount, 4);
-    QCOMPARE(child2->pressCount, 1);
-    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
-    QTest::qWait(50);
-    QCOMPARE(child1->releaseCount, 1);
-    QCOMPARE(child2->releaseCount, 2);
-
-    delete child1;
-    delete child2;
-    delete canvas;
-}
-
-void tst_qsgitem::polishOutsideAnimation()
-{
-    QSGCanvas *canvas = new QSGCanvas;
-    canvas->resize(200, 200);
-    canvas->show();
-
-    TestPolishItem *item = new TestPolishItem(canvas->rootItem());
-    item->setSize(QSizeF(200, 100));
-    QTest::qWait(50);
-    QTRY_VERIFY(item->wasPolished);
-
-    delete item;
-    delete canvas;
-}
-
-void tst_qsgitem::wheelEvent_data()
-{
-    QTest::addColumn<bool>("visible");
-    QTest::addColumn<bool>("enabled");
-
-    QTest::newRow("visible and enabled") << true << true;
-    QTest::newRow("visible and disabled") << true << false;
-    QTest::newRow("invisible and enabled") << false << true;
-    QTest::newRow("invisible and disabled") << false << false;
-}
-
-void tst_qsgitem::wheelEvent()
-{
-    QFETCH(bool, visible);
-    QFETCH(bool, enabled);
-
-    const bool shouldReceiveWheelEvents = visible && enabled;
-
-    QSGCanvas *canvas = new QSGCanvas;
-    canvas->resize(200, 200);
-    canvas->show();
-
-    TestItem *item = new TestItem;
-    item->setSize(QSizeF(200, 100));
-    item->setParentItem(canvas->rootItem());
-
-    item->setEnabled(enabled);
-    item->setVisible(visible);
-
-    QWheelEvent event(QPoint(100, 50), -120, Qt::NoButton, Qt::NoModifier, Qt::Vertical);
-    event.setAccepted(false);
-    QApplication::sendEvent(canvas, &event);
-
-    if (shouldReceiveWheelEvents) {
-        QVERIFY(event.isAccepted());
-        QCOMPARE(item->wheelCount, 1);
-    } else {
-        QVERIFY(!event.isAccepted());
-        QCOMPARE(item->wheelCount, 0);
-    }
-
-    delete canvas;
-}
-
-class HoverItem : public QSGItem
-{
-Q_OBJECT
-public:
-    HoverItem(QSGItem *parent = 0)
-        : QSGItem(parent), hoverEnterCount(0), hoverMoveCount(0), hoverLeaveCount(0)
-    { }
-    void resetCounters() {
-        hoverEnterCount = 0;
-        hoverMoveCount = 0;
-        hoverLeaveCount = 0;
-    }
-    int hoverEnterCount;
-    int hoverMoveCount;
-    int hoverLeaveCount;
-protected:
-    virtual void hoverEnterEvent(QHoverEvent *event) {
-        event->accept();
-        ++hoverEnterCount;
-    }
-    virtual void hoverMoveEvent(QHoverEvent *event) {
-        event->accept();
-        ++hoverMoveCount;
-    }
-    virtual void hoverLeaveEvent(QHoverEvent *event) {
-        event->accept();
-        ++hoverLeaveCount;
-    }
-};
-
-void tst_qsgitem::hoverEvent_data()
-{
-    QTest::addColumn<bool>("visible");
-    QTest::addColumn<bool>("enabled");
-    QTest::addColumn<bool>("acceptHoverEvents");
-
-    QTest::newRow("visible, enabled, accept hover") << true << true << true;
-    QTest::newRow("visible, disabled, accept hover") << true << false << true;
-    QTest::newRow("invisible, enabled, accept hover") << false << true << true;
-    QTest::newRow("invisible, disabled, accept hover") << false << false << true;
-
-    QTest::newRow("visible, enabled, not accept hover") << true << true << false;
-    QTest::newRow("visible, disabled, not accept hover") << true << false << false;
-    QTest::newRow("invisible, enabled, not accept hover") << false << true << false;
-    QTest::newRow("invisible, disabled, not accept hover") << false << false << false;
-}
-
-// ### For some unknown reason QTest::mouseMove() isn't working correctly.
-static void sendMouseMove(QObject *object, const QPoint &position)
-{
-    QMouseEvent moveEvent(QEvent::MouseMove, position, Qt::NoButton, Qt::NoButton, 0);
-    QApplication::sendEvent(object, &moveEvent);
-}
-
-void tst_qsgitem::hoverEvent()
-{
-    QFETCH(bool, visible);
-    QFETCH(bool, enabled);
-    QFETCH(bool, acceptHoverEvents);
-
-    QSGCanvas *canvas = new QSGCanvas();
-    canvas->resize(200, 200);
-    canvas->show();
-
-    HoverItem *item = new HoverItem;
-    item->setSize(QSizeF(100, 100));
-    item->setParentItem(canvas->rootItem());
-
-    item->setEnabled(enabled);
-    item->setVisible(visible);
-    item->setAcceptHoverEvents(acceptHoverEvents);
-
-    const QPoint outside(150, 150);
-    const QPoint inside(50, 50);
-    const QPoint anotherInside(51, 51);
-
-    sendMouseMove(canvas, outside);
-    item->resetCounters();
-
-    // Enter, then move twice inside, then leave.
-    sendMouseMove(canvas, inside);
-    sendMouseMove(canvas, anotherInside);
-    sendMouseMove(canvas, inside);
-    sendMouseMove(canvas, outside);
-
-    const bool shouldReceiveHoverEvents = visible && enabled && acceptHoverEvents;
-    if (shouldReceiveHoverEvents) {
-        QCOMPARE(item->hoverEnterCount, 1);
-        QCOMPARE(item->hoverMoveCount, 2);
-        QCOMPARE(item->hoverLeaveCount, 1);
-    } else {
-        QCOMPARE(item->hoverEnterCount, 0);
-        QCOMPARE(item->hoverMoveCount, 0);
-        QCOMPARE(item->hoverLeaveCount, 0);
-    }
-
-    delete canvas;
-}
-
-void tst_qsgitem::hoverEventInParent()
-{
-    QSGCanvas *canvas = new QSGCanvas();
-    canvas->resize(200, 200);
-    canvas->show();
-
-    HoverItem *parentItem = new HoverItem(canvas->rootItem());
-    parentItem->setSize(QSizeF(200, 200));
-    parentItem->setAcceptHoverEvents(true);
-
-    HoverItem *leftItem = new HoverItem(parentItem);
-    leftItem->setSize(QSizeF(100, 200));
-    leftItem->setAcceptHoverEvents(true);
-
-    HoverItem *rightItem = new HoverItem(parentItem);
-    rightItem->setSize(QSizeF(100, 200));
-    rightItem->setPos(QPointF(100, 0));
-    rightItem->setAcceptHoverEvents(true);
-
-    const QPoint insideLeft(50, 100);
-    const QPoint insideRight(150, 100);
-
-    sendMouseMove(canvas, insideLeft);
-    parentItem->resetCounters();
-    leftItem->resetCounters();
-    rightItem->resetCounters();
-
-    sendMouseMove(canvas, insideRight);
-    QCOMPARE(parentItem->hoverEnterCount, 0);
-    QCOMPARE(parentItem->hoverLeaveCount, 0);
-    QCOMPARE(leftItem->hoverEnterCount, 0);
-    QCOMPARE(leftItem->hoverLeaveCount, 1);
-    QCOMPARE(rightItem->hoverEnterCount, 1);
-    QCOMPARE(rightItem->hoverLeaveCount, 0);
-
-    sendMouseMove(canvas, insideLeft);
-    QCOMPARE(parentItem->hoverEnterCount, 0);
-    QCOMPARE(parentItem->hoverLeaveCount, 0);
-    QCOMPARE(leftItem->hoverEnterCount, 1);
-    QCOMPARE(leftItem->hoverLeaveCount, 1);
-    QCOMPARE(rightItem->hoverEnterCount, 1);
-    QCOMPARE(rightItem->hoverLeaveCount, 1);
-
-    delete canvas;
-}
-
-QTEST_MAIN(tst_qsgitem)
-
-#include "tst_qsgitem.moc"
diff --git a/tests/auto/declarative/qsgitem2/qsgitem2.pro b/tests/auto/declarative/qsgitem2/qsgitem2.pro
deleted file mode 100644 (file)
index 517e676..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-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
deleted file mode 100644 (file)
index fe29de1..0000000
+++ /dev/null
@@ -1,1261 +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 <QtTest/QSignalSpy>
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtDeclarative/qdeclarativecontext.h>
-#include <QtDeclarative/qsgview.h>
-#include <private/qsgrectangle_p.h>
-#include <private/qsgitem_p.h>
-#include "../shared/util.h"
-
-class tst_QSGItem : public QObject
-{
-    Q_OBJECT
-public:
-    tst_QSGItem();
-
-private slots:
-    void initTestCase();
-    void keys();
-    void keysProcessingOrder();
-    void keyNavigation();
-    void keyNavigation_RightToLeft();
-    void keyNavigation_skipNotVisible();
-    void keyNavigation_implicitSetting();
-    void layoutMirroring();
-    void layoutMirroringIllegalParent();
-    void smooth();
-    void clip();
-    void mapCoordinates();
-    void mapCoordinates_data();
-    void propertyChanges();
-    void transforms();
-    void transforms_data();
-    void childrenRect();
-    void childrenRectBug();
-    void childrenRectBug2();
-    void childrenRectBug3();
-
-    void childrenProperty();
-    void resourcesProperty();
-
-    void transformCrash();
-    void implicitSize();
-    void qtbug_16871();
-private:
-    QDeclarativeEngine engine;
-};
-
-template<typename T>
-T *findItem(QSGItem *parent, const QString &objectName)
-{
-    if (!parent)
-        return 0;
-
-    const QMetaObject &mo = T::staticMetaObject;
-    //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)
-            continue;
-        //qDebug() << "try" << item;
-        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName))
-            return static_cast<T*>(item);
-        item = findItem<T>(item, objectName);
-        if (item)
-            return static_cast<T*>(item);
-    }
-
-    return 0;
-}
-
-class KeysTestObject : public QObject
-{
-    Q_OBJECT
-
-    Q_PROPERTY(bool processLast READ processLast NOTIFY processLastChanged)
-
-public:
-    KeysTestObject() : mKey(0), mModifiers(0), mForwardedKey(0), mLast(false) {}
-
-    void reset() {
-        mKey = 0;
-        mText = QString();
-        mModifiers = 0;
-        mForwardedKey = 0;
-    }
-
-    bool processLast() const { return mLast; }
-    void setProcessLast(bool b) {
-        if (b != mLast) {
-            mLast = b;
-            emit processLastChanged();
-        }
-    }
-
-public slots:
-    void keyPress(int key, QString text, int modifiers) {
-        mKey = key;
-        mText = text;
-        mModifiers = modifiers;
-    }
-    void keyRelease(int key, QString text, int modifiers) {
-        mKey = key;
-        mText = text;
-        mModifiers = modifiers;
-    }
-    void forwardedKey(int key) {
-        mForwardedKey = key;
-    }
-
-signals:
-    void processLastChanged();
-
-public:
-    int mKey;
-    QString mText;
-    int mModifiers;
-    int mForwardedKey;
-    bool mLast;
-
-private:
-};
-
-class KeyTestItem : public QSGItem
-{
-    Q_OBJECT
-public:
-    KeyTestItem(QSGItem *parent=0) : QSGItem(parent), mKey(0) {}
-
-protected:
-    void keyPressEvent(QKeyEvent *e) {
-        mKey = e->key();
-
-        if (e->key() == Qt::Key_A)
-            e->accept();
-        else
-            e->ignore();
-    }
-
-    void keyReleaseEvent(QKeyEvent *e) {
-        if (e->key() == Qt::Key_B)
-            e->accept();
-        else
-            e->ignore();
-    }
-
-public:
-    int mKey;
-};
-
-QML_DECLARE_TYPE(KeyTestItem);
-
-
-tst_QSGItem::tst_QSGItem()
-{
-}
-
-void tst_QSGItem::initTestCase()
-{
-    qmlRegisterType<KeyTestItem>("Test",1,0,"KeyTestItem");
-}
-
-void tst_QSGItem::keys()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setBaseSize(QSize(240,320));
-
-    KeysTestObject *testObject = new KeysTestObject;
-    canvas->rootContext()->setContextProperty("keysTestObject", testObject);
-
-    canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(true));
-    canvas->rootContext()->setContextProperty("forwardeeVisible", QVariant(true));
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("keystest.qml")));
-    canvas->show();
-    qApp->processEvents();
-
-    QEvent wa(QEvent::WindowActivate);
-    QApplication::sendEvent(canvas, &wa);
-    QFocusEvent fe(QEvent::FocusIn);
-    QApplication::sendEvent(canvas, &fe);
-
-    QVERIFY(canvas->rootObject());
-    QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), true);
-
-    QKeyEvent key(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QCOMPARE(testObject->mKey, int(Qt::Key_A));
-    QCOMPARE(testObject->mForwardedKey, int(Qt::Key_A));
-    QCOMPARE(testObject->mText, QLatin1String("A"));
-    QVERIFY(testObject->mModifiers == Qt::NoModifier);
-    QVERIFY(!key.isAccepted());
-
-    testObject->reset();
-
-    key = QKeyEvent(QEvent::KeyRelease, Qt::Key_A, Qt::ShiftModifier, "A", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QCOMPARE(testObject->mKey, int(Qt::Key_A));
-    QCOMPARE(testObject->mForwardedKey, int(Qt::Key_A));
-    QCOMPARE(testObject->mText, QLatin1String("A"));
-    QVERIFY(testObject->mModifiers == Qt::ShiftModifier);
-    QVERIFY(key.isAccepted());
-
-    testObject->reset();
-
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QCOMPARE(testObject->mKey, int(Qt::Key_Return));
-    QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Return));
-    QCOMPARE(testObject->mText, QLatin1String("Return"));
-    QVERIFY(testObject->mModifiers == Qt::NoModifier);
-    QVERIFY(key.isAccepted());
-
-    testObject->reset();
-
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_0, Qt::NoModifier, "0", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QCOMPARE(testObject->mKey, int(Qt::Key_0));
-    QCOMPARE(testObject->mForwardedKey, int(Qt::Key_0));
-    QCOMPARE(testObject->mText, QLatin1String("0"));
-    QVERIFY(testObject->mModifiers == Qt::NoModifier);
-    QVERIFY(key.isAccepted());
-
-    testObject->reset();
-
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_9, Qt::NoModifier, "9", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QCOMPARE(testObject->mKey, int(Qt::Key_9));
-    QCOMPARE(testObject->mForwardedKey, int(Qt::Key_9));
-    QCOMPARE(testObject->mText, QLatin1String("9"));
-    QVERIFY(testObject->mModifiers == Qt::NoModifier);
-    QVERIFY(!key.isAccepted());
-
-    testObject->reset();
-
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QCOMPARE(testObject->mKey, int(Qt::Key_Tab));
-    QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Tab));
-    QCOMPARE(testObject->mText, QLatin1String("Tab"));
-    QVERIFY(testObject->mModifiers == Qt::NoModifier);
-    QVERIFY(key.isAccepted());
-
-    testObject->reset();
-
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QCOMPARE(testObject->mKey, int(Qt::Key_Backtab));
-    QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Backtab));
-    QCOMPARE(testObject->mText, QLatin1String("Backtab"));
-    QVERIFY(testObject->mModifiers == Qt::NoModifier);
-    QVERIFY(key.isAccepted());
-
-    testObject->reset();
-
-    canvas->rootContext()->setContextProperty("forwardeeVisible", QVariant(false));
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QCOMPARE(testObject->mKey, int(Qt::Key_A));
-    QCOMPARE(testObject->mForwardedKey, 0);
-    QCOMPARE(testObject->mText, QLatin1String("A"));
-    QVERIFY(testObject->mModifiers == Qt::NoModifier);
-    QVERIFY(!key.isAccepted());
-
-    testObject->reset();
-
-    canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(false));
-    QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), false);
-
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QCOMPARE(testObject->mKey, 0);
-    QVERIFY(!key.isAccepted());
-
-    canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(true));
-    QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), true);
-
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QCOMPARE(testObject->mKey, int(Qt::Key_Return));
-    QVERIFY(key.isAccepted());
-
-    delete canvas;
-    delete testObject;
-}
-
-void tst_QSGItem::keysProcessingOrder()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setBaseSize(QSize(240,320));
-
-    KeysTestObject *testObject = new KeysTestObject;
-    canvas->rootContext()->setContextProperty("keysTestObject", testObject);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("keyspriority.qml")));
-    canvas->show();
-    qApp->processEvents();
-
-    KeyTestItem *testItem = qobject_cast<KeyTestItem*>(canvas->rootObject());
-    QVERIFY(testItem);
-
-    QEvent wa(QEvent::WindowActivate);
-    QApplication::sendEvent(canvas, &wa);
-    QFocusEvent fe(QEvent::FocusIn);
-    QApplication::sendEvent(canvas, &fe);
-
-    QKeyEvent key(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QCOMPARE(testObject->mKey, int(Qt::Key_A));
-    QCOMPARE(testObject->mText, QLatin1String("A"));
-    QVERIFY(testObject->mModifiers == Qt::NoModifier);
-    QVERIFY(key.isAccepted());
-
-    testObject->reset();
-
-    testObject->setProcessLast(true);
-
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QCOMPARE(testObject->mKey, 0);
-    QVERIFY(key.isAccepted());
-
-    testObject->reset();
-
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_B, Qt::NoModifier, "B", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QCOMPARE(testObject->mKey, int(Qt::Key_B));
-    QCOMPARE(testObject->mText, QLatin1String("B"));
-    QVERIFY(testObject->mModifiers == Qt::NoModifier);
-    QVERIFY(!key.isAccepted());
-
-    testObject->reset();
-
-    key = QKeyEvent(QEvent::KeyRelease, Qt::Key_B, Qt::NoModifier, "B", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QCOMPARE(testObject->mKey, 0);
-    QVERIFY(key.isAccepted());
-
-    delete canvas;
-    delete testObject;
-}
-
-QSGItemPrivate *childPrivate(QSGItem *rootItem, const char * itemString)
-{
-    QSGItem *item = findItem<QSGItem>(rootItem, QString(QLatin1String(itemString)));
-    QSGItemPrivate* itemPrivate = QSGItemPrivate::get(item);
-    return itemPrivate;
-}
-
-QVariant childProperty(QSGItem *rootItem, const char * itemString, const char * property)
-{
-    QSGItem *item = findItem<QSGItem>(rootItem, QString(QLatin1String(itemString)));
-    return item->property(property);
-}
-
-bool anchorsMirrored(QSGItem *rootItem, const char * itemString)
-{
-    QSGItem *item = findItem<QSGItem>(rootItem, QString(QLatin1String(itemString)));
-    QSGItemPrivate* itemPrivate = QSGItemPrivate::get(item);
-    return itemPrivate->anchors()->mirrored();
-}
-
-void tst_QSGItem::layoutMirroring()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("layoutmirroring.qml")));
-    canvas->show();
-
-    QSGItem *rootItem = qobject_cast<QSGItem*>(canvas->rootObject());
-    QVERIFY(rootItem);
-    QSGItemPrivate *rootPrivate = QSGItemPrivate::get(rootItem);
-    QVERIFY(rootPrivate);
-
-    QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true);
-    QCOMPARE(childPrivate(rootItem, "mirrored2")->effectiveLayoutMirror, true);
-    QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false);
-    QCOMPARE(childPrivate(rootItem, "notMirrored2")->effectiveLayoutMirror, false);
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, true);
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, true);
-
-    QCOMPARE(anchorsMirrored(rootItem, "mirrored1"), true);
-    QCOMPARE(anchorsMirrored(rootItem, "mirrored2"), true);
-    QCOMPARE(anchorsMirrored(rootItem, "notMirrored1"), false);
-    QCOMPARE(anchorsMirrored(rootItem, "notMirrored2"), false);
-    QCOMPARE(anchorsMirrored(rootItem, "inheritedMirror1"), true);
-    QCOMPARE(anchorsMirrored(rootItem, "inheritedMirror2"), true);
-
-    QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, true);
-    QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritedLayoutMirror, false);
-    QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, true);
-    QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritedLayoutMirror, false);
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, true);
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, true);
-
-    QCOMPARE(childPrivate(rootItem, "mirrored1")->isMirrorImplicit, false);
-    QCOMPARE(childPrivate(rootItem, "mirrored2")->isMirrorImplicit, false);
-    QCOMPARE(childPrivate(rootItem, "notMirrored1")->isMirrorImplicit, false);
-    QCOMPARE(childPrivate(rootItem, "notMirrored2")->isMirrorImplicit, true);
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->isMirrorImplicit, true);
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->isMirrorImplicit, true);
-
-    QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritMirrorFromParent, true);
-    QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritMirrorFromParent, false);
-    QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritMirrorFromParent, true);
-    QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritMirrorFromParent, false);
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritMirrorFromParent, true);
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritMirrorFromParent, true);
-
-    QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritMirrorFromItem, true);
-    QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritMirrorFromItem, false);
-    QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritMirrorFromItem, false);
-    QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritMirrorFromItem, false);
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritMirrorFromItem, false);
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritMirrorFromItem, false);
-
-    // load dynamic content using Loader that needs to inherit mirroring
-    rootItem->setProperty("state", "newContent");
-    QCOMPARE(childPrivate(rootItem, "notMirrored3")->effectiveLayoutMirror, false);
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->effectiveLayoutMirror, true);
-
-    QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritedLayoutMirror, true);
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->inheritedLayoutMirror, true);
-
-    QCOMPARE(childPrivate(rootItem, "notMirrored3")->isMirrorImplicit, false);
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->isMirrorImplicit, true);
-
-    QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromParent, true);
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->inheritMirrorFromParent, true);
-
-    QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromItem, false);
-    QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromItem, false);
-
-    // disable inheritance
-    rootItem->setProperty("childrenInherit", false);
-
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, false);
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, false);
-    QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true);
-    QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false);
-
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, false);
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, false);
-    QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, false);
-    QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, false);
-
-    // re-enable inheritance
-    rootItem->setProperty("childrenInherit", true);
-
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, true);
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, true);
-    QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true);
-    QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false);
-
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, true);
-    QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, true);
-    QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, true);
-    QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, true);
-
-    //
-    // dynamic parenting
-    //
-    QSGItem *parentItem1 = new QSGItem();
-    QSGItemPrivate::get(parentItem1)->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true
-    QSGItemPrivate::get(parentItem1)->isMirrorImplicit = false;
-    QSGItemPrivate::get(parentItem1)->inheritMirrorFromItem = true; // LayoutMirroring.childrenInherit: true
-    QSGItemPrivate::get(parentItem1)->resolveLayoutMirror();
-
-    // inherit in constructor
-    QSGItem *childItem1 = new QSGItem(parentItem1);
-    QCOMPARE(QSGItemPrivate::get(childItem1)->effectiveLayoutMirror, true);
-    QCOMPARE(QSGItemPrivate::get(childItem1)->inheritMirrorFromParent, true);
-
-    // inherit through a parent change
-    QSGItem *childItem2 = new QSGItem();
-    QCOMPARE(QSGItemPrivate::get(childItem2)->effectiveLayoutMirror, false);
-    QCOMPARE(QSGItemPrivate::get(childItem2)->inheritMirrorFromParent, false);
-    childItem2->setParentItem(parentItem1);
-    QCOMPARE(QSGItemPrivate::get(childItem2)->effectiveLayoutMirror, true);
-    QCOMPARE(QSGItemPrivate::get(childItem2)->inheritMirrorFromParent, true);
-
-    // stop inherting through a parent change
-    QSGItem *parentItem2 = new QSGItem();
-    QSGItemPrivate::get(parentItem2)->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true
-    QSGItemPrivate::get(parentItem2)->resolveLayoutMirror();
-    childItem2->setParentItem(parentItem2);
-    QCOMPARE(QSGItemPrivate::get(childItem2)->effectiveLayoutMirror, false);
-    QCOMPARE(QSGItemPrivate::get(childItem2)->inheritMirrorFromParent, false);
-
-    delete parentItem1;
-    delete parentItem2;
-}
-
-void tst_QSGItem::layoutMirroringIllegalParent()
-{
-    QDeclarativeComponent component(&engine);
-    component.setData("import QtQuick 2.0; QtObject { LayoutMirroring.enabled: true; LayoutMirroring.childrenInherit: true }", QUrl::fromLocalFile(""));
-    QTest::ignoreMessage(QtWarningMsg, "file::1:21: QML QtObject: LayoutDirection attached property only works with Items");
-    QObject *object = component.create();
-    QVERIFY(object != 0);
-}
-
-void tst_QSGItem::keyNavigation()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setBaseSize(QSize(240,320));
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest.qml")));
-    canvas->show();
-    qApp->processEvents();
-
-    QEvent wa(QEvent::WindowActivate);
-    QApplication::sendEvent(canvas, &wa);
-    QFocusEvent fe(QEvent::FocusIn);
-    QApplication::sendEvent(canvas, &fe);
-
-    QSGItem *item = findItem<QSGItem>(canvas->rootObject(), "item1");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    QVariant result;
-    QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify",
-            Q_RETURN_ARG(QVariant, result)));
-    QVERIFY(result.toBool());
-
-    // right
-    QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item2");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // down
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item4");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // left
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item3");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // up
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item1");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // tab
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item2");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // backtab
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item1");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    delete canvas;
-}
-
-void tst_QSGItem::keyNavigation_RightToLeft()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setBaseSize(QSize(240,320));
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest.qml")));
-    canvas->show();
-    qApp->processEvents();
-
-    QSGItem *rootItem = qobject_cast<QSGItem*>(canvas->rootObject());
-    QVERIFY(rootItem);
-    QSGItemPrivate* rootItemPrivate = QSGItemPrivate::get(rootItem);
-
-    rootItemPrivate->effectiveLayoutMirror = true; // LayoutMirroring.mirror: true
-    rootItemPrivate->isMirrorImplicit = false;
-    rootItemPrivate->inheritMirrorFromItem = true; // LayoutMirroring.inherit: true
-    rootItemPrivate->resolveLayoutMirror();
-
-    QEvent wa(QEvent::WindowActivate);
-    QApplication::sendEvent(canvas, &wa);
-    QFocusEvent fe(QEvent::FocusIn);
-    QApplication::sendEvent(canvas, &fe);
-
-    QSGItem *item = findItem<QSGItem>(canvas->rootObject(), "item1");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    QVariant result;
-    QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify",
-            Q_RETURN_ARG(QVariant, result)));
-    QVERIFY(result.toBool());
-
-    // right
-    QKeyEvent key(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item2");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // left
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item1");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    delete canvas;
-}
-
-void tst_QSGItem::keyNavigation_skipNotVisible()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setBaseSize(QSize(240,320));
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest.qml")));
-    canvas->show();
-    qApp->processEvents();
-
-    QEvent wa(QEvent::WindowActivate);
-    QApplication::sendEvent(canvas, &wa);
-    QFocusEvent fe(QEvent::FocusIn);
-    QApplication::sendEvent(canvas, &fe);
-
-    QSGItem *item = findItem<QSGItem>(canvas->rootObject(), "item1");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // Set item 2 to not visible
-    item = findItem<QSGItem>(canvas->rootObject(), "item2");
-    QVERIFY(item);
-    item->setVisible(false);
-    QVERIFY(!item->isVisible());
-
-    // right
-    QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item1");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // tab
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item3");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // backtab
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item1");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    //Set item 3 to not visible
-    item = findItem<QSGItem>(canvas->rootObject(), "item3");
-    QVERIFY(item);
-    item->setVisible(false);
-    QVERIFY(!item->isVisible());
-
-    // tab
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item4");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // backtab
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item1");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    delete canvas;
-}
-
-void tst_QSGItem::keyNavigation_implicitSetting()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setBaseSize(QSize(240,320));
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest_implicit.qml")));
-    canvas->show();
-    qApp->processEvents();
-
-    QEvent wa(QEvent::WindowActivate);
-    QApplication::sendEvent(canvas, &wa);
-    QFocusEvent fe(QEvent::FocusIn);
-    QApplication::sendEvent(canvas, &fe);
-
-    QSGItem *item = findItem<QSGItem>(canvas->rootObject(), "item1");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    QVariant result;
-    QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify",
-            Q_RETURN_ARG(QVariant, result)));
-    QVERIFY(result.toBool());
-
-    // right
-    QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item2");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // back to item1
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item1");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // down
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item3");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // move to item4
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item4");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // left
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item3");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // back to item4
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item4");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // up
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item2");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // back to item4
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item4");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // tab
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item1");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // back to item4
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item4");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    // backtab
-    key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
-    QApplication::sendEvent(canvas, &key);
-    QVERIFY(key.isAccepted());
-
-    item = findItem<QSGItem>(canvas->rootObject(), "item3");
-    QVERIFY(item);
-    QVERIFY(item->hasActiveFocus());
-
-    delete canvas;
-}
-
-void tst_QSGItem::smooth()
-{
-    QDeclarativeComponent component(&engine);
-    component.setData("import QtQuick 2.0; Item { smooth: false; }", QUrl::fromLocalFile(""));
-    QSGItem *item = qobject_cast<QSGItem*>(component.create());
-    QSignalSpy spy(item, SIGNAL(smoothChanged(bool)));
-
-    QVERIFY(item);
-    QVERIFY(!item->smooth());
-
-    item->setSmooth(true);
-    QVERIFY(item->smooth());
-    QCOMPARE(spy.count(),1);
-    QList<QVariant> arguments = spy.first();
-    QVERIFY(arguments.count() == 1);
-    QVERIFY(arguments.at(0).toBool() == true);
-
-    item->setSmooth(true);
-    QCOMPARE(spy.count(),1);
-
-    item->setSmooth(false);
-    QVERIFY(!item->smooth());
-    QCOMPARE(spy.count(),2);
-    item->setSmooth(false);
-    QCOMPARE(spy.count(),2);
-
-    delete item;
-}
-
-void tst_QSGItem::clip()
-{
-    QDeclarativeComponent component(&engine);
-    component.setData("import QtQuick 2.0\nItem { clip: false\n }", QUrl::fromLocalFile(""));
-    QSGItem *item = qobject_cast<QSGItem*>(component.create());
-    QSignalSpy spy(item, SIGNAL(clipChanged(bool)));
-
-    QVERIFY(item);
-    QVERIFY(!item->clip());
-
-    item->setClip(true);
-    QVERIFY(item->clip());
-
-    QList<QVariant> arguments = spy.first();
-    QVERIFY(arguments.count() == 1);
-    QVERIFY(arguments.at(0).toBool() == true);
-
-    QCOMPARE(spy.count(),1);
-    item->setClip(true);
-    QCOMPARE(spy.count(),1);
-
-    item->setClip(false);
-    QVERIFY(!item->clip());
-    QCOMPARE(spy.count(),2);
-    item->setClip(false);
-    QCOMPARE(spy.count(),2);
-
-    delete item;
-}
-
-void tst_QSGItem::mapCoordinates()
-{
-    QFETCH(int, x);
-    QFETCH(int, y);
-
-    QSGView *canvas = new QSGView(0);
-    canvas->setBaseSize(QSize(300, 300));
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("mapCoordinates.qml")));
-    canvas->show();
-    qApp->processEvents();
-
-    QSGItem *root = qobject_cast<QSGItem*>(canvas->rootObject());
-    QVERIFY(root != 0);
-    QSGItem *a = findItem<QSGItem>(canvas->rootObject(), "itemA");
-    QVERIFY(a != 0);
-    QSGItem *b = findItem<QSGItem>(canvas->rootObject(), "itemB");
-    QVERIFY(b != 0);
-
-    QVariant result;
-
-    QVERIFY(QMetaObject::invokeMethod(root, "mapAToB",
-            Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
-    QCOMPARE(result.value<QPointF>(), qobject_cast<QSGItem*>(a)->mapToItem(b, QPointF(x, y)));
-
-    QVERIFY(QMetaObject::invokeMethod(root, "mapAFromB",
-            Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
-    QCOMPARE(result.value<QPointF>(), qobject_cast<QSGItem*>(a)->mapFromItem(b, QPointF(x, y)));
-
-    QVERIFY(QMetaObject::invokeMethod(root, "mapAToNull",
-            Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
-    QCOMPARE(result.value<QPointF>(), qobject_cast<QSGItem*>(a)->mapToScene(QPointF(x, y)));
-
-    QVERIFY(QMetaObject::invokeMethod(root, "mapAFromNull",
-            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(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",
-            Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
-    QVERIFY(result.toBool());
-
-    QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
-    QVERIFY(QMetaObject::invokeMethod(root, "checkMapAFromInvalid",
-            Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
-    QVERIFY(result.toBool());
-
-    delete canvas;
-}
-
-void tst_QSGItem::mapCoordinates_data()
-{
-    QTest::addColumn<int>("x");
-    QTest::addColumn<int>("y");
-
-    for (int i=-20; i<=20; i+=10)
-        QTest::newRow(QTest::toString(i)) << i << i;
-}
-
-void tst_QSGItem::transforms_data()
-{
-    QTest::addColumn<QByteArray>("qml");
-    QTest::addColumn<QTransform>("transform");
-    QTest::newRow("translate") << QByteArray("Translate { x: 10; y: 20 }")
-        << QTransform(1,0,0,0,1,0,10,20,1);
-    QTest::newRow("rotation") << QByteArray("Rotation { angle: 90 }")
-        << QTransform(0,1,0,-1,0,0,0,0,1);
-    QTest::newRow("scale") << QByteArray("Scale { xScale: 1.5; yScale: -2  }")
-        << QTransform(1.5,0,0,0,-2,0,0,0,1);
-    QTest::newRow("sequence") << QByteArray("[ Translate { x: 10; y: 20 }, Scale { xScale: 1.5; yScale: -2  } ]")
-        << QTransform(1,0,0,0,1,0,10,20,1) * QTransform(1.5,0,0,0,-2,0,0,0,1);
-}
-
-void tst_QSGItem::transforms()
-{
-    QFETCH(QByteArray, qml);
-    QFETCH(QTransform, transform);
-    QDeclarativeComponent component(&engine);
-    component.setData("import QtQuick 2.0\nItem { transform: "+qml+"}", QUrl::fromLocalFile(""));
-    QSGItem *item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-    QCOMPARE(item->itemTransform(0,0), transform);
-}
-
-void tst_QSGItem::childrenProperty()
-{
-    QDeclarativeComponent component(&engine, TESTDATA("childrenProperty.qml"));
-
-    QObject *o = component.create();
-    QVERIFY(o != 0);
-
-    QCOMPARE(o->property("test1").toBool(), true);
-    QCOMPARE(o->property("test2").toBool(), true);
-    QCOMPARE(o->property("test3").toBool(), true);
-    QCOMPARE(o->property("test4").toBool(), true);
-    QCOMPARE(o->property("test5").toBool(), true);
-    delete o;
-}
-
-void tst_QSGItem::resourcesProperty()
-{
-    QDeclarativeComponent component(&engine, TESTDATA("resourcesProperty.qml"));
-
-    QObject *o = component.create();
-    QVERIFY(o != 0);
-
-    QCOMPARE(o->property("test1").toBool(), true);
-    QCOMPARE(o->property("test2").toBool(), true);
-    QCOMPARE(o->property("test3").toBool(), true);
-    QCOMPARE(o->property("test4").toBool(), true);
-    QCOMPARE(o->property("test5").toBool(), true);
-    delete o;
-}
-
-void tst_QSGItem::propertyChanges()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setBaseSize(QSize(300, 300));
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml")));
-    canvas->show();
-
-    QTest::qWaitForWindowShown(canvas);
-
-    QSGItem *item = findItem<QSGItem>(canvas->rootObject(), "item");
-    QSGItem *parentItem = findItem<QSGItem>(canvas->rootObject(), "parentItem");
-
-    QVERIFY(item);
-    QVERIFY(parentItem);
-
-    QSignalSpy parentSpy(item, SIGNAL(parentChanged(QSGItem *)));
-    QSignalSpy widthSpy(item, SIGNAL(widthChanged()));
-    QSignalSpy heightSpy(item, SIGNAL(heightChanged()));
-    QSignalSpy baselineOffsetSpy(item, SIGNAL(baselineOffsetChanged(qreal)));
-    QSignalSpy childrenRectSpy(parentItem, SIGNAL(childrenRectChanged(QRectF)));
-    QSignalSpy focusSpy(item, SIGNAL(focusChanged(bool)));
-    QSignalSpy wantsFocusSpy(parentItem, SIGNAL(activeFocusChanged(bool)));
-    QSignalSpy childrenChangedSpy(parentItem, SIGNAL(childrenChanged()));
-    QSignalSpy xSpy(item, SIGNAL(xChanged()));
-    QSignalSpy ySpy(item, SIGNAL(yChanged()));
-
-    item->setParentItem(parentItem);
-    item->setWidth(100.0);
-    item->setHeight(200.0);
-    item->setFocus(true);
-    item->setBaselineOffset(10.0);
-
-    QCOMPARE(item->parentItem(), parentItem);
-    QCOMPARE(parentSpy.count(),1);
-    QList<QVariant> parentArguments = parentSpy.first();
-    QVERIFY(parentArguments.count() == 1);
-    QCOMPARE(item->parentItem(), qvariant_cast<QSGItem *>(parentArguments.at(0)));
-    QCOMPARE(childrenChangedSpy.count(),1);
-
-    item->setParentItem(parentItem);
-    QCOMPARE(childrenChangedSpy.count(),1);
-
-    QCOMPARE(item->width(), 100.0);
-    QCOMPARE(widthSpy.count(),1);
-
-    QCOMPARE(item->height(), 200.0);
-    QCOMPARE(heightSpy.count(),1);
-
-    QCOMPARE(item->baselineOffset(), 10.0);
-    QCOMPARE(baselineOffsetSpy.count(),1);
-    QList<QVariant> baselineOffsetArguments = baselineOffsetSpy.first();
-    QVERIFY(baselineOffsetArguments.count() == 1);
-    QCOMPARE(item->baselineOffset(), baselineOffsetArguments.at(0).toReal());
-
-    QCOMPARE(parentItem->childrenRect(), QRectF(0.0,0.0,100.0,200.0));
-    QCOMPARE(childrenRectSpy.count(),2);
-    QList<QVariant> childrenRectArguments = childrenRectSpy.at(1);
-    QVERIFY(childrenRectArguments.count() == 1);
-    QCOMPARE(parentItem->childrenRect(), childrenRectArguments.at(0).toRectF());
-
-    QCOMPARE(item->hasActiveFocus(), true);
-    QCOMPARE(focusSpy.count(),1);
-    QList<QVariant> focusArguments = focusSpy.first();
-    QVERIFY(focusArguments.count() == 1);
-    QCOMPARE(focusArguments.at(0).toBool(), true);
-
-    QCOMPARE(parentItem->hasActiveFocus(), false);
-    QCOMPARE(parentItem->hasFocus(), false);
-    QCOMPARE(wantsFocusSpy.count(),0);
-
-    item->setX(10.0);
-    QCOMPARE(item->x(), 10.0);
-    QCOMPARE(xSpy.count(), 1);
-
-    item->setY(10.0);
-    QCOMPARE(item->y(), 10.0);
-    QCOMPARE(ySpy.count(), 1);
-
-    delete canvas;
-}
-
-void tst_QSGItem::childrenRect()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRect.qml")));
-    canvas->setBaseSize(QSize(240,320));
-    canvas->show();
-
-    QSGItem *o = canvas->rootObject();
-    QSGItem *item = o->findChild<QSGItem*>("testItem");
-    QCOMPARE(item->width(), qreal(0));
-    QCOMPARE(item->height(), qreal(0));
-
-    o->setProperty("childCount", 1);
-    QCOMPARE(item->width(), qreal(10));
-    QCOMPARE(item->height(), qreal(20));
-
-    o->setProperty("childCount", 5);
-    QCOMPARE(item->width(), qreal(50));
-    QCOMPARE(item->height(), qreal(100));
-
-    o->setProperty("childCount", 0);
-    QCOMPARE(item->width(), qreal(0));
-    QCOMPARE(item->height(), qreal(0));
-
-    delete o;
-    delete canvas;
-}
-
-// QTBUG-11383
-void tst_QSGItem::childrenRectBug()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRectBug.qml")));
-    canvas->show();
-
-    QSGItem *o = canvas->rootObject();
-    QSGItem *item = o->findChild<QSGItem*>("theItem");
-    QCOMPARE(item->width(), qreal(200));
-    QCOMPARE(item->height(), qreal(100));
-    QCOMPARE(item->x(), qreal(100));
-
-    delete canvas;
-}
-
-// QTBUG-11465
-void tst_QSGItem::childrenRectBug2()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRectBug2.qml")));
-    canvas->show();
-
-    QSGRectangle *rect = qobject_cast<QSGRectangle*>(canvas->rootObject());
-    QVERIFY(rect);
-    QSGItem *item = rect->findChild<QSGItem*>("theItem");
-    QCOMPARE(item->width(), qreal(100));
-    QCOMPARE(item->height(), qreal(110));
-    QCOMPARE(item->x(), qreal(130));
-
-    QSGItemPrivate *rectPrivate = QSGItemPrivate::get(rect);
-    rectPrivate->setState("row");
-    QCOMPARE(item->width(), qreal(210));
-    QCOMPARE(item->height(), qreal(50));
-    QCOMPARE(item->x(), qreal(75));
-
-    delete canvas;
-}
-
-// QTBUG-12722
-void tst_QSGItem::childrenRectBug3()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRectBug3.qml")));
-    canvas->show();
-
-    //don't crash on delete
-    delete canvas;
-}
-
-// QTBUG-13893
-void tst_QSGItem::transformCrash()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("transformCrash.qml")));
-    canvas->show();
-
-    delete canvas;
-}
-
-void tst_QSGItem::implicitSize()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("implicitsize.qml")));
-    canvas->show();
-
-    QSGItem *item = qobject_cast<QSGItem*>(canvas->rootObject());
-    QVERIFY(item);
-    QCOMPARE(item->width(), qreal(80));
-    QCOMPARE(item->height(), qreal(60));
-
-    QCOMPARE(item->implicitWidth(), qreal(200));
-    QCOMPARE(item->implicitHeight(), qreal(100));
-
-    QMetaObject::invokeMethod(item, "resetSize");
-
-    QCOMPARE(item->width(), qreal(200));
-    QCOMPARE(item->height(), qreal(100));
-
-    QMetaObject::invokeMethod(item, "changeImplicit");
-
-    QCOMPARE(item->implicitWidth(), qreal(150));
-    QCOMPARE(item->implicitHeight(), qreal(80));
-    QCOMPARE(item->width(), qreal(150));
-    QCOMPARE(item->height(), qreal(80));
-
-    delete canvas;
-}
-
-void tst_QSGItem::qtbug_16871()
-{
-    QDeclarativeComponent component(&engine, TESTDATA("qtbug_16871.qml"));
-    QObject *o = component.create();
-    QVERIFY(o != 0);
-    delete o;
-}
-
-QTEST_MAIN(tst_QSGItem)
-
-#include "tst_qsgitem.moc"
diff --git a/tests/auto/declarative/qsglistview/qsglistview.pro b/tests/auto/declarative/qsglistview/qsglistview.pro
deleted file mode 100644 (file)
index 3322f30..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsglistview
-macx:CONFIG -= app_bundle
-
-HEADERS += incrementalmodel.h
-SOURCES += tst_qsglistview.cpp incrementalmodel.cpp
-
-testDataFiles.files = data
-testDataFiles.path = .
-DEPLOYMENT += testDataFiles
-
-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
deleted file mode 100644 (file)
index 8e2375d..0000000
+++ /dev/null
@@ -1,4166 +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 <QtTest/QtTest>
-#include <QtWidgets/QStringListModel>
-#include <QtDeclarative/qsgview.h>
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativecontext.h>
-#include <QtDeclarative/qdeclarativeexpression.h>
-#include <QtDeclarative/private/qsgitem_p.h>
-#include <QtDeclarative/private/qsglistview_p.h>
-#include <QtDeclarative/private/qsgtext_p.h>
-#include <QtDeclarative/private/qsgvisualitemmodel_p.h>
-#include <QtDeclarative/private/qdeclarativelistmodel_p.h>
-#include <QtDeclarative/private/qlistmodelinterface_p.h>
-#include <QtDeclarative/private/qdeclarativechangeset_p.h>
-#include "../shared/util.h"
-#include "incrementalmodel.h"
-#include <math.h>
-
-Q_DECLARE_METATYPE(Qt::LayoutDirection)
-Q_DECLARE_METATYPE(QSGListView::Orientation)
-
-class tst_QSGListView : public QObject
-{
-    Q_OBJECT
-public:
-    tst_QSGListView();
-
-private slots:
-    void initTestCase();
-    void cleanupTestCase();
-    // Test both QListModelInterface and QAbstractItemModel model types
-    void qListModelInterface_items();
-    void qAbstractItemModel_items();
-
-    void qListModelInterface_changed();
-    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();
-
-    void qListModelInterface_moved();
-    void qListModelInterface_moved_data();
-    void qAbstractItemModel_moved();
-    void qAbstractItemModel_moved_data();
-
-    void multipleChanges();
-    void multipleChanges_data();
-
-    void qListModelInterface_clear();
-    void qAbstractItemModel_clear();
-
-    void swapWithFirstItem();
-    void itemList();
-    void currentIndex_delayedItemCreation();
-    void currentIndex_delayedItemCreation_data();
-    void currentIndex();
-    void noCurrentIndex();
-    void enforceRange();
-    void enforceRange_withoutHighlight();
-    void spacing();
-    void sections();
-    void sectionsPositioning();
-    void sectionsDelegate();
-    void cacheBuffer();
-    void positionViewAtIndex();
-    void resetModel();
-    void propertyChanges();
-    void componentChanges();
-    void modelChanges();
-    void manualHighlight();
-    void header();
-    void header_data();
-    void header_delayItemCreation();
-    void footer();
-    void footer_data();
-    void headerFooter();
-    void resizeView();
-    void resizeViewAndRepaint();
-    void sizeLessThan1();
-    void QTBUG_14821();
-    void resizeDelegate();
-    void resizeFirstDelegate();
-    void QTBUG_16037();
-    void indexAt();
-    void incrementalModel();
-    void onAdd();
-    void onAdd_data();
-    void onRemove();
-    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);
-    template<typename T>
-    QList<T*> findItems(QSGItem *parent, const QString &objectName);
-    void dumpTree(QSGItem *parent, int depth = 0);
-
-    void inserted_more_data();
-    void moved_data();
-};
-
-void tst_QSGListView::initTestCase()
-{
-}
-
-void tst_QSGListView::cleanupTestCase()
-{
-
-}
-class TestObject : public QObject
-{
-    Q_OBJECT
-
-    Q_PROPERTY(bool error READ error WRITE setError NOTIFY changedError)
-    Q_PROPERTY(bool animate READ animate NOTIFY changedAnim)
-    Q_PROPERTY(bool invalidHighlight READ invalidHighlight NOTIFY changedHl)
-    Q_PROPERTY(int cacheBuffer READ cacheBuffer NOTIFY changedCacheBuffer)
-
-public:
-    TestObject(QObject *parent = 0)
-        : QObject(parent), mError(true), mAnimate(false), mInvalidHighlight(false)
-        , mCacheBuffer(0) {}
-
-    bool error() const { return mError; }
-    void setError(bool err) { mError = err; emit changedError(); }
-
-    bool animate() const { return mAnimate; }
-    void setAnimate(bool anim) { mAnimate = anim; emit changedAnim(); }
-
-    bool invalidHighlight() const { return mInvalidHighlight; }
-    void setInvalidHighlight(bool invalid) { mInvalidHighlight = invalid; emit changedHl(); }
-
-    int cacheBuffer() const { return mCacheBuffer; }
-    void setCacheBuffer(int buffer) { mCacheBuffer = buffer; emit changedCacheBuffer(); }
-
-signals:
-    void changedError();
-    void changedAnim();
-    void changedHl();
-    void changedCacheBuffer();
-
-public:
-    bool mError;
-    bool mAnimate;
-    bool mInvalidHighlight;
-    int mCacheBuffer;
-};
-
-template<typename T>
-void tst_qsglistview_move(int from, int to, int n, T *items)
-{
-    if (from > to) {
-        // Only move forwards - flip if backwards moving
-        int tfrom = from;
-        int tto = to;
-        from = tto;
-        to = tto+n;
-        n = tfrom-tto;
-    }
-    if (n == 1) {
-        items->move(from, to);
-    } else {
-        T replaced;
-        int i=0;
-        typename T::ConstIterator it=items->begin(); it += from+n;
-        for (; i<to-from; ++i,++it)
-            replaced.append(*it);
-        i=0;
-        it=items->begin(); it += from;
-        for (; i<n; ++i,++it)
-            replaced.append(*it);
-        typename T::ConstIterator f=replaced.begin();
-        typename T::Iterator t=items->begin(); t += from;
-        for (; f != replaced.end(); ++f, ++t)
-            *t = *f;
-    }
-}
-
-class TestModel : public QListModelInterface
-{
-    Q_OBJECT
-public:
-    TestModel(QObject *parent = 0) : QListModelInterface(parent) {}
-    ~TestModel() {}
-
-    enum Roles { Name, Number };
-
-    QString name(int index) const { return list.at(index).first; }
-    QString number(int index) const { return list.at(index).second; }
-
-    int count() const { return list.count(); }
-
-    QList<int> roles() const { return QList<int>() << Name << Number; }
-    QString toString(int role) const {
-        switch (role) {
-        case Name:
-            return "name";
-        case Number:
-            return "number";
-        default:
-            return "";
-        }
-    }
-
-    QVariant data(int index, int role) const
-    {
-        if (role==0)
-            return list.at(index).first;
-        if (role==1)
-            return list.at(index).second;
-        return QVariant();
-    }
-    QHash<int, QVariant> data(int index, const QList<int> &roles) const {
-        QHash<int,QVariant> returnHash;
-
-        for (int i = 0; i < roles.size(); ++i) {
-            int role = roles.at(i);
-            QVariant info;
-            switch (role) {
-            case Name:
-                info = list.at(index).first;
-                break;
-            case Number:
-                info = list.at(index).second;
-                break;
-            default:
-                break;
-            }
-            returnHash.insert(role, info);
-        }
-        return returnHash;
-    }
-
-    void addItem(const QString &name, const QString &number) {
-        list.append(QPair<QString,QString>(name, number));
-        emit itemsInserted(list.count()-1, 1);
-    }
-
-    void insertItem(int index, const QString &name, const QString &number) {
-        list.insert(index, QPair<QString,QString>(name, number));
-        emit itemsInserted(index, 1);
-    }
-
-    void insertItems(int index, const QList<QPair<QString, QString> > &items) {
-        for (int i=0; i<items.count(); i++)
-            list.insert(index + i, QPair<QString,QString>(items[i].first, items[i].second));
-        emit itemsInserted(index, items.count());
-    }
-
-    void removeItem(int index) {
-        list.removeAt(index);
-        emit itemsRemoved(index, 1);
-    }
-
-    void removeItems(int index, int count) {
-        int c = count;
-        while (c--)
-            list.removeAt(index);
-        emit itemsRemoved(index, count);
-    }
-
-    void moveItem(int from, int to) {
-        list.move(from, to);
-        emit itemsMoved(from, to, 1);
-    }
-
-    void moveItems(int from, int to, int count) {
-        tst_qsglistview_move(from, to, count, &list);
-        emit itemsMoved(from, to, count);
-    }
-
-    void modifyItem(int index, const QString &name, const QString &number) {
-        list[index] = QPair<QString,QString>(name, number);
-        emit itemsChanged(index, 1, roles());
-    }
-
-    void clear() {
-        int count = list.count();
-        list.clear();
-        emit itemsRemoved(0, count);
-    }
-
-private:
-    QList<QPair<QString,QString> > list;
-};
-
-
-class TestModel2 : public QAbstractListModel
-{
-public:
-    enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 };
-
-    TestModel2(QObject *parent=0) : QAbstractListModel(parent) {
-        QHash<int, QByteArray> roles;
-        roles[Name] = "name";
-        roles[Number] = "number";
-        setRoleNames(roles);
-    }
-
-    int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); }
-    QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
-        QVariant rv;
-        if (role == Name)
-            rv = list.at(index.row()).first;
-        else if (role == Number)
-            rv = list.at(index.row()).second;
-
-        return rv;
-    }
-
-    int count() const { return rowCount(); }
-    QString name(int index) const { return list.at(index).first; }
-    QString number(int index) const { return list.at(index).second; }
-
-    void addItem(const QString &name, const QString &number) {
-        emit beginInsertRows(QModelIndex(), list.count(), list.count());
-        list.append(QPair<QString,QString>(name, number));
-        emit endInsertRows();
-    }
-
-    void addItems(const QList<QPair<QString, QString> > &items) {
-        emit beginInsertRows(QModelIndex(), list.count(), list.count()+items.count()-1);
-        for (int i=0; i<items.count(); i++)
-            list.append(QPair<QString,QString>(items[i].first, items[i].second));
-        emit endInsertRows();
-    }
-
-    void insertItem(int index, const QString &name, const QString &number) {
-        emit beginInsertRows(QModelIndex(), index, index);
-        list.insert(index, QPair<QString,QString>(name, number));
-        emit endInsertRows();
-    }
-
-    void insertItems(int index, const QList<QPair<QString, QString> > &items) {
-        emit beginInsertRows(QModelIndex(), index, index+items.count()-1);
-        for (int i=0; i<items.count(); i++)
-            list.insert(index + i, QPair<QString,QString>(items[i].first, items[i].second));
-        emit endInsertRows();
-    }
-
-    void removeItem(int index) {
-        emit beginRemoveRows(QModelIndex(), index, index);
-        list.removeAt(index);
-        emit endRemoveRows();
-    }
-
-    void removeItems(int index, int count) {
-        emit beginRemoveRows(QModelIndex(), index, index+count-1);
-        while (count--)
-            list.removeAt(index);
-        emit endRemoveRows();
-    }
-
-    void moveItem(int from, int to) {
-        emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
-        list.move(from, to);
-        emit endMoveRows();
-    }
-
-    void moveItems(int from, int to, int count) {
-        emit beginMoveRows(QModelIndex(), from, from+count-1, QModelIndex(), to > from ? to+count : to);
-        tst_qsglistview_move(from, to, count, &list);
-        emit endMoveRows();
-    }
-
-    void modifyItem(int idx, const QString &name, const QString &number) {
-        list[idx] = QPair<QString,QString>(name, number);
-        emit dataChanged(index(idx,0), index(idx,0));
-    }
-
-    void clear() {
-        int count = list.count();
-        emit beginRemoveRows(QModelIndex(), 0, count-1);
-        list.clear();
-        emit endRemoveRows();
-    }
-
-private:
-    QList<QPair<QString,QString> > list;
-};
-
-tst_QSGListView::tst_QSGListView()
-{
-}
-
-template <class T>
-void tst_QSGListView::items()
-{
-    QSGView *canvas = createView();
-
-    T model;
-    model.addItem("Fred", "12345");
-    model.addItem("John", "2345");
-    model.addItem("Bob", "54321");
-
-    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);
-
-    QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
-    QTRY_VERIFY(testObject->error() == false);
-
-    QTRY_VERIFY(listview->highlightItem() != 0);
-    QTRY_COMPARE(listview->count(), model.count());
-    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
-    QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
-
-    // current item should be first item
-    QTRY_COMPARE(listview->currentItem(), findItem<QSGItem>(contentItem, "wrapper", 0));
-
-    for (int i = 0; i < model.count(); ++i) {
-        QSGText *name = findItem<QSGText>(contentItem, "textName", i);
-        QTRY_VERIFY(name != 0);
-        QTRY_COMPARE(name->text(), model.name(i));
-        QSGText *number = findItem<QSGText>(contentItem, "textNumber", i);
-        QTRY_VERIFY(number != 0);
-        QTRY_COMPARE(number->text(), model.number(i));
-    }
-
-    // switch to other delegate
-    testObject->setAnimate(true);
-    QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
-    QTRY_VERIFY(testObject->error() == false);
-    QTRY_VERIFY(listview->currentItem());
-
-    // set invalid highlight
-    testObject->setInvalidHighlight(true);
-    QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
-    QTRY_VERIFY(testObject->error() == false);
-    QTRY_VERIFY(listview->currentItem());
-    QTRY_VERIFY(listview->highlightItem() == 0);
-
-    // back to normal highlight
-    testObject->setInvalidHighlight(false);
-    QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
-    QTRY_VERIFY(testObject->error() == false);
-    QTRY_VERIFY(listview->currentItem());
-    QTRY_VERIFY(listview->highlightItem() != 0);
-
-    // set an empty model and confirm that items are destroyed
-    T model2;
-    ctxt->setContextProperty("testModel", &model2);
-
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    QTRY_VERIFY(itemCount == 0);
-
-    QTRY_COMPARE(listview->highlightResizeSpeed(), 1000.0);
-    QTRY_COMPARE(listview->highlightMoveSpeed(), 1000.0);
-
-    delete canvas;
-    delete testObject;
-}
-
-
-template <class T>
-void tst_QSGListView::changed()
-{
-    QSGView *canvas = createView();
-
-    T model;
-    model.addItem("Fred", "12345");
-    model.addItem("John", "2345");
-    model.addItem("Bob", "54321");
-
-    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();
-
-    QSGFlickable *listview = findItem<QSGFlickable>(canvas->rootObject(), "list");
-    QTRY_VERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    model.modifyItem(1, "Will", "9876");
-    QSGText *name = findItem<QSGText>(contentItem, "textName", 1);
-    QTRY_VERIFY(name != 0);
-    QTRY_COMPARE(name->text(), model.name(1));
-    QSGText *number = findItem<QSGText>(contentItem, "textNumber", 1);
-    QTRY_VERIFY(number != 0);
-    QTRY_COMPARE(number->text(), model.number(1));
-
-    delete canvas;
-    delete testObject;
-}
-
-template <class T>
-void tst_QSGListView::inserted()
-{
-    QSGView *canvas = createView();
-    canvas->show();
-
-    T model;
-    model.addItem("Fred", "12345");
-    model.addItem("John", "2345");
-    model.addItem("Bob", "54321");
-
-    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);
-
-    model.insertItem(1, "Will", "9876");
-
-    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
-    QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
-
-    QSGText *name = findItem<QSGText>(contentItem, "textName", 1);
-    QTRY_VERIFY(name != 0);
-    QTRY_COMPARE(name->text(), model.name(1));
-    QSGText *number = findItem<QSGText>(contentItem, "textNumber", 1);
-    QTRY_VERIFY(number != 0);
-    QTRY_COMPARE(number->text(), model.number(1));
-
-    // Confirm items positioned correctly
-    for (int i = 0; i < model.count(); ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        QTRY_COMPARE(item->y(), i*20.0);
-    }
-
-    model.insertItem(0, "Foo", "1111"); // zero index, and current item
-
-    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
-    QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
-
-    name = findItem<QSGText>(contentItem, "textName", 0);
-    QTRY_VERIFY(name != 0);
-    QTRY_COMPARE(name->text(), model.name(0));
-    number = findItem<QSGText>(contentItem, "textNumber", 0);
-    QTRY_VERIFY(number != 0);
-    QTRY_COMPARE(number->text(), model.number(0));
-
-    QTRY_COMPARE(listview->currentIndex(), 1);
-
-    // Confirm items positioned correctly
-    for (int i = 0; i < model.count(); ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        QTRY_COMPARE(item->y(), i*20.0);
-    }
-
-    for (int i = model.count(); i < 30; ++i)
-        model.insertItem(i, "Hello", QString::number(i));
-
-    listview->setContentY(80);
-
-    // Insert item outside visible area
-    model.insertItem(1, "Hello", "1324");
-
-    QTRY_VERIFY(listview->contentY() == 80);
-
-    // Confirm items positioned correctly
-    for (int i = 5; i < 5+15; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->y(), i*20.0 - 20.0);
-    }
-
-//    QTRY_COMPARE(listview->contentItemHeight(), model.count() * 20.0);
-
-    // QTBUG-19675
-    model.clear();
-    model.insertItem(0, "Hello", "1234");
-    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
-
-    QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", 0);
-    QVERIFY(item);
-    QCOMPARE(item->y(), 0.);
-    QVERIFY(listview->contentY() == 0);
-
-    delete canvas;
-    delete testObject;
-}
-
-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();
-
-    T model;
-    for (int i = 0; i < 50; 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")));
-    canvas->show();
-    qApp->processEvents();
-
-    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
-    QTRY_VERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    model.removeItem(1);
-    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
-
-    QSGText *name = findItem<QSGText>(contentItem, "textName", 1);
-    QTRY_VERIFY(name != 0);
-    QTRY_COMPARE(name->text(), model.name(1));
-    QSGText *number = findItem<QSGText>(contentItem, "textNumber", 1);
-    QTRY_VERIFY(number != 0);
-    QTRY_COMPARE(number->text(), model.number(1));
-
-    // Confirm items positioned correctly
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_VERIFY(item->y() == i*20);
-    }
-
-    // Remove first item (which is the current item);
-    model.removeItem(0);  // post: top item starts at 20
-    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
-
-    name = findItem<QSGText>(contentItem, "textName", 0);
-    QTRY_VERIFY(name != 0);
-    QTRY_COMPARE(name->text(), model.name(0));
-    number = findItem<QSGText>(contentItem, "textNumber", 0);
-    QTRY_VERIFY(number != 0);
-    QTRY_COMPARE(number->text(), model.number(0));
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->y(),i*20.0 + 20.0);
-    }
-
-    // Remove items not visible
-    model.removeItem(18);
-    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->y(),i*20.0+20.0);
-    }
-
-    // Remove items before visible
-    listview->setContentY(80);
-    listview->setCurrentIndex(10);
-
-    model.removeItem(1); // post: top item will be at 40
-    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
-
-    // Confirm items positioned correctly
-    for (int i = 2; i < 18; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->y(),40+i*20.0);
-    }
-
-    // Remove current index
-    QTRY_VERIFY(listview->currentIndex() == 9);
-    QSGItem *oldCurrent = listview->currentItem();
-    model.removeItem(9);
-
-    QTRY_COMPARE(listview->currentIndex(), 9);
-    QTRY_VERIFY(listview->currentItem() != oldCurrent);
-
-    listview->setContentY(40); // That's the top now
-    // let transitions settle.
-    QTest::qWait(300);
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->y(),40+i*20.0);
-    }
-
-    // remove current item beyond visible items.
-    listview->setCurrentIndex(20);
-    listview->setContentY(40);
-    model.removeItem(20);
-
-    QTRY_COMPARE(listview->currentIndex(), 20);
-    QTRY_VERIFY(listview->currentItem() != 0);
-
-    // remove item before current, but visible
-    listview->setCurrentIndex(8);
-    oldCurrent = listview->currentItem();
-    model.removeItem(6);
-
-    QTRY_COMPARE(listview->currentIndex(), 7);
-    QTRY_VERIFY(listview->currentItem() == oldCurrent);
-
-    listview->setContentY(80);
-    QTest::qWait(300);
-
-    // remove all visible items
-    model.removeItems(1, 18);
-    QTRY_COMPARE(listview->count() , model.count());
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i+2);
-        if (!item) qWarning() << "Item" << i+2 << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->y(),80+i*20.0);
-    }
-
-    model.removeItems(1, 17);
-    QTRY_COMPARE(listview->count() , model.count());
-
-    model.removeItems(2, 1);
-    QTRY_COMPARE(listview->count() , model.count());
-
-    model.addItem("New", "1");
-    QTRY_COMPARE(listview->count() , model.count());
-
-    QTRY_VERIFY(name = findItem<QSGText>(contentItem, "textName", model.count()-1));
-    QCOMPARE(name->text(), QString("New"));
-
-    // Add some more items so that we don't run out
-    model.clear();
-    for (int i = 0; i < 50; i++)
-        model.addItem("Item" + QString::number(i), "");
-
-    // QTBUG-QTBUG-20575
-    listview->setCurrentIndex(0);
-    listview->setContentY(30);
-    model.removeItem(0);
-    QTRY_VERIFY(name = findItem<QSGText>(contentItem, "textName", 0));
-
-    // QTBUG-19198 move to end and remove all visible items one at a time.
-    listview->positionViewAtEnd();
-    for (int i = 0; i < 18; ++i)
-        model.removeItems(model.count() - 1, 1);
-    QTRY_VERIFY(findItems<QSGItem>(contentItem, "wrapper").count() > 16);
-
-    delete canvas;
-    delete testObject;
-}
-
-template <class T>
-void tst_QSGListView::clear()
-{
-    QSGView *canvas = createView();
-
-    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);
-
-    model.clear();
-
-    QTRY_VERIFY(listview->count() == 0);
-    QTRY_VERIFY(listview->currentItem() == 0);
-    QTRY_VERIFY(listview->contentY() == 0);
-    QVERIFY(listview->currentIndex() == -1);
-
-    // confirm sanity when adding an item to cleared list
-    model.addItem("New", "1");
-    QTRY_VERIFY(listview->count() == 1);
-    QVERIFY(listview->currentItem() != 0);
-    QVERIFY(listview->currentIndex() == 0);
-
-    delete canvas;
-    delete testObject;
-}
-
-template <class T>
-void tst_QSGListView::moved()
-{
-    QFETCH(qreal, contentY);
-    QFETCH(int, from);
-    QFETCH(int, to);
-    QFETCH(int, count);
-    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);
-
-    QSGItem *currentItem = listview->currentItem();
-    QTRY_VERIFY(currentItem != 0);
-
-    listview->setContentY(contentY);
-    model.moveItems(from, to, count);
-
-    // wait for items to move
-    QTest::qWait(100);
-
-    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) {
-        if (i >= firstVisibleIndex + 16)    // index has moved out of view
-            continue;
-        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));
-
-        // current index should have been updated
-        if (item == currentItem)
-            QTRY_COMPARE(listview->currentIndex(), i);
-    }
-
-    delete canvas;
-    delete testObject;
-}
-
-void tst_QSGListView::moved_data()
-{
-    QTest::addColumn<qreal>("contentY");
-    QTest::addColumn<int>("from");
-    QTest::addColumn<int>("to");
-    QTest::addColumn<int>("count");
-    QTest::addColumn<qreal>("itemsOffsetAfterMove");
-
-    // model starts with 30 items, each 20px high, in area 320px high
-    // 16 items should be visible at a time
-    // itemsOffsetAfterMove should be > 0 whenever items above the visible pos have moved
-
-    QTest::newRow("move 1 forwards, within visible items")
-            << 0.0
-            << 1 << 4 << 1
-            << 0.0;
-
-    QTest::newRow("move 1 forwards, from non-visible -> visible")
-            << 80.0     // show 4-19
-            << 1 << 18 << 1
-            << 20.0;    // removed 1 item above the first visible, so item 0 should drop down by 1 to minimize movement
-
-    QTest::newRow("move 1 forwards, from non-visible -> visible (move first item)")
-            << 80.0     // show 4-19
-            << 0 << 4 << 1
-            << 20.0;    // first item has moved to below item4, everything drops down by size of 1 item
-
-    QTest::newRow("move 1 forwards, from visible -> non-visible")
-            << 0.0
-            << 1 << 16 << 1
-            << 0.0;
-
-    QTest::newRow("move 1 forwards, from visible -> non-visible (move first item)")
-            << 0.0
-            << 0 << 16 << 1
-            << 0.0;
-
-
-    QTest::newRow("move 1 backwards, within visible items")
-            << 0.0
-            << 4 << 1 << 1
-            << 0.0;
-
-    QTest::newRow("move 1 backwards, within visible items (to first index)")
-            << 0.0
-            << 4 << 0 << 1
-            << 0.0;
-
-    QTest::newRow("move 1 backwards, from non-visible -> visible")
-            << 0.0
-            << 20 << 4 << 1
-            << 0.0;
-
-    QTest::newRow("move 1 backwards, from non-visible -> visible (move last item)")
-            << 0.0
-            << 29 << 15 << 1
-            << 0.0;
-
-    QTest::newRow("move 1 backwards, from visible -> non-visible")
-            << 80.0     // show 4-19
-            << 16 << 1 << 1
-            << -20.0;   // to minimize movement, item 0 moves to -20, and other items do not move
-
-    QTest::newRow("move 1 backwards, from visible -> non-visible (move first item)")
-            << 80.0     // show 4-19
-            << 16 << 0 << 1
-            << -20.0;   // to minimize movement, item 16 (now at 0) moves to -20, and other items do not move
-
-
-    QTest::newRow("move multiple forwards, within visible items")
-            << 0.0
-            << 0 << 5 << 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
-            << 1 << 5 << 3
-            << 20.0 * 3;    // moving 3 from above the content y should adjust y positions accordingly
-
-    QTest::newRow("move multiple forwards, from non-visible -> visible (move first item)")
-            << 80.0     // show 4-19
-            << 0 << 5 << 3
-            << 20.0 * 3;        // moving 3 from above the content y should adjust y positions accordingly
-
-    QTest::newRow("move multiple forwards, from visible -> non-visible")
-            << 0.0
-            << 1 << 16 << 3
-            << 0.0;
-
-    QTest::newRow("move multiple forwards, from visible -> non-visible (move first item)")
-            << 0.0
-            << 0 << 16 << 3
-            << 0.0;
-
-
-    QTest::newRow("move multiple backwards, within visible items")
-            << 0.0
-            << 4 << 1 << 3
-            << 0.0;
-
-    QTest::newRow("move multiple backwards, from non-visible -> visible")
-            << 0.0
-            << 20 << 4 << 3
-            << 0.0;
-
-    QTest::newRow("move multiple backwards, from non-visible -> visible (move last item)")
-            << 0.0
-            << 27 << 10 << 3
-            << 0.0;
-
-    QTest::newRow("move multiple backwards, from visible -> non-visible")
-            << 80.0     // show 4-19
-            << 16 << 1 << 3
-            << -20.0 * 3;   // to minimize movement, 0 moves by -60, and other items do not move
-
-    QTest::newRow("move multiple backwards, from visible -> non-visible (move first item)")
-            << 80.0     // show 4-19
-            << 16 << 0 << 3
-            << -20.0 * 3;   // to minimize movement, 16,17,18 move to above item 0, and other items do not move
-}
-
-
-struct ListChange {
-    enum { Inserted, Removed, Moved, SetCurrent } type;
-    int index;
-    int count;
-    int to;     // Move
-
-    static ListChange insert(int index, int count = 1) { ListChange c = { Inserted, index, count, -1 }; return c; }
-    static ListChange remove(int index, int count = 1) { ListChange c = { Removed, index, count, -1 }; return c; }
-    static ListChange move(int index, int to, int count) { ListChange c = { Moved, index, count, to }; return c; }
-    static ListChange setCurrent(int index) { ListChange c = { SetCurrent, index, -1, -1 }; return c; }
-};
-Q_DECLARE_METATYPE(QList<ListChange>)
-
-void tst_QSGListView::multipleChanges()
-{
-    QFETCH(int, startCount);
-    QFETCH(QList<ListChange>, changes);
-    QFETCH(int, newCount);
-    QFETCH(int, newCurrentIndex);
-
-    QSGView *canvas = createView();
-    canvas->show();
-
-    TestModel model;
-    for (int i = 0; i < startCount; 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);
-
-    for (int i=0; i<changes.count(); i++) {
-        switch (changes[i].type) {
-            case ListChange::Inserted:
-            {
-                QList<QPair<QString, QString> > items;
-                for (int j=changes[i].index; j<changes[i].index + changes[i].count; ++j)
-                    items << qMakePair(QString("new item " + j), QString::number(j));
-                model.insertItems(changes[i].index, items);
-                break;
-            }
-            case ListChange::Removed:
-                model.removeItems(changes[i].index, changes[i].count);
-                break;
-            case ListChange::Moved:
-                model.moveItems(changes[i].index, changes[i].to, changes[i].count);
-                break;
-            case ListChange::SetCurrent:
-                listview->setCurrentIndex(changes[i].index);
-                break;
-        }
-    }
-
-    QTRY_COMPARE(listview->count(), newCount);
-    QCOMPARE(listview->count(), model.count());
-    QTRY_COMPARE(listview->currentIndex(), newCurrentIndex);
-
-    QSGText *name;
-    QSGText *number;
-    QSGItem *contentItem = listview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i=0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
-        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 testObject;
-    delete canvas;
-}
-
-void tst_QSGListView::multipleChanges_data()
-{
-    QTest::addColumn<int>("startCount");
-    QTest::addColumn<QList<ListChange> >("changes");
-    QTest::addColumn<int>("newCount");
-    QTest::addColumn<int>("newCurrentIndex");
-
-    QList<ListChange> changes;
-
-    for (int i=1; i<30; i++)
-        changes << ListChange::remove(0);
-    QTest::newRow("remove all but 1, first->last") << 30 << changes << 1 << 0;
-
-    changes << ListChange::remove(0);
-    QTest::newRow("remove all") << 30 << changes << 0 << -1;
-
-    changes.clear();
-    changes << ListChange::setCurrent(29);
-    for (int i=29; i>0; i--)
-        changes << ListChange::remove(i);
-    QTest::newRow("remove last (current) -> first") << 30 << changes << 1 << 0;
-
-    QTest::newRow("remove then insert at 0") << 10 << (QList<ListChange>()
-            << ListChange::remove(0, 1)
-            << ListChange::insert(0, 1)
-            ) << 10 << 1;
-
-    QTest::newRow("remove then insert at non-zero index") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(2)
-            << ListChange::remove(2, 1)
-            << ListChange::insert(2, 1)
-            ) << 10 << 3;
-
-    QTest::newRow("remove current then insert below it") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(1)
-            << ListChange::remove(1, 3)
-            << ListChange::insert(2, 2)
-            ) << 9 << 1;
-
-    QTest::newRow("remove current index then move it down") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(2)
-            << ListChange::remove(1, 3)
-            << ListChange::move(1, 5, 1)
-            ) << 7 << 5;
-
-    QTest::newRow("remove current index then move it up") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(5)
-            << ListChange::remove(4, 3)
-            << ListChange::move(4, 1, 1)
-            ) << 7 << 1;
-
-
-    QTest::newRow("insert multiple times") << 0 << (QList<ListChange>()
-            << ListChange::insert(0, 2)
-            << ListChange::insert(0, 4)
-            << ListChange::insert(0, 6)
-            ) << 12 << 10;
-
-    QTest::newRow("insert multiple times with current index changes") << 0 << (QList<ListChange>()
-            << ListChange::insert(0, 2)
-            << ListChange::insert(0, 4)
-            << ListChange::insert(0, 6)
-            << ListChange::setCurrent(3)
-            << ListChange::insert(3, 2)
-            ) << 14 << 5;
-
-    QTest::newRow("insert and remove all") << 0 << (QList<ListChange>()
-            << ListChange::insert(0, 30)
-            << ListChange::remove(0, 30)
-            ) << 0 << -1;
-
-    QTest::newRow("insert and remove current") << 30 << (QList<ListChange>()
-            << ListChange::insert(1)
-            << ListChange::setCurrent(1)
-            << ListChange::remove(1)
-            ) << 30 << 1;
-
-    QTest::newRow("insert before 0, then remove cross section of new and old items") << 10 << (QList<ListChange>()
-            << ListChange::insert(0, 10)
-            << ListChange::remove(5, 10)
-            ) << 10 << 5;
-
-    QTest::newRow("insert multiple, then move new items to end") << 10 << (QList<ListChange>()
-            << ListChange::insert(0, 3)
-            << ListChange::move(0, 10, 3)
-            ) << 13 << 0;
-
-    QTest::newRow("insert multiple, then move new and some old items to end") << 10 << (QList<ListChange>()
-            << ListChange::insert(0, 3)
-            << ListChange::move(0, 8, 5)
-            ) << 13 << 11;
-
-    QTest::newRow("insert multiple at end, then move new and some old items to start") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(9)
-            << ListChange::insert(10, 3)
-            << ListChange::move(8, 0, 5)
-            ) << 13 << 1;
-
-
-    QTest::newRow("move back and forth to same index") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(1)
-            << ListChange::move(1, 2, 2)
-            << ListChange::move(2, 1, 2)
-            ) << 10 << 1;
-
-    QTest::newRow("move forwards then back") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(2)
-            << ListChange::move(1, 2, 3)
-            << ListChange::move(3, 0, 5)
-            ) << 10 << 0;
-
-    QTest::newRow("move current, then remove it") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(5)
-            << ListChange::move(5, 0, 1)
-            << ListChange::remove(0)
-            ) << 9 << 0;
-
-    QTest::newRow("move current, then insert before it") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(5)
-            << ListChange::move(5, 0, 1)
-            << ListChange::insert(0)
-            ) << 11 << 1;
-
-    QTest::newRow("move multiple, then remove them") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(1)
-            << ListChange::move(5, 1, 3)
-            << ListChange::remove(1, 3)
-            ) << 7 << 1;
-
-    QTest::newRow("move multiple, then insert before them") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(5)
-            << ListChange::move(5, 1, 3)
-            << ListChange::insert(1, 5)
-            ) << 15 << 6;
-
-    QTest::newRow("move multiple, then insert after them") << 10 << (QList<ListChange>()
-            << ListChange::setCurrent(3)
-            << ListChange::move(0, 1, 2)
-            << ListChange::insert(3, 5)
-            ) << 15 << 8;
-
-
-    QTest::newRow("clear current") << 0 << (QList<ListChange>()
-            << ListChange::insert(0, 5)
-            << ListChange::setCurrent(-1)
-            << ListChange::remove(0, 5)
-            << ListChange::insert(0, 5)
-            ) << 5 << -1;
-}
-
-void tst_QSGListView::swapWithFirstItem()
-{
-    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);
-
-    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);
-
-    // ensure content position is stable
-    listview->setContentY(0);
-    model.moveItem(1, 0);
-    QTRY_VERIFY(listview->contentY() == 0);
-
-    delete testObject;
-    delete canvas;
-}
-
-void tst_QSGListView::enforceRange()
-{
-    QSGView *canvas = createView();
-
-    TestModel model;
-    for (int i = 0; i < 30; i++)
-        model.addItem("Item" + QString::number(i), "");
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-enforcerange.qml")));
-    qApp->processEvents();
-
-    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
-    QTRY_VERIFY(listview != 0);
-
-    QTRY_COMPARE(listview->preferredHighlightBegin(), 100.0);
-    QTRY_COMPARE(listview->preferredHighlightEnd(), 100.0);
-    QTRY_COMPARE(listview->highlightRangeMode(), QSGListView::StrictlyEnforceRange);
-
-    QSGItem *contentItem = listview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    // view should be positioned at the top of the range.
-    QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", 0);
-    QTRY_VERIFY(item);
-    QTRY_COMPARE(listview->contentY(), -100.0);
-
-    QSGText *name = findItem<QSGText>(contentItem, "textName", 0);
-    QTRY_VERIFY(name != 0);
-    QTRY_COMPARE(name->text(), model.name(0));
-    QSGText *number = findItem<QSGText>(contentItem, "textNumber", 0);
-    QTRY_VERIFY(number != 0);
-    QTRY_COMPARE(number->text(), model.number(0));
-
-    // Check currentIndex is updated when contentItem moves
-    listview->setContentY(20);
-
-    QTRY_COMPARE(listview->currentIndex(), 6);
-
-    // change model
-    TestModel model2;
-    for (int i = 0; i < 5; i++)
-        model2.addItem("Item" + QString::number(i), "");
-
-    ctxt->setContextProperty("testModel", &model2);
-    QCOMPARE(listview->count(), 5);
-
-    delete canvas;
-}
-
-void tst_QSGListView::enforceRange_withoutHighlight()
-{
-    // QTBUG-20287
-    // If no highlight is set but StrictlyEnforceRange is used, the content should still move
-    // to the correct position (i.e. to the next/previous item, not next/previous section)
-    // when moving up/down via incrementCurrentIndex() and decrementCurrentIndex()
-
-    QSGView *canvas = createView();
-    canvas->show();
-    QTest::qWait(200);
-
-    TestModel model;
-    model.addItem("Item 0", "a");
-    model.addItem("Item 1", "b");
-    model.addItem("Item 2", "b");
-    model.addItem("Item 3", "c");
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-enforcerange-nohighlight.qml")));
-    qApp->processEvents();
-
-    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
-    QTRY_VERIFY(listview != 0);
-
-    qreal expectedPos = -100.0;
-
-    expectedPos += 10.0;    // scroll past 1st section's delegate (10px height)
-    QTRY_COMPARE(listview->contentY(), expectedPos);
-
-    expectedPos += 20 + 10;     // scroll past 1st section and section delegate of 2nd section
-    QTest::keyClick(canvas, Qt::Key_Down);
-
-    QTRY_COMPARE(listview->contentY(), expectedPos);
-
-    expectedPos += 20;     // scroll past 1st item of 2nd section
-    QTest::keyClick(canvas, Qt::Key_Down);
-    QTRY_COMPARE(listview->contentY(), expectedPos);
-
-    expectedPos += 20 + 10;     // scroll past 2nd item of 2nd section and section delegate of 3rd section
-    QTest::keyClick(canvas, Qt::Key_Down);
-    QTRY_COMPARE(listview->contentY(), expectedPos);
-
-    delete canvas;
-}
-
-void tst_QSGListView::spacing()
-{
-    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);
-
-    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);
-
-    // Confirm items positioned correctly
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_VERIFY(item->y() == i*20);
-    }
-
-    listview->setSpacing(10);
-    QTRY_VERIFY(listview->spacing() == 10);
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_VERIFY(item->y() == i*30);
-    }
-
-    listview->setSpacing(0);
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->y(), i*20.0);
-    }
-
-    delete canvas;
-    delete testObject;
-}
-
-void tst_QSGListView::sections()
-{
-    QSGView *canvas = createView();
-    canvas->show();
-
-    TestModel model;
-    for (int i = 0; i < 30; i++)
-        model.addItem("Item" + QString::number(i), QString::number(i/5));
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-sections.qml")));
-    qApp->processEvents();
-
-    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
-    QTRY_VERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    // Confirm items positioned correctly
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->y(), qreal(i*20 + ((i+4)/5) * 20));
-        QSGText *next = findItem<QSGText>(item, "nextSection");
-        QCOMPARE(next->text().toInt(), (i+1)/5);
-    }
-
-    QSignalSpy currentSectionChangedSpy(listview, SIGNAL(currentSectionChanged()));
-
-    // Remove section boundary
-    model.removeItem(5);
-    QTRY_COMPARE(listview->count(), model.count());
-
-    // New section header created
-    QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", 5);
-    QTRY_VERIFY(item);
-    QTRY_COMPARE(item->height(), 40.0);
-
-    model.insertItem(3, "New Item", "0");
-    QTRY_COMPARE(listview->count(), model.count());
-
-    // Section header moved
-    item = findItem<QSGItem>(contentItem, "wrapper", 5);
-    QTRY_VERIFY(item);
-    QTRY_COMPARE(item->height(), 20.0);
-
-    item = findItem<QSGItem>(contentItem, "wrapper", 6);
-    QTRY_VERIFY(item);
-    QTRY_COMPARE(item->height(), 40.0);
-
-    // insert item which will become a section header
-    model.insertItem(6, "Replace header", "1");
-    QTRY_COMPARE(listview->count(), model.count());
-
-    item = findItem<QSGItem>(contentItem, "wrapper", 6);
-    QTRY_VERIFY(item);
-    QTRY_COMPARE(item->height(), 40.0);
-
-    item = findItem<QSGItem>(contentItem, "wrapper", 7);
-    QTRY_VERIFY(item);
-    QTRY_COMPARE(item->height(), 20.0);
-
-    QTRY_COMPARE(listview->currentSection(), QString("0"));
-
-    listview->setContentY(140);
-    QTRY_COMPARE(listview->currentSection(), QString("1"));
-
-    QTRY_COMPARE(currentSectionChangedSpy.count(), 1);
-
-    listview->setContentY(20);
-    QTRY_COMPARE(listview->currentSection(), QString("0"));
-
-    QTRY_COMPARE(currentSectionChangedSpy.count(), 2);
-
-    item = findItem<QSGItem>(contentItem, "wrapper", 1);
-    QTRY_VERIFY(item);
-    QTRY_COMPARE(item->height(), 20.0);
-
-    // check that headers change when item changes
-    listview->setContentY(0);
-    model.modifyItem(0, "changed", "2");
-    QTest::qWait(300);
-
-    item = findItem<QSGItem>(contentItem, "wrapper", 1);
-    QTRY_VERIFY(item);
-    QTRY_COMPARE(item->height(), 40.0);
-
-    delete canvas;
-}
-
-void tst_QSGListView::sectionsDelegate()
-{
-    QSGView *canvas = createView();
-    canvas->show();
-
-    TestModel model;
-    for (int i = 0; i < 30; i++)
-        model.addItem("Item" + QString::number(i), QString::number(i/5));
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-sections_delegate.qml")));
-    qApp->processEvents();
-
-    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
-    QTRY_VERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    // Confirm items positioned correctly
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->y(), qreal(i*20 + ((i+5)/5) * 20));
-        QSGText *next = findItem<QSGText>(item, "nextSection");
-        QCOMPARE(next->text().toInt(), (i+1)/5);
-    }
-
-    for (int i = 0; i < 3; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "sect_" + QString::number(i));
-        QVERIFY(item);
-        QTRY_COMPARE(item->y(), qreal(i*20*6));
-    }
-
-    model.modifyItem(0, "One", "aaa");
-    model.modifyItem(1, "Two", "aaa");
-    model.modifyItem(2, "Three", "aaa");
-    model.modifyItem(3, "Four", "aaa");
-    model.modifyItem(4, "Five", "aaa");
-    QTest::qWait(300);
-
-    for (int i = 0; i < 3; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem,
-                "sect_" + (i == 0 ? QString("aaa") : QString::number(i)));
-        QVERIFY(item);
-        QTRY_COMPARE(item->y(), qreal(i*20*6));
-    }
-
-    // remove section boundary
-    model.removeItem(5);
-    QTRY_COMPARE(listview->count(), model.count());
-    for (int i = 0; i < 3; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem,
-                "sect_" + (i == 0 ? QString("aaa") : QString::number(i)));
-        QVERIFY(item);
-    }
-
-    // QTBUG-17606
-    QList<QSGItem*> items = findItems<QSGItem>(contentItem, "sect_1");
-    QCOMPARE(items.count(), 1);
-
-    // QTBUG-17759
-    model.modifyItem(0, "One", "aaa");
-    model.modifyItem(1, "One", "aaa");
-    model.modifyItem(2, "One", "aaa");
-    model.modifyItem(3, "Four", "aaa");
-    model.modifyItem(4, "Four", "aaa");
-    model.modifyItem(5, "Four", "aaa");
-    model.modifyItem(6, "Five", "aaa");
-    model.modifyItem(7, "Five", "aaa");
-    model.modifyItem(8, "Five", "aaa");
-    model.modifyItem(9, "Two", "aaa");
-    model.modifyItem(10, "Two", "aaa");
-    model.modifyItem(11, "Two", "aaa");
-    QTRY_COMPARE(findItems<QSGItem>(contentItem, "sect_aaa").count(), 1);
-    canvas->rootObject()->setProperty("sectionProperty", "name");
-    // ensure view has settled.
-    QTRY_COMPARE(findItems<QSGItem>(contentItem, "sect_Four").count(), 1);
-    for (int i = 0; i < 4; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem,
-                "sect_" + model.name(i*3));
-        QVERIFY(item);
-        QTRY_COMPARE(item->y(), qreal(i*20*4));
-    }
-
-    // QTBUG-17769
-    model.removeItems(10, 20);
-    // ensure view has settled.
-    QTRY_COMPARE(findItems<QSGItem>(contentItem, "wrapper").count(), 10);
-    // Drag view up beyond bounds
-    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(20,20));
-    {
-        QMouseEvent mv(QEvent::MouseMove, QPoint(20,0), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
-        QApplication::sendEvent(canvas, &mv);
-    }
-    {
-        QMouseEvent mv(QEvent::MouseMove, QPoint(20,-50), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
-        QApplication::sendEvent(canvas, &mv);
-    }
-    {
-        QMouseEvent mv(QEvent::MouseMove, QPoint(20,-200), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
-        QApplication::sendEvent(canvas, &mv);
-    }
-    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(20,-200));
-    // view should settle back at 0
-    QTRY_COMPARE(listview->contentY(), 0.0);
-
-    delete canvas;
-}
-
-void tst_QSGListView::sectionsPositioning()
-{
-    QSGView *canvas = createView();
-    canvas->show();
-
-    TestModel model;
-    for (int i = 0; i < 30; i++)
-        model.addItem("Item" + QString::number(i), QString::number(i/5));
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-sections_delegate.qml")));
-    qApp->processEvents();
-    canvas->rootObject()->setProperty("sectionPositioning", QVariant(int(QSGViewSection::InlineLabels | QSGViewSection::CurrentLabelAtStart | QSGViewSection::NextLabelAtEnd)));
-
-    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
-    QTRY_VERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    for (int i = 0; i < 3; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "sect_" + QString::number(i));
-        QVERIFY(item);
-        QTRY_COMPARE(item->y(), qreal(i*20*6));
-    }
-
-    QSGItem *topItem = findVisibleChild(contentItem, "sect_0"); // section header
-    QVERIFY(topItem);
-    QCOMPARE(topItem->y(), 0.);
-
-    QSGItem *bottomItem = findVisibleChild(contentItem, "sect_3"); // section footer
-    QVERIFY(bottomItem);
-    QCOMPARE(bottomItem->y(), 300.);
-
-    // move down a little and check that section header is at top
-    listview->setContentY(10);
-    QCOMPARE(topItem->y(), 0.);
-
-    // push the top header up
-    listview->setContentY(110);
-    topItem = findVisibleChild(contentItem, "sect_0"); // section header
-    QVERIFY(topItem);
-    QCOMPARE(topItem->y(), 100.);
-
-    QSGItem *item = findVisibleChild(contentItem, "sect_1");
-    QVERIFY(item);
-    QCOMPARE(item->y(), 120.);
-
-    bottomItem = findVisibleChild(contentItem, "sect_4"); // section footer
-    QVERIFY(bottomItem);
-    QCOMPARE(bottomItem->y(), 410.);
-
-    // Move past section 0
-    listview->setContentY(120);
-    topItem = findVisibleChild(contentItem, "sect_0"); // section header
-    QVERIFY(!topItem);
-
-    // Push section footer down
-    listview->setContentY(70);
-    bottomItem = findVisibleChild(contentItem, "sect_4"); // section footer
-    QVERIFY(bottomItem);
-    QCOMPARE(bottomItem->y(), 380.);
-
-    // Change current section
-    listview->setContentY(10);
-    model.modifyItem(0, "One", "aaa");
-    model.modifyItem(1, "Two", "aaa");
-    model.modifyItem(2, "Three", "aaa");
-    model.modifyItem(3, "Four", "aaa");
-    model.modifyItem(4, "Five", "aaa");
-    QTest::qWait(300);
-
-    QTRY_COMPARE(listview->currentSection(), QString("aaa"));
-
-    for (int i = 0; i < 3; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem,
-                "sect_" + (i == 0 ? QString("aaa") : QString::number(i)));
-        QVERIFY(item);
-        QTRY_COMPARE(item->y(), qreal(i*20*6));
-    }
-
-    topItem = findVisibleChild(contentItem, "sect_aaa"); // section header
-    QVERIFY(topItem);
-    QCOMPARE(topItem->y(), 10.);
-
-    // remove section boundary
-    listview->setContentY(120);
-    model.removeItem(5);
-    QTRY_COMPARE(listview->count(), model.count());
-    for (int i = 0; i < 3; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem,
-                "sect_" + (i == 0 ? QString("aaa") : QString::number(i)));
-        QVERIFY(item);
-        QTRY_COMPARE(item->y(), qreal(i*20*6));
-    }
-
-    QTRY_VERIFY(topItem = findVisibleChild(contentItem, "sect_aaa")); // section header
-    QCOMPARE(topItem->y(), 120.);
-    QVERIFY(topItem = findVisibleChild(contentItem, "sect_1"));
-    QTRY_COMPARE(topItem->y(), 140.);
-
-    // Change the next section
-    listview->setContentY(0);
-    bottomItem = findVisibleChild(contentItem, "sect_3"); // section footer
-    QVERIFY(bottomItem);
-    QTRY_COMPARE(bottomItem->y(), 320.);
-
-    model.modifyItem(14, "New", "new");
-
-    QTRY_VERIFY(bottomItem = findVisibleChild(contentItem, "sect_new")); // section footer
-    QTRY_COMPARE(bottomItem->y(), 320.);
-
-    // Turn sticky footer off
-    listview->setContentY(50);
-    canvas->rootObject()->setProperty("sectionPositioning", QVariant(int(QSGViewSection::InlineLabels | QSGViewSection::CurrentLabelAtStart)));
-    item = findVisibleChild(contentItem, "sect_new"); // inline label restored
-    QCOMPARE(item->y(), 360.);
-
-    // Turn sticky header off
-    listview->setContentY(50);
-    canvas->rootObject()->setProperty("sectionPositioning", QVariant(int(QSGViewSection::InlineLabels)));
-    item = findVisibleChild(contentItem, "sect_aaa"); // inline label restored
-    QCOMPARE(item->y(), 20.);
-
-    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;
-    for (int i = 0; i < 30; i++)
-        model.addItem("Item" + QString::number(i), QString::number(i));
-
-    QSGView *canvas = new QSGView(0);
-    canvas->setGeometry(0,0,240,320);
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-    ctxt->setContextProperty("testWrap", QVariant(false));
-
-    QString filename(TESTDATA("listview-initCurrent.qml"));
-    canvas->setSource(QUrl::fromLocalFile(filename));
-
-    qApp->processEvents();
-
-    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
-    QTRY_VERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    // current item should be 20th item at startup
-    // and current item should be in view
-    QCOMPARE(listview->currentIndex(), 20);
-    QCOMPARE(listview->contentY(), 100.0);
-    QCOMPARE(listview->currentItem(), findItem<QSGItem>(contentItem, "wrapper", 20));
-    QCOMPARE(listview->highlightItem()->y(), listview->currentItem()->y());
-
-    // no wrap
-    listview->setCurrentIndex(0);
-    QCOMPARE(listview->currentIndex(), 0);
-    // confirm that the velocity is updated
-    QTRY_VERIFY(listview->verticalVelocity() != 0.0);
-
-    listview->incrementCurrentIndex();
-    QCOMPARE(listview->currentIndex(), 1);
-    listview->decrementCurrentIndex();
-    QCOMPARE(listview->currentIndex(), 0);
-
-    listview->decrementCurrentIndex();
-    QCOMPARE(listview->currentIndex(), 0);
-
-    // with wrap
-    ctxt->setContextProperty("testWrap", QVariant(true));
-    QVERIFY(listview->isWrapEnabled());
-
-    listview->decrementCurrentIndex();
-    QCOMPARE(listview->currentIndex(), model.count()-1);
-
-    QTRY_COMPARE(listview->contentY(), 280.0);
-
-    listview->incrementCurrentIndex();
-    QCOMPARE(listview->currentIndex(), 0);
-
-    QTRY_COMPARE(listview->contentY(), 0.0);
-
-
-    // footer should become visible if it is out of view, and then current index is set to count-1
-    canvas->rootObject()->setProperty("showFooter", true);
-    QTRY_VERIFY(listview->footerItem());
-    listview->setCurrentIndex(model.count()-2);
-    QTRY_VERIFY(listview->footerItem()->y() > listview->contentY() + listview->height());
-    listview->setCurrentIndex(model.count()-1);
-    QTRY_COMPARE(listview->contentY() + listview->height(), (20.0 * model.count()) + listview->footerItem()->height());
-    canvas->rootObject()->setProperty("showFooter", false);
-
-    // header should become visible if it is out of view, and then current index is set to 0
-    canvas->rootObject()->setProperty("showHeader", true);
-    QTRY_VERIFY(listview->headerItem());
-    listview->setCurrentIndex(1);
-    QTRY_VERIFY(listview->headerItem()->y() + listview->headerItem()->height() < listview->contentY());
-    listview->setCurrentIndex(0);
-    QTRY_COMPARE(listview->contentY(), -listview->headerItem()->height());
-    canvas->rootObject()->setProperty("showHeader", false);
-
-
-    // Test keys
-    canvas->show();
-    canvas->requestActivateWindow();
-    QTest::qWaitForWindowShown(canvas);
-    QTRY_VERIFY(qGuiApp->focusWindow() == canvas);
-
-    listview->setCurrentIndex(0);
-
-    QTest::keyClick(canvas, Qt::Key_Down);
-    QCOMPARE(listview->currentIndex(), 1);
-
-    QTest::keyClick(canvas, Qt::Key_Up);
-    QCOMPARE(listview->currentIndex(), 0);
-
-    // hold down Key_Down
-    for (int i=0; i<model.count()-1; i++) {
-        QTest::simulateEvent(canvas, true, Qt::Key_Down, Qt::NoModifier, "", true);
-        QTRY_COMPARE(listview->currentIndex(), i+1);
-    }
-    QTest::keyRelease(canvas, Qt::Key_Down);
-    QTRY_COMPARE(listview->currentIndex(), model.count()-1);
-    QTRY_COMPARE(listview->contentY(), 280.0);
-
-    // hold down Key_Up
-    for (int i=model.count()-1; i > 0; i--) {
-        QTest::simulateEvent(canvas, true, Qt::Key_Up, Qt::NoModifier, "", true);
-        QTRY_COMPARE(listview->currentIndex(), i-1);
-    }
-    QTest::keyRelease(canvas, Qt::Key_Up);
-    QTRY_COMPARE(listview->currentIndex(), 0);
-    QTRY_COMPARE(listview->contentY(), 0.0);
-
-
-    // turn off auto highlight
-    listview->setHighlightFollowsCurrentItem(false);
-    QVERIFY(listview->highlightFollowsCurrentItem() == false);
-
-    QVERIFY(listview->highlightItem());
-    qreal hlPos = listview->highlightItem()->y();
-
-    listview->setCurrentIndex(4);
-    QTRY_COMPARE(listview->highlightItem()->y(), hlPos);
-
-    // insert item before currentIndex
-    listview->setCurrentIndex(28);
-    model.insertItem(0, "Foo", "1111");
-    QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29);
-
-    // check removing highlight by setting currentIndex to -1;
-    listview->setCurrentIndex(-1);
-
-    QCOMPARE(listview->currentIndex(), -1);
-    QVERIFY(!listview->highlightItem());
-    QVERIFY(!listview->currentItem());
-
-    delete canvas;
-}
-
-void tst_QSGListView::noCurrentIndex()
-{
-    TestModel model;
-    for (int i = 0; i < 30; i++)
-        model.addItem("Item" + QString::number(i), QString::number(i));
-
-    QSGView *canvas = new QSGView(0);
-    canvas->setGeometry(0,0,240,320);
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-
-    QString filename(TESTDATA("listview-noCurrent.qml"));
-    canvas->setSource(QUrl::fromLocalFile(filename));
-
-    qApp->processEvents();
-
-    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
-    QTRY_VERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    // current index should be -1 at startup
-    // and we should not have a currentItem or highlightItem
-    QCOMPARE(listview->currentIndex(), -1);
-    QCOMPARE(listview->contentY(), 0.0);
-    QVERIFY(!listview->highlightItem());
-    QVERIFY(!listview->currentItem());
-
-    listview->setCurrentIndex(2);
-    QCOMPARE(listview->currentIndex(), 2);
-    QVERIFY(listview->highlightItem());
-    QVERIFY(listview->currentItem());
-
-    delete canvas;
-}
-
-void tst_QSGListView::itemList()
-{
-    QSGView *canvas = createView();
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("itemlist.qml")));
-    qApp->processEvents();
-
-    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "view");
-    QTRY_VERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    QSGVisualItemModel *model = canvas->rootObject()->findChild<QSGVisualItemModel*>("itemModel");
-    QTRY_VERIFY(model != 0);
-
-    QTRY_VERIFY(model->count() == 3);
-    QTRY_COMPARE(listview->currentIndex(), 0);
-
-    QSGItem *item = findItem<QSGItem>(contentItem, "item1");
-    QTRY_VERIFY(item);
-    QTRY_COMPARE(item->x(), 0.0);
-    QCOMPARE(item->height(), listview->height());
-
-    QSGText *text = findItem<QSGText>(contentItem, "text1");
-    QTRY_VERIFY(text);
-    QTRY_COMPARE(text->text(), QLatin1String("index: 0"));
-
-    listview->setCurrentIndex(2);
-
-    item = findItem<QSGItem>(contentItem, "item3");
-    QTRY_VERIFY(item);
-    QTRY_COMPARE(item->x(), 480.0);
-
-    text = findItem<QSGText>(contentItem, "text3");
-    QTRY_VERIFY(text);
-    QTRY_COMPARE(text->text(), QLatin1String("index: 2"));
-
-    delete canvas;
-}
-
-void tst_QSGListView::cacheBuffer()
-{
-    QSGView *canvas = createView();
-
-    TestModel 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);
-    QTRY_VERIFY(listview->delegate() != 0);
-    QTRY_VERIFY(listview->model() != 0);
-    QTRY_VERIFY(listview->highlight() != 0);
-
-    // Confirm items positioned correctly
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_VERIFY(item->y() == i*20);
-    }
-
-    testObject->setCacheBuffer(400);
-    QTRY_VERIFY(listview->cacheBuffer() == 400);
-
-    int newItemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    QTRY_VERIFY(newItemCount > itemCount);
-
-    // Confirm items positioned correctly
-    for (int i = 0; i < model.count() && i < newItemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_VERIFY(item->y() == i*20);
-    }
-
-    delete canvas;
-    delete testObject;
-}
-
-void tst_QSGListView::positionViewAtIndex()
-{
-    QSGView *canvas = createView();
-
-    TestModel model;
-    for (int i = 0; i < 40; 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);
-
-    // Confirm items positioned correctly
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->y(), i*20.);
-    }
-
-    // Position on a currently visible item
-    listview->positionViewAtIndex(3, QSGListView::Beginning);
-    QTRY_COMPARE(listview->contentY(), 60.);
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 3; i < model.count() && i < itemCount-3-1; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->y(), i*20.);
-    }
-
-    // Position on an item beyond the visible items
-    listview->positionViewAtIndex(22, QSGListView::Beginning);
-    QTRY_COMPARE(listview->contentY(), 440.);
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 22; i < model.count() && i < itemCount-22-1; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->y(), i*20.);
-    }
-
-    // Position on an item that would leave empty space if positioned at the top
-    listview->positionViewAtIndex(28, QSGListView::Beginning);
-    QTRY_COMPARE(listview->contentY(), 480.);
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 24; i < model.count() && i < itemCount-24-1; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->y(), i*20.);
-    }
-
-    // Position at the beginning again
-    listview->positionViewAtIndex(0, QSGListView::Beginning);
-    QTRY_COMPARE(listview->contentY(), 0.);
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount-1; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->y(), i*20.);
-    }
-
-    // Position at End using last index
-    listview->positionViewAtIndex(model.count()-1, QSGListView::End);
-    QTRY_COMPARE(listview->contentY(), 480.);
-
-    // Confirm items positioned correctly
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 24; i < model.count(); ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->y(), i*20.);
-    }
-
-    // Position at End
-    listview->positionViewAtIndex(20, QSGListView::End);
-    QTRY_COMPARE(listview->contentY(), 100.);
-
-    // Position in Center
-    listview->positionViewAtIndex(15, QSGListView::Center);
-    QTRY_COMPARE(listview->contentY(), 150.);
-
-    // Ensure at least partially visible
-    listview->positionViewAtIndex(15, QSGListView::Visible);
-    QTRY_COMPARE(listview->contentY(), 150.);
-
-    listview->setContentY(302);
-    listview->positionViewAtIndex(15, QSGListView::Visible);
-    QTRY_COMPARE(listview->contentY(), 302.);
-
-    listview->setContentY(320);
-    listview->positionViewAtIndex(15, QSGListView::Visible);
-    QTRY_COMPARE(listview->contentY(), 300.);
-
-    listview->setContentY(85);
-    listview->positionViewAtIndex(20, QSGListView::Visible);
-    QTRY_COMPARE(listview->contentY(), 85.);
-
-    listview->setContentY(75);
-    listview->positionViewAtIndex(20, QSGListView::Visible);
-    QTRY_COMPARE(listview->contentY(), 100.);
-
-    // Ensure completely visible
-    listview->setContentY(120);
-    listview->positionViewAtIndex(20, QSGListView::Contain);
-    QTRY_COMPARE(listview->contentY(), 120.);
-
-    listview->setContentY(302);
-    listview->positionViewAtIndex(15, QSGListView::Contain);
-    QTRY_COMPARE(listview->contentY(), 300.);
-
-    listview->setContentY(85);
-    listview->positionViewAtIndex(20, QSGListView::Contain);
-    QTRY_COMPARE(listview->contentY(), 100.);
-
-    // positionAtBeginnging
-    listview->positionViewAtBeginning();
-    QTRY_COMPARE(listview->contentY(), 0.);
-
-    listview->setContentY(80);
-    canvas->rootObject()->setProperty("showHeader", true);
-    listview->positionViewAtBeginning();
-    QTRY_COMPARE(listview->contentY(), -30.);
-
-    // positionAtEnd
-    listview->positionViewAtEnd();
-    QTRY_COMPARE(listview->contentY(), 480.); // 40*20 - 320
-
-    listview->setContentY(80);
-    canvas->rootObject()->setProperty("showFooter", true);
-    listview->positionViewAtEnd();
-    QTRY_COMPARE(listview->contentY(), 510.);
-
-    // set current item to outside visible view, position at beginning
-    // and ensure highlight moves to current item
-    listview->setCurrentIndex(1);
-    listview->positionViewAtBeginning();
-    QTRY_COMPARE(listview->contentY(), -30.);
-    QVERIFY(listview->highlightItem());
-    QCOMPARE(listview->highlightItem()->y(), 20.);
-
-    delete canvas;
-    delete testObject;
-}
-
-void tst_QSGListView::resetModel()
-{
-    QSGView *canvas = createView();
-
-    QStringList strings;
-    strings << "one" << "two" << "three";
-    QStringListModel model(strings);
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaylist.qml")));
-    qApp->processEvents();
-
-    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
-    QTRY_VERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    QTRY_COMPARE(listview->count(), model.rowCount());
-
-    for (int i = 0; i < model.rowCount(); ++i) {
-        QSGText *display = findItem<QSGText>(contentItem, "displayText", i);
-        QTRY_VERIFY(display != 0);
-        QTRY_COMPARE(display->text(), strings.at(i));
-    }
-
-    strings.clear();
-    strings << "four" << "five" << "six" << "seven";
-    model.setStringList(strings);
-
-    QTRY_COMPARE(listview->count(), model.rowCount());
-
-    for (int i = 0; i < model.rowCount(); ++i) {
-        QSGText *display = findItem<QSGText>(contentItem, "displayText", i);
-        QTRY_VERIFY(display != 0);
-        QTRY_COMPARE(display->text(), strings.at(i));
-    }
-
-    delete canvas;
-}
-
-void tst_QSGListView::propertyChanges()
-{
-    QSGView *canvas = createView();
-    QTRY_VERIFY(canvas);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml")));
-
-    QSGListView *listView = canvas->rootObject()->findChild<QSGListView*>("listView");
-    QTRY_VERIFY(listView);
-
-    QSignalSpy highlightFollowsCurrentItemSpy(listView, SIGNAL(highlightFollowsCurrentItemChanged()));
-    QSignalSpy preferredHighlightBeginSpy(listView, SIGNAL(preferredHighlightBeginChanged()));
-    QSignalSpy preferredHighlightEndSpy(listView, SIGNAL(preferredHighlightEndChanged()));
-    QSignalSpy highlightRangeModeSpy(listView, SIGNAL(highlightRangeModeChanged()));
-    QSignalSpy keyNavigationWrapsSpy(listView, SIGNAL(keyNavigationWrapsChanged()));
-    QSignalSpy cacheBufferSpy(listView, SIGNAL(cacheBufferChanged()));
-    QSignalSpy snapModeSpy(listView, SIGNAL(snapModeChanged()));
-
-    QTRY_COMPARE(listView->highlightFollowsCurrentItem(), true);
-    QTRY_COMPARE(listView->preferredHighlightBegin(), 0.0);
-    QTRY_COMPARE(listView->preferredHighlightEnd(), 0.0);
-    QTRY_COMPARE(listView->highlightRangeMode(), QSGListView::ApplyRange);
-    QTRY_COMPARE(listView->isWrapEnabled(), true);
-    QTRY_COMPARE(listView->cacheBuffer(), 10);
-    QTRY_COMPARE(listView->snapMode(), QSGListView::SnapToItem);
-
-    listView->setHighlightFollowsCurrentItem(false);
-    listView->setPreferredHighlightBegin(1.0);
-    listView->setPreferredHighlightEnd(1.0);
-    listView->setHighlightRangeMode(QSGListView::StrictlyEnforceRange);
-    listView->setWrapEnabled(false);
-    listView->setCacheBuffer(3);
-    listView->setSnapMode(QSGListView::SnapOneItem);
-
-    QTRY_COMPARE(listView->highlightFollowsCurrentItem(), false);
-    QTRY_COMPARE(listView->preferredHighlightBegin(), 1.0);
-    QTRY_COMPARE(listView->preferredHighlightEnd(), 1.0);
-    QTRY_COMPARE(listView->highlightRangeMode(), QSGListView::StrictlyEnforceRange);
-    QTRY_COMPARE(listView->isWrapEnabled(), false);
-    QTRY_COMPARE(listView->cacheBuffer(), 3);
-    QTRY_COMPARE(listView->snapMode(), QSGListView::SnapOneItem);
-
-    QTRY_COMPARE(highlightFollowsCurrentItemSpy.count(),1);
-    QTRY_COMPARE(preferredHighlightBeginSpy.count(),1);
-    QTRY_COMPARE(preferredHighlightEndSpy.count(),1);
-    QTRY_COMPARE(highlightRangeModeSpy.count(),1);
-    QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
-    QTRY_COMPARE(cacheBufferSpy.count(),1);
-    QTRY_COMPARE(snapModeSpy.count(),1);
-
-    listView->setHighlightFollowsCurrentItem(false);
-    listView->setPreferredHighlightBegin(1.0);
-    listView->setPreferredHighlightEnd(1.0);
-    listView->setHighlightRangeMode(QSGListView::StrictlyEnforceRange);
-    listView->setWrapEnabled(false);
-    listView->setCacheBuffer(3);
-    listView->setSnapMode(QSGListView::SnapOneItem);
-
-    QTRY_COMPARE(highlightFollowsCurrentItemSpy.count(),1);
-    QTRY_COMPARE(preferredHighlightBeginSpy.count(),1);
-    QTRY_COMPARE(preferredHighlightEndSpy.count(),1);
-    QTRY_COMPARE(highlightRangeModeSpy.count(),1);
-    QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
-    QTRY_COMPARE(cacheBufferSpy.count(),1);
-    QTRY_COMPARE(snapModeSpy.count(),1);
-
-    delete canvas;
-}
-
-void tst_QSGListView::componentChanges()
-{
-    QSGView *canvas = createView();
-    QTRY_VERIFY(canvas);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml")));
-
-    QSGListView *listView = canvas->rootObject()->findChild<QSGListView*>("listView");
-    QTRY_VERIFY(listView);
-
-    QDeclarativeComponent component(canvas->engine());
-    component.setData("import QtQuick 2.0; Rectangle { color: \"blue\"; }", QUrl::fromLocalFile(""));
-
-    QDeclarativeComponent delegateComponent(canvas->engine());
-    delegateComponent.setData("import QtQuick 2.0; Text { text: '<b>Name:</b> ' + name }", QUrl::fromLocalFile(""));
-
-    QSignalSpy highlightSpy(listView, SIGNAL(highlightChanged()));
-    QSignalSpy delegateSpy(listView, SIGNAL(delegateChanged()));
-    QSignalSpy headerSpy(listView, SIGNAL(headerChanged()));
-    QSignalSpy footerSpy(listView, SIGNAL(footerChanged()));
-
-    listView->setHighlight(&component);
-    listView->setHeader(&component);
-    listView->setFooter(&component);
-    listView->setDelegate(&delegateComponent);
-
-    QTRY_COMPARE(listView->highlight(), &component);
-    QTRY_COMPARE(listView->header(), &component);
-    QTRY_COMPARE(listView->footer(), &component);
-    QTRY_COMPARE(listView->delegate(), &delegateComponent);
-
-    QTRY_COMPARE(highlightSpy.count(),1);
-    QTRY_COMPARE(delegateSpy.count(),1);
-    QTRY_COMPARE(headerSpy.count(),1);
-    QTRY_COMPARE(footerSpy.count(),1);
-
-    listView->setHighlight(&component);
-    listView->setHeader(&component);
-    listView->setFooter(&component);
-    listView->setDelegate(&delegateComponent);
-
-    QTRY_COMPARE(highlightSpy.count(),1);
-    QTRY_COMPARE(delegateSpy.count(),1);
-    QTRY_COMPARE(headerSpy.count(),1);
-    QTRY_COMPARE(footerSpy.count(),1);
-
-    delete canvas;
-}
-
-void tst_QSGListView::modelChanges()
-{
-    QSGView *canvas = createView();
-    QTRY_VERIFY(canvas);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml")));
-
-    QSGListView *listView = canvas->rootObject()->findChild<QSGListView*>("listView");
-    QTRY_VERIFY(listView);
-
-    QDeclarativeListModel *alternateModel = canvas->rootObject()->findChild<QDeclarativeListModel*>("alternateModel");
-    QTRY_VERIFY(alternateModel);
-    QVariant modelVariant = QVariant::fromValue<QObject *>(alternateModel);
-    QSignalSpy modelSpy(listView, SIGNAL(modelChanged()));
-
-    listView->setModel(modelVariant);
-    QTRY_COMPARE(listView->model(), modelVariant);
-    QTRY_COMPARE(modelSpy.count(),1);
-
-    listView->setModel(modelVariant);
-    QTRY_COMPARE(modelSpy.count(),1);
-
-    listView->setModel(QVariant());
-    QTRY_COMPARE(modelSpy.count(),2);
-
-    delete canvas;
-}
-
-void tst_QSGListView::QTBUG_9791()
-{
-    QSGView *canvas = createView();
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("strictlyenforcerange.qml")));
-    qApp->processEvents();
-
-    QSGListView *listview = qobject_cast<QSGListView*>(canvas->rootObject());
-    QTRY_VERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-    QTRY_VERIFY(listview->delegate() != 0);
-    QTRY_VERIFY(listview->model() != 0);
-
-    QMetaObject::invokeMethod(listview, "fillModel");
-    qApp->processEvents();
-
-    // Confirm items positioned correctly
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    QCOMPARE(itemCount, 3);
-
-    for (int i = 0; i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->x(), i*300.0);
-    }
-
-    // check that view is positioned correctly
-    QTRY_COMPARE(listview->contentX(), 590.0);
-
-    delete canvas;
-}
-
-void tst_QSGListView::manualHighlight()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setGeometry(0,0,240,320);
-
-    QString filename(TESTDATA("manual-highlight.qml"));
-    canvas->setSource(QUrl::fromLocalFile(filename));
-
-    qApp->processEvents();
-
-    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
-    QTRY_VERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    QTRY_COMPARE(listview->currentIndex(), 0);
-    QTRY_COMPARE(listview->currentItem(), findItem<QSGItem>(contentItem, "wrapper", 0));
-    QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y());
-
-    listview->setCurrentIndex(2);
-
-    QTRY_COMPARE(listview->currentIndex(), 2);
-    QTRY_COMPARE(listview->currentItem(), findItem<QSGItem>(contentItem, "wrapper", 2));
-    QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y());
-
-    // QTBUG-15972
-    listview->positionViewAtIndex(3, QSGListView::Contain);
-
-    QTRY_COMPARE(listview->currentIndex(), 2);
-    QTRY_COMPARE(listview->currentItem(), findItem<QSGItem>(contentItem, "wrapper", 2));
-    QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y());
-
-    delete canvas;
-}
-
-void tst_QSGListView::QTBUG_11105()
-{
-    QSGView *canvas = createView();
-
-    TestModel 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);
-
-    // Confirm items positioned correctly
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_VERIFY(item->y() == i*20);
-    }
-
-    listview->positionViewAtIndex(20, QSGListView::Beginning);
-    QCOMPARE(listview->contentY(), 280.);
-
-    TestModel model2;
-    for (int i = 0; i < 5; i++)
-        model2.addItem("Item" + QString::number(i), "");
-
-    ctxt->setContextProperty("testModel", &model2);
-
-    itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    QCOMPARE(itemCount, 5);
-
-    delete canvas;
-    delete testObject;
-}
-
-void tst_QSGListView::header()
-{
-    QFETCH(QSGListView::Orientation, orientation);
-    QFETCH(Qt::LayoutDirection, layoutDirection);
-    QFETCH(QPointF, initialHeaderPos);
-    QFETCH(QPointF, firstDelegatePos);
-    QFETCH(QPointF, initialContentPos);
-    QFETCH(QPointF, changedHeaderPos);
-    QFETCH(QPointF, changedContentPos);
-    QFETCH(QPointF, resizeContentPos);
-
-    TestModel model;
-    for (int i = 0; i < 30; i++)
-        model.addItem("Item" + QString::number(i), "");
-
-    QSGView *canvas = createView();
-    canvas->rootContext()->setContextProperty("testModel", &model);
-    canvas->rootContext()->setContextProperty("initialViewWidth", 240);
-    canvas->rootContext()->setContextProperty("initialViewHeight", 320);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml")));
-
-    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
-    QTRY_VERIFY(listview != 0);
-    listview->setOrientation(orientation);
-    listview->setLayoutDirection(layoutDirection);
-
-    QSGItem *contentItem = listview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    QSGText *header = findItem<QSGText>(contentItem, "header");
-    QVERIFY(header);
-
-    QVERIFY(header == listview->headerItem());
-
-    QCOMPARE(header->width(), 100.);
-    QCOMPARE(header->height(), 30.);
-    QCOMPARE(header->pos(), initialHeaderPos);
-    QCOMPARE(QPointF(listview->contentX(), listview->contentY()), initialContentPos);
-
-    QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", 0);
-    QVERIFY(item);
-    QCOMPARE(item->pos(), firstDelegatePos);
-
-    model.clear();
-    QCOMPARE(header->pos(), initialHeaderPos); // header should stay where it is
-
-    for (int i = 0; i < 30; i++)
-        model.addItem("Item" + QString::number(i), "");
-
-    QSignalSpy headerItemSpy(listview, SIGNAL(headerItemChanged()));
-    QMetaObject::invokeMethod(canvas->rootObject(), "changeHeader");
-
-    QCOMPARE(headerItemSpy.count(), 1);
-
-    header = findItem<QSGText>(contentItem, "header");
-    QVERIFY(!header);
-    header = findItem<QSGText>(contentItem, "header2");
-    QVERIFY(header);
-
-    QVERIFY(header == listview->headerItem());
-
-    QCOMPARE(header->pos(), changedHeaderPos);
-    QCOMPARE(header->width(), 50.);
-    QCOMPARE(header->height(), 20.);
-    QTRY_COMPARE(QPointF(listview->contentX(), listview->contentY()), changedContentPos);
-    QCOMPARE(item->pos(), firstDelegatePos);
-
-    delete canvas;
-
-
-    // QTBUG-21207 header should become visible if view resizes from initial empty size
-
-    canvas = createView();
-    canvas->rootContext()->setContextProperty("testModel", &model);
-    canvas->rootContext()->setContextProperty("initialViewWidth", 0.0);
-    canvas->rootContext()->setContextProperty("initialViewHeight", 0.0);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml")));
-
-    listview = findItem<QSGListView>(canvas->rootObject(), "list");
-    QTRY_VERIFY(listview != 0);
-    listview->setOrientation(orientation);
-    listview->setLayoutDirection(layoutDirection);
-
-    listview->setWidth(240);
-    listview->setHeight(320);
-    QTRY_COMPARE(listview->headerItem()->pos(), initialHeaderPos);
-    QCOMPARE(QPointF(listview->contentX(), listview->contentY()), initialContentPos);
-
-
-    delete canvas;
-}
-
-void tst_QSGListView::header_data()
-{
-    QTest::addColumn<QSGListView::Orientation>("orientation");
-    QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
-    QTest::addColumn<QPointF>("initialHeaderPos");
-    QTest::addColumn<QPointF>("changedHeaderPos");
-    QTest::addColumn<QPointF>("initialContentPos");
-    QTest::addColumn<QPointF>("changedContentPos");
-    QTest::addColumn<QPointF>("firstDelegatePos");
-    QTest::addColumn<QPointF>("resizeContentPos");
-
-    // header1 = 100 x 30
-    // header2 = 50 x 20
-    // delegates = 240 x 20
-    // view width = 240
-
-    // header above items, top left
-    QTest::newRow("vertical, left to right") << QSGListView::Vertical << Qt::LeftToRight
-        << QPointF(0, -30)
-        << QPointF(0, -20)
-        << QPointF(0, -30)
-        << QPointF(0, -20)
-        << QPointF(0, 0)
-        << QPointF(0, -10);
-
-    // header above items, top right
-    QTest::newRow("vertical, layout right to left") << QSGListView::Vertical << Qt::RightToLeft
-        << QPointF(0, -30)
-        << QPointF(0, -20)
-        << QPointF(0, -30)
-        << QPointF(0, -20)
-        << QPointF(0, 0)
-        << QPointF(0, -10);
-
-    // header to left of items
-    QTest::newRow("horizontal, layout left to right") << QSGListView::Horizontal << Qt::LeftToRight
-        << QPointF(-100, 0)
-        << QPointF(-50, 0)
-        << QPointF(-100, 0)
-        << QPointF(-50, 0)
-        << QPointF(0, 0)
-        << QPointF(-40, 0);
-
-    // header to right of items
-    QTest::newRow("horizontal, layout right to left") << QSGListView::Horizontal << Qt::RightToLeft
-        << QPointF(0, 0)
-        << QPointF(0, 0)
-        << QPointF(-240 + 100, 0)
-        << QPointF(-240 + 50, 0)
-        << QPointF(-240, 0)
-        << QPointF(-240 + 40, 0);
-}
-
-void tst_QSGListView::header_delayItemCreation()
-{
-    QSGView *canvas = createView();
-
-    TestModel model;
-
-    canvas->rootContext()->setContextProperty("setCurrentToZero", false);
-    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);
-
-    QSGText *header = findItem<QSGText>(contentItem, "header");
-    QVERIFY(header);
-    QCOMPARE(header->y(), -header->height());
-
-    QCOMPARE(listview->contentY(), -header->height());
-
-    model.clear();
-    QTRY_COMPARE(header->y(), -header->height());
-
-    delete canvas;
-}
-
-void tst_QSGListView::footer()
-{
-    QFETCH(QSGListView::Orientation, orientation);
-    QFETCH(Qt::LayoutDirection, layoutDirection);
-    QFETCH(QPointF, initialFooterPos);
-    QFETCH(QPointF, firstDelegatePos);
-    QFETCH(QPointF, initialContentPos);
-    QFETCH(QPointF, changedFooterPos);
-    QFETCH(QPointF, changedContentPos);
-    QFETCH(QPointF, resizeContentPos);
-
-    QSGView *canvas = createView();
-
-    TestModel model;
-    for (int i = 0; i < 3; i++)
-        model.addItem("Item" + QString::number(i), "");
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("footer.qml")));
-    canvas->show();
-    qApp->processEvents();
-
-    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
-    QTRY_VERIFY(listview != 0);
-    listview->setOrientation(orientation);
-    listview->setLayoutDirection(layoutDirection);
-
-    QSGItem *contentItem = listview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    QSGText *footer = findItem<QSGText>(contentItem, "footer");
-    QVERIFY(footer);
-
-    QVERIFY(footer == listview->footerItem());
-
-    QCOMPARE(footer->pos(), initialFooterPos);
-    QCOMPARE(footer->width(), 100.);
-    QCOMPARE(footer->height(), 30.);
-    QCOMPARE(QPointF(listview->contentX(), listview->contentY()), initialContentPos);
-
-    QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", 0);
-    QVERIFY(item);
-    QCOMPARE(item->pos(), firstDelegatePos);
-
-    // remove one item
-    model.removeItem(1);
-
-    if (orientation == QSGListView::Vertical) {
-        QTRY_COMPARE(footer->y(), initialFooterPos.y() - 20);   // delegate height = 20
-    } else {
-        QTRY_COMPARE(footer->x(), layoutDirection == Qt::LeftToRight ?
-                initialFooterPos.x() - 40 : initialFooterPos.x() + 40);  // delegate width = 40
-    }
-
-    // remove all items
-    model.clear();
-
-    QPointF posWhenNoItems(0, 0);
-    if (orientation == QSGListView::Horizontal && layoutDirection == Qt::RightToLeft)
-        posWhenNoItems.setX(-100);
-    QTRY_COMPARE(footer->pos(), posWhenNoItems);
-
-    // if header is present, it's at a negative pos, so the footer should not move
-    canvas->rootObject()->setProperty("showHeader", true);
-    QTRY_COMPARE(footer->pos(), posWhenNoItems);
-    canvas->rootObject()->setProperty("showHeader", false);
-
-    // add 30 items
-    for (int i = 0; i < 30; i++)
-        model.addItem("Item" + QString::number(i), "");
-
-    QSignalSpy footerItemSpy(listview, SIGNAL(footerItemChanged()));
-    QMetaObject::invokeMethod(canvas->rootObject(), "changeFooter");
-
-    QCOMPARE(footerItemSpy.count(), 1);
-
-    footer = findItem<QSGText>(contentItem, "footer");
-    QVERIFY(!footer);
-    footer = findItem<QSGText>(contentItem, "footer2");
-    QVERIFY(footer);
-
-    QVERIFY(footer == listview->footerItem());
-
-    QCOMPARE(footer->pos(), changedFooterPos);
-    QCOMPARE(footer->width(), 50.);
-    QCOMPARE(footer->height(), 20.);
-    QTRY_COMPARE(QPointF(listview->contentX(), listview->contentY()), changedContentPos);
-
-    item = findItem<QSGItem>(contentItem, "wrapper", 0);
-    QVERIFY(item);
-    QCOMPARE(item->pos(), firstDelegatePos);
-
-    listview->positionViewAtEnd();
-    footer->setHeight(10);
-    footer->setWidth(40);
-    QTRY_COMPARE(QPointF(listview->contentX(), listview->contentY()), resizeContentPos);
-
-    delete canvas;
-}
-
-void tst_QSGListView::footer_data()
-{
-    QTest::addColumn<QSGListView::Orientation>("orientation");
-    QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
-    QTest::addColumn<QPointF>("initialFooterPos");
-    QTest::addColumn<QPointF>("changedFooterPos");
-    QTest::addColumn<QPointF>("initialContentPos");
-    QTest::addColumn<QPointF>("changedContentPos");
-    QTest::addColumn<QPointF>("firstDelegatePos");
-    QTest::addColumn<QPointF>("resizeContentPos");
-
-    // footer1 = 100 x 30
-    // footer2 = 50 x 20
-    // delegates = 40 x 20
-    // view width = 240
-    // view height = 320
-
-    // footer below items, bottom left
-    QTest::newRow("vertical, layout left to right") << QSGListView::Vertical << Qt::LeftToRight
-        << QPointF(0, 3 * 20)
-        << QPointF(0, 30 * 20)  // added 30 items
-        << QPointF(0, 0)
-        << QPointF(0, 0)
-        << QPointF(0, 0)
-        << QPointF(0, 30 * 20 - 320 + 10);
-
-    // footer below items, bottom right
-    QTest::newRow("vertical, layout right to left") << QSGListView::Vertical << Qt::RightToLeft
-        << QPointF(0, 3 * 20)
-        << QPointF(0, 30 * 20)
-        << QPointF(0, 0)
-        << QPointF(0, 0)
-        << QPointF(0, 0)
-        << QPointF(0, 30 * 20 - 320 + 10);
-
-    // footer to right of items
-    QTest::newRow("horizontal, layout left to right") << QSGListView::Horizontal << Qt::LeftToRight
-        << QPointF(40 * 3, 0)
-        << QPointF(40 * 30, 0)
-        << QPointF(0, 0)
-        << QPointF(0, 0)
-        << QPointF(0, 0)
-        << QPointF(40 * 30 - 240 + 40, 0);
-
-    // footer to left of items
-    QTest::newRow("horizontal, layout right to left") << QSGListView::Horizontal << Qt::RightToLeft
-        << QPointF(-(40 * 3) - 100, 0)
-        << QPointF(-(40 * 30) - 50, 0)     // 50 = new footer width
-        << QPointF(-240, 0)
-        << QPointF(-240, 0)
-        << QPointF(-40, 0)
-        << QPointF(-(40 * 30) - 40, 0);
-}
-
-class LVAccessor : public QSGListView
-{
-public:
-    qreal minY() const { return minYExtent(); }
-    qreal maxY() const { return maxYExtent(); }
-    qreal minX() const { return minXExtent(); }
-    qreal maxX() const { return maxXExtent(); }
-};
-
-void tst_QSGListView::headerFooter()
-{
-    {
-        // Vertical
-        QSGView *canvas = createView();
-
-        TestModel model;
-        QDeclarativeContext *ctxt = canvas->rootContext();
-        ctxt->setContextProperty("testModel", &model);
-
-        canvas->setSource(QUrl::fromLocalFile(TESTDATA("headerfooter.qml")));
-        qApp->processEvents();
-
-        QSGListView *listview = qobject_cast<QSGListView*>(canvas->rootObject());
-        QTRY_VERIFY(listview != 0);
-
-        QSGItem *contentItem = listview->contentItem();
-        QTRY_VERIFY(contentItem != 0);
-
-        QSGItem *header = findItem<QSGItem>(contentItem, "header");
-        QVERIFY(header);
-        QCOMPARE(header->y(), -header->height());
-
-        QSGItem *footer = findItem<QSGItem>(contentItem, "footer");
-        QVERIFY(footer);
-        QCOMPARE(footer->y(), 0.);
-
-        QCOMPARE(static_cast<LVAccessor*>(listview)->minY(), header->height());
-        QCOMPARE(static_cast<LVAccessor*>(listview)->maxY(), header->height());
-
-        delete canvas;
-    }
-    {
-        // Horizontal
-        QSGView *canvas = createView();
-
-        TestModel model;
-        QDeclarativeContext *ctxt = canvas->rootContext();
-        ctxt->setContextProperty("testModel", &model);
-
-        canvas->setSource(QUrl::fromLocalFile(TESTDATA("headerfooter.qml")));
-        canvas->rootObject()->setProperty("horizontal", true);
-        qApp->processEvents();
-
-        QSGListView *listview = qobject_cast<QSGListView*>(canvas->rootObject());
-        QTRY_VERIFY(listview != 0);
-
-        QSGItem *contentItem = listview->contentItem();
-        QTRY_VERIFY(contentItem != 0);
-
-        QSGItem *header = findItem<QSGItem>(contentItem, "header");
-        QVERIFY(header);
-        QCOMPARE(header->x(), -header->width());
-
-        QSGItem *footer = findItem<QSGItem>(contentItem, "footer");
-        QVERIFY(footer);
-        QCOMPARE(footer->x(), 0.);
-
-        QCOMPARE(static_cast<LVAccessor*>(listview)->minX(), header->width());
-        QCOMPARE(static_cast<LVAccessor*>(listview)->maxX(), header->width());
-
-        delete canvas;
-    }
-    {
-        // Horizontal RTL
-        QSGView *canvas = createView();
-
-        TestModel model;
-        QDeclarativeContext *ctxt = canvas->rootContext();
-        ctxt->setContextProperty("testModel", &model);
-
-        canvas->setSource(QUrl::fromLocalFile(TESTDATA("headerfooter.qml")));
-        canvas->rootObject()->setProperty("horizontal", true);
-        canvas->rootObject()->setProperty("rtl", true);
-        qApp->processEvents();
-
-        QSGListView *listview = qobject_cast<QSGListView*>(canvas->rootObject());
-        QTRY_VERIFY(listview != 0);
-
-        QSGItem *contentItem = listview->contentItem();
-        QTRY_VERIFY(contentItem != 0);
-
-        QSGItem *header = findItem<QSGItem>(contentItem, "header");
-        QVERIFY(header);
-        QCOMPARE(header->x(), 0.);
-
-        QSGItem *footer = findItem<QSGItem>(contentItem, "footer");
-        QVERIFY(footer);
-        QCOMPARE(footer->x(), -footer->width());
-
-        QCOMPARE(static_cast<LVAccessor*>(listview)->minX(), 240. - header->width());
-        QCOMPARE(static_cast<LVAccessor*>(listview)->maxX(), 240. - header->width());
-
-        delete canvas;
-    }
-}
-
-void tst_QSGListView::resizeView()
-{
-    QSGView *canvas = createView();
-
-    TestModel model;
-    for (int i = 0; i < 40; 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);
-
-    // Confirm items positioned correctly
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->y(), i*20.);
-    }
-
-    QVariant heightRatio;
-    QMetaObject::invokeMethod(canvas->rootObject(), "heightRatio", Q_RETURN_ARG(QVariant, heightRatio));
-    QCOMPARE(heightRatio.toReal(), 0.4);
-
-    listview->setHeight(200);
-
-    QMetaObject::invokeMethod(canvas->rootObject(), "heightRatio", Q_RETURN_ARG(QVariant, heightRatio));
-    QCOMPARE(heightRatio.toReal(), 0.25);
-
-    delete canvas;
-    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();
-
-    TestModel 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("sizelessthan1.qml")));
-    qApp->processEvents();
-
-    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
-    QTRY_VERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    // Confirm items positioned correctly
-    int itemCount = findItems<QSGItem>(contentItem, "wrapper").count();
-    for (int i = 0; i < model.count() && i < itemCount; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        if (!item) qWarning() << "Item" << i << "not found";
-        QTRY_VERIFY(item);
-        QTRY_COMPARE(item->y(), i*0.5);
-    }
-
-    delete canvas;
-    delete testObject;
-}
-
-void tst_QSGListView::QTBUG_14821()
-{
-    QSGView *canvas = createView();
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("qtbug14821.qml")));
-    qApp->processEvents();
-
-    QSGListView *listview = qobject_cast<QSGListView*>(canvas->rootObject());
-    QVERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QVERIFY(contentItem != 0);
-
-    listview->decrementCurrentIndex();
-    QCOMPARE(listview->currentIndex(), 99);
-
-    listview->incrementCurrentIndex();
-    QCOMPARE(listview->currentIndex(), 0);
-
-    delete canvas;
-}
-
-void tst_QSGListView::resizeDelegate()
-{
-    QSGView *canvas = createView();
-    canvas->show();
-
-    QStringList strings;
-    for (int i = 0; i < 30; ++i)
-        strings << QString::number(i);
-    QStringListModel model(strings);
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaylist.qml")));
-    qApp->processEvents();
-
-    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
-    QVERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QVERIFY(contentItem != 0);
-
-    QCOMPARE(listview->count(), model.rowCount());
-
-    listview->setCurrentIndex(25);
-    listview->setContentY(0);
-    QTest::qWait(300);
-
-    for (int i = 0; i < 16; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        QVERIFY(item != 0);
-        QCOMPARE(item->y(), i*20.0);
-    }
-
-    QCOMPARE(listview->currentItem()->y(), 500.0);
-    QTRY_COMPARE(listview->highlightItem()->y(), 500.0);
-
-    canvas->rootObject()->setProperty("delegateHeight", 30);
-    QTest::qWait(300);
-
-    for (int i = 0; i < 11; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        QVERIFY(item != 0);
-        QTRY_COMPARE(item->y(), i*30.0);
-    }
-
-    QTRY_COMPARE(listview->currentItem()->y(), 750.0);
-    QTRY_COMPARE(listview->highlightItem()->y(), 750.0);
-
-    listview->setCurrentIndex(1);
-    listview->positionViewAtIndex(25, QSGListView::Beginning);
-    listview->positionViewAtIndex(5, QSGListView::Beginning);
-
-    for (int i = 5; i < 16; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        QVERIFY(item != 0);
-        QCOMPARE(item->y(), i*30.0);
-    }
-
-    QTRY_COMPARE(listview->currentItem()->y(), 30.0);
-    QTRY_COMPARE(listview->highlightItem()->y(), 30.0);
-
-    canvas->rootObject()->setProperty("delegateHeight", 20);
-    QTest::qWait(300);
-
-    for (int i = 5; i < 11; ++i) {
-        QSGItem *item = findItem<QSGItem>(contentItem, "wrapper", i);
-        QVERIFY(item != 0);
-        QTRY_COMPARE(item->y(), 150 + (i-5)*20.0);
-    }
-
-    QTRY_COMPARE(listview->currentItem()->y(), 70.0);
-    QTRY_COMPARE(listview->highlightItem()->y(), 70.0);
-
-    delete canvas;
-}
-
-void tst_QSGListView::resizeFirstDelegate()
-{
-    // QTBUG-20712: Content Y jumps constantly if first delegate height == 0
-    // and other delegates have height > 0
-
-    QSGView *canvas = createView();
-    canvas->show();
-
-    // bug only occurs when all items in the model are visible
-    TestModel model;
-    for (int i = 0; i < 10; 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");
-    QVERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QVERIFY(contentItem != 0);
-
-    QSGItem *item = 0;
-    for (int i = 0; i < model.count(); ++i) {
-        item = findItem<QSGItem>(contentItem, "wrapper", i);
-        QVERIFY(item != 0);
-        QCOMPARE(item->y(), i*20.0);
-    }
-
-    item = findItem<QSGItem>(contentItem, "wrapper", 0);
-    item->setHeight(0);
-
-    // check the content y has not jumped up and down
-    QCOMPARE(listview->contentY(), 0.0);
-    QSignalSpy spy(listview, SIGNAL(contentYChanged()));
-    QTest::qWait(300);
-    QCOMPARE(spy.count(), 0);
-
-    for (int i = 1; i < model.count(); ++i) {
-        item = findItem<QSGItem>(contentItem, "wrapper", i);
-        QVERIFY(item != 0);
-        QTRY_COMPARE(item->y(), (i-1)*20.0);
-    }
-
-    delete testObject;
-    delete canvas;
-}
-
-void tst_QSGListView::QTBUG_16037()
-{
-    QSGView *canvas = createView();
-    canvas->show();
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("qtbug16037.qml")));
-    qApp->processEvents();
-
-    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "listview");
-    QTRY_VERIFY(listview != 0);
-
-    QVERIFY(listview->contentHeight() <= 0.0);
-
-    QMetaObject::invokeMethod(canvas->rootObject(), "setModel");
-
-    QTRY_COMPARE(listview->contentHeight(), 80.0);
-
-    delete canvas;
-}
-
-void tst_QSGListView::indexAt()
-{
-    QSGView *canvas = createView();
-
-    TestModel 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);
-
-    QCOMPARE(listview->indexAt(0,0), 0);
-    QCOMPARE(listview->indexAt(0,19), 0);
-    QCOMPARE(listview->indexAt(239,19), 0);
-    QCOMPARE(listview->indexAt(0,20), 1);
-    QCOMPARE(listview->indexAt(240,20), -1);
-
-    delete canvas;
-    delete testObject;
-}
-
-void tst_QSGListView::incrementalModel()
-{
-    QSGView *canvas = createView();
-
-    IncrementalModel model;
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaylist.qml")));
-    qApp->processEvents();
-
-    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
-    QTRY_VERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    QTRY_COMPARE(listview->count(), 20);
-
-    listview->positionViewAtIndex(10, QSGListView::Beginning);
-
-    QTRY_COMPARE(listview->count(), 25);
-
-    delete canvas;
-}
-
-void tst_QSGListView::onAdd()
-{
-    QFETCH(int, initialItemCount);
-    QFETCH(int, itemsToAdd);
-
-    const int delegateHeight = 10;
-    TestModel2 model;
-
-    // these initial items should not trigger ListView.onAdd
-    for (int i=0; i<initialItemCount; i++)
-        model.addItem("dummy value", "dummy value");
-
-    QSGView *canvas = createView();
-    canvas->setGeometry(0,0,200, delegateHeight * (initialItemCount + itemsToAdd));
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-    ctxt->setContextProperty("delegateHeight", delegateHeight);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml")));
-
-    QObject *object = canvas->rootObject();
-    object->setProperty("width", canvas->width());
-    object->setProperty("height", canvas->height());
-    qApp->processEvents();
-
-    QList<QPair<QString, QString> > items;
-    for (int i=0; i<itemsToAdd; i++)
-        items << qMakePair(QString("value %1").arg(i), QString::number(i));
-    model.addItems(items);
-    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
-
-    QVariantList result = object->property("addedDelegates").toList();
-    QCOMPARE(result.count(), items.count());
-    for (int i=0; i<items.count(); i++)
-        QCOMPARE(result[i].toString(), items[i].first);
-
-    delete canvas;
-}
-
-void tst_QSGListView::onAdd_data()
-{
-    QTest::addColumn<int>("initialItemCount");
-    QTest::addColumn<int>("itemsToAdd");
-
-    QTest::newRow("0, add 1") << 0 << 1;
-    QTest::newRow("0, add 2") << 0 << 2;
-    QTest::newRow("0, add 10") << 0 << 10;
-
-    QTest::newRow("1, add 1") << 1 << 1;
-    QTest::newRow("1, add 2") << 1 << 2;
-    QTest::newRow("1, add 10") << 1 << 10;
-
-    QTest::newRow("5, add 1") << 5 << 1;
-    QTest::newRow("5, add 2") << 5 << 2;
-    QTest::newRow("5, add 10") << 5 << 10;
-}
-
-void tst_QSGListView::onRemove()
-{
-    QFETCH(int, initialItemCount);
-    QFETCH(int, indexToRemove);
-    QFETCH(int, removeCount);
-
-    const int delegateHeight = 10;
-    TestModel2 model;
-    for (int i=0; i<initialItemCount; i++)
-        model.addItem(QString("value %1").arg(i), "dummy value");
-
-    QSGView *canvas = createView();
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-    ctxt->setContextProperty("delegateHeight", delegateHeight);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml")));
-    QObject *object = canvas->rootObject();
-
-    model.removeItems(indexToRemove, removeCount);
-    QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count());
-
-    QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount));
-
-    delete canvas;
-}
-
-void tst_QSGListView::onRemove_data()
-{
-    QTest::addColumn<int>("initialItemCount");
-    QTest::addColumn<int>("indexToRemove");
-    QTest::addColumn<int>("removeCount");
-
-    QTest::newRow("remove first") << 1 << 0 << 1;
-    QTest::newRow("two items, remove first") << 2 << 0 << 1;
-    QTest::newRow("two items, remove last") << 2 << 1 << 1;
-    QTest::newRow("two items, remove all") << 2 << 0 << 2;
-
-    QTest::newRow("four items, remove first") << 4 << 0 << 1;
-    QTest::newRow("four items, remove 0-2") << 4 << 0 << 2;
-    QTest::newRow("four items, remove 1-3") << 4 << 1 << 2;
-    QTest::newRow("four items, remove 2-4") << 4 << 2 << 2;
-    QTest::newRow("four items, remove last") << 4 << 3 << 1;
-    QTest::newRow("four items, remove all") << 4 << 0 << 4;
-
-    QTest::newRow("ten items, remove 1-8") << 10 << 0 << 8;
-    QTest::newRow("ten items, remove 2-7") << 10 << 2 << 5;
-    QTest::newRow("ten items, remove 4-10") << 10 << 4 << 6;
-}
-
-void tst_QSGListView::rightToLeft()
-{
-    QSGView *canvas = createView();
-    canvas->setGeometry(0,0,640,320);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("rightToLeft.qml")));
-    qApp->processEvents();
-
-    QVERIFY(canvas->rootObject() != 0);
-    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "view");
-    QTRY_VERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QTRY_VERIFY(contentItem != 0);
-
-    QSGVisualItemModel *model = canvas->rootObject()->findChild<QSGVisualItemModel*>("itemModel");
-    QTRY_VERIFY(model != 0);
-
-    QTRY_VERIFY(model->count() == 3);
-    QTRY_COMPARE(listview->currentIndex(), 0);
-
-    // initial position at first item, right edge aligned
-    QCOMPARE(listview->contentX(), -640.);
-
-    QSGItem *item = findItem<QSGItem>(contentItem, "item1");
-    QTRY_VERIFY(item);
-    QTRY_COMPARE(item->x(), -100.0);
-    QCOMPARE(item->height(), listview->height());
-
-    QSGText *text = findItem<QSGText>(contentItem, "text1");
-    QTRY_VERIFY(text);
-    QTRY_COMPARE(text->text(), QLatin1String("index: 0"));
-
-    listview->setCurrentIndex(2);
-
-    item = findItem<QSGItem>(contentItem, "item3");
-    QTRY_VERIFY(item);
-    QTRY_COMPARE(item->x(), -540.0);
-
-    text = findItem<QSGText>(contentItem, "text3");
-    QTRY_VERIFY(text);
-    QTRY_COMPARE(text->text(), QLatin1String("index: 2"));
-
-    QCOMPARE(listview->contentX(), -640.);
-
-    // Ensure resizing maintains position relative to right edge
-    qobject_cast<QSGItem*>(canvas->rootObject())->setWidth(600);
-    QTRY_COMPARE(listview->contentX(), -600.);
-
-    delete canvas;
-}
-
-void tst_QSGListView::test_mirroring()
-{
-    QSGView *canvasA = createView();
-    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(TESTDATA("rightToLeft.qml")));
-    QSGListView *listviewB = findItem<QSGListView>(canvasB->rootObject(), "view");
-    QTRY_VERIFY(listviewA != 0);
-    qApp->processEvents();
-
-    QList<QString> objectNames;
-    objectNames << "item1" << "item2"; // << "item3"
-
-    listviewA->setProperty("layoutDirection", Qt::LeftToRight);
-    listviewB->setProperty("layoutDirection", Qt::RightToLeft);
-    QCOMPARE(listviewA->layoutDirection(), listviewA->effectiveLayoutDirection());
-
-    // LTR != RTL
-    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)
-        QCOMPARE(findItem<QSGItem>(listviewA, objectName)->x(), findItem<QSGItem>(listviewB, objectName)->x());
-
-    QVERIFY(listviewB->layoutDirection() == listviewB->effectiveLayoutDirection());
-    QSGItemPrivate::get(listviewB)->setLayoutMirror(true);
-    QVERIFY(listviewB->layoutDirection() != listviewB->effectiveLayoutDirection());
-
-    // LTR != LTR+mirror
-    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)
-        QCOMPARE(findItem<QSGItem>(listviewA, objectName)->x(), findItem<QSGItem>(listviewB, objectName)->x());
-
-    listviewB->setProperty("layoutDirection", Qt::RightToLeft);
-
-    // RTL != RTL+mirror
-    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)
-        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>();
-}
-
-void tst_QSGListView::qAbstractItemModel_items()
-{
-    items<TestModel2>();
-}
-
-void tst_QSGListView::qListModelInterface_changed()
-{
-    changed<TestModel>();
-}
-
-void tst_QSGListView::qAbstractItemModel_changed()
-{
-    changed<TestModel2>();
-}
-
-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);
-    removed<TestModel>(true);
-}
-
-void tst_QSGListView::qAbstractItemModel_removed()
-{
-    removed<TestModel2>(false);
-    removed<TestModel2>(true);
-}
-
-void tst_QSGListView::qListModelInterface_moved()
-{
-    moved<TestModel>();
-}
-
-void tst_QSGListView::qListModelInterface_moved_data()
-{
-    moved_data();
-}
-
-void tst_QSGListView::qAbstractItemModel_moved()
-{
-    moved<TestModel2>();
-}
-
-void tst_QSGListView::qAbstractItemModel_moved_data()
-{
-    moved_data();
-}
-
-void tst_QSGListView::qListModelInterface_clear()
-{
-    clear<TestModel>();
-}
-
-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);
-    canvas->setGeometry(0,0,240,320);
-
-    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;
-    QList<QSGItem*> items = parent->findChildren<QSGItem*>(objectName);
-    for (int i = 0; i < items.count(); ++i) {
-        if (items.at(i)->isVisible()) {
-            item = items.at(i);
-            break;
-        }
-    }
-    return item;
-}
-/*
-   Find an item with the specified objectName.  If index is supplied then the
-   item must also evaluate the {index} expression equal to index
-*/
-template<typename T>
-T *tst_QSGListView::findItem(QSGItem *parent, const QString &objectName, int index)
-{
-    const QMetaObject &mo = T::staticMetaObject;
-    //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)
-            continue;
-        //qDebug() << "try" << item;
-        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
-            if (index != -1) {
-                QDeclarativeExpression e(qmlContext(item), item, "index");
-                if (e.evaluate().toInt() == index)
-                    return static_cast<T*>(item);
-            } else {
-                return static_cast<T*>(item);
-            }
-        }
-        item = findItem<T>(item, objectName, index);
-        if (item)
-            return static_cast<T*>(item);
-    }
-
-    return 0;
-}
-
-template<typename T>
-QList<T*> tst_QSGListView::findItems(QSGItem *parent, const QString &objectName)
-{
-    QList<T*> items;
-    const QMetaObject &mo = T::staticMetaObject;
-    //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())
-            continue;
-        //qDebug() << "try" << item;
-        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName))
-            items.append(static_cast<T*>(item));
-        items += findItems<T>(item, objectName);
-    }
-
-    return items;
-}
-
-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)
-            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/qsgloader.pro b/tests/auto/declarative/qsgloader/qsgloader.pro
deleted file mode 100644 (file)
index 01e942e..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsgloader
-macx:CONFIG -= app_bundle
-
-INCLUDEPATH += ../shared/
-HEADERS += ../shared/testhttpserver.h
-SOURCES += tst_qsgloader.cpp \
-           ../shared/testhttpserver.cpp
-
-testDataFiles.files = data
-testDataFiles.path = .
-DEPLOYMENT += testDataFiles
-
-CONFIG += parallel_test
-
-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
deleted file mode 100644 (file)
index 3968a92..0000000
+++ /dev/null
@@ -1,950 +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 <QSignalSpy>
-
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtDeclarative/qdeclarativeincubator.h>
-#include <private/qsgloader_p.h>
-#include "testhttpserver.h"
-#include "../shared/util.h"
-
-#define SERVER_PORT 14450
-
-inline QUrl TEST_FILE(const QString &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
-
-{
-    Q_OBJECT
-public:
-    tst_QSGLoader();
-
-private slots:
-    void sourceOrComponent();
-    void sourceOrComponent_data();
-    void clear();
-    void urlToComponent();
-    void componentToUrl();
-    void anchoredLoader();
-    void sizeLoaderToItem();
-    void sizeItemToLoader();
-    void noResize();
-    void networkRequestUrl();
-    void failNetworkRequest();
-//    void networkComponent();
-    void active();
-    void initialPropertyValues_data();
-    void initialPropertyValues();
-    void initialPropertyValuesBinding();
-    void initialPropertyValuesError_data();
-    void initialPropertyValuesError();
-
-    void deleteComponentCrash();
-    void nonItem();
-    void vmeErrors();
-    void creationContext();
-    void QTBUG_16928();
-    void implicitSize();
-    void QTBUG_17114();
-    void asynchronous_data();
-    void asynchronous();
-    void asynchronous_clear();
-
-private:
-    QDeclarativeEngine engine;
-};
-
-
-tst_QSGLoader::tst_QSGLoader()
-{
-}
-
-void tst_QSGLoader::sourceOrComponent()
-{
-    QFETCH(QString, sourceOrComponent);
-    QFETCH(QString, sourceDefinition);
-    QFETCH(QUrl, sourceUrl);
-    QFETCH(QString, errorString);
-
-    bool error = !errorString.isEmpty();
-    if (error)
-        QTest::ignoreMessage(QtWarningMsg, errorString.toUtf8().constData());
-
-    QDeclarativeComponent component(&engine);
-    component.setData(QByteArray(
-            "import QtQuick 2.0\n"
-            "Loader {\n"
-            "   property int onItemChangedCount: 0\n"
-            "   property int onSourceChangedCount: 0\n"
-            "   property int onSourceComponentChangedCount: 0\n"
-            "   property int onStatusChangedCount: 0\n"
-            "   property int onProgressChangedCount: 0\n"
-            "   property int onLoadedCount: 0\n")
-            + sourceDefinition.toUtf8()
-            + QByteArray(
-            "   onItemChanged: onItemChangedCount += 1\n"
-            "   onSourceChanged: onSourceChangedCount += 1\n"
-            "   onSourceComponentChanged: onSourceComponentChangedCount += 1\n"
-            "   onStatusChanged: onStatusChangedCount += 1\n"
-            "   onProgressChanged: onProgressChangedCount += 1\n"
-            "   onLoaded: onLoadedCount += 1\n"
-            "}")
-        , TEST_FILE(""));
-
-    QSGLoader *loader = qobject_cast<QSGLoader*>(component.create());
-    QVERIFY(loader != 0);
-    QCOMPARE(loader->item() == 0, error);
-    QCOMPARE(loader->source(), sourceUrl);
-    QCOMPARE(loader->progress(), 1.0);
-
-    QCOMPARE(loader->status(), error ? QSGLoader::Error : QSGLoader::Ready);
-    QCOMPARE(static_cast<QSGItem*>(loader)->childItems().count(), error ? 0: 1);
-
-    if (!error) {
-        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") {
-        QCOMPARE(loader->property("onSourceComponentChangedCount").toInt(), 1);
-        QCOMPARE(loader->property("onSourceChangedCount").toInt(), 0);
-    } else {
-        QCOMPARE(loader->property("onSourceComponentChangedCount").toInt(), 0);
-        QCOMPARE(loader->property("onSourceChangedCount").toInt(), 1);
-    }
-    QCOMPARE(loader->property("onStatusChangedCount").toInt(), 1);
-    QCOMPARE(loader->property("onProgressChangedCount").toInt(), 1);
-
-    QCOMPARE(loader->property("onItemChangedCount").toInt(), error ? 0 : 1);
-    QCOMPARE(loader->property("onLoadedCount").toInt(), error ? 0 : 1);
-
-    delete loader;
-}
-
-void tst_QSGLoader::sourceOrComponent_data()
-{
-    QTest::addColumn<QString>("sourceOrComponent");
-    QTest::addColumn<QString>("sourceDefinition");
-    QTest::addColumn<QUrl>("sourceUrl");
-    QTest::addColumn<QString>("errorString");
-
-    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(TESTDATA("IDontExist.qml"))
-            << QString(QUrl::fromLocalFile(TESTDATA("IDontExist.qml")).toString() + ": File not found");
-}
-
-void tst_QSGLoader::clear()
-{
-    {
-        QDeclarativeComponent component(&engine);
-        component.setData(QByteArray(
-                    "import QtQuick 2.0\n"
-                    " Loader { id: loader\n"
-                    "  source: 'Rect120x60.qml'\n"
-                    "  Timer { interval: 200; running: true; onTriggered: loader.source = '' }\n"
-                    " }")
-                , TEST_FILE(""));
-        QSGLoader *loader = qobject_cast<QSGLoader*>(component.create());
-        QVERIFY(loader != 0);
-        QVERIFY(loader->item());
-        QCOMPARE(loader->progress(), 1.0);
-        QCOMPARE(static_cast<QSGItem*>(loader)->childItems().count(), 1);
-
-        QTRY_VERIFY(loader->item() == 0);
-        QCOMPARE(loader->progress(), 0.0);
-        QCOMPARE(loader->status(), QSGLoader::Null);
-        QCOMPARE(static_cast<QSGItem*>(loader)->childItems().count(), 0);
-
-        delete loader;
-    }
-    {
-        QDeclarativeComponent component(&engine, TEST_FILE("/SetSourceComponent.qml"));
-        QSGItem *item = qobject_cast<QSGItem*>(component.create());
-        QVERIFY(item);
-
-        QSGLoader *loader = qobject_cast<QSGLoader*>(item->QSGItem::childItems().at(0));
-        QVERIFY(loader);
-        QVERIFY(loader->item());
-        QCOMPARE(loader->progress(), 1.0);
-        QCOMPARE(static_cast<QSGItem*>(loader)->childItems().count(), 1);
-
-        loader->setSourceComponent(0);
-
-        QVERIFY(loader->item() == 0);
-        QCOMPARE(loader->progress(), 0.0);
-        QCOMPARE(loader->status(), QSGLoader::Null);
-        QCOMPARE(static_cast<QSGItem*>(loader)->childItems().count(), 0);
-
-        delete item;
-    }
-    {
-        QDeclarativeComponent component(&engine, TEST_FILE("/SetSourceComponent.qml"));
-        QSGItem *item = qobject_cast<QSGItem*>(component.create());
-        QVERIFY(item);
-
-        QSGLoader *loader = qobject_cast<QSGLoader*>(item->QSGItem::childItems().at(0));
-        QVERIFY(loader);
-        QVERIFY(loader->item());
-        QCOMPARE(loader->progress(), 1.0);
-        QCOMPARE(static_cast<QSGItem*>(loader)->childItems().count(), 1);
-
-        QMetaObject::invokeMethod(item, "clear");
-
-        QVERIFY(loader->item() == 0);
-        QCOMPARE(loader->progress(), 0.0);
-        QCOMPARE(loader->status(), QSGLoader::Null);
-        QCOMPARE(static_cast<QSGItem*>(loader)->childItems().count(), 0);
-
-        delete item;
-    }
-}
-
-void tst_QSGLoader::urlToComponent()
-{
-    QDeclarativeComponent component(&engine);
-    component.setData(QByteArray("import QtQuick 2.0\n"
-                "Loader {\n"
-                " id: loader\n"
-                " Component { id: myComp; Rectangle { width: 10; height: 10 } }\n"
-                " source: \"Rect120x60.qml\"\n"
-                " Timer { interval: 100; running: true; onTriggered: loader.sourceComponent = myComp }\n"
-                "}" )
-            , TEST_FILE(""));
-    QSGLoader *loader = qobject_cast<QSGLoader*>(component.create());
-    QTest::qWait(200);
-    QTRY_VERIFY(loader != 0);
-    QVERIFY(loader->item());
-    QCOMPARE(loader->progress(), 1.0);
-    QCOMPARE(static_cast<QSGItem*>(loader)->childItems().count(), 1);
-    QCOMPARE(loader->width(), 10.0);
-    QCOMPARE(loader->height(), 10.0);
-
-    delete loader;
-}
-
-void tst_QSGLoader::componentToUrl()
-{
-    QDeclarativeComponent component(&engine, TEST_FILE("/SetSourceComponent.qml"));
-    QSGItem *item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-
-    QSGLoader *loader = qobject_cast<QSGLoader*>(item->QSGItem::childItems().at(0));
-    QVERIFY(loader);
-    QVERIFY(loader->item());
-    QCOMPARE(loader->progress(), 1.0);
-    QCOMPARE(static_cast<QSGItem*>(loader)->childItems().count(), 1);
-
-    loader->setSource(TEST_FILE("/Rect120x60.qml"));
-    QVERIFY(loader->item());
-    QCOMPARE(loader->progress(), 1.0);
-    QCOMPARE(static_cast<QSGItem*>(loader)->childItems().count(), 1);
-    QCOMPARE(loader->width(), 120.0);
-    QCOMPARE(loader->height(), 60.0);
-
-    delete item;
-}
-
-void tst_QSGLoader::anchoredLoader()
-{
-    QDeclarativeComponent component(&engine, TEST_FILE("/AnchoredLoader.qml"));
-    QSGItem *rootItem = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(rootItem != 0);
-    QSGItem *loader = rootItem->findChild<QSGItem*>("loader");
-    QSGItem *sourceElement = rootItem->findChild<QSGItem*>("sourceElement");
-
-    QVERIFY(loader != 0);
-    QVERIFY(sourceElement != 0);
-
-    QCOMPARE(rootItem->width(), 300.0);
-    QCOMPARE(rootItem->height(), 200.0);
-
-    QCOMPARE(loader->width(), 300.0);
-    QCOMPARE(loader->height(), 200.0);
-
-    QCOMPARE(sourceElement->width(), 300.0);
-    QCOMPARE(sourceElement->height(), 200.0);
-}
-
-void tst_QSGLoader::sizeLoaderToItem()
-{
-    QDeclarativeComponent component(&engine, TEST_FILE("/SizeToItem.qml"));
-    QSGLoader *loader = qobject_cast<QSGLoader*>(component.create());
-    QVERIFY(loader != 0);
-    QCOMPARE(loader->width(), 120.0);
-    QCOMPARE(loader->height(), 60.0);
-
-    // Check resize
-    QSGItem *rect = qobject_cast<QSGItem*>(loader->item());
-    QVERIFY(rect);
-    rect->setWidth(150);
-    rect->setHeight(45);
-    QCOMPARE(loader->width(), 150.0);
-    QCOMPARE(loader->height(), 45.0);
-
-    // Check explicit width
-    loader->setWidth(200.0);
-    QCOMPARE(loader->width(), 200.0);
-    QCOMPARE(rect->width(), 200.0);
-    rect->setWidth(100.0); // when rect changes ...
-    QCOMPARE(rect->width(), 100.0); // ... it changes
-    QCOMPARE(loader->width(), 200.0); // ... but loader stays the same
-
-    // Check explicit height
-    loader->setHeight(200.0);
-    QCOMPARE(loader->height(), 200.0);
-    QCOMPARE(rect->height(), 200.0);
-    rect->setHeight(100.0); // when rect changes ...
-    QCOMPARE(rect->height(), 100.0); // ... it changes
-    QCOMPARE(loader->height(), 200.0); // ... but loader stays the same
-
-    // Switch mode
-    loader->setWidth(180);
-    loader->setHeight(30);
-    QCOMPARE(rect->width(), 180.0);
-    QCOMPARE(rect->height(), 30.0);
-
-    delete loader;
-}
-
-void tst_QSGLoader::sizeItemToLoader()
-{
-    QDeclarativeComponent component(&engine, TEST_FILE("/SizeToLoader.qml"));
-    QSGLoader *loader = qobject_cast<QSGLoader*>(component.create());
-    QVERIFY(loader != 0);
-    QCOMPARE(loader->width(), 200.0);
-    QCOMPARE(loader->height(), 80.0);
-
-    QSGItem *rect = qobject_cast<QSGItem*>(loader->item());
-    QVERIFY(rect);
-    QCOMPARE(rect->width(), 200.0);
-    QCOMPARE(rect->height(), 80.0);
-
-    // Check resize
-    loader->setWidth(180);
-    loader->setHeight(30);
-    QCOMPARE(rect->width(), 180.0);
-    QCOMPARE(rect->height(), 30.0);
-
-    // Switch mode
-    loader->resetWidth(); // reset explicit size
-    loader->resetHeight();
-    rect->setWidth(160);
-    rect->setHeight(45);
-    QCOMPARE(loader->width(), 160.0);
-    QCOMPARE(loader->height(), 45.0);
-
-    delete loader;
-}
-
-void tst_QSGLoader::noResize()
-{
-    QDeclarativeComponent component(&engine, TEST_FILE("/NoResize.qml"));
-    QSGItem* item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item != 0);
-    QCOMPARE(item->width(), 200.0);
-    QCOMPARE(item->height(), 80.0);
-
-    delete item;
-}
-
-void tst_QSGLoader::networkRequestUrl()
-{
-    TestHTTPServer server(SERVER_PORT);
-    QVERIFY(server.isValid());
-    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(TESTDATA("../dummy.qml")));
-    if (component.isError())
-        qDebug() << component.errors();
-    QSGLoader *loader = qobject_cast<QSGLoader*>(component.create());
-    QVERIFY(loader != 0);
-
-    QTRY_VERIFY(loader->status() == QSGLoader::Ready);
-
-    QVERIFY(loader->item());
-    QCOMPARE(loader->progress(), 1.0);
-    QCOMPARE(loader->property("signalCount").toInt(), 1);
-    QCOMPARE(static_cast<QSGItem*>(loader)->childItems().count(), 1);
-
-    delete loader;
-}
-
-/* XXX Component waits until all dependencies are loaded.  Is this actually possible?
-void tst_QSGLoader::networkComponent()
-{
-    TestHTTPServer server(SERVER_PORT);
-    QVERIFY(server.isValid());
-    server.serveDirectory("slowdata", TestHTTPServer::Delay);
-
-    QDeclarativeComponent component(&engine);
-    component.setData(QByteArray(
-                "import QtQuick 2.0\n"
-                "import \"http://127.0.0.1:14450/\" as NW\n"
-                "Item {\n"
-                " Component { id: comp; NW.SlowRect {} }\n"
-                " Loader { sourceComponent: comp } }")
-            , TEST_FILE(""));
-
-    QSGItem *item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-
-    QSGLoader *loader = qobject_cast<QSGLoader*>(item->QSGItem::children().at(1));
-    QVERIFY(loader);
-    QTRY_VERIFY(loader->status() == QSGLoader::Ready);
-
-    QVERIFY(loader->item());
-    QCOMPARE(loader->progress(), 1.0);
-    QCOMPARE(loader->status(), QSGLoader::Ready);
-    QCOMPARE(static_cast<QSGItem*>(loader)->children().count(), 1);
-
-    delete loader;
-}
-*/
-
-void tst_QSGLoader::failNetworkRequest()
-{
-    TestHTTPServer server(SERVER_PORT);
-    QVERIFY(server.isValid());
-    server.serveDirectory(TESTDATA(""));
-
-    QTest::ignoreMessage(QtWarningMsg, "http://127.0.0.1:14450/IDontExist.qml: File not found");
-
-    QDeclarativeComponent component(&engine);
-    component.setData(QByteArray("import QtQuick 2.0\nLoader { property int did_load: 123; source: \"http://127.0.0.1:14450/IDontExist.qml\"; onLoaded: did_load=456 }"), QUrl::fromLocalFile("http://127.0.0.1:14450/dummy.qml"));
-    QSGLoader *loader = qobject_cast<QSGLoader*>(component.create());
-    QVERIFY(loader != 0);
-
-    QTRY_VERIFY(loader->status() == QSGLoader::Error);
-
-    QVERIFY(loader->item() == 0);
-    QCOMPARE(loader->progress(), 0.0);
-    QCOMPARE(loader->property("did_load").toInt(), 123);
-    QCOMPARE(static_cast<QSGItem*>(loader)->childItems().count(), 0);
-
-    delete loader;
-}
-
-void tst_QSGLoader::active()
-{
-    // check that the item isn't instantiated until active is set to true
-    {
-        QDeclarativeComponent component(&engine, TEST_FILE("active.1.qml"));
-        QObject *object = component.create();
-        QVERIFY(object != 0);
-        QSGLoader *loader = object->findChild<QSGLoader*>("loader");
-
-        QVERIFY(loader->active() == false); // set manually to false
-        QVERIFY(loader->item() == 0);
-        QMetaObject::invokeMethod(object, "doSetSourceComponent");
-        QVERIFY(loader->item() == 0);
-        QMetaObject::invokeMethod(object, "doSetSource");
-        QVERIFY(loader->item() == 0);
-        QMetaObject::invokeMethod(object, "doSetActive");
-        QVERIFY(loader->item() != 0);
-
-        delete object;
-    }
-
-    // check that the status is Null if active is set to false
-    {
-        QDeclarativeComponent component(&engine, TEST_FILE("active.2.qml"));
-        QObject *object = component.create();
-        QVERIFY(object != 0);
-        QSGLoader *loader = object->findChild<QSGLoader*>("loader");
-
-        QVERIFY(loader->active() == true); // active is true by default
-        QCOMPARE(loader->status(), QSGLoader::Ready);
-        int currStatusChangedCount = loader->property("statusChangedCount").toInt();
-        QMetaObject::invokeMethod(object, "doSetInactive");
-        QCOMPARE(loader->status(), QSGLoader::Null);
-        QCOMPARE(loader->property("statusChangedCount").toInt(), (currStatusChangedCount+1));
-
-        delete object;
-    }
-
-    // check that the source is not cleared if active is set to false
-    {
-        QDeclarativeComponent component(&engine, TEST_FILE("active.3.qml"));
-        QObject *object = component.create();
-        QVERIFY(object != 0);
-        QSGLoader *loader = object->findChild<QSGLoader*>("loader");
-
-        QVERIFY(loader->active() == true); // active is true by default
-        QVERIFY(!loader->source().isEmpty());
-        int currSourceChangedCount = loader->property("sourceChangedCount").toInt();
-        QMetaObject::invokeMethod(object, "doSetInactive");
-        QVERIFY(!loader->source().isEmpty());
-        QCOMPARE(loader->property("sourceChangedCount").toInt(), currSourceChangedCount);
-
-        delete object;
-    }
-
-    // check that the sourceComponent is not cleared if active is set to false
-    {
-        QDeclarativeComponent component(&engine, TEST_FILE("active.4.qml"));
-        QObject *object = component.create();
-        QVERIFY(object != 0);
-        QSGLoader *loader = object->findChild<QSGLoader*>("loader");
-
-        QVERIFY(loader->active() == true); // active is true by default
-        QVERIFY(loader->sourceComponent() != 0);
-        int currSourceComponentChangedCount = loader->property("sourceComponentChangedCount").toInt();
-        QMetaObject::invokeMethod(object, "doSetInactive");
-        QVERIFY(loader->sourceComponent() != 0);
-        QCOMPARE(loader->property("sourceComponentChangedCount").toInt(), currSourceComponentChangedCount);
-
-        delete object;
-    }
-
-    // check that the item is released if active is set to false
-    {
-        QDeclarativeComponent component(&engine, TEST_FILE("active.5.qml"));
-        QObject *object = component.create();
-        QVERIFY(object != 0);
-        QSGLoader *loader = object->findChild<QSGLoader*>("loader");
-
-        QVERIFY(loader->active() == true); // active is true by default
-        QVERIFY(loader->item() != 0);
-        int currItemChangedCount = loader->property("itemChangedCount").toInt();
-        QMetaObject::invokeMethod(object, "doSetInactive");
-        QVERIFY(loader->item() == 0);
-        QCOMPARE(loader->property("itemChangedCount").toInt(), (currItemChangedCount+1));
-
-        delete object;
-    }
-
-    // check that the activeChanged signal is emitted correctly
-    {
-        QDeclarativeComponent component(&engine, TEST_FILE("active.6.qml"));
-        QObject *object = component.create();
-        QVERIFY(object != 0);
-        QSGLoader *loader = object->findChild<QSGLoader*>("loader");
-
-        QVERIFY(loader->active() == true); // active is true by default
-        loader->setActive(true);           // no effect
-        QCOMPARE(loader->property("activeChangedCount").toInt(), 0);
-        loader->setActive(false);          // change signal should be emitted
-        QCOMPARE(loader->property("activeChangedCount").toInt(), 1);
-        loader->setActive(false);          // no effect
-        QCOMPARE(loader->property("activeChangedCount").toInt(), 1);
-        loader->setActive(true);           // change signal should be emitted
-        QCOMPARE(loader->property("activeChangedCount").toInt(), 2);
-        loader->setActive(false);          // change signal should be emitted
-        QCOMPARE(loader->property("activeChangedCount").toInt(), 3);
-        QMetaObject::invokeMethod(object, "doSetActive");
-        QCOMPARE(loader->property("activeChangedCount").toInt(), 4);
-        QMetaObject::invokeMethod(object, "doSetActive");
-        QCOMPARE(loader->property("activeChangedCount").toInt(), 4);
-        QMetaObject::invokeMethod(object, "doSetInactive");
-        QCOMPARE(loader->property("activeChangedCount").toInt(), 5);
-        loader->setActive(true);           // change signal should be emitted
-        QCOMPARE(loader->property("activeChangedCount").toInt(), 6);
-
-        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()
-{
-    QTest::addColumn<QUrl>("qmlFile");
-    QTest::addColumn<QStringList>("expectedWarnings");
-    QTest::addColumn<QStringList>("propertyNames");
-    QTest::addColumn<QVariantList>("propertyValues");
-
-    QTest::newRow("source url with value set in onLoaded, initially active = true") << TEST_FILE("initialPropertyValues.1.qml")
-            << QStringList()
-            << (QStringList() << "initialValue" << "behaviorCount")
-            << (QVariantList() << 1 << 1);
-
-    QTest::newRow("set source with initial property values specified, active = true") << TEST_FILE("initialPropertyValues.2.qml")
-            << QStringList()
-            << (QStringList() << "initialValue" << "behaviorCount")
-            << (QVariantList() << 2 << 0);
-
-    QTest::newRow("set source with initial property values specified, active = false") << TEST_FILE("initialPropertyValues.3.qml")
-            << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("initialPropertyValues.3.qml").toLocalFile() + QLatin1String(":16: TypeError: Cannot read property 'canary' of null")))
-            << (QStringList())
-            << (QVariantList());
-
-    QTest::newRow("set source with initial property values specified, active = false, with active set true later") << TEST_FILE("initialPropertyValues.4.qml")
-            << QStringList()
-            << (QStringList() << "initialValue" << "behaviorCount")
-            << (QVariantList() << 4 << 0);
-
-    QTest::newRow("set source without initial property values specified, active = true") << TEST_FILE("initialPropertyValues.5.qml")
-            << QStringList()
-            << (QStringList() << "initialValue" << "behaviorCount")
-            << (QVariantList() << 0 << 0);
-
-    QTest::newRow("set source with initial property values specified with binding, active = true") << TEST_FILE("initialPropertyValues.6.qml")
-            << QStringList()
-            << (QStringList() << "initialValue" << "behaviorCount")
-            << (QVariantList() << 6 << 0);
-
-    QTest::newRow("ensure initial property value semantics mimic createObject") << TEST_FILE("initialPropertyValues.7.qml")
-            << 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()
-{
-    QFETCH(QUrl, qmlFile);
-    QFETCH(QStringList, expectedWarnings);
-    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));
-
-    delete object;
-}
-
-void tst_QSGLoader::initialPropertyValuesBinding()
-{
-    QDeclarativeComponent component(&engine, TEST_FILE("initialPropertyValues.binding.qml"));
-    QObject *object = component.create();
-    QVERIFY(object != 0);
-
-    QVERIFY(object->setProperty("bindable", QVariant(8)));
-    QCOMPARE(object->property("canaryValue").toInt(), 8);
-
-    delete object;
-}
-
-void tst_QSGLoader::initialPropertyValuesError_data()
-{
-    QTest::addColumn<QUrl>("qmlFile");
-    QTest::addColumn<QStringList>("expectedWarnings");
-
-    QTest::newRow("invalid initial property values object") << TEST_FILE("initialPropertyValues.error.1.qml")
-            << (QStringList() << QString(TEST_FILE("initialPropertyValues.error.1.qml").toString() + ":6:5: QML Loader: setSource: value is not an object"));
-
-    QTest::newRow("nonexistent source url") << TEST_FILE("initialPropertyValues.error.2.qml")
-            << (QStringList() << QString(TEST_FILE("NonexistentSourceComponent.qml").toString() + ": File not found"));
-
-    QTest::newRow("invalid source url") << TEST_FILE("initialPropertyValues.error.3.qml")
-            << (QStringList() << QString(TEST_FILE("InvalidSourceComponent.qml").toString() + ":5:1: Syntax error"));
-
-    QTest::newRow("invalid initial property values object with invalid property access") << TEST_FILE("initialPropertyValues.error.4.qml")
-            << (QStringList() << QString(TEST_FILE("initialPropertyValues.error.4.qml").toString() + ":7:5: QML Loader: setSource: value is not an object")
-                              << QString(TEST_FILE("initialPropertyValues.error.4.qml").toString() + ":5: TypeError: Cannot read property 'canary' of null"));
-}
-
-void tst_QSGLoader::initialPropertyValuesError()
-{
-    QFETCH(QUrl, qmlFile);
-    QFETCH(QStringList, expectedWarnings);
-
-    foreach (const QString &warning, expectedWarnings)
-        QTest::ignoreMessage(QtWarningMsg, warning.toUtf8().constData());
-
-    QDeclarativeComponent component(&engine, qmlFile);
-    QObject *object = component.create();
-    QVERIFY(object != 0);
-    QSGLoader *loader = object->findChild<QSGLoader*>("loader");
-    QVERIFY(loader != 0);
-    QVERIFY(loader->item() == 0);
-    delete object;
-}
-
-// QTBUG-9241
-void tst_QSGLoader::deleteComponentCrash()
-{
-    QDeclarativeComponent component(&engine, TEST_FILE("crash.qml"));
-    QSGItem *item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-
-    item->metaObject()->invokeMethod(item, "setLoaderSource");
-
-    QSGLoader *loader = qobject_cast<QSGLoader*>(item->QSGItem::childItems().at(0));
-    QVERIFY(loader);
-    QVERIFY(loader->item());
-    QCOMPARE(loader->item()->objectName(), QLatin1String("blue"));
-    QCOMPARE(loader->progress(), 1.0);
-    QCOMPARE(loader->status(), QSGLoader::Ready);
-    qApp->processEvents(QEventLoop::DeferredDeletion);
-    QTRY_COMPARE(static_cast<QSGItem*>(loader)->childItems().count(), 1);
-    QVERIFY(loader->source() == QUrl::fromLocalFile(TESTDATA("BlueRect.qml")));
-
-    delete item;
-}
-
-void tst_QSGLoader::nonItem()
-{
-    QDeclarativeComponent component(&engine, TEST_FILE("nonItem.qml"));
-    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());
-    QVERIFY(loader);
-    QVERIFY(loader->item() == 0);
-
-    delete loader;
-}
-
-void tst_QSGLoader::vmeErrors()
-{
-    QDeclarativeComponent component(&engine, TEST_FILE("vmeErrors.qml"));
-    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);
-    QVERIFY(loader->item() == 0);
-
-    delete loader;
-}
-
-// QTBUG-13481
-void tst_QSGLoader::creationContext()
-{
-    QDeclarativeComponent component(&engine, TEST_FILE("creationContext.qml"));
-
-    QObject *o = component.create();
-    QVERIFY(o != 0);
-
-    QCOMPARE(o->property("test").toBool(), true);
-
-    delete o;
-}
-
-void tst_QSGLoader::QTBUG_16928()
-{
-    QDeclarativeComponent component(&engine, TEST_FILE("QTBUG_16928.qml"));
-    QSGItem *item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-
-    QCOMPARE(item->width(), 250.);
-    QCOMPARE(item->height(), 250.);
-
-    delete item;
-}
-
-void tst_QSGLoader::implicitSize()
-{
-    QDeclarativeComponent component(&engine, TEST_FILE("implicitSize.qml"));
-    QSGItem *item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-
-    QCOMPARE(item->width(), 150.);
-    QCOMPARE(item->height(), 150.);
-
-    QCOMPARE(item->property("implHeight").toReal(), 100.);
-    QCOMPARE(item->property("implWidth").toReal(), 100.);
-
-    delete item;
-}
-
-void tst_QSGLoader::QTBUG_17114()
-{
-    QDeclarativeComponent component(&engine, TEST_FILE("QTBUG_17114.qml"));
-    QSGItem *item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-
-    QCOMPARE(item->property("loaderWidth").toReal(), 32.);
-    QCOMPARE(item->property("loaderHeight").toReal(), 32.);
-
-    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
deleted file mode 100644 (file)
index 39abd5a..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsgmousearea
-macx:CONFIG -= app_bundle
-
-HEADERS += ../shared/testhttpserver.h
-SOURCES += tst_qsgmousearea.cpp ../shared/testhttpserver.cpp
-
-testDataFiles.files = data
-testDataFiles.path = .
-DEPLOYMENT += testDataFiles
-
-CONFIG += parallel_test
-
-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
deleted file mode 100644 (file)
index be6a601..0000000
+++ /dev/null
@@ -1,805 +0,0 @@
-/****************************************************************************
-**
-** 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 <private/qsgmousearea_p.h>
-#include <private/qsgrectangle_p.h>
-#include <private/qsgflickable_p.h>
-#include <QtDeclarative/qsgview.h>
-#include <QtDeclarative/qdeclarativecontext.h>
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtOpenGL/QGLShaderProgram>
-#include "../shared/util.h"
-
-//#define OLDWAY
-
-class tst_QSGMouseArea: public QObject
-{
-    Q_OBJECT
-private slots:
-    void initTestCase();
-    void cleanupTestCase();
-    void dragProperties();
-    void resetDrag();
-    void dragging();
-    void updateMouseAreaPosOnClick();
-    void updateMouseAreaPosOnResize();
-    void noOnClickedWithPressAndHold();
-    void onMousePressRejected();
-    void pressedCanceledOnWindowDeactivate();
-    void doubleClick();
-    void clickTwice();
-    void pressedOrdering();
-    void preventStealing();
-    void clickThrough();
-    void testQtQuick11Attributes();
-    void testQtQuick11Attributes_data();
-    void hoverPosition();
-    void hoverPropagation();
-
-private:
-    QSGView *createView();
-};
-
-void tst_QSGMouseArea::initTestCase()
-{
-
-}
-
-void tst_QSGMouseArea::cleanupTestCase()
-{
-
-}
-
-void tst_QSGMouseArea::dragProperties()
-{
-    QSGView *canvas = createView();
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragproperties.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QVERIFY(canvas->rootObject() != 0);
-
-    QSGMouseArea *mouseRegion = canvas->rootObject()->findChild<QSGMouseArea*>("mouseregion");
-    QSGDrag *drag = mouseRegion->drag();
-    QVERIFY(mouseRegion != 0);
-    QVERIFY(drag != 0);
-
-    // target
-    QSGItem *blackRect = canvas->rootObject()->findChild<QSGItem*>("blackrect");
-    QVERIFY(blackRect != 0);
-    QVERIFY(blackRect == drag->target());
-    QSGItem *rootItem = qobject_cast<QSGItem*>(canvas->rootObject());
-    QVERIFY(rootItem != 0);
-    QSignalSpy targetSpy(drag, SIGNAL(targetChanged()));
-    drag->setTarget(rootItem);
-    QCOMPARE(targetSpy.count(),1);
-    drag->setTarget(rootItem);
-    QCOMPARE(targetSpy.count(),1);
-
-    // axis
-    QCOMPARE(drag->axis(), QSGDrag::XandYAxis);
-    QSignalSpy axisSpy(drag, SIGNAL(axisChanged()));
-    drag->setAxis(QSGDrag::XAxis);
-    QCOMPARE(drag->axis(), QSGDrag::XAxis);
-    QCOMPARE(axisSpy.count(),1);
-    drag->setAxis(QSGDrag::XAxis);
-    QCOMPARE(axisSpy.count(),1);
-
-    // minimum and maximum properties
-    QSignalSpy xminSpy(drag, SIGNAL(minimumXChanged()));
-    QSignalSpy xmaxSpy(drag, SIGNAL(maximumXChanged()));
-    QSignalSpy yminSpy(drag, SIGNAL(minimumYChanged()));
-    QSignalSpy ymaxSpy(drag, SIGNAL(maximumYChanged()));
-
-    QCOMPARE(drag->xmin(), 0.0);
-    QCOMPARE(drag->xmax(), rootItem->width()-blackRect->width());
-    QCOMPARE(drag->ymin(), 0.0);
-    QCOMPARE(drag->ymax(), rootItem->height()-blackRect->height());
-
-    drag->setXmin(10);
-    drag->setXmax(10);
-    drag->setYmin(10);
-    drag->setYmax(10);
-
-    QCOMPARE(drag->xmin(), 10.0);
-    QCOMPARE(drag->xmax(), 10.0);
-    QCOMPARE(drag->ymin(), 10.0);
-    QCOMPARE(drag->ymax(), 10.0);
-
-    QCOMPARE(xminSpy.count(),1);
-    QCOMPARE(xmaxSpy.count(),1);
-    QCOMPARE(yminSpy.count(),1);
-    QCOMPARE(ymaxSpy.count(),1);
-
-    drag->setXmin(10);
-    drag->setXmax(10);
-    drag->setYmin(10);
-    drag->setYmax(10);
-
-    QCOMPARE(xminSpy.count(),1);
-    QCOMPARE(xmaxSpy.count(),1);
-    QCOMPARE(yminSpy.count(),1);
-    QCOMPARE(ymaxSpy.count(),1);
-
-    // filterChildren
-    QSignalSpy filterChildrenSpy(drag, SIGNAL(filterChildrenChanged()));
-
-    drag->setFilterChildren(true);
-
-    QVERIFY(drag->filterChildren());
-    QCOMPARE(filterChildrenSpy.count(), 1);
-
-    drag->setFilterChildren(true);
-    QCOMPARE(filterChildrenSpy.count(), 1);
-
-    delete canvas;
-}
-
-void tst_QSGMouseArea::resetDrag()
-{
-    QSGView *canvas = createView();
-
-    canvas->rootContext()->setContextProperty("haveTarget", QVariant(true));
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragreset.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QVERIFY(canvas->rootObject() != 0);
-
-    QSGMouseArea *mouseRegion = canvas->rootObject()->findChild<QSGMouseArea*>("mouseregion");
-    QSGDrag *drag = mouseRegion->drag();
-    QVERIFY(mouseRegion != 0);
-    QVERIFY(drag != 0);
-
-    // target
-    QSGItem *blackRect = canvas->rootObject()->findChild<QSGItem*>("blackrect");
-    QVERIFY(blackRect != 0);
-    QVERIFY(blackRect == drag->target());
-    QSGItem *rootItem = qobject_cast<QSGItem*>(canvas->rootObject());
-    QVERIFY(rootItem != 0);
-    QSignalSpy targetSpy(drag, SIGNAL(targetChanged()));
-    QVERIFY(drag->target() != 0);
-    canvas->rootContext()->setContextProperty("haveTarget", QVariant(false));
-    QCOMPARE(targetSpy.count(),1);
-    QVERIFY(drag->target() == 0);
-
-    delete canvas;
-}
-
-
-void tst_QSGMouseArea::dragging()
-{
-    QSGView *canvas = createView();
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragging.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QTest::qWait(20);
-    QVERIFY(canvas->rootObject() != 0);
-
-    QSGMouseArea *mouseRegion = canvas->rootObject()->findChild<QSGMouseArea*>("mouseregion");
-    QSGDrag *drag = mouseRegion->drag();
-    QVERIFY(mouseRegion != 0);
-    QVERIFY(drag != 0);
-
-    // target
-    QSGItem *blackRect = canvas->rootObject()->findChild<QSGItem*>("blackrect");
-    QVERIFY(blackRect != 0);
-    QVERIFY(blackRect == drag->target());
-
-    QVERIFY(!drag->active());
-
-#ifdef OLDWAY
-    QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
-    QApplication::sendEvent(canvas, &pressEvent);
-#else
-    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
-#endif
-
-    QVERIFY(!drag->active());
-    QCOMPARE(blackRect->x(), 50.0);
-    QCOMPARE(blackRect->y(), 50.0);
-
-    // First move event triggers drag, second is acted upon.
-    // This is due to possibility of higher stacked area taking precedence.
-
-    QTest::mouseMove(canvas, QPoint(111,111));
-    QTest::qWait(50);
-    QTest::mouseMove(canvas, QPoint(122,122));
-    QTest::qWait(50);
-
-    QVERIFY(drag->active());
-    QCOMPARE(blackRect->x(), 72.0);
-    QCOMPARE(blackRect->y(), 72.0);
-
-#ifdef OLDWAY
-    QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
-    QApplication::sendEvent(canvas, &releaseEvent);
-#else
-    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(122,122));
-    QTest::qWait(50);
-#endif
-
-    QVERIFY(!drag->active());
-    QCOMPARE(blackRect->x(), 72.0);
-    QCOMPARE(blackRect->y(), 72.0);
-
-    delete canvas;
-}
-
-QSGView *tst_QSGMouseArea::createView()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setBaseSize(QSize(240,320));
-
-    return canvas;
-}
-
-void tst_QSGMouseArea::updateMouseAreaPosOnClick()
-{
-    QSGView *canvas = createView();
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("updateMousePosOnClick.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QVERIFY(canvas->rootObject() != 0);
-
-    QSGMouseArea *mouseRegion = canvas->rootObject()->findChild<QSGMouseArea*>("mouseregion");
-    QVERIFY(mouseRegion != 0);
-
-    QSGRectangle *rect = canvas->rootObject()->findChild<QSGRectangle*>("ball");
-    QVERIFY(rect != 0);
-
-    QCOMPARE(mouseRegion->mouseX(), rect->x());
-    QCOMPARE(mouseRegion->mouseY(), rect->y());
-
-    QMouseEvent event(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
-    QApplication::sendEvent(canvas, &event);
-
-    QCOMPARE(mouseRegion->mouseX(), 100.0);
-    QCOMPARE(mouseRegion->mouseY(), 100.0);
-
-    QCOMPARE(mouseRegion->mouseX(), rect->x());
-    QCOMPARE(mouseRegion->mouseY(), rect->y());
-
-    delete canvas;
-}
-
-void tst_QSGMouseArea::updateMouseAreaPosOnResize()
-{
-    QSGView *canvas = createView();
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("updateMousePosOnResize.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QVERIFY(canvas->rootObject() != 0);
-
-    QSGMouseArea *mouseRegion = canvas->rootObject()->findChild<QSGMouseArea*>("mouseregion");
-    QVERIFY(mouseRegion != 0);
-
-    QSGRectangle *rect = canvas->rootObject()->findChild<QSGRectangle*>("brother");
-    QVERIFY(rect != 0);
-
-    QCOMPARE(mouseRegion->mouseX(), 0.0);
-    QCOMPARE(mouseRegion->mouseY(), 0.0);
-
-    QMouseEvent event(QEvent::MouseButtonPress, rect->pos().toPoint(), Qt::LeftButton, Qt::LeftButton, 0);
-    QApplication::sendEvent(canvas, &event);
-
-    QVERIFY(!mouseRegion->property("emitPositionChanged").toBool());
-    QVERIFY(mouseRegion->property("mouseMatchesPos").toBool());
-
-    QCOMPARE(mouseRegion->property("x1").toInt(), 0);
-    QCOMPARE(mouseRegion->property("y1").toInt(), 0);
-
-    // XXX: is it on purpose that mouseX is real and mouse.x is int?
-    QCOMPARE(mouseRegion->property("x2").toInt(), (int) rect->x());
-    QCOMPARE(mouseRegion->property("y2").toInt(), (int) rect->y());
-
-    QCOMPARE(mouseRegion->mouseX(), rect->x());
-    QCOMPARE(mouseRegion->mouseY(), rect->y());
-
-    delete canvas;
-}
-
-void tst_QSGMouseArea::noOnClickedWithPressAndHold()
-{
-    {
-        // We handle onPressAndHold, therefore no onClicked
-        QSGView *canvas = createView();
-        canvas->setSource(QUrl::fromLocalFile(TESTDATA("clickandhold.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);
-
-        QVERIFY(!canvas->rootObject()->property("clicked").toBool());
-        QVERIFY(!canvas->rootObject()->property("held").toBool());
-
-        QTest::qWait(1000);
-
-        QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
-        QApplication::sendEvent(canvas, &releaseEvent);
-
-        QVERIFY(!canvas->rootObject()->property("clicked").toBool());
-        QVERIFY(canvas->rootObject()->property("held").toBool());
-
-        delete canvas;
-    }
-
-    {
-        // We do not handle onPressAndHold, therefore we get onClicked
-        QSGView *canvas = createView();
-        canvas->setSource(QUrl::fromLocalFile(TESTDATA("noclickandhold.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);
-
-        QVERIFY(!canvas->rootObject()->property("clicked").toBool());
-
-        QTest::qWait(1000);
-
-        QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
-        QApplication::sendEvent(canvas, &releaseEvent);
-
-        QVERIFY(canvas->rootObject()->property("clicked").toBool());
-
-        delete canvas;
-    }
-}
-
-void tst_QSGMouseArea::onMousePressRejected()
-{
-    QSGView *canvas = createView();
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("rejectEvent.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QVERIFY(canvas->rootObject() != 0);
-    QVERIFY(canvas->rootObject()->property("enabled").toBool());
-
-    QVERIFY(!canvas->rootObject()->property("mr1_pressed").toBool());
-    QVERIFY(!canvas->rootObject()->property("mr1_released").toBool());
-    QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
-    QVERIFY(!canvas->rootObject()->property("mr2_pressed").toBool());
-    QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
-    QVERIFY(!canvas->rootObject()->property("mr2_canceled").toBool());
-
-    QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
-    QApplication::sendEvent(canvas, &pressEvent);
-
-    QVERIFY(canvas->rootObject()->property("mr1_pressed").toBool());
-    QVERIFY(!canvas->rootObject()->property("mr1_released").toBool());
-    QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
-    QVERIFY(canvas->rootObject()->property("mr2_pressed").toBool());
-    QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
-    QVERIFY(canvas->rootObject()->property("mr2_canceled").toBool());
-
-    QTest::qWait(200);
-
-    QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
-    QApplication::sendEvent(canvas, &releaseEvent);
-
-    QVERIFY(canvas->rootObject()->property("mr1_released").toBool());
-    QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
-    QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
-
-    delete canvas;
-}
-void tst_QSGMouseArea::pressedCanceledOnWindowDeactivate()
-{
-    QSGView *canvas = createView();
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pressedCanceled.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QVERIFY(canvas->rootObject() != 0);
-    QVERIFY(!canvas->rootObject()->property("pressed").toBool());
-    QVERIFY(!canvas->rootObject()->property("canceled").toBool());
-    QVERIFY(!canvas->rootObject()->property("released").toBool());
-
-    QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
-    QApplication::sendEvent(canvas, &pressEvent);
-
-    QVERIFY(canvas->rootObject()->property("pressed").toBool());
-    QVERIFY(!canvas->rootObject()->property("canceled").toBool());
-    QVERIFY(!canvas->rootObject()->property("released").toBool());
-
-    QTest::qWait(200);
-
-    QEvent windowDeactivateEvent(QEvent::WindowDeactivate);
-    QApplication::sendEvent(canvas, &windowDeactivateEvent);
-    QVERIFY(!canvas->rootObject()->property("pressed").toBool());
-    QVERIFY(canvas->rootObject()->property("canceled").toBool());
-    QVERIFY(!canvas->rootObject()->property("released").toBool());
-
-    QTest::qWait(200);
-
-    //press again
-    QApplication::sendEvent(canvas, &pressEvent);
-    QVERIFY(canvas->rootObject()->property("pressed").toBool());
-    QVERIFY(!canvas->rootObject()->property("canceled").toBool());
-    QVERIFY(!canvas->rootObject()->property("released").toBool());
-
-    QTest::qWait(200);
-
-    //release
-    QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
-    QApplication::sendEvent(canvas, &releaseEvent);
-    QVERIFY(!canvas->rootObject()->property("pressed").toBool());
-    QVERIFY(!canvas->rootObject()->property("canceled").toBool());
-    QVERIFY(canvas->rootObject()->property("released").toBool());
-
-    delete canvas;
-}
-void tst_QSGMouseArea::doubleClick()
-{
-    QSGView *canvas = createView();
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("doubleclick.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);
-
-    QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
-    QApplication::sendEvent(canvas, &releaseEvent);
-
-    QCOMPARE(canvas->rootObject()->property("released").toInt(), 1);
-
-    pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
-    QApplication::sendEvent(canvas, &pressEvent);
-
-    QApplication::sendEvent(canvas, &releaseEvent);
-
-    QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 1);
-    QCOMPARE(canvas->rootObject()->property("doubleClicked").toInt(), 1);
-    QCOMPARE(canvas->rootObject()->property("released").toInt(), 2);
-
-    delete canvas;
-}
-
-// QTBUG-14832
-void tst_QSGMouseArea::clickTwice()
-{
-    QSGView *canvas = createView();
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("clicktwice.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);
-
-    QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
-    QApplication::sendEvent(canvas, &releaseEvent);
-
-    QCOMPARE(canvas->rootObject()->property("pressed").toInt(), 1);
-    QCOMPARE(canvas->rootObject()->property("released").toInt(), 1);
-    QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 1);
-
-    pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
-    QApplication::sendEvent(canvas, &pressEvent);
-
-    QApplication::sendEvent(canvas, &pressEvent);
-    QApplication::sendEvent(canvas, &releaseEvent);
-
-    QCOMPARE(canvas->rootObject()->property("pressed").toInt(), 2);
-    QCOMPARE(canvas->rootObject()->property("released").toInt(), 2);
-    QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 2);
-
-    delete canvas;
-}
-
-void tst_QSGMouseArea::pressedOrdering()
-{
-    QSGView *canvas = createView();
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pressedOrdering.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QVERIFY(canvas->rootObject() != 0);
-
-    QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("base"));
-
-    QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
-    QApplication::sendEvent(canvas, &pressEvent);
-
-    QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("pressed"));
-
-    QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
-    QApplication::sendEvent(canvas, &releaseEvent);
-
-    QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("toggled"));
-
-    QApplication::sendEvent(canvas, &pressEvent);
-
-    QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("pressed"));
-
-    delete canvas;
-}
-
-void tst_QSGMouseArea::preventStealing()
-{
-    QSGView *canvas = createView();
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("preventstealing.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QVERIFY(canvas->rootObject() != 0);
-
-    QSGFlickable *flickable = qobject_cast<QSGFlickable*>(canvas->rootObject());
-    QVERIFY(flickable != 0);
-
-    QSGMouseArea *mouseArea = canvas->rootObject()->findChild<QSGMouseArea*>("mousearea");
-    QVERIFY(mouseArea != 0);
-
-    QSignalSpy mousePositionSpy(mouseArea, SIGNAL(positionChanged(QSGMouseEvent*)));
-
-    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(80, 80));
-
-    // Without preventStealing, mouse movement over MouseArea would
-    // cause the Flickable to steal mouse and trigger content movement.
-
-    QTest::mouseMove(canvas,QPoint(69,69));
-    QTest::mouseMove(canvas,QPoint(58,58));
-    QTest::mouseMove(canvas,QPoint(47,47));
-
-    // We should have received all three move events
-    QCOMPARE(mousePositionSpy.count(), 3);
-    QVERIFY(mouseArea->pressed());
-
-    // Flickable content should not have moved.
-    QCOMPARE(flickable->contentX(), 0.);
-    QCOMPARE(flickable->contentY(), 0.);
-
-    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(47, 47));
-
-    // Now allow stealing and confirm Flickable does its thing.
-    canvas->rootObject()->setProperty("stealing", false);
-
-    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(80, 80));
-
-    // Without preventStealing, mouse movement over MouseArea would
-    // cause the Flickable to steal mouse and trigger content movement.
-
-    QTest::mouseMove(canvas,QPoint(69,69));
-    QTest::mouseMove(canvas,QPoint(58,58));
-    QTest::mouseMove(canvas,QPoint(47,47));
-
-    // We should only have received the first move event
-    QCOMPARE(mousePositionSpy.count(), 4);
-    // Our press should be taken away
-    QVERIFY(!mouseArea->pressed());
-
-    // Flickable content should have moved.
-
-    QCOMPARE(flickable->contentX(), 11.);
-    QCOMPARE(flickable->contentY(), 11.);
-
-    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 50));
-
-    delete canvas;
-}
-
-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(TESTDATA("clickThrough.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QVERIFY(canvas->rootObject() != 0);
-
-    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
-    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
-
-    QTRY_COMPARE(canvas->rootObject()->property("presses").toInt(), 0);
-    QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
-
-    QTest::qWait(800); // to avoid generating a double click.
-
-    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
-    QTest::qWait(1000);
-    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
-
-    QTRY_COMPARE(canvas->rootObject()->property("presses").toInt(), 0);
-    QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
-    QTRY_COMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
-
-    QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
-    QTest::qWait(100);
-
-    QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
-    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(TESTDATA("clickThrough2.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QVERIFY(canvas->rootObject() != 0);
-
-    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);
-
-    QTest::qWait(800); // to avoid generating a double click.
-
-    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
-    QTest::qWait(1000);
-    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);
-
-    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);
-    QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 0);
-    QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 0);
-
-    canvas->rootObject()->setProperty("letThrough", QVariant(true));
-
-    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);
-    QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
-
-    QTest::qWait(800); // to avoid generating a double click.
-    QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
-    QTest::qWait(1000);
-    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);
-
-    QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
-    QTest::qWait(100);
-
-    QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
-    QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2);
-    QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1);
-    QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
-
-    delete canvas;
-}
-
-void tst_QSGMouseArea::testQtQuick11Attributes()
-{
-    QFETCH(QString, code);
-    QFETCH(QString, warning);
-    QFETCH(QString, error);
-
-    QDeclarativeEngine engine;
-    QObject *obj;
-
-    QDeclarativeComponent valid(&engine);
-    valid.setData("import QtQuick 1.1; MouseArea { " + code.toUtf8() + " }", QUrl(""));
-    obj = valid.create();
-    QVERIFY(obj);
-    QVERIFY(valid.errorString().isEmpty());
-    delete obj;
-
-    QDeclarativeComponent invalid(&engine);
-    invalid.setData("import QtQuick 1.0; MouseArea { " + code.toUtf8() + " }", QUrl(""));
-    QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
-    obj = invalid.create();
-    QCOMPARE(invalid.errorString(), error);
-    delete obj;
-}
-
-void tst_QSGMouseArea::testQtQuick11Attributes_data()
-{
-    QTest::addColumn<QString>("code");
-    QTest::addColumn<QString>("warning");
-    QTest::addColumn<QString>("error");
-
-    QTest::newRow("preventStealing") << "preventStealing: true"
-        << "QDeclarativeComponent: Component is not ready"
-        << ":1 \"MouseArea.preventStealing\" is not available in QtQuick 1.0.\n";
-}
-
-void tst_QSGMouseArea::hoverPosition()
-{
-    QSGView *canvas = createView();
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("hoverPosition.qml")));
-
-    QSGItem *root = canvas->rootObject();
-    QVERIFY(root != 0);
-
-    QCOMPARE(root->property("mouseX").toReal(), qreal(0));
-    QCOMPARE(root->property("mouseY").toReal(), qreal(0));
-
-    QTest::mouseMove(canvas,QPoint(10,32));
-
-
-    QCOMPARE(root->property("mouseX").toReal(), qreal(10));
-    QCOMPARE(root->property("mouseY").toReal(), qreal(32));
-
-    delete canvas;
-}
-
-void tst_QSGMouseArea::hoverPropagation()
-{
-    //QTBUG-18175, to behave like GV did.
-    QSGView *canvas = createView();
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("hoverPropagation.qml")));
-
-    QSGItem *root = canvas->rootObject();
-    QVERIFY(root != 0);
-
-    QCOMPARE(root->property("point1").toBool(), false);
-    QCOMPARE(root->property("point2").toBool(), false);
-
-    QMouseEvent moveEvent(QEvent::MouseMove, QPoint(32, 32), Qt::NoButton, Qt::NoButton, 0);
-    QApplication::sendEvent(canvas, &moveEvent);
-
-    QCOMPARE(root->property("point1").toBool(), true);
-    QCOMPARE(root->property("point2").toBool(), false);
-
-    QMouseEvent moveEvent2(QEvent::MouseMove, QPoint(232, 32), Qt::NoButton, Qt::NoButton, 0);
-    QApplication::sendEvent(canvas, &moveEvent2);
-    QCOMPARE(root->property("point1").toBool(), false);
-    QCOMPARE(root->property("point2").toBool(), true);
-
-    delete canvas;
-}
-
-QTEST_MAIN(tst_QSGMouseArea)
-
-#include "tst_qsgmousearea.moc"
diff --git a/tests/auto/declarative/qsgpathview/qsgpathview.pro b/tests/auto/declarative/qsgpathview/qsgpathview.pro
deleted file mode 100644 (file)
index d4c237d..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsgpathview
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_qsgpathview.cpp
-
-testDataFiles.files = data
-testDataFiles.path = .
-DEPLOYMENT += testDataFiles
-
-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
deleted file mode 100644 (file)
index c6440cf..0000000
+++ /dev/null
@@ -1,1155 +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 <QtTest/QtTest>
-#include <QtDeclarative/qsgview.h>
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtDeclarative/qdeclarativecontext.h>
-#include <QtDeclarative/qdeclarativeexpression.h>
-#include <QtDeclarative/private/qsgpathview_p.h>
-#include <QtDeclarative/private/qdeclarativepath_p.h>
-#include <QtDeclarative/private/qsgtext_p.h>
-#include <QtDeclarative/private/qsgrectangle_p.h>
-#include <QtDeclarative/private/qdeclarativelistmodel_p.h>
-#include <QtDeclarative/private/qdeclarativevaluetype_p.h>
-#include <QAbstractListModel>
-#include <QStringListModel>
-#include <QStandardItemModel>
-#include <QFile>
-
-#include "../shared/util.h"
-
-static void initStandardTreeModel(QStandardItemModel *model)
-{
-    QStandardItem *item;
-    item = new QStandardItem(QLatin1String("Row 1 Item"));
-    model->insertRow(0, item);
-
-    item = new QStandardItem(QLatin1String("Row 2 Item"));
-    item->setCheckable(true);
-    model->insertRow(1, item);
-
-    QStandardItem *childItem = new QStandardItem(QLatin1String("Row 2 Child Item"));
-    item->setChild(0, childItem);
-
-    item = new QStandardItem(QLatin1String("Row 3 Item"));
-    item->setIcon(QIcon());
-    model->insertRow(2, item);
-}
-
-
-class tst_QSGPathView : public QObject
-{
-    Q_OBJECT
-public:
-    tst_QSGPathView();
-
-private slots:
-    void initTestCase();
-    void cleanupTestCase();
-    void initValues();
-    void items();
-    void dataModel();
-    void pathview2();
-    void pathview3();
-    void path();
-    void pathMoved();
-    void setCurrentIndex();
-    void resetModel();
-    void propertyChanges();
-    void pathChanges();
-    void componentChanges();
-    void modelChanges();
-    void pathUpdateOnStartChanged();
-    void package();
-    void emptyModel();
-    void closed();
-    void pathUpdate();
-    void visualDataModel();
-    void undefinedPath();
-    void mouseDrag();
-    void treeModel();
-    void changePreferredHighlight();
-    void missingPercent();
-    void creationContext();
-
-private:
-    QSGView *createView();
-    template<typename T>
-    T *findItem(QSGItem *parent, const QString &objectName, int index=-1);
-    template<typename T>
-    QList<T*> findItems(QSGItem *parent, const QString &objectName);
-};
-
-void tst_QSGPathView::initTestCase()
-{
-}
-
-void tst_QSGPathView::cleanupTestCase()
-{
-
-}
-
-class TestObject : public QObject
-{
-    Q_OBJECT
-
-    Q_PROPERTY(bool error READ error WRITE setError)
-    Q_PROPERTY(bool useModel READ useModel NOTIFY useModelChanged)
-    Q_PROPERTY(int pathItemCount READ pathItemCount NOTIFY pathItemCountChanged)
-
-public:
-    TestObject() : QObject(), mError(true), mUseModel(true), mPathItemCount(-1) {}
-
-    bool error() const { return mError; }
-    void setError(bool err) { mError = err; }
-
-    bool useModel() const { return mUseModel; }
-    void setUseModel(bool use) { mUseModel = use; emit useModelChanged(); }
-
-    int pathItemCount() const { return mPathItemCount; }
-    void setPathItemCount(int count) { mPathItemCount = count; emit pathItemCountChanged(); }
-
-signals:
-    void useModelChanged();
-    void pathItemCountChanged();
-
-private:
-    bool mError;
-    bool mUseModel;
-    int mPathItemCount;
-};
-
-class TestModel : public QAbstractListModel
-{
-public:
-    enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 };
-
-    TestModel(QObject *parent=0) : QAbstractListModel(parent) {
-        QHash<int, QByteArray> roles;
-        roles[Name] = "name";
-        roles[Number] = "number";
-        setRoleNames(roles);
-    }
-
-    int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); }
-    QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
-        QVariant rv;
-        if (role == Name)
-            rv = list.at(index.row()).first;
-        else if (role == Number)
-            rv = list.at(index.row()).second;
-
-        return rv;
-    }
-
-    int count() const { return rowCount(); }
-    QString name(int index) const { return list.at(index).first; }
-    QString number(int index) const { return list.at(index).second; }
-
-    void addItem(const QString &name, const QString &number) {
-        beginInsertRows(QModelIndex(), list.count(), list.count());
-        list.append(QPair<QString,QString>(name, number));
-        endInsertRows();
-    }
-
-    void insertItem(int index, const QString &name, const QString &number) {
-        beginInsertRows(QModelIndex(), index, index);
-        list.insert(index, QPair<QString,QString>(name, number));
-        endInsertRows();
-    }
-
-    void removeItem(int index) {
-        beginRemoveRows(QModelIndex(), index, index);
-        list.removeAt(index);
-        endRemoveRows();
-    }
-
-    void moveItem(int from, int to) {
-        beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
-        list.move(from, to);
-        endMoveRows();
-    }
-
-    void modifyItem(int idx, const QString &name, const QString &number) {
-        list[idx] = QPair<QString,QString>(name, number);
-        emit dataChanged(index(idx,0), index(idx,0));
-    }
-
-private:
-    QList<QPair<QString,QString> > list;
-};
-
-
-tst_QSGPathView::tst_QSGPathView()
-{
-}
-
-void tst_QSGPathView::initValues()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathview1.qml")));
-    QSGPathView *obj = qobject_cast<QSGPathView*>(c.create());
-
-    QVERIFY(obj != 0);
-    QVERIFY(obj->path() == 0);
-    QVERIFY(obj->delegate() == 0);
-    QCOMPARE(obj->model(), QVariant());
-    QCOMPARE(obj->currentIndex(), 0);
-    QCOMPARE(obj->offset(), 0.);
-    QCOMPARE(obj->preferredHighlightBegin(), 0.);
-    QCOMPARE(obj->dragMargin(), 0.);
-    QCOMPARE(obj->count(), 0);
-    QCOMPARE(obj->pathItemCount(), -1);
-}
-
-void tst_QSGPathView::items()
-{
-    QSGView *canvas = createView();
-
-    TestModel model;
-    model.addItem("Fred", "12345");
-    model.addItem("John", "2345");
-    model.addItem("Bob", "54321");
-    model.addItem("Bill", "4321");
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml")));
-    qApp->processEvents();
-
-    QSGPathView *pathview = findItem<QSGPathView>(canvas->rootObject(), "view");
-    QVERIFY(pathview != 0);
-
-    QCOMPARE(pathview->count(), model.count());
-    QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count());
-    QCOMPARE(pathview->childItems().count(), model.count()+1); // assumes all are visible, including highlight
-
-    for (int i = 0; i < model.count(); ++i) {
-        QSGText *name = findItem<QSGText>(pathview, "textName", i);
-        QVERIFY(name != 0);
-        QCOMPARE(name->text(), model.name(i));
-        QSGText *number = findItem<QSGText>(pathview, "textNumber", i);
-        QVERIFY(number != 0);
-        QCOMPARE(number->text(), model.number(i));
-    }
-
-    QDeclarativePath *path = qobject_cast<QDeclarativePath*>(pathview->path());
-    QVERIFY(path);
-
-    QVERIFY(pathview->highlightItem());
-    QPointF start = path->pointAt(0.0);
-    QPointF offset;
-    offset.setX(pathview->highlightItem()->width()/2);
-    offset.setY(pathview->highlightItem()->height()/2);
-    QCOMPARE(pathview->highlightItem()->pos() + offset, start);
-
-    delete canvas;
-}
-
-void tst_QSGPathView::pathview2()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathview2.qml")));
-    QSGPathView *obj = qobject_cast<QSGPathView*>(c.create());
-
-    QVERIFY(obj != 0);
-    QVERIFY(obj->path() != 0);
-    QVERIFY(obj->delegate() != 0);
-    QVERIFY(obj->model() != QVariant());
-    QCOMPARE(obj->currentIndex(), 0);
-    QCOMPARE(obj->offset(), 0.);
-    QCOMPARE(obj->preferredHighlightBegin(), 0.);
-    QCOMPARE(obj->dragMargin(), 0.);
-    QCOMPARE(obj->count(), 8);
-    QCOMPARE(obj->pathItemCount(), 10);
-}
-
-void tst_QSGPathView::pathview3()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathview3.qml")));
-    QSGPathView *obj = qobject_cast<QSGPathView*>(c.create());
-
-    QVERIFY(obj != 0);
-    QVERIFY(obj->path() != 0);
-    QVERIFY(obj->delegate() != 0);
-    QVERIFY(obj->model() != QVariant());
-    QCOMPARE(obj->currentIndex(), 0);
-    QCOMPARE(obj->offset(), 1.0);
-    QCOMPARE(obj->preferredHighlightBegin(), 0.5);
-    QCOMPARE(obj->dragMargin(), 24.);
-    QCOMPARE(obj->count(), 8);
-    QCOMPARE(obj->pathItemCount(), 4);
-}
-
-void tst_QSGPathView::path()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathtest.qml")));
-    QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create());
-
-    QVERIFY(obj != 0);
-    QCOMPARE(obj->startX(), 120.);
-    QCOMPARE(obj->startY(), 100.);
-    QVERIFY(obj->path() != QPainterPath());
-
-    QDeclarativeListReference list(obj, "pathElements");
-    QCOMPARE(list.count(), 5);
-
-    QDeclarativePathAttribute* attr = qobject_cast<QDeclarativePathAttribute*>(list.at(0));
-    QVERIFY(attr != 0);
-    QCOMPARE(attr->name(), QString("scale"));
-    QCOMPARE(attr->value(), 1.0);
-
-    QDeclarativePathQuad* quad = qobject_cast<QDeclarativePathQuad*>(list.at(1));
-    QVERIFY(quad != 0);
-    QCOMPARE(quad->x(), 120.);
-    QCOMPARE(quad->y(), 25.);
-    QCOMPARE(quad->controlX(), 260.);
-    QCOMPARE(quad->controlY(), 75.);
-
-    QDeclarativePathPercent* perc = qobject_cast<QDeclarativePathPercent*>(list.at(2));
-    QVERIFY(perc != 0);
-    QCOMPARE(perc->value(), 0.3);
-
-    QDeclarativePathLine* line = qobject_cast<QDeclarativePathLine*>(list.at(3));
-    QVERIFY(line != 0);
-    QCOMPARE(line->x(), 120.);
-    QCOMPARE(line->y(), 100.);
-
-    QDeclarativePathCubic* cubic = qobject_cast<QDeclarativePathCubic*>(list.at(4));
-    QVERIFY(cubic != 0);
-    QCOMPARE(cubic->x(), 180.);
-    QCOMPARE(cubic->y(), 0.);
-    QCOMPARE(cubic->control1X(), -10.);
-    QCOMPARE(cubic->control1Y(), 90.);
-    QCOMPARE(cubic->control2X(), 210.);
-    QCOMPARE(cubic->control2Y(), 90.);
-}
-
-void tst_QSGPathView::dataModel()
-{
-    QSGView *canvas = createView();
-    canvas->show();
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    TestObject *testObject = new TestObject;
-    ctxt->setContextProperty("testObject", testObject);
-
-    TestModel model;
-    model.addItem("red", "1");
-    model.addItem("green", "2");
-    model.addItem("blue", "3");
-    model.addItem("purple", "4");
-    model.addItem("gray", "5");
-    model.addItem("brown", "6");
-    model.addItem("yellow", "7");
-    model.addItem("thistle", "8");
-    model.addItem("cyan", "9");
-    model.addItem("peachpuff", "10");
-    model.addItem("powderblue", "11");
-    model.addItem("gold", "12");
-    model.addItem("sandybrown", "13");
-
-    ctxt->setContextProperty("testData", &model);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("datamodel.qml")));
-    qApp->processEvents();
-
-    QSGPathView *pathview = qobject_cast<QSGPathView*>(canvas->rootObject());
-    QVERIFY(pathview != 0);
-
-    QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
-    QVERIFY(testObject->error() == false);
-
-    QSGItem *item = findItem<QSGItem>(pathview, "wrapper", 0);
-    QVERIFY(item);
-    QCOMPARE(item->x(), 110.0);
-    QCOMPARE(item->y(), 10.0);
-
-    model.insertItem(4, "orange", "10");
-    QTest::qWait(100);
-
-    QCOMPARE(canvas->rootObject()->property("viewCount").toInt(), model.count());
-    QTRY_COMPARE(findItems<QSGItem>(pathview, "wrapper").count(), 14);
-
-    QVERIFY(pathview->currentIndex() == 0);
-    QCOMPARE(pathview->currentItem(), findItem<QSGItem>(pathview, "wrapper", 0));
-
-    QSGText *text = findItem<QSGText>(pathview, "myText", 4);
-    QVERIFY(text);
-    QCOMPARE(text->text(), model.name(4));
-
-    model.removeItem(2);
-    QCOMPARE(canvas->rootObject()->property("viewCount").toInt(), model.count());
-    text = findItem<QSGText>(pathview, "myText", 2);
-    QVERIFY(text);
-    QCOMPARE(text->text(), model.name(2));
-    QCOMPARE(pathview->currentItem(), findItem<QSGItem>(pathview, "wrapper", 0));
-
-    testObject->setPathItemCount(5);
-    QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
-    QVERIFY(testObject->error() == false);
-
-    QTRY_COMPARE(findItems<QSGItem>(pathview, "wrapper").count(), 5);
-
-    QSGRectangle *testItem = findItem<QSGRectangle>(pathview, "wrapper", 4);
-    QVERIFY(testItem != 0);
-    testItem = findItem<QSGRectangle>(pathview, "wrapper", 5);
-    QVERIFY(testItem == 0);
-
-    pathview->setCurrentIndex(1);
-    QCOMPARE(pathview->currentItem(), findItem<QSGItem>(pathview, "wrapper", 1));
-    QTest::qWait(100);
-
-    model.insertItem(2, "pink", "2");
-    QTest::qWait(100);
-
-    QTRY_COMPARE(findItems<QSGItem>(pathview, "wrapper").count(), 5);
-    QVERIFY(pathview->currentIndex() == 1);
-    QCOMPARE(pathview->currentItem(), findItem<QSGItem>(pathview, "wrapper", 1));
-
-    text = findItem<QSGText>(pathview, "myText", 2);
-    QVERIFY(text);
-    QCOMPARE(text->text(), model.name(2));
-
-    model.removeItem(3);
-    QTRY_COMPARE(findItems<QSGItem>(pathview, "wrapper").count(), 5);
-    text = findItem<QSGText>(pathview, "myText", 3);
-    QVERIFY(text);
-    QCOMPARE(text->text(), model.name(3));
-    QCOMPARE(pathview->currentItem(), findItem<QSGItem>(pathview, "wrapper", 1));
-
-    model.moveItem(3, 5);
-    QTRY_COMPARE(findItems<QSGItem>(pathview, "wrapper").count(), 5);
-    QList<QSGItem*> items = findItems<QSGItem>(pathview, "wrapper");
-    foreach (QSGItem *item, items) {
-        QVERIFY(item->property("onPath").toBool());
-    }
-    QCOMPARE(pathview->currentItem(), findItem<QSGItem>(pathview, "wrapper", 1));
-
-    // QTBUG-14199
-    pathview->setOffset(7);
-    pathview->setOffset(0);
-    QCOMPARE(findItems<QSGItem>(pathview, "wrapper").count(), 5);
-
-    pathview->setCurrentIndex(model.count()-1);
-    model.removeItem(model.count()-1);
-    QCOMPARE(pathview->currentIndex(), model.count()-1);
-
-    delete canvas;
-    delete testObject;
-}
-
-void tst_QSGPathView::pathMoved()
-{
-    QSGView *canvas = createView();
-    canvas->show();
-
-    TestModel model;
-    model.addItem("Ben", "12345");
-    model.addItem("Bohn", "2345");
-    model.addItem("Bob", "54321");
-    model.addItem("Bill", "4321");
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml")));
-    qApp->processEvents();
-
-    QSGPathView *pathview = findItem<QSGPathView>(canvas->rootObject(), "view");
-    QVERIFY(pathview != 0);
-
-    QSGRectangle *firstItem = findItem<QSGRectangle>(pathview, "wrapper", 0);
-    QVERIFY(firstItem);
-    QDeclarativePath *path = qobject_cast<QDeclarativePath*>(pathview->path());
-    QVERIFY(path);
-    QPointF start = path->pointAt(0.0);
-    QPointF offset;//Center of item is at point, but pos is from corner
-    offset.setX(firstItem->width()/2);
-    offset.setY(firstItem->height()/2);
-    QCOMPARE(firstItem->pos() + offset, start);
-    pathview->setOffset(1.0);
-
-    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())));
-    }
-
-    pathview->setOffset(0.0);
-    QCOMPARE(firstItem->pos() + offset, start);
-
-    // Change delegate size
-    pathview->setOffset(0.1);
-    pathview->setOffset(0.0);
-    canvas->rootObject()->setProperty("delegateWidth", 30);
-    QCOMPARE(firstItem->width(), 30.0);
-    offset.setX(firstItem->width()/2);
-    QTRY_COMPARE(firstItem->pos() + offset, start);
-
-    // Change delegate scale
-    pathview->setOffset(0.1);
-    pathview->setOffset(0.0);
-    canvas->rootObject()->setProperty("delegateScale", 1.2);
-    QTRY_COMPARE(firstItem->pos() + offset, start);
-
-    delete canvas;
-}
-
-void tst_QSGPathView::setCurrentIndex()
-{
-    QSGView *canvas = createView();
-    canvas->show();
-
-    TestModel model;
-    model.addItem("Ben", "12345");
-    model.addItem("Bohn", "2345");
-    model.addItem("Bob", "54321");
-    model.addItem("Bill", "4321");
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml")));
-    qApp->processEvents();
-
-    QSGPathView *pathview = findItem<QSGPathView>(canvas->rootObject(), "view");
-    QVERIFY(pathview != 0);
-
-    QSGRectangle *firstItem = findItem<QSGRectangle>(pathview, "wrapper", 0);
-    QVERIFY(firstItem);
-    QDeclarativePath *path = qobject_cast<QDeclarativePath*>(pathview->path());
-    QVERIFY(path);
-    QPointF start = path->pointAt(0.0);
-    QPointF offset;//Center of item is at point, but pos is from corner
-    offset.setX(firstItem->width()/2);
-    offset.setY(firstItem->height()/2);
-    QCOMPARE(firstItem->pos() + offset, start);
-    QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 0);
-    QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 0);
-
-    pathview->setCurrentIndex(2);
-
-    firstItem = findItem<QSGRectangle>(pathview, "wrapper", 2);
-    QTRY_COMPARE(firstItem->pos() + offset, start);
-    QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 2);
-    QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 2);
-    QCOMPARE(pathview->currentItem(), firstItem);
-    QCOMPARE(firstItem->property("onPath"), QVariant(true));
-
-    pathview->decrementCurrentIndex();
-    QTRY_COMPARE(pathview->currentIndex(), 1);
-    firstItem = findItem<QSGRectangle>(pathview, "wrapper", 1);
-    QVERIFY(firstItem);
-    QTRY_COMPARE(firstItem->pos() + offset, start);
-    QCOMPARE(pathview->currentItem(), firstItem);
-    QCOMPARE(firstItem->property("onPath"), QVariant(true));
-
-    pathview->decrementCurrentIndex();
-    QTRY_COMPARE(pathview->currentIndex(), 0);
-    firstItem = findItem<QSGRectangle>(pathview, "wrapper", 0);
-    QVERIFY(firstItem);
-    QTRY_COMPARE(firstItem->pos() + offset, start);
-    QCOMPARE(pathview->currentItem(), firstItem);
-    QCOMPARE(firstItem->property("onPath"), QVariant(true));
-
-    pathview->decrementCurrentIndex();
-    QTRY_COMPARE(pathview->currentIndex(), 3);
-    firstItem = findItem<QSGRectangle>(pathview, "wrapper", 3);
-    QVERIFY(firstItem);
-    QTRY_COMPARE(firstItem->pos() + offset, start);
-    QCOMPARE(pathview->currentItem(), firstItem);
-    QCOMPARE(firstItem->property("onPath"), QVariant(true));
-
-    pathview->incrementCurrentIndex();
-    QTRY_COMPARE(pathview->currentIndex(), 0);
-    firstItem = findItem<QSGRectangle>(pathview, "wrapper", 0);
-    QVERIFY(firstItem);
-    QTRY_COMPARE(firstItem->pos() + offset, start);
-    QCOMPARE(pathview->currentItem(), firstItem);
-    QCOMPARE(firstItem->property("onPath"), QVariant(true));
-
-    // Check the current item is still created when outside the bounds of pathItemCount.
-    pathview->setPathItemCount(2);
-    pathview->setHighlightRangeMode(QSGPathView::NoHighlightRange);
-    QVERIFY(findItem<QSGRectangle>(pathview, "wrapper", 0));
-    QVERIFY(findItem<QSGRectangle>(pathview, "wrapper", 1));
-    QVERIFY(!findItem<QSGRectangle>(pathview, "wrapper", 2));
-    QVERIFY(!findItem<QSGRectangle>(pathview, "wrapper", 3));
-
-    pathview->setCurrentIndex(2);
-    firstItem = findItem<QSGRectangle>(pathview, "wrapper", 2);
-    QCOMPARE(pathview->currentItem(), firstItem);
-    QCOMPARE(firstItem->property("onPath"), QVariant(false));
-
-    pathview->decrementCurrentIndex();
-    QTRY_COMPARE(pathview->currentIndex(), 1);
-    firstItem = findItem<QSGRectangle>(pathview, "wrapper", 1);
-    QVERIFY(firstItem);
-    QCOMPARE(pathview->currentItem(), firstItem);
-    QCOMPARE(firstItem->property("onPath"), QVariant(true));
-
-    pathview->decrementCurrentIndex();
-    QTRY_COMPARE(pathview->currentIndex(), 0);
-    firstItem = findItem<QSGRectangle>(pathview, "wrapper", 0);
-    QVERIFY(firstItem);
-    QCOMPARE(pathview->currentItem(), firstItem);
-    QCOMPARE(firstItem->property("onPath"), QVariant(true));
-
-    pathview->decrementCurrentIndex();
-    QTRY_COMPARE(pathview->currentIndex(), 3);
-    firstItem = findItem<QSGRectangle>(pathview, "wrapper", 3);
-    QVERIFY(firstItem);
-    QCOMPARE(pathview->currentItem(), firstItem);
-    QCOMPARE(firstItem->property("onPath"), QVariant(false));
-
-    pathview->incrementCurrentIndex();
-    QTRY_COMPARE(pathview->currentIndex(), 0);
-    firstItem = findItem<QSGRectangle>(pathview, "wrapper", 0);
-    QVERIFY(firstItem);
-    QCOMPARE(pathview->currentItem(), firstItem);
-    QCOMPARE(firstItem->property("onPath"), QVariant(true));
-
-    delete canvas;
-}
-
-void tst_QSGPathView::resetModel()
-{
-    QSGView *canvas = createView();
-
-    QStringList strings;
-    strings << "one" << "two" << "three";
-    QStringListModel model(strings);
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testModel", &model);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaypath.qml")));
-    qApp->processEvents();
-
-    QSGPathView *pathview = findItem<QSGPathView>(canvas->rootObject(), "view");
-    QVERIFY(pathview != 0);
-
-    QCOMPARE(pathview->count(), model.rowCount());
-
-    for (int i = 0; i < model.rowCount(); ++i) {
-        QSGText *display = findItem<QSGText>(pathview, "displayText", i);
-        QVERIFY(display != 0);
-        QCOMPARE(display->text(), strings.at(i));
-    }
-
-    strings.clear();
-    strings << "four" << "five" << "six" << "seven";
-    model.setStringList(strings);
-
-    QCOMPARE(pathview->count(), model.rowCount());
-
-    for (int i = 0; i < model.rowCount(); ++i) {
-        QSGText *display = findItem<QSGText>(pathview, "displayText", i);
-        QVERIFY(display != 0);
-        QCOMPARE(display->text(), strings.at(i));
-    }
-
-    delete canvas;
-}
-
-void tst_QSGPathView::propertyChanges()
-{
-    QSGView *canvas = createView();
-    QVERIFY(canvas);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml")));
-
-    QSGPathView *pathView = canvas->rootObject()->findChild<QSGPathView*>("pathView");
-    QVERIFY(pathView);
-
-    QSignalSpy snapPositionSpy(pathView, SIGNAL(preferredHighlightBeginChanged()));
-    QSignalSpy dragMarginSpy(pathView, SIGNAL(dragMarginChanged()));
-
-    QCOMPARE(pathView->preferredHighlightBegin(), 0.1);
-    QCOMPARE(pathView->dragMargin(), 5.0);
-
-    pathView->setPreferredHighlightBegin(0.4);
-    pathView->setPreferredHighlightEnd(0.4);
-    pathView->setDragMargin(20.0);
-
-    QCOMPARE(pathView->preferredHighlightBegin(), 0.4);
-    QCOMPARE(pathView->preferredHighlightEnd(), 0.4);
-    QCOMPARE(pathView->dragMargin(), 20.0);
-
-    QCOMPARE(snapPositionSpy.count(), 1);
-    QCOMPARE(dragMarginSpy.count(), 1);
-
-    pathView->setPreferredHighlightBegin(0.4);
-    pathView->setPreferredHighlightEnd(0.4);
-    pathView->setDragMargin(20.0);
-
-    QCOMPARE(snapPositionSpy.count(), 1);
-    QCOMPARE(dragMarginSpy.count(), 1);
-    delete canvas;
-}
-
-void tst_QSGPathView::pathChanges()
-{
-    QSGView *canvas = createView();
-    QVERIFY(canvas);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml")));
-
-    QSGPathView *pathView = canvas->rootObject()->findChild<QSGPathView*>("pathView");
-    QVERIFY(pathView);
-
-    QDeclarativePath *path = canvas->rootObject()->findChild<QDeclarativePath*>("path");
-    QVERIFY(path);
-
-    QSignalSpy startXSpy(path, SIGNAL(startXChanged()));
-    QSignalSpy startYSpy(path, SIGNAL(startYChanged()));
-
-    QCOMPARE(path->startX(), 220.0);
-    QCOMPARE(path->startY(), 200.0);
-
-    path->setStartX(240.0);
-    path->setStartY(220.0);
-
-    QCOMPARE(path->startX(), 240.0);
-    QCOMPARE(path->startY(), 220.0);
-
-    QCOMPARE(startXSpy.count(),1);
-    QCOMPARE(startYSpy.count(),1);
-
-    path->setStartX(240);
-    path->setStartY(220);
-
-    QCOMPARE(startXSpy.count(),1);
-    QCOMPARE(startYSpy.count(),1);
-
-    QDeclarativePath *alternatePath = canvas->rootObject()->findChild<QDeclarativePath*>("alternatePath");
-    QVERIFY(alternatePath);
-
-    QSignalSpy pathSpy(pathView, SIGNAL(pathChanged()));
-
-    QCOMPARE(pathView->path(), path);
-
-    pathView->setPath(alternatePath);
-    QCOMPARE(pathView->path(), alternatePath);
-    QCOMPARE(pathSpy.count(),1);
-
-    pathView->setPath(alternatePath);
-    QCOMPARE(pathSpy.count(),1);
-
-    QDeclarativePathAttribute *pathAttribute = canvas->rootObject()->findChild<QDeclarativePathAttribute*>("pathAttribute");
-    QVERIFY(pathAttribute);
-
-    QSignalSpy nameSpy(pathAttribute, SIGNAL(nameChanged()));
-    QCOMPARE(pathAttribute->name(), QString("opacity"));
-
-    pathAttribute->setName("scale");
-    QCOMPARE(pathAttribute->name(), QString("scale"));
-    QCOMPARE(nameSpy.count(),1);
-
-    pathAttribute->setName("scale");
-    QCOMPARE(nameSpy.count(),1);
-    delete canvas;
-}
-
-void tst_QSGPathView::componentChanges()
-{
-    QSGView *canvas = createView();
-    QVERIFY(canvas);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml")));
-
-    QSGPathView *pathView = canvas->rootObject()->findChild<QSGPathView*>("pathView");
-    QVERIFY(pathView);
-
-    QDeclarativeComponent delegateComponent(canvas->engine());
-    delegateComponent.setData("import QtQuick 2.0; Text { text: '<b>Name:</b> ' + name }", QUrl::fromLocalFile(""));
-
-    QSignalSpy delegateSpy(pathView, SIGNAL(delegateChanged()));
-
-    pathView->setDelegate(&delegateComponent);
-    QCOMPARE(pathView->delegate(), &delegateComponent);
-    QCOMPARE(delegateSpy.count(),1);
-
-    pathView->setDelegate(&delegateComponent);
-    QCOMPARE(delegateSpy.count(),1);
-    delete canvas;
-}
-
-void tst_QSGPathView::modelChanges()
-{
-    QSGView *canvas = createView();
-    QVERIFY(canvas);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml")));
-
-    QSGPathView *pathView = canvas->rootObject()->findChild<QSGPathView*>("pathView");
-    QVERIFY(pathView);
-
-    QDeclarativeListModel *alternateModel = canvas->rootObject()->findChild<QDeclarativeListModel*>("alternateModel");
-    QVERIFY(alternateModel);
-    QVariant modelVariant = QVariant::fromValue<QObject *>(alternateModel);
-    QSignalSpy modelSpy(pathView, SIGNAL(modelChanged()));
-
-    pathView->setModel(modelVariant);
-    QCOMPARE(pathView->model(), modelVariant);
-    QCOMPARE(modelSpy.count(),1);
-
-    pathView->setModel(modelVariant);
-    QCOMPARE(modelSpy.count(),1);
-
-    pathView->setModel(QVariant());
-    QCOMPARE(modelSpy.count(),2);
-
-    delete canvas;
-}
-
-void tst_QSGPathView::pathUpdateOnStartChanged()
-{
-    QSGView *canvas = createView();
-    QVERIFY(canvas);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathUpdateOnStartChanged.qml")));
-
-    QSGPathView *pathView = canvas->rootObject()->findChild<QSGPathView*>("pathView");
-    QVERIFY(pathView);
-
-    QDeclarativePath *path = canvas->rootObject()->findChild<QDeclarativePath*>("path");
-    QVERIFY(path);
-    QCOMPARE(path->startX(), 400.0);
-    QCOMPARE(path->startY(), 300.0);
-
-    QSGItem *item = findItem<QSGItem>(pathView, "wrapper", 0);
-    QVERIFY(item);
-    QCOMPARE(item->x(), path->startX() - item->width() / 2.0);
-    QCOMPARE(item->y(), path->startY() - item->height() / 2.0);
-
-    delete canvas;
-}
-
-void tst_QSGPathView::package()
-{
-    QSGView *canvas = createView();
-    QVERIFY(canvas);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview_package.qml")));
-
-    QSGPathView *pathView = canvas->rootObject()->findChild<QSGPathView*>("photoPathView");
-    QVERIFY(pathView);
-
-    QSGItem *item = findItem<QSGItem>(pathView, "pathItem");
-    QVERIFY(item);
-    QVERIFY(item->scale() != 1.0);
-
-    delete canvas;
-}
-
-//QTBUG-13017
-void tst_QSGPathView::emptyModel()
-{
-    QSGView *canvas = createView();
-
-    QStringListModel model;
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("emptyModel", &model);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("emptymodel.qml")));
-    qApp->processEvents();
-
-    QSGPathView *pathview = qobject_cast<QSGPathView*>(canvas->rootObject());
-    QVERIFY(pathview != 0);
-
-    QCOMPARE(pathview->offset(), qreal(0.0));
-
-    delete canvas;
-}
-
-void tst_QSGPathView::closed()
-{
-    QDeclarativeEngine engine;
-
-    {
-        QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("openPath.qml")));
-        QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create());
-        QVERIFY(obj);
-        QCOMPARE(obj->isClosed(), false);
-        delete obj;
-    }
-
-    {
-        QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("closedPath.qml")));
-        QDeclarativePath *obj = qobject_cast<QDeclarativePath*>(c.create());
-        QVERIFY(obj);
-        QCOMPARE(obj->isClosed(), true);
-        delete obj;
-    }
-}
-
-// QTBUG-14239
-void tst_QSGPathView::pathUpdate()
-{
-    QSGView *canvas = createView();
-    QVERIFY(canvas);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathUpdate.qml")));
-
-    QSGPathView *pathView = canvas->rootObject()->findChild<QSGPathView*>("pathView");
-    QVERIFY(pathView);
-
-    QSGItem *item = findItem<QSGItem>(pathView, "wrapper", 0);
-    QVERIFY(item);
-    QCOMPARE(item->x(), 150.0);
-
-    delete canvas;
-}
-
-void tst_QSGPathView::visualDataModel()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("vdm.qml")));
-
-    QSGPathView *obj = qobject_cast<QSGPathView*>(c.create());
-    QVERIFY(obj != 0);
-
-    QCOMPARE(obj->count(), 3);
-
-    delete obj;
-}
-
-void tst_QSGPathView::undefinedPath()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("undefinedpath.qml")));
-
-    QSGPathView *obj = qobject_cast<QSGPathView*>(c.create());
-    QVERIFY(obj != 0);
-
-    QCOMPARE(obj->count(), 3);
-
-    delete obj;
-}
-
-void tst_QSGPathView::mouseDrag()
-{
-    QSGView *canvas = createView();
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragpath.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QTest::qWaitForWindowShown(canvas);
-    QTRY_COMPARE(canvas, qGuiApp->focusWindow());
-
-    QSGPathView *pathview = qobject_cast<QSGPathView*>(canvas->rootObject());
-    QVERIFY(pathview != 0);
-
-    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);
-        QApplication::sendEvent(canvas, &mv);
-    }
-    {
-        QMouseEvent mv(QEvent::MouseMove, QPoint(90,100), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
-        QApplication::sendEvent(canvas, &mv);
-    }
-
-    QVERIFY(pathview->currentIndex() != current);
-
-    QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(40,100));
-
-    delete canvas;
-}
-
-void tst_QSGPathView::treeModel()
-{
-    QSGView *canvas = createView();
-    canvas->show();
-
-    QStandardItemModel model;
-    initStandardTreeModel(&model);
-    canvas->engine()->rootContext()->setContextProperty("myModel", &model);
-
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("treemodel.qml")));
-
-    QSGPathView *pathview = qobject_cast<QSGPathView*>(canvas->rootObject());
-    QVERIFY(pathview != 0);
-    QCOMPARE(pathview->count(), 3);
-
-    QSGText *item = findItem<QSGText>(pathview, "wrapper", 0);
-    QVERIFY(item);
-    QCOMPARE(item->text(), QLatin1String("Row 1 Item"));
-
-    QVERIFY(QMetaObject::invokeMethod(pathview, "setRoot", Q_ARG(QVariant, 1)));
-    QCOMPARE(pathview->count(), 1);
-
-    QTRY_VERIFY(item = findItem<QSGText>(pathview, "wrapper", 0));
-    QTRY_COMPARE(item->text(), QLatin1String("Row 2 Child Item"));
-
-    delete canvas;
-}
-
-void tst_QSGPathView::changePreferredHighlight()
-{
-    QSGView *canvas = createView();
-    canvas->setGeometry(0,0,400,200);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragpath.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QTest::qWaitForWindowShown(canvas);
-    QTRY_COMPARE(canvas, qGuiApp->focusWindow());
-
-    QSGPathView *pathview = qobject_cast<QSGPathView*>(canvas->rootObject());
-    QVERIFY(pathview != 0);
-
-    int current = pathview->currentIndex();
-    QCOMPARE(current, 0);
-
-    QSGRectangle *firstItem = findItem<QSGRectangle>(pathview, "wrapper", 0);
-    QVERIFY(firstItem);
-    QDeclarativePath *path = qobject_cast<QDeclarativePath*>(pathview->path());
-    QVERIFY(path);
-    QPointF start = path->pointAt(0.5);
-    start.setX(qRound(start.x()));
-    start.setY(qRound(start.y()));
-    QPointF offset;//Center of item is at point, but pos is from corner
-    offset.setX(firstItem->width()/2);
-    offset.setY(firstItem->height()/2);
-    QTRY_COMPARE(firstItem->pos() + offset, start);
-
-    pathview->setPreferredHighlightBegin(0.8);
-    pathview->setPreferredHighlightEnd(0.8);
-    start = path->pointAt(0.8);
-    start.setX(qRound(start.x()));
-    start.setY(qRound(start.y()));
-    QTRY_COMPARE(firstItem->pos() + offset, start);
-    QCOMPARE(pathview->currentIndex(), 0);
-
-    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);
-    canvas->setGeometry(0,0,240,320);
-
-    return canvas;
-}
-
-/*
-   Find an item with the specified objectName.  If index is supplied then the
-   item must also evaluate the {index} expression equal to index
- */
-template<typename T>
-T *tst_QSGPathView::findItem(QSGItem *parent, const QString &objectName, int index)
-{
-    const QMetaObject &mo = T::staticMetaObject;
-    //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)
-            continue;
-        //qDebug() << "try" << item;
-        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
-            if (index != -1) {
-                QDeclarativeExpression e(qmlContext(item), item, "index");
-                if (e.evaluate().toInt() == index)
-                    return static_cast<T*>(item);
-            } else {
-                return static_cast<T*>(item);
-            }
-        }
-        item = findItem<T>(item, objectName, index);
-        if (item)
-            return static_cast<T*>(item);
-    }
-
-    return 0;
-}
-
-template<typename T>
-QList<T*> tst_QSGPathView::findItems(QSGItem *parent, const QString &objectName)
-{
-    QList<T*> items;
-    const QMetaObject &mo = T::staticMetaObject;
-    //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)
-            continue;
-        //qDebug() << "try" << item;
-        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName))
-            items.append(static_cast<T*>(item));
-        items += findItems<T>(item, objectName);
-    }
-
-    return items;
-}
-
-void tst_QSGPathView::missingPercent()
-{
-    QDeclarativeEngine engine;
-    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));
-    delete obj;
-}
-
-
-QTEST_MAIN(tst_QSGPathView)
-
-#include "tst_qsgpathview.moc"
diff --git a/tests/auto/declarative/qsgpincharea/qsgpincharea.pro b/tests/auto/declarative/qsgpincharea/qsgpincharea.pro
deleted file mode 100644 (file)
index 628bbc7..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsgpincharea
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_qsgpincharea.cpp
-
-testDataFiles.files = data
-testDataFiles.path = .
-DEPLOYMENT += testDataFiles
-
-CONFIG += parallel_test
-
-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
deleted file mode 100644 (file)
index 24cdf90..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-/****************************************************************************
-**
-** 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 <private/qsgpincharea_p.h>
-#include <private/qsgrectangle_p.h>
-#include <QtDeclarative/qsgview.h>
-#include <QtDeclarative/qdeclarativecontext.h>
-#include "../shared/util.h"
-
-class tst_QSGPinchArea: public QObject
-{
-    Q_OBJECT
-private slots:
-    void initTestCase();
-    void cleanupTestCase();
-    void pinchProperties();
-    void scale();
-    void pan();
-    void retouch();
-
-private:
-    QSGView *createView();
-};
-void tst_QSGPinchArea::initTestCase()
-{
-}
-
-void tst_QSGPinchArea::cleanupTestCase()
-{
-
-}
-void tst_QSGPinchArea::pinchProperties()
-{
-    QSGView *canvas = createView();
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QVERIFY(canvas->rootObject() != 0);
-
-    QSGPinchArea *pinchArea = canvas->rootObject()->findChild<QSGPinchArea*>("pincharea");
-    QSGPinch *pinch = pinchArea->pinch();
-    QVERIFY(pinchArea != 0);
-    QVERIFY(pinch != 0);
-
-    // target
-    QSGItem *blackRect = canvas->rootObject()->findChild<QSGItem*>("blackrect");
-    QVERIFY(blackRect != 0);
-    QVERIFY(blackRect == pinch->target());
-    QSGItem *rootItem = qobject_cast<QSGItem*>(canvas->rootObject());
-    QVERIFY(rootItem != 0);
-    QSignalSpy targetSpy(pinch, SIGNAL(targetChanged()));
-    pinch->setTarget(rootItem);
-    QCOMPARE(targetSpy.count(),1);
-    pinch->setTarget(rootItem);
-    QCOMPARE(targetSpy.count(),1);
-
-    // axis
-    QCOMPARE(pinch->axis(), QSGPinch::XandYAxis);
-    QSignalSpy axisSpy(pinch, SIGNAL(dragAxisChanged()));
-    pinch->setAxis(QSGPinch::XAxis);
-    QCOMPARE(pinch->axis(), QSGPinch::XAxis);
-    QCOMPARE(axisSpy.count(),1);
-    pinch->setAxis(QSGPinch::XAxis);
-    QCOMPARE(axisSpy.count(),1);
-
-    // minimum and maximum drag properties
-    QSignalSpy xminSpy(pinch, SIGNAL(minimumXChanged()));
-    QSignalSpy xmaxSpy(pinch, SIGNAL(maximumXChanged()));
-    QSignalSpy yminSpy(pinch, SIGNAL(minimumYChanged()));
-    QSignalSpy ymaxSpy(pinch, SIGNAL(maximumYChanged()));
-
-    QCOMPARE(pinch->xmin(), 0.0);
-    QCOMPARE(pinch->xmax(), rootItem->width()-blackRect->width());
-    QCOMPARE(pinch->ymin(), 0.0);
-    QCOMPARE(pinch->ymax(), rootItem->height()-blackRect->height());
-
-    pinch->setXmin(10);
-    pinch->setXmax(10);
-    pinch->setYmin(10);
-    pinch->setYmax(10);
-
-    QCOMPARE(pinch->xmin(), 10.0);
-    QCOMPARE(pinch->xmax(), 10.0);
-    QCOMPARE(pinch->ymin(), 10.0);
-    QCOMPARE(pinch->ymax(), 10.0);
-
-    QCOMPARE(xminSpy.count(),1);
-    QCOMPARE(xmaxSpy.count(),1);
-    QCOMPARE(yminSpy.count(),1);
-    QCOMPARE(ymaxSpy.count(),1);
-
-    pinch->setXmin(10);
-    pinch->setXmax(10);
-    pinch->setYmin(10);
-    pinch->setYmax(10);
-
-    QCOMPARE(xminSpy.count(),1);
-    QCOMPARE(xmaxSpy.count(),1);
-    QCOMPARE(yminSpy.count(),1);
-    QCOMPARE(ymaxSpy.count(),1);
-
-    // minimum and maximum scale properties
-    QSignalSpy scaleMinSpy(pinch, SIGNAL(minimumScaleChanged()));
-    QSignalSpy scaleMaxSpy(pinch, SIGNAL(maximumScaleChanged()));
-
-    QCOMPARE(pinch->minimumScale(), 1.0);
-    QCOMPARE(pinch->maximumScale(), 2.0);
-
-    pinch->setMinimumScale(0.5);
-    pinch->setMaximumScale(1.5);
-
-    QCOMPARE(pinch->minimumScale(), 0.5);
-    QCOMPARE(pinch->maximumScale(), 1.5);
-
-    QCOMPARE(scaleMinSpy.count(),1);
-    QCOMPARE(scaleMaxSpy.count(),1);
-
-    pinch->setMinimumScale(0.5);
-    pinch->setMaximumScale(1.5);
-
-    QCOMPARE(scaleMinSpy.count(),1);
-    QCOMPARE(scaleMaxSpy.count(),1);
-
-    // minimum and maximum rotation properties
-    QSignalSpy rotMinSpy(pinch, SIGNAL(minimumRotationChanged()));
-    QSignalSpy rotMaxSpy(pinch, SIGNAL(maximumRotationChanged()));
-
-    QCOMPARE(pinch->minimumRotation(), 0.0);
-    QCOMPARE(pinch->maximumRotation(), 90.0);
-
-    pinch->setMinimumRotation(-90.0);
-    pinch->setMaximumRotation(45.0);
-
-    QCOMPARE(pinch->minimumRotation(), -90.0);
-    QCOMPARE(pinch->maximumRotation(), 45.0);
-
-    QCOMPARE(rotMinSpy.count(),1);
-    QCOMPARE(rotMaxSpy.count(),1);
-
-    pinch->setMinimumRotation(-90.0);
-    pinch->setMaximumRotation(45.0);
-
-    QCOMPARE(rotMinSpy.count(),1);
-    QCOMPARE(rotMaxSpy.count(),1);
-
-    delete canvas;
-}
-
-QTouchEvent::TouchPoint makeTouchPoint(int id, QPoint p, QSGView *v, QSGItem *i)
-{
-    QTouchEvent::TouchPoint touchPoint(id);
-    touchPoint.setPos(i->mapFromScene(p));
-    touchPoint.setScreenPos(v->mapToGlobal(p));
-    touchPoint.setScenePos(p);
-    return touchPoint;
-}
-
-void tst_QSGPinchArea::scale()
-{
-    QSGView *canvas = createView();
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QTest::qWaitForWindowShown(canvas);
-    QVERIFY(canvas->rootObject() != 0);
-    qApp->processEvents();
-
-    QSGPinchArea *pinchArea = canvas->rootObject()->findChild<QSGPinchArea*>("pincharea");
-    QSGPinch *pinch = pinchArea->pinch();
-    QVERIFY(pinchArea != 0);
-    QVERIFY(pinch != 0);
-
-    QSGItem *root = qobject_cast<QSGItem*>(canvas->rootObject());
-    QVERIFY(root != 0);
-
-    // target
-    QSGItem *blackRect = canvas->rootObject()->findChild<QSGItem*>("blackrect");
-    QVERIFY(blackRect != 0);
-
-    QPoint p1(80, 80);
-    QPoint p2(100, 100);
-
-    QTest::touchEvent(canvas).press(0, p1, canvas);
-    QTest::touchEvent(canvas).stationary(0).press(1, p2, canvas);
-    p1 -= QPoint(10,10);
-    p2 += QPoint(10,10);
-    QTest::touchEvent(canvas).move(0, p1,canvas).move(1, p2,canvas);
-
-    QCOMPARE(root->property("scale").toReal(), 1.0);
-
-    p1 -= QPoint(10,10);
-    p2 += QPoint(10,10);
-    QTest::touchEvent(canvas).move(0, p1,canvas).move(1, p2,canvas);
-
-    QCOMPARE(root->property("scale").toReal(), 1.5);
-    QCOMPARE(root->property("center").toPointF(), QPointF(40, 40)); // blackrect is at 50,50
-    QCOMPARE(blackRect->scale(), 1.5);
-
-    // scale beyond bound
-    p1 -= QPoint(50,50);
-    p2 += QPoint(50,50);
-    QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas);
-
-    QCOMPARE(blackRect->scale(), 2.0);
-
-    QTest::touchEvent(canvas).release(0, p1, canvas).release(1, p2, canvas);
-
-    delete canvas;
-}
-
-void tst_QSGPinchArea::pan()
-{
-    QSGView *canvas = createView();
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QTest::qWaitForWindowShown(canvas);
-    QVERIFY(canvas->rootObject() != 0);
-    qApp->processEvents();
-
-    QSGPinchArea *pinchArea = canvas->rootObject()->findChild<QSGPinchArea*>("pincharea");
-    QSGPinch *pinch = pinchArea->pinch();
-    QVERIFY(pinchArea != 0);
-    QVERIFY(pinch != 0);
-
-    QSGItem *root = qobject_cast<QSGItem*>(canvas->rootObject());
-    QVERIFY(root != 0);
-
-    // target
-    QSGItem *blackRect = canvas->rootObject()->findChild<QSGItem*>("blackrect");
-    QVERIFY(blackRect != 0);
-
-    QPoint p1(80, 80);
-    QPoint p2(100, 100);
-
-    QTest::touchEvent(canvas).press(0, p1, canvas);
-    QTest::touchEvent(canvas).stationary(0).press(1, p2, canvas);
-    p1 += QPoint(10,10);
-    p2 += QPoint(10,10);
-    QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas);
-
-    QCOMPARE(root->property("scale").toReal(), 1.0);
-
-    p1 += QPoint(10,10);
-    p2 += QPoint(10,10);
-    QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas);
-
-    QCOMPARE(root->property("center").toPointF(), QPointF(60, 60)); // blackrect is at 50,50
-
-    QCOMPARE(blackRect->x(), 60.0);
-    QCOMPARE(blackRect->y(), 60.0);
-
-    // pan x beyond bound
-    p1 += QPoint(100,100);
-    p2 += QPoint(100,100);
-    QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas);
-
-    QCOMPARE(blackRect->x(), 140.0);
-    QCOMPARE(blackRect->y(), 160.0);
-
-    QTest::touchEvent(canvas).release(0, p1, canvas).release(1, p2, canvas);
-
-    delete canvas;
-}
-
-// test pinch, release one point, touch again to continue pinch
-void tst_QSGPinchArea::retouch()
-{
-    QSGView *canvas = createView();
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml")));
-    canvas->show();
-    canvas->requestActivateWindow();
-    QTest::qWaitForWindowShown(canvas);
-    QVERIFY(canvas->rootObject() != 0);
-    qApp->processEvents();
-
-    QSGPinchArea *pinchArea = canvas->rootObject()->findChild<QSGPinchArea*>("pincharea");
-    QSGPinch *pinch = pinchArea->pinch();
-    QVERIFY(pinchArea != 0);
-    QVERIFY(pinch != 0);
-
-    QSGItem *root = qobject_cast<QSGItem*>(canvas->rootObject());
-    QVERIFY(root != 0);
-
-    QSignalSpy startedSpy(pinchArea, SIGNAL(pinchStarted(QSGPinchEvent *)));
-    QSignalSpy finishedSpy(pinchArea, SIGNAL(pinchFinished(QSGPinchEvent *)));
-
-    // target
-    QSGItem *blackRect = canvas->rootObject()->findChild<QSGItem*>("blackrect");
-    QVERIFY(blackRect != 0);
-
-    QPoint p1(80, 80);
-    QPoint p2(100, 100);
-
-    QTest::touchEvent(canvas).press(0, p1, canvas);
-    QTest::touchEvent(canvas).stationary(0).press(1, p2, canvas);
-    p1 -= QPoint(10,10);
-    p2 += QPoint(10,10);
-    QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas);
-
-    QCOMPARE(root->property("scale").toReal(), 1.0);
-
-    p1 -= QPoint(10,10);
-    p2 += QPoint(10,10);
-    QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas);
-
-    QCOMPARE(startedSpy.count(), 1);
-
-    QCOMPARE(root->property("scale").toReal(), 1.5);
-    QCOMPARE(root->property("center").toPointF(), QPointF(40, 40)); // blackrect is at 50,50
-    QCOMPARE(blackRect->scale(), 1.5);
-
-    QCOMPARE(canvas->rootObject()->property("pointCount").toInt(), 2);
-
-    QCOMPARE(startedSpy.count(), 1);
-    QCOMPARE(finishedSpy.count(), 0);
-
-    QTest::touchEvent(canvas).stationary(0).release(1, p2, canvas);
-
-    QCOMPARE(startedSpy.count(), 1);
-    QCOMPARE(finishedSpy.count(), 0);
-
-    QCOMPARE(canvas->rootObject()->property("pointCount").toInt(), 1);
-
-    QTest::touchEvent(canvas).stationary(0).press(1, p2, canvas);
-    p1 -= QPoint(10,10);
-    p2 += QPoint(10,10);
-    QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas);
-
-    // Lifting and retouching results in onPinchStarted being called again
-    QCOMPARE(startedSpy.count(), 2);
-    QCOMPARE(finishedSpy.count(), 0);
-
-    QCOMPARE(canvas->rootObject()->property("pointCount").toInt(), 2);
-
-    QTest::touchEvent(canvas).release(0, p1, canvas).release(1, p2, canvas);
-
-    QCOMPARE(startedSpy.count(), 2);
-    QCOMPARE(finishedSpy.count(), 1);
-
-    delete canvas;
-}
-
-
-QSGView *tst_QSGPinchArea::createView()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setGeometry(0,0,240,320);
-
-    return canvas;
-}
-
-QTEST_MAIN(tst_QSGPinchArea)
-
-#include "tst_qsgpincharea.moc"
diff --git a/tests/auto/declarative/qsgpositioners/qsgpositioners.pro b/tests/auto/declarative/qsgpositioners/qsgpositioners.pro
deleted file mode 100644 (file)
index d0ecbd6..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsgpositioners
-SOURCES += tst_qsgpositioners.cpp
-macx:CONFIG -= app_bundle
-
-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/qsgpositioners/tst_qsgpositioners.cpp b/tests/auto/declarative/qsgpositioners/tst_qsgpositioners.cpp
deleted file mode 100644 (file)
index 22a3386..0000000
+++ /dev/null
@@ -1,1476 +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 <QtTest/QtTest>
-#include <private/qlistmodelinterface_p.h>
-#include <qsgview.h>
-#include <qdeclarativeengine.h>
-#include <private/qsgrectangle_p.h>
-#include <private/qsgpositioners_p.h>
-#include <private/qdeclarativetransition_p.h>
-#include <private/qsgitem_p.h>
-#include <qdeclarativeexpression.h>
-#include "../shared/util.h"
-
-class tst_qsgpositioners : public QObject
-{
-    Q_OBJECT
-public:
-    tst_qsgpositioners();
-
-private slots:
-    void test_horizontal();
-    void test_horizontal_rtl();
-    void test_horizontal_spacing();
-    void test_horizontal_spacing_rightToLeft();
-    void test_horizontal_animated();
-    void test_horizontal_animated_rightToLeft();
-    void test_horizontal_animated_disabled();
-    void test_vertical();
-    void test_vertical_spacing();
-    void test_vertical_animated();
-    void test_grid();
-    void test_grid_topToBottom();
-    void test_grid_rightToLeft();
-    void test_grid_spacing();
-    void test_grid_row_column_spacing();
-    void test_grid_animated();
-    void test_grid_animated_rightToLeft();
-    void test_grid_zero_columns();
-    void test_propertychanges();
-    void test_repeater();
-    void test_flow();
-    void test_flow_rightToLeft();
-    void test_flow_topToBottom();
-    void test_flow_resize();
-    void test_flow_resize_rightToLeft();
-    void test_flow_implicit_resize();
-    void test_conflictinganchors();
-    void test_mirroring();
-    void test_allInvisible();
-    void test_attachedproperties();
-    void test_attachedproperties_data();
-    void test_attachedproperties_dynamic();
-
-private:
-    QSGView *createView(const QString &filename, bool wait=true);
-};
-
-tst_qsgpositioners::tst_qsgpositioners()
-{
-}
-
-void tst_qsgpositioners::test_horizontal()
-{
-    QSGView *canvas = createView(TESTDATA("horizontal.qml"));
-
-    canvas->rootObject()->setProperty("testRightToLeft", false);
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-
-    QCOMPARE(one->x(), 0.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 50.0);
-    QCOMPARE(two->y(), 0.0);
-    QCOMPARE(three->x(), 70.0);
-    QCOMPARE(three->y(), 0.0);
-
-    QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
-    QCOMPARE(row->width(), 110.0);
-    QCOMPARE(row->height(), 50.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_horizontal_rtl()
-{
-    QSGView *canvas = createView(TESTDATA("horizontal.qml"));
-
-    canvas->rootObject()->setProperty("testRightToLeft", true);
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-
-    QCOMPARE(one->x(), 60.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 40.0);
-    QCOMPARE(two->y(), 0.0);
-    QCOMPARE(three->x(), 0.0);
-    QCOMPARE(three->y(), 0.0);
-
-    QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
-    QCOMPARE(row->width(), 110.0);
-    QCOMPARE(row->height(), 50.0);
-
-    // Change the width of the row and check that items stay to the right
-    row->setWidth(200);
-    QTRY_COMPARE(one->x(), 150.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 130.0);
-    QCOMPARE(two->y(), 0.0);
-    QCOMPARE(three->x(), 90.0);
-    QCOMPARE(three->y(), 0.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_horizontal_spacing()
-{
-    QSGView *canvas = createView(TESTDATA("horizontal-spacing.qml"));
-
-    canvas->rootObject()->setProperty("testRightToLeft", false);
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-
-    QCOMPARE(one->x(), 0.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 60.0);
-    QCOMPARE(two->y(), 0.0);
-    QCOMPARE(three->x(), 90.0);
-    QCOMPARE(three->y(), 0.0);
-
-    QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
-    QCOMPARE(row->width(), 130.0);
-    QCOMPARE(row->height(), 50.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_horizontal_spacing_rightToLeft()
-{
-    QSGView *canvas = createView(TESTDATA("horizontal-spacing.qml"));
-
-    canvas->rootObject()->setProperty("testRightToLeft", true);
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-
-    QCOMPARE(one->x(), 80.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 50.0);
-    QCOMPARE(two->y(), 0.0);
-    QCOMPARE(three->x(), 00.0);
-    QCOMPARE(three->y(), 0.0);
-
-    QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
-    QCOMPARE(row->width(), 130.0);
-    QCOMPARE(row->height(), 50.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_horizontal_animated()
-{
-    QSGView *canvas = createView(TESTDATA("horizontal-animated.qml"), false);
-
-    canvas->rootObject()->setProperty("testRightToLeft", false);
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-
-    //Note that they animate in
-    QCOMPARE(one->x(), -100.0);
-    QCOMPARE(two->x(), -100.0);
-    QCOMPARE(three->x(), -100.0);
-
-    QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
-
-    QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
-    QVERIFY(row);
-    QCOMPARE(row->width(), 100.0);
-    QCOMPARE(row->height(), 50.0);
-
-    //QTRY_COMPARE used instead of waiting for the expected time of animation completion
-    //Note that this means the duration of the animation is NOT tested
-
-    QTRY_COMPARE(one->x(), 0.0);
-    QTRY_COMPARE(one->y(), 0.0);
-    QTRY_COMPARE(two->isVisible(), false);
-    QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet
-    QTRY_COMPARE(two->y(), 0.0);
-    QTRY_COMPARE(three->x(), 50.0);
-    QTRY_COMPARE(three->y(), 0.0);
-
-    //Add 'two'
-    two->setVisible(true);
-    QTRY_COMPARE(two->isVisible(), true);
-    QTRY_COMPARE(row->width(), 150.0);
-    QTRY_COMPARE(row->height(), 50.0);
-
-    QTest::qWait(0);//Let the animation start
-    QCOMPARE(two->x(), -100.0);
-    QCOMPARE(three->x(), 50.0);
-
-    QTRY_COMPARE(two->x(), 50.0);
-    QTRY_COMPARE(three->x(), 100.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_horizontal_animated_rightToLeft()
-{
-    QSGView *canvas = createView(TESTDATA("horizontal-animated.qml"), false);
-
-    canvas->rootObject()->setProperty("testRightToLeft", true);
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-
-    //Note that they animate in
-    QCOMPARE(one->x(), -100.0);
-    QCOMPARE(two->x(), -100.0);
-    QCOMPARE(three->x(), -100.0);
-
-    QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
-
-    QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
-    QVERIFY(row);
-    QCOMPARE(row->width(), 100.0);
-    QCOMPARE(row->height(), 50.0);
-
-    //QTRY_COMPARE used instead of waiting for the expected time of animation completion
-    //Note that this means the duration of the animation is NOT tested
-
-    QTRY_COMPARE(one->x(), 50.0);
-    QTRY_COMPARE(one->y(), 0.0);
-    QTRY_COMPARE(two->isVisible(), false);
-    QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet
-    QTRY_COMPARE(two->y(), 0.0);
-    QTRY_COMPARE(three->x(), 0.0);
-    QTRY_COMPARE(three->y(), 0.0);
-
-    //Add 'two'
-    two->setVisible(true);
-    QTRY_COMPARE(two->isVisible(), true);
-
-    // New size should propagate after visible change
-    QTRY_COMPARE(row->width(), 150.0);
-    QTRY_COMPARE(row->height(), 50.0);
-
-    QTest::qWait(0);//Let the animation start
-    QCOMPARE(one->x(), 50.0);
-    QCOMPARE(two->x(), -100.0);
-
-    QTRY_COMPARE(one->x(), 100.0);
-    QTRY_COMPARE(two->x(), 50.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_horizontal_animated_disabled()
-{
-    QSGView *canvas = createView(TESTDATA("horizontal-animated-disabled.qml"));
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-
-    QSGItem *row = canvas->rootObject()->findChild<QSGItem*>("row");
-    QVERIFY(row);
-
-    qApp->processEvents();
-
-    QCOMPARE(one->x(), 0.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->isVisible(), false);
-    QCOMPARE(two->x(), -100.0);//Not 'in' yet
-    QCOMPARE(two->y(), 0.0);
-    QCOMPARE(three->x(), 50.0);
-    QCOMPARE(three->y(), 0.0);
-
-    //Add 'two'
-    two->setVisible(true);
-    QCOMPARE(two->isVisible(), true);
-    qApp->processEvents();
-    QCOMPARE(row->width(), 150.0);
-    QCOMPARE(row->height(), 50.0);
-
-    qApp->processEvents();
-    QCOMPARE(two->x(), 50.0);
-    QCOMPARE(three->x(), 100.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_vertical()
-{
-    QSGView *canvas = createView(TESTDATA("vertical.qml"));
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-
-    QCOMPARE(one->x(), 0.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 0.0);
-    QCOMPARE(two->y(), 50.0);
-    QCOMPARE(three->x(), 0.0);
-    QCOMPARE(three->y(), 60.0);
-
-    QSGItem *column = canvas->rootObject()->findChild<QSGItem*>("column");
-    QVERIFY(column);
-    QCOMPARE(column->height(), 80.0);
-    QCOMPARE(column->width(), 50.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_vertical_spacing()
-{
-    QSGView *canvas = createView(TESTDATA("vertical-spacing.qml"));
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-
-    QCOMPARE(one->x(), 0.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 0.0);
-    QCOMPARE(two->y(), 60.0);
-    QCOMPARE(three->x(), 0.0);
-    QCOMPARE(three->y(), 80.0);
-
-    QSGItem *column = canvas->rootObject()->findChild<QSGItem*>("column");
-    QCOMPARE(column->height(), 100.0);
-    QCOMPARE(column->width(), 50.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_vertical_animated()
-{
-    QSGView *canvas = createView(TESTDATA("vertical-animated.qml"), false);
-
-    //Note that they animate in
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-    QCOMPARE(one->y(), -100.0);
-
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-    QCOMPARE(two->y(), -100.0);
-
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-    QCOMPARE(three->y(), -100.0);
-
-    QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
-
-    QSGItem *column = canvas->rootObject()->findChild<QSGItem*>("column");
-    QVERIFY(column);
-    QCOMPARE(column->height(), 100.0);
-    QCOMPARE(column->width(), 50.0);
-
-    //QTRY_COMPARE used instead of waiting for the expected time of animation completion
-    //Note that this means the duration of the animation is NOT tested
-
-    QTRY_COMPARE(one->y(), 0.0);
-    QTRY_COMPARE(one->x(), 0.0);
-    QTRY_COMPARE(two->isVisible(), false);
-    QTRY_COMPARE(two->y(), -100.0);//Not 'in' yet
-    QTRY_COMPARE(two->x(), 0.0);
-    QTRY_COMPARE(three->y(), 50.0);
-    QTRY_COMPARE(three->x(), 0.0);
-
-    //Add 'two'
-    two->setVisible(true);
-    QTRY_COMPARE(two->isVisible(), true);
-    QTRY_COMPARE(column->height(), 150.0);
-    QTRY_COMPARE(column->width(), 50.0);
-    QTest::qWait(0);//Let the animation start
-    QCOMPARE(two->y(), -100.0);
-    QCOMPARE(three->y(), 50.0);
-
-    QTRY_COMPARE(two->y(), 50.0);
-    QTRY_COMPARE(three->y(), 100.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_grid()
-{
-    QSGView *canvas = createView(TESTDATA("gridtest.qml"));
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-    QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
-    QVERIFY(four != 0);
-    QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
-    QVERIFY(five != 0);
-
-    QCOMPARE(one->x(), 0.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 50.0);
-    QCOMPARE(two->y(), 0.0);
-    QCOMPARE(three->x(), 70.0);
-    QCOMPARE(three->y(), 0.0);
-    QCOMPARE(four->x(), 0.0);
-    QCOMPARE(four->y(), 50.0);
-    QCOMPARE(five->x(), 50.0);
-    QCOMPARE(five->y(), 50.0);
-
-    QSGGrid *grid = canvas->rootObject()->findChild<QSGGrid*>("grid");
-    QCOMPARE(grid->flow(), QSGGrid::LeftToRight);
-    QCOMPARE(grid->width(), 100.0);
-    QCOMPARE(grid->height(), 100.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_grid_topToBottom()
-{
-    QSGView *canvas = createView(TESTDATA("grid-toptobottom.qml"));
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-    QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
-    QVERIFY(four != 0);
-    QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
-    QVERIFY(five != 0);
-
-    QCOMPARE(one->x(), 0.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 0.0);
-    QCOMPARE(two->y(), 50.0);
-    QCOMPARE(three->x(), 0.0);
-    QCOMPARE(three->y(), 100.0);
-    QCOMPARE(four->x(), 50.0);
-    QCOMPARE(four->y(), 0.0);
-    QCOMPARE(five->x(), 50.0);
-    QCOMPARE(five->y(), 50.0);
-
-    QSGGrid *grid = canvas->rootObject()->findChild<QSGGrid*>("grid");
-    QCOMPARE(grid->flow(), QSGGrid::TopToBottom);
-    QCOMPARE(grid->width(), 100.0);
-    QCOMPARE(grid->height(), 120.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_grid_rightToLeft()
-{
-    QSGView *canvas = createView(TESTDATA("gridtest.qml"));
-
-    canvas->rootObject()->setProperty("testRightToLeft", true);
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-    QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
-    QVERIFY(four != 0);
-    QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
-    QVERIFY(five != 0);
-
-    QCOMPARE(one->x(), 50.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 30.0);
-    QCOMPARE(two->y(), 0.0);
-    QCOMPARE(three->x(), 0.0);
-    QCOMPARE(three->y(), 0.0);
-    QCOMPARE(four->x(), 50.0);
-    QCOMPARE(four->y(), 50.0);
-    QCOMPARE(five->x(), 40.0);
-    QCOMPARE(five->y(), 50.0);
-
-    QSGGrid *grid = canvas->rootObject()->findChild<QSGGrid*>("grid");
-    QCOMPARE(grid->layoutDirection(), Qt::RightToLeft);
-    QCOMPARE(grid->width(), 100.0);
-    QCOMPARE(grid->height(), 100.0);
-
-    // Change the width of the grid and check that items stay to the right
-    grid->setWidth(200);
-    QTRY_COMPARE(one->x(), 150.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 130.0);
-    QCOMPARE(two->y(), 0.0);
-    QCOMPARE(three->x(), 100.0);
-    QCOMPARE(three->y(), 0.0);
-    QCOMPARE(four->x(), 150.0);
-    QCOMPARE(four->y(), 50.0);
-    QCOMPARE(five->x(), 140.0);
-    QCOMPARE(five->y(), 50.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_grid_spacing()
-{
-    QSGView *canvas = createView(TESTDATA("grid-spacing.qml"));
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-    QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
-    QVERIFY(four != 0);
-    QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
-    QVERIFY(five != 0);
-
-    QCOMPARE(one->x(), 0.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 54.0);
-    QCOMPARE(two->y(), 0.0);
-    QCOMPARE(three->x(), 78.0);
-    QCOMPARE(three->y(), 0.0);
-    QCOMPARE(four->x(), 0.0);
-    QCOMPARE(four->y(), 54.0);
-    QCOMPARE(five->x(), 54.0);
-    QCOMPARE(five->y(), 54.0);
-
-    QSGItem *grid = canvas->rootObject()->findChild<QSGItem*>("grid");
-    QCOMPARE(grid->width(), 128.0);
-    QCOMPARE(grid->height(), 104.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_grid_row_column_spacing()
-{
-    QSGView *canvas = createView(TESTDATA("grid-row-column-spacing.qml"));
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-    QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
-    QVERIFY(four != 0);
-    QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
-    QVERIFY(five != 0);
-
-    QCOMPARE(one->x(), 0.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 61.0);
-    QCOMPARE(two->y(), 0.0);
-    QCOMPARE(three->x(), 92.0);
-    QCOMPARE(three->y(), 0.0);
-    QCOMPARE(four->x(), 0.0);
-    QCOMPARE(four->y(), 57.0);
-    QCOMPARE(five->x(), 61.0);
-    QCOMPARE(five->y(), 57.0);
-
-    QSGItem *grid = canvas->rootObject()->findChild<QSGItem*>("grid");
-    QCOMPARE(grid->width(), 142.0);
-    QCOMPARE(grid->height(), 107.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_grid_animated()
-{
-    QSGView *canvas = createView(TESTDATA("grid-animated.qml"), false);
-
-    canvas->rootObject()->setProperty("testRightToLeft", false);
-
-    //Note that all animate in
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-    QCOMPARE(one->x(), -100.0);
-    QCOMPARE(one->y(), -100.0);
-
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-    QCOMPARE(two->x(), -100.0);
-    QCOMPARE(two->y(), -100.0);
-
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-    QCOMPARE(three->x(), -100.0);
-    QCOMPARE(three->y(), -100.0);
-
-    QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
-    QVERIFY(four != 0);
-    QCOMPARE(four->x(), -100.0);
-    QCOMPARE(four->y(), -100.0);
-
-    QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
-    QVERIFY(five != 0);
-    QCOMPARE(five->x(), -100.0);
-    QCOMPARE(five->y(), -100.0);
-
-    QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
-
-    QSGItem *grid = canvas->rootObject()->findChild<QSGItem*>("grid");
-    QVERIFY(grid);
-    QCOMPARE(grid->width(), 150.0);
-    QCOMPARE(grid->height(), 100.0);
-
-    //QTRY_COMPARE used instead of waiting for the expected time of animation completion
-    //Note that this means the duration of the animation is NOT tested
-
-    QTRY_COMPARE(one->y(), 0.0);
-    QTRY_COMPARE(one->x(), 0.0);
-    QTRY_COMPARE(two->isVisible(), false);
-    QTRY_COMPARE(two->y(), -100.0);
-    QTRY_COMPARE(two->x(), -100.0);
-    QTRY_COMPARE(three->y(), 0.0);
-    QTRY_COMPARE(three->x(), 50.0);
-    QTRY_COMPARE(four->y(), 0.0);
-    QTRY_COMPARE(four->x(), 100.0);
-    QTRY_COMPARE(five->y(), 50.0);
-    QTRY_COMPARE(five->x(), 0.0);
-
-    //Add 'two'
-    two->setVisible(true);
-    QCOMPARE(two->isVisible(), true);
-    QCOMPARE(grid->width(), 150.0);
-    QCOMPARE(grid->height(), 100.0);
-    QTest::qWait(0);//Let the animation start
-    QCOMPARE(two->x(), -100.0);
-    QCOMPARE(two->y(), -100.0);
-    QCOMPARE(one->x(), 0.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(three->x(), 50.0);
-    QCOMPARE(three->y(), 0.0);
-    QCOMPARE(four->x(), 100.0);
-    QCOMPARE(four->y(), 0.0);
-    QCOMPARE(five->x(), 0.0);
-    QCOMPARE(five->y(), 50.0);
-    //Let the animation complete
-    QTRY_COMPARE(two->x(), 50.0);
-    QTRY_COMPARE(two->y(), 0.0);
-    QTRY_COMPARE(one->x(), 0.0);
-    QTRY_COMPARE(one->y(), 0.0);
-    QTRY_COMPARE(three->x(), 100.0);
-    QTRY_COMPARE(three->y(), 0.0);
-    QTRY_COMPARE(four->x(), 0.0);
-    QTRY_COMPARE(four->y(), 50.0);
-    QTRY_COMPARE(five->x(), 50.0);
-    QTRY_COMPARE(five->y(), 50.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_grid_animated_rightToLeft()
-{
-    QSGView *canvas = createView(TESTDATA("grid-animated.qml"), false);
-
-    canvas->rootObject()->setProperty("testRightToLeft", true);
-
-    //Note that all animate in
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-    QCOMPARE(one->x(), -100.0);
-    QCOMPARE(one->y(), -100.0);
-
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-    QCOMPARE(two->x(), -100.0);
-    QCOMPARE(two->y(), -100.0);
-
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-    QCOMPARE(three->x(), -100.0);
-    QCOMPARE(three->y(), -100.0);
-
-    QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
-    QVERIFY(four != 0);
-    QCOMPARE(four->x(), -100.0);
-    QCOMPARE(four->y(), -100.0);
-
-    QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
-    QVERIFY(five != 0);
-    QCOMPARE(five->x(), -100.0);
-    QCOMPARE(five->y(), -100.0);
-
-    QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
-
-    QSGItem *grid = canvas->rootObject()->findChild<QSGItem*>("grid");
-    QVERIFY(grid);
-    QCOMPARE(grid->width(), 150.0);
-    QCOMPARE(grid->height(), 100.0);
-
-    //QTRY_COMPARE used instead of waiting for the expected time of animation completion
-    //Note that this means the duration of the animation is NOT tested
-
-    QTRY_COMPARE(one->y(), 0.0);
-    QTRY_COMPARE(one->x(), 100.0);
-    QTRY_COMPARE(two->isVisible(), false);
-    QTRY_COMPARE(two->y(), -100.0);
-    QTRY_COMPARE(two->x(), -100.0);
-    QTRY_COMPARE(three->y(), 0.0);
-    QTRY_COMPARE(three->x(), 50.0);
-    QTRY_COMPARE(four->y(), 0.0);
-    QTRY_COMPARE(four->x(), 0.0);
-    QTRY_COMPARE(five->y(), 50.0);
-    QTRY_COMPARE(five->x(), 100.0);
-
-    //Add 'two'
-    two->setVisible(true);
-    QCOMPARE(two->isVisible(), true);
-    QCOMPARE(grid->width(), 150.0);
-    QCOMPARE(grid->height(), 100.0);
-    QTest::qWait(0);//Let the animation start
-    QCOMPARE(two->x(), -100.0);
-    QCOMPARE(two->y(), -100.0);
-    QCOMPARE(one->x(), 100.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(three->x(), 50.0);
-    QCOMPARE(three->y(), 0.0);
-    QCOMPARE(four->x(), 0.0);
-    QCOMPARE(four->y(), 0.0);
-    QCOMPARE(five->x(), 100.0);
-    QCOMPARE(five->y(), 50.0);
-    //Let the animation complete
-    QTRY_COMPARE(two->x(), 50.0);
-    QTRY_COMPARE(two->y(), 0.0);
-    QTRY_COMPARE(one->x(), 100.0);
-    QTRY_COMPARE(one->y(), 0.0);
-    QTRY_COMPARE(three->x(), 0.0);
-    QTRY_COMPARE(three->y(), 0.0);
-    QTRY_COMPARE(four->x(), 100.0);
-    QTRY_COMPARE(four->y(), 50.0);
-    QTRY_COMPARE(five->x(), 50.0);
-    QTRY_COMPARE(five->y(), 50.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_grid_zero_columns()
-{
-    QSGView *canvas = createView(TESTDATA("gridzerocolumns.qml"));
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-    QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
-    QVERIFY(four != 0);
-    QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
-    QVERIFY(five != 0);
-
-    QCOMPARE(one->x(), 0.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 50.0);
-    QCOMPARE(two->y(), 0.0);
-    QCOMPARE(three->x(), 70.0);
-    QCOMPARE(three->y(), 0.0);
-    QCOMPARE(four->x(), 120.0);
-    QCOMPARE(four->y(), 0.0);
-    QCOMPARE(five->x(), 0.0);
-    QCOMPARE(five->y(), 50.0);
-
-    QSGItem *grid = canvas->rootObject()->findChild<QSGItem*>("grid");
-    QCOMPARE(grid->width(), 170.0);
-    QCOMPARE(grid->height(), 60.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_propertychanges()
-{
-    QSGView *canvas = createView(TESTDATA("propertychangestest.qml"));
-
-    QSGGrid *grid = qobject_cast<QSGGrid*>(canvas->rootObject());
-    QVERIFY(grid != 0);
-    QDeclarativeTransition *rowTransition = canvas->rootObject()->findChild<QDeclarativeTransition*>("rowTransition");
-    QDeclarativeTransition *columnTransition = canvas->rootObject()->findChild<QDeclarativeTransition*>("columnTransition");
-
-    QSignalSpy addSpy(grid, SIGNAL(addChanged()));
-    QSignalSpy moveSpy(grid, SIGNAL(moveChanged()));
-    QSignalSpy columnsSpy(grid, SIGNAL(columnsChanged()));
-    QSignalSpy rowsSpy(grid, SIGNAL(rowsChanged()));
-
-    QVERIFY(grid);
-    QVERIFY(rowTransition);
-    QVERIFY(columnTransition);
-    QCOMPARE(grid->add(), columnTransition);
-    QCOMPARE(grid->move(), columnTransition);
-    QCOMPARE(grid->columns(), 4);
-    QCOMPARE(grid->rows(), -1);
-
-    grid->setAdd(rowTransition);
-    grid->setMove(rowTransition);
-    QCOMPARE(grid->add(), rowTransition);
-    QCOMPARE(grid->move(), rowTransition);
-    QCOMPARE(addSpy.count(),1);
-    QCOMPARE(moveSpy.count(),1);
-
-    grid->setAdd(rowTransition);
-    grid->setMove(rowTransition);
-    QCOMPARE(addSpy.count(),1);
-    QCOMPARE(moveSpy.count(),1);
-
-    grid->setAdd(0);
-    grid->setMove(0);
-    QCOMPARE(addSpy.count(),2);
-    QCOMPARE(moveSpy.count(),2);
-
-    grid->setColumns(-1);
-    grid->setRows(3);
-    QCOMPARE(grid->columns(), -1);
-    QCOMPARE(grid->rows(), 3);
-    QCOMPARE(columnsSpy.count(),1);
-    QCOMPARE(rowsSpy.count(),1);
-
-    grid->setColumns(-1);
-    grid->setRows(3);
-    QCOMPARE(columnsSpy.count(),1);
-    QCOMPARE(rowsSpy.count(),1);
-
-    grid->setColumns(2);
-    grid->setRows(2);
-    QCOMPARE(columnsSpy.count(),2);
-    QCOMPARE(rowsSpy.count(),2);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_repeater()
-{
-    QSGView *canvas = createView(TESTDATA("repeatertest.qml"));
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-
-    QCOMPARE(one->x(), 0.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 50.0);
-    QCOMPARE(two->y(), 0.0);
-    QCOMPARE(three->x(), 100.0);
-    QCOMPARE(three->y(), 0.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_flow()
-{
-    QSGView *canvas = createView(TESTDATA("flowtest.qml"));
-
-    canvas->rootObject()->setProperty("testRightToLeft", false);
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-    QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
-    QVERIFY(four != 0);
-    QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
-    QVERIFY(five != 0);
-
-    QCOMPARE(one->x(), 0.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 50.0);
-    QCOMPARE(two->y(), 0.0);
-    QCOMPARE(three->x(), 0.0);
-    QCOMPARE(three->y(), 50.0);
-    QCOMPARE(four->x(), 0.0);
-    QCOMPARE(four->y(), 70.0);
-    QCOMPARE(five->x(), 50.0);
-    QCOMPARE(five->y(), 70.0);
-
-    QSGItem *flow = canvas->rootObject()->findChild<QSGItem*>("flow");
-    QVERIFY(flow);
-    QCOMPARE(flow->width(), 90.0);
-    QCOMPARE(flow->height(), 120.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_flow_rightToLeft()
-{
-    QSGView *canvas = createView(TESTDATA("flowtest.qml"));
-
-    canvas->rootObject()->setProperty("testRightToLeft", true);
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-    QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
-    QVERIFY(four != 0);
-    QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
-    QVERIFY(five != 0);
-
-    QCOMPARE(one->x(), 40.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 20.0);
-    QCOMPARE(two->y(), 0.0);
-    QCOMPARE(three->x(), 40.0);
-    QCOMPARE(three->y(), 50.0);
-    QCOMPARE(four->x(), 40.0);
-    QCOMPARE(four->y(), 70.0);
-    QCOMPARE(five->x(), 30.0);
-    QCOMPARE(five->y(), 70.0);
-
-    QSGItem *flow = canvas->rootObject()->findChild<QSGItem*>("flow");
-    QVERIFY(flow);
-    QCOMPARE(flow->width(), 90.0);
-    QCOMPARE(flow->height(), 120.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_flow_topToBottom()
-{
-    QSGView *canvas = createView(TESTDATA("flowtest-toptobottom.qml"));
-
-    canvas->rootObject()->setProperty("testRightToLeft", false);
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-    QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
-    QVERIFY(four != 0);
-    QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
-    QVERIFY(five != 0);
-
-    QCOMPARE(one->x(), 0.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 50.0);
-    QCOMPARE(two->y(), 0.0);
-    QCOMPARE(three->x(), 50.0);
-    QCOMPARE(three->y(), 50.0);
-    QCOMPARE(four->x(), 100.0);
-    QCOMPARE(four->y(), 00.0);
-    QCOMPARE(five->x(), 100.0);
-    QCOMPARE(five->y(), 50.0);
-
-    QSGItem *flow = canvas->rootObject()->findChild<QSGItem*>("flow");
-    QVERIFY(flow);
-    QCOMPARE(flow->height(), 90.0);
-    QCOMPARE(flow->width(), 150.0);
-
-    canvas->rootObject()->setProperty("testRightToLeft", true);
-
-    QVERIFY(flow);
-    QCOMPARE(flow->height(), 90.0);
-    QCOMPARE(flow->width(), 150.0);
-
-    QCOMPARE(one->x(), 100.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 80.0);
-    QCOMPARE(two->y(), 0.0);
-    QCOMPARE(three->x(), 50.0);
-    QCOMPARE(three->y(), 50.0);
-    QCOMPARE(four->x(), 0.0);
-    QCOMPARE(four->y(), 0.0);
-    QCOMPARE(five->x(), 40.0);
-    QCOMPARE(five->y(), 50.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_flow_resize()
-{
-    QSGView *canvas = createView(TESTDATA("flowtest.qml"));
-
-    QSGItem *root = qobject_cast<QSGItem*>(canvas->rootObject());
-    QVERIFY(root);
-    root->setWidth(125);
-    root->setProperty("testRightToLeft", false);
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QVERIFY(one != 0);
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-    QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
-    QVERIFY(four != 0);
-    QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
-    QVERIFY(five != 0);
-
-    QTRY_COMPARE(one->x(), 0.0);
-    QTRY_COMPARE(one->y(), 0.0);
-    QTRY_COMPARE(two->x(), 50.0);
-    QTRY_COMPARE(two->y(), 0.0);
-    QTRY_COMPARE(three->x(), 70.0);
-    QTRY_COMPARE(three->y(), 0.0);
-    QTRY_COMPARE(four->x(), 0.0);
-    QTRY_COMPARE(four->y(), 50.0);
-    QTRY_COMPARE(five->x(), 50.0);
-    QTRY_COMPARE(five->y(), 50.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_flow_resize_rightToLeft()
-{
-    QSGView *canvas = createView(TESTDATA("flowtest.qml"));
-
-    QSGItem *root = qobject_cast<QSGItem*>(canvas->rootObject());
-    QVERIFY(root);
-    root->setWidth(125);
-    root->setProperty("testRightToLeft", true);
-
-    QSGRectangle *one = canvas->rootObject()->findChild<QSGRectangle*>("one");
-    QTRY_VERIFY(one != 0);
-    QSGRectangle *two = canvas->rootObject()->findChild<QSGRectangle*>("two");
-    QVERIFY(two != 0);
-    QSGRectangle *three = canvas->rootObject()->findChild<QSGRectangle*>("three");
-    QVERIFY(three != 0);
-    QSGRectangle *four = canvas->rootObject()->findChild<QSGRectangle*>("four");
-    QVERIFY(four != 0);
-    QSGRectangle *five = canvas->rootObject()->findChild<QSGRectangle*>("five");
-    QVERIFY(five != 0);
-
-    QCOMPARE(one->x(), 75.0);
-    QCOMPARE(one->y(), 0.0);
-    QCOMPARE(two->x(), 55.0);
-    QCOMPARE(two->y(), 0.0);
-    QCOMPARE(three->x(), 5.0);
-    QCOMPARE(three->y(), 0.0);
-    QCOMPARE(four->x(), 75.0);
-    QCOMPARE(four->y(), 50.0);
-    QCOMPARE(five->x(), 65.0);
-    QCOMPARE(five->y(), 50.0);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_flow_implicit_resize()
-{
-    QSGView *canvas = createView(TESTDATA("flow-testimplicitsize.qml"));
-    QVERIFY(canvas->rootObject() != 0);
-
-    QSGFlow *flow = canvas->rootObject()->findChild<QSGFlow*>("flow");
-    QVERIFY(flow != 0);
-
-    QCOMPARE(flow->width(), 100.0);
-    QCOMPARE(flow->height(), 120.0);
-
-    canvas->rootObject()->setProperty("flowLayout", 0);
-    QCOMPARE(flow->flow(), QSGFlow::LeftToRight);
-    QCOMPARE(flow->width(), 220.0);
-    QCOMPARE(flow->height(), 50.0);
-
-    canvas->rootObject()->setProperty("flowLayout", 1);
-    QCOMPARE(flow->flow(), QSGFlow::TopToBottom);
-    QCOMPARE(flow->width(), 100.0);
-    QCOMPARE(flow->height(), 120.0);
-
-    canvas->rootObject()->setProperty("flowLayout", 2);
-    QCOMPARE(flow->layoutDirection(), Qt::RightToLeft);
-    QCOMPARE(flow->width(), 220.0);
-    QCOMPARE(flow->height(), 50.0);
-
-    delete canvas;
-}
-
-QString warningMessage;
-
-void interceptWarnings(QtMsgType type, const char *msg)
-{
-    Q_UNUSED( type );
-    warningMessage = msg;
-}
-
-void tst_qsgpositioners::test_conflictinganchors()
-{
-    QtMsgHandler oldMsgHandler = qInstallMsgHandler(interceptWarnings);
-    QDeclarativeEngine engine;
-    QDeclarativeComponent component(&engine);
-
-    component.setData("import QtQuick 2.0\nColumn { Item {} }", QUrl::fromLocalFile(""));
-    QSGItem *item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-    QVERIFY(warningMessage.isEmpty());
-    delete item;
-
-    component.setData("import QtQuick 2.0\nRow { Item {} }", QUrl::fromLocalFile(""));
-    item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-    QVERIFY(warningMessage.isEmpty());
-    delete item;
-
-    component.setData("import QtQuick 2.0\nGrid { Item {} }", QUrl::fromLocalFile(""));
-    item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-    QVERIFY(warningMessage.isEmpty());
-    delete item;
-
-    component.setData("import QtQuick 2.0\nFlow { Item {} }", QUrl::fromLocalFile(""));
-    item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-    QVERIFY(warningMessage.isEmpty());
-    delete item;
-
-    component.setData("import QtQuick 2.0\nColumn { Item { anchors.top: parent.top } }", QUrl::fromLocalFile(""));
-    item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-    QCOMPARE(warningMessage, QString("file::2:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column"));
-    warningMessage.clear();
-    delete item;
-
-    component.setData("import QtQuick 2.0\nColumn { Item { anchors.centerIn: parent } }", QUrl::fromLocalFile(""));
-    item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-    QCOMPARE(warningMessage, QString("file::2:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column"));
-    warningMessage.clear();
-    delete item;
-
-    component.setData("import QtQuick 2.0\nColumn { Item { anchors.left: parent.left } }", QUrl::fromLocalFile(""));
-    item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-    QVERIFY(warningMessage.isEmpty());
-    warningMessage.clear();
-    delete item;
-
-    component.setData("import QtQuick 2.0\nRow { Item { anchors.left: parent.left } }", QUrl::fromLocalFile(""));
-    item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-    QCOMPARE(warningMessage, QString("file::2:1: QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row"));
-    warningMessage.clear();
-    delete item;
-
-    component.setData("import QtQuick 2.0\nRow { Item { anchors.fill: parent } }", QUrl::fromLocalFile(""));
-    item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-    QCOMPARE(warningMessage, QString("file::2:1: QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row"));
-    warningMessage.clear();
-    delete item;
-
-    component.setData("import QtQuick 2.0\nRow { Item { anchors.top: parent.top } }", QUrl::fromLocalFile(""));
-    item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-    QVERIFY(warningMessage.isEmpty());
-    warningMessage.clear();
-    delete item;
-
-    component.setData("import QtQuick 2.0\nGrid { Item { anchors.horizontalCenter: parent.horizontalCenter } }", QUrl::fromLocalFile(""));
-    item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-    QCOMPARE(warningMessage, QString("file::2:1: QML Grid: Cannot specify anchors for items inside Grid"));
-    warningMessage.clear();
-    delete item;
-
-    component.setData("import QtQuick 2.0\nGrid { Item { anchors.centerIn: parent } }", QUrl::fromLocalFile(""));
-    item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-    QCOMPARE(warningMessage, QString("file::2:1: QML Grid: Cannot specify anchors for items inside Grid"));
-    warningMessage.clear();
-    delete item;
-
-    component.setData("import QtQuick 2.0\nFlow { Item { anchors.verticalCenter: parent.verticalCenter } }", QUrl::fromLocalFile(""));
-    item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-    QCOMPARE(warningMessage, QString("file::2:1: QML Flow: Cannot specify anchors for items inside Flow"));
-    delete item;
-
-    component.setData("import QtQuick 2.0\nFlow { Item { anchors.fill: parent } }", QUrl::fromLocalFile(""));
-    item = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(item);
-    QCOMPARE(warningMessage, QString("file::2:1: QML Flow: Cannot specify anchors for items inside Flow"));
-    qInstallMsgHandler(oldMsgHandler);
-    delete item;
-}
-
-void tst_qsgpositioners::test_mirroring()
-{
-    QList<QString> qmlFiles;
-    qmlFiles << "horizontal.qml" << "gridtest.qml" << "flowtest.qml";
-    QList<QString> objectNames;
-    objectNames << "one" << "two" << "three" << "four" << "five";
-
-    foreach (const QString qmlFile, qmlFiles) {
-        QSGView *canvasA = createView(TESTDATA(qmlFile));
-        QSGItem *rootA = qobject_cast<QSGItem*>(canvasA->rootObject());
-
-        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) {
-            // horizontal.qml only has three items
-            if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
-                break;
-            QSGItem *itemA = rootA->findChild<QSGItem*>(objectName);
-            QSGItem *itemB = rootB->findChild<QSGItem*>(objectName);
-            QTRY_VERIFY(itemA->x() != itemB->x());
-        }
-
-        QSGItemPrivate* rootPrivateB = QSGItemPrivate::get(rootB);
-
-        rootPrivateB->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true
-        rootPrivateB->isMirrorImplicit = false;
-        rootPrivateB->inheritMirrorFromItem = true; // LayoutMirroring.childrenInherit: true
-        rootPrivateB->resolveLayoutMirror();
-
-        // RTL == mirror
-        foreach (const QString objectName, objectNames) {
-            // horizontal.qml only has three items
-            if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
-                break;
-            QSGItem *itemA = rootA->findChild<QSGItem*>(objectName);
-            QSGItem *itemB = rootB->findChild<QSGItem*>(objectName);
-            QTRY_COMPARE(itemA->x(), itemB->x());
-        }
-
-        rootA->setProperty("testRightToLeft", false); // layoutDirection: Qt.LeftToRight
-        rootB->setProperty("testRightToLeft", true); // layoutDirection: Qt.RightToLeft
-
-        // LTR == RTL + mirror
-        foreach (const QString objectName, objectNames) {
-            // horizontal.qml only has three items
-            if (qmlFile == QString("horizontal.qml") && objectName == QString("four"))
-                break;
-            QSGItem *itemA = rootA->findChild<QSGItem*>(objectName);
-            QSGItem *itemB = rootB->findChild<QSGItem*>(objectName);
-            QTRY_COMPARE(itemA->x(), itemB->x());
-        }
-        delete canvasA;
-        delete canvasB;
-    }
-}
-
-void tst_qsgpositioners::test_allInvisible()
-{
-    //QTBUG-19361
-    QSGView *canvas = createView(TESTDATA("allInvisible.qml"));
-
-    QSGItem *root = qobject_cast<QSGItem*>(canvas->rootObject());
-    QVERIFY(root);
-
-    QSGRow *row = canvas->rootObject()->findChild<QSGRow*>("row");
-    QVERIFY(row != 0);
-    QVERIFY(row->width() == 0);
-    QVERIFY(row->height() == 0);
-    QSGColumn *column = canvas->rootObject()->findChild<QSGColumn*>("column");
-    QVERIFY(column != 0);
-    QVERIFY(column->width() == 0);
-    QVERIFY(column->height() == 0);
-}
-
-void tst_qsgpositioners::test_attachedproperties()
-{
-    QFETCH(QString, filename);
-
-    QSGView *canvas = createView(filename);
-    QVERIFY(canvas->rootObject() != 0);
-
-    QSGRectangle *greenRect = canvas->rootObject()->findChild<QSGRectangle *>("greenRect");
-    QVERIFY(greenRect != 0);
-
-    int posIndex = greenRect->property("posIndex").toInt();
-    QVERIFY(posIndex == 0);
-    bool isFirst = greenRect->property("isFirstItem").toBool();
-    QVERIFY(isFirst == true);
-    bool isLast = greenRect->property("isLastItem").toBool();
-    QVERIFY(isLast == false);
-
-    QSGRectangle *yellowRect = canvas->rootObject()->findChild<QSGRectangle *>("yellowRect");
-    QVERIFY(yellowRect != 0);
-
-    posIndex = yellowRect->property("posIndex").toInt();
-    QVERIFY(posIndex == -1);
-    isFirst = yellowRect->property("isFirstItem").toBool();
-    QVERIFY(isFirst == false);
-    isLast = yellowRect->property("isLastItem").toBool();
-    QVERIFY(isLast == false);
-
-    yellowRect->metaObject()->invokeMethod(yellowRect, "onDemandPositioner");
-
-    posIndex = yellowRect->property("posIndex").toInt();
-    QVERIFY(posIndex == 1);
-    isFirst = yellowRect->property("isFirstItem").toBool();
-    QVERIFY(isFirst == false);
-    isLast = yellowRect->property("isLastItem").toBool();
-    QVERIFY(isLast == true);
-
-    delete canvas;
-}
-
-void tst_qsgpositioners::test_attachedproperties_data()
-{
-    QTest::addColumn<QString>("filename");
-
-    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()
-{
-    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");
-    QVERIFY(row != 0);
-
-    QSGRectangle *rect0 = canvas->rootObject()->findChild<QSGRectangle *>("rect0");
-    QVERIFY(rect0 != 0);
-
-    int posIndex = rect0->property("index").toInt();
-    QVERIFY(posIndex == 0);
-    bool isFirst = rect0->property("firstItem").toBool();
-    QVERIFY(isFirst == true);
-    bool isLast = rect0->property("lastItem").toBool();
-    QVERIFY(isLast == false);
-
-    QSGRectangle *rect1 = canvas->rootObject()->findChild<QSGRectangle *>("rect1");
-    QVERIFY(rect1 != 0);
-
-    posIndex = rect1->property("index").toInt();
-    QVERIFY(posIndex == 1);
-    isFirst = rect1->property("firstItem").toBool();
-    QVERIFY(isFirst == false);
-    isLast = rect1->property("lastItem").toBool();
-    QVERIFY(isLast == true);
-
-    row->metaObject()->invokeMethod(row, "createSubRect");
-
-    QTRY_VERIFY(rect1->property("index").toInt() == 1);
-    QTRY_VERIFY(rect1->property("firstItem").toBool() == false);
-    QTRY_VERIFY(rect1->property("lastItem").toBool() == false);
-
-    QSGRectangle *rect2 = canvas->rootObject()->findChild<QSGRectangle *>("rect2");
-    QVERIFY(rect2 != 0);
-
-    posIndex = rect2->property("index").toInt();
-    QVERIFY(posIndex == 2);
-    isFirst = rect2->property("firstItem").toBool();
-    QVERIFY(isFirst == false);
-    isLast = rect2->property("lastItem").toBool();
-    QVERIFY(isLast == true);
-
-    row->metaObject()->invokeMethod(row, "destroySubRect");
-
-    qApp->processEvents(QEventLoop::DeferredDeletion);
-
-    QTRY_VERIFY(rect1->property("index").toInt() == 1);
-    QTRY_VERIFY(rect1->property("firstItem").toBool() == false);
-    QTRY_VERIFY(rect1->property("lastItem").toBool() == true);
-
-    delete canvas;
-}
-
-QSGView *tst_qsgpositioners::createView(const QString &filename, bool wait)
-{
-    QSGView *canvas = new QSGView(0);
-
-    canvas->setSource(QUrl::fromLocalFile(filename));
-    canvas->show();
-    if (wait)
-        QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
-
-    return canvas;
-}
-
-
-QTEST_MAIN(tst_qsgpositioners)
-
-#include "tst_qsgpositioners.moc"
diff --git a/tests/auto/declarative/qsgrepeater/qsgrepeater.pro b/tests/auto/declarative/qsgrepeater/qsgrepeater.pro
deleted file mode 100644 (file)
index aa15c71..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsgrepeater
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_qsgrepeater.cpp
-
-testFiles.files = data
-testFiles.path = .
-DEPLOYMENT += testFiles
-
-CONFIG += parallel_test
-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
deleted file mode 100644 (file)
index 40d7b77..0000000
+++ /dev/null
@@ -1,694 +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 <QtTest/QtTest>
-#include <QtTest/QSignalSpy>
-#include <private/qlistmodelinterface_p.h>
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qsgview.h>
-#include <QtDeclarative/qdeclarativecontext.h>
-#include <QtDeclarative/qdeclarativeexpression.h>
-#include <private/qsgrepeater_p.h>
-#include <private/qsgtext_p.h>
-
-#include "../shared/util.h"
-
-inline QUrl TEST_FILE(const QString &filename)
-{
-    return QUrl::fromLocalFile(TESTDATA(filename));
-}
-
-class tst_QSGRepeater : public QObject
-{
-    Q_OBJECT
-public:
-    tst_QSGRepeater();
-
-private slots:
-    void numberModel();
-    void objectList();
-    void stringList();
-    void dataModel_adding();
-    void dataModel_removing();
-    void dataModel_changes();
-    void itemModel();
-    void resetModel();
-    void modelChanged();
-    void properties();
-
-private:
-    QSGView *createView();
-    template<typename T>
-    T *findItem(QObject *parent, const QString &objectName, int index);
-    template<typename T>
-    T *findItem(QObject *parent, const QString &id);
-};
-
-class TestObject : public QObject
-{
-    Q_OBJECT
-
-    Q_PROPERTY(bool error READ error WRITE setError)
-    Q_PROPERTY(bool useModel READ useModel NOTIFY useModelChanged)
-
-public:
-    TestObject() : QObject(), mError(true), mUseModel(false) {}
-
-    bool error() const { return mError; }
-    void setError(bool err) { mError = err; }
-
-    bool useModel() const { return mUseModel; }
-    void setUseModel(bool use) { mUseModel = use; emit useModelChanged(); }
-
-signals:
-    void useModelChanged();
-
-private:
-    bool mError;
-    bool mUseModel;
-};
-
-class TestModel : public QAbstractListModel
-{
-public:
-    enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 };
-
-    TestModel(QObject *parent=0) : QAbstractListModel(parent) {
-        QHash<int, QByteArray> roles;
-        roles[Name] = "name";
-        roles[Number] = "number";
-        setRoleNames(roles);
-    }
-
-    int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); }
-    QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const {
-        QVariant rv;
-        if (role == Name)
-            rv = list.at(index.row()).first;
-        else if (role == Number)
-            rv = list.at(index.row()).second;
-
-        return rv;
-    }
-
-    int count() const { return rowCount(); }
-    QString name(int index) const { return list.at(index).first; }
-    QString number(int index) const { return list.at(index).second; }
-
-    void addItem(const QString &name, const QString &number) {
-        emit beginInsertRows(QModelIndex(), list.count(), list.count());
-        list.append(QPair<QString,QString>(name, number));
-        emit endInsertRows();
-    }
-
-    void insertItem(int index, const QString &name, const QString &number) {
-        emit beginInsertRows(QModelIndex(), index, index);
-        list.insert(index, QPair<QString,QString>(name, number));
-        emit endInsertRows();
-    }
-
-    void removeItem(int index) {
-        emit beginRemoveRows(QModelIndex(), index, index);
-        list.removeAt(index);
-        emit endRemoveRows();
-    }
-
-    void moveItem(int from, int to) {
-        emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
-        list.move(from, to);
-        emit endMoveRows();
-    }
-
-    void modifyItem(int idx, const QString &name, const QString &number) {
-        list[idx] = QPair<QString,QString>(name, number);
-        emit dataChanged(index(idx,0), index(idx,0));
-    }
-
-private:
-    QList<QPair<QString,QString> > list;
-};
-
-
-tst_QSGRepeater::tst_QSGRepeater()
-{
-}
-
-void tst_QSGRepeater::numberModel()
-{
-    QSGView *canvas = createView();
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testData", 5);
-    TestObject *testObject = new TestObject;
-    ctxt->setContextProperty("testObject", testObject);
-
-    canvas->setSource(TEST_FILE("intmodel.qml"));
-    qApp->processEvents();
-
-    QSGRepeater *repeater = findItem<QSGRepeater>(canvas->rootObject(), "repeater");
-    QVERIFY(repeater != 0);
-    QCOMPARE(repeater->parentItem()->childItems().count(), 5+1);
-
-    QVERIFY(!repeater->itemAt(-1));
-    for (int i=0; i<repeater->count(); i++)
-        QCOMPARE(repeater->itemAt(i), repeater->parentItem()->childItems().at(i));
-    QVERIFY(!repeater->itemAt(repeater->count()));
-
-    QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
-    QVERIFY(testObject->error() == false);
-
-    delete testObject;
-    delete canvas;
-}
-
-class MyObject : public QObject
-{
-    Q_OBJECT
-    Q_PROPERTY(int idx READ idx CONSTANT)
-public:
-    MyObject(int i) : QObject(), m_idx(i) {}
-
-    int idx() const { return m_idx; }
-
-    int m_idx;
-};
-
-void tst_QSGRepeater::objectList()
-{
-    QSGView *canvas = createView();
-    QObjectList data;
-    for (int i=0; i<100; i++)
-        data << new MyObject(i);
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testData", QVariant::fromValue(data));
-
-    canvas->setSource(TEST_FILE("objlist.qml"));
-    qApp->processEvents();
-
-    QSGRepeater *repeater = findItem<QSGRepeater>(canvas->rootObject(), "repeater");
-    QVERIFY(repeater != 0);
-    QCOMPARE(repeater->property("errors").toInt(), 0);//If this fails either they are out of order or can't find the object's data
-    QCOMPARE(repeater->property("instantiated").toInt(), 100);
-
-    QVERIFY(!repeater->itemAt(-1));
-    for (int i=0; i<data.count(); i++)
-        QCOMPARE(repeater->itemAt(i), repeater->parentItem()->childItems().at(i));
-    QVERIFY(!repeater->itemAt(data.count()));
-
-    QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QSGItem*)));
-    QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QSGItem*)));
-    ctxt->setContextProperty("testData", QVariant::fromValue(data));
-    QCOMPARE(addedSpy.count(), data.count());
-    QCOMPARE(removedSpy.count(), data.count());
-
-    qDeleteAll(data);
-    delete canvas;
-}
-
-/*
-The Repeater element creates children at its own position in its parent's
-stacking order.  In this test we insert a repeater between two other Text
-elements to test this.
-*/
-void tst_QSGRepeater::stringList()
-{
-    QSGView *canvas = createView();
-
-    QStringList data;
-    data << "One";
-    data << "Two";
-    data << "Three";
-    data << "Four";
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testData", data);
-
-    canvas->setSource(TEST_FILE("repeater1.qml"));
-    qApp->processEvents();
-
-    QSGRepeater *repeater = findItem<QSGRepeater>(canvas->rootObject(), "repeater");
-    QVERIFY(repeater != 0);
-
-    QSGItem *container = findItem<QSGItem>(canvas->rootObject(), "container");
-    QVERIFY(container != 0);
-
-    QCOMPARE(container->childItems().count(), data.count() + 3);
-
-    bool saw_repeater = false;
-    for (int i = 0; i < container->childItems().count(); ++i) {
-
-        if (i == 0) {
-            QSGText *name = qobject_cast<QSGText*>(container->childItems().at(i));
-            QVERIFY(name != 0);
-            QCOMPARE(name->text(), QLatin1String("Zero"));
-        } else if (i == container->childItems().count() - 2) {
-            // The repeater itself
-            QSGRepeater *rep = qobject_cast<QSGRepeater*>(container->childItems().at(i));
-            QCOMPARE(rep, repeater);
-            saw_repeater = true;
-            continue;
-        } else if (i == container->childItems().count() - 1) {
-            QSGText *name = qobject_cast<QSGText*>(container->childItems().at(i));
-            QVERIFY(name != 0);
-            QCOMPARE(name->text(), QLatin1String("Last"));
-        } else {
-            QSGText *name = qobject_cast<QSGText*>(container->childItems().at(i));
-            QVERIFY(name != 0);
-            QCOMPARE(name->text(), data.at(i-1));
-        }
-    }
-    QVERIFY(saw_repeater);
-
-    delete canvas;
-}
-
-void tst_QSGRepeater::dataModel_adding()
-{
-    QSGView *canvas = createView();
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    TestObject *testObject = new TestObject;
-    ctxt->setContextProperty("testObject", testObject);
-
-    TestModel testModel;
-    ctxt->setContextProperty("testData", &testModel);
-    canvas->setSource(TEST_FILE("repeater2.qml"));
-    qApp->processEvents();
-
-    QSGRepeater *repeater = findItem<QSGRepeater>(canvas->rootObject(), "repeater");
-    QVERIFY(repeater != 0);
-    QSGItem *container = findItem<QSGItem>(canvas->rootObject(), "container");
-    QVERIFY(container != 0);
-
-    QVERIFY(!repeater->itemAt(0));
-
-    QSignalSpy countSpy(repeater, SIGNAL(countChanged()));
-    QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QSGItem*)));
-
-    // add to empty model
-    testModel.addItem("two", "2");
-    QCOMPARE(repeater->itemAt(0), container->childItems().at(0));
-    QCOMPARE(countSpy.count(), 1); countSpy.clear();
-    QCOMPARE(addedSpy.count(), 1);
-    QCOMPARE(addedSpy.at(0).at(0).toInt(), 0);
-    QCOMPARE(addedSpy.at(0).at(1).value<QSGItem*>(), container->childItems().at(0));
-    addedSpy.clear();
-
-    // insert at start
-    testModel.insertItem(0, "one", "1");
-    QCOMPARE(repeater->itemAt(0), container->childItems().at(0));
-    QCOMPARE(countSpy.count(), 1); countSpy.clear();
-    QCOMPARE(addedSpy.count(), 1);
-    QCOMPARE(addedSpy.at(0).at(0).toInt(), 0);
-    QCOMPARE(addedSpy.at(0).at(1).value<QSGItem*>(), container->childItems().at(0));
-    addedSpy.clear();
-
-    // insert at end
-    testModel.insertItem(2, "four", "4");
-    QCOMPARE(repeater->itemAt(2), container->childItems().at(2));
-    QCOMPARE(countSpy.count(), 1); countSpy.clear();
-    QCOMPARE(addedSpy.count(), 1);
-    QCOMPARE(addedSpy.at(0).at(0).toInt(), 2);
-    QCOMPARE(addedSpy.at(0).at(1).value<QSGItem*>(), container->childItems().at(2));
-    addedSpy.clear();
-
-    // insert in middle
-    testModel.insertItem(2, "three", "3");
-    QCOMPARE(repeater->itemAt(2), container->childItems().at(2));
-    QCOMPARE(countSpy.count(), 1); countSpy.clear();
-    QCOMPARE(addedSpy.count(), 1);
-    QCOMPARE(addedSpy.at(0).at(0).toInt(), 2);
-    QCOMPARE(addedSpy.at(0).at(1).value<QSGItem*>(), container->childItems().at(2));
-    addedSpy.clear();
-
-    delete testObject;
-    addedSpy.clear();
-    countSpy.clear();
-    delete canvas;
-}
-
-void tst_QSGRepeater::dataModel_removing()
-{
-    QSGView *canvas = createView();
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    TestObject *testObject = new TestObject;
-    ctxt->setContextProperty("testObject", testObject);
-
-    TestModel testModel;
-    testModel.addItem("one", "1");
-    testModel.addItem("two", "2");
-    testModel.addItem("three", "3");
-    testModel.addItem("four", "4");
-    testModel.addItem("five", "5");
-
-    ctxt->setContextProperty("testData", &testModel);
-    canvas->setSource(TEST_FILE("repeater2.qml"));
-    qApp->processEvents();
-
-    QSGRepeater *repeater = findItem<QSGRepeater>(canvas->rootObject(), "repeater");
-    QVERIFY(repeater != 0);
-    QSGItem *container = findItem<QSGItem>(canvas->rootObject(), "container");
-    QVERIFY(container != 0);
-    QCOMPARE(container->childItems().count(), repeater->count()+1);
-
-    QSignalSpy countSpy(repeater, SIGNAL(countChanged()));
-    QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QSGItem*)));
-
-    // remove at start
-    QSGItem *item = repeater->itemAt(0);
-    QCOMPARE(item, container->childItems().at(0));
-
-    testModel.removeItem(0);
-    QVERIFY(repeater->itemAt(0) != item);
-    QCOMPARE(countSpy.count(), 1); countSpy.clear();
-    QCOMPARE(removedSpy.count(), 1);
-    QCOMPARE(removedSpy.at(0).at(0).toInt(), 0);
-    QCOMPARE(removedSpy.at(0).at(1).value<QSGItem*>(), item);
-    removedSpy.clear();
-
-    // remove at end
-    int lastIndex = testModel.count()-1;
-    item = repeater->itemAt(lastIndex);
-    QCOMPARE(item, container->childItems().at(lastIndex));
-
-    testModel.removeItem(lastIndex);
-    QVERIFY(repeater->itemAt(lastIndex) != item);
-    QCOMPARE(countSpy.count(), 1); countSpy.clear();
-    QCOMPARE(removedSpy.count(), 1);
-    QCOMPARE(removedSpy.at(0).at(0).toInt(), lastIndex);
-    QCOMPARE(removedSpy.at(0).at(1).value<QSGItem*>(), item);
-    removedSpy.clear();
-
-    // remove from middle
-    item = repeater->itemAt(1);
-    QCOMPARE(item, container->childItems().at(1));
-
-    testModel.removeItem(1);
-    QVERIFY(repeater->itemAt(lastIndex) != item);
-    QCOMPARE(countSpy.count(), 1); countSpy.clear();
-    QCOMPARE(removedSpy.count(), 1);
-    QCOMPARE(removedSpy.at(0).at(0).toInt(), 1);
-    QCOMPARE(removedSpy.at(0).at(1).value<QSGItem*>(), item);
-    removedSpy.clear();
-
-    delete testObject;
-    delete canvas;
-}
-
-void tst_QSGRepeater::dataModel_changes()
-{
-    QSGView *canvas = createView();
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    TestObject *testObject = new TestObject;
-    ctxt->setContextProperty("testObject", testObject);
-
-    TestModel testModel;
-    testModel.addItem("one", "1");
-    testModel.addItem("two", "2");
-    testModel.addItem("three", "3");
-
-    ctxt->setContextProperty("testData", &testModel);
-    canvas->setSource(TEST_FILE("repeater2.qml"));
-    qApp->processEvents();
-
-    QSGRepeater *repeater = findItem<QSGRepeater>(canvas->rootObject(), "repeater");
-    QVERIFY(repeater != 0);
-    QSGItem *container = findItem<QSGItem>(canvas->rootObject(), "container");
-    QVERIFY(container != 0);
-    QCOMPARE(container->childItems().count(), repeater->count()+1);
-
-    // Check that model changes are propagated
-    QSGText *text = findItem<QSGText>(canvas->rootObject(), "myName", 1);
-    QVERIFY(text);
-    QCOMPARE(text->text(), QString("two"));
-
-    testModel.modifyItem(1, "Item two", "_2");
-    text = findItem<QSGText>(canvas->rootObject(), "myName", 1);
-    QVERIFY(text);
-    QCOMPARE(text->text(), QString("Item two"));
-
-    text = findItem<QSGText>(canvas->rootObject(), "myNumber", 1);
-    QVERIFY(text);
-    QCOMPARE(text->text(), QString("_2"));
-
-    delete testObject;
-    delete canvas;
-}
-
-void tst_QSGRepeater::itemModel()
-{
-    QSGView *canvas = createView();
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    TestObject *testObject = new TestObject;
-    ctxt->setContextProperty("testObject", testObject);
-
-    canvas->setSource(TEST_FILE("itemlist.qml"));
-    qApp->processEvents();
-
-    QSGRepeater *repeater = findItem<QSGRepeater>(canvas->rootObject(), "repeater");
-    QVERIFY(repeater != 0);
-
-    QSGItem *container = findItem<QSGItem>(canvas->rootObject(), "container");
-    QVERIFY(container != 0);
-
-    QCOMPARE(container->childItems().count(), 1);
-
-    testObject->setUseModel(true);
-    QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties");
-    QVERIFY(testObject->error() == false);
-
-    QCOMPARE(container->childItems().count(), 4);
-    QVERIFY(qobject_cast<QObject*>(container->childItems().at(0))->objectName() == "item1");
-    QVERIFY(qobject_cast<QObject*>(container->childItems().at(1))->objectName() == "item2");
-    QVERIFY(qobject_cast<QObject*>(container->childItems().at(2))->objectName() == "item3");
-    QVERIFY(container->childItems().at(3) == repeater);
-
-    QMetaObject::invokeMethod(canvas->rootObject(), "switchModel");
-    QCOMPARE(container->childItems().count(), 3);
-    QVERIFY(qobject_cast<QObject*>(container->childItems().at(0))->objectName() == "item4");
-    QVERIFY(qobject_cast<QObject*>(container->childItems().at(1))->objectName() == "item5");
-    QVERIFY(container->childItems().at(2) == repeater);
-
-    testObject->setUseModel(false);
-    QCOMPARE(container->childItems().count(), 1);
-
-    delete testObject;
-    delete canvas;
-}
-
-void tst_QSGRepeater::resetModel()
-{
-    QSGView *canvas = createView();
-
-    QStringList dataA;
-    for (int i=0; i<10; i++)
-        dataA << QString::number(i);
-
-    QDeclarativeContext *ctxt = canvas->rootContext();
-    ctxt->setContextProperty("testData", dataA);
-    canvas->setSource(TEST_FILE("repeater1.qml"));
-    qApp->processEvents();
-    QSGRepeater *repeater = findItem<QSGRepeater>(canvas->rootObject(), "repeater");
-    QVERIFY(repeater != 0);
-    QSGItem *container = findItem<QSGItem>(canvas->rootObject(), "container");
-    QVERIFY(container != 0);
-
-    QCOMPARE(repeater->count(), dataA.count());
-    for (int i=0; i<repeater->count(); i++)
-        QCOMPARE(repeater->itemAt(i), container->childItems().at(i+1)); // +1 to skip first Text object
-
-    QSignalSpy modelChangedSpy(repeater, SIGNAL(modelChanged()));
-    QSignalSpy countSpy(repeater, SIGNAL(countChanged()));
-    QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QSGItem*)));
-    QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QSGItem*)));
-
-    QStringList dataB;
-    for (int i=0; i<20; i++)
-        dataB << QString::number(i);
-
-    // reset context property
-    ctxt->setContextProperty("testData", dataB);
-    QCOMPARE(repeater->count(), dataB.count());
-
-    QCOMPARE(modelChangedSpy.count(), 1);
-    QCOMPARE(countSpy.count(), 1);
-    QCOMPARE(removedSpy.count(), dataA.count());
-    QCOMPARE(addedSpy.count(), dataB.count());
-    for (int i=0; i<dataB.count(); i++) {
-        QCOMPARE(addedSpy.at(i).at(0).toInt(), i);
-        QCOMPARE(addedSpy.at(i).at(1).value<QSGItem*>(), repeater->itemAt(i));
-    }
-    modelChangedSpy.clear();
-    countSpy.clear();
-    removedSpy.clear();
-    addedSpy.clear();
-
-    // reset via setModel()
-    repeater->setModel(dataA);
-    QCOMPARE(repeater->count(), dataA.count());
-
-    QCOMPARE(modelChangedSpy.count(), 1);
-    QCOMPARE(countSpy.count(), 1);
-    QCOMPARE(removedSpy.count(), dataB.count());
-    QCOMPARE(addedSpy.count(), dataA.count());
-    for (int i=0; i<dataA.count(); i++) {
-        QCOMPARE(addedSpy.at(i).at(0).toInt(), i);
-        QCOMPARE(addedSpy.at(i).at(1).value<QSGItem*>(), repeater->itemAt(i));
-    }
-
-    modelChangedSpy.clear();
-    countSpy.clear();
-    removedSpy.clear();
-    addedSpy.clear();
-
-    delete canvas;
-}
-
-// QTBUG-17156
-void tst_QSGRepeater::modelChanged()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent component(&engine, TEST_FILE("modelChanged.qml"));
-
-    QSGItem *rootObject = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(rootObject);
-    QSGRepeater *repeater = findItem<QSGRepeater>(rootObject, "repeater");
-    QVERIFY(repeater);
-
-    repeater->setModel(4);
-    QCOMPARE(repeater->count(), 4);
-    QCOMPARE(repeater->property("itemsCount").toInt(), 4);
-    QCOMPARE(repeater->property("itemsFound").toList().count(), 4);
-
-    repeater->setModel(10);
-    QCOMPARE(repeater->count(), 10);
-    QCOMPARE(repeater->property("itemsCount").toInt(), 10);
-    QCOMPARE(repeater->property("itemsFound").toList().count(), 10);
-
-    delete rootObject;
-}
-
-void tst_QSGRepeater::properties()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent component(&engine, TEST_FILE("properties.qml"));
-
-    QSGItem *rootObject = qobject_cast<QSGItem*>(component.create());
-    QVERIFY(rootObject);
-
-    QSGRepeater *repeater = findItem<QSGRepeater>(rootObject, "repeater");
-    QVERIFY(repeater);
-
-    QSignalSpy modelSpy(repeater, SIGNAL(modelChanged()));
-    repeater->setModel(3);
-    QCOMPARE(modelSpy.count(),1);
-    repeater->setModel(3);
-    QCOMPARE(modelSpy.count(),1);
-
-    QSignalSpy delegateSpy(repeater, SIGNAL(delegateChanged()));
-
-    QDeclarativeComponent rectComponent(&engine);
-    rectComponent.setData("import QtQuick 2.0; Rectangle {}", QUrl::fromLocalFile(""));
-
-    repeater->setDelegate(&rectComponent);
-    QCOMPARE(delegateSpy.count(),1);
-    repeater->setDelegate(&rectComponent);
-    QCOMPARE(delegateSpy.count(),1);
-
-    delete rootObject;
-}
-
-QSGView *tst_QSGRepeater::createView()
-{
-    QSGView *canvas = new QSGView(0);
-    canvas->setGeometry(0,0,240,320);
-
-    return canvas;
-}
-
-template<typename T>
-T *tst_QSGRepeater::findItem(QObject *parent, const QString &objectName, int index)
-{
-    const QMetaObject &mo = T::staticMetaObject;
-    //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)
-            continue;
-        //qDebug() << "try" << item;
-        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
-            if (index != -1) {
-                QDeclarativeExpression e(qmlContext(item), item, "index");
-                if (e.evaluate().toInt() == index)
-                    return static_cast<T*>(item);
-            } else {
-                return static_cast<T*>(item);
-            }
-        }
-        item = findItem<T>(item, objectName, index);
-        if (item)
-            return static_cast<T*>(item);
-    }
-
-    return 0;
-}
-
-template<typename T>
-T *tst_QSGRepeater::findItem(QObject *parent, const QString &objectName)
-{
-    const QMetaObject &mo = T::staticMetaObject;
-    if (mo.cast(parent) && (objectName.isEmpty() || parent->objectName() == objectName))
-        return static_cast<T*>(parent);
-    for (int i = 0; i < parent->children().count(); ++i) {
-        QSGItem *child = qobject_cast<QSGItem*>(parent->children().at(i));
-        if (!child)
-            continue;
-        QSGItem *item = findItem<T>(child, objectName);
-        if (item)
-            return static_cast<T*>(item);
-    }
-
-    return 0;
-}
-
-QTEST_MAIN(tst_QSGRepeater)
-
-#include "tst_qsgrepeater.moc"
diff --git a/tests/auto/declarative/qsgtext/qsgtext.pro b/tests/auto/declarative/qsgtext/qsgtext.pro
deleted file mode 100644 (file)
index a04c079..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsgtext
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_qsgtext.cpp
-
-INCLUDEPATH += ../shared/
-HEADERS += ../shared/testhttpserver.h
-SOURCES += ../shared/testhttpserver.cpp
-
-testDataFiles.files = data
-testDataFiles.path = .
-DEPLOYMENT += testDataFiles
-
-CONFIG += parallel_test
-
-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
deleted file mode 100644 (file)
index a46969e..0000000
+++ /dev/null
@@ -1,1433 +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 <QTextDocument>
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativecomponent.h>
-#include <private/qsgtext_p.h>
-#include <private/qsgtext_p_p.h>
-#include <private/qdeclarativevaluetype_p.h>
-#include <private/qsgdistancefieldglyphcache_p.h>
-#include <QFontMetrics>
-#include <QGraphicsSceneMouseEvent>
-#include <qmath.h>
-#include <QSGView>
-#include <private/qapplication_p.h>
-#include <limits.h>
-#include <QtGui/QMouseEvent>
-#include "../shared/util.h"
-#include "testhttpserver.h"
-
-DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
-
-class tst_qsgtext : public QObject
-{
-    Q_OBJECT
-public:
-    tst_qsgtext();
-
-private slots:
-    void initTestCase();
-    void cleanupTestCase();
-    void text();
-    void width();
-    void wrap();
-    void elide();
-    void textFormat();
-
-    void alignments_data();
-    void alignments();
-
-    void embeddedImages_data();
-    void embeddedImages();
-
-    void lineCount();
-    void lineHeight();
-
-    // ### these tests may be trivial
-    void horizontalAlignment();
-    void horizontalAlignment_RightToLeft();
-    void verticalAlignment();
-    void font();
-    void style();
-    void color();
-    void smooth();
-
-    // QDeclarativeFontValueType
-    void weight();
-    void underline();
-    void overline();
-    void strikeout();
-    void capitalization();
-    void letterSpacing();
-    void wordSpacing();
-
-    void clickLink();
-
-    void implicitSize_data();
-    void implicitSize();
-
-    void lineLaidOut();
-
-
-private:
-    QStringList standard;
-    QStringList richText;
-
-    QStringList horizontalAlignmentmentStrings;
-    QStringList verticalAlignmentmentStrings;
-
-    QList<Qt::Alignment> verticalAlignmentments;
-    QList<Qt::Alignment> horizontalAlignmentments;
-
-    QStringList styleStrings;
-    QList<QSGText::TextStyle> styles;
-
-    QStringList colorStrings;
-
-    QDeclarativeEngine engine;
-
-    QSGView *createView(const QString &filename);
-};
-void tst_qsgtext::initTestCase()
-{
-}
-
-void tst_qsgtext::cleanupTestCase()
-{
-
-}
-tst_qsgtext::tst_qsgtext()
-{
-    standard << "the quick brown fox jumped over the lazy dog"
-            << "the quick brown fox\n jumped over the lazy dog";
-
-    richText << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a> jumped over the <b>lazy</b> dog</i>"
-            << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a><br>jumped over the <b>lazy</b> dog</i>";
-
-    horizontalAlignmentmentStrings << "AlignLeft"
-            << "AlignRight"
-            << "AlignHCenter";
-
-    verticalAlignmentmentStrings << "AlignTop"
-            << "AlignBottom"
-            << "AlignVCenter";
-
-    horizontalAlignmentments << Qt::AlignLeft
-            << Qt::AlignRight
-            << Qt::AlignHCenter;
-
-    verticalAlignmentments << Qt::AlignTop
-            << Qt::AlignBottom
-            << Qt::AlignVCenter;
-
-    styleStrings << "Normal"
-            << "Outline"
-            << "Raised"
-            << "Sunken";
-
-    styles << QSGText::Normal
-            << QSGText::Outline
-            << QSGText::Raised
-            << QSGText::Sunken;
-
-    colorStrings << "aliceblue"
-            << "antiquewhite"
-            << "aqua"
-            << "darkkhaki"
-            << "darkolivegreen"
-            << "dimgray"
-            << "palevioletred"
-            << "lightsteelblue"
-            << "#000000"
-            << "#AAAAAA"
-            << "#FFFFFF"
-            << "#2AC05F";
-    //
-    // need a different test to do alpha channel test
-    // << "#AA0011DD"
-    // << "#00F16B11";
-    //
-}
-
-QSGView *tst_qsgtext::createView(const QString &filename)
-{
-    QSGView *canvas = new QSGView(0);
-
-    canvas->setSource(QUrl::fromLocalFile(filename));
-    return canvas;
-}
-
-void tst_qsgtext::text()
-{
-    {
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData("import QtQuick 2.0\nText { text: \"\" }", QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE(textObject->text(), QString(""));
-        QVERIFY(textObject->width() == 0);
-
-        delete textObject;
-    }
-
-    for (int i = 0; i < standard.size(); i++)
-    {
-        QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE(textObject->text(), standard.at(i));
-        QVERIFY(textObject->width() > 0);
-
-        delete textObject;
-    }
-
-    for (int i = 0; i < richText.size(); i++)
-    {
-        QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QString expected = richText.at(i);
-        QCOMPARE(textObject->text(), expected.replace("\\\"", "\""));
-        QVERIFY(textObject->width() > 0);
-
-        delete textObject;
-    }
-}
-
-void tst_qsgtext::width()
-{
-    // uses Font metrics to find the width for standard and document to find the width for rich
-    {
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData("import QtQuick 2.0\nText { text: \"\" }", QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE(textObject->width(), 0.);
-
-        delete textObject;
-    }
-
-    bool requiresUnhintedMetrics = !qmlDisableDistanceField();
-
-    for (int i = 0; i < standard.size(); i++)
-    {
-        QVERIFY(!Qt::mightBeRichText(standard.at(i))); // self-test
-
-        QFont f;
-        qreal metricWidth = 0.0;
-
-        if (requiresUnhintedMetrics) {
-            QString s = standard.at(i);
-            s.replace(QLatin1Char('\n'), QChar::LineSeparator);
-
-            QTextLayout layout(s);
-            layout.setFlags(Qt::TextExpandTabs | Qt::TextShowMnemonic);
-            {
-                QTextOption option;
-                option.setUseDesignMetrics(true);
-                layout.setTextOption(option);
-            }
-
-            layout.beginLayout();
-            forever {
-                QTextLine line = layout.createLine();
-                if (!line.isValid())
-                    break;
-            }
-
-            layout.endLayout();
-
-            metricWidth = qCeil(layout.boundingRect().width());
-        } else {
-            QFontMetricsF fm(f);
-            qreal metricWidth = fm.size(Qt::TextExpandTabs && Qt::TextShowMnemonic, standard.at(i)).width();
-            metricWidth = qCeil(metricWidth);
-        }
-
-        QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QVERIFY(textObject->boundingRect().width() > 0);
-        QCOMPARE(textObject->width(), qreal(metricWidth));
-        QVERIFY(textObject->textFormat() == QSGText::AutoText); // setting text doesn't change format
-
-        delete textObject;
-    }
-
-    for (int i = 0; i < richText.size(); i++)
-    {
-        QVERIFY(Qt::mightBeRichText(richText.at(i))); // self-test
-
-        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);
-
-        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;
-    }
-}
-
-void tst_qsgtext::wrap()
-{
-    int textHeight = 0;
-    // for specified width and wrap set true
-    {
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData("import QtQuick 2.0\nText { text: \"Hello\"; wrapMode: Text.WordWrap; width: 300 }", QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-        textHeight = textObject->height();
-
-        QVERIFY(textObject != 0);
-        QVERIFY(textObject->wrapMode() == QSGText::WordWrap);
-        QCOMPARE(textObject->width(), 300.);
-
-        delete textObject;
-    }
-
-    for (int i = 0; i < standard.size(); i++)
-    {
-        QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; text: \"" + standard.at(i) + "\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE(textObject->width(), 30.);
-        QVERIFY(textObject->height() > textHeight);
-
-        int oldHeight = textObject->height();
-        textObject->setWidth(100);
-        QVERIFY(textObject->height() < oldHeight);
-
-        delete textObject;
-    }
-
-    for (int i = 0; i < richText.size(); i++)
-    {
-        QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; text: \"" + richText.at(i) + "\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE(textObject->width(), 30.);
-        QVERIFY(textObject->height() > textHeight);
-
-        qreal oldHeight = textObject->height();
-        textObject->setWidth(100);
-        QVERIFY(textObject->height() < oldHeight);
-
-        delete textObject;
-    }
-
-    // richtext again with a fixed height
-    for (int i = 0; i < richText.size(); i++)
-    {
-        QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; height: 50; text: \"" + richText.at(i) + "\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE(textObject->width(), 30.);
-        QVERIFY(textObject->implicitHeight() > textHeight);
-
-        qreal oldHeight = textObject->implicitHeight();
-        textObject->setWidth(100);
-        QVERIFY(textObject->implicitHeight() < oldHeight);
-
-        delete textObject;
-    }
-}
-
-void tst_qsgtext::elide()
-{
-    for (QSGText::TextElideMode m = QSGText::ElideLeft; m<=QSGText::ElideNone; m=QSGText::TextElideMode(int(m)+1)) {
-        const char* elidename[]={"ElideLeft", "ElideRight", "ElideMiddle", "ElideNone"};
-        QString elide = "elide: Text." + QString(elidename[int(m)]) + ";";
-
-        // XXX Poor coverage.
-
-        {
-            QDeclarativeComponent textComponent(&engine);
-            textComponent.setData(("import QtQuick 2.0\nText { text: \"\"; "+elide+" width: 100 }").toLatin1(), QUrl::fromLocalFile(""));
-            QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-            QCOMPARE(textObject->elideMode(), m);
-            QCOMPARE(textObject->width(), 100.);
-
-            delete textObject;
-        }
-
-        for (int i = 0; i < standard.size(); i++)
-        {
-            QString componentStr = "import QtQuick 2.0\nText { "+elide+" width: 100; text: \"" + standard.at(i) + "\" }";
-            QDeclarativeComponent textComponent(&engine);
-            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-            QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-            QCOMPARE(textObject->elideMode(), m);
-            QCOMPARE(textObject->width(), 100.);
-
-            delete textObject;
-        }
-
-        // richtext - does nothing
-        for (int i = 0; i < richText.size(); i++)
-        {
-            QString componentStr = "import QtQuick 2.0\nText { "+elide+" width: 100; text: \"" + richText.at(i) + "\" }";
-            QDeclarativeComponent textComponent(&engine);
-            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-            QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-            QCOMPARE(textObject->elideMode(), m);
-            QCOMPARE(textObject->width(), 100.);
-
-            delete textObject;
-        }
-    }
-}
-
-void tst_qsgtext::textFormat()
-{
-    {
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData("import QtQuick 2.0\nText { text: \"Hello\"; textFormat: Text.RichText }", QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        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;
-    }
-    {
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData("import QtQuick 2.0\nText { text: \"<b>Hello</b>\"; textFormat: Text.PlainText }", QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QVERIFY(textObject->textFormat() == QSGText::PlainText);
-
-        delete textObject;
-    }
-}
-
-
-void tst_qsgtext::alignments_data()
-{
-    QTest::addColumn<int>("hAlign");
-    QTest::addColumn<int>("vAlign");
-    QTest::addColumn<QString>("expectfile");
-
-    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) << 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) << 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");
-#if (0)// No widgets in scenegraph
-    QFETCH(int, hAlign);
-    QFETCH(int, vAlign);
-    QFETCH(QString, expectfile);
-
-#ifdef Q_WS_X11
-    // Font-specific, but not likely platform-specific, so only test on one platform
-    QFont fn;
-    fn.setRawName("-misc-fixed-medium-r-*-*-8-*-*-*-*-*-*-*");
-    QApplication::setFont(fn);
-#endif
-
-    QSGView *canvas = createView(TESTDATA("alignments.qml"));
-
-    canvas->show();
-    canvas->requestActivateWindow();
-    QTest::qWait(50);
-    QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
-
-    QObject *ob = canvas->rootObject();
-    QVERIFY(ob != 0);
-    ob->setProperty("horizontalAlignment",hAlign);
-    ob->setProperty("verticalAlignment",vAlign);
-    QTRY_COMPARE(ob->property("running").toBool(),false);
-    QImage actual(canvas->width(), canvas->height(), QImage::Format_RGB32);
-    actual.fill(qRgb(255,255,255));
-    QPainter p(&actual);
-    canvas->render(&p);
-
-    QImage expect(expectfile);
-
-#ifdef Q_WS_X11
-    // Font-specific, but not likely platform-specific, so only test on one platform
-    if (QApplicationPrivate::graphics_system_name == "raster" || QApplicationPrivate::graphics_system_name == "") {
-        QCOMPARE(actual,expect);
-    }
-#endif
-
-    delete canvas;
-#endif
-}
-
-//the alignment tests may be trivial o.oa
-void tst_qsgtext::horizontalAlignment()
-{
-    //test one align each, and then test if two align fails.
-
-    for (int i = 0; i < standard.size(); i++)
-    {
-        for (int j=0; j < horizontalAlignmentmentStrings.size(); j++)
-        {
-            QString componentStr = "import QtQuick 2.0\nText { horizontalAlignment: \"" + horizontalAlignmentmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }";
-            QDeclarativeComponent textComponent(&engine);
-            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-            QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-            QCOMPARE((int)textObject->hAlign(), (int)horizontalAlignmentments.at(j));
-
-            delete textObject;
-        }
-    }
-
-    for (int i = 0; i < richText.size(); i++)
-    {
-        for (int j=0; j < horizontalAlignmentmentStrings.size(); j++)
-        {
-            QString componentStr = "import QtQuick 2.0\nText { horizontalAlignment: \"" + horizontalAlignmentmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }";
-            QDeclarativeComponent textComponent(&engine);
-            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-            QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-            QCOMPARE((int)textObject->hAlign(), (int)horizontalAlignmentments.at(j));
-
-            delete textObject;
-        }
-    }
-
-}
-
-void tst_qsgtext::horizontalAlignment_RightToLeft()
-{
-    QSGView *canvas = createView(TESTDATA("horizontalAlignment_RightToLeft.qml"));
-    QSGText *text = canvas->rootObject()->findChild<QSGText*>("text");
-    QVERIFY(text != 0);
-    canvas->show();
-
-    QSGTextPrivate *textPrivate = QSGTextPrivate::get(text);
-    QVERIFY(textPrivate != 0);
-
-    // implicit alignment should follow the reading direction of RTL text
-    QCOMPARE(text->hAlign(), QSGText::AlignRight);
-    QCOMPARE(text->effectiveHAlign(), text->hAlign());
-    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
-
-    // explicitly left aligned text
-    text->setHAlign(QSGText::AlignLeft);
-    QCOMPARE(text->hAlign(), QSGText::AlignLeft);
-    QCOMPARE(text->effectiveHAlign(), text->hAlign());
-    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
-
-    // explicitly right aligned text
-    text->setHAlign(QSGText::AlignRight);
-    QCOMPARE(text->hAlign(), QSGText::AlignRight);
-    QCOMPARE(text->effectiveHAlign(), text->hAlign());
-    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
-
-    // change to rich text
-    QString textString = text->text();
-    text->setText(QString("<i>") + textString + QString("</i>"));
-    text->setTextFormat(QSGText::RichText);
-    text->resetHAlign();
-
-    // implicitly aligned rich text should follow the reading direction of text
-    QCOMPARE(text->hAlign(), QSGText::AlignRight);
-    QCOMPARE(text->effectiveHAlign(), text->hAlign());
-    QVERIFY(textPrivate->textDocument()->defaultTextOption().alignment() & Qt::AlignLeft);
-
-    // explicitly left aligned rich text
-    text->setHAlign(QSGText::AlignLeft);
-    QCOMPARE(text->hAlign(), QSGText::AlignLeft);
-    QCOMPARE(text->effectiveHAlign(), text->hAlign());
-    QVERIFY(textPrivate->textDocument()->defaultTextOption().alignment() & Qt::AlignRight);
-
-    // explicitly right aligned rich text
-    text->setHAlign(QSGText::AlignRight);
-    QCOMPARE(text->hAlign(), QSGText::AlignRight);
-    QCOMPARE(text->effectiveHAlign(), text->hAlign());
-    QVERIFY(textPrivate->textDocument()->defaultTextOption().alignment() & Qt::AlignLeft);
-
-    text->setText(textString);
-    text->setTextFormat(QSGText::PlainText);
-
-    // explicitly center aligned
-    text->setHAlign(QSGText::AlignHCenter);
-    QCOMPARE(text->hAlign(), QSGText::AlignHCenter);
-    QCOMPARE(text->effectiveHAlign(), text->hAlign());
-    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
-    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().right() > canvas->width()/2);
-
-    // reseted alignment should go back to following the text reading direction
-    text->resetHAlign();
-    QCOMPARE(text->hAlign(), QSGText::AlignRight);
-    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
-
-    // mirror the text item
-    QSGItemPrivate::get(text)->setLayoutMirror(true);
-
-    // mirrored implicit alignment should continue to follow the reading direction of the text
-    QCOMPARE(text->hAlign(), QSGText::AlignRight);
-    QCOMPARE(text->effectiveHAlign(), QSGText::AlignRight);
-    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
-
-    // mirrored explicitly right aligned behaves as left aligned
-    text->setHAlign(QSGText::AlignRight);
-    QCOMPARE(text->hAlign(), QSGText::AlignRight);
-    QCOMPARE(text->effectiveHAlign(), QSGText::AlignLeft);
-    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
-
-    // mirrored explicitly left aligned behaves as right aligned
-    text->setHAlign(QSGText::AlignLeft);
-    QCOMPARE(text->hAlign(), QSGText::AlignLeft);
-    QCOMPARE(text->effectiveHAlign(), QSGText::AlignRight);
-    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
-
-    // disable mirroring
-    QSGItemPrivate::get(text)->setLayoutMirror(false);
-    text->resetHAlign();
-
-    // English text should be implicitly left aligned
-    text->setText("Hello world!");
-    QCOMPARE(text->hAlign(), QSGText::AlignLeft);
-    QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
-
-#ifndef Q_OS_MAC    // QTBUG-18040
-    // empty text with implicit alignment follows the system locale-based
-    // keyboard input direction from QApplication::keyboardInputDirection
-    text->setText("");
-    QCOMPARE(text->hAlign(), QApplication::keyboardInputDirection() == Qt::LeftToRight ?
-                                  QSGText::AlignLeft : QSGText::AlignRight);
-    text->setHAlign(QSGText::AlignRight);
-    QCOMPARE(text->hAlign(), QSGText::AlignRight);
-#endif
-
-    delete canvas;
-
-#ifndef Q_OS_MAC    // QTBUG-18040
-    // alignment of Text with no text set to it
-    QString componentStr = "import QtQuick 2.0\nText {}";
-    QDeclarativeComponent textComponent(&engine);
-    textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-    QCOMPARE(textObject->hAlign(), QApplication::keyboardInputDirection() == Qt::LeftToRight ?
-                                  QSGText::AlignLeft : QSGText::AlignRight);
-    delete textObject;
-#endif
-}
-
-void tst_qsgtext::verticalAlignment()
-{
-    //test one align each, and then test if two align fails.
-
-    for (int i = 0; i < standard.size(); i++)
-    {
-        for (int j=0; j < verticalAlignmentmentStrings.size(); j++)
-        {
-            QString componentStr = "import QtQuick 2.0\nText { verticalAlignment: \"" + verticalAlignmentmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }";
-            QDeclarativeComponent textComponent(&engine);
-            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-            QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-            QVERIFY(textObject != 0);
-            QCOMPARE((int)textObject->vAlign(), (int)verticalAlignmentments.at(j));
-
-            delete textObject;
-        }
-    }
-
-    for (int i = 0; i < richText.size(); i++)
-    {
-        for (int j=0; j < verticalAlignmentmentStrings.size(); j++)
-        {
-            QString componentStr = "import QtQuick 2.0\nText { verticalAlignment: \"" + verticalAlignmentmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }";
-            QDeclarativeComponent textComponent(&engine);
-            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-            QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-            QVERIFY(textObject != 0);
-            QCOMPARE((int)textObject->vAlign(), (int)verticalAlignmentments.at(j));
-
-            delete textObject;
-        }
-    }
-
-}
-
-void tst_qsgtext::font()
-{
-    //test size, then bold, then italic, then family
-    {
-        QString componentStr = "import QtQuick 2.0\nText { font.pointSize: 40; text: \"Hello World\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QCOMPARE(textObject->font().pointSize(), 40);
-        QCOMPARE(textObject->font().bold(), false);
-        QCOMPARE(textObject->font().italic(), false);
-
-        delete textObject;
-    }
-
-    {
-        QString componentStr = "import QtQuick 2.0\nText { font.pixelSize: 40; text: \"Hello World\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QCOMPARE(textObject->font().pixelSize(), 40);
-        QCOMPARE(textObject->font().bold(), false);
-        QCOMPARE(textObject->font().italic(), false);
-
-        delete textObject;
-    }
-
-    {
-        QString componentStr = "import QtQuick 2.0\nText { font.bold: true; text: \"Hello World\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QCOMPARE(textObject->font().bold(), true);
-        QCOMPARE(textObject->font().italic(), false);
-
-        delete textObject;
-    }
-
-    {
-        QString componentStr = "import QtQuick 2.0\nText { font.italic: true; text: \"Hello World\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QCOMPARE(textObject->font().italic(), true);
-        QCOMPARE(textObject->font().bold(), false);
-
-        delete textObject;
-    }
-
-    {
-        QString componentStr = "import QtQuick 2.0\nText { font.family: \"Helvetica\"; text: \"Hello World\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QCOMPARE(textObject->font().family(), QString("Helvetica"));
-        QCOMPARE(textObject->font().bold(), false);
-        QCOMPARE(textObject->font().italic(), false);
-
-        delete textObject;
-    }
-
-    {
-        QString componentStr = "import QtQuick 2.0\nText { font.family: \"\"; text: \"Hello World\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QCOMPARE(textObject->font().family(), QString(""));
-
-        delete textObject;
-    }
-}
-
-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(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QCOMPARE((int)textObject->style(), (int)styles.at(i));
-        QCOMPARE(textObject->styleColor(), QColor("white"));
-
-        delete textObject;
-    }
-    QString componentStr = "import QtQuick 2.0\nText { text: \"Hello World\" }";
-    QDeclarativeComponent textComponent(&engine);
-    textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-    QRectF brPre = textObject->boundingRect();
-    textObject->setStyle(QSGText::Outline);
-    QRectF brPost = textObject->boundingRect();
-
-    QVERIFY(brPre.width() < brPost.width());
-    QVERIFY(brPre.height() < brPost.height());
-
-    delete textObject;
-}
-
-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(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QCOMPARE(textObject->color(), QColor(colorStrings.at(i)));
-        QCOMPARE(textObject->styleColor(), QColor());
-
-        delete textObject;
-    }
-
-    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(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QCOMPARE(textObject->styleColor(), QColor(colorStrings.at(i)));
-        // default color to black?
-        QCOMPARE(textObject->color(), QColor("black"));
-
-        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\" }";
-            QDeclarativeComponent textComponent(&engine);
-            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-            QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-            QCOMPARE(textObject->color(), QColor(colorStrings.at(i)));
-            QCOMPARE(textObject->styleColor(), QColor(colorStrings.at(j)));
-
-            delete textObject;
-        }
-    }
-    {
-        QString colorStr = "#AA001234";
-        QColor testColor("#001234");
-        testColor.setAlpha(170);
-
-        QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStr + "\"; text: \"Hello World\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QCOMPARE(textObject->color(), testColor);
-
-        delete textObject;
-    }
-}
-
-void tst_qsgtext::smooth()
-{
-    for (int i = 0; i < standard.size(); i++)
-    {
-        {
-            QString componentStr = "import QtQuick 2.0\nText { smooth: true; text: \"" + standard.at(i) + "\" }";
-            QDeclarativeComponent textComponent(&engine);
-            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-            QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-            QCOMPARE(textObject->smooth(), true);
-
-            delete textObject;
-        }
-        {
-            QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }";
-            QDeclarativeComponent textComponent(&engine);
-            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-            QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-            QCOMPARE(textObject->smooth(), false);
-
-            delete textObject;
-        }
-    }
-    for (int i = 0; i < richText.size(); i++)
-    {
-        {
-            QString componentStr = "import QtQuick 2.0\nText { smooth: true; text: \"" + richText.at(i) + "\" }";
-            QDeclarativeComponent textComponent(&engine);
-            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-            QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-            QCOMPARE(textObject->smooth(), true);
-
-            delete textObject;
-        }
-        {
-            QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\" }";
-            QDeclarativeComponent textComponent(&engine);
-            textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-            QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-            QCOMPARE(textObject->smooth(), false);
-
-            delete textObject;
-        }
-    }
-}
-
-void tst_qsgtext::weight()
-{
-    {
-        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE((int)textObject->font().weight(), (int)QDeclarativeFontValueType::Normal);
-
-        delete textObject;
-    }
-    {
-        QString componentStr = "import QtQuick 2.0\nText { font.weight: \"Bold\"; text: \"Hello world!\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE((int)textObject->font().weight(), (int)QDeclarativeFontValueType::Bold);
-
-        delete textObject;
-    }
-}
-
-void tst_qsgtext::underline()
-{
-    {
-        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE(textObject->font().underline(), false);
-
-        delete textObject;
-    }
-    {
-        QString componentStr = "import QtQuick 2.0\nText { font.underline: true; text: \"Hello world!\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE(textObject->font().underline(), true);
-
-        delete textObject;
-    }
-}
-
-void tst_qsgtext::overline()
-{
-    {
-        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE(textObject->font().overline(), false);
-
-        delete textObject;
-    }
-    {
-        QString componentStr = "import QtQuick 2.0\nText { font.overline: true; text: \"Hello world!\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE(textObject->font().overline(), true);
-
-        delete textObject;
-    }
-}
-
-void tst_qsgtext::strikeout()
-{
-    {
-        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE(textObject->font().strikeOut(), false);
-
-        delete textObject;
-    }
-    {
-        QString componentStr = "import QtQuick 2.0\nText { font.strikeout: true; text: \"Hello world!\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE(textObject->font().strikeOut(), true);
-
-        delete textObject;
-    }
-}
-
-void tst_qsgtext::capitalization()
-{
-    {
-        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::MixedCase);
-
-        delete textObject;
-    }
-    {
-        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"AllUppercase\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::AllUppercase);
-
-        delete textObject;
-    }
-    {
-        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"AllLowercase\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::AllLowercase);
-
-        delete textObject;
-    }
-    {
-        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"SmallCaps\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::SmallCaps);
-
-        delete textObject;
-    }
-    {
-        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"Capitalize\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::Capitalize);
-
-        delete textObject;
-    }
-}
-
-void tst_qsgtext::letterSpacing()
-{
-    {
-        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE(textObject->font().letterSpacing(), 0.0);
-
-        delete textObject;
-    }
-    {
-        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.letterSpacing: -2 }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE(textObject->font().letterSpacing(), -2.);
-
-        delete textObject;
-    }
-    {
-        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.letterSpacing: 3 }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE(textObject->font().letterSpacing(), 3.);
-
-        delete textObject;
-    }
-}
-
-void tst_qsgtext::wordSpacing()
-{
-    {
-        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE(textObject->font().wordSpacing(), 0.0);
-
-        delete textObject;
-    }
-    {
-        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.wordSpacing: -50 }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE(textObject->font().wordSpacing(), -50.);
-
-        delete textObject;
-    }
-    {
-        QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.wordSpacing: 200 }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QCOMPARE(textObject->font().wordSpacing(), 200.);
-
-        delete textObject;
-    }
-}
-
-
-
-
-class EventSender : public QSGItem
-{
-public:
-    void sendEvent(QMouseEvent *event) {
-        if (event->type() == QEvent::MouseButtonPress)
-            mousePressEvent(event);
-        else if (event->type() == QEvent::MouseButtonRelease)
-            mouseReleaseEvent(event);
-        else
-            qWarning() << "Trying to send unsupported event type";
-    }
-};
-
-class LinkTest : public QObject
-{
-    Q_OBJECT
-public:
-    LinkTest() {}
-
-    QString link;
-
-public slots:
-    void linkClicked(QString l) { link = l; }
-};
-
-void tst_qsgtext::clickLink()
-{
-    {
-        QString componentStr = "import QtQuick 2.0\nText { text: \"<a href=\\\"http://qt.nokia.com\\\">Hello world!</a>\" }";
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-        QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-
-        LinkTest test;
-        QObject::connect(textObject, SIGNAL(linkActivated(QString)), &test, SLOT(linkClicked(QString)));
-
-        {
-            QMouseEvent me(QEvent::MouseButtonPress,QPointF(textObject->x()/2, textObject->y()/2), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
-            static_cast<EventSender*>(static_cast<QSGItem*>(textObject))->sendEvent(&me);
-
-        }
-
-        {
-            QMouseEvent me(QEvent::MouseButtonRelease,QPointF(textObject->x()/2, textObject->y()/2), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
-            static_cast<EventSender*>(static_cast<QSGItem*>(textObject))->sendEvent(&me);
-
-        }
-
-
-        QCOMPARE(test.link, QLatin1String("http://qt.nokia.com"));
-
-        delete textObject;
-    }
-}
-
-void tst_qsgtext::embeddedImages_data()
-{
-    QTest::addColumn<QUrl>("qmlfile");
-    QTest::addColumn<QString>("error");
-    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()
-{
-    // Tests QTBUG-9900
-
-    QFETCH(QUrl, qmlfile);
-    QFETCH(QString, error);
-
-    TestHTTPServer server(14453);
-    server.serveDirectory(TESTDATA("http"));
-
-    if (!error.isEmpty())
-        QTest::ignoreMessage(QtWarningMsg, error.toLatin1());
-
-    QDeclarativeComponent textComponent(&engine, qmlfile);
-    QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-    QVERIFY(textObject != 0);
-
-    QTRY_COMPARE(textObject->resourcesLoading(), 0);
-
-    QPixmap pm(TESTDATA("http/exists.png"));
-    if (error.isEmpty()) {
-        QCOMPARE(textObject->width(), double(pm.width()));
-        QCOMPARE(textObject->height(), double(pm.height()));
-    } else {
-        QVERIFY(16 != pm.width()); // check test is effective
-        QCOMPARE(textObject->width(), 16.0); // default size of QTextDocument broken image icon
-        QCOMPARE(textObject->height(), 16.0);
-    }
-
-    delete textObject;
-}
-
-void tst_qsgtext::lineCount()
-{
-    QSGView *canvas = createView(TESTDATA("lineCount.qml"));
-
-    QSGText *myText = canvas->rootObject()->findChild<QSGText*>("myText");
-    QVERIFY(myText != 0);
-
-    QVERIFY(myText->lineCount() > 1);
-    QVERIFY(!myText->truncated());
-    QCOMPARE(myText->maximumLineCount(), INT_MAX);
-
-    myText->setMaximumLineCount(2);
-    QCOMPARE(myText->lineCount(), 2);
-    QCOMPARE(myText->truncated(), true);
-    QCOMPARE(myText->maximumLineCount(), 2);
-
-    myText->resetMaximumLineCount();
-    QCOMPARE(myText->maximumLineCount(), INT_MAX);
-    QCOMPARE(myText->truncated(), false);
-
-    myText->setElideMode(QSGText::ElideRight);
-    myText->setMaximumLineCount(2);
-    QCOMPARE(myText->lineCount(), 2);
-    QCOMPARE(myText->truncated(), true);
-    QCOMPARE(myText->maximumLineCount(), 2);
-
-    delete canvas;
-}
-
-void tst_qsgtext::lineHeight()
-{
-    QSGView *canvas = createView(TESTDATA("lineHeight.qml"));
-
-    QSGText *myText = canvas->rootObject()->findChild<QSGText*>("myText");
-    QVERIFY(myText != 0);
-
-    QVERIFY(myText->lineHeight() == 1);
-    QVERIFY(myText->lineHeightMode() == QSGText::ProportionalHeight);
-
-    qreal h = myText->height();
-    myText->setLineHeight(1.5);
-#ifdef Q_WS_QPA
-    QEXPECT_FAIL("", "QTBUG-21009 fails", Continue);
-#endif
-    QVERIFY(myText->height() == h * 1.5);
-
-    myText->setLineHeightMode(QSGText::FixedHeight);
-    myText->setLineHeight(20);
-    QCOMPARE(myText->height(), myText->lineCount() * 20.0);
-
-    myText->setText("Lorem ipsum sit <b>amet</b>, consectetur adipiscing elit. Integer felis nisl, varius in pretium nec, venenatis non erat. Proin lobortis interdum dictum.");
-    myText->setLineHeightMode(QSGText::ProportionalHeight);
-    myText->setLineHeight(1.0);
-
-    qreal h2 = myText->height();
-    myText->setLineHeight(2.0);
-    QVERIFY(myText->height() == h2 * 2.0);
-
-    myText->setLineHeightMode(QSGText::FixedHeight);
-    myText->setLineHeight(10);
-    QCOMPARE(myText->height(), myText->lineCount() * 10.0);
-
-    delete canvas;
-}
-
-void tst_qsgtext::implicitSize_data()
-{
-    QTest::addColumn<QString>("text");
-    QTest::addColumn<QString>("wrap");
-    QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "Text.NoWrap";
-    QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "Text.NoWrap";
-    QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "Text.Wrap";
-    QTest::newRow("richtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "Text.Wrap";
-}
-
-void tst_qsgtext::implicitSize()
-{
-    QFETCH(QString, text);
-    QFETCH(QString, wrap);
-    QString componentStr = "import QtQuick 2.0\nText { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + " }";
-    QDeclarativeComponent textComponent(&engine);
-    textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGText *textObject = qobject_cast<QSGText*>(textComponent.create());
-
-    QVERIFY(textObject->width() < textObject->implicitWidth());
-    QVERIFY(textObject->height() == textObject->implicitHeight());
-
-    textObject->resetWidth();
-    QVERIFY(textObject->width() == textObject->implicitWidth());
-    QVERIFY(textObject->height() == textObject->implicitHeight());
-
-    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)
-
-#include "tst_qsgtext.moc"
diff --git a/tests/auto/declarative/qsgtextedit/qsgtextedit.pro b/tests/auto/declarative/qsgtextedit/qsgtextedit.pro
deleted file mode 100644 (file)
index 41c7b65..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsgtextedit
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_qsgtextedit.cpp ../shared/testhttpserver.cpp
-HEADERS += ../shared/testhttpserver.h
-
-testDataFiles.files = data
-testDataFiles.path = .
-DEPLOYMENT += testDataFiles
-
-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
deleted file mode 100644 (file)
index 9b48b5f..0000000
+++ /dev/null
@@ -1,2467 +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 <QtTest/QSignalSpy>
-#include "../shared/testhttpserver.h"
-#include <math.h>
-#include <QFile>
-#include <QTextDocument>
-#include <QtDeclarative/qdeclarativeengine.h>
-#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>
-#include <QFontMetrics>
-#include <QSGView>
-#include <QDir>
-#include <QStyle>
-#include <QInputContext>
-#include <QInputPanel>
-#include <QClipboard>
-#include <QMimeData>
-#include <private/qtextcontrol_p.h>
-#include "../shared/util.h"
-
-#ifdef Q_WS_MAC
-#include <Carbon/Carbon.h>
-#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)
-
-QString createExpectedFileIfNotFound(const QString& filebasename, const QImage& actual)
-{
-    // XXX This will be replaced by some clever persistent platform image store.
-    QString persistent_dir = TESTDATA("");
-    QString arch = "unknown-architecture"; // QTest needs to help with this.
-
-    QString expectfile = persistent_dir + QDir::separator() + filebasename + "-" + arch + ".png";
-
-    if (!QFile::exists(expectfile)) {
-        actual.save(expectfile);
-        qWarning() << "created" << expectfile;
-    }
-
-    return expectfile;
-}
-
-
-class tst_qsgtextedit : public QObject
-
-{
-    Q_OBJECT
-public:
-    tst_qsgtextedit();
-
-private slots:
-    void initTestCase();
-    void cleanupTestCase();
-    void text();
-    void width();
-    void wrap();
-    void textFormat();
-    void alignments();
-    void alignments_data();
-
-    // ### these tests may be trivial
-    void hAlign();
-    void hAlign_RightToLeft();
-    void vAlign();
-    void font();
-    void color();
-    void textMargin();
-    void persistentSelection();
-    void focusOnPress();
-    void selection();
-    void isRightToLeft_data();
-    void isRightToLeft();
-    void keySelection();
-    void moveCursorSelection_data();
-    void moveCursorSelection();
-    void moveCursorSelectionSequence_data();
-    void moveCursorSelectionSequence();
-    void mouseSelection_data();
-    void mouseSelection();
-    void mouseSelectionMode_data();
-    void mouseSelectionMode();
-    void dragMouseSelection();
-    void inputMethodHints();
-
-    void positionAt();
-
-    void cursorDelegate();
-    void cursorVisible();
-    void delegateLoading_data();
-    void delegateLoading();
-    void navigation();
-    void readOnly();
-    void copyAndPaste();
-    void canPaste();
-    void canPasteEmpty();
-    void textInput();
-    void openInputPanel();
-    void geometrySignals();
-    void pastingRichText_QTBUG_14003();
-    void implicitSize_data();
-    void implicitSize();
-    void testQtQuick11Attributes();
-    void testQtQuick11Attributes_data();
-
-    void preeditMicroFocus();
-    void inputContextMouseHandler();
-    void inputMethodComposing();
-    void cursorRectangleSize();
-
-    void emptytags_QTBUG_22058();
-
-private:
-    void simulateKey(QSGView *, int key, Qt::KeyboardModifiers modifiers = 0);
-
-    QStringList standard;
-    QStringList richText;
-
-    QStringList hAlignmentStrings;
-    QStringList vAlignmentStrings;
-
-    QList<Qt::Alignment> vAlignments;
-    QList<Qt::Alignment> hAlignments;
-
-    QStringList colorStrings;
-
-    QDeclarativeEngine engine;
-};
-void tst_qsgtextedit::initTestCase()
-{
-}
-
-void tst_qsgtextedit::cleanupTestCase()
-{
-
-}
-tst_qsgtextedit::tst_qsgtextedit()
-{
-    standard << "the quick brown fox jumped over the lazy dog"
-             << "the quick brown fox\n jumped over the lazy dog"
-             << "Hello, world!"
-             << "!dlrow ,olleH";
-
-    richText << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a> jumped over the <b>lazy</b> dog</i>"
-             << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a><br>jumped over the <b>lazy</b> dog</i>";
-
-    hAlignmentStrings << "AlignLeft"
-                      << "AlignRight"
-                      << "AlignHCenter";
-
-    vAlignmentStrings << "AlignTop"
-                      << "AlignBottom"
-                      << "AlignVCenter";
-
-    hAlignments << Qt::AlignLeft
-                << Qt::AlignRight
-                << Qt::AlignHCenter;
-
-    vAlignments << Qt::AlignTop
-                << Qt::AlignBottom
-                << Qt::AlignVCenter;
-
-    colorStrings << "aliceblue"
-                 << "antiquewhite"
-                 << "aqua"
-                 << "darkkhaki"
-                 << "darkolivegreen"
-                 << "dimgray"
-                 << "palevioletred"
-                 << "lightsteelblue"
-                 << "#000000"
-                 << "#AAAAAA"
-                 << "#FFFFFF"
-                 << "#2AC05F";
-                 //
-                 // need a different test to do alpha channel test
-                 // << "#AA0011DD"
-                 // << "#00F16B11";
-                 //
-}
-
-void tst_qsgtextedit::text()
-{
-    {
-        QDeclarativeComponent texteditComponent(&engine);
-        texteditComponent.setData("import QtQuick 2.0\nTextEdit {  text: \"\"  }", QUrl());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->text(), QString(""));
-    }
-
-    for (int i = 0; i < standard.size(); i++)
-    {
-        QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + standard.at(i) + "\" }";
-        QDeclarativeComponent texteditComponent(&engine);
-        texteditComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->text(), standard.at(i));
-    }
-
-    for (int i = 0; i < richText.size(); i++)
-    {
-        QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + richText.at(i) + "\" }";
-        QDeclarativeComponent texteditComponent(&engine);
-        texteditComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-        QVERIFY(textEditObject != 0);
-        QString actual = textEditObject->text();
-        QString expected = richText.at(i);
-        actual.replace(QRegExp(".*<body[^>]*>"),"");
-        actual.replace(QRegExp("(<[^>]*>)+"),"<>");
-        expected.replace(QRegExp("(<[^>]*>)+"),"<>");
-        QCOMPARE(actual.simplified(),expected.simplified());
-    }
-}
-
-void tst_qsgtextedit::width()
-{
-    // uses Font metrics to find the width for standard and document to find the width for rich
-    {
-        QDeclarativeComponent texteditComponent(&engine);
-        texteditComponent.setData("import QtQuick 2.0\nTextEdit {  text: \"\" }", QUrl());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->width(), 0.0);
-    }
-
-    bool requiresUnhintedMetrics = !qmlDisableDistanceField();
-
-    for (int i = 0; i < standard.size(); i++)
-    {
-        QFont f;
-        qreal metricWidth = 0.0;
-
-        if (requiresUnhintedMetrics) {
-            QString s = standard.at(i);
-            s.replace(QLatin1Char('\n'), QChar::LineSeparator);
-
-            QTextLayout layout(s);
-            layout.setFlags(Qt::TextExpandTabs | Qt::TextShowMnemonic);
-            {
-                QTextOption option;
-                option.setUseDesignMetrics(true);
-                layout.setTextOption(option);
-            }
-
-            layout.beginLayout();
-            forever {
-                QTextLine line = layout.createLine();
-                if (!line.isValid())
-                    break;
-            }
-
-            layout.endLayout();
-
-            metricWidth = ceil(layout.boundingRect().width());
-        } else {
-            QFontMetricsF fm(f);
-            metricWidth = fm.size(Qt::TextExpandTabs | Qt::TextShowMnemonic, standard.at(i)).width();
-            metricWidth = ceil(metricWidth);
-        }
-
-        QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + standard.at(i) + "\" }";
-        QDeclarativeComponent texteditComponent(&engine);
-        texteditComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->width(), qreal(metricWidth));
-    }
-
-    for (int i = 0; i < richText.size(); i++)
-    {
-        QTextDocument document;
-        document.setHtml(richText.at(i));
-        document.setDocumentMargin(0);
-        if (requiresUnhintedMetrics)
-            document.setUseDesignMetrics(true);
-
-        int documentWidth = ceil(document.idealWidth());
-
-        QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + richText.at(i) + "\" }";
-        QDeclarativeComponent texteditComponent(&engine);
-        texteditComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->width(), qreal(documentWidth));
-    }
-}
-
-void tst_qsgtextedit::wrap()
-{
-    // for specified width and wrap set true
-    {
-        QDeclarativeComponent texteditComponent(&engine);
-        texteditComponent.setData("import QtQuick 2.0\nTextEdit {  text: \"\"; wrapMode: TextEdit.WordWrap; width: 300 }", QUrl());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->width(), 300.);
-    }
-
-    for (int i = 0; i < standard.size(); i++)
-    {
-        QString componentStr = "import QtQuick 2.0\nTextEdit {  wrapMode: TextEdit.WordWrap; width: 300; text: \"" + standard.at(i) + "\" }";
-        QDeclarativeComponent texteditComponent(&engine);
-        texteditComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->width(), 300.);
-    }
-
-    for (int i = 0; i < richText.size(); i++)
-    {
-        QString componentStr = "import QtQuick 2.0\nTextEdit {  wrapMode: TextEdit.WordWrap; width: 300; text: \"" + richText.at(i) + "\" }";
-        QDeclarativeComponent texteditComponent(&engine);
-        texteditComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->width(), 300.);
-    }
-
-}
-
-void tst_qsgtextedit::textFormat()
-{
-    {
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData("import QtQuick 2.0\nTextEdit { text: \"Hello\"; textFormat: Text.RichText }", QUrl::fromLocalFile(""));
-        QSGTextEdit *textObject = qobject_cast<QSGTextEdit*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QVERIFY(textObject->textFormat() == QSGTextEdit::RichText);
-    }
-    {
-        QDeclarativeComponent textComponent(&engine);
-        textComponent.setData("import QtQuick 2.0\nTextEdit { text: \"<b>Hello</b>\"; textFormat: Text.PlainText }", QUrl::fromLocalFile(""));
-        QSGTextEdit *textObject = qobject_cast<QSGTextEdit*>(textComponent.create());
-
-        QVERIFY(textObject != 0);
-        QVERIFY(textObject->textFormat() == QSGTextEdit::PlainText);
-    }
-}
-
-void tst_qsgtextedit::alignments_data()
-{
-    QTest::addColumn<int>("hAlign");
-    QTest::addColumn<int>("vAlign");
-    QTest::addColumn<QString>("expectfile");
-
-    QTest::newRow("LT") << int(Qt::AlignLeft) << int(Qt::AlignTop) << "alignments_lt";
-    QTest::newRow("RT") << int(Qt::AlignRight) << int(Qt::AlignTop) << "alignments_rt";
-    QTest::newRow("CT") << int(Qt::AlignHCenter) << int(Qt::AlignTop) << "alignments_ct";
-
-    QTest::newRow("LB") << int(Qt::AlignLeft) << int(Qt::AlignBottom) << "alignments_lb";
-    QTest::newRow("RB") << int(Qt::AlignRight) << int(Qt::AlignBottom) << "alignments_rb";
-    QTest::newRow("CB") << int(Qt::AlignHCenter) << int(Qt::AlignBottom) << "alignments_cb";
-
-    QTest::newRow("LC") << int(Qt::AlignLeft) << int(Qt::AlignVCenter) << "alignments_lc";
-    QTest::newRow("RC") << int(Qt::AlignRight) << int(Qt::AlignVCenter) << "alignments_rc";
-    QTest::newRow("CC") << int(Qt::AlignHCenter) << int(Qt::AlignVCenter) << "alignments_cc";
-}
-
-
-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(TESTDATA("alignments.qml")));
-
-    canvas.show();
-    canvas.requestActivateWindow();
-    QTest::qWaitForWindowShown(&canvas);
-    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
-
-    QObject *ob = canvas.rootObject();
-    QVERIFY(ob != 0);
-    ob->setProperty("horizontalAlignment",hAlign);
-    ob->setProperty("verticalAlignment",vAlign);
-    QTRY_COMPARE(ob->property("running").toBool(),false);
-    QImage actual = canvas.grabFrameBuffer();
-
-    expectfile = createExpectedFileIfNotFound(expectfile, actual);
-
-    QImage expect(expectfile);
-
-    QCOMPARE(actual,expect);
-}
-
-
-//the alignment tests may be trivial o.oa
-void tst_qsgtextedit::hAlign()
-{
-    //test one align each, and then test if two align fails.
-
-    for (int i = 0; i < standard.size(); i++)
-    {
-        for (int j=0; j < hAlignmentStrings.size(); j++)
-        {
-            QString componentStr = "import QtQuick 2.0\nTextEdit {  horizontalAlignment: \"" + hAlignmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }";
-            QDeclarativeComponent texteditComponent(&engine);
-            texteditComponent.setData(componentStr.toLatin1(), QUrl());
-            QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-            QVERIFY(textEditObject != 0);
-            QCOMPARE((int)textEditObject->hAlign(), (int)hAlignments.at(j));
-        }
-    }
-
-    for (int i = 0; i < richText.size(); i++)
-    {
-        for (int j=0; j < hAlignmentStrings.size(); j++)
-        {
-            QString componentStr = "import QtQuick 2.0\nTextEdit {  horizontalAlignment: \"" + hAlignmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }";
-            QDeclarativeComponent texteditComponent(&engine);
-            texteditComponent.setData(componentStr.toLatin1(), QUrl());
-            QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-            QVERIFY(textEditObject != 0);
-            QCOMPARE((int)textEditObject->hAlign(), (int)hAlignments.at(j));
-        }
-    }
-
-}
-
-void tst_qsgtextedit::hAlign_RightToLeft()
-{
-    QSGView canvas(QUrl::fromLocalFile(TESTDATA("horizontalAlignment_RightToLeft.qml")));
-    QSGTextEdit *textEdit = canvas.rootObject()->findChild<QSGTextEdit*>("text");
-    QVERIFY(textEdit != 0);
-    canvas.show();
-
-    const QString rtlText = textEdit->text();
-
-    // implicit alignment should follow the reading direction of text
-    QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignRight);
-    QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
-
-    // explicitly left aligned
-    textEdit->setHAlign(QSGTextEdit::AlignLeft);
-    QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignLeft);
-    QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2);
-
-    // explicitly right aligned
-    textEdit->setHAlign(QSGTextEdit::AlignRight);
-    QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignRight);
-    QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
-
-    QString textString = textEdit->text();
-    textEdit->setText(QString("<i>") + textString + QString("</i>"));
-    textEdit->resetHAlign();
-
-    // implicitly aligned rich text should follow the reading direction of RTL text
-    QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignRight);
-    QCOMPARE(textEdit->effectiveHAlign(), textEdit->hAlign());
-    QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
-
-    // explicitly left aligned rich text
-    textEdit->setHAlign(QSGTextEdit::AlignLeft);
-    QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignLeft);
-    QCOMPARE(textEdit->effectiveHAlign(), textEdit->hAlign());
-    QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2);
-
-    // explicitly right aligned rich text
-    textEdit->setHAlign(QSGTextEdit::AlignRight);
-    QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignRight);
-    QCOMPARE(textEdit->effectiveHAlign(), textEdit->hAlign());
-    QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
-
-    textEdit->setText(textString);
-
-    // explicitly center aligned
-    textEdit->setHAlign(QSGTextEdit::AlignHCenter);
-    QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignHCenter);
-    QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
-
-    // reseted alignment should go back to following the text reading direction
-    textEdit->resetHAlign();
-    QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignRight);
-    QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
-
-    // mirror the text item
-    QSGItemPrivate::get(textEdit)->setLayoutMirror(true);
-
-    // mirrored implicit alignment should continue to follow the reading direction of the text
-    QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignRight);
-    QCOMPARE(textEdit->effectiveHAlign(), QSGTextEdit::AlignRight);
-    QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
-
-    // mirrored explicitly right aligned behaves as left aligned
-    textEdit->setHAlign(QSGTextEdit::AlignRight);
-    QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignRight);
-    QCOMPARE(textEdit->effectiveHAlign(), QSGTextEdit::AlignLeft);
-    QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2);
-
-    // mirrored explicitly left aligned behaves as right aligned
-    textEdit->setHAlign(QSGTextEdit::AlignLeft);
-    QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignLeft);
-    QCOMPARE(textEdit->effectiveHAlign(), QSGTextEdit::AlignRight);
-    QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
-
-    // disable mirroring
-    QSGItemPrivate::get(textEdit)->setLayoutMirror(false);
-    textEdit->resetHAlign();
-
-    // English text should be implicitly left aligned
-    textEdit->setText("Hello world!");
-    QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignLeft);
-    QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2);
-
-    canvas.requestActivateWindow();
-    QTest::qWaitForWindowShown(&canvas);
-    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
-
-    textEdit->setText(QString());
-    { 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>()); 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 QGuiApplication::keyboardInputDirection
-    textEdit->setText("");
-    QCOMPARE(textEdit->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ?
-                                  QSGTextEdit::AlignLeft : QSGTextEdit::AlignRight);
-    if (QGuiApplication::keyboardInputDirection() == Qt::LeftToRight)
-        QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2);
-    else
-        QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
-    textEdit->setHAlign(QSGTextEdit::AlignRight);
-    QCOMPARE(textEdit->hAlign(), QSGTextEdit::AlignRight);
-    QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
-#endif
-
-#ifndef Q_OS_MAC    // QTBUG-18040
-    // alignment of TextEdit with no text set to it
-    QString componentStr = "import QtQuick 2.0\nTextEdit {}";
-    QDeclarativeComponent textComponent(&engine);
-    textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGTextEdit *textObject = qobject_cast<QSGTextEdit*>(textComponent.create());
-    QCOMPARE(textObject->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ?
-                                  QSGTextEdit::AlignLeft : QSGTextEdit::AlignRight);
-    delete textObject;
-#endif
-}
-
-void tst_qsgtextedit::vAlign()
-{
-    //test one align each, and then test if two align fails.
-
-    for (int i = 0; i < standard.size(); i++)
-    {
-        for (int j=0; j < vAlignmentStrings.size(); j++)
-        {
-            QString componentStr = "import QtQuick 2.0\nTextEdit {  verticalAlignment: \"" + vAlignmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }";
-            QDeclarativeComponent texteditComponent(&engine);
-            texteditComponent.setData(componentStr.toLatin1(), QUrl());
-            QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-            QVERIFY(textEditObject != 0);
-            QCOMPARE((int)textEditObject->vAlign(), (int)vAlignments.at(j));
-        }
-    }
-
-    for (int i = 0; i < richText.size(); i++)
-    {
-        for (int j=0; j < vAlignmentStrings.size(); j++)
-        {
-            QString componentStr = "import QtQuick 2.0\nTextEdit {  verticalAlignment: \"" + vAlignmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }";
-            QDeclarativeComponent texteditComponent(&engine);
-            texteditComponent.setData(componentStr.toLatin1(), QUrl());
-            QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-            QVERIFY(textEditObject != 0);
-            QCOMPARE((int)textEditObject->vAlign(), (int)vAlignments.at(j));
-        }
-    }
-
-}
-
-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());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->font().pointSize(), 40);
-        QCOMPARE(textEditObject->font().bold(), false);
-        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());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->font().bold(), true);
-        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());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->font().italic(), true);
-        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());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->font().family(), QString("Helvetica"));
-        QCOMPARE(textEditObject->font().bold(), false);
-        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());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->font().family(), QString(""));
-    }
-}
-
-void tst_qsgtextedit::color()
-{
-    //test initial color
-    {
-        QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"Hello World\" }";
-        QDeclarativeComponent texteditComponent(&engine);
-        texteditComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-        QSGTextEditPrivate *textEditPrivate = static_cast<QSGTextEditPrivate*>(QSGItemPrivate::get(textEditObject));
-
-        QVERIFY(textEditObject);
-        QVERIFY(textEditPrivate);
-        QVERIFY(textEditPrivate->control);
-
-        QPalette pal = textEditPrivate->control->palette();
-        QCOMPARE(textEditPrivate->color, QColor("black"));
-        QCOMPARE(textEditPrivate->color, pal.color(QPalette::Text));
-    }
-    //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());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-        //qDebug() << "textEditObject: " << textEditObject->color() << "vs. " << QColor(colorStrings.at(i));
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->color(), QColor(colorStrings.at(i)));
-    }
-
-    //test selection
-    for (int i = 0; i < colorStrings.size(); i++)
-    {
-        QString componentStr = "import QtQuick 2.0\nTextEdit {  selectionColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
-        QDeclarativeComponent texteditComponent(&engine);
-        texteditComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->selectionColor(), QColor(colorStrings.at(i)));
-    }
-
-    //test selected text
-    for (int i = 0; i < colorStrings.size(); i++)
-    {
-        QString componentStr = "import QtQuick 2.0\nTextEdit {  selectedTextColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
-        QDeclarativeComponent texteditComponent(&engine);
-        texteditComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->selectedTextColor(), QColor(colorStrings.at(i)));
-    }
-
-    {
-        QString colorStr = "#AA001234";
-        QColor testColor("#001234");
-        testColor.setAlpha(170);
-
-        QString componentStr = "import QtQuick 2.0\nTextEdit {  color: \"" + colorStr + "\"; text: \"Hello World\" }";
-        QDeclarativeComponent texteditComponent(&engine);
-        texteditComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->color(), testColor);
-    }
-}
-
-void tst_qsgtextedit::textMargin()
-{
-    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());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->textMargin(), i);
-    }
-}
-
-void tst_qsgtextedit::persistentSelection()
-{
-    {
-        QString componentStr = "import QtQuick 2.0\nTextEdit {  persistentSelection: true; text: \"Hello World\" }";
-        QDeclarativeComponent texteditComponent(&engine);
-        texteditComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->persistentSelection(), true);
-    }
-
-    {
-        QString componentStr = "import QtQuick 2.0\nTextEdit {  persistentSelection: false; text: \"Hello World\" }";
-        QDeclarativeComponent texteditComponent(&engine);
-        texteditComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->persistentSelection(), false);
-    }
-}
-
-void tst_qsgtextedit::focusOnPress()
-{
-    {
-        QString componentStr = "import QtQuick 2.0\nTextEdit {  activeFocusOnPress: true; text: \"Hello World\" }";
-        QDeclarativeComponent texteditComponent(&engine);
-        texteditComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->focusOnPress(), true);
-    }
-
-    {
-        QString componentStr = "import QtQuick 2.0\nTextEdit {  activeFocusOnPress: false; text: \"Hello World\" }";
-        QDeclarativeComponent texteditComponent(&engine);
-        texteditComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-        QVERIFY(textEditObject != 0);
-        QCOMPARE(textEditObject->focusOnPress(), false);
-    }
-}
-
-void tst_qsgtextedit::selection()
-{
-    QString testStr = standard[0];//TODO: What should happen for multiline/rich text?
-    QString componentStr = "import QtQuick 2.0\nTextEdit {  text: \""+ testStr +"\"; }";
-    QDeclarativeComponent texteditComponent(&engine);
-    texteditComponent.setData(componentStr.toLatin1(), QUrl());
-    QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-    QVERIFY(textEditObject != 0);
-
-
-    //Test selection follows cursor
-    for (int i=0; i<= testStr.size(); i++) {
-        textEditObject->setCursorPosition(i);
-        QCOMPARE(textEditObject->cursorPosition(), i);
-        QCOMPARE(textEditObject->selectionStart(), i);
-        QCOMPARE(textEditObject->selectionEnd(), i);
-        QVERIFY(textEditObject->selectedText().isNull());
-    }
-
-    textEditObject->setCursorPosition(0);
-    QVERIFY(textEditObject->cursorPosition() == 0);
-    QVERIFY(textEditObject->selectionStart() == 0);
-    QVERIFY(textEditObject->selectionEnd() == 0);
-    QVERIFY(textEditObject->selectedText().isNull());
-
-    // Verify invalid positions are ignored.
-    textEditObject->setCursorPosition(-1);
-    QVERIFY(textEditObject->cursorPosition() == 0);
-    QVERIFY(textEditObject->selectionStart() == 0);
-    QVERIFY(textEditObject->selectionEnd() == 0);
-    QVERIFY(textEditObject->selectedText().isNull());
-
-    textEditObject->setCursorPosition(textEditObject->text().count()+1);
-    QVERIFY(textEditObject->cursorPosition() == 0);
-    QVERIFY(textEditObject->selectionStart() == 0);
-    QVERIFY(textEditObject->selectionEnd() == 0);
-    QVERIFY(textEditObject->selectedText().isNull());
-
-    //Test selection
-    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++) {
-        textEditObject->select(i,testStr.size());
-        QCOMPARE(testStr.mid(i,testStr.size()-i), textEditObject->selectedText());
-    }
-
-    textEditObject->setCursorPosition(0);
-    QVERIFY(textEditObject->cursorPosition() == 0);
-    QVERIFY(textEditObject->selectionStart() == 0);
-    QVERIFY(textEditObject->selectionEnd() == 0);
-    QVERIFY(textEditObject->selectedText().isNull());
-
-    //Test Error Ignoring behaviour
-    textEditObject->setCursorPosition(0);
-    QVERIFY(textEditObject->selectedText().isNull());
-    textEditObject->select(-10,0);
-    QVERIFY(textEditObject->selectedText().isNull());
-    textEditObject->select(100,101);
-    QVERIFY(textEditObject->selectedText().isNull());
-    textEditObject->select(0,-10);
-    QVERIFY(textEditObject->selectedText().isNull());
-    textEditObject->select(0,100);
-    QVERIFY(textEditObject->selectedText().isNull());
-    textEditObject->select(0,10);
-    QVERIFY(textEditObject->selectedText().size() == 10);
-    textEditObject->select(-10,0);
-    QVERIFY(textEditObject->selectedText().size() == 10);
-    textEditObject->select(100,101);
-    QVERIFY(textEditObject->selectedText().size() == 10);
-    textEditObject->select(0,-10);
-    QVERIFY(textEditObject->selectedText().size() == 10);
-    textEditObject->select(0,100);
-    QVERIFY(textEditObject->selectedText().size() == 10);
-
-    textEditObject->deselect();
-    QVERIFY(textEditObject->selectedText().isNull());
-    textEditObject->select(0,10);
-    QVERIFY(textEditObject->selectedText().size() == 10);
-    textEditObject->deselect();
-    QVERIFY(textEditObject->selectedText().isNull());
-}
-
-void tst_qsgtextedit::isRightToLeft_data()
-{
-    QTest::addColumn<QString>("text");
-    QTest::addColumn<bool>("emptyString");
-    QTest::addColumn<bool>("firstCharacter");
-    QTest::addColumn<bool>("lastCharacter");
-    QTest::addColumn<bool>("middleCharacter");
-    QTest::addColumn<bool>("startString");
-    QTest::addColumn<bool>("midString");
-    QTest::addColumn<bool>("endString");
-
-    const quint16 arabic_str[] = { 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0647};
-    QTest::newRow("Empty") << "" << false << false << false << false << false << false << false;
-    QTest::newRow("Neutral") << "23244242" << false << false << false << false << false << false << false;
-    QTest::newRow("LTR") << "Hello world" << false << false << false << false << false << false << false;
-    QTest::newRow("RTL") << QString::fromUtf16(arabic_str, 11) << false << true << true << true << true << true << true;
-    QTest::newRow("Bidi RTL + LTR + RTL") << QString::fromUtf16(arabic_str, 11) + QString("Hello world") + QString::fromUtf16(arabic_str, 11) << false << true << true << false << true << true << true;
-    QTest::newRow("Bidi LTR + RTL + LTR") << QString("Hello world") + QString::fromUtf16(arabic_str, 11) + QString("Hello world") << false << false << false << true << false << false << false;
-}
-
-void tst_qsgtextedit::isRightToLeft()
-{
-    QFETCH(QString, text);
-    QFETCH(bool, emptyString);
-    QFETCH(bool, firstCharacter);
-    QFETCH(bool, lastCharacter);
-    QFETCH(bool, middleCharacter);
-    QFETCH(bool, startString);
-    QFETCH(bool, midString);
-    QFETCH(bool, endString);
-
-    QSGTextEdit textEdit;
-    textEdit.setText(text);
-
-    // first test that the right string is delivered to the QString::isRightToLeft()
-    QCOMPARE(textEdit.isRightToLeft(0,0), text.mid(0,0).isRightToLeft());
-    QCOMPARE(textEdit.isRightToLeft(0,1), text.mid(0,1).isRightToLeft());
-    QCOMPARE(textEdit.isRightToLeft(text.count()-2, text.count()-1), text.mid(text.count()-2, text.count()-1).isRightToLeft());
-    QCOMPARE(textEdit.isRightToLeft(text.count()/2, text.count()/2 + 1), text.mid(text.count()/2, text.count()/2 + 1).isRightToLeft());
-    QCOMPARE(textEdit.isRightToLeft(0,text.count()/4), text.mid(0,text.count()/4).isRightToLeft());
-    QCOMPARE(textEdit.isRightToLeft(text.count()/4,3*text.count()/4), text.mid(text.count()/4,3*text.count()/4).isRightToLeft());
-    if (text.isEmpty())
-        QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML TextEdit: isRightToLeft(start, end) called with the end property being smaller than the start.");
-    QCOMPARE(textEdit.isRightToLeft(3*text.count()/4,text.count()-1), text.mid(3*text.count()/4,text.count()-1).isRightToLeft());
-
-    // then test that the feature actually works
-    QCOMPARE(textEdit.isRightToLeft(0,0), emptyString);
-    QCOMPARE(textEdit.isRightToLeft(0,1), firstCharacter);
-    QCOMPARE(textEdit.isRightToLeft(text.count()-2, text.count()-1), lastCharacter);
-    QCOMPARE(textEdit.isRightToLeft(text.count()/2, text.count()/2 + 1), middleCharacter);
-    QCOMPARE(textEdit.isRightToLeft(0,text.count()/4), startString);
-    QCOMPARE(textEdit.isRightToLeft(text.count()/4,3*text.count()/4), midString);
-    if (text.isEmpty())
-        QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML TextEdit: isRightToLeft(start, end) called with the end property being smaller than the start.");
-    QCOMPARE(textEdit.isRightToLeft(3*text.count()/4,text.count()-1), endString);
-}
-
-void tst_qsgtextedit::keySelection()
-{
-    QSGView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml")));
-    canvas.show();
-    canvas.requestActivateWindow();
-    QTest::qWaitForWindowShown(&canvas);
-    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
-    canvas.requestActivateWindow();
-
-    QVERIFY(canvas.rootObject() != 0);
-
-    QSGTextEdit *input = qobject_cast<QSGTextEdit *>(qvariant_cast<QObject *>(canvas.rootObject()->property("myInput")));
-
-    QVERIFY(input != 0);
-    QTRY_VERIFY(input->hasActiveFocus() == true);
-
-    QSignalSpy spy(input, SIGNAL(selectionChanged()));
-
-    simulateKey(&canvas, Qt::Key_Right, Qt::ShiftModifier);
-    QVERIFY(input->hasActiveFocus() == true);
-    QCOMPARE(input->selectedText(), QString("a"));
-    QCOMPARE(spy.count(), 1);
-    simulateKey(&canvas, Qt::Key_Right);
-    QVERIFY(input->hasActiveFocus() == true);
-    QCOMPARE(input->selectedText(), QString());
-    QCOMPARE(spy.count(), 2);
-    simulateKey(&canvas, Qt::Key_Right);
-    QVERIFY(input->hasActiveFocus() == false);
-    QCOMPARE(input->selectedText(), QString());
-    QCOMPARE(spy.count(), 2);
-
-    simulateKey(&canvas, Qt::Key_Left);
-    QVERIFY(input->hasActiveFocus() == true);
-    QCOMPARE(spy.count(), 2);
-    simulateKey(&canvas, Qt::Key_Left, Qt::ShiftModifier);
-    QVERIFY(input->hasActiveFocus() == true);
-    QCOMPARE(input->selectedText(), QString("a"));
-    QCOMPARE(spy.count(), 3);
-    simulateKey(&canvas, Qt::Key_Left);
-    QVERIFY(input->hasActiveFocus() == true);
-    QCOMPARE(input->selectedText(), QString());
-    QCOMPARE(spy.count(), 4);
-    simulateKey(&canvas, Qt::Key_Left);
-    QVERIFY(input->hasActiveFocus() == false);
-    QCOMPARE(input->selectedText(), QString());
-    QCOMPARE(spy.count(), 4);
-}
-
-void tst_qsgtextedit::moveCursorSelection_data()
-{
-    QTest::addColumn<QString>("testStr");
-    QTest::addColumn<int>("cursorPosition");
-    QTest::addColumn<int>("movePosition");
-    QTest::addColumn<QSGTextEdit::SelectionMode>("mode");
-    QTest::addColumn<int>("selectionStart");
-    QTest::addColumn<int>("selectionEnd");
-    QTest::addColumn<bool>("reversible");
-
-    QTest::newRow("(t)he|characters")
-            << standard[0] << 0 << 1 << QSGTextEdit::SelectCharacters << 0 << 1 << true;
-    QTest::newRow("do(g)|characters")
-            << standard[0] << 43 << 44 << QSGTextEdit::SelectCharacters << 43 << 44 << true;
-    QTest::newRow("jum(p)ed|characters")
-            << standard[0] << 23 << 24 << QSGTextEdit::SelectCharacters << 23 << 24 << true;
-    QTest::newRow("jumped( )over|characters")
-            << standard[0] << 26 << 27 << QSGTextEdit::SelectCharacters << 26 << 27 << true;
-    QTest::newRow("(the )|characters")
-            << standard[0] << 0 << 4 << QSGTextEdit::SelectCharacters << 0 << 4 << true;
-    QTest::newRow("( dog)|characters")
-            << standard[0] << 40 << 44 << QSGTextEdit::SelectCharacters << 40 << 44 << true;
-    QTest::newRow("( jumped )|characters")
-            << standard[0] << 19 << 27 << QSGTextEdit::SelectCharacters << 19 << 27 << true;
-    QTest::newRow("th(e qu)ick|characters")
-            << standard[0] << 2 << 6 << QSGTextEdit::SelectCharacters << 2 << 6 << true;
-    QTest::newRow("la(zy d)og|characters")
-            << standard[0] << 38 << 42 << QSGTextEdit::SelectCharacters << 38 << 42 << true;
-    QTest::newRow("jum(ped ov)er|characters")
-            << standard[0] << 23 << 29 << QSGTextEdit::SelectCharacters << 23 << 29 << true;
-    QTest::newRow("()the|characters")
-            << standard[0] << 0 << 0 << QSGTextEdit::SelectCharacters << 0 << 0 << true;
-    QTest::newRow("dog()|characters")
-            << standard[0] << 44 << 44 << QSGTextEdit::SelectCharacters << 44 << 44 << true;
-    QTest::newRow("jum()ped|characters")
-            << standard[0] << 23 << 23 << QSGTextEdit::SelectCharacters << 23 << 23 << true;
-
-    QTest::newRow("<(t)he>|words")
-            << standard[0] << 0 << 1 << QSGTextEdit::SelectWords << 0 << 3 << true;
-    QTest::newRow("<do(g)>|words")
-            << standard[0] << 43 << 44 << QSGTextEdit::SelectWords << 41 << 44 << true;
-    QTest::newRow("<jum(p)ed>|words")
-            << standard[0] << 23 << 24 << QSGTextEdit::SelectWords << 20 << 26 << true;
-    QTest::newRow("<jumped( )>over|words")
-            << standard[0] << 26 << 27 << QSGTextEdit::SelectWords << 20 << 27 << false;
-    QTest::newRow("jumped<( )over>|words,reversed")
-            << standard[0] << 27 << 26 << QSGTextEdit::SelectWords << 26 << 31 << false;
-    QTest::newRow("<(the )>quick|words")
-            << standard[0] << 0 << 4 << QSGTextEdit::SelectWords << 0 << 4 << false;
-    QTest::newRow("<(the )quick>|words,reversed")
-            << standard[0] << 4 << 0 << QSGTextEdit::SelectWords << 0 << 9 << false;
-    QTest::newRow("<lazy( dog)>|words")
-            << standard[0] << 40 << 44 << QSGTextEdit::SelectWords << 36 << 44 << false;
-    QTest::newRow("lazy<( dog)>|words,reversed")
-            << standard[0] << 44 << 40 << QSGTextEdit::SelectWords << 40 << 44 << false;
-    QTest::newRow("<fox( jumped )>over|words")
-            << standard[0] << 19 << 27 << QSGTextEdit::SelectWords << 16 << 27 << false;
-    QTest::newRow("fox<( jumped )over>|words,reversed")
-            << standard[0] << 27 << 19 << QSGTextEdit::SelectWords << 19 << 31 << false;
-    QTest::newRow("<th(e qu)ick>|words")
-            << standard[0] << 2 << 6 << QSGTextEdit::SelectWords << 0 << 9 << true;
-    QTest::newRow("<la(zy d)og|words>")
-            << standard[0] << 38 << 42 << QSGTextEdit::SelectWords << 36 << 44 << true;
-    QTest::newRow("<jum(ped ov)er>|words")
-            << standard[0] << 23 << 29 << QSGTextEdit::SelectWords << 20 << 31 << true;
-    QTest::newRow("<()>the|words")
-            << standard[0] << 0 << 0 << QSGTextEdit::SelectWords << 0 << 0 << true;
-    QTest::newRow("dog<()>|words")
-            << standard[0] << 44 << 44 << QSGTextEdit::SelectWords << 44 << 44 << true;
-    QTest::newRow("jum<()>ped|words")
-            << standard[0] << 23 << 23 << QSGTextEdit::SelectWords << 23 << 23 << true;
-
-    QTest::newRow("Hello<(,)> |words")
-            << standard[2] << 5 << 6 << QSGTextEdit::SelectWords << 5 << 6 << true;
-    QTest::newRow("Hello<(, )>world|words")
-            << standard[2] << 5 << 7 << QSGTextEdit::SelectWords << 5 << 7 << false;
-    QTest::newRow("Hello<(, )world>|words,reversed")
-            << standard[2] << 7 << 5 << QSGTextEdit::SelectWords << 5 << 12 << false;
-    QTest::newRow("<Hel(lo, )>world|words")
-            << standard[2] << 3 << 7 << QSGTextEdit::SelectWords << 0 << 7 << false;
-    QTest::newRow("<Hel(lo, )world>|words,reversed")
-            << standard[2] << 7 << 3 << QSGTextEdit::SelectWords << 0 << 12 << false;
-    QTest::newRow("<Hel(lo)>,|words")
-            << standard[2] << 3 << 5 << QSGTextEdit::SelectWords << 0 << 5 << true;
-    QTest::newRow("Hello<()>,|words")
-            << standard[2] << 5 << 5 << QSGTextEdit::SelectWords << 5 << 5 << true;
-    QTest::newRow("Hello,<()>|words")
-            << standard[2] << 6 << 6 << QSGTextEdit::SelectWords << 6 << 6 << true;
-    QTest::newRow("Hello<,( )>world|words")
-            << standard[2] << 6 << 7 << QSGTextEdit::SelectWords << 5 << 7 << false;
-    QTest::newRow("Hello,<( )world>|words,reversed")
-            << standard[2] << 7 << 6 << QSGTextEdit::SelectWords << 6 << 12 << false;
-    QTest::newRow("Hello<,( world)>|words")
-            << standard[2] << 6 << 12 << QSGTextEdit::SelectWords << 5 << 12 << false;
-    QTest::newRow("Hello,<( world)>|words,reversed")
-            << standard[2] << 12 << 6 << QSGTextEdit::SelectWords << 6 << 12 << false;
-    QTest::newRow("Hello<,( world!)>|words")
-            << standard[2] << 6 << 13 << QSGTextEdit::SelectWords << 5 << 13 << false;
-    QTest::newRow("Hello,<( world!)>|words,reversed")
-            << standard[2] << 13 << 6 << QSGTextEdit::SelectWords << 6 << 13 << false;
-    QTest::newRow("Hello<(, world!)>|words")
-            << standard[2] << 5 << 13 << QSGTextEdit::SelectWords << 5 << 13 << true;
-    QTest::newRow("world<(!)>|words")
-            << standard[2] << 12 << 13 << QSGTextEdit::SelectWords << 12 << 13 << true;
-    QTest::newRow("world!<()>)|words")
-            << standard[2] << 13 << 13 << QSGTextEdit::SelectWords << 13 << 13 << true;
-    QTest::newRow("world<()>!)|words")
-            << standard[2] << 12 << 12 << QSGTextEdit::SelectWords << 12 << 12 << true;
-
-    QTest::newRow("<(,)>olleH |words")
-            << standard[3] << 7 << 8 << QSGTextEdit::SelectWords << 7 << 8 << true;
-    QTest::newRow("<dlrow( ,)>olleH|words")
-            << standard[3] << 6 << 8 << QSGTextEdit::SelectWords << 1 << 8 << false;
-    QTest::newRow("dlrow<( ,)>olleH|words,reversed")
-            << standard[3] << 8 << 6 << QSGTextEdit::SelectWords << 6 << 8 << false;
-    QTest::newRow("<dlrow( ,ol)leH>|words")
-            << standard[3] << 6 << 10 << QSGTextEdit::SelectWords << 1 << 13 << false;
-    QTest::newRow("dlrow<( ,ol)leH>|words,reversed")
-            << standard[3] << 10 << 6 << QSGTextEdit::SelectWords << 6 << 13 << false;
-    QTest::newRow(",<(ol)leH>,|words")
-            << standard[3] << 8 << 10 << QSGTextEdit::SelectWords << 8 << 13 << true;
-    QTest::newRow(",<()>olleH|words")
-            << standard[3] << 8 << 8 << QSGTextEdit::SelectWords << 8 << 8 << true;
-    QTest::newRow("<()>,olleH|words")
-            << standard[3] << 7 << 7 << QSGTextEdit::SelectWords << 7 << 7 << true;
-    QTest::newRow("<dlrow( )>,olleH|words")
-            << standard[3] << 6 << 7 << QSGTextEdit::SelectWords << 1 << 7 << false;
-    QTest::newRow("dlrow<( ),>olleH|words,reversed")
-            << standard[3] << 7 << 6 << QSGTextEdit::SelectWords << 6 << 8 << false;
-    QTest::newRow("<(dlrow )>,olleH|words")
-            << standard[3] << 1 << 7 << QSGTextEdit::SelectWords << 1 << 7 << false;
-    QTest::newRow("<(dlrow ),>olleH|words,reversed")
-            << standard[3] << 7 << 1 << QSGTextEdit::SelectWords << 1 << 8 << false;
-    QTest::newRow("<(!dlrow )>,olleH|words")
-            << standard[3] << 0 << 7 << QSGTextEdit::SelectWords << 0 << 7 << false;
-    QTest::newRow("<(!dlrow ),>olleH|words,reversed")
-            << standard[3] << 7 << 0 << QSGTextEdit::SelectWords << 0 << 8 << false;
-    QTest::newRow("(!dlrow ,)olleH|words")
-            << standard[3] << 0 << 8 << QSGTextEdit::SelectWords << 0 << 8 << true;
-    QTest::newRow("<(!)>dlrow|words")
-            << standard[3] << 0 << 1 << QSGTextEdit::SelectWords << 0 << 1 << true;
-    QTest::newRow("<()>!dlrow|words")
-            << standard[3] << 0 << 0 << QSGTextEdit::SelectWords << 0 << 0 << true;
-    QTest::newRow("!<()>dlrow|words")
-            << standard[3] << 1 << 1 << QSGTextEdit::SelectWords << 1 << 1 << true;
-}
-
-void tst_qsgtextedit::moveCursorSelection()
-{
-    QFETCH(QString, testStr);
-    QFETCH(int, cursorPosition);
-    QFETCH(int, movePosition);
-    QFETCH(QSGTextEdit::SelectionMode, mode);
-    QFETCH(int, selectionStart);
-    QFETCH(int, selectionEnd);
-    QFETCH(bool, reversible);
-
-    QString componentStr = "import QtQuick 2.0\nTextEdit {  text: \""+ testStr +"\"; }";
-    QDeclarativeComponent textinputComponent(&engine);
-    textinputComponent.setData(componentStr.toLatin1(), QUrl());
-    QSGTextEdit *texteditObject = qobject_cast<QSGTextEdit*>(textinputComponent.create());
-    QVERIFY(texteditObject != 0);
-
-    texteditObject->setCursorPosition(cursorPosition);
-    texteditObject->moveCursorSelection(movePosition, mode);
-
-    QCOMPARE(texteditObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart));
-    QCOMPARE(texteditObject->selectionStart(), selectionStart);
-    QCOMPARE(texteditObject->selectionEnd(), selectionEnd);
-
-    if (reversible) {
-        texteditObject->setCursorPosition(movePosition);
-        texteditObject->moveCursorSelection(cursorPosition, mode);
-
-        QCOMPARE(texteditObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart));
-        QCOMPARE(texteditObject->selectionStart(), selectionStart);
-        QCOMPARE(texteditObject->selectionEnd(), selectionEnd);
-    }
-}
-
-void tst_qsgtextedit::moveCursorSelectionSequence_data()
-{
-    QTest::addColumn<QString>("testStr");
-    QTest::addColumn<int>("cursorPosition");
-    QTest::addColumn<int>("movePosition1");
-    QTest::addColumn<int>("movePosition2");
-    QTest::addColumn<int>("selection1Start");
-    QTest::addColumn<int>("selection1End");
-    QTest::addColumn<int>("selection2Start");
-    QTest::addColumn<int>("selection2End");
-
-    QTest::newRow("the {<quick( bro)wn> f^ox} jumped|ltr")
-            << standard[0]
-            << 9 << 13 << 17
-            << 4 << 15
-            << 4 << 19;
-    QTest::newRow("the quick<( {bro)wn> f^ox} jumped|rtl")
-            << standard[0]
-            << 13 << 9 << 17
-            << 9 << 15
-            << 10 << 19;
-    QTest::newRow("the {<quick( bro)wn> ^}fox jumped|ltr")
-            << standard[0]
-            << 9 << 13 << 16
-            << 4 << 15
-            << 4 << 16;
-    QTest::newRow("the quick<( {bro)wn> ^}fox jumped|rtl")
-            << standard[0]
-            << 13 << 9 << 16
-            << 9 << 15
-            << 10 << 16;
-    QTest::newRow("the {<quick( bro)wn^>} fox jumped|ltr")
-            << standard[0]
-            << 9 << 13 << 15
-            << 4 << 15
-            << 4 << 15;
-    QTest::newRow("the quick<( {bro)wn^>} f^ox jumped|rtl")
-            << standard[0]
-            << 13 << 9 << 15
-            << 9 << 15
-            << 10 << 15;
-    QTest::newRow("the {<quick() ^}bro)wn> fox|ltr")
-            << standard[0]
-            << 9 << 13 << 10
-            << 4 << 15
-            << 4 << 10;
-    QTest::newRow("the quick<(^ {^bro)wn>} fox|rtl")
-            << standard[0]
-            << 13 << 9 << 10
-            << 9 << 15
-            << 10 << 15;
-    QTest::newRow("the {<quick^}( bro)wn> fox|ltr")
-            << standard[0]
-            << 9 << 13 << 9
-            << 4 << 15
-            << 4 << 9;
-    QTest::newRow("the quick{<(^ bro)wn>} fox|rtl")
-            << standard[0]
-            << 13 << 9 << 9
-            << 9 << 15
-            << 9 << 15;
-    QTest::newRow("the {<qui^ck}( bro)wn> fox|ltr")
-            << standard[0]
-            << 9 << 13 << 7
-            << 4 << 15
-            << 4 << 9;
-    QTest::newRow("the {<qui^ck}( bro)wn> fox|rtl")
-            << standard[0]
-            << 13 << 9 << 7
-            << 9 << 15
-            << 4 << 15;
-    QTest::newRow("the {<^quick}( bro)wn> fox|ltr")
-            << standard[0]
-            << 9 << 13 << 4
-            << 4 << 15
-            << 4 << 9;
-    QTest::newRow("the {<^quick}( bro)wn> fox|rtl")
-            << standard[0]
-            << 13 << 9 << 4
-            << 9 << 15
-            << 4 << 15;
-    QTest::newRow("the{^ <quick}( bro)wn> fox|ltr")
-            << standard[0]
-            << 9 << 13 << 3
-            << 4 << 15
-            << 3 << 9;
-    QTest::newRow("the{^ <quick}( bro)wn> fox|rtl")
-            << standard[0]
-            << 13 << 9 << 3
-            << 9 << 15
-            << 3 << 15;
-    QTest::newRow("{t^he <quick}( bro)wn> fox|ltr")
-            << standard[0]
-            << 9 << 13 << 1
-            << 4 << 15
-            << 0 << 9;
-    QTest::newRow("{t^he <quick}( bro)wn> fox|rtl")
-            << standard[0]
-            << 13 << 9 << 1
-            << 9 << 15
-            << 0 << 15;
-
-    QTest::newRow("{<He(ll)o>, w^orld}!|ltr")
-            << standard[2]
-            << 2 << 4 << 8
-            << 0 << 5
-            << 0 << 12;
-    QTest::newRow("{<He(ll)o>, w^orld}!|rtl")
-            << standard[2]
-            << 4 << 2 << 8
-            << 0 << 5
-            << 0 << 12;
-
-    QTest::newRow("!{dlro^w ,<o(ll)eH>}|ltr")
-            << standard[3]
-            << 9 << 11 << 5
-            << 8 << 13
-            << 1 << 13;
-    QTest::newRow("!{dlro^w ,<o(ll)eH>}|rtl")
-            << standard[3]
-            << 11 << 9 << 5
-            << 8 << 13
-            << 1 << 13;
-}
-
-void tst_qsgtextedit::moveCursorSelectionSequence()
-{
-    QFETCH(QString, testStr);
-    QFETCH(int, cursorPosition);
-    QFETCH(int, movePosition1);
-    QFETCH(int, movePosition2);
-    QFETCH(int, selection1Start);
-    QFETCH(int, selection1End);
-    QFETCH(int, selection2Start);
-    QFETCH(int, selection2End);
-
-    QString componentStr = "import QtQuick 2.0\nTextEdit {  text: \""+ testStr +"\"; }";
-    QDeclarativeComponent texteditComponent(&engine);
-    texteditComponent.setData(componentStr.toLatin1(), QUrl());
-    QSGTextEdit *texteditObject = qobject_cast<QSGTextEdit*>(texteditComponent.create());
-    QVERIFY(texteditObject != 0);
-
-    texteditObject->setCursorPosition(cursorPosition);
-
-    texteditObject->moveCursorSelection(movePosition1, QSGTextEdit::SelectWords);
-    QCOMPARE(texteditObject->selectedText(), testStr.mid(selection1Start, selection1End - selection1Start));
-    QCOMPARE(texteditObject->selectionStart(), selection1Start);
-    QCOMPARE(texteditObject->selectionEnd(), selection1End);
-
-    texteditObject->moveCursorSelection(movePosition2, QSGTextEdit::SelectWords);
-    QCOMPARE(texteditObject->selectedText(), testStr.mid(selection2Start, selection2End - selection2Start));
-    QCOMPARE(texteditObject->selectionStart(), selection2Start);
-    QCOMPARE(texteditObject->selectionEnd(), selection2End);
-}
-
-
-void tst_qsgtextedit::mouseSelection_data()
-{
-    QTest::addColumn<QString>("qmlfile");
-    QTest::addColumn<int>("from");
-    QTest::addColumn<int>("to");
-    QTest::addColumn<QString>("selectedText");
-
-    // import installed
-    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()
-{
-    QFETCH(QString, qmlfile);
-    QFETCH(int, from);
-    QFETCH(int, to);
-    QFETCH(QString, selectedText);
-
-    QSGView canvas(QUrl::fromLocalFile(qmlfile));
-
-    canvas.show();
-    canvas.requestActivateWindow();
-    QTest::qWaitForWindowShown(&canvas);
-    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
-
-    QVERIFY(canvas.rootObject() != 0);
-    QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit *>(canvas.rootObject());
-    QVERIFY(textEditObject != 0);
-
-    // press-and-drag-and-release from x1 to x2
-    QPoint p1 = textEditObject->positionToRectangle(from).center().toPoint();
-    QPoint p2 = textEditObject->positionToRectangle(to).center().toPoint();
-    QTest::mousePress(&canvas, Qt::LeftButton, 0, p1);
-    QTest::mouseMove(&canvas, p2);
-    QTest::mouseRelease(&canvas, Qt::LeftButton, 0, p2);
-    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);
-    QTest::qWait(50);
-    if (!selectedText.isEmpty())
-        QEXPECT_FAIL("", "QTBUG-21743", Continue);
-    QTRY_COMPARE(textEditObject->selectedText(), selectedText);
-}
-
-void tst_qsgtextedit::dragMouseSelection()
-{
-    QString qmlfile = TESTDATA("mouseselection_true.qml");
-
-    QSGView canvas(QUrl::fromLocalFile(qmlfile));
-
-    canvas.show();
-    canvas.requestActivateWindow();
-    QTest::qWaitForWindowShown(&canvas);
-    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
-
-    QVERIFY(canvas.rootObject() != 0);
-    QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit *>(canvas.rootObject());
-    QVERIFY(textEditObject != 0);
-
-    // press-and-drag-and-release from x1 to x2
-    int x1 = 10;
-    int x2 = 70;
-    int y = textEditObject->height()/2;
-    QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y));
-    QTest::mouseMove(&canvas, QPoint(x2, y));
-    QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y));
-    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));
-    QTest::mouseMove(&canvas, QPoint(x2, y));
-    QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y));
-    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.
-}
-
-void tst_qsgtextedit::mouseSelectionMode_data()
-{
-    QTest::addColumn<QString>("qmlfile");
-    QTest::addColumn<bool>("selectWords");
-
-    // import installed
-    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()
-{
-    QFETCH(QString, qmlfile);
-    QFETCH(bool, selectWords);
-
-    QString text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
-    QSGView canvas(QUrl::fromLocalFile(qmlfile));
-
-    canvas.show();
-    canvas.requestActivateWindow();
-    QTest::qWaitForWindowShown(&canvas);
-    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
-
-    QVERIFY(canvas.rootObject() != 0);
-    QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit *>(canvas.rootObject());
-    QVERIFY(textEditObject != 0);
-
-    // press-and-drag-and-release from x1 to x2
-    int x1 = 10;
-    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);
-//    QGuiApplication::sendEvent(&canvas, &mv);
-    QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y));
-    QString str = textEditObject->selectedText();
-    if (selectWords) {
-        QTRY_COMPARE(textEditObject->selectedText(), text);
-    } else {
-        QTRY_VERIFY(textEditObject->selectedText().length() > 3);
-        QVERIFY(str != text);
-    }
-}
-
-void tst_qsgtextedit::inputMethodHints()
-{
-    QSGView canvas(QUrl::fromLocalFile(TESTDATA("inputmethodhints.qml")));
-    canvas.show();
-    canvas.requestActivateWindow();
-
-    QVERIFY(canvas.rootObject() != 0);
-    QSGTextEdit *textEditObject = qobject_cast<QSGTextEdit *>(canvas.rootObject());
-    QVERIFY(textEditObject != 0);
-    QVERIFY(textEditObject->inputMethodHints() & Qt::ImhNoPredictiveText);
-    textEditObject->setInputMethodHints(Qt::ImhUppercaseOnly);
-    QVERIFY(textEditObject->inputMethodHints() & Qt::ImhUppercaseOnly);
-}
-
-void tst_qsgtextedit::positionAt()
-{
-    QSGView canvas(QUrl::fromLocalFile(TESTDATA("positionAt.qml")));
-    QVERIFY(canvas.rootObject() != 0);
-    canvas.show();
-    canvas.requestActivateWindow();
-    canvas.requestActivateWindow();
-    QTest::qWaitForWindowShown(&canvas);
-
-    QSGTextEdit *texteditObject = qobject_cast<QSGTextEdit *>(canvas.rootObject());
-    QVERIFY(texteditObject != 0);
-
-    QFontMetrics fm(texteditObject->font());
-    const int y0 = fm.height() / 2;
-    const int y1 = fm.height() * 3 / 2;
-
-    int pos = texteditObject->positionAt(texteditObject->width()/2, y0);
-    int width = 0;
-    if (!qmlDisableDistanceField()) {
-        QTextLayout layout(texteditObject->text().left(pos));
-
-        {
-            QTextOption option;
-            option.setUseDesignMetrics(true);
-            layout.setTextOption(option);
-        }
-
-        layout.beginLayout();
-        QTextLine line = layout.createLine();
-        layout.endLayout();
-
-        width = ceil(line.horizontalAdvance());
-
-    } else {
-        width = fm.width(texteditObject->text().left(pos));
-    }
-
-
-    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);
-#else
-    QVERIFY(diff < 5);
-#endif
-
-    const qreal x0 = texteditObject->positionToRectangle(pos).x();
-    const qreal x1 = texteditObject->positionToRectangle(pos + 1).x();
-
-    QString preeditText = texteditObject->text().mid(0, pos);
-    texteditObject->setText(texteditObject->text().mid(pos));
-    texteditObject->setCursorPosition(0);
-
-    QInputMethodEvent inputEvent(preeditText, QList<QInputMethodEvent::Attribute>());
-    QGuiApplication::sendEvent(&canvas, &inputEvent);
-
-    // Check all points within the preedit text return the same position.
-    QCOMPARE(texteditObject->positionAt(0, y0), 0);
-    QCOMPARE(texteditObject->positionAt(x0 / 2, y0), 0);
-    QCOMPARE(texteditObject->positionAt(x0, y0), 0);
-
-    // Verify positioning returns to normal after the preedit text.
-    QCOMPARE(texteditObject->positionAt(x1, y0), 1);
-    QCOMPARE(texteditObject->positionToRectangle(1).x(), x1);
-
-    QVERIFY(texteditObject->positionAt(x0 / 2, y1) > 0);
-}
-
-void tst_qsgtextedit::cursorDelegate()
-{
-    QSGView view(QUrl::fromLocalFile(TESTDATA("cursorTest.qml")));
-    view.show();
-    view.requestActivateWindow();
-    QSGTextEdit *textEditObject = view.rootObject()->findChild<QSGTextEdit*>("textEditObject");
-    QVERIFY(textEditObject != 0);
-    QVERIFY(textEditObject->findChild<QSGItem*>("cursorInstance"));
-    //Test Delegate gets created
-    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++) {
-        textEditObject->setCursorPosition(i);
-        QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
-        QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
-    }
-    // Clear preedit text;
-    QInputMethodEvent event;
-    QGuiApplication::sendEvent(&view, &event);
-
-
-    // Test delegate gets moved on mouse press.
-    textEditObject->setSelectByMouse(true);
-    textEditObject->setCursorPosition(0);
-    const QPoint point1 = textEditObject->positionToRectangle(5).center().toPoint();
-    QTest::mouseClick(&view, Qt::LeftButton, 0, point1);
-    QTest::qWait(50);
-    QTRY_VERIFY(textEditObject->cursorPosition() != 0);
-    QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
-    QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
-
-    // Test delegate gets moved on mouse drag
-    textEditObject->setCursorPosition(0);
-    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);
-    QGuiApplication::sendEvent(&view, &mv);
-    QTest::mouseRelease(&view, Qt::LeftButton, 0, point2);
-    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());
-    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());
-    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);
-    QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x()));
-    QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y()));
-    //Test Delegate gets deleted
-    textEditObject->setCursorDelegate(0);
-    QVERIFY(!textEditObject->findChild<QSGItem*>("cursorInstance"));
-}
-
-void tst_qsgtextedit::cursorVisible()
-{
-    QSGView view(QUrl::fromLocalFile(TESTDATA("cursorVisible.qml")));
-    view.show();
-    view.requestActivateWindow();
-    QTest::qWaitForWindowShown(&view);
-    QTRY_COMPARE(&view, qGuiApp->focusWindow());
-
-    QSGTextEdit edit;
-    QSignalSpy spy(&edit, SIGNAL(cursorVisibleChanged(bool)));
-
-    QCOMPARE(edit.isCursorVisible(), false);
-
-    edit.setCursorVisible(true);
-    QCOMPARE(edit.isCursorVisible(), true);
-    QCOMPARE(spy.count(), 1);
-
-    edit.setCursorVisible(false);
-    QCOMPARE(edit.isCursorVisible(), false);
-    QCOMPARE(spy.count(), 2);
-
-    edit.setFocus(true);
-    QCOMPARE(edit.isCursorVisible(), false);
-    QCOMPARE(spy.count(), 2);
-
-    edit.setParentItem(view.rootObject());
-    QCOMPARE(edit.isCursorVisible(), true);
-    QCOMPARE(spy.count(), 3);
-
-    edit.setFocus(false);
-    QCOMPARE(edit.isCursorVisible(), false);
-    QCOMPARE(spy.count(), 4);
-
-    edit.setFocus(true);
-    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);
-
-    view.requestActivateWindow();
-    QCOMPARE(edit.isCursorVisible(), true);
-    QCOMPARE(spy.count(), 7);
-
-    // 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)
-    // 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
-}
-
-void tst_qsgtextedit::delegateLoading_data()
-{
-    QTest::addColumn<QString>("qmlfile");
-    QTest::addColumn<QString>("error");
-
-    // import installed
-    QTest::newRow("pass") << "cursorHttpTestPass.qml" << "";
-    QTest::newRow("fail1") << "cursorHttpTestFail1.qml" << "http://localhost:42332/FailItem.qml: Remote host closed the connection ";
-    QTest::newRow("fail2") << "cursorHttpTestFail2.qml" << "http://localhost:42332/ErrItem.qml:4:5: Fungus is not a type ";
-}
-
-void tst_qsgtextedit::delegateLoading()
-{
-    QFETCH(QString, qmlfile);
-    QFETCH(QString, error);
-
-    TestHTTPServer server(42332);
-    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();
-    view.requestActivateWindow();
-
-    if (!error.isEmpty()) {
-        QTest::ignoreMessage(QtWarningMsg, error.toUtf8());
-        QTRY_VERIFY(view.status()==QSGView::Error);
-        QTRY_VERIFY(!view.rootObject()); // there is fail item inside this test
-    } else {
-        QTRY_VERIFY(view.rootObject());//Wait for loading to finish.
-        QSGTextEdit *textEditObject = view.rootObject()->findChild<QSGTextEdit*>("textEditObject");
-        //    view.rootObject()->dumpObjectTree();
-        QVERIFY(textEditObject != 0);
-        textEditObject->setFocus(true);
-        QSGItem *delegate;
-        delegate = view.rootObject()->findChild<QSGItem*>("delegateOkay");
-        QVERIFY(delegate);
-        delegate = view.rootObject()->findChild<QSGItem*>("delegateSlow");
-        QVERIFY(delegate);
-
-        delete delegate;
-    }
-
-
-    //A test should be added here with a component which is ready but component.create() returns null
-    //Not sure how to accomplish this with QSGTextEdits cursor delegate
-    //###This was only needed for code coverage, and could be a case of overzealous defensive programming
-    //delegate = view.rootObject()->findChild<QSGItem*>("delegateErrorB");
-    //QVERIFY(!delegate);
-}
-
-/*
-TextEdit element should only handle left/right keys until the cursor reaches
-the extent of the text, then they should ignore the keys.
-*/
-void tst_qsgtextedit::navigation()
-{
-    QSGView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml")));
-    canvas.show();
-    canvas.requestActivateWindow();
-
-    QVERIFY(canvas.rootObject() != 0);
-
-    QSGItem *input = qobject_cast<QSGItem *>(qvariant_cast<QObject *>(canvas.rootObject()->property("myInput")));
-
-    QVERIFY(input != 0);
-    QTRY_VERIFY(input->hasActiveFocus() == true);
-    simulateKey(&canvas, Qt::Key_Left);
-    QVERIFY(input->hasActiveFocus() == false);
-    simulateKey(&canvas, Qt::Key_Right);
-    QVERIFY(input->hasActiveFocus() == true);
-    simulateKey(&canvas, Qt::Key_Right);
-    QVERIFY(input->hasActiveFocus() == true);
-    simulateKey(&canvas, Qt::Key_Right);
-    QVERIFY(input->hasActiveFocus() == false);
-    simulateKey(&canvas, Qt::Key_Left);
-    QVERIFY(input->hasActiveFocus() == true);
-}
-
-void tst_qsgtextedit::copyAndPaste() {
-#ifndef QT_NO_CLIPBOARD
-
-#ifdef Q_WS_MAC
-    {
-        PasteboardRef pasteboard;
-        OSStatus status = PasteboardCreate(0, &pasteboard);
-        if (status == noErr)
-            CFRelease(pasteboard);
-        else
-            QSKIP("This machine doesn't support the clipboard");
-    }
-#endif
-
-    QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"Hello world!\" }";
-    QDeclarativeComponent textEditComponent(&engine);
-    textEditComponent.setData(componentStr.toLatin1(), QUrl());
-    QSGTextEdit *textEdit = qobject_cast<QSGTextEdit*>(textEditComponent.create());
-    QVERIFY(textEdit != 0);
-
-    // copy and paste
-    QCOMPARE(textEdit->text().length(), 12);
-    textEdit->select(0, textEdit->text().length());;
-    textEdit->copy();
-    QCOMPARE(textEdit->selectedText(), QString("Hello world!"));
-    QCOMPARE(textEdit->selectedText().length(), 12);
-    textEdit->setCursorPosition(0);
-    QVERIFY(textEdit->canPaste());
-    textEdit->paste();
-    QCOMPARE(textEdit->text(), QString("Hello world!Hello world!"));
-    QCOMPARE(textEdit->text().length(), 24);
-
-    // canPaste
-    QVERIFY(textEdit->canPaste());
-    textEdit->setReadOnly(true);
-    QVERIFY(!textEdit->canPaste());
-    textEdit->setReadOnly(false);
-    QVERIFY(textEdit->canPaste());
-
-    // QTBUG-12339
-    // test that document and internal text attribute are in sync
-    QSGItemPrivate* pri = QSGItemPrivate::get(textEdit);
-    QSGTextEditPrivate *editPrivate = static_cast<QSGTextEditPrivate*>(pri);
-    QCOMPARE(textEdit->text(), editPrivate->text);
-
-    // select word
-    textEdit->setCursorPosition(0);
-    textEdit->selectWord();
-    QCOMPARE(textEdit->selectedText(), QString("Hello"));
-
-    // select all and cut
-    textEdit->selectAll();
-    textEdit->cut();
-    QCOMPARE(textEdit->text().length(), 0);
-    textEdit->paste();
-    QCOMPARE(textEdit->text(), QString("Hello world!Hello world!"));
-    QCOMPARE(textEdit->text().length(), 24);
-#endif
-}
-
-void tst_qsgtextedit::canPaste() {
-#ifndef QT_NO_CLIPBOARD
-
-    QGuiApplication::clipboard()->setText("Some text");
-
-    QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"Hello world!\" }";
-    QDeclarativeComponent textEditComponent(&engine);
-    textEditComponent.setData(componentStr.toLatin1(), QUrl());
-    QSGTextEdit *textEdit = qobject_cast<QSGTextEdit*>(textEditComponent.create());
-    QVERIFY(textEdit != 0);
-
-    // check initial value - QTBUG-17765
-    QTextControl tc;
-    QCOMPARE(textEdit->canPaste(), tc.canPaste());
-
-#endif
-}
-
-void tst_qsgtextedit::canPasteEmpty() {
-#ifndef QT_NO_CLIPBOARD
-
-    QGuiApplication::clipboard()->clear();
-
-    QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"Hello world!\" }";
-    QDeclarativeComponent textEditComponent(&engine);
-    textEditComponent.setData(componentStr.toLatin1(), QUrl());
-    QSGTextEdit *textEdit = qobject_cast<QSGTextEdit*>(textEditComponent.create());
-    QVERIFY(textEdit != 0);
-
-    // check initial value - QTBUG-17765
-    QTextControl tc;
-    QCOMPARE(textEdit->canPaste(), tc.canPaste());
-
-#endif
-}
-
-void tst_qsgtextedit::readOnly()
-{
-    QSGView canvas(QUrl::fromLocalFile(TESTDATA("readOnly.qml")));
-    canvas.show();
-    canvas.requestActivateWindow();
-
-    QVERIFY(canvas.rootObject() != 0);
-
-    QSGTextEdit *edit = qobject_cast<QSGTextEdit *>(qvariant_cast<QObject *>(canvas.rootObject()->property("myInput")));
-
-    QVERIFY(edit != 0);
-    QTRY_VERIFY(edit->hasActiveFocus() == true);
-    QVERIFY(edit->isReadOnly() == true);
-    QString initial = edit->text();
-    for (int k=Qt::Key_0; k<=Qt::Key_Z; k++)
-        simulateKey(&canvas, k);
-    simulateKey(&canvas, Qt::Key_Return);
-    simulateKey(&canvas, Qt::Key_Space);
-    simulateKey(&canvas, Qt::Key_Escape);
-    QCOMPARE(edit->text(), initial);
-
-    edit->setCursorPosition(3);
-    edit->setReadOnly(false);
-    QCOMPARE(edit->isReadOnly(), false);
-    QCOMPARE(edit->cursorPosition(), edit->text().length());
-}
-
-void tst_qsgtextedit::simulateKey(QSGView *view, int key, Qt::KeyboardModifiers modifiers)
-{
-    QKeyEvent press(QKeyEvent::KeyPress, key, modifiers);
-    QKeyEvent release(QKeyEvent::KeyRelease, key, modifiers);
-
-    QGuiApplication::sendEvent(view, &press);
-    QGuiApplication::sendEvent(view, &release);
-}
-
-
-#ifndef QTBUG_21691
-class MyInputContext : public QInputContext
-{
-public:
-    MyInputContext() : updateReceived(false), eventType(QEvent::None) {}
-    ~MyInputContext() {}
-
-    QString identifierName() { return QString(); }
-    QString language() { return QString(); }
-
-    void reset() {}
-
-    bool isComposing() const { return false; }
-
-    void update() { updateReceived = true; }
-
-    void sendPreeditText(const QString &text, int cursor)
-    {
-        QList<QInputMethodEvent::Attribute> attributes;
-        attributes.append(QInputMethodEvent::Attribute(
-                QInputMethodEvent::Cursor, cursor, text.length(), QVariant()));
-
-        QInputMethodEvent event(text, attributes);
-        sendEvent(event);
-    }
-
-    void mouseHandler(int x, QMouseEvent *event)
-    {
-        cursor = x;
-        eventType = event->type();
-        eventPosition = event->pos();
-        eventGlobalPosition = event->globalPos();
-        eventButton = event->button();
-        eventButtons = event->buttons();
-        eventModifiers = event->modifiers();
-    }
-
-    bool updateReceived;
-    int cursor;
-    QEvent::Type eventType;
-    QPoint eventPosition;
-    QPoint eventGlobalPosition;
-    Qt::MouseButton eventButton;
-    Qt::MouseButtons eventButtons;
-    Qt::KeyboardModifiers eventModifiers;
-};
-#endif
-
-void tst_qsgtextedit::textInput()
-{
-    QSGView view(QUrl::fromLocalFile(TESTDATA("inputMethodEvent.qml")));
-    view.show();
-    view.requestActivateWindow();
-    QTest::qWaitForWindowShown(&view);
-    QTRY_COMPARE(&view, qGuiApp->focusWindow());
-    QSGTextEdit *edit = qobject_cast<QSGTextEdit *>(view.rootObject());
-    QVERIFY(edit);
-    QVERIFY(edit->hasActiveFocus() == true);
-
-    // test that input method event is committed
-    QInputMethodEvent event;
-    event.setCommitString( "Hello world!", 0, 0);
-    QGuiApplication::sendEvent(&view, &event);
-    QEXPECT_FAIL("", "QTBUG-21689", Abort);
-    QCOMPARE(edit->text(), QString("Hello world!"));
-
-    // QTBUG-12339
-    // test that document and internal text attribute are in sync
-    QSGTextEditPrivate *editPrivate = static_cast<QSGTextEditPrivate*>(QSGItemPrivate::get(edit));
-    QCOMPARE(editPrivate->text, QString("Hello world!"));
-}
-
-void tst_qsgtextedit::openInputPanel()
-{
-    QSGView view(QUrl::fromLocalFile(TESTDATA("openInputPanel.qml")));
-    view.show();
-    view.requestActivateWindow();
-    QTest::qWaitForWindowShown(&view);
-    QTRY_COMPARE(&view, qGuiApp->focusWindow());
-
-    QSGTextEdit *edit = qobject_cast<QSGTextEdit *>(view.rootObject());
-    QVERIFY(edit);
-
-    // check default values
-    QVERIFY(edit->focusOnPress());
-    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(qApp->inputPanel()->inputItem(), edit);
-    QCOMPARE(qApp->inputPanel()->visible(), true);
-    QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint);
-
-    // 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, noModifiers, centerPoint);
-    QGuiApplication::processEvents();
-    QCOMPARE(qApp->inputPanel()->visible(), true);
-    QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint);
-
-    // 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);
-    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);
-    QCOMPARE(qApp->inputPanel()->inputItem(), static_cast<QObject*>(0));
-    QCOMPARE(view.activeFocusItem(), &item);
-
-    qApp->inputPanel()->hide();
-
-    // input panel should not be opened if TextEdit is read only
-    edit->setReadOnly(true);
-    edit->setFocus(true);
-    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);
-
-    // input panel should not be opened if focusOnPress is set to false
-    edit->setFocusOnPress(false);
-    edit->setFocus(false);
-    edit->setFocus(true);
-    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 panel should open when openSoftwareInputPanel is called
-    edit->openSoftwareInputPanel();
-    QCOMPARE(qApp->inputPanel()->visible(), true);
-
-    // input panel should close when closeSoftwareInputPanel is called
-    edit->closeSoftwareInputPanel();
-    QCOMPARE(qApp->inputPanel()->visible(), false);
-}
-
-void tst_qsgtextedit::geometrySignals()
-{
-    QDeclarativeComponent component(&engine, TESTDATA("geometrySignals.qml"));
-    QObject *o = component.create();
-    QVERIFY(o);
-    QCOMPARE(o->property("bindingWidth").toInt(), 400);
-    QCOMPARE(o->property("bindingHeight").toInt(), 500);
-    delete o;
-}
-
-void tst_qsgtextedit::pastingRichText_QTBUG_14003()
-{
-#ifndef QT_NO_CLIPBOARD
-    QString componentStr = "import QtQuick 2.0\nTextEdit { textFormat: TextEdit.PlainText }";
-    QDeclarativeComponent component(&engine);
-    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGTextEdit *obj = qobject_cast<QSGTextEdit*>(component.create());
-
-    QTRY_VERIFY(obj != 0);
-    QTRY_VERIFY(obj->textFormat() == QSGTextEdit::PlainText);
-
-    QMimeData *mData = new QMimeData;
-    mData->setHtml("<font color=\"red\">Hello</font>");
-    QGuiApplication::clipboard()->setMimeData(mData);
-
-    obj->paste();
-    QTRY_VERIFY(obj->text() == "");
-    QTRY_VERIFY(obj->textFormat() == QSGTextEdit::PlainText);
-#endif
-}
-
-void tst_qsgtextedit::implicitSize_data()
-{
-    QTest::addColumn<QString>("text");
-    QTest::addColumn<QString>("wrap");
-    QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap";
-    QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.NoWrap";
-    QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap";
-    QTest::newRow("richtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.Wrap";
-}
-
-void tst_qsgtextedit::implicitSize()
-{
-    QFETCH(QString, text);
-    QFETCH(QString, wrap);
-    QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + " }";
-    QDeclarativeComponent textComponent(&engine);
-    textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGTextEdit *textObject = qobject_cast<QSGTextEdit*>(textComponent.create());
-
-    QVERIFY(textObject->width() < textObject->implicitWidth());
-    QVERIFY(textObject->height() == textObject->implicitHeight());
-
-    textObject->resetWidth();
-    QVERIFY(textObject->width() == textObject->implicitWidth());
-    QVERIFY(textObject->height() == textObject->implicitHeight());
-}
-
-void tst_qsgtextedit::testQtQuick11Attributes()
-{
-    QFETCH(QString, code);
-    QFETCH(QString, warning);
-    QFETCH(QString, error);
-
-    QDeclarativeEngine engine;
-    QObject *obj;
-
-    QDeclarativeComponent valid(&engine);
-    valid.setData("import QtQuick 2.0; TextEdit { " + code.toUtf8() + " }", QUrl(""));
-    obj = valid.create();
-    QVERIFY(obj);
-    QVERIFY(valid.errorString().isEmpty());
-    delete obj;
-
-    QDeclarativeComponent invalid(&engine);
-    invalid.setData("import QtQuick 1.0; TextEdit { " + code.toUtf8() + " }", QUrl(""));
-    QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
-    obj = invalid.create();
-    QCOMPARE(invalid.errorString(), error);
-    delete obj;
-}
-
-void tst_qsgtextedit::testQtQuick11Attributes_data()
-{
-    QTest::addColumn<QString>("code");
-    QTest::addColumn<QString>("warning");
-    QTest::addColumn<QString>("error");
-
-    QTest::newRow("canPaste") << "property bool foo: canPaste"
-        << "<Unknown File>:1: ReferenceError: Can't find variable: canPaste"
-        << "";
-
-    QTest::newRow("lineCount") << "property int foo: lineCount"
-        << "<Unknown File>:1: ReferenceError: Can't find variable: lineCount"
-        << "";
-
-    QTest::newRow("moveCursorSelection") << "Component.onCompleted: moveCursorSelection(0, TextEdit.SelectCharacters)"
-        << "<Unknown File>:1: ReferenceError: Can't find variable: moveCursorSelection"
-        << "";
-
-    QTest::newRow("deselect") << "Component.onCompleted: deselect()"
-        << "<Unknown File>:1: ReferenceError: Can't find variable: deselect"
-        << "";
-
-    QTest::newRow("onLinkActivated") << "onLinkActivated: {}"
-        << "QDeclarativeComponent: Component is not ready"
-        << ":1 \"TextEdit.onLinkActivated\" is not available in QtQuick 1.0.\n";
-}
-
-void tst_qsgtextedit::preeditMicroFocus()
-{
-#ifdef QTBUG_21691
-    QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
-    QVERIFY(false);
-#else
-    QString preeditText = "super";
-
-    QSGView view(QUrl::fromLocalFile(TESTDATA("inputMethodEvent.qml")));
-    view.show();
-    view.requestActivateWindow();
-    QTest::qWaitForWindowShown(&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::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::ImCursorRectangle).toRect();
-    QCOMPARE(currentRect, previousRect);
-#if defined(Q_WS_X11) || defined(Q_WS_QWS)
-    QCOMPARE(ic.updateReceived, false); // The cursor position hasn't changed.
-#endif
-    QCOMPARE(cursorRectangleSpy.count(), 0);
-
-    // Verify that the micro focus rect moves to the left as the cursor position
-    // is incremented.
-    for (int i = 1; i <= 5; ++i) {
-        ic.updateReceived = false;
-        ic.sendPreeditText(preeditText, i);
-        currentRect = edit->inputMethodQuery(Qt::ImCursorRectangle).toRect();
-        QVERIFY(previousRect.left() < currentRect.left());
-#if defined(Q_WS_X11) || defined(Q_WS_QWS)
-        QCOMPARE(ic.updateReceived, true);
-#endif
-        QVERIFY(cursorRectangleSpy.count() > 0);
-        cursorRectangleSpy.clear();
-        previousRect = currentRect;
-    }
-
-    // Verify that if there is no preedit cursor then the micro focus rect is the
-    // same as it would be if it were positioned at the end of the preedit text.
-    ic.sendPreeditText(preeditText, 0);
-    ic.updateReceived = false;
-    ic.sendEvent(QInputMethodEvent(preeditText, QList<QInputMethodEvent::Attribute>()));
-    currentRect = edit->inputMethodQuery(Qt::ImCursorRectangle).toRect();
-    QCOMPARE(currentRect, previousRect);
-#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(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.
-    view.setAttribute(Qt::WA_InputMethodEnabled, true);
-    view.setInputContext(&ic);
-    view.setAttribute(Qt::WA_InputMethodEnabled, false);
-    view.show();
-    view.requestActivateWindow();
-    QTest::qWaitForWindowShown(&view);
-
-    QTRY_COMPARE(&view, qGuiApp->focusWindow());
-    QSGTextEdit *edit = qobject_cast<QSGTextEdit *>(view.rootObject());
-    QVERIFY(edit);
-    edit->setCursorPosition(12);
-
-    QFontMetricsF fm(edit->font());
-    const qreal y = fm.height() / 2;
-
-    QPoint position2 = edit->mapToScene(QPointF(fm.width(text.mid(0, 2)), y)).toPoint();
-    QPoint position8 = edit->mapToScene(QPointF(fm.width(text.mid(0, 8)), y)).toPoint();
-    QPoint position20 = edit->mapToScene(QPointF(fm.width(text.mid(0, 20)), y)).toPoint();
-    QPoint position27 = edit->mapToScene(QPointF(fm.width(text.mid(0, 27)), y)).toPoint();
-    QPoint globalPosition2 = view.mapToGlobal(position2);
-    QPoint globalposition8 = view.mapToGlobal(position8);
-    QPoint globalposition20 = view.mapToGlobal(position20);
-    QPoint globalposition27 = view.mapToGlobal(position27);
-
-    ic.sendEvent(QInputMethodEvent(text.mid(12), QList<QInputMethodEvent::Attribute>()));
-
-    QTest::mouseDClick(&view, Qt::LeftButton, Qt::NoModifier, position2);
-    QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
-    QCOMPARE(ic.eventPosition, position2);
-    QCOMPARE(ic.eventGlobalPosition, globalPosition2);
-    QCOMPARE(ic.eventButton, Qt::LeftButton);
-    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
-    QVERIFY(ic.cursor < 0);
-    ic.eventType = QEvent::None;
-
-    QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, position2);
-    QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
-    QCOMPARE(ic.eventPosition, position2);
-    QCOMPARE(ic.eventGlobalPosition, globalPosition2);
-    QCOMPARE(ic.eventButton, Qt::LeftButton);
-    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
-    QVERIFY(ic.cursor < 0);
-    ic.eventType = QEvent::None;
-
-    {   QMouseEvent mv(QEvent::MouseMove, position8, globalposition8, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
-        QGuiApplication::sendEvent(&view, &mv); }
-    QCOMPARE(ic.eventType, QEvent::None);
-
-    {   QMouseEvent mv(QEvent::MouseMove, position27, globalposition27, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
-        QGuiApplication::sendEvent(&view, &mv); }
-    QCOMPARE(ic.eventType, QEvent::MouseMove);
-    QCOMPARE(ic.eventPosition, position27);
-        QCOMPARE(ic.eventGlobalPosition, globalposition27);
-    QCOMPARE(ic.eventButton, Qt::LeftButton);
-    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
-    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);    // 15 is expected but some platforms may be off by one.
-    ic.eventType = QEvent::None;
-
-    QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, position27);
-    QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
-    QCOMPARE(ic.eventPosition, position27);
-    QCOMPARE(ic.eventGlobalPosition, globalposition27);
-    QCOMPARE(ic.eventButton, Qt::LeftButton);
-    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
-    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
-    ic.eventType = QEvent::None;
-
-    // And in the other direction.
-    QTest::mouseDClick(&view, Qt::LeftButton, Qt::ControlModifier, position27);
-    QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
-    QCOMPARE(ic.eventPosition, position27);
-    QCOMPARE(ic.eventGlobalPosition, globalposition27);
-    QCOMPARE(ic.eventButton, Qt::LeftButton);
-    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
-    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
-    ic.eventType = QEvent::None;
-
-    QTest::mousePress(&view, Qt::RightButton, Qt::ControlModifier, position27);
-    QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
-    QCOMPARE(ic.eventPosition, position27);
-    QCOMPARE(ic.eventGlobalPosition, globalposition27);
-    QCOMPARE(ic.eventButton, Qt::RightButton);
-    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
-    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
-    ic.eventType = QEvent::None;
-
-    {   QMouseEvent mv(QEvent::MouseMove, position20, globalposition20, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
-        QGuiApplication::sendEvent(&view, &mv); }
-    QCOMPARE(ic.eventType, QEvent::MouseMove);
-    QCOMPARE(ic.eventPosition, position20);
-    QCOMPARE(ic.eventGlobalPosition, globalposition20);
-    QCOMPARE(ic.eventButton, Qt::RightButton);
-    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
-    QVERIFY(ic.cursor >= 7 && ic.cursor <= 9);
-    ic.eventType = QEvent::None;
-
-    {   QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
-        QGuiApplication::sendEvent(&view, &mv); }
-    QCOMPARE(ic.eventType, QEvent::None);
-
-    QTest::mouseRelease(&view, Qt::RightButton, Qt::ControlModifier, position2);
-    QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
-    QCOMPARE(ic.eventPosition, position2);
-    QCOMPARE(ic.eventGlobalPosition, globalPosition2);
-    QCOMPARE(ic.eventButton, Qt::RightButton);
-    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(TESTDATA("inputContext.qml")));
-    view.show();
-    view.requestActivateWindow();
-    QTest::qWaitForWindowShown(&view);
-    QTRY_COMPARE(&view, qGuiApp->focusWindow());
-    QSGTextEdit *edit = qobject_cast<QSGTextEdit *>(view.rootObject());
-    QVERIFY(edit);
-    QSignalSpy spy(edit, SIGNAL(inputMethodComposingChanged()));
-    edit->setCursorPosition(12);
-
-    QCOMPARE(edit->isInputMethodComposing(), false);
-
-    {
-        QInputMethodEvent event(text.mid(3), QList<QInputMethodEvent::Attribute>());
-        QGuiApplication::sendEvent(edit, &event);
-    }
-
-    QCOMPARE(edit->isInputMethodComposing(), true);
-    QCOMPARE(spy.count(), 1);
-
-    {
-        QInputMethodEvent event(text.mid(12), QList<QInputMethodEvent::Attribute>());
-        QGuiApplication::sendEvent(edit, &event);
-    }
-    QCOMPARE(spy.count(), 1);
-
-    {
-        QInputMethodEvent event;
-        QGuiApplication::sendEvent(edit, &event);
-    }
-    QCOMPARE(edit->isInputMethodComposing(), false);
-    QCOMPARE(spy.count(), 2);
-}
-
-void tst_qsgtextedit::cursorRectangleSize()
-{
-    QSGView *canvas = new QSGView(QUrl::fromLocalFile(TESTDATA("CursorRect.qml")));
-    QVERIFY(canvas->rootObject() != 0);
-    canvas->show();
-    canvas->requestActivateWindow();
-    QTest::qWaitForWindowShown(canvas);
-
-    QSGTextEdit *textEdit = qobject_cast<QSGTextEdit *>(canvas->rootObject());
-    QVERIFY(textEdit != 0);
-    textEdit->setFocus(Qt::OtherFocusReason);
-    QRectF cursorRect = textEdit->positionToRectangle(textEdit->cursorPosition());
-    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());
-
-    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/qsgtextinput.pro b/tests/auto/declarative/qsgtextinput/qsgtextinput.pro
deleted file mode 100644 (file)
index 1c988be..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsgtextinput
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_qsgtextinput.cpp
-
-testDataFiles.files = data
-testDataFiles.path = .
-DEPLOYMENT += testDataFiles
-
-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
deleted file mode 100644 (file)
index 09f4fb8..0000000
+++ /dev/null
@@ -1,2725 +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 <QtTest/QSignalSpy>
-#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 <private/qsgdistancefieldglyphcache_p.h>
-#include <QtOpenGL/QGLShaderProgram>
-#include <math.h>
-
-#include "qplatformdefs.h"
-
-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 = TESTDATA("");
-    QString arch = "unknown-architecture"; // QTest needs to help with this.
-
-    QString expectfile = persistent_dir + QDir::separator() + filebasename + "-" + arch + ".png";
-
-    if (!QFile::exists(expectfile)) {
-        actual.save(expectfile);
-        qWarning() << "created" << expectfile;
-    }
-
-    return expectfile;
-}
-
-class tst_qsgtextinput : public QObject
-
-{
-    Q_OBJECT
-public:
-    tst_qsgtextinput();
-
-private slots:
-    void initTestCase();
-    void cleanupTestCase();
-    void text();
-    void width();
-    void font();
-    void color();
-    void selection();
-    void isRightToLeft_data();
-    void isRightToLeft();
-    void moveCursorSelection_data();
-    void moveCursorSelection();
-    void moveCursorSelectionSequence_data();
-    void moveCursorSelectionSequence();
-    void dragMouseSelection();
-    void mouseSelectionMode_data();
-    void mouseSelectionMode();
-    void tripleClickSelectsAll();
-
-    void horizontalAlignment_data();
-    void horizontalAlignment();
-    void horizontalAlignment_RightToLeft();
-
-    void positionAt();
-
-    void maxLength();
-    void masks();
-    void validators();
-    void inputMethods();
-
-    void passwordCharacter();
-    void cursorDelegate();
-    void cursorVisible();
-    void cursorRectangle();
-    void navigation();
-    void navigation_RTL();
-    void copyAndPaste();
-    void canPasteEmpty();
-    void canPaste();
-    void readOnly();
-
-    void openInputPanel();
-    void setHAlignClearCache();
-    void focusOutClearSelection();
-
-    void echoMode();
-#ifdef QT_GUI_PASSWORD_ECHO_DELAY
-    void passwordEchoDelay();
-#endif
-    void geometrySignals();
-    void testQtQuick11Attributes();
-    void testQtQuick11Attributes_data();
-
-    void preeditAutoScroll();
-    void preeditMicroFocus();
-    void inputContextMouseHandler();
-    void inputMethodComposing();
-    void cursorRectangleSize();
-
-    void QTBUG_19956();
-    void QTBUG_19956_data();
-    void QTBUG_19956_regexp();
-
-private:
-    void simulateKey(QSGView *, int key);
-
-    QDeclarativeEngine engine;
-    QStringList standard;
-    QStringList colorStrings;
-};
-void tst_qsgtextinput::initTestCase()
-{
-}
-
-void tst_qsgtextinput::cleanupTestCase()
-{
-
-}
-tst_qsgtextinput::tst_qsgtextinput()
-{
-    standard << "the quick brown fox jumped over the lazy dog"
-        << "It's supercalifragisiticexpialidocious!"
-        << "Hello, world!"
-        << "!dlrow ,olleH"
-        << " spacey   text ";
-
-    colorStrings << "aliceblue"
-                 << "antiquewhite"
-                 << "aqua"
-                 << "darkkhaki"
-                 << "darkolivegreen"
-                 << "dimgray"
-                 << "palevioletred"
-                 << "lightsteelblue"
-                 << "#000000"
-                 << "#AAAAAA"
-                 << "#FFFFFF"
-                 << "#2AC05F";
-}
-
-void tst_qsgtextinput::text()
-{
-    {
-        QDeclarativeComponent textinputComponent(&engine);
-        textinputComponent.setData("import QtQuick 2.0\nTextInput {  text: \"\"  }", QUrl());
-        QSGTextInput *textinputObject = qobject_cast<QSGTextInput*>(textinputComponent.create());
-
-        QVERIFY(textinputObject != 0);
-        QCOMPARE(textinputObject->text(), QString(""));
-
-        delete textinputObject;
-    }
-
-    for (int i = 0; i < standard.size(); i++)
-    {
-        QString componentStr = "import QtQuick 2.0\nTextInput { text: \"" + standard.at(i) + "\" }";
-        QDeclarativeComponent textinputComponent(&engine);
-        textinputComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextInput *textinputObject = qobject_cast<QSGTextInput*>(textinputComponent.create());
-
-        QVERIFY(textinputObject != 0);
-        QCOMPARE(textinputObject->text(), standard.at(i));
-
-        delete textinputObject;
-    }
-
-}
-
-void tst_qsgtextinput::width()
-{
-    // uses Font metrics to find the width for standard
-    {
-        QDeclarativeComponent textinputComponent(&engine);
-        textinputComponent.setData("import QtQuick 2.0\nTextInput {  text: \"\" }", QUrl());
-        QSGTextInput *textinputObject = qobject_cast<QSGTextInput*>(textinputComponent.create());
-
-        QVERIFY(textinputObject != 0);
-        QCOMPARE(textinputObject->width(), 0.0);
-
-        delete textinputObject;
-    }
-
-    bool requiresUnhintedMetrics = !qmlDisableDistanceField();
-
-    for (int i = 0; i < standard.size(); i++)
-    {
-        QFont f;
-        qreal metricWidth = 0.0;
-        if (requiresUnhintedMetrics) {
-            QString s = standard.at(i);
-            s.replace(QLatin1Char('\n'), QChar::LineSeparator);
-
-            QTextLayout layout(s);
-            layout.setFlags(Qt::TextExpandTabs | Qt::TextShowMnemonic);
-            {
-                QTextOption option;
-                option.setUseDesignMetrics(true);
-                layout.setTextOption(option);
-            }
-
-            layout.beginLayout();
-            forever {
-                QTextLine line = layout.createLine();
-                if (!line.isValid())
-                    break;
-            }
-
-            layout.endLayout();
-
-            metricWidth = ceil(layout.boundingRect().width());
-        } else {
-            QFontMetricsF fm(f);
-            metricWidth = fm.width(standard.at(i));
-        }
-
-        QString componentStr = "import QtQuick 2.0\nTextInput { text: \"" + standard.at(i) + "\" }";
-        QDeclarativeComponent textinputComponent(&engine);
-        textinputComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextInput *textinputObject = qobject_cast<QSGTextInput*>(textinputComponent.create());
-
-        QVERIFY(textinputObject != 0);
-        int delta = abs(int(int(textinputObject->width()) - metricWidth));
-        QVERIFY(delta <= 3.0); // As best as we can hope for cross-platform.
-
-        delete textinputObject;
-    }
-}
-
-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());
-        QSGTextInput *textinputObject = qobject_cast<QSGTextInput*>(textinputComponent.create());
-
-        QVERIFY(textinputObject != 0);
-        QCOMPARE(textinputObject->font().pointSize(), 40);
-        QCOMPARE(textinputObject->font().bold(), false);
-        QCOMPARE(textinputObject->font().italic(), false);
-
-        delete textinputObject;
-    }
-
-    {
-        QString componentStr = "import QtQuick 2.0\nTextInput {  font.bold: true; text: \"Hello World\" }";
-        QDeclarativeComponent textinputComponent(&engine);
-        textinputComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextInput *textinputObject = qobject_cast<QSGTextInput*>(textinputComponent.create());
-
-        QVERIFY(textinputObject != 0);
-        QCOMPARE(textinputObject->font().bold(), true);
-        QCOMPARE(textinputObject->font().italic(), false);
-
-        delete textinputObject;
-    }
-
-    {
-        QString componentStr = "import QtQuick 2.0\nTextInput {  font.italic: true; text: \"Hello World\" }";
-        QDeclarativeComponent textinputComponent(&engine);
-        textinputComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextInput *textinputObject = qobject_cast<QSGTextInput*>(textinputComponent.create());
-
-        QVERIFY(textinputObject != 0);
-        QCOMPARE(textinputObject->font().italic(), true);
-        QCOMPARE(textinputObject->font().bold(), false);
-
-        delete textinputObject;
-    }
-
-    {
-        QString componentStr = "import QtQuick 2.0\nTextInput {  font.family: \"Helvetica\"; text: \"Hello World\" }";
-        QDeclarativeComponent textinputComponent(&engine);
-        textinputComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextInput *textinputObject = qobject_cast<QSGTextInput*>(textinputComponent.create());
-
-        QVERIFY(textinputObject != 0);
-        QCOMPARE(textinputObject->font().family(), QString("Helvetica"));
-        QCOMPARE(textinputObject->font().bold(), false);
-        QCOMPARE(textinputObject->font().italic(), false);
-
-        delete textinputObject;
-    }
-
-    {
-        QString componentStr = "import QtQuick 2.0\nTextInput {  font.family: \"\"; text: \"Hello World\" }";
-        QDeclarativeComponent textinputComponent(&engine);
-        textinputComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextInput *textinputObject = qobject_cast<QSGTextInput*>(textinputComponent.create());
-
-        QVERIFY(textinputObject != 0);
-        QCOMPARE(textinputObject->font().family(), QString(""));
-
-        delete textinputObject;
-    }
-}
-
-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());
-        QSGTextInput *textinputObject = qobject_cast<QSGTextInput*>(textinputComponent.create());
-        QVERIFY(textinputObject != 0);
-        QCOMPARE(textinputObject->color(), QColor(colorStrings.at(i)));
-
-        delete textinputObject;
-    }
-
-    //test selection color
-    for (int i = 0; i < colorStrings.size(); i++)
-    {
-        QString componentStr = "import QtQuick 2.0\nTextInput {  selectionColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
-        QDeclarativeComponent textinputComponent(&engine);
-        textinputComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextInput *textinputObject = qobject_cast<QSGTextInput*>(textinputComponent.create());
-        QVERIFY(textinputObject != 0);
-        QCOMPARE(textinputObject->selectionColor(), QColor(colorStrings.at(i)));
-
-        delete textinputObject;
-    }
-
-    //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());
-        QSGTextInput *textinputObject = qobject_cast<QSGTextInput*>(textinputComponent.create());
-        QVERIFY(textinputObject != 0);
-        QCOMPARE(textinputObject->selectedTextColor(), QColor(colorStrings.at(i)));
-
-        delete textinputObject;
-    }
-
-    {
-        QString colorStr = "#AA001234";
-        QColor testColor("#001234");
-        testColor.setAlpha(170);
-
-        QString componentStr = "import QtQuick 2.0\nTextInput {  color: \"" + colorStr + "\"; text: \"Hello World\" }";
-        QDeclarativeComponent textinputComponent(&engine);
-        textinputComponent.setData(componentStr.toLatin1(), QUrl());
-        QSGTextInput *textinputObject = qobject_cast<QSGTextInput*>(textinputComponent.create());
-
-        QVERIFY(textinputObject != 0);
-        QCOMPARE(textinputObject->color(), testColor);
-
-        delete textinputObject;
-    }
-}
-
-void tst_qsgtextinput::selection()
-{
-    QString testStr = standard[0];
-    QString componentStr = "import QtQuick 2.0\nTextInput {  text: \""+ testStr +"\"; }";
-    QDeclarativeComponent textinputComponent(&engine);
-    textinputComponent.setData(componentStr.toLatin1(), QUrl());
-    QSGTextInput *textinputObject = qobject_cast<QSGTextInput*>(textinputComponent.create());
-    QVERIFY(textinputObject != 0);
-
-
-    //Test selection follows cursor
-    for (int i=0; i<= testStr.size(); i++) {
-        textinputObject->setCursorPosition(i);
-        QCOMPARE(textinputObject->cursorPosition(), i);
-        QCOMPARE(textinputObject->selectionStart(), i);
-        QCOMPARE(textinputObject->selectionEnd(), i);
-        QVERIFY(textinputObject->selectedText().isNull());
-    }
-
-    textinputObject->setCursorPosition(0);
-    QVERIFY(textinputObject->cursorPosition() == 0);
-    QVERIFY(textinputObject->selectionStart() == 0);
-    QVERIFY(textinputObject->selectionEnd() == 0);
-    QVERIFY(textinputObject->selectedText().isNull());
-
-    // Verify invalid positions are ignored.
-    textinputObject->setCursorPosition(-1);
-    QVERIFY(textinputObject->cursorPosition() == 0);
-    QVERIFY(textinputObject->selectionStart() == 0);
-    QVERIFY(textinputObject->selectionEnd() == 0);
-    QVERIFY(textinputObject->selectedText().isNull());
-
-    textinputObject->setCursorPosition(textinputObject->text().count()+1);
-    QVERIFY(textinputObject->cursorPosition() == 0);
-    QVERIFY(textinputObject->selectionStart() == 0);
-    QVERIFY(textinputObject->selectionEnd() == 0);
-    QVERIFY(textinputObject->selectedText().isNull());
-
-    //Test selection
-    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++) {
-        textinputObject->select(i,testStr.size());
-        QCOMPARE(testStr.mid(i,testStr.size()-i), textinputObject->selectedText());
-    }
-
-    textinputObject->setCursorPosition(0);
-    QVERIFY(textinputObject->cursorPosition() == 0);
-    QVERIFY(textinputObject->selectionStart() == 0);
-    QVERIFY(textinputObject->selectionEnd() == 0);
-    QVERIFY(textinputObject->selectedText().isNull());
-
-    //Test Error Ignoring behaviour
-    textinputObject->setCursorPosition(0);
-    QVERIFY(textinputObject->selectedText().isNull());
-    textinputObject->select(-10,0);
-    QVERIFY(textinputObject->selectedText().isNull());
-    textinputObject->select(100,110);
-    QVERIFY(textinputObject->selectedText().isNull());
-    textinputObject->select(0,-10);
-    QVERIFY(textinputObject->selectedText().isNull());
-    textinputObject->select(0,100);
-    QVERIFY(textinputObject->selectedText().isNull());
-    textinputObject->select(0,10);
-    QVERIFY(textinputObject->selectedText().size() == 10);
-    textinputObject->select(-10,10);
-    QVERIFY(textinputObject->selectedText().size() == 10);
-    textinputObject->select(100,101);
-    QVERIFY(textinputObject->selectedText().size() == 10);
-    textinputObject->select(0,-10);
-    QVERIFY(textinputObject->selectedText().size() == 10);
-    textinputObject->select(0,100);
-    QVERIFY(textinputObject->selectedText().size() == 10);
-
-    textinputObject->deselect();
-    QVERIFY(textinputObject->selectedText().isNull());
-    textinputObject->select(0,10);
-    QVERIFY(textinputObject->selectedText().size() == 10);
-    textinputObject->deselect();
-    QVERIFY(textinputObject->selectedText().isNull());
-
-    delete textinputObject;
-}
-
-void tst_qsgtextinput::isRightToLeft_data()
-{
-    QTest::addColumn<QString>("text");
-    QTest::addColumn<bool>("emptyString");
-    QTest::addColumn<bool>("firstCharacter");
-    QTest::addColumn<bool>("lastCharacter");
-    QTest::addColumn<bool>("middleCharacter");
-    QTest::addColumn<bool>("startString");
-    QTest::addColumn<bool>("midString");
-    QTest::addColumn<bool>("endString");
-
-    const quint16 arabic_str[] = { 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0647};
-    QTest::newRow("Empty") << "" << false << false << false << false << false << false << false;
-    QTest::newRow("Neutral") << "23244242" << false << false << false << false << false << false << false;
-    QTest::newRow("LTR") << "Hello world" << false << false << false << false << false << false << false;
-    QTest::newRow("RTL") << QString::fromUtf16(arabic_str, 11) << false << true << true << true << true << true << true;
-    QTest::newRow("Bidi RTL + LTR + RTL") << QString::fromUtf16(arabic_str, 11) + QString("Hello world") + QString::fromUtf16(arabic_str, 11) << false << true << true << false << true << true << true;
-    QTest::newRow("Bidi LTR + RTL + LTR") << QString("Hello world") + QString::fromUtf16(arabic_str, 11) + QString("Hello world") << false << false << false << true << false << false << false;
-}
-
-void tst_qsgtextinput::isRightToLeft()
-{
-    QFETCH(QString, text);
-    QFETCH(bool, emptyString);
-    QFETCH(bool, firstCharacter);
-    QFETCH(bool, lastCharacter);
-    QFETCH(bool, middleCharacter);
-    QFETCH(bool, startString);
-    QFETCH(bool, midString);
-    QFETCH(bool, endString);
-
-    QSGTextInput textInput;
-    textInput.setText(text);
-
-    // first test that the right string is delivered to the QString::isRightToLeft()
-    QCOMPARE(textInput.isRightToLeft(0,0), text.mid(0,0).isRightToLeft());
-    QCOMPARE(textInput.isRightToLeft(0,1), text.mid(0,1).isRightToLeft());
-    QCOMPARE(textInput.isRightToLeft(text.count()-2, text.count()-1), text.mid(text.count()-2, text.count()-1).isRightToLeft());
-    QCOMPARE(textInput.isRightToLeft(text.count()/2, text.count()/2 + 1), text.mid(text.count()/2, text.count()/2 + 1).isRightToLeft());
-    QCOMPARE(textInput.isRightToLeft(0,text.count()/4), text.mid(0,text.count()/4).isRightToLeft());
-    QCOMPARE(textInput.isRightToLeft(text.count()/4,3*text.count()/4), text.mid(text.count()/4,3*text.count()/4).isRightToLeft());
-    if (text.isEmpty())
-        QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML TextInput: isRightToLeft(start, end) called with the end property being smaller than the start.");
-    QCOMPARE(textInput.isRightToLeft(3*text.count()/4,text.count()-1), text.mid(3*text.count()/4,text.count()-1).isRightToLeft());
-
-    // then test that the feature actually works
-    QCOMPARE(textInput.isRightToLeft(0,0), emptyString);
-    QCOMPARE(textInput.isRightToLeft(0,1), firstCharacter);
-    QCOMPARE(textInput.isRightToLeft(text.count()-2, text.count()-1), lastCharacter);
-    QCOMPARE(textInput.isRightToLeft(text.count()/2, text.count()/2 + 1), middleCharacter);
-    QCOMPARE(textInput.isRightToLeft(0,text.count()/4), startString);
-    QCOMPARE(textInput.isRightToLeft(text.count()/4,3*text.count()/4), midString);
-    if (text.isEmpty())
-        QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML TextInput: isRightToLeft(start, end) called with the end property being smaller than the start.");
-    QCOMPARE(textInput.isRightToLeft(3*text.count()/4,text.count()-1), endString);
-}
-
-void tst_qsgtextinput::moveCursorSelection_data()
-{
-    QTest::addColumn<QString>("testStr");
-    QTest::addColumn<int>("cursorPosition");
-    QTest::addColumn<int>("movePosition");
-    QTest::addColumn<QSGTextInput::SelectionMode>("mode");
-    QTest::addColumn<int>("selectionStart");
-    QTest::addColumn<int>("selectionEnd");
-    QTest::addColumn<bool>("reversible");
-
-    // () contains the text selected by the cursor.
-    // <> contains the actual selection.
-
-    QTest::newRow("(t)he|characters")
-            << standard[0] << 0 << 1 << QSGTextInput::SelectCharacters << 0 << 1 << true;
-    QTest::newRow("do(g)|characters")
-            << standard[0] << 43 << 44 << QSGTextInput::SelectCharacters << 43 << 44 << true;
-    QTest::newRow("jum(p)ed|characters")
-            << standard[0] << 23 << 24 << QSGTextInput::SelectCharacters << 23 << 24 << true;
-    QTest::newRow("jumped( )over|characters")
-            << standard[0] << 26 << 27 << QSGTextInput::SelectCharacters << 26 << 27 << true;
-    QTest::newRow("(the )|characters")
-            << standard[0] << 0 << 4 << QSGTextInput::SelectCharacters << 0 << 4 << true;
-    QTest::newRow("( dog)|characters")
-            << standard[0] << 40 << 44 << QSGTextInput::SelectCharacters << 40 << 44 << true;
-    QTest::newRow("( jumped )|characters")
-            << standard[0] << 19 << 27 << QSGTextInput::SelectCharacters << 19 << 27 << true;
-    QTest::newRow("th(e qu)ick|characters")
-            << standard[0] << 2 << 6 << QSGTextInput::SelectCharacters << 2 << 6 << true;
-    QTest::newRow("la(zy d)og|characters")
-            << standard[0] << 38 << 42 << QSGTextInput::SelectCharacters << 38 << 42 << true;
-    QTest::newRow("jum(ped ov)er|characters")
-            << standard[0] << 23 << 29 << QSGTextInput::SelectCharacters << 23 << 29 << true;
-    QTest::newRow("()the|characters")
-            << standard[0] << 0 << 0 << QSGTextInput::SelectCharacters << 0 << 0 << true;
-    QTest::newRow("dog()|characters")
-            << standard[0] << 44 << 44 << QSGTextInput::SelectCharacters << 44 << 44 << true;
-    QTest::newRow("jum()ped|characters")
-            << standard[0] << 23 << 23 << QSGTextInput::SelectCharacters << 23 << 23 << true;
-
-    QTest::newRow("<(t)he>|words")
-            << standard[0] << 0 << 1 << QSGTextInput::SelectWords << 0 << 3 << true;
-    QTest::newRow("<do(g)>|words")
-            << standard[0] << 43 << 44 << QSGTextInput::SelectWords << 41 << 44 << true;
-    QTest::newRow("<jum(p)ed>|words")
-            << standard[0] << 23 << 24 << QSGTextInput::SelectWords << 20 << 26 << true;
-    QTest::newRow("<jumped( )>over|words,ltr")
-            << standard[0] << 26 << 27 << QSGTextInput::SelectWords << 20 << 27 << false;
-    QTest::newRow("jumped<( )over>|words,rtl")
-            << standard[0] << 27 << 26 << QSGTextInput::SelectWords << 26 << 31 << false;
-    QTest::newRow("<(the )>quick|words,ltr")
-            << standard[0] << 0 << 4 << QSGTextInput::SelectWords << 0 << 4 << false;
-    QTest::newRow("<(the )quick>|words,rtl")
-            << standard[0] << 4 << 0 << QSGTextInput::SelectWords << 0 << 9 << false;
-    QTest::newRow("<lazy( dog)>|words,ltr")
-            << standard[0] << 40 << 44 << QSGTextInput::SelectWords << 36 << 44 << false;
-    QTest::newRow("lazy<( dog)>|words,rtl")
-            << standard[0] << 44 << 40 << QSGTextInput::SelectWords << 40 << 44 << false;
-    QTest::newRow("<fox( jumped )>over|words,ltr")
-            << standard[0] << 19 << 27 << QSGTextInput::SelectWords << 16 << 27 << false;
-    QTest::newRow("fox<( jumped )over>|words,rtl")
-            << standard[0] << 27 << 19 << QSGTextInput::SelectWords << 19 << 31 << false;
-    QTest::newRow("<th(e qu)ick>|words")
-            << standard[0] << 2 << 6 << QSGTextInput::SelectWords << 0 << 9 << true;
-    QTest::newRow("<la(zy d)og|words>")
-            << standard[0] << 38 << 42 << QSGTextInput::SelectWords << 36 << 44 << true;
-    QTest::newRow("<jum(ped ov)er>|words")
-            << standard[0] << 23 << 29 << QSGTextInput::SelectWords << 20 << 31 << true;
-    QTest::newRow("<()>the|words")
-            << standard[0] << 0 << 0 << QSGTextInput::SelectWords << 0 << 0 << true;
-    QTest::newRow("dog<()>|words")
-            << standard[0] << 44 << 44 << QSGTextInput::SelectWords << 44 << 44 << true;
-    QTest::newRow("jum<()>ped|words")
-            << standard[0] << 23 << 23 << QSGTextInput::SelectWords << 23 << 23 << true;
-
-    QTest::newRow("Hello<(,)> |words")
-            << standard[2] << 5 << 6 << QSGTextInput::SelectWords << 5 << 6 << true;
-    QTest::newRow("Hello<(, )>world|words,ltr")
-            << standard[2] << 5 << 7 << QSGTextInput::SelectWords << 5 << 7 << false;
-    QTest::newRow("Hello<(, )world>|words,rtl")
-            << standard[2] << 7 << 5 << QSGTextInput::SelectWords << 5 << 12 << false;
-    QTest::newRow("<Hel(lo, )>world|words,ltr")
-            << standard[2] << 3 << 7 << QSGTextInput::SelectWords << 0 << 7 << false;
-    QTest::newRow("<Hel(lo, )world>|words,rtl")
-            << standard[2] << 7 << 3 << QSGTextInput::SelectWords << 0 << 12 << false;
-    QTest::newRow("<Hel(lo)>,|words")
-            << standard[2] << 3 << 5 << QSGTextInput::SelectWords << 0 << 5 << true;
-    QTest::newRow("Hello<()>,|words")
-            << standard[2] << 5 << 5 << QSGTextInput::SelectWords << 5 << 5 << true;
-    QTest::newRow("Hello,<()>|words")
-            << standard[2] << 6 << 6 << QSGTextInput::SelectWords << 6 << 6 << true;
-    QTest::newRow("Hello<,( )>world|words,ltr")
-            << standard[2] << 6 << 7 << QSGTextInput::SelectWords << 5 << 7 << false;
-    QTest::newRow("Hello,<( )world>|words,rtl")
-            << standard[2] << 7 << 6 << QSGTextInput::SelectWords << 6 << 12 << false;
-    QTest::newRow("Hello<,( world)>|words,ltr")
-            << standard[2] << 6 << 12 << QSGTextInput::SelectWords << 5 << 12 << false;
-    QTest::newRow("Hello,<( world)>|words,rtl")
-            << standard[2] << 12 << 6 << QSGTextInput::SelectWords << 6 << 12 << false;
-    QTest::newRow("Hello<,( world!)>|words,ltr")
-            << standard[2] << 6 << 13 << QSGTextInput::SelectWords << 5 << 13 << false;
-    QTest::newRow("Hello,<( world!)>|words,rtl")
-            << standard[2] << 13 << 6 << QSGTextInput::SelectWords << 6 << 13 << false;
-    QTest::newRow("Hello<(, world!)>|words")
-            << standard[2] << 5 << 13 << QSGTextInput::SelectWords << 5 << 13 << true;
-    // Fails due to an issue with QTextBoundaryFinder and punctuation at the end of strings.
-    // QTBUG-11365
-    // QTest::newRow("world<(!)>|words")
-    //         << standard[2] << 12 << 13 << QSGTextInput::SelectWords << 12 << 13 << true;
-    QTest::newRow("world!<()>)|words")
-            << standard[2] << 13 << 13 << QSGTextInput::SelectWords << 13 << 13 << true;
-    QTest::newRow("world<()>!)|words")
-            << standard[2] << 12 << 12 << QSGTextInput::SelectWords << 12 << 12 << true;
-
-    QTest::newRow("<(,)>olleH |words")
-            << standard[3] << 7 << 8 << QSGTextInput::SelectWords << 7 << 8 << true;
-    QTest::newRow("<dlrow( ,)>olleH|words,ltr")
-            << standard[3] << 6 << 8 << QSGTextInput::SelectWords << 1 << 8 << false;
-    QTest::newRow("dlrow<( ,)>olleH|words,rtl")
-            << standard[3] << 8 << 6 << QSGTextInput::SelectWords << 6 << 8 << false;
-    QTest::newRow("<dlrow( ,ol)leH>|words,ltr")
-            << standard[3] << 6 << 10 << QSGTextInput::SelectWords << 1 << 13 << false;
-    QTest::newRow("dlrow<( ,ol)leH>|words,rtl")
-            << standard[3] << 10 << 6 << QSGTextInput::SelectWords << 6 << 13 << false;
-    QTest::newRow(",<(ol)leH>,|words")
-            << standard[3] << 8 << 10 << QSGTextInput::SelectWords << 8 << 13 << true;
-    QTest::newRow(",<()>olleH|words")
-            << standard[3] << 8 << 8 << QSGTextInput::SelectWords << 8 << 8 << true;
-    QTest::newRow("<()>,olleH|words")
-            << standard[3] << 7 << 7 << QSGTextInput::SelectWords << 7 << 7 << true;
-    QTest::newRow("<dlrow( )>,olleH|words,ltr")
-            << standard[3] << 6 << 7 << QSGTextInput::SelectWords << 1 << 7 << false;
-    QTest::newRow("dlrow<( ),>olleH|words,rtl")
-            << standard[3] << 7 << 6 << QSGTextInput::SelectWords << 6 << 8 << false;
-    QTest::newRow("<(dlrow )>,olleH|words,ltr")
-            << standard[3] << 1 << 7 << QSGTextInput::SelectWords << 1 << 7 << false;
-    QTest::newRow("<(dlrow ),>olleH|words,rtl")
-            << standard[3] << 7 << 1 << QSGTextInput::SelectWords << 1 << 8 << false;
-    QTest::newRow("<(!dlrow )>,olleH|words,ltr")
-            << standard[3] << 0 << 7 << QSGTextInput::SelectWords << 0 << 7 << false;
-    QTest::newRow("<(!dlrow ),>olleH|words,rtl")
-            << standard[3] << 7 << 0 << QSGTextInput::SelectWords << 0 << 8 << false;
-    QTest::newRow("(!dlrow ,)olleH|words")
-            << standard[3] << 0 << 8 << QSGTextInput::SelectWords << 0 << 8 << true;
-    QTest::newRow("<(!)>dlrow|words")
-            << standard[3] << 0 << 1 << QSGTextInput::SelectWords << 0 << 1 << true;
-    QTest::newRow("<()>!dlrow|words")
-            << standard[3] << 0 << 0 << QSGTextInput::SelectWords << 0 << 0 << true;
-    QTest::newRow("!<()>dlrow|words")
-            << standard[3] << 1 << 1 << QSGTextInput::SelectWords << 1 << 1 << true;
-
-    QTest::newRow(" <s(pac)ey>   text |words")
-            << standard[4] << 1 << 4 << QSGTextInput::SelectWords << 1 << 7 << true;
-    QTest::newRow(" spacey   <t(ex)t> |words")
-            << standard[4] << 11 << 13 << QSGTextInput::SelectWords << 10 << 14 << false; // Should be reversible. QTBUG-11365
-    QTest::newRow("<( )>spacey   text |words|ltr")
-            << standard[4] << 0 << 1 << QSGTextInput::SelectWords << 0 << 1 << false;
-    QTest::newRow("<( )spacey>   text |words|rtl")
-            << standard[4] << 1 << 0 << QSGTextInput::SelectWords << 0 << 7 << false;
-    QTest::newRow("spacey   <text( )>|words|ltr")
-            << standard[4] << 14 << 15 << QSGTextInput::SelectWords << 10 << 15 << false;
-//    QTBUG-11365
-//    QTest::newRow("spacey   text<( )>|words|rtl")
-//            << standard[4] << 15 << 14 << QSGTextInput::SelectWords << 14 << 15 << false;
-    QTest::newRow("<()> spacey   text |words")
-            << standard[4] << 0 << 0 << QSGTextInput::SelectWords << 0 << 0 << false;
-    QTest::newRow(" spacey   text <()>|words")
-            << standard[4] << 15 << 15 << QSGTextInput::SelectWords << 15 << 15 << false;
-}
-
-void tst_qsgtextinput::moveCursorSelection()
-{
-    QFETCH(QString, testStr);
-    QFETCH(int, cursorPosition);
-    QFETCH(int, movePosition);
-    QFETCH(QSGTextInput::SelectionMode, mode);
-    QFETCH(int, selectionStart);
-    QFETCH(int, selectionEnd);
-    QFETCH(bool, reversible);
-
-    QString componentStr = "import QtQuick 2.0\nTextInput {  text: \""+ testStr +"\"; }";
-    QDeclarativeComponent textinputComponent(&engine);
-    textinputComponent.setData(componentStr.toLatin1(), QUrl());
-    QSGTextInput *textinputObject = qobject_cast<QSGTextInput*>(textinputComponent.create());
-    QVERIFY(textinputObject != 0);
-
-    textinputObject->setCursorPosition(cursorPosition);
-    textinputObject->moveCursorSelection(movePosition, mode);
-
-    QCOMPARE(textinputObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart));
-    QCOMPARE(textinputObject->selectionStart(), selectionStart);
-    QCOMPARE(textinputObject->selectionEnd(), selectionEnd);
-
-    if (reversible) {
-        textinputObject->setCursorPosition(movePosition);
-        textinputObject->moveCursorSelection(cursorPosition, mode);
-
-        QCOMPARE(textinputObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart));
-        QCOMPARE(textinputObject->selectionStart(), selectionStart);
-        QCOMPARE(textinputObject->selectionEnd(), selectionEnd);
-    }
-
-    delete textinputObject;
-}
-
-void tst_qsgtextinput::moveCursorSelectionSequence_data()
-{
-    QTest::addColumn<QString>("testStr");
-    QTest::addColumn<int>("cursorPosition");
-    QTest::addColumn<int>("movePosition1");
-    QTest::addColumn<int>("movePosition2");
-    QTest::addColumn<int>("selection1Start");
-    QTest::addColumn<int>("selection1End");
-    QTest::addColumn<int>("selection2Start");
-    QTest::addColumn<int>("selection2End");
-
-    // () contains the text selected by the cursor.
-    // <> contains the actual selection.
-    // ^ is the revised cursor position.
-    // {} contains the revised selection.
-
-    QTest::newRow("the {<quick( bro)wn> f^ox} jumped|ltr")
-            << standard[0]
-            << 9 << 13 << 17
-            << 4 << 15
-            << 4 << 19;
-    QTest::newRow("the quick<( {bro)wn> f^ox} jumped|rtl")
-            << standard[0]
-            << 13 << 9 << 17
-            << 9 << 15
-            << 10 << 19;
-    QTest::newRow("the {<quick( bro)wn> ^}fox jumped|ltr")
-            << standard[0]
-            << 9 << 13 << 16
-            << 4 << 15
-            << 4 << 16;
-    QTest::newRow("the quick<( {bro)wn> ^}fox jumped|rtl")
-            << standard[0]
-            << 13 << 9 << 16
-            << 9 << 15
-            << 10 << 16;
-    QTest::newRow("the {<quick( bro)wn^>} fox jumped|ltr")
-            << standard[0]
-            << 9 << 13 << 15
-            << 4 << 15
-            << 4 << 15;
-    QTest::newRow("the quick<( {bro)wn^>} f^ox jumped|rtl")
-            << standard[0]
-            << 13 << 9 << 15
-            << 9 << 15
-            << 10 << 15;
-    QTest::newRow("the {<quick() ^}bro)wn> fox|ltr")
-            << standard[0]
-            << 9 << 13 << 10
-            << 4 << 15
-            << 4 << 10;
-    QTest::newRow("the quick<( {^bro)wn>} fox|rtl")
-            << standard[0]
-            << 13 << 9 << 10
-            << 9 << 15
-            << 10 << 15;
-    QTest::newRow("the {<quick^}( bro)wn> fox|ltr")
-            << standard[0]
-            << 9 << 13 << 9
-            << 4 << 15
-            << 4 << 9;
-    QTest::newRow("the quick{<(^ bro)wn>} fox|rtl")
-            << standard[0]
-            << 13 << 9 << 9
-            << 9 << 15
-            << 9 << 15;
-    QTest::newRow("the {<qui^ck}( bro)wn> fox|ltr")
-            << standard[0]
-            << 9 << 13 << 7
-            << 4 << 15
-            << 4 << 9;
-    QTest::newRow("the {<qui^ck}( bro)wn> fox|rtl")
-            << standard[0]
-            << 13 << 9 << 7
-            << 9 << 15
-            << 4 << 15;
-    QTest::newRow("the {<^quick}( bro)wn> fox|ltr")
-            << standard[0]
-            << 9 << 13 << 4
-            << 4 << 15
-            << 4 << 9;
-    QTest::newRow("the {<^quick}( bro)wn> fox|rtl")
-            << standard[0]
-            << 13 << 9 << 4
-            << 9 << 15
-            << 4 << 15;
-    QTest::newRow("the{^ <quick}( bro)wn> fox|ltr")
-            << standard[0]
-            << 9 << 13 << 3
-            << 4 << 15
-            << 3 << 9;
-    QTest::newRow("the{^ <quick}( bro)wn> fox|rtl")
-            << standard[0]
-            << 13 << 9 << 3
-            << 9 << 15
-            << 3 << 15;
-    QTest::newRow("{t^he <quick}( bro)wn> fox|ltr")
-            << standard[0]
-            << 9 << 13 << 1
-            << 4 << 15
-            << 0 << 9;
-    QTest::newRow("{t^he <quick}( bro)wn> fox|rtl")
-            << standard[0]
-            << 13 << 9 << 1
-            << 9 << 15
-            << 0 << 15;
-
-    QTest::newRow("{<He(ll)o>, w^orld}!|ltr")
-            << standard[2]
-            << 2 << 4 << 8
-            << 0 << 5
-            << 0 << 12;
-    QTest::newRow("{<He(ll)o>, w^orld}!|rtl")
-            << standard[2]
-            << 4 << 2 << 8
-            << 0 << 5
-            << 0 << 12;
-
-    QTest::newRow("!{dlro^w ,<o(ll)eH>}|ltr")
-            << standard[3]
-            << 9 << 11 << 5
-            << 8 << 13
-            << 1 << 13;
-    QTest::newRow("!{dlro^w ,<o(ll)eH>}|rtl")
-            << standard[3]
-            << 11 << 9 << 5
-            << 8 << 13
-            << 1 << 13;
-
-    QTest::newRow("{<(^} sp)acey>   text |ltr")
-            << standard[4]
-            << 0 << 3 << 0
-            << 0 << 7
-            << 0 << 0;
-    QTest::newRow("{<( ^}sp)acey>   text |ltr")
-            << standard[4]
-            << 0 << 3 << 1
-            << 0 << 7
-            << 0 << 1;
-    QTest::newRow("<( {s^p)acey>}   text |rtl")
-            << standard[4]
-            << 3 << 0 << 2
-            << 0 << 7
-            << 1 << 7;
-    QTest::newRow("<( {^sp)acey>}   text |rtl")
-            << standard[4]
-            << 3 << 0 << 1
-            << 0 << 7
-            << 1 << 7;
-
-    QTest::newRow(" spacey   <te(xt {^)>}|rtl")
-            << standard[4]
-            << 15 << 12 << 15
-            << 10 << 15
-            << 15 << 15;
-//    QTBUG-11365
-//    QTest::newRow(" spacey   <te(xt{^ )>}|rtl")
-//            << standard[4]
-//            << 15 << 12 << 14
-//            << 10 << 15
-//            << 14 << 15;
-    QTest::newRow(" spacey   {<te(x^t} )>|ltr")
-            << standard[4]
-            << 12 << 15 << 13
-            << 10 << 15
-            << 10 << 14;
-//    QTBUG-11365
-//    QTest::newRow(" spacey   {<te(xt^} )>|ltr")
-//            << standard[4]
-//            << 12 << 15 << 14
-//            << 10 << 15
-//            << 10 << 14;
-}
-
-void tst_qsgtextinput::moveCursorSelectionSequence()
-{
-    QFETCH(QString, testStr);
-    QFETCH(int, cursorPosition);
-    QFETCH(int, movePosition1);
-    QFETCH(int, movePosition2);
-    QFETCH(int, selection1Start);
-    QFETCH(int, selection1End);
-    QFETCH(int, selection2Start);
-    QFETCH(int, selection2End);
-
-    QString componentStr = "import QtQuick 2.0\nTextInput {  text: \""+ testStr +"\"; }";
-    QDeclarativeComponent textinputComponent(&engine);
-    textinputComponent.setData(componentStr.toLatin1(), QUrl());
-    QSGTextInput *textinputObject = qobject_cast<QSGTextInput*>(textinputComponent.create());
-    QVERIFY(textinputObject != 0);
-
-    textinputObject->setCursorPosition(cursorPosition);
-
-    textinputObject->moveCursorSelection(movePosition1, QSGTextInput::SelectWords);
-    QCOMPARE(textinputObject->selectedText(), testStr.mid(selection1Start, selection1End - selection1Start));
-    QCOMPARE(textinputObject->selectionStart(), selection1Start);
-    QCOMPARE(textinputObject->selectionEnd(), selection1End);
-
-    textinputObject->moveCursorSelection(movePosition2, QSGTextInput::SelectWords);
-    QCOMPARE(textinputObject->selectedText(), testStr.mid(selection2Start, selection2End - selection2Start));
-    QCOMPARE(textinputObject->selectionStart(), selection2Start);
-    QCOMPARE(textinputObject->selectionEnd(), selection2End);
-
-    delete textinputObject;
-}
-
-void tst_qsgtextinput::dragMouseSelection()
-{
-    QString qmlfile = TESTDATA("mouseselection_true.qml");
-
-    QSGView canvas(QUrl::fromLocalFile(qmlfile));
-
-    canvas.show();
-    canvas.requestActivateWindow();
-    QTest::qWaitForWindowShown(&canvas);
-
-    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
-
-    QVERIFY(canvas.rootObject() != 0);
-    QSGTextInput *textInputObject = qobject_cast<QSGTextInput *>(canvas.rootObject());
-    QVERIFY(textInputObject != 0);
-
-    // press-and-drag-and-release from x1 to x2
-    int x1 = 10;
-    int x2 = 70;
-    int y = textInputObject->height()/2;
-    QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y));
-    QTest::mouseMove(&canvas, QPoint(x2, y));
-    QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y));
-    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));
-    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);
-}
-
-void tst_qsgtextinput::mouseSelectionMode_data()
-{
-    QTest::addColumn<QString>("qmlfile");
-    QTest::addColumn<bool>("selectWords");
-
-    // import installed
-    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()
-{
-    QFETCH(QString, qmlfile);
-    QFETCH(bool, selectWords);
-
-    QString text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
-    QSGView canvas(QUrl::fromLocalFile(qmlfile));
-
-    canvas.show();
-    canvas.requestActivateWindow();
-    QTest::qWaitForWindowShown(&canvas);
-    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
-
-    QVERIFY(canvas.rootObject() != 0);
-    QSGTextInput *textInputObject = qobject_cast<QSGTextInput *>(canvas.rootObject());
-    QVERIFY(textInputObject != 0);
-
-    // press-and-drag-and-release from x1 to x2
-    int x1 = 10;
-    int x2 = 70;
-    int y = textInputObject->height()/2;
-    QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y));
-    QTest::mouseMove(&canvas, QPoint(x2,y)); // doesn't work
-    QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y));
-    QTest::qWait(300);
-    if (selectWords) {
-        QTRY_COMPARE(textInputObject->selectedText(), text);
-    } else {
-        QTRY_VERIFY(textInputObject->selectedText().length() > 3);
-        QVERIFY(textInputObject->selectedText() != text);
-    }
-}
-
-void tst_qsgtextinput::horizontalAlignment_data()
-{
-    QTest::addColumn<int>("hAlign");
-    QTest::addColumn<QString>("expectfile");
-
-    QTest::newRow("L") << int(Qt::AlignLeft) << "halign_left";
-    QTest::newRow("R") << int(Qt::AlignRight) << "halign_right";
-    QTest::newRow("C") << int(Qt::AlignHCenter) << "halign_center";
-}
-
-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(TESTDATA("horizontalAlignment.qml")));
-
-    canvas.show();
-    canvas.requestActivateWindow();
-    QTest::qWaitForWindowShown(&canvas);
-    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
-    QObject *ob = canvas.rootObject();
-    QVERIFY(ob != 0);
-    ob->setProperty("horizontalAlignment",hAlign);
-    QImage actual = canvas.grabFrameBuffer();
-
-    expectfile = createExpectedFileIfNotFound(expectfile, actual);
-
-    QImage expect(expectfile);
-
-    QCOMPARE(actual,expect);
-}
-
-void tst_qsgtextinput::horizontalAlignment_RightToLeft()
-{
-    QSGView canvas(QUrl::fromLocalFile(TESTDATA("horizontalAlignment_RightToLeft.qml")));
-    QSGTextInput *textInput = canvas.rootObject()->findChild<QSGTextInput*>("text");
-    QVERIFY(textInput != 0);
-    canvas.show();
-
-    const QString rtlText = textInput->text();
-
-    QSGTextInputPrivate *textInputPrivate = QSGTextInputPrivate::get(textInput);
-    QVERIFY(textInputPrivate != 0);
-    QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
-
-    // implicit alignment should follow the reading direction of RTL text
-    QCOMPARE(textInput->hAlign(), QSGTextInput::AlignRight);
-    QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
-    QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
-
-    // explicitly left aligned
-    textInput->setHAlign(QSGTextInput::AlignLeft);
-    QCOMPARE(textInput->hAlign(), QSGTextInput::AlignLeft);
-    QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
-    QVERIFY(-textInputPrivate->hscroll < canvas.width()/2);
-
-    // explicitly right aligned
-    textInput->setHAlign(QSGTextInput::AlignRight);
-    QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
-    QCOMPARE(textInput->hAlign(), QSGTextInput::AlignRight);
-    QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
-
-    // explicitly center aligned
-    textInput->setHAlign(QSGTextInput::AlignHCenter);
-    QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
-    QCOMPARE(textInput->hAlign(), QSGTextInput::AlignHCenter);
-    QVERIFY(-textInputPrivate->hscroll < canvas.width()/2);
-    QVERIFY(-textInputPrivate->hscroll + textInputPrivate->width > canvas.width()/2);
-
-    // reseted alignment should go back to following the text reading direction
-    textInput->resetHAlign();
-    QCOMPARE(textInput->hAlign(), QSGTextInput::AlignRight);
-    QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
-    QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
-
-    // mirror the text item
-    QSGItemPrivate::get(textInput)->setLayoutMirror(true);
-
-    // mirrored implicit alignment should continue to follow the reading direction of the text
-    QCOMPARE(textInput->hAlign(), QSGTextInput::AlignRight);
-    QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
-    QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
-
-    // explicitly right aligned behaves as left aligned
-    textInput->setHAlign(QSGTextInput::AlignRight);
-    QCOMPARE(textInput->hAlign(), QSGTextInput::AlignRight);
-    QCOMPARE(textInput->effectiveHAlign(), QSGTextInput::AlignLeft);
-    QVERIFY(-textInputPrivate->hscroll < canvas.width()/2);
-
-    // mirrored explicitly left aligned behaves as right aligned
-    textInput->setHAlign(QSGTextInput::AlignLeft);
-    QCOMPARE(textInput->hAlign(), QSGTextInput::AlignLeft);
-    QCOMPARE(textInput->effectiveHAlign(), QSGTextInput::AlignRight);
-    QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
-
-    // disable mirroring
-    QSGItemPrivate::get(textInput)->setLayoutMirror(false);
-    QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
-    textInput->resetHAlign();
-
-    // English text should be implicitly left aligned
-    textInput->setText("Hello world!");
-    QCOMPARE(textInput->hAlign(), QSGTextInput::AlignLeft);
-    QVERIFY(-textInputPrivate->hscroll < canvas.width()/2);
-
-    canvas.requestActivateWindow();
-    QTest::qWaitForWindowShown(&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>()); QGuiApplication::sendEvent(&canvas, &ev); }
-    QEXPECT_FAIL("", "QTBUG-21691", Continue);
-    QCOMPARE(textInput->hAlign(), QSGTextInput::AlignRight);
-    { 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 QGuiApplication::keyboardInputDirection
-    textInput->setText("");
-    QCOMPARE(textInput->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ?
-                                  QSGTextInput::AlignLeft : QSGTextInput::AlignRight);
-    if (QGuiApplication::keyboardInputDirection() == Qt::LeftToRight)
-        QVERIFY(-textInputPrivate->hscroll < canvas.width()/2);
-    else
-        QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
-    textInput->setHAlign(QSGTextInput::AlignRight);
-    QCOMPARE(textInput->hAlign(), QSGTextInput::AlignRight);
-    QVERIFY(-textInputPrivate->hscroll > canvas.width()/2);
-#endif
-
-#ifndef Q_OS_MAC    // QTBUG-18040
-    // alignment of TextInput with no text set to it
-    QString componentStr = "import QtQuick 2.0\nTextInput {}";
-    QDeclarativeComponent textComponent(&engine);
-    textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
-    QSGTextInput *textObject = qobject_cast<QSGTextInput*>(textComponent.create());
-    QCOMPARE(textObject->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ?
-                                  QSGTextInput::AlignLeft : QSGTextInput::AlignRight);
-    delete textObject;
-#endif
-}
-
-void tst_qsgtextinput::positionAt()
-{
-    QSGView canvas(QUrl::fromLocalFile(TESTDATA("positionAt.qml")));
-    QVERIFY(canvas.rootObject() != 0);
-    canvas.show();
-    canvas.requestActivateWindow();
-    QTest::qWaitForWindowShown(&canvas);
-
-    QSGTextInput *textinputObject = qobject_cast<QSGTextInput *>(canvas.rootObject());
-    QVERIFY(textinputObject != 0);
-
-    // Check autoscrolled...
-    QFontMetrics fm(textinputObject->font());
-
-    int pos = textinputObject->positionAt(textinputObject->width()/2);
-    int textWidth = 0;
-    int textLeftWidth = 0;
-    if (!qmlDisableDistanceField()) {
-        {
-            QTextLayout layout(textinputObject->text().left(pos));
-
-            {
-                QTextOption option;
-                option.setUseDesignMetrics(true);
-                layout.setTextOption(option);
-            }
-
-            layout.beginLayout();
-            QTextLine line = layout.createLine();
-            layout.endLayout();
-
-            textLeftWidth = ceil(line.horizontalAdvance());
-        }
-        {
-            QTextLayout layout(textinputObject->text());
-
-            {
-                QTextOption option;
-                option.setUseDesignMetrics(true);
-                layout.setTextOption(option);
-            }
-
-            layout.beginLayout();
-            QTextLine line = layout.createLine();
-            layout.endLayout();
-
-            textWidth = ceil(line.horizontalAdvance());
-        }
-    } else {
-        textWidth = fm.width(textinputObject->text());
-        textLeftWidth = fm.width(textinputObject->text().left(pos));
-    }
-
-    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
-    QVERIFY(diff < 5);
-#endif
-
-    int x = textinputObject->positionToRectangle(pos + 1).x() - 1;
-    QCOMPARE(textinputObject->positionAt(x, QSGTextInput::CursorBetweenCharacters), pos + 1);
-    QCOMPARE(textinputObject->positionAt(x, QSGTextInput::CursorOnCharacter), pos);
-
-    // Check without autoscroll...
-    textinputObject->setAutoScroll(false);
-    pos = textinputObject->positionAt(textinputObject->width()/2);
-
-    if (!qmlDisableDistanceField()) {
-        {
-            QTextLayout layout(textinputObject->text().left(pos));
-
-            {
-                QTextOption option;
-                option.setUseDesignMetrics(true);
-                layout.setTextOption(option);
-            }
-
-            layout.beginLayout();
-            QTextLine line = layout.createLine();
-            layout.endLayout();
-
-            textLeftWidth = ceil(line.horizontalAdvance());
-        }
-    } else {
-        textLeftWidth = fm.width(textinputObject->text().left(pos));
-    }
-
-    diff = abs(int(textLeftWidth-textinputObject->width()/2));
-
-    // some tollerance for different fonts.
-#ifdef Q_OS_LINUX
-    QVERIFY(diff < 2);
-#else
-    QVERIFY(diff < 5);
-#endif
-
-    x = textinputObject->positionToRectangle(pos + 1).x() - 1;
-    QCOMPARE(textinputObject->positionAt(x, QSGTextInput::CursorBetweenCharacters), pos + 1);
-    QCOMPARE(textinputObject->positionAt(x, QSGTextInput::CursorOnCharacter), pos);
-
-    const qreal x0 = textinputObject->positionToRectangle(pos).x();
-    const qreal x1 = textinputObject->positionToRectangle(pos + 1).x();
-
-    QString preeditText = textinputObject->text().mid(0, pos);
-    textinputObject->setText(textinputObject->text().mid(pos));
-    textinputObject->setCursorPosition(0);
-
-    QInputMethodEvent inputEvent(preeditText, QList<QInputMethodEvent::Attribute>());
-    QGuiApplication::sendEvent(&canvas, &inputEvent);
-
-    // Check all points within the preedit text return the same position.
-    QCOMPARE(textinputObject->positionAt(0), 0);
-    QCOMPARE(textinputObject->positionAt(x0 / 2), 0);
-    QCOMPARE(textinputObject->positionAt(x0), 0);
-
-    // Verify positioning returns to normal after the preedit text.
-    QCOMPARE(textinputObject->positionAt(x1), 1);
-    QCOMPARE(textinputObject->positionToRectangle(1).x(), x1);
-}
-
-void tst_qsgtextinput::maxLength()
-{
-    QSGView canvas(QUrl::fromLocalFile(TESTDATA("maxLength.qml")));
-    QVERIFY(canvas.rootObject() != 0);
-    canvas.show();
-    canvas.requestActivateWindow();
-    QTest::qWaitForWindowShown(&canvas);
-
-    QSGTextInput *textinputObject = qobject_cast<QSGTextInput *>(canvas.rootObject());
-    QVERIFY(textinputObject != 0);
-    QVERIFY(textinputObject->text().isEmpty());
-    QVERIFY(textinputObject->maxLength() == 10);
-    foreach (const QString &str, standard) {
-        QVERIFY(textinputObject->text().length() <= 10);
-        textinputObject->setText(str);
-        QVERIFY(textinputObject->text().length() <= 10);
-    }
-
-    textinputObject->setText("");
-    QTRY_VERIFY(textinputObject->hasActiveFocus() == true);
-    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);
-    }
-}
-
-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(TESTDATA("masks.qml")));
-    canvas.show();
-    canvas.requestActivateWindow();
-    QVERIFY(canvas.rootObject() != 0);
-    QSGTextInput *textinputObject = qobject_cast<QSGTextInput *>(canvas.rootObject());
-    QVERIFY(textinputObject != 0);
-    QTRY_VERIFY(textinputObject->hasActiveFocus() == true);
-    QVERIFY(textinputObject->text().length() == 0);
-    QCOMPARE(textinputObject->inputMask(), QString("HHHHhhhh; "));
-    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);
-    }
-}
-
-void tst_qsgtextinput::validators()
-{
-    // Note that this test assumes that the validators are working properly
-    // 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(TESTDATA("validators.qml")));
-    canvas.show();
-    canvas.requestActivateWindow();
-
-    QVERIFY(canvas.rootObject() != 0);
-
-    QSGTextInput *intInput = qobject_cast<QSGTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("intInput")));
-    QVERIFY(intInput);
-    intInput->setFocus(true);
-    QTRY_VERIFY(intInput->hasActiveFocus());
-    QTest::keyPress(&canvas, Qt::Key_1);
-    QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10);
-    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);
-    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);
-
-    QSGTextInput *dblInput = qobject_cast<QSGTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("dblInput")));
-    QTRY_VERIFY(dblInput);
-    dblInput->setFocus(true);
-    QVERIFY(dblInput->hasActiveFocus() == true);
-    QTest::keyPress(&canvas, Qt::Key_1);
-    QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10);
-    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);
-    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);
-    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);
-    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);
-    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);
-    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")));
-    QTRY_VERIFY(strInput);
-    strInput->setFocus(true);
-    QVERIFY(strInput->hasActiveFocus() == true);
-    QTest::keyPress(&canvas, Qt::Key_1);
-    QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10);
-    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);
-    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);
-    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);
-    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);
-    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);
-    QTest::qWait(50);
-    QTRY_COMPARE(strInput->text(), QLatin1String("aaaa"));
-    QCOMPARE(strInput->hasAcceptableInput(), true);
-}
-
-void tst_qsgtextinput::inputMethods()
-{
-    QSGView canvas(QUrl::fromLocalFile(TESTDATA("inputmethods.qml")));
-    canvas.show();
-    canvas.requestActivateWindow();
-    QTest::qWaitForWindowShown(&canvas);
-
-    // test input method hints
-    QVERIFY(canvas.rootObject() != 0);
-    QSGTextInput *input = qobject_cast<QSGTextInput *>(canvas.rootObject());
-    QVERIFY(input != 0);
-    QVERIFY(input->inputMethodHints() & Qt::ImhNoPredictiveText);
-    input->setInputMethodHints(Qt::ImhUppercaseOnly);
-    QVERIFY(input->inputMethodHints() & Qt::ImhUppercaseOnly);
-
-    input->setFocus(true);
-    QVERIFY(input->hasActiveFocus() == true);
-    // test that input method event is committed
-    QInputMethodEvent event;
-    event.setCommitString( "My ", -12, 0);
-    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);
-    QGuiApplication::sendEvent(&canvas, &event);
-    QCOMPARE(input->text(), QString("Your Hello world!"));
-    QCOMPARE(input->cursorPosition(), 4);
-
-    input->setCursorPosition(7);
-    event.setCommitString("Goodbye", -2, 5);
-    QGuiApplication::sendEvent(&canvas, &event);
-    QCOMPARE(input->text(), QString("Your Goodbye world!"));
-    QCOMPARE(input->cursorPosition(), 12);
-
-    input->setCursorPosition(8);
-    event.setCommitString("Our", -8, 4);
-    QGuiApplication::sendEvent(&canvas, &event);
-    QCOMPARE(input->text(), QString("Our Goodbye world!"));
-    QCOMPARE(input->cursorPosition(), 7);
-}
-
-/*
-TextInput element should only handle left/right keys until the cursor reaches
-the extent of the text, then they should ignore the keys.
-
-*/
-void tst_qsgtextinput::navigation()
-{
-    QSGView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml")));
-    canvas.show();
-    canvas.requestActivateWindow();
-
-    QVERIFY(canvas.rootObject() != 0);
-
-    QSGTextInput *input = qobject_cast<QSGTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("myInput")));
-
-    QVERIFY(input != 0);
-    input->setCursorPosition(0);
-    QTRY_VERIFY(input->hasActiveFocus() == true);
-    simulateKey(&canvas, Qt::Key_Left);
-    QVERIFY(input->hasActiveFocus() == false);
-    simulateKey(&canvas, Qt::Key_Right);
-    QVERIFY(input->hasActiveFocus() == true);
-    //QT-2944: If text is selected, ensure we deselect upon cursor motion
-    input->setCursorPosition(input->text().length());
-    input->select(0,input->text().length());
-    QVERIFY(input->selectionStart() != input->selectionEnd());
-    simulateKey(&canvas, Qt::Key_Right);
-    QVERIFY(input->selectionStart() == input->selectionEnd());
-    QVERIFY(input->selectionStart() == input->text().length());
-    QVERIFY(input->hasActiveFocus() == true);
-    simulateKey(&canvas, Qt::Key_Right);
-    QVERIFY(input->hasActiveFocus() == false);
-    simulateKey(&canvas, Qt::Key_Left);
-    QVERIFY(input->hasActiveFocus() == true);
-
-    // Up and Down should NOT do Home/End, even on Mac OS X (QTBUG-10438).
-    input->setCursorPosition(2);
-    QCOMPARE(input->cursorPosition(),2);
-    simulateKey(&canvas, Qt::Key_Up);
-    QCOMPARE(input->cursorPosition(),2);
-    simulateKey(&canvas, Qt::Key_Down);
-    QCOMPARE(input->cursorPosition(),2);
-}
-
-void tst_qsgtextinput::navigation_RTL()
-{
-    QSGView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml")));
-    canvas.show();
-    canvas.requestActivateWindow();
-
-    QVERIFY(canvas.rootObject() != 0);
-
-    QSGTextInput *input = qobject_cast<QSGTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("myInput")));
-
-    QVERIFY(input != 0);
-    const quint16 arabic_str[] = { 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0647};
-    input->setText(QString::fromUtf16(arabic_str, 11));
-
-    input->setCursorPosition(0);
-    QTRY_VERIFY(input->hasActiveFocus() == true);
-
-    // move off
-    simulateKey(&canvas, Qt::Key_Right);
-    QVERIFY(input->hasActiveFocus() == false);
-
-    // move back
-    simulateKey(&canvas, Qt::Key_Left);
-    QVERIFY(input->hasActiveFocus() == true);
-
-    input->setCursorPosition(input->text().length());
-    QVERIFY(input->hasActiveFocus() == true);
-
-    // move off
-    simulateKey(&canvas, Qt::Key_Left);
-    QVERIFY(input->hasActiveFocus() == false);
-
-    // move back
-    simulateKey(&canvas, Qt::Key_Right);
-    QVERIFY(input->hasActiveFocus() == true);
-}
-
-void tst_qsgtextinput::copyAndPaste() {
-#ifndef QT_NO_CLIPBOARD
-
-#ifdef Q_WS_MAC
-    {
-        PasteboardRef pasteboard;
-        OSStatus status = PasteboardCreate(0, &pasteboard);
-        if (status == noErr)
-            CFRelease(pasteboard);
-        else
-            QSKIP("This machine doesn't support the clipboard");
-    }
-#endif
-
-    QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\" }";
-    QDeclarativeComponent textInputComponent(&engine);
-    textInputComponent.setData(componentStr.toLatin1(), QUrl());
-    QSGTextInput *textInput = qobject_cast<QSGTextInput*>(textInputComponent.create());
-    QVERIFY(textInput != 0);
-
-    // copy and paste
-    QCOMPARE(textInput->text().length(), 12);
-    textInput->select(0, textInput->text().length());;
-    textInput->copy();
-    QCOMPARE(textInput->selectedText(), QString("Hello world!"));
-    QCOMPARE(textInput->selectedText().length(), 12);
-    textInput->setCursorPosition(0);
-    QVERIFY(textInput->canPaste());
-    textInput->paste();
-    QCOMPARE(textInput->text(), QString("Hello world!Hello world!"));
-    QCOMPARE(textInput->text().length(), 24);
-
-    // can paste
-    QVERIFY(textInput->canPaste());
-    textInput->setReadOnly(true);
-    QVERIFY(!textInput->canPaste());
-    textInput->setReadOnly(false);
-    QVERIFY(textInput->canPaste());
-
-    // select word
-    textInput->setCursorPosition(0);
-    textInput->selectWord();
-    QCOMPARE(textInput->selectedText(), QString("Hello"));
-
-    // select all and cut
-    textInput->selectAll();
-    textInput->cut();
-    QCOMPARE(textInput->text().length(), 0);
-    textInput->paste();
-    QCOMPARE(textInput->text(), QString("Hello world!Hello world!"));
-    QCOMPARE(textInput->text().length(), 24);
-
-    // clear copy buffer
-    QClipboard *clipboard = QGuiApplication::clipboard();
-    QVERIFY(clipboard);
-    clipboard->clear();
-    QVERIFY(!textInput->canPaste());
-
-    // test that copy functionality is disabled
-    // when echo mode is set to hide text/password mode
-    int index = 0;
-    while (index < 4) {
-        QSGTextInput::EchoMode echoMode = QSGTextInput::EchoMode(index);
-        textInput->setEchoMode(echoMode);
-        textInput->setText("My password");
-        textInput->select(0, textInput->text().length());;
-        textInput->copy();
-        if (echoMode == QSGTextInput::Normal) {
-            QVERIFY(!clipboard->text().isEmpty());
-            QCOMPARE(clipboard->text(), QString("My password"));
-            clipboard->clear();
-        } else {
-            QVERIFY(clipboard->text().isEmpty());
-        }
-        index++;
-    }
-
-    delete textInput;
-#endif
-}
-
-void tst_qsgtextinput::canPasteEmpty() {
-#ifndef QT_NO_CLIPBOARD
-
-    QGuiApplication::clipboard()->clear();
-
-    QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\" }";
-    QDeclarativeComponent textInputComponent(&engine);
-    textInputComponent.setData(componentStr.toLatin1(), QUrl());
-    QSGTextInput *textInput = qobject_cast<QSGTextInput*>(textInputComponent.create());
-    QVERIFY(textInput != 0);
-
-    QLineControl lc;
-    bool cp = !lc.isReadOnly() && QGuiApplication::clipboard()->text().length() != 0;
-    QCOMPARE(textInput->canPaste(), cp);
-
-#endif
-}
-
-void tst_qsgtextinput::canPaste() {
-#ifndef QT_NO_CLIPBOARD
-
-    QGuiApplication::clipboard()->setText("Some text");
-
-    QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\" }";
-    QDeclarativeComponent textInputComponent(&engine);
-    textInputComponent.setData(componentStr.toLatin1(), QUrl());
-    QSGTextInput *textInput = qobject_cast<QSGTextInput*>(textInputComponent.create());
-    QVERIFY(textInput != 0);
-
-    QLineControl lc;
-    bool cp = !lc.isReadOnly() && QGuiApplication::clipboard()->text().length() != 0;
-    QCOMPARE(textInput->canPaste(), cp);
-
-#endif
-}
-
-void tst_qsgtextinput::passwordCharacter()
-{
-    QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\"; font.family: \"Helvetica\"; echoMode: TextInput.Password }";
-    QDeclarativeComponent textInputComponent(&engine);
-    textInputComponent.setData(componentStr.toLatin1(), QUrl());
-    QSGTextInput *textInput = qobject_cast<QSGTextInput*>(textInputComponent.create());
-    QVERIFY(textInput != 0);
-
-    textInput->setPasswordCharacter("X");
-    qreal implicitWidth = textInput->implicitWidth();
-    textInput->setPasswordCharacter(".");
-
-    // QTBUG-12383 content is updated and redrawn
-    QVERIFY(textInput->implicitWidth() < implicitWidth);
-
-    delete textInput;
-}
-
-void tst_qsgtextinput::cursorDelegate()
-{
-    QSGView view(QUrl::fromLocalFile(TESTDATA("cursorTest.qml")));
-    view.show();
-    view.requestActivateWindow();
-    QSGTextInput *textInputObject = view.rootObject()->findChild<QSGTextInput*>("textInputObject");
-    QVERIFY(textInputObject != 0);
-    QVERIFY(textInputObject->findChild<QSGItem*>("cursorInstance"));
-    //Test Delegate gets created
-    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++) {
-        textInputObject->setCursorPosition(i);
-        QCOMPARE(textInputObject->cursorRectangle().x(), qRound(delegateObject->x()));
-        QCOMPARE(textInputObject->cursorRectangle().y(), qRound(delegateObject->y()));
-    }
-    textInputObject->setCursorPosition(0);
-    QCOMPARE(textInputObject->cursorRectangle().x(), qRound(delegateObject->x()));
-    QCOMPARE(textInputObject->cursorRectangle().y(), qRound(delegateObject->y()));
-    //Test Delegate gets deleted
-    textInputObject->setCursorDelegate(0);
-    QVERIFY(!textInputObject->findChild<QSGItem*>("cursorInstance"));
-}
-
-void tst_qsgtextinput::cursorVisible()
-{
-    QSGView view(QUrl::fromLocalFile(TESTDATA("cursorVisible.qml")));
-    view.show();
-    view.requestActivateWindow();
-    QTest::qWaitForWindowShown(&view);
-    QTRY_COMPARE(&view, qGuiApp->focusWindow());
-
-    QSGTextInput input;
-    QSignalSpy spy(&input, SIGNAL(cursorVisibleChanged(bool)));
-
-    QCOMPARE(input.isCursorVisible(), false);
-
-    input.setCursorVisible(true);
-    QCOMPARE(input.isCursorVisible(), true);
-    QCOMPARE(spy.count(), 1);
-
-    input.setCursorVisible(false);
-    QCOMPARE(input.isCursorVisible(), false);
-    QCOMPARE(spy.count(), 2);
-
-    input.setFocus(true);
-    QCOMPARE(input.isCursorVisible(), false);
-    QCOMPARE(spy.count(), 2);
-
-    input.setParentItem(view.rootObject());
-    QCOMPARE(input.isCursorVisible(), true);
-    QCOMPARE(spy.count(), 3);
-
-    input.setFocus(false);
-    QCOMPARE(input.isCursorVisible(), false);
-    QCOMPARE(spy.count(), 4);
-
-    input.setFocus(true);
-    QCOMPARE(input.isCursorVisible(), true);
-    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);
-
-    view.requestActivateWindow();
-    QCOMPARE(input.isCursorVisible(), true);
-    QCOMPARE(spy.count(), 7);
-
-    // 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)
-    // 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;
-    input.setText(text);
-    QFontMetricsF fm(input.font());
-    input.setWidth(fm.width(text.mid(0, 5)));
-
-    QRect r;
-
-    // some tolerance for different fonts.
-#ifdef Q_OS_LINUX
-    const int error = 2;
-#else
-    const int error = 5;
-#endif
-
-
-    for (int i = 0; i <= 5; ++i) {
-        input.setCursorPosition(i);
-        r = input.cursorRectangle();
-        int textWidth = fm.width(text.mid(0, i));
-
-        QVERIFY(r.left() < textWidth + error);
-        QVERIFY(r.right() > textWidth - error);
-        QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
-    }
-
-    // Check the cursor rectangle remains within the input bounding rect when auto scrolling.
-    QVERIFY(r.left() < input.boundingRect().width());
-    QVERIFY(r.right() >= input.width() - error);
-
-    for (int i = 6; i < text.length(); ++i) {
-        input.setCursorPosition(i);
-        QCOMPARE(r, input.cursorRectangle());
-        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::ImCursorRectangle).toRect(), r);
-    }
-
-    input.setText("Hi!");
-    input.setHAlign(QSGTextInput::AlignRight);
-    r = input.cursorRectangle();
-    QVERIFY(r.left() < input.boundingRect().width());
-    QVERIFY(r.right() >= input.width() - error);
-}
-
-void tst_qsgtextinput::readOnly()
-{
-    QSGView canvas(QUrl::fromLocalFile(TESTDATA("readOnly.qml")));
-    canvas.show();
-    canvas.requestActivateWindow();
-
-    QVERIFY(canvas.rootObject() != 0);
-
-    QSGTextInput *input = qobject_cast<QSGTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("myInput")));
-
-    QVERIFY(input != 0);
-    QTRY_VERIFY(input->hasActiveFocus() == true);
-    QVERIFY(input->isReadOnly() == true);
-    QString initial = input->text();
-    for (int k=Qt::Key_0; k<=Qt::Key_Z; k++)
-        simulateKey(&canvas, k);
-    simulateKey(&canvas, Qt::Key_Return);
-    simulateKey(&canvas, Qt::Key_Space);
-    simulateKey(&canvas, Qt::Key_Escape);
-    QCOMPARE(input->text(), initial);
-
-    input->setCursorPosition(3);
-    input->setReadOnly(false);
-    QCOMPARE(input->isReadOnly(), false);
-    QCOMPARE(input->cursorPosition(), input->text().length());
-}
-
-void tst_qsgtextinput::echoMode()
-{
-    QSGView canvas(QUrl::fromLocalFile(TESTDATA("echoMode.qml")));
-    canvas.show();
-    canvas.requestActivateWindow();
-    QTest::qWaitForWindowShown(&canvas);
-    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
-
-    QVERIFY(canvas.rootObject() != 0);
-
-    QSGTextInput *input = qobject_cast<QSGTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("myInput")));
-
-    QVERIFY(input != 0);
-    QTRY_VERIFY(input->hasActiveFocus() == true);
-    QString initial = input->text();
-    Qt::InputMethodHints ref;
-    QCOMPARE(initial, QLatin1String("ABCDefgh"));
-    QCOMPARE(input->echoMode(), QSGTextInput::Normal);
-    QCOMPARE(input->displayText(), input->text());
-    //Normal
-    ref &= ~Qt::ImhHiddenText;
-    ref &= ~(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText);
-    QCOMPARE(input->inputMethodHints(), ref);
-    input->setEchoMode(QSGTextInput::NoEcho);
-    QCOMPARE(input->text(), initial);
-    QCOMPARE(input->displayText(), QLatin1String(""));
-    QCOMPARE(input->passwordCharacter(), QLatin1String("*"));
-    //NoEcho
-    ref |= Qt::ImhHiddenText;
-    ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText);
-    QCOMPARE(input->inputMethodHints(), ref);
-    input->setEchoMode(QSGTextInput::Password);
-    //Password
-    ref |= Qt::ImhHiddenText;
-    ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText);
-    QCOMPARE(input->text(), initial);
-    QCOMPARE(input->displayText(), QLatin1String("********"));
-    QCOMPARE(input->inputMethodHints(), ref);
-    input->setPasswordCharacter(QChar('Q'));
-    QCOMPARE(input->passwordCharacter(), QLatin1String("Q"));
-    QCOMPARE(input->text(), initial);
-    QCOMPARE(input->displayText(), QLatin1String("QQQQQQQQ"));
-    input->setEchoMode(QSGTextInput::PasswordEchoOnEdit);
-    //PasswordEchoOnEdit
-    ref &= ~Qt::ImhHiddenText;
-    ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText);
-    QCOMPARE(input->inputMethodHints(), ref);
-    QCOMPARE(input->text(), initial);
-    QCOMPARE(input->displayText(), QLatin1String("QQQQQQQQ"));
-    QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QLatin1String("QQQQQQQQ"));
-    QTest::keyPress(&canvas, Qt::Key_A);//Clearing previous entry is part of PasswordEchoOnEdit
-    QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10);
-    QCOMPARE(input->text(), QLatin1String("a"));
-    QCOMPARE(input->displayText(), QLatin1String("a"));
-    QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QLatin1String("a"));
-    input->setFocus(false);
-    QVERIFY(input->hasActiveFocus() == false);
-    QCOMPARE(input->displayText(), QLatin1String("Q"));
-    QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QLatin1String("Q"));
-    input->setFocus(true);
-    QVERIFY(input->hasActiveFocus());
-    QInputMethodEvent inputEvent;
-    inputEvent.setCommitString(initial);
-    QGuiApplication::sendEvent(input, &inputEvent);
-    QCOMPARE(input->text(), initial);
-    QCOMPARE(input->displayText(), initial);
-    QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), initial);
-}
-
-#ifdef QT_GUI_PASSWORD_ECHO_DELAY
-void tst_qdeclarativetextinput::passwordEchoDelay()
-{
-    QSGView canvas(QUrl::fromLocalFile(TESTDATA("echoMode.qml")));
-    canvas.show();
-    canvas.setFocus();
-    QGuiApplication::setActiveWindow(&canvas);
-    QTest::qWaitForWindowShown(&canvas);
-    QTRY_COMPARE(&canvas, qGuiApp->focusWindow());
-
-    QVERIFY(canvas.rootObject() != 0);
-
-    QSGTextInput *input = qobject_cast<QSGTextInput *>(qvariant_cast<QObject *>(canvas.rootObject()->property("myInput")));
-
-    QChar fillChar = QLatin1Char('*');
-
-    input->setEchoMode(QDeclarativeTextInput::Password);
-    QCOMPARE(input->displayText(), QString(8, fillChar));
-    input->setText(QString());
-    QCOMPARE(input->displayText(), QString());
-
-    QTest::keyPress(&canvas, '0');
-    QTest::keyPress(&canvas, '1');
-    QTest::keyPress(&canvas, '2');
-    QCOMPARE(input->displayText(), QString(2, fillChar) + QLatin1Char('2'));
-    QTest::keyPress(&canvas, '3');
-    QTest::keyPress(&canvas, '4');
-    QCOMPARE(input->displayText(), QString(4, fillChar) + QLatin1Char('4'));
-    QTest::keyPress(&canvas, Qt::Key_Backspace);
-    QCOMPARE(input->displayText(), QString(4, fillChar));
-    QTest::keyPress(&canvas, '4');
-    QCOMPARE(input->displayText(), QString(4, fillChar) + QLatin1Char('4'));
-    QTest::qWait(QT_GUI_PASSWORD_ECHO_DELAY);
-    QTRY_COMPARE(input->displayText(), QString(5, fillChar));
-    QTest::keyPress(&canvas, '5');
-    QCOMPARE(input->displayText(), QString(5, fillChar) + QLatin1Char('5'));
-    input->setFocus(false);
-    QVERIFY(!input->hasFocus());
-    QCOMPARE(input->displayText(), QString(6, fillChar));
-    input->setFocus(true);
-    QTRY_VERIFY(input->hasFocus());
-    QCOMPARE(input->displayText(), QString(6, fillChar));
-    QTest::keyPress(&canvas, '6');
-    QCOMPARE(input->displayText(), QString(6, fillChar) + QLatin1Char('6'));
-
-    QInputMethodEvent ev;
-    ev.setCommitString(QLatin1String("7"));
-    QGuiApplication::sendEvent(&canvas, &ev);
-    QCOMPARE(input->displayText(), QString(7, fillChar) + QLatin1Char('7'));
-}
-#endif
-
-
-void tst_qsgtextinput::simulateKey(QSGView *view, int key)
-{
-    QKeyEvent press(QKeyEvent::KeyPress, key, 0);
-    QKeyEvent release(QKeyEvent::KeyRelease, key, 0);
-
-    QGuiApplication::sendEvent(view, &press);
-    QGuiApplication::sendEvent(view, &release);
-}
-
-#ifndef QTBUG_21691
-class MyInputContext : public QInputContext
-{
-public:
-    MyInputContext() : updateReceived(false), eventType(QEvent::None) {}
-    ~MyInputContext() {}
-
-    QString identifierName() { return QString(); }
-    QString language() { return QString(); }
-
-    void reset() {}
-
-    bool isComposing() const { return false; }
-
-    void update() { updateReceived = true; }
-
-    void mouseHandler(int x, QMouseEvent *event)
-    {
-        cursor = x;
-        eventType = event->type();
-        eventPosition = event->pos();
-        eventGlobalPosition = event->globalPos();
-        eventButton = event->button();
-        eventButtons = event->buttons();
-        eventModifiers = event->modifiers();
-    }
-
-    void sendPreeditText(const QString &text, int cursor)
-    {
-        QList<QInputMethodEvent::Attribute> attributes;
-        attributes.append(QInputMethodEvent::Attribute(
-                QInputMethodEvent::Cursor, cursor, text.length(), QVariant()));
-
-        QInputMethodEvent event(text, attributes);
-        sendEvent(event);
-    }
-
-    bool updateReceived;
-    int cursor;
-    QEvent::Type eventType;
-    QPoint eventPosition;
-    QPoint eventGlobalPosition;
-    Qt::MouseButton eventButton;
-    Qt::MouseButtons eventButtons;
-    Qt::KeyboardModifiers eventModifiers;
-};
-#endif
-
-void tst_qsgtextinput::openInputPanel()
-{
-    QSGView view(QUrl::fromLocalFile(TESTDATA("openInputPanel.qml")));
-    view.show();
-    view.requestActivateWindow();
-    QTest::qWaitForWindowShown(&view);
-    QTRY_COMPARE(&view, qGuiApp->focusWindow());
-
-    QSGTextInput *input = qobject_cast<QSGTextInput *>(view.rootObject());
-    QVERIFY(input);
-
-    // check default values
-    QVERIFY(input->focusOnPress());
-    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(qApp->inputPanel()->inputItem(), input);
-    QCOMPARE(qApp->inputPanel()->visible(), true);
-    QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint);
-
-    // 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, noModifiers, centerPoint);
-    QGuiApplication::processEvents();
-    QCOMPARE(qApp->inputPanel()->visible(), true);
-    QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint);
-
-    // input panel should stay visible if focus is lost to another text inputor
-    QSignalSpy inputPanelVisibilitySpy(qApp->inputPanel(), SIGNAL(visibleChanged()));
-    QSGTextInput anotherInput;
-    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);
-
-    // 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);
-    QCOMPARE(qApp->inputPanel()->inputItem(), static_cast<QObject*>(0));
-    QCOMPARE(view.activeFocusItem(), &item);
-
-    qApp->inputPanel()->hide();
-
-    // input panel should not be opened if TextInput is read only
-    input->setReadOnly(true);
-    input->setFocus(true);
-    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);
-
-    // input panel should not be opened if focusOnPress is set to false
-    input->setFocusOnPress(false);
-    input->setFocus(false);
-    input->setFocus(true);
-    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 panel should open when openSoftwareInputPanel is called
-    input->openSoftwareInputPanel();
-    QCOMPARE(qApp->inputPanel()->visible(), true);
-
-    // input panel should close when closeSoftwareInputPanel is called
-    input->closeSoftwareInputPanel();
-    QCOMPARE(qApp->inputPanel()->visible(), false);
-}
-
-class MyTextInput : public QSGTextInput
-{
-public:
-    MyTextInput(QSGItem *parent = 0) : QSGTextInput(parent)
-    {
-        nbPaint = 0;
-    }
-    virtual QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *data)
-    {
-       nbPaint++;
-       return QSGTextInput::updatePaintNode(node, data);
-    }
-    int nbPaint;
-};
-
-void tst_qsgtextinput::setHAlignClearCache()
-{
-    QSGView view;
-    MyTextInput input;
-    input.setText("Hello world");
-    input.setParentItem(view.rootItem());
-    view.show();
-    view.requestActivateWindow();
-    QTest::qWaitForWindowShown(&view);
-    QTRY_COMPARE(input.nbPaint, 1);
-    input.setHAlign(QSGTextInput::AlignRight);
-    //Changing the alignment should trigger a repaint
-    QTRY_COMPARE(input.nbPaint, 2);
-}
-
-void tst_qsgtextinput::focusOutClearSelection()
-{
-    QSGView view;
-    QSGTextInput input;
-    QSGTextInput input2;
-    input.setText(QLatin1String("Hello world"));
-    input.setFocus(true);
-    input2.setParentItem(view.rootItem());
-    input.setParentItem(view.rootItem());
-    view.show();
-    view.requestActivateWindow();
-    QTest::qWaitForWindowShown(&view);
-    input.select(2,5);
-    //The selection should work
-    QTRY_COMPARE(input.selectedText(), QLatin1String("llo"));
-    input2.setFocus(true);
-    QGuiApplication::processEvents();
-    //The input lost the focus selection should be cleared
-    QTRY_COMPARE(input.selectedText(), QLatin1String(""));
-}
-
-void tst_qsgtextinput::geometrySignals()
-{
-    QDeclarativeComponent component(&engine, TESTDATA("geometrySignals.qml"));
-    QObject *o = component.create();
-    QVERIFY(o);
-    QCOMPARE(o->property("bindingWidth").toInt(), 400);
-    QCOMPARE(o->property("bindingHeight").toInt(), 500);
-    delete o;
-}
-
-void tst_qsgtextinput::testQtQuick11Attributes()
-{
-    QFETCH(QString, code);
-    QFETCH(QString, warning);
-    QFETCH(QString, error);
-
-    QDeclarativeEngine engine;
-    QObject *obj;
-
-    QDeclarativeComponent valid(&engine);
-    valid.setData("import QtQuick 2.0; TextInput { " + code.toUtf8() + " }", QUrl(""));
-    obj = valid.create();
-    QVERIFY(obj);
-    QVERIFY(valid.errorString().isEmpty());
-    delete obj;
-
-    QDeclarativeComponent invalid(&engine);
-    invalid.setData("import QtQuick 1.0; TextInput { " + code.toUtf8() + " }", QUrl(""));
-    QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
-    obj = invalid.create();
-    QCOMPARE(invalid.errorString(), error);
-    delete obj;
-}
-
-void tst_qsgtextinput::testQtQuick11Attributes_data()
-{
-    QTest::addColumn<QString>("code");
-    QTest::addColumn<QString>("warning");
-    QTest::addColumn<QString>("error");
-
-    QTest::newRow("canPaste") << "property bool foo: canPaste"
-        << "<Unknown File>:1: ReferenceError: Can't find variable: canPaste"
-        << "";
-
-    QTest::newRow("moveCursorSelection") << "Component.onCompleted: moveCursorSelection(0, TextEdit.SelectCharacters)"
-        << "<Unknown File>:1: ReferenceError: Can't find variable: moveCursorSelection"
-        << "";
-
-    QTest::newRow("deselect") << "Component.onCompleted: deselect()"
-        << "<Unknown File>:1: ReferenceError: Can't find variable: deselect"
-        << "";
-}
-
-void tst_qsgtextinput::preeditAutoScroll()
-{
-#ifdef QTBUG_21691
-    QEXPECT_FAIL("", QTBUG_21691_MESSAGE, Abort);
-    QVERIFY(false);
-#else
-    QString preeditText = "califragisiticexpialidocious!";
-
-    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.
-    view.setAttribute(Qt::WA_InputMethodEnabled, true);
-    view.setInputContext(&ic);
-    view.setAttribute(Qt::WA_InputMethodEnabled, false);
-    view.show();
-    view.requestActivateWindow();
-    QTest::qWaitForWindowShown(&view);
-    QTRY_COMPARE(&view, qGuiApp->focusWindow());
-    QSGTextInput *input = qobject_cast<QSGTextInput *>(view.rootObject());
-    QVERIFY(input);
-
-    QSignalSpy cursorRectangleSpy(input, SIGNAL(cursorRectangleChanged()));
-    int cursorRectangleChanges = 0;
-
-    QFontMetricsF fm(input->font());
-    input->setWidth(fm.width(input->text()));
-
-    // test the text is scrolled so the preedit is visible.
-    ic.sendPreeditText(preeditText.mid(0, 3), 1);
-    QVERIFY(input->positionAt(0) != 0);
-    QVERIFY(input->cursorRectangle().left() < input->boundingRect().width());
-    QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
-
-    // test the text is scrolled back when the preedit is removed.
-    ic.sendEvent(QInputMethodEvent());
-    QCOMPARE(input->positionAt(0), 0);
-    QCOMPARE(input->positionAt(input->width()), 5);
-    QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
-
-    // some tolerance for different fonts.
-#ifdef Q_OS_LINUX
-    const int error = 2;
-#else
-    const int error = 5;
-#endif
-
-    // test if the preedit is larger than the text input that the
-    // character preceding the cursor is still visible.
-    qreal x = input->positionToRectangle(0).x();
-    for (int i = 0; i < 3; ++i) {
-        ic.sendPreeditText(preeditText, i + 1);
-        QVERIFY(input->cursorRectangle().right() >= fm.width(preeditText.at(i)) - error);
-        QVERIFY(input->positionToRectangle(0).x() < x);
-        QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
-        x = input->positionToRectangle(0).x();
-    }
-    for (int i = 1; i >= 0; --i) {
-        ic.sendPreeditText(preeditText, i + 1);
-        QVERIFY(input->cursorRectangle().right() >= fm.width(preeditText.at(i)) - error);
-        QVERIFY(input->positionToRectangle(0).x() > x);
-        QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
-        x = input->positionToRectangle(0).x();
-    }
-
-    // Test incrementing the preedit cursor doesn't cause further
-    // scrolling when right most text is visible.
-    ic.sendPreeditText(preeditText, preeditText.length() - 3);
-    QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
-    x = input->positionToRectangle(0).x();
-    for (int i = 2; i >= 0; --i) {
-        ic.sendPreeditText(preeditText, preeditText.length() - i);
-        QCOMPARE(input->positionToRectangle(0).x(), x);
-        QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
-    }
-    for (int i = 1; i <  3; ++i) {
-        ic.sendPreeditText(preeditText, preeditText.length() - i);
-        QCOMPARE(input->positionToRectangle(0).x(), x);
-        QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges);
-    }
-
-    // Test disabling auto scroll.
-    ic.sendEvent(QInputMethodEvent());
-
-    input->setAutoScroll(false);
-    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(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.
-    view.setAttribute(Qt::WA_InputMethodEnabled, true);
-    view.setInputContext(&ic);
-    view.setAttribute(Qt::WA_InputMethodEnabled, false);
-    view.show();
-    view.requestActivateWindow();
-    QTest::qWaitForWindowShown(&view);
-    QTRY_COMPARE(&view, qGuiApp->focusWindow());
-    QSGTextInput *input = qobject_cast<QSGTextInput *>(view.rootObject());
-    QVERIFY(input);
-
-    QRect currentRect;
-    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::ImCursorRectangle).toRect();
-    QCOMPARE(currentRect, previousRect);
-#if defined(Q_WS_X11) || defined(Q_WS_QWS)
-    QCOMPARE(ic.updateReceived, true);
-#endif
-
-    // Verify that the micro focus rect moves to the left as the cursor position
-    // is incremented.
-    for (int i = 1; i <= 5; ++i) {
-        ic.updateReceived = false;
-        ic.sendPreeditText(preeditText, i);
-        currentRect = input->inputMethodQuery(Qt::ImCursorRectangle).toRect();
-        QVERIFY(previousRect.left() < currentRect.left());
-#if defined(Q_WS_X11) || defined(Q_WS_QWS)
-        QCOMPARE(ic.updateReceived, true);
-#endif
-        previousRect = currentRect;
-    }
-
-    // Verify that if there is no preedit cursor then the micro focus rect is the
-    // same as it would be if it were positioned at the end of the preedit text.
-    ic.sendPreeditText(preeditText, 0);
-    ic.updateReceived = false;
-    ic.sendEvent(QInputMethodEvent(preeditText, QList<QInputMethodEvent::Attribute>()));
-    currentRect = input->inputMethodQuery(Qt::ImCursorRectangle).toRect();
-    QCOMPARE(currentRect, previousRect);
-#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(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.
-    view.setAttribute(Qt::WA_InputMethodEnabled, true);
-    view.setInputContext(&ic);
-    view.setAttribute(Qt::WA_InputMethodEnabled, false);
-    view.show();
-    view.requestActivateWindow();
-    QTest::qWaitForWindowShown(&view);
-    QTRY_COMPARE(&view, qGuiApp->focusWindow());
-    QSGTextInput *input = qobject_cast<QSGTextInput *>(view.rootObject());
-    QVERIFY(input);
-
-    QFontMetricsF fm(input->font());
-    const qreal y = fm.height() / 2;
-
-    QPoint position2 = input->mapToScene(QPointF(fm.width(text.mid(0, 2)), y)).toPoint();
-    QPoint position8 = input->mapToScene(QPointF(fm.width(text.mid(0, 8)), y)).toPoint();
-    QPoint position20 = input->mapToScene(QPointF(fm.width(text.mid(0, 20)), y)).toPoint();
-    QPoint position27 = input->mapToScene(QPointF(fm.width(text.mid(0, 27)), y)).toPoint();
-    QPoint globalPosition2 = view.mapToGlobal(position2);
-    QPoint globalposition8 = view.mapToGlobal(position8);
-    QPoint globalposition20 = view.mapToGlobal(position20);
-    QPoint globalposition27 = view.mapToGlobal(position27);
-
-    ic.sendEvent(QInputMethodEvent(text.mid(12), QList<QInputMethodEvent::Attribute>()));
-
-    QTest::mouseDClick(&view, Qt::LeftButton, Qt::NoModifier, position2);
-    QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
-    QCOMPARE(ic.eventPosition, position2);
-    QCOMPARE(ic.eventGlobalPosition, globalPosition2);
-    QCOMPARE(ic.eventButton, Qt::LeftButton);
-    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
-    QVERIFY(ic.cursor < 0);
-    ic.eventType = QEvent::None;
-
-    QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, position2);
-    QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
-    QCOMPARE(ic.eventPosition, position2);
-    QCOMPARE(ic.eventGlobalPosition, globalPosition2);
-    QCOMPARE(ic.eventButton, Qt::LeftButton);
-    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
-    QVERIFY(ic.cursor < 0);
-    ic.eventType = QEvent::None;
-
-    {   QMouseEvent mv(QEvent::MouseMove, position8, globalposition8, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
-        QGuiApplication::sendEvent(&view, &mv); }
-    QCOMPARE(ic.eventType, QEvent::None);
-
-    {   QMouseEvent mv(QEvent::MouseMove, position27, globalposition27, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier);
-        QGuiApplication::sendEvent(&view, &mv); }
-    QCOMPARE(ic.eventType, QEvent::MouseMove);
-    QCOMPARE(ic.eventPosition, position27);
-    QCOMPARE(ic.eventGlobalPosition, globalposition27);
-    QCOMPARE(ic.eventButton, Qt::LeftButton);
-    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
-    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);    // 15 is expected but some platforms may be off by one.
-    ic.eventType = QEvent::None;
-
-    QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, position27);
-    QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
-    QCOMPARE(ic.eventPosition, position27);
-    QCOMPARE(ic.eventGlobalPosition, globalposition27);
-    QCOMPARE(ic.eventButton, Qt::LeftButton);
-    QCOMPARE(ic.eventModifiers, Qt::NoModifier);
-    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
-    ic.eventType = QEvent::None;
-
-    // And in the other direction.
-    QTest::mouseDClick(&view, Qt::LeftButton, Qt::ControlModifier, position27);
-    QCOMPARE(ic.eventType, QEvent::MouseButtonDblClick);
-    QCOMPARE(ic.eventPosition, position27);
-    QCOMPARE(ic.eventGlobalPosition, globalposition27);
-    QCOMPARE(ic.eventButton, Qt::LeftButton);
-    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
-    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
-    ic.eventType = QEvent::None;
-
-    QTest::mousePress(&view, Qt::RightButton, Qt::ControlModifier, position27);
-    QCOMPARE(ic.eventType, QEvent::MouseButtonPress);
-    QCOMPARE(ic.eventPosition, position27);
-    QCOMPARE(ic.eventGlobalPosition, globalposition27);
-    QCOMPARE(ic.eventButton, Qt::RightButton);
-    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
-    QVERIFY(ic.cursor >= 14 && ic.cursor <= 16);
-    ic.eventType = QEvent::None;
-
-    {   QMouseEvent mv(QEvent::MouseMove, position20, globalposition20, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
-        QGuiApplication::sendEvent(&view, &mv); }
-    QCOMPARE(ic.eventType, QEvent::MouseMove);
-    QCOMPARE(ic.eventPosition, position20);
-    QCOMPARE(ic.eventGlobalPosition, globalposition20);
-    QCOMPARE(ic.eventButton, Qt::RightButton);
-    QCOMPARE(ic.eventModifiers, Qt::ControlModifier);
-    QVERIFY(ic.cursor >= 7 && ic.cursor <= 9);
-    ic.eventType = QEvent::None;
-
-    {   QMouseEvent mv(QEvent::MouseMove, position2, globalPosition2, Qt::RightButton, Qt::RightButton,Qt::ControlModifier);
-        QGuiApplication::sendEvent(&view, &mv); }
-    QCOMPARE(ic.eventType, QEvent::None);
-
-    QTest::mouseRelease(&view, Qt::RightButton, Qt::ControlModifier, position2);
-    QCOMPARE(ic.eventType, QEvent::MouseButtonRelease);
-    QCOMPARE(ic.eventPosition, position2);
-    QCOMPARE(ic.eventGlobalPosition, globalPosition2);
-    QCOMPARE(ic.eventButton, Qt::RightButton);
-    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(TESTDATA("inputContext.qml")));
-    view.show();
-    view.requestActivateWindow();
-    QTest::qWaitForWindowShown(&view);
-    QTRY_COMPARE(&view, qGuiApp->focusWindow());
-    QSGTextInput *input = qobject_cast<QSGTextInput *>(view.rootObject());
-    QVERIFY(input);
-    QSignalSpy spy(input, SIGNAL(inputMethodComposingChanged()));
-
-    QCOMPARE(input->isInputMethodComposing(), false);
-    {
-        QInputMethodEvent event(text.mid(3), QList<QInputMethodEvent::Attribute>());
-        QGuiApplication::sendEvent(input, &event);
-    }
-    QCOMPARE(input->isInputMethodComposing(), true);
-    QCOMPARE(spy.count(), 1);
-
-    {
-        QInputMethodEvent event(text.mid(12), QList<QInputMethodEvent::Attribute>());
-        QGuiApplication::sendEvent(input, &event);
-    }
-    QCOMPARE(spy.count(), 1);
-
-    {
-        QInputMethodEvent event;
-        QGuiApplication::sendEvent(input, &event);
-    }
-    QCOMPARE(input->isInputMethodComposing(), false);
-    QCOMPARE(spy.count(), 2);
-}
-
-void tst_qsgtextinput::cursorRectangleSize()
-{
-    QSGView *canvas = new QSGView(QUrl::fromLocalFile(TESTDATA("positionAt.qml")));
-    QVERIFY(canvas->rootObject() != 0);
-    canvas->show();
-    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::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());
-
-    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());
-}
-
-void tst_qsgtextinput::QTBUG_19956_data()
-{
-    QTest::addColumn<QString>("url");
-    QTest::newRow("intvalidator") << "qtbug-19956int.qml";
-    QTest::newRow("doublevalidator") << "qtbug-19956double.qml";
-}
-
-void tst_qsgtextinput::QTBUG_19956()
-{
-    QFETCH(QString, url);
-
-    QSGView canvas(QUrl::fromLocalFile(TESTDATA(url)));
-    canvas.show();
-    canvas.requestActivateWindow();
-    QTest::qWaitForWindowShown(&canvas);
-    QVERIFY(canvas.rootObject() != 0);
-    QSGTextInput *input = qobject_cast<QSGTextInput*>(canvas.rootObject());
-    QVERIFY(input);
-    input->setFocus(true);
-    QVERIFY(input->hasActiveFocus());
-
-    QCOMPARE(canvas.rootObject()->property("topvalue").toInt(), 30);
-    QCOMPARE(canvas.rootObject()->property("bottomvalue").toInt(), 10);
-    QCOMPARE(canvas.rootObject()->property("text").toString(), QString("20"));
-    QVERIFY(canvas.rootObject()->property("acceptableInput").toBool());
-
-    canvas.rootObject()->setProperty("topvalue", 15);
-    QCOMPARE(canvas.rootObject()->property("topvalue").toInt(), 15);
-    QVERIFY(!canvas.rootObject()->property("acceptableInput").toBool());
-
-    canvas.rootObject()->setProperty("topvalue", 25);
-    QCOMPARE(canvas.rootObject()->property("topvalue").toInt(), 25);
-    QVERIFY(canvas.rootObject()->property("acceptableInput").toBool());
-
-    canvas.rootObject()->setProperty("bottomvalue", 21);
-    QCOMPARE(canvas.rootObject()->property("bottomvalue").toInt(), 21);
-    QVERIFY(!canvas.rootObject()->property("acceptableInput").toBool());
-
-    canvas.rootObject()->setProperty("bottomvalue", 10);
-    QCOMPARE(canvas.rootObject()->property("bottomvalue").toInt(), 10);
-    QVERIFY(canvas.rootObject()->property("acceptableInput").toBool());
-}
-
-void tst_qsgtextinput::QTBUG_19956_regexp()
-{
-    QSGView canvas(QUrl::fromLocalFile(TESTDATA("qtbug-19956regexp.qml")));
-    canvas.show();
-    canvas.requestActivateWindow();
-    QTest::qWaitForWindowShown(&canvas);
-    QVERIFY(canvas.rootObject() != 0);
-    QSGTextInput *input = qobject_cast<QSGTextInput*>(canvas.rootObject());
-    QVERIFY(input);
-    input->setFocus(true);
-    QVERIFY(input->hasActiveFocus());
-
-    canvas.rootObject()->setProperty("regexvalue", QRegExp("abc"));
-    QCOMPARE(canvas.rootObject()->property("regexvalue").toRegExp(), QRegExp("abc"));
-    QCOMPARE(canvas.rootObject()->property("text").toString(), QString("abc"));
-    QVERIFY(canvas.rootObject()->property("acceptableInput").toBool());
-
-    canvas.rootObject()->setProperty("regexvalue", QRegExp("abcd"));
-    QCOMPARE(canvas.rootObject()->property("regexvalue").toRegExp(), QRegExp("abcd"));
-    QVERIFY(!canvas.rootObject()->property("acceptableInput").toBool());
-
-    canvas.rootObject()->setProperty("regexvalue", QRegExp("abc"));
-    QCOMPARE(canvas.rootObject()->property("regexvalue").toRegExp(), QRegExp("abc"));
-    QVERIFY(canvas.rootObject()->property("acceptableInput").toBool());
-}
-
-QTEST_MAIN(tst_qsgtextinput)
-
-#include "tst_qsgtextinput.moc"
diff --git a/tests/auto/declarative/qsgview/qsgview.pro b/tests/auto/declarative/qsgview/qsgview.pro
deleted file mode 100644 (file)
index dd67cff..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsgview
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_qsgview.cpp
-
-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
deleted file mode 100644 (file)
index d2c51d6..0000000
+++ /dev/null
@@ -1,209 +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 <QtTest/QSignalSpy>
-#include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtDeclarative/qdeclarativecontext.h>
-#include <QtDeclarative/qsgview.h>
-#include <QtDeclarative/qsgitem.h>
-#include "../shared/util.h"
-#include <QtGui/QWindow>
-#include <QtCore/QDebug>
-
-class tst_QSGView : public QObject
-{
-    Q_OBJECT
-public:
-    tst_QSGView();
-
-private slots:
-    void resizemodeitem();
-    void errors();
-};
-
-
-tst_QSGView::tst_QSGView()
-{
-}
-
-void tst_QSGView::resizemodeitem()
-{
-    QWindow window;
-    window.setGeometry(0, 0, 400, 400);
-
-    QSGView *canvas = new QSGView(&window);
-    QVERIFY(canvas);
-    canvas->setResizeMode(QSGView::SizeRootObjectToView);
-    QCOMPARE(QSize(0,0), canvas->initialSize());
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizemodeitem.qml")));
-    QSGItem* item = qobject_cast<QSGItem*>(canvas->rootObject());
-    QVERIFY(item);
-    window.show();
-
-    canvas->show();
-
-    // initial size from root object
-    QCOMPARE(item->width(), 200.0);
-    QCOMPARE(item->height(), 200.0);
-    QCOMPARE(canvas->size(), QSize(200, 200));
-    QCOMPARE(canvas->size(), canvas->sizeHint());
-    QCOMPARE(canvas->size(), canvas->initialSize());
-
-    // size update from view
-    canvas->resize(QSize(80,100));
-    QTest::qWait(50);
-
-    QCOMPARE(item->width(), 80.0);
-    QCOMPARE(item->height(), 100.0);
-    QCOMPARE(canvas->size(), QSize(80, 100));
-    QCOMPARE(canvas->size(), canvas->sizeHint());
-
-    canvas->setResizeMode(QSGView::SizeViewToRootObject);
-
-    // size update from view disabled
-    canvas->resize(QSize(60,80));
-    QCOMPARE(item->width(), 80.0);
-    QCOMPARE(item->height(), 100.0);
-    QTest::qWait(50);
-    QCOMPARE(canvas->size(), QSize(60, 80));
-
-    // size update from root object
-    item->setWidth(250);
-    item->setHeight(350);
-    QCOMPARE(item->width(), 250.0);
-    QCOMPARE(item->height(), 350.0);
-    QTRY_COMPARE(canvas->size(), QSize(250, 350));
-    QCOMPARE(canvas->size(), QSize(250, 350));
-    QCOMPARE(canvas->size(), canvas->sizeHint());
-
-    // reset canvas
-    window.hide();
-    delete canvas;
-    canvas = new QSGView(&window);
-    QVERIFY(canvas);
-    canvas->setResizeMode(QSGView::SizeViewToRootObject);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizemodeitem.qml")));
-    item = qobject_cast<QSGItem*>(canvas->rootObject());
-    QVERIFY(item);
-    window.show();
-
-    canvas->show();
-
-    // initial size for root object
-    QCOMPARE(item->width(), 200.0);
-    QCOMPARE(item->height(), 200.0);
-    QCOMPARE(canvas->size(), canvas->sizeHint());
-    QCOMPARE(canvas->size(), canvas->initialSize());
-
-    // size update from root object
-    item->setWidth(80);
-    item->setHeight(100);
-    QCOMPARE(item->width(), 80.0);
-    QCOMPARE(item->height(), 100.0);
-    QTRY_COMPARE(canvas->size(), QSize(80, 100));
-    QCOMPARE(canvas->size(), QSize(80, 100));
-    QCOMPARE(canvas->size(), canvas->sizeHint());
-
-    // size update from root object disabled
-    canvas->setResizeMode(QSGView::SizeRootObjectToView);
-    item->setWidth(60);
-    item->setHeight(80);
-    QCOMPARE(canvas->width(), 80);
-    QCOMPARE(canvas->height(), 100);
-    QCOMPARE(QSize(item->width(), item->height()), canvas->sizeHint());
-
-    // size update from view
-    canvas->resize(QSize(200,300));
-    QTest::qWait(50);
-    QCOMPARE(item->width(), 200.0);
-    QCOMPARE(item->height(), 300.0);
-    QCOMPARE(canvas->size(), QSize(200, 300));
-    QCOMPARE(canvas->size(), canvas->sizeHint());
-
-    window.hide();
-    delete canvas;
-
-    // if we set a specific size for the view then it should keep that size
-    // for SizeRootObjectToView mode.
-    canvas = new QSGView(&window);
-    canvas->resize(300, 300);
-    canvas->setResizeMode(QSGView::SizeRootObjectToView);
-    QCOMPARE(QSize(0,0), canvas->initialSize());
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizemodeitem.qml")));
-    canvas->resize(300, 300);
-    item = qobject_cast<QSGItem*>(canvas->rootObject());
-    QVERIFY(item);
-    window.show();
-
-    canvas->show();
-    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));
-    QCOMPARE(canvas->size(), canvas->sizeHint());
-    QCOMPARE(canvas->initialSize(), QSize(200, 200)); // initial object size
-
-    delete canvas;
-}
-
-static void silentErrorsMsgHandler(QtMsgType, const char *)
-{
-}
-
-void tst_QSGView::errors()
-{
-    QSGView *canvas = new QSGView;
-    QVERIFY(canvas);
-    QtMsgHandler old = qInstallMsgHandler(silentErrorsMsgHandler);
-    canvas->setSource(QUrl::fromLocalFile(TESTDATA("error1.qml")));
-    qInstallMsgHandler(old);
-    QVERIFY(canvas->status() == QSGView::Error);
-    QVERIFY(canvas->errors().count() == 1);
-    delete canvas;
-}
-
-
-QTEST_MAIN(tst_QSGView)
-
-#include "tst_qsgview.moc"
diff --git a/tests/auto/declarative/qsgvisualdatamodel/qsgvisualdatamodel.pro b/tests/auto/declarative/qsgvisualdatamodel/qsgvisualdatamodel.pro
deleted file mode 100644 (file)
index 1e8b8a2..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qsgvisualdatamodel
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_qsgvisualdatamodel.cpp
-
-testDataFiles.files = data
-testDataFiles.path = .
-DEPLOYMENT += testDataFiles
-
-CONFIG += parallel_test
-
-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
deleted file mode 100644 (file)
index 0194931..0000000
+++ /dev/null
@@ -1,1555 +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 "../shared/util.h"
-#include <qtest.h>
-#include <QtTest/QSignalSpy>
-#include <QStandardItemModel>
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtDeclarative/qdeclarativecontext.h>
-#include <QtDeclarative/qdeclarativeexpression.h>
-#include <QtDeclarative/qsgview.h>
-#include <private/qsglistview_p.h>
-#include <private/qsgtext_p.h>
-#include <private/qsgvisualdatamodel_p.h>
-#include <private/qdeclarativevaluetype_p.h>
-#include <private/qdeclarativechangeset_p.h>
-#include <private/qdeclarativeengine_p.h>
-#include <math.h>
-
-template <typename T, int N> int lengthOf(const T (&)[N]) { return N; }
-
-static void initStandardTreeModel(QStandardItemModel *model)
-{
-    QStandardItem *item;
-    item = new QStandardItem(QLatin1String("Row 1 Item"));
-    model->insertRow(0, item);
-
-    item = new QStandardItem(QLatin1String("Row 2 Item"));
-    item->setCheckable(true);
-    model->insertRow(1, item);
-
-    QStandardItem *childItem = new QStandardItem(QLatin1String("Row 2 Child Item"));
-    item->setChild(0, childItem);
-
-    item = new QStandardItem(QLatin1String("Row 3 Item"));
-    item->setIcon(QIcon());
-    model->insertRow(2, item);
-}
-
-class SingleRoleModel : public QAbstractListModel
-{
-    Q_OBJECT
-
-public:
-    SingleRoleModel(const QByteArray &role = "name", QObject *parent = 0) {
-        QHash<int, QByteArray> roles;
-        roles.insert(Qt::DisplayRole , role);
-        setRoleNames(roles);
-        list << "one" << "two" << "three" << "four";
-    }
-
-    void emitMove(int sourceFirst, int sourceLast, int destinationChild) {
-        emit beginMoveRows(QModelIndex(), sourceFirst, sourceLast, QModelIndex(), destinationChild);
-        emit endMoveRows();
-    }
-
-    QStringList list;
-
-public slots:
-    void set(int idx, QString string) {
-        list[idx] = string;
-        emit dataChanged(index(idx,0), index(idx,0));
-    }
-
-protected:
-    int rowCount(const QModelIndex &parent = QModelIndex()) const {
-        return list.count();
-    }
-    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const {
-        if (role == Qt::DisplayRole)
-            return list.at(index.row());
-        return QVariant();
-    }
-};
-
-
-class tst_qsgvisualdatamodel : public QObject
-{
-    Q_OBJECT
-public:
-    tst_qsgvisualdatamodel();
-
-private slots:
-    void initTestCase();
-    void cleanupTestCase();
-    void rootIndex();
-    void updateLayout();
-    void childChanged();
-    void objectListModel();
-    void singleRole();
-    void modelProperties();
-    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);
-};
-
-Q_DECLARE_METATYPE(QDeclarativeChangeSet)
-
-void tst_qsgvisualdatamodel::initTestCase()
-{
-    qRegisterMetaType<QDeclarativeChangeSet>();
-}
-
-void tst_qsgvisualdatamodel::cleanupTestCase()
-{
-
-}
-class DataObject : public QObject
-{
-    Q_OBJECT
-
-    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
-    Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
-
-public:
-    DataObject(QObject *parent=0) : QObject(parent) {}
-    DataObject(const QString &name, const QString &color, QObject *parent=0)
-        : QObject(parent), m_name(name), m_color(color) { }
-
-
-    QString name() const { return m_name; }
-    void setName(const QString &name) {
-        if (name != m_name) {
-            m_name = name;
-            emit nameChanged();
-        }
-    }
-
-    QString color() const { return m_color; }
-    void setColor(const QString &color) {
-        if (color != m_color) {
-            m_color = color;
-            emit colorChanged();
-        }
-    }
-
-signals:
-    void nameChanged();
-    void colorChanged();
-
-private:
-    QString m_name;
-    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()
-{
-}
-
-void tst_qsgvisualdatamodel::rootIndex()
-{
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("visualdatamodel.qml")));
-
-    QStandardItemModel model;
-    initStandardTreeModel(&model);
-
-    engine.rootContext()->setContextProperty("myModel", &model);
-
-    QSGVisualDataModel *obj = qobject_cast<QSGVisualDataModel*>(c.create());
-    QVERIFY(obj != 0);
-
-    QMetaObject::invokeMethod(obj, "setRoot");
-    QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == model.index(0,0));
-
-    QMetaObject::invokeMethod(obj, "setRootToParent");
-    QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex());
-
-    QMetaObject::invokeMethod(obj, "setRoot");
-    QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == model.index(0,0));
-    model.clear(); // will emit modelReset()
-    QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex());
-
-    delete obj;
-}
-
-void tst_qsgvisualdatamodel::updateLayout()
-{
-    QSGView view;
-
-    QStandardItemModel model;
-    initStandardTreeModel(&model);
-
-    view.rootContext()->setContextProperty("myModel", &model);
-
-    view.setSource(QUrl::fromLocalFile(TESTDATA("datalist.qml")));
-
-    QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
-    QVERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QVERIFY(contentItem != 0);
-
-    QSGText *name = findItem<QSGText>(contentItem, "display", 0);
-    QVERIFY(name);
-    QCOMPARE(name->text(), QString("Row 1 Item"));
-    name = findItem<QSGText>(contentItem, "display", 1);
-    QVERIFY(name);
-    QCOMPARE(name->text(), QString("Row 2 Item"));
-    name = findItem<QSGText>(contentItem, "display", 2);
-    QVERIFY(name);
-    QCOMPARE(name->text(), QString("Row 3 Item"));
-
-    model.invisibleRootItem()->sortChildren(0, Qt::DescendingOrder);
-
-    name = findItem<QSGText>(contentItem, "display", 0);
-    QVERIFY(name);
-    QCOMPARE(name->text(), QString("Row 3 Item"));
-    name = findItem<QSGText>(contentItem, "display", 1);
-    QVERIFY(name);
-    QCOMPARE(name->text(), QString("Row 2 Item"));
-    name = findItem<QSGText>(contentItem, "display", 2);
-    QVERIFY(name);
-    QCOMPARE(name->text(), QString("Row 1 Item"));
-}
-
-void tst_qsgvisualdatamodel::childChanged()
-{
-    QSGView view;
-
-    QStandardItemModel model;
-    initStandardTreeModel(&model);
-
-    view.rootContext()->setContextProperty("myModel", &model);
-
-    view.setSource(QUrl::fromLocalFile(TESTDATA("datalist.qml")));
-
-    QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
-    QVERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QVERIFY(contentItem != 0);
-
-    QSGVisualDataModel *vdm = listview->findChild<QSGVisualDataModel*>("visualModel");
-    vdm->setRootIndex(QVariant::fromValue(model.indexFromItem(model.item(1,0))));
-    QCOMPARE(listview->count(), 1);
-
-    QSGText *name = findItem<QSGText>(contentItem, "display", 0);
-    QVERIFY(name);
-    QCOMPARE(name->text(), QString("Row 2 Child Item"));
-
-    model.item(1,0)->child(0,0)->setText("Row 2 updated child");
-
-    name = findItem<QSGText>(contentItem, "display", 0);
-    QVERIFY(name);
-    QCOMPARE(name->text(), QString("Row 2 updated child"));
-
-    model.item(1,0)->appendRow(new QStandardItem(QLatin1String("Row 2 Child Item 2")));
-    QCOMPARE(listview->count(), 2);
-
-    name = findItem<QSGText>(contentItem, "display", 1);
-    QVERIFY(name != 0);
-    QCOMPARE(name->text(), QString("Row 2 Child Item 2"));
-
-    model.item(1,0)->takeRow(1);
-    name = findItem<QSGText>(contentItem, "display", 1);
-    QVERIFY(name == 0);
-
-    vdm->setRootIndex(QVariant::fromValue(QModelIndex()));
-    QCOMPARE(listview->count(), 3);
-    name = findItem<QSGText>(contentItem, "display", 0);
-    QVERIFY(name);
-    QCOMPARE(name->text(), QString("Row 1 Item"));
-    name = findItem<QSGText>(contentItem, "display", 1);
-    QVERIFY(name);
-    QCOMPARE(name->text(), QString("Row 2 Item"));
-    name = findItem<QSGText>(contentItem, "display", 2);
-    QVERIFY(name);
-    QCOMPARE(name->text(), QString("Row 3 Item"));
-}
-
-void tst_qsgvisualdatamodel::objectListModel()
-{
-    QSGView view;
-
-    QList<QObject*> dataList;
-    dataList.append(new DataObject("Item 1", "red"));
-    dataList.append(new DataObject("Item 2", "green"));
-    dataList.append(new DataObject("Item 3", "blue"));
-    dataList.append(new DataObject("Item 4", "yellow"));
-
-    QDeclarativeContext *ctxt = view.rootContext();
-    ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
-
-    view.setSource(QUrl::fromLocalFile(TESTDATA("objectlist.qml")));
-
-    QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
-    QVERIFY(listview != 0);
-
-    QSGItem *contentItem = listview->contentItem();
-    QVERIFY(contentItem != 0);
-
-    QSGText *name = findItem<QSGText>(contentItem, "name", 0);
-    QCOMPARE(name->text(), QString("Item 1"));
-
-    QSGText *section = findItem<QSGText>(contentItem, "section", 0);
-    QCOMPARE(section->text(), QString("Item 1"));
-
-    dataList[0]->setProperty("name", QLatin1String("Changed"));
-    QCOMPARE(name->text(), QString("Changed"));
-}
-
-void tst_qsgvisualdatamodel::singleRole()
-{
-    {
-        QSGView view;
-
-        SingleRoleModel model;
-
-        QDeclarativeContext *ctxt = view.rootContext();
-        ctxt->setContextProperty("myModel", &model);
-
-        view.setSource(QUrl::fromLocalFile(TESTDATA("singlerole1.qml")));
-
-        QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
-        QVERIFY(listview != 0);
-
-        QSGItem *contentItem = listview->contentItem();
-        QVERIFY(contentItem != 0);
-
-        QSGText *name = findItem<QSGText>(contentItem, "name", 1);
-        QCOMPARE(name->text(), QString("two"));
-
-        model.set(1, "Changed");
-        QCOMPARE(name->text(), QString("Changed"));
-    }
-    {
-        QSGView view;
-
-        SingleRoleModel model;
-
-        QDeclarativeContext *ctxt = view.rootContext();
-        ctxt->setContextProperty("myModel", &model);
-
-        view.setSource(QUrl::fromLocalFile(TESTDATA("singlerole2.qml")));
-
-        QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
-        QVERIFY(listview != 0);
-
-        QSGItem *contentItem = listview->contentItem();
-        QVERIFY(contentItem != 0);
-
-        QSGText *name = findItem<QSGText>(contentItem, "name", 1);
-        QCOMPARE(name->text(), QString("two"));
-
-        model.set(1, "Changed");
-        QCOMPARE(name->text(), QString("Changed"));
-    }
-    {
-        QSGView view;
-
-        SingleRoleModel model("modelData");
-
-        QDeclarativeContext *ctxt = view.rootContext();
-        ctxt->setContextProperty("myModel", &model);
-
-        view.setSource(QUrl::fromLocalFile(TESTDATA("singlerole2.qml")));
-
-        QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
-        QVERIFY(listview != 0);
-
-        QSGItem *contentItem = listview->contentItem();
-        QVERIFY(contentItem != 0);
-
-        QSGText *name = findItem<QSGText>(contentItem, "name", 1);
-        QCOMPARE(name->text(), QString("two"));
-
-        model.set(1, "Changed");
-        QCOMPARE(name->text(), QString("Changed"));
-    }
-}
-
-void tst_qsgvisualdatamodel::modelProperties()
-{
-    {
-        QSGView view;
-
-        SingleRoleModel model;
-
-        QDeclarativeContext *ctxt = view.rootContext();
-        ctxt->setContextProperty("myModel", &model);
-
-        view.setSource(QUrl::fromLocalFile(TESTDATA("modelproperties.qml")));
-
-        QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
-        QVERIFY(listview != 0);
-
-        QSGItem *contentItem = listview->contentItem();
-        QVERIFY(contentItem != 0);
-
-        QSGItem *delegate = findItem<QSGItem>(contentItem, "delegate", 1);
-        QVERIFY(delegate);
-        QCOMPARE(delegate->property("test1").toString(),QString("two"));
-        QCOMPARE(delegate->property("test2").toString(),QString("two"));
-        QCOMPARE(delegate->property("test3").toString(),QString("two"));
-        QCOMPARE(delegate->property("test4").toString(),QString("two"));
-        QVERIFY(!delegate->property("test9").isValid());
-        QCOMPARE(delegate->property("test5").toString(),QString(""));
-        QVERIFY(delegate->property("test6").value<QObject*>() != 0);
-        QCOMPARE(delegate->property("test7").toInt(),1);
-        QCOMPARE(delegate->property("test8").toInt(),1);
-    }
-
-    {
-        QSGView view;
-
-        QList<QObject*> dataList;
-        dataList.append(new DataObject("Item 1", "red"));
-        dataList.append(new DataObject("Item 2", "green"));
-        dataList.append(new DataObject("Item 3", "blue"));
-        dataList.append(new DataObject("Item 4", "yellow"));
-
-        QDeclarativeContext *ctxt = view.rootContext();
-        ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
-
-        view.setSource(QUrl::fromLocalFile(TESTDATA("modelproperties.qml")));
-
-        QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
-        QVERIFY(listview != 0);
-
-        QSGItem *contentItem = listview->contentItem();
-        QVERIFY(contentItem != 0);
-
-        QSGItem *delegate = findItem<QSGItem>(contentItem, "delegate", 1);
-        QVERIFY(delegate);
-        QCOMPARE(delegate->property("test1").toString(),QString("Item 2"));
-        QCOMPARE(delegate->property("test2").toString(),QString("Item 2"));
-        QVERIFY(qobject_cast<DataObject*>(delegate->property("test3").value<QObject*>()) != 0);
-        QVERIFY(qobject_cast<DataObject*>(delegate->property("test4").value<QObject*>()) != 0);
-        QCOMPARE(delegate->property("test5").toString(),QString("Item 2"));
-        QCOMPARE(delegate->property("test9").toString(),QString("Item 2"));
-        QVERIFY(delegate->property("test6").value<QObject*>() != 0);
-        QCOMPARE(delegate->property("test7").toInt(),1);
-        QCOMPARE(delegate->property("test8").toInt(),1);
-    }
-
-    {
-        QSGView view;
-
-        QStandardItemModel model;
-        initStandardTreeModel(&model);
-
-        view.rootContext()->setContextProperty("myModel", &model);
-
-        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");
-        QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData");
-        QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData");
-        QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData");
-        QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData");
-        QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData");
-        QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
-        QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
-        QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined");
-
-        view.setSource(source);
-
-        QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
-        QVERIFY(listview != 0);
-
-        QSGItem *contentItem = listview->contentItem();
-        QVERIFY(contentItem != 0);
-
-        QSGItem *delegate = findItem<QSGItem>(contentItem, "delegate", 1);
-        QVERIFY(delegate);
-        QCOMPARE(delegate->property("test1").toString(),QString("Row 2 Item"));
-        QCOMPARE(delegate->property("test2").toString(),QString("Row 2 Item"));
-        QVERIFY(!delegate->property("test3").isValid());
-        QVERIFY(!delegate->property("test4").isValid());
-        QVERIFY(!delegate->property("test5").isValid());
-        QVERIFY(!delegate->property("test9").isValid());
-        QVERIFY(delegate->property("test6").value<QObject*>() != 0);
-        QCOMPARE(delegate->property("test7").toInt(),1);
-        QCOMPARE(delegate->property("test8").toInt(),1);
-    }
-
-    //### should also test QStringList and QVariantList
-}
-
-void tst_qsgvisualdatamodel::noDelegate()
-{
-    QSGView view;
-
-    QStandardItemModel model;
-    initStandardTreeModel(&model);
-
-    view.rootContext()->setContextProperty("myModel", &model);
-
-    view.setSource(QUrl::fromLocalFile(TESTDATA("datalist.qml")));
-
-    QSGListView *listview = qobject_cast<QSGListView*>(view.rootObject());
-    QVERIFY(listview != 0);
-
-    QSGVisualDataModel *vdm = listview->findChild<QSGVisualDataModel*>("visualModel");
-    QVERIFY(vdm != 0);
-    QCOMPARE(vdm->count(), 3);
-
-    vdm->setDelegate(0);
-    QCOMPARE(vdm->count(), 0);
-}
-
-
-void tst_qsgvisualdatamodel::qaimRowsMoved()
-{
-    // Test parameters passed in QAIM::rowsMoved() signal are converted correctly
-    // when translated and emitted as the QListModelInterface::itemsMoved() signal
-    QFETCH(int, sourceFirst);
-    QFETCH(int, sourceLast);
-    QFETCH(int, destinationChild);
-    QFETCH(int, expectFrom);
-    QFETCH(int, expectTo);
-    QFETCH(int, expectCount);
-
-    QDeclarativeEngine engine;
-    QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("visualdatamodel.qml")));
-
-    SingleRoleModel model;
-    model.list.clear();
-    for (int i=0; i<30; i++)
-        model.list << ("item " + i);
-    engine.rootContext()->setContextProperty("myModel", &model);
-
-    QSGVisualDataModel *obj = qobject_cast<QSGVisualDataModel*>(c.create());
-    QVERIFY(obj != 0);
-
-    QSignalSpy spy(obj, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)));
-    model.emitMove(sourceFirst, sourceLast, destinationChild);
-    // QAbstractItemModel also emits the changed signal when items are moved.
-    QCOMPARE(spy.count(), 2);
-
-    bool move = false;
-    for (int i = 0; i < 2; ++i) {
-        QCOMPARE(spy[1].count(), 2);
-        QDeclarativeChangeSet changeSet = spy[i][0].value<QDeclarativeChangeSet>();
-        if (!changeSet.changes().isEmpty())
-            continue;
-        move = true;
-        QCOMPARE(changeSet.removes().count(), 1);
-        QCOMPARE(changeSet.removes().at(0).index, expectFrom);
-        QCOMPARE(changeSet.removes().at(0).count, expectCount);
-        QCOMPARE(changeSet.inserts().count(), 1);
-        QCOMPARE(changeSet.inserts().at(0).index, expectTo);
-        QCOMPARE(changeSet.inserts().at(0).count, expectCount);
-        QCOMPARE(changeSet.removes().at(0).moveId, changeSet.inserts().at(0).moveId);
-        QCOMPARE(spy[i][1].toBool(), false);
-    }
-    QVERIFY(move);
-
-    delete obj;
-}
-
-void tst_qsgvisualdatamodel::qaimRowsMoved_data()
-{
-    QTest::addColumn<int>("sourceFirst");
-    QTest::addColumn<int>("sourceLast");
-    QTest::addColumn<int>("destinationChild");
-    QTest::addColumn<int>("expectFrom");
-    QTest::addColumn<int>("expectTo");
-    QTest::addColumn<int>("expectCount");
-
-    QTest::newRow("move 1 forward")
-        << 1 << 1 << 6
-        << 1 << 5 << 1;
-
-    QTest::newRow("move 1 backwards")
-        << 4 << 4 << 1
-        << 4 << 1 << 1;
-
-    QTest::newRow("move multiple forwards")
-        << 0 << 2 << 13
-        << 0 << 10 << 3;
-
-    QTest::newRow("move multiple forwards, with same to")
-        << 0 << 1 << 3
-        << 0 << 1 << 2;
-
-    QTest::newRow("move multiple backwards")
-        << 10 << 14 << 1
-        << 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)
-{
-    const QMetaObject &mo = T::staticMetaObject;
-    //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)
-            continue;
-        //qDebug() << "try" << item;
-        if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
-            if (index != -1) {
-                QDeclarativeExpression e(qmlContext(item), item, "index");
-                if (e.evaluate().toInt() == index)
-                    return static_cast<T*>(item);
-            } else {
-                return static_cast<T*>(item);
-            }
-        }
-        item = findItem<T>(item, objectName, index);
-        if (item)
-        return static_cast<T*>(item);
-    }
-
-    return 0;
-}
-
-QTEST_MAIN(tst_qsgvisualdatamodel)
-
-#include "tst_qsgvisualdatamodel.moc"
index faa2675..7dc3e6a 100644 (file)
@@ -64,7 +64,7 @@ tst_qsgage::tst_qsgage()
 
 void tst_qsgage::test_kill()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/kill.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/kill.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
@@ -88,7 +88,7 @@ void tst_qsgage::test_kill()
 
 void tst_qsgage::test_jump()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/jump.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/jump.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
@@ -113,7 +113,7 @@ void tst_qsgage::test_jump()
 
 void tst_qsgage::test_onceOff()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/onceoff.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/onceoff.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
@@ -137,7 +137,7 @@ void tst_qsgage::test_onceOff()
 
 void tst_qsgage::test_sustained()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/sustained.qml", 600);
+    QQuickView* 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
index dbb23ff..2957b9e 100644 (file)
@@ -62,7 +62,7 @@ tst_qsgangleddirection::tst_qsgangleddirection()
 
 void tst_qsgangleddirection::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
index 00efff5..0a21949 100644 (file)
@@ -61,7 +61,7 @@ tst_qsgcumulativedirection::tst_qsgcumulativedirection()
 
 void tst_qsgcumulativedirection::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
index 2b36d31..d49f6cb 100644 (file)
@@ -61,7 +61,7 @@ tst_qsgcustomaffector::tst_qsgcustomaffector()
 
 void tst_qsgcustomaffector::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
index 92762ea..6fd02cd 100644 (file)
@@ -61,7 +61,7 @@ tst_qsgcustomparticle::tst_qsgcustomparticle()
 
 void tst_qsgcustomparticle::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QVERIFY(view);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
index 040a5e9..92ee0c2 100644 (file)
@@ -77,7 +77,7 @@ bool tst_qsgellipseextruder::inCircle(qreal x, qreal y, qreal r, bool borderOnly
 
 void tst_qsgellipseextruder::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
index bc622e4..ad37c3e 100644 (file)
@@ -61,7 +61,7 @@ tst_qsgfriction::tst_qsgfriction()
 
 void tst_qsgfriction::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
index 4758094..ae82384 100644 (file)
@@ -61,7 +61,7 @@ tst_qsggravity::tst_qsggravity()
 
 void tst_qsggravity::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
index a416271..cd03783 100644 (file)
@@ -67,7 +67,7 @@ tst_qsgimageparticle::tst_qsgimageparticle()
 
 void tst_qsgimageparticle::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
@@ -110,7 +110,7 @@ void tst_qsgimageparticle::test_basic()
 
 void tst_qsgimageparticle::test_colored()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/colored.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/colored.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
@@ -153,7 +153,7 @@ void tst_qsgimageparticle::test_colored()
 
 void tst_qsgimageparticle::test_deformed()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/deformed.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/deformed.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
@@ -196,7 +196,7 @@ void tst_qsgimageparticle::test_deformed()
 
 void tst_qsgimageparticle::test_tabled()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/tabled.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/tabled.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
@@ -240,7 +240,7 @@ void tst_qsgimageparticle::test_tabled()
 
 void tst_qsgimageparticle::test_sprite()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/sprite.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/sprite.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
index e58ab83..07ae377 100644 (file)
@@ -42,7 +42,7 @@
 #include <QtTest/QtTest>
 #include "../shared/particlestestsshared.h"
 #include <private/qsgparticlesystem_p.h>
-#include <private/qsgimage_p.h>
+#include <private/qquickimage_p.h>
 #include <private/qabstractanimation_p.h>
 
 class tst_qsgitemparticle : public QObject
@@ -62,7 +62,7 @@ tst_qsgitemparticle::tst_qsgitemparticle()
 
 void tst_qsgitemparticle::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
@@ -86,7 +86,7 @@ void tst_qsgitemparticle::test_basic()
         if (d->t < ((qreal)system->timeInt/1000.0) - 0.45)//Delegates cleared on death
             continue;
         QVERIFY(d->delegate);
-        QVERIFY(qobject_cast<QSGImage*>(d->delegate));
+        QVERIFY(qobject_cast<QQuickImage*>(d->delegate));
     }
 }
 
index 0f25f50..b66c174 100644 (file)
@@ -61,7 +61,7 @@ tst_qsglineextruder::tst_qsglineextruder()
 
 void tst_qsglineextruder::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
index 03070d8..962ab27 100644 (file)
@@ -61,7 +61,7 @@ tst_qsgmaskextruder::tst_qsgmaskextruder()
 
 void tst_qsgmaskextruder::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
index 49dc197..f49f3c4 100644 (file)
@@ -61,7 +61,7 @@ tst_qsgparticlegroup::tst_qsgparticlegroup()
 
 void tst_qsgparticlegroup::test_instantTransition()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
index 9c6f299..06a2414 100644 (file)
@@ -61,7 +61,7 @@ tst_qsgparticlesystem::tst_qsgparticlesystem()
 
 void tst_qsgparticlesystem::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
index 9e4ff32..14207f9 100644 (file)
@@ -61,7 +61,7 @@ tst_qsgpointattractor::tst_qsgpointattractor()
 
 void tst_qsgpointattractor::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
index c6a3a2c..b9b3dc1 100644 (file)
@@ -61,7 +61,7 @@ tst_qsgpointdirection::tst_qsgpointdirection()
 
 void tst_qsgpointdirection::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
index e8c27aa..dd86713 100644 (file)
@@ -61,7 +61,7 @@ tst_qsgrectangleextruder::tst_qsgrectangleextruder()
 
 void tst_qsgrectangleextruder::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
index decc961..5637c4c 100644 (file)
@@ -61,7 +61,7 @@ tst_qsgtargetdirection::tst_qsgtargetdirection()
 
 void tst_qsgtargetdirection::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
index e24c63c..19a63fb 100644 (file)
@@ -61,7 +61,7 @@ tst_qsgtrailemitter::tst_qsgtrailemitter()
 
 void tst_qsgtrailemitter::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
index 4230bc5..ca8a797 100644 (file)
@@ -61,7 +61,7 @@ tst_qsgturbulence::tst_qsgturbulence()
 
 void tst_qsgturbulence::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
index b200b6f..56ae15e 100644 (file)
@@ -61,7 +61,7 @@ tst_qsgwander::tst_qsgwander()
 
 void tst_qsgwander::test_basic()
 {
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
+    QQuickView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml", 600);
     QSGParticleSystem* system = view->rootObject()->findChild<QSGParticleSystem*>("system");
     ensureAnimTime(600, system->m_animation);
 
index ed483ba..ab6b5f1 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef PARTICLES_TESTS_SHARED
 #define PARTICLES_TESTS_SHARED
-#include <QSGView>
+#include <QQuickView>
 #include <QtTest>
 #include <QAbstractAnimation>
 const qreal EPSILON = 0.0001;
@@ -66,12 +66,12 @@ bool myFuzzyGEQ(qreal a, qreal b)
     return (a + EPSILON > b);
 }
 
-QSGView* createView(const QString &filename, int additionalWait=0)
+QQuickView* createView(const QString &filename, int additionalWait=0)
 {
-    QSGView *canvas = new QSGView(0);
+    QQuickView *canvas = new QQuickView(0);
 
     canvas->setSource(QUrl::fromLocalFile(filename));
-    if (canvas->status() != QSGView::Ready)
+    if (canvas->status() != QQuickView::Ready)
         return 0;
     canvas->show();
     QTest::qWaitForWindowShown(canvas);
index c902cd7..e8e9c23 100644 (file)
@@ -231,8 +231,8 @@ Item {
 
 
         function test_invalidSciFile() {
-            ignoreWarning("QSGGridScaledImage: Invalid tile rule specified. Using Stretch.") // for "Roun"
-            ignoreWarning("QSGGridScaledImage: Invalid tile rule specified. Using Stretch.") // for "Repea"
+            ignoreWarning("QQuickGridScaledImage: Invalid tile rule specified. Using Stretch.") // for "Roun"
+            ignoreWarning("QQuickGridScaledImage: Invalid tile rule specified. Using Stretch.") // for "Repea"
 
             var component = Qt.createComponent("InvalidSciFile.qml")
             var invalidSciFile = component.createObject(top)
index f85f877..18068b2 100644 (file)
@@ -82,7 +82,7 @@ void tst_affectors::test_filtered_data()
 void tst_affectors::test_basic()
 {
     QFETCH(int, dt);
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml");
+    QQuickView* 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;
@@ -122,7 +122,7 @@ void tst_affectors::test_basic()
 void tst_affectors::test_filtered()
 {
     QFETCH(int, dt);
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/filtered.qml");
+    QQuickView* 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;
index 66ce547..01e2476 100644 (file)
@@ -73,7 +73,7 @@ void tst_emission::test_basic_data()
 void tst_emission::test_basic()
 {
     QFETCH(int, dt);
-    QSGView* view = createView(QCoreApplication::applicationDirPath() + "/data/basic.qml");
+    QQuickView* 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;
index d0ab0d8..b4cf2da 100644 (file)
@@ -42,8 +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 <QtDeclarative/private/qquickevents_p_p.h>
+#include <QtDeclarative/private/qquickpincharea_p.h>
 
 #include <QtWidgets/QApplication>
 
@@ -586,8 +586,8 @@ int main(int argc, char *argv[])
     QList<QDeclarativeType *> defaultTypes = QDeclarativeMetaType::qmlTypes();
 
     // add some otherwise unreachable QMetaObjects
-    defaultReachable.insert(&QSGMouseEvent::staticMetaObject);
-    // QSGKeyEvent, QSGPinchEvent, QSGDropEvent are not exported
+    defaultReachable.insert(&QQuickMouseEvent::staticMetaObject);
+    // QQuickKeyEvent, QQuickPinchEvent, QQuickDropEvent are not exported
 
     // this will hold the meta objects we want to dump information of
     QSet<const QMetaObject *> metas;
index c5f9274..4706c72 100644 (file)
@@ -58,8 +58,8 @@
 #include <QtDeclarative/qdeclarativecontext.h>
 
 // ### This should be private API
-#include <qsgitem.h>
-#include <qsgview.h>
+#include <qquickitem.h>
+#include <qquickview.h>
 
 #define QT_NO_SCENEGRAPHITEM
 
@@ -143,12 +143,12 @@ void RenderStatistics::printTotalStats()
 }
 #endif
 
-class MyQSGView : public QSGView
+class MyQQuickView : public QQuickView
 {
 public:
-    MyQSGView() : QSGView()
+    MyQQuickView() : QQuickView()
     {
-        setResizeMode(QSGView::SizeRootObjectToView);
+        setResizeMode(QQuickView::SizeRootObjectToView);
     }
 };
 
@@ -491,7 +491,7 @@ int main(int argc, char ** argv)
 #endif
         if (options.versionDetection)
             checkAndAdaptVersion(options.file);
-        QSGView *qxView = new MyQSGView();
+        QQuickView *qxView = new MyQQuickView();
         qxView->setVSyncAnimations(options.vsync);
         engine = qxView->engine();
         for (int i = 0; i < imports.size(); ++i)