aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/config/qtquick-dita.qdocconf18
-rw-r--r--doc/config/qtquick.qdocconf5
-rw-r--r--doc/src/images/gridview-layout-lefttoright-ltr-btt.pngbin0 -> 8722 bytes
-rw-r--r--doc/src/images/gridview-layout-lefttoright-ltr-ttb.pngbin0 -> 7727 bytes
-rw-r--r--doc/src/images/gridview-layout-lefttoright-rtl-btt.pngbin0 -> 8725 bytes
-rw-r--r--doc/src/images/gridview-layout-lefttoright-rtl-ttb.pngbin0 -> 8693 bytes
-rw-r--r--doc/src/images/gridview-layout-toptobottom-ltr-btt.pngbin0 -> 8746 bytes
-rw-r--r--doc/src/images/gridview-layout-toptobottom-ltr-ttb.pngbin0 -> 8655 bytes
-rw-r--r--doc/src/images/gridview-layout-toptobottom-rtl-btt.pngbin0 -> 8746 bytes
-rw-r--r--doc/src/images/gridview-layout-toptobottom-rtl-ttb.pngbin0 -> 7657 bytes
-rw-r--r--doc/src/images/listview-layout-bottomtotop.pngbin0 -> 5620 bytes
-rw-r--r--doc/src/images/listview-layout-lefttoright.pngbin0 -> 5859 bytes
-rw-r--r--doc/src/images/listview-layout-righttoleft.pngbin0 -> 5840 bytes
-rw-r--r--doc/src/images/listview-layout-toptobottom.pngbin0 -> 5587 bytes
-rw-r--r--doc/src/qml/external-resources.qdoc (renamed from doc/src/external-resources.qdoc)3
-rw-r--r--doc/src/qml/hostenvironment.qdoc92
-rw-r--r--doc/src/qml/qmlengine.qdoc10
-rw-r--r--doc/src/qml/qmli18n.qdoc4
-rw-r--r--doc/src/qml/qtqml.qdoc (renamed from doc/src/qml/qtdeclarative.qdoc)12
-rw-r--r--doc/src/qtquick2/qtdeclarative.qdoc (renamed from doc/src/qtdeclarative.qdoc)0
-rw-r--r--doc/src/qtquick2/qtquick.qdoc (renamed from doc/src/quick/qtquick.qdoc)0
-rw-r--r--doc/src/qtquick2/whatsnew.qdoc (renamed from doc/src/whatsnew.qdoc)0
-rw-r--r--examples/demos/stockchart/contents/Button.qml87
-rw-r--r--examples/demos/stockchart/contents/ScrollBar.qml74
-rw-r--r--examples/demos/stockchart/contents/Stocks.qml147
-rw-r--r--examples/demos/stockchart/contents/TitleBar.qml70
-rw-r--r--examples/demos/stockchart/contents/ToolBar.qml69
-rwxr-xr-xexamples/demos/stockchart/contents/images/quit.pngbin0 -> 2369 bytes
-rwxr-xr-xexamples/demos/stockchart/contents/images/stripes.pngbin0 -> 257 bytes
-rw-r--r--examples/demos/stockchart/stock.qml2
-rw-r--r--modules/qt_quickparticles.pri17
-rw-r--r--src/imports/particles/particles.pro2
-rw-r--r--src/particles/particleresources/noise.png (renamed from src/quick/particles/particleresources/noise.png)bin19477 -> 19477 bytes
-rw-r--r--src/particles/particles.pri (renamed from src/quick/particles/particles.pri)3
-rw-r--r--src/particles/particles.pro40
-rw-r--r--src/particles/particles.qrc (renamed from src/quick/particles/particles.qrc)0
-rw-r--r--src/particles/qquickage.cpp (renamed from src/quick/particles/qquickage.cpp)0
-rw-r--r--src/particles/qquickage_p.h (renamed from src/quick/particles/qquickage_p.h)0
-rw-r--r--src/particles/qquickangledirection.cpp (renamed from src/quick/particles/qquickangledirection.cpp)0
-rw-r--r--src/particles/qquickangledirection_p.h (renamed from src/quick/particles/qquickangledirection_p.h)0
-rw-r--r--src/particles/qquickcumulativedirection.cpp (renamed from src/quick/particles/qquickcumulativedirection.cpp)0
-rw-r--r--src/particles/qquickcumulativedirection_p.h (renamed from src/quick/particles/qquickcumulativedirection_p.h)0
-rw-r--r--src/particles/qquickcustomaffector.cpp (renamed from src/quick/particles/qquickcustomaffector.cpp)0
-rw-r--r--src/particles/qquickcustomaffector_p.h (renamed from src/quick/particles/qquickcustomaffector_p.h)0
-rw-r--r--src/particles/qquickcustomparticle.cpp (renamed from src/quick/particles/qquickcustomparticle.cpp)0
-rw-r--r--src/particles/qquickcustomparticle_p.h (renamed from src/quick/particles/qquickcustomparticle_p.h)0
-rw-r--r--src/particles/qquickdirection.cpp (renamed from src/quick/particles/qquickdirection.cpp)0
-rw-r--r--src/particles/qquickdirection_p.h (renamed from src/quick/particles/qquickdirection_p.h)0
-rw-r--r--src/particles/qquickellipseextruder.cpp (renamed from src/quick/particles/qquickellipseextruder.cpp)0
-rw-r--r--src/particles/qquickellipseextruder_p.h (renamed from src/quick/particles/qquickellipseextruder_p.h)0
-rw-r--r--src/particles/qquickfriction.cpp (renamed from src/quick/particles/qquickfriction.cpp)0
-rw-r--r--src/particles/qquickfriction_p.h (renamed from src/quick/particles/qquickfriction_p.h)0
-rw-r--r--src/particles/qquickgravity.cpp (renamed from src/quick/particles/qquickgravity.cpp)0
-rw-r--r--src/particles/qquickgravity_p.h (renamed from src/quick/particles/qquickgravity_p.h)0
-rw-r--r--src/particles/qquickgroupgoal.cpp (renamed from src/quick/particles/qquickgroupgoal.cpp)0
-rw-r--r--src/particles/qquickgroupgoal_p.h (renamed from src/quick/particles/qquickgroupgoal_p.h)0
-rw-r--r--src/particles/qquickimageparticle.cpp (renamed from src/quick/particles/qquickimageparticle.cpp)0
-rw-r--r--src/particles/qquickimageparticle_p.h (renamed from src/quick/particles/qquickimageparticle_p.h)0
-rw-r--r--src/particles/qquickitemparticle.cpp (renamed from src/quick/particles/qquickitemparticle.cpp)0
-rw-r--r--src/particles/qquickitemparticle_p.h (renamed from src/quick/particles/qquickitemparticle_p.h)0
-rw-r--r--src/particles/qquicklineextruder.cpp (renamed from src/quick/particles/qquicklineextruder.cpp)0
-rw-r--r--src/particles/qquicklineextruder_p.h (renamed from src/quick/particles/qquicklineextruder_p.h)0
-rw-r--r--src/particles/qquickmaskextruder.cpp (renamed from src/quick/particles/qquickmaskextruder.cpp)0
-rw-r--r--src/particles/qquickmaskextruder_p.h (renamed from src/quick/particles/qquickmaskextruder_p.h)0
-rw-r--r--src/particles/qquickparticleaffector.cpp (renamed from src/quick/particles/qquickparticleaffector.cpp)0
-rw-r--r--src/particles/qquickparticleaffector_p.h (renamed from src/quick/particles/qquickparticleaffector_p.h)0
-rw-r--r--src/particles/qquickparticleemitter.cpp (renamed from src/quick/particles/qquickparticleemitter.cpp)0
-rw-r--r--src/particles/qquickparticleemitter_p.h (renamed from src/quick/particles/qquickparticleemitter_p.h)0
-rw-r--r--src/particles/qquickparticleextruder.cpp (renamed from src/quick/particles/qquickparticleextruder.cpp)0
-rw-r--r--src/particles/qquickparticleextruder_p.h (renamed from src/quick/particles/qquickparticleextruder_p.h)0
-rw-r--r--src/particles/qquickparticlegroup.cpp (renamed from src/quick/particles/qquickparticlegroup.cpp)0
-rw-r--r--src/particles/qquickparticlegroup_p.h (renamed from src/quick/particles/qquickparticlegroup_p.h)0
-rw-r--r--src/particles/qquickparticlepainter.cpp (renamed from src/quick/particles/qquickparticlepainter.cpp)0
-rw-r--r--src/particles/qquickparticlepainter_p.h (renamed from src/quick/particles/qquickparticlepainter_p.h)0
-rw-r--r--src/particles/qquickparticlesmodule.cpp (renamed from src/quick/particles/qquickparticlesmodule.cpp)0
-rw-r--r--src/particles/qquickparticlesmodule_p.h (renamed from src/quick/particles/qquickparticlesmodule_p.h)4
-rw-r--r--src/particles/qquickparticlesystem.cpp (renamed from src/quick/particles/qquickparticlesystem.cpp)0
-rw-r--r--src/particles/qquickparticlesystem_p.h (renamed from src/quick/particles/qquickparticlesystem_p.h)0
-rw-r--r--src/particles/qquickpointattractor.cpp (renamed from src/quick/particles/qquickpointattractor.cpp)0
-rw-r--r--src/particles/qquickpointattractor_p.h (renamed from src/quick/particles/qquickpointattractor_p.h)0
-rw-r--r--src/particles/qquickpointdirection.cpp (renamed from src/quick/particles/qquickpointdirection.cpp)0
-rw-r--r--src/particles/qquickpointdirection_p.h (renamed from src/quick/particles/qquickpointdirection_p.h)0
-rw-r--r--src/particles/qquickrectangleextruder.cpp (renamed from src/quick/particles/qquickrectangleextruder.cpp)0
-rw-r--r--src/particles/qquickrectangleextruder_p.h (renamed from src/quick/particles/qquickrectangleextruder_p.h)0
-rw-r--r--src/particles/qquickspritegoal.cpp (renamed from src/quick/particles/qquickspritegoal.cpp)0
-rw-r--r--src/particles/qquickspritegoal_p.h (renamed from src/quick/particles/qquickspritegoal_p.h)0
-rw-r--r--src/particles/qquicktargetdirection.cpp (renamed from src/quick/particles/qquicktargetdirection.cpp)0
-rw-r--r--src/particles/qquicktargetdirection_p.h (renamed from src/quick/particles/qquicktargetdirection_p.h)0
-rw-r--r--src/particles/qquicktrailemitter.cpp (renamed from src/quick/particles/qquicktrailemitter.cpp)0
-rw-r--r--src/particles/qquicktrailemitter_p.h (renamed from src/quick/particles/qquicktrailemitter_p.h)0
-rw-r--r--src/particles/qquickturbulence.cpp (renamed from src/quick/particles/qquickturbulence.cpp)0
-rw-r--r--src/particles/qquickturbulence_p.h (renamed from src/quick/particles/qquickturbulence_p.h)0
-rw-r--r--src/particles/qquickv8particledata.cpp (renamed from src/quick/particles/qquickv8particledata.cpp)0
-rw-r--r--src/particles/qquickv8particledata_p.h (renamed from src/quick/particles/qquickv8particledata_p.h)0
-rw-r--r--src/particles/qquickwander.cpp (renamed from src/quick/particles/qquickwander.cpp)0
-rw-r--r--src/particles/qquickwander_p.h (renamed from src/quick/particles/qquickwander_p.h)0
-rw-r--r--src/particles/qtquickparticlesglobal_p.h69
-rw-r--r--src/plugins/qmltooling/qmldbg_qtquick2/highlight.cpp68
-rw-r--r--src/plugins/qmltooling/qmldbg_qtquick2/highlight.h11
-rw-r--r--src/plugins/qmltooling/qmldbg_qtquick2/inspecttool.cpp45
-rw-r--r--src/plugins/qmltooling/qmldbg_qtquick2/inspecttool.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.cpp31
-rw-r--r--src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.h4
-rw-r--r--src/qml/animations/qabstractanimationjob.cpp1
-rw-r--r--src/qml/animations/qabstractanimationjob_p.h1
-rw-r--r--src/qml/debugger/qv8debugservice.cpp24
-rw-r--r--src/qml/debugger/qv8debugservice_p.h2
-rw-r--r--src/qml/qml/ftw/qqmlpool.cpp1
-rw-r--r--src/qml/qml/qqmllist.cpp2
-rw-r--r--src/qml/qml/qqmllocale.cpp4
-rw-r--r--src/qml/qml/v4/qv4bindings.cpp130
-rw-r--r--src/qml/qml/v4/qv4compiler.cpp21
-rw-r--r--src/qml/qml/v4/qv4instruction.cpp24
-rw-r--r--src/qml/qml/v4/qv4instruction_p.h8
-rw-r--r--src/qml/qml/v4/qv4ir.cpp2
-rw-r--r--src/qml/qml/v4/qv4ir_p.h2
-rw-r--r--src/qml/qml/v4/qv4irbuilder.cpp12
-rw-r--r--src/qml/qml/v8/qjsconverter_impl_p.h1
-rw-r--r--src/qml/qml/v8/qv8qobjectwrapper.cpp4
-rw-r--r--src/qmltest/qmltest.pro4
-rw-r--r--src/quick/items/qquickcanvas.cpp1
-rw-r--r--src/quick/items/qquickgridview.cpp381
-rw-r--r--src/quick/items/qquickgridview_p.h6
-rw-r--r--src/quick/items/qquickimplicitsizeitem_p.h2
-rw-r--r--src/quick/items/qquickitemview.cpp255
-rw-r--r--src/quick/items/qquickitemview_p.h23
-rw-r--r--src/quick/items/qquickitemview_p_p.h18
-rw-r--r--src/quick/items/qquickitemviewtransition_p.h10
-rw-r--r--src/quick/items/qquicklistview.cpp205
-rw-r--r--src/quick/items/qquickshadereffect_p.h5
-rw-r--r--src/quick/items/qquickshadereffectnode_p.h5
-rw-r--r--src/quick/items/qquickspriteengine.cpp2
-rw-r--r--src/quick/items/qquickspriteengine_p.h9
-rw-r--r--src/quick/items/qquicktext.cpp65
-rw-r--r--src/quick/items/qquicktext_p.h2
-rw-r--r--src/quick/items/qquicktext_p_p.h3
-rw-r--r--src/quick/items/qquicktextcontrol.cpp13
-rw-r--r--src/quick/items/qquicktextcontrol_p.h2
-rw-r--r--src/quick/items/qquickwindowmanager.cpp12
-rw-r--r--src/quick/quick.pro1
-rw-r--r--src/quick/scenegraph/coreapi/qsgdefaultrenderer_p.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsggeometry.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer_p.h2
-rw-r--r--src/quick/util/qquickanimation.cpp23
-rw-r--r--src/quick/util/qquicktransition.cpp106
-rw-r--r--src/quick/util/qquicktransition_p.h9
-rw-r--r--src/src.pro2
-rw-r--r--sync.profile5
-rw-r--r--tests/auto/particles/particles.pro2
-rw-r--r--tests/auto/particles/qquickage/qquickage.pro2
-rw-r--r--tests/auto/particles/qquickangleddirection/qquickangleddirection.pro2
-rw-r--r--tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro2
-rw-r--r--tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro2
-rw-r--r--tests/auto/particles/qquickcustomparticle/data/deleteSourceItem.qml81
-rw-r--r--tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro2
-rw-r--r--tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp15
-rw-r--r--tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro2
-rw-r--r--tests/auto/particles/qquickfriction/qquickfriction.pro2
-rw-r--r--tests/auto/particles/qquickgravity/qquickgravity.pro2
-rw-r--r--tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro2
-rw-r--r--tests/auto/particles/qquickimageparticle/qquickimageparticle.pro2
-rw-r--r--tests/auto/particles/qquickitemparticle/qquickitemparticle.pro2
-rw-r--r--tests/auto/particles/qquicklineextruder/qquicklineextruder.pro2
-rw-r--r--tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro2
-rw-r--r--tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro2
-rw-r--r--tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro2
-rw-r--r--tests/auto/particles/qquickpointattractor/qquickpointattractor.pro2
-rw-r--r--tests/auto/particles/qquickpointdirection/qquickpointdirection.pro2
-rw-r--r--tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro2
-rw-r--r--tests/auto/particles/qquickspritegoal/data/basic.qml4
-rw-r--r--tests/auto/particles/qquickspritegoal/qquickspritegoal.pro2
-rw-r--r--tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro2
-rw-r--r--tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro2
-rw-r--r--tests/auto/particles/qquickturbulence/qquickturbulence.pro2
-rw-r--r--tests/auto/particles/qquickwander/qquickwander.pro2
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/data/test.qml6
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp33
-rw-r--r--tests/auto/qml/debugger/qv8profilerservice/qv8profilerservice.pro2
-rw-r--r--tests/auto/qml/debugger/shared/debugutil_p.h1
-rw-r--r--tests/auto/qml/v4/data/variantHandling.qml67
-rw-r--r--tests/auto/qml/v4/tst_v4.cpp9
-rw-r--r--tests/auto/qmltest/qmltest.pro2
-rw-r--r--tests/auto/quick/qquickanimations/tst_qquickanimations.cpp29
-rw-r--r--tests/auto/quick/qquickcanvas/data/ownershipRootItem.qml11
-rw-r--r--tests/auto/quick/qquickcanvas/qquickcanvas.pro3
-rw-r--r--tests/auto/quick/qquickcanvas/tst_qquickcanvas.cpp74
-rw-r--r--tests/auto/quick/qquickgridview/data/gridview1.qml6
-rw-r--r--tests/auto/quick/qquickgridview/data/headerfooter.qml15
-rw-r--r--tests/auto/quick/qquickgridview/data/layouts.qml62
-rw-r--r--tests/auto/quick/qquickgridview/data/resizegrid.qml51
-rw-r--r--tests/auto/quick/qquickgridview/tst_qquickgridview.cpp2039
-rw-r--r--tests/auto/quick/qquicklistview/data/header.qml2
-rw-r--r--tests/auto/quick/qquicklistview/data/headerfooter.qml15
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp759
-rw-r--r--tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro2
-rw-r--r--tests/auto/quick/qquickpositioners/qquickpositioners.pro1
-rw-r--r--tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp4
-rw-r--r--tests/auto/quick/qquickshadereffect/data/deleteShaderEffectSource.qml74
-rw-r--r--tests/auto/quick/qquickshadereffect/data/deleteSourceItem.qml75
-rw-r--r--tests/auto/quick/qquickshadereffect/data/star.pngbin0 -> 1550 bytes
-rw-r--r--tests/auto/quick/qquickshadereffect/qquickshadereffect.pro1
-rw-r--r--tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp40
-rw-r--r--tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp70
-rw-r--r--tests/auto/quick/qquicktext/tst_qquicktext.cpp254
-rw-r--r--tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp5
-rw-r--r--tools/easingcurveeditor/mainwindow.cpp2
206 files changed, 4669 insertions, 1496 deletions
diff --git a/doc/config/qtquick-dita.qdocconf b/doc/config/qtquick-dita.qdocconf
index e259a2fa74..ee471c1df1 100644
--- a/doc/config/qtquick-dita.qdocconf
+++ b/doc/config/qtquick-dita.qdocconf
@@ -7,9 +7,21 @@ project = Qt Quick
# Images should be placed in <rootdir>/dic/images and examples in
# <rootdir>/examples.
# Paths are relative to the location of this file.
-exampledirs += ../src/examples
-headerdirs += ../src
-sourcedirs += ../src
+exampledirs += ../src/examples \
+ ../.. \
+ ../../examples
+
+headerdirs += ../src \
+ ../../src
+
+imagedirs += ../src/images \
+
+sourcedirs += ../src \
+ ../../src
+
+excludedirs += ../src/qtquick1 \
+ ../../src/qtquick1
+
diff --git a/doc/config/qtquick.qdocconf b/doc/config/qtquick.qdocconf
index 3f4645aeaa..0870bde323 100644
--- a/doc/config/qtquick.qdocconf
+++ b/doc/config/qtquick.qdocconf
@@ -37,10 +37,7 @@ qhp.projects = qtquick
qhp.qtquick.file = qtquick.qhp
# Namespace for the output file. This namespace is used to distinguish between
-# different documentation files in Creator/Assistant. Normal format for MP
-# projects should be: com.nokia.mp.<projectname>.version with version being
-# a number containing a major, minor and revision element. E.g. version 1.0
-# becomes 100.
+# different documentation files in Creator/Assistant. Qt Quick 2 release.
qhp.qtquick.namespace = qtquick.200
# Title for the package, will be the main title for the package in
diff --git a/doc/src/images/gridview-layout-lefttoright-ltr-btt.png b/doc/src/images/gridview-layout-lefttoright-ltr-btt.png
new file mode 100644
index 0000000000..4439f8370a
--- /dev/null
+++ b/doc/src/images/gridview-layout-lefttoright-ltr-btt.png
Binary files differ
diff --git a/doc/src/images/gridview-layout-lefttoright-ltr-ttb.png b/doc/src/images/gridview-layout-lefttoright-ltr-ttb.png
new file mode 100644
index 0000000000..af745b7d1e
--- /dev/null
+++ b/doc/src/images/gridview-layout-lefttoright-ltr-ttb.png
Binary files differ
diff --git a/doc/src/images/gridview-layout-lefttoright-rtl-btt.png b/doc/src/images/gridview-layout-lefttoright-rtl-btt.png
new file mode 100644
index 0000000000..bc7e568972
--- /dev/null
+++ b/doc/src/images/gridview-layout-lefttoright-rtl-btt.png
Binary files differ
diff --git a/doc/src/images/gridview-layout-lefttoright-rtl-ttb.png b/doc/src/images/gridview-layout-lefttoright-rtl-ttb.png
new file mode 100644
index 0000000000..3ebf74fae5
--- /dev/null
+++ b/doc/src/images/gridview-layout-lefttoright-rtl-ttb.png
Binary files differ
diff --git a/doc/src/images/gridview-layout-toptobottom-ltr-btt.png b/doc/src/images/gridview-layout-toptobottom-ltr-btt.png
new file mode 100644
index 0000000000..b60ab4b5e7
--- /dev/null
+++ b/doc/src/images/gridview-layout-toptobottom-ltr-btt.png
Binary files differ
diff --git a/doc/src/images/gridview-layout-toptobottom-ltr-ttb.png b/doc/src/images/gridview-layout-toptobottom-ltr-ttb.png
new file mode 100644
index 0000000000..9078cbde6f
--- /dev/null
+++ b/doc/src/images/gridview-layout-toptobottom-ltr-ttb.png
Binary files differ
diff --git a/doc/src/images/gridview-layout-toptobottom-rtl-btt.png b/doc/src/images/gridview-layout-toptobottom-rtl-btt.png
new file mode 100644
index 0000000000..0d0f095598
--- /dev/null
+++ b/doc/src/images/gridview-layout-toptobottom-rtl-btt.png
Binary files differ
diff --git a/doc/src/images/gridview-layout-toptobottom-rtl-ttb.png b/doc/src/images/gridview-layout-toptobottom-rtl-ttb.png
new file mode 100644
index 0000000000..c1c353a4da
--- /dev/null
+++ b/doc/src/images/gridview-layout-toptobottom-rtl-ttb.png
Binary files differ
diff --git a/doc/src/images/listview-layout-bottomtotop.png b/doc/src/images/listview-layout-bottomtotop.png
new file mode 100644
index 0000000000..980f81d07f
--- /dev/null
+++ b/doc/src/images/listview-layout-bottomtotop.png
Binary files differ
diff --git a/doc/src/images/listview-layout-lefttoright.png b/doc/src/images/listview-layout-lefttoright.png
new file mode 100644
index 0000000000..2ee0e4c4ff
--- /dev/null
+++ b/doc/src/images/listview-layout-lefttoright.png
Binary files differ
diff --git a/doc/src/images/listview-layout-righttoleft.png b/doc/src/images/listview-layout-righttoleft.png
new file mode 100644
index 0000000000..2c54a2a7b1
--- /dev/null
+++ b/doc/src/images/listview-layout-righttoleft.png
Binary files differ
diff --git a/doc/src/images/listview-layout-toptobottom.png b/doc/src/images/listview-layout-toptobottom.png
new file mode 100644
index 0000000000..2054a5743b
--- /dev/null
+++ b/doc/src/images/listview-layout-toptobottom.png
Binary files differ
diff --git a/doc/src/external-resources.qdoc b/doc/src/qml/external-resources.qdoc
index b4aecbad75..386992f439 100644
--- a/doc/src/external-resources.qdoc
+++ b/doc/src/qml/external-resources.qdoc
@@ -28,5 +28,8 @@
/*!
\externalpage http://www.ecma-international.org/publications/standards/Ecma-262.htm
\title ECMA-262
+
+ \externalpage http://www.w3schools.com/jsref/default.asp
+ \title W3Schools JavaScript Reference
*/
diff --git a/doc/src/qml/hostenvironment.qdoc b/doc/src/qml/hostenvironment.qdoc
new file mode 100644
index 0000000000..b0d9118944
--- /dev/null
+++ b/doc/src/qml/hostenvironment.qdoc
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms
+** and conditions contained in a signed written agreement between you
+** and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+\page qmlhostenvironment.html
+\title QML JavaScript Host Environment
+
+QML provides a JavaScript host environment tailored to writing QML applications.
+This environment is different from the host environment provided by a browser
+or a server-side JavaScript environment such as Node.js. For example, QML does
+not provide a \c window object or \c{DOM API} as commonly found in a browser environment.
+
+\section1 Common Base
+
+Like a browser or server-side JavaScript environment, the QML runtime implements the
+\l{ECMA-262}{ECMAScript Language Specification} standard. This provides access to
+all of the built-in types and functions defined by the standard, such as Object, Array, and Math.
+The QML runtime implements the 5th edition of the standard, which is the same edition commonly
+implemented by browsers.
+
+The standard ECMAScript built-ins are not explicitly documented in the QML documentation. For more
+information on their use, please refer to the ECMA-262 5th edition standard or one of the many online
+JavaScript reference and tutorial sites, such as the \l{W3Schools JavaScript Reference} (JavaScript Objects
+Reference section). Many sites focus on JavaScript in the browser, so in some cases you may need to double
+check the specification to determine whether a given function or object is part of standard ECMAScript or
+specific to the browser environment. In the case of the W3Schools link above, the \c{JavaScript Objects
+Reference} section generally covers the standard, while the \c{Browser Objects Reference} and \c{HTML DOM
+Objects Reference} sections are browser specific (and thus not applicable to QML).
+
+\section1 Host Objects and Functions
+
+The QML JavaScript host environment implements the following host objects and functions:
+
+\list
+\li The \l{QmlGlobalQtObject}{Qt object}: This object is specific to QML, and provides helper methods
+ and properties specific to the QML environment.
+\li qsTr(), qsTranslate(), qsTrId(), QT_TR_NOOP(), QT_TRANSLATE_NOOP(), and QT_TRID_NOOP() functions:
+ These functions are specific to QML, and provide \l{Translation}{translation capabilities} to the QML environment.
+\li gc() function: This function is specific to QML, and provides a way to manually trigger garbage collection.
+\li print() function: This function is specific to QML, and provides a simple way to output information to the console.
+\li The \l{Console API}{console object}: This object implements a subset of the \l{http://getfirebug.com/wiki/index.php/Console_API}{FireBug Console API}.
+\li \l{XMLHttpRequest}, DOMException: These objects implement a subset of the \l{http://www.w3.org/TR/XMLHttpRequest/}{W3C XMLHttpRequest specification}.
+\endlist
+
+See \l{QML Global Object} for more details on these host objects and functions.
+
+\section1 Native Object Modification
+
+QML makes the following modifications to native objects:
+
+\list
+\li An arg() function is added to the String prototype.
+\li Locale-aware coversion functions are added to the \l{Date} and \l{Number} prototypes.
+\endlist
+
+\section1 Restrictions
+
+QML implements the following restrictions for JavaScript code:
+
+\list
+\li JavaScript code cannot modify the global object.
+\li Global code is run in a reduced scope.
+\li The value of \c this is undefined in QML in the majority of contexts.
+\endlist
+
+See \l {QML JavaScript Restrictions} for more details on these restrictions.
+
+*/
diff --git a/doc/src/qml/qmlengine.qdoc b/doc/src/qml/qmlengine.qdoc
index b0754fe3ab..ad77d43cb5 100644
--- a/doc/src/qml/qmlengine.qdoc
+++ b/doc/src/qml/qmlengine.qdoc
@@ -467,9 +467,13 @@ specified in QML files, plugins, or applications.
\section1 JavaScript Runtime
- The runtime implements the \l{ECMA-262}{ECMAScript Language Specification} standard.
- The reserved words, conditionals, variables, and object behaviors follow
- after the standard.
+ The runtime implements the \l{ECMA-262}{ECMAScript Language Specification} standard,
+ 5th edition. The reserved words, conditionals, variables, and object behaviors
+ follow after the standard.
+
+ The \l{QML JavaScript Host Environment} article has information about the
+ JavaScript host environment provided by QML, which is different than the
+ browser host environment many are familiar with.
The \l{JavaScript Code} article has information about placing JavaScript
code within QML code.
diff --git a/doc/src/qml/qmli18n.qdoc b/doc/src/qml/qmli18n.qdoc
index d15beafb38..b65c001e8e 100644
--- a/doc/src/qml/qmli18n.qdoc
+++ b/doc/src/qml/qmli18n.qdoc
@@ -33,8 +33,8 @@
\section1 Translation
-Strings in QML can be marked for translation using the qsTr(), qsTranslate(),
-QT_TR_NOOP(), and QT_TRANSLATE_NOOP() functions.
+Strings in QML can be marked for translation using the qsTr(), qsTranslate(), qsTrId(),
+QT_TR_NOOP(), QT_TRANSLATE_NOOP(), and QT_TRID_NOOP() functions.
For example:
\qml
diff --git a/doc/src/qml/qtdeclarative.qdoc b/doc/src/qml/qtqml.qdoc
index 5ad637ab50..7bd797e8d0 100644
--- a/doc/src/qml/qtdeclarative.qdoc
+++ b/doc/src/qml/qtqml.qdoc
@@ -27,10 +27,10 @@
/*!
\module QtQml
- \title Qt Qml Module
+ \title Qt QML Module
\ingroup modules
- \brief The Qt Qml module provides a declarative framework
+ \brief The Qt QML module provides a declarative framework
for building highly dynamic, custom user interfaces.
To include the definitions of the module's classes, use the
@@ -47,8 +47,8 @@
QT += qml
\endcode
- For more information on the Qt Qml module (including the visual
- elements which are implemented on top of the Qt Qml module) see the
+ For more information on the Qt QML module (including the visual
+ elements which are implemented on top of the Qt QML module) see the
\l{Qt Quick} documentation.
*/
@@ -68,7 +68,7 @@
Declares additional properties of the given \a Type as described by the
specified \a Flags.
-
+
Current the only supported type info is \c QML_HAS_ATTACHED_PROPERTIES which
declares that the \a Type supports \l {Attached Properties}.
@@ -113,7 +113,7 @@
qmlRegisterType<MySliderItem>("com.mycompany.qmlcomponents", 1, 0, "Slider");
\endcode
- Once this is registered, the type can be used in QML by importing the
+ Once this is registered, the type can be used in QML by importing the
specified module name and version number:
\qml
diff --git a/doc/src/qtdeclarative.qdoc b/doc/src/qtquick2/qtdeclarative.qdoc
index d9b9234c90..d9b9234c90 100644
--- a/doc/src/qtdeclarative.qdoc
+++ b/doc/src/qtquick2/qtdeclarative.qdoc
diff --git a/doc/src/quick/qtquick.qdoc b/doc/src/qtquick2/qtquick.qdoc
index c38ef3c801..c38ef3c801 100644
--- a/doc/src/quick/qtquick.qdoc
+++ b/doc/src/qtquick2/qtquick.qdoc
diff --git a/doc/src/whatsnew.qdoc b/doc/src/qtquick2/whatsnew.qdoc
index 1997a42a6b..1997a42a6b 100644
--- a/doc/src/whatsnew.qdoc
+++ b/doc/src/qtquick2/whatsnew.qdoc
diff --git a/examples/demos/stockchart/contents/Button.qml b/examples/demos/stockchart/contents/Button.qml
new file mode 100644
index 0000000000..ab9ce350db
--- /dev/null
+++ b/examples/demos/stockchart/contents/Button.qml
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ id: container
+
+ signal clicked
+
+ property string text
+ width: buttonText.width + 28
+ height: buttonText.height + 14
+
+ BorderImage {
+ id: buttonImage
+ source: "images/toolbutton.sci"
+ width: container.width - 10
+ height: container.height
+ }
+ BorderImage {
+ id: pressed
+ opacity: 0
+ source: "images/toolbutton.sci"
+ width: container.width - 10
+ height: container.height
+ }
+ MouseArea {
+ id: mouseRegion
+ anchors.fill: buttonImage
+ onClicked: { container.clicked(); }
+ }
+ Text {
+ id: buttonText
+ color: "white"
+ anchors.centerIn: buttonImage
+ font.bold: true
+ font.pointSize: 15
+ text: container.text
+ style: Text.Raised
+ styleColor: "black"
+ }
+ states: [
+ State {
+ name: "Pressed"
+ when: mouseRegion.pressed == true
+ PropertyChanges { target: pressed; opacity: 1 }
+ }
+ ]
+}
diff --git a/examples/demos/stockchart/contents/ScrollBar.qml b/examples/demos/stockchart/contents/ScrollBar.qml
new file mode 100644
index 0000000000..98b8efee4a
--- /dev/null
+++ b/examples/demos/stockchart/contents/ScrollBar.qml
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ id: scrollBar
+ // The properties that define the scrollbar's state.
+ // position and pageSize are in the range 0.0 - 1.0. They are relative to the
+ // height of the page, i.e. a pageSize of 0.5 means that you can see 50%
+ // of the height of the view.
+ // orientation can be either 'Vertical' or 'Horizontal'
+ property real position
+ property real pageSize
+ property string orientation : "Vertical"
+ property alias bgColor: background.color
+ property alias fgColor: thumb.color
+
+ // A light, semi-transparent background
+ Rectangle {
+ id: background
+ radius: orientation == 'Vertical' ? (width/2 - 1) : (height/2 - 1)
+ color: "white"; opacity: 0.3
+ anchors.fill: parent
+ }
+ // Size the bar to the required size, depending upon the orientation.
+ Rectangle {
+ id: thumb
+ opacity: 0.7
+ color: "black"
+ radius: orientation == 'Vertical' ? (width/2 - 1) : (height/2 - 1)
+ x: orientation == 'Vertical' ? 1 : (scrollBar.position * (scrollBar.width-2) + 1)
+ y: orientation == 'Vertical' ? (scrollBar.position * (scrollBar.height-2) + 1) : 1
+ width: orientation == 'Vertical' ? (parent.width-2) : (scrollBar.pageSize * (scrollBar.width-2))
+ height: orientation == 'Vertical' ? (scrollBar.pageSize * (scrollBar.height-2)) : (parent.height-2)
+ }
+}
diff --git a/examples/demos/stockchart/contents/Stocks.qml b/examples/demos/stockchart/contents/Stocks.qml
new file mode 100644
index 0000000000..043bca132e
--- /dev/null
+++ b/examples/demos/stockchart/contents/Stocks.qml
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+ListModel {
+ id:stocks
+ //Data from : http://en.wikipedia.org/wiki/NASDAQ-100
+
+ ListElement {name:"Activision Blizzard"; stockId:"ATVI"}
+ ListElement {name:"Adobe Systems Incorporated"; stockId:"ADBE"}
+ ListElement {name:"Akamai Technologies, Inc"; stockId:"AKAM"}
+ ListElement {name:"Alexion Pharmaceuticals"; stockId:"ALXN"}
+ ListElement {name:"Altera Corporation"; stockId:"ALTR"}
+ ListElement {name:"Amazon.com, Inc."; stockId:"AMZN"}
+ ListElement {name:"Amgen Inc."; stockId:"AMGN"}
+ ListElement {name:"Apollo Group, Inc."; stockId:"APOL"}
+ ListElement {name:"Apple Inc."; stockId:"AAPL"}
+ ListElement {name:"Applied Materials, Inc."; stockId:"AMAT"}
+ ListElement {name:"Autodesk, Inc."; stockId:"ADSK"}
+ ListElement {name:"Automatic Data Processing, Inc."; stockId:"ADP"}
+ ListElement {name:"Baidu.com, Inc."; stockId:"BIDU"}
+ ListElement {name:"Bed Bath & Beyond Inc."; stockId:"BBBY"}
+ ListElement {name:"Biogen Idec, Inc"; stockId:"BIIB"}
+ ListElement {name:"BMC Software, Inc."; stockId:"BMC"}
+ ListElement {name:"Broadcom Corporation"; stockId:"BRCM"}
+ ListElement {name:"C. H. Robinson Worldwide, Inc."; stockId:"CHRW"}
+ ListElement {name:"CA, Inc."; stockId:"CA"}
+ ListElement {name:"Celgene Corporation"; stockId:"CELG"}
+ ListElement {name:"Cephalon, Inc."; stockId:"CEPH"}
+ ListElement {name:"Cerner Corporation"; stockId:"CERN"}
+ ListElement {name:"Check Point Software Technologies Ltd."; stockId:"CHKP"}
+ ListElement {name:"Cisco Systems, Inc."; stockId:"CSCO"}
+ ListElement {name:"Citrix Systems, Inc."; stockId:"CTXS"}
+ ListElement {name:"Cognizant Technology Solutions Corporation"; stockId:"CTSH"}
+ ListElement {name:"Comcast Corporation"; stockId:"CMCSA"}
+ ListElement {name:"Costco Wholesale Corporation"; stockId:"COST"}
+ ListElement {name:"Ctrip.com International, Ltd."; stockId:"CTRP"}
+ ListElement {name:"Dell Inc."; stockId:"DELL"}
+ ListElement {name:"DENTSPLY International Inc."; stockId:"XRAY"}
+ ListElement {name:"DirecTV"; stockId:"DTV"}
+ ListElement {name:"Dollar Tree, Inc."; stockId:"DLTR"}
+ ListElement {name:"eBay Inc."; stockId:"EBAY"}
+ ListElement {name:"Electronic Arts Inc."; stockId:"ERTS"}
+ ListElement {name:"Expedia, Inc."; stockId:"EXPE"}
+ ListElement {name:"Expeditors International of Washington, Inc."; stockId:"EXPD"}
+ ListElement {name:"Express Scripts, Inc."; stockId:"ESRX"}
+ ListElement {name:"F5 Networks, Inc."; stockId:"FFIV"}
+ ListElement {name:"Fastenal Company"; stockId:"FAST"}
+ ListElement {name:"First Solar, Inc."; stockId:"FSLR"}
+ ListElement {name:"Fiserv, Inc."; stockId:"FISV"}
+ ListElement {name:"Flextronics International Ltd."; stockId:"FLEX"}
+ ListElement {name:"FLIR Systems, Inc."; stockId:"FLIR"}
+ ListElement {name:"Garmin Ltd."; stockId:"GRMN"}
+ ListElement {name:"Gilead Sciences, Inc."; stockId:"GILD"}
+ ListElement {name:"Google Inc."; stockId:"GOOG"}
+ ListElement {name:"Green Mountain Coffee Roasters, Inc."; stockId:"GMCR"}
+ ListElement {name:"Henry Schein, Inc."; stockId:"HSIC"}
+ ListElement {name:"Illumina, Inc."; stockId:"ILMN"}
+ ListElement {name:"Infosys Technologies"; stockId:"INFY"}
+ ListElement {name:"Intel Corporation"; stockId:"INTC"}
+ ListElement {name:"Intuit, Inc."; stockId:"INTU"}
+ ListElement {name:"Intuitive Surgical Inc."; stockId:"ISRG"}
+ ListElement {name:"Joy Global Inc."; stockId:"JOYG"}
+ ListElement {name:"KLA Tencor Corporation"; stockId:"KLAC"}
+ ListElement {name:"Lam Research Corporation"; stockId:"LRCX"}
+ ListElement {name:"Liberty Media Corporation, Interactive Series A"; stockId:"LINTA"}
+ ListElement {name:"Life Technologies Corporation"; stockId:"LIFE"}
+ ListElement {name:"Linear Technology Corporation"; stockId:"LLTC"}
+ ListElement {name:"Marvell Technology Group, Ltd."; stockId:"MRVL"}
+ ListElement {name:"Mattel, Inc."; stockId:"MAT"}
+ ListElement {name:"Maxim Integrated Products"; stockId:"MXIM"}
+ ListElement {name:"Microchip Technology Incorporated"; stockId:"MCHP"}
+ ListElement {name:"Micron Technology, Inc."; stockId:"MU"}
+ ListElement {name:"Microsoft Corporation"; stockId:"MSFT"}
+ ListElement {name:"Mylan, Inc."; stockId:"MYL"}
+ ListElement {name:"NetApp, Inc."; stockId:"NTAP"}
+ ListElement {name:"Netflix, Inc."; stockId:"NFLX"}
+ ListElement {name:"News Corporation, Ltd."; stockId:"NWSA"}
+ ListElement {name:"NII Holdings, Inc."; stockId:"NIHD"}
+ ListElement {name:"NVIDIA Corporation"; stockId:"NVDA"}
+ ListElement {name:"O'Reilly Automotive, Inc."; stockId:"ORLY"}
+ ListElement {name:"Oracle Corporation"; stockId:"ORCL"}
+ ListElement {name:"PACCAR Inc."; stockId:"PCAR"}
+ ListElement {name:"Paychex, Inc."; stockId:"PAYX"}
+ ListElement {name:"Priceline.com, Incorporated"; stockId:"PCLN"}
+ ListElement {name:"Qiagen N.V."; stockId:"QGEN"}
+ ListElement {name:"QUALCOMM Incorporated"; stockId:"QCOM"}
+ ListElement {name:"Research in Motion Limited"; stockId:"RIMM"}
+ ListElement {name:"Ross Stores Inc."; stockId:"ROST"}
+ ListElement {name:"SanDisk Corporation"; stockId:"SNDK"}
+ ListElement {name:"Seagate Technology Holdings"; stockId:"STX"}
+ ListElement {name:"Sears Holdings Corporation"; stockId:"SHLD"}
+ ListElement {name:"Sigma-Aldrich Corporation"; stockId:"SIAL"}
+ ListElement {name:"Staples Inc."; stockId:"SPLS"}
+ ListElement {name:"Starbucks Corporation"; stockId:"SBUX"}
+ ListElement {name:"Stericycle, Inc"; stockId:"SRCL"}
+ ListElement {name:"Symantec Corporation"; stockId:"SYMC"}
+ ListElement {name:"Teva Pharmaceutical Industries Ltd."; stockId:"TEVA"}
+ ListElement {name:"Urban Outfitters, Inc."; stockId:"URBN"}
+ ListElement {name:"VeriSign, Inc."; stockId:"VRSN"}
+ ListElement {name:"Vertex Pharmaceuticals"; stockId:"VRTX"}
+ ListElement {name:"Virgin Media, Inc."; stockId:"VMED"}
+ ListElement {name:"Vodafone Group, plc."; stockId:"VOD"}
+ ListElement {name:"Warner Chilcott, Ltd."; stockId:"WCRX"}
+ ListElement {name:"Whole Foods Market, Inc."; stockId:"WFM"}
+ ListElement {name:"Wynn Resorts Ltd."; stockId:"WYNN"}
+ ListElement {name:"Xilinx, Inc."; stockId:"XLNX"}
+ ListElement {name:"Yahoo! Inc."; stockId:"YHOO"}
+}
diff --git a/examples/demos/stockchart/contents/TitleBar.qml b/examples/demos/stockchart/contents/TitleBar.qml
new file mode 100644
index 0000000000..28edda2ae7
--- /dev/null
+++ b/examples/demos/stockchart/contents/TitleBar.qml
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ id: titleBar
+ property string title: ""
+
+ BorderImage { source: "images/titlebar.sci"; width: parent.width; height: parent.height + 14; y: -7 }
+
+ Image {
+ id: quitButton
+ anchors.left: parent.left//; anchors.leftMargin: 0
+ anchors.verticalCenter: parent.verticalCenter
+ source: "images/quit.png"
+ MouseArea {
+ anchors.fill: parent
+ onClicked: Qt.quit()
+ }
+ }
+
+ Text {
+ id: categoryText
+ anchors {
+ left: quitButton.right; right: parent.right; //leftMargin: 10; rightMargin: 10
+ verticalCenter: parent.verticalCenter
+ }
+ elide: Text.ElideLeft
+ text: title
+ font.bold: true; font.pointSize: 20; color: "White"; style: Text.Raised; styleColor: "Black"
+ }
+}
diff --git a/examples/demos/stockchart/contents/ToolBar.qml b/examples/demos/stockchart/contents/ToolBar.qml
new file mode 100644
index 0000000000..7ae7391ddf
--- /dev/null
+++ b/examples/demos/stockchart/contents/ToolBar.qml
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ id: toolbar
+
+ property variant labels
+ signal buttonClicked(int index)
+
+ BorderImage {
+ source: "images/titlebar.sci"
+ width: parent.width
+ height: parent.height + 14
+ y: -7
+ }
+
+ Row {
+ y: 3
+ anchors.horizontalCenter: parent.horizontalCenter
+ Repeater {
+ model: toolbar.labels
+ delegate:
+ Button {
+ text: modelData
+ onClicked: toolbar.buttonClicked(model.index)
+ }
+ }
+ }
+
+}
diff --git a/examples/demos/stockchart/contents/images/quit.png b/examples/demos/stockchart/contents/images/quit.png
new file mode 100755
index 0000000000..5bda1b6e0d
--- /dev/null
+++ b/examples/demos/stockchart/contents/images/quit.png
Binary files differ
diff --git a/examples/demos/stockchart/contents/images/stripes.png b/examples/demos/stockchart/contents/images/stripes.png
new file mode 100755
index 0000000000..9f36727ea4
--- /dev/null
+++ b/examples/demos/stockchart/contents/images/stripes.png
Binary files differ
diff --git a/examples/demos/stockchart/stock.qml b/examples/demos/stockchart/stock.qml
index 1c95fde2ce..819625c808 100644
--- a/examples/demos/stockchart/stock.qml
+++ b/examples/demos/stockchart/stock.qml
@@ -39,7 +39,7 @@
****************************************************************************/
import QtQuick 2.0
import com.nokia.StockChartExample 1.0
-import "../contents"
+import "./contents"
Rectangle {
id:container
diff --git a/modules/qt_quickparticles.pri b/modules/qt_quickparticles.pri
new file mode 100644
index 0000000000..ae1064aca8
--- /dev/null
+++ b/modules/qt_quickparticles.pri
@@ -0,0 +1,17 @@
+QT.quickparticles.VERSION = 5.0.0
+QT.quickparticles.MAJOR_VERSION = 5
+QT.quickparticles.MINOR_VERSION = 0
+QT.quickparticles.PATCH_VERSION = 0
+
+QT.quickparticles.name = QtQuickParticles
+QT.quickparticles.bins = $$QT_MODULE_BIN_BASE
+QT.quickparticles.includes = $$QT_MODULE_INCLUDE_BASE $$QT_MODULE_INCLUDE_BASE/QtQuickParticles
+QT.quickparticles.private_includes = $$QT_MODULE_INCLUDE_BASE/QtQuickParticles/$$QT.quickparticles.VERSION
+QT.quickparticles.sources = $$QT_MODULE_BASE/src/particles
+QT.quickparticles.libs = $$QT_MODULE_LIB_BASE
+QT.quickparticles.plugins = $$QT_MODULE_PLUGIN_BASE
+QT.quickparticles.imports = $$QT_MODULE_IMPORT_BASE
+QT.quickparticles.depends = qml quick
+QT.quickparticles.DEFINES = QT_QUICKPARTICLES_LIB
+
+QT_CONFIG += quickparticles
diff --git a/src/imports/particles/particles.pro b/src/imports/particles/particles.pro
index dc3198d124..a9d0ece448 100644
--- a/src/imports/particles/particles.pro
+++ b/src/imports/particles/particles.pro
@@ -5,7 +5,7 @@ include(../qimportbase.pri)
SOURCES += \
plugin.cpp
-QT += quick-private qml-private
+QT += quick-private quickparticles-private qml-private
OTHER_FILES += \
qmldir
diff --git a/src/quick/particles/particleresources/noise.png b/src/particles/particleresources/noise.png
index 3c723e1a5a..3c723e1a5a 100644
--- a/src/quick/particles/particleresources/noise.png
+++ b/src/particles/particleresources/noise.png
Binary files differ
diff --git a/src/quick/particles/particles.pri b/src/particles/particles.pri
index 3a40a3b911..3e083ab291 100644
--- a/src/quick/particles/particles.pri
+++ b/src/particles/particles.pri
@@ -28,7 +28,8 @@ HEADERS += \
$$PWD/qquickv8particledata_p.h \
$$PWD/qquickrectangleextruder_p.h \
$$PWD/qquickparticlegroup_p.h \
- $$PWD/qquickgroupgoal_p.h
+ $$PWD/qquickgroupgoal_p.h \
+ $$PWD/qtquickparticlesglobal_p.h
SOURCES += \
$$PWD/qquickangledirection.cpp \
diff --git a/src/particles/particles.pro b/src/particles/particles.pro
new file mode 100644
index 0000000000..3aff6bbcc0
--- /dev/null
+++ b/src/particles/particles.pro
@@ -0,0 +1,40 @@
+load(qt_module)
+
+TARGET = QtQuickParticles
+
+CONFIG += module
+CONFIG += dll warn_on
+MODULE_PRI = ../../modules/qt_quickparticles.pri
+
+QT = core-private gui-private v8-private qml-private quick-private
+
+DEFINES += QT_BUILD_QUICKPARTICLES_LIB QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES
+win32-msvc*:DEFINES *= _CRT_SECURE_NO_WARNINGS
+solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2
+
+exists("qqml_enable_gcov") {
+ QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage -fno-elide-constructors
+ LIBS += -lgcov
+}
+
+MODULE = quickparticles
+load(qt_module_config)
+
+include(particles.pri)
+
+mac {
+ # FIXME: this is a workaround for broken qmake logic in qtAddModule()
+ # This function refuses to use frameworks unless the framework exists on
+ # the filesystem at the time qmake is run, resulting in a build failure
+ # if QtQuick is qmaked before QtQml is built and frameworks are
+ # in use. qtAddLibrary() contains correct logic to deal with this, so
+ # we'll explicitly call that for now.
+ load(qt)
+ LIBS -= -lQtQml # in non-framework builds, these should be re-added
+ LIBS -= -lQtQml_debug # within the qtAddLibrary if appropriate, so no
+ qtAddLibrary(QtQml) # harm done :)
+ LIBS -= -lQtQuick
+ LIBS -= -lQtQuick_debug
+ qtAddLibrary(QtQuick)
+}
+
diff --git a/src/quick/particles/particles.qrc b/src/particles/particles.qrc
index 344f9489a4..344f9489a4 100644
--- a/src/quick/particles/particles.qrc
+++ b/src/particles/particles.qrc
diff --git a/src/quick/particles/qquickage.cpp b/src/particles/qquickage.cpp
index 9f24cba3cc..9f24cba3cc 100644
--- a/src/quick/particles/qquickage.cpp
+++ b/src/particles/qquickage.cpp
diff --git a/src/quick/particles/qquickage_p.h b/src/particles/qquickage_p.h
index 2ec8faae4b..2ec8faae4b 100644
--- a/src/quick/particles/qquickage_p.h
+++ b/src/particles/qquickage_p.h
diff --git a/src/quick/particles/qquickangledirection.cpp b/src/particles/qquickangledirection.cpp
index e77c47362c..e77c47362c 100644
--- a/src/quick/particles/qquickangledirection.cpp
+++ b/src/particles/qquickangledirection.cpp
diff --git a/src/quick/particles/qquickangledirection_p.h b/src/particles/qquickangledirection_p.h
index 84633cd40e..84633cd40e 100644
--- a/src/quick/particles/qquickangledirection_p.h
+++ b/src/particles/qquickangledirection_p.h
diff --git a/src/quick/particles/qquickcumulativedirection.cpp b/src/particles/qquickcumulativedirection.cpp
index d7c4094297..d7c4094297 100644
--- a/src/quick/particles/qquickcumulativedirection.cpp
+++ b/src/particles/qquickcumulativedirection.cpp
diff --git a/src/quick/particles/qquickcumulativedirection_p.h b/src/particles/qquickcumulativedirection_p.h
index e1675a18d8..e1675a18d8 100644
--- a/src/quick/particles/qquickcumulativedirection_p.h
+++ b/src/particles/qquickcumulativedirection_p.h
diff --git a/src/quick/particles/qquickcustomaffector.cpp b/src/particles/qquickcustomaffector.cpp
index acec98192d..acec98192d 100644
--- a/src/quick/particles/qquickcustomaffector.cpp
+++ b/src/particles/qquickcustomaffector.cpp
diff --git a/src/quick/particles/qquickcustomaffector_p.h b/src/particles/qquickcustomaffector_p.h
index 1266830f94..1266830f94 100644
--- a/src/quick/particles/qquickcustomaffector_p.h
+++ b/src/particles/qquickcustomaffector_p.h
diff --git a/src/quick/particles/qquickcustomparticle.cpp b/src/particles/qquickcustomparticle.cpp
index 7d27e48c6b..7d27e48c6b 100644
--- a/src/quick/particles/qquickcustomparticle.cpp
+++ b/src/particles/qquickcustomparticle.cpp
diff --git a/src/quick/particles/qquickcustomparticle_p.h b/src/particles/qquickcustomparticle_p.h
index f689091268..f689091268 100644
--- a/src/quick/particles/qquickcustomparticle_p.h
+++ b/src/particles/qquickcustomparticle_p.h
diff --git a/src/quick/particles/qquickdirection.cpp b/src/particles/qquickdirection.cpp
index 4127d06be0..4127d06be0 100644
--- a/src/quick/particles/qquickdirection.cpp
+++ b/src/particles/qquickdirection.cpp
diff --git a/src/quick/particles/qquickdirection_p.h b/src/particles/qquickdirection_p.h
index 651865a1f5..651865a1f5 100644
--- a/src/quick/particles/qquickdirection_p.h
+++ b/src/particles/qquickdirection_p.h
diff --git a/src/quick/particles/qquickellipseextruder.cpp b/src/particles/qquickellipseextruder.cpp
index 083564e5cb..083564e5cb 100644
--- a/src/quick/particles/qquickellipseextruder.cpp
+++ b/src/particles/qquickellipseextruder.cpp
diff --git a/src/quick/particles/qquickellipseextruder_p.h b/src/particles/qquickellipseextruder_p.h
index c2d0c634ab..c2d0c634ab 100644
--- a/src/quick/particles/qquickellipseextruder_p.h
+++ b/src/particles/qquickellipseextruder_p.h
diff --git a/src/quick/particles/qquickfriction.cpp b/src/particles/qquickfriction.cpp
index d37d109f48..d37d109f48 100644
--- a/src/quick/particles/qquickfriction.cpp
+++ b/src/particles/qquickfriction.cpp
diff --git a/src/quick/particles/qquickfriction_p.h b/src/particles/qquickfriction_p.h
index 3b06710529..3b06710529 100644
--- a/src/quick/particles/qquickfriction_p.h
+++ b/src/particles/qquickfriction_p.h
diff --git a/src/quick/particles/qquickgravity.cpp b/src/particles/qquickgravity.cpp
index cf4f35eb72..cf4f35eb72 100644
--- a/src/quick/particles/qquickgravity.cpp
+++ b/src/particles/qquickgravity.cpp
diff --git a/src/quick/particles/qquickgravity_p.h b/src/particles/qquickgravity_p.h
index a738fd3ef3..a738fd3ef3 100644
--- a/src/quick/particles/qquickgravity_p.h
+++ b/src/particles/qquickgravity_p.h
diff --git a/src/quick/particles/qquickgroupgoal.cpp b/src/particles/qquickgroupgoal.cpp
index 0d7f15a9e1..0d7f15a9e1 100644
--- a/src/quick/particles/qquickgroupgoal.cpp
+++ b/src/particles/qquickgroupgoal.cpp
diff --git a/src/quick/particles/qquickgroupgoal_p.h b/src/particles/qquickgroupgoal_p.h
index f553badbd6..f553badbd6 100644
--- a/src/quick/particles/qquickgroupgoal_p.h
+++ b/src/particles/qquickgroupgoal_p.h
diff --git a/src/quick/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp
index d9eb6ed01b..d9eb6ed01b 100644
--- a/src/quick/particles/qquickimageparticle.cpp
+++ b/src/particles/qquickimageparticle.cpp
diff --git a/src/quick/particles/qquickimageparticle_p.h b/src/particles/qquickimageparticle_p.h
index 4db2c9801a..4db2c9801a 100644
--- a/src/quick/particles/qquickimageparticle_p.h
+++ b/src/particles/qquickimageparticle_p.h
diff --git a/src/quick/particles/qquickitemparticle.cpp b/src/particles/qquickitemparticle.cpp
index 91ef06fcb2..91ef06fcb2 100644
--- a/src/quick/particles/qquickitemparticle.cpp
+++ b/src/particles/qquickitemparticle.cpp
diff --git a/src/quick/particles/qquickitemparticle_p.h b/src/particles/qquickitemparticle_p.h
index c7b8a2661e..c7b8a2661e 100644
--- a/src/quick/particles/qquickitemparticle_p.h
+++ b/src/particles/qquickitemparticle_p.h
diff --git a/src/quick/particles/qquicklineextruder.cpp b/src/particles/qquicklineextruder.cpp
index f555de3f72..f555de3f72 100644
--- a/src/quick/particles/qquicklineextruder.cpp
+++ b/src/particles/qquicklineextruder.cpp
diff --git a/src/quick/particles/qquicklineextruder_p.h b/src/particles/qquicklineextruder_p.h
index 6f2b2493a6..6f2b2493a6 100644
--- a/src/quick/particles/qquicklineextruder_p.h
+++ b/src/particles/qquicklineextruder_p.h
diff --git a/src/quick/particles/qquickmaskextruder.cpp b/src/particles/qquickmaskextruder.cpp
index 50b71749c0..50b71749c0 100644
--- a/src/quick/particles/qquickmaskextruder.cpp
+++ b/src/particles/qquickmaskextruder.cpp
diff --git a/src/quick/particles/qquickmaskextruder_p.h b/src/particles/qquickmaskextruder_p.h
index 8b6c3f0b2d..8b6c3f0b2d 100644
--- a/src/quick/particles/qquickmaskextruder_p.h
+++ b/src/particles/qquickmaskextruder_p.h
diff --git a/src/quick/particles/qquickparticleaffector.cpp b/src/particles/qquickparticleaffector.cpp
index 0005af86af..0005af86af 100644
--- a/src/quick/particles/qquickparticleaffector.cpp
+++ b/src/particles/qquickparticleaffector.cpp
diff --git a/src/quick/particles/qquickparticleaffector_p.h b/src/particles/qquickparticleaffector_p.h
index 4147488f87..4147488f87 100644
--- a/src/quick/particles/qquickparticleaffector_p.h
+++ b/src/particles/qquickparticleaffector_p.h
diff --git a/src/quick/particles/qquickparticleemitter.cpp b/src/particles/qquickparticleemitter.cpp
index 035d66cbcd..035d66cbcd 100644
--- a/src/quick/particles/qquickparticleemitter.cpp
+++ b/src/particles/qquickparticleemitter.cpp
diff --git a/src/quick/particles/qquickparticleemitter_p.h b/src/particles/qquickparticleemitter_p.h
index eb9e1fd591..eb9e1fd591 100644
--- a/src/quick/particles/qquickparticleemitter_p.h
+++ b/src/particles/qquickparticleemitter_p.h
diff --git a/src/quick/particles/qquickparticleextruder.cpp b/src/particles/qquickparticleextruder.cpp
index 279f7c05f3..279f7c05f3 100644
--- a/src/quick/particles/qquickparticleextruder.cpp
+++ b/src/particles/qquickparticleextruder.cpp
diff --git a/src/quick/particles/qquickparticleextruder_p.h b/src/particles/qquickparticleextruder_p.h
index e24950e4e8..e24950e4e8 100644
--- a/src/quick/particles/qquickparticleextruder_p.h
+++ b/src/particles/qquickparticleextruder_p.h
diff --git a/src/quick/particles/qquickparticlegroup.cpp b/src/particles/qquickparticlegroup.cpp
index 9a165074a1..9a165074a1 100644
--- a/src/quick/particles/qquickparticlegroup.cpp
+++ b/src/particles/qquickparticlegroup.cpp
diff --git a/src/quick/particles/qquickparticlegroup_p.h b/src/particles/qquickparticlegroup_p.h
index 8889187558..8889187558 100644
--- a/src/quick/particles/qquickparticlegroup_p.h
+++ b/src/particles/qquickparticlegroup_p.h
diff --git a/src/quick/particles/qquickparticlepainter.cpp b/src/particles/qquickparticlepainter.cpp
index e490b70240..e490b70240 100644
--- a/src/quick/particles/qquickparticlepainter.cpp
+++ b/src/particles/qquickparticlepainter.cpp
diff --git a/src/quick/particles/qquickparticlepainter_p.h b/src/particles/qquickparticlepainter_p.h
index 1ae4625856..1ae4625856 100644
--- a/src/quick/particles/qquickparticlepainter_p.h
+++ b/src/particles/qquickparticlepainter_p.h
diff --git a/src/quick/particles/qquickparticlesmodule.cpp b/src/particles/qquickparticlesmodule.cpp
index e83cde3cd1..e83cde3cd1 100644
--- a/src/quick/particles/qquickparticlesmodule.cpp
+++ b/src/particles/qquickparticlesmodule.cpp
diff --git a/src/quick/particles/qquickparticlesmodule_p.h b/src/particles/qquickparticlesmodule_p.h
index 23a40488cf..87e99fa6bb 100644
--- a/src/quick/particles/qquickparticlesmodule_p.h
+++ b/src/particles/qquickparticlesmodule_p.h
@@ -42,13 +42,13 @@
#ifndef QQUICKPARTICLESMODULE_H
#define QQUICKPARTICLESMODULE_H
-#include <private/qtquickglobal_p.h>
+#include <private/qtquickparticlesglobal_p.h>
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-class Q_QUICK_PRIVATE_EXPORT QQuickParticlesModule
+class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticlesModule
{
public:
static void defineModule();
diff --git a/src/quick/particles/qquickparticlesystem.cpp b/src/particles/qquickparticlesystem.cpp
index 4fd6108f2f..4fd6108f2f 100644
--- a/src/quick/particles/qquickparticlesystem.cpp
+++ b/src/particles/qquickparticlesystem.cpp
diff --git a/src/quick/particles/qquickparticlesystem_p.h b/src/particles/qquickparticlesystem_p.h
index f70cc5af94..f70cc5af94 100644
--- a/src/quick/particles/qquickparticlesystem_p.h
+++ b/src/particles/qquickparticlesystem_p.h
diff --git a/src/quick/particles/qquickpointattractor.cpp b/src/particles/qquickpointattractor.cpp
index a54ee41c1e..a54ee41c1e 100644
--- a/src/quick/particles/qquickpointattractor.cpp
+++ b/src/particles/qquickpointattractor.cpp
diff --git a/src/quick/particles/qquickpointattractor_p.h b/src/particles/qquickpointattractor_p.h
index 85b7a9aa30..85b7a9aa30 100644
--- a/src/quick/particles/qquickpointattractor_p.h
+++ b/src/particles/qquickpointattractor_p.h
diff --git a/src/quick/particles/qquickpointdirection.cpp b/src/particles/qquickpointdirection.cpp
index e35eb4854c..e35eb4854c 100644
--- a/src/quick/particles/qquickpointdirection.cpp
+++ b/src/particles/qquickpointdirection.cpp
diff --git a/src/quick/particles/qquickpointdirection_p.h b/src/particles/qquickpointdirection_p.h
index 7b18e6d8d7..7b18e6d8d7 100644
--- a/src/quick/particles/qquickpointdirection_p.h
+++ b/src/particles/qquickpointdirection_p.h
diff --git a/src/quick/particles/qquickrectangleextruder.cpp b/src/particles/qquickrectangleextruder.cpp
index ad2207ca9a..ad2207ca9a 100644
--- a/src/quick/particles/qquickrectangleextruder.cpp
+++ b/src/particles/qquickrectangleextruder.cpp
diff --git a/src/quick/particles/qquickrectangleextruder_p.h b/src/particles/qquickrectangleextruder_p.h
index 1d4f8cc439..1d4f8cc439 100644
--- a/src/quick/particles/qquickrectangleextruder_p.h
+++ b/src/particles/qquickrectangleextruder_p.h
diff --git a/src/quick/particles/qquickspritegoal.cpp b/src/particles/qquickspritegoal.cpp
index 95d913cafa..95d913cafa 100644
--- a/src/quick/particles/qquickspritegoal.cpp
+++ b/src/particles/qquickspritegoal.cpp
diff --git a/src/quick/particles/qquickspritegoal_p.h b/src/particles/qquickspritegoal_p.h
index 2b6b4f28fc..2b6b4f28fc 100644
--- a/src/quick/particles/qquickspritegoal_p.h
+++ b/src/particles/qquickspritegoal_p.h
diff --git a/src/quick/particles/qquicktargetdirection.cpp b/src/particles/qquicktargetdirection.cpp
index 695684dfde..695684dfde 100644
--- a/src/quick/particles/qquicktargetdirection.cpp
+++ b/src/particles/qquicktargetdirection.cpp
diff --git a/src/quick/particles/qquicktargetdirection_p.h b/src/particles/qquicktargetdirection_p.h
index 0e0e942ca8..0e0e942ca8 100644
--- a/src/quick/particles/qquicktargetdirection_p.h
+++ b/src/particles/qquicktargetdirection_p.h
diff --git a/src/quick/particles/qquicktrailemitter.cpp b/src/particles/qquicktrailemitter.cpp
index 32f8763599..32f8763599 100644
--- a/src/quick/particles/qquicktrailemitter.cpp
+++ b/src/particles/qquicktrailemitter.cpp
diff --git a/src/quick/particles/qquicktrailemitter_p.h b/src/particles/qquicktrailemitter_p.h
index 0b63a444ec..0b63a444ec 100644
--- a/src/quick/particles/qquicktrailemitter_p.h
+++ b/src/particles/qquicktrailemitter_p.h
diff --git a/src/quick/particles/qquickturbulence.cpp b/src/particles/qquickturbulence.cpp
index 18ecc6a4cd..18ecc6a4cd 100644
--- a/src/quick/particles/qquickturbulence.cpp
+++ b/src/particles/qquickturbulence.cpp
diff --git a/src/quick/particles/qquickturbulence_p.h b/src/particles/qquickturbulence_p.h
index cd5535c387..cd5535c387 100644
--- a/src/quick/particles/qquickturbulence_p.h
+++ b/src/particles/qquickturbulence_p.h
diff --git a/src/quick/particles/qquickv8particledata.cpp b/src/particles/qquickv8particledata.cpp
index 8e50e41091..8e50e41091 100644
--- a/src/quick/particles/qquickv8particledata.cpp
+++ b/src/particles/qquickv8particledata.cpp
diff --git a/src/quick/particles/qquickv8particledata_p.h b/src/particles/qquickv8particledata_p.h
index 21ec6458c1..21ec6458c1 100644
--- a/src/quick/particles/qquickv8particledata_p.h
+++ b/src/particles/qquickv8particledata_p.h
diff --git a/src/quick/particles/qquickwander.cpp b/src/particles/qquickwander.cpp
index 0f9a5f069b..0f9a5f069b 100644
--- a/src/quick/particles/qquickwander.cpp
+++ b/src/particles/qquickwander.cpp
diff --git a/src/quick/particles/qquickwander_p.h b/src/particles/qquickwander_p.h
index bb418f7912..bb418f7912 100644
--- a/src/quick/particles/qquickwander_p.h
+++ b/src/particles/qquickwander_p.h
diff --git a/src/particles/qtquickparticlesglobal_p.h b/src/particles/qtquickparticlesglobal_p.h
new file mode 100644
index 0000000000..d7814f759d
--- /dev/null
+++ b/src/particles/qtquickparticlesglobal_p.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtQuickParticles module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this 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 QTQUICKPARTICLESGLOBAL_P_H
+#define QTQUICKPARTICLESGLOBAL_P_H
+
+#include <QtCore/qglobal.h>
+
+// We only have private exports from this library
+
+#if defined(Q_OS_WIN)
+# if defined(QT_MAKEDLL) /* create a Qt DLL library */
+# if defined(QT_BUILD_QUICKPARTICLES_LIB)
+# define Q_QUICKPARTICLES_PRIVATE_EXPORT Q_DECL_EXPORT
+# else
+# define Q_QUICKPARTICLES_PRIVATE_EXPORT Q_DECL_IMPORT
+# endif
+# elif defined(QT_DLL) /* use a Qt DLL library */
+# define Q_QUICKPARTICLES_PRIVATE_EXPORT Q_DECL_IMPORT
+# endif
+#endif
+
+#if !defined(Q_QUICKPARTICLES_PRIVATE_EXPORT)
+# if defined(QT_SHARED)
+# define Q_QUICKPARTICLES_PRIVATE_EXPORT Q_DECL_EXPORT
+# else
+# define Q_QUICKPARTICLES_PRIVATE_EXPORT
+# endif
+#endif
+
+#endif // QTQUICKPARTICLESGLOBAL_P_H
diff --git a/src/plugins/qmltooling/qmldbg_qtquick2/highlight.cpp b/src/plugins/qmltooling/qmldbg_qtquick2/highlight.cpp
index da959933f7..d014dd4e0d 100644
--- a/src/plugins/qmltooling/qmldbg_qtquick2/highlight.cpp
+++ b/src/plugins/qmltooling/qmldbg_qtquick2/highlight.cpp
@@ -42,6 +42,7 @@
#include "highlight.h"
#include <QtGui/QPainter>
+#include <QtQuick/QQuickCanvas>
namespace QmlJSDebugger {
namespace QtQuick2 {
@@ -55,7 +56,7 @@ Highlight::Highlight(QQuickItem *item, QQuickItem *parent)
void Highlight::setItem(QQuickItem *item)
{
if (m_item)
- m_item.data()->disconnect(this);
+ m_item->disconnect(this);
if (item) {
connect(item, SIGNAL(xChanged()), SLOT(adjust()));
@@ -66,34 +67,81 @@ void Highlight::setItem(QQuickItem *item)
connect(item, SIGNAL(transformOriginChanged(TransformOrigin)),
SLOT(adjust()));
}
-
+ QQuickCanvas *view = item->canvas();
+ QQuickItem * rootItem = view->rootItem();
+ if (rootItem) {
+ connect(rootItem, SIGNAL(xChanged()), SLOT(adjust()));
+ connect(rootItem, SIGNAL(yChanged()), SLOT(adjust()));
+ connect(rootItem, SIGNAL(widthChanged()), SLOT(adjust()));
+ connect(rootItem, SIGNAL(heightChanged()), SLOT(adjust()));
+ connect(rootItem, SIGNAL(rotationChanged()), SLOT(adjust()));
+ connect(rootItem, SIGNAL(transformOriginChanged(TransformOrigin)),
+ SLOT(adjust()));
+ }
m_item = item;
adjust();
}
void Highlight::adjust()
{
- const QQuickItem *item = m_item.data();
- setSize(QSizeF(item->width(), item->height()));
- setPos(parentItem()->mapFromItem(item->parentItem(), item->pos()));
- setRotation(item->rotation());
- setTransformOrigin(item->transformOrigin());
+ if (!m_item)
+ return;
+
+ bool success = false;
+ m_transform = m_item->itemTransform(0, &success);
+ if (!success)
+ m_transform = QTransform();
+
+ setSize(QSizeF(m_item->width(), m_item->height()));
+ qreal scaleFactor = 1;
+ QPointF originOffset = QPointF(0,0);
+ QQuickCanvas *view = m_item->canvas();
+ if (view->rootItem()) {
+ scaleFactor = view->rootItem()->scale();
+ originOffset -= view->rootItem()->pos();
+ }
+ // The scale transform for the overlay needs to be cancelled
+ // as the Item's transform which will be applied to the painter
+ // takes care of it.
+ parentItem()->setScale(1/scaleFactor);
+ setPos(originOffset);
+ setContentsSize(view->size());
+ update();
}
void HoverHighlight::paint(QPainter *painter)
{
+ if (!item())
+ return;
+
+ painter->save();
+ painter->setTransform(transform());
painter->setPen(QColor(108, 141, 221));
- painter->drawRect(QRect(0, 0, width() - 1, height() - 1));
+ painter->drawRect(QRect(0, 0, item()->width() - 1, item()->height() - 1));
+ painter->restore();
}
void SelectionHighlight::paint(QPainter *painter)
{
+ if (!item())
+ return;
+
+ painter->save();
+ painter->setTransform(transform());
+ if (item()->height() >= 10 && item()->width() >= 10) {
+ QColor colorHighlight = Qt::green;
+ painter->fillRect(QRectF(0, 0, item()->width(), 5), colorHighlight);
+ painter->fillRect(QRectF(0, item()->height()-5, item()->width(), 5), colorHighlight);
+ painter->fillRect(QRectF(0, 5, 5, item()->height() - 10), colorHighlight);
+ painter->fillRect(QRectF(item()->width()-5, 5, 5, item()->height() - 10), colorHighlight);
+ }
painter->setPen(QPen(QColor(0, 22, 159)));
- painter->drawRect(QRect(1, 1, width() - 3, height() - 3));
+ painter->drawRect(QRect(1, 1, item()->width() - 3, item()->height() - 3));
painter->setPen(QColor(158, 199, 255));
- painter->drawRect(QRect(0, 0, width() - 1, height() - 1));
+ painter->drawRect(QRect(0, 0, item()->width() - 1, item()->height() - 1));
+ painter->restore();
}
} // namespace QtQuick2
diff --git a/src/plugins/qmltooling/qmldbg_qtquick2/highlight.h b/src/plugins/qmltooling/qmldbg_qtquick2/highlight.h
index 1b1f10c8bb..3dbd109934 100644
--- a/src/plugins/qmltooling/qmldbg_qtquick2/highlight.h
+++ b/src/plugins/qmltooling/qmldbg_qtquick2/highlight.h
@@ -42,9 +42,11 @@
#ifndef HIGHLIGHT_H
#define HIGHLIGHT_H
-#include <QtCore/QWeakPointer>
+#include <QtCore/QPointer>
+#include <QtGui/QTransform>
#include <QtQuick/QQuickPaintedItem>
+
namespace QmlJSDebugger {
namespace QtQuick2 {
@@ -57,12 +59,17 @@ public:
Highlight(QQuickItem *item, QQuickItem *parent);
void setItem(QQuickItem *item);
+ QQuickItem *item() {return m_item;}
+
+protected:
+ QTransform transform() {return m_transform;}
private slots:
void adjust();
private:
- QWeakPointer<QQuickItem> m_item;
+ QPointer<QQuickItem> m_item;
+ QTransform m_transform;
};
/**
diff --git a/src/plugins/qmltooling/qmldbg_qtquick2/inspecttool.cpp b/src/plugins/qmltooling/qmldbg_qtquick2/inspecttool.cpp
index 67b12822be..796549f237 100644
--- a/src/plugins/qmltooling/qmldbg_qtquick2/inspecttool.cpp
+++ b/src/plugins/qmltooling/qmldbg_qtquick2/inspecttool.cpp
@@ -68,7 +68,6 @@ InspectTool::InspectTool(QQuickViewInspector *inspector, QQuickView *view) :
m_tapEvent(false),
m_rootItem(view->rootItem()),
m_originalPosition(view->rootItem()->pos()),
- m_currentScale(1.0f),
m_smoothScaleFactor(Constants::ZoomSnapDelta),
m_minScale(0.125f),
m_maxScale(48.0f),
@@ -128,16 +127,20 @@ void InspectTool::mouseReleaseEvent(QMouseEvent *event)
{
m_mousePosition = event->posF();
m_pressAndHoldTimer.stop();
- if (event->button() == Qt::LeftButton)
+ if (event->button() == Qt::LeftButton && !m_dragStarted) {
selectItem();
+ m_hoverHighlight->setVisible(false);
+ }
}
void InspectTool::mouseDoubleClickEvent(QMouseEvent *event)
{
m_mousePosition = event->posF();
m_pressAndHoldTimer.stop();
- if (event->button() == Qt::LeftButton)
+ if (event->button() == Qt::LeftButton) {
selectNextItem();
+ m_hoverHighlight->setVisible(false);
+ }
}
void InspectTool::mouseMoveEvent(QMouseEvent *event)
@@ -167,8 +170,8 @@ void InspectTool::wheelEvent(QWheelEvent *event)
Qt::KeyboardModifier smoothZoomModifier = Qt::ControlModifier;
if (event->modifiers() & smoothZoomModifier) {
int numDegrees = event->delta() / 8;
- qreal newScale = m_currentScale + m_smoothScaleFactor * (numDegrees / 15.0f);
- scaleView(newScale / m_currentScale, m_mousePosition, m_mousePosition);
+ qreal newScale = m_rootItem->scale() + m_smoothScaleFactor * (numDegrees / 15.0f);
+ scaleView(newScale / m_rootItem->scale(), m_mousePosition, m_mousePosition);
} else if (!event->modifiers()) {
if (event->delta() > 0) {
zoomIn();
@@ -197,7 +200,7 @@ void InspectTool::keyReleaseEvent(QKeyEvent *event)
case Qt::Key_8:
case Qt::Key_9: {
qreal newScale = ((event->key() - Qt::Key_0) * 1.0f);
- scaleView(newScale / m_currentScale, m_mousePosition, m_mousePosition);
+ scaleView(newScale / m_rootItem->scale(), m_mousePosition, m_mousePosition);
break;
}
default:
@@ -273,38 +276,34 @@ void InspectTool::touchEvent(QTouchEvent *event)
void InspectTool::scaleView(const qreal &factor, const QPointF &newcenter, const QPointF &oldcenter)
{
m_pressAndHoldTimer.stop();
- if (((m_currentScale * factor) > m_maxScale)
- || ((m_currentScale * factor) < m_minScale)) {
+ if (((m_rootItem->scale() * factor) > m_maxScale)
+ || ((m_rootItem->scale() * factor) < m_minScale)) {
return;
}
//New position = new center + scalefactor * (oldposition - oldcenter)
- m_adjustedOrigin = newcenter + (factor * (m_adjustedOrigin - oldcenter));
- m_currentScale *= factor;
-
- m_rootItem->setScale(m_currentScale);
- m_rootItem->setPos(m_adjustedOrigin);
+ QPointF newPosition = newcenter + (factor * (m_rootItem->pos() - oldcenter));
+ m_rootItem->setScale(m_rootItem->scale() * factor);
+ m_rootItem->setPos(newPosition);
}
void InspectTool::zoomIn()
{
qreal newScale = nextZoomScale(ZoomIn);
- scaleView(newScale / m_currentScale, m_mousePosition, m_mousePosition);
+ scaleView(newScale / m_rootItem->scale(), m_mousePosition, m_mousePosition);
}
void InspectTool::zoomOut()
{
qreal newScale = nextZoomScale(ZoomOut);
- scaleView(newScale / m_currentScale, m_mousePosition, m_mousePosition);
+ scaleView(newScale / m_rootItem->scale(), m_mousePosition, m_mousePosition);
}
void InspectTool::zoomTo100()
{
m_didPressAndHold = true;
- m_currentScale = 1.0;
- m_adjustedOrigin = QPointF(0, 0);
- m_rootItem->setPos(m_adjustedOrigin);
- m_rootItem->setScale(m_currentScale);
+ m_rootItem->setPos(QPointF(0, 0));
+ m_rootItem->setScale(1.0);
}
qreal InspectTool::nextZoomScale(ZoomDirection direction)
@@ -332,13 +331,13 @@ qreal InspectTool::nextZoomScale(ZoomDirection direction)
if (direction == ZoomIn) {
for (int i = 0; i < zoomScales.length(); ++i) {
- if (zoomScales[i] > m_currentScale)
+ if (zoomScales[i] > m_rootItem->scale())
return zoomScales[i];
}
return zoomScales.last();
} else {
for (int i = zoomScales.length() - 1; i >= 0; --i) {
- if (zoomScales[i] < m_currentScale)
+ if (zoomScales[i] < m_rootItem->scale())
return zoomScales[i];
}
return zoomScales.first();
@@ -355,9 +354,9 @@ void InspectTool::initializeDrag(const QPointF &pos)
void InspectTool::dragItemToPosition()
{
- m_adjustedOrigin += m_mousePosition - m_dragStartPosition;
+ QPointF newPosition = m_rootItem->pos() + m_mousePosition - m_dragStartPosition;
m_dragStartPosition = m_mousePosition;
- m_rootItem->setPos(m_adjustedOrigin);
+ m_rootItem->setPos(newPosition);
}
void InspectTool::moveItem(bool valid)
diff --git a/src/plugins/qmltooling/qmldbg_qtquick2/inspecttool.h b/src/plugins/qmltooling/qmldbg_qtquick2/inspecttool.h
index 25d0c634b2..f452802f6a 100644
--- a/src/plugins/qmltooling/qmldbg_qtquick2/inspecttool.h
+++ b/src/plugins/qmltooling/qmldbg_qtquick2/inspecttool.h
@@ -108,11 +108,9 @@ private:
bool m_didPressAndHold;
bool m_tapEvent;
QPointer<QQuickItem> m_rootItem;
- QPointF m_adjustedOrigin;
QPointF m_dragStartPosition;
QPointF m_mousePosition;
QPointF m_originalPosition;
- qreal m_currentScale;
qreal m_smoothScaleFactor;
qreal m_minScale;
qreal m_maxScale;
diff --git a/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.cpp b/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.cpp
index 95ce86678c..f92fbb94c6 100644
--- a/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.cpp
+++ b/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.cpp
@@ -58,8 +58,8 @@ namespace QtQuick2 {
/*
* Collects all the items at the given position, from top to bottom.
*/
-static void collectItemsAt(QQuickItem *item, const QPointF &pos, QQuickItem *overlay,
- QList<QQuickItem *> &resultList)
+static void collectItemsAt(QQuickItem *item, const QPointF &pos,
+ QQuickItem *overlay, QList<QQuickItem *> &resultList)
{
if (item == overlay)
return;
@@ -85,7 +85,8 @@ static void collectItemsAt(QQuickItem *item, const QPointF &pos, QQuickItem *ove
* Returns the first visible item at the given position, or 0 when no such
* child exists.
*/
-static QQuickItem *itemAt(QQuickItem *item, const QPointF &pos, QQuickItem *overlay)
+static QQuickItem *itemAt(QQuickItem *item, const QPointF &pos,
+ QQuickItem *overlay)
{
if (item == overlay)
return 0;
@@ -101,7 +102,8 @@ static QQuickItem *itemAt(QQuickItem *item, const QPointF &pos, QQuickItem *over
QList<QQuickItem *> children = QQuickItemPrivate::get(item)->paintOrderChildItems();
for (int i = children.count() - 1; i >= 0; --i) {
QQuickItem *child = children.at(i);
- if (QQuickItem *betterCandidate = itemAt(child, item->mapToItem(child, pos), overlay))
+ if (QQuickItem *betterCandidate = itemAt(child, item->mapToItem(child, pos),
+ overlay))
return betterCandidate;
}
@@ -171,6 +173,8 @@ void QQuickViewInspector::changeTool(InspectorProtocol::Tool tool)
setCurrentTool(m_inspectTool);
emit inspectToolActivated();
break;
+ default:
+ break;
}
}
@@ -213,16 +217,17 @@ QList<QQuickItem *> QQuickViewInspector::itemsAt(const QPointF &pos) const
{
QQuickItem *root = m_view->rootItem();
QList<QQuickItem *> resultList;
- collectItemsAt(root, root->mapFromScene(pos), m_overlay, resultList);
+ collectItemsAt(root, root->mapFromScene(pos), m_overlay,
+ resultList);
return resultList;
}
QList<QQuickItem*> QQuickViewInspector::selectedItems() const
{
QList<QQuickItem *> selection;
- foreach (const QWeakPointer<QQuickItem> &selectedItem, m_selectedItems) {
+ foreach (const QPointer<QQuickItem> &selectedItem, m_selectedItems) {
if (selectedItem)
- selection << selectedItem.data();
+ selection << selectedItem;
}
return selection;
}
@@ -244,16 +249,16 @@ bool QQuickViewInspector::syncSelectedItems(const QList<QQuickItem *> &items)
bool selectionChanged = false;
// Disconnect and remove items that are no longer selected
- foreach (const QWeakPointer<QQuickItem> &item, m_selectedItems) {
+ foreach (const QPointer<QQuickItem> &item, m_selectedItems) {
if (!item) // Don't see how this can happen due to handling of destroyed()
continue;
- if (items.contains(item.data()))
+ if (items.contains(item))
continue;
selectionChanged = true;
- item.data()->disconnect(this);
+ item->disconnect(this);
m_selectedItems.removeOne(item);
- delete m_highlightItems.take(item.data());
+ delete m_highlightItems.take(item);
}
// Connect and add newly selected items
@@ -264,7 +269,9 @@ bool QQuickViewInspector::syncSelectedItems(const QList<QQuickItem *> &items)
selectionChanged = true;
connect(item, SIGNAL(destroyed(QObject*)), this, SLOT(removeFromSelectedItems(QObject*)));
m_selectedItems.append(item);
- m_highlightItems.insert(item, new SelectionHighlight(item, m_overlay));
+ SelectionHighlight *selectionHighlightItem;
+ selectionHighlightItem = new SelectionHighlight(item, m_overlay);
+ m_highlightItems.insert(item, selectionHighlightItem);
}
return selectionChanged;
diff --git a/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.h b/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.h
index 0fd2948279..bcc008cbac 100644
--- a/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.h
+++ b/src/plugins/qmltooling/qmldbg_qtquick2/qquickviewinspector.h
@@ -44,7 +44,7 @@
#include "abstractviewinspector.h"
-#include <QtCore/QWeakPointer>
+#include <QtCore/QPointer>
#include <QtCore/QHash>
QT_BEGIN_NAMESPACE
@@ -100,7 +100,7 @@ private:
InspectTool *m_inspectTool;
- QList<QWeakPointer<QQuickItem> > m_selectedItems;
+ QList<QPointer<QQuickItem> > m_selectedItems;
QHash<QQuickItem*, SelectionHighlight*> m_highlightItems;
bool m_designMode;
diff --git a/src/qml/animations/qabstractanimationjob.cpp b/src/qml/animations/qabstractanimationjob.cpp
index fecd8fbc5d..d1b8880087 100644
--- a/src/qml/animations/qabstractanimationjob.cpp
+++ b/src/qml/animations/qabstractanimationjob.cpp
@@ -567,7 +567,6 @@ void QAbstractAnimationJob::removeAnimationChangeListener(QAnimationJobChangeLis
changeListeners.removeOne(ChangeListener(listener, changes));
}
-
QT_END_NAMESPACE
//#include "moc_qabstractanimation2_p.cpp"
diff --git a/src/qml/animations/qabstractanimationjob_p.h b/src/qml/animations/qabstractanimationjob_p.h
index e7d96ddfce..d26aa868ce 100644
--- a/src/qml/animations/qabstractanimationjob_p.h
+++ b/src/qml/animations/qabstractanimationjob_p.h
@@ -113,7 +113,6 @@ public:
void addAnimationChangeListener(QAnimationJobChangeListener *listener, QAbstractAnimationJob::ChangeTypes);
void removeAnimationChangeListener(QAnimationJobChangeListener *listener, QAbstractAnimationJob::ChangeTypes);
-
QAbstractAnimationJob *nextSibling() const { return m_nextSibling; }
QAbstractAnimationJob *previousSibling() const { return m_previousSibling; }
diff --git a/src/qml/debugger/qv8debugservice.cpp b/src/qml/debugger/qv8debugservice.cpp
index 7d54a59ac0..f8831db6c6 100644
--- a/src/qml/debugger/qv8debugservice.cpp
+++ b/src/qml/debugger/qv8debugservice.cpp
@@ -67,7 +67,6 @@ const char *V8_DEBUGGER_KEY_DISCONNECT = "disconnect";
const char *V8_DEBUGGER_KEY_REQUEST = "v8request";
const char *V8_DEBUGGER_KEY_V8MESSAGE = "v8message";
const char *V8_DEBUGGER_KEY_BREAK_ON_SIGNAL = "breakonsignal";
-const char *V8_DEBUGGER_KEY_BREAK_AFTER_COMPILE = "breakaftercompile";
QT_BEGIN_NAMESPACE
@@ -92,10 +91,15 @@ void DebugMessageHandler(const v8::Debug::Message& message)
{
v8::DebugEvent event = message.GetEvent();
- if (event != v8::Break && event != v8::Exception &&
- event != v8::AfterCompile && event != v8::BeforeCompile)
+ if (message.IsEvent()) {
+ if (event == v8::AfterCompile || event == v8::BeforeCompile)
return;
- v8ServiceInstancePtr->debugMessageHandler(QJSConverter::toString(message.GetJSON()), event);
+ } else if (event != v8::Break && event != v8::Exception &&
+ event != v8::AfterCompile && event != v8::BeforeCompile) {
+ return;
+ }
+
+ v8ServiceInstancePtr->debugMessageHandler(QJSConverter::toString(message.GetJSON()));
}
class QV8DebugServicePrivate : public QQmlDebugServicePrivate
@@ -103,7 +107,6 @@ class QV8DebugServicePrivate : public QQmlDebugServicePrivate
public:
QV8DebugServicePrivate()
: connectReceived(false)
- , breakAfterCompile(false)
, engine(0)
{
}
@@ -113,7 +116,6 @@ public:
static QByteArray packMessage(const QString &type, const QString &message = QString());
bool connectReceived;
- bool breakAfterCompile;
QMutex initializeMutex;
QStringList breakOnSignals;
const QV8Engine *engine;
@@ -160,12 +162,9 @@ void QV8DebugService::setEngine(const QV8Engine *engine)
d->engine = engine;
}
-void QV8DebugService::debugMessageHandler(const QString &message, const v8::DebugEvent &event)
+void QV8DebugService::debugMessageHandler(const QString &message)
{
- Q_D(QV8DebugService);
sendMessage(QV8DebugServicePrivate::packMessage(QLatin1String(V8_DEBUGGER_KEY_V8MESSAGE), message));
- if (event == v8::AfterCompile && d->breakAfterCompile)
- scheduledDebugBreak(true);
}
void QV8DebugService::signalEmitted(const QString &signal)
@@ -262,11 +261,6 @@ void QV8DebugService::messageReceived(const QByteArray &message)
d->breakOnSignals.removeOne(signalName);
sendMessage(QV8DebugServicePrivate::packMessage(QLatin1String(V8_DEBUGGER_KEY_BREAK_ON_SIGNAL)));
- } else if (command == V8_DEBUGGER_KEY_BREAK_AFTER_COMPILE) {
- QDataStream rs(data);
- rs >> d->breakAfterCompile;
- sendMessage(QV8DebugServicePrivate::packMessage(QLatin1String(V8_DEBUGGER_KEY_BREAK_AFTER_COMPILE)));
-
}
}
}
diff --git a/src/qml/debugger/qv8debugservice_p.h b/src/qml/debugger/qv8debugservice_p.h
index 8ff4adc778..84b300cee4 100644
--- a/src/qml/debugger/qv8debugservice_p.h
+++ b/src/qml/debugger/qv8debugservice_p.h
@@ -74,7 +74,7 @@ public:
static QV8DebugService *instance();
static void initialize(const QV8Engine *engine);
- void debugMessageHandler(const QString &message, const v8::DebugEvent &event);
+ void debugMessageHandler(const QString &message);
void signalEmitted(const QString &signal);
diff --git a/src/qml/qml/ftw/qqmlpool.cpp b/src/qml/qml/ftw/qqmlpool.cpp
index 64df87ada5..2ff2cd054f 100644
--- a/src/qml/qml/ftw/qqmlpool.cpp
+++ b/src/qml/qml/ftw/qqmlpool.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qqmlpool_p.h"
+#include <stdlib.h>
#ifdef Q_OS_QNX
#include <malloc.h>
diff --git a/src/qml/qml/qqmllist.cpp b/src/qml/qml/qqmllist.cpp
index ad28e38a64..c3537dac9d 100644
--- a/src/qml/qml/qqmllist.cpp
+++ b/src/qml/qml/qqmllist.cpp
@@ -88,7 +88,7 @@ void QQmlListReferencePrivate::release()
/*!
\class QQmlListReference
\since 5.0
-\module QtQml
+\inmodule QtQml
\brief The QQmlListReference class allows the manipulation of QQmlListProperty properties.
QQmlListReference allows C++ programs to read from, and assign values to a QML list property in a
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index 4a4563ccd4..f15565c0a5 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -750,8 +750,8 @@ V8_DEFINE_EXTENSION(QV8LocaleDataDeletable, localeV8Data);
\inqmlmodule QtQuick 2
\brief The Locale object provides locale specific properties and formatted data.
- The Locale object is created via the \l{QML:Qt::locale()}{Qt.locale()} function. It cannot be created
- directly.
+ The Locale object may only be created via the \l{QML:Qt::locale()}{Qt.locale()} function.
+ It cannot be created directly.
The \l{QML:Qt::locale()}{Qt.locale()} function returns a JS Locale object representing the
locale with the specified name, which has the format
diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp
index 4c92598c32..e055cad4f2 100644
--- a/src/qml/qml/v4/qv4bindings.cpp
+++ b/src/qml/qml/v4/qv4bindings.cpp
@@ -94,11 +94,9 @@ struct Register {
inline QVariant *getvariantptr() { return (QVariant *)typeDataPtr(); }
inline QString *getstringptr() { return (QString *)typeDataPtr(); }
inline QUrl *geturlptr() { return (QUrl *)typeDataPtr(); }
- inline QColor *getcolorptr() { return (QColor *)typeDataPtr(); }
inline const QVariant *getvariantptr() const { return (QVariant *)typeDataPtr(); }
inline const QString *getstringptr() const { return (QString *)typeDataPtr(); }
inline const QUrl *geturlptr() const { return (QUrl *)typeDataPtr(); }
- inline const QColor *getcolorptr() const { return (QColor *)typeDataPtr(); }
size_t dataSize() { return sizeof(data); }
inline void *typeDataPtr() { return (void *)&data; }
@@ -458,7 +456,7 @@ static void testBindingResult(const QString &binding, int line, int column,
if (expression.hasError()) {
iserror = true;
qtscriptResult = "exception";
- } else if (value.userType() != resultType) {
+ } else if ((value.userType() != resultType) && (resultType != QMetaType::QVariant)) {
// Override the QMetaType conversions to make them more JS friendly.
if (value.userType() == QMetaType::Double && (resultType == QMetaType::QString ||
resultType == QMetaType::QUrl)) {
@@ -508,6 +506,12 @@ static void testBindingResult(const QString &binding, int line, int column,
case QMetaType::Double:
v4value = result.getnumber();
break;
+ case QMetaType::QColor:
+ v4value = QVariant(QMetaType::QColor, result.typeDataPtr());
+ break;
+ case QMetaType::QVariant:
+ v4value = *result.getvariantptr();
+ break;
default:
if (resultType == QQmlMetaType::QQuickAnchorLineMetaTypeId()) {
v4value = QVariant(QQmlMetaType::QQuickAnchorLineMetaTypeId(), result.typeDataPtr());
@@ -884,6 +888,19 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertBoolToString, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertBoolToVariant, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ new (output.getvariantptr()) QVariant(src.getbool());
+ VARIANT_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertBoolToVariant, unaryop)
+
QML_V4_BEGIN_INSTR(ConvertIntToBool, unaryop)
{
const Register &src = registers[instr->unaryop.src];
@@ -908,13 +925,26 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
Register &output = registers[instr->unaryop.output];
if (src.isUndefined()) {
output.setUndefined();
- } else {
+ } else {
new (output.getstringptr()) QString(QString::number(src.getint()));
STRING_REGISTER(instr->unaryop.output);
}
}
QML_V4_END_INSTR(ConvertIntToString, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertIntToVariant, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ new (output.getvariantptr()) QVariant(src.getint());
+ VARIANT_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertIntToVariant, unaryop)
+
QML_V4_BEGIN_INSTR(ConvertNumberToBool, unaryop)
{
const Register &src = registers[instr->unaryop.src];
@@ -947,6 +977,19 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertNumberToString, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertNumberToVariant, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ new (output.getvariantptr()) QVariant(src.getnumber());
+ VARIANT_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertNumberToVariant, unaryop)
+
QML_V4_BEGIN_INSTR(ConvertStringToBool, unaryop)
{
const Register &src = registers[instr->unaryop.src];
@@ -1049,6 +1092,25 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertStringToUrl, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertStringToVariant, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ const QString tmp(*src.getstringptr());
+ if (instr->unaryop.src == instr->unaryop.output) {
+ output.cleanupString();
+ MARK_CLEAN_REGISTER(instr->unaryop.output);
+ }
+ new (output.getvariantptr()) QVariant(tmp);
+
+ VARIANT_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertStringToVariant, unaryop)
+
QML_V4_BEGIN_INSTR(ConvertUrlToBool, unaryop)
{
const Register &src = registers[instr->unaryop.src];
@@ -1086,6 +1148,25 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertUrlToString, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertUrlToVariant, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ // ### NaN
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ const QUrl tmp(*src.geturlptr());
+ if (instr->unaryop.src == instr->unaryop.output) {
+ output.cleanupUrl();
+ MARK_CLEAN_REGISTER(instr->unaryop.output);
+ }
+ new (output.getvariantptr()) QVariant(tmp);
+ VARIANT_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertUrlToVariant, unaryop)
+
QML_V4_BEGIN_INSTR(ConvertColorToBool, unaryop)
{
const Register &src = registers[instr->unaryop.src];
@@ -1114,6 +1195,25 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertColorToString, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertColorToVariant, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ // ### NaN
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ QVariant tmp(QMetaType::QColor, src.typeDataPtr());
+ if (instr->unaryop.src == instr->unaryop.output) {
+ output.cleanupColor();
+ MARK_CLEAN_REGISTER(instr->unaryop.output);
+ }
+ new (output.getvariantptr()) QVariant(tmp);
+ VARIANT_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertColorToVariant, unaryop)
+
QML_V4_BEGIN_INSTR(ConvertObjectToBool, unaryop)
{
const Register &src = registers[instr->unaryop.src];
@@ -1126,6 +1226,20 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertObjectToBool, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertObjectToVariant, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ // ### NaN
+ if (src.isUndefined())
+ output.setUndefined();
+ else {
+ new (output.getvariantptr()) QVariant(qVariantFromValue<QObject *>(src.getQObject()));
+ VARIANT_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertObjectToVariant, unaryop)
+
QML_V4_BEGIN_INSTR(ConvertNullToObject, unaryop)
{
Register &output = registers[instr->unaryop.output];
@@ -1133,6 +1247,14 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertNullToObject, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertNullToVariant, unaryop)
+ {
+ Register &output = registers[instr->unaryop.output];
+ new (output.getvariantptr()) QVariant();
+ VARIANT_REGISTER(instr->unaryop.output);
+ }
+ QML_V4_END_INSTR(ConvertNullToVariant, unaryop)
+
QML_V4_BEGIN_INSTR(ResolveUrl, unaryop)
{
const Register &src = registers[instr->unaryop.src];
diff --git a/src/qml/qml/v4/qv4compiler.cpp b/src/qml/qml/v4/qv4compiler.cpp
index 045a14fbb5..e03270cf1d 100644
--- a/src/qml/qml/v4/qv4compiler.cpp
+++ b/src/qml/qml/v4/qv4compiler.cpp
@@ -377,6 +377,9 @@ void QV4CompilerPrivate::visitName(IR::Name *e)
case QMetaType::QColor:
regType = QColorType;
break;
+ case QMetaType::QVariant:
+ regType = QVariantType;
+ break;
default:
if (propTy == QQmlMetaType::QQuickAnchorLineMetaTypeId()) {
@@ -966,6 +969,7 @@ void QV4CompilerPrivate::visitMove(IR::Move *s)
switch (targetTy) {
case IR::BoolType:
case IR::StringType:
+ case IR::VariantType:
// nothing to do. V4 will generate optimized
// url-to-xxx conversions.
break;
@@ -1068,6 +1072,20 @@ void QV4CompilerPrivate::visitMove(IR::Move *s)
case IR::NullType: opcode = V4Instr::ConvertNullToObject; break;
default: break;
} // switch
+ } else if (targetTy == IR::VariantType) {
+ if (s->isMoveForReturn) {
+ switch (sourceTy) {
+ case IR::BoolType: opcode = V4Instr::ConvertBoolToVariant; break;
+ case IR::IntType: opcode = V4Instr::ConvertIntToVariant; break;
+ case IR::NumberType: opcode = V4Instr::ConvertNumberToVariant; break;
+ case IR::UrlType: opcode = V4Instr::ConvertUrlToVariant; break;
+ case IR::ColorType: opcode = V4Instr::ConvertColorToVariant; break;
+ case IR::StringType: opcode = V4Instr::ConvertStringToVariant; break;
+ case IR::ObjectType: opcode = V4Instr::ConvertObjectToVariant; break;
+ case IR::NullType: opcode = V4Instr::ConvertNullToVariant; break;
+ default: break;
+ } // switch
+ }
}
if (opcode != V4Instr::Noop) {
V4Instr conv;
@@ -1141,6 +1159,9 @@ void QV4CompilerPrivate::visitRet(IR::Ret *s)
case IR::ObjectType:
test.regType = QMetaType::QObjectStar;
break;
+ case IR::VariantType:
+ test.regType = QMetaType::QVariant;
+ break;
case IR::BoolType:
test.regType = QMetaType::Bool;
break;
diff --git a/src/qml/qml/v4/qv4instruction.cpp b/src/qml/qml/v4/qv4instruction.cpp
index ecd4f01ef3..c20297975d 100644
--- a/src/qml/qml/v4/qv4instruction.cpp
+++ b/src/qml/qml/v4/qv4instruction.cpp
@@ -144,6 +144,9 @@ void Bytecode::dump(const V4Instr *i, int address) const
case V4Instr::ConvertBoolToString:
INSTR_DUMP << "\t" << "ConvertBoolToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertBoolToVariant:
+ INSTR_DUMP << "\t" << "ConvertBoolToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertIntToBool:
INSTR_DUMP << "\t" << "ConvertIntToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
@@ -153,6 +156,9 @@ void Bytecode::dump(const V4Instr *i, int address) const
case V4Instr::ConvertIntToString:
INSTR_DUMP << "\t" << "ConvertIntToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertIntToVariant:
+ INSTR_DUMP << "\t" << "ConvertIntToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertNumberToBool:
INSTR_DUMP << "\t" << "ConvertNumberToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
@@ -162,6 +168,9 @@ void Bytecode::dump(const V4Instr *i, int address) const
case V4Instr::ConvertNumberToString:
INSTR_DUMP << "\t" << "ConvertNumberToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertNumberToVariant:
+ INSTR_DUMP << "\t" << "ConvertNumberToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertStringToBool:
INSTR_DUMP << "\t" << "ConvertStringToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
@@ -177,24 +186,39 @@ void Bytecode::dump(const V4Instr *i, int address) const
case V4Instr::ConvertStringToColor:
INSTR_DUMP << "\t" << "ConvertStringToColor" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertStringToVariant:
+ INSTR_DUMP << "\t" << "ConvertStringToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertUrlToBool:
INSTR_DUMP << "\t" << "ConvertUrlToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
case V4Instr::ConvertUrlToString:
INSTR_DUMP << "\t" << "ConvertUrlToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertUrlToVariant:
+ INSTR_DUMP << "\t" << "ConvertUrlToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertColorToBool:
INSTR_DUMP << "\t" << "ConvertColorToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
case V4Instr::ConvertColorToString:
INSTR_DUMP << "\t" << "ConvertColorToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertColorToVariant:
+ INSTR_DUMP << "\t" << "ConvertColorToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertObjectToBool:
INSTR_DUMP << "\t" << "ConvertObjectToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertObjectToVariant:
+ INSTR_DUMP << "\t" << "ConvertObjectToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertNullToObject:
INSTR_DUMP << "\t" << "ConvertNullToObject" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertNullToVariant:
+ INSTR_DUMP << "\t" << "ConvertNullToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ResolveUrl:
INSTR_DUMP << "\t" << "ResolveUrl" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
diff --git a/src/qml/qml/v4/qv4instruction_p.h b/src/qml/qml/v4/qv4instruction_p.h
index 310bfbaff5..6eb9efa50f 100644
--- a/src/qml/qml/v4/qv4instruction_p.h
+++ b/src/qml/qml/v4/qv4instruction_p.h
@@ -83,23 +83,31 @@ QT_BEGIN_NAMESPACE
F(ConvertBoolToInt, unaryop) \
F(ConvertBoolToNumber, unaryop) \
F(ConvertBoolToString, unaryop) \
+ F(ConvertBoolToVariant, unaryop) \
F(ConvertIntToBool, unaryop) \
F(ConvertIntToNumber, unaryop) \
F(ConvertIntToString, unaryop) \
+ F(ConvertIntToVariant, unaryop) \
F(ConvertNumberToBool, unaryop) \
F(ConvertNumberToInt, unaryop) \
F(ConvertNumberToString, unaryop) \
+ F(ConvertNumberToVariant, unaryop) \
F(ConvertStringToBool, unaryop) \
F(ConvertStringToInt, unaryop) \
F(ConvertStringToNumber, unaryop) \
F(ConvertStringToUrl, unaryop) \
F(ConvertStringToColor, unaryop) \
+ F(ConvertStringToVariant, unaryop) \
F(ConvertUrlToBool, unaryop) \
F(ConvertUrlToString, unaryop) \
+ F(ConvertUrlToVariant, unaryop) \
F(ConvertColorToBool, unaryop) \
F(ConvertColorToString, unaryop) \
+ F(ConvertColorToVariant, unaryop) \
F(ConvertObjectToBool, unaryop) \
+ F(ConvertObjectToVariant, unaryop) \
F(ConvertNullToObject, unaryop) \
+ F(ConvertNullToVariant, unaryop) \
F(ResolveUrl, unaryop) \
F(MathSinNumber, unaryop) \
F(MathCosNumber, unaryop) \
diff --git a/src/qml/qml/v4/qv4ir.cpp b/src/qml/qml/v4/qv4ir.cpp
index ba0faec80e..45e909f54b 100644
--- a/src/qml/qml/v4/qv4ir.cpp
+++ b/src/qml/qml/v4/qv4ir.cpp
@@ -63,6 +63,8 @@ const char *typeName(Type t)
case SGAnchorLineType: return "SGAnchorLine";
case AttachType: return "AttachType";
case ObjectType: return "object";
+ case VariantType: return "variant";
+ case VarType: return "var";
case BoolType: return "bool";
case IntType: return "int";
case FloatType: return "float";
diff --git a/src/qml/qml/v4/qv4ir_p.h b/src/qml/qml/v4/qv4ir_p.h
index 26bd43c406..254b810403 100644
--- a/src/qml/qml/v4/qv4ir_p.h
+++ b/src/qml/qml/v4/qv4ir_p.h
@@ -146,6 +146,8 @@ enum Type {
SGAnchorLineType,
AttachType,
ObjectType,
+ VariantType,
+ VarType,
FirstNumberType,
BoolType = FirstNumberType,
diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp
index 31ed9a5a6a..82da09f485 100644
--- a/src/qml/qml/v4/qv4irbuilder.cpp
+++ b/src/qml/qml/v4/qv4irbuilder.cpp
@@ -116,8 +116,16 @@ bool QV4IRBuilder::operator()(QQmlJS::IR::Function *function,
//_block->MOVE(_block->TEMP(IR::InvalidType), r.code);
if (r.code) {
- const QMetaObject *m = 0;
- const IR::Type targetType = irTypeFromVariantType(m_expression->property->type, m_engine, m);
+ IR::Type targetType = IR::InvalidType;
+
+ // This is the only operation where variant is supported:
+ QQmlPropertyData *data = &m_expression->property->core;
+ if (data->propType == QMetaType::QVariant) {
+ targetType = (data->isVMEProperty() ? IR::VarType : IR::VariantType);
+ } else {
+ targetType = irTypeFromVariantType(data->propType, m_engine, 0);
+ }
+
if (targetType != r.type()) {
IR::Expr *x = _block->TEMP(targetType);
_block->MOVE(x, r, true);
diff --git a/src/qml/qml/v8/qjsconverter_impl_p.h b/src/qml/qml/v8/qjsconverter_impl_p.h
index c2775df7f5..ab004a543e 100644
--- a/src/qml/qml/v8/qjsconverter_impl_p.h
+++ b/src/qml/qml/v8/qjsconverter_impl_p.h
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qjsconverter_p.h"
+#include <stdlib.h>
#ifndef QJSCONVERTER_IMPL_P_H
#define QJSCONVERTER_IMPL_P_H
diff --git a/src/qml/qml/v8/qv8qobjectwrapper.cpp b/src/qml/qml/v8/qv8qobjectwrapper.cpp
index 9a5aaca6e4..176d4fb76f 100644
--- a/src/qml/qml/v8/qv8qobjectwrapper.cpp
+++ b/src/qml/qml/v8/qv8qobjectwrapper.cpp
@@ -301,8 +301,8 @@ static v8::Handle<v8::Value> GenericValueGetter(v8::Local<v8::String>, const v8:
#define FAST_GETTER_FUNCTION(property, cpptype) \
(property->hasAccessors()?((v8::AccessorGetter)GenericValueGetter<cpptype, &ReadAccessor::Accessor>):(property->isDirect()?((v8::AccessorGetter)GenericValueGetter<cpptype, &ReadAccessor::Direct>):((v8::AccessorGetter)GenericValueGetter<cpptype, &ReadAccessor::Indirect>)))
-static quint32 toStringHash = -1;
-static quint32 destroyHash = -1;
+static quint32 toStringHash = quint32(-1);
+static quint32 destroyHash = quint32(-1);
void QV8QObjectWrapper::init(QV8Engine *engine)
{
diff --git a/src/qmltest/qmltest.pro b/src/qmltest/qmltest.pro
index 157cfe97c0..3e3adaba99 100644
--- a/src/qmltest/qmltest.pro
+++ b/src/qmltest/qmltest.pro
@@ -4,7 +4,7 @@ TARGET = QtQuickTest
QPRO_PWD = $$PWD
CONFIG += module
-CONFIG += dll warn_on declarative_debug
+CONFIG += dll warn_on
MODULE_PRI += ../../modules/qt_qmltest.pri
QT += testlib testlib-private qml quick gui
@@ -33,4 +33,4 @@ HEADERS += \
$$PWD/qtestoptions_p.h
-DEFINES += QT_BUILD_QUICK_TEST_LIB \ No newline at end of file
+DEFINES += QT_BUILD_QUICK_TEST_LIB QT_QML_DEBUG_NO_WARNING \ No newline at end of file
diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp
index 3f08c8f056..a288531beb 100644
--- a/src/quick/items/qquickcanvas.cpp
+++ b/src/quick/items/qquickcanvas.cpp
@@ -330,6 +330,7 @@ void QQuickCanvasPrivate::init(QQuickCanvas *c)
Q_Q(QQuickCanvas);
rootItem = new QQuickRootItem;
+ QQmlEngine::setObjectOwnership(rootItem, QQmlEngine::CppOwnership);
QQuickItemPrivate *rootItemPrivate = QQuickItemPrivate::get(rootItem);
rootItemPrivate->canvas = q;
rootItemPrivate->canvasRefCount = 1;
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index 1fab4a8c99..0518fccd10 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -92,7 +92,7 @@ public:
}
qreal size() const {
- return view->flow() == QQuickGridView::LeftToRight ? view->cellHeight() : view->cellWidth();
+ return view->flow() == QQuickGridView::FlowLeftToRight ? view->cellHeight() : view->cellWidth();
}
qreal sectionSize() const {
@@ -100,14 +100,14 @@ public:
}
qreal rowPos() const {
- if (view->flow() == QQuickGridView::LeftToRight)
- return itemY();
+ if (view->flow() == QQuickGridView::FlowLeftToRight)
+ return (view->verticalLayoutDirection() == QQuickItemView::BottomToTop ? -view->cellHeight()-itemY() : itemY());
else
return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -view->cellWidth()-itemX() : itemX());
}
qreal colPos() const {
- if (view->flow() == QQuickGridView::LeftToRight) {
+ if (view->flow() == QQuickGridView::FlowLeftToRight) {
if (view->effectiveLayoutDirection() == Qt::RightToLeft) {
qreal colSize = view->cellWidth();
int columns = view->width()/colSize;
@@ -116,12 +116,19 @@ public:
return itemX();
}
} else {
- return itemY();
+ if (view->verticalLayoutDirection() == QQuickItemView::BottomToTop) {
+ return -view->cellHeight() - itemY();
+ } else {
+ return itemY();
+ }
}
}
qreal endRowPos() const {
- if (view->flow() == QQuickGridView::LeftToRight) {
- return itemY() + view->cellHeight();
+ if (view->flow() == QQuickGridView::FlowLeftToRight) {
+ if (view->verticalLayoutDirection() == QQuickItemView::BottomToTop)
+ return -itemY();
+ else
+ return itemY() + view->cellHeight();
} else {
if (view->effectiveLayoutDirection() == Qt::RightToLeft)
return -itemX();
@@ -141,19 +148,24 @@ public:
private:
QPointF pointForPosition(qreal col, qreal row) const {
- if (view->effectiveLayoutDirection() == Qt::RightToLeft) {
- if (view->flow() == QQuickGridView::LeftToRight) {
+ qreal x;
+ qreal y;
+ if (view->flow() == QQuickGridView::FlowLeftToRight) {
+ x = col;
+ y = row;
+ if (view->effectiveLayoutDirection() == Qt::RightToLeft) {
int columns = view->width()/view->cellWidth();
- return QPointF(view->cellWidth() * (columns-1) - col, row);
- } else {
- return QPointF(-view->cellWidth() - row, col);
+ x = view->cellWidth() * (columns-1) - col;
}
} else {
- if (view->flow() == QQuickGridView::LeftToRight)
- return QPointF(col, row);
- else
- return QPointF(row, col);
+ x = row;
+ y = col;
+ if (view->effectiveLayoutDirection() == Qt::RightToLeft)
+ x = -view->cellWidth() - row;
}
+ if (view->verticalLayoutDirection() == QQuickItemView::BottomToTop)
+ y = -view->cellHeight() - y;
+ return QPointF(x, y);
}
};
@@ -166,7 +178,6 @@ class QQuickGridViewPrivate : public QQuickItemViewPrivate
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;
@@ -180,6 +191,8 @@ public:
qreal snapPosAt(qreal pos) const;
FxViewItem *snapItemAt(qreal pos) const;
int snapIndex() const;
+ qreal contentXForPosition(qreal pos) const;
+ qreal contentYForPosition(qreal pos) const;
void resetColumns();
@@ -229,7 +242,7 @@ public:
QSmoothedAnimation *highlightYAnimator;
QQuickGridViewPrivate()
- : flow(QQuickGridView::LeftToRight)
+ : flow(QQuickGridView::FlowLeftToRight)
, cellWidth(100), cellHeight(100), columns(1)
, snapMode(QQuickGridView::NoSnap)
, highlightXAnimator(0), highlightYAnimator(0)
@@ -243,18 +256,15 @@ public:
Qt::Orientation QQuickGridViewPrivate::layoutOrientation() const
{
- return flow == QQuickGridView::LeftToRight ? Qt::Vertical : Qt::Horizontal;
+ return flow == QQuickGridView::FlowLeftToRight ? 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;
+
+ return (flow == QQuickGridView::FlowLeftToRight && verticalLayoutDirection == QQuickItemView::BottomToTop)
+ || (flow == QQuickGridView::FlowTopToBottom && q->effectiveLayoutDirection() == Qt::RightToLeft);
}
void QQuickGridViewPrivate::changedVisibleIndex(int newIndex)
@@ -265,16 +275,8 @@ void QQuickGridViewPrivate::changedVisibleIndex(int newIndex)
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);
- }
+ q->QQuickFlickable::setContentX(contentXForPosition(pos));
+ q->QQuickFlickable::setContentY(contentYForPosition(pos));
}
qreal QQuickGridViewPrivate::originPosition() const
@@ -306,10 +308,10 @@ qreal QQuickGridViewPrivate::endPositionAt(int index) const
}
qreal QQuickGridViewPrivate::rowSize() const {
- return flow == QQuickGridView::LeftToRight ? cellHeight : cellWidth;
+ return flow == QQuickGridView::FlowLeftToRight ? cellHeight : cellWidth;
}
qreal QQuickGridViewPrivate::colSize() const {
- return flow == QQuickGridView::LeftToRight ? cellWidth : cellHeight;
+ return flow == QQuickGridView::FlowLeftToRight ? cellWidth : cellHeight;
}
qreal QQuickGridViewPrivate::colPosAt(int modelIndex) const
@@ -375,12 +377,12 @@ qreal QQuickGridViewPrivate::snapPosAt(qreal pos) const
snapPos -= highlightStart;
qreal maxExtent;
qreal minExtent;
- if (isRightToLeftTopToBottom()) {
+ if (isContentFlowReversed()) {
maxExtent = q->minXExtent()-size();
minExtent = q->maxXExtent()-size();
} else {
- maxExtent = flow == QQuickGridView::LeftToRight ? -q->maxYExtent() : -q->maxXExtent();
- minExtent = flow == QQuickGridView::LeftToRight ? -q->minYExtent() : -q->minXExtent();
+ maxExtent = flow == QQuickGridView::FlowLeftToRight ? -q->maxYExtent() : -q->maxXExtent();
+ minExtent = flow == QQuickGridView::FlowLeftToRight ? -q->minYExtent() : -q->minXExtent();
}
if (snapPos > maxExtent)
snapPos = maxExtent;
@@ -421,10 +423,49 @@ int QQuickGridViewPrivate::snapIndex() const
return index;
}
+qreal QQuickGridViewPrivate::contentXForPosition(qreal pos) const
+{
+ Q_Q(const QQuickGridView);
+ if (flow == QQuickGridView::FlowLeftToRight) {
+ // vertical scroll
+ if (q->effectiveLayoutDirection() == Qt::LeftToRight) {
+ return 0;
+ } else {
+ qreal colSize = cellWidth;
+ int columns = q->width()/colSize;
+ return -q->width() + (cellWidth * columns);
+ }
+ } else {
+ // horizontal scroll
+ if (q->effectiveLayoutDirection() == Qt::LeftToRight)
+ return pos;
+ else
+ return -pos - q->width();
+ }
+}
+
+qreal QQuickGridViewPrivate::contentYForPosition(qreal pos) const
+{
+ Q_Q(const QQuickGridView);
+ if (flow == QQuickGridView::FlowLeftToRight) {
+ // vertical scroll
+ if (verticalLayoutDirection == QQuickItemView::TopToBottom)
+ return pos;
+ else
+ return -pos - q->height();
+ } else {
+ // horizontal scroll
+ if (verticalLayoutDirection == QQuickItemView::TopToBottom)
+ return 0;
+ else
+ return -q->height();
+ }
+}
+
void QQuickGridViewPrivate::resetColumns()
{
Q_Q(QQuickGridView);
- qreal length = flow == QQuickGridView::LeftToRight ? q->width() : q->height();
+ qreal length = flow == QQuickGridView::FlowLeftToRight ? q->width() : q->height();
columns = (int)qMax((length + colSize()/2) / colSize(), qreal(1.));
}
@@ -641,15 +682,22 @@ 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)));
+ if (flow == QQuickGridView::FlowLeftToRight) {
+ if (item->y() + item->height() > pos && item->y() < pos + q->height()) {
+ qreal y = (verticalLayoutDirection == QQuickItemView::TopToBottom)
+ ? rowPosAt(index)
+ : -rowPosAt(index) - item->height();
+ item->setPos(QPointF(colPosAt(index), y));
+ }
} else {
if (item->x() + item->width() > pos && item->x() < pos + q->width()) {
- if (isRightToLeftTopToBottom())
- item->setPos(QPointF(-rowPosAt(index)-item->width(), colPosAt(index)));
+ qreal y = (verticalLayoutDirection == QQuickItemView::TopToBottom)
+ ? colPosAt(index)
+ : -colPosAt(index) - item->height();
+ if (flow == QQuickGridView::FlowTopToBottom && q->effectiveLayoutDirection() == Qt::RightToLeft)
+ item->setPos(QPointF(-rowPosAt(index)-item->width(), y));
else
- item->setPos(QPointF(rowPosAt(index), colPosAt(index)));
+ item->setPos(QPointF(rowPosAt(index), y));
}
}
}
@@ -744,14 +792,14 @@ qreal QQuickGridViewPrivate::headerSize() const
{
if (!header)
return 0.0;
- return flow == QQuickGridView::LeftToRight ? header->item->height() : header->item->width();
+ return flow == QQuickGridView::FlowLeftToRight ? 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();
+ return flow == QQuickGridView::FlowLeftToRight? footer->item->height() : footer->item->width();
}
bool QQuickGridViewPrivate::showHeaderForIndex(int index) const
@@ -781,17 +829,23 @@ void QQuickGridViewPrivate::updateFooter()
qreal colOffset = 0;
qreal rowOffset = 0;
if (q->effectiveLayoutDirection() == Qt::RightToLeft) {
- if (flow == QQuickGridView::TopToBottom)
- rowOffset = gridItem->item->width() - cellWidth;
+ if (flow == QQuickGridView::FlowTopToBottom)
+ rowOffset += gridItem->item->width() - cellWidth;
+ else
+ colOffset += gridItem->item->width() - cellWidth;
+ }
+ if (verticalLayoutDirection == QQuickItemView::BottomToTop) {
+ if (flow == QQuickGridView::FlowTopToBottom)
+ colOffset += gridItem->item->height() - cellHeight;
else
- colOffset = gridItem->item->width() - cellWidth;
+ rowOffset += gridItem->item->height() - cellHeight;
}
if (visibleItems.count()) {
qreal endPos = lastPosition();
if (findLastVisibleIndex() == model->count()-1) {
gridItem->setPosition(colOffset, endPos + rowOffset);
} else {
- qreal visiblePos = isRightToLeftTopToBottom() ? -position() : position() + size();
+ qreal visiblePos = isContentFlowReversed() ? -position() : position() + size();
if (endPos <= visiblePos || gridItem->endPosition() <= endPos + rowOffset)
gridItem->setPosition(colOffset, endPos + rowOffset);
}
@@ -820,23 +874,29 @@ void QQuickGridViewPrivate::updateHeader()
qreal colOffset = 0;
qreal rowOffset = -headerSize();
if (q->effectiveLayoutDirection() == Qt::RightToLeft) {
- if (flow == QQuickGridView::TopToBottom)
- rowOffset += gridItem->item->width()-cellWidth;
+ if (flow == QQuickGridView::FlowTopToBottom)
+ rowOffset += gridItem->item->width() - cellWidth;
+ else
+ colOffset += gridItem->item->width() - cellWidth;
+ }
+ if (verticalLayoutDirection == QQuickItemView::BottomToTop) {
+ if (flow == QQuickGridView::FlowTopToBottom)
+ colOffset += gridItem->item->height() - cellHeight;
else
- colOffset = gridItem->item->width()-cellWidth;
+ rowOffset += gridItem->item->height() - cellHeight;
}
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();
+ qreal tempPos = isContentFlowReversed() ? -position()-size() : position();
+ qreal headerPos = isContentFlowReversed() ? gridItem->rowPos() + cellWidth - headerSize() : gridItem->rowPos();
if (tempPos <= startPos || headerPos > startPos + rowOffset)
gridItem->setPosition(colOffset, startPos + rowOffset);
}
} else {
- if (isRightToLeftTopToBottom())
+ if (isContentFlowReversed())
gridItem->setPosition(colOffset, rowOffset);
else
gridItem->setPosition(colOffset, -headerSize());
@@ -861,7 +921,7 @@ void QQuickGridViewPrivate::initializeCurrentItem()
void QQuickGridViewPrivate::fixupPosition()
{
moveReason = Other;
- if (flow == QQuickGridView::LeftToRight)
+ if (flow == QQuickGridView::FlowLeftToRight)
fixupY();
else
fixupX();
@@ -869,17 +929,17 @@ void QQuickGridViewPrivate::fixupPosition()
void QQuickGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
{
- if ((flow == QQuickGridView::TopToBottom && &data == &vData)
- || (flow == QQuickGridView::LeftToRight && &data == &hData))
+ if ((flow == QQuickGridView::FlowTopToBottom && &data == &vData)
+ || (flow == QQuickGridView::FlowLeftToRight && &data == &hData))
return;
fixupMode = moveReason == Mouse ? fixupMode : Immediate;
- qreal viewPos = isRightToLeftTopToBottom() ? -position()-size() : position();
+ qreal viewPos = isContentFlowReversed() ? -position()-size() : position();
bool strictHighlightRange = haveHighlightRange && highlightRange == QQuickGridView::StrictlyEnforceRange;
if (snapMode != QQuickGridView::NoSnap) {
- qreal tempPosition = isRightToLeftTopToBottom() ? -position()-size() : position();
+ qreal tempPosition = isContentFlowReversed() ? -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);
@@ -888,7 +948,7 @@ void QQuickGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte
bias = rowSize()/2;
else if (data.velocity < 0 && dist < -QML_FLICK_SNAPONETHRESHOLD && dist > -rowSize()/2)
bias = -rowSize()/2;
- if (isRightToLeftTopToBottom())
+ if (isContentFlowReversed())
bias = -bias;
tempPosition -= bias;
}
@@ -909,15 +969,15 @@ void QQuickGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte
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;
+ pos = isContentFlowReversed() ? - headerPos + highlightRangeStart - size() : headerPos - highlightRangeStart;
} else {
- if (isRightToLeftTopToBottom())
+ if (isContentFlowReversed())
pos = qMax(qMin(-topItem->position() + highlightRangeStart - size(), -maxExtent), -minExtent);
else
pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent);
}
} else if (bottomItem && isInBounds) {
- if (isRightToLeftTopToBottom())
+ if (isContentFlowReversed())
pos = qMax(qMin(-bottomItem->position() + highlightRangeEnd - size(), -maxExtent), -minExtent);
else
pos = qMax(qMin(bottomItem->position() - highlightRangeEnd, -maxExtent), -minExtent);
@@ -945,7 +1005,7 @@ void QQuickGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte
viewPos = pos + rowSize() - highlightRangeEnd;
if (viewPos > pos - highlightRangeStart)
viewPos = pos - highlightRangeStart;
- if (isRightToLeftTopToBottom())
+ if (isContentFlowReversed())
viewPos = -viewPos-size();
timeline.reset(data.move);
if (viewPos != position()) {
@@ -977,7 +1037,7 @@ void QQuickGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte
return;
}
qreal maxDistance = 0;
- qreal dataValue = isRightToLeftTopToBottom() ? -data.move.value()+size() : data.move.value();
+ qreal dataValue = isContentFlowReversed() ? -data.move.value()+size() : data.move.value();
// -ve velocity means list is moving up/left
if (velocity > 0) {
if (data.move.value() < minExtent) {
@@ -985,7 +1045,7 @@ void QQuickGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte
// 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())
+ if (isContentFlowReversed())
bias = -bias;
data.flickTarget = -snapPosAt(-dataValue - bias);
maxDistance = qAbs(data.flickTarget - data.move.value());
@@ -1002,7 +1062,7 @@ void QQuickGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte
// 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())
+ if (isContentFlowReversed())
bias = -bias;
data.flickTarget = -snapPosAt(-dataValue + bias);
maxDistance = qAbs(data.flickTarget - data.move.value());
@@ -1034,10 +1094,10 @@ void QQuickGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte
if (v > 0)
dist = -dist;
if (snapMode != QQuickGridView::SnapOneRow) {
- qreal distTemp = isRightToLeftTopToBottom() ? -dist : dist;
+ qreal distTemp = isContentFlowReversed() ? -dist : dist;
data.flickTarget = -snapPosAt(-dataValue + distTemp);
}
- data.flickTarget = isRightToLeftTopToBottom() ? -data.flickTarget+size() : data.flickTarget;
+ data.flickTarget = isContentFlowReversed() ? -data.flickTarget+size() : data.flickTarget;
if (overShoot) {
if (data.flickTarget >= minExtent) {
overshootDist = overShootDistance(vSize);
@@ -1159,6 +1219,60 @@ void QQuickGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte
to set this property to true in order to clip the items that are partially or
fully outside the view.
+
+ \section1 GridView layouts
+
+ The layout of the items in a GridView can be controlled by these properties:
+
+ \list
+ \li \l flow - controls whether items flow from left to right (as a series of rows)
+ or from top to bottom (as a series of columns). This value can be either
+ GridView.LeftToRight or GridView.TopToBottom.
+ \li \l layoutDirection - controls the horizontal layout direction: that is, whether items
+ are laid out from the left side of the view to the right, or vice-versa. This value can
+ be either Qt.LeftToRight or Qt.RightToLeft.
+ \li \l verticalLayoutDirection - controls the vertical layout direction: that is, whether items
+ are laid out from the top of the view down towards the bottom of the view, or vice-versa.
+ This value can be either GridView.TopToBottom or GridView.BottomToTop.
+ \endlist
+
+ By default, a GridView flows from left to right, and items are laid out from left to right
+ horizontally, and from top to bottom vertically.
+
+ These properties can be combined to produce a variety of layouts, as shown in the table below.
+ The GridViews in the first row all have a \l flow value of GridView.LeftToRight, but use
+ different combinations of horizontal and vertical layout directions (specified by \l layoutDirection
+ and \l verticalLayoutDirection respectively). Similarly, the GridViews in the second row below
+ all have a \l flow value of GridView.TopToBottom, but use different combinations of horizontal and
+ vertical layout directions to lay out their items in different ways.
+
+ \table
+ \header
+ \li {4, 1}
+ \bold GridViews with GridView.LeftToRight flow
+ \row
+ \li \bold (H) Left to right \bold (V) Top to bottom
+ \image gridview-layout-lefttoright-ltr-ttb.png
+ \li \bold (H) Right to left \bold (V) Top to bottom
+ \image gridview-layout-lefttoright-rtl-ttb.png
+ \li \bold (H) Left to right \bold (V) Bottom to top
+ \image gridview-layout-lefttoright-ltr-btt.png
+ \li \bold (H) Right to left \bold (V) Bottom to top
+ \image gridview-layout-lefttoright-rtl-btt.png
+ \header
+ \li {4, 1}
+ \bold GridViews with GridView.TopToBottom flow
+ \row
+ \li \bold (H) Left to right \bold (V) Top to bottom
+ \image gridview-layout-toptobottom-ltr-ttb.png
+ \li \bold (H) Right to left \bold (V) Top to bottom
+ \image gridview-layout-toptobottom-rtl-ttb.png
+ \li \bold (H) Left to right \bold (V) Bottom to top
+ \image gridview-layout-toptobottom-ltr-btt.png
+ \li \bold (H) Right to left \bold (V) Bottom to top
+ \image gridview-layout-toptobottom-rtl-btt.png
+ \endtable
+
\sa {declarative/modelviews/gridview}{GridView example}
*/
@@ -1380,6 +1494,8 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight)
\b 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.
+
+ \sa GridView::effectiveLayoutDirection, GridView::verticalLayoutDirection
*/
@@ -1393,6 +1509,21 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight)
\sa GridView::layoutDirection, {LayoutMirroring}{LayoutMirroring}
*/
+
+/*!
+ \qmlproperty enumeration QtQuick2::GridView::verticalLayoutDirection
+ This property holds the vertical layout direction of the grid.
+
+ Possible values:
+
+ \list
+ \li GridView.TopToBottom (default) - Items are laid out from the top of the view down to the bottom of the view.
+ \li GridView.BottomToTop - Items are laid out from the bottom of the view up to the top of the view.
+ \endlist
+
+ \sa GridView::layoutDirection
+*/
+
/*!
\qmlproperty bool QtQuick2::GridView::keyNavigationWraps
This property holds whether the grid wraps key navigation
@@ -1461,7 +1592,7 @@ void QQuickGridView::setFlow(Flow flow)
Q_D(QQuickGridView);
if (d->flow != flow) {
d->flow = flow;
- if (d->flow == LeftToRight) {
+ if (d->flow == FlowLeftToRight) {
setContentWidth(-1);
setFlickableDirection(VerticalFlick);
} else {
@@ -1877,14 +2008,19 @@ void QQuickGridView::viewportMoved()
return;
d->inViewportMoved = true;
- if (yflick())
- d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter;
- else if (d->isRightToLeftTopToBottom())
- d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferAfter : QQuickItemViewPrivate::BufferBefore;
- else
- d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter;
+ if (yflick()) {
+ if (d->isContentFlowReversed())
+ d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferAfter : QQuickItemViewPrivate::BufferBefore;
+ else
+ d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter;
+ } else {
+ if (d->isContentFlowReversed())
+ d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferAfter : QQuickItemViewPrivate::BufferBefore;
+ else
+ d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter;
+ }
- d->refill();
+ d->refillOrLayout();
// Set visibility of items to eliminate cost of items outside the visible area.
qreal from = d->isContentFlowReversed() ? -d->position()-d->size() : d->position();
@@ -1904,7 +2040,7 @@ void QQuickGridView::viewportMoved()
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();
+ qreal viewPos = d->isContentFlowReversed() ? -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)
@@ -1923,7 +2059,7 @@ void QQuickGridView::viewportMoved()
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)
+ if (d->flow == FlowLeftToRight)
d->highlightXAnimator->to = d->currentItem->itemX();
else
d->highlightYAnimator->to = d->currentItem->itemY();
@@ -1970,6 +2106,16 @@ void QQuickGridView::geometryChanged(const QRectF &newGeometry, const QRectF &ol
{
Q_D(QQuickGridView);
d->resetColumns();
+
+ if (newGeometry.width() != oldGeometry.width()
+ && newGeometry.height() != oldGeometry.height()) {
+ d->setPosition(d->position());
+ } else if (newGeometry.width() != oldGeometry.width()) {
+ QQuickFlickable::setContentX(d->contentXForPosition(d->position()));
+ } else if (newGeometry.height() != oldGeometry.height()) {
+ QQuickFlickable::setContentY(d->contentYForPosition(d->position()));
+ }
+
QQuickItemView::geometryChanged(newGeometry, oldGeometry);
}
@@ -1990,15 +2136,29 @@ void QQuickGridView::moveCurrentIndexUp()
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);
+ if (d->verticalLayoutDirection == QQuickItemView::TopToBottom) {
+ if (d->flow == QQuickGridView::FlowLeftToRight) {
+ 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);
+ }
}
} else {
- if (currentIndex() > 0 || d->wrap) {
- int index = currentIndex() - 1;
- setCurrentIndex((index >= 0 && index < count) ? index : count-1);
+ if (d->flow == QQuickGridView::FlowLeftToRight) {
+ 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);
+ }
}
}
}
@@ -2018,15 +2178,30 @@ void QQuickGridView::moveCurrentIndexDown()
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);
+
+ if (d->verticalLayoutDirection == QQuickItemView::TopToBottom) {
+ if (d->flow == QQuickGridView::FlowLeftToRight) {
+ 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);
+ }
}
} else {
- if (currentIndex() < count - 1 || d->wrap) {
- int index = currentIndex() + 1;
- setCurrentIndex((index >= 0 && index < count) ? index : 0);
+ if (d->flow == QQuickGridView::FlowLeftToRight) {
+ 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);
+ }
}
}
}
@@ -2047,7 +2222,7 @@ void QQuickGridView::moveCurrentIndexLeft()
if (!count)
return;
if (effectiveLayoutDirection() == Qt::LeftToRight) {
- if (d->flow == QQuickGridView::LeftToRight) {
+ if (d->flow == QQuickGridView::FlowLeftToRight) {
if (currentIndex() > 0 || d->wrap) {
int index = currentIndex() - 1;
setCurrentIndex((index >= 0 && index < count) ? index : count-1);
@@ -2059,7 +2234,7 @@ void QQuickGridView::moveCurrentIndexLeft()
}
}
} else {
- if (d->flow == QQuickGridView::LeftToRight) {
+ if (d->flow == QQuickGridView::FlowLeftToRight) {
if (currentIndex() < count - 1 || d->wrap) {
int index = currentIndex() + 1;
setCurrentIndex((index >= 0 && index < count) ? index : 0);
@@ -2090,7 +2265,7 @@ void QQuickGridView::moveCurrentIndexRight()
if (!count)
return;
if (effectiveLayoutDirection() == Qt::LeftToRight) {
- if (d->flow == QQuickGridView::LeftToRight) {
+ if (d->flow == QQuickGridView::FlowLeftToRight) {
if (currentIndex() < count - 1 || d->wrap) {
int index = currentIndex() + 1;
setCurrentIndex((index >= 0 && index < count) ? index : 0);
@@ -2102,7 +2277,7 @@ void QQuickGridView::moveCurrentIndexRight()
}
}
} else {
- if (d->flow == QQuickGridView::LeftToRight) {
+ if (d->flow == QQuickGridView::FlowLeftToRight) {
if (currentIndex() > 0 || d->wrap) {
int index = currentIndex() - 1;
setCurrentIndex((index >= 0 && index < count) ? index : count-1);
@@ -2146,7 +2321,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert &
}
}
- qreal tempPos = isRightToLeftTopToBottom() ? -position()-size()+q->width()+1 : position();
+ qreal tempPos = isContentFlowReversed() ? -position()-size()+q->width()+1 : position();
qreal colPos = 0;
qreal rowPos = 0;
int colNum = 0;
diff --git a/src/quick/items/qquickgridview_p.h b/src/quick/items/qquickgridview_p.h
index ac3c8f097d..789c6411a5 100644
--- a/src/quick/items/qquickgridview_p.h
+++ b/src/quick/items/qquickgridview_p.h
@@ -69,13 +69,17 @@ class Q_AUTOTEST_EXPORT QQuickGridView : public QQuickItemView
Q_CLASSINFO("DefaultProperty", "data")
public:
+ enum Flow {
+ FlowLeftToRight = LeftToRight,
+ FlowTopToBottom = TopToBottom
+ };
+
QQuickGridView(QQuickItem *parent=0);
~QQuickGridView();
virtual void setHighlightFollowsCurrentItem(bool);
virtual void setHighlightMoveDuration(int);
- enum Flow { LeftToRight, TopToBottom };
Flow flow() const;
void setFlow(Flow);
diff --git a/src/quick/items/qquickimplicitsizeitem_p.h b/src/quick/items/qquickimplicitsizeitem_p.h
index a6d58325d8..be2b479d7a 100644
--- a/src/quick/items/qquickimplicitsizeitem_p.h
+++ b/src/quick/items/qquickimplicitsizeitem_p.h
@@ -49,7 +49,7 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
class QQuickImplicitSizeItemPrivate;
-class Q_AUTOTEST_EXPORT QQuickImplicitSizeItem : public QQuickItem
+class Q_QUICK_EXPORT QQuickImplicitSizeItem : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(qreal implicitWidth READ implicitWidth NOTIFY implicitWidthChanged)
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 209d30aa74..e70e923c4d 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -442,7 +442,7 @@ void QQuickItemView::setCacheBuffer(int b)
d->buffer = b;
if (isComponentComplete()) {
d->bufferMode = QQuickItemViewPrivate::BufferBefore | QQuickItemViewPrivate::BufferAfter;
- d->refill();
+ d->refillOrLayout();
}
emit cacheBufferChanged();
}
@@ -475,6 +475,21 @@ Qt::LayoutDirection QQuickItemView::effectiveLayoutDirection() const
return d->layoutDirection;
}
+QQuickItemView::VerticalLayoutDirection QQuickItemView::verticalLayoutDirection() const
+{
+ Q_D(const QQuickItemView);
+ return d->verticalLayoutDirection;
+}
+
+void QQuickItemView::setVerticalLayoutDirection(VerticalLayoutDirection layoutDirection)
+{
+ Q_D(QQuickItemView);
+ if (d->verticalLayoutDirection != layoutDirection) {
+ d->verticalLayoutDirection = layoutDirection;
+ d->regenerate();
+ emit verticalLayoutDirectionChanged();
+ }
+}
QQmlComponent *QQuickItemView::header() const
{
@@ -818,7 +833,7 @@ void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode)
FxViewItem *item = visibleItem(idx);
qreal maxExtent;
if (layoutOrientation() == Qt::Vertical)
- maxExtent = -q->maxYExtent();
+ maxExtent = isContentFlowReversed() ? q->minYExtent()-size(): -q->maxYExtent();
else
maxExtent = isContentFlowReversed() ? q->minXExtent()-size(): -q->maxXExtent();
if (!item) {
@@ -864,7 +879,7 @@ void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode)
pos = qMin(pos, maxExtent);
qreal minExtent;
if (layoutOrientation() == Qt::Vertical)
- minExtent = -q->minYExtent();
+ minExtent = isContentFlowReversed() ? q->maxYExtent()-size(): -q->minYExtent();
else
minExtent = isContentFlowReversed() ? q->maxXExtent()-size(): -q->minXExtent();
pos = qMax(pos, minExtent);
@@ -948,6 +963,89 @@ int QQuickItemViewPrivate::findMoveKeyIndex(QQuickChangeSet::MoveKey key, const
return -1;
}
+qreal QQuickItemViewPrivate::minExtentForAxis(const AxisData &axisData, bool forXAxis) const
+{
+ Q_Q(const QQuickItemView);
+
+ qreal highlightStart;
+ qreal highlightEnd;
+ qreal endPositionFirstItem = 0;
+ qreal extent = -startPosition() + axisData.startMargin;
+ if (isContentFlowReversed()) {
+ if (model && model->count())
+ endPositionFirstItem = positionAt(model->count()-1);
+ else
+ extent += headerSize();
+ highlightStart = highlightRangeEndValid ? size() - highlightRangeEnd : size();
+ highlightEnd = highlightRangeStartValid ? size() - highlightRangeStart : size();
+ extent += footerSize();
+ qreal maxExtentAlongAxis = forXAxis ? q->maxXExtent() : q->maxYExtent();
+ if (extent < maxExtentAlongAxis)
+ extent = maxExtentAlongAxis;
+ } else {
+ endPositionFirstItem = endPositionAt(0);
+ highlightStart = highlightRangeStart;
+ highlightEnd = highlightRangeEnd;
+ extent += headerSize();
+ }
+ if (haveHighlightRange && highlightRange == QQuickItemView::StrictlyEnforceRange) {
+ extent += highlightStart;
+ FxViewItem *firstItem = visibleItem(0);
+ if (firstItem)
+ extent -= firstItem->sectionSize();
+ extent = isContentFlowReversed()
+ ? qMin(extent, endPositionFirstItem + highlightEnd)
+ : qMax(extent, -(endPositionFirstItem - highlightEnd));
+ }
+ return extent;
+}
+
+qreal QQuickItemViewPrivate::maxExtentForAxis(const AxisData &axisData, bool forXAxis) const
+{
+ Q_Q(const QQuickItemView);
+
+ qreal highlightStart;
+ qreal highlightEnd;
+ qreal lastItemPosition = 0;
+ qreal extent = 0;
+ if (isContentFlowReversed()) {
+ highlightStart = highlightRangeEndValid ? size() - highlightRangeEnd : size();
+ highlightEnd = highlightRangeStartValid ? size() - highlightRangeStart : size();
+ lastItemPosition = endPosition();
+ } else {
+ highlightStart = highlightRangeStart;
+ highlightEnd = highlightRangeEnd;
+ if (model && model->count())
+ lastItemPosition = positionAt(model->count()-1);
+ }
+ if (!model || !model->count()) {
+ if (!isContentFlowReversed())
+ maxExtent = header ? -headerSize() : 0;
+ extent += forXAxis ? q->width() : q->height();
+ } else if (haveHighlightRange && highlightRange == QQuickItemView::StrictlyEnforceRange) {
+ extent = -(lastItemPosition - highlightStart);
+ if (highlightEnd != highlightStart) {
+ extent = isContentFlowReversed()
+ ? qMax(extent, -(endPosition() - highlightEnd))
+ : qMin(extent, -(endPosition() - highlightEnd));
+ }
+ } else {
+ extent = -(endPosition() - (forXAxis ? q->width() : q->height()));
+ }
+ if (isContentFlowReversed()) {
+ extent -= headerSize();
+ extent -= axisData.endMargin;
+ } else {
+ extent -= footerSize();
+ extent -= axisData.endMargin;
+ qreal minExtentAlongAxis = forXAxis ? q->minXExtent() : q->minYExtent();
+ if (extent > minExtentAlongAxis)
+ extent = minExtentAlongAxis;
+ }
+
+ return extent;
+}
+
// for debugging only
void QQuickItemViewPrivate::checkVisible() const
{
@@ -1075,7 +1173,7 @@ void QQuickItemView::animStopped()
{
Q_D(QQuickItemView);
d->bufferMode = QQuickItemViewPrivate::BufferBefore | QQuickItemViewPrivate::BufferAfter;
- d->refill();
+ d->refillOrLayout();
if (d->haveHighlightRange && d->highlightRange == QQuickItemView::StrictlyEnforceRange)
d->updateHighlight();
}
@@ -1119,12 +1217,17 @@ void QQuickItemView::trackedPositionChanged()
toItemEndPos -= startOffset;
} else if (d->showFooterForIndex(d->currentIndex)) {
qreal endOffset = d->footerSize();
- if (d->layoutOrientation() == Qt::Vertical)
- endOffset += d->vData.endMargin;
- else if (d->isContentFlowReversed())
- endOffset += d->hData.startMargin;
- else
- endOffset += d->hData.endMargin;
+ if (d->layoutOrientation() == Qt::Vertical) {
+ if (d->isContentFlowReversed())
+ endOffset += d->vData.startMargin;
+ else
+ endOffset += d->vData.endMargin;
+ } else {
+ if (d->isContentFlowReversed())
+ endOffset += d->hData.startMargin;
+ else
+ endOffset += d->hData.endMargin;
+ }
trackedPos += endOffset;
trackedEndPos += endOffset;
toItemPos += endOffset;
@@ -1166,7 +1269,6 @@ void QQuickItemView::geometryChanged(const QRectF &newGeometry, const QRectF &ol
QQuickFlickable::geometryChanged(newGeometry, oldGeometry);
}
-
qreal QQuickItemView::minYExtent() const
{
Q_D(const QQuickItemView);
@@ -1174,15 +1276,7 @@ qreal QQuickItemView::minYExtent() const
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->minExtent = d->minExtentForAxis(d->vData, false);
d->vData.minExtentDirty = false;
}
@@ -1196,25 +1290,10 @@ qreal QQuickItemView::maxYExtent() const
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->maxExtent = d->maxExtentForAxis(d->vData, false);
d->vData.maxExtentDirty = false;
}
+
return d->maxExtent;
}
@@ -1225,35 +1304,7 @@ qreal QQuickItemView::minXExtent() const
return QQuickFlickable::minXExtent();
if (d->hData.minExtentDirty) {
- d->minExtent = -d->startPosition() + d->hData.startMargin;
- qreal highlightStart;
- qreal highlightEnd;
- qreal endPositionFirstItem = 0;
- if (d->isContentFlowReversed()) {
- 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 {
- 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->minExtent = d->minExtentForAxis(d->hData, true);
d->hData.minExtentDirty = false;
}
@@ -1267,46 +1318,7 @@ qreal QQuickItemView::maxXExtent() const
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.endMargin;
- } else {
- if (d->footer)
- d->maxExtent -= d->footerSize();
- d->maxExtent -= d->hData.endMargin;
- qreal minX = minXExtent();
- if (d->maxExtent > minX)
- d->maxExtent = minX;
- }
+ d->maxExtent = d->maxExtentForAxis(d->hData, true);
d->hData.maxExtentDirty = false;
}
@@ -1338,6 +1350,15 @@ qreal QQuickItemView::xOrigin() const
return -minXExtent() + d->hData.startMargin;
}
+qreal QQuickItemView::yOrigin() const
+{
+ Q_D(const QQuickItemView);
+ if (d->isContentFlowReversed())
+ return -maxYExtent() + d->size() - d->vData.endMargin;
+ else
+ return -minYExtent() + d->vData.startMargin;
+}
+
void QQuickItemView::updatePolish()
{
Q_D(QQuickItemView);
@@ -1385,7 +1406,7 @@ void QQuickItemView::componentComplete()
QQuickItemViewPrivate::QQuickItemViewPrivate()
: itemCount(0)
, buffer(0), bufferMode(BufferBefore | BufferAfter)
- , layoutDirection(Qt::LeftToRight)
+ , layoutDirection(Qt::LeftToRight), verticalLayoutDirection(QQuickItemView::TopToBottom)
, moveReason(Other)
, visibleIndex(0)
, currentIndex(-1), currentItem(0)
@@ -1442,13 +1463,17 @@ qreal QQuickItemViewPrivate::endPosition() const
qreal QQuickItemViewPrivate::contentStartOffset() const
{
qreal pos = -headerSize();
- if (layoutOrientation() == Qt::Vertical)
- pos -= vData.startMargin;
- else if (isContentFlowReversed())
- pos -= hData.endMargin;
- else
- pos -= hData.startMargin;
-
+ if (layoutOrientation() == Qt::Vertical) {
+ if (isContentFlowReversed())
+ pos -= vData.endMargin;
+ else
+ pos -= vData.startMargin;
+ } else {
+ if (isContentFlowReversed())
+ pos -= hData.endMargin;
+ else
+ pos -= hData.startMargin;
+ }
return pos;
}
@@ -1777,7 +1802,7 @@ void QQuickItemViewPrivate::layout()
bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult, ChangeResult *totalRemovalResult)
{
Q_Q(QQuickItemView);
- if (!q->isComponentComplete() || (!currentChanges.hasPendingChanges() && !bufferedChanges.hasPendingChanges() && !runDelayedRemoveTransition) || disableLayout)
+ if (!q->isComponentComplete() || !hasPendingChanges() || disableLayout)
return false;
disableLayout = true;
diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h
index f252fb58f1..89e59306f9 100644
--- a/src/quick/items/qquickitemview_p.h
+++ b/src/quick/items/qquickitemview_p.h
@@ -70,6 +70,7 @@ class Q_AUTOTEST_EXPORT QQuickItemView : public QQuickFlickable
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
+ Q_PROPERTY(VerticalLayoutDirection verticalLayoutDirection READ verticalLayoutDirection WRITE setVerticalLayoutDirection NOTIFY verticalLayoutDirectionChanged)
Q_PROPERTY(QQmlComponent *header READ header WRITE setHeader NOTIFY headerChanged)
Q_PROPERTY(QQuickItem *headerItem READ headerItem NOTIFY headerItemChanged)
@@ -95,8 +96,25 @@ class Q_AUTOTEST_EXPORT QQuickItemView : public QQuickFlickable
Q_ENUMS(HighlightRangeMode)
Q_ENUMS(PositionMode)
+ Q_ENUMS(VerticalLayoutDirection)
+ Q_ENUMS(LayoutDirection)
public:
+ // this holds all layout enum values so they can be referred to by other enums
+ // to ensure consistent values - e.g. QML references to GridView.TopToBottom flow
+ // and GridView.TopToBottom vertical layout direction should have same value
+ enum LayoutDirection {
+ LeftToRight = Qt::LeftToRight,
+ RightToLeft = Qt::RightToLeft,
+ VerticalTopToBottom,
+ VerticalBottomToTop
+ };
+
+ enum VerticalLayoutDirection {
+ TopToBottom = VerticalTopToBottom,
+ BottomToTop = VerticalBottomToTop
+ };
+
QQuickItemView(QQuickFlickablePrivate &dd, QQuickItem *parent = 0);
~QQuickItemView();
@@ -123,6 +141,9 @@ public:
void setLayoutDirection(Qt::LayoutDirection);
Qt::LayoutDirection effectiveLayoutDirection() const;
+ VerticalLayoutDirection verticalLayoutDirection() const;
+ void setVerticalLayoutDirection(VerticalLayoutDirection layoutDirection);
+
QQmlComponent *footer() const;
void setFooter(QQmlComponent *);
QQuickItem *footerItem() const;
@@ -189,6 +210,7 @@ public:
virtual void setContentX(qreal pos);
virtual void setContentY(qreal pos);
virtual qreal xOrigin() const;
+ virtual qreal yOrigin() const;
signals:
void modelChanged();
@@ -202,6 +224,7 @@ signals:
void layoutDirectionChanged();
void effectiveLayoutDirectionChanged();
+ void verticalLayoutDirectionChanged();
void headerChanged();
void footerChanged();
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index e352c461d6..8fc83a99e3 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -204,6 +204,10 @@ public:
void updateUnrequestedPositions();
void updateVisibleIndex();
void positionViewAtIndex(int index, int mode);
+
+ qreal minExtentForAxis(const AxisData &axisData, bool forXAxis) const;
+ qreal maxExtentForAxis(const AxisData &axisData, bool forXAxis) const;
+
void applyPendingChanges();
bool applyModelChanges(ChangeResult *insertionResult, ChangeResult *removalResult);
bool applyRemovalChange(const QQuickChangeSet::Remove &removal, ChangeResult *changeResult, int *removedCount);
@@ -229,12 +233,26 @@ public:
hData.markExtentsDirty();
}
+ bool hasPendingChanges() const {
+ return currentChanges.hasPendingChanges()
+ || bufferedChanges.hasPendingChanges()
+ ||runDelayedRemoveTransition;
+ }
+
+ void refillOrLayout() {
+ if (hasPendingChanges())
+ layout();
+ else
+ refill();
+ }
+
QQmlGuard<QQuickVisualModel> model;
QVariant modelVariant;
int itemCount;
int buffer;
int bufferMode;
Qt::LayoutDirection layoutDirection;
+ QQuickItemView::VerticalLayoutDirection verticalLayoutDirection;
MovementReason moveReason;
diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h
index 9e17385c46..0ec87ba51c 100644
--- a/src/quick/items/qquickitemviewtransition_p.h
+++ b/src/quick/items/qquickitemviewtransition_p.h
@@ -147,11 +147,11 @@ public:
QQuickItem *item;
QQuickItemViewTransitionJob *transition;
QQuickItemViewTransitioner::TransitionType nextTransitionType;
- bool isTransitionTarget;
- bool nextTransitionToSet;
- bool nextTransitionFromSet;
- bool lastMovedToSet;
- bool prepared;
+ bool isTransitionTarget : 1;
+ bool nextTransitionToSet : 1;
+ bool nextTransitionFromSet : 1;
+ bool lastMovedToSet : 1;
+ bool prepared : 1;
private:
friend class QQuickItemViewTransitioner;
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 1cc2637fe6..df50d3eb8c 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -73,6 +73,7 @@ public:
virtual Qt::Orientation layoutOrientation() const;
virtual bool isContentFlowReversed() const;
bool isRightToLeft() const;
+ bool isBottomToTop() const;
virtual qreal positionAt(int index) const;
virtual qreal endPositionAt(int index) const;
@@ -265,7 +266,7 @@ public:
qreal position() const {
if (section()) {
if (view->orientation() == QQuickListView::Vertical)
- return section()->y();
+ return (view->verticalLayoutDirection() == QQuickItemView::BottomToTop ? -section()->height()-section()->y() : section()->y());
else
return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -section()->width()-section()->x() : section()->x());
} else {
@@ -274,7 +275,7 @@ public:
}
qreal itemPosition() const {
if (view->orientation() == QQuickListView::Vertical)
- return itemY();
+ return (view->verticalLayoutDirection() == QQuickItemView::BottomToTop ? -item->height()-itemY() : itemY());
else
return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -item->width()-itemX() : itemX());
}
@@ -294,7 +295,9 @@ public:
}
qreal endPosition() const {
if (view->orientation() == QQuickListView::Vertical) {
- return itemY() + item->height();
+ return (view->verticalLayoutDirection() == QQuickItemView::BottomToTop
+ ? -itemY()
+ : itemY() + item->height());
} else {
return (view->effectiveLayoutDirection() == Qt::RightToLeft
? -itemX()
@@ -305,7 +308,10 @@ public:
// position the section immediately even if there is a transition
if (section()) {
if (view->orientation() == QQuickListView::Vertical) {
- section()->setY(pos);
+ if (view->verticalLayoutDirection() == QQuickItemView::BottomToTop)
+ section()->setY(-section()->height()-pos);
+ else
+ section()->setY(pos);
} else {
if (view->effectiveLayoutDirection() == Qt::RightToLeft)
section()->setX(-section()->width()-pos);
@@ -331,9 +337,15 @@ public:
private:
QPointF pointForPosition(qreal pos) const {
if (view->orientation() == QQuickListView::Vertical) {
- if (section())
- pos += section()->height();
- return QPointF(itemX(), pos);
+ if (view->verticalLayoutDirection() == QQuickItemView::BottomToTop) {
+ if (section())
+ pos += section()->height();
+ return QPointF(itemX(), -item->height() - pos);
+ } else {
+ if (section())
+ pos += section()->height();
+ return QPointF(itemX(), pos);
+ }
} else {
if (view->effectiveLayoutDirection() == Qt::RightToLeft) {
if (section())
@@ -352,7 +364,7 @@ private:
bool QQuickListViewPrivate::isContentFlowReversed() const
{
- return isRightToLeft();
+ return isRightToLeft() || isBottomToTop();
}
Qt::Orientation QQuickListViewPrivate::layoutOrientation() const
@@ -366,6 +378,11 @@ bool QQuickListViewPrivate::isRightToLeft() const
return orient == QQuickListView::Horizontal && q->effectiveLayoutDirection() == Qt::RightToLeft;
}
+bool QQuickListViewPrivate::isBottomToTop() const
+{
+ return orient == QQuickListView::Vertical && verticalLayoutDirection == QQuickItemView::BottomToTop;
+}
+
// Returns the item before modelIndex, if created.
// May return an item marked for removal.
FxViewItem *QQuickListViewPrivate::itemBefore(int modelIndex) const
@@ -391,7 +408,10 @@ void QQuickListViewPrivate::setPosition(qreal pos)
{
Q_Q(QQuickListView);
if (orient == QQuickListView::Vertical) {
- q->QQuickFlickable::setContentY(pos);
+ if (isBottomToTop())
+ q->QQuickFlickable::setContentY(-pos-size());
+ else
+ q->QQuickFlickable::setContentY(pos);
} else {
if (isRightToLeft())
q->QQuickFlickable::setContentX(-pos-size());
@@ -797,8 +817,12 @@ 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));
+ if (item->y() + item->height() > pos && item->y() < pos + q->height()) {
+ if (isBottomToTop())
+ item->setY(-positionAt(index)-item->height());
+ else
+ item->setY(positionAt(index));
+ }
} else {
if (item->x() + item->width() > pos && item->x() < pos + q->width()) {
if (isRightToLeft())
@@ -880,7 +904,7 @@ void QQuickListViewPrivate::updateHighlight()
if (currentItem && autoHighlight && highlight && (!strictHighlight || !pressed)) {
// auto-update highlight
FxListItemSG *listItem = static_cast<FxListItemSG*>(currentItem);
- highlightPosAnimator->to = isRightToLeft()
+ highlightPosAnimator->to = isContentFlowReversed()
? -listItem->itemPosition()-listItem->itemSize()
: listItem->itemPosition();
highlightSizeAnimator->to = listItem->itemSize();
@@ -987,8 +1011,8 @@ void QQuickListViewPrivate::updateStickySections()
|| (!sectionCriteria->labelPositioning() && !currentSectionItem && !nextSectionItem))
return;
- bool isRtl = isRightToLeft();
- qreal viewPos = isRightToLeft() ? -position()-size() : position();
+ bool isFlowReversed = isContentFlowReversed();
+ qreal viewPos = isFlowReversed ? -position()-size() : position();
QQuickItem *sectionItem = 0;
QQuickItem *lastSectionItem = 0;
int index = 0;
@@ -1000,14 +1024,14 @@ void QQuickListViewPrivate::updateStickySections()
qreal sectionSize = orient == QQuickListView::Vertical ? section->height() : section->width();
bool visTop = true;
if (sectionCriteria->labelPositioning() & QQuickViewSection::CurrentLabelAtStart)
- visTop = isRtl ? -sectionPos-sectionSize >= viewPos : sectionPos >= viewPos;
+ visTop = isFlowReversed ? -sectionPos-sectionSize >= viewPos : sectionPos >= viewPos;
bool visBot = true;
if (sectionCriteria->labelPositioning() & QQuickViewSection::NextLabelAtEnd)
- visBot = isRtl ? -sectionPos <= viewPos + size() : sectionPos + sectionSize < viewPos + size();
+ visBot = isFlowReversed ? -sectionPos <= viewPos + size() : sectionPos + sectionSize < viewPos + size();
section->setVisible(visBot && visTop);
if (visTop && !sectionItem)
sectionItem = section;
- if (isRtl) {
+ if (isFlowReversed) {
if (-sectionPos <= viewPos + size())
lastSectionItem = section;
} else {
@@ -1031,17 +1055,18 @@ void QQuickListViewPrivate::updateStickySections()
return;
qreal sectionSize = orient == QQuickListView::Vertical ? currentSectionItem->height() : currentSectionItem->width();
- bool atBeginning = orient == QQuickListView::Vertical ? vData.atBeginning : (isRightToLeft() ? hData.atEnd : hData.atBeginning);
+ bool atBeginning = orient == QQuickListView::Vertical ? (isBottomToTop() ? vData.atEnd : vData.atBeginning) : (isRightToLeft() ? hData.atEnd : hData.atBeginning);
+
currentSectionItem->setVisible(!atBeginning && (!header || header->endPosition() < viewPos));
- qreal pos = isRtl ? position() + size() - sectionSize : viewPos;
+ qreal pos = isFlowReversed ? 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);
+ pos = isFlowReversed ? qMax(pos, sectionPos + sectionSize) : qMin(pos, sectionPos - sectionSize);
}
if (header)
- pos = isRtl ? qMin(header->endPosition(), pos) : qMax(header->endPosition(), pos);
+ pos = isFlowReversed ? qMin(header->endPosition(), pos) : qMax(header->endPosition(), pos);
if (footer)
- pos = isRtl ? qMax(-footer->position(), pos) : qMin(footer->position() - sectionSize, pos);
+ pos = isFlowReversed ? qMax(-footer->position(), pos) : qMin(footer->position() - sectionSize, pos);
if (orient == QQuickListView::Vertical)
currentSectionItem->setY(pos);
else
@@ -1065,13 +1090,13 @@ void QQuickListViewPrivate::updateStickySections()
qreal sectionSize = orient == QQuickListView::Vertical ? nextSectionItem->height() : nextSectionItem->width();
nextSectionItem->setVisible(!nextSection.isEmpty());
- qreal pos = isRtl ? position() : viewPos + size() - sectionSize;
+ qreal pos = isFlowReversed ? 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);
+ pos = isFlowReversed ? qMin(pos, sectionPos - sectionSize) : qMax(pos, sectionPos + sectionSize);
}
if (header)
- pos = isRtl ? qMin(header->endPosition() - sectionSize, pos) : qMax(header->endPosition(), pos);
+ pos = isFlowReversed ? qMin(header->endPosition() - sectionSize, pos) : qMax(header->endPosition(), pos);
if (orient == QQuickListView::Vertical)
nextSectionItem->setY(pos);
else
@@ -1162,7 +1187,7 @@ void QQuickListViewPrivate::updateCurrentSection()
// section when that changes. Clearing lastVisibleSection will also
// force searching.
QString lastSection = currentSection;
- qreal endPos = isRightToLeft() ? -position() : position() + size();
+ qreal endPos = isContentFlowReversed() ? -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) {
@@ -1341,10 +1366,10 @@ void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte
fixupMode = moveReason == Mouse ? fixupMode : Immediate;
bool strictHighlightRange = haveHighlightRange && highlightRange == QQuickListView::StrictlyEnforceRange;
- qreal viewPos = isRightToLeft() ? -position()-size() : position();
+ qreal viewPos = isContentFlowReversed() ? -position()-size() : position();
if (snapMode != QQuickListView::NoSnap && moveReason != QQuickListViewPrivate::SetIndex) {
- qreal tempPosition = isRightToLeft() ? -position()-size() : position();
+ qreal tempPosition = isContentFlowReversed() ? -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);
@@ -1353,7 +1378,7 @@ void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte
bias = averageSize/2;
else if (data.velocity < 0 && dist < -QML_FLICK_SNAPONETHRESHOLD && dist > -averageSize/2)
bias = -averageSize/2;
- if (isRightToLeft())
+ if (isContentFlowReversed())
bias = -bias;
tempPosition -= bias;
}
@@ -1373,15 +1398,15 @@ void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte
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;
+ pos = isContentFlowReversed() ? - header->position() + highlightRangeStart - size() : header->position() - highlightRangeStart;
} else {
- if (isRightToLeft())
+ if (isContentFlowReversed())
pos = qMax(qMin(-topItem->position() + highlightRangeStart - size(), -maxExtent), -minExtent);
else
pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent);
}
} else if (bottomItem && isInBounds) {
- if (isRightToLeft())
+ if (isContentFlowReversed())
pos = qMax(qMin(-bottomItem->position() + highlightRangeEnd - size(), -maxExtent), -minExtent);
else
pos = qMax(qMin(bottomItem->position() - highlightRangeEnd, -maxExtent), -minExtent);
@@ -1408,7 +1433,7 @@ void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte
viewPos = pos + static_cast<FxListItemSG*>(currentItem)->itemSize() - highlightRangeEnd;
if (viewPos > pos - highlightRangeStart)
viewPos = pos - highlightRangeStart;
- if (isRightToLeft())
+ if (isContentFlowReversed())
viewPos = -viewPos-size();
timeline.reset(data.move);
@@ -1441,7 +1466,7 @@ void QQuickListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte
return;
}
qreal maxDistance = 0;
- qreal dataValue = isRightToLeft() ? -data.move.value()+size() : data.move.value();
+ qreal dataValue = isContentFlowReversed() ? -data.move.value()+size() : data.move.value();
// -ve velocity means list is moving up/left
if (velocity > 0) {
@@ -1450,7 +1475,7 @@ void QQuickListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte
// 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())
+ if (isContentFlowReversed())
bias = -bias;
data.flickTarget = -snapPosAt(-(dataValue - highlightRangeStart) - bias) + highlightRangeStart;
maxDistance = qAbs(data.flickTarget - data.move.value());
@@ -1467,7 +1492,7 @@ void QQuickListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte
// 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())
+ if (isContentFlowReversed())
bias = -bias;
data.flickTarget = -snapPosAt(-(dataValue - highlightRangeStart) + bias) + highlightRangeStart;
maxDistance = qAbs(data.flickTarget - data.move.value());
@@ -1505,10 +1530,10 @@ void QQuickListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte
dist = -dist;
if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QQuickListView::SnapOneItem) {
if (snapMode != QQuickListView::SnapOneItem) {
- qreal distTemp = isRightToLeft() ? -dist : dist;
+ qreal distTemp = isContentFlowReversed() ? -dist : dist;
data.flickTarget = -snapPosAt(-(dataValue - highlightRangeStart) + distTemp) + highlightRangeStart;
}
- data.flickTarget = isRightToLeft() ? -data.flickTarget+size() : data.flickTarget;
+ data.flickTarget = isContentFlowReversed() ? -data.flickTarget+size() : data.flickTarget;
if (overShoot) {
if (data.flickTarget >= minExtent) {
overshootDist = overShootDistance(vSize);
@@ -1561,9 +1586,9 @@ void QQuickListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte
// reevaluate the target boundary.
qreal newtarget = data.flickTarget;
if (snapMode != QQuickListView::NoSnap || highlightRange == QQuickListView::StrictlyEnforceRange) {
- qreal tempFlickTarget = isRightToLeft() ? -data.flickTarget+size() : data.flickTarget;
+ qreal tempFlickTarget = isContentFlowReversed() ? -data.flickTarget+size() : data.flickTarget;
newtarget = -snapPosAt(-(tempFlickTarget - highlightRangeStart)) + highlightRangeStart;
- newtarget = isRightToLeft() ? -newtarget+size() : newtarget;
+ newtarget = isContentFlowReversed() ? -newtarget+size() : newtarget;
}
if (velocity < 0 && newtarget <= maxExtent)
newtarget = maxExtent - overshootDist;
@@ -1655,6 +1680,45 @@ void QQuickListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExte
to set \e {clip: true} in order to have the out of view items clipped
nicely.
+
+ \section1 ListView layouts
+
+ The layout of the items in a ListView can be controlled by these properties:
+
+ \list
+ \li \l orientation - controls whether items flow horizontally or vertically.
+ This value can be either Qt.Horizontal or Qt.Vertical.
+ \li \l layoutDirection - controls the horizontal layout direction for a
+ horizontally-oriented view: that is, whether items are laid out from the left side of
+ the view to the right, or vice-versa. This value can be either Qt.LeftToRight or Qt.RightToLeft.
+ \li \l verticalLayoutDirection - controls the vertical layout direction for a vertically-oriented
+ view: that is, whether items are laid out from the top of the view down towards the bottom of
+ the view, or vice-versa. This value can be either ListView.TopToBottom or ListView.BottomToTop.
+ \endlist
+
+ By default, a ListView has a vertical orientation, and items are laid out from top to bottom. The
+ table below shows the different layouts that a ListView can have, depending on the values of
+ the properties listed above.
+
+ \table
+ \header
+ \li {2, 1}
+ \bold ListViews with Qt.Vertical orientation
+ \row
+ \li Top to bottom
+ \image listview-layout-toptobottom.png
+ \li Bottom to top
+ \image listview-layout-bottomtotop.png
+ \header
+ \li {2, 1}
+ \bold ListViews with Qt.Horizontal orientation
+ \row
+ \li Left to right
+ \image listview-layout-lefttoright.png
+ \li Right to left
+ \image listview-layout-righttoleft.png
+ \endtable
+
\sa {QML Data Models}, GridView, {declarative/modelviews/listview}{ListView examples}
*/
QQuickListView::QQuickListView(QQuickItem *parent)
@@ -1956,7 +2020,7 @@ void QQuickListView::setOrientation(QQuickListView::Orientation orientation)
/*!
\qmlproperty enumeration QtQuick2::ListView::layoutDirection
- This property holds the layout direction of the horizontal list.
+ This property holds the layout direction of a horizontally-oriented list.
Possible values:
@@ -1965,13 +2029,15 @@ void QQuickListView::setOrientation(QQuickListView::Orientation orientation)
\li Qt.RightToLeft - Items will be laid out from right to let.
\endlist
- \sa ListView::effectiveLayoutDirection
+ Setting this property has no effect if the \l orientation is Qt.Vertical.
+
+ \sa ListView::effectiveLayoutDirection, ListView::verticalLayoutDirection
*/
/*!
\qmlproperty enumeration QtQuick2::ListView::effectiveLayoutDirection
- This property holds the effective layout direction of the horizontal list.
+ This property holds the effective layout direction of a horizontally-oriented 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
@@ -1980,6 +2046,24 @@ void QQuickListView::setOrientation(QQuickListView::Orientation orientation)
\sa ListView::layoutDirection, {LayoutMirroring}{LayoutMirroring}
*/
+
+/*!
+ \qmlproperty enumeration QtQuick2::ListView::verticalLayoutDirection
+ This property holds the layout direction of a vertically-oriented list.
+
+ Possible values:
+
+ \list
+ \li ListView.TopToBottom (default) - Items are laid out from the top of the view down to the bottom of the view.
+ \li ListView.BottomToTop - Items are laid out from the bottom of the view up to the top of the view.
+ \endlist
+
+ Setting this property has no effect if the \l orientation is Qt.Horizontal.
+
+ \sa ListView::layoutDirection
+*/
+
+
/*!
\qmlproperty bool QtQuick2::ListView::keyNavigationWraps
This property holds whether the list wraps key navigation.
@@ -2550,14 +2634,19 @@ void QQuickListView::viewportMoved()
return;
d->inViewportMoved = true;
- if (yflick())
- d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickListViewPrivate::BufferBefore : QQuickListViewPrivate::BufferAfter;
- else if (d->isRightToLeft())
- d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickListViewPrivate::BufferAfter : QQuickListViewPrivate::BufferBefore;
- else
- d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickListViewPrivate::BufferBefore : QQuickListViewPrivate::BufferAfter;
+ if (yflick()) {
+ if (d->isBottomToTop())
+ d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickListViewPrivate::BufferAfter : QQuickListViewPrivate::BufferBefore;
+ else
+ d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickListViewPrivate::BufferBefore : QQuickListViewPrivate::BufferAfter;
+ } else {
+ if (d->isRightToLeft())
+ d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickListViewPrivate::BufferAfter : QQuickListViewPrivate::BufferBefore;
+ else
+ d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickListViewPrivate::BufferBefore : QQuickListViewPrivate::BufferAfter;
+ }
- d->refill();
+ d->refillOrLayout();
// Set visibility of items to eliminate cost of items outside the visible area.
qreal from = d->isContentFlowReversed() ? -d->position()-d->size() : d->position();
@@ -2575,7 +2664,7 @@ void QQuickListView::viewportMoved()
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();
+ qreal viewPos = d->isContentFlowReversed() ? -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)
@@ -2641,7 +2730,8 @@ void QQuickListView::keyPressEvent(QKeyEvent *event)
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)) {
+ || (d->orient == QQuickListView::Vertical && !d->isBottomToTop() && event->key() == Qt::Key_Up)
+ || (d->orient == QQuickListView::Vertical && d->isBottomToTop() && event->key() == Qt::Key_Down)) {
if (currentIndex() > 0 || (d->wrap && !event->isAutoRepeat())) {
decrementCurrentIndex();
event->accept();
@@ -2652,7 +2742,8 @@ void QQuickListView::keyPressEvent(QKeyEvent *event)
}
} 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)) {
+ || (d->orient == QQuickListView::Vertical && !d->isBottomToTop() && event->key() == Qt::Key_Down)
+ || (d->orient == QQuickListView::Vertical && d->isBottomToTop() && event->key() == Qt::Key_Up)) {
if (currentIndex() < d->model->count() - 1 || (d->wrap && !event->isAutoRepeat())) {
incrementCurrentIndex();
event->accept();
@@ -2670,10 +2761,14 @@ void QQuickListView::keyPressEvent(QKeyEvent *event)
void QQuickListView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickListView);
- if (d->isRightToLeft() && d->orient == QQuickListView::Horizontal) {
+ if (d->isRightToLeft()) {
// maintain position relative to the right edge
int dx = newGeometry.width() - oldGeometry.width();
setContentX(contentX() - dx);
+ } else if (d->isBottomToTop()) {
+ // maintain position relative to the bottom edge
+ int dy = newGeometry.height() - oldGeometry.height();
+ setContentY(contentY() - dy);
}
QQuickItemView::geometryChanged(newGeometry, oldGeometry);
}
@@ -2740,7 +2835,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert &
int modelIndex = change.index;
int count = change.count;
- qreal tempPos = isRightToLeft() ? -position()-size() : position();
+ qreal tempPos = isContentFlowReversed() ? -position()-size() : position();
int index = visibleItems.count() ? mapFromModel(modelIndex) : 0;
if (index < 0) {
diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h
index 32f12fad30..541bb34a2e 100644
--- a/src/quick/items/qquickshadereffect_p.h
+++ b/src/quick/items/qquickshadereffect_p.h
@@ -45,6 +45,7 @@
#include <QtQuick/qquickitem.h>
#include <QtQuick/qsgmaterial.h>
+#include <private/qtquickglobal_p.h>
#include <private/qsgadaptationlayer_p.h>
#include <private/qquickshadereffectnode_p.h>
#include "qquickshadereffectmesh_p.h"
@@ -63,7 +64,7 @@ class QSignalMapper;
class QQuickCustomMaterialShader;
// Common class for QQuickShaderEffect and QQuickCustomParticle.
-struct QQuickShaderEffectCommon
+struct Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectCommon
{
typedef QQuickShaderEffectMaterialKey Key;
typedef QQuickShaderEffectMaterial::UniformData UniformData;
@@ -90,7 +91,7 @@ struct QQuickShaderEffectCommon
};
-class Q_AUTOTEST_EXPORT QQuickShaderEffect : public QQuickItem
+class Q_QUICK_EXPORT QQuickShaderEffect : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(QByteArray fragmentShader READ fragmentShader WRITE setFragmentShader NOTIFY fragmentShaderChanged)
diff --git a/src/quick/items/qquickshadereffectnode_p.h b/src/quick/items/qquickshadereffectnode_p.h
index 1bbce86426..2b2aab5365 100644
--- a/src/quick/items/qquickshadereffectnode_p.h
+++ b/src/quick/items/qquickshadereffectnode_p.h
@@ -46,6 +46,7 @@
#include <QtQuick/qsgmaterial.h>
#include <QtQuick/qsgtextureprovider.h>
#include <QtQuick/qquickitem.h>
+#include <private/qtquickglobal_p.h>
#include <QtCore/qsharedpointer.h>
#include <QtCore/qpointer.h>
@@ -73,7 +74,7 @@ uint qHash(const QQuickShaderEffectMaterialKey &key);
class QQuickCustomMaterialShader;
class QQuickShaderEffectNode;
-class QQuickShaderEffectMaterial : public QSGMaterial
+class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectMaterial : public QSGMaterial
{
public:
struct UniformData
@@ -127,7 +128,7 @@ protected:
class QSGShaderEffectMesh;
-class QQuickShaderEffectNode : public QObject, public QSGGeometryNode
+class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectNode : public QObject, public QSGGeometryNode
{
Q_OBJECT
public:
diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp
index 900cb84de8..8904a83176 100644
--- a/src/quick/items/qquickspriteengine.cpp
+++ b/src/quick/items/qquickspriteengine.cpp
@@ -621,7 +621,7 @@ uint QQuickStochasticEngine::updateSprites(uint time)//### would returning a lis
m_advanceTime.start();
m_addAdvance = true;
if (m_stateUpdates.isEmpty())
- return -1;
+ return uint(-1);
return m_stateUpdates.first().first;
}
diff --git a/src/quick/items/qquickspriteengine_p.h b/src/quick/items/qquickspriteengine_p.h
index 00cefbfbc0..f6ef79ca50 100644
--- a/src/quick/items/qquickspriteengine_p.h
+++ b/src/quick/items/qquickspriteengine_p.h
@@ -50,14 +50,15 @@
#include <QQmlListProperty>
#include <QImage>
#include <QPair>
-#include <QtQuick/private/qquickpixmapcache_p.h>
+#include <private/qquickpixmapcache_p.h>
+#include <private/qtquickglobal_p.h>
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
class QQuickSprite;
-class Q_AUTOTEST_EXPORT QQuickStochasticState : public QObject //Currently for internal use only - Sprite and ParticleGroup
+class Q_QUICK_PRIVATE_EXPORT QQuickStochasticState : public QObject //Currently for internal use only - Sprite and ParticleGroup
{
Q_OBJECT
Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
@@ -173,7 +174,7 @@ private:
bool m_randomStart;
};
-class Q_AUTOTEST_EXPORT QQuickStochasticEngine : public QObject
+class Q_QUICK_PRIVATE_EXPORT QQuickStochasticEngine : public QObject
{
Q_OBJECT
//TODO: Optimize single state case?
@@ -252,7 +253,7 @@ protected:
bool m_addAdvance;
};
-class QQuickSpriteEngine : public QQuickStochasticEngine
+class Q_QUICK_PRIVATE_EXPORT QQuickSpriteEngine : public QQuickStochasticEngine
{
Q_OBJECT
Q_PROPERTY(QQmlListProperty<QQuickSprite> sprites READ sprites)
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 24dd10ac9f..f34c062c98 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -382,6 +382,22 @@ void QQuickText::imageDownloadFinished()
}
}
+void QQuickTextPrivate::updateBaseline(qreal baseline, qreal dy)
+{
+ Q_Q(QQuickText);
+
+ qreal yoff = 0;
+
+ if (q->heightValid()) {
+ if (vAlign == QQuickText::AlignBottom)
+ yoff = dy;
+ else if (vAlign == QQuickText::AlignVCenter)
+ yoff = dy/2;
+ }
+
+ q->setBaselineOffset(baseline + yoff);
+}
+
void QQuickTextPrivate::updateSize()
{
Q_Q(QQuickText);
@@ -398,9 +414,19 @@ void QQuickTextPrivate::updateSize()
return;
}
- QFontMetricsF fm(font);
- if (text.isEmpty()) {
- qreal fontHeight = fm.height();
+ if (text.isEmpty() && !isLineLaidOutConnected() && fontSizeMode() == QQuickText::FixedSize) {
+ // How much more expensive is it to just do a full layout on an empty string here?
+ // There may be subtle differences in the height and baseline calculations between
+ // QTextLayout and QFontMetrics and the number of variables that can affect the size
+ // and position of a line is increasing.
+ QFontMetricsF fm(font);
+ qreal fontHeight = qCeil(fm.height()); // QScriptLine and therefore QTextLine rounds up
+ if (!richText) { // line height, so we will as well.
+ fontHeight = lineHeightMode() == QQuickText::FixedHeight
+ ? lineHeight()
+ : fontHeight * lineHeight();
+ }
+ updateBaseline(fm.ascent(), q->height() - fontHeight);
q->setImplicitSize(0, fontHeight);
layedOutTextRect = QRectF(0, 0, 0, fontHeight);
emit q->contentSizeChanged();
@@ -411,7 +437,6 @@ void QQuickTextPrivate::updateSize()
qreal naturalWidth = 0;
- qreal dy = q->height();
QSizeF size(0, 0);
QSizeF previousSize = layedOutTextRect.size();
#if defined(Q_OS_MAC)
@@ -420,14 +445,15 @@ void QQuickTextPrivate::updateSize()
//setup instance of QTextLayout for all cases other than richtext
if (!richText) {
- QRectF textRect = setupTextLayout(&naturalWidth);
+ qreal baseline = 0;
+ QRectF textRect = setupTextLayout(&naturalWidth, &baseline);
if (internalWidthUpdate) // probably the result of a binding loop, but by letting it
return; // get this far we'll get a warning to that effect if it is.
layedOutTextRect = textRect;
size = textRect.size();
- dy -= size.height();
+ updateBaseline(baseline, q->height() - size.height());
} else {
singleline = false; // richtext can't elide or be optimized for single-line case
ensureDoc();
@@ -458,20 +484,13 @@ void QQuickTextPrivate::updateSize()
extra->doc->setTextWidth(q->width());
else
extra->doc->setTextWidth(extra->doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug)
- dy -= extra->doc->size().height();
QSizeF dsize = extra->doc->size();
layedOutTextRect = QRectF(QPointF(0,0), dsize);
size = QSizeF(extra->doc->idealWidth(),dsize.height());
- }
- qreal yoff = 0;
- if (q->heightValid()) {
- if (vAlign == QQuickText::AlignBottom)
- yoff = dy;
- else if (vAlign == QQuickText::AlignVCenter)
- yoff = dy/2;
+ QFontMetricsF fm(font);
+ updateBaseline(fm.ascent(), q->height() - size.height());
}
- q->setBaselineOffset(fm.ascent() + yoff);
//### need to comfirm cost of always setting these for richText
internalWidthUpdate = true;
@@ -669,7 +688,7 @@ QString QQuickTextPrivate::elidedText(qreal lineWidth, const QTextLine &line, QT
already absolutely positioned horizontally).
*/
-QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
+QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *const baseline)
{
Q_Q(QQuickText);
layout.setCacheEnabled(true);
@@ -712,9 +731,10 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
internalWidthUpdate = wasInLayout;
}
- QFontMetrics fm(font);
+ QFontMetricsF fm(font);
qreal height = (lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : fm.height() * lineHeight();
- return QRect(0, 0, 0, height);
+ *baseline = fm.ascent();
+ return QRectF(0, 0, 0, height);
}
qreal lineWidth = q->widthValid() && q->width() > 0 ? q->width() : FLT_MAX;
@@ -893,12 +913,13 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
QTextLayout widthLayout(layoutText.mid(characterCount), scaledFont);
widthLayout.setTextOption(layout.textOption());
+ widthLayout.beginLayout();
for (; unwrappedLineCount <= maxLineCount; ++unwrappedLineCount) {
QTextLine line = widthLayout.createLine();
if (!line.isValid())
break;
}
-
+ widthLayout.endLayout();
*naturalWidth = qMax(*naturalWidth, widthLayout.maximumWidth());
}
@@ -1024,6 +1045,12 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
elideLayout = 0;
}
+ QTextLine firstLine = visibleCount == 1 && elideLayout
+ ? elideLayout->lineAt(0)
+ : layout.lineAt(0);
+ Q_ASSERT(firstLine.isValid());
+ *baseline = firstLine.y() + firstLine.ascent();
+
if (!customLayout)
br.setHeight(height);
diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h
index d73c6e1a10..e643d1dfb9 100644
--- a/src/quick/items/qquicktext_p.h
+++ b/src/quick/items/qquicktext_p.h
@@ -245,7 +245,7 @@ private:
};
class QTextLine;
-class Q_AUTOTEST_EXPORT QQuickTextLine : public QObject
+class Q_QUICK_EXPORT QQuickTextLine : public QObject
{
Q_OBJECT
Q_PROPERTY(int number READ number)
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index 0425c37406..cfa37789cc 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -75,6 +75,7 @@ public:
~QQuickTextPrivate();
void init();
+ void updateBaseline(qreal baseline, qreal dy);
void updateSize();
void updateLayout();
bool determineHorizontalAlignment();
@@ -163,7 +164,7 @@ public:
void ensureDoc();
- QRectF setupTextLayout(qreal *const naturalWidth);
+ QRectF setupTextLayout(qreal *const naturalWidth, qreal * const baseline);
void setupCustomLineGeometry(QTextLine &line, qreal &height, int lineOffset = 0);
bool isLinkActivatedConnected();
QString anchorAt(const QPointF &pos);
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index 739b5f859b..f63e6a7523 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -46,7 +46,6 @@
#include <qcoreapplication.h>
#include <qfont.h>
-#include <qpainter.h>
#include <qevent.h>
#include <qdebug.h>
#include <qdrag.h>
@@ -60,8 +59,6 @@
#include "qtextlist.h"
#include "qtextdocumentwriter.h"
#include "private/qtextcursor_p.h"
-#include "qpagedpaintdevice.h"
-#include "private/qpagedpaintdevice_p.h"
#include <qtextformat.h>
#include <qdatetime.h>
@@ -429,8 +426,11 @@ void QQuickTextControlPrivate::repaintOldAndNewSelection(const QTextCursor &oldS
void QQuickTextControlPrivate::selectionChanged(bool forceEmitSelectionChanged /*=false*/)
{
Q_Q(QQuickTextControl);
- if (forceEmitSelectionChanged)
+ if (forceEmitSelectionChanged) {
+ if (hasFocus)
+ qGuiApp->inputMethod()->update(Qt::ImCurrentSelection);
emit q->selectionChanged();
+ }
bool current = cursor.hasSelection();
if (current == lastSelectionState)
@@ -438,8 +438,11 @@ void QQuickTextControlPrivate::selectionChanged(bool forceEmitSelectionChanged /
lastSelectionState = current;
emit q->copyAvailable(current);
- if (!forceEmitSelectionChanged)
+ if (!forceEmitSelectionChanged) {
+ if (hasFocus)
+ qGuiApp->inputMethod()->update(Qt::ImCurrentSelection);
emit q->selectionChanged();
+ }
emit q->cursorRectangleChanged();
}
diff --git a/src/quick/items/qquicktextcontrol_p.h b/src/quick/items/qquicktextcontrol_p.h
index be3f7f7ccf..aae9e12dad 100644
--- a/src/quick/items/qquicktextcontrol_p.h
+++ b/src/quick/items/qquicktextcontrol_p.h
@@ -74,7 +74,6 @@ class QQuickTextControlPrivate;
class QAbstractScrollArea;
class QEvent;
class QTimerEvent;
-class QPagedPaintDevice;
class Q_AUTOTEST_EXPORT QQuickTextControl : public QObject
{
@@ -122,7 +121,6 @@ public:
virtual int hitTest(const QPointF &point, Qt::HitTestAccuracy accuracy) const;
virtual QRectF blockBoundingRect(const QTextBlock &block) const;
- QAbstractTextDocumentLayout::PaintContext getPaintContext() const;
public Q_SLOTS:
void setPlainText(const QString &text);
diff --git a/src/quick/items/qquickwindowmanager.cpp b/src/quick/items/qquickwindowmanager.cpp
index d075d3b64b..45a379a1c0 100644
--- a/src/quick/items/qquickwindowmanager.cpp
+++ b/src/quick/items/qquickwindowmanager.cpp
@@ -404,7 +404,7 @@ void QQuickRenderThreadSingleContextWindowManager::handleAddedWindow(QQuickCanva
CanvasData *data = new CanvasData;
data->sizeWasChanged = false;
data->windowSize = canvas->size();
- data->isVisible = canvas->visible();
+ data->isVisible = canvas->isVisible();
m_rendered_windows[canvas] = data;
isExternalUpdatePending = true;
@@ -516,7 +516,7 @@ void QQuickRenderThreadSingleContextWindowManager::canvasVisibilityChanged()
CanvasTracker &t = const_cast<CanvasTracker &>(m_tracked_windows.at(i));
QQuickCanvas *win = t.canvas;
- Q_ASSERT(win->visible() || QQuickCanvasPrivate::get(win)->renderWithoutShowing || t.toBeRemoved);
+ Q_ASSERT(win->isVisible() || QQuickCanvasPrivate::get(win)->renderWithoutShowing || t.toBeRemoved);
bool canvasVisible = win->width() > 0 && win->height() > 0;
anyoneShowing |= (canvasVisible && !t.toBeRemoved);
@@ -1121,7 +1121,7 @@ void QQuickRenderThreadSingleContextWindowManager::wakeup()
{
lockInGui();
isExternalUpdatePending = true;
- if (isRenderBlocked || isPostingSyncEvent)
+ if (isRenderBlocked)
wake();
unlockInGui();
}
@@ -1173,11 +1173,11 @@ void QQuickTrivialWindowManager::renderCanvas(QQuickCanvas *canvas)
CanvasData &data = const_cast<CanvasData &>(m_windows[canvas]);
QQuickCanvas *masterCanvas = 0;
- if (!canvas->visible()) {
+ if (!canvas->isVisible()) {
// Find a "proper surface" to bind...
for (QHash<QQuickCanvas *, CanvasData>::const_iterator it = m_windows.constBegin();
it != m_windows.constEnd() && !masterCanvas; ++it) {
- if (it.key()->visible())
+ if (it.key()->isVisible())
masterCanvas = it.key();
}
} else {
@@ -1211,7 +1211,7 @@ void QQuickTrivialWindowManager::renderCanvas(QQuickCanvas *canvas)
data.grabOnly = false;
}
- if (alsoSwap && canvas->visible()) {
+ if (alsoSwap && canvas->isVisible()) {
gl->swapBuffers(canvas);
cd->fireFrameSwapped();
}
diff --git a/src/quick/quick.pro b/src/quick/quick.pro
index 0f0120ee79..87d4c90509 100644
--- a/src/quick/quick.pro
+++ b/src/quick/quick.pro
@@ -22,7 +22,6 @@ load(qt_module_config)
include(util/util.pri)
include(scenegraph/scenegraph.pri)
include(items/items.pri)
-include(particles/particles.pri)
include(designer/designer.pri)
HEADERS += \
diff --git a/src/quick/scenegraph/coreapi/qsgdefaultrenderer_p.h b/src/quick/scenegraph/coreapi/qsgdefaultrenderer_p.h
index 3896d03a80..e7cd1b0465 100644
--- a/src/quick/scenegraph/coreapi/qsgdefaultrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgdefaultrenderer_p.h
@@ -51,7 +51,7 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-class QSGDefaultRenderer : public QSGRenderer
+class Q_QUICK_EXPORT QSGDefaultRenderer : public QSGRenderer
{
Q_OBJECT
public:
diff --git a/src/quick/scenegraph/coreapi/qsggeometry.h b/src/quick/scenegraph/coreapi/qsggeometry.h
index 3a3d87a233..a11ec42976 100644
--- a/src/quick/scenegraph/coreapi/qsggeometry.h
+++ b/src/quick/scenegraph/coreapi/qsggeometry.h
@@ -56,7 +56,7 @@ class Q_QUICK_EXPORT QSGGeometry
{
public:
- struct Attribute
+ struct Q_QUICK_EXPORT Attribute
{
int position;
int tupleSize;
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer_p.h b/src/quick/scenegraph/coreapi/qsgrenderer_p.h
index 9d2402d727..3dced9cfa9 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgrenderer_p.h
@@ -108,7 +108,7 @@ public:
qreal determinant() const { return m_current_determinant; }
void setProjectionMatrixToDeviceRect();
- void setProjectionMatrixToRect(const QRectF &rect);
+ virtual void setProjectionMatrixToRect(const QRectF &rect);
void setProjectionMatrix(const QMatrix4x4 &matrix);
QMatrix4x4 projectionMatrix() const { return m_projection_matrix; }
bool isMirrored() const { return m_mirrored; }
diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp
index fc1e6ec89f..badbf51240 100644
--- a/src/quick/util/qquickanimation.cpp
+++ b/src/quick/util/qquickanimation.cpp
@@ -231,6 +231,11 @@ void QQuickAbstractAnimation::setRunning(bool r)
d->commence();
emit started();
} else {
+ if (d->paused) {
+ d->paused = false; //reset paused state to false when stopped
+ emit pausedChanged(d->paused);
+ }
+
if (d->animationInstance) {
if (d->alwaysRunToEnd) {
if (d->loopCount != 1)
@@ -260,6 +265,7 @@ void QQuickAbstractAnimation::setRunning(bool r)
bool QQuickAbstractAnimation::isPaused() const
{
Q_D(const QQuickAbstractAnimation);
+ Q_ASSERT((d->paused && d->running) || !d->paused);
return d->paused;
}
@@ -269,6 +275,11 @@ void QQuickAbstractAnimation::setPaused(bool p)
if (d->paused == p)
return;
+ if (!d->running) {
+ qmlInfo(this) << "setPaused() cannot be used when animation isn't running.";
+ return;
+ }
+
if (d->group || d->disableUserControl) {
qmlInfo(this) << "setPaused() cannot be used on non-root animation nodes.";
return;
@@ -445,8 +456,8 @@ void QQuickAbstractAnimation::start()
\qmlmethod QtQuick2::Animation::pause()
\brief Pauses the animation.
- If the animation is already paused, calling this method has no effect. The
- \c paused property will be true following a call to \c pause().
+ If the animation is already paused or not \c running, calling this method has no effect.
+ The \c paused property will be true following a call to \c pause().
*/
void QQuickAbstractAnimation::pause()
{
@@ -457,8 +468,8 @@ void QQuickAbstractAnimation::pause()
\qmlmethod QtQuick2::Animation::resume()
\brief Resumes a paused animation.
- If the animation is not paused, calling this method has no effect. The
- \c paused property will be false following a call to \c resume().
+ If the animation is not paused or not \c running, calling this method has no effect.
+ The \c paused property will be false following a call to \c resume().
*/
void QQuickAbstractAnimation::resume()
{
@@ -469,8 +480,8 @@ void QQuickAbstractAnimation::resume()
\qmlmethod QtQuick2::Animation::stop()
\brief Stops the animation.
- If the animation is not running, calling this method has no effect. The
- \c running property will be false following a call to \c stop().
+ If the animation is not running, calling this method has no effect. Both the
+ \c running and \c paused properties will be false following a call to \c stop().
Normally \c stop() stops the animation immediately, and the animation has
no further influence on property values. In this example animation
diff --git a/src/quick/util/qquicktransition.cpp b/src/quick/util/qquicktransition.cpp
index 5d9a2880d2..0f6ccb238b 100644
--- a/src/quick/util/qquicktransition.cpp
+++ b/src/quick/util/qquicktransition.cpp
@@ -96,34 +96,6 @@ QT_BEGIN_NAMESPACE
\sa {QML Animation and Transitions}, {declarative/animation/states}{states example}, {qmlstates}{States}, {QtQml}
*/
-QQuickTransitionInstance::QQuickTransitionInstance()
- : m_anim(0)
-{
-}
-
-QQuickTransitionInstance::~QQuickTransitionInstance()
-{
- delete m_anim;
-}
-
-void QQuickTransitionInstance::start()
-{
- if (m_anim)
- m_anim->start();
-}
-
-void QQuickTransitionInstance::stop()
-{
- if (m_anim)
- m_anim->stop();
-}
-
-bool QQuickTransitionInstance::isRunning() const
-{
- return m_anim && m_anim->state() == QAbstractAnimationJob::Running;
-}
-
-
//ParallelAnimationWrapper allows us to do a "callback" when the animation finishes, rather than connecting
//and disconnecting signals and slots frequently
class ParallelAnimationWrapper : public QParallelAnimationGroupJob
@@ -136,21 +108,32 @@ protected:
virtual void updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState);
};
-class QQuickTransitionPrivate : public QObjectPrivate
+class QQuickTransitionPrivate : public QObjectPrivate, QAnimationJobChangeListener
{
Q_DECLARE_PUBLIC(QQuickTransition)
public:
QQuickTransitionPrivate()
- : fromState(QLatin1String("*")), toState(QLatin1String("*")),
- reversed(false), reversible(false), enabled(true)
+ : fromState(QLatin1String("*")), toState(QLatin1String("*"))
+ , runningInstanceCount(0), state(QAbstractAnimationJob::Stopped)
+ , reversed(false), reversible(false), enabled(true)
{
}
+ void removeStateChangeListener(QAbstractAnimationJob *anim)
+ {
+ if (anim)
+ anim->removeAnimationChangeListener(this, QAbstractAnimationJob::StateChange);
+ }
+
QString fromState;
QString toState;
+ quint32 runningInstanceCount;
+ QAbstractAnimationJob::State state;
bool reversed;
bool reversible;
bool enabled;
+protected:
+ virtual void animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State, QAbstractAnimationJob::State);
static void append_animation(QQmlListProperty<QQuickAbstractAnimation> *list, QQuickAbstractAnimation *a);
static int animation_count(QQmlListProperty<QQuickAbstractAnimation> *list);
@@ -187,6 +170,21 @@ void QQuickTransitionPrivate::clear_animations(QQmlListProperty<QQuickAbstractAn
}
}
+void QQuickTransitionPrivate::animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State newState, QAbstractAnimationJob::State)
+{
+ Q_Q(QQuickTransition);
+
+ if (newState == QAbstractAnimationJob::Running) {
+ if (!runningInstanceCount)
+ emit q->runningChanged();
+ runningInstanceCount++;
+ } else if (newState == QAbstractAnimationJob::Stopped) {
+ runningInstanceCount--;
+ if (!runningInstanceCount)
+ emit q->runningChanged();
+ }
+}
+
void ParallelAnimationWrapper::updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState)
{
QParallelAnimationGroupJob::updateState(newState, oldState);
@@ -198,6 +196,34 @@ void ParallelAnimationWrapper::updateState(QAbstractAnimationJob::State newState
}
}
+QQuickTransitionInstance::QQuickTransitionInstance(QQuickTransitionPrivate *transition, QAbstractAnimationJob *anim)
+ : m_transition(transition)
+ , m_anim(anim)
+{
+}
+
+QQuickTransitionInstance::~QQuickTransitionInstance()
+{
+ m_transition->removeStateChangeListener(m_anim);
+ delete m_anim;
+}
+
+void QQuickTransitionInstance::start()
+{
+ if (m_anim)
+ m_anim->start();
+}
+
+void QQuickTransitionInstance::stop()
+{
+ if (m_anim)
+ m_anim->stop();
+}
+
+bool QQuickTransitionInstance::isRunning() const
+{
+ return m_anim && m_anim->state() == QAbstractAnimationJob::Running;
+}
QQuickTransition::QQuickTransition(QObject *parent)
: QObject(*(new QQuickTransitionPrivate), parent)
@@ -240,8 +266,8 @@ QQuickTransitionInstance *QQuickTransition::prepare(QQuickStateOperation::Action
group->setDirection(d->reversed ? QAbstractAnimationJob::Backward : QAbstractAnimationJob::Forward);
- QQuickTransitionInstance *wrapper = new QQuickTransitionInstance;
- wrapper->m_anim = group;
+ group->addAnimationChangeListener(d, QAbstractAnimationJob::StateChange);
+ QQuickTransitionInstance *wrapper = new QQuickTransitionInstance(d, group);
return wrapper;
}
@@ -386,6 +412,20 @@ void QQuickTransition::setEnabled(bool enabled)
}
/*!
+ \qmlproperty bool QtQuick2::Transition::running
+
+ This property holds whether the transition is currently running.
+
+ This property is read only.
+*/
+bool QQuickTransition::running() const
+{
+ Q_D(const QQuickTransition);
+ return d->runningInstanceCount;
+}
+
+
+/*!
\qmlproperty list<Animation> QtQuick2::Transition::animations
\default
diff --git a/src/quick/util/qquicktransition_p.h b/src/quick/util/qquicktransition_p.h
index ebd82fde2c..976439c236 100644
--- a/src/quick/util/qquicktransition_p.h
+++ b/src/quick/util/qquicktransition_p.h
@@ -43,6 +43,7 @@
#define QQUICKTRANSITION_H
#include "qquickstate_p.h"
+#include <private/qabstractanimationjob_p.h>
#include <qqml.h>
#include <QtCore/qobject.h>
@@ -55,12 +56,11 @@ class QQuickAbstractAnimation;
class QQuickTransitionPrivate;
class QQuickTransitionManager;
class QQuickTransition;
-class QAbstractAnimationJob;
class Q_QUICK_EXPORT QQuickTransitionInstance
{
public:
- QQuickTransitionInstance();
+ QQuickTransitionInstance(QQuickTransitionPrivate *transition, QAbstractAnimationJob *anim);
~QQuickTransitionInstance();
void start();
@@ -69,6 +69,7 @@ public:
bool isRunning() const;
private:
+ QQuickTransitionPrivate *m_transition;
QAbstractAnimationJob *m_anim;
friend class QQuickTransition;
};
@@ -81,6 +82,7 @@ class Q_QUICK_EXPORT QQuickTransition : public QObject
Q_PROPERTY(QString from READ fromState WRITE setFromState NOTIFY fromChanged)
Q_PROPERTY(QString to READ toState WRITE setToState NOTIFY toChanged)
Q_PROPERTY(bool reversible READ reversible WRITE setReversible NOTIFY reversibleChanged)
+ Q_PROPERTY(bool running READ running NOTIFY runningChanged)
Q_PROPERTY(QQmlListProperty<QQuickAbstractAnimation> animations READ animations)
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
Q_CLASSINFO("DefaultProperty", "animations")
@@ -102,6 +104,8 @@ public:
bool enabled() const;
void setEnabled(bool enabled);
+ bool running() const;
+
QQmlListProperty<QQuickAbstractAnimation> animations();
QQuickTransitionInstance *prepare(QQuickStateOperation::ActionList &actions,
@@ -116,6 +120,7 @@ Q_SIGNALS:
void toChanged();
void reversibleChanged();
void enabledChanged();
+ void runningChanged();
};
QT_END_NAMESPACE
diff --git a/src/src.pro b/src/src.pro
index 0246eea409..7631910c3c 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -1,6 +1,6 @@
TEMPLATE = subdirs
CONFIG += ordered
-SUBDIRS += qml quick plugins
+SUBDIRS += qml quick particles plugins
contains(QT_CONFIG, qmltest): SUBDIRS += qmltest
diff --git a/sync.profile b/sync.profile
index e03ca08883..39978aee02 100644
--- a/sync.profile
+++ b/sync.profile
@@ -1,6 +1,7 @@
%modules = ( # path to module name map
"QtQml" => "$basedir/src/qml",
"QtQuick" => "$basedir/src/quick",
+ "QtQuickParticles" => "$basedir/src/particles",
"QtQuickTest" => "$basedir/src/qmltest",
"QtQmlDevTools" => "$basedir/src/qmldevtools",
"QtDeclarative" => "$basedir/src/compatibility",
@@ -18,10 +19,12 @@
"network" => "#include <QtNetwork/QtNetwork>\n",
"testlib" => "#include <QtTest/QtTest>\n",
"qml" => "#include <QtQml/QtQml>\n",
+ "quick" => "#include <QtQuick/QtQuick>\n",
);
%modulepris = (
"QtQml" => "$basedir/modules/qt_qml.pri",
"QtQuick" => "$basedir/modules/qt_quick.pri",
+ "QtQuickParticles" => "$basedir/modules/qt_quickparticles.pri",
"QtQuickTest" => "$basedir/modules/qt_qmltest.pri",
"QtQmlDevTools" => "$basedir/modules/qt_qmldevtools.pri",
"QtDeclarative" => "$basedir/modules/qt_declarative.pri",
@@ -220,7 +223,7 @@
# - any git symbolic ref resolvable from the module's repository (e.g. "refs/heads/master" to track master branch)
#
%dependencies = (
- "qtbase" => "refs/heads/api_changes",
+ "qtbase" => "refs/heads/master",
"qtxmlpatterns" => "refs/heads/master",
"qtjsbackend" => "refs/heads/master",
);
diff --git a/tests/auto/particles/particles.pro b/tests/auto/particles/particles.pro
index d376b9305e..265a1eabc7 100644
--- a/tests/auto/particles/particles.pro
+++ b/tests/auto/particles/particles.pro
@@ -7,6 +7,7 @@ PRIVATETESTS += \
qquickcustomaffector \
qquickcustomparticle \
qquickellipseextruder \
+ qquickgroupgoal \
qquickfriction \
qquickgravity \
qquickimageparticle \
@@ -18,6 +19,7 @@ PRIVATETESTS += \
qquickpointattractor \
qquickpointdirection \
qquickrectangleextruder \
+ qquickspritegoal \
qquicktargetdirection \
qquicktrailemitter \
qquickturbulence \
diff --git a/tests/auto/particles/qquickage/qquickage.pro b/tests/auto/particles/qquickage/qquickage.pro
index 8e5c2f0e33..71ea279ada 100644
--- a/tests/auto/particles/qquickage/qquickage.pro
+++ b/tests/auto/particles/qquickage/qquickage.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro b/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro
index df8d460d3e..0462fff1bd 100644
--- a/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro
+++ b/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro b/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro
index 4ea8739c21..e3f79d47fb 100644
--- a/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro
+++ b/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro b/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro
index 0855187d47..41ceb8c1fc 100644
--- a/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro
+++ b/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquickcustomparticle/data/deleteSourceItem.qml b/tests/auto/particles/qquickcustomparticle/data/deleteSourceItem.qml
new file mode 100644
index 0000000000..a68373e7e4
--- /dev/null
+++ b/tests/auto/particles/qquickcustomparticle/data/deleteSourceItem.qml
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+
+ CustomParticle {
+ id: cp
+ property variant source
+ }
+
+ Emitter{
+ //0,0 position
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+ }
+
+ ShaderEffectSource {
+ id: doomedses
+ hideSource: true
+ sourceItem: Image {
+ id: doomed
+ source: "../../shared/star.png"
+ }
+ }
+
+ function setDeletedSourceItem() {
+ doomed.destroy();
+ cp.source = doomedses;
+ }
+}
diff --git a/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro b/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro
index d5c21abef3..0ee7fc9863 100644
--- a/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro
+++ b/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp b/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp
index a54e10afc6..a81edca35e 100644
--- a/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp
+++ b/tests/auto/particles/qquickcustomparticle/tst_qquickcustomparticle.cpp
@@ -55,6 +55,7 @@ public:
private slots:
void initTestCase();
void test_basic();
+ void test_deleteSourceItem();
};
void tst_qquickcustomparticle::initTestCase()
@@ -94,6 +95,20 @@ void tst_qquickcustomparticle::test_basic()
QVERIFY(oneNonZero);//Zero is a valid value, but it also needs to be set to a random number
}
+void tst_qquickcustomparticle::test_deleteSourceItem()
+{
+ // purely to ensure that deleting the sourceItem of a shader doesn't cause a crash
+ QQuickView* view = createView(testFileUrl("deleteSourceItem.qml"), 600);
+ QVERIFY(view);
+ QObject *obj = view->rootObject();
+ QVERIFY(obj);
+ QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
+ ensureAnimTime(200, system->m_animation);
+ QMetaObject::invokeMethod(obj, "setDeletedSourceItem");
+ ensureAnimTime(200, system->m_animation);
+ delete view;
+}
+
QTEST_MAIN(tst_qquickcustomparticle);
#include "tst_qquickcustomparticle.moc"
diff --git a/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro b/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro
index 33241a4792..9e6b95339f 100644
--- a/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro
+++ b/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquickfriction/qquickfriction.pro b/tests/auto/particles/qquickfriction/qquickfriction.pro
index 36cf9aaa60..3bc61942d7 100644
--- a/tests/auto/particles/qquickfriction/qquickfriction.pro
+++ b/tests/auto/particles/qquickfriction/qquickfriction.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquickgravity/qquickgravity.pro b/tests/auto/particles/qquickgravity/qquickgravity.pro
index 331def26b5..03610742c0 100644
--- a/tests/auto/particles/qquickgravity/qquickgravity.pro
+++ b/tests/auto/particles/qquickgravity/qquickgravity.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro b/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro
index f7f09ed9d0..9ae573fe13 100644
--- a/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro
+++ b/tests/auto/particles/qquickgroupgoal/qquickgroupgoal.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private testlib
+QT += core-private gui-private v8-private qml-private testlib quick-private quickparticles-private
diff --git a/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro b/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro
index 226d844263..57909444af 100644
--- a/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro
+++ b/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro
@@ -6,4 +6,4 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro b/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro
index ec7fa48e26..047af9faf8 100644
--- a/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro
+++ b/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro b/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro
index a1297b1e26..83ff8eddcf 100644
--- a/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro
+++ b/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro b/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro
index 99f50a286d..90cf2da4a3 100644
--- a/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro
+++ b/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro b/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro
index c5c908e305..4fa17e2ce0 100644
--- a/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro
+++ b/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro b/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro
index 2179ae3ae9..e8cc4f2cbd 100644
--- a/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro
+++ b/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro b/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro
index 43c8022b0a..07dd50369e 100644
--- a/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro
+++ b/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro b/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro
index 71b21e5f56..e9c73305e1 100644
--- a/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro
+++ b/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro b/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro
index 5e595204cc..e968c4a1f7 100644
--- a/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro
+++ b/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquickspritegoal/data/basic.qml b/tests/auto/particles/qquickspritegoal/data/basic.qml
index 622f6bdd70..23effe3a68 100644
--- a/tests/auto/particles/qquickspritegoal/data/basic.qml
+++ b/tests/auto/particles/qquickspritegoal/data/basic.qml
@@ -57,12 +57,12 @@ Rectangle {
name: "happy"
source: "../../shared/squarefacesprite.png"
frames: 6
- duration: 120
+ frameDuration: 120
}, Sprite {
name: "twoHappy"
source: "../../shared/squarefacesprite.png"
frames: 3
- duration: 240
+ frameDuration: 240
}]
}
diff --git a/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro b/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro
index cfe932aabd..a5f491aedc 100644
--- a/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro
+++ b/tests/auto/particles/qquickspritegoal/qquickspritegoal.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private testlib
+QT += core-private gui-private v8-private qml-private testlib quick-private quickparticles-private
diff --git a/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro b/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro
index b7ba905f2e..2d2751e5ab 100644
--- a/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro
+++ b/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro b/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro
index 5a76e2fba4..a5d823911c 100644
--- a/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro
+++ b/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquickturbulence/qquickturbulence.pro b/tests/auto/particles/qquickturbulence/qquickturbulence.pro
index 3bfb94addf..5ccf83b337 100644
--- a/tests/auto/particles/qquickturbulence/qquickturbulence.pro
+++ b/tests/auto/particles/qquickturbulence/qquickturbulence.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/particles/qquickwander/qquickwander.pro b/tests/auto/particles/qquickwander/qquickwander.pro
index 1cd4269074..65075e5417 100644
--- a/tests/auto/particles/qquickwander/qquickwander.pro
+++ b/tests/auto/particles/qquickwander/qquickwander.pro
@@ -6,5 +6,5 @@ macx:CONFIG -= app_bundle
include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private v8-private qml-private quick-private testlib
+QT += core-private gui-private v8-private qml-private quick-private quickparticles-private testlib
diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/test.qml b/tests/auto/qml/debugger/qqmldebugjs/data/test.qml
index 200f26b1c3..e6c6faa912 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/data/test.qml
+++ b/tests/auto/qml/debugger/qqmldebugjs/data/test.qml
@@ -50,5 +50,11 @@ Item {
var c
var d = 12
}
+ function foo() {
+ var a = [1, 2]
+ var b = {a: "hello", d: 1 }
+ var c
+ var d = 12
+ }
}
diff --git a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
index 8293ec6cda..b93be16e0e 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
+++ b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
@@ -107,7 +107,6 @@ const char *GARBAGECOLLECTOR = "gc";
const char *CONNECT = "connect";
const char *INTERRUPT = "interrupt";
-const char *BREAKAFTERCOMPILE = "breakaftercompile";
const char *REQUEST = "request";
const char *IN = "in";
@@ -173,7 +172,6 @@ private slots:
void connect();
void interrupt();
- void breakAfterCompile();
void getVersion();
void getVersionWhenAttaching();
@@ -270,7 +268,6 @@ public:
void connect();
void interrupt();
- void breakAfterCompile(bool enabled);
void continueDebugging(StepAction stepAction, int stepCount = 1);
void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap());
@@ -301,7 +298,6 @@ signals:
void enabled();
void connected();
void interruptRequested();
- void breakAfterCompileRequested();
void result();
void stopped();
void scriptsResult();
@@ -334,14 +330,6 @@ void QJSDebugClient::interrupt()
sendMessage(packMessage(INTERRUPT));
}
-void QJSDebugClient::breakAfterCompile(bool enabled)
-{
- QByteArray request;
- QDataStream rs(&request, QIODevice::WriteOnly);
- rs << enabled;
- sendMessage(packMessage(BREAKAFTERCOMPILE, request));
-}
-
void QJSDebugClient::continueDebugging(StepAction action, int count)
{
// { "seq" : <number>,
@@ -957,9 +945,6 @@ void QJSDebugClient::messageReceived(const QByteArray &data)
emit stopped();
}
- } else if (type == BREAKAFTERCOMPILE) {
- emit breakAfterCompileRequested();
-
}
}
}
@@ -1074,18 +1059,6 @@ void tst_QQmlDebugJS::interrupt()
QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(interruptRequested())));
}
-void tst_QQmlDebugJS::breakAfterCompile()
-{
- //void breakAfterCompile(bool enabled)
-
- QVERIFY(init());
- client->breakAfterCompile(true);
- client->connect();
-
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(breakAfterCompileRequested())));
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-}
-
void tst_QQmlDebugJS::getVersion()
{
//void version()
@@ -1146,9 +1119,9 @@ void tst_QQmlDebugJS::listBreakpoints()
{
//void listBreakpoints()
- int sourceLine1 = 47;
- int sourceLine2 = 48;
- int sourceLine3 = 49;
+ int sourceLine1 = 53;
+ int sourceLine2 = 54;
+ int sourceLine3 = 55;
QVERIFY(init());
client->connect();
diff --git a/tests/auto/qml/debugger/qv8profilerservice/qv8profilerservice.pro b/tests/auto/qml/debugger/qv8profilerservice/qv8profilerservice.pro
index 5088953c92..13d39c0225 100644
--- a/tests/auto/qml/debugger/qv8profilerservice/qv8profilerservice.pro
+++ b/tests/auto/qml/debugger/qv8profilerservice/qv8profilerservice.pro
@@ -13,3 +13,5 @@ OTHER_FILES += data/test.qml
CONFIG += parallel_test declarative_debug
QT += qml testlib
+
+macx:CONFIG += insignificant_test # QTBUG-25288
diff --git a/tests/auto/qml/debugger/shared/debugutil_p.h b/tests/auto/qml/debugger/shared/debugutil_p.h
index 2ea295b822..4350056caf 100644
--- a/tests/auto/qml/debugger/shared/debugutil_p.h
+++ b/tests/auto/qml/debugger/shared/debugutil_p.h
@@ -48,6 +48,7 @@
#include <QThread>
#include <QTest>
#include <QProcess>
+#include <QMutex>
#include <QtQml/qqmlengine.h>
diff --git a/tests/auto/qml/v4/data/variantHandling.qml b/tests/auto/qml/v4/data/variantHandling.qml
new file mode 100644
index 0000000000..3d48eef57e
--- /dev/null
+++ b/tests/auto/qml/v4/data/variantHandling.qml
@@ -0,0 +1,67 @@
+import QtQuick 2.0
+
+QtObject {
+ property bool pBool: true
+ property int pInt: 666
+ property real pReal: 3.1415927
+ property string pString: 'foo'
+ property url pUrl: 'http://tools.ietf.org/html/rfc3986#section-1.1.2'
+ property color pColor: Qt.rgba(1, 0, 0, 0.5)
+ property QtObject pObject: QtObject { property string foo: 'bar' }
+
+ // Test assignment to variant
+ property variant pBoolVar: pBool
+ property variant pIntVar: pInt
+ property variant pRealVar: pReal
+ property variant pStringVar: pString
+ property variant pUrlVar: pUrl
+ property variant pColorVar: pColor
+ property variant pObjectVar: pObject
+ property variant pNullVar: null
+ property variant pVarVar: pUrlVar
+
+ // Test equivalence
+ property bool boolConversionSuccess: (pBoolVar == true)
+ property bool intConversionSuccess: (pIntVar == 666)
+ property bool realConversionSuccess: (pRealVar == 3.1415927)
+ property bool stringConversionSuccess: (pStringVar == 'foo')
+
+ property url comparisonUrl: 'http://tools.ietf.org/html/rfc3986#section-1.1.2'
+ property bool urlConversionSuccess: (pUrlVar == comparisonUrl)
+
+ property color comparisonColor: Qt.rgba(1, 0, 0, 0.5)
+ property bool colorConversionSuccess: (pColorVar == comparisonColor)
+
+ property bool objectConversionSuccess: (pObjectVar == pObject)
+ property bool nullConversionSuccess: (pNullVar == null)
+
+ property bool variantConversionSuccess: (pVarVar == comparisonUrl)
+
+ // Operations are not handled by V4 - they should pass through correctly
+ property variant pVarNot: !pBoolVar
+ property variant pVarComplement: ~pIntVar
+ property variant pVarEqual: (pBoolVar == pBoolVar)
+ property variant pVarLiteralEqual: (pBoolVar == true)
+ property variant pVarUnequal: (pUrlVar == pColorVar)
+ property variant pVarComparison: (pIntVar <= pIntVar)
+ property variant pVarShift: (pIntVar >> 1)
+
+ Component.onCompleted: {
+ if (!boolConversionSuccess) console.warn('QV4: bool conversion failed');
+ if (!intConversionSuccess) console.warn('QV4: int conversion failed');
+ if (!realConversionSuccess) console.warn('QV4: real conversion failed');
+ if (!stringConversionSuccess) console.warn('QV4: string conversion failed');
+ if (!urlConversionSuccess) console.warn('QV4: url conversion failed');
+ if (!colorConversionSuccess) console.warn('QV4: color conversion failed');
+ if (!objectConversionSuccess) console.warn('QV4: object conversion failed');
+ if (!nullConversionSuccess) console.warn('QV4: null conversion failed');
+ if (!variantConversionSuccess) console.warn('QV4: variant conversion failed');
+ if (pVarNot != false) console.warn('QV4: variant negation impeded');
+ if (pVarComplement != ~666) console.warn('QV4: variant complement impeded');
+ if (pVarEqual != true) console.warn('QV4: variant equality impeded');
+ if (pVarLiteralEqual != true) console.warn('QV4: variant/literal equality impeded');
+ if (pVarUnequal != false) console.warn('QV4: variant unequality impeded');
+ if (pVarComparison != true) console.warn('QV4: variant comparison impeded');
+ if (pVarShift != 333) console.warn('QV4: variant shift impeded');
+ }
+}
diff --git a/tests/auto/qml/v4/tst_v4.cpp b/tests/auto/qml/v4/tst_v4.cpp
index dfb7cc48c7..99a4405afa 100644
--- a/tests/auto/qml/v4/tst_v4.cpp
+++ b/tests/auto/qml/v4/tst_v4.cpp
@@ -150,6 +150,7 @@ void tst_v4::qtscript_data()
QTest::newRow("conversion from string") << "conversions.6.qml"; // QTBUG-24706
QTest::newRow("conversion from url") << "conversions.7.qml"; // QTBUG-24706
QTest::newRow("conversion from vec3") << "conversions.8.qml";
+ QTest::newRow("variantHandling") << "variantHandling.qml";
}
void tst_v4::unnecessaryReeval()
@@ -856,23 +857,31 @@ void tst_v4::debuggingDumpInstructions()
expectedPreAddress << "\t\tConvertBoolToInt\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertBoolToNumber\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertBoolToString\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertBoolToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertIntToBool\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertIntToNumber\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertIntToString\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertIntToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertNumberToBool\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertNumberToInt\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertNumberToString\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertNumberToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertStringToBool\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertStringToInt\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertStringToNumber\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertStringToUrl\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertStringToColor\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertStringToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertUrlToBool\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertUrlToString\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertUrlToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertColorToBool\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertColorToString\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertColorToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertObjectToBool\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertObjectToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertNullToObject\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertNullToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tResolveUrl\t\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tMathSinNumber\t\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tMathCosNumber\t\tInput_Reg(0) -> Output_Reg(0)";
diff --git a/tests/auto/qmltest/qmltest.pro b/tests/auto/qmltest/qmltest.pro
index b1b2ee2228..ca39dacdb9 100644
--- a/tests/auto/qmltest/qmltest.pro
+++ b/tests/auto/qmltest/qmltest.pro
@@ -9,4 +9,4 @@ importFiles.files = borderimage buttonclick createbenchmark events qqmlbindi
importFiles.path = .
DEPLOYMENT += importFiles
-CONFIG+=insignificant_test \ No newline at end of file
+CONFIG+=insignificant_test # QTBUG-25306
diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
index 166f4b8276..7460263d71 100644
--- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
+++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
@@ -624,6 +624,32 @@ void tst_qquickanimations::resume()
QTest::qWait(400);
animation.stop();
QVERIFY(rect.x() > x);
+
+ animation.start();
+ QVERIFY(animation.isRunning());
+ animation.pause();
+ QVERIFY(animation.isPaused());
+ animation.resume();
+ QVERIFY(!animation.isPaused());
+
+ QSignalSpy spy(&animation, SIGNAL(pausedChanged(bool)));
+ animation.pause();
+ QCOMPARE(spy.count(), 1);
+ QVERIFY(animation.isPaused());
+ animation.stop();
+ QVERIFY(!animation.isPaused());
+ QCOMPARE(spy.count(), 2);
+
+ qmlRegisterType<QQuickPropertyAnimation>("QtQuick",2,0,"PropertyAnimation"); //make sure QQuickPropertyAnimation has correct qml type name
+ QByteArray message = "<Unknown File>: QML PropertyAnimation: setPaused() cannot be used when animation isn't running.";
+ QTest::ignoreMessage(QtWarningMsg, message);
+ animation.pause();
+ QCOMPARE(spy.count(), 2);
+ QVERIFY(!animation.isPaused());
+ animation.resume();
+ QVERIFY(!animation.isPaused());
+ QVERIFY(!animation.isRunning());
+ QCOMPARE(spy.count(), 2);
}
void tst_qquickanimations::dotProperty()
@@ -961,11 +987,12 @@ void tst_qquickanimations::disabledTransition()
QCOMPARE(myRect->x(),qreal(200));
trans->setEnabled(true);
-
+ QSignalSpy runningSpy(trans, SIGNAL(runningChanged()));
QQuickItemPrivate::get(rect)->setState("");
QCOMPARE(myRect->x(),qreal(200));
QTest::qWait(300);
QTIMED_COMPARE(myRect->x(),qreal(100));
+ QCOMPARE(runningSpy.count(), 2); //stopped, running, stopped
}
void tst_qquickanimations::invalidDuration()
diff --git a/tests/auto/quick/qquickcanvas/data/ownershipRootItem.qml b/tests/auto/quick/qquickcanvas/data/ownershipRootItem.qml
new file mode 100644
index 0000000000..dfc4159f4e
--- /dev/null
+++ b/tests/auto/quick/qquickcanvas/data/ownershipRootItem.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.0
+import QtQuick.Window 2.0 as Window
+
+Window.Window {
+RootItemAccessor {
+ id:accessor
+ objectName:"accessor"
+ Component.onCompleted:accessor.rootItem();
+}
+
+} \ No newline at end of file
diff --git a/tests/auto/quick/qquickcanvas/qquickcanvas.pro b/tests/auto/quick/qquickcanvas/qquickcanvas.pro
index 817eb2534f..b9ed73d577 100644
--- a/tests/auto/quick/qquickcanvas/qquickcanvas.pro
+++ b/tests/auto/quick/qquickcanvas/qquickcanvas.pro
@@ -7,7 +7,7 @@ include (../../shared/util.pri)
macx:CONFIG -= app_bundle
CONFIG += parallel_test
-QT += core-private gui-private qml-private quick-private testlib
+QT += core-private gui-private qml-private quick-private v8-private testlib
TESTDATA = data/*
@@ -15,4 +15,3 @@ OTHER_FILES += \
data/AnimationsWhileHidden.qml \
data/Headless.qml
-
diff --git a/tests/auto/quick/qquickcanvas/tst_qquickcanvas.cpp b/tests/auto/quick/qquickcanvas/tst_qquickcanvas.cpp
index 7250504e73..ca2165d711 100644
--- a/tests/auto/quick/qquickcanvas/tst_qquickcanvas.cpp
+++ b/tests/auto/quick/qquickcanvas/tst_qquickcanvas.cpp
@@ -50,6 +50,7 @@
#include <QtGui/QWindowSystemInterface>
#include "../../shared/util.h"
#include <QSignalSpy>
+#include <private/qquickcanvas_p.h>
struct TouchEventData {
QEvent::Type type;
@@ -108,6 +109,36 @@ static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, Qt::TouchPoin
} \
}
+
+class RootItemAccessor : public QQuickItem
+{
+ Q_OBJECT
+public:
+ RootItemAccessor()
+ : m_rootItemDestroyed(false)
+ , m_rootItem(0)
+ {
+ }
+ Q_INVOKABLE QQuickItem *rootItem()
+ {
+ if (!m_rootItem) {
+ QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas());
+ m_rootItem = c->rootItem;
+ QObject::connect(m_rootItem, SIGNAL(destroyed()), this, SLOT(rootItemDestroyed()));
+ }
+ return m_rootItem;
+ }
+ bool isRootItemDestroyed() {return m_rootItemDestroyed;}
+public slots:
+ void rootItemDestroyed() {
+ m_rootItemDestroyed = true;
+ }
+
+private:
+ bool m_rootItemDestroyed;
+ QQuickItem *m_rootItem;
+};
+
class TestTouchItem : public QQuickRectangle
{
Q_OBJECT
@@ -214,6 +245,7 @@ private slots:
void ignoreUnhandledMouseEvents();
+ void ownershipRootItem();
private:
QTouchDevice *touchDevice;
};
@@ -234,7 +266,7 @@ void tst_qquickcanvas::touchEvent_basic()
QQuickCanvas *canvas = new QQuickCanvas;
canvas->resize(250, 250);
- canvas->move(100, 100);
+ canvas->setPos(100, 100);
canvas->show();
TestTouchItem *bottomItem = new TestTouchItem(canvas->rootItem());
@@ -355,7 +387,7 @@ void tst_qquickcanvas::touchEvent_propagation()
QQuickCanvas *canvas = new QQuickCanvas;
canvas->resize(250, 250);
- canvas->move(100, 100);
+ canvas->setPos(100, 100);
canvas->show();
TestTouchItem *bottomItem = new TestTouchItem(canvas->rootItem());
@@ -483,7 +515,7 @@ void tst_qquickcanvas::touchEvent_cancel()
QQuickCanvas *canvas = new QQuickCanvas;
canvas->resize(250, 250);
- canvas->move(100, 100);
+ canvas->setPos(100, 100);
canvas->show();
TestTouchItem *item = new TestTouchItem(canvas->rootItem());
@@ -529,7 +561,7 @@ void tst_qquickcanvas::mouseFiltering()
QQuickCanvas *canvas = new QQuickCanvas;
canvas->resize(250, 250);
- canvas->move(100, 100);
+ canvas->setPos(100, 100);
canvas->show();
TestTouchItem *bottomItem = new TestTouchItem(canvas->rootItem());
@@ -586,7 +618,7 @@ void tst_qquickcanvas::clearColor()
//### Can we examine rendering to make sure it is really blue?
QQuickCanvas *canvas = new QQuickCanvas;
canvas->resize(250, 250);
- canvas->move(100, 100);
+ canvas->setPos(100, 100);
canvas->setClearColor(Qt::blue);
canvas->show();
QTest::qWaitForWindowShown(canvas);
@@ -620,7 +652,7 @@ void tst_qquickcanvas::multipleWindows()
c->setPos(100 + i * 30, 100 + i * 20);
c->show();
windows << c;
- QVERIFY(c->visible());
+ QVERIFY(c->isVisible());
}
// move them
@@ -647,15 +679,15 @@ void tst_qquickcanvas::animationsWhileHidden()
QQuickCanvas* canvas = qobject_cast<QQuickCanvas*>(created);
QVERIFY(canvas);
- QVERIFY(canvas->visible());
+ QVERIFY(canvas->isVisible());
// Now hide the window and verify that it went off screen
canvas->hide();
QTest::qWait(10);
- QVERIFY(!canvas->visible());
+ QVERIFY(!canvas->isVisible());
// Running animaiton should cause it to become visible again shortly.
- QTRY_VERIFY(canvas->visible());
+ QTRY_VERIFY(canvas->isVisible());
delete canvas;
}
@@ -672,7 +704,7 @@ void tst_qquickcanvas::headless()
QVERIFY(canvas);
QTest::qWaitForWindowShown(canvas);
- QVERIFY(canvas->visible());
+ QVERIFY(canvas->isVisible());
QSignalSpy initialized(canvas, SIGNAL(sceneGraphInitialized()));
QSignalSpy invalidated(canvas, SIGNAL(sceneGraphInvalidated()));
@@ -770,6 +802,28 @@ void tst_qquickcanvas::ignoreUnhandledMouseEvents()
delete canvas;
}
+
+void tst_qquickcanvas::ownershipRootItem()
+{
+ qmlRegisterType<RootItemAccessor>("QtQuick", 2, 0, "RootItemAccessor");
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.loadUrl(testFileUrl("ownershipRootItem.qml"));
+ QObject* created = component.create();
+
+ QQuickCanvas* canvas = qobject_cast<QQuickCanvas*>(created);
+ QVERIFY(canvas);
+ QTest::qWaitForWindowShown(canvas);
+
+ RootItemAccessor* accessor = canvas->findChild<RootItemAccessor*>("accessor");
+ QVERIFY(accessor);
+ engine.collectGarbage();
+
+ QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ QCoreApplication::processEvents();
+ QVERIFY(!accessor->isRootItemDestroyed());
+}
QTEST_MAIN(tst_qquickcanvas)
#include "tst_qquickcanvas.moc"
diff --git a/tests/auto/quick/qquickgridview/data/gridview1.qml b/tests/auto/quick/qquickgridview/data/gridview1.qml
index 4bf6f0b952..1424955689 100644
--- a/tests/auto/quick/qquickgridview/data/gridview1.qml
+++ b/tests/auto/quick/qquickgridview/data/gridview1.qml
@@ -26,8 +26,9 @@ Rectangle {
text: index
}
Text {
- x: 40
+ x: 30
text: wrapper.x + ", " + wrapper.y
+ font.pixelSize: 12
}
Text {
y: 20
@@ -58,12 +59,11 @@ Rectangle {
height: 320
cellWidth: 80
cellHeight: 60
- flow: (testTopToBottom == false) ? GridView.LeftToRight : GridView.TopToBottom
- layoutDirection: (testRightToLeft == true) ? Qt.RightToLeft : Qt.LeftToRight
model: testModel
delegate: myDelegate
header: root.showHeader ? headerFooter : null
footer: root.showFooter ? headerFooter : null
cacheBuffer: root.cacheBuffer
+ focus: true
}
}
diff --git a/tests/auto/quick/qquickgridview/data/headerfooter.qml b/tests/auto/quick/qquickgridview/data/headerfooter.qml
index 322cfed388..f0f73a0dac 100644
--- a/tests/auto/quick/qquickgridview/data/headerfooter.qml
+++ b/tests/auto/quick/qquickgridview/data/headerfooter.qml
@@ -2,24 +2,22 @@ import QtQuick 2.0
GridView {
id: view
- property bool horizontal: false
- property bool rtl: false
+
width: 240
height: 320
model: testModel
-
- flow: horizontal ? GridView.TopToBottom : GridView.LeftToRight
+
header: Rectangle {
objectName: "header"
- width: horizontal ? 20 : view.width
- height: horizontal ? view.height : 20
+ width: flow == GridView.TopToBottom ? 20 : view.width
+ height: flow == GridView.TopToBottom ? view.height : 20
color: "red"
}
footer: Rectangle {
objectName: "footer"
- width: horizontal ? 30 : view.width
- height: horizontal ? view.height : 30
+ width: flow == GridView.TopToBottom ? 30 : view.width
+ height: flow == GridView.TopToBottom ? view.height : 30
color: "blue"
}
@@ -27,5 +25,4 @@ GridView {
cellHeight: 80;
delegate: Text { width: 80; height: 80; text: index + "(" + x + ")" }
- layoutDirection: rtl ? Qt.RightToLeft : Qt.LeftToRight
}
diff --git a/tests/auto/quick/qquickgridview/data/layouts.qml b/tests/auto/quick/qquickgridview/data/layouts.qml
new file mode 100644
index 0000000000..e00351f1bf
--- /dev/null
+++ b/tests/auto/quick/qquickgridview/data/layouts.qml
@@ -0,0 +1,62 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ width: 240
+ height: 320
+
+ property bool showHeader: false
+ property bool showFooter: false
+
+ Component {
+ id: myDelegate
+ Rectangle {
+ id: wrapper
+ objectName: "wrapper"
+ width: 80
+ height: 60
+ border.width: 1
+ Text { text: index }
+ Text {
+ x: 30
+ text: wrapper.x + ", " + wrapper.y
+ font.pixelSize: 12
+ }
+ Text {
+ y: 20
+ id: textName
+ objectName: "textName"
+ text: name
+ }
+ Text {
+ y: 40
+ id: textNumber
+ objectName: "textNumber"
+ text: number
+ }
+
+ property string theName: name
+ color: GridView.isCurrentItem ? "lightsteelblue" : "white"
+ }
+ }
+
+ Component {
+ id: headerFooter
+ Rectangle { width: 30; height: 320; color: "blue" }
+ }
+
+ GridView {
+ objectName: "grid"
+ width: 240
+ height: 320
+ cellWidth: 80
+ cellHeight: 60
+ flow: (testTopToBottom == false) ? GridView.LeftToRight : GridView.TopToBottom
+ layoutDirection: (testRightToLeft == true) ? Qt.RightToLeft : Qt.LeftToRight
+ verticalLayoutDirection: (testBottomToTop == true) ? GridView.BottomToTop : GridView.TopToBottom
+ model: testModel
+ delegate: myDelegate
+ header: root.showHeader ? headerFooter : null
+ footer: root.showFooter ? headerFooter : null
+ }
+}
diff --git a/tests/auto/quick/qquickgridview/data/resizegrid.qml b/tests/auto/quick/qquickgridview/data/resizegrid.qml
new file mode 100644
index 0000000000..7ea2f120e8
--- /dev/null
+++ b/tests/auto/quick/qquickgridview/data/resizegrid.qml
@@ -0,0 +1,51 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+
+ Component {
+ id: myDelegate
+ Rectangle {
+ id: wrapper
+ objectName: "wrapper"
+ width: 80
+ height: 60
+ border.width: 1
+ Text { text: index }
+ Text {
+ x: 30
+ text: wrapper.x + ", " + wrapper.y
+ font.pixelSize: 12
+ }
+ Text {
+ y: 20
+ id: textName
+ objectName: "textName"
+ text: name
+ }
+ color: GridView.isCurrentItem ? "lightsteelblue" : "white"
+ }
+ }
+
+ // the grid is specifically placed inside another item to test a bug where
+ // resizing from anchor changes did not update the content pos correctly
+ Item {
+ anchors.fill: parent
+
+ GridView {
+ clip: true
+ objectName: "grid"
+ anchors.fill: parent
+ cellWidth: 80
+ cellHeight: 60
+
+ flow: (testTopToBottom == false) ? GridView.LeftToRight : GridView.TopToBottom
+ layoutDirection: (testRightToLeft == true) ? Qt.RightToLeft : Qt.LeftToRight
+ verticalLayoutDirection: (testBottomToTop == true) ? GridView.BottomToTop : GridView.TopToBottom
+ model: testModel
+ delegate: myDelegate
+ }
+
+ }
+}
+
diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
index 22c9004ccc..bc0108c842 100644
--- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
+++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
@@ -58,8 +58,10 @@
#include "../shared/visualtestutil.h"
#include <QtGui/qguiapplication.h>
-Q_DECLARE_METATYPE(Qt::LayoutDirection)
Q_DECLARE_METATYPE(QQuickGridView::Flow)
+Q_DECLARE_METATYPE(Qt::LayoutDirection)
+Q_DECLARE_METATYPE(QQuickItemView::VerticalLayoutDirection)
+Q_DECLARE_METATYPE(Qt::Key)
using namespace QQuickViewTestUtil;
using namespace QQuickVisualTestUtil;
@@ -76,25 +78,29 @@ private slots:
void init();
void items();
void changed();
- void inserted();
- void inserted_more();
- void inserted_more_data();
+ void inserted_basic();
+ void inserted_defaultLayout(QQuickGridView::Flow flow = QQuickGridView::FlowLeftToRight, Qt::LayoutDirection horizLayout = Qt::LeftToRight, QQuickItemView::VerticalLayoutDirection verticalLayout = QQuickItemView::TopToBottom);
+ void inserted_defaultLayout_data();
void insertBeforeVisible();
void insertBeforeVisible_data();
- void removed();
- void removed_more();
- void removed_more_data();
+ void removed_basic();
+ void removed_defaultLayout(QQuickGridView::Flow flow = QQuickGridView::FlowLeftToRight, Qt::LayoutDirection horizLayout = Qt::LeftToRight, QQuickItemView::VerticalLayoutDirection verticalLayout = QQuickItemView::TopToBottom);
+ void removed_defaultLayout_data();
void addOrRemoveBeforeVisible();
void addOrRemoveBeforeVisible_data();
void clear();
- void moved();
- void moved_data();
- void multipleChanges();
- void multipleChanges_data();
+ void moved_defaultLayout(QQuickGridView::Flow flow = QQuickGridView::FlowLeftToRight, Qt::LayoutDirection horizLayout = Qt::LeftToRight, QQuickItemView::VerticalLayoutDirection verticalLayout = QQuickItemView::TopToBottom);
+ void moved_defaultLayout_data();
+ void multipleChanges_condensed() { multipleChanges(true); }
+ void multipleChanges_condensed_data() { multipleChanges_data(); }
+ void multipleChanges_uncondensed() { multipleChanges(false); }
+ void multipleChanges_uncondensed_data() { multipleChanges_data(); }
void swapWithFirstItem();
void changeFlow();
void currentIndex();
void noCurrentIndex();
+ void keyNavigation();
+ void keyNavigation_data();
void defaultValues();
void properties();
void propertyChanges();
@@ -114,7 +120,11 @@ private slots:
void header();
void header_data();
void headerFooter();
+ void headerFooter_data();
+ void resetModel_headerFooter();
void resizeViewAndRepaint();
+ void resizeGrid();
+ void resizeGrid_data();
void changeColumnCount();
void indexAt_itemAt_data();
void indexAt_itemAt();
@@ -148,12 +158,117 @@ private slots:
void multipleTransitions_data();
void multipleDisplaced();
+ void inserted_leftToRight_RtL_TtB();
+ void inserted_leftToRight_RtL_TtB_data();
+ void inserted_leftToRight_LtR_BtT();
+ void inserted_leftToRight_LtR_BtT_data();
+ void inserted_leftToRight_RtL_BtT();
+ void inserted_leftToRight_RtL_BtT_data();
+ void inserted_topToBottom_LtR_TtB();
+ void inserted_topToBottom_LtR_TtB_data();
+ void inserted_topToBottom_RtL_TtB();
+ void inserted_topToBottom_RtL_TtB_data();
+ void inserted_topToBottom_LtR_BtT();
+ void inserted_topToBottom_LtR_BtT_data();
+ void inserted_topToBottom_RtL_BtT();
+ void inserted_topToBottom_RtL_BtT_data();
+
+ void removed_leftToRight_RtL_TtB();
+ void removed_leftToRight_RtL_TtB_data();
+ void removed_leftToRight_LtR_BtT();
+ void removed_leftToRight_LtR_BtT_data();
+ void removed_leftToRight_RtL_BtT();
+ void removed_leftToRight_RtL_BtT_data();
+ void removed_topToBottom_LtR_TtB();
+ void removed_topToBottom_LtR_TtB_data();
+ void removed_topToBottom_RtL_TtB();
+ void removed_topToBottom_RtL_TtB_data();
+ void removed_topToBottom_LtR_BtT();
+ void removed_topToBottom_LtR_BtT_data();
+ void removed_topToBottom_RtL_BtT();
+ void removed_topToBottom_RtL_BtT_data();
+
+ void moved_leftToRight_RtL_TtB();
+ void moved_leftToRight_RtL_TtB_data();
+ void moved_leftToRight_LtR_BtT();
+ void moved_leftToRight_LtR_BtT_data();
+ void moved_leftToRight_RtL_BtT();
+ void moved_leftToRight_RtL_BtT_data();
+ void moved_topToBottom_LtR_TtB();
+ void moved_topToBottom_LtR_TtB_data();
+ void moved_topToBottom_RtL_TtB();
+ void moved_topToBottom_RtL_TtB_data();
+ void moved_topToBottom_LtR_BtT();
+ void moved_topToBottom_LtR_BtT_data();
+ void moved_topToBottom_RtL_BtT();
+ void moved_topToBottom_RtL_BtT_data();
+
private:
QList<int> toIntList(const QVariantList &list);
void matchIndexLists(const QVariantList &indexLists, const QList<int> &expectedIndexes);
void matchItemsAndIndexes(const QVariantMap &items, const QaimModel &model, const QList<int> &expectedIndexes);
void matchItemLists(const QVariantList &itemLists, const QList<QQuickItem *> &expectedItems);
+ void multipleChanges(bool condensed);
+ void multipleChanges_data();
+
+ QPointF expectedItemPos(QQuickGridView *grid, int index, qreal rowOffset = 0) {
+ qreal x;
+ qreal y;
+ if (grid->flow() == QQuickGridView::FlowLeftToRight) {
+ int columns = grid->width() / grid->cellWidth();
+ x = (index % columns) * grid->cellWidth();
+ y = (index / columns) * grid->cellHeight();
+ if (grid->effectiveLayoutDirection() == Qt::RightToLeft) {
+ int col = (index % columns) * grid->cellWidth();
+ x = grid->cellWidth() * (columns - 1) - col;
+ }
+
+ qreal offset = grid->cellHeight() * rowOffset;
+ if (grid->verticalLayoutDirection() == QQuickItemView::TopToBottom)
+ y += offset;
+ else
+ y = -grid->cellHeight() - y - offset;
+ } else {
+ int rows = grid->height() / grid->cellHeight();
+ x = (index / rows) * grid->cellWidth();
+ y = (index % rows) * grid->cellHeight();
+ if (grid->effectiveLayoutDirection() == Qt::RightToLeft)
+ x = -x - grid->cellWidth();
+
+ qreal offset = grid->cellWidth() * rowOffset;
+ if (grid->effectiveLayoutDirection() == Qt::RightToLeft)
+ x -= offset;
+ else
+ x += offset;
+ if (grid->verticalLayoutDirection() == QQuickItemView::BottomToTop)
+ y = -grid->cellHeight() - y;
+ }
+ return QPointF(x, y);
+ }
+
+ // Sets contentY (or contentX in TopToBottom flow) according to given row offset
+ // (in LeftToRight flow) or col offset (in TopToBottom).
+ bool setContentPos(QQuickGridView *gridview, qreal rowOrColOffset) {
+ bool contentPosChanged = (rowOrColOffset != 0);
+ qreal contentOffset = gridview->flow() == QQuickGridView::FlowLeftToRight
+ ? rowOrColOffset * gridview->cellHeight()
+ : rowOrColOffset * gridview->cellWidth();
+
+ if (gridview->flow() == QQuickGridView::FlowLeftToRight) {
+ if (gridview->verticalLayoutDirection() == QQuickItemView::BottomToTop)
+ contentOffset = -gridview->height() - contentOffset;
+ } else {
+ if (gridview->effectiveLayoutDirection() == Qt::RightToLeft)
+ contentOffset = -gridview->width() - contentOffset;
+ }
+ if (gridview->flow() == QQuickGridView::FlowLeftToRight)
+ gridview->setContentY(contentOffset);
+ else
+ gridview->setContentX(contentOffset);
+ return contentPosChanged;
+ }
+
#ifdef SHARE_VIEWS
QQuickView *getView() {
if (m_view) {
@@ -217,8 +332,6 @@ void tst_QQuickGridView::items()
QQmlContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("testRightToLeft", QVariant(false));
- ctxt->setContextProperty("testTopToBottom", QVariant(false));
canvas->setSource(testFileUrl("gridview1.qml"));
qApp->processEvents();
@@ -267,8 +380,6 @@ void tst_QQuickGridView::changed()
QQmlContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("testRightToLeft", QVariant(false));
- ctxt->setContextProperty("testTopToBottom", QVariant(false));
canvas->setSource(testFileUrl("gridview1.qml"));
qApp->processEvents();
@@ -290,7 +401,7 @@ void tst_QQuickGridView::changed()
delete canvas;
}
-void tst_QQuickGridView::inserted()
+void tst_QQuickGridView::inserted_basic()
{
QQuickView *canvas = createView();
canvas->show();
@@ -300,11 +411,7 @@ void tst_QQuickGridView::inserted()
model.addItem("John", "2345");
model.addItem("Bob", "54321");
- QQmlContext *ctxt = canvas->rootContext();
- ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("testRightToLeft", QVariant(false));
- ctxt->setContextProperty("testTopToBottom", QVariant(false));
-
+ canvas->rootContext()->setContextProperty("testModel", &model);
canvas->setSource(testFileUrl("gridview1.qml"));
qApp->processEvents();
@@ -370,12 +477,16 @@ void tst_QQuickGridView::inserted()
delete canvas;
}
-void tst_QQuickGridView::inserted_more()
+void tst_QQuickGridView::inserted_defaultLayout(QQuickGridView::Flow flow,
+ Qt::LayoutDirection horizLayout,
+ QQuickItemView::VerticalLayoutDirection verticalLayout)
{
- QFETCH(qreal, contentY);
+ QFETCH(qreal, contentYRowOffset);
QFETCH(int, insertIndex);
QFETCH(int, insertCount);
- QFETCH(qreal, itemsOffsetAfterMove);
+ QFETCH(int, insertIndex_ttb);
+ QFETCH(int, insertCount_ttb);
+ QFETCH(qreal, rowOffsetAfterMove);
QaimModel model;
for (int i = 0; i < 30; i++)
@@ -384,10 +495,10 @@ void tst_QQuickGridView::inserted_more()
QQuickView *canvas = getView();
QQmlContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("testRightToLeft", QVariant(false));
- ctxt->setContextProperty("testTopToBottom", QVariant(false));
-
- canvas->setSource(testFileUrl("gridview1.qml"));
+ ctxt->setContextProperty("testTopToBottom", flow == QQuickGridView::FlowTopToBottom);
+ ctxt->setContextProperty("testRightToLeft", horizLayout == Qt::RightToLeft);
+ ctxt->setContextProperty("testBottomToTop", verticalLayout == QQuickGridView::BottomToTop);
+ canvas->setSource(testFileUrl("layouts.qml"));
canvas->show();
qApp->processEvents();
@@ -396,8 +507,12 @@ void tst_QQuickGridView::inserted_more()
QQuickItem *contentItem = gridview->contentItem();
QTRY_VERIFY(contentItem != 0);
- gridview->setContentY(contentY);
- QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
+ if (flow == QQuickGridView::FlowTopToBottom) {
+ insertIndex = insertIndex_ttb;
+ insertCount = insertCount_ttb;
+ }
+ if (setContentPos(gridview, contentYRowOffset))
+ QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
QList<QPair<QString, QString> > newData;
for (int i=0; i<insertCount; i++)
@@ -408,137 +523,152 @@ void tst_QQuickGridView::inserted_more()
// check visibleItems.first() is in correct position
QQuickItem *item0 = findItem<QQuickItem>(contentItem, "wrapper", 0);
QVERIFY(item0);
- QCOMPARE(item0->y(), 0.0);
+ QPointF firstPos(0, 0);
+ if (horizLayout == Qt::RightToLeft)
+ firstPos.rx() = flow == QQuickGridView::FlowLeftToRight ? gridview->width() - gridview->cellWidth() : -gridview->cellWidth();
+ if (verticalLayout == QQuickItemView::BottomToTop)
+ firstPos.ry() -= gridview->cellHeight();
+ QCOMPARE(item0->pos(), firstPos);
QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper");
int firstVisibleIndex = -1;
for (int i=0; i<items.count(); i++) {
- if (items[i]->y() >= contentY) {
- QQmlExpression e(qmlContext(items[i]), items[i], "index");
- firstVisibleIndex = e.evaluate().toInt();
+ QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+ if (item && item->isVisible()) {
+ firstVisibleIndex = i;
break;
}
}
QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex));
// Confirm items positioned correctly and indexes correct
- int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
- QQuickText *name;
- QQuickText *number;
- for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) {
+ for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++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);
+ QCOMPARE(item->pos(), expectedItemPos(gridview, i, rowOffsetAfterMove));
+ QQuickText *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));
}
releaseView(canvas);
}
-void tst_QQuickGridView::inserted_more_data()
+void tst_QQuickGridView::inserted_defaultLayout_data()
{
- QTest::addColumn<qreal>("contentY");
+ QTest::addColumn<qreal>("contentYRowOffset");
QTest::addColumn<int>("insertIndex");
QTest::addColumn<int>("insertCount");
- QTest::addColumn<qreal>("itemsOffsetAfterMove");
+ QTest::addColumn<int>("insertIndex_ttb");
+ QTest::addColumn<int>("insertCount_ttb");
+ QTest::addColumn<qreal>("rowOffsetAfterMove");
QTest::newRow("add 1, before visible items")
- << 120.0 // show 6-23
+ << 2.0 // show 6-23
<< 5 << 1
+ << 9 << 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
+ << 2.0 // show 6-23
<< 5 << 2
+ << 9 << 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
+ << 2.0 // show 6-23
<< 5 << 3
- << -60.0; // insert 3 (1 row) above first visible in negative pos, first visible does not move
+ << 9 << 5
+ << -1.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
+ << 2.0 // show 6-23
<< 5 << 5
- << -60.0; // insert 1 row + 2 items above first visible, 1 row added at negative pos,
+ << 9 << 7
+ << -1.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
+ << 2.0 // show 6-23
<< 5 << 6
- << -60.0 * 2; // insert 2 rows above first visible in negative pos, first visible does not move
+ << 9 << 10
+ << -1.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 << 1
<< 0.0;
QTest::newRow("add multiple, at start of visible, content at start")
<< 0.0
<< 0 << 3
+ << 0 << 5
<< 0.0;
QTest::newRow("add 1, at start of visible, content not at start")
- << 120.0 // show 6-23
+ << 2.0 // show 6-23
<< 6 << 1
+ << 10 << 1
<< 0.0;
QTest::newRow("add multiple, at start of visible, content not at start")
- << 120.0 // show 6-23
+ << 2.0 // show 6-23
<< 6 << 3
+ << 10 << 5
<< 0.0;
QTest::newRow("add 1, at end of visible, content at start")
<< 0.0
<< 17 << 1
+ << 14 << 1
<< 0.0;
- QTest::newRow("add 1, at end of visible, content at start")
+ QTest::newRow("add row, at end of visible, content at start")
<< 0.0
<< 17 << 3
+ << 14 << 5
<< 0.0;
QTest::newRow("add 1, at end of visible, content not at start")
- << 120.0 // show 6-23
- << 23 << 1
+ << 2.0 // show 6-23
+ << 17+6 << 1
+ << 14+10 << 1
<< 0.0;
QTest::newRow("add multiple, at end of visible, content not at start")
- << 120.0 // show 6-23
- << 23 << 3
+ << 2.0 // show 6-23
+ << 17+6 << 3
+ << 14+10 << 5
<< 0.0;
QTest::newRow("add 1, after visible, content at start")
<< 0.0
<< 20 << 1
+ << 18 << 1
<< 0.0;
- QTest::newRow("add 1, after visible, content at start")
+ QTest::newRow("add row, after visible, content at start")
<< 0.0
<< 20 << 3
+ << 18 << 5
<< 0.0;
QTest::newRow("add 1, after visible, content not at start")
- << 120.0 // show 6-23
- << 24 << 1
+ << 2.0 // show 6-23
+ << 20+6 << 1
+ << 18+10 << 1
<< 0.0;
QTest::newRow("add multiple, after visible, content not at start")
- << 120.0 // show 6-23
- << 24 << 3
+ << 2.0 // show 6-23
+ << 20+6 << 3
+ << 18+10 << 3
<< 0.0;
}
@@ -557,8 +687,6 @@ void tst_QQuickGridView::insertBeforeVisible()
QQmlContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("testRightToLeft", QVariant(false));
- ctxt->setContextProperty("testTopToBottom", QVariant(false));
canvas->setSource(testFileUrl("gridview1.qml"));
canvas->show();
qApp->processEvents();
@@ -633,7 +761,7 @@ void tst_QQuickGridView::insertBeforeVisible_data()
QTest::newRow("insert multiple at 1, 500 buffer") << 1 << 6 << 500;
}
-void tst_QQuickGridView::removed()
+void tst_QQuickGridView::removed_basic()
{
QQuickView *canvas = createView();
canvas->show();
@@ -642,11 +770,7 @@ void tst_QQuickGridView::removed()
for (int i = 0; i < 40; i++)
model.addItem("Item" + QString::number(i), "");
- QQmlContext *ctxt = canvas->rootContext();
- ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("testRightToLeft", QVariant(false));
- ctxt->setContextProperty("testTopToBottom", QVariant(false));
-
+ canvas->rootContext()->setContextProperty("testModel", &model);
canvas->setSource(testFileUrl("gridview1.qml"));
qApp->processEvents();
@@ -778,16 +902,19 @@ void tst_QQuickGridView::removed()
delete canvas;
}
-void tst_QQuickGridView::removed_more()
+void tst_QQuickGridView::removed_defaultLayout(QQuickGridView::Flow flow,
+ Qt::LayoutDirection horizLayout,
+ QQuickItemView::VerticalLayoutDirection verticalLayout)
{
- QFETCH(qreal, contentY);
+ QFETCH(qreal, contentYRowOffset);
QFETCH(int, removeIndex);
QFETCH(int, removeCount);
- QFETCH(qreal, itemsOffsetAfterMove);
+ QFETCH(int, removeIndex_ttb);
+ QFETCH(int, removeCount_ttb);
+ QFETCH(qreal, rowOffsetAfterMove);
QFETCH(QString, firstVisible);
+ QFETCH(QString, firstVisible_ttb);
- QQuickText *name;
- QQuickText *number;
QQuickView *canvas = getView();
QaimModel model;
@@ -796,9 +923,10 @@ void tst_QQuickGridView::removed_more()
QQmlContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("testRightToLeft", QVariant(false));
- ctxt->setContextProperty("testTopToBottom", QVariant(false));
- canvas->setSource(testFileUrl("gridview1.qml"));
+ ctxt->setContextProperty("testTopToBottom", flow == QQuickGridView::FlowTopToBottom);
+ ctxt->setContextProperty("testRightToLeft", horizLayout == Qt::RightToLeft);
+ ctxt->setContextProperty("testBottomToTop", verticalLayout == QQuickGridView::BottomToTop);
+ canvas->setSource(testFileUrl("layouts.qml"));
canvas->show();
qApp->processEvents();
@@ -807,8 +935,13 @@ void tst_QQuickGridView::removed_more()
QQuickItem *contentItem = gridview->contentItem();
QTRY_VERIFY(contentItem != 0);
- gridview->setContentY(contentY);
- QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
+ if (flow == QQuickGridView::FlowTopToBottom) {
+ removeIndex = removeIndex_ttb;
+ removeCount = removeCount_ttb;
+ firstVisible = firstVisible_ttb;
+ }
+ if (setContentPos(gridview, contentYRowOffset))
+ QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
model.removeItems(removeIndex, removeCount);
QTRY_COMPARE(gridview->property("count").toInt(), model.count());
@@ -816,161 +949,183 @@ void tst_QQuickGridView::removed_more()
QString firstName;
int firstVisibleIndex = -1;
QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper");
+ QRectF viewRect(gridview->contentX(), gridview->contentY(), gridview->width(), gridview->height());
for (int i=0; i<items.count(); i++) {
- if (items[i]->y() >= contentY) {
- QQmlExpression e(qmlContext(items[i]), items[i], "index");
- firstVisibleIndex = e.evaluate().toInt();
- QQmlExpression en(qmlContext(items[i]), items[i], "name");
- firstName = en.evaluate().toString();
- break;
+ QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+ if (item) {
+ QRectF itemRect(item->x(), item->y(), item->width(), item->height());
+ if (item->isVisible() && viewRect.intersects(itemRect)) {
+ firstVisibleIndex = i;
+ QQmlExpression en(qmlContext(item), item, "name");
+ firstName = en.evaluate().toString();
+ break;
+ }
}
}
QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex));
QCOMPARE(firstName, firstVisible);
// Confirm items positioned correctly and indexes correct
- int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
- for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) {
+ for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++i) {
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);
+ QCOMPARE(item->pos(), expectedItemPos(gridview, i, rowOffsetAfterMove));
+ QQuickText *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));
}
releaseView(canvas);
}
-void tst_QQuickGridView::removed_more_data()
+void tst_QQuickGridView::removed_defaultLayout_data()
{
- QTest::addColumn<qreal>("contentY");
+ QTest::addColumn<qreal>("contentYRowOffset");
QTest::addColumn<int>("removeIndex");
QTest::addColumn<int>("removeCount");
- QTest::addColumn<qreal>("itemsOffsetAfterMove");
+ QTest::addColumn<int>("removeIndex_ttb");
+ QTest::addColumn<int>("removeCount_ttb");
+ QTest::addColumn<qreal>("rowOffsetAfterMove");
QTest::addColumn<QString>("firstVisible");
+ QTest::addColumn<QString>("firstVisible_ttb");
QTest::newRow("remove 1, before visible items")
- << 120.0 // show 6-23
+ << 2.0 // show 6-23
<< 2 << 1
- << 0.0 << "Item7";
+ << 4 << 1
+ << 0.0 << "Item7" << "Item11";
QTest::newRow("remove 1, before visible position")
- << 120.0 // show 6-23
+ << 2.0 // show 6-23
<< 3 << 1
- << 0.0 << "Item7";
+ << 5 << 1
+ << 0.0 << "Item7" << "Item11";
- QTest::newRow("remove multiple, all before visible items")
- << 120.0
+ QTest::newRow("remove multiple (1 row), all before visible items")
+ << 2.0
<< 1 << 3
- << 60.0 << "Item6"; // removed top row, slide down by 1 row
+ << 1 << 5
+ << 1.0 << "Item6" << "Item10"; // removed top row, slide down by 1 row
QTest::newRow("remove multiple, all before visible items, remove item 0")
- << 120.0
+ << 2.0
<< 0 << 4
- << 60.0 << "Item7"; // removed top row, slide down by 1 row
+ << 0 << 6
+ << 1.0 << "Item7" << "Item11"; // removed top row, slide down by 1 row
QTest::newRow("remove multiple rows, all before visible items")
- << 240.0 // show 12-29
+ << 4.0 // show 12-29
<< 1 << 7
- << 120.0 << "Item13";
+ << 1 << 12
+ << 2.0 << "Item13" << "Item17";
QTest::newRow("remove one row before visible, content y not on item border")
- << 100.0
+ << 1.5
<< 0 << 3
- << 60.0 << "Item6"; // 1 row removed
+ << 0 << 5
+ << 1.0 << "Item3" << "Item5"; // 1 row removed
QTest::newRow("remove mix of visible/non-visible")
- << 120.0 // show 6-23
+ << 2.0 // show 6-23
<< 2 << 3
- << 60.0 << "Item6"; // 1 row removed
+ << 4 << 3
+ << 1.0 << "Item6" << "Item8"; // 1 row removed
// remove 3,4,5 before the visible pos, first row moves down to just before the visible pos,
// items 6,7 are removed from view, item 8 slides up to original pos of item 6 (120px)
QTest::newRow("remove multiple, mix of items from before and within visible items")
- << 120.0
+ << 2.0
<< 3 << 5
- << 60.0 << "Item8"; // adjust for the 1 row removed before the visible
+ << 5 << 7
+ << 1.0 << "Item8" << "Item12"; // adjust for the 1 row removed before the visible
QTest::newRow("remove multiple, mix of items from before and within visible items, remove item 0")
- << 120.0
+ << 2.0
<< 0 << 8
- << 60.0 * 2 << "Item8"; // adjust for the 2 rows removed before the visible
+ << 0 << 12
+ << 1.0 * 2 << "Item8" << "Item12"; // adjust for the 2 rows removed before the visible
QTest::newRow("remove 1, from start of visible, content at start")
<< 0.0
<< 0 << 1
- << 0.0 << "Item1";
+ << 0 << 1
+ << 0.0 << "Item1" << "Item1";
QTest::newRow("remove multiple, from start of visible, content at start")
<< 0.0
<< 0 << 3
- << 0.0 << "Item3";
+ << 0 << 5
+ << 0.0 << "Item3" << "Item5";
QTest::newRow("remove 1, from start of visible, content not at start")
- << 120.0 // show 6-23
+ << 2.0 // show 6-23
<< 4 << 1
- << 0.0 << "Item7";
+ << 7 << 1
+ << 0.0 << "Item7" << "Item11";
QTest::newRow("remove multiple, from start of visible, content not at start")
- << 120.0 // show 6-23
+ << 2.0 // show 6-23
<< 4 << 3
- << 0.0 << "Item9";
+ << 7 << 5
+ << 0.0 << "Item9" << "Item15";
QTest::newRow("remove 1, from middle of visible, content at start")
<< 0.0
<< 10 << 1
- << 0.0 << "Item0";
+ << 12 << 1
+ << 0.0 << "Item0" << "Item0";
QTest::newRow("remove multiple, from middle of visible, content at start")
<< 0.0
<< 10 << 5
- << 0.0 << "Item0";
+ << 12 << 5
+ << 0.0 << "Item0" << "Item0";
QTest::newRow("remove 1, from middle of visible, content not at start")
- << 120.0 // show 6-23
+ << 2.0 // show 6-23
<< 10 << 1
- << 0.0 << "Item6";
+ << 12 << 1
+ << 0.0 << "Item6" << "Item10";
QTest::newRow("remove multiple, from middle of visible, content not at start")
- << 120.0 // show 6-23
+ << 2.0 // show 6-23
<< 10 << 5
- << 0.0 << "Item6";
+ << 12 << 7
+ << 0.0 << "Item6" << "Item10";
QTest::newRow("remove 1, after visible, content at start")
<< 0.0
<< 16 << 1
- << 0.0 << "Item0";
+ << 15 << 1
+ << 0.0 << "Item0" << "Item0";
QTest::newRow("remove multiple, after visible, content at start")
<< 0.0
<< 16 << 5
- << 0.0 << "Item0";
+ << 15 << 7
+ << 0.0 << "Item0" << "Item0";
QTest::newRow("remove 1, after visible, content not at start")
- << 120.0 // show 6-23
+ << 2.0 // show 6-23
<< 16+4 << 1
- << 0.0 << "Item6";
+ << 15+10 << 1
+ << 0.0 << "Item6" << "Item10";
QTest::newRow("remove multiple, after visible, content not at start")
- << 120.0 // show 6-23
+ << 2.0 // show 6-23
<< 16+4 << 5
- << 0.0 << "Item6";
+ << 15+10 << 7
+ << 0.0 << "Item6" << "Item10";
QTest::newRow("remove multiple, mix of items from within and after visible items")
- << 120.0 // show 6-23
+ << 2.0 // show 6-23
<< 20 << 5
- << 0.0 << "Item6";
+ << 22 << 7
+ << 0.0 << "Item6" << "Item10";
}
void tst_QQuickGridView::addOrRemoveBeforeVisible()
@@ -988,10 +1143,7 @@ void tst_QQuickGridView::addOrRemoveBeforeVisible()
for (int i = 0; i < 30; i++)
model.addItem("Item" + QString::number(i), "");
- QQmlContext *ctxt = canvas->rootContext();
- ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("testRightToLeft", QVariant(false));
- ctxt->setContextProperty("testTopToBottom", QVariant(false));
+ canvas->rootContext()->setContextProperty("testModel", &model);
canvas->setSource(testFileUrl("gridview1.qml"));
QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
@@ -1067,11 +1219,7 @@ void tst_QQuickGridView::clear()
for (int i = 0; i < 30; i++)
model.addItem("Item" + QString::number(i), "");
- QQmlContext *ctxt = canvas->rootContext();
- ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("testRightToLeft", QVariant(false));
- ctxt->setContextProperty("testTopToBottom", QVariant(false));
-
+ canvas->rootContext()->setContextProperty("testModel", &model);
canvas->setSource(testFileUrl("gridview1.qml"));
canvas->show();
qApp->processEvents();
@@ -1098,28 +1246,31 @@ void tst_QQuickGridView::clear()
delete canvas;
}
-void tst_QQuickGridView::moved()
+void tst_QQuickGridView::moved_defaultLayout(QQuickGridView::Flow flow,
+ Qt::LayoutDirection horizLayout,
+ QQuickItemView::VerticalLayoutDirection verticalLayout)
{
- QFETCH(qreal, contentY);
+ QFETCH(qreal, contentYRowOffset);
QFETCH(int, from);
QFETCH(int, to);
QFETCH(int, count);
- QFETCH(qreal, itemsOffsetAfterMove);
+ QFETCH(int, from_ttb);
+ QFETCH(int, to_ttb);
+ QFETCH(int, count_ttb);
+ QFETCH(qreal, rowOffsetAfterMove);
- QQuickText *name;
- QQuickText *number;
QQuickView *canvas = getView();
QaimModel model;
for (int i = 0; i < 30; i++)
model.addItem("Item" + QString::number(i), "");
- QQmlContext *ctxt = canvas->rootContext();
+ QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("testRightToLeft", QVariant(false));
- ctxt->setContextProperty("testTopToBottom", QVariant(false));
-
- canvas->setSource(testFileUrl("gridview1.qml"));
+ ctxt->setContextProperty("testTopToBottom", flow == QQuickGridView::FlowTopToBottom);
+ ctxt->setContextProperty("testRightToLeft", horizLayout == Qt::RightToLeft);
+ ctxt->setContextProperty("testBottomToTop", verticalLayout == QQuickGridView::BottomToTop);
+ canvas->setSource(testFileUrl("layouts.qml"));
canvas->show();
qApp->processEvents();
@@ -1132,32 +1283,41 @@ void tst_QQuickGridView::moved()
QQuickItem *currentItem = gridview->currentItem();
QTRY_VERIFY(currentItem != 0);
- if (contentY != 0) {
- gridview->setContentY(contentY);
- QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
+ if (flow == QQuickGridView::FlowTopToBottom) {
+ from = from_ttb;
+ to = to_ttb;
+ count = count_ttb;
}
+ if (setContentPos(gridview, contentYRowOffset))
+ QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
model.moveItems(from, to, count);
QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
// 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;
+ QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper");
+ int firstVisibleIndex = -1;
+ for (int i=0; i<items.count(); i++) {
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);
+ if (item && item->isVisible()) {
+ firstVisibleIndex = i;
+ break;
+ }
+ }
+ QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex));
- name = findItem<QQuickText>(contentItem, "textName", i);
+ for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++i) {
+ QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+ if (!item &&
+ ( (flow == QQuickGridView::FlowLeftToRight && i >= firstVisibleIndex + (3*6))
+ || flow == QQuickGridView::FlowTopToBottom && i >= firstVisibleIndex + (5*3) ) ) {
+ continue; // index has moved out of view
+ }
+ QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+ QCOMPARE(item->pos(), expectedItemPos(gridview, i, rowOffsetAfterMove));
+ QQuickText *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)
@@ -1167,13 +1327,16 @@ void tst_QQuickGridView::moved()
releaseView(canvas);
}
-void tst_QQuickGridView::moved_data()
+void tst_QQuickGridView::moved_defaultLayout_data()
{
- QTest::addColumn<qreal>("contentY");
+ QTest::addColumn<qreal>("contentYRowOffset");
QTest::addColumn<int>("from");
QTest::addColumn<int>("to");
QTest::addColumn<int>("count");
- QTest::addColumn<qreal>("itemsOffsetAfterMove");
+ QTest::addColumn<int>("from_ttb");
+ QTest::addColumn<int>("to_ttb");
+ QTest::addColumn<int>("count_ttb");
+ QTest::addColumn<qreal>("rowOffsetAfterMove");
// model starts with 30 items, each 80x60, in area 240x320
// 18 items should be visible at a time
@@ -1185,143 +1348,170 @@ void tst_QQuickGridView::moved_data()
QTest::newRow("move 1 forwards, within visible items")
<< 0.0
<< 1 << 8 << 1
+ << 2 << 12 << 1
<< 0.0;
QTest::newRow("move 1 forwards, from non-visible -> visible")
- << 120.0 // show 6-23
- << 1 << 23 << 1
+ << 2.0 // show 6-23
+ << 1 << 8+6 << 1
+ << 2 << 12+10 << 1
<< 0.0;
QTest::newRow("move 1 forwards, from non-visible -> visible (move first item)")
- << 120.0 // // show 6-23
+ << 2.0 // // show 6-23
<< 0 << 6 << 1
+ << 0 << 10 << 1
<< 0.0;
QTest::newRow("move 1 forwards, from visible -> non-visible")
<< 0.0
<< 1 << 20 << 1
+ << 1 << 20 << 1
<< 0.0;
QTest::newRow("move 1 forwards, from visible -> non-visible (move first item)")
<< 0.0
<< 0 << 20 << 1
+ << 0 << 20 << 1
<< 0.0;
QTest::newRow("move 1 backwards, within visible items")
<< 0.0
<< 10 << 5 << 1
+ << 10 << 5 << 1
<< 0.0;
QTest::newRow("move 1 backwards, within visible items (to first index)")
<< 0.0
<< 10 << 0 << 1
+ << 10 << 0 << 1
<< 0.0;
QTest::newRow("move 1 backwards, from non-visible -> visible")
<< 0.0
<< 28 << 8 << 1
+ << 28 << 8 << 1
<< 0.0;
QTest::newRow("move 1 backwards, from non-visible -> visible (move last item)")
<< 0.0
<< 29 << 14 << 1
+ << 29 << 14 << 1
<< 0.0;
QTest::newRow("move 1 backwards, from visible -> non-visible")
- << 120.0 // show 6-23
+ << 2.0 // show 6-23
<< 7 << 1 << 1
+ << 10 << 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
+ << 2.0 // show 6-23
<< 7 << 0 << 1
+ << 10 << 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 << 7 << 5
<< 0.0;
QTest::newRow("move multiple backwards, within visible items (move first item)")
<< 0.0
<< 10 << 0 << 3
+ << 12 << 0 << 5
<< 0.0;
QTest::newRow("move multiple forwards, before visible items")
- << 120.0 // show 6-23
+ << 2.0 // show 6-23
<< 3 << 4 << 3 // 3, 4, 5 move to after 6
- << 60.0; // row of 3,4,5 has moved down
+ << 5 << 6 << 5
+ << 1.0; // row of 3,4,5 has moved down
QTest::newRow("move multiple forwards, from non-visible -> visible")
- << 120.0 // show 6-23
+ << 2.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
+ << 1 << 10 << 5
+ << 1.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
+ << 2.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
+ << 0 << 10 << 5
+ << 1.0; // top row moved and shifted to below 3rd row, all items should shift down by 1 row
QTest::newRow("move multiple forwards, mix of non-visible/visible")
- << 120.0
+ << 2.0
<< 3 << 16 << 6
- << 60.0; // top two rows removed, third row is now the first visible
+ << 5 << 18 << 10
+ << 1.0; // top two rows removed, third row is now the first visible
QTest::newRow("move multiple forwards, to bottom of view")
<< 0.0
<< 5 << 13 << 5
+ << 1 << 8 << 6
<< 0.0;
QTest::newRow("move multiple forwards, to bottom of view, first row -> last")
<< 0.0
<< 0 << 15 << 3
+ << 0 << 10 << 5
<< 0.0;
QTest::newRow("move multiple forwards, to bottom of view, content y not 0")
- << 120.0
+ << 2.0
<< 5+4 << 13+4 << 5
+ << 11 << 19 << 6
<< 0.0;
QTest::newRow("move multiple forwards, from visible -> non-visible")
<< 0.0
<< 1 << 16 << 3
+ << 1 << 18 << 5
<< 0.0;
QTest::newRow("move multiple forwards, from visible -> non-visible (move first item)")
<< 0.0
<< 0 << 16 << 3
+ << 1 << 18 << 5
<< 0.0;
QTest::newRow("move multiple backwards, within visible items")
<< 0.0
<< 4 << 1 << 3
+ << 7 << 1 << 5
<< 0.0;
QTest::newRow("move multiple backwards, from non-visible -> visible")
<< 0.0
<< 20 << 4 << 3
+ << 20 << 4 << 5
<< 0.0;
QTest::newRow("move multiple backwards, from non-visible -> visible (move last item)")
<< 0.0
<< 27 << 10 << 3
+ << 25 << 8 << 5
<< 0.0;
QTest::newRow("move multiple backwards, from visible -> non-visible")
- << 120.0 // show 6-23
+ << 2.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
+ << 17 << 1 << 5
+ << -1.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
+ << 2.0 // show 6-23
<< 16 << 0 << 3
- << -60.0; // 16,17,18 move to above item 0, all items move up by 1 row
+ << 17 << 0 << 5
+ << -1.0; // 16,17,18 move to above item 0, all items move up by 1 row
}
-void tst_QQuickGridView::multipleChanges()
+void tst_QQuickGridView::multipleChanges(bool condensed)
{
QFETCH(int, startCount);
QFETCH(QList<ListChange>, changes);
@@ -1334,11 +1524,7 @@ void tst_QQuickGridView::multipleChanges()
for (int i = 0; i < startCount; i++)
model.addItem("Item" + QString::number(i), "");
- QQmlContext *ctxt = canvas->rootContext();
- ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("testRightToLeft", QVariant(false));
- ctxt->setContextProperty("testTopToBottom", QVariant(false));
-
+ canvas->rootContext()->setContextProperty("testModel", &model);
canvas->setSource(testFileUrl("gridview1.qml"));
canvas->show();
qApp->processEvents();
@@ -1359,26 +1545,26 @@ void tst_QQuickGridView::multipleChanges()
}
case ListChange::Removed:
model.removeItems(changes[i].index, changes[i].count);
- QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
break;
case ListChange::Moved:
model.moveItems(changes[i].index, changes[i].to, changes[i].count);
- QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
break;
case ListChange::SetCurrent:
gridview->setCurrentIndex(changes[i].index);
- QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
break;
case ListChange::SetContentY:
gridview->setContentY(changes[i].pos);
- QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
break;
}
+ if (condensed) {
+ QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
+ }
}
+ QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
- QTRY_COMPARE(gridview->count(), newCount);
+ QCOMPARE(gridview->count(), newCount);
QCOMPARE(gridview->count(), model.count());
- QTRY_COMPARE(gridview->currentIndex(), newCurrentIndex);
+ QCOMPARE(gridview->currentIndex(), newCurrentIndex);
QQuickText *name;
QQuickText *number;
@@ -1547,6 +1733,28 @@ void tst_QQuickGridView::multipleChanges_data()
<< ListChange::remove(0, 5)
<< ListChange::insert(0, 5)
) << 5 << -1;
+
+ QTest::newRow("remove, scroll") << 30 << (QList<ListChange>()
+ << ListChange::remove(20, 5)
+ << ListChange::setContentY(20)
+ ) << 25 << 0;
+
+ QTest::newRow("insert, scroll") << 10 << (QList<ListChange>()
+ << ListChange::insert(9, 5)
+ << ListChange::setContentY(20)
+ ) << 15 << 0;
+
+ QTest::newRow("move, scroll") << 20 << (QList<ListChange>()
+ << ListChange::move(15, 8, 3)
+ << ListChange::setContentY(0)
+ ) << 20 << 0;
+
+ QTest::newRow("clear, insert, scroll") << 30 << (QList<ListChange>()
+ << ListChange::setContentY(20)
+ << ListChange::remove(0, 30)
+ << ListChange::insert(0, 2)
+ << ListChange::setContentY(0)
+ ) << 2 << 0;
}
@@ -1559,11 +1767,7 @@ void tst_QQuickGridView::swapWithFirstItem()
for (int i = 0; i < 30; i++)
model.addItem("Item" + QString::number(i), "");
- QQmlContext *ctxt = canvas->rootContext();
- ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("testRightToLeft", QVariant(false));
- ctxt->setContextProperty("testTopToBottom", QVariant(false));
-
+ canvas->rootContext()->setContextProperty("testModel", &model);
canvas->setSource(testFileUrl("gridview1.qml"));
canvas->show();
qApp->processEvents();
@@ -1610,57 +1814,11 @@ void tst_QQuickGridView::currentIndex()
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);
-
- // wait until motion stops
- QTRY_VERIFY(gridview->verticalVelocity() == 0.0);
-
- // 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());
@@ -1679,78 +1837,6 @@ void tst_QQuickGridView::currentIndex()
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);
@@ -1774,54 +1860,6 @@ void tst_QQuickGridView::currentIndex()
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());
-
// moving currentItem out of view should make it invisible
gridview->setCurrentIndex(0);
QTRY_VERIFY(gridview->currentItem()->isVisible());
@@ -1868,6 +1906,199 @@ void tst_QQuickGridView::noCurrentIndex()
delete canvas;
}
+void tst_QQuickGridView::keyNavigation()
+{
+ QFETCH(QQuickGridView::Flow, flow);
+ QFETCH(Qt::LayoutDirection, layoutDirection);
+ QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection);
+ QFETCH(Qt::Key, forwardsKey);
+ QFETCH(Qt::Key, backwardsKey);
+ QFETCH(QPointF, contentPosAtFirstItem);
+ QFETCH(QPointF, contentPosAtLastItem);
+ QFETCH(int, indexRightOf7);
+ QFETCH(int, indexLeftOf7);
+ QFETCH(int, indexUpFrom7);
+ QFETCH(int, indexDownFrom7);
+
+ QmlListModel model;
+ for (int i = 0; i < 18; i++)
+ model.addItem("Item" + QString::number(i), "");
+
+ QQuickView *canvas = getView();
+ canvas->rootContext()->setContextProperty("testModel", &model);
+ canvas->setSource(testFileUrl("gridview1.qml"));
+ canvas->show();
+ qApp->processEvents();
+
+ QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+ QTRY_VERIFY(gridview != 0);
+ gridview->setFlow(flow);
+ gridview->setLayoutDirection(layoutDirection);
+ gridview->setVerticalLayoutDirection(verticalLayoutDirection);
+ QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
+
+ canvas->requestActivateWindow();
+ QTRY_VERIFY(qGuiApp->focusWindow() == canvas);
+ QCOMPARE(gridview->currentIndex(), 0);
+
+ QTest::keyClick(canvas, forwardsKey);
+ QCOMPARE(gridview->currentIndex(), 1);
+
+ QTest::keyClick(canvas, backwardsKey);
+ QCOMPARE(gridview->currentIndex(), 0);
+
+ gridview->setCurrentIndex(7);
+ gridview->moveCurrentIndexRight();
+ QCOMPARE(gridview->currentIndex(), indexRightOf7);
+ gridview->moveCurrentIndexLeft();
+ QCOMPARE(gridview->currentIndex(), 7);
+ gridview->moveCurrentIndexLeft();
+ QCOMPARE(gridview->currentIndex(), indexLeftOf7);
+ gridview->moveCurrentIndexRight();
+ QCOMPARE(gridview->currentIndex(), 7);
+ gridview->moveCurrentIndexUp();
+ QCOMPARE(gridview->currentIndex(), indexUpFrom7);
+ gridview->moveCurrentIndexDown();
+ QCOMPARE(gridview->currentIndex(), 7);
+ gridview->moveCurrentIndexDown();
+ QCOMPARE(gridview->currentIndex(), indexDownFrom7);
+
+ gridview->setCurrentIndex(7);
+ QTest::keyClick(canvas, Qt::Key_Right);
+ QCOMPARE(gridview->currentIndex(), indexRightOf7);
+ QTest::keyClick(canvas, Qt::Key_Left);
+ QCOMPARE(gridview->currentIndex(), 7);
+ QTest::keyClick(canvas, Qt::Key_Left);
+ QCOMPARE(gridview->currentIndex(), indexLeftOf7);
+ QTest::keyClick(canvas, Qt::Key_Right);
+ QCOMPARE(gridview->currentIndex(), 7);
+ QTest::keyClick(canvas, Qt::Key_Up);
+ QCOMPARE(gridview->currentIndex(), indexUpFrom7);
+ QTest::keyClick(canvas, Qt::Key_Down);
+ QCOMPARE(gridview->currentIndex(), 7);
+ QTest::keyClick(canvas, Qt::Key_Down);
+ QCOMPARE(gridview->currentIndex(), indexDownFrom7);
+
+ // hold down a key to go forwards
+ gridview->setCurrentIndex(0);
+ for (int i=0; i<model.count()-1; i++) {
+// QTest::qWait(500);
+ QTest::simulateEvent(canvas, true, forwardsKey, Qt::NoModifier, "", true);
+ QTRY_COMPARE(gridview->currentIndex(), i+1);
+ }
+ QTest::keyRelease(canvas, forwardsKey);
+ QTRY_COMPARE(gridview->currentIndex(), model.count()-1);
+ QTRY_COMPARE(gridview->contentX(), contentPosAtLastItem.x());
+ QTRY_COMPARE(gridview->contentY(), contentPosAtLastItem.y());
+
+ // hold down a key to go backwards
+ for (int i=model.count()-1; i > 0; i--) {
+ QTest::simulateEvent(canvas, true, backwardsKey, Qt::NoModifier, "", true);
+ QTRY_COMPARE(gridview->currentIndex(), i-1);
+ }
+ QTest::keyRelease(canvas, backwardsKey);
+ QTRY_COMPARE(gridview->currentIndex(), 0);
+ QTRY_COMPARE(gridview->contentX(), contentPosAtFirstItem.x());
+ QTRY_COMPARE(gridview->contentY(), contentPosAtFirstItem.y());
+
+ // no wrap
+ QVERIFY(!gridview->isWrapEnabled());
+ QTest::keyClick(canvas, forwardsKey);
+ QCOMPARE(gridview->currentIndex(), 1);
+ QTest::keyClick(canvas, backwardsKey);
+ QCOMPARE(gridview->currentIndex(), 0);
+
+ QTest::keyClick(canvas, backwardsKey);
+ QCOMPARE(gridview->currentIndex(), 0);
+
+ // with wrap
+ gridview->setWrapEnabled(true);
+ QVERIFY(gridview->isWrapEnabled());
+
+ QTest::keyClick(canvas, backwardsKey);
+ QCOMPARE(gridview->currentIndex(), model.count()-1);
+ QTRY_COMPARE(gridview->contentX(), contentPosAtLastItem.x());
+ QTRY_COMPARE(gridview->contentY(), contentPosAtLastItem.y());
+
+ QTest::keyClick(canvas, forwardsKey);
+ QCOMPARE(gridview->currentIndex(), 0);
+ QTRY_COMPARE(gridview->contentX(), contentPosAtFirstItem.x());
+ QTRY_COMPARE(gridview->contentY(), contentPosAtFirstItem.y());
+
+ releaseView(canvas);
+}
+
+void tst_QQuickGridView::keyNavigation_data()
+{
+ QTest::addColumn<QQuickGridView::Flow>("flow");
+ QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<QQuickItemView::VerticalLayoutDirection>("verticalLayoutDirection");
+ QTest::addColumn<Qt::Key>("forwardsKey");
+ QTest::addColumn<Qt::Key>("backwardsKey");
+ QTest::addColumn<QPointF>("contentPosAtFirstItem");
+ QTest::addColumn<QPointF>("contentPosAtLastItem");
+ QTest::addColumn<int>("indexRightOf7");
+ QTest::addColumn<int>("indexLeftOf7");
+ QTest::addColumn<int>("indexUpFrom7");
+ QTest::addColumn<int>("indexDownFrom7");
+
+ QTest::newRow("LeftToRight, LtR, TtB")
+ << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::TopToBottom
+ << Qt::Key_Right << Qt::Key_Left
+ << QPointF(0, 0)
+ << QPointF(0, 40)
+ << 8 << 6 << 4 << 10;
+
+ QTest::newRow("LeftToRight, RtL, TtB")
+ << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::TopToBottom
+ << Qt::Key_Left << Qt::Key_Right
+ << QPointF(0, 0)
+ << QPointF(0, 40)
+ << 6 << 8 << 4 << 10;
+
+ QTest::newRow("LeftToRight, LtR, BtT")
+ << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::BottomToTop
+ << Qt::Key_Right << Qt::Key_Left
+ << QPointF(0, -320)
+ << QPointF(0, -360)
+ << 8 << 6 << 10 << 4;
+
+ QTest::newRow("LeftToRight, RtL, BtT")
+ << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::BottomToTop
+ << Qt::Key_Left << Qt::Key_Right
+ << QPointF(0, -320)
+ << QPointF(0, -360)
+ << 6 << 8 << 10 << 4;
+
+ QTest::newRow("TopToBottom, LtR, TtB")
+ << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::TopToBottom
+ << Qt::Key_Down << Qt::Key_Up
+ << QPointF(0, 0)
+ << QPointF(80, 0)
+ << 12 << 2 << 6 << 8;
+
+ QTest::newRow("TopToBottom, RtL, TtB")
+ << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::TopToBottom
+ << Qt::Key_Down << Qt::Key_Up
+ << QPointF(-240, 0)
+ << QPointF(-320, 0)
+ << 2 << 12 << 6 << 8;
+
+ QTest::newRow("TopToBottom, LtR, BtT")
+ << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::BottomToTop
+ << Qt::Key_Up << Qt::Key_Down
+ << QPointF(0, -320)
+ << QPointF(80, -320)
+ << 12 << 2 << 8 << 6;
+
+ QTest::newRow("TopToBottom, RtL, BtT")
+ << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::BottomToTop
+ << Qt::Key_Up << Qt::Key_Down
+ << QPointF(-240, -320)
+ << QPointF(-320, -320)
+ << 2 << 12 << 8 << 6;
+}
+
void tst_QQuickGridView::changeFlow()
{
QQuickView *canvas = createView();
@@ -1880,8 +2111,9 @@ void tst_QQuickGridView::changeFlow()
ctxt->setContextProperty("testModel", &model);
ctxt->setContextProperty("testRightToLeft", QVariant(false));
ctxt->setContextProperty("testTopToBottom", QVariant(false));
+ ctxt->setContextProperty("testBottomToTop", QVariant(false));
- canvas->setSource(testFileUrl("gridview1.qml"));
+ canvas->setSource(testFileUrl("layouts.qml"));
qApp->processEvents();
QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
@@ -2027,15 +2259,15 @@ void tst_QQuickGridView::propertyChanges()
QTRY_COMPARE(gridView->isWrapEnabled(), true);
QTRY_COMPARE(gridView->cacheBuffer(), 10);
- QTRY_COMPARE(gridView->flow(), QQuickGridView::LeftToRight);
+ QTRY_COMPARE(gridView->flow(), QQuickGridView::FlowLeftToRight);
gridView->setWrapEnabled(false);
gridView->setCacheBuffer(3);
- gridView->setFlow(QQuickGridView::TopToBottom);
+ gridView->setFlow(QQuickGridView::FlowTopToBottom);
QTRY_COMPARE(gridView->isWrapEnabled(), false);
QTRY_COMPARE(gridView->cacheBuffer(), 3);
- QTRY_COMPARE(gridView->flow(), QQuickGridView::TopToBottom);
+ QTRY_COMPARE(gridView->flow(), QQuickGridView::FlowTopToBottom);
QTRY_COMPARE(keyNavigationWrapsSpy.count(),1);
QTRY_COMPARE(cacheBufferSpy.count(),1);
@@ -2043,14 +2275,14 @@ void tst_QQuickGridView::propertyChanges()
gridView->setWrapEnabled(false);
gridView->setCacheBuffer(3);
- gridView->setFlow(QQuickGridView::TopToBottom);
+ gridView->setFlow(QQuickGridView::FlowTopToBottom);
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->setFlow(QQuickGridView::FlowLeftToRight);
+ QTRY_COMPARE(gridView->flow(), QQuickGridView::FlowLeftToRight);
gridView->setWrapEnabled(true);
gridView->setCacheBuffer(5);
@@ -2074,11 +2306,11 @@ void tst_QQuickGridView::propertyChanges()
QTRY_COMPARE(layoutSpy.count(),1);
QTRY_COMPARE(flowSpy.count(),2);
- gridView->setFlow(QQuickGridView::TopToBottom);
- QTRY_COMPARE(gridView->flow(), QQuickGridView::TopToBottom);
+ gridView->setFlow(QQuickGridView::FlowTopToBottom);
+ QTRY_COMPARE(gridView->flow(), QQuickGridView::FlowTopToBottom);
QTRY_COMPARE(flowSpy.count(),3);
- gridView->setFlow(QQuickGridView::TopToBottom);
+ gridView->setFlow(QQuickGridView::FlowTopToBottom);
QTRY_COMPARE(flowSpy.count(),3);
delete canvas;
@@ -2179,8 +2411,9 @@ void tst_QQuickGridView::positionViewAtIndex()
ctxt->setContextProperty("testModel", &model);
ctxt->setContextProperty("testRightToLeft", QVariant(false));
ctxt->setContextProperty("testTopToBottom", QVariant(false));
+ ctxt->setContextProperty("testBottomToTop", QVariant(false));
- canvas->setSource(testFileUrl("gridview1.qml"));
+ canvas->setSource(testFileUrl("layouts.qml"));
canvas->show();
qApp->processEvents();
@@ -2377,11 +2610,7 @@ void tst_QQuickGridView::snapping()
for (int i = 0; i < 40; i++)
model.addItem("Item" + QString::number(i), "");
- QQmlContext *ctxt = canvas->rootContext();
- ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("testTopToBottom", QVariant(false));
- ctxt->setContextProperty("testRightToLeft", QVariant(false));
-
+ canvas->rootContext()->setContextProperty("testModel", &model);
canvas->setSource(testFileUrl("gridview1.qml"));
qApp->processEvents();
@@ -2483,8 +2712,9 @@ void tst_QQuickGridView::positionViewAtIndex_rightToLeft()
ctxt->setContextProperty("testModel", &model);
ctxt->setContextProperty("testTopToBottom", QVariant(true));
ctxt->setContextProperty("testRightToLeft", QVariant(true));
+ ctxt->setContextProperty("testBottomToTop", QVariant(false));
- canvas->setSource(testFileUrl("gridview1.qml"));
+ canvas->setSource(testFileUrl("layouts.qml"));
qApp->processEvents();
QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
@@ -2812,8 +3042,8 @@ void tst_QQuickGridView::manualHighlight()
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->setFlow(QQuickGridView::FlowTopToBottom);
+ QTRY_COMPARE(gridview->flow(), QQuickGridView::FlowTopToBottom);
gridview->setCurrentIndex(0);
QTRY_COMPARE(gridview->currentIndex(), 0);
@@ -2829,10 +3059,10 @@ void tst_QQuickGridView::footer()
{
QFETCH(QQuickGridView::Flow, flow);
QFETCH(Qt::LayoutDirection, layoutDirection);
+ QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection);
QFETCH(QPointF, initialFooterPos);
QFETCH(QPointF, changedFooterPos);
QFETCH(QPointF, initialContentPos);
- QFETCH(QPointF, changedContentPos);
QFETCH(QPointF, firstDelegatePos);
QFETCH(QPointF, resizeContentPos);
@@ -2845,7 +3075,6 @@ void tst_QQuickGridView::footer()
QQmlContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
-
canvas->setSource(testFileUrl("footer.qml"));
qApp->processEvents();
@@ -2853,13 +3082,14 @@ void tst_QQuickGridView::footer()
QTRY_VERIFY(gridview != 0);
gridview->setFlow(flow);
gridview->setLayoutDirection(layoutDirection);
+ gridview->setVerticalLayoutDirection(verticalLayoutDirection);
+ QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
QQuickItem *contentItem = gridview->contentItem();
QTRY_VERIFY(contentItem != 0);
QQuickText *footer = findItem<QQuickText>(contentItem, "footer");
QVERIFY(footer);
-
QVERIFY(footer == gridview->footerItem());
QCOMPARE(footer->pos(), initialFooterPos);
@@ -2867,7 +3097,7 @@ void tst_QQuickGridView::footer()
QCOMPARE(footer->height(), 30.);
QCOMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos);
- if (flow == QQuickGridView::LeftToRight)
+ if (flow == QQuickGridView::FlowLeftToRight)
QCOMPARE(gridview->contentHeight(), (model.count()+2) / 3 * 60. + footer->height());
else
QCOMPARE(gridview->contentWidth(), (model.count()+3) / 5 * 80. + footer->width());
@@ -2876,10 +3106,13 @@ void tst_QQuickGridView::footer()
QVERIFY(item);
QCOMPARE(item->pos(), firstDelegatePos);
- if (flow == QQuickGridView::LeftToRight) {
+ if (flow == QQuickGridView::FlowLeftToRight) {
// shrink by one row
model.removeItem(2);
- QTRY_COMPARE(footer->y(), initialFooterPos.y() - gridview->cellHeight());
+ if (verticalLayoutDirection == QQuickItemView::TopToBottom)
+ QTRY_COMPARE(footer->y(), initialFooterPos.y() - gridview->cellHeight());
+ else
+ QTRY_COMPARE(footer->y(), initialFooterPos.y() + gridview->cellHeight());
} else {
// shrink by one column
model.removeItem(2);
@@ -2895,10 +3128,12 @@ void tst_QQuickGridView::footer()
QPointF posWhenNoItems(0, 0);
if (layoutDirection == Qt::RightToLeft)
- posWhenNoItems.setX(flow == QQuickGridView::LeftToRight ? gridview->width() - footer->width() : -footer->width());
+ posWhenNoItems.setX(flow == QQuickGridView::FlowLeftToRight ? gridview->width() - footer->width() : -footer->width());
+ if (verticalLayoutDirection == QQuickItemView::BottomToTop)
+ posWhenNoItems.setY(-footer->height());
QTRY_COMPARE(footer->pos(), posWhenNoItems);
- // if header is present, it's at a negative pos, so the footer should not move
+ // if header is toggled, it shouldn't affect the footer position
canvas->rootObject()->setProperty("showHeader", true);
QVERIFY(findItem<QQuickItem>(contentItem, "header") != 0);
QTRY_COMPARE(footer->pos(), posWhenNoItems);
@@ -2917,13 +3152,14 @@ void tst_QQuickGridView::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);
+
+ // changing the footer shouldn't change the content pos
+ QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos);
item = findItem<QQuickItem>(contentItem, "wrapper", 0);
QVERIFY(item);
@@ -2941,10 +3177,10 @@ void tst_QQuickGridView::footer_data()
{
QTest::addColumn<QQuickGridView::Flow>("flow");
QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<QQuickItemView::VerticalLayoutDirection>("verticalLayoutDirection");
QTest::addColumn<QPointF>("initialFooterPos");
QTest::addColumn<QPointF>("changedFooterPos");
QTest::addColumn<QPointF>("initialContentPos");
- QTest::addColumn<QPointF>("changedContentPos");
QTest::addColumn<QPointF>("firstDelegatePos");
QTest::addColumn<QPointF>("resizeContentPos");
@@ -2955,46 +3191,84 @@ void tst_QQuickGridView::footer_data()
// view height = 320
// footer below items, bottom left
- QTest::newRow("flow left to right") << QQuickGridView::LeftToRight << Qt::LeftToRight
+ QTest::newRow("LeftToRight, LtR, TtB")
+ << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::TopToBottom
<< 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);
+ << 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
+ QTest::newRow("LeftToRight, RtL, TtB")
+ << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::TopToBottom
<< 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(0, (10 * 60) - 320 + 10);
+
+ // footer above items, top left
+ QTest::newRow("LeftToRight, LtR, BtT")
+ << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::BottomToTop
+ << QPointF(0, -(3 * 60) - 30)
+ << QPointF(0, -(10 * 60) - 20)
+ << QPointF(0, -320)
+ << QPointF(0, -60)
+ << QPointF(0, -(10 * 60) - 10);
+
+ // footer above items, top right
+ QTest::newRow("LeftToRight, RtL, BtT")
+ << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::BottomToTop
+ << QPointF(240 - 100, -(3 * 60) - 30)
+ << QPointF((240 - 100) + 50, -(10 * 60) - 20)
+ << QPointF(0, -320)
+ << QPointF(240 - 80, -60)
+ << QPointF(0, -(10 * 60) - 10);
+
+
+ // footer to right of items, bottom right
+ QTest::newRow("TopToBottom, LtR, TtB")
+ << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::TopToBottom
<< 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);
+ << 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
+ // footer to left of items, bottom right
+ QTest::newRow("TopToBottom, RtL, TtB")
+ << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::TopToBottom
<< 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);
+
+ // footer to right of items, top right
+ QTest::newRow("TopToBottom, LtR, BtT")
+ << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::BottomToTop
+ << QPointF(2 * 80, -30)
+ << QPointF(6 * 80, -20)
+ << QPointF(0, -320)
+ << QPointF(0, -60)
+ << QPointF((6 * 80) - 240 + 40, -320);
+
+ // footer to left of items, top left
+ QTest::newRow("TopToBottom, RtL, BtT")
+ << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::BottomToTop
+ << QPointF(-(2 * 80) - 100, -30)
+ << QPointF(-(6 * 80) - 50, -20)
+ << QPointF(-240, -320)
+ << QPointF(-80, -60)
+ << QPointF(-(6 * 80) - 40, -320);
}
void tst_QQuickGridView::header()
{
QFETCH(QQuickGridView::Flow, flow);
QFETCH(Qt::LayoutDirection, layoutDirection);
+ QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection);
QFETCH(QPointF, initialHeaderPos);
QFETCH(QPointF, changedHeaderPos);
QFETCH(QPointF, initialContentPos);
@@ -3018,6 +3292,7 @@ void tst_QQuickGridView::header()
QTRY_VERIFY(gridview != 0);
gridview->setFlow(flow);
gridview->setLayoutDirection(layoutDirection);
+ gridview->setVerticalLayoutDirection(verticalLayoutDirection);
QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
QQuickItem *contentItem = gridview->contentItem();
@@ -3025,7 +3300,6 @@ void tst_QQuickGridView::header()
QQuickText *header = findItem<QQuickText>(contentItem, "header");
QVERIFY(header);
-
QVERIFY(header == gridview->headerItem());
QCOMPARE(header->pos(), initialHeaderPos);
@@ -3033,7 +3307,7 @@ void tst_QQuickGridView::header()
QCOMPARE(header->height(), 30.);
QCOMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos);
- if (flow == QQuickGridView::LeftToRight)
+ if (flow == QQuickGridView::FlowLeftToRight)
QCOMPARE(gridview->contentHeight(), (model.count()+2) / 3 * 60. + header->height());
else
QCOMPARE(gridview->contentWidth(), (model.count()+3) / 5 * 80. + header->width());
@@ -3091,6 +3365,7 @@ void tst_QQuickGridView::header()
QTRY_VERIFY(gridview != 0);
gridview->setFlow(flow);
gridview->setLayoutDirection(layoutDirection);
+ gridview->setVerticalLayoutDirection(verticalLayoutDirection);
QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
gridview->setWidth(240);
@@ -3105,6 +3380,7 @@ void tst_QQuickGridView::header_data()
{
QTest::addColumn<QQuickGridView::Flow>("flow");
QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<QQuickItemView::VerticalLayoutDirection>("verticalLayoutDirection");
QTest::addColumn<QPointF>("initialHeaderPos");
QTest::addColumn<QPointF>("changedHeaderPos");
QTest::addColumn<QPointF>("initialContentPos");
@@ -3118,7 +3394,8 @@ void tst_QQuickGridView::header_data()
// view width = 240
// header above items, top left
- QTest::newRow("flow left to right") << QQuickGridView::LeftToRight << Qt::LeftToRight
+ QTest::newRow("LeftToRight, LtR, TtB")
+ << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::TopToBottom
<< QPointF(0, -30)
<< QPointF(0, -20)
<< QPointF(0, -30)
@@ -3127,7 +3404,8 @@ void tst_QQuickGridView::header_data()
<< QPointF(0, -10);
// header above items, top right
- QTest::newRow("flow left to right, layout right to left") << QQuickGridView::LeftToRight << Qt::RightToLeft
+ QTest::newRow("LeftToRight, RtL, TtB")
+ << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::TopToBottom
<< QPointF(240 - 100, -30)
<< QPointF((240 - 100) + 50, -20) // 50 = width diff between old and new headers
<< QPointF(0, -30)
@@ -3135,8 +3413,30 @@ void tst_QQuickGridView::header_data()
<< 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
+ // header below items, bottom left
+ QTest::newRow("LeftToRight, LtR, BtT")
+ << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::BottomToTop
+ << QPointF(0, 0)
+ << QPointF(0, 0)
+ << QPointF(0, -320 + 30)
+ << QPointF(0, -320 + 20)
+ << QPointF(0, -60)
+ << QPointF(0, -320 + 10);
+
+ // header above items, top right
+ QTest::newRow("LeftToRight, RtL, BtT")
+ << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::BottomToTop
+ << QPointF(240 - 100, 0)
+ << QPointF((240 - 100) + 50, 0)
+ << QPointF(0, -320 + 30)
+ << QPointF(0, -320 + 20)
+ << QPointF(160, -60)
+ << QPointF(0, -320 + 10);
+
+
+ // header to left of items, bottom left
+ QTest::newRow("TopToBottom, LtR, TtB")
+ << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::TopToBottom
<< QPointF(-100, 0)
<< QPointF(-50, 0)
<< QPointF(-100, 0)
@@ -3144,14 +3444,35 @@ void tst_QQuickGridView::header_data()
<< 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
+ // header to right of items, bottom right
+ QTest::newRow("TopToBottom, RtL, TtB")
+ << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::TopToBottom
<< QPointF(0, 0)
<< QPointF(0, 0)
<< QPointF(-(240 - 100), 0)
<< QPointF(-(240 - 50), 0)
<< QPointF(-80, 0)
<< QPointF(-(240 - 40), 0);
+
+ // header to left of items, top left
+ QTest::newRow("TopToBottom, LtR, BtT")
+ << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::BottomToTop
+ << QPointF(-100, -30)
+ << QPointF(-50, -20)
+ << QPointF(-100, -320)
+ << QPointF(-50, -320)
+ << QPointF(0, -60)
+ << QPointF(-40, -320);
+
+ // header to right of items, top right
+ QTest::newRow("TopToBottom, RtL, BtT")
+ << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::BottomToTop
+ << QPointF(0, -30)
+ << QPointF(0, -20)
+ << QPointF(-(240 - 100), -320)
+ << QPointF(-(240 - 50), -320)
+ << QPointF(-80, -60)
+ << QPointF(-(240 - 40), -320);
}
class GVAccessor : public QQuickGridView
@@ -3165,138 +3486,144 @@ public:
void tst_QQuickGridView::headerFooter()
{
- {
- // Vertical
- QQuickView *canvas = createView();
-
- QmlListModel model;
- QQmlContext *ctxt = canvas->rootContext();
- ctxt->setContextProperty("testModel", &model);
-
- canvas->setSource(testFileUrl("headerfooter.qml"));
- qApp->processEvents();
-
- QQuickGridView *gridview = qobject_cast<QQuickGridView*>(canvas->rootObject());
- QTRY_VERIFY(gridview != 0);
-
- QQuickItem *contentItem = gridview->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<GVAccessor*>(gridview)->minY(), header->height());
- QCOMPARE(static_cast<GVAccessor*>(gridview)->maxY(), header->height());
-
- delete canvas;
- }
- {
- // Horizontal
- QQuickView *canvas = createView();
-
- QmlListModel model;
- QQmlContext *ctxt = canvas->rootContext();
- ctxt->setContextProperty("testModel", &model);
-
- canvas->setSource(testFileUrl("headerfooter.qml"));
- canvas->rootObject()->setProperty("horizontal", true);
- qApp->processEvents();
-
- QQuickGridView *gridview = qobject_cast<QQuickGridView*>(canvas->rootObject());
- QTRY_VERIFY(gridview != 0);
-
- QQuickItem *contentItem = gridview->contentItem();
- QTRY_VERIFY(contentItem != 0);
-
- QQuickItem *header = findItem<QQuickItem>(contentItem, "header");
- QVERIFY(header);
- QCOMPARE(header->x(), -header->width());
+ QFETCH(QQuickGridView::Flow, flow);
+ QFETCH(Qt::LayoutDirection, layoutDirection);
+ QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection);
+ QFETCH(QPointF, headerPos);
+ QFETCH(QPointF, footerPos);
+ QFETCH(QPointF, minPos);
+ QFETCH(QPointF, maxPos);
- QQuickItem *footer = findItem<QQuickItem>(contentItem, "footer");
- QVERIFY(footer);
- QCOMPARE(footer->x(), 0.);
+ QQuickView *canvas = getView();
- QCOMPARE(static_cast<GVAccessor*>(gridview)->minX(), header->width());
- QCOMPARE(static_cast<GVAccessor*>(gridview)->maxX(), header->width());
+ QmlListModel model;
+ QQmlContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+ canvas->setSource(testFileUrl("headerfooter.qml"));
+ canvas->show();
+ qApp->processEvents();
- delete canvas;
- }
- {
- // Horizontal RTL
- QQuickView *canvas = createView();
+ QQuickGridView *gridview = qobject_cast<QQuickGridView*>(canvas->rootObject());
+ QTRY_VERIFY(gridview != 0);
+ gridview->setFlow(flow);
+ gridview->setLayoutDirection(layoutDirection);
+ gridview->setVerticalLayoutDirection(verticalLayoutDirection);
+ QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
- QmlListModel model;
- QQmlContext *ctxt = canvas->rootContext();
- ctxt->setContextProperty("testModel", &model);
+ QQuickItem *contentItem = gridview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
- canvas->setSource(testFileUrl("headerfooter.qml"));
- canvas->rootObject()->setProperty("horizontal", true);
- canvas->rootObject()->setProperty("rtl", true);
- qApp->processEvents();
+ QQuickItem *header = findItem<QQuickItem>(contentItem, "header");
+ QVERIFY(header);
+ QCOMPARE(header->pos(), headerPos);
- QQuickGridView *gridview = qobject_cast<QQuickGridView*>(canvas->rootObject());
- QTRY_VERIFY(gridview != 0);
+ QQuickItem *footer = findItem<QQuickItem>(contentItem, "footer");
+ QVERIFY(footer);
+ QCOMPARE(footer->pos(), footerPos);
- QQuickItem *contentItem = gridview->contentItem();
- QTRY_VERIFY(contentItem != 0);
+ QCOMPARE(static_cast<GVAccessor*>(gridview)->minX(), minPos.x());
+ QCOMPARE(static_cast<GVAccessor*>(gridview)->minY(), minPos.y());
+ QCOMPARE(static_cast<GVAccessor*>(gridview)->maxX(), maxPos.x());
+ QCOMPARE(static_cast<GVAccessor*>(gridview)->maxY(), maxPos.y());
- QQuickItem *header = findItem<QQuickItem>(contentItem, "header");
- QVERIFY(header);
- QCOMPARE(header->x(), 0.);
+ releaseView(canvas);
+}
- QQuickItem *footer = findItem<QQuickItem>(contentItem, "footer");
- QVERIFY(footer);
- QCOMPARE(footer->x(), -footer->width());
+void tst_QQuickGridView::headerFooter_data()
+{
+ QTest::addColumn<QQuickGridView::Flow>("flow");
+ QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<QQuickItemView::VerticalLayoutDirection>("verticalLayoutDirection");
+ QTest::addColumn<QPointF>("headerPos");
+ QTest::addColumn<QPointF>("footerPos");
+ QTest::addColumn<QPointF>("minPos");
+ QTest::addColumn<QPointF>("maxPos");
+
+ // header is 240x20 (or 20x320 in TopToBottom)
+ // footer is 240x30 (or 30x320 in TopToBottom)
+
+ QTest::newRow("LeftToRight, LtR, TtB")
+ << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::TopToBottom
+ << QPointF(0, -20) << QPointF(0, 0)
+ << QPointF(0, 20) << QPointF(240, 20);
+
+ QTest::newRow("LeftToRight, RtL, TtB")
+ << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::TopToBottom
+ << QPointF(0, -20) << QPointF(0, 0)
+ << QPointF(0, 20) << QPointF(240, 20);
+
+ QTest::newRow("LeftToRight, LtR, BtT")
+ << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::BottomToTop
+ << QPointF(0, 0) << QPointF(0, -30)
+ << QPointF(0, 320 - 20) << QPointF(240, 320 - 20); // content flow is reversed
+
+ QTest::newRow("LeftToRight, RtL, BtT")
+ << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::BottomToTop
+ << QPointF(0, 0) << QPointF(0, -30)
+ << QPointF(0, 320 - 20) << QPointF(240, 320 - 20); // content flow is reversed
+
+
+ QTest::newRow("TopToBottom, LtR, TtB")
+ << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::TopToBottom
+ << QPointF(-20, 0) << QPointF(0, 0)
+ << QPointF(20, 0) << QPointF(20, 320);
+
+ QTest::newRow("TopToBottom, RtL, TtB")
+ << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::TopToBottom
+ << QPointF(0, 0) << QPointF(-30, 0)
+ << QPointF(240 - 20, 0) << QPointF(240 - 20, 320); // content flow is reversed
+
+ QTest::newRow("TopToBottom, LtR, BtT")
+ << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::BottomToTop
+ << QPointF(-20, -320) << QPointF(0, -320)
+ << QPointF(20, 0) << QPointF(20, 320);
+
+ QTest::newRow("TopToBottom, RtL, BtT")
+ << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::BottomToTop
+ << QPointF(0, -320) << QPointF(-30, -320)
+ << QPointF(240 - 20, 0) << QPointF(240 - 20, 320); // content flow is reversed
+}
- QCOMPARE(static_cast<GVAccessor*>(gridview)->minX(), 240. - header->width());
- QCOMPARE(static_cast<GVAccessor*>(gridview)->maxX(), 240. - header->width());
+void tst_QQuickGridView::resetModel_headerFooter()
+{
+ // Resetting a model shouldn't crash in views with header/footer
- delete canvas;
- }
- {
- // Reset model
- QQuickView *canvas = createView();
+ QQuickView *canvas = createView();
- QaimModel model;
- for (int i = 0; i < 6; i++)
- model.addItem("Item" + QString::number(i), "");
- QQmlContext *ctxt = canvas->rootContext();
- ctxt->setContextProperty("testModel", &model);
+ QaimModel model;
+ for (int i = 0; i < 6; i++)
+ model.addItem("Item" + QString::number(i), "");
+ QQmlContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
- canvas->setSource(testFileUrl("headerfooter.qml"));
- qApp->processEvents();
+ canvas->setSource(testFileUrl("headerfooter.qml"));
+ qApp->processEvents();
- QQuickGridView *gridview = qobject_cast<QQuickGridView*>(canvas->rootObject());
- QTRY_VERIFY(gridview != 0);
+ QQuickGridView *gridview = qobject_cast<QQuickGridView*>(canvas->rootObject());
+ QTRY_VERIFY(gridview != 0);
- QQuickItem *contentItem = gridview->contentItem();
- QTRY_VERIFY(contentItem != 0);
+ QQuickItem *contentItem = gridview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
- QQuickItem *header = findItem<QQuickItem>(contentItem, "header");
- QVERIFY(header);
- QCOMPARE(header->y(), -header->height());
+ QQuickItem *header = findItem<QQuickItem>(contentItem, "header");
+ QVERIFY(header);
+ QCOMPARE(header->y(), -header->height());
- QQuickItem *footer = findItem<QQuickItem>(contentItem, "footer");
- QVERIFY(footer);
- QCOMPARE(footer->y(), 80.*2);
+ QQuickItem *footer = findItem<QQuickItem>(contentItem, "footer");
+ QVERIFY(footer);
+ QCOMPARE(footer->y(), 80.*2);
- model.reset();
+ model.reset();
- header = findItem<QQuickItem>(contentItem, "header");
- QVERIFY(header);
- QCOMPARE(header->y(), -header->height());
+ header = findItem<QQuickItem>(contentItem, "header");
+ QVERIFY(header);
+ QCOMPARE(header->y(), -header->height());
- footer = findItem<QQuickItem>(contentItem, "footer");
- QVERIFY(footer);
- QCOMPARE(footer->y(), 80.*2);
+ footer = findItem<QQuickItem>(contentItem, "footer");
+ QVERIFY(footer);
+ QCOMPARE(footer->y(), 80.*2);
- delete canvas;
- }
+ delete canvas;
}
void tst_QQuickGridView::resizeViewAndRepaint()
@@ -3370,6 +3697,147 @@ void tst_QQuickGridView::resizeViewAndRepaint()
delete canvas;
}
+void tst_QQuickGridView::resizeGrid()
+{
+ QFETCH(QQuickGridView::Flow, flow);
+ QFETCH(Qt::LayoutDirection, layoutDirection);
+ QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection);
+ QFETCH(QPointF, initialContentPos);
+ QFETCH(QPointF, firstItemPos);
+
+ QaimModel model;
+ for (int i = 0; i < 30; i++)
+ model.addItem("Item" + QString::number(i), "");
+
+ QQuickView *canvas = getView();
+ QQmlContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+ ctxt->setContextProperty("testTopToBottom", flow == QQuickGridView::FlowTopToBottom);
+ ctxt->setContextProperty("testRightToLeft", layoutDirection == Qt::RightToLeft);
+ ctxt->setContextProperty("testBottomToTop", verticalLayoutDirection == QQuickGridView::BottomToTop);
+ canvas->setSource(testFileUrl("resizegrid.qml"));
+ canvas->show();
+ qApp->processEvents();
+
+ QQuickGridView *gridview = findItem<QQuickGridView>(canvas->rootObject(), "grid");
+ QTRY_VERIFY(gridview != 0);
+ QQuickItem *contentItem = gridview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ // set the width to slightly larger than 3 items across, to test
+ // items are aligned correctly in right-to-left
+ canvas->rootObject()->setWidth(260);
+ canvas->rootObject()->setHeight(320);
+ QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
+
+ QCOMPARE(gridview->contentX(), initialContentPos.x());
+ QCOMPARE(gridview->contentY(), initialContentPos.y());
+
+ QQuickItem *item0 = findItem<QQuickItem>(contentItem, "wrapper", 0);
+ QVERIFY(item0);
+ QCOMPARE(item0->pos(), firstItemPos);
+
+ // Confirm items positioned correctly and indexes correct
+ QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper");
+ QVERIFY(items.count() >= 18 && items.count() <= 21);
+ for (int i = 0; i < model.count() && i < items.count(); ++i) {
+ QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+ QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+ QCOMPARE(item->pos(), expectedItemPos(gridview, i, 0));
+ QQuickText *name = findItem<QQuickText>(contentItem, "textName", i);
+ QVERIFY(name != 0);
+ QCOMPARE(name->text(), model.name(i));
+ }
+
+ // change from 3x5 grid to 4x7
+ canvas->rootObject()->setWidth(canvas->rootObject()->width() + 80);
+ canvas->rootObject()->setHeight(canvas->rootObject()->height() + 60*2);
+ QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
+
+ // other than in LeftToRight+RightToLeft layout, the first item should not move
+ // if view is resized
+ QCOMPARE(findItem<QQuickItem>(contentItem, "wrapper", 0), item0);
+ if (flow == QQuickGridView::FlowLeftToRight && layoutDirection == Qt::RightToLeft)
+ firstItemPos.rx() += 80;
+ QCOMPARE(item0->pos(), firstItemPos);
+
+ QPointF newContentPos = initialContentPos;
+ if (flow == QQuickGridView::FlowTopToBottom && layoutDirection == Qt::RightToLeft)
+ newContentPos.rx() -= 80.0;
+ if (verticalLayoutDirection == QQuickItemView::BottomToTop)
+ newContentPos.ry() -= 60.0 * 2;
+ QCOMPARE(gridview->contentX(), newContentPos.x());
+ QCOMPARE(gridview->contentY(), newContentPos.y());
+
+ // Confirm items positioned correctly and indexes correct
+ items = findItems<QQuickItem>(contentItem, "wrapper");
+ QVERIFY(items.count() >= 28);
+ for (int i = 0; i < model.count() && i < items.count(); ++i) {
+ QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+ QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+ QCOMPARE(item->pos(), expectedItemPos(gridview, i, 0));
+ QQuickText *name = findItem<QQuickText>(contentItem, "textName", i);
+ QVERIFY(name != 0);
+ QCOMPARE(name->text(), model.name(i));
+ }
+
+ releaseView(canvas);
+}
+
+void tst_QQuickGridView::resizeGrid_data()
+{
+ QTest::addColumn<QQuickGridView::Flow>("flow");
+ QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<QQuickItemView::VerticalLayoutDirection>("verticalLayoutDirection");
+ QTest::addColumn<QPointF>("initialContentPos");
+ QTest::addColumn<QPointF>("firstItemPos");
+
+ // Initial view width is 260, so in LeftToRight + right-to-left mode the
+ // content x should be -20
+
+ QTest::newRow("LeftToRight, LtR, TtB")
+ << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::TopToBottom
+ << QPointF(0, 0)
+ << QPointF(0, 0);
+
+ QTest::newRow("LeftToRight, RtL, TtB")
+ << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::TopToBottom
+ << QPointF(-20.0, 0)
+ << QPointF(80.0 * 2, 0);
+
+ QTest::newRow("LeftToRight, LtR, BtT")
+ << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::BottomToTop
+ << QPointF(0, -320)
+ << QPointF(0, -60.0);
+
+ QTest::newRow("LeftToRight, RtL, BtT")
+ << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::BottomToTop
+ << QPointF(-20.0, -320)
+ << QPointF(80.0 * 2, -60.0);
+
+
+ QTest::newRow("TopToBottom, LtR, TtB")
+ << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::TopToBottom
+ << QPointF(0, 0)
+ << QPointF(0, 0);
+
+ QTest::newRow("TopToBottom, RtL, TtB")
+ << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::TopToBottom
+ << QPointF(-260, 0)
+ << QPointF(-80.0, 0);
+
+ QTest::newRow("TopToBottom, LtR, BtT")
+ << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::BottomToTop
+ << QPointF(0, -320)
+ << QPointF(0, -60.0);
+
+ QTest::newRow("TopToBottom, RtL, BtT")
+ << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::BottomToTop
+ << QPointF(-260, -320)
+ << QPointF(-80.0, -60.0);
+}
+
+
void tst_QQuickGridView::changeColumnCount()
{
QmlListModel model;
@@ -3458,11 +3926,7 @@ void tst_QQuickGridView::indexAt_itemAt()
model.addItem("Ben", "04321");
model.addItem("Jim", "0780");
- QQmlContext *ctxt = canvas->rootContext();
- ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("testRightToLeft", QVariant(false));
- ctxt->setContextProperty("testTopToBottom", QVariant(false));
-
+ canvas->rootContext()->setContextProperty("testModel", &model);
canvas->setSource(testFileUrl("gridview1.qml"));
qApp->processEvents();
@@ -3776,22 +4240,22 @@ void tst_QQuickGridView::snapToRow_data()
QTest::addColumn<qreal>("endExtent");
QTest::addColumn<qreal>("startExtent");
- QTest::newRow("vertical, left to right") << QQuickGridView::LeftToRight << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
+ QTest::newRow("vertical, left to right") << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
<< QPoint(20, 200) << QPoint(20, 20) << 60.0 << 800.0 << 0.0;
- QTest::newRow("horizontal, left to right") << QQuickGridView::TopToBottom << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
+ QTest::newRow("horizontal, left to right") << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
<< QPoint(200, 20) << QPoint(20, 20) << 60.0 << 800.0 << 0.0;
- QTest::newRow("horizontal, right to left") << QQuickGridView::TopToBottom << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange)
+ QTest::newRow("horizontal, right to left") << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange)
<< QPoint(20, 20) << QPoint(200, 20) << -60.0 << -800.0 - 240.0 << -240.0;
- QTest::newRow("vertical, left to right, enforce range") << QQuickGridView::LeftToRight << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
+ QTest::newRow("vertical, left to right, enforce range") << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
<< QPoint(20, 200) << QPoint(20, 20) << 60.0 << 940.0 << -20.0;
- QTest::newRow("horizontal, left to right, enforce range") << QQuickGridView::TopToBottom << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
+ QTest::newRow("horizontal, left to right, enforce range") << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
<< QPoint(200, 20) << QPoint(20, 20) << 60.0 << 940.0 << -20.0;
- QTest::newRow("horizontal, right to left, enforce range") << QQuickGridView::TopToBottom << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange)
+ QTest::newRow("horizontal, right to left, enforce range") << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange)
<< QPoint(20, 20) << QPoint(200, 20) << -60.0 << -800.0 - 240.0 - 140.0 << -220.0;
}
@@ -3826,7 +4290,7 @@ void tst_QQuickGridView::snapToRow()
// 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)
+ if (flow == QQuickGridView::FlowLeftToRight)
QCOMPARE(qreal(fmod(gridview->contentY(),80.0)), snapAlignment);
else
QCOMPARE(qreal(fmod(gridview->contentX(),80.0)), snapAlignment);
@@ -3835,11 +4299,11 @@ void tst_QQuickGridView::snapToRow()
do {
flick(canvas, flickStart, flickEnd, 180);
QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops
- } while (flow == QQuickGridView::LeftToRight
+ } while (flow == QQuickGridView::FlowLeftToRight
? !gridview->isAtYEnd()
: layoutDirection == Qt::LeftToRight ? !gridview->isAtXEnd() : !gridview->isAtXBeginning());
- if (flow == QQuickGridView::LeftToRight)
+ if (flow == QQuickGridView::FlowLeftToRight)
QCOMPARE(gridview->contentY(), endExtent);
else
QCOMPARE(gridview->contentX(), endExtent);
@@ -3848,11 +4312,11 @@ void tst_QQuickGridView::snapToRow()
do {
flick(canvas, flickEnd, flickStart, 180);
QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops
- } while (flow == QQuickGridView::LeftToRight
+ } while (flow == QQuickGridView::FlowLeftToRight
? !gridview->isAtYBeginning()
: layoutDirection == Qt::LeftToRight ? !gridview->isAtXBeginning() : !gridview->isAtXEnd());
- if (flow == QQuickGridView::LeftToRight)
+ if (flow == QQuickGridView::FlowLeftToRight)
QCOMPARE(gridview->contentY(), startExtent);
else
QCOMPARE(gridview->contentX(), startExtent);
@@ -3871,22 +4335,22 @@ void tst_QQuickGridView::snapOneRow_data()
QTest::addColumn<qreal>("endExtent");
QTest::addColumn<qreal>("startExtent");
- QTest::newRow("vertical, left to right") << QQuickGridView::LeftToRight << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
+ QTest::newRow("vertical, left to right") << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
<< QPoint(20, 200) << QPoint(20, 20) << 100.0 << 240.0 << 0.0;
- QTest::newRow("horizontal, left to right") << QQuickGridView::TopToBottom << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
+ QTest::newRow("horizontal, left to right") << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
<< QPoint(200, 20) << QPoint(20, 20) << 100.0 << 240.0 << 0.0;
- QTest::newRow("horizontal, right to left") << QQuickGridView::TopToBottom << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange)
+ QTest::newRow("horizontal, right to left") << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange)
<< QPoint(20, 20) << QPoint(200, 20) << -340.0 << -240.0 - 240.0 << -240.0;
- QTest::newRow("vertical, left to right, enforce range") << QQuickGridView::LeftToRight << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
+ QTest::newRow("vertical, left to right, enforce range") << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
<< QPoint(20, 200) << QPoint(20, 20) << 100.0 << 340.0 << -20.0;
- QTest::newRow("horizontal, left to right, enforce range") << QQuickGridView::TopToBottom << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
+ QTest::newRow("horizontal, left to right, enforce range") << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
<< QPoint(200, 20) << QPoint(20, 20) << 100.0 << 340.0 << -20.0;
- QTest::newRow("horizontal, right to left, enforce range") << QQuickGridView::TopToBottom << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange)
+ QTest::newRow("horizontal, right to left, enforce range") << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange)
<< QPoint(20, 20) << QPoint(200, 20) << -340.0 << -240.0 - 240.0 - 100.0 << -220.0;
}
@@ -3923,7 +4387,7 @@ void tst_QQuickGridView::snapOneRow()
// confirm that a flick hits next row boundary
flick(canvas, flickStart, flickEnd, 180);
QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops
- if (flow == QQuickGridView::LeftToRight)
+ if (flow == QQuickGridView::FlowLeftToRight)
QCOMPARE(gridview->contentY(), snapAlignment);
else
QCOMPARE(gridview->contentX(), snapAlignment);
@@ -3937,7 +4401,7 @@ void tst_QQuickGridView::snapOneRow()
do {
flick(canvas, flickStart, flickEnd, 180);
QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops
- } while (flow == QQuickGridView::LeftToRight
+ } while (flow == QQuickGridView::FlowLeftToRight
? !gridview->isAtYEnd()
: layoutDirection == Qt::LeftToRight ? !gridview->isAtXEnd() : !gridview->isAtXBeginning());
@@ -3946,7 +4410,7 @@ void tst_QQuickGridView::snapOneRow()
QCOMPARE(currentIndexSpy.count(), 3);
}
- if (flow == QQuickGridView::LeftToRight)
+ if (flow == QQuickGridView::FlowLeftToRight)
QCOMPARE(gridview->contentY(), endExtent);
else
QCOMPARE(gridview->contentX(), endExtent);
@@ -3955,11 +4419,11 @@ void tst_QQuickGridView::snapOneRow()
do {
flick(canvas, flickEnd, flickStart, 180);
QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops
- } while (flow == QQuickGridView::LeftToRight
+ } while (flow == QQuickGridView::FlowLeftToRight
? !gridview->isAtYBeginning()
: layoutDirection == Qt::LeftToRight ? !gridview->isAtXBeginning() : !gridview->isAtXEnd());
- if (flow == QQuickGridView::LeftToRight)
+ if (flow == QQuickGridView::FlowLeftToRight)
QCOMPARE(gridview->contentY(), startExtent);
else
QCOMPARE(gridview->contentX(), startExtent);
@@ -4171,7 +4635,7 @@ void tst_QQuickGridView::addTransitions()
{
QFETCH(int, initialItemCount);
QFETCH(bool, shouldAnimateTargets);
- QFETCH(qreal, contentY);
+ QFETCH(qreal, contentYRowOffset);
QFETCH(int, insertionIndex);
QFETCH(int, insertionCount);
QFETCH(ListRange, expectedDisplacedIndexes);
@@ -4204,8 +4668,8 @@ void tst_QQuickGridView::addTransitions()
QVERIFY(contentItem != 0);
QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
- if (contentY != 0) {
- gridview->setContentY(contentY);
+ if (contentYRowOffset != 0) {
+ gridview->setContentY(contentYRowOffset * 60.0);
QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
}
@@ -4220,7 +4684,7 @@ void tst_QQuickGridView::addTransitions()
newData << qMakePair(QString("New item %1").arg(i), QString(""));
// last visible item is the first item of the row beneath the view
- if (i >= (contentY / 60)*3 && i < qCeil((contentY + gridview->height()) / 60.0)*3) {
+ if (i >= (gridview->contentY() / 60)*3 && i < qCeil((gridview->contentY() + gridview->height()) / 60.0)*3) {
expectedTargetData << newData.last();
targetIndexes << i;
}
@@ -4264,7 +4728,7 @@ void tst_QQuickGridView::addTransitions()
QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper");
int firstVisibleIndex = -1;
for (int i=0; i<items.count(); i++) {
- if (items[i]->y() >= contentY) {
+ if (items[i]->y() >= gridview->contentY()) {
QQmlExpression e(qmlContext(items[i]), items[i], "index");
firstVisibleIndex = e.evaluate().toInt();
break;
@@ -4273,8 +4737,7 @@ void tst_QQuickGridView::addTransitions()
QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex));
// verify all items moved to the correct final positions
- int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
- for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) {
+ for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++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);
@@ -4290,7 +4753,7 @@ void tst_QQuickGridView::addTransitions()
void tst_QQuickGridView::addTransitions_data()
{
QTest::addColumn<int>("initialItemCount");
- QTest::addColumn<qreal>("contentY");
+ QTest::addColumn<qreal>("contentYRowOffset");
QTest::addColumn<bool>("shouldAnimateTargets");
QTest::addColumn<int>("insertionIndex");
QTest::addColumn<int>("insertionCount");
@@ -4298,19 +4761,19 @@ void tst_QQuickGridView::addTransitions_data()
// if inserting a full row before visible index, items don't appear or animate in, even if there are > 1 new items
QTest::newRow("insert 1, just before start")
- << 30 << 20.0 << false
+ << 30 << 1.0 << false
<< 0 << 1 << ListRange();
QTest::newRow("insert 1, way before start")
- << 30 << 20.0 << false
+ << 30 << 1.0 << false
<< 0 << 1 << ListRange();
QTest::newRow("insert multiple, just before start")
- << 30 << 100.0 << false
+ << 30 << 1.0 << false
<< 0 << 3 << ListRange();
QTest::newRow("insert multiple (< 1 row), just before start")
- << 30 << 100.0 << false
+ << 30 << 1.0 << false
<< 0 << 2 << ListRange();
QTest::newRow("insert multiple, way before start")
- << 30 << 100.0 << false
+ << 30 << 3.0 << false
<< 0 << 3 << ListRange();
QTest::newRow("insert 1 at start")
@@ -4323,13 +4786,13 @@ void tst_QQuickGridView::addTransitions_data()
<< 30 << 0.0 << true
<< 0 << 5 << ListRange(0, 17);
QTest::newRow("insert 1 at start, content y not 0")
- << 30 << 60.0 << true // first visible is index 3
+ << 30 << 1.0 << true // first visible is index 3
<< 3 << 1 << ListRange(0 + 3, 17 + 3);
QTest::newRow("insert multiple at start, content y not 0")
- << 30 << 60.0 << true // first visible is index 3
+ << 30 << 1.0 << true // first visible is index 3
<< 3 << 3 << ListRange(0 + 3, 17 + 3);
QTest::newRow("insert multiple (> 1 row) at start, content y not 0")
- << 30 << 60.0 << true // first visible is index 3
+ << 30 << 1.0 << true // first visible is index 3
<< 3 << 5 << ListRange(0 + 3, 17 + 3);
QTest::newRow("insert 1 at start, to empty grid")
@@ -4356,10 +4819,10 @@ void tst_QQuickGridView::addTransitions_data()
<< 30 << 0.0 << true
<< 17 << 3 << ListRange(17, 17);
QTest::newRow("insert 1 at bottom, content y not 0")
- << 30 << 20.0 * 3 << true
+ << 30 << 1.0 << true
<< 17 + 3 << 1 << ListRange(17 + 3, 17 + 3);
QTest::newRow("insert multiple at bottom, content y not 0")
- << 30 << 20.0 * 3 << true
+ << 30 << 1.0 << true
<< 17 + 3 << 3 << ListRange(17 + 3, 17 + 3);
@@ -4376,8 +4839,8 @@ void tst_QQuickGridView::addTransitions_data()
void tst_QQuickGridView::moveTransitions()
{
QFETCH(int, initialItemCount);
- QFETCH(qreal, contentY);
- QFETCH(qreal, itemsOffsetAfterMove);
+ QFETCH(qreal, contentYRowOffset);
+ QFETCH(qreal, rowOffsetAfterMove);
QFETCH(int, moveFrom);
QFETCH(int, moveTo);
QFETCH(int, moveCount);
@@ -4409,8 +4872,8 @@ void tst_QQuickGridView::moveTransitions()
QVERIFY(contentItem != 0);
QQuickText *name;
- if (contentY != 0) {
- gridview->setContentY(contentY);
+ if (contentYRowOffset != 0) {
+ gridview->setContentY(contentYRowOffset * 60.0);
QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
}
@@ -4422,8 +4885,8 @@ void tst_QQuickGridView::moveTransitions()
QList<int> targetIndexes;
for (int i=moveFrom; i<moveFrom+moveCount; i++) {
int toIndex = moveTo + (i - moveFrom);
- int firstVisibleIndex = (contentY / 60) * 3;
- int lastVisibleIndex = (qCeil((contentY + gridview->height()) / 60.0)*3) - 1;
+ int firstVisibleIndex = (gridview->contentY() / 60) * 3;
+ int lastVisibleIndex = (qCeil((gridview->contentY() + gridview->height()) / 60.0)*3) - 1;
if ((i >= firstVisibleIndex && i <= lastVisibleIndex)
|| (toIndex >= firstVisibleIndex && toIndex <= lastVisibleIndex)) {
expectedTargetData << qMakePair(model.name(i), model.number(i));
@@ -4461,7 +4924,7 @@ void tst_QQuickGridView::moveTransitions()
QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper");
int firstVisibleIndex = -1;
for (int i=0; i<items.count(); i++) {
- if (items[i]->y() >= contentY) {
+ if (items[i]->y() >= gridview->contentY()) {
QQmlExpression e(qmlContext(items[i]), items[i], "index");
firstVisibleIndex = e.evaluate().toInt();
break;
@@ -4470,12 +4933,12 @@ void tst_QQuickGridView::moveTransitions()
QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex));
// verify all items moved to the correct final positions
- int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
- for (int i=firstVisibleIndex; i < model.count() && i < itemCount; ++i) {
+ qreal pixelOffset = 60 * rowOffsetAfterMove;
+ for (int i=firstVisibleIndex; i < model.count() && i < items.count(); ++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);
+ QCOMPARE(item->y(), (i/3)*60.0 + pixelOffset);
name = findItem<QQuickText>(contentItem, "textName", i);
QVERIFY(name != 0);
QTRY_COMPARE(name->text(), model.name(i));
@@ -4487,94 +4950,132 @@ void tst_QQuickGridView::moveTransitions()
void tst_QQuickGridView::moveTransitions_data()
{
QTest::addColumn<int>("initialItemCount");
- QTest::addColumn<qreal>("contentY");
- QTest::addColumn<qreal>("itemsOffsetAfterMove");
+ QTest::addColumn<qreal>("contentYRowOffset");
+ QTest::addColumn<qreal>("rowOffsetAfterMove");
QTest::addColumn<int>("moveFrom");
QTest::addColumn<int>("moveTo");
QTest::addColumn<int>("moveCount");
QTest::addColumn<ListRange>("expectedDisplacedIndexes");
- QTest::newRow("move from above view, outside visible items, move 1") << 30 << 120.0 << 0.0
+ QTest::newRow("move from above view, outside visible items, move 1")
+ << 30 << 2.0 << 0.0
<< 1 << 10 << 1 << ListRange(6, 10);
- QTest::newRow("move from above view, outside visible items, move 1 (first item)") << 30 << 120.0 << 0.0
+ QTest::newRow("move from above view, outside visible items, move 1 (first item)")
+ << 30 << 2.0 << 0.0
<< 0 << 10 << 1 << ListRange(6, 10);
- QTest::newRow("move from above view, outside visible items, move multiple") << 30 << 120.0 << 60.0
+ QTest::newRow("move from above view, outside visible items, move multiple")
+ << 30 << 2.0 << 1.0
<< 1 << 10 << 3 << ListRange(13, 23);
- QTest::newRow("move from above view, mix of visible/non-visible") << 30 << 120.0 << 60.0
+ QTest::newRow("move from above view, mix of visible/non-visible")
+ << 30 << 2.0 << 1.0
<< 1 << 10 << 6 << (ListRange(7, 15) + ListRange(16, 23));
- QTest::newRow("move from above view, mix of visible/non-visible (move first)") << 30 << 120.0 << 120.0
+ QTest::newRow("move from above view, mix of visible/non-visible (move first)")
+ << 30 << 2.0 << 2.0
<< 0 << 10 << 6 << ListRange(16, 23);
- QTest::newRow("move within view, move 1 down") << 30 << 0.0 << 0.0
+ QTest::newRow("move within view, move 1 down")
+ << 30 << 0.0 << 0.0
<< 1 << 10 << 1 << ListRange(2, 10);
- QTest::newRow("move within view, move 1 down, move first item") << 30 << 0.0 << 0.0
+ QTest::newRow("move within view, move 1 down, move first item")
+ << 30 << 0.0 << 0.0
<< 0 << 10 << 1 << ListRange(1, 10);
- QTest::newRow("move within view, move 1 down, move first item, contentY not 0") << 30 << 120.0 << 0.0
+ QTest::newRow("move within view, move 1 down, move first item, contentY not 0")
+ << 30 << 2.0 << 0.0
<< 0+6 << 10+6 << 1 << ListRange(1+6, 10+6);
- QTest::newRow("move within view, move 1 down, to last item") << 30 << 0.0 << 0.0
+ QTest::newRow("move within view, move 1 down, to last item")
+ << 30 << 0.0 << 0.0
<< 10 << 17 << 1 << ListRange(11, 17);
- QTest::newRow("move within view, move first->last") << 30 << 0.0 << 0.0
+ QTest::newRow("move within view, move first->last")
+ << 30 << 0.0 << 0.0
<< 0 << 17 << 1 << ListRange(1, 17);
- QTest::newRow("move within view, move multiple down") << 30 << 0.0 << 0.0
+ QTest::newRow("move within view, move multiple down")
+ << 30 << 0.0 << 0.0
<< 1 << 10 << 3 << ListRange(4, 12);
- QTest::newRow("move within view, move multiple down, move first item") << 30 << 0.0 << 0.0
+ QTest::newRow("move within view, move multiple down, move first item")
+ << 30 << 0.0 << 0.0
<< 0 << 10 << 3 << ListRange(3, 12);
- QTest::newRow("move within view, move multiple down, move first item, contentY not 0") << 30 << 60.0 << 0.0
+ QTest::newRow("move within view, move multiple down, move first item, contentY not 0")
+ << 30 << 1.0 << 0.0
<< 0+3 << 10+3 << 3 << ListRange(3+3, 12+3);
- QTest::newRow("move within view, move multiple down, displace last item") << 30 << 0.0 << 0.0
+ QTest::newRow("move within view, move multiple down, displace last item")
+ << 30 << 0.0 << 0.0
<< 5 << 15 << 3 << ListRange(8, 17);
- QTest::newRow("move within view, move multiple down, move first->last") << 30 << 0.0 << 0.0
+ QTest::newRow("move within view, move multiple down, move first->last")
+ << 30 << 0.0 << 0.0
<< 0 << 15 << 3 << ListRange(3, 17);
- QTest::newRow("move within view, move 1 up") << 30 << 0.0 << 0.0
+ QTest::newRow("move within view, move 1 up")
+ << 30 << 0.0 << 0.0
<< 10 << 1 << 1 << ListRange(1, 9);
- QTest::newRow("move within view, move 1 up, move to first index") << 30 << 0.0 << 0.0
+ QTest::newRow("move within view, move 1 up, move to first index")
+ << 30 << 0.0 << 0.0
<< 10 << 0 << 1 << ListRange(0, 9);
- QTest::newRow("move within view, move 1 up, move to first index, contentY not 0") << 30 << 120.0 << 0.0
+ QTest::newRow("move within view, move 1 up, move to first index, contentY not 0")
+ << 30 << 2.0 << 0.0
<< 10+6 << 0+6 << 1 << ListRange(0+6, 9+6);
- QTest::newRow("move within view, move 1 up, move to first index, contentY not on item border") << 30 << 80.0 << 0.0
+ QTest::newRow("move within view, move 1 up, move to first index, contentY not on item border")
+ << 30 << 1.5 << 0.0
<< 10+3 << 0+3 << 1 << ListRange(0+3, 9+3);
- QTest::newRow("move within view, move 1 up, move last item") << 30 << 0.0 << 0.0
+ QTest::newRow("move within view, move 1 up, move last item")
+ << 30 << 0.0 << 0.0
<< 17 << 10 << 1 << ListRange(10, 16);
- QTest::newRow("move within view, move 1 up, move last->first") << 30 << 0.0 << 0.0
+ QTest::newRow("move within view, move 1 up, move last->first")
+ << 30 << 0.0 << 0.0
<< 17 << 0 << 1 << ListRange(0, 16);
- QTest::newRow("move within view, move multiple up") << 30 << 0.0 << 0.0
+ QTest::newRow("move within view, move multiple up")
+ << 30 << 0.0 << 0.0
<< 10 << 1 << 3 << ListRange(1, 9);
- QTest::newRow("move within view, move multiple (> 1 row) up") << 30 << 0.0 << 0.0
+ QTest::newRow("move within view, move multiple (> 1 row) up")
+ << 30 << 0.0 << 0.0
<< 10 << 1 << 5 << ListRange(1, 9);
- QTest::newRow("move within view, move multiple up, move to first index") << 30 << 0.0 << 0.0
+ QTest::newRow("move within view, move multiple up, move to first index")
+ << 30 << 0.0 << 0.0
<< 10 << 0 << 3 << ListRange(0, 9);
- QTest::newRow("move within view, move multiple up, move to first index, contentY not 0") << 30 << 60.0 << 0.0
+ QTest::newRow("move within view, move multiple up, move to first index, contentY not 0")
+ << 30 << 1.0 << 0.0
<< 10+3 << 0+3 << 3 << ListRange(0+3, 9+3);
- QTest::newRow("move within view, move multiple up (> 1 row), move to first index, contentY not on border") << 30 << 80.0 << 0.0
+ QTest::newRow("move within view, move multiple up (> 1 row), move to first index, contentY not on border")
+ << 30 << 1.5 << 0.0
<< 10+3 << 0+3 << 5 << ListRange(0+3, 9+3);
- QTest::newRow("move within view, move multiple up, move last item") << 30 << 0.0 << 0.0
+ QTest::newRow("move within view, move multiple up, move last item")
+ << 30 << 0.0 << 0.0
<< 15 << 5 << 3 << ListRange(5, 14);
- QTest::newRow("move within view, move multiple up, move last->first") << 30 << 0.0 << 0.0
+ QTest::newRow("move within view, move multiple up, move last->first")
+ << 30 << 0.0 << 0.0
<< 15 << 0 << 3 << ListRange(0, 14);
- QTest::newRow("move from below view, move 1 up") << 30 << 0.0 << 0.0
+ QTest::newRow("move from below view, move 1 up")
+ << 30 << 0.0 << 0.0
<< 20 << 5 << 1 << ListRange(5, 17);
- QTest::newRow("move from below view, move 1 up, move to top") << 30 << 0.0 << 0.0
+ QTest::newRow("move from below view, move 1 up, move to top")
+ << 30 << 0.0 << 0.0
<< 20 << 0 << 1 << ListRange(0, 17);
- QTest::newRow("move from below view, move 1 up, move to top, contentY not 0") << 30 << 60.0 << 0.0
+ QTest::newRow("move from below view, move 1 up, move to top, contentY not 0")
+ << 30 << 1.0 << 0.0
<< 25 << 3 << 1 << ListRange(0+3, 17+3);
- QTest::newRow("move from below view, move multiple (> 1 row) up") << 30 << 0.0 << 0.0
+ QTest::newRow("move from below view, move multiple (> 1 row) up")
+ << 30 << 0.0 << 0.0
<< 20 << 5 << 5 << ListRange(5, 17);
- QTest::newRow("move from below view, move multiple up, move to top") << 30 << 0.0 << 0.0
+ QTest::newRow("move from below view, move multiple up, move to top")
+ << 30 << 0.0 << 0.0
<< 20 << 0 << 3 << ListRange(0, 17);
- QTest::newRow("move from below view, move multiple up, move to top, contentY not 0") << 30 << 60.0 << 0.0
+ QTest::newRow("move from below view, move multiple up, move to top, contentY not 0")
+ << 30 << 1.0 << 0.0
<< 25 << 3 << 3 << ListRange(0+3, 17+3);
- QTest::newRow("move from below view, move 1 up, move to bottom") << 30 << 0.0 << 0.0
+ QTest::newRow("move from below view, move 1 up, move to bottom")
+ << 30 << 0.0 << 0.0
<< 20 << 17 << 1 << ListRange(17, 17);
- QTest::newRow("move from below view, move 1 up, move to bottom, contentY not 0") << 30 << 60.0 << 0.0
+ QTest::newRow("move from below view, move 1 up, move to bottom, contentY not 0")
+ << 30 << 1.0 << 0.0
<< 25 << 17+3 << 1 << ListRange(17+3, 17+3);
- QTest::newRow("move from below view, move multiple up, move to to bottom") << 30 << 0.0 << 0.0
+ QTest::newRow("move from below view, move multiple up, move to to bottom")
+ << 30 << 0.0 << 0.0
<< 20 << 17 << 3 << ListRange(17, 17);
- QTest::newRow("move from below view, move multiple up, move to bottom, contentY not 0") << 30 << 60.0 << 0.0
+ QTest::newRow("move from below view, move multiple up, move to bottom, contentY not 0")
+ << 30 << 1.0 << 0.0
<< 25 << 17+3 << 3 << ListRange(17+3, 17+3);
}
@@ -4582,7 +5083,7 @@ void tst_QQuickGridView::removeTransitions()
{
QFETCH(int, initialItemCount);
QFETCH(bool, shouldAnimateTargets);
- QFETCH(qreal, contentY);
+ QFETCH(qreal, contentYRowOffset);
QFETCH(int, removalIndex);
QFETCH(int, removalCount);
QFETCH(ListRange, expectedDisplacedIndexes);
@@ -4615,8 +5116,8 @@ void tst_QQuickGridView::removeTransitions()
QVERIFY(contentItem != 0);
QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
- if (contentY != 0) {
- gridview->setContentY(contentY);
+ if (contentYRowOffset != 0) {
+ gridview->setContentY(contentYRowOffset * 60.0);
QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
}
@@ -4627,8 +5128,8 @@ void tst_QQuickGridView::removeTransitions()
QList<int> targetIndexes;
if (shouldAnimateTargets) {
for (int i=removalIndex; i<removalIndex+removalCount; i++) {
- int firstVisibleIndex = (contentY / 60.0)*3;
- int lastVisibleIndex = (qCeil((contentY + gridview->height()) / 60.0)*3) - 1;
+ int firstVisibleIndex = (gridview->contentY() / 60.0)*3;
+ int lastVisibleIndex = (qCeil((gridview->contentY() + gridview->height()) / 60.0)*3) - 1;
if (i >= firstVisibleIndex && i <= lastVisibleIndex) {
expectedTargetData << qMakePair(model.name(i), model.number(i));
targetIndexes << i;
@@ -4678,7 +5179,7 @@ void tst_QQuickGridView::removeTransitions()
for (int i=0; i<items.count(); i++) {
QQmlExpression e(qmlContext(items[i]), items[i], "index");
int index = e.evaluate().toInt();
- if (firstVisibleIndex < 0 && items[i]->y() >= contentY)
+ if (firstVisibleIndex < 0 && items[i]->y() >= gridview->contentY())
firstVisibleIndex = index;
else if (index < 0)
itemCount--; // exclude deleted items
@@ -4690,7 +5191,7 @@ void tst_QQuickGridView::removeTransitions()
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(), contentY + ((i-firstVisibleIndex)/3) * 60.0);
+ QCOMPARE(item->y(), gridview->contentY() + ((i-firstVisibleIndex)/3) * 60.0);
QQuickText *name = findItem<QQuickText>(contentItem, "textName", i);
QVERIFY(name != 0);
QTRY_COMPARE(name->text(), model.name(i));
@@ -4702,7 +5203,7 @@ void tst_QQuickGridView::removeTransitions()
void tst_QQuickGridView::removeTransitions_data()
{
QTest::addColumn<int>("initialItemCount");
- QTest::addColumn<qreal>("contentY");
+ QTest::addColumn<qreal>("contentYRowOffset");
QTest::addColumn<bool>("shouldAnimateTargets");
QTest::addColumn<int>("removalIndex");
QTest::addColumn<int>("removalCount");
@@ -4714,19 +5215,19 @@ void tst_QQuickGridView::removeTransitions_data()
// For a GridView, removing any number of items other than a full row before the start
// should displace all items in the view
QTest::newRow("remove 1 before start")
- << 30 << 120.0 << false
+ << 30 << 2.0 << false
<< 2 << 1 << ListRange(6, 24); // 6-24 are displaced
QTest::newRow("remove 1 row, before start")
- << 30 << 120.0 << false
+ << 30 << 2.0 << false
<< 3 << 3 << ListRange();
QTest::newRow("remove between 1-2 rows, before start")
- << 30 << 120.0 << false
+ << 30 << 2.0 << false
<< 0 << 5 << ListRange(6, 25);
QTest::newRow("remove 2 rows, before start")
- << 30 << 120.0 << false
+ << 30 << 2.0 << false
<< 0 << 6 << ListRange();
QTest::newRow("remove mix of before and after start")
- << 30 << 60.0 << true
+ << 30 << 1.0 << true
<< 2 << 3 << ListRange(5, 23); // 5-23 are displaced into view
@@ -4737,10 +5238,10 @@ void tst_QQuickGridView::removeTransitions_data()
<< 30 << 0.0 << true
<< 0 << 3 << ListRange(3, 20); // 3-18 are displaced into view
QTest::newRow("remove 1 from start, content y not 0")
- << 30 << 60.0 << true
+ << 30 << 1.0 << true
<< 3 << 1 << ListRange(1 + 3, 18 + 3);
QTest::newRow("remove multiple from start, content y not 0")
- << 30 << 60.0 << true
+ << 30 << 1.0 << true
<< 3 << 3 << ListRange(3 + 3, 20 + 3);
@@ -4762,10 +5263,10 @@ void tst_QQuickGridView::removeTransitions_data()
<< 30 << 0.0 << true
<< 15 << 5 << ListRange(20, 22);
QTest::newRow("remove 1 from bottom, content y not 0")
- << 30 << 60.0 << true
+ << 30 << 1.0 << true
<< 17 + 3 << 1 << ListRange(18 + 3, 18 + 3);
QTest::newRow("remove multiple (1 row) from bottom, content y not 0")
- << 30 << 60.0 << true
+ << 30 << 1.0 << true
<< 15 + 3 << 3 << ListRange(18 + 3, 20 + 3);
@@ -5246,11 +5747,7 @@ void tst_QQuickGridView::cacheBuffer()
for (int i = 0; i < 90; i++)
model.addItem("Item" + QString::number(i), "");
- QQmlContext *ctxt = canvas->rootContext();
- ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("testRightToLeft", QVariant(false));
- ctxt->setContextProperty("testTopToBottom", QVariant(false));
-
+ canvas->rootContext()->setContextProperty("testModel", &model);
canvas->setSource(testFileUrl("gridview1.qml"));
canvas->show();
qApp->processEvents();
@@ -5554,6 +6051,220 @@ void tst_QQuickGridView::unrequestedVisibility()
delete canvas;
}
+
+void tst_QQuickGridView::inserted_leftToRight_RtL_TtB()
+{
+ inserted_defaultLayout(QQuickGridView::FlowLeftToRight, Qt::RightToLeft);
+}
+
+void tst_QQuickGridView::inserted_leftToRight_RtL_TtB_data()
+{
+ inserted_defaultLayout_data();
+}
+
+void tst_QQuickGridView::inserted_topToBottom_LtR_TtB()
+{
+ inserted_defaultLayout(QQuickGridView::FlowTopToBottom);
+}
+
+void tst_QQuickGridView::inserted_topToBottom_LtR_TtB_data()
+{
+ inserted_defaultLayout_data();
+}
+
+void tst_QQuickGridView::inserted_topToBottom_RtL_TtB()
+{
+ inserted_defaultLayout(QQuickGridView::FlowTopToBottom, Qt::RightToLeft);
+}
+
+void tst_QQuickGridView::inserted_topToBottom_RtL_TtB_data()
+{
+ inserted_defaultLayout_data();
+}
+
+void tst_QQuickGridView::inserted_leftToRight_LtR_BtT()
+{
+ inserted_defaultLayout(QQuickGridView::FlowLeftToRight, Qt::LeftToRight, QQuickItemView::BottomToTop);
+}
+
+void tst_QQuickGridView::inserted_leftToRight_LtR_BtT_data()
+{
+ inserted_defaultLayout_data();
+}
+
+void tst_QQuickGridView::inserted_leftToRight_RtL_BtT()
+{
+ inserted_defaultLayout(QQuickGridView::FlowLeftToRight, Qt::RightToLeft, QQuickItemView::BottomToTop);
+}
+
+void tst_QQuickGridView::inserted_leftToRight_RtL_BtT_data()
+{
+ inserted_defaultLayout_data();
+}
+
+void tst_QQuickGridView::inserted_topToBottom_LtR_BtT()
+{
+ inserted_defaultLayout(QQuickGridView::FlowTopToBottom, Qt::LeftToRight, QQuickItemView::BottomToTop);
+}
+
+void tst_QQuickGridView::inserted_topToBottom_LtR_BtT_data()
+{
+ inserted_defaultLayout_data();
+}
+
+void tst_QQuickGridView::inserted_topToBottom_RtL_BtT()
+{
+ inserted_defaultLayout(QQuickGridView::FlowTopToBottom, Qt::RightToLeft, QQuickItemView::BottomToTop);
+}
+
+void tst_QQuickGridView::inserted_topToBottom_RtL_BtT_data()
+{
+ inserted_defaultLayout_data();
+}
+
+
+void tst_QQuickGridView::removed_leftToRight_RtL_TtB()
+{
+ removed_defaultLayout(QQuickGridView::FlowLeftToRight, Qt::RightToLeft);
+}
+
+void tst_QQuickGridView::removed_leftToRight_RtL_TtB_data()
+{
+ removed_defaultLayout_data();
+}
+
+void tst_QQuickGridView::removed_topToBottom_LtR_TtB()
+{
+ removed_defaultLayout(QQuickGridView::FlowTopToBottom);
+}
+
+void tst_QQuickGridView::removed_topToBottom_LtR_TtB_data()
+{
+ removed_defaultLayout_data();
+}
+
+void tst_QQuickGridView::removed_topToBottom_RtL_TtB()
+{
+ removed_defaultLayout(QQuickGridView::FlowTopToBottom, Qt::RightToLeft);
+}
+
+void tst_QQuickGridView::removed_topToBottom_RtL_TtB_data()
+{
+ removed_defaultLayout_data();
+}
+
+void tst_QQuickGridView::removed_leftToRight_LtR_BtT()
+{
+ removed_defaultLayout(QQuickGridView::FlowLeftToRight, Qt::LeftToRight, QQuickItemView::BottomToTop);
+}
+
+void tst_QQuickGridView::removed_leftToRight_LtR_BtT_data()
+{
+ removed_defaultLayout_data();
+}
+
+void tst_QQuickGridView::removed_leftToRight_RtL_BtT()
+{
+ removed_defaultLayout(QQuickGridView::FlowLeftToRight, Qt::RightToLeft, QQuickItemView::BottomToTop);
+}
+
+void tst_QQuickGridView::removed_leftToRight_RtL_BtT_data()
+{
+ removed_defaultLayout_data();
+}
+
+void tst_QQuickGridView::removed_topToBottom_LtR_BtT()
+{
+ removed_defaultLayout(QQuickGridView::FlowTopToBottom, Qt::LeftToRight, QQuickItemView::BottomToTop);
+}
+
+void tst_QQuickGridView::removed_topToBottom_LtR_BtT_data()
+{
+ removed_defaultLayout_data();
+}
+
+void tst_QQuickGridView::removed_topToBottom_RtL_BtT()
+{
+ removed_defaultLayout(QQuickGridView::FlowTopToBottom, Qt::RightToLeft, QQuickItemView::BottomToTop);
+}
+
+void tst_QQuickGridView::removed_topToBottom_RtL_BtT_data()
+{
+ removed_defaultLayout_data();
+}
+
+
+void tst_QQuickGridView::moved_leftToRight_RtL_TtB()
+{
+ moved_defaultLayout(QQuickGridView::FlowLeftToRight, Qt::RightToLeft);
+}
+
+void tst_QQuickGridView::moved_leftToRight_RtL_TtB_data()
+{
+ moved_defaultLayout_data();
+}
+
+void tst_QQuickGridView::moved_topToBottom_LtR_TtB()
+{
+ moved_defaultLayout(QQuickGridView::FlowTopToBottom);
+}
+
+void tst_QQuickGridView::moved_topToBottom_LtR_TtB_data()
+{
+ moved_defaultLayout_data();
+}
+
+void tst_QQuickGridView::moved_topToBottom_RtL_TtB()
+{
+ moved_defaultLayout(QQuickGridView::FlowTopToBottom, Qt::RightToLeft);
+}
+
+void tst_QQuickGridView::moved_topToBottom_RtL_TtB_data()
+{
+ moved_defaultLayout_data();
+}
+
+void tst_QQuickGridView::moved_leftToRight_LtR_BtT()
+{
+ moved_defaultLayout(QQuickGridView::FlowLeftToRight, Qt::LeftToRight, QQuickItemView::BottomToTop);
+}
+
+void tst_QQuickGridView::moved_leftToRight_LtR_BtT_data()
+{
+ moved_defaultLayout_data();
+}
+
+void tst_QQuickGridView::moved_leftToRight_RtL_BtT()
+{
+ moved_defaultLayout(QQuickGridView::FlowLeftToRight, Qt::RightToLeft, QQuickItemView::BottomToTop);
+}
+
+void tst_QQuickGridView::moved_leftToRight_RtL_BtT_data()
+{
+ moved_defaultLayout_data();
+}
+
+void tst_QQuickGridView::moved_topToBottom_LtR_BtT()
+{
+ moved_defaultLayout(QQuickGridView::FlowTopToBottom, Qt::LeftToRight, QQuickItemView::BottomToTop);
+}
+
+void tst_QQuickGridView::moved_topToBottom_LtR_BtT_data()
+{
+ moved_defaultLayout_data();
+}
+
+void tst_QQuickGridView::moved_topToBottom_RtL_BtT()
+{
+ moved_defaultLayout(QQuickGridView::FlowTopToBottom, Qt::RightToLeft, QQuickItemView::BottomToTop);
+}
+
+void tst_QQuickGridView::moved_topToBottom_RtL_BtT_data()
+{
+ moved_defaultLayout_data();
+}
+
+
QList<int> tst_QQuickGridView::toIntList(const QVariantList &list)
{
QList<int> ret;
diff --git a/tests/auto/quick/qquicklistview/data/header.qml b/tests/auto/quick/qquicklistview/data/header.qml
index bf70310630..1cc4ae09ee 100644
--- a/tests/auto/quick/qquicklistview/data/header.qml
+++ b/tests/auto/quick/qquicklistview/data/header.qml
@@ -15,7 +15,7 @@ Rectangle {
height: 30
width: 240
Text {
- text: index + " " + x + "," + y
+ text: index + " " + parent.x + "," + parent.y
}
color: ListView.isCurrentItem ? "lightsteelblue" : "white"
}
diff --git a/tests/auto/quick/qquicklistview/data/headerfooter.qml b/tests/auto/quick/qquicklistview/data/headerfooter.qml
index 4c3eeca328..07a331a4b7 100644
--- a/tests/auto/quick/qquicklistview/data/headerfooter.qml
+++ b/tests/auto/quick/qquicklistview/data/headerfooter.qml
@@ -2,27 +2,24 @@ import QtQuick 2.0
ListView {
id: view
- property bool horizontal: false
- property bool rtl: false
+
width: 240
height: 320
model: testModel
-
- orientation: horizontal ? ListView.Horizontal : ListView.Vertical
+
header: Rectangle {
objectName: "header"
- width: horizontal ? 20 : view.width
- height: horizontal ? view.height : 20
+ width: orientation == ListView.Horizontal ? 20 : view.width
+ height: orientation == ListView.Horizontal ? view.height : 20
color: "red"
}
footer: Rectangle {
objectName: "footer"
- width: horizontal ? 30 : view.width
- height: horizontal ? view.height : 30
+ width: orientation == ListView.Horizontal ? 30 : view.width
+ height: orientation == ListView.Horizontal ? view.height : 30
color: "blue"
}
delegate: Text { width: 30; height: 30; text: index + "(" + x + ")" }
- layoutDirection: rtl ? Qt.RightToLeft : Qt.LeftToRight
}
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index 1ef895d111..3369cf7933 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -58,7 +58,9 @@
#include <math.h>
Q_DECLARE_METATYPE(Qt::LayoutDirection)
+Q_DECLARE_METATYPE(QQuickItemView::VerticalLayoutDirection)
Q_DECLARE_METATYPE(QQuickListView::Orientation)
+Q_DECLARE_METATYPE(Qt::Key)
using namespace QQuickViewTestUtil;
using namespace QQuickVisualTestUtil;
@@ -89,6 +91,8 @@ private slots:
void qAbstractItemModel_inserted();
void qAbstractItemModel_inserted_more();
void qAbstractItemModel_inserted_more_data();
+ void qAbstractItemModel_inserted_more_bottomToTop();
+ void qAbstractItemModel_inserted_more_bottomToTop_data();
void qListModelInterface_removed();
void qListModelInterface_removed_more();
@@ -97,6 +101,8 @@ private slots:
void qAbstractItemModel_removed();
void qAbstractItemModel_removed_more();
void qAbstractItemModel_removed_more_data();
+ void qAbstractItemModel_removed_more_bottomToTop();
+ void qAbstractItemModel_removed_more_bottomToTop_data();
void qListModelInterface_moved();
void qListModelInterface_moved_data();
@@ -104,13 +110,18 @@ private slots:
void qListModelInterface_package_moved_data();
void qAbstractItemModel_moved();
void qAbstractItemModel_moved_data();
+ void qAbstractItemModel_moved_bottomToTop();
+ void qAbstractItemModel_moved_bottomToTop_data();
- void multipleChanges();
- void multipleChanges_data();
+ void multipleChanges_condensed() { multipleChanges(true); }
+ void multipleChanges_condensed_data() { multipleChanges_data(); }
+ void multipleChanges_uncondensed() { multipleChanges(false); }
+ void multipleChanges_uncondensed_data() { multipleChanges_data(); }
void qListModelInterface_clear();
void qListModelInterface_package_clear();
void qAbstractItemModel_clear();
+ void qAbstractItemModel_clear_bottomToTop();
void insertBeforeVisible();
void insertBeforeVisible_data();
@@ -120,6 +131,8 @@ private slots:
void currentIndex_delayedItemCreation_data();
void currentIndex();
void noCurrentIndex();
+ void keyNavigation();
+ void keyNavigation_data();
void enforceRange();
void enforceRange_withoutHighlight();
void spacing();
@@ -142,6 +155,8 @@ private slots:
void footer();
void footer_data();
void headerFooter();
+ void headerFooter_data();
+ void resetModel_headerFooter();
void resizeView();
void resizeViewAndRepaint();
void sizeLessThan1();
@@ -195,13 +210,16 @@ private:
template <class T> void items(const QUrl &source, bool forceLayout);
template <class T> void changed(const QUrl &source, bool forceLayout);
template <class T> void inserted(const QUrl &source);
- template <class T> void inserted_more();
+ template <class T> void inserted_more(QQuickItemView::VerticalLayoutDirection verticalLayoutDirection = QQuickItemView::TopToBottom);
template <class T> void removed(const QUrl &source, bool animated);
- template <class T> void removed_more(const QUrl &source);
- template <class T> void moved(const QUrl &source);
- template <class T> void clear(const QUrl &source);
+ template <class T> void removed_more(const QUrl &source, QQuickItemView::VerticalLayoutDirection verticalLayoutDirection = QQuickItemView::TopToBottom);
+ template <class T> void moved(const QUrl &source, QQuickItemView::VerticalLayoutDirection verticalLayoutDirection = QQuickItemView::TopToBottom);
+ template <class T> void clear(const QUrl &source, QQuickItemView::VerticalLayoutDirection verticalLayoutDirection = QQuickItemView::TopToBottom);
template <class T> void sections(const QUrl &source);
+ void multipleChanges(bool condensed);
+ void multipleChanges_data();
+
QList<int> toIntList(const QVariantList &list);
void matchIndexLists(const QVariantList &indexLists, const QList<int> &expectedIndexes);
void matchItemsAndIndexes(const QVariantMap &items, const QaimModel &model, const QList<int> &expectedIndexes);
@@ -522,7 +540,7 @@ void tst_QQuickListView::inserted(const QUrl &source)
}
template <class T>
-void tst_QQuickListView::inserted_more()
+void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection verticalLayoutDirection)
{
QFETCH(qreal, contentY);
QFETCH(int, insertIndex);
@@ -550,8 +568,15 @@ void tst_QQuickListView::inserted_more()
QQuickItem *contentItem = listview->contentItem();
QTRY_VERIFY(contentItem != 0);
+ bool waitForPolish = (contentY != 0);
+ if (verticalLayoutDirection == QQuickItemView::BottomToTop) {
+ listview->setVerticalLayoutDirection(verticalLayoutDirection);
+ QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
+ contentY = -listview->height() - contentY;
+ }
listview->setContentY(contentY);
- QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
+ if (waitForPolish)
+ QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
QList<QPair<QString, QString> > newData;
for (int i=0; i<insertCount; i++)
@@ -562,27 +587,32 @@ void tst_QQuickListView::inserted_more()
// check visibleItems.first() is in correct position
QQuickItem *item0 = findItem<QQuickItem>(contentItem, "wrapper", 0);
QVERIFY(item0);
- QCOMPARE(item0->y(), itemsOffsetAfterMove);
+ if (verticalLayoutDirection == QQuickItemView::BottomToTop)
+ QCOMPARE(item0->y(), -item0->height() - itemsOffsetAfterMove);
+ else
+ 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) {
- QQmlExpression e(qmlContext(items[i]), items[i], "index");
- firstVisibleIndex = e.evaluate().toInt();
+ QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+ if (item && item->isVisible()) {
+ firstVisibleIndex = i;
break;
}
}
QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex));
// Confirm items positioned correctly and indexes correct
- int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
QQuickText *name;
QQuickText *number;
- for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) {
+ for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++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);
+ qreal pos = i*20.0 + itemsOffsetAfterMove;
+ if (verticalLayoutDirection == QQuickItemView::BottomToTop)
+ pos = -item0->height() - pos;
+ QTRY_COMPARE(item->y(), pos);
name = findItem<QQuickText>(contentItem, "textName", i);
QVERIFY(name != 0);
QTRY_COMPARE(name->text(), model.name(i));
@@ -952,15 +982,13 @@ void tst_QQuickListView::removed(const QUrl &source, bool /* animated */)
}
template <class T>
-void tst_QQuickListView::removed_more(const QUrl &source)
+void tst_QQuickListView::removed_more(const QUrl &source, QQuickItemView::VerticalLayoutDirection verticalLayoutDirection)
{
QFETCH(qreal, contentY);
QFETCH(int, removeIndex);
QFETCH(int, removeCount);
QFETCH(qreal, itemsOffsetAfterMove);
- QQuickText *name;
- QQuickText *number;
QQuickView *canvas = getView();
T model;
@@ -983,13 +1011,15 @@ void tst_QQuickListView::removed_more(const QUrl &source)
QQuickItem *contentItem = listview->contentItem();
QTRY_VERIFY(contentItem != 0);
+ bool waitForPolish = (contentY != 0);
+ if (verticalLayoutDirection == QQuickItemView::BottomToTop) {
+ listview->setVerticalLayoutDirection(verticalLayoutDirection);
+ QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
+ contentY = -listview->height() - contentY;
+ }
listview->setContentY(contentY);
- QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
-
- // wait for refill (after refill, items above the firstVisibleIndex-1 should not be rendered)
- int firstVisibleIndex = contentY / 20;
- if (firstVisibleIndex - 2 >= 0)
- QTRY_VERIFY(!findItem<QQuickText>(contentItem, "textName", firstVisibleIndex - 2));
+ if (waitForPolish)
+ QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
model.removeItems(removeIndex, removeCount);
QTRY_COMPARE(listview->property("count").toInt(), model.count());
@@ -997,24 +1027,33 @@ void tst_QQuickListView::removed_more(const QUrl &source)
// check visibleItems.first() is in correct position
QQuickItem *item0 = findItem<QQuickItem>(contentItem, "wrapper", 0);
QVERIFY(item0);
- QCOMPARE(item0->y(), itemsOffsetAfterMove);
+ QVERIFY(item0);
+ if (verticalLayoutDirection == QQuickItemView::BottomToTop)
+ QCOMPARE(item0->y(), -item0->height() - itemsOffsetAfterMove);
+ else
+ 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) {
- QQmlExpression e(qmlContext(items[i]), items[i], "index");
- firstVisibleIndex = e.evaluate().toInt();
+ QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+ if (item && item->isVisible()) {
+ firstVisibleIndex = i;
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) {
+ QQuickText *name;
+ QQuickText *number;
+ for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++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);
+ qreal pos = i*20.0 + itemsOffsetAfterMove;
+ if (verticalLayoutDirection == QQuickItemView::BottomToTop)
+ pos = -item0->height() - pos;
+ QTRY_COMPARE(item->y(), pos);
name = findItem<QQuickText>(contentItem, "textName", i);
QVERIFY(name != 0);
QTRY_COMPARE(name->text(), model.name(i));
@@ -1131,7 +1170,7 @@ void tst_QQuickListView::removed_more_data()
}
template <class T>
-void tst_QQuickListView::clear(const QUrl &source)
+void tst_QQuickListView::clear(const QUrl &source, QQuickItemView::VerticalLayoutDirection verticalLayoutDirection)
{
QQuickView *canvas = createView();
@@ -1153,13 +1192,19 @@ void tst_QQuickListView::clear(const QUrl &source)
QTRY_VERIFY(listview != 0);
QQuickItem *contentItem = listview->contentItem();
QTRY_VERIFY(contentItem != 0);
+
+ listview->setVerticalLayoutDirection(verticalLayoutDirection);
QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
model.clear();
+ QTRY_COMPARE(findItems<QQuickListView>(contentItem, "wrapper").count(), 0);
QTRY_VERIFY(listview->count() == 0);
QTRY_VERIFY(listview->currentItem() == 0);
- QTRY_VERIFY(listview->contentY() == 0);
+ if (verticalLayoutDirection == QQuickItemView::TopToBottom)
+ QTRY_COMPARE(listview->contentY(), 0.0);
+ else
+ QTRY_COMPARE(listview->contentY(), -listview->height());
QVERIFY(listview->currentIndex() == -1);
// confirm sanity when adding an item to cleared list
@@ -1173,7 +1218,7 @@ void tst_QQuickListView::clear(const QUrl &source)
}
template <class T>
-void tst_QQuickListView::moved(const QUrl &source)
+void tst_QQuickListView::moved(const QUrl &source, QQuickItemView::VerticalLayoutDirection verticalLayoutDirection)
{
QFETCH(qreal, contentY);
QFETCH(int, from);
@@ -1204,15 +1249,19 @@ void tst_QQuickListView::moved(const QUrl &source)
QTRY_VERIFY(listview != 0);
QQuickItem *contentItem = listview->contentItem();
QTRY_VERIFY(contentItem != 0);
- QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
- QQuickItem *currentItem = listview->currentItem();
- QTRY_VERIFY(currentItem != 0);
+ // always need to wait for view to be painted before the first move()
+ QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
- if (contentY != 0) {
- listview->setContentY(contentY);
+ bool waitForPolish = (contentY != 0);
+ if (verticalLayoutDirection == QQuickItemView::BottomToTop) {
+ listview->setVerticalLayoutDirection(verticalLayoutDirection);
QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
+ contentY = -listview->height() - contentY;
}
+ listview->setContentY(contentY);
+ if (waitForPolish)
+ QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
model.moveItems(from, to, count);
QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
@@ -1220,22 +1269,22 @@ void tst_QQuickListView::moved(const QUrl &source)
QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper");
int firstVisibleIndex = -1;
for (int i=0; i<items.count(); i++) {
- if (items[i]->y() >= contentY) {
- QQmlExpression e(qmlContext(items[i]), items[i], "index");
- firstVisibleIndex = e.evaluate().toInt();
+ QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
+ if (item && item->isVisible()) {
+ firstVisibleIndex = i;
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;
+ for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++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);
+ qreal pos = i*20.0 + itemsOffsetAfterMove;
+ if (verticalLayoutDirection == QQuickItemView::BottomToTop)
+ pos = -item->height() - pos;
+ QTRY_COMPARE(item->y(), pos);
name = findItem<QQuickText>(contentItem, "textName", i);
QVERIFY(name != 0);
QTRY_COMPARE(name->text(), model.name(i));
@@ -1244,7 +1293,7 @@ void tst_QQuickListView::moved(const QUrl &source)
QTRY_COMPARE(number->text(), model.number(i));
// current index should have been updated
- if (item == currentItem)
+ if (item == listview->currentItem())
QTRY_COMPARE(listview->currentIndex(), i);
}
@@ -1403,7 +1452,7 @@ void tst_QQuickListView::moved_data()
<< -20.0 * 3; // to minimize movement, 16,17,18 move to above item 0, and other items do not move
}
-void tst_QQuickListView::multipleChanges()
+void tst_QQuickListView::multipleChanges(bool condensed)
{
QFETCH(int, startCount);
QFETCH(QList<ListChange>, changes);
@@ -1439,31 +1488,32 @@ void tst_QQuickListView::multipleChanges()
for (int j=changes[i].index; j<changes[i].index + changes[i].count; ++j)
items << qMakePair(QString("new item %1").arg(j), QString::number(j));
model.insertItems(changes[i].index, items);
- QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
break;
}
case ListChange::Removed:
model.removeItems(changes[i].index, changes[i].count);
- QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
break;
case ListChange::Moved:
model.moveItems(changes[i].index, changes[i].to, changes[i].count);
- QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
break;
case ListChange::SetCurrent:
listview->setCurrentIndex(changes[i].index);
- QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
break;
case ListChange::SetContentY:
listview->setContentY(changes[i].pos);
- QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
break;
+ default:
+ continue;
+ }
+ if (!condensed) {
+ QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
}
}
+ QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
- QTRY_COMPARE(listview->count(), newCount);
+ QCOMPARE(listview->count(), newCount);
QCOMPARE(listview->count(), model.count());
- QTRY_COMPARE(listview->currentIndex(), newCurrentIndex);
+ QCOMPARE(listview->currentIndex(), newCurrentIndex);
QQuickText *name;
QQuickText *number;
@@ -1626,13 +1676,34 @@ void tst_QQuickListView::multipleChanges_data()
<< 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;
+
+ QTest::newRow("remove, scroll") << 30 << (QList<ListChange>()
+ << ListChange::remove(20, 5)
+ << ListChange::setContentY(20)
+ ) << 25 << 0;
+
+ QTest::newRow("insert, scroll") << 10 << (QList<ListChange>()
+ << ListChange::insert(9, 5)
+ << ListChange::setContentY(20)
+ ) << 15 << 0;
+
+ QTest::newRow("move, scroll") << 20 << (QList<ListChange>()
+ << ListChange::move(15, 8, 3)
+ << ListChange::setContentY(0)
+ ) << 20 << 0;
+
+ QTest::newRow("clear, insert, scroll") << 30 << (QList<ListChange>()
+ << ListChange::setContentY(20)
+ << ListChange::remove(0, 30)
+ << ListChange::insert(0, 2)
+ << ListChange::setContentY(0)
+ ) << 2 << 0;
}
void tst_QQuickListView::swapWithFirstItem()
@@ -2313,35 +2384,11 @@ void tst_QQuickListView::currentIndex()
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());
@@ -2360,40 +2407,6 @@ void tst_QQuickListView::currentIndex()
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);
@@ -2416,6 +2429,7 @@ void tst_QQuickListView::currentIndex()
QVERIFY(!listview->highlightItem());
QVERIFY(!listview->currentItem());
+ // moving currentItem out of view should make it invisible
listview->setCurrentIndex(0);
QTRY_VERIFY(listview->currentItem()->isVisible());
listview->setContentY(200);
@@ -2462,6 +2476,129 @@ void tst_QQuickListView::noCurrentIndex()
delete canvas;
}
+void tst_QQuickListView::keyNavigation()
+{
+ QFETCH(QQuickListView::Orientation, orientation);
+ QFETCH(Qt::LayoutDirection, layoutDirection);
+ QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection);
+ QFETCH(Qt::Key, forwardsKey);
+ QFETCH(Qt::Key, backwardsKey);
+ QFETCH(QPointF, contentPosAtFirstItem);
+ QFETCH(QPointF, contentPosAtLastItem);
+
+ QmlListModel model;
+ for (int i = 0; i < 30; i++)
+ model.addItem("Item" + QString::number(i), "");
+
+ QQuickView *canvas = getView();
+ TestObject *testObject = new TestObject;
+ canvas->rootContext()->setContextProperty("testModel", &model);
+ canvas->rootContext()->setContextProperty("testObject", testObject);
+ canvas->setSource(testFileUrl("listviewtest.qml"));
+ canvas->show();
+ qApp->processEvents();
+
+ QQuickListView *listview = findItem<QQuickListView>(canvas->rootObject(), "list");
+ QTRY_VERIFY(listview != 0);
+
+ listview->setOrientation(orientation);
+ listview->setLayoutDirection(layoutDirection);
+ listview->setVerticalLayoutDirection(verticalLayoutDirection);
+ QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
+
+ canvas->requestActivateWindow();
+ QTRY_VERIFY(qGuiApp->focusWindow() == canvas);
+ QCOMPARE(listview->currentIndex(), 0);
+
+ QTest::keyClick(canvas, forwardsKey);
+ QCOMPARE(listview->currentIndex(), 1);
+
+ QTest::keyClick(canvas, backwardsKey);
+ QCOMPARE(listview->currentIndex(), 0);
+
+ // hold down a key to go forwards
+ for (int i=0; i<model.count()-1; i++) {
+ QTest::simulateEvent(canvas, true, forwardsKey, Qt::NoModifier, "", true);
+ QTRY_COMPARE(listview->currentIndex(), i+1);
+ }
+ QTest::keyRelease(canvas, forwardsKey);
+ QTRY_COMPARE(listview->currentIndex(), model.count()-1);
+ QTRY_COMPARE(listview->contentX(), contentPosAtLastItem.x());
+ QTRY_COMPARE(listview->contentY(), contentPosAtLastItem.y());
+
+ // hold down a key to go backwards
+ for (int i=model.count()-1; i > 0; i--) {
+ QTest::simulateEvent(canvas, true, backwardsKey, Qt::NoModifier, "", true);
+ QTRY_COMPARE(listview->currentIndex(), i-1);
+ }
+ QTest::keyRelease(canvas, backwardsKey);
+ QTRY_COMPARE(listview->currentIndex(), 0);
+ QTRY_COMPARE(listview->contentX(), contentPosAtFirstItem.x());
+ QTRY_COMPARE(listview->contentY(), contentPosAtFirstItem.y());
+
+ // no wrap
+ QVERIFY(!listview->isWrapEnabled());
+ listview->incrementCurrentIndex();
+ QCOMPARE(listview->currentIndex(), 1);
+ listview->decrementCurrentIndex();
+ QCOMPARE(listview->currentIndex(), 0);
+
+ listview->decrementCurrentIndex();
+ QCOMPARE(listview->currentIndex(), 0);
+
+ // with wrap
+ listview->setWrapEnabled(true);
+ QVERIFY(listview->isWrapEnabled());
+
+ listview->decrementCurrentIndex();
+ QCOMPARE(listview->currentIndex(), model.count()-1);
+ QTRY_COMPARE(listview->contentX(), contentPosAtLastItem.x());
+ QTRY_COMPARE(listview->contentY(), contentPosAtLastItem.y());
+
+ listview->incrementCurrentIndex();
+ QCOMPARE(listview->currentIndex(), 0);
+ QTRY_COMPARE(listview->contentX(), contentPosAtFirstItem.x());
+ QTRY_COMPARE(listview->contentY(), contentPosAtFirstItem.y());
+
+ releaseView(canvas);
+ delete testObject;
+}
+
+void tst_QQuickListView::keyNavigation_data()
+{
+ QTest::addColumn<QQuickListView::Orientation>("orientation");
+ QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<QQuickItemView::VerticalLayoutDirection>("verticalLayoutDirection");
+ QTest::addColumn<Qt::Key>("forwardsKey");
+ QTest::addColumn<Qt::Key>("backwardsKey");
+ QTest::addColumn<QPointF>("contentPosAtFirstItem");
+ QTest::addColumn<QPointF>("contentPosAtLastItem");
+
+ QTest::newRow("Vertical, TopToBottom")
+ << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom
+ << Qt::Key_Down << Qt::Key_Up
+ << QPointF(0, 0)
+ << QPointF(0, 30*20 - 320);
+
+ QTest::newRow("Vertical, BottomToTop")
+ << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop
+ << Qt::Key_Up << Qt::Key_Down
+ << QPointF(0, -320)
+ << QPointF(0, -(30 * 20));
+
+ QTest::newRow("Horizontal, LeftToRight")
+ << QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom
+ << Qt::Key_Right << Qt::Key_Left
+ << QPointF(0, 0)
+ << QPointF(30*240 - 240, 0);
+
+ QTest::newRow("Horizontal, RightToLeft")
+ << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom
+ << Qt::Key_Left << Qt::Key_Right
+ << QPointF(-240, 0)
+ << QPointF(-(30 * 240), 0);
+}
+
void tst_QQuickListView::itemList()
{
QQuickView *canvas = createView();
@@ -3083,11 +3220,12 @@ void tst_QQuickListView::header()
{
QFETCH(QQuickListView::Orientation, orientation);
QFETCH(Qt::LayoutDirection, layoutDirection);
+ QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection);
QFETCH(QPointF, initialHeaderPos);
- QFETCH(QPointF, firstDelegatePos);
- QFETCH(QPointF, initialContentPos);
QFETCH(QPointF, changedHeaderPos);
+ QFETCH(QPointF, initialContentPos);
QFETCH(QPointF, changedContentPos);
+ QFETCH(QPointF, firstDelegatePos);
QFETCH(QPointF, resizeContentPos);
QmlListModel model;
@@ -3106,6 +3244,8 @@ void tst_QQuickListView::header()
QTRY_VERIFY(listview != 0);
listview->setOrientation(orientation);
listview->setLayoutDirection(layoutDirection);
+ listview->setVerticalLayoutDirection(verticalLayoutDirection);
+ QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
QQuickItem *contentItem = listview->contentItem();
QTRY_VERIFY(contentItem != 0);
@@ -3156,6 +3296,11 @@ void tst_QQuickListView::header()
QVERIFY(item);
QCOMPARE(item->pos(), firstDelegatePos);
+ listview->positionViewAtBeginning();
+ header->setHeight(10);
+ header->setWidth(40);
+ QTRY_COMPARE(QPointF(listview->contentX(), listview->contentY()), resizeContentPos);
+
releaseView(canvas);
@@ -3173,6 +3318,7 @@ void tst_QQuickListView::header()
QTRY_VERIFY(listview != 0);
listview->setOrientation(orientation);
listview->setLayoutDirection(layoutDirection);
+ listview->setVerticalLayoutDirection(verticalLayoutDirection);
QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
listview->setWidth(240);
@@ -3187,6 +3333,7 @@ void tst_QQuickListView::header_data()
{
QTest::addColumn<QQuickListView::Orientation>("orientation");
QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<QQuickItemView::VerticalLayoutDirection>("verticalLayoutDirection");
QTest::addColumn<QPointF>("initialHeaderPos");
QTest::addColumn<QPointF>("changedHeaderPos");
QTest::addColumn<QPointF>("initialContentPos");
@@ -3196,11 +3343,11 @@ void tst_QQuickListView::header_data()
// header1 = 100 x 30
// header2 = 50 x 20
- // delegates = 240 x 20
+ // delegates = 240 x 30
// view width = 240
// header above items, top left
- QTest::newRow("vertical, left to right") << QQuickListView::Vertical << Qt::LeftToRight
+ QTest::newRow("vertical, left to right") << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom
<< QPointF(0, -30)
<< QPointF(0, -20)
<< QPointF(0, -30)
@@ -3209,7 +3356,7 @@ void tst_QQuickListView::header_data()
<< QPointF(0, -10);
// header above items, top right
- QTest::newRow("vertical, layout right to left") << QQuickListView::Vertical << Qt::RightToLeft
+ QTest::newRow("vertical, layout right to left") << QQuickListView::Vertical << Qt::RightToLeft << QQuickItemView::TopToBottom
<< QPointF(0, -30)
<< QPointF(0, -20)
<< QPointF(0, -30)
@@ -3218,7 +3365,7 @@ void tst_QQuickListView::header_data()
<< QPointF(0, -10);
// header to left of items
- QTest::newRow("horizontal, layout left to right") << QQuickListView::Horizontal << Qt::LeftToRight
+ QTest::newRow("horizontal, layout left to right") << QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom
<< QPointF(-100, 0)
<< QPointF(-50, 0)
<< QPointF(-100, 0)
@@ -3227,13 +3374,22 @@ void tst_QQuickListView::header_data()
<< QPointF(-40, 0);
// header to right of items
- QTest::newRow("horizontal, layout right to left") << QQuickListView::Horizontal << Qt::RightToLeft
+ QTest::newRow("horizontal, layout right to left") << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom
<< QPointF(0, 0)
<< QPointF(0, 0)
<< QPointF(-240 + 100, 0)
<< QPointF(-240 + 50, 0)
<< QPointF(-240, 0)
<< QPointF(-240 + 40, 0);
+
+ // header below items
+ QTest::newRow("vertical, bottom to top") << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop
+ << QPointF(0, 0)
+ << QPointF(0, 0)
+ << QPointF(0, -320 + 30)
+ << QPointF(0, -320 + 20)
+ << QPointF(0, -30)
+ << QPointF(0, -320 + 10);
}
void tst_QQuickListView::header_delayItemCreation()
@@ -3268,6 +3424,7 @@ void tst_QQuickListView::footer()
{
QFETCH(QQuickListView::Orientation, orientation);
QFETCH(Qt::LayoutDirection, layoutDirection);
+ QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection);
QFETCH(QPointF, initialFooterPos);
QFETCH(QPointF, firstDelegatePos);
QFETCH(QPointF, initialContentPos);
@@ -3292,6 +3449,7 @@ void tst_QQuickListView::footer()
QTRY_VERIFY(listview != 0);
listview->setOrientation(orientation);
listview->setLayoutDirection(layoutDirection);
+ listview->setVerticalLayoutDirection(verticalLayoutDirection);
QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
QQuickItem *contentItem = listview->contentItem();
@@ -3320,7 +3478,8 @@ void tst_QQuickListView::footer()
model.removeItem(1);
if (orientation == QQuickListView::Vertical) {
- QTRY_COMPARE(footer->y(), initialFooterPos.y() - 20); // delegate height = 20
+ QTRY_COMPARE(footer->y(), verticalLayoutDirection == QQuickItemView::TopToBottom ?
+ initialFooterPos.y() - 20 : initialFooterPos.y() + 20); // delegate width = 40
} else {
QTRY_COMPARE(footer->x(), layoutDirection == Qt::LeftToRight ?
initialFooterPos.x() - 40 : initialFooterPos.x() + 40); // delegate width = 40
@@ -3332,6 +3491,8 @@ void tst_QQuickListView::footer()
QPointF posWhenNoItems(0, 0);
if (orientation == QQuickListView::Horizontal && layoutDirection == Qt::RightToLeft)
posWhenNoItems.setX(-100);
+ else if (orientation == QQuickListView::Vertical && verticalLayoutDirection == QQuickItemView::BottomToTop)
+ posWhenNoItems.setY(-30);
QTRY_COMPARE(footer->pos(), posWhenNoItems);
// if header is present, it's at a negative pos, so the footer should not move
@@ -3376,6 +3537,7 @@ void tst_QQuickListView::footer_data()
{
QTest::addColumn<QQuickListView::Orientation>("orientation");
QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<QQuickItemView::VerticalLayoutDirection>("verticalLayoutDirection");
QTest::addColumn<QPointF>("initialFooterPos");
QTest::addColumn<QPointF>("changedFooterPos");
QTest::addColumn<QPointF>("initialContentPos");
@@ -3390,7 +3552,7 @@ void tst_QQuickListView::footer_data()
// view height = 320
// footer below items, bottom left
- QTest::newRow("vertical, layout left to right") << QQuickListView::Vertical << Qt::LeftToRight
+ QTest::newRow("vertical, layout left to right") << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom
<< QPointF(0, 3 * 20)
<< QPointF(0, 30 * 20) // added 30 items
<< QPointF(0, 0)
@@ -3399,7 +3561,7 @@ void tst_QQuickListView::footer_data()
<< QPointF(0, 30 * 20 - 320 + 10);
// footer below items, bottom right
- QTest::newRow("vertical, layout right to left") << QQuickListView::Vertical << Qt::RightToLeft
+ QTest::newRow("vertical, layout right to left") << QQuickListView::Vertical << Qt::RightToLeft << QQuickItemView::TopToBottom
<< QPointF(0, 3 * 20)
<< QPointF(0, 30 * 20)
<< QPointF(0, 0)
@@ -3408,7 +3570,7 @@ void tst_QQuickListView::footer_data()
<< QPointF(0, 30 * 20 - 320 + 10);
// footer to right of items
- QTest::newRow("horizontal, layout left to right") << QQuickListView::Horizontal << Qt::LeftToRight
+ QTest::newRow("horizontal, layout left to right") << QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom
<< QPointF(40 * 3, 0)
<< QPointF(40 * 30, 0)
<< QPointF(0, 0)
@@ -3417,13 +3579,22 @@ void tst_QQuickListView::footer_data()
<< QPointF(40 * 30 - 240 + 40, 0);
// footer to left of items
- QTest::newRow("horizontal, layout right to left") << QQuickListView::Horizontal << Qt::RightToLeft
+ QTest::newRow("horizontal, layout right to left") << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom
<< 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);
+
+ // footer above items
+ QTest::newRow("vertical, layout left to right") << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop
+ << QPointF(0, -(3 * 20) - 30)
+ << QPointF(0, -(30 * 20) - 20)
+ << QPointF(0, -320)
+ << QPointF(0, -320)
+ << QPointF(0, -20)
+ << QPointF(0, -(30 * 20) - 10);
}
class LVAccessor : public QQuickListView
@@ -3435,140 +3606,127 @@ public:
qreal maxX() const { return maxXExtent(); }
};
+
void tst_QQuickListView::headerFooter()
{
- {
- // Vertical
- QQuickView *canvas = createView();
-
- QmlListModel model;
- QQmlContext *ctxt = canvas->rootContext();
- ctxt->setContextProperty("testModel", &model);
-
- canvas->setSource(testFileUrl("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();
-
- QmlListModel model;
- QQmlContext *ctxt = canvas->rootContext();
- ctxt->setContextProperty("testModel", &model);
-
- canvas->setSource(testFileUrl("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());
+ QFETCH(QQuickListView::Orientation, orientation);
+ QFETCH(Qt::LayoutDirection, layoutDirection);
+ QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection);
+ QFETCH(QPointF, headerPos);
+ QFETCH(QPointF, footerPos);
+ QFETCH(QPointF, minPos);
+ QFETCH(QPointF, maxPos);
- QQuickItem *footer = findItem<QQuickItem>(contentItem, "footer");
- QVERIFY(footer);
- QCOMPARE(footer->x(), 0.);
+ QQuickView *canvas = getView();
- QCOMPARE(static_cast<LVAccessor*>(listview)->minX(), header->width());
- QCOMPARE(static_cast<LVAccessor*>(listview)->maxX(), header->width());
+ QmlListModel model;
+ QQmlContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+ canvas->setSource(testFileUrl("headerfooter.qml"));
+ canvas->show();
+ qApp->processEvents();
- delete canvas;
- }
- {
- // Horizontal RTL
- QQuickView *canvas = createView();
+ QQuickListView *listview = qobject_cast<QQuickListView*>(canvas->rootObject());
+ QTRY_VERIFY(listview != 0);
+ listview->setOrientation(orientation);
+ listview->setLayoutDirection(layoutDirection);
+ listview->setVerticalLayoutDirection(verticalLayoutDirection);
+ QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
- QmlListModel model;
- QQmlContext *ctxt = canvas->rootContext();
- ctxt->setContextProperty("testModel", &model);
+ QQuickItem *contentItem = listview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
- canvas->setSource(testFileUrl("headerfooter.qml"));
- canvas->rootObject()->setProperty("horizontal", true);
- canvas->rootObject()->setProperty("rtl", true);
- qApp->processEvents();
+ QQuickItem *header = findItem<QQuickItem>(contentItem, "header");
+ QVERIFY(header);
+ QCOMPARE(header->pos(), headerPos);
- QQuickListView *listview = qobject_cast<QQuickListView*>(canvas->rootObject());
- QTRY_VERIFY(listview != 0);
+ QQuickItem *footer = findItem<QQuickItem>(contentItem, "footer");
+ QVERIFY(footer);
+ QCOMPARE(footer->pos(), footerPos);
- QQuickItem *contentItem = listview->contentItem();
- QTRY_VERIFY(contentItem != 0);
+ QCOMPARE(static_cast<LVAccessor*>(listview)->minX(), minPos.x());
+ QCOMPARE(static_cast<LVAccessor*>(listview)->minY(), minPos.y());
+ QCOMPARE(static_cast<LVAccessor*>(listview)->maxX(), maxPos.x());
+ QCOMPARE(static_cast<LVAccessor*>(listview)->maxY(), maxPos.y());
- QQuickItem *header = findItem<QQuickItem>(contentItem, "header");
- QVERIFY(header);
- QCOMPARE(header->x(), 0.);
+ releaseView(canvas);
+}
- QQuickItem *footer = findItem<QQuickItem>(contentItem, "footer");
- QVERIFY(footer);
- QCOMPARE(footer->x(), -footer->width());
+void tst_QQuickListView::headerFooter_data()
+{
+ QTest::addColumn<QQuickListView::Orientation>("orientation");
+ QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<QQuickItemView::VerticalLayoutDirection>("verticalLayoutDirection");
+ QTest::addColumn<QPointF>("headerPos");
+ QTest::addColumn<QPointF>("footerPos");
+ QTest::addColumn<QPointF>("minPos");
+ QTest::addColumn<QPointF>("maxPos");
+
+ // header is 240x20 (or 20x320 in Horizontal orientation)
+ // footer is 240x30 (or 30x320 in Horizontal orientation)
+
+ QTest::newRow("Vertical, TopToBottom")
+ << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom
+ << QPointF(0, -20) << QPointF(0, 0)
+ << QPointF(0, 20) << QPointF(240, 20);
+
+ QTest::newRow("Vertical, BottomToTop")
+ << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop
+ << QPointF(0, 0) << QPointF(0, -30)
+ << QPointF(0, 320 - 20) << QPointF(240, 320 - 20); // content flow is reversed
+
+
+ QTest::newRow("Horizontal, LeftToRight")
+ << QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom
+ << QPointF(-20, 0) << QPointF(0, 0)
+ << QPointF(20, 0) << QPointF(20, 320);
+
+ QTest::newRow("Horizontal, RightToLeft")
+ << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom
+ << QPointF(0, 0) << QPointF(-30, 0)
+ << QPointF(240 - 20, 0) << QPointF(240 - 20, 320); // content flow is reversed
+}
- QCOMPARE(static_cast<LVAccessor*>(listview)->minX(), 240. - header->width());
- QCOMPARE(static_cast<LVAccessor*>(listview)->maxX(), 240. - header->width());
+void tst_QQuickListView::resetModel_headerFooter()
+{
+ // Resetting a model shouldn't crash in views with header/footer
- delete canvas;
- }
- {
- // Reset model
- QQuickView *canvas = createView();
+ QQuickView *canvas = createView();
- QaimModel model;
- for (int i = 0; i < 4; i++)
- model.addItem("Item" + QString::number(i), "");
- QQmlContext *ctxt = canvas->rootContext();
- ctxt->setContextProperty("testModel", &model);
+ QaimModel model;
+ for (int i = 0; i < 4; i++)
+ model.addItem("Item" + QString::number(i), "");
+ QQmlContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
- canvas->setSource(testFileUrl("headerfooter.qml"));
- qApp->processEvents();
+ canvas->setSource(testFileUrl("headerfooter.qml"));
+ qApp->processEvents();
- QQuickListView *listview = qobject_cast<QQuickListView*>(canvas->rootObject());
- QTRY_VERIFY(listview != 0);
+ QQuickListView *listview = qobject_cast<QQuickListView*>(canvas->rootObject());
+ QTRY_VERIFY(listview != 0);
- QQuickItem *contentItem = listview->contentItem();
- QTRY_VERIFY(contentItem != 0);
+ QQuickItem *contentItem = listview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
- QQuickItem *header = findItem<QQuickItem>(contentItem, "header");
- QVERIFY(header);
- QCOMPARE(header->y(), -header->height());
+ QQuickItem *header = findItem<QQuickItem>(contentItem, "header");
+ QVERIFY(header);
+ QCOMPARE(header->y(), -header->height());
- QQuickItem *footer = findItem<QQuickItem>(contentItem, "footer");
- QVERIFY(footer);
- QCOMPARE(footer->y(), 30.*4);
+ QQuickItem *footer = findItem<QQuickItem>(contentItem, "footer");
+ QVERIFY(footer);
+ QCOMPARE(footer->y(), 30.*4);
- model.reset();
+ model.reset();
- header = findItem<QQuickItem>(contentItem, "header");
- QVERIFY(header);
- QCOMPARE(header->y(), -header->height());
+ header = findItem<QQuickItem>(contentItem, "header");
+ QVERIFY(header);
+ QCOMPARE(header->y(), -header->height());
- footer = findItem<QQuickItem>(contentItem, "footer");
- QVERIFY(footer);
- QCOMPARE(footer->y(), 30.*4);
+ footer = findItem<QQuickItem>(contentItem, "footer");
+ QVERIFY(footer);
+ QCOMPARE(footer->y(), 30.*4);
- delete canvas;
- }
+ delete canvas;
}
void tst_QQuickListView::resizeView()
@@ -4288,13 +4446,14 @@ void tst_QQuickListView::marginsResize()
{
QFETCH(QQuickListView::Orientation, orientation);
QFETCH(Qt::LayoutDirection, layoutDirection);
+ QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection);
QFETCH(qreal, start);
QFETCH(qreal, end);
QPoint flickStart(20, 20);
QPoint flickEnd(20, 20);
if (orientation == QQuickListView::Vertical)
- flickStart.ry() += 180;
+ flickStart.ry() += (verticalLayoutDirection == QQuickItemView::TopToBottom) ? 180 : -180;
else
flickStart.rx() += (layoutDirection == Qt::LeftToRight) ? 180 : -180;
@@ -4309,6 +4468,7 @@ void tst_QQuickListView::marginsResize()
listview->setOrientation(orientation);
listview->setLayoutDirection(layoutDirection);
+ listview->setVerticalLayoutDirection(verticalLayoutDirection);
QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
// view is resized after componentCompleted - top margin should still be visible
@@ -4354,20 +4514,34 @@ void tst_QQuickListView::marginsResize_data()
{
QTest::addColumn<QQuickListView::Orientation>("orientation");
QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<QQuickListView::VerticalLayoutDirection>("verticalLayoutDirection");
QTest::addColumn<qreal>("start");
QTest::addColumn<qreal>("end");
// in Right to Left mode, leftMargin still means leftMargin - it doesn't reverse to mean rightMargin
- QTest::newRow("vertical") << QQuickListView::Vertical << Qt::LeftToRight << -40.0 << 1020.0;
- QTest::newRow("horizontal") << QQuickListView::Horizontal << Qt::LeftToRight << -40.0 << 1020.0;
- QTest::newRow("horizontal, rtl") << QQuickListView::Horizontal << Qt::RightToLeft << -180.0 << -1240.0;
+ QTest::newRow("vertical")
+ << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom
+ << -40.0 << 1020.0;
+
+ QTest::newRow("vertical, BottomToTop")
+ << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop
+ << -180.0 << -1240.0;
+
+ QTest::newRow("horizontal")
+ << QQuickListView::Horizontal<< Qt::LeftToRight << QQuickItemView::TopToBottom
+ << -40.0 << 1020.0;
+
+ QTest::newRow("horizontal, rtl")
+ << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom
+ << -180.0 << -1240.0;
}
void tst_QQuickListView::snapToItem_data()
{
QTest::addColumn<QQuickListView::Orientation>("orientation");
QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<QQuickItemView::VerticalLayoutDirection>("verticalLayoutDirection");
QTest::addColumn<int>("highlightRangeMode");
QTest::addColumn<QPoint>("flickStart");
QTest::addColumn<QPoint>("flickEnd");
@@ -4375,22 +4549,36 @@ void tst_QQuickListView::snapToItem_data()
QTest::addColumn<qreal>("endExtent");
QTest::addColumn<qreal>("startExtent");
- QTest::newRow("vertical, left to right") << QQuickListView::Vertical << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
+ QTest::newRow("vertical, top to bottom")
+ << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::NoHighlightRange)
<< QPoint(20, 200) << QPoint(20, 20) << 60.0 << 560.0 << 0.0;
- QTest::newRow("horizontal, left to right") << QQuickListView::Horizontal << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
+ QTest::newRow("vertical, bottom to top")
+ << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop << int(QQuickItemView::NoHighlightRange)
+ << QPoint(20, 20) << QPoint(20, 200) << -60.0 << -560.0 - 240.0 << -240.0;
+
+ QTest::newRow("horizontal, left to right")
+ << QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::NoHighlightRange)
<< QPoint(200, 20) << QPoint(20, 20) << 60.0 << 560.0 << 0.0;
- QTest::newRow("horizontal, right to left") << QQuickListView::Horizontal << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange)
+ QTest::newRow("horizontal, right to left")
+ << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom << int(QQuickItemView::NoHighlightRange)
<< QPoint(20, 20) << QPoint(200, 20) << -60.0 << -560.0 - 240.0 << -240.0;
- QTest::newRow("vertical, left to right, enforce range") << QQuickListView::Vertical << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
+ QTest::newRow("vertical, top to bottom, enforce range")
+ << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::StrictlyEnforceRange)
<< QPoint(20, 200) << QPoint(20, 20) << 60.0 << 700.0 << -20.0;
- QTest::newRow("horizontal, left to right, enforce range") << QQuickListView::Horizontal << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
+ QTest::newRow("vertical, bottom to top, enforce range")
+ << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop << int(QQuickItemView::StrictlyEnforceRange)
+ << QPoint(20, 20) << QPoint(20, 200) << -60.0 << -560.0 - 240.0 - 140.0 << -220.0;
+
+ QTest::newRow("horizontal, left to right, enforce range")
+ << QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::StrictlyEnforceRange)
<< QPoint(200, 20) << QPoint(20, 20) << 60.0 << 700.0 << -20.0;
- QTest::newRow("horizontal, right to left, enforce range") << QQuickListView::Horizontal << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange)
+ QTest::newRow("horizontal, right to left, enforce range")
+ << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom << int(QQuickItemView::StrictlyEnforceRange)
<< QPoint(20, 20) << QPoint(200, 20) << -60.0 << -560.0 - 240.0 - 140.0 << -220.0;
}
@@ -4398,6 +4586,7 @@ void tst_QQuickListView::snapToItem()
{
QFETCH(QQuickListView::Orientation, orientation);
QFETCH(Qt::LayoutDirection, layoutDirection);
+ QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection);
QFETCH(int, highlightRangeMode);
QFETCH(QPoint, flickStart);
QFETCH(QPoint, flickEnd);
@@ -4416,6 +4605,7 @@ void tst_QQuickListView::snapToItem()
listview->setOrientation(orientation);
listview->setLayoutDirection(layoutDirection);
+ listview->setVerticalLayoutDirection(verticalLayoutDirection);
listview->setHighlightRangeMode(QQuickItemView::HighlightRangeMode(highlightRangeMode));
QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
@@ -4435,7 +4625,7 @@ void tst_QQuickListView::snapToItem()
flick(canvas, flickStart, flickEnd, 180);
QTRY_VERIFY(listview->isMoving() == false); // wait until it stops
} while (orientation == QQuickListView::Vertical
- ? !listview->isAtYEnd()
+ ? verticalLayoutDirection == QQuickItemView::TopToBottom ? !listview->isAtYEnd() : !listview->isAtYBeginning()
: layoutDirection == Qt::LeftToRight ? !listview->isAtXEnd() : !listview->isAtXBeginning());
if (orientation == QQuickListView::Vertical)
@@ -4448,7 +4638,7 @@ void tst_QQuickListView::snapToItem()
flick(canvas, flickEnd, flickStart, 180);
QTRY_VERIFY(listview->isMoving() == false); // wait until it stops
} while (orientation == QQuickListView::Vertical
- ? !listview->isAtYBeginning()
+ ? verticalLayoutDirection == QQuickItemView::TopToBottom ? !listview->isAtYBeginning() : !listview->isAtYEnd()
: layoutDirection == Qt::LeftToRight ? !listview->isAtXBeginning() : !listview->isAtXEnd());
if (orientation == QQuickListView::Vertical)
@@ -4524,6 +4714,16 @@ void tst_QQuickListView::qAbstractItemModel_inserted_more_data()
inserted_more_data();
}
+void tst_QQuickListView::qAbstractItemModel_inserted_more_bottomToTop()
+{
+ inserted_more<QaimModel>(QQuickItemView::BottomToTop);
+}
+
+void tst_QQuickListView::qAbstractItemModel_inserted_more_bottomToTop_data()
+{
+ inserted_more_data();
+}
+
void tst_QQuickListView::qListModelInterface_removed()
{
removed<QmlListModel>(testFileUrl("listviewtest.qml"), false);
@@ -4562,6 +4762,16 @@ void tst_QQuickListView::qAbstractItemModel_removed_more_data()
removed_more_data();
}
+void tst_QQuickListView::qAbstractItemModel_removed_more_bottomToTop()
+{
+ removed_more<QaimModel>(testFileUrl("listviewtest.qml"), QQuickItemView::BottomToTop);
+}
+
+void tst_QQuickListView::qAbstractItemModel_removed_more_bottomToTop_data()
+{
+ removed_more_data();
+}
+
void tst_QQuickListView::qListModelInterface_moved()
{
moved<QmlListModel>(testFileUrl("listviewtest.qml"));
@@ -4592,6 +4802,16 @@ void tst_QQuickListView::qAbstractItemModel_moved_data()
moved_data();
}
+void tst_QQuickListView::qAbstractItemModel_moved_bottomToTop()
+{
+ moved<QaimModel>(testFileUrl("listviewtest-package.qml"), QQuickItemView::BottomToTop);
+}
+
+void tst_QQuickListView::qAbstractItemModel_moved_bottomToTop_data()
+{
+ moved_data();
+}
+
void tst_QQuickListView::qListModelInterface_clear()
{
clear<QmlListModel>(testFileUrl("listviewtest.qml"));
@@ -4607,6 +4827,11 @@ void tst_QQuickListView::qAbstractItemModel_clear()
clear<QaimModel>(testFileUrl("listviewtest.qml"));
}
+void tst_QQuickListView::qAbstractItemModel_clear_bottomToTop()
+{
+ clear<QaimModel>(testFileUrl("listviewtest.qml"), QQuickItemView::BottomToTop);
+}
+
void tst_QQuickListView::qListModelInterface_sections()
{
sections<QmlListModel>(testFileUrl("listview-sections.qml"));
@@ -4705,6 +4930,7 @@ void tst_QQuickListView::snapOneItem_data()
{
QTest::addColumn<QQuickListView::Orientation>("orientation");
QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<QQuickItemView::VerticalLayoutDirection>("verticalLayoutDirection");
QTest::addColumn<int>("highlightRangeMode");
QTest::addColumn<QPoint>("flickStart");
QTest::addColumn<QPoint>("flickEnd");
@@ -4712,22 +4938,36 @@ void tst_QQuickListView::snapOneItem_data()
QTest::addColumn<qreal>("endExtent");
QTest::addColumn<qreal>("startExtent");
- QTest::newRow("vertical, left to right") << QQuickListView::Vertical << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
+ QTest::newRow("vertical, top to bottom")
+ << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::NoHighlightRange)
<< QPoint(20, 200) << QPoint(20, 20) << 180.0 << 560.0 << 0.0;
- QTest::newRow("horizontal, left to right") << QQuickListView::Horizontal << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange)
+ QTest::newRow("vertical, bottom to top")
+ << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop << int(QQuickItemView::NoHighlightRange)
+ << QPoint(20, 20) << QPoint(20, 200) << -420.0 << -560.0 - 240.0 << -240.0;
+
+ QTest::newRow("horizontal, left to right")
+ << QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::NoHighlightRange)
<< QPoint(200, 20) << QPoint(20, 20) << 180.0 << 560.0 << 0.0;
- QTest::newRow("horizontal, right to left") << QQuickListView::Horizontal << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange)
+ QTest::newRow("horizontal, right to left")
+ << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom << int(QQuickItemView::NoHighlightRange)
<< QPoint(20, 20) << QPoint(200, 20) << -420.0 << -560.0 - 240.0 << -240.0;
- QTest::newRow("vertical, left to right, enforce range") << QQuickListView::Vertical << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
+ QTest::newRow("vertical, top to bottom, enforce range")
+ << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::StrictlyEnforceRange)
<< QPoint(20, 200) << QPoint(20, 20) << 180.0 << 580.0 << -20.0;
- QTest::newRow("horizontal, left to right, enforce range") << QQuickListView::Horizontal << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange)
+ QTest::newRow("vertical, bottom to top, enforce range")
+ << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop << int(QQuickItemView::StrictlyEnforceRange)
+ << QPoint(20, 20) << QPoint(20, 200) << -420.0 << -580.0 - 240.0 << -220.0;
+
+ QTest::newRow("horizontal, left to right, enforce range")
+ << QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom << int(QQuickItemView::StrictlyEnforceRange)
<< QPoint(200, 20) << QPoint(20, 20) << 180.0 << 580.0 << -20.0;
- QTest::newRow("horizontal, right to left, enforce range") << QQuickListView::Horizontal << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange)
+ QTest::newRow("horizontal, right to left, enforce range")
+ << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom << int(QQuickItemView::StrictlyEnforceRange)
<< QPoint(20, 20) << QPoint(200, 20) << -420.0 << -580.0 - 240.0 << -220.0;
}
@@ -4735,6 +4975,7 @@ void tst_QQuickListView::snapOneItem()
{
QFETCH(QQuickListView::Orientation, orientation);
QFETCH(Qt::LayoutDirection, layoutDirection);
+ QFETCH(QQuickItemView::VerticalLayoutDirection, verticalLayoutDirection);
QFETCH(int, highlightRangeMode);
QFETCH(QPoint, flickStart);
QFETCH(QPoint, flickEnd);
@@ -4758,6 +4999,7 @@ void tst_QQuickListView::snapOneItem()
listview->setOrientation(orientation);
listview->setLayoutDirection(layoutDirection);
+ listview->setVerticalLayoutDirection(verticalLayoutDirection);
listview->setHighlightRangeMode(QQuickItemView::HighlightRangeMode(highlightRangeMode));
QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
@@ -4784,7 +5026,7 @@ void tst_QQuickListView::snapOneItem()
flick(canvas, flickStart, flickEnd, 180);
QTRY_VERIFY(listview->isMoving() == false); // wait until it stops
} while (orientation == QQuickListView::Vertical
- ? !listview->isAtYEnd()
+ ? verticalLayoutDirection == QQuickItemView::TopToBottom ? !listview->isAtYEnd() : !listview->isAtYBeginning()
: layoutDirection == Qt::LeftToRight ? !listview->isAtXEnd() : !listview->isAtXBeginning());
if (orientation == QQuickListView::Vertical)
@@ -4802,7 +5044,7 @@ void tst_QQuickListView::snapOneItem()
flick(canvas, flickEnd, flickStart, 180);
QTRY_VERIFY(listview->isMoving() == false); // wait until it stops
} while (orientation == QQuickListView::Vertical
- ? !listview->isAtYBeginning()
+ ? verticalLayoutDirection == QQuickItemView::TopToBottom ? !listview->isAtYBeginning() : !listview->isAtYEnd()
: layoutDirection == Qt::LeftToRight ? !listview->isAtXBeginning() : !listview->isAtXEnd());
if (orientation == QQuickListView::Vertical)
@@ -6277,3 +6519,4 @@ QTEST_MAIN(tst_QQuickListView)
#include "tst_qquicklistview.moc"
+
diff --git a/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro b/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro
index a24ea52e11..831ffd3c35 100644
--- a/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro
+++ b/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro
@@ -15,6 +15,6 @@ TESTDATA = data/*
# LIBS += -lgcov
CONFIG += parallel_test
-CONFIG += insignificant_test
+CONFIG += insignificant_test # QTBUG-25307
QT += core-private gui-private qml-private quick-private network testlib concurrent
diff --git a/tests/auto/quick/qquickpositioners/qquickpositioners.pro b/tests/auto/quick/qquickpositioners/qquickpositioners.pro
index dbbfae0ebf..e4fce55548 100644
--- a/tests/auto/quick/qquickpositioners/qquickpositioners.pro
+++ b/tests/auto/quick/qquickpositioners/qquickpositioners.pro
@@ -1,4 +1,5 @@
CONFIG += testcase
+CONFIG += insignificant_test
TARGET = tst_qquickpositioners
SOURCES += tst_qquickpositioners.cpp
diff --git a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp
index ae2bdc7fae..6ceacdfaf0 100644
--- a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp
+++ b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp
@@ -1875,11 +1875,15 @@ void tst_qquickpositioners::test_attachedproperties_dynamic()
QQuickView *tst_qquickpositioners::createView(const QString &filename, bool wait)
{
QQuickView *canvas = new QQuickView(0);
+ qDebug() << "1";
canvas->setSource(QUrl::fromLocalFile(filename));
+ qDebug() << "2";
canvas->show();
+ qDebug() << "3";
if (wait)
QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn
+ qDebug() << "4";
return canvas;
}
diff --git a/tests/auto/quick/qquickshadereffect/data/deleteShaderEffectSource.qml b/tests/auto/quick/qquickshadereffect/data/deleteShaderEffectSource.qml
new file mode 100644
index 0000000000..4e0eb4eb17
--- /dev/null
+++ b/tests/auto/quick/qquickshadereffect/data/deleteShaderEffectSource.qml
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ShaderEffect {
+ id: sei
+ property variant source
+ }
+
+ ShaderEffectSource {
+ id: doomed
+ hideSource: true
+ sourceItem: Image {
+ source: "star.png"
+ }
+ }
+
+ function setDeletedShaderEffectSource() {
+ sei.source = doomed;
+ doomed.destroy();
+ // now set a fragment shader to trigger source texture detection.
+ sei.fragmentShader = "varying highp vec2 qt_TexCoord0;\
+ uniform sampler2D source;\
+ uniform lowp float qt_Opacity;\
+ void main() {\
+ gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;\
+ }";
+ }
+}
diff --git a/tests/auto/quick/qquickshadereffect/data/deleteSourceItem.qml b/tests/auto/quick/qquickshadereffect/data/deleteSourceItem.qml
new file mode 100644
index 0000000000..ecf4cbd4bb
--- /dev/null
+++ b/tests/auto/quick/qquickshadereffect/data/deleteSourceItem.qml
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ShaderEffect {
+ id: sei
+ property variant source
+ }
+
+ ShaderEffectSource {
+ id: doomedses
+ hideSource: true
+ sourceItem: Image {
+ id: doomed
+ source: "star.png"
+ }
+ }
+
+ function setDeletedSourceItem() {
+ doomed.destroy();
+ sei.source = doomedses;
+ // now set a fragment shader to trigger source texture detection.
+ sei.fragmentShader = "varying highp vec2 qt_TexCoord0;\
+ uniform sampler2D source;\
+ uniform lowp float qt_Opacity;\
+ void main() {\
+ gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;\
+ }";
+ }
+}
diff --git a/tests/auto/quick/qquickshadereffect/data/star.png b/tests/auto/quick/qquickshadereffect/data/star.png
new file mode 100644
index 0000000000..0d592cfa87
--- /dev/null
+++ b/tests/auto/quick/qquickshadereffect/data/star.png
Binary files differ
diff --git a/tests/auto/quick/qquickshadereffect/qquickshadereffect.pro b/tests/auto/quick/qquickshadereffect/qquickshadereffect.pro
index 142d368aed..10aa3daecb 100644
--- a/tests/auto/quick/qquickshadereffect/qquickshadereffect.pro
+++ b/tests/auto/quick/qquickshadereffect/qquickshadereffect.pro
@@ -2,6 +2,7 @@ CONFIG += testcase
TARGET = tst_qquickshadereffect
SOURCES += tst_qquickshadereffect.cpp
+include (../../shared/util.pri)
macx:CONFIG -= app_bundle
CONFIG += parallel_test
diff --git a/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp b/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp
index 1edf511ebf..2816fe62ea 100644
--- a/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp
+++ b/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp
@@ -45,6 +45,10 @@
#include <QByteArray>
#include <private/qquickshadereffect_p.h>
+#include <QtQuick/QQuickView>
+#include "../../shared/util.h"
+
+
class TestShaderEffect : public QQuickShaderEffect
{
Q_OBJECT
@@ -68,7 +72,7 @@ private:
QList<QByteArray> m_signals;
};
-class tst_qquickshadereffect : public QObject
+class tst_qquickshadereffect : public QQmlDataTest
{
Q_OBJECT
public:
@@ -81,6 +85,9 @@ private slots:
void lookThroughShaderCode_data();
void lookThroughShaderCode();
+ void deleteSourceItem();
+ void deleteShaderEffectSource();
+
private:
enum PresenceFlags {
VertexPresent = 0x01,
@@ -97,6 +104,7 @@ tst_qquickshadereffect::tst_qquickshadereffect()
void tst_qquickshadereffect::initTestCase()
{
+ QQmlDataTest::initTestCase();
}
void tst_qquickshadereffect::cleanupTestCase()
@@ -269,6 +277,36 @@ void tst_qquickshadereffect::lookThroughShaderCode()
QCOMPARE(item.isConnected(SIGNAL(dummyChanged())), (presenceFlags & PropertyPresent) != 0);
}
+void tst_qquickshadereffect::deleteSourceItem()
+{
+ // purely to ensure that deleting the sourceItem of a shader doesn't cause a crash
+ QQuickView *view = new QQuickView(0);
+ view->setSource(QUrl::fromLocalFile(testFile("deleteSourceItem.qml")));
+ view->show();
+ QTest::qWaitForWindowShown(view);
+ QVERIFY(view);
+ QObject *obj = view->rootObject();
+ QVERIFY(obj);
+ QMetaObject::invokeMethod(obj, "setDeletedSourceItem");
+ QTest::qWait(50);
+ delete view;
+}
+
+void tst_qquickshadereffect::deleteShaderEffectSource()
+{
+ // purely to ensure that deleting the sourceItem of a shader doesn't cause a crash
+ QQuickView *view = new QQuickView(0);
+ view->setSource(QUrl::fromLocalFile(testFile("deleteShaderEffectSource.qml")));
+ view->show();
+ QTest::qWaitForWindowShown(view);
+ QVERIFY(view);
+ QObject *obj = view->rootObject();
+ QVERIFY(obj);
+ QMetaObject::invokeMethod(obj, "setDeletedShaderEffectSource");
+ QTest::qWait(50);
+ delete view;
+}
+
QTEST_MAIN(tst_qquickshadereffect)
#include "tst_qquickshadereffect.moc"
diff --git a/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp b/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp
index 35ce724a64..d6e5370711 100644
--- a/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp
+++ b/tests/auto/quick/qquickstyledtext/tst_qquickstyledtext.cpp
@@ -56,7 +56,8 @@ public:
enum Type {
Bold = 0x01,
Underline = 0x02,
- Italic = 0x04
+ Italic = 0x04,
+ Anchor = 0x08
};
Format(int t, int s, int l)
: type(t), start(s), length(l) {}
@@ -73,6 +74,9 @@ public:
private slots:
void textOutput();
void textOutput_data();
+ void anchors();
+ void anchors_data();
+ void longString();
};
Q_DECLARE_METATYPE(tst_qquickstyledtext::FormatList);
@@ -90,7 +94,13 @@ void tst_qquickstyledtext::textOutput_data()
QTest::addColumn<FormatList>("formats");
QTest::addColumn<bool>("modifiesFontSize");
+ QTest::newRow("empty") << "" << "" << FormatList() << false;
+ QTest::newRow("empty tag") << "<>test</>" << "test" << FormatList() << false;
+ QTest::newRow("nest opening") << "<b<b>>test</b>" << ">test" << FormatList() << false;
+ QTest::newRow("nest closing") << "<b>test<</b>/b>" << "test/b>" << (FormatList() << Format(Format::Bold, 0, 7)) << false;
QTest::newRow("bold") << "<b>bold</b>" << "bold" << (FormatList() << Format(Format::Bold, 0, 4)) << false;
+ QTest::newRow("bold 2") << "<b>>>>>bold</b>" << ">>>>bold" << (FormatList() << Format(Format::Bold, 0, 8)) << false;
+ QTest::newRow("bold 3") << "<b>bold<>/b>" << "bold/b>" << (FormatList() << Format(Format::Bold, 0, 7)) << false;
QTest::newRow("italic") << "<i>italic</i>" << "italic" << (FormatList() << Format(Format::Italic, 0, 6)) << false;
QTest::newRow("underline") << "<u>underline</u>" << "underline" << (FormatList() << Format(Format::Underline, 0, 9)) << false;
QTest::newRow("strong") << "<strong>strong</strong>" << "strong" << (FormatList() << Format(Format::Bold, 0, 6)) << false;
@@ -111,11 +121,10 @@ void tst_qquickstyledtext::textOutput_data()
QTest::newRow("extra space") << "<b >text</b>" << "text" << (FormatList() << Format(Format::Bold, 0, 4)) << false;
QTest::newRow("entities") << "&lt;b&gt;this &amp; that&lt;/b&gt;" << "<b>this & that</b>" << FormatList() << false;
QTest::newRow("newline") << "text<br>more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList() << false;
+ QTest::newRow("self-closing newline") << "text<br/>more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList() << false;
QTest::newRow("paragraph") << "text<p>more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList() << false;
QTest::newRow("paragraph closed") << "text<p>more text</p>more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList() << false;
QTest::newRow("paragraph closed bold") << "<b>text<p>more text</p>more text</b>" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << (FormatList() << Format(Format::Bold, 0, 24)) << false;
- QTest::newRow("self-closing newline") << "text<br/>more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") << FormatList() << false;
- QTest::newRow("empty") << "" << "" << FormatList() << false;
QTest::newRow("unknown tag") << "<a href='#'><foo>underline</foo></a> not" << "underline not" << (FormatList() << Format(Format::Underline, 0, 9)) << false;
QTest::newRow("ordered list") << "<ol><li>one<li>two" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("1.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("2.") + QString(2, QChar::Nbsp) + QLatin1String("two") << FormatList() << false;
QTest::newRow("ordered list closed") << "<ol><li>one</li><li>two</li></ol>" << QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("1.") + QString(2, QChar::Nbsp) + QLatin1String("one") + QChar(QChar::LineSeparator) + QString(6, QChar::Nbsp) + QLatin1String("2.") + QString(2, QChar::Nbsp) + QLatin1String("two") + QChar(QChar::LineSeparator) << FormatList() << false;
@@ -151,6 +160,7 @@ void tst_qquickstyledtext::textOutput_data()
QTest::newRow("space leading bold") << "this is<b> bold</b>" << "this is bold" << (FormatList() << Format(Format::Bold, 7, 5)) << false;
QTest::newRow("space trailing bold") << "this is <b>bold </b>" << "this is bold " << (FormatList() << Format(Format::Bold, 8, 5)) << false;
QTest::newRow("img") << "a<img src=\"blah.png\"/>b" << "a b" << FormatList() << false;
+ QTest::newRow("tag mix") << "<f6>ds<b></img><pro>gfh</b><w><w>ghj</stron><ql><sl><pl>dfg</j6><img><bol><r><prp>dfg<bkj></b><up><string>ewrq</al><bl>jklhj<zl>" << "dsgfhghjdfgdfgewrqjklhj" << (FormatList() << Format(Format::Bold, 2, 3)) << false;
}
void tst_qquickstyledtext::textOutput()
@@ -183,6 +193,60 @@ void tst_qquickstyledtext::textOutput()
QCOMPARE(fontSizeModified, modifiesFontSize);
}
+void tst_qquickstyledtext::anchors()
+{
+ QFETCH(QString, input);
+ QFETCH(QString, output);
+ QFETCH(FormatList, formats);
+
+ QTextLayout layout;
+ QList<QQuickStyledTextImgTag*> imgTags;
+ bool fontSizeModified = false;
+ QQuickStyledText::parse(input, layout, imgTags, QUrl(), 0, false, &fontSizeModified);
+
+ QCOMPARE(layout.text(), output);
+
+ QList<QTextLayout::FormatRange> layoutFormats = layout.additionalFormats();
+
+ QCOMPARE(layoutFormats.count(), formats.count());
+ for (int i = 0; i < formats.count(); ++i) {
+ QCOMPARE(layoutFormats.at(i).start, formats.at(i).start);
+ QCOMPARE(layoutFormats.at(i).length, formats.at(i).length);
+ QVERIFY(layoutFormats.at(i).format.isAnchor() == bool(formats.at(i).type & Format::Anchor));
+ }
+}
+
+void tst_qquickstyledtext::anchors_data()
+{
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<QString>("output");
+ QTest::addColumn<FormatList>("formats");
+
+ QTest::newRow("empty 1") << "Test string with <a href=>url</a>." << "Test string with url." << FormatList();
+ QTest::newRow("empty 2") << "Test string with <a href="">url</a>." << "Test string with url." << FormatList();
+ QTest::newRow("unknown attr") << "Test string with <a hfre=\"http://strange<username>@ok-hostname\">url</a>." << "Test string with url." << FormatList();
+ QTest::newRow("close") << "Test string with <a href=\"http://strange<username>@ok-hostname\"/>url." << "Test string with url." << (FormatList() << Format(Format::Anchor, 17, 4));
+ QTest::newRow("username") << "Test string with <a href=\"http://strange<username>@ok-hostname\">url</a>." << "Test string with url." << (FormatList() << Format(Format::Anchor, 17, 3));
+ QTest::newRow("query") << "Test string with <a href=\"http://www.foo.bar?hello=world\">url</a>." << "Test string with url." << (FormatList() << Format(Format::Anchor, 17, 3));
+ QTest::newRow("ipv6") << "Test string with <a href=\"//user:pass@[56::56:56:56:127.0.0.1]:99\">url</a>." << "Test string with url." << (FormatList() << Format(Format::Anchor, 17, 3));
+ QTest::newRow("uni") << "Test string with <a href=\"data:text/javascript,d5%20%3D%20'five\\u0027s'%3B\">url</a>." << "Test string with url." << (FormatList() << Format(Format::Anchor, 17, 3));
+ QTest::newRow("utf8") << "Test string with <a href=\"http://www.räksmörgås.se/pub?a=b&a=dø&a=f#vræl\">url</a>." << "Test string with url." << (FormatList() << Format(Format::Anchor, 17, 3));
+}
+
+void tst_qquickstyledtext::longString()
+{
+ QTextLayout layout;
+ QList<QQuickStyledTextImgTag*> imgTags;
+ bool fontSizeModified = false;
+
+ QString input(9999999, QChar('.'));
+ QQuickStyledText::parse(input, layout, imgTags, QUrl(), 0, false, &fontSizeModified);
+ QCOMPARE(layout.text(), input);
+
+ input = QString(9999999, QChar('\t')); // whitespace
+ QQuickStyledText::parse(input, layout, imgTags, QUrl(), 0, false, &fontSizeModified);
+ QCOMPARE(layout.text(), QString(""));
+}
QTEST_MAIN(tst_qquickstyledtext)
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index 724b24280a..a31b30dc60 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -131,6 +131,9 @@ private slots:
void fontFormatSizes_data();
void fontFormatSizes();
+ void baselineOffset_data();
+ void baselineOffset();
+
private:
QStringList standard;
QStringList richText;
@@ -1579,18 +1582,20 @@ void tst_qquicktext::implicitSize()
QFETCH(QString, wrap);
QFETCH(QString, elide);
QString componentStr = "import QtQuick 2.0\nText { "
+ "property real iWidth: implicitWidth; "
"text: \"" + text + "\"; "
"width: " + width + "; "
"textFormat: " + format + "; "
"wrapMode: " + wrap + "; "
"elide: " + elide + "; "
- "maximumLineCount: 1 }";
+ "maximumLineCount: 2 }";
QQmlComponent 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());
+ QCOMPARE(textObject->property("iWidth").toReal(), textObject->implicitWidth());
textObject->resetWidth();
QVERIFY(textObject->width() == textObject->implicitWidth());
@@ -1692,7 +1697,7 @@ void tst_qquicktext::boundingRect()
QCOMPARE(text->boundingRect().x(), qreal(0));
QCOMPARE(text->boundingRect().y(), qreal(0));
QCOMPARE(text->boundingRect().width(), qreal(0));
- QCOMPARE(text->boundingRect().height(), QFontMetricsF(text->font()).height());
+ QCOMPARE(text->boundingRect().height(), qreal(qCeil(QFontMetricsF(text->font()).height())));
text->setText("Hello World");
@@ -2592,6 +2597,251 @@ void tst_qquicktext::fontFormatSizes()
delete view;
}
+typedef qreal (*ExpectedBaseline)(QQuickText *item);
+Q_DECLARE_METATYPE(ExpectedBaseline)
+
+static qreal expectedBaselineTop(QQuickText *item)
+{
+ QFontMetricsF fm(item->font());
+ return fm.ascent();
+}
+
+static qreal expectedBaselineBottom(QQuickText *item)
+{
+ QFontMetricsF fm(item->font());
+ return item->height() - item->contentHeight() + fm.ascent();
+}
+
+static qreal expectedBaselineCenter(QQuickText *item)
+{
+ QFontMetricsF fm(item->font());
+ return ((item->height() - item->contentHeight()) / 2) + fm.ascent();
+}
+
+static qreal expectedBaselineBold(QQuickText *item)
+{
+ QFont font = item->font();
+ font.setBold(true);
+ QFontMetricsF fm(font);
+ return fm.ascent();
+}
+
+static qreal expectedBaselineImage(QQuickText *item)
+{
+ QFontMetricsF fm(item->font());
+ // The line is positioned so the bottom of the line is aligned with the bottom of the image,
+ // or image height - line height and the baseline is line position + ascent. Because
+ // QTextLine's height is rounded up this can give slightly different results to image height
+ // - descent.
+ return 181 - qCeil(fm.height()) + fm.ascent();
+}
+
+static qreal expectedBaselineCustom(QQuickText *item)
+{
+ QFontMetricsF fm(item->font());
+ return 16 + fm.ascent();
+}
+
+static qreal expectedBaselineScaled(QQuickText *item)
+{
+ QFont font = item->font();
+ QTextLayout layout(item->text().replace(QLatin1Char('\n'), QChar::LineSeparator));
+ do {
+ layout.setFont(font);
+ qreal width = 0;
+ layout.beginLayout();
+ for (QTextLine line = layout.createLine(); line.isValid(); line = layout.createLine()) {
+ line.setLineWidth(FLT_MAX);
+ width = qMax(line.naturalTextWidth(), width);
+ }
+ layout.endLayout();
+
+ if (width < item->width()) {
+ QFontMetricsF fm(layout.font());
+ return fm.ascent();
+ }
+ font.setPointSize(font.pointSize() - 1);
+ } while (font.pointSize() > 0);
+ return 0;
+}
+
+static qreal expectedBaselineFixedBottom(QQuickText *item)
+{
+ QFontMetricsF fm(item->font());
+ qreal dy = item->text().contains(QLatin1Char('\n'))
+ ? 160
+ : 180;
+ return dy + fm.ascent();
+}
+
+static qreal expectedBaselineProportionalBottom(QQuickText *item)
+{
+ QFontMetricsF fm(item->font());
+ qreal dy = item->text().contains(QLatin1Char('\n'))
+ ? 200 - (qCeil(fm.height()) * 3)
+ : 200 - (qCeil(fm.height()) * 1.5);
+ return dy + fm.ascent();
+}
+
+void tst_qquicktext::baselineOffset_data()
+{
+ qRegisterMetaType<ExpectedBaseline>();
+ QTest::addColumn<QString>("text");
+ QTest::addColumn<QString>("wrappedText");
+ QTest::addColumn<QByteArray>("bindings");
+ QTest::addColumn<ExpectedBaseline>("expectedBaseline");
+ QTest::addColumn<ExpectedBaseline>("expectedBaselineEmpty");
+
+ QTest::newRow("top align")
+ << "hello world"
+ << "hello\nworld"
+ << QByteArray("height: 200; verticalAlignment: Text.AlignTop")
+ << &expectedBaselineTop
+ << &expectedBaselineTop;
+ QTest::newRow("bottom align")
+ << "hello world"
+ << "hello\nworld"
+ << QByteArray("height: 200; verticalAlignment: Text.AlignBottom")
+ << &expectedBaselineBottom
+ << &expectedBaselineBottom;
+ QTest::newRow("center align")
+ << "hello world"
+ << "hello\nworld"
+ << QByteArray("height: 200; verticalAlignment: Text.AlignVCenter")
+ << &expectedBaselineCenter
+ << &expectedBaselineCenter;
+
+ QTest::newRow("bold")
+ << "<b>hello world</b>"
+ << "<b>hello<br/>world</b>"
+ << QByteArray("height: 200")
+ << &expectedBaselineTop
+ << &expectedBaselineBold;
+
+ QTest::newRow("richText")
+ << "<b>hello world</b>"
+ << "<b>hello<br/>world</b>"
+ << QByteArray("height: 200; textFormat: Text.RichText")
+ << &expectedBaselineTop
+ << &expectedBaselineTop;
+
+ QTest::newRow("elided")
+ << "hello world"
+ << "hello\nworld"
+ << QByteArray("width: 20; height: 8; elide: Text.ElideRight")
+ << &expectedBaselineTop
+ << &expectedBaselineTop;
+
+ QTest::newRow("elided bottom align")
+ << "hello world"
+ << "hello\nworld!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
+ << QByteArray("width: 200; height: 200; elide: Text.ElideRight; verticalAlignment: Text.AlignBottom")
+ << &expectedBaselineBottom
+ << &expectedBaselineBottom;
+
+ QTest::newRow("image")
+ << "hello <img src=\"images/heart200.png\" /> world"
+ << "hello <img src=\"images/heart200.png\" /><br/>world"
+ << QByteArray("height: 200\n; baseUrl: \"") + testFileUrl("reference").toEncoded() + QByteArray("\"")
+ << &expectedBaselineImage
+ << &expectedBaselineTop;
+
+ QTest::newRow("customLine")
+ << "hello world"
+ << "hello\nworld"
+ << QByteArray("height: 200; onLineLaidOut: line.y += 16")
+ << &expectedBaselineCustom
+ << &expectedBaselineCustom;
+
+ QTest::newRow("scaled font")
+ << "hello world"
+ << "hello\nworld"
+ << QByteArray("width: 200; minimumPointSize: 1; font.pointSize: 64; fontSizeMode: Text.HorizontalFit")
+ << &expectedBaselineScaled
+ << &expectedBaselineTop;
+
+ QTest::newRow("fixed line height top align")
+ << "hello world"
+ << "hello\nworld"
+ << QByteArray("height: 200; lineHeightMode: Text.FixedHeight; lineHeight: 20; verticalAlignment: Text.AlignTop")
+ << &expectedBaselineTop
+ << &expectedBaselineTop;
+
+ QTest::newRow("fixed line height bottom align")
+ << "hello world"
+ << "hello\nworld"
+ << QByteArray("height: 200; lineHeightMode: Text.FixedHeight; lineHeight: 20; verticalAlignment: Text.AlignBottom")
+ << &expectedBaselineFixedBottom
+ << &expectedBaselineFixedBottom;
+
+ QTest::newRow("proportional line height top align")
+ << "hello world"
+ << "hello\nworld"
+ << QByteArray("height: 200; lineHeightMode: Text.ProportionalHeight; lineHeight: 1.5; verticalAlignment: Text.AlignTop")
+ << &expectedBaselineTop
+ << &expectedBaselineTop;
+
+ QTest::newRow("proportional line height bottom align")
+ << "hello world"
+ << "hello\nworld"
+ << QByteArray("height: 200; lineHeightMode: Text.ProportionalHeight; lineHeight: 1.5; verticalAlignment: Text.AlignBottom")
+ << &expectedBaselineProportionalBottom
+ << &expectedBaselineProportionalBottom;
+}
+
+void tst_qquicktext::baselineOffset()
+{
+ QFETCH(QString, text);
+ QFETCH(QString, wrappedText);
+ QFETCH(QByteArray, bindings);
+ QFETCH(ExpectedBaseline, expectedBaseline);
+ QFETCH(ExpectedBaseline, expectedBaselineEmpty);
+
+ QQmlComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "Text {\n"
+ + bindings + "\n"
+ "}", QUrl());
+
+ QScopedPointer<QObject> object(component.create());
+
+ QQuickText *item = qobject_cast<QQuickText *>(object.data());
+ QVERIFY(item);
+
+ {
+ qreal baseline = expectedBaselineEmpty(item);
+
+ QCOMPARE(item->baselineOffset(), baseline);
+
+ item->setText(text);
+ if (expectedBaseline != expectedBaselineEmpty)
+ baseline = expectedBaseline(item);
+
+ QCOMPARE(item->baselineOffset(), baseline);
+
+ item->setText(wrappedText);
+ QCOMPARE(item->baselineOffset(), expectedBaseline(item));
+ }
+
+ QFont font = item->font();
+ font.setPointSize(font.pointSize() + 8);
+
+ {
+ QCOMPARE(item->baselineOffset(), expectedBaseline(item));
+
+ item->setText(text);
+ qreal baseline = expectedBaseline(item);
+ QCOMPARE(item->baselineOffset(), baseline);
+
+ item->setText(QString());
+ if (expectedBaselineEmpty != expectedBaseline)
+ baseline = expectedBaselineEmpty(item);
+
+ QCOMPARE(item->baselineOffset(), baseline);
+ }
+}
+
QTEST_MAIN(tst_qquicktext)
#include "tst_qquicktext.moc"
diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
index dd9aa0acad..7113141800 100644
--- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
@@ -2379,6 +2379,11 @@ void tst_qquicktextedit::inputMethodUpdate()
QVERIFY(edit->selectionStart() != edit->selectionEnd());
QVERIFY(platformInputContext.m_updateCallCount > 0);
+ // programmatical selections trigger update
+ platformInputContext.clear();
+ edit->selectAll();
+ QCOMPARE(platformInputContext.m_updateCallCount, 1);
+
// font changes
platformInputContext.clear();
QFont font = edit->font();
diff --git a/tools/easingcurveeditor/mainwindow.cpp b/tools/easingcurveeditor/mainwindow.cpp
index 569b74ae29..3bd5b3e88f 100644
--- a/tools/easingcurveeditor/mainwindow.cpp
+++ b/tools/easingcurveeditor/mainwindow.cpp
@@ -104,7 +104,7 @@ MainWindow::MainWindow(QWidget *parent) :
void MainWindow::showQuickView()
{
const int margin = 16;
- quickView.move(pos() + QPoint(0, frameGeometry().height() + margin));
+ quickView.setPos(pos() + QPoint(0, frameGeometry().height() + margin));
quickView.raise();
quickView.show();